tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rtp_header_extensions.h (15322B)


      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 <cstdint>
     17 #include <optional>
     18 #include <string>
     19 #include <vector>
     20 
     21 #include "absl/strings/string_view.h"
     22 #include "api/array_view.h"
     23 #include "api/rtp_headers.h"
     24 #include "api/rtp_parameters.h"
     25 #include "api/units/time_delta.h"
     26 #include "api/units/timestamp.h"
     27 #include "api/video/color_space.h"
     28 #include "api/video/hdr_metadata.h"
     29 #include "api/video/video_content_type.h"
     30 #include "api/video/video_rotation.h"
     31 #include "api/video/video_timing.h"
     32 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     33 #include "rtc_base/checks.h"
     34 #include "system_wrappers/include/ntp_time.h"
     35 
     36 // This file contains class definitions for reading/writing each RTP header
     37 // extension. Each class must be defined such that it is compatible with being
     38 // an argument to the templated RtpPacket::GetExtension and
     39 // RtpPacketToSend::SetExtension methods. New header extensions must have class
     40 // names ending with "Extension", for the purpose of avoiding collisions with
     41 // RTP extension information exposed in the public API of WebRTC.
     42 
     43 namespace webrtc {
     44 
     45 class AbsoluteSendTime {
     46 public:
     47  using value_type = uint32_t;
     48  static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteSendTime;
     49  static constexpr uint8_t kValueSizeBytes = 3;
     50  static constexpr absl::string_view Uri() {
     51    return RtpExtension::kAbsSendTimeUri;
     52  }
     53 
     54  static bool Parse(ArrayView<const uint8_t> data, uint32_t* time_24bits);
     55  static size_t ValueSize(uint32_t /* time_24bits */) {
     56    return kValueSizeBytes;
     57  }
     58  static bool Write(ArrayView<uint8_t> data, uint32_t time_24bits);
     59 
     60  static constexpr uint32_t To24Bits(Timestamp time) {
     61    int64_t time_us = time.us() % (int64_t{1 << 6} * 1'000'000);
     62    int64_t time6x18 = (time_us << 18) / 1'000'000;
     63    RTC_DCHECK_GE(time6x18, 0);
     64    RTC_DCHECK_LT(time6x18, 1 << 24);
     65    return static_cast<uint32_t>(time6x18);
     66  }
     67 
     68  static uint32_t To24Bits(NtpTime ntp_time) {
     69    uint64_t ntp_time32x32 = static_cast<uint64_t>(ntp_time);
     70    return (ntp_time32x32 >> 14) & 0x00FF'FFFF;
     71  }
     72 
     73  static constexpr Timestamp ToTimestamp(uint32_t time_24bits) {
     74    RTC_DCHECK_LT(time_24bits, (1 << 24));
     75    return Timestamp::Micros((time_24bits * int64_t{1'000'000}) >> 18);
     76  }
     77 };
     78 
     79 class AbsoluteCaptureTimeExtension {
     80 public:
     81  using value_type = AbsoluteCaptureTime;
     82  static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteCaptureTime;
     83  static constexpr uint8_t kValueSizeBytes = 16;
     84  static constexpr uint8_t kValueSizeBytesWithoutEstimatedCaptureClockOffset =
     85      8;
     86  static constexpr absl::string_view Uri() {
     87    return RtpExtension::kAbsoluteCaptureTimeUri;
     88  }
     89 
     90  static bool Parse(ArrayView<const uint8_t> data,
     91                    AbsoluteCaptureTime* extension);
     92  static size_t ValueSize(const AbsoluteCaptureTime& extension);
     93  static bool Write(ArrayView<uint8_t> data,
     94                    const AbsoluteCaptureTime& extension);
     95 };
     96 
     97 class AudioLevelExtension {
     98 public:
     99  using value_type = AudioLevel;
    100  static constexpr RTPExtensionType kId = kRtpExtensionAudioLevel;
    101  static constexpr uint8_t kValueSizeBytes = 1;
    102  static constexpr absl::string_view Uri() {
    103    return RtpExtension::kAudioLevelUri;
    104  }
    105 
    106  static bool Parse(ArrayView<const uint8_t> data, AudioLevel* extension);
    107  static size_t ValueSize(const AudioLevel& /* extension */) {
    108    return kValueSizeBytes;
    109  }
    110  static bool Write(ArrayView<uint8_t> data, const AudioLevel& extension);
    111 };
    112 
    113 #if !defined(WEBRTC_MOZILLA_BUILD)
    114 class CsrcAudioLevel {
    115 public:
    116  static constexpr RTPExtensionType kId = kRtpExtensionCsrcAudioLevel;
    117  static constexpr uint8_t kMaxValueSizeBytes = 15;
    118  static constexpr absl::string_view Uri() {
    119    return RtpExtension::kCsrcAudioLevelsUri;
    120  }
    121 
    122  static bool Parse(ArrayView<const uint8_t> data,
    123                    std::vector<uint8_t>* csrc_audio_levels);
    124  static size_t ValueSize(ArrayView<const uint8_t> csrc_audio_levels);
    125  static bool Write(ArrayView<uint8_t> data,
    126                    ArrayView<const uint8_t> csrc_audio_levels);
    127 };
    128 #endif
    129 
    130 class TransmissionOffset {
    131 public:
    132  using value_type = int32_t;
    133  static constexpr RTPExtensionType kId = kRtpExtensionTransmissionTimeOffset;
    134  static constexpr uint8_t kValueSizeBytes = 3;
    135  static constexpr absl::string_view Uri() {
    136    return RtpExtension::kTimestampOffsetUri;
    137  }
    138 
    139  static bool Parse(ArrayView<const uint8_t> data, int32_t* rtp_time);
    140  static size_t ValueSize(int32_t /* rtp_time */) { return kValueSizeBytes; }
    141  static bool Write(ArrayView<uint8_t> data, int32_t rtp_time);
    142 };
    143 
    144 class TransportSequenceNumber {
    145 public:
    146  using value_type = uint16_t;
    147  static constexpr RTPExtensionType kId = kRtpExtensionTransportSequenceNumber;
    148  static constexpr uint8_t kValueSizeBytes = 2;
    149  static constexpr absl::string_view Uri() {
    150    return RtpExtension::kTransportSequenceNumberUri;
    151  }
    152 
    153  static bool Parse(ArrayView<const uint8_t> data,
    154                    uint16_t* transport_sequence_number);
    155  static size_t ValueSize(uint16_t /*transport_sequence_number*/) {
    156    return kValueSizeBytes;
    157  }
    158  static bool Write(ArrayView<uint8_t> data,
    159                    uint16_t transport_sequence_number);
    160 };
    161 
    162 class TransportSequenceNumberV2 {
    163 public:
    164  static constexpr RTPExtensionType kId =
    165      kRtpExtensionTransportSequenceNumber02;
    166  static constexpr uint8_t kValueSizeBytes = 4;
    167  static constexpr uint8_t kValueSizeBytesWithoutFeedbackRequest = 2;
    168  static constexpr absl::string_view Uri() {
    169    return RtpExtension::kTransportSequenceNumberV2Uri;
    170  }
    171 
    172  static bool Parse(ArrayView<const uint8_t> data,
    173                    uint16_t* transport_sequence_number,
    174                    std::optional<FeedbackRequest>* feedback_request);
    175  static size_t ValueSize(
    176      uint16_t /*transport_sequence_number*/,
    177      const std::optional<FeedbackRequest>& feedback_request) {
    178    return feedback_request ? kValueSizeBytes
    179                            : kValueSizeBytesWithoutFeedbackRequest;
    180  }
    181  static bool Write(ArrayView<uint8_t> data,
    182                    uint16_t transport_sequence_number,
    183                    const std::optional<FeedbackRequest>& feedback_request);
    184 
    185 private:
    186  static constexpr uint16_t kIncludeTimestampsBit = 1 << 15;
    187 };
    188 
    189 class VideoOrientation {
    190 public:
    191  using value_type = VideoRotation;
    192  static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation;
    193  static constexpr uint8_t kValueSizeBytes = 1;
    194  static constexpr absl::string_view Uri() {
    195    return RtpExtension::kVideoRotationUri;
    196  }
    197 
    198  static bool Parse(ArrayView<const uint8_t> data, VideoRotation* value);
    199  static size_t ValueSize(VideoRotation) { return kValueSizeBytes; }
    200  static bool Write(ArrayView<uint8_t> data, VideoRotation value);
    201  static bool Parse(ArrayView<const uint8_t> data, uint8_t* value);
    202  static size_t ValueSize(uint8_t /* value */) { return kValueSizeBytes; }
    203  static bool Write(ArrayView<uint8_t> data, uint8_t value);
    204 };
    205 
    206 class PlayoutDelayLimits {
    207 public:
    208  using value_type = VideoPlayoutDelay;
    209  static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay;
    210  static constexpr uint8_t kValueSizeBytes = 3;
    211  static constexpr absl::string_view Uri() {
    212    return RtpExtension::kPlayoutDelayUri;
    213  }
    214 
    215  // Playout delay in milliseconds. A playout delay limit (min or max)
    216  // has 12 bits allocated. This allows a range of 0-4095 values which
    217  // translates to a range of 0-40950 in milliseconds.
    218  static constexpr TimeDelta kGranularity = TimeDelta::Millis(10);
    219  // Maximum playout delay value in milliseconds.
    220  static constexpr TimeDelta kMax = 0xfff * kGranularity;  // 40950.
    221 
    222  static bool Parse(ArrayView<const uint8_t> data,
    223                    VideoPlayoutDelay* playout_delay);
    224  static size_t ValueSize(const VideoPlayoutDelay&) { return kValueSizeBytes; }
    225  static bool Write(ArrayView<uint8_t> data,
    226                    const VideoPlayoutDelay& playout_delay);
    227 };
    228 
    229 class VideoContentTypeExtension {
    230 public:
    231  using value_type = VideoContentType;
    232  static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType;
    233  static constexpr uint8_t kValueSizeBytes = 1;
    234  static constexpr absl::string_view Uri() {
    235    return RtpExtension::kVideoContentTypeUri;
    236  }
    237 
    238  static bool Parse(ArrayView<const uint8_t> data,
    239                    VideoContentType* content_type);
    240  static size_t ValueSize(VideoContentType) { return kValueSizeBytes; }
    241  static bool Write(ArrayView<uint8_t> data, VideoContentType content_type);
    242 };
    243 
    244 class VideoTimingExtension {
    245 public:
    246  using value_type = VideoSendTiming;
    247  static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming;
    248  static constexpr uint8_t kValueSizeBytes = 13;
    249  static constexpr absl::string_view Uri() {
    250    return RtpExtension::kVideoTimingUri;
    251  }
    252 
    253  // Offsets of the fields in the RTP header extension, counting from the first
    254  // byte after the one-byte header.
    255  static constexpr uint8_t kFlagsOffset = 0;
    256  static constexpr uint8_t kEncodeStartDeltaOffset = 1;
    257  static constexpr uint8_t kEncodeFinishDeltaOffset = 3;
    258  static constexpr uint8_t kPacketizationFinishDeltaOffset = 5;
    259  static constexpr uint8_t kPacerExitDeltaOffset = 7;
    260  static constexpr uint8_t kNetworkTimestampDeltaOffset = 9;
    261  static constexpr uint8_t kNetwork2TimestampDeltaOffset = 11;
    262 
    263  static bool Parse(ArrayView<const uint8_t> data, VideoSendTiming* timing);
    264  static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; }
    265  static bool Write(ArrayView<uint8_t> data, const VideoSendTiming& timing);
    266 
    267  static size_t ValueSize(uint16_t /* time_delta_ms */, uint8_t /* idx */) {
    268    return kValueSizeBytes;
    269  }
    270  // Writes only single time delta to position idx.
    271  static bool Write(ArrayView<uint8_t> data,
    272                    uint16_t time_delta_ms,
    273                    uint8_t offset);
    274 };
    275 
    276 class ColorSpaceExtension {
    277 public:
    278  using value_type = ColorSpace;
    279  static constexpr RTPExtensionType kId = kRtpExtensionColorSpace;
    280  static constexpr uint8_t kValueSizeBytes = 28;
    281  static constexpr uint8_t kValueSizeBytesWithoutHdrMetadata = 4;
    282  static constexpr absl::string_view Uri() {
    283    return RtpExtension::kColorSpaceUri;
    284  }
    285 
    286  static bool Parse(ArrayView<const uint8_t> data, ColorSpace* color_space);
    287  static size_t ValueSize(const ColorSpace& color_space) {
    288    return color_space.hdr_metadata() ? kValueSizeBytes
    289                                      : kValueSizeBytesWithoutHdrMetadata;
    290  }
    291  static bool Write(ArrayView<uint8_t> data, const ColorSpace& color_space);
    292 
    293 private:
    294  static constexpr int kChromaticityDenominator = 50000;  // 0.00002 resolution.
    295  static constexpr int kLuminanceMaxDenominator = 1;      // 1 resolution.
    296  static constexpr int kLuminanceMinDenominator = 10000;  // 0.0001 resolution.
    297 
    298  static uint8_t CombineRangeAndChromaSiting(
    299      ColorSpace::RangeID range,
    300      ColorSpace::ChromaSiting chroma_siting_horizontal,
    301      ColorSpace::ChromaSiting chroma_siting_vertical);
    302  static size_t ParseHdrMetadata(ArrayView<const uint8_t> data,
    303                                 HdrMetadata* hdr_metadata);
    304  static size_t ParseChromaticity(const uint8_t* data,
    305                                  HdrMasteringMetadata::Chromaticity* p);
    306  static size_t ParseLuminance(const uint8_t* data, float* f, int denominator);
    307  static size_t WriteHdrMetadata(ArrayView<uint8_t> data,
    308                                 const HdrMetadata& hdr_metadata);
    309  static size_t WriteChromaticity(uint8_t* data,
    310                                  const HdrMasteringMetadata::Chromaticity& p);
    311  static size_t WriteLuminance(uint8_t* data, float f, int denominator);
    312 };
    313 
    314 #if defined(WEBRTC_MOZILLA_BUILD)
    315 class CsrcAudioLevel {
    316 public:
    317  static constexpr RTPExtensionType kId = kRtpExtensionCsrcAudioLevel;
    318  static constexpr absl::string_view Uri() {
    319    return RtpExtension::kCsrcAudioLevelsUri;
    320  }
    321  static constexpr const char* kUri =
    322      "urn:ietf:params:rtp-hdrext:csrc-audio-level";
    323 
    324  static bool Parse(webrtc::ArrayView<const uint8_t> data,
    325                    CsrcAudioLevelList* csrcAudioLevels);
    326  static size_t ValueSize(const CsrcAudioLevelList& csrcAudioLevels);
    327  static bool Write(webrtc::ArrayView<uint8_t> data,
    328                    const CsrcAudioLevelList& csrcAudioLevels);
    329 };
    330 #endif
    331 
    332 // Base extension class for RTP header extensions which are strings.
    333 // Subclasses must defined kId and kUri static constexpr members.
    334 class BaseRtpStringExtension {
    335 public:
    336  using value_type = std::string;
    337  // String RTP header extensions are limited to 16 bytes because it is the
    338  // maximum length that can be encoded with one-byte header extensions.
    339  static constexpr uint8_t kMaxValueSizeBytes = 16;
    340 
    341  static bool Parse(ArrayView<const uint8_t> data, std::string* str);
    342  static size_t ValueSize(absl::string_view str) { return str.size(); }
    343  static bool Write(ArrayView<uint8_t> data, absl::string_view str);
    344 };
    345 
    346 class RtpStreamId : public BaseRtpStringExtension {
    347 public:
    348  static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId;
    349  static constexpr absl::string_view Uri() { return RtpExtension::kRidUri; }
    350 };
    351 
    352 class RepairedRtpStreamId : public BaseRtpStringExtension {
    353 public:
    354  static constexpr RTPExtensionType kId = kRtpExtensionRepairedRtpStreamId;
    355  static constexpr absl::string_view Uri() {
    356    return RtpExtension::kRepairedRidUri;
    357  }
    358 };
    359 
    360 class RtpMid : public BaseRtpStringExtension {
    361 public:
    362  static constexpr RTPExtensionType kId = kRtpExtensionMid;
    363  static constexpr absl::string_view Uri() { return RtpExtension::kMidUri; }
    364 };
    365 
    366 class InbandComfortNoiseExtension {
    367 public:
    368  using value_type = std::optional<uint8_t>;
    369 
    370  static constexpr RTPExtensionType kId = kRtpExtensionInbandComfortNoise;
    371  static constexpr uint8_t kValueSizeBytes = 1;
    372  static constexpr const char kUri[] =
    373      "http://www.webrtc.org/experiments/rtp-hdrext/inband-cn";
    374  static constexpr absl::string_view Uri() { return kUri; }
    375 
    376  static bool Parse(ArrayView<const uint8_t> data,
    377                    std::optional<uint8_t>* level);
    378  static size_t ValueSize(std::optional<uint8_t> /* level */) {
    379    return kValueSizeBytes;
    380  }
    381  static bool Write(ArrayView<uint8_t> data, std::optional<uint8_t> level);
    382 };
    383 
    384 class VideoFrameTrackingIdExtension {
    385 public:
    386  using value_type = uint16_t;
    387  static constexpr RTPExtensionType kId = kRtpExtensionVideoFrameTrackingId;
    388  static constexpr uint8_t kValueSizeBytes = 2;
    389  static constexpr absl::string_view Uri() {
    390    return RtpExtension::kVideoFrameTrackingIdUri;
    391  }
    392 
    393  static bool Parse(ArrayView<const uint8_t> data,
    394                    uint16_t* video_frame_tracking_id);
    395  static size_t ValueSize(uint16_t /*video_frame_tracking_id*/) {
    396    return kValueSizeBytes;
    397  }
    398  static bool Write(ArrayView<uint8_t> data, uint16_t video_frame_tracking_id);
    399 };
    400 
    401 }  // namespace webrtc
    402 #endif  // MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSIONS_H_