tor-browser

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

video_codec_unittest.cc (7281B)


      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 "modules/video_coding/codecs/test/video_codec_unittest.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <optional>
     17 #include <utility>
     18 #include <vector>
     19 
     20 #include "api/environment/environment_factory.h"
     21 #include "api/test/create_frame_generator.h"
     22 #include "api/test/frame_generator_interface.h"
     23 #include "api/units/time_delta.h"
     24 #include "api/video/encoded_image.h"
     25 #include "api/video/video_codec_type.h"
     26 #include "api/video/video_frame.h"
     27 #include "api/video_codecs/video_codec.h"
     28 #include "api/video_codecs/video_decoder.h"
     29 #include "api/video_codecs/video_encoder.h"
     30 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     31 #include "modules/video_coding/include/video_error_codes.h"
     32 #include "rtc_base/checks.h"
     33 #include "rtc_base/synchronization/mutex.h"
     34 #include "test/gtest.h"
     35 #include "test/video_codec_settings.h"
     36 
     37 static constexpr webrtc::TimeDelta kEncodeTimeout =
     38    webrtc::TimeDelta::Millis(100);
     39 static constexpr webrtc::TimeDelta kDecodeTimeout =
     40    webrtc::TimeDelta::Millis(25);
     41 // Set bitrate to get higher quality.
     42 static const int kStartBitrate = 300;
     43 static const int kMaxBitrate = 4000;
     44 static const int kWidth = 176;        // Width of the input image.
     45 static const int kHeight = 144;       // Height of the input image.
     46 static const int kMaxFramerate = 30;  // Arbitrary value.
     47 
     48 namespace webrtc {
     49 namespace {
     50 const VideoEncoder::Capabilities kCapabilities(false);
     51 }  // namespace
     52 
     53 EncodedImageCallback::Result
     54 VideoCodecUnitTest::FakeEncodeCompleteCallback::OnEncodedImage(
     55    const EncodedImage& frame,
     56    const CodecSpecificInfo* codec_specific_info) {
     57  MutexLock lock(&test_->encoded_frame_section_);
     58  test_->encoded_frames_.push_back(frame);
     59  RTC_DCHECK(codec_specific_info);
     60  test_->codec_specific_infos_.push_back(*codec_specific_info);
     61  if (!test_->wait_for_encoded_frames_threshold_) {
     62    test_->encoded_frame_event_.Set();
     63    return Result(Result::OK);
     64  }
     65 
     66  if (test_->encoded_frames_.size() ==
     67      test_->wait_for_encoded_frames_threshold_) {
     68    test_->wait_for_encoded_frames_threshold_ = 1;
     69    test_->encoded_frame_event_.Set();
     70  }
     71  return Result(Result::OK);
     72 }
     73 
     74 void VideoCodecUnitTest::FakeDecodeCompleteCallback::Decoded(
     75    VideoFrame& frame,
     76    std::optional<int32_t> /* decode_time_ms */,
     77    std::optional<uint8_t> qp) {
     78  MutexLock lock(&test_->decoded_frame_section_);
     79  test_->decoded_frame_.emplace(frame);
     80  test_->decoded_qp_ = qp;
     81  test_->decoded_frame_event_.Set();
     82 }
     83 
     84 void VideoCodecUnitTest::SetUp() {
     85  EnvironmentFactory factory(env_);
     86  factory.Set(field_trials_.CreateCopy());
     87  env_ = factory.Create();
     88  test::CodecSettings(kVideoCodecVP8, &codec_settings_);
     89  codec_settings_.startBitrate = kStartBitrate;
     90  codec_settings_.maxBitrate = kMaxBitrate;
     91  codec_settings_.maxFramerate = kMaxFramerate;
     92  codec_settings_.width = kWidth;
     93  codec_settings_.height = kHeight;
     94 
     95  ModifyCodecSettings(&codec_settings_);
     96 
     97  input_frame_generator_ = test::CreateSquareFrameGenerator(
     98      codec_settings_.width, codec_settings_.height,
     99      test::FrameGeneratorInterface::OutputType::kI420, std::optional<int>());
    100 
    101  encoder_ = CreateEncoder();
    102  decoder_ = CreateDecoder();
    103  encoder_->RegisterEncodeCompleteCallback(&encode_complete_callback_);
    104  decoder_->RegisterDecodeCompleteCallback(&decode_complete_callback_);
    105 
    106  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
    107            encoder_->InitEncode(
    108                &codec_settings_,
    109                VideoEncoder::Settings(kCapabilities, 1 /* number of cores */,
    110                                       0 /* max payload size (unused) */)));
    111 
    112  VideoDecoder::Settings decoder_settings;
    113  decoder_settings.set_codec_type(codec_settings_.codecType);
    114  decoder_settings.set_max_render_resolution(
    115      {codec_settings_.width, codec_settings_.height});
    116  EXPECT_TRUE(decoder_->Configure(decoder_settings));
    117 }
    118 
    119 void VideoCodecUnitTest::ModifyCodecSettings(VideoCodec* /* codec_settings */) {
    120 }
    121 
    122 VideoFrame VideoCodecUnitTest::NextInputFrame() {
    123  test::FrameGeneratorInterface::VideoFrameData frame_data =
    124      input_frame_generator_->NextFrame();
    125  VideoFrame input_frame = VideoFrame::Builder()
    126                               .set_video_frame_buffer(frame_data.buffer)
    127                               .set_update_rect(frame_data.update_rect)
    128                               .build();
    129 
    130  const uint32_t timestamp =
    131      last_input_frame_timestamp_ +
    132      kVideoPayloadTypeFrequency / codec_settings_.maxFramerate;
    133  input_frame.set_rtp_timestamp(timestamp);
    134  input_frame.set_timestamp_us(timestamp * (1000 / 90));
    135 
    136  last_input_frame_timestamp_ = timestamp;
    137  return input_frame;
    138 }
    139 
    140 bool VideoCodecUnitTest::WaitForEncodedFrame(
    141    EncodedImage* frame,
    142    CodecSpecificInfo* codec_specific_info) {
    143  std::vector<EncodedImage> frames;
    144  std::vector<CodecSpecificInfo> codec_specific_infos;
    145  if (!WaitForEncodedFrames(&frames, &codec_specific_infos))
    146    return false;
    147  EXPECT_EQ(frames.size(), static_cast<size_t>(1));
    148  EXPECT_EQ(frames.size(), codec_specific_infos.size());
    149  *frame = frames[0];
    150  *codec_specific_info = codec_specific_infos[0];
    151  return true;
    152 }
    153 
    154 void VideoCodecUnitTest::SetWaitForEncodedFramesThreshold(size_t num_frames) {
    155  MutexLock lock(&encoded_frame_section_);
    156  wait_for_encoded_frames_threshold_ = num_frames;
    157 }
    158 
    159 bool VideoCodecUnitTest::WaitForEncodedFrames(
    160    std::vector<EncodedImage>* frames,
    161    std::vector<CodecSpecificInfo>* codec_specific_info) {
    162  EXPECT_TRUE(encoded_frame_event_.Wait(kEncodeTimeout))
    163      << "Timed out while waiting for encoded frame.";
    164  // This becomes unsafe if there are multiple threads waiting for frames.
    165  MutexLock lock(&encoded_frame_section_);
    166  EXPECT_FALSE(encoded_frames_.empty());
    167  EXPECT_FALSE(codec_specific_infos_.empty());
    168  EXPECT_EQ(encoded_frames_.size(), codec_specific_infos_.size());
    169  if (!encoded_frames_.empty()) {
    170    *frames = encoded_frames_;
    171    encoded_frames_.clear();
    172    RTC_DCHECK(!codec_specific_infos_.empty());
    173    *codec_specific_info = codec_specific_infos_;
    174    codec_specific_infos_.clear();
    175    return true;
    176  } else {
    177    return false;
    178  }
    179 }
    180 
    181 bool VideoCodecUnitTest::WaitForDecodedFrame(std::unique_ptr<VideoFrame>* frame,
    182                                             std::optional<uint8_t>* qp) {
    183  bool ret = decoded_frame_event_.Wait(kDecodeTimeout);
    184  EXPECT_TRUE(ret) << "Timed out while waiting for a decoded frame.";
    185  // This becomes unsafe if there are multiple threads waiting for frames.
    186  MutexLock lock(&decoded_frame_section_);
    187  EXPECT_TRUE(decoded_frame_);
    188  if (decoded_frame_) {
    189    frame->reset(new VideoFrame(std::move(*decoded_frame_)));
    190    *qp = decoded_qp_;
    191    decoded_frame_.reset();
    192    return true;
    193  } else {
    194    return false;
    195  }
    196 }
    197 
    198 size_t VideoCodecUnitTest::GetNumEncodedFrames() {
    199  MutexLock lock(&encoded_frame_section_);
    200  return encoded_frames_.size();
    201 }
    202 
    203 }  // namespace webrtc