xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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