202 lines · 7.4 KB · C++
RawDownload
/* *  Copyright (c) 2020 The WebM project authors. All Rights Reserved. * *  Use of this source code is governed by a BSD-style license *  that can be found in the LICENSE file in the root of the source *  tree. An additional intellectual property rights grant can be found *  in the file PATENTS.  All contributing project authors may *  be found in the AUTHORS file in the root of the source tree. */ #include <cstdint>#include <new> #include "test/codec_factory.h"#include "test/encode_test_driver.h"#include "test/util.h"#include "test/yuv_video_source.h"#include "third_party/googletest/src/include/gtest/gtest.h"#include "vpx/vpx_ext_ratectrl.h" namespace { constexpr int kModelMagicNumber = 51396;constexpr uintptr_t PrivMagicNumber = 5566;constexpr int kFrameNum = 5;constexpr int kLosslessCodingIndex = 2; struct ToyRateCtrl {  int magic_number;  int coding_index;}; vpx_rc_status_t rc_create_model(void *priv,                                const vpx_rc_config_t *ratectrl_config,                                vpx_rc_model_t *rate_ctrl_model_pt) {  ToyRateCtrl *toy_rate_ctrl = new (std::nothrow) ToyRateCtrl;  EXPECT_NE(toy_rate_ctrl, nullptr);  toy_rate_ctrl->magic_number = kModelMagicNumber;  toy_rate_ctrl->coding_index = -1;  *rate_ctrl_model_pt = toy_rate_ctrl;  EXPECT_EQ(priv, reinterpret_cast<void *>(PrivMagicNumber));  EXPECT_EQ(ratectrl_config->frame_width, 352);  EXPECT_EQ(ratectrl_config->frame_height, 288);  EXPECT_EQ(ratectrl_config->show_frame_count, kFrameNum);  EXPECT_EQ(ratectrl_config->target_bitrate_kbps, 24000);  EXPECT_EQ(ratectrl_config->frame_rate_num, 30);  EXPECT_EQ(ratectrl_config->frame_rate_den, 1);  return VPX_RC_OK;} vpx_rc_status_t rc_send_firstpass_stats(    vpx_rc_model_t rate_ctrl_model,    const vpx_rc_firstpass_stats_t *first_pass_stats) {  const ToyRateCtrl *toy_rate_ctrl =      static_cast<ToyRateCtrl *>(rate_ctrl_model);  EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);  EXPECT_EQ(first_pass_stats->num_frames, kFrameNum);  for (int i = 0; i < first_pass_stats->num_frames; ++i) {    EXPECT_DOUBLE_EQ(first_pass_stats->frame_stats[i].frame, i);  }  return VPX_RC_OK;} vpx_rc_status_t rc_get_encodeframe_decision(    vpx_rc_model_t rate_ctrl_model,    const vpx_rc_encodeframe_info_t *encode_frame_info,    vpx_rc_encodeframe_decision_t *frame_decision) {  ToyRateCtrl *toy_rate_ctrl = static_cast<ToyRateCtrl *>(rate_ctrl_model);  toy_rate_ctrl->coding_index += 1;   EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);   EXPECT_LT(encode_frame_info->show_index, kFrameNum);  EXPECT_EQ(encode_frame_info->coding_index, toy_rate_ctrl->coding_index);   if (encode_frame_info->coding_index == 0) {    EXPECT_EQ(encode_frame_info->show_index, 0);    EXPECT_EQ(encode_frame_info->gop_index, 0);    EXPECT_EQ(encode_frame_info->frame_type, 0 /*kFrameTypeKey*/);    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],              0);  // kRefFrameTypeLast    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],              0);  // kRefFrameTypePast    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],              0);  // kRefFrameTypeFuture  }   if (encode_frame_info->coding_index == 1) {    EXPECT_EQ(encode_frame_info->show_index, 4);    EXPECT_EQ(encode_frame_info->gop_index, 1);    EXPECT_EQ(encode_frame_info->frame_type, 2 /*kFrameTypeAltRef*/);    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],              1);  // kRefFrameTypeLast    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],              0);  // kRefFrameTypePast    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],              0);  // kRefFrameTypeFuture    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[0],              0);  // kRefFrameTypeLast  }   if (encode_frame_info->coding_index >= 2 &&      encode_frame_info->coding_index < 5) {    // In the first group of pictures, coding_index and gop_index are equal.    EXPECT_EQ(encode_frame_info->gop_index, encode_frame_info->coding_index);    EXPECT_EQ(encode_frame_info->frame_type, 1 /*kFrameTypeInter*/);  }   if (encode_frame_info->coding_index == 5) {    EXPECT_EQ(encode_frame_info->show_index, 4);    EXPECT_EQ(encode_frame_info->gop_index, 0);    EXPECT_EQ(encode_frame_info->frame_type, 3 /*kFrameTypeOverlay*/);    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0],              1);  // kRefFrameTypeLast    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1],              1);  // kRefFrameTypePast    EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2],              1);  // kRefFrameTypeFuture    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[0],              4);  // kRefFrameTypeLast    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[1],              0);  // kRefFrameTypePast    EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[2],              1);  // kRefFrameTypeFuture  }  if (encode_frame_info->coding_index == kLosslessCodingIndex) {    // We should get sse == 0 at rc_update_encodeframe_result()    frame_decision->q_index = 0;  } else {    frame_decision->q_index = 100;  }  frame_decision->max_frame_size = 0;  return VPX_RC_OK;} vpx_rc_status_t rc_update_encodeframe_result(    vpx_rc_model_t rate_ctrl_model,    const vpx_rc_encodeframe_result_t *encode_frame_result) {  const ToyRateCtrl *toy_rate_ctrl =      static_cast<ToyRateCtrl *>(rate_ctrl_model);  EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);   const int64_t ref_pixel_count = 352 * 288 * 3 / 2;  EXPECT_EQ(encode_frame_result->pixel_count, ref_pixel_count);  if (toy_rate_ctrl->coding_index == kLosslessCodingIndex) {    EXPECT_EQ(encode_frame_result->sse, 0);  }  if (toy_rate_ctrl->coding_index == kLosslessCodingIndex) {    EXPECT_EQ(encode_frame_result->actual_encoding_qindex, 0);  } else {    EXPECT_EQ(encode_frame_result->actual_encoding_qindex, 100);  }  return VPX_RC_OK;} vpx_rc_status_t rc_delete_model(vpx_rc_model_t rate_ctrl_model) {  ToyRateCtrl *toy_rate_ctrl = static_cast<ToyRateCtrl *>(rate_ctrl_model);  EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);  delete toy_rate_ctrl;  return VPX_RC_OK;} class ExtRateCtrlTest : public ::libvpx_test::EncoderTest,                        public ::testing::Test { protected:  ExtRateCtrlTest() : EncoderTest(&::libvpx_test::kVP9) {}   ~ExtRateCtrlTest() override = default;   void SetUp() override {    InitializeConfig();    SetMode(::libvpx_test::kTwoPassGood);  }   void PreEncodeFrameHook(::libvpx_test::VideoSource *video,                          ::libvpx_test::Encoder *encoder) override {    if (video->frame() == 0) {      vpx_rc_funcs_t rc_funcs;      rc_funcs.create_model = rc_create_model;      rc_funcs.send_firstpass_stats = rc_send_firstpass_stats;      rc_funcs.get_encodeframe_decision = rc_get_encodeframe_decision;      rc_funcs.update_encodeframe_result = rc_update_encodeframe_result;      rc_funcs.delete_model = rc_delete_model;      rc_funcs.priv = reinterpret_cast<void *>(PrivMagicNumber);      encoder->Control(VP9E_SET_EXTERNAL_RATE_CONTROL, &rc_funcs);    }  }}; TEST_F(ExtRateCtrlTest, EncodeTest) {  cfg_.rc_target_bitrate = 24000;   std::unique_ptr<libvpx_test::VideoSource> video;  video.reset(new (std::nothrow) libvpx_test::YUVVideoSource(      "bus_352x288_420_f20_b8.yuv", VPX_IMG_FMT_I420, 352, 288, 30, 1, 0,      kFrameNum));   ASSERT_NE(video.get(), nullptr);  ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));} }  // namespace

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t