tor-browser

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

rtp_vp8_ref_finder_unittest.cc (13938B)


      1 /*
      2 *  Copyright (c) 2020 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 "modules/video_coding/rtp_vp8_ref_finder.h"
     12 
     13 #include <cstdint>
     14 #include <memory>
     15 #include <optional>
     16 #include <utility>
     17 #include <vector>
     18 
     19 #include "api/array_view.h"
     20 #include "api/rtp_packet_infos.h"
     21 #include "api/video/encoded_frame.h"
     22 #include "api/video/encoded_image.h"
     23 #include "api/video/video_codec_type.h"
     24 #include "api/video/video_content_type.h"
     25 #include "api/video/video_frame_type.h"
     26 #include "api/video/video_rotation.h"
     27 #include "api/video/video_timing.h"
     28 #include "modules/rtp_rtcp/source/frame_object.h"
     29 #include "modules/rtp_rtcp/source/rtp_video_header.h"
     30 #include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
     31 #include "test/gmock.h"
     32 #include "test/gtest.h"
     33 
     34 using ::testing::Contains;
     35 using ::testing::Eq;
     36 using ::testing::Matcher;
     37 using ::testing::Matches;
     38 using ::testing::SizeIs;
     39 using ::testing::UnorderedElementsAreArray;
     40 
     41 namespace webrtc {
     42 namespace {
     43 
     44 MATCHER_P2(HasIdAndRefs, id, refs, "") {
     45  return Matches(Eq(id))(arg->Id()) &&
     46         Matches(UnorderedElementsAreArray(refs))(
     47             ArrayView<int64_t>(arg->references, arg->num_references));
     48 }
     49 
     50 Matcher<const std::vector<std::unique_ptr<EncodedFrame>>&>
     51 HasFrameWithIdAndRefs(int64_t frame_id, const std::vector<int64_t>& refs) {
     52  return Contains(HasIdAndRefs(frame_id, refs));
     53 }
     54 
     55 class Frame {
     56 public:
     57  Frame& AsKeyFrame(bool is_keyframe = true) {
     58    is_keyframe_ = is_keyframe;
     59    return *this;
     60  }
     61 
     62  Frame& Pid(int pid) {
     63    picture_id_ = pid;
     64    return *this;
     65  }
     66 
     67  Frame& Tid(int tid) {
     68    temporal_id_ = tid;
     69    return *this;
     70  }
     71 
     72  Frame& Tl0(int tl0) {
     73    tl0_idx_ = tl0;
     74    return *this;
     75  }
     76 
     77  Frame& AsSync(bool is_sync = true) {
     78    sync = is_sync;
     79    return *this;
     80  }
     81 
     82  operator std::unique_ptr<RtpFrameObject>() {
     83    RTPVideoHeaderVP8 vp8_header{};
     84    vp8_header.pictureId = *picture_id_;
     85    vp8_header.temporalIdx = *temporal_id_;
     86    vp8_header.tl0PicIdx = *tl0_idx_;
     87    vp8_header.layerSync = sync;
     88 
     89    RTPVideoHeader video_header;
     90    video_header.frame_type = is_keyframe_ ? VideoFrameType::kVideoFrameKey
     91                                           : VideoFrameType::kVideoFrameDelta;
     92    video_header.video_type_header = vp8_header;
     93    // clang-format off
     94    return std::make_unique<RtpFrameObject>(
     95        /*seq_num_start=*/0,
     96        /*seq_num_end=*/0,
     97        /*markerBit=*/true,
     98        /*times_nacked=*/0,
     99        /*first_packet_received_time=*/0,
    100        /*last_packet_received_time=*/0,
    101        /*rtp_timestamp=*/0,
    102        /*ntp_time_ms=*/0,
    103        VideoSendTiming(),
    104        /*payload_type=*/0,
    105        kVideoCodecVP8,
    106        kVideoRotation_0,
    107        VideoContentType::UNSPECIFIED,
    108        video_header,
    109        /*color_space=*/std::nullopt,
    110        /*frame_instrumentation_data=*/std::nullopt,
    111        RtpPacketInfos(),
    112        EncodedImageBuffer::Create(/*size=*/0));
    113    // clang-format on
    114  }
    115 
    116 private:
    117  bool is_keyframe_ = false;
    118  std::optional<int> picture_id_;
    119  std::optional<int> temporal_id_;
    120  std::optional<int> tl0_idx_;
    121  bool sync = false;
    122 };
    123 
    124 }  // namespace
    125 
    126 class RtpVp8RefFinderTest : public ::testing::Test {
    127 protected:
    128  RtpVp8RefFinderTest() : ref_finder_(std::make_unique<RtpVp8RefFinder>()) {}
    129 
    130  void Insert(std::unique_ptr<RtpFrameObject> frame) {
    131    for (auto& f : ref_finder_->ManageFrame(std::move(frame))) {
    132      frames_.push_back(std::move(f));
    133    }
    134  }
    135 
    136  std::unique_ptr<RtpVp8RefFinder> ref_finder_;
    137  std::vector<std::unique_ptr<EncodedFrame>> frames_;
    138 };
    139 
    140 TEST_F(RtpVp8RefFinderTest, Vp8RepeatedFrame_0) {
    141  Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame());
    142  Insert(Frame().Pid(1).Tid(0).Tl0(2));
    143  Insert(Frame().Pid(1).Tid(0).Tl0(2));
    144 
    145  EXPECT_THAT(frames_, SizeIs(2));
    146  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    147  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    148 }
    149 
    150 TEST_F(RtpVp8RefFinderTest, Vp8RepeatedFrameLayerSync_01) {
    151  Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame());
    152  Insert(Frame().Pid(1).Tid(1).Tl0(1).AsSync());
    153  Insert(Frame().Pid(1).Tid(1).Tl0(1).AsSync());
    154 
    155  EXPECT_THAT(frames_, SizeIs(2));
    156  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    157  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    158 }
    159 
    160 TEST_F(RtpVp8RefFinderTest, Vp8RepeatedFrame_01) {
    161  Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame());
    162  Insert(Frame().Pid(1).Tid(0).Tl0(2).AsSync());
    163  Insert(Frame().Pid(2).Tid(0).Tl0(3));
    164  Insert(Frame().Pid(3).Tid(0).Tl0(4));
    165  Insert(Frame().Pid(3).Tid(0).Tl0(4));
    166 
    167  EXPECT_THAT(frames_, SizeIs(4));
    168  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    169  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    170  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {1}));
    171  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {2}));
    172 }
    173 
    174 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayers_0) {
    175  Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame());
    176  Insert(Frame().Pid(1).Tid(0).Tl0(2));
    177 
    178  EXPECT_THAT(frames_, SizeIs(2));
    179  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    180  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    181 }
    182 
    183 TEST_F(RtpVp8RefFinderTest, Vp8DuplicateTl1Frames) {
    184  Insert(Frame().Pid(0).Tid(0).Tl0(0).AsKeyFrame());
    185  Insert(Frame().Pid(1).Tid(1).Tl0(0).AsSync());
    186  Insert(Frame().Pid(2).Tid(0).Tl0(1));
    187  Insert(Frame().Pid(3).Tid(1).Tl0(1));
    188  Insert(Frame().Pid(3).Tid(1).Tl0(1));
    189  Insert(Frame().Pid(4).Tid(0).Tl0(2));
    190  Insert(Frame().Pid(5).Tid(1).Tl0(2));
    191 
    192  EXPECT_THAT(frames_, SizeIs(6));
    193  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    194  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    195  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0}));
    196  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1, 2}));
    197  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {2}));
    198  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {3, 4}));
    199 }
    200 
    201 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayersReordering_0) {
    202  Insert(Frame().Pid(1).Tid(0).Tl0(2));
    203  Insert(Frame().Pid(0).Tid(0).Tl0(1).AsKeyFrame());
    204  Insert(Frame().Pid(3).Tid(0).Tl0(4));
    205  Insert(Frame().Pid(2).Tid(0).Tl0(3));
    206  Insert(Frame().Pid(5).Tid(0).Tl0(6));
    207  Insert(Frame().Pid(6).Tid(0).Tl0(7));
    208  Insert(Frame().Pid(4).Tid(0).Tl0(5));
    209 
    210  EXPECT_THAT(frames_, SizeIs(7));
    211  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    212  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    213  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {1}));
    214  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {2}));
    215  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {3}));
    216  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {4}));
    217  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {5}));
    218 }
    219 
    220 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayers_01) {
    221  Insert(Frame().Pid(0).Tid(0).Tl0(255).AsKeyFrame());
    222  Insert(Frame().Pid(1).Tid(1).Tl0(255).AsSync());
    223  Insert(Frame().Pid(2).Tid(0).Tl0(0));
    224  Insert(Frame().Pid(3).Tid(1).Tl0(0));
    225 
    226  EXPECT_THAT(frames_, SizeIs(4));
    227  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    228  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    229  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0}));
    230  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1, 2}));
    231 }
    232 
    233 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayersReordering_01) {
    234  Insert(Frame().Pid(1).Tid(1).Tl0(255).AsSync());
    235  Insert(Frame().Pid(0).Tid(0).Tl0(255).AsKeyFrame());
    236  Insert(Frame().Pid(3).Tid(1).Tl0(0));
    237  Insert(Frame().Pid(5).Tid(1).Tl0(1));
    238  Insert(Frame().Pid(2).Tid(0).Tl0(0));
    239  Insert(Frame().Pid(4).Tid(0).Tl0(1));
    240  Insert(Frame().Pid(6).Tid(0).Tl0(2));
    241  Insert(Frame().Pid(7).Tid(1).Tl0(2));
    242 
    243  EXPECT_THAT(frames_, SizeIs(8));
    244  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    245  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    246  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0}));
    247  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1, 2}));
    248  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {2}));
    249  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {3, 4}));
    250  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {4}));
    251  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(7, {5, 6}));
    252 }
    253 
    254 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayers_0212) {
    255  Insert(Frame().Pid(0).Tid(0).Tl0(55).AsKeyFrame());
    256  Insert(Frame().Pid(1).Tid(2).Tl0(55).AsSync());
    257  Insert(Frame().Pid(2).Tid(1).Tl0(55).AsSync());
    258  Insert(Frame().Pid(3).Tid(2).Tl0(55));
    259  Insert(Frame().Pid(4).Tid(0).Tl0(56));
    260  Insert(Frame().Pid(5).Tid(2).Tl0(56));
    261  Insert(Frame().Pid(6).Tid(1).Tl0(56));
    262  Insert(Frame().Pid(7).Tid(2).Tl0(56));
    263  Insert(Frame().Pid(8).Tid(0).Tl0(57));
    264  Insert(Frame().Pid(9).Tid(2).Tl0(57).AsSync());
    265  Insert(Frame().Pid(10).Tid(1).Tl0(57).AsSync());
    266  Insert(Frame().Pid(11).Tid(2).Tl0(57));
    267 
    268  EXPECT_THAT(frames_, SizeIs(12));
    269  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    270  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    271  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0}));
    272  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {0, 1, 2}));
    273  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {0}));
    274  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {2, 3, 4}));
    275  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {2, 4}));
    276  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(7, {4, 5, 6}));
    277  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(8, {4}));
    278  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(9, {8}));
    279  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {8}));
    280  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(11, {8, 9, 10}));
    281 }
    282 
    283 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayersMissingFrame_0212) {
    284  Insert(Frame().Pid(0).Tid(0).Tl0(55).AsKeyFrame());
    285  Insert(Frame().Pid(2).Tid(1).Tl0(55).AsSync());
    286  Insert(Frame().Pid(3).Tid(2).Tl0(55));
    287 
    288  EXPECT_THAT(frames_, SizeIs(2));
    289  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    290  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0}));
    291 }
    292 
    293 // Test with 3 temporal layers in a 0212 pattern.
    294 TEST_F(RtpVp8RefFinderTest, Vp8TemporalLayersReordering_0212) {
    295  Insert(Frame().Pid(127).Tid(2).Tl0(55).AsSync());
    296  Insert(Frame().Pid(126).Tid(0).Tl0(55).AsKeyFrame());
    297  Insert(Frame().Pid(128).Tid(1).Tl0(55).AsSync());
    298  Insert(Frame().Pid(130).Tid(0).Tl0(56));
    299  Insert(Frame().Pid(131).Tid(2).Tl0(56));
    300  Insert(Frame().Pid(129).Tid(2).Tl0(55));
    301  Insert(Frame().Pid(133).Tid(2).Tl0(56));
    302  Insert(Frame().Pid(135).Tid(2).Tl0(57).AsSync());
    303  Insert(Frame().Pid(132).Tid(1).Tl0(56));
    304  Insert(Frame().Pid(134).Tid(0).Tl0(57));
    305  Insert(Frame().Pid(137).Tid(2).Tl0(57));
    306  Insert(Frame().Pid(136).Tid(1).Tl0(57).AsSync());
    307 
    308  EXPECT_THAT(frames_, SizeIs(12));
    309  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(126, {}));
    310  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(127, {126}));
    311  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(128, {126}));
    312  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(129, {126, 127, 128}));
    313  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(130, {126}));
    314  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(131, {128, 129, 130}));
    315  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(132, {128, 130}));
    316  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(133, {130, 131, 132}));
    317  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(134, {130}));
    318  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(135, {134}));
    319  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(136, {134}));
    320  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(137, {134, 135, 136}));
    321 }
    322 
    323 TEST_F(RtpVp8RefFinderTest, Vp8LayerSync) {
    324  Insert(Frame().Pid(0).Tid(0).Tl0(0).AsKeyFrame());
    325  Insert(Frame().Pid(1).Tid(1).Tl0(0).AsSync());
    326  Insert(Frame().Pid(2).Tid(0).Tl0(1));
    327  Insert(Frame().Pid(4).Tid(0).Tl0(2));
    328  Insert(Frame().Pid(5).Tid(1).Tl0(2).AsSync());
    329  Insert(Frame().Pid(6).Tid(0).Tl0(3));
    330  Insert(Frame().Pid(7).Tid(1).Tl0(3));
    331 
    332  EXPECT_THAT(frames_, SizeIs(7));
    333  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
    334  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
    335  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {0}));
    336  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {2}));
    337  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {4}));
    338  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {4}));
    339  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(7, {5, 6}));
    340 }
    341 
    342 TEST_F(RtpVp8RefFinderTest, Vp8Tl1SyncFrameAfterTl1Frame) {
    343  Insert(Frame().Pid(1).Tid(0).Tl0(247).AsKeyFrame().AsSync());
    344  Insert(Frame().Pid(3).Tid(0).Tl0(248));
    345  Insert(Frame().Pid(4).Tid(1).Tl0(248));
    346  Insert(Frame().Pid(5).Tid(1).Tl0(248).AsSync());
    347 
    348  EXPECT_THAT(frames_, SizeIs(3));
    349  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {}));
    350  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1}));
    351  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {3}));
    352 }
    353 
    354 TEST_F(RtpVp8RefFinderTest, Vp8DetectMissingFrame_0212) {
    355  Insert(Frame().Pid(1).Tid(0).Tl0(1).AsKeyFrame());
    356  Insert(Frame().Pid(2).Tid(2).Tl0(1).AsSync());
    357  Insert(Frame().Pid(3).Tid(1).Tl0(1).AsSync());
    358  Insert(Frame().Pid(4).Tid(2).Tl0(1));
    359  Insert(Frame().Pid(6).Tid(2).Tl0(2));
    360  Insert(Frame().Pid(7).Tid(1).Tl0(2));
    361  Insert(Frame().Pid(8).Tid(2).Tl0(2));
    362  Insert(Frame().Pid(5).Tid(0).Tl0(2));
    363 
    364  EXPECT_THAT(frames_, SizeIs(8));
    365  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {}));
    366  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(2, {1}));
    367  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(3, {1}));
    368  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(4, {1, 2, 3}));
    369  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {1}));
    370  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {3, 4, 5}));
    371  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(7, {3, 5}));
    372  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(8, {5, 6, 7}));
    373 }
    374 
    375 TEST_F(RtpVp8RefFinderTest, StashedFramesDoNotWrapTl0Backwards) {
    376  Insert(Frame().Pid(0).Tid(0).Tl0(0));
    377  EXPECT_THAT(frames_, SizeIs(0));
    378 
    379  Insert(Frame().Pid(128).Tid(0).Tl0(128).AsKeyFrame());
    380  EXPECT_THAT(frames_, SizeIs(1));
    381  Insert(Frame().Pid(129).Tid(0).Tl0(129));
    382  EXPECT_THAT(frames_, SizeIs(2));
    383 }
    384 
    385 }  // namespace webrtc