blob: e36c83f31b02da8fefc7003b4c6dbd0cb3ce6fb8 [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"
Yves Gerey988cc082018-10-23 12:03:01 +020024#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
danilchap1edb7ab2016-04-20 05:25:10 -070026
27namespace webrtc {
28
29class AbsoluteSendTime {
30 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +010031 using value_type = uint32_t;
danilchap1edb7ab2016-04-20 05:25:10 -070032 static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteSendTime;
33 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -070034 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -080035 "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
danilchape2a01772016-10-28 07:08:58 -070036
danilchap978504e2017-04-06 01:03:53 -070037 static bool Parse(rtc::ArrayView<const uint8_t> data, uint32_t* time_24bits);
Danil Chapovalovf3ba6482017-06-12 15:43:55 +020038 static size_t ValueSize(uint32_t time_24bits) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +020039 static bool Write(rtc::ArrayView<uint8_t> data, uint32_t time_24bits);
danilchapa897f262016-08-26 05:42:41 -070040
41 static constexpr uint32_t MsTo24Bits(int64_t time_ms) {
42 return static_cast<uint32_t>(((time_ms << 18) + 500) / 1000) & 0x00FFFFFF;
43 }
danilchap1edb7ab2016-04-20 05:25:10 -070044};
45
46class AudioLevel {
47 public:
48 static constexpr RTPExtensionType kId = kRtpExtensionAudioLevel;
49 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -070050 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -080051 "urn:ietf:params:rtp-hdrext:ssrc-audio-level";
danilchape2a01772016-10-28 07:08:58 -070052
danilchap978504e2017-04-06 01:03:53 -070053 static bool Parse(rtc::ArrayView<const uint8_t> data,
danilchap1edb7ab2016-04-20 05:25:10 -070054 bool* voice_activity,
55 uint8_t* audio_level);
erikvargae6b16192017-05-11 02:36:32 -070056 static size_t ValueSize(bool voice_activity, uint8_t audio_level) {
57 return kValueSizeBytes;
58 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +020059 static bool Write(rtc::ArrayView<uint8_t> data,
60 bool voice_activity,
61 uint8_t audio_level);
danilchap1edb7ab2016-04-20 05:25:10 -070062};
63
64class TransmissionOffset {
65 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +010066 using value_type = int32_t;
danilchap1edb7ab2016-04-20 05:25:10 -070067 static constexpr RTPExtensionType kId = kRtpExtensionTransmissionTimeOffset;
68 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -070069 static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:toffset";
danilchape2a01772016-10-28 07:08:58 -070070
danilchap978504e2017-04-06 01:03:53 -070071 static bool Parse(rtc::ArrayView<const uint8_t> data, int32_t* rtp_time);
erikvargae6b16192017-05-11 02:36:32 -070072 static size_t ValueSize(int32_t rtp_time) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +020073 static bool Write(rtc::ArrayView<uint8_t> data, int32_t rtp_time);
danilchap1edb7ab2016-04-20 05:25:10 -070074};
75
76class TransportSequenceNumber {
77 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +010078 using value_type = uint16_t;
danilchap1edb7ab2016-04-20 05:25:10 -070079 static constexpr RTPExtensionType kId = kRtpExtensionTransportSequenceNumber;
80 static constexpr uint8_t kValueSizeBytes = 2;
Steve Antond14d9f72017-07-21 10:59:39 -070081 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -080082 "http://www.ietf.org/id/"
83 "draft-holmer-rmcat-transport-wide-cc-extensions-01";
Johannes Kron54047be2019-02-21 14:09:20 +000084 static bool Parse(rtc::ArrayView<const uint8_t> data,
85 uint16_t* transport_sequence_number);
86 static size_t ValueSize(uint16_t /*transport_sequence_number*/) {
87 return kValueSizeBytes;
88 }
89 static bool Write(rtc::ArrayView<uint8_t> data,
90 uint16_t transport_sequence_number);
91};
92
93class TransportSequenceNumberV2 {
94 public:
95 static constexpr RTPExtensionType kId =
96 kRtpExtensionTransportSequenceNumber02;
Johannes Kron0da25a12019-03-06 09:34:13 +010097 static constexpr uint8_t kValueSizeBytes = 4;
98 static constexpr uint8_t kValueSizeBytesWithoutFeedbackRequest = 2;
Johannes Kron54047be2019-02-21 14:09:20 +000099 static constexpr const char kUri[] =
100 "http://www.ietf.org/id/"
101 "draft-holmer-rmcat-transport-wide-cc-extensions-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) {
Johannes Kron0da25a12019-03-06 09:34:13 +0100108 return feedback_request ? kValueSizeBytes
109 : kValueSizeBytesWithoutFeedbackRequest;
Johannes Kron54047be2019-02-21 14:09:20 +0000110 }
111 static bool Write(rtc::ArrayView<uint8_t> data,
112 uint16_t transport_sequence_number,
113 const absl::optional<FeedbackRequest>& feedback_request);
114
115 private:
116 static constexpr uint16_t kIncludeTimestampsBit = 1 << 15;
danilchap1edb7ab2016-04-20 05:25:10 -0700117};
118
119class VideoOrientation {
120 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100121 using value_type = VideoRotation;
danilchap1edb7ab2016-04-20 05:25:10 -0700122 static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation;
123 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -0700124 static constexpr const char kUri[] = "urn:3gpp:video-orientation";
danilchape2a01772016-10-28 07:08:58 -0700125
danilchap978504e2017-04-06 01:03:53 -0700126 static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value);
erikvargae6b16192017-05-11 02:36:32 -0700127 static size_t ValueSize(VideoRotation) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200128 static bool Write(rtc::ArrayView<uint8_t> data, VideoRotation value);
danilchap978504e2017-04-06 01:03:53 -0700129 static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value);
erikvargae6b16192017-05-11 02:36:32 -0700130 static size_t ValueSize(uint8_t value) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200131 static bool Write(rtc::ArrayView<uint8_t> data, uint8_t value);
danilchap1edb7ab2016-04-20 05:25:10 -0700132};
133
Danil Chapovalov08b03512016-09-07 15:08:13 +0200134class PlayoutDelayLimits {
135 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100136 using value_type = PlayoutDelay;
Danil Chapovalov08b03512016-09-07 15:08:13 +0200137 static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay;
138 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -0700139 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -0800140 "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay";
danilchape2a01772016-10-28 07:08:58 -0700141
Danil Chapovalov08b03512016-09-07 15:08:13 +0200142 // Playout delay in milliseconds. A playout delay limit (min or max)
143 // has 12 bits allocated. This allows a range of 0-4095 values which
144 // translates to a range of 0-40950 in milliseconds.
145 static constexpr int kGranularityMs = 10;
146 // Maximum playout delay value in milliseconds.
147 static constexpr int kMaxMs = 0xfff * kGranularityMs; // 40950.
148
danilchap978504e2017-04-06 01:03:53 -0700149 static bool Parse(rtc::ArrayView<const uint8_t> data,
150 PlayoutDelay* playout_delay);
erikvargae6b16192017-05-11 02:36:32 -0700151 static size_t ValueSize(const PlayoutDelay&) {
152 return kValueSizeBytes;
153 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200154 static bool Write(rtc::ArrayView<uint8_t> data,
155 const PlayoutDelay& playout_delay);
Danil Chapovalov08b03512016-09-07 15:08:13 +0200156};
157
ilnik00d802b2017-04-11 10:34:31 -0700158class VideoContentTypeExtension {
159 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100160 using value_type = VideoContentType;
ilnik00d802b2017-04-11 10:34:31 -0700161 static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType;
162 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -0700163 static constexpr const char kUri[] =
ilnik00d802b2017-04-11 10:34:31 -0700164 "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type";
165
166 static bool Parse(rtc::ArrayView<const uint8_t> data,
167 VideoContentType* content_type);
erikvargae6b16192017-05-11 02:36:32 -0700168 static size_t ValueSize(VideoContentType) {
169 return kValueSizeBytes;
170 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200171 static bool Write(rtc::ArrayView<uint8_t> data,
172 VideoContentType content_type);
ilnik00d802b2017-04-11 10:34:31 -0700173};
174
ilnik04f4d122017-06-19 07:18:55 -0700175class VideoTimingExtension {
176 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100177 using value_type = VideoSendTiming;
ilnik04f4d122017-06-19 07:18:55 -0700178 static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming;
sprangba050a62017-08-18 02:51:12 -0700179 static constexpr uint8_t kValueSizeBytes = 13;
Steve Antond14d9f72017-07-21 10:59:39 -0700180 static constexpr const char kUri[] =
ilnik04f4d122017-06-19 07:18:55 -0700181 "http://www.webrtc.org/experiments/rtp-hdrext/video-timing";
182
ilnik2edc6842017-07-06 03:06:50 -0700183 static bool Parse(rtc::ArrayView<const uint8_t> data,
184 VideoSendTiming* timing);
185 static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200186 static bool Write(rtc::ArrayView<uint8_t> data,
187 const VideoSendTiming& timing);
ilnik04f4d122017-06-19 07:18:55 -0700188
189 static size_t ValueSize(uint16_t time_delta_ms, uint8_t idx) {
190 return kValueSizeBytes;
191 }
192 // Writes only single time delta to position idx.
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200193 static bool Write(rtc::ArrayView<uint8_t> data,
194 uint16_t time_delta_ms,
195 uint8_t idx);
ilnik04f4d122017-06-19 07:18:55 -0700196};
197
Johnny Leee0c8b232018-09-11 16:50:49 -0400198class FrameMarkingExtension {
199 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100200 using value_type = FrameMarking;
Johnny Leee0c8b232018-09-11 16:50:49 -0400201 static constexpr RTPExtensionType kId = kRtpExtensionFrameMarking;
202 static constexpr const char kUri[] =
203 "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07";
204
205 static bool Parse(rtc::ArrayView<const uint8_t> data,
206 FrameMarking* frame_marking);
207 static size_t ValueSize(const FrameMarking& frame_marking);
208 static bool Write(rtc::ArrayView<uint8_t> data,
209 const FrameMarking& frame_marking);
210
211 private:
212 static bool IsScalable(uint8_t temporal_id, uint8_t layer_id);
213};
214
Johannes Kron09d65882018-11-27 14:36:41 +0100215class ColorSpaceExtension {
Johannes Kronad1d9f02018-11-09 11:12:36 +0100216 public:
Johannes Kron09d65882018-11-27 14:36:41 +0100217 using value_type = ColorSpace;
218 static constexpr RTPExtensionType kId = kRtpExtensionColorSpace;
Johannes Kronc13f4be2018-12-12 09:52:53 +0100219 static constexpr uint8_t kValueSizeBytes = 28;
Johannes Kron09d65882018-11-27 14:36:41 +0100220 static constexpr uint8_t kValueSizeBytesWithoutHdrMetadata = 4;
Johannes Krond0b69a82018-12-03 14:18:53 +0100221 static constexpr const char kUri[] =
222 "http://www.webrtc.org/experiments/rtp-hdrext/color-space";
Johannes Kronad1d9f02018-11-09 11:12:36 +0100223
224 static bool Parse(rtc::ArrayView<const uint8_t> data,
Johannes Kron09d65882018-11-27 14:36:41 +0100225 ColorSpace* color_space);
226 static size_t ValueSize(const ColorSpace& color_space) {
227 return color_space.hdr_metadata() ? kValueSizeBytes
228 : kValueSizeBytesWithoutHdrMetadata;
229 }
Johannes Kronad1d9f02018-11-09 11:12:36 +0100230 static bool Write(rtc::ArrayView<uint8_t> data,
Johannes Kron09d65882018-11-27 14:36:41 +0100231 const ColorSpace& color_space);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100232
233 private:
Johannes Kronc13f4be2018-12-12 09:52:53 +0100234 static constexpr int kChromaticityDenominator = 50000; // 0.00002 resolution.
235 static constexpr int kLuminanceMaxDenominator = 1; // 1 resolution.
Johannes Kronad1d9f02018-11-09 11:12:36 +0100236 static constexpr int kLuminanceMinDenominator = 10000; // 0.0001 resolution.
Johannes Kronc13f4be2018-12-12 09:52:53 +0100237
238 static uint8_t CombineRangeAndChromaSiting(
239 ColorSpace::RangeID range,
240 ColorSpace::ChromaSiting chroma_siting_horizontal,
241 ColorSpace::ChromaSiting chroma_siting_vertical);
242 static size_t ParseHdrMetadata(rtc::ArrayView<const uint8_t> data,
243 HdrMetadata* hdr_metadata);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100244 static size_t ParseChromaticity(const uint8_t* data,
245 HdrMasteringMetadata::Chromaticity* p);
246 static size_t ParseLuminance(const uint8_t* data, float* f, int denominator);
Johannes Kronc13f4be2018-12-12 09:52:53 +0100247 static size_t WriteHdrMetadata(rtc::ArrayView<uint8_t> data,
248 const HdrMetadata& hdr_metadata);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100249 static size_t WriteChromaticity(uint8_t* data,
250 const HdrMasteringMetadata::Chromaticity& p);
251 static size_t WriteLuminance(uint8_t* data, float f, int denominator);
252};
253
Steve Antona3251dd2017-07-21 09:58:31 -0700254// Base extension class for RTP header extensions which are strings.
255// Subclasses must defined kId and kUri static constexpr members.
256class BaseRtpStringExtension {
257 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100258 using value_type = std::string;
Steve Antonf0482ea2018-04-09 13:33:52 -0700259 // String RTP header extensions are limited to 16 bytes because it is the
260 // maximum length that can be encoded with one-byte header extensions.
261 static constexpr uint8_t kMaxValueSizeBytes = 16;
262
Steve Antona3251dd2017-07-21 09:58:31 -0700263 static bool Parse(rtc::ArrayView<const uint8_t> data,
264 StringRtpHeaderExtension* str);
265 static size_t ValueSize(const StringRtpHeaderExtension& str) {
266 return str.size();
267 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200268 static bool Write(rtc::ArrayView<uint8_t> data,
269 const StringRtpHeaderExtension& str);
Steve Antona3251dd2017-07-21 09:58:31 -0700270
271 static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* str);
272 static size_t ValueSize(const std::string& str) { return str.size(); }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200273 static bool Write(rtc::ArrayView<uint8_t> data, const std::string& str);
Steve Antona3251dd2017-07-21 09:58:31 -0700274};
275
276class RtpStreamId : public BaseRtpStringExtension {
danilchapef8d7732017-04-19 02:59:48 -0700277 public:
278 static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId;
Steve Antond14d9f72017-07-21 10:59:39 -0700279 static constexpr const char kUri[] =
danilchapef8d7732017-04-19 02:59:48 -0700280 "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
danilchapef8d7732017-04-19 02:59:48 -0700281};
282
Steve Antona3251dd2017-07-21 09:58:31 -0700283class RepairedRtpStreamId : public BaseRtpStringExtension {
danilchapef8d7732017-04-19 02:59:48 -0700284 public:
285 static constexpr RTPExtensionType kId = kRtpExtensionRepairedRtpStreamId;
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:repaired-rtp-stream-id";
Steve Antona3251dd2017-07-21 09:58:31 -0700288};
danilchapef8d7732017-04-19 02:59:48 -0700289
Steve Antona3251dd2017-07-21 09:58:31 -0700290class RtpMid : public BaseRtpStringExtension {
291 public:
292 static constexpr RTPExtensionType kId = kRtpExtensionMid;
Steve Antond14d9f72017-07-21 10:59:39 -0700293 static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:sdes:mid";
danilchapef8d7732017-04-19 02:59:48 -0700294};
295
danilchap1edb7ab2016-04-20 05:25:10 -0700296} // namespace webrtc
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200297#endif // MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_