blob: 927c9c31fb00b1f2170cfea02024499ac5cfe5b4 [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>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
danilchapef8d7732017-04-19 02:59:48 -070016#include <string>
pbosc7c26a02017-01-02 08:42:32 -080017
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/array_view.h"
Yves Gerey988cc082018-10-23 12:03:01 +020019#include "api/rtp_headers.h"
Johannes Kron09d65882018-11-27 14:36:41 +010020#include "api/video/color_space.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "api/video/video_content_type.h"
Yves Gerey988cc082018-10-23 12:03:01 +020022#include "api/video/video_frame_marking.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "api/video/video_rotation.h"
24#include "api/video/video_timing.h"
25#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
Chen Xingcd8a6e22019-07-01 10:56:51 +020046class AbsoluteCaptureTimeExtension {
47 public:
48 using value_type = AbsoluteCaptureTime;
49 static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteCaptureTime;
50 static constexpr uint8_t kValueSizeBytes = 16;
51 static constexpr uint8_t kValueSizeBytesWithoutEstimatedCaptureClockOffset =
52 8;
53 static constexpr const char kUri[] =
54 "http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time";
55
56 static bool Parse(rtc::ArrayView<const uint8_t> data,
57 AbsoluteCaptureTime* extension);
58 static size_t ValueSize(const AbsoluteCaptureTime& extension);
59 static bool Write(rtc::ArrayView<uint8_t> data,
60 const AbsoluteCaptureTime& extension);
61};
62
danilchap1edb7ab2016-04-20 05:25:10 -070063class AudioLevel {
64 public:
65 static constexpr RTPExtensionType kId = kRtpExtensionAudioLevel;
66 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -070067 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -080068 "urn:ietf:params:rtp-hdrext:ssrc-audio-level";
danilchape2a01772016-10-28 07:08:58 -070069
danilchap978504e2017-04-06 01:03:53 -070070 static bool Parse(rtc::ArrayView<const uint8_t> data,
danilchap1edb7ab2016-04-20 05:25:10 -070071 bool* voice_activity,
72 uint8_t* audio_level);
erikvargae6b16192017-05-11 02:36:32 -070073 static size_t ValueSize(bool voice_activity, uint8_t audio_level) {
74 return kValueSizeBytes;
75 }
Danil Chapovalov9bf31582018-06-18 13:48:20 +020076 static bool Write(rtc::ArrayView<uint8_t> data,
77 bool voice_activity,
78 uint8_t audio_level);
danilchap1edb7ab2016-04-20 05:25:10 -070079};
80
81class TransmissionOffset {
82 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +010083 using value_type = int32_t;
danilchap1edb7ab2016-04-20 05:25:10 -070084 static constexpr RTPExtensionType kId = kRtpExtensionTransmissionTimeOffset;
85 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -070086 static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:toffset";
danilchape2a01772016-10-28 07:08:58 -070087
danilchap978504e2017-04-06 01:03:53 -070088 static bool Parse(rtc::ArrayView<const uint8_t> data, int32_t* rtp_time);
erikvargae6b16192017-05-11 02:36:32 -070089 static size_t ValueSize(int32_t rtp_time) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +020090 static bool Write(rtc::ArrayView<uint8_t> data, int32_t rtp_time);
danilchap1edb7ab2016-04-20 05:25:10 -070091};
92
93class TransportSequenceNumber {
94 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +010095 using value_type = uint16_t;
danilchap1edb7ab2016-04-20 05:25:10 -070096 static constexpr RTPExtensionType kId = kRtpExtensionTransportSequenceNumber;
97 static constexpr uint8_t kValueSizeBytes = 2;
Steve Antond14d9f72017-07-21 10:59:39 -070098 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -080099 "http://www.ietf.org/id/"
100 "draft-holmer-rmcat-transport-wide-cc-extensions-01";
Johannes Kron54047be2019-02-21 14:09:20 +0000101 static bool Parse(rtc::ArrayView<const uint8_t> data,
102 uint16_t* transport_sequence_number);
103 static size_t ValueSize(uint16_t /*transport_sequence_number*/) {
104 return kValueSizeBytes;
105 }
106 static bool Write(rtc::ArrayView<uint8_t> data,
107 uint16_t transport_sequence_number);
108};
109
110class TransportSequenceNumberV2 {
111 public:
112 static constexpr RTPExtensionType kId =
113 kRtpExtensionTransportSequenceNumber02;
Johannes Kron0da25a12019-03-06 09:34:13 +0100114 static constexpr uint8_t kValueSizeBytes = 4;
115 static constexpr uint8_t kValueSizeBytesWithoutFeedbackRequest = 2;
Johannes Kron54047be2019-02-21 14:09:20 +0000116 static constexpr const char kUri[] =
Johannes Kron8cc711a2019-03-07 22:36:35 +0100117 "http://www.webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02";
Johannes Kron54047be2019-02-21 14:09:20 +0000118 static bool Parse(rtc::ArrayView<const uint8_t> data,
119 uint16_t* transport_sequence_number,
120 absl::optional<FeedbackRequest>* feedback_request);
121 static size_t ValueSize(
122 uint16_t /*transport_sequence_number*/,
123 const absl::optional<FeedbackRequest>& feedback_request) {
Johannes Kron0da25a12019-03-06 09:34:13 +0100124 return feedback_request ? kValueSizeBytes
125 : kValueSizeBytesWithoutFeedbackRequest;
Johannes Kron54047be2019-02-21 14:09:20 +0000126 }
127 static bool Write(rtc::ArrayView<uint8_t> data,
128 uint16_t transport_sequence_number,
129 const absl::optional<FeedbackRequest>& feedback_request);
130
131 private:
132 static constexpr uint16_t kIncludeTimestampsBit = 1 << 15;
danilchap1edb7ab2016-04-20 05:25:10 -0700133};
134
135class VideoOrientation {
136 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100137 using value_type = VideoRotation;
danilchap1edb7ab2016-04-20 05:25:10 -0700138 static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation;
139 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -0700140 static constexpr const char kUri[] = "urn:3gpp:video-orientation";
danilchape2a01772016-10-28 07:08:58 -0700141
danilchap978504e2017-04-06 01:03:53 -0700142 static bool Parse(rtc::ArrayView<const uint8_t> data, VideoRotation* value);
erikvargae6b16192017-05-11 02:36:32 -0700143 static size_t ValueSize(VideoRotation) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200144 static bool Write(rtc::ArrayView<uint8_t> data, VideoRotation value);
danilchap978504e2017-04-06 01:03:53 -0700145 static bool Parse(rtc::ArrayView<const uint8_t> data, uint8_t* value);
erikvargae6b16192017-05-11 02:36:32 -0700146 static size_t ValueSize(uint8_t value) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200147 static bool Write(rtc::ArrayView<uint8_t> data, uint8_t value);
danilchap1edb7ab2016-04-20 05:25:10 -0700148};
149
Danil Chapovalov08b03512016-09-07 15:08:13 +0200150class PlayoutDelayLimits {
151 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100152 using value_type = PlayoutDelay;
Danil Chapovalov08b03512016-09-07 15:08:13 +0200153 static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay;
154 static constexpr uint8_t kValueSizeBytes = 3;
Steve Antond14d9f72017-07-21 10:59:39 -0700155 static constexpr const char kUri[] =
danilchap6ba58d62016-11-09 05:46:39 -0800156 "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay";
danilchape2a01772016-10-28 07:08:58 -0700157
Danil Chapovalov08b03512016-09-07 15:08:13 +0200158 // Playout delay in milliseconds. A playout delay limit (min or max)
159 // has 12 bits allocated. This allows a range of 0-4095 values which
160 // translates to a range of 0-40950 in milliseconds.
161 static constexpr int kGranularityMs = 10;
162 // Maximum playout delay value in milliseconds.
163 static constexpr int kMaxMs = 0xfff * kGranularityMs; // 40950.
164
danilchap978504e2017-04-06 01:03:53 -0700165 static bool Parse(rtc::ArrayView<const uint8_t> data,
166 PlayoutDelay* playout_delay);
Jonas Olssona4d87372019-07-05 19:08:33 +0200167 static size_t ValueSize(const PlayoutDelay&) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200168 static bool Write(rtc::ArrayView<uint8_t> data,
169 const PlayoutDelay& playout_delay);
Danil Chapovalov08b03512016-09-07 15:08:13 +0200170};
171
ilnik00d802b2017-04-11 10:34:31 -0700172class VideoContentTypeExtension {
173 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100174 using value_type = VideoContentType;
ilnik00d802b2017-04-11 10:34:31 -0700175 static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType;
176 static constexpr uint8_t kValueSizeBytes = 1;
Steve Antond14d9f72017-07-21 10:59:39 -0700177 static constexpr const char kUri[] =
ilnik00d802b2017-04-11 10:34:31 -0700178 "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type";
179
180 static bool Parse(rtc::ArrayView<const uint8_t> data,
181 VideoContentType* content_type);
Jonas Olssona4d87372019-07-05 19:08:33 +0200182 static size_t ValueSize(VideoContentType) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200183 static bool Write(rtc::ArrayView<uint8_t> data,
184 VideoContentType content_type);
ilnik00d802b2017-04-11 10:34:31 -0700185};
186
ilnik04f4d122017-06-19 07:18:55 -0700187class VideoTimingExtension {
188 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100189 using value_type = VideoSendTiming;
ilnik04f4d122017-06-19 07:18:55 -0700190 static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming;
sprangba050a62017-08-18 02:51:12 -0700191 static constexpr uint8_t kValueSizeBytes = 13;
Steve Antond14d9f72017-07-21 10:59:39 -0700192 static constexpr const char kUri[] =
ilnik04f4d122017-06-19 07:18:55 -0700193 "http://www.webrtc.org/experiments/rtp-hdrext/video-timing";
194
ilnik2edc6842017-07-06 03:06:50 -0700195 static bool Parse(rtc::ArrayView<const uint8_t> data,
196 VideoSendTiming* timing);
197 static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200198 static bool Write(rtc::ArrayView<uint8_t> data,
199 const VideoSendTiming& timing);
ilnik04f4d122017-06-19 07:18:55 -0700200
201 static size_t ValueSize(uint16_t time_delta_ms, uint8_t idx) {
202 return kValueSizeBytes;
203 }
204 // Writes only single time delta to position idx.
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200205 static bool Write(rtc::ArrayView<uint8_t> data,
206 uint16_t time_delta_ms,
207 uint8_t idx);
ilnik04f4d122017-06-19 07:18:55 -0700208};
209
Johnny Leee0c8b232018-09-11 16:50:49 -0400210class FrameMarkingExtension {
211 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100212 using value_type = FrameMarking;
Johnny Leee0c8b232018-09-11 16:50:49 -0400213 static constexpr RTPExtensionType kId = kRtpExtensionFrameMarking;
214 static constexpr const char kUri[] =
215 "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07";
216
217 static bool Parse(rtc::ArrayView<const uint8_t> data,
218 FrameMarking* frame_marking);
219 static size_t ValueSize(const FrameMarking& frame_marking);
220 static bool Write(rtc::ArrayView<uint8_t> data,
221 const FrameMarking& frame_marking);
222
223 private:
224 static bool IsScalable(uint8_t temporal_id, uint8_t layer_id);
225};
226
Johannes Kron09d65882018-11-27 14:36:41 +0100227class ColorSpaceExtension {
Johannes Kronad1d9f02018-11-09 11:12:36 +0100228 public:
Johannes Kron09d65882018-11-27 14:36:41 +0100229 using value_type = ColorSpace;
230 static constexpr RTPExtensionType kId = kRtpExtensionColorSpace;
Johannes Kronc13f4be2018-12-12 09:52:53 +0100231 static constexpr uint8_t kValueSizeBytes = 28;
Johannes Kron09d65882018-11-27 14:36:41 +0100232 static constexpr uint8_t kValueSizeBytesWithoutHdrMetadata = 4;
Johannes Krond0b69a82018-12-03 14:18:53 +0100233 static constexpr const char kUri[] =
234 "http://www.webrtc.org/experiments/rtp-hdrext/color-space";
Johannes Kronad1d9f02018-11-09 11:12:36 +0100235
236 static bool Parse(rtc::ArrayView<const uint8_t> data,
Johannes Kron09d65882018-11-27 14:36:41 +0100237 ColorSpace* color_space);
238 static size_t ValueSize(const ColorSpace& color_space) {
239 return color_space.hdr_metadata() ? kValueSizeBytes
240 : kValueSizeBytesWithoutHdrMetadata;
241 }
Johannes Kronad1d9f02018-11-09 11:12:36 +0100242 static bool Write(rtc::ArrayView<uint8_t> data,
Johannes Kron09d65882018-11-27 14:36:41 +0100243 const ColorSpace& color_space);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100244
245 private:
Johannes Kronc13f4be2018-12-12 09:52:53 +0100246 static constexpr int kChromaticityDenominator = 50000; // 0.00002 resolution.
247 static constexpr int kLuminanceMaxDenominator = 1; // 1 resolution.
Johannes Kronad1d9f02018-11-09 11:12:36 +0100248 static constexpr int kLuminanceMinDenominator = 10000; // 0.0001 resolution.
Johannes Kronc13f4be2018-12-12 09:52:53 +0100249
250 static uint8_t CombineRangeAndChromaSiting(
251 ColorSpace::RangeID range,
252 ColorSpace::ChromaSiting chroma_siting_horizontal,
253 ColorSpace::ChromaSiting chroma_siting_vertical);
254 static size_t ParseHdrMetadata(rtc::ArrayView<const uint8_t> data,
255 HdrMetadata* hdr_metadata);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100256 static size_t ParseChromaticity(const uint8_t* data,
257 HdrMasteringMetadata::Chromaticity* p);
258 static size_t ParseLuminance(const uint8_t* data, float* f, int denominator);
Johannes Kronc13f4be2018-12-12 09:52:53 +0100259 static size_t WriteHdrMetadata(rtc::ArrayView<uint8_t> data,
260 const HdrMetadata& hdr_metadata);
Johannes Kronad1d9f02018-11-09 11:12:36 +0100261 static size_t WriteChromaticity(uint8_t* data,
262 const HdrMasteringMetadata::Chromaticity& p);
263 static size_t WriteLuminance(uint8_t* data, float f, int denominator);
264};
265
Steve Antona3251dd2017-07-21 09:58:31 -0700266// Base extension class for RTP header extensions which are strings.
267// Subclasses must defined kId and kUri static constexpr members.
268class BaseRtpStringExtension {
269 public:
Danil Chapovalovc5dd3002018-11-08 15:12:45 +0100270 using value_type = std::string;
Steve Antonf0482ea2018-04-09 13:33:52 -0700271 // String RTP header extensions are limited to 16 bytes because it is the
272 // maximum length that can be encoded with one-byte header extensions.
273 static constexpr uint8_t kMaxValueSizeBytes = 16;
274
Steve Antona3251dd2017-07-21 09:58:31 -0700275 static bool Parse(rtc::ArrayView<const uint8_t> data, std::string* str);
276 static size_t ValueSize(const std::string& str) { return str.size(); }
Danil Chapovalov9bf31582018-06-18 13:48:20 +0200277 static bool Write(rtc::ArrayView<uint8_t> data, const std::string& str);
Steve Antona3251dd2017-07-21 09:58:31 -0700278};
279
280class RtpStreamId : public BaseRtpStringExtension {
danilchapef8d7732017-04-19 02:59:48 -0700281 public:
282 static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId;
Steve Antond14d9f72017-07-21 10:59:39 -0700283 static constexpr const char kUri[] =
danilchapef8d7732017-04-19 02:59:48 -0700284 "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
danilchapef8d7732017-04-19 02:59:48 -0700285};
286
Steve Antona3251dd2017-07-21 09:58:31 -0700287class RepairedRtpStreamId : public BaseRtpStringExtension {
danilchapef8d7732017-04-19 02:59:48 -0700288 public:
289 static constexpr RTPExtensionType kId = kRtpExtensionRepairedRtpStreamId;
Steve Antond14d9f72017-07-21 10:59:39 -0700290 static constexpr const char kUri[] =
danilchapef8d7732017-04-19 02:59:48 -0700291 "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";
Steve Antona3251dd2017-07-21 09:58:31 -0700292};
danilchapef8d7732017-04-19 02:59:48 -0700293
Steve Antona3251dd2017-07-21 09:58:31 -0700294class RtpMid : public BaseRtpStringExtension {
295 public:
296 static constexpr RTPExtensionType kId = kRtpExtensionMid;
Steve Antond14d9f72017-07-21 10:59:39 -0700297 static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:sdes:mid";
danilchapef8d7732017-04-19 02:59:48 -0700298};
299
danilchap1edb7ab2016-04-20 05:25:10 -0700300} // namespace webrtc
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200301#endif // MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_