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 13 #include <stddef.h> 14 #include <stdint.h> 15 16 #include <string> 17 #include <vector> 18 19 #include "absl/strings/string_view.h" 20 #include "api/array_view.h" 21 #include "api/rtp_headers.h" 22 #include "api/rtp_parameters.h" 23 #include "api/units/timestamp.h" 24 #include "api/video/color_space.h" 25 #include "api/video/video_content_type.h" 26 #include "api/video/video_rotation.h" 27 #include "api/video/video_timing.h" 28 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 29 30 namespace webrtc { 31 32 class AbsoluteSendTime { 33 public: 34 using value_type = uint32_t; 35 static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteSendTime; 36 static constexpr uint8_t kValueSizeBytes = 3; Uri()37 static constexpr absl::string_view Uri() { 38 return RtpExtension::kAbsSendTimeUri; 39 } 40 41 static bool Parse(rtc::ArrayView<const uint8_t> data, uint32_t* time_24bits); ValueSize(uint32_t time_24bits)42 static size_t ValueSize(uint32_t time_24bits) { return kValueSizeBytes; } 43 static bool Write(rtc::ArrayView<uint8_t> data, uint32_t time_24bits); 44 To24Bits(Timestamp time)45 static constexpr uint32_t To24Bits(Timestamp time) { 46 int64_t time_us = time.us() % (int64_t{1 << 6} * 1'000'000); 47 int64_t time6x18 = (time_us << 18) / 1'000'000; 48 RTC_DCHECK_GE(time6x18, 0); 49 RTC_DCHECK_LT(time6x18, 1 << 24); 50 return static_cast<uint32_t>(time6x18); 51 } 52 }; 53 54 class AbsoluteCaptureTimeExtension { 55 public: 56 using value_type = AbsoluteCaptureTime; 57 static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteCaptureTime; 58 static constexpr uint8_t kValueSizeBytes = 16; 59 static constexpr uint8_t kValueSizeBytesWithoutEstimatedCaptureClockOffset = 60 8; Uri()61 static constexpr absl::string_view Uri() { 62 return RtpExtension::kAbsoluteCaptureTimeUri; 63 } 64 65 static bool Parse(rtc::ArrayView<const uint8_t> data, 66 AbsoluteCaptureTime* extension); 67 static size_t ValueSize(const AbsoluteCaptureTime& extension); 68 static bool Write(rtc::ArrayView<uint8_t> data, 69 const AbsoluteCaptureTime& extension); 70 }; 71 72 class AudioLevel { 73 public: 74 static constexpr RTPExtensionType kId = kRtpExtensionAudioLevel; 75 static constexpr uint8_t kValueSizeBytes = 1; Uri()76 static constexpr absl::string_view Uri() { 77 return RtpExtension::kAudioLevelUri; 78 } 79 80 static bool Parse(rtc::ArrayView<const uint8_t> data, 81 bool* voice_activity, 82 uint8_t* audio_level); ValueSize(bool voice_activity,uint8_t audio_level)83 static size_t ValueSize(bool voice_activity, uint8_t audio_level) { 84 return kValueSizeBytes; 85 } 86 static bool Write(rtc::ArrayView<uint8_t> data, 87 bool voice_activity, 88 uint8_t audio_level); 89 }; 90 91 class CsrcAudioLevel { 92 public: 93 static constexpr RTPExtensionType kId = kRtpExtensionCsrcAudioLevel; 94 static constexpr uint8_t kMaxValueSizeBytes = 15; Uri()95 static constexpr absl::string_view Uri() { 96 return RtpExtension::kCsrcAudioLevelsUri; 97 } 98 99 static bool Parse(rtc::ArrayView<const uint8_t> data, 100 std::vector<uint8_t>* csrc_audio_levels); 101 static size_t ValueSize(rtc::ArrayView<const uint8_t> csrc_audio_levels); 102 static bool Write(rtc::ArrayView<uint8_t> data, 103 rtc::ArrayView<const uint8_t> csrc_audio_levels); 104 }; 105 106 class TransmissionOffset { 107 public: 108 using value_type = int32_t; 109 static constexpr RTPExtensionType kId = kRtpExtensionTransmissionTimeOffset; 110 static constexpr uint8_t kValueSizeBytes = 3; Uri()111 static constexpr absl::string_view Uri() { 112 return RtpExtension::kTimestampOffsetUri; 113 } 114 115 static bool Parse(rtc::ArrayView<const uint8_t> data, int32_t* rtp_time); ValueSize(int32_t rtp_time)116 static size_t ValueSize(int32_t rtp_time) { return kValueSizeBytes; } 117 static bool Write(rtc::ArrayView<uint8_t> data, int32_t rtp_time); 118 }; 119 120 class TransportSequenceNumber { 121 public: 122 using value_type = uint16_t; 123 static constexpr RTPExtensionType kId = kRtpExtensionTransportSequenceNumber; 124 static constexpr uint8_t kValueSizeBytes = 2; Uri()125 static constexpr absl::string_view Uri() { 126 return RtpExtension::kTransportSequenceNumberUri; 127 } 128 129 static bool Parse(rtc::ArrayView<const uint8_t> data, 130 uint16_t* transport_sequence_number); ValueSize(uint16_t)131 static size_t ValueSize(uint16_t /*transport_sequence_number*/) { 132 return kValueSizeBytes; 133 } 134 static bool Write(rtc::ArrayView<uint8_t> data, 135 uint16_t transport_sequence_number); 136 }; 137 138 class TransportSequenceNumberV2 { 139 public: 140 static constexpr RTPExtensionType kId = 141 kRtpExtensionTransportSequenceNumber02; 142 static constexpr uint8_t kValueSizeBytes = 4; 143 static constexpr uint8_t kValueSizeBytesWithoutFeedbackRequest = 2; Uri()144 static constexpr absl::string_view Uri() { 145 return RtpExtension::kTransportSequenceNumberV2Uri; 146 } 147 148 static bool Parse(rtc::ArrayView<const uint8_t> data, 149 uint16_t* transport_sequence_number, 150 absl::optional<FeedbackRequest>* feedback_request); ValueSize(uint16_t,const absl::optional<FeedbackRequest> & feedback_request)151 static size_t ValueSize( 152 uint16_t /*transport_sequence_number*/, 153 const absl::optional<FeedbackRequest>& feedback_request) { 154 return feedback_request ? kValueSizeBytes 155 : kValueSizeBytesWithoutFeedbackRequest; 156 } 157 static bool Write(rtc::ArrayView<uint8_t> data, 158 uint16_t transport_sequence_number, 159 const absl::optional<FeedbackRequest>& feedback_request); 160 161 private: 162 static constexpr uint16_t kIncludeTimestampsBit = 1 << 15; 163 }; 164 165 class VideoOrientation { 166 public: 167 using value_type = VideoRotation; 168 static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation; 169 static constexpr uint8_t kValueSizeBytes = 1; Uri()170 static constexpr absl::string_view Uri() { 171 return RtpExtension::kVideoRotationUri; 172 } 173 174 static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value); ValueSize(VideoRotation)175 static size_t ValueSize(VideoRotation) { return kValueSizeBytes; } 176 static bool Write(rtc::ArrayView<uint8_t> data, VideoRotation value); 177 static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value); ValueSize(uint8_t value)178 static size_t ValueSize(uint8_t value) { return kValueSizeBytes; } 179 static bool Write(rtc::ArrayView<uint8_t> data, uint8_t value); 180 }; 181 182 class PlayoutDelayLimits { 183 public: 184 using value_type = VideoPlayoutDelay; 185 static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay; 186 static constexpr uint8_t kValueSizeBytes = 3; Uri()187 static constexpr absl::string_view Uri() { 188 return RtpExtension::kPlayoutDelayUri; 189 } 190 191 // Playout delay in milliseconds. A playout delay limit (min or max) 192 // has 12 bits allocated. This allows a range of 0-4095 values which 193 // translates to a range of 0-40950 in milliseconds. 194 static constexpr int kGranularityMs = 10; 195 // Maximum playout delay value in milliseconds. 196 static constexpr int kMaxMs = 0xfff * kGranularityMs; // 40950. 197 198 static bool Parse(rtc::ArrayView<const uint8_t> data, 199 VideoPlayoutDelay* playout_delay); ValueSize(const VideoPlayoutDelay &)200 static size_t ValueSize(const VideoPlayoutDelay&) { return kValueSizeBytes; } 201 static bool Write(rtc::ArrayView<uint8_t> data, 202 const VideoPlayoutDelay& playout_delay); 203 }; 204 205 class VideoContentTypeExtension { 206 public: 207 using value_type = VideoContentType; 208 static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType; 209 static constexpr uint8_t kValueSizeBytes = 1; Uri()210 static constexpr absl::string_view Uri() { 211 return RtpExtension::kVideoContentTypeUri; 212 } 213 214 static bool Parse(rtc::ArrayView<const uint8_t> data, 215 VideoContentType* content_type); ValueSize(VideoContentType)216 static size_t ValueSize(VideoContentType) { return kValueSizeBytes; } 217 static bool Write(rtc::ArrayView<uint8_t> data, 218 VideoContentType content_type); 219 }; 220 221 class VideoTimingExtension { 222 public: 223 using value_type = VideoSendTiming; 224 static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming; 225 static constexpr uint8_t kValueSizeBytes = 13; Uri()226 static constexpr absl::string_view Uri() { 227 return RtpExtension::kVideoTimingUri; 228 } 229 230 // Offsets of the fields in the RTP header extension, counting from the first 231 // byte after the one-byte header. 232 static constexpr uint8_t kFlagsOffset = 0; 233 static constexpr uint8_t kEncodeStartDeltaOffset = 1; 234 static constexpr uint8_t kEncodeFinishDeltaOffset = 3; 235 static constexpr uint8_t kPacketizationFinishDeltaOffset = 5; 236 static constexpr uint8_t kPacerExitDeltaOffset = 7; 237 static constexpr uint8_t kNetworkTimestampDeltaOffset = 9; 238 static constexpr uint8_t kNetwork2TimestampDeltaOffset = 11; 239 240 static bool Parse(rtc::ArrayView<const uint8_t> data, 241 VideoSendTiming* timing); ValueSize(const VideoSendTiming &)242 static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; } 243 static bool Write(rtc::ArrayView<uint8_t> data, 244 const VideoSendTiming& timing); 245 ValueSize(uint16_t time_delta_ms,uint8_t idx)246 static size_t ValueSize(uint16_t time_delta_ms, uint8_t idx) { 247 return kValueSizeBytes; 248 } 249 // Writes only single time delta to position idx. 250 static bool Write(rtc::ArrayView<uint8_t> data, 251 uint16_t time_delta_ms, 252 uint8_t offset); 253 }; 254 255 class ColorSpaceExtension { 256 public: 257 using value_type = ColorSpace; 258 static constexpr RTPExtensionType kId = kRtpExtensionColorSpace; 259 static constexpr uint8_t kValueSizeBytes = 28; 260 static constexpr uint8_t kValueSizeBytesWithoutHdrMetadata = 4; Uri()261 static constexpr absl::string_view Uri() { 262 return RtpExtension::kColorSpaceUri; 263 } 264 265 static bool Parse(rtc::ArrayView<const uint8_t> data, 266 ColorSpace* color_space); ValueSize(const ColorSpace & color_space)267 static size_t ValueSize(const ColorSpace& color_space) { 268 return color_space.hdr_metadata() ? kValueSizeBytes 269 : kValueSizeBytesWithoutHdrMetadata; 270 } 271 static bool Write(rtc::ArrayView<uint8_t> data, 272 const ColorSpace& color_space); 273 274 private: 275 static constexpr int kChromaticityDenominator = 50000; // 0.00002 resolution. 276 static constexpr int kLuminanceMaxDenominator = 1; // 1 resolution. 277 static constexpr int kLuminanceMinDenominator = 10000; // 0.0001 resolution. 278 279 static uint8_t CombineRangeAndChromaSiting( 280 ColorSpace::RangeID range, 281 ColorSpace::ChromaSiting chroma_siting_horizontal, 282 ColorSpace::ChromaSiting chroma_siting_vertical); 283 static size_t ParseHdrMetadata(rtc::ArrayView<const uint8_t> data, 284 HdrMetadata* hdr_metadata); 285 static size_t ParseChromaticity(const uint8_t* data, 286 HdrMasteringMetadata::Chromaticity* p); 287 static size_t ParseLuminance(const uint8_t* data, float* f, int denominator); 288 static size_t WriteHdrMetadata(rtc::ArrayView<uint8_t> data, 289 const HdrMetadata& hdr_metadata); 290 static size_t WriteChromaticity(uint8_t* data, 291 const HdrMasteringMetadata::Chromaticity& p); 292 static size_t WriteLuminance(uint8_t* data, float f, int denominator); 293 }; 294 295 // Base extension class for RTP header extensions which are strings. 296 // Subclasses must defined kId and kUri static constexpr members. 297 class BaseRtpStringExtension { 298 public: 299 using value_type = std::string; 300 // String RTP header extensions are limited to 16 bytes because it is the 301 // maximum length that can be encoded with one-byte header extensions. 302 static constexpr uint8_t kMaxValueSizeBytes = 16; 303 304 static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* str); ValueSize(absl::string_view str)305 static size_t ValueSize(absl::string_view str) { return str.size(); } 306 static bool Write(rtc::ArrayView<uint8_t> data, absl::string_view str); 307 }; 308 309 class RtpStreamId : public BaseRtpStringExtension { 310 public: 311 static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId; Uri()312 static constexpr absl::string_view Uri() { return RtpExtension::kRidUri; } 313 }; 314 315 class RepairedRtpStreamId : public BaseRtpStringExtension { 316 public: 317 static constexpr RTPExtensionType kId = kRtpExtensionRepairedRtpStreamId; Uri()318 static constexpr absl::string_view Uri() { 319 return RtpExtension::kRepairedRidUri; 320 } 321 }; 322 323 class RtpMid : public BaseRtpStringExtension { 324 public: 325 static constexpr RTPExtensionType kId = kRtpExtensionMid; Uri()326 static constexpr absl::string_view Uri() { return RtpExtension::kMidUri; } 327 }; 328 329 class InbandComfortNoiseExtension { 330 public: 331 using value_type = absl::optional<uint8_t>; 332 333 static constexpr RTPExtensionType kId = kRtpExtensionInbandComfortNoise; 334 static constexpr uint8_t kValueSizeBytes = 1; 335 static constexpr const char kUri[] = 336 "http://www.webrtc.org/experiments/rtp-hdrext/inband-cn"; Uri()337 static constexpr absl::string_view Uri() { return kUri; } 338 339 static bool Parse(rtc::ArrayView<const uint8_t> data, 340 absl::optional<uint8_t>* level); ValueSize(absl::optional<uint8_t> level)341 static size_t ValueSize(absl::optional<uint8_t> level) { 342 return kValueSizeBytes; 343 } 344 static bool Write(rtc::ArrayView<uint8_t> data, 345 absl::optional<uint8_t> level); 346 }; 347 348 class VideoFrameTrackingIdExtension { 349 public: 350 using value_type = uint16_t; 351 static constexpr RTPExtensionType kId = kRtpExtensionVideoFrameTrackingId; 352 static constexpr uint8_t kValueSizeBytes = 2; Uri()353 static constexpr absl::string_view Uri() { 354 return RtpExtension::kVideoFrameTrackingIdUri; 355 } 356 357 static bool Parse(rtc::ArrayView<const uint8_t> data, 358 uint16_t* video_frame_tracking_id); ValueSize(uint16_t)359 static size_t ValueSize(uint16_t /*video_frame_tracking_id*/) { 360 return kValueSizeBytes; 361 } 362 static bool Write(rtc::ArrayView<uint8_t> data, 363 uint16_t video_frame_tracking_id); 364 }; 365 366 } // namespace webrtc 367 #endif // MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_ 368