tor-browser

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

rtx_receive_stream_unittest.cc (8640B)


      1 /*
      2 *  Copyright (c) 2017 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 
     11 #include "call/rtx_receive_stream.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <cstring>
     16 #include <map>
     17 
     18 #include "api/array_view.h"
     19 #include "api/units/timestamp.h"
     20 #include "api/video/video_rotation.h"
     21 #include "call/test/mock_rtp_packet_sink_interface.h"
     22 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
     23 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     24 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
     25 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     26 #include "test/gmock.h"
     27 #include "test/gtest.h"
     28 
     29 namespace webrtc {
     30 
     31 namespace {
     32 
     33 using ::testing::Property;
     34 using ::testing::StrictMock;
     35 
     36 constexpr int kMediaPayloadType = 100;
     37 constexpr int kRtxPayloadType = 98;
     38 constexpr int kUnknownPayloadType = 90;
     39 constexpr uint32_t kMediaSSRC = 0x3333333;
     40 constexpr uint16_t kMediaSeqno = 0x5657;
     41 
     42 constexpr uint8_t kRtxPacket[] = {
     43    0x80,  // Version 2.
     44    98,    // Payload type.
     45    0x12,
     46    0x34,  // Seqno.
     47    0x11,
     48    0x11,
     49    0x11,
     50    0x11,  // Timestamp.
     51    0x22,
     52    0x22,
     53    0x22,
     54    0x22,  // SSRC.
     55    // RTX header.
     56    0x56,
     57    0x57,  // Orig seqno.
     58    // Payload.
     59    0xee,
     60 };
     61 
     62 constexpr uint8_t kRtxPacketWithPadding[] = {
     63    0xa0,  // Version 2, P set
     64    98,    // Payload type.
     65    0x12,
     66    0x34,  // Seqno.
     67    0x11,
     68    0x11,
     69    0x11,
     70    0x11,  // Timestamp.
     71    0x22,
     72    0x22,
     73    0x22,
     74    0x22,  // SSRC.
     75    // RTX header.
     76    0x56,
     77    0x57,  // Orig seqno.
     78    // Padding
     79    0x1,
     80 };
     81 
     82 constexpr uint8_t kRtxPacketWithCVO[] = {
     83    0x90,  // Version 2, X set.
     84    98,    // Payload type.
     85    0x12,
     86    0x34,  // Seqno.
     87    0x11,
     88    0x11,
     89    0x11,
     90    0x11,  // Timestamp.
     91    0x22,
     92    0x22,
     93    0x22,
     94    0x22,  // SSRC.
     95    0xbe,
     96    0xde,
     97    0x00,
     98    0x01,  // Extension header.
     99    0x30,
    100    0x01,
    101    0x00,
    102    0x00,  // 90 degree rotation.
    103    // RTX header.
    104    0x56,
    105    0x57,  // Orig seqno.
    106    // Payload.
    107    0xee,
    108 };
    109 
    110 std::map<int, int> PayloadTypeMapping() {
    111  const std::map<int, int> m = {{kRtxPayloadType, kMediaPayloadType}};
    112  return m;
    113 }
    114 
    115 template <typename T>
    116 ArrayView<T> Truncate(ArrayView<T> a, size_t drop) {
    117  return a.subview(0, a.size() - drop);
    118 }
    119 
    120 }  // namespace
    121 
    122 TEST(RtxReceiveStreamTest, RestoresPacketPayload) {
    123  StrictMock<MockRtpPacketSink> media_sink;
    124  RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
    125  RtpPacketReceived rtx_packet;
    126  EXPECT_TRUE(rtx_packet.Parse(ArrayView<const uint8_t>(kRtxPacket)));
    127 
    128  EXPECT_CALL(media_sink, OnRtpPacket)
    129      .WillOnce([](const RtpPacketReceived& packet) {
    130        EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
    131        EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
    132        EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
    133        EXPECT_THAT(packet.payload(), ::testing::ElementsAre(0xee));
    134      });
    135 
    136  rtx_sink.OnRtpPacket(rtx_packet);
    137 }
    138 
    139 TEST(RtxReceiveStreamTest, SetsRecoveredFlag) {
    140  StrictMock<MockRtpPacketSink> media_sink;
    141  RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
    142  RtpPacketReceived rtx_packet;
    143  EXPECT_TRUE(rtx_packet.Parse(ArrayView<const uint8_t>(kRtxPacket)));
    144  EXPECT_FALSE(rtx_packet.recovered());
    145  EXPECT_CALL(media_sink, OnRtpPacket)
    146      .WillOnce([](const RtpPacketReceived& packet) {
    147        EXPECT_TRUE(packet.recovered());
    148      });
    149 
    150  rtx_sink.OnRtpPacket(rtx_packet);
    151 }
    152 
    153 TEST(RtxReceiveStreamTest, IgnoresUnknownPayloadType) {
    154  StrictMock<MockRtpPacketSink> media_sink;
    155  const std::map<int, int> payload_type_mapping = {
    156      {kUnknownPayloadType, kMediaPayloadType}};
    157 
    158  RtxReceiveStream rtx_sink(&media_sink, payload_type_mapping, kMediaSSRC);
    159  RtpPacketReceived rtx_packet;
    160  EXPECT_TRUE(rtx_packet.Parse(ArrayView<const uint8_t>(kRtxPacket)));
    161  rtx_sink.OnRtpPacket(rtx_packet);
    162 }
    163 
    164 TEST(RtxReceiveStreamTest, IgnoresTruncatedPacket) {
    165  StrictMock<MockRtpPacketSink> media_sink;
    166  RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
    167  RtpPacketReceived rtx_packet;
    168  EXPECT_TRUE(
    169      rtx_packet.Parse(Truncate(ArrayView<const uint8_t>(kRtxPacket), 2)));
    170  rtx_sink.OnRtpPacket(rtx_packet);
    171 }
    172 
    173 TEST(RtxReceiveStreamTest, CopiesRtpHeaderExtensions) {
    174  StrictMock<MockRtpPacketSink> media_sink;
    175  RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
    176  RtpHeaderExtensionMap extension_map;
    177  extension_map.RegisterByType(3, kRtpExtensionVideoRotation);
    178  RtpPacketReceived rtx_packet(&extension_map);
    179  EXPECT_TRUE(rtx_packet.Parse(ArrayView<const uint8_t>(kRtxPacketWithCVO)));
    180 
    181  VideoRotation rotation = kVideoRotation_0;
    182  EXPECT_TRUE(rtx_packet.GetExtension<VideoOrientation>(&rotation));
    183  EXPECT_EQ(kVideoRotation_90, rotation);
    184 
    185  EXPECT_CALL(media_sink, OnRtpPacket)
    186      .WillOnce([](const RtpPacketReceived& packet) {
    187        EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
    188        EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
    189        EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
    190        EXPECT_THAT(packet.payload(), ::testing::ElementsAre(0xee));
    191        VideoRotation rotation = kVideoRotation_0;
    192        EXPECT_TRUE(packet.GetExtension<VideoOrientation>(&rotation));
    193        EXPECT_EQ(rotation, kVideoRotation_90);
    194      });
    195 
    196  rtx_sink.OnRtpPacket(rtx_packet);
    197 }
    198 
    199 TEST(RtxReceiveStreamTest, PropagatesArrivalTime) {
    200  StrictMock<MockRtpPacketSink> media_sink;
    201  RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
    202  RtpPacketReceived rtx_packet(nullptr);
    203  EXPECT_TRUE(rtx_packet.Parse(ArrayView<const uint8_t>(kRtxPacket)));
    204  rtx_packet.set_arrival_time(Timestamp::Millis(123));
    205  EXPECT_CALL(media_sink, OnRtpPacket(Property(&RtpPacketReceived::arrival_time,
    206                                               Timestamp::Millis(123))));
    207  rtx_sink.OnRtpPacket(rtx_packet);
    208 }
    209 
    210 TEST(RtxReceiveStreamTest, SupportsLargePacket) {
    211  StrictMock<MockRtpPacketSink> media_sink;
    212  RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
    213  RtpPacketReceived rtx_packet;
    214  constexpr int kRtxPacketSize = 2000;
    215  constexpr int kRtxPayloadOffset = 14;
    216  uint8_t large_rtx_packet[kRtxPacketSize];
    217  memcpy(large_rtx_packet, kRtxPacket, sizeof(kRtxPacket));
    218  ArrayView<uint8_t> payload(large_rtx_packet + kRtxPayloadOffset,
    219                             kRtxPacketSize - kRtxPayloadOffset);
    220 
    221  // Fill payload.
    222  for (size_t i = 0; i < payload.size(); i++) {
    223    payload[i] = i;
    224  }
    225  EXPECT_TRUE(rtx_packet.Parse(ArrayView<const uint8_t>(large_rtx_packet)));
    226 
    227  EXPECT_CALL(media_sink, OnRtpPacket)
    228      .WillOnce([&](const RtpPacketReceived& packet) {
    229        EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
    230        EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
    231        EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
    232        EXPECT_THAT(packet.payload(), ::testing::ElementsAreArray(payload));
    233      });
    234 
    235  rtx_sink.OnRtpPacket(rtx_packet);
    236 }
    237 
    238 TEST(RtxReceiveStreamTest, SupportsLargePacketWithPadding) {
    239  StrictMock<MockRtpPacketSink> media_sink;
    240  RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
    241  RtpPacketReceived rtx_packet;
    242  constexpr int kRtxPacketSize = 2000;
    243  constexpr int kRtxPayloadOffset = 14;
    244  constexpr int kRtxPaddingSize = 50;
    245  uint8_t large_rtx_packet[kRtxPacketSize];
    246  memcpy(large_rtx_packet, kRtxPacketWithPadding,
    247         sizeof(kRtxPacketWithPadding));
    248  ArrayView<uint8_t> payload(
    249      large_rtx_packet + kRtxPayloadOffset,
    250      kRtxPacketSize - kRtxPayloadOffset - kRtxPaddingSize);
    251  ArrayView<uint8_t> padding(
    252      large_rtx_packet + kRtxPacketSize - kRtxPaddingSize, kRtxPaddingSize);
    253 
    254  // Fill payload.
    255  for (size_t i = 0; i < payload.size(); i++) {
    256    payload[i] = i;
    257  }
    258  // Fill padding. Only value of last padding byte matters.
    259  for (size_t i = 0; i < padding.size(); i++) {
    260    padding[i] = kRtxPaddingSize;
    261  }
    262 
    263  EXPECT_TRUE(rtx_packet.Parse(ArrayView<const uint8_t>(large_rtx_packet)));
    264 
    265  EXPECT_CALL(media_sink, OnRtpPacket)
    266      .WillOnce([&](const RtpPacketReceived& packet) {
    267        EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
    268        EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
    269        EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
    270        EXPECT_THAT(packet.payload(), ::testing::ElementsAreArray(payload));
    271      });
    272 
    273  rtx_sink.OnRtpPacket(rtx_packet);
    274 }
    275 
    276 }  // namespace webrtc