packet.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef MODULES_AUDIO_CODING_NETEQ_PACKET_H_
  11. #define MODULES_AUDIO_CODING_NETEQ_PACKET_H_
  12. #include <stdint.h>
  13. #include <list>
  14. #include <memory>
  15. #include "api/audio_codecs/audio_decoder.h"
  16. #include "api/neteq/tick_timer.h"
  17. #include "api/rtp_packet_info.h"
  18. #include "rtc_base/buffer.h"
  19. #include "rtc_base/checks.h"
  20. namespace webrtc {
  21. // Struct for holding RTP packets.
  22. struct Packet {
  23. struct Priority {
  24. Priority() : codec_level(0), red_level(0) {}
  25. Priority(int codec_level, int red_level)
  26. : codec_level(codec_level), red_level(red_level) {
  27. CheckInvariant();
  28. }
  29. int codec_level;
  30. int red_level;
  31. // Priorities are sorted low-to-high, first on the level the codec
  32. // prioritizes it, then on the level of RED packet it is; i.e. if it is a
  33. // primary or secondary payload of a RED packet. For example: with Opus, an
  34. // Fec packet (which the decoder prioritizes lower than a regular packet)
  35. // will not be used if there is _any_ RED payload for the same
  36. // timeframe. The highest priority packet will have levels {0, 0}. Negative
  37. // priorities are not allowed.
  38. bool operator<(const Priority& b) const {
  39. CheckInvariant();
  40. b.CheckInvariant();
  41. if (codec_level == b.codec_level)
  42. return red_level < b.red_level;
  43. return codec_level < b.codec_level;
  44. }
  45. bool operator==(const Priority& b) const {
  46. CheckInvariant();
  47. b.CheckInvariant();
  48. return codec_level == b.codec_level && red_level == b.red_level;
  49. }
  50. bool operator!=(const Priority& b) const { return !(*this == b); }
  51. bool operator>(const Priority& b) const { return b < *this; }
  52. bool operator<=(const Priority& b) const { return !(b > *this); }
  53. bool operator>=(const Priority& b) const { return !(b < *this); }
  54. private:
  55. void CheckInvariant() const {
  56. RTC_DCHECK_GE(codec_level, 0);
  57. RTC_DCHECK_GE(red_level, 0);
  58. }
  59. };
  60. uint32_t timestamp;
  61. uint16_t sequence_number;
  62. uint8_t payload_type;
  63. // Datagram excluding RTP header and header extension.
  64. rtc::Buffer payload;
  65. Priority priority;
  66. RtpPacketInfo packet_info;
  67. std::unique_ptr<TickTimer::Stopwatch> waiting_time;
  68. std::unique_ptr<AudioDecoder::EncodedAudioFrame> frame;
  69. Packet();
  70. Packet(Packet&& b);
  71. ~Packet();
  72. // Packets should generally be moved around but sometimes it's useful to make
  73. // a copy, for example for testing purposes. NOTE: Will only work for
  74. // un-parsed packets, i.e. |frame| must be unset. The payload will, however,
  75. // be copied. |waiting_time| will also not be copied.
  76. Packet Clone() const;
  77. Packet& operator=(Packet&& b);
  78. // Comparison operators. Establish a packet ordering based on (1) timestamp,
  79. // (2) sequence number and (3) redundancy.
  80. // Timestamp and sequence numbers are compared taking wrap-around into
  81. // account. For two packets with the same sequence number and timestamp a
  82. // primary payload is considered "smaller" than a secondary.
  83. bool operator==(const Packet& rhs) const {
  84. return (this->timestamp == rhs.timestamp &&
  85. this->sequence_number == rhs.sequence_number &&
  86. this->priority == rhs.priority);
  87. }
  88. bool operator!=(const Packet& rhs) const { return !operator==(rhs); }
  89. bool operator<(const Packet& rhs) const {
  90. if (this->timestamp == rhs.timestamp) {
  91. if (this->sequence_number == rhs.sequence_number) {
  92. // Timestamp and sequence numbers are identical - deem the left hand
  93. // side to be "smaller" (i.e., "earlier") if it has higher priority.
  94. return this->priority < rhs.priority;
  95. }
  96. return (static_cast<uint16_t>(rhs.sequence_number -
  97. this->sequence_number) < 0xFFFF / 2);
  98. }
  99. return (static_cast<uint32_t>(rhs.timestamp - this->timestamp) <
  100. 0xFFFFFFFF / 2);
  101. }
  102. bool operator>(const Packet& rhs) const { return rhs.operator<(*this); }
  103. bool operator<=(const Packet& rhs) const { return !operator>(rhs); }
  104. bool operator>=(const Packet& rhs) const { return !operator<(rhs); }
  105. bool empty() const { return !frame && payload.empty(); }
  106. };
  107. // A list of packets.
  108. typedef std::list<Packet> PacketList;
  109. } // namespace webrtc
  110. #endif // MODULES_AUDIO_CODING_NETEQ_PACKET_H_