xref: /aosp_15_r20/external/libvpx/test/vp9_ext_ratectrl_test.cc (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker  *  Copyright (c) 2020 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker  *
4*fb1b10abSAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker  */
10*fb1b10abSAndroid Build Coastguard Worker 
11*fb1b10abSAndroid Build Coastguard Worker #include <cstdint>
12*fb1b10abSAndroid Build Coastguard Worker #include <new>
13*fb1b10abSAndroid Build Coastguard Worker #include <memory>
14*fb1b10abSAndroid Build Coastguard Worker 
15*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h"
16*fb1b10abSAndroid Build Coastguard Worker 
17*fb1b10abSAndroid Build Coastguard Worker #include "gtest/gtest.h"
18*fb1b10abSAndroid Build Coastguard Worker #include "test/codec_factory.h"
19*fb1b10abSAndroid Build Coastguard Worker #include "test/encode_test_driver.h"
20*fb1b10abSAndroid Build Coastguard Worker #include "test/util.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "test/yuv_video_source.h"
22*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_DECODER
23*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vp8dx.h"
24*fb1b10abSAndroid Build Coastguard Worker #endif
25*fb1b10abSAndroid Build Coastguard Worker #include "vp9/simple_encode.h"
26*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_codec.h"
27*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_encoder.h"
28*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_ext_ratectrl.h"
29*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_image.h"
30*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_tpl.h"
31*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/vpx_dsp_common.h"
32*fb1b10abSAndroid Build Coastguard Worker 
33*fb1b10abSAndroid Build Coastguard Worker namespace {
34*fb1b10abSAndroid Build Coastguard Worker 
35*fb1b10abSAndroid Build Coastguard Worker constexpr int kShowFrameCount = 10;
36*fb1b10abSAndroid Build Coastguard Worker constexpr int kKeyframeQp = 10;
37*fb1b10abSAndroid Build Coastguard Worker constexpr int kLeafQp = 40;
38*fb1b10abSAndroid Build Coastguard Worker constexpr int kArfQp = 15;
39*fb1b10abSAndroid Build Coastguard Worker 
40*fb1b10abSAndroid Build Coastguard Worker // Simple external rate controller for testing.
41*fb1b10abSAndroid Build Coastguard Worker class RateControllerForTest {
42*fb1b10abSAndroid Build Coastguard Worker  public:
RateControllerForTest()43*fb1b10abSAndroid Build Coastguard Worker   RateControllerForTest() : current_gop_(-1) {}
~RateControllerForTest()44*fb1b10abSAndroid Build Coastguard Worker   ~RateControllerForTest() {}
45*fb1b10abSAndroid Build Coastguard Worker 
StartNextGop()46*fb1b10abSAndroid Build Coastguard Worker   void StartNextGop() { ++current_gop_; }
47*fb1b10abSAndroid Build Coastguard Worker 
GetCurrentGop() const48*fb1b10abSAndroid Build Coastguard Worker   vpx_rc_gop_decision_t GetCurrentGop() const {
49*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_gop_decision_t gop_decision;
50*fb1b10abSAndroid Build Coastguard Worker     if (current_gop_ == 0) {
51*fb1b10abSAndroid Build Coastguard Worker       gop_decision.use_key_frame = 1;
52*fb1b10abSAndroid Build Coastguard Worker       gop_decision.use_alt_ref = 1;
53*fb1b10abSAndroid Build Coastguard Worker       gop_decision.gop_coding_frames =
54*fb1b10abSAndroid Build Coastguard Worker           kShowFrameCount - 1 + gop_decision.use_alt_ref;
55*fb1b10abSAndroid Build Coastguard Worker       // key frame
56*fb1b10abSAndroid Build Coastguard Worker       gop_decision.update_type[0] = VPX_RC_KF_UPDATE;
57*fb1b10abSAndroid Build Coastguard Worker       gop_decision.update_ref_index[0] = 0;
58*fb1b10abSAndroid Build Coastguard Worker       gop_decision.ref_frame_list[0] = get_kf_ref_frame();
59*fb1b10abSAndroid Build Coastguard Worker       // arf
60*fb1b10abSAndroid Build Coastguard Worker       gop_decision.update_type[1] = VPX_RC_ARF_UPDATE;
61*fb1b10abSAndroid Build Coastguard Worker       gop_decision.update_ref_index[1] = 1;
62*fb1b10abSAndroid Build Coastguard Worker       gop_decision.ref_frame_list[1] = get_arf_ref_frame();
63*fb1b10abSAndroid Build Coastguard Worker       // leafs
64*fb1b10abSAndroid Build Coastguard Worker       for (int i = 2; i < gop_decision.gop_coding_frames; ++i) {
65*fb1b10abSAndroid Build Coastguard Worker         gop_decision.update_type[i] = VPX_RC_LF_UPDATE;
66*fb1b10abSAndroid Build Coastguard Worker         gop_decision.update_ref_index[i] = 2;
67*fb1b10abSAndroid Build Coastguard Worker         gop_decision.ref_frame_list[i] = get_leaf_ref_frame(i);
68*fb1b10abSAndroid Build Coastguard Worker       }
69*fb1b10abSAndroid Build Coastguard Worker     } else {
70*fb1b10abSAndroid Build Coastguard Worker       // Pad a overlay-only GOP as the last GOP.
71*fb1b10abSAndroid Build Coastguard Worker       EXPECT_EQ(current_gop_, 1);
72*fb1b10abSAndroid Build Coastguard Worker       gop_decision.use_key_frame = 0;
73*fb1b10abSAndroid Build Coastguard Worker       gop_decision.use_alt_ref = 0;
74*fb1b10abSAndroid Build Coastguard Worker       gop_decision.gop_coding_frames = 1;
75*fb1b10abSAndroid Build Coastguard Worker 
76*fb1b10abSAndroid Build Coastguard Worker       gop_decision.update_type[0] = VPX_RC_OVERLAY_UPDATE;
77*fb1b10abSAndroid Build Coastguard Worker       gop_decision.update_ref_index[0] = 1;
78*fb1b10abSAndroid Build Coastguard Worker       gop_decision.ref_frame_list[0] = get_ovl_ref_frame();
79*fb1b10abSAndroid Build Coastguard Worker     }
80*fb1b10abSAndroid Build Coastguard Worker     return gop_decision;
81*fb1b10abSAndroid Build Coastguard Worker   }
82*fb1b10abSAndroid Build Coastguard Worker 
CalculateFrameDecision(int frame_index)83*fb1b10abSAndroid Build Coastguard Worker   int CalculateFrameDecision(int frame_index) {
84*fb1b10abSAndroid Build Coastguard Worker     if (current_gop_ == 0 && frame_index == 0) {
85*fb1b10abSAndroid Build Coastguard Worker       // Key frame, first frame in the first GOP.
86*fb1b10abSAndroid Build Coastguard Worker       return kKeyframeQp;
87*fb1b10abSAndroid Build Coastguard Worker     } else if (frame_index == 1) {
88*fb1b10abSAndroid Build Coastguard Worker       // ARF, we always use ARF for this test.
89*fb1b10abSAndroid Build Coastguard Worker       return kArfQp;
90*fb1b10abSAndroid Build Coastguard Worker     } else {
91*fb1b10abSAndroid Build Coastguard Worker       return kLeafQp;
92*fb1b10abSAndroid Build Coastguard Worker     }
93*fb1b10abSAndroid Build Coastguard Worker   }
94*fb1b10abSAndroid Build Coastguard Worker 
95*fb1b10abSAndroid Build Coastguard Worker  private:
get_kf_ref_frame() const96*fb1b10abSAndroid Build Coastguard Worker   vpx_rc_ref_frame_t get_kf_ref_frame() const {
97*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_ref_frame_t ref_frame;
98*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[0] = -1;
99*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[1] = -1;
100*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[2] = -1;
101*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[0] = VPX_RC_INVALID_REF_FRAME;
102*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[1] = VPX_RC_INVALID_REF_FRAME;
103*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[2] = VPX_RC_INVALID_REF_FRAME;
104*fb1b10abSAndroid Build Coastguard Worker     return ref_frame;
105*fb1b10abSAndroid Build Coastguard Worker   }
get_arf_ref_frame() const106*fb1b10abSAndroid Build Coastguard Worker   vpx_rc_ref_frame_t get_arf_ref_frame() const {
107*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_ref_frame_t ref_frame;
108*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[0] = 0;
109*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[1] = -1;
110*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[2] = -1;
111*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[0] = VPX_RC_GOLDEN_FRAME;
112*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[1] = VPX_RC_INVALID_REF_FRAME;
113*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[2] = VPX_RC_INVALID_REF_FRAME;
114*fb1b10abSAndroid Build Coastguard Worker     return ref_frame;
115*fb1b10abSAndroid Build Coastguard Worker   }
get_leaf_ref_frame(int count) const116*fb1b10abSAndroid Build Coastguard Worker   vpx_rc_ref_frame_t get_leaf_ref_frame(int count) const {
117*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_ref_frame_t ref_frame;
118*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[0] = 0;
119*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[1] = 1;
120*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[2] = count > 2 ? 2 : -1;
121*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[0] = VPX_RC_GOLDEN_FRAME;
122*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[1] = VPX_RC_ALTREF_FRAME;
123*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[2] =
124*fb1b10abSAndroid Build Coastguard Worker         count > 2 ? VPX_RC_LAST_FRAME : VPX_RC_INVALID_REF_FRAME;
125*fb1b10abSAndroid Build Coastguard Worker     return ref_frame;
126*fb1b10abSAndroid Build Coastguard Worker   }
get_ovl_ref_frame() const127*fb1b10abSAndroid Build Coastguard Worker   vpx_rc_ref_frame_t get_ovl_ref_frame() const {
128*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_ref_frame_t ref_frame;
129*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[0] = 1;
130*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[1] = -1;
131*fb1b10abSAndroid Build Coastguard Worker     ref_frame.index[2] = -1;
132*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[0] = VPX_RC_ALTREF_FRAME;
133*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[1] = VPX_RC_INVALID_REF_FRAME;
134*fb1b10abSAndroid Build Coastguard Worker     ref_frame.name[2] = VPX_RC_INVALID_REF_FRAME;
135*fb1b10abSAndroid Build Coastguard Worker     return ref_frame;
136*fb1b10abSAndroid Build Coastguard Worker   }
137*fb1b10abSAndroid Build Coastguard Worker 
138*fb1b10abSAndroid Build Coastguard Worker   int current_gop_;
139*fb1b10abSAndroid Build Coastguard Worker };
140*fb1b10abSAndroid Build Coastguard Worker 
141*fb1b10abSAndroid Build Coastguard Worker // Callbacks used in this test.
rc_test_create_model(void *,const vpx_rc_config_t *,vpx_rc_model_t * rate_ctrl_model_ptr)142*fb1b10abSAndroid Build Coastguard Worker vpx_rc_status_t rc_test_create_model(
143*fb1b10abSAndroid Build Coastguard Worker     void * /*priv*/, const vpx_rc_config_t * /*ratectrl_config*/,
144*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_model_t *rate_ctrl_model_ptr) {
145*fb1b10abSAndroid Build Coastguard Worker   std::unique_ptr<RateControllerForTest> test_controller(
146*fb1b10abSAndroid Build Coastguard Worker       new RateControllerForTest());
147*fb1b10abSAndroid Build Coastguard Worker   *rate_ctrl_model_ptr = test_controller.release();
148*fb1b10abSAndroid Build Coastguard Worker   return VPX_RC_OK;
149*fb1b10abSAndroid Build Coastguard Worker }
150*fb1b10abSAndroid Build Coastguard Worker 
rc_test_send_firstpass_stats(vpx_rc_model_t,const vpx_rc_firstpass_stats_t * first_pass_stats)151*fb1b10abSAndroid Build Coastguard Worker vpx_rc_status_t rc_test_send_firstpass_stats(
152*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_model_t /*rate_ctrl_model*/,
153*fb1b10abSAndroid Build Coastguard Worker     const vpx_rc_firstpass_stats_t *first_pass_stats) {
154*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(first_pass_stats->num_frames, kShowFrameCount);
155*fb1b10abSAndroid Build Coastguard Worker   for (int i = 0; i < first_pass_stats->num_frames; ++i) {
156*fb1b10abSAndroid Build Coastguard Worker     EXPECT_DOUBLE_EQ(first_pass_stats->frame_stats[i].frame, i);
157*fb1b10abSAndroid Build Coastguard Worker   }
158*fb1b10abSAndroid Build Coastguard Worker   return VPX_RC_OK;
159*fb1b10abSAndroid Build Coastguard Worker }
160*fb1b10abSAndroid Build Coastguard Worker 
rc_test_send_tpl_gop_stats(vpx_rc_model_t,const VpxTplGopStats * tpl_gop_stats)161*fb1b10abSAndroid Build Coastguard Worker vpx_rc_status_t rc_test_send_tpl_gop_stats(
162*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_model_t /*rate_ctrl_model*/, const VpxTplGopStats *tpl_gop_stats) {
163*fb1b10abSAndroid Build Coastguard Worker   EXPECT_GT(tpl_gop_stats->size, 0);
164*fb1b10abSAndroid Build Coastguard Worker 
165*fb1b10abSAndroid Build Coastguard Worker   for (int i = 0; i < tpl_gop_stats->size; ++i) {
166*fb1b10abSAndroid Build Coastguard Worker     EXPECT_GT(tpl_gop_stats->frame_stats_list[i].num_blocks, 0);
167*fb1b10abSAndroid Build Coastguard Worker   }
168*fb1b10abSAndroid Build Coastguard Worker   return VPX_RC_OK;
169*fb1b10abSAndroid Build Coastguard Worker }
170*fb1b10abSAndroid Build Coastguard Worker 
rc_test_get_encodeframe_decision(vpx_rc_model_t rate_ctrl_model,const int frame_gop_index,vpx_rc_encodeframe_decision_t * frame_decision)171*fb1b10abSAndroid Build Coastguard Worker vpx_rc_status_t rc_test_get_encodeframe_decision(
172*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_model_t rate_ctrl_model, const int frame_gop_index,
173*fb1b10abSAndroid Build Coastguard Worker     vpx_rc_encodeframe_decision_t *frame_decision) {
174*fb1b10abSAndroid Build Coastguard Worker   RateControllerForTest *test_controller =
175*fb1b10abSAndroid Build Coastguard Worker       static_cast<RateControllerForTest *>(rate_ctrl_model);
176*fb1b10abSAndroid Build Coastguard Worker   frame_decision->q_index =
177*fb1b10abSAndroid Build Coastguard Worker       test_controller->CalculateFrameDecision(frame_gop_index);
178*fb1b10abSAndroid Build Coastguard Worker   return VPX_RC_OK;
179*fb1b10abSAndroid Build Coastguard Worker }
180*fb1b10abSAndroid Build Coastguard Worker 
rc_test_get_gop_decision(vpx_rc_model_t rate_ctrl_model,vpx_rc_gop_decision_t * gop_decision)181*fb1b10abSAndroid Build Coastguard Worker vpx_rc_status_t rc_test_get_gop_decision(vpx_rc_model_t rate_ctrl_model,
182*fb1b10abSAndroid Build Coastguard Worker                                          vpx_rc_gop_decision_t *gop_decision) {
183*fb1b10abSAndroid Build Coastguard Worker   RateControllerForTest *test_controller =
184*fb1b10abSAndroid Build Coastguard Worker       static_cast<RateControllerForTest *>(rate_ctrl_model);
185*fb1b10abSAndroid Build Coastguard Worker   test_controller->StartNextGop();
186*fb1b10abSAndroid Build Coastguard Worker   *gop_decision = test_controller->GetCurrentGop();
187*fb1b10abSAndroid Build Coastguard Worker   return VPX_RC_OK;
188*fb1b10abSAndroid Build Coastguard Worker }
189*fb1b10abSAndroid Build Coastguard Worker 
rc_delete_model(vpx_rc_model_t rate_ctrl_model)190*fb1b10abSAndroid Build Coastguard Worker vpx_rc_status_t rc_delete_model(vpx_rc_model_t rate_ctrl_model) {
191*fb1b10abSAndroid Build Coastguard Worker   RateControllerForTest *test_controller =
192*fb1b10abSAndroid Build Coastguard Worker       static_cast<RateControllerForTest *>(rate_ctrl_model);
193*fb1b10abSAndroid Build Coastguard Worker   delete test_controller;
194*fb1b10abSAndroid Build Coastguard Worker   return VPX_RC_OK;
195*fb1b10abSAndroid Build Coastguard Worker }
196*fb1b10abSAndroid Build Coastguard Worker 
197*fb1b10abSAndroid Build Coastguard Worker class ExtRateCtrlTest : public ::libvpx_test::EncoderTest,
198*fb1b10abSAndroid Build Coastguard Worker                         public ::testing::Test {
199*fb1b10abSAndroid Build Coastguard Worker  protected:
ExtRateCtrlTest()200*fb1b10abSAndroid Build Coastguard Worker   ExtRateCtrlTest()
201*fb1b10abSAndroid Build Coastguard Worker       : EncoderTest(&::libvpx_test::kVP9), received_show_frame_count_(0),
202*fb1b10abSAndroid Build Coastguard Worker         current_frame_qp_(0) {}
203*fb1b10abSAndroid Build Coastguard Worker 
204*fb1b10abSAndroid Build Coastguard Worker   ~ExtRateCtrlTest() override = default;
205*fb1b10abSAndroid Build Coastguard Worker 
SetUp()206*fb1b10abSAndroid Build Coastguard Worker   void SetUp() override {
207*fb1b10abSAndroid Build Coastguard Worker     InitializeConfig();
208*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY
209*fb1b10abSAndroid Build Coastguard Worker     SetMode(::libvpx_test::kRealTime);
210*fb1b10abSAndroid Build Coastguard Worker #else
211*fb1b10abSAndroid Build Coastguard Worker     SetMode(::libvpx_test::kTwoPassGood);
212*fb1b10abSAndroid Build Coastguard Worker #endif
213*fb1b10abSAndroid Build Coastguard Worker   }
214*fb1b10abSAndroid Build Coastguard Worker 
PreEncodeFrameHook(::libvpx_test::VideoSource * video,::libvpx_test::Encoder * encoder)215*fb1b10abSAndroid Build Coastguard Worker   void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
216*fb1b10abSAndroid Build Coastguard Worker                           ::libvpx_test::Encoder *encoder) override {
217*fb1b10abSAndroid Build Coastguard Worker     if (video->frame() == 0) {
218*fb1b10abSAndroid Build Coastguard Worker       vpx_rc_funcs_t rc_funcs = {};
219*fb1b10abSAndroid Build Coastguard Worker       rc_funcs.rc_type = VPX_RC_GOP_QP;
220*fb1b10abSAndroid Build Coastguard Worker       rc_funcs.create_model = rc_test_create_model;
221*fb1b10abSAndroid Build Coastguard Worker       rc_funcs.send_firstpass_stats = rc_test_send_firstpass_stats;
222*fb1b10abSAndroid Build Coastguard Worker       rc_funcs.send_tpl_gop_stats = rc_test_send_tpl_gop_stats;
223*fb1b10abSAndroid Build Coastguard Worker       rc_funcs.get_gop_decision = rc_test_get_gop_decision;
224*fb1b10abSAndroid Build Coastguard Worker       rc_funcs.get_encodeframe_decision = rc_test_get_encodeframe_decision;
225*fb1b10abSAndroid Build Coastguard Worker       rc_funcs.delete_model = rc_delete_model;
226*fb1b10abSAndroid Build Coastguard Worker       encoder->Control(VP9E_SET_EXTERNAL_RATE_CONTROL, &rc_funcs);
227*fb1b10abSAndroid Build Coastguard Worker     }
228*fb1b10abSAndroid Build Coastguard Worker   }
229*fb1b10abSAndroid Build Coastguard Worker 
230*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_DECODER
HandleDecodeResult(const vpx_codec_err_t res_dec,const::libvpx_test::VideoSource &,::libvpx_test::Decoder * decoder)231*fb1b10abSAndroid Build Coastguard Worker   bool HandleDecodeResult(const vpx_codec_err_t res_dec,
232*fb1b10abSAndroid Build Coastguard Worker                           const ::libvpx_test::VideoSource & /*video*/,
233*fb1b10abSAndroid Build Coastguard Worker                           ::libvpx_test::Decoder *decoder) override {
234*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
235*fb1b10abSAndroid Build Coastguard Worker     decoder->Control(VPXD_GET_LAST_QUANTIZER, &current_frame_qp_);
236*fb1b10abSAndroid Build Coastguard Worker     return VPX_CODEC_OK == res_dec;
237*fb1b10abSAndroid Build Coastguard Worker   }
238*fb1b10abSAndroid Build Coastguard Worker 
FramePktHook(const vpx_codec_cx_pkt_t * pkt)239*fb1b10abSAndroid Build Coastguard Worker   void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override {
240*fb1b10abSAndroid Build Coastguard Worker     // We are not comparing current_frame_qp_ here because the encoder will
241*fb1b10abSAndroid Build Coastguard Worker     // pack ARF and the next show frame into one pkt. Therefore, we might
242*fb1b10abSAndroid Build Coastguard Worker     // receive two frames in one pkt. However, one thing we are sure is that
243*fb1b10abSAndroid Build Coastguard Worker     // each pkt will have just one show frame. Therefore, we can check if the
244*fb1b10abSAndroid Build Coastguard Worker     // received show frame count match the actual show frame count.
245*fb1b10abSAndroid Build Coastguard Worker     if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
246*fb1b10abSAndroid Build Coastguard Worker       ++received_show_frame_count_;
247*fb1b10abSAndroid Build Coastguard Worker     }
248*fb1b10abSAndroid Build Coastguard Worker   }
249*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_DECODER
250*fb1b10abSAndroid Build Coastguard Worker 
251*fb1b10abSAndroid Build Coastguard Worker   int received_show_frame_count_;
252*fb1b10abSAndroid Build Coastguard Worker   int current_frame_qp_;
253*fb1b10abSAndroid Build Coastguard Worker };
254*fb1b10abSAndroid Build Coastguard Worker 
TEST_F(ExtRateCtrlTest,EncodeTest)255*fb1b10abSAndroid Build Coastguard Worker TEST_F(ExtRateCtrlTest, EncodeTest) {
256*fb1b10abSAndroid Build Coastguard Worker   cfg_.rc_target_bitrate = 4000;
257*fb1b10abSAndroid Build Coastguard Worker   cfg_.g_lag_in_frames = 25;
258*fb1b10abSAndroid Build Coastguard Worker 
259*fb1b10abSAndroid Build Coastguard Worker   std::unique_ptr<libvpx_test::VideoSource> video;
260*fb1b10abSAndroid Build Coastguard Worker   video.reset(new (std::nothrow) libvpx_test::YUVVideoSource(
261*fb1b10abSAndroid Build Coastguard Worker       "bus_352x288_420_f20_b8.yuv", VPX_IMG_FMT_I420, 352, 288, 30, 1, 0,
262*fb1b10abSAndroid Build Coastguard Worker       kShowFrameCount));
263*fb1b10abSAndroid Build Coastguard Worker 
264*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(video, nullptr);
265*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
266*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(received_show_frame_count_, kShowFrameCount);
267*fb1b10abSAndroid Build Coastguard Worker }
268*fb1b10abSAndroid Build Coastguard Worker 
269*fb1b10abSAndroid Build Coastguard Worker }  // namespace
270