tor-browser

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

generic_decoder_unittest.cc (9156B)


      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 
     11 #include "modules/video_coding/generic_decoder.h"
     12 
     13 #include <cstdint>
     14 #include <optional>
     15 #include <utility>
     16 #include <vector>
     17 
     18 #include "api/array_view.h"
     19 #include "api/field_trials.h"
     20 #include "api/rtp_packet_infos.h"
     21 #include "api/scoped_refptr.h"
     22 #include "api/units/time_delta.h"
     23 #include "api/units/timestamp.h"
     24 #include "api/video/corruption_detection/frame_instrumentation_data.h"
     25 #include "api/video/encoded_frame.h"
     26 #include "api/video/i420_buffer.h"
     27 #include "api/video/video_codec_type.h"
     28 #include "api/video/video_content_type.h"
     29 #include "api/video/video_frame.h"
     30 #include "api/video/video_frame_type.h"
     31 #include "api/video/video_timing.h"
     32 #include "api/video_codecs/video_decoder.h"
     33 #include "common_video/include/corruption_score_calculator.h"
     34 #include "common_video/test/utilities.h"
     35 #include "modules/video_coding/include/video_coding_defines.h"
     36 #include "modules/video_coding/timing/timing.h"
     37 #include "system_wrappers/include/clock.h"
     38 #include "test/create_test_field_trials.h"
     39 #include "test/fake_decoder.h"
     40 #include "test/gmock.h"
     41 #include "test/gtest.h"
     42 #include "test/time_controller/simulated_time_controller.h"
     43 
     44 using ::testing::Eq;
     45 using ::testing::Field;
     46 using ::testing::Property;
     47 using ::testing::Return;
     48 
     49 namespace webrtc {
     50 namespace video_coding {
     51 
     52 class MockCorruptionScoreCalculator : public CorruptionScoreCalculator {
     53 public:
     54  MOCK_METHOD(void,
     55              CalculateCorruptionScore,
     56              (const VideoFrame& frame,
     57               const FrameInstrumentationData& frame_instrumentation_data,
     58               VideoContentType content_type),
     59              (override));
     60 };
     61 
     62 class ReceiveCallback : public VCMReceiveCallback {
     63 public:
     64  int32_t OnFrameToRender(const FrameToRender& arguments) override {
     65    frames_.push_back(arguments.video_frame);
     66    return 0;
     67  }
     68 
     69  std::optional<VideoFrame> PopLastFrame() {
     70    if (frames_.empty())
     71      return std::nullopt;
     72    auto ret = frames_.front();
     73    frames_.pop_back();
     74    return ret;
     75  }
     76 
     77  ArrayView<const VideoFrame> GetAllFrames() const { return frames_; }
     78 
     79  void OnDroppedFrames(uint32_t frames_dropped) override {
     80    frames_dropped_ += frames_dropped;
     81  }
     82 
     83  uint32_t frames_dropped() const { return frames_dropped_; }
     84 
     85 private:
     86  std::vector<VideoFrame> frames_;
     87  uint32_t frames_dropped_ = 0;
     88 };
     89 
     90 class GenericDecoderTest : public ::testing::Test {
     91 protected:
     92  GenericDecoderTest()
     93      : time_controller_(Timestamp::Zero()),
     94        clock_(time_controller_.GetClock()),
     95        field_trials_(CreateTestFieldTrials()),
     96        timing_(time_controller_.GetClock(), field_trials_),
     97        decoder_(time_controller_.GetTaskQueueFactory()),
     98        vcm_callback_(&timing_,
     99                      time_controller_.GetClock(),
    100                      field_trials_,
    101                      &corruption_score_calculator_),
    102        generic_decoder_(&decoder_) {}
    103 
    104  void SetUp() override {
    105    generic_decoder_.RegisterDecodeCompleteCallback(&vcm_callback_);
    106    vcm_callback_.SetUserReceiveCallback(&user_callback_);
    107    VideoDecoder::Settings settings;
    108    settings.set_codec_type(kVideoCodecVP8);
    109    settings.set_max_render_resolution({10, 10});
    110    settings.set_number_of_cores(4);
    111    generic_decoder_.Configure(settings);
    112  }
    113 
    114  GlobalSimulatedTimeController time_controller_;
    115  Clock* const clock_;
    116  FieldTrials field_trials_;
    117  VCMTiming timing_;
    118  test::FakeDecoder decoder_;
    119  VCMDecodedFrameCallback vcm_callback_;
    120  VCMGenericDecoder generic_decoder_;
    121  ReceiveCallback user_callback_;
    122  MockCorruptionScoreCalculator corruption_score_calculator_;
    123 };
    124 
    125 TEST_F(GenericDecoderTest, PassesPacketInfos) {
    126  RtpPacketInfos packet_infos = CreatePacketInfos(3);
    127  EncodedFrame encoded_frame;
    128  encoded_frame.SetPacketInfos(packet_infos);
    129  generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
    130  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    131  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
    132  ASSERT_TRUE(decoded_frame.has_value());
    133  EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
    134 }
    135 
    136 TEST_F(GenericDecoderTest, FrameDroppedIfTooManyFramesInFlight) {
    137  constexpr int kMaxFramesInFlight = 10;
    138  decoder_.SetDelayedDecoding(10);
    139  for (int i = 0; i < kMaxFramesInFlight + 1; ++i) {
    140    EncodedFrame encoded_frame;
    141    encoded_frame.SetRtpTimestamp(90000 * i);
    142    generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
    143  }
    144 
    145  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    146 
    147  auto frames = user_callback_.GetAllFrames();
    148  ASSERT_EQ(10U, frames.size());
    149  // Expect that the first frame was dropped since all decodes released at the
    150  // same time and the oldest frame info is the first one dropped.
    151  EXPECT_EQ(frames[0].rtp_timestamp(), 90000u);
    152  EXPECT_EQ(1u, user_callback_.frames_dropped());
    153 }
    154 
    155 TEST_F(GenericDecoderTest, PassesPacketInfosForDelayedDecoders) {
    156  RtpPacketInfos packet_infos = CreatePacketInfos(3);
    157  decoder_.SetDelayedDecoding(100);
    158 
    159  {
    160    // Ensure the original frame is destroyed before the decoding is completed.
    161    EncodedFrame encoded_frame;
    162    encoded_frame.SetPacketInfos(packet_infos);
    163    generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
    164  }
    165 
    166  time_controller_.AdvanceTime(TimeDelta::Millis(200));
    167  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
    168  ASSERT_TRUE(decoded_frame.has_value());
    169  EXPECT_EQ(decoded_frame->packet_infos().size(), 3U);
    170 }
    171 
    172 TEST_F(GenericDecoderTest, MaxCompositionDelayNotSetByDefault) {
    173  EncodedFrame encoded_frame;
    174  generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
    175  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    176  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
    177  ASSERT_TRUE(decoded_frame.has_value());
    178  EXPECT_THAT(
    179      decoded_frame->render_parameters().max_composition_delay_in_frames,
    180      testing::Eq(std::nullopt));
    181 }
    182 
    183 TEST_F(GenericDecoderTest, MaxCompositionDelayActivatedByPlayoutDelay) {
    184  EncodedFrame encoded_frame;
    185  // VideoReceiveStream2 would set MaxCompositionDelayInFrames if playout delay
    186  // is specified as X,Y, where X=0, Y>0.
    187  constexpr int kMaxCompositionDelayInFrames = 3;  // ~50 ms at 60 fps.
    188  timing_.SetMaxCompositionDelayInFrames(
    189      std::make_optional(kMaxCompositionDelayInFrames));
    190  generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
    191  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    192  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
    193  ASSERT_TRUE(decoded_frame.has_value());
    194  EXPECT_THAT(
    195      decoded_frame->render_parameters().max_composition_delay_in_frames,
    196      testing::Optional(kMaxCompositionDelayInFrames));
    197 }
    198 
    199 TEST_F(GenericDecoderTest, IsLowLatencyStreamFalseByDefault) {
    200  EncodedFrame encoded_frame;
    201  generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
    202  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    203  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
    204  ASSERT_TRUE(decoded_frame.has_value());
    205  EXPECT_FALSE(decoded_frame->render_parameters().use_low_latency_rendering);
    206 }
    207 
    208 TEST_F(GenericDecoderTest, IsLowLatencyStreamActivatedByPlayoutDelay) {
    209  EncodedFrame encoded_frame;
    210  const VideoPlayoutDelay kPlayoutDelay(TimeDelta::Zero(),
    211                                        TimeDelta::Millis(50));
    212  timing_.set_playout_delay(kPlayoutDelay);
    213  generic_decoder_.Decode(encoded_frame, clock_->CurrentTime());
    214  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    215  std::optional<VideoFrame> decoded_frame = user_callback_.PopLastFrame();
    216  ASSERT_TRUE(decoded_frame.has_value());
    217  EXPECT_TRUE(decoded_frame->render_parameters().use_low_latency_rendering);
    218 }
    219 
    220 TEST_F(GenericDecoderTest, CallCalculateCorruptionScoreInDecoded) {
    221  constexpr uint32_t kRtpTimestamp = 1;
    222  FrameInfo frame_info;
    223  frame_info.frame_instrumentation_data.emplace();
    224  frame_info.frame_instrumentation_data->SetSequenceIndex(1);
    225  frame_info.rtp_timestamp = kRtpTimestamp;
    226  frame_info.decode_start = Timestamp::Zero();
    227  frame_info.content_type = VideoContentType::SCREENSHARE;
    228  frame_info.frame_type = VideoFrameType::kVideoFrameDelta;
    229  VideoFrame video_frame = VideoFrame::Builder()
    230                               .set_video_frame_buffer(I420Buffer::Create(5, 5))
    231                               .set_rtp_timestamp(kRtpTimestamp)
    232                               .build();
    233  vcm_callback_.Map(std::move(frame_info));
    234 
    235  EXPECT_CALL(corruption_score_calculator_,
    236              CalculateCorruptionScore(
    237                  Property(&VideoFrame::rtp_timestamp, Eq(kRtpTimestamp)),
    238                  Property(&FrameInstrumentationData::sequence_index, Eq(1)),
    239                  VideoContentType::SCREENSHARE));
    240  vcm_callback_.Decoded(video_frame);
    241 }
    242 
    243 }  // namespace video_coding
    244 }  // namespace webrtc