rtp_header_extensions.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*
  2. * Copyright (c) 2016 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_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_
  11. #define MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_
  12. #include <stddef.h>
  13. #include <stdint.h>
  14. #include <string>
  15. #include "api/array_view.h"
  16. #include "api/rtp_headers.h"
  17. #include "api/video/color_space.h"
  18. #include "api/video/video_content_type.h"
  19. #include "api/video/video_rotation.h"
  20. #include "api/video/video_timing.h"
  21. #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
  22. namespace webrtc {
  23. class AbsoluteSendTime {
  24. public:
  25. using value_type = uint32_t;
  26. static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteSendTime;
  27. static constexpr uint8_t kValueSizeBytes = 3;
  28. static constexpr const char kUri[] =
  29. "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
  30. static bool Parse(rtc::ArrayView<const uint8_t> data, uint32_t* time_24bits);
  31. static size_t ValueSize(uint32_t time_24bits) { return kValueSizeBytes; }
  32. static bool Write(rtc::ArrayView<uint8_t> data, uint32_t time_24bits);
  33. static constexpr uint32_t MsTo24Bits(int64_t time_ms) {
  34. return static_cast<uint32_t>(((time_ms << 18) + 500) / 1000) & 0x00FFFFFF;
  35. }
  36. };
  37. class AbsoluteCaptureTimeExtension {
  38. public:
  39. using value_type = AbsoluteCaptureTime;
  40. static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteCaptureTime;
  41. static constexpr uint8_t kValueSizeBytes = 16;
  42. static constexpr uint8_t kValueSizeBytesWithoutEstimatedCaptureClockOffset =
  43. 8;
  44. static constexpr const char kUri[] =
  45. "http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time";
  46. static bool Parse(rtc::ArrayView<const uint8_t> data,
  47. AbsoluteCaptureTime* extension);
  48. static size_t ValueSize(const AbsoluteCaptureTime& extension);
  49. static bool Write(rtc::ArrayView<uint8_t> data,
  50. const AbsoluteCaptureTime& extension);
  51. };
  52. class AudioLevel {
  53. public:
  54. static constexpr RTPExtensionType kId = kRtpExtensionAudioLevel;
  55. static constexpr uint8_t kValueSizeBytes = 1;
  56. static constexpr const char kUri[] =
  57. "urn:ietf:params:rtp-hdrext:ssrc-audio-level";
  58. static bool Parse(rtc::ArrayView<const uint8_t> data,
  59. bool* voice_activity,
  60. uint8_t* audio_level);
  61. static size_t ValueSize(bool voice_activity, uint8_t audio_level) {
  62. return kValueSizeBytes;
  63. }
  64. static bool Write(rtc::ArrayView<uint8_t> data,
  65. bool voice_activity,
  66. uint8_t audio_level);
  67. };
  68. class TransmissionOffset {
  69. public:
  70. using value_type = int32_t;
  71. static constexpr RTPExtensionType kId = kRtpExtensionTransmissionTimeOffset;
  72. static constexpr uint8_t kValueSizeBytes = 3;
  73. static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:toffset";
  74. static bool Parse(rtc::ArrayView<const uint8_t> data, int32_t* rtp_time);
  75. static size_t ValueSize(int32_t rtp_time) { return kValueSizeBytes; }
  76. static bool Write(rtc::ArrayView<uint8_t> data, int32_t rtp_time);
  77. };
  78. class TransportSequenceNumber {
  79. public:
  80. using value_type = uint16_t;
  81. static constexpr RTPExtensionType kId = kRtpExtensionTransportSequenceNumber;
  82. static constexpr uint8_t kValueSizeBytes = 2;
  83. static constexpr const char kUri[] =
  84. "http://www.ietf.org/id/"
  85. "draft-holmer-rmcat-transport-wide-cc-extensions-01";
  86. static bool Parse(rtc::ArrayView<const uint8_t> data,
  87. uint16_t* transport_sequence_number);
  88. static size_t ValueSize(uint16_t /*transport_sequence_number*/) {
  89. return kValueSizeBytes;
  90. }
  91. static bool Write(rtc::ArrayView<uint8_t> data,
  92. uint16_t transport_sequence_number);
  93. };
  94. class TransportSequenceNumberV2 {
  95. public:
  96. static constexpr RTPExtensionType kId =
  97. kRtpExtensionTransportSequenceNumber02;
  98. static constexpr uint8_t kValueSizeBytes = 4;
  99. static constexpr uint8_t kValueSizeBytesWithoutFeedbackRequest = 2;
  100. static constexpr const char kUri[] =
  101. "http://www.webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02";
  102. static bool Parse(rtc::ArrayView<const uint8_t> data,
  103. uint16_t* transport_sequence_number,
  104. absl::optional<FeedbackRequest>* feedback_request);
  105. static size_t ValueSize(
  106. uint16_t /*transport_sequence_number*/,
  107. const absl::optional<FeedbackRequest>& feedback_request) {
  108. return feedback_request ? kValueSizeBytes
  109. : kValueSizeBytesWithoutFeedbackRequest;
  110. }
  111. static bool Write(rtc::ArrayView<uint8_t> data,
  112. uint16_t transport_sequence_number,
  113. const absl::optional<FeedbackRequest>& feedback_request);
  114. private:
  115. static constexpr uint16_t kIncludeTimestampsBit = 1 << 15;
  116. };
  117. class VideoOrientation {
  118. public:
  119. using value_type = VideoRotation;
  120. static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation;
  121. static constexpr uint8_t kValueSizeBytes = 1;
  122. static constexpr const char kUri[] = "urn:3gpp:video-orientation";
  123. static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value);
  124. static size_t ValueSize(VideoRotation) { return kValueSizeBytes; }
  125. static bool Write(rtc::ArrayView<uint8_t> data, VideoRotation value);
  126. static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value);
  127. static size_t ValueSize(uint8_t value) { return kValueSizeBytes; }
  128. static bool Write(rtc::ArrayView<uint8_t> data, uint8_t value);
  129. };
  130. class PlayoutDelayLimits {
  131. public:
  132. using value_type = VideoPlayoutDelay;
  133. static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay;
  134. static constexpr uint8_t kValueSizeBytes = 3;
  135. static constexpr const char kUri[] =
  136. "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay";
  137. // Playout delay in milliseconds. A playout delay limit (min or max)
  138. // has 12 bits allocated. This allows a range of 0-4095 values which
  139. // translates to a range of 0-40950 in milliseconds.
  140. static constexpr int kGranularityMs = 10;
  141. // Maximum playout delay value in milliseconds.
  142. static constexpr int kMaxMs = 0xfff * kGranularityMs; // 40950.
  143. static bool Parse(rtc::ArrayView<const uint8_t> data,
  144. VideoPlayoutDelay* playout_delay);
  145. static size_t ValueSize(const VideoPlayoutDelay&) { return kValueSizeBytes; }
  146. static bool Write(rtc::ArrayView<uint8_t> data,
  147. const VideoPlayoutDelay& playout_delay);
  148. };
  149. class VideoContentTypeExtension {
  150. public:
  151. using value_type = VideoContentType;
  152. static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType;
  153. static constexpr uint8_t kValueSizeBytes = 1;
  154. static constexpr const char kUri[] =
  155. "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type";
  156. static bool Parse(rtc::ArrayView<const uint8_t> data,
  157. VideoContentType* content_type);
  158. static size_t ValueSize(VideoContentType) { return kValueSizeBytes; }
  159. static bool Write(rtc::ArrayView<uint8_t> data,
  160. VideoContentType content_type);
  161. };
  162. class VideoTimingExtension {
  163. public:
  164. using value_type = VideoSendTiming;
  165. static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming;
  166. static constexpr uint8_t kValueSizeBytes = 13;
  167. static constexpr const char kUri[] =
  168. "http://www.webrtc.org/experiments/rtp-hdrext/video-timing";
  169. // Offsets of the fields in the RTP header extension, counting from the first
  170. // byte after the one-byte header.
  171. static constexpr uint8_t kFlagsOffset = 0;
  172. static constexpr uint8_t kEncodeStartDeltaOffset = 1;
  173. static constexpr uint8_t kEncodeFinishDeltaOffset = 3;
  174. static constexpr uint8_t kPacketizationFinishDeltaOffset = 5;
  175. static constexpr uint8_t kPacerExitDeltaOffset = 7;
  176. static constexpr uint8_t kNetworkTimestampDeltaOffset = 9;
  177. static constexpr uint8_t kNetwork2TimestampDeltaOffset = 11;
  178. static bool Parse(rtc::ArrayView<const uint8_t> data,
  179. VideoSendTiming* timing);
  180. static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; }
  181. static bool Write(rtc::ArrayView<uint8_t> data,
  182. const VideoSendTiming& timing);
  183. static size_t ValueSize(uint16_t time_delta_ms, uint8_t idx) {
  184. return kValueSizeBytes;
  185. }
  186. // Writes only single time delta to position idx.
  187. static bool Write(rtc::ArrayView<uint8_t> data,
  188. uint16_t time_delta_ms,
  189. uint8_t offset);
  190. };
  191. class ColorSpaceExtension {
  192. public:
  193. using value_type = ColorSpace;
  194. static constexpr RTPExtensionType kId = kRtpExtensionColorSpace;
  195. static constexpr uint8_t kValueSizeBytes = 28;
  196. static constexpr uint8_t kValueSizeBytesWithoutHdrMetadata = 4;
  197. static constexpr const char kUri[] =
  198. "http://www.webrtc.org/experiments/rtp-hdrext/color-space";
  199. static bool Parse(rtc::ArrayView<const uint8_t> data,
  200. ColorSpace* color_space);
  201. static size_t ValueSize(const ColorSpace& color_space) {
  202. return color_space.hdr_metadata() ? kValueSizeBytes
  203. : kValueSizeBytesWithoutHdrMetadata;
  204. }
  205. static bool Write(rtc::ArrayView<uint8_t> data,
  206. const ColorSpace& color_space);
  207. private:
  208. static constexpr int kChromaticityDenominator = 50000; // 0.00002 resolution.
  209. static constexpr int kLuminanceMaxDenominator = 1; // 1 resolution.
  210. static constexpr int kLuminanceMinDenominator = 10000; // 0.0001 resolution.
  211. static uint8_t CombineRangeAndChromaSiting(
  212. ColorSpace::RangeID range,
  213. ColorSpace::ChromaSiting chroma_siting_horizontal,
  214. ColorSpace::ChromaSiting chroma_siting_vertical);
  215. static size_t ParseHdrMetadata(rtc::ArrayView<const uint8_t> data,
  216. HdrMetadata* hdr_metadata);
  217. static size_t ParseChromaticity(const uint8_t* data,
  218. HdrMasteringMetadata::Chromaticity* p);
  219. static size_t ParseLuminance(const uint8_t* data, float* f, int denominator);
  220. static size_t WriteHdrMetadata(rtc::ArrayView<uint8_t> data,
  221. const HdrMetadata& hdr_metadata);
  222. static size_t WriteChromaticity(uint8_t* data,
  223. const HdrMasteringMetadata::Chromaticity& p);
  224. static size_t WriteLuminance(uint8_t* data, float f, int denominator);
  225. };
  226. // Base extension class for RTP header extensions which are strings.
  227. // Subclasses must defined kId and kUri static constexpr members.
  228. class BaseRtpStringExtension {
  229. public:
  230. using value_type = std::string;
  231. // String RTP header extensions are limited to 16 bytes because it is the
  232. // maximum length that can be encoded with one-byte header extensions.
  233. static constexpr uint8_t kMaxValueSizeBytes = 16;
  234. static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* str);
  235. static size_t ValueSize(const std::string& str) { return str.size(); }
  236. static bool Write(rtc::ArrayView<uint8_t> data, const std::string& str);
  237. };
  238. class RtpStreamId : public BaseRtpStringExtension {
  239. public:
  240. static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId;
  241. static constexpr const char kUri[] =
  242. "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
  243. };
  244. class RepairedRtpStreamId : public BaseRtpStringExtension {
  245. public:
  246. static constexpr RTPExtensionType kId = kRtpExtensionRepairedRtpStreamId;
  247. static constexpr const char kUri[] =
  248. "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";
  249. };
  250. class RtpMid : public BaseRtpStringExtension {
  251. public:
  252. static constexpr RTPExtensionType kId = kRtpExtensionMid;
  253. static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:sdes:mid";
  254. };
  255. class InbandComfortNoiseExtension {
  256. public:
  257. using value_type = absl::optional<uint8_t>;
  258. static constexpr RTPExtensionType kId = kRtpExtensionInbandComfortNoise;
  259. static constexpr uint8_t kValueSizeBytes = 1;
  260. static constexpr const char kUri[] =
  261. "http://www.webrtc.org/experiments/rtp-hdrext/inband-cn";
  262. static bool Parse(rtc::ArrayView<const uint8_t> data,
  263. absl::optional<uint8_t>* level);
  264. static size_t ValueSize(absl::optional<uint8_t> level) {
  265. return kValueSizeBytes;
  266. }
  267. static bool Write(rtc::ArrayView<uint8_t> data,
  268. absl::optional<uint8_t> level);
  269. };
  270. } // namespace webrtc
  271. #endif // MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_