blob: 5cf6c4f6e8e05ec2c674d5c8d57db6bd97c64d39 [file] [log] [blame]
danilchap1edb7ab2016-04-20 05:25:10 -07001/*
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 */
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020010#ifndef MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_
11#define MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_
danilchap1edb7ab2016-04-20 05:25:10 -070012
Yves Gerey988cc082018-10-23 12:03:01 +020013#include <stddef.h>
pbosc7c26a02017-01-02 08:42:32 -080014#include <stdint.h>
danilchapef8d7732017-04-19 02:59:48 -070015#include <string>
pbosc7c26a02017-01-02 08:42:32 -080016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/array_view.h"
Yves Gerey988cc082018-10-23 12:03:01 +020018#include "api/rtp_headers.h"
Johannes Kron09d65882018-11-27 14:36:41 +010019#include "api/video/color_space.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "api/video/video_content_type.h"
Yves Gerey988cc082018-10-23 12:03:01 +020021#include "api/video/video_frame_marking.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "api/video/video_rotation.h"
23#include "api/video/video_timing.h"
24#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
danilchap1edb7ab2016-04-20 05:25:10 -070025
26namespace webrtc {
27
28class AbsoluteSendTime {
29 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +010030 using value_type = uint32_t;
danilchap1edb7ab2016-04-20 05:25:10 -070031 static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteSendTime;
32 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -070033 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -080034 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
danilchape2a01772016-10-28 07:08:58 -070035
danilchap978504e2017-04-06 01:03:53 -070036 static bool Parse(rtc::ArrayView<const uint8_t> data, uint32_t* time_24bits);
Danil Chapovalovf3ba6482017-06-12 15:43:55 +020037 static size_t ValueSize(uint32_t time_24bits) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +020038 static bool Write(rtc::ArrayView<uint8_t> data, uint32_t time_24bits);
danilchapa897f262016-08-26 05:42:41 -070039
40 static constexpr uint32_t MsTo24Bits(int64_t time_ms) {
41 return static_cast<uint32_t>(((time_ms << 18) + 500) / 1000) & 0x00FFFFFF;
42 }
danilchap1edb7ab2016-04-20 05:25:10 -070043};
44
Chen Xingcd8a6e22019-07-01 10:56:51 +020045class AbsoluteCaptureTimeExtension {
46 public:
47 using value_type = AbsoluteCaptureTime;
48 static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteCaptureTime;
49 static constexpr uint8_t kValueSizeBytes = 16;
50 static constexpr uint8_t kValueSizeBytesWithoutEstimatedCaptureClockOffset =
51 8;
52 static constexpr const char kUri[] =
53 "http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time";
54
55 static bool Parse(rtc::ArrayView<const uint8_t> data,
56 AbsoluteCaptureTime* extension);
57 static size_t ValueSize(const AbsoluteCaptureTime& extension);
58 static bool Write(rtc::ArrayView<uint8_t> data,
59 const AbsoluteCaptureTime& extension);
60};
61
danilchap1edb7ab2016-04-20 05:25:10 -070062class AudioLevel {
63 public:
64 static constexpr RTPExtensionType kId = kRtpExtensionAudioLevel;
65 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -070066 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -080067 "urn:ietf:params:rtp-hdrext:ssrc-audio-level";
danilchape2a01772016-10-28 07:08:58 -070068
danilchap978504e2017-04-06 01:03:53 -070069 static bool Parse(rtc::ArrayView<const uint8_t> data,
danilchap1edb7ab2016-04-20 05:25:10 -070070 bool* voice_activity,
71 uint8_t* audio_level);
erikvargae6b16192017-05-11 02:36:32 -070072 static size_t ValueSize(bool voice_activity, uint8_t audio_level) {
73 return kValueSizeBytes;
74 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +020075 static bool Write(rtc::ArrayView<uint8_t> data,
76 bool voice_activity,
77 uint8_t audio_level);
danilchap1edb7ab2016-04-20 05:25:10 -070078};
79
80class TransmissionOffset {
81 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +010082 using value_type = int32_t;
danilchap1edb7ab2016-04-20 05:25:10 -070083 static constexpr RTPExtensionType kId = kRtpExtensionTransmissionTimeOffset;
84 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -070085 static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:toffset";
danilchape2a01772016-10-28 07:08:58 -070086
danilchap978504e2017-04-06 01:03:53 -070087 static bool Parse(rtc::ArrayView<const uint8_t> data, int32_t* rtp_time);
erikvargae6b16192017-05-11 02:36:32 -070088 static size_t ValueSize(int32_t rtp_time) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +020089 static bool Write(rtc::ArrayView<uint8_t> data, int32_t rtp_time);
danilchap1edb7ab2016-04-20 05:25:10 -070090};
91
92class TransportSequenceNumber {
93 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +010094 using value_type = uint16_t;
danilchap1edb7ab2016-04-20 05:25:10 -070095 static constexpr RTPExtensionType kId = kRtpExtensionTransportSequenceNumber;
96 static constexpr uint8_t kValueSizeBytes = 2;
Steve Antond14d9f72017-07-21 10:59:39 -070097 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -080098 "http://www.ietf.org/id/"
99 "draft-holmer-rmcat-transport-wide-cc-extensions-01";
Johannes Kron54047be2019-02-21 14:09:20 +0000100 static bool Parse(rtc::ArrayView<const uint8_t> data,
101 uint16_t* transport_sequence_number);
102 static size_t ValueSize(uint16_t /*transport_sequence_number*/) {
103 return kValueSizeBytes;
104 }
105 static bool Write(rtc::ArrayView<uint8_t> data,
106 uint16_t transport_sequence_number);
107};
108
109class TransportSequenceNumberV2 {
110 public:
111 static constexpr RTPExtensionType kId =
112 kRtpExtensionTransportSequenceNumber02;
Johannes Kron0da25a12019-03-06 09:34:13 +0100113 static constexpr uint8_t kValueSizeBytes = 4;
114 static constexpr uint8_t kValueSizeBytesWithoutFeedbackRequest = 2;
Johannes Kron54047be2019-02-21 14:09:20 +0000115 static constexpr const char kUri[] =
Johannes Kron8cc711a2019-03-07 22:36:35 +0100116 "http://www.webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02";
Johannes Kron54047be2019-02-21 14:09:20 +0000117 static bool Parse(rtc::ArrayView<const uint8_t> data,
118 uint16_t* transport_sequence_number,
119 absl::optional<FeedbackRequest>* feedback_request);
120 static size_t ValueSize(
121 uint16_t /*transport_sequence_number*/,
122 const absl::optional<FeedbackRequest>& feedback_request) {
Johannes Kron0da25a12019-03-06 09:34:13 +0100123 return feedback_request ? kValueSizeBytes
124 : kValueSizeBytesWithoutFeedbackRequest;
Johannes Kron54047be2019-02-21 14:09:20 +0000125 }
126 static bool Write(rtc::ArrayView<uint8_t> data,
127 uint16_t transport_sequence_number,
128 const absl::optional<FeedbackRequest>& feedback_request);
129
130 private:
131 static constexpr uint16_t kIncludeTimestampsBit = 1 << 15;
danilchap1edb7ab2016-04-20 05:25:10 -0700132};
133
134class VideoOrientation {
135 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100136 using value_type = VideoRotation;
danilchap1edb7ab2016-04-20 05:25:10 -0700137 static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation;
138 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -0700139 static constexpr const char kUri[] = "urn:3gpp:video-orientation";
danilchape2a01772016-10-28 07:08:58 -0700140
danilchap978504e2017-04-06 01:03:53 -0700141 static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value);
erikvargae6b16192017-05-11 02:36:32 -0700142 static size_t ValueSize(VideoRotation) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200143 static bool Write(rtc::ArrayView<uint8_t> data, VideoRotation value);
danilchap978504e2017-04-06 01:03:53 -0700144 static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value);
erikvargae6b16192017-05-11 02:36:32 -0700145 static size_t ValueSize(uint8_t value) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200146 static bool Write(rtc::ArrayView<uint8_t> data, uint8_t value);
danilchap1edb7ab2016-04-20 05:25:10 -0700147};
148
Danil Chapovalov08b03512016-09-07 15:08:13 +0200149class PlayoutDelayLimits {
150 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100151 using value_type = PlayoutDelay;
Danil Chapovalov08b03512016-09-07 15:08:13 +0200152 static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay;
153 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -0700154 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -0800155 "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay";
danilchape2a01772016-10-28 07:08:58 -0700156
Danil Chapovalov08b03512016-09-07 15:08:13 +0200157 // Playout delay in milliseconds. A playout delay limit (min or max)
158 // has 12 bits allocated. This allows a range of 0-4095 values which
159 // translates to a range of 0-40950 in milliseconds.
160 static constexpr int kGranularityMs = 10;
161 // Maximum playout delay value in milliseconds.
162 static constexpr int kMaxMs = 0xfff * kGranularityMs; // 40950.
163
danilchap978504e2017-04-06 01:03:53 -0700164 static bool Parse(rtc::ArrayView<const uint8_t> data,
165 PlayoutDelay* playout_delay);
erikvargae6b16192017-05-11 02:36:32 -0700166 static size_t ValueSize(const PlayoutDelay&) {
167 return kValueSizeBytes;
168 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200169 static bool Write(rtc::ArrayView<uint8_t> data,
170 const PlayoutDelay& playout_delay);
Danil Chapovalov08b03512016-09-07 15:08:13 +0200171};
172
ilnik00d802b2017-04-11 10:34:31 -0700173class VideoContentTypeExtension {
174 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100175 using value_type = VideoContentType;
ilnik00d802b2017-04-11 10:34:31 -0700176 static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType;
177 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -0700178 static constexpr const char kUri[] =
ilnik00d802b2017-04-11 10:34:31 -0700179 "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type";
180
181 static bool Parse(rtc::ArrayView<const uint8_t> data,
182 VideoContentType* content_type);
erikvargae6b16192017-05-11 02:36:32 -0700183 static size_t ValueSize(VideoContentType) {
184 return kValueSizeBytes;
185 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200186 static bool Write(rtc::ArrayView<uint8_t> data,
187 VideoContentType content_type);
ilnik00d802b2017-04-11 10:34:31 -0700188};
189
ilnik04f4d122017-06-19 07:18:55 -0700190class VideoTimingExtension {
191 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100192 using value_type = VideoSendTiming;
ilnik04f4d122017-06-19 07:18:55 -0700193 static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming;
sprangba050a62017-08-18 02:51:12 -0700194 static constexpr uint8_t kValueSizeBytes = 13;
Steve Antond14d9f72017-07-21 10:59:39 -0700195 static constexpr const char kUri[] =
ilnik04f4d122017-06-19 07:18:55 -0700196 "http://www.webrtc.org/experiments/rtp-hdrext/video-timing";
197
ilnik2edc6842017-07-06 03:06:50 -0700198 static bool Parse(rtc::ArrayView<const uint8_t> data,
199 VideoSendTiming* timing);
200 static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200201 static bool Write(rtc::ArrayView<uint8_t> data,
202 const VideoSendTiming& timing);
ilnik04f4d122017-06-19 07:18:55 -0700203
204 static size_t ValueSize(uint16_t time_delta_ms, uint8_t idx) {
205 return kValueSizeBytes;
206 }
207 // Writes only single time delta to position idx.
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200208 static bool Write(rtc::ArrayView<uint8_t> data,
209 uint16_t time_delta_ms,
210 uint8_t idx);
ilnik04f4d122017-06-19 07:18:55 -0700211};
212
Johnny Leee0c8b232018-09-11 16:50:49 -0400213class FrameMarkingExtension {
214 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100215 using value_type = FrameMarking;
Johnny Leee0c8b232018-09-11 16:50:49 -0400216 static constexpr RTPExtensionType kId = kRtpExtensionFrameMarking;
217 static constexpr const char kUri[] =
218 "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07";
219
220 static bool Parse(rtc::ArrayView<const uint8_t> data,
221 FrameMarking* frame_marking);
222 static size_t ValueSize(const FrameMarking& frame_marking);
223 static bool Write(rtc::ArrayView<uint8_t> data,
224 const FrameMarking& frame_marking);
225
226 private:
227 static bool IsScalable(uint8_t temporal_id, uint8_t layer_id);
228};
229
Johannes Kron09d65882018-11-27 14:36:41 +0100230class ColorSpaceExtension {
Johannes Kronad1d9f02018-11-09 11:12:36 +0100231 public:
Johannes Kron09d65882018-11-27 14:36:41 +0100232 using value_type = ColorSpace;
233 static constexpr RTPExtensionType kId = kRtpExtensionColorSpace;
Johannes Kronc13f4be2018-12-12 09:52:53 +0100234 static constexpr uint8_t kValueSizeBytes = 28;
Johannes Kron09d65882018-11-27 14:36:41 +0100235 static constexpr uint8_t kValueSizeBytesWithoutHdrMetadata = 4;
Johannes Krond0b69a82018-12-03 14:18:53 +0100236 static constexpr const char kUri[] =
237 "http://www.webrtc.org/experiments/rtp-hdrext/color-space";
Johannes Kronad1d9f02018-11-09 11:12:36 +0100238
239 static bool Parse(rtc::ArrayView<const uint8_t> data,
Johannes Kron09d65882018-11-27 14:36:41 +0100240 ColorSpace* color_space);
241 static size_t ValueSize(const ColorSpace& color_space) {
242 return color_space.hdr_metadata() ? kValueSizeBytes
243 : kValueSizeBytesWithoutHdrMetadata;
244 }
Johannes Kronad1d9f02018-11-09 11:12:36 +0100245 static bool Write(rtc::ArrayView<uint8_t> data,
Johannes Kron09d65882018-11-27 14:36:41 +0100246 const ColorSpace& color_space);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100247
248 private:
Johannes Kronc13f4be2018-12-12 09:52:53 +0100249 static constexpr int kChromaticityDenominator = 50000; // 0.00002 resolution.
250 static constexpr int kLuminanceMaxDenominator = 1; // 1 resolution.
Johannes Kronad1d9f02018-11-09 11:12:36 +0100251 static constexpr int kLuminanceMinDenominator = 10000; // 0.0001 resolution.
Johannes Kronc13f4be2018-12-12 09:52:53 +0100252
253 static uint8_t CombineRangeAndChromaSiting(
254 ColorSpace::RangeID range,
255 ColorSpace::ChromaSiting chroma_siting_horizontal,
256 ColorSpace::ChromaSiting chroma_siting_vertical);
257 static size_t ParseHdrMetadata(rtc::ArrayView<const uint8_t> data,
258 HdrMetadata* hdr_metadata);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100259 static size_t ParseChromaticity(const uint8_t* data,
260 HdrMasteringMetadata::Chromaticity* p);
261 static size_t ParseLuminance(const uint8_t* data, float* f, int denominator);
Johannes Kronc13f4be2018-12-12 09:52:53 +0100262 static size_t WriteHdrMetadata(rtc::ArrayView<uint8_t> data,
263 const HdrMetadata& hdr_metadata);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100264 static size_t WriteChromaticity(uint8_t* data,
265 const HdrMasteringMetadata::Chromaticity& p);
266 static size_t WriteLuminance(uint8_t* data, float f, int denominator);
267};
268
Steve Antona3251dd2017-07-21 09:58:31 -0700269// Base extension class for RTP header extensions which are strings.
270// Subclasses must defined kId and kUri static constexpr members.
271class BaseRtpStringExtension {
272 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100273 using value_type = std::string;
Steve Antonf0482ea2018-04-09 13:33:52 -0700274 // String RTP header extensions are limited to 16 bytes because it is the
275 // maximum length that can be encoded with one-byte header extensions.
276 static constexpr uint8_t kMaxValueSizeBytes = 16;
277
Steve Antona3251dd2017-07-21 09:58:31 -0700278 static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* str);
279 static size_t ValueSize(const std::string& str) { return str.size(); }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200280 static bool Write(rtc::ArrayView<uint8_t> data, const std::string& str);
Steve Antona3251dd2017-07-21 09:58:31 -0700281};
282
283class RtpStreamId : public BaseRtpStringExtension {
danilchapef8d7732017-04-19 02:59:48 -0700284 public:
285 static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId;
Steve Antond14d9f72017-07-21 10:59:39 -0700286 static constexpr const char kUri[] =
danilchapef8d7732017-04-19 02:59:48 -0700287 "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
danilchapef8d7732017-04-19 02:59:48 -0700288};
289
Steve Antona3251dd2017-07-21 09:58:31 -0700290class RepairedRtpStreamId : public BaseRtpStringExtension {
danilchapef8d7732017-04-19 02:59:48 -0700291 public:
292 static constexpr RTPExtensionType kId = kRtpExtensionRepairedRtpStreamId;
Steve Antond14d9f72017-07-21 10:59:39 -0700293 static constexpr const char kUri[] =
danilchapef8d7732017-04-19 02:59:48 -0700294 "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";
Steve Antona3251dd2017-07-21 09:58:31 -0700295};
danilchapef8d7732017-04-19 02:59:48 -0700296
Steve Antona3251dd2017-07-21 09:58:31 -0700297class RtpMid : public BaseRtpStringExtension {
298 public:
299 static constexpr RTPExtensionType kId = kRtpExtensionMid;
Steve Antond14d9f72017-07-21 10:59:39 -0700300 static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:sdes:mid";
danilchapef8d7732017-04-19 02:59:48 -0700301};
302
danilchap1edb7ab2016-04-20 05:25:10 -0700303} // namespace webrtc
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200304#endif // MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_