blob: 8aacb9acb04927f8643a1d4986003f1678611abd [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[] =
Johannes Kron8cc711a2019-03-07 22:36:35 +0100100 "http://www.webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02";
Johannes Kron54047be2019-02-21 14:09:20 +0000101 static bool Parse(rtc::ArrayView<const uint8_t> data,
102 uint16_t* transport_sequence_number,
103 absl::optional<FeedbackRequest>* feedback_request);
104 static size_t ValueSize(
105 uint16_t /*transport_sequence_number*/,
106 const absl::optional<FeedbackRequest>& feedback_request) {
Johannes Kron0da25a12019-03-06 09:34:13 +0100107 return feedback_request ? kValueSizeBytes
108 : kValueSizeBytesWithoutFeedbackRequest;
Johannes Kron54047be2019-02-21 14:09:20 +0000109 }
110 static bool Write(rtc::ArrayView<uint8_t> data,
111 uint16_t transport_sequence_number,
112 const absl::optional<FeedbackRequest>& feedback_request);
113
114 private:
115 static constexpr uint16_t kIncludeTimestampsBit = 1 << 15;
danilchap1edb7ab2016-04-20 05:25:10 -0700116};
117
118class VideoOrientation {
119 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100120 using value_type = VideoRotation;
danilchap1edb7ab2016-04-20 05:25:10 -0700121 static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation;
122 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -0700123 static constexpr const char kUri[] = "urn:3gpp:video-orientation";
danilchape2a01772016-10-28 07:08:58 -0700124
danilchap978504e2017-04-06 01:03:53 -0700125 static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value);
erikvargae6b16192017-05-11 02:36:32 -0700126 static size_t ValueSize(VideoRotation) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200127 static bool Write(rtc::ArrayView<uint8_t> data, VideoRotation value);
danilchap978504e2017-04-06 01:03:53 -0700128 static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value);
erikvargae6b16192017-05-11 02:36:32 -0700129 static size_t ValueSize(uint8_t value) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200130 static bool Write(rtc::ArrayView<uint8_t> data, uint8_t value);
danilchap1edb7ab2016-04-20 05:25:10 -0700131};
132
Danil Chapovalov08b03512016-09-07 15:08:13 +0200133class PlayoutDelayLimits {
134 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100135 using value_type = PlayoutDelay;
Danil Chapovalov08b03512016-09-07 15:08:13 +0200136 static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay;
137 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -0700138 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -0800139 "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay";
danilchape2a01772016-10-28 07:08:58 -0700140
Danil Chapovalov08b03512016-09-07 15:08:13 +0200141 // Playout delay in milliseconds. A playout delay limit (min or max)
142 // has 12 bits allocated. This allows a range of 0-4095 values which
143 // translates to a range of 0-40950 in milliseconds.
144 static constexpr int kGranularityMs = 10;
145 // Maximum playout delay value in milliseconds.
146 static constexpr int kMaxMs = 0xfff * kGranularityMs; // 40950.
147
danilchap978504e2017-04-06 01:03:53 -0700148 static bool Parse(rtc::ArrayView<const uint8_t> data,
149 PlayoutDelay* playout_delay);
erikvargae6b16192017-05-11 02:36:32 -0700150 static size_t ValueSize(const PlayoutDelay&) {
151 return kValueSizeBytes;
152 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200153 static bool Write(rtc::ArrayView<uint8_t> data,
154 const PlayoutDelay& playout_delay);
Danil Chapovalov08b03512016-09-07 15:08:13 +0200155};
156
ilnik00d802b2017-04-11 10:34:31 -0700157class VideoContentTypeExtension {
158 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100159 using value_type = VideoContentType;
ilnik00d802b2017-04-11 10:34:31 -0700160 static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType;
161 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -0700162 static constexpr const char kUri[] =
ilnik00d802b2017-04-11 10:34:31 -0700163 "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type";
164
165 static bool Parse(rtc::ArrayView<const uint8_t> data,
166 VideoContentType* content_type);
erikvargae6b16192017-05-11 02:36:32 -0700167 static size_t ValueSize(VideoContentType) {
168 return kValueSizeBytes;
169 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200170 static bool Write(rtc::ArrayView<uint8_t> data,
171 VideoContentType content_type);
ilnik00d802b2017-04-11 10:34:31 -0700172};
173
ilnik04f4d122017-06-19 07:18:55 -0700174class VideoTimingExtension {
175 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100176 using value_type = VideoSendTiming;
ilnik04f4d122017-06-19 07:18:55 -0700177 static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming;
sprangba050a62017-08-18 02:51:12 -0700178 static constexpr uint8_t kValueSizeBytes = 13;
Steve Antond14d9f72017-07-21 10:59:39 -0700179 static constexpr const char kUri[] =
ilnik04f4d122017-06-19 07:18:55 -0700180 "http://www.webrtc.org/experiments/rtp-hdrext/video-timing";
181
ilnik2edc6842017-07-06 03:06:50 -0700182 static bool Parse(rtc::ArrayView<const uint8_t> data,
183 VideoSendTiming* timing);
184 static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200185 static bool Write(rtc::ArrayView<uint8_t> data,
186 const VideoSendTiming& timing);
ilnik04f4d122017-06-19 07:18:55 -0700187
188 static size_t ValueSize(uint16_t time_delta_ms, uint8_t idx) {
189 return kValueSizeBytes;
190 }
191 // Writes only single time delta to position idx.
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200192 static bool Write(rtc::ArrayView<uint8_t> data,
193 uint16_t time_delta_ms,
194 uint8_t idx);
ilnik04f4d122017-06-19 07:18:55 -0700195};
196
Johnny Leee0c8b232018-09-11 16:50:49 -0400197class FrameMarkingExtension {
198 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100199 using value_type = FrameMarking;
Johnny Leee0c8b232018-09-11 16:50:49 -0400200 static constexpr RTPExtensionType kId = kRtpExtensionFrameMarking;
201 static constexpr const char kUri[] =
202 "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07";
203
204 static bool Parse(rtc::ArrayView<const uint8_t> data,
205 FrameMarking* frame_marking);
206 static size_t ValueSize(const FrameMarking& frame_marking);
207 static bool Write(rtc::ArrayView<uint8_t> data,
208 const FrameMarking& frame_marking);
209
210 private:
211 static bool IsScalable(uint8_t temporal_id, uint8_t layer_id);
212};
213
Johannes Kron09d65882018-11-27 14:36:41 +0100214class ColorSpaceExtension {
Johannes Kronad1d9f02018-11-09 11:12:36 +0100215 public:
Johannes Kron09d65882018-11-27 14:36:41 +0100216 using value_type = ColorSpace;
217 static constexpr RTPExtensionType kId = kRtpExtensionColorSpace;
Johannes Kronc13f4be2018-12-12 09:52:53 +0100218 static constexpr uint8_t kValueSizeBytes = 28;
Johannes Kron09d65882018-11-27 14:36:41 +0100219 static constexpr uint8_t kValueSizeBytesWithoutHdrMetadata = 4;
Johannes Krond0b69a82018-12-03 14:18:53 +0100220 static constexpr const char kUri[] =
221 "http://www.webrtc.org/experiments/rtp-hdrext/color-space";
Johannes Kronad1d9f02018-11-09 11:12:36 +0100222
223 static bool Parse(rtc::ArrayView<const uint8_t> data,
Johannes Kron09d65882018-11-27 14:36:41 +0100224 ColorSpace* color_space);
225 static size_t ValueSize(const ColorSpace& color_space) {
226 return color_space.hdr_metadata() ? kValueSizeBytes
227 : kValueSizeBytesWithoutHdrMetadata;
228 }
Johannes Kronad1d9f02018-11-09 11:12:36 +0100229 static bool Write(rtc::ArrayView<uint8_t> data,
Johannes Kron09d65882018-11-27 14:36:41 +0100230 const ColorSpace& color_space);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100231
232 private:
Johannes Kronc13f4be2018-12-12 09:52:53 +0100233 static constexpr int kChromaticityDenominator = 50000; // 0.00002 resolution.
234 static constexpr int kLuminanceMaxDenominator = 1; // 1 resolution.
Johannes Kronad1d9f02018-11-09 11:12:36 +0100235 static constexpr int kLuminanceMinDenominator = 10000; // 0.0001 resolution.
Johannes Kronc13f4be2018-12-12 09:52:53 +0100236
237 static uint8_t CombineRangeAndChromaSiting(
238 ColorSpace::RangeID range,
239 ColorSpace::ChromaSiting chroma_siting_horizontal,
240 ColorSpace::ChromaSiting chroma_siting_vertical);
241 static size_t ParseHdrMetadata(rtc::ArrayView<const uint8_t> data,
242 HdrMetadata* hdr_metadata);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100243 static size_t ParseChromaticity(const uint8_t* data,
244 HdrMasteringMetadata::Chromaticity* p);
245 static size_t ParseLuminance(const uint8_t* data, float* f, int denominator);
Johannes Kronc13f4be2018-12-12 09:52:53 +0100246 static size_t WriteHdrMetadata(rtc::ArrayView<uint8_t> data,
247 const HdrMetadata& hdr_metadata);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100248 static size_t WriteChromaticity(uint8_t* data,
249 const HdrMasteringMetadata::Chromaticity& p);
250 static size_t WriteLuminance(uint8_t* data, float f, int denominator);
251};
252
Steve Antona3251dd2017-07-21 09:58:31 -0700253// Base extension class for RTP header extensions which are strings.
254// Subclasses must defined kId and kUri static constexpr members.
255class BaseRtpStringExtension {
256 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100257 using value_type = std::string;
Steve Antonf0482ea2018-04-09 13:33:52 -0700258 // String RTP header extensions are limited to 16 bytes because it is the
259 // maximum length that can be encoded with one-byte header extensions.
260 static constexpr uint8_t kMaxValueSizeBytes = 16;
261
Steve Antona3251dd2017-07-21 09:58:31 -0700262 static bool Parse(rtc::ArrayView<const uint8_t> data,
263 StringRtpHeaderExtension* str);
264 static size_t ValueSize(const StringRtpHeaderExtension& str) {
265 return str.size();
266 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200267 static bool Write(rtc::ArrayView<uint8_t> data,
268 const StringRtpHeaderExtension& str);
Steve Antona3251dd2017-07-21 09:58:31 -0700269
270 static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* str);
271 static size_t ValueSize(const std::string& str) { return str.size(); }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200272 static bool Write(rtc::ArrayView<uint8_t> data, const std::string& str);
Steve Antona3251dd2017-07-21 09:58:31 -0700273};
274
275class RtpStreamId : public BaseRtpStringExtension {
danilchapef8d7732017-04-19 02:59:48 -0700276 public:
277 static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId;
Steve Antond14d9f72017-07-21 10:59:39 -0700278 static constexpr const char kUri[] =
danilchapef8d7732017-04-19 02:59:48 -0700279 "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
danilchapef8d7732017-04-19 02:59:48 -0700280};
281
Steve Antona3251dd2017-07-21 09:58:31 -0700282class RepairedRtpStreamId : public BaseRtpStringExtension {
danilchapef8d7732017-04-19 02:59:48 -0700283 public:
284 static constexpr RTPExtensionType kId = kRtpExtensionRepairedRtpStreamId;
Steve Antond14d9f72017-07-21 10:59:39 -0700285 static constexpr const char kUri[] =
danilchapef8d7732017-04-19 02:59:48 -0700286 "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";
Steve Antona3251dd2017-07-21 09:58:31 -0700287};
danilchapef8d7732017-04-19 02:59:48 -0700288
Steve Antona3251dd2017-07-21 09:58:31 -0700289class RtpMid : public BaseRtpStringExtension {
290 public:
291 static constexpr RTPExtensionType kId = kRtpExtensionMid;
Steve Antond14d9f72017-07-21 10:59:39 -0700292 static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:sdes:mid";
danilchapef8d7732017-04-19 02:59:48 -0700293};
294
danilchap1edb7ab2016-04-20 05:25:10 -0700295} // namespace webrtc
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200296#endif // MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_