xref: /aosp_15_r20/external/libvpx/test/encode_api_test.cc (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker  *  Copyright (c) 2016 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 <cassert>
12*fb1b10abSAndroid Build Coastguard Worker #include <climits>
13*fb1b10abSAndroid Build Coastguard Worker #include <cstdint>
14*fb1b10abSAndroid Build Coastguard Worker #include <cstdio>
15*fb1b10abSAndroid Build Coastguard Worker #include <cstdlib>
16*fb1b10abSAndroid Build Coastguard Worker #include <cstring>
17*fb1b10abSAndroid Build Coastguard Worker #include <initializer_list>
18*fb1b10abSAndroid Build Coastguard Worker #include <vector>
19*fb1b10abSAndroid Build Coastguard Worker 
20*fb1b10abSAndroid Build Coastguard Worker #include "gtest/gtest.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "test/acm_random.h"
22*fb1b10abSAndroid Build Coastguard Worker #include "test/video_source.h"
23*fb1b10abSAndroid Build Coastguard Worker #include "test/y4m_video_source.h"
24*fb1b10abSAndroid Build Coastguard Worker 
25*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h"
26*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vp8cx.h"
27*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_codec.h"
28*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_encoder.h"
29*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_image.h"
30*fb1b10abSAndroid Build Coastguard Worker 
31*fb1b10abSAndroid Build Coastguard Worker namespace {
32*fb1b10abSAndroid Build Coastguard Worker 
33*fb1b10abSAndroid Build Coastguard Worker vpx_codec_iface_t *kCodecIfaces[] = {
34*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP8_ENCODER
35*fb1b10abSAndroid Build Coastguard Worker   &vpx_codec_vp8_cx_algo,
36*fb1b10abSAndroid Build Coastguard Worker #endif
37*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_ENCODER
38*fb1b10abSAndroid Build Coastguard Worker   &vpx_codec_vp9_cx_algo,
39*fb1b10abSAndroid Build Coastguard Worker #endif
40*fb1b10abSAndroid Build Coastguard Worker };
41*fb1b10abSAndroid Build Coastguard Worker 
IsVP9(vpx_codec_iface_t * iface)42*fb1b10abSAndroid Build Coastguard Worker bool IsVP9(vpx_codec_iface_t *iface) {
43*fb1b10abSAndroid Build Coastguard Worker   static const char kVP9Name[] = "WebM Project VP9";
44*fb1b10abSAndroid Build Coastguard Worker   return strncmp(kVP9Name, vpx_codec_iface_name(iface), sizeof(kVP9Name) - 1) ==
45*fb1b10abSAndroid Build Coastguard Worker          0;
46*fb1b10abSAndroid Build Coastguard Worker }
47*fb1b10abSAndroid Build Coastguard Worker 
Memset16(void * dest,int val,size_t length)48*fb1b10abSAndroid Build Coastguard Worker void *Memset16(void *dest, int val, size_t length) {
49*fb1b10abSAndroid Build Coastguard Worker   uint16_t *dest16 = reinterpret_cast<uint16_t *>(dest);
50*fb1b10abSAndroid Build Coastguard Worker   for (size_t i = 0; i < length; i++) {
51*fb1b10abSAndroid Build Coastguard Worker     *dest16++ = val;
52*fb1b10abSAndroid Build Coastguard Worker   }
53*fb1b10abSAndroid Build Coastguard Worker   return dest;
54*fb1b10abSAndroid Build Coastguard Worker }
55*fb1b10abSAndroid Build Coastguard Worker 
CreateImage(vpx_bit_depth_t bit_depth,vpx_img_fmt_t fmt,unsigned int width,unsigned int height)56*fb1b10abSAndroid Build Coastguard Worker vpx_image_t *CreateImage(vpx_bit_depth_t bit_depth, vpx_img_fmt_t fmt,
57*fb1b10abSAndroid Build Coastguard Worker                          unsigned int width, unsigned int height) {
58*fb1b10abSAndroid Build Coastguard Worker   assert(fmt != VPX_IMG_FMT_NV12);
59*fb1b10abSAndroid Build Coastguard Worker   if (bit_depth > VPX_BITS_8) {
60*fb1b10abSAndroid Build Coastguard Worker     fmt = static_cast<vpx_img_fmt_t>(fmt | VPX_IMG_FMT_HIGHBITDEPTH);
61*fb1b10abSAndroid Build Coastguard Worker   }
62*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *image = vpx_img_alloc(nullptr, fmt, width, height, 1);
63*fb1b10abSAndroid Build Coastguard Worker   if (!image) return image;
64*fb1b10abSAndroid Build Coastguard Worker 
65*fb1b10abSAndroid Build Coastguard Worker   const int val = 1 << (bit_depth - 1);
66*fb1b10abSAndroid Build Coastguard Worker   const unsigned int uv_h =
67*fb1b10abSAndroid Build Coastguard Worker       (image->d_h + image->y_chroma_shift) >> image->y_chroma_shift;
68*fb1b10abSAndroid Build Coastguard Worker   const unsigned int uv_w =
69*fb1b10abSAndroid Build Coastguard Worker       (image->d_w + image->x_chroma_shift) >> image->x_chroma_shift;
70*fb1b10abSAndroid Build Coastguard Worker   if (bit_depth > VPX_BITS_8) {
71*fb1b10abSAndroid Build Coastguard Worker     for (unsigned int i = 0; i < image->d_h; ++i) {
72*fb1b10abSAndroid Build Coastguard Worker       Memset16(image->planes[0] + i * image->stride[0], val, image->d_w);
73*fb1b10abSAndroid Build Coastguard Worker     }
74*fb1b10abSAndroid Build Coastguard Worker     for (unsigned int i = 0; i < uv_h; ++i) {
75*fb1b10abSAndroid Build Coastguard Worker       Memset16(image->planes[1] + i * image->stride[1], val, uv_w);
76*fb1b10abSAndroid Build Coastguard Worker       Memset16(image->planes[2] + i * image->stride[2], val, uv_w);
77*fb1b10abSAndroid Build Coastguard Worker     }
78*fb1b10abSAndroid Build Coastguard Worker   } else {
79*fb1b10abSAndroid Build Coastguard Worker     for (unsigned int i = 0; i < image->d_h; ++i) {
80*fb1b10abSAndroid Build Coastguard Worker       memset(image->planes[0] + i * image->stride[0], val, image->d_w);
81*fb1b10abSAndroid Build Coastguard Worker     }
82*fb1b10abSAndroid Build Coastguard Worker     for (unsigned int i = 0; i < uv_h; ++i) {
83*fb1b10abSAndroid Build Coastguard Worker       memset(image->planes[1] + i * image->stride[1], val, uv_w);
84*fb1b10abSAndroid Build Coastguard Worker       memset(image->planes[2] + i * image->stride[2], val, uv_w);
85*fb1b10abSAndroid Build Coastguard Worker     }
86*fb1b10abSAndroid Build Coastguard Worker   }
87*fb1b10abSAndroid Build Coastguard Worker 
88*fb1b10abSAndroid Build Coastguard Worker   return image;
89*fb1b10abSAndroid Build Coastguard Worker }
90*fb1b10abSAndroid Build Coastguard Worker 
InitCodec(vpx_codec_iface_t & iface,int width,int height,vpx_codec_ctx_t * enc,vpx_codec_enc_cfg_t * cfg)91*fb1b10abSAndroid Build Coastguard Worker void InitCodec(vpx_codec_iface_t &iface, int width, int height,
92*fb1b10abSAndroid Build Coastguard Worker                vpx_codec_ctx_t *enc, vpx_codec_enc_cfg_t *cfg) {
93*fb1b10abSAndroid Build Coastguard Worker   cfg->g_w = width;
94*fb1b10abSAndroid Build Coastguard Worker   cfg->g_h = height;
95*fb1b10abSAndroid Build Coastguard Worker   cfg->g_lag_in_frames = 0;
96*fb1b10abSAndroid Build Coastguard Worker   cfg->g_pass = VPX_RC_ONE_PASS;
97*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(enc, &iface, cfg, 0), VPX_CODEC_OK);
98*fb1b10abSAndroid Build Coastguard Worker 
99*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control_(enc, VP8E_SET_CPUUSED, 2), VPX_CODEC_OK);
100*fb1b10abSAndroid Build Coastguard Worker }
101*fb1b10abSAndroid Build Coastguard Worker 
102*fb1b10abSAndroid Build Coastguard Worker // Encodes 1 frame of size |cfg.g_w| x |cfg.g_h| setting |enc|'s configuration
103*fb1b10abSAndroid Build Coastguard Worker // to |cfg|.
EncodeWithConfig(const vpx_codec_enc_cfg_t & cfg,vpx_codec_ctx_t * enc)104*fb1b10abSAndroid Build Coastguard Worker void EncodeWithConfig(const vpx_codec_enc_cfg_t &cfg, vpx_codec_ctx_t *enc) {
105*fb1b10abSAndroid Build Coastguard Worker   libvpx_test::DummyVideoSource video;
106*fb1b10abSAndroid Build Coastguard Worker   video.SetSize(cfg.g_w, cfg.g_h);
107*fb1b10abSAndroid Build Coastguard Worker   video.Begin();
108*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(vpx_codec_enc_config_set(enc, &cfg), VPX_CODEC_OK)
109*fb1b10abSAndroid Build Coastguard Worker       << vpx_codec_error_detail(enc);
110*fb1b10abSAndroid Build Coastguard Worker 
111*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(vpx_codec_encode(enc, video.img(), video.pts(), video.duration(),
112*fb1b10abSAndroid Build Coastguard Worker                              /*flags=*/0, VPX_DL_GOOD_QUALITY),
113*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK)
114*fb1b10abSAndroid Build Coastguard Worker       << vpx_codec_error_detail(enc);
115*fb1b10abSAndroid Build Coastguard Worker }
116*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,InvalidParams)117*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, InvalidParams) {
118*fb1b10abSAndroid Build Coastguard Worker   uint8_t buf[1] = { 0 };
119*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t img;
120*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
121*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
122*fb1b10abSAndroid Build Coastguard Worker 
123*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf));
124*fb1b10abSAndroid Build Coastguard Worker 
125*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
126*fb1b10abSAndroid Build Coastguard Worker             vpx_codec_enc_init(nullptr, nullptr, nullptr, 0));
127*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
128*fb1b10abSAndroid Build Coastguard Worker             vpx_codec_enc_init(&enc, nullptr, nullptr, 0));
129*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
130*fb1b10abSAndroid Build Coastguard Worker             vpx_codec_encode(nullptr, nullptr, 0, 0, 0, 0));
131*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
132*fb1b10abSAndroid Build Coastguard Worker             vpx_codec_encode(nullptr, &img, 0, 0, 0, 0));
133*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(nullptr));
134*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
135*fb1b10abSAndroid Build Coastguard Worker             vpx_codec_enc_config_default(nullptr, nullptr, 0));
136*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
137*fb1b10abSAndroid Build Coastguard Worker             vpx_codec_enc_config_default(nullptr, &cfg, 0));
138*fb1b10abSAndroid Build Coastguard Worker   EXPECT_NE(vpx_codec_error(nullptr), nullptr);
139*fb1b10abSAndroid Build Coastguard Worker 
140*fb1b10abSAndroid Build Coastguard Worker   for (const auto *iface : kCodecIfaces) {
141*fb1b10abSAndroid Build Coastguard Worker     SCOPED_TRACE(vpx_codec_iface_name(iface));
142*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
143*fb1b10abSAndroid Build Coastguard Worker               vpx_codec_enc_init(nullptr, iface, nullptr, 0));
144*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
145*fb1b10abSAndroid Build Coastguard Worker               vpx_codec_enc_init(&enc, iface, nullptr, 0));
146*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
147*fb1b10abSAndroid Build Coastguard Worker               vpx_codec_enc_config_default(iface, &cfg, 1));
148*fb1b10abSAndroid Build Coastguard Worker 
149*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(iface, &cfg, 0));
150*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, iface, &cfg, 0));
151*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, nullptr, 0, 0, 0, 0));
152*fb1b10abSAndroid Build Coastguard Worker 
153*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
154*fb1b10abSAndroid Build Coastguard Worker   }
155*fb1b10abSAndroid Build Coastguard Worker }
156*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,HighBitDepthCapability)157*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, HighBitDepthCapability) {
158*fb1b10abSAndroid Build Coastguard Worker // VP8 should not claim VP9 HBD as a capability.
159*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP8_ENCODER
160*fb1b10abSAndroid Build Coastguard Worker   const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo);
161*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
162*fb1b10abSAndroid Build Coastguard Worker #endif
163*fb1b10abSAndroid Build Coastguard Worker 
164*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_ENCODER
165*fb1b10abSAndroid Build Coastguard Worker   const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo);
166*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
167*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
168*fb1b10abSAndroid Build Coastguard Worker #else
169*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
170*fb1b10abSAndroid Build Coastguard Worker #endif
171*fb1b10abSAndroid Build Coastguard Worker #endif
172*fb1b10abSAndroid Build Coastguard Worker }
173*fb1b10abSAndroid Build Coastguard Worker 
174*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP8_ENCODER
TEST(EncodeAPI,ImageSizeSetting)175*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, ImageSizeSetting) {
176*fb1b10abSAndroid Build Coastguard Worker   const int width = 711;
177*fb1b10abSAndroid Build Coastguard Worker   const int height = 360;
178*fb1b10abSAndroid Build Coastguard Worker   const int bps = 12;
179*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t img;
180*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
181*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
182*fb1b10abSAndroid Build Coastguard Worker   uint8_t *img_buf = reinterpret_cast<uint8_t *>(
183*fb1b10abSAndroid Build Coastguard Worker       calloc(width * height * bps / 8, sizeof(*img_buf)));
184*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0);
185*fb1b10abSAndroid Build Coastguard Worker 
186*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = width;
187*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = height;
188*fb1b10abSAndroid Build Coastguard Worker 
189*fb1b10abSAndroid Build Coastguard Worker   vpx_img_wrap(&img, VPX_IMG_FMT_I420, width, height, 1, img_buf);
190*fb1b10abSAndroid Build Coastguard Worker 
191*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_init(&enc, vpx_codec_vp8_cx(), &cfg, 0);
192*fb1b10abSAndroid Build Coastguard Worker 
193*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, &img, 0, 1, 0, 0));
194*fb1b10abSAndroid Build Coastguard Worker 
195*fb1b10abSAndroid Build Coastguard Worker   free(img_buf);
196*fb1b10abSAndroid Build Coastguard Worker 
197*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_destroy(&enc);
198*fb1b10abSAndroid Build Coastguard Worker }
199*fb1b10abSAndroid Build Coastguard Worker 
200*fb1b10abSAndroid Build Coastguard Worker // Verifies the fix for a float-cast-overflow in vp8_change_config().
201*fb1b10abSAndroid Build Coastguard Worker //
202*fb1b10abSAndroid Build Coastguard Worker // Causes cpi->framerate to become the largest possible value (10,000,000) in
203*fb1b10abSAndroid Build Coastguard Worker // VP8 by setting cfg.g_timebase to 1/10000000 and passing a duration of 1 to
204*fb1b10abSAndroid Build Coastguard Worker // vpx_codec_encode().
TEST(EncodeAPI,HugeFramerateVp8)205*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, HugeFramerateVp8) {
206*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp8_cx();
207*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
208*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
209*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 271;
210*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 1080;
211*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.num = 1;
212*fb1b10abSAndroid Build Coastguard Worker   // Largest value (VP8's TICKS_PER_SEC) such that frame duration is nonzero (1
213*fb1b10abSAndroid Build Coastguard Worker   // tick).
214*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.den = 10000000;
215*fb1b10abSAndroid Build Coastguard Worker   cfg.g_pass = VPX_RC_ONE_PASS;
216*fb1b10abSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 0;
217*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_end_usage = VPX_CBR;
218*fb1b10abSAndroid Build Coastguard Worker 
219*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
220*fb1b10abSAndroid Build Coastguard Worker   // Before we encode the first frame, cpi->framerate is set to a guess (the
221*fb1b10abSAndroid Build Coastguard Worker   // reciprocal of cfg.g_timebase). If this guess doesn't seem reasonable
222*fb1b10abSAndroid Build Coastguard Worker   // (> 180), cpi->framerate is set to 30.
223*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
224*fb1b10abSAndroid Build Coastguard Worker 
225*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, -12), VPX_CODEC_OK);
226*fb1b10abSAndroid Build Coastguard Worker 
227*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *const image =
228*fb1b10abSAndroid Build Coastguard Worker       vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h, 1);
229*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
230*fb1b10abSAndroid Build Coastguard Worker 
231*fb1b10abSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < image->d_h; ++i) {
232*fb1b10abSAndroid Build Coastguard Worker     memset(image->planes[0] + i * image->stride[0], 128, image->d_w);
233*fb1b10abSAndroid Build Coastguard Worker   }
234*fb1b10abSAndroid Build Coastguard Worker   const unsigned int uv_h = (image->d_h + 1) / 2;
235*fb1b10abSAndroid Build Coastguard Worker   const unsigned int uv_w = (image->d_w + 1) / 2;
236*fb1b10abSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < uv_h; ++i) {
237*fb1b10abSAndroid Build Coastguard Worker     memset(image->planes[1] + i * image->stride[1], 128, uv_w);
238*fb1b10abSAndroid Build Coastguard Worker     memset(image->planes[2] + i * image->stride[2], 128, uv_w);
239*fb1b10abSAndroid Build Coastguard Worker   }
240*fb1b10abSAndroid Build Coastguard Worker 
241*fb1b10abSAndroid Build Coastguard Worker   // Encode a frame.
242*fb1b10abSAndroid Build Coastguard Worker   // Up to this point cpi->framerate is 30. Now pass a duration of only 1. This
243*fb1b10abSAndroid Build Coastguard Worker   // causes cpi->framerate to become 10,000,000.
244*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_encode(&enc, image, 0, 1, 0, VPX_DL_REALTIME),
245*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
246*fb1b10abSAndroid Build Coastguard Worker 
247*fb1b10abSAndroid Build Coastguard Worker   // Change to the same config. Since cpi->framerate is now huge, when it is
248*fb1b10abSAndroid Build Coastguard Worker   // used to calculate raw_target_rate (bit rate of uncompressed frames), the
249*fb1b10abSAndroid Build Coastguard Worker   // result is likely to overflow an unsigned int.
250*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_set(&enc, &cfg), VPX_CODEC_OK);
251*fb1b10abSAndroid Build Coastguard Worker 
252*fb1b10abSAndroid Build Coastguard Worker   vpx_img_free(image);
253*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
254*fb1b10abSAndroid Build Coastguard Worker }
255*fb1b10abSAndroid Build Coastguard Worker 
256*fb1b10abSAndroid Build Coastguard Worker // A test that reproduces https://crbug.com/webm/1831.
TEST(EncodeAPI,RandomPixelsVp8)257*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, RandomPixelsVp8) {
258*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder
259*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp8_cx();
260*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
261*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
262*fb1b10abSAndroid Build Coastguard Worker 
263*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 2000;
264*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 1280;
265*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 720;
266*fb1b10abSAndroid Build Coastguard Worker 
267*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
268*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
269*fb1b10abSAndroid Build Coastguard Worker 
270*fb1b10abSAndroid Build Coastguard Worker   // Generate random frame data and encode
271*fb1b10abSAndroid Build Coastguard Worker   libvpx_test::RandomVideoSource video;
272*fb1b10abSAndroid Build Coastguard Worker   video.SetSize(cfg.g_w, cfg.g_h);
273*fb1b10abSAndroid Build Coastguard Worker   video.SetImageFormat(VPX_IMG_FMT_I420);
274*fb1b10abSAndroid Build Coastguard Worker   video.Begin();
275*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_encode(&enc, video.img(), video.pts(), video.duration(),
276*fb1b10abSAndroid Build Coastguard Worker                              /*flags=*/0, VPX_DL_BEST_QUALITY),
277*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
278*fb1b10abSAndroid Build Coastguard Worker 
279*fb1b10abSAndroid Build Coastguard Worker   // Destroy libvpx encoder
280*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_destroy(&enc);
281*fb1b10abSAndroid Build Coastguard Worker }
282*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,ChangeToL1T3AndSetBitrateVp8)283*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, ChangeToL1T3AndSetBitrateVp8) {
284*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder
285*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp8_cx();
286*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
287*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
288*fb1b10abSAndroid Build Coastguard Worker 
289*fb1b10abSAndroid Build Coastguard Worker   cfg.g_threads = 1;
290*fb1b10abSAndroid Build Coastguard Worker   cfg.g_profile = 0;
291*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 1;
292*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 64;
293*fb1b10abSAndroid Build Coastguard Worker   cfg.g_bit_depth = VPX_BITS_8;
294*fb1b10abSAndroid Build Coastguard Worker   cfg.g_input_bit_depth = 8;
295*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.num = 1;
296*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.den = 1000000;
297*fb1b10abSAndroid Build Coastguard Worker   cfg.g_pass = VPX_RC_ONE_PASS;
298*fb1b10abSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 0;
299*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_dropframe_thresh = 0;  // Don't drop frames
300*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_resize_allowed = 0;
301*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_end_usage = VPX_VBR;
302*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 10;
303*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_min_quantizer = 2;
304*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_max_quantizer = 58;
305*fb1b10abSAndroid Build Coastguard Worker   cfg.kf_mode = VPX_KF_AUTO;
306*fb1b10abSAndroid Build Coastguard Worker   cfg.kf_min_dist = 0;
307*fb1b10abSAndroid Build Coastguard Worker   cfg.kf_max_dist = 10000;
308*fb1b10abSAndroid Build Coastguard Worker 
309*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
310*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
311*fb1b10abSAndroid Build Coastguard Worker 
312*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, -6), VPX_CODEC_OK);
313*fb1b10abSAndroid Build Coastguard Worker 
314*fb1b10abSAndroid Build Coastguard Worker   // Generate random frame data and encode
315*fb1b10abSAndroid Build Coastguard Worker   uint8_t img[1 * 64 * 3 / 2];
316*fb1b10abSAndroid Build Coastguard Worker   libvpx_test::ACMRandom rng;
317*fb1b10abSAndroid Build Coastguard Worker   for (size_t i = 0; i < sizeof(img); ++i) {
318*fb1b10abSAndroid Build Coastguard Worker     img[i] = rng.Rand8();
319*fb1b10abSAndroid Build Coastguard Worker   }
320*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t img_wrapper;
321*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(
322*fb1b10abSAndroid Build Coastguard Worker       vpx_img_wrap(&img_wrapper, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h, 1, img),
323*fb1b10abSAndroid Build Coastguard Worker       &img_wrapper);
324*fb1b10abSAndroid Build Coastguard Worker   vpx_enc_frame_flags_t flags = VPX_EFLAG_FORCE_KF;
325*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(
326*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_encode(&enc, &img_wrapper, 0, 500000, flags, VPX_DL_REALTIME),
327*fb1b10abSAndroid Build Coastguard Worker       VPX_CODEC_OK);
328*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_encode(&enc, nullptr, -1, 0, 0, 0), VPX_CODEC_OK);
329*fb1b10abSAndroid Build Coastguard Worker 
330*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 4294967;
331*fb1b10abSAndroid Build Coastguard Worker   // Set the scalability mode to L1T3.
332*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_number_layers = 3;
333*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_periodicity = 4;
334*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_layer_id[0] = 0;
335*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_layer_id[1] = 2;
336*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_layer_id[2] = 1;
337*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_layer_id[3] = 2;
338*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_rate_decimator[0] = 4;
339*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_rate_decimator[1] = 2;
340*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_rate_decimator[2] = 1;
341*fb1b10abSAndroid Build Coastguard Worker   // Bitrate allocation L0: 50% L1: 20% L2: 30%
342*fb1b10abSAndroid Build Coastguard Worker   cfg.layer_target_bitrate[0] = cfg.ts_target_bitrate[0] =
343*fb1b10abSAndroid Build Coastguard Worker       50 * cfg.rc_target_bitrate / 100;
344*fb1b10abSAndroid Build Coastguard Worker   cfg.layer_target_bitrate[1] = cfg.ts_target_bitrate[1] =
345*fb1b10abSAndroid Build Coastguard Worker       70 * cfg.rc_target_bitrate / 100;
346*fb1b10abSAndroid Build Coastguard Worker   cfg.layer_target_bitrate[2] = cfg.ts_target_bitrate[2] =
347*fb1b10abSAndroid Build Coastguard Worker       cfg.rc_target_bitrate;
348*fb1b10abSAndroid Build Coastguard Worker   cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_0212;
349*fb1b10abSAndroid Build Coastguard Worker   cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
350*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_set(&enc, &cfg), VPX_CODEC_OK);
351*fb1b10abSAndroid Build Coastguard Worker 
352*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_TEMPORAL_LAYER_ID, 2),
353*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
354*fb1b10abSAndroid Build Coastguard Worker 
355*fb1b10abSAndroid Build Coastguard Worker   constexpr vpx_enc_frame_flags_t VP8_UPDATE_NOTHING =
356*fb1b10abSAndroid Build Coastguard Worker       VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
357*fb1b10abSAndroid Build Coastguard Worker   // Layer 2: only reference last frame, no updates
358*fb1b10abSAndroid Build Coastguard Worker   // It only depends on layer 0
359*fb1b10abSAndroid Build Coastguard Worker   flags = VP8_UPDATE_NOTHING | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF;
360*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(
361*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_encode(&enc, &img_wrapper, 0, 500000, flags, VPX_DL_REALTIME),
362*fb1b10abSAndroid Build Coastguard Worker       VPX_CODEC_OK);
363*fb1b10abSAndroid Build Coastguard Worker 
364*fb1b10abSAndroid Build Coastguard Worker   // Destroy libvpx encoder
365*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_destroy(&enc);
366*fb1b10abSAndroid Build Coastguard Worker }
367*fb1b10abSAndroid Build Coastguard Worker 
368*fb1b10abSAndroid Build Coastguard Worker // Emulates the WebCodecs VideoEncoder interface.
369*fb1b10abSAndroid Build Coastguard Worker class VP8Encoder {
370*fb1b10abSAndroid Build Coastguard Worker  public:
VP8Encoder(int speed)371*fb1b10abSAndroid Build Coastguard Worker   explicit VP8Encoder(int speed) : speed_(speed) {}
372*fb1b10abSAndroid Build Coastguard Worker   ~VP8Encoder();
373*fb1b10abSAndroid Build Coastguard Worker 
374*fb1b10abSAndroid Build Coastguard Worker   void Configure(unsigned int threads, unsigned int width, unsigned int height,
375*fb1b10abSAndroid Build Coastguard Worker                  vpx_rc_mode end_usage, vpx_enc_deadline_t deadline);
376*fb1b10abSAndroid Build Coastguard Worker   void Encode(bool key_frame);
377*fb1b10abSAndroid Build Coastguard Worker 
378*fb1b10abSAndroid Build Coastguard Worker  private:
379*fb1b10abSAndroid Build Coastguard Worker   const int speed_;
380*fb1b10abSAndroid Build Coastguard Worker   bool initialized_ = false;
381*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg_;
382*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc_;
383*fb1b10abSAndroid Build Coastguard Worker   int frame_index_ = 0;
384*fb1b10abSAndroid Build Coastguard Worker   vpx_enc_deadline_t deadline_ = 0;
385*fb1b10abSAndroid Build Coastguard Worker };
386*fb1b10abSAndroid Build Coastguard Worker 
~VP8Encoder()387*fb1b10abSAndroid Build Coastguard Worker VP8Encoder::~VP8Encoder() {
388*fb1b10abSAndroid Build Coastguard Worker   if (initialized_) {
389*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_destroy(&enc_), VPX_CODEC_OK);
390*fb1b10abSAndroid Build Coastguard Worker   }
391*fb1b10abSAndroid Build Coastguard Worker }
392*fb1b10abSAndroid Build Coastguard Worker 
Configure(unsigned int threads,unsigned int width,unsigned int height,vpx_rc_mode end_usage,vpx_enc_deadline_t deadline)393*fb1b10abSAndroid Build Coastguard Worker void VP8Encoder::Configure(unsigned int threads, unsigned int width,
394*fb1b10abSAndroid Build Coastguard Worker                            unsigned int height, vpx_rc_mode end_usage,
395*fb1b10abSAndroid Build Coastguard Worker                            vpx_enc_deadline_t deadline) {
396*fb1b10abSAndroid Build Coastguard Worker   deadline_ = deadline;
397*fb1b10abSAndroid Build Coastguard Worker 
398*fb1b10abSAndroid Build Coastguard Worker   if (!initialized_) {
399*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_iface_t *const iface = vpx_codec_vp8_cx();
400*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg_, /*usage=*/0),
401*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_OK);
402*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_threads = threads;
403*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_w = width;
404*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_h = height;
405*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_timebase.num = 1;
406*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_timebase.den = 1000 * 1000;  // microseconds
407*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_pass = VPX_RC_ONE_PASS;
408*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_lag_in_frames = 0;
409*fb1b10abSAndroid Build Coastguard Worker     cfg_.rc_end_usage = end_usage;
410*fb1b10abSAndroid Build Coastguard Worker     cfg_.rc_min_quantizer = 2;
411*fb1b10abSAndroid Build Coastguard Worker     cfg_.rc_max_quantizer = 58;
412*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_init(&enc_, iface, &cfg_, 0), VPX_CODEC_OK);
413*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_control(&enc_, VP8E_SET_CPUUSED, speed_), VPX_CODEC_OK);
414*fb1b10abSAndroid Build Coastguard Worker     initialized_ = true;
415*fb1b10abSAndroid Build Coastguard Worker     return;
416*fb1b10abSAndroid Build Coastguard Worker   }
417*fb1b10abSAndroid Build Coastguard Worker 
418*fb1b10abSAndroid Build Coastguard Worker   cfg_.g_threads = threads;
419*fb1b10abSAndroid Build Coastguard Worker   cfg_.g_w = width;
420*fb1b10abSAndroid Build Coastguard Worker   cfg_.g_h = height;
421*fb1b10abSAndroid Build Coastguard Worker   cfg_.rc_end_usage = end_usage;
422*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_set(&enc_, &cfg_), VPX_CODEC_OK)
423*fb1b10abSAndroid Build Coastguard Worker       << vpx_codec_error_detail(&enc_);
424*fb1b10abSAndroid Build Coastguard Worker }
425*fb1b10abSAndroid Build Coastguard Worker 
Encode(bool key_frame)426*fb1b10abSAndroid Build Coastguard Worker void VP8Encoder::Encode(bool key_frame) {
427*fb1b10abSAndroid Build Coastguard Worker   assert(initialized_);
428*fb1b10abSAndroid Build Coastguard Worker   const vpx_codec_cx_pkt_t *pkt;
429*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *image =
430*fb1b10abSAndroid Build Coastguard Worker       CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg_.g_w, cfg_.g_h);
431*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
432*fb1b10abSAndroid Build Coastguard Worker   const vpx_enc_frame_flags_t flags = key_frame ? VPX_EFLAG_FORCE_KF : 0;
433*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_encode(&enc_, image, frame_index_, 1, flags, deadline_),
434*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
435*fb1b10abSAndroid Build Coastguard Worker   ++frame_index_;
436*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iter_t iter = nullptr;
437*fb1b10abSAndroid Build Coastguard Worker   while ((pkt = vpx_codec_get_cx_data(&enc_, &iter)) != nullptr) {
438*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(pkt->kind, VPX_CODEC_CX_FRAME_PKT);
439*fb1b10abSAndroid Build Coastguard Worker     if (key_frame) {
440*fb1b10abSAndroid Build Coastguard Worker       ASSERT_EQ(pkt->data.frame.flags & VPX_FRAME_IS_KEY, VPX_FRAME_IS_KEY);
441*fb1b10abSAndroid Build Coastguard Worker     }
442*fb1b10abSAndroid Build Coastguard Worker   }
443*fb1b10abSAndroid Build Coastguard Worker   vpx_img_free(image);
444*fb1b10abSAndroid Build Coastguard Worker }
445*fb1b10abSAndroid Build Coastguard Worker 
446*fb1b10abSAndroid Build Coastguard Worker // This is the reproducer testcase for crbug.com/324459561. However,
447*fb1b10abSAndroid Build Coastguard Worker // just running this test is not enough to reproduce the bug. We also
448*fb1b10abSAndroid Build Coastguard Worker // need to send signals to the test.
TEST(EncodeAPI,Chromium324459561)449*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Chromium324459561) {
450*fb1b10abSAndroid Build Coastguard Worker   VP8Encoder encoder(-12);
451*fb1b10abSAndroid Build Coastguard Worker 
452*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(11, 1685, 652, VPX_CBR, VPX_DL_REALTIME);
453*fb1b10abSAndroid Build Coastguard Worker 
454*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
455*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
456*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
457*fb1b10abSAndroid Build Coastguard Worker 
458*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1685, 1, VPX_VBR, VPX_DL_REALTIME);
459*fb1b10abSAndroid Build Coastguard Worker }
460*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,VP8GlobalHeaders)461*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, VP8GlobalHeaders) {
462*fb1b10abSAndroid Build Coastguard Worker   constexpr int kWidth = 320;
463*fb1b10abSAndroid Build Coastguard Worker   constexpr int kHeight = 240;
464*fb1b10abSAndroid Build Coastguard Worker 
465*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg = {};
466*fb1b10abSAndroid Build Coastguard Worker   struct Encoder {
467*fb1b10abSAndroid Build Coastguard Worker     ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); }
468*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_ctx_t ctx = {};
469*fb1b10abSAndroid Build Coastguard Worker   } enc;
470*fb1b10abSAndroid Build Coastguard Worker 
471*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0),
472*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
473*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NO_FATAL_FAILURE(
474*fb1b10abSAndroid Build Coastguard Worker       InitCodec(*vpx_codec_vp8_cx(), kWidth, kHeight, &enc.ctx, &cfg));
475*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(vpx_codec_get_global_headers(&enc.ctx), nullptr);
476*fb1b10abSAndroid Build Coastguard Worker   EXPECT_NO_FATAL_FAILURE(EncodeWithConfig(cfg, &enc.ctx));
477*fb1b10abSAndroid Build Coastguard Worker   EXPECT_EQ(vpx_codec_get_global_headers(&enc.ctx), nullptr);
478*fb1b10abSAndroid Build Coastguard Worker }
479*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,AomediaIssue3509VbrMinSection2PercentVP8)480*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, AomediaIssue3509VbrMinSection2PercentVP8) {
481*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder.
482*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp8_cx();
483*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
484*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
485*fb1b10abSAndroid Build Coastguard Worker 
486*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
487*fb1b10abSAndroid Build Coastguard Worker 
488*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 1920;
489*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 1080;
490*fb1b10abSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 0;
491*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1000000;
492*fb1b10abSAndroid Build Coastguard Worker   // Set this to more than 1 percent to cause a signed integer overflow in the
493*fb1b10abSAndroid Build Coastguard Worker   // multiplication cpi->av_per_frame_bandwidth *
494*fb1b10abSAndroid Build Coastguard Worker   // cpi->oxcf.two_pass_vbrmin_section in vp8_new_framerate() if the
495*fb1b10abSAndroid Build Coastguard Worker   // multiplication is done in the `int` type.
496*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_2pass_vbr_minsection_pct = 2;
497*fb1b10abSAndroid Build Coastguard Worker 
498*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
499*fb1b10abSAndroid Build Coastguard Worker 
500*fb1b10abSAndroid Build Coastguard Worker   // Create input image.
501*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *const image =
502*fb1b10abSAndroid Build Coastguard Worker       CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h);
503*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
504*fb1b10abSAndroid Build Coastguard Worker 
505*fb1b10abSAndroid Build Coastguard Worker   // Encode frame.
506*fb1b10abSAndroid Build Coastguard Worker   // `duration` can go as high as 300, but the UBSan error is gone if
507*fb1b10abSAndroid Build Coastguard Worker   // `duration` is 301 or higher.
508*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(
509*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_encode(&enc, image, 0, /*duration=*/300, 0, VPX_DL_REALTIME),
510*fb1b10abSAndroid Build Coastguard Worker       VPX_CODEC_OK);
511*fb1b10abSAndroid Build Coastguard Worker 
512*fb1b10abSAndroid Build Coastguard Worker   // Free resources.
513*fb1b10abSAndroid Build Coastguard Worker   vpx_img_free(image);
514*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
515*fb1b10abSAndroid Build Coastguard Worker }
516*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,AomediaIssue3509VbrMinSection101PercentVP8)517*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, AomediaIssue3509VbrMinSection101PercentVP8) {
518*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder.
519*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp8_cx();
520*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
521*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
522*fb1b10abSAndroid Build Coastguard Worker 
523*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
524*fb1b10abSAndroid Build Coastguard Worker 
525*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 1920;
526*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 1080;
527*fb1b10abSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 0;
528*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1000000;
529*fb1b10abSAndroid Build Coastguard Worker   // Set this to more than 100 percent to cause an error when vbr_min_bits is
530*fb1b10abSAndroid Build Coastguard Worker   // cast to `int` in vp8_new_framerate() if vbr_min_bits is not clamped to
531*fb1b10abSAndroid Build Coastguard Worker   // INT_MAX.
532*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_2pass_vbr_minsection_pct = 101;
533*fb1b10abSAndroid Build Coastguard Worker 
534*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
535*fb1b10abSAndroid Build Coastguard Worker 
536*fb1b10abSAndroid Build Coastguard Worker   // Create input image.
537*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *const image =
538*fb1b10abSAndroid Build Coastguard Worker       CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h);
539*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
540*fb1b10abSAndroid Build Coastguard Worker 
541*fb1b10abSAndroid Build Coastguard Worker   // Encode frame.
542*fb1b10abSAndroid Build Coastguard Worker   // `duration` can go as high as 300, but the UBSan error is gone if
543*fb1b10abSAndroid Build Coastguard Worker   // `duration` is 301 or higher.
544*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(
545*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_encode(&enc, image, 0, /*duration=*/300, 0, VPX_DL_REALTIME),
546*fb1b10abSAndroid Build Coastguard Worker       VPX_CODEC_OK);
547*fb1b10abSAndroid Build Coastguard Worker 
548*fb1b10abSAndroid Build Coastguard Worker   // Free resources.
549*fb1b10abSAndroid Build Coastguard Worker   vpx_img_free(image);
550*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
551*fb1b10abSAndroid Build Coastguard Worker }
552*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,OssFuzz69100)553*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, OssFuzz69100) {
554*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder.
555*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp8_cx();
556*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
557*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
558*fb1b10abSAndroid Build Coastguard Worker 
559*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
560*fb1b10abSAndroid Build Coastguard Worker 
561*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 64;
562*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 64;
563*fb1b10abSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 25;
564*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.num = 1;
565*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.den = 6240592;
566*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1202607620;
567*fb1b10abSAndroid Build Coastguard Worker   cfg.kf_max_dist = 24377;
568*fb1b10abSAndroid Build Coastguard Worker 
569*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
570*fb1b10abSAndroid Build Coastguard Worker 
571*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, 1), VPX_CODEC_OK);
572*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_ARNR_MAXFRAMES, 0), VPX_CODEC_OK);
573*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_ARNR_STRENGTH, 3), VPX_CODEC_OK);
574*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control_(&enc, VP8E_SET_ARNR_TYPE, 3),
575*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);  // deprecated
576*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_NOISE_SENSITIVITY, 0),
577*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
578*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_TOKEN_PARTITIONS, 0),
579*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
580*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_STATIC_THRESHOLD, 0),
581*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
582*fb1b10abSAndroid Build Coastguard Worker 
583*fb1b10abSAndroid Build Coastguard Worker   libvpx_test::RandomVideoSource video;
584*fb1b10abSAndroid Build Coastguard Worker   video.set_limit(30);
585*fb1b10abSAndroid Build Coastguard Worker   video.SetSize(cfg.g_w, cfg.g_h);
586*fb1b10abSAndroid Build Coastguard Worker   video.SetImageFormat(VPX_IMG_FMT_I420);
587*fb1b10abSAndroid Build Coastguard Worker   video.Begin();
588*fb1b10abSAndroid Build Coastguard Worker   do {
589*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, video.img(), video.pts(), video.duration(),
590*fb1b10abSAndroid Build Coastguard Worker                                /*flags=*/0, VPX_DL_GOOD_QUALITY),
591*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_OK);
592*fb1b10abSAndroid Build Coastguard Worker     video.Next();
593*fb1b10abSAndroid Build Coastguard Worker   } while (video.img() != nullptr);
594*fb1b10abSAndroid Build Coastguard Worker 
595*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
596*fb1b10abSAndroid Build Coastguard Worker }
597*fb1b10abSAndroid Build Coastguard Worker 
EncodeOssFuzz69906(int cpu_used,vpx_enc_deadline_t deadline)598*fb1b10abSAndroid Build Coastguard Worker void EncodeOssFuzz69906(int cpu_used, vpx_enc_deadline_t deadline) {
599*fb1b10abSAndroid Build Coastguard Worker   char str[80];
600*fb1b10abSAndroid Build Coastguard Worker   snprintf(str, sizeof(str), "cpu_used: %d deadline: %d", cpu_used,
601*fb1b10abSAndroid Build Coastguard Worker            static_cast<int>(deadline));
602*fb1b10abSAndroid Build Coastguard Worker   SCOPED_TRACE(str);
603*fb1b10abSAndroid Build Coastguard Worker 
604*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder.
605*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp8_cx();
606*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
607*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
608*fb1b10abSAndroid Build Coastguard Worker 
609*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
610*fb1b10abSAndroid Build Coastguard Worker 
611*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 4097;
612*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 16;
613*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1237084865;
614*fb1b10abSAndroid Build Coastguard Worker   cfg.kf_max_dist = 4336;
615*fb1b10abSAndroid Build Coastguard Worker 
616*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
617*fb1b10abSAndroid Build Coastguard Worker 
618*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, cpu_used), VPX_CODEC_OK);
619*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_ARNR_MAXFRAMES, 0), VPX_CODEC_OK);
620*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_ARNR_STRENGTH, 3), VPX_CODEC_OK);
621*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control_(&enc, VP8E_SET_ARNR_TYPE, 3),
622*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);  // deprecated
623*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_NOISE_SENSITIVITY, 0),
624*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
625*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_TOKEN_PARTITIONS, 0),
626*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
627*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_STATIC_THRESHOLD, 0),
628*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
629*fb1b10abSAndroid Build Coastguard Worker 
630*fb1b10abSAndroid Build Coastguard Worker   libvpx_test::Y4mVideoSource video("repro-oss-fuzz-69906.y4m", /*start=*/0,
631*fb1b10abSAndroid Build Coastguard Worker                                     /*limit=*/3);
632*fb1b10abSAndroid Build Coastguard Worker   video.Begin();
633*fb1b10abSAndroid Build Coastguard Worker   do {
634*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, video.img(), video.pts(), video.duration(),
635*fb1b10abSAndroid Build Coastguard Worker                                /*flags=*/0, deadline),
636*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_OK);
637*fb1b10abSAndroid Build Coastguard Worker     video.Next();
638*fb1b10abSAndroid Build Coastguard Worker   } while (video.img() != nullptr);
639*fb1b10abSAndroid Build Coastguard Worker 
640*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
641*fb1b10abSAndroid Build Coastguard Worker }
642*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,OssFuzz69906)643*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, OssFuzz69906) {
644*fb1b10abSAndroid Build Coastguard Worker   // Note the original bug report was for speed 1, good quality. The remainder
645*fb1b10abSAndroid Build Coastguard Worker   // of the settings are for added coverage.
646*fb1b10abSAndroid Build Coastguard Worker   for (int cpu_used = 0; cpu_used <= 5; ++cpu_used) {
647*fb1b10abSAndroid Build Coastguard Worker     EncodeOssFuzz69906(cpu_used, VPX_DL_GOOD_QUALITY);
648*fb1b10abSAndroid Build Coastguard Worker   }
649*fb1b10abSAndroid Build Coastguard Worker 
650*fb1b10abSAndroid Build Coastguard Worker   for (int cpu_used = -16; cpu_used <= -5; ++cpu_used) {
651*fb1b10abSAndroid Build Coastguard Worker     EncodeOssFuzz69906(cpu_used, VPX_DL_REALTIME);
652*fb1b10abSAndroid Build Coastguard Worker   }
653*fb1b10abSAndroid Build Coastguard Worker }
654*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP8_ENCODER
655*fb1b10abSAndroid Build Coastguard Worker 
656*fb1b10abSAndroid Build Coastguard Worker // Set up 2 spatial streams with 2 temporal layers per stream, and generate
657*fb1b10abSAndroid Build Coastguard Worker // invalid configuration by setting the temporal layer rate allocation
658*fb1b10abSAndroid Build Coastguard Worker // (ts_target_bitrate[]) to 0 for both layers. This should fail independent of
659*fb1b10abSAndroid Build Coastguard Worker // CONFIG_MULTI_RES_ENCODING.
TEST(EncodeAPI,MultiResEncode)660*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, MultiResEncode) {
661*fb1b10abSAndroid Build Coastguard Worker   const int width = 1280;
662*fb1b10abSAndroid Build Coastguard Worker   const int height = 720;
663*fb1b10abSAndroid Build Coastguard Worker   const int width_down = width / 2;
664*fb1b10abSAndroid Build Coastguard Worker   const int height_down = height / 2;
665*fb1b10abSAndroid Build Coastguard Worker   const int target_bitrate = 1000;
666*fb1b10abSAndroid Build Coastguard Worker   const int framerate = 30;
667*fb1b10abSAndroid Build Coastguard Worker 
668*fb1b10abSAndroid Build Coastguard Worker   for (const auto *iface : kCodecIfaces) {
669*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_ctx_t enc[2];
670*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_enc_cfg_t cfg[2];
671*fb1b10abSAndroid Build Coastguard Worker     vpx_rational_t dsf[2] = { { 2, 1 }, { 2, 1 } };
672*fb1b10abSAndroid Build Coastguard Worker 
673*fb1b10abSAndroid Build Coastguard Worker     memset(enc, 0, sizeof(enc));
674*fb1b10abSAndroid Build Coastguard Worker 
675*fb1b10abSAndroid Build Coastguard Worker     for (int i = 0; i < 2; i++) {
676*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_enc_config_default(iface, &cfg[i], 0);
677*fb1b10abSAndroid Build Coastguard Worker     }
678*fb1b10abSAndroid Build Coastguard Worker 
679*fb1b10abSAndroid Build Coastguard Worker     /* Highest-resolution encoder settings */
680*fb1b10abSAndroid Build Coastguard Worker     cfg[0].g_w = width;
681*fb1b10abSAndroid Build Coastguard Worker     cfg[0].g_h = height;
682*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_dropframe_thresh = 0;
683*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_end_usage = VPX_CBR;
684*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_resize_allowed = 0;
685*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_min_quantizer = 2;
686*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_max_quantizer = 56;
687*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_undershoot_pct = 100;
688*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_overshoot_pct = 15;
689*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_buf_initial_sz = 500;
690*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_buf_optimal_sz = 600;
691*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_buf_sz = 1000;
692*fb1b10abSAndroid Build Coastguard Worker     cfg[0].g_error_resilient = 1; /* Enable error resilient mode */
693*fb1b10abSAndroid Build Coastguard Worker     cfg[0].g_lag_in_frames = 0;
694*fb1b10abSAndroid Build Coastguard Worker 
695*fb1b10abSAndroid Build Coastguard Worker     cfg[0].kf_mode = VPX_KF_AUTO;
696*fb1b10abSAndroid Build Coastguard Worker     cfg[0].kf_min_dist = 3000;
697*fb1b10abSAndroid Build Coastguard Worker     cfg[0].kf_max_dist = 3000;
698*fb1b10abSAndroid Build Coastguard Worker 
699*fb1b10abSAndroid Build Coastguard Worker     cfg[0].rc_target_bitrate = target_bitrate; /* Set target bitrate */
700*fb1b10abSAndroid Build Coastguard Worker     cfg[0].g_timebase.num = 1;                 /* Set fps */
701*fb1b10abSAndroid Build Coastguard Worker     cfg[0].g_timebase.den = framerate;
702*fb1b10abSAndroid Build Coastguard Worker 
703*fb1b10abSAndroid Build Coastguard Worker     memcpy(&cfg[1], &cfg[0], sizeof(cfg[0]));
704*fb1b10abSAndroid Build Coastguard Worker     cfg[1].rc_target_bitrate = 500;
705*fb1b10abSAndroid Build Coastguard Worker     cfg[1].g_w = width_down;
706*fb1b10abSAndroid Build Coastguard Worker     cfg[1].g_h = height_down;
707*fb1b10abSAndroid Build Coastguard Worker 
708*fb1b10abSAndroid Build Coastguard Worker     for (int i = 0; i < 2; i++) {
709*fb1b10abSAndroid Build Coastguard Worker       cfg[i].ts_number_layers = 2;
710*fb1b10abSAndroid Build Coastguard Worker       cfg[i].ts_periodicity = 2;
711*fb1b10abSAndroid Build Coastguard Worker       cfg[i].ts_rate_decimator[0] = 2;
712*fb1b10abSAndroid Build Coastguard Worker       cfg[i].ts_rate_decimator[1] = 1;
713*fb1b10abSAndroid Build Coastguard Worker       cfg[i].ts_layer_id[0] = 0;
714*fb1b10abSAndroid Build Coastguard Worker       cfg[i].ts_layer_id[1] = 1;
715*fb1b10abSAndroid Build Coastguard Worker       // Invalid parameters.
716*fb1b10abSAndroid Build Coastguard Worker       cfg[i].ts_target_bitrate[0] = 0;
717*fb1b10abSAndroid Build Coastguard Worker       cfg[i].ts_target_bitrate[1] = 0;
718*fb1b10abSAndroid Build Coastguard Worker     }
719*fb1b10abSAndroid Build Coastguard Worker 
720*fb1b10abSAndroid Build Coastguard Worker     // VP9 should report incapable, VP8 invalid for all configurations.
721*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(IsVP9(iface) ? VPX_CODEC_INCAPABLE : VPX_CODEC_INVALID_PARAM,
722*fb1b10abSAndroid Build Coastguard Worker               vpx_codec_enc_init_multi(&enc[0], iface, &cfg[0], 2, 0, &dsf[0]));
723*fb1b10abSAndroid Build Coastguard Worker 
724*fb1b10abSAndroid Build Coastguard Worker     for (int i = 0; i < 2; i++) {
725*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_destroy(&enc[i]);
726*fb1b10abSAndroid Build Coastguard Worker     }
727*fb1b10abSAndroid Build Coastguard Worker   }
728*fb1b10abSAndroid Build Coastguard Worker }
729*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,SetRoi)730*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, SetRoi) {
731*fb1b10abSAndroid Build Coastguard Worker   static struct {
732*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_iface_t *iface;
733*fb1b10abSAndroid Build Coastguard Worker     int ctrl_id;
734*fb1b10abSAndroid Build Coastguard Worker   } kCodecs[] = {
735*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP8_ENCODER
736*fb1b10abSAndroid Build Coastguard Worker     { &vpx_codec_vp8_cx_algo, VP8E_SET_ROI_MAP },
737*fb1b10abSAndroid Build Coastguard Worker #endif
738*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_ENCODER
739*fb1b10abSAndroid Build Coastguard Worker     { &vpx_codec_vp9_cx_algo, VP9E_SET_ROI_MAP },
740*fb1b10abSAndroid Build Coastguard Worker #endif
741*fb1b10abSAndroid Build Coastguard Worker   };
742*fb1b10abSAndroid Build Coastguard Worker   constexpr int kWidth = 64;
743*fb1b10abSAndroid Build Coastguard Worker   constexpr int kHeight = 64;
744*fb1b10abSAndroid Build Coastguard Worker 
745*fb1b10abSAndroid Build Coastguard Worker   for (const auto &codec : kCodecs) {
746*fb1b10abSAndroid Build Coastguard Worker     SCOPED_TRACE(vpx_codec_iface_name(codec.iface));
747*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_ctx_t enc;
748*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_enc_cfg_t cfg;
749*fb1b10abSAndroid Build Coastguard Worker 
750*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_enc_config_default(codec.iface, &cfg, 0), VPX_CODEC_OK);
751*fb1b10abSAndroid Build Coastguard Worker     cfg.g_w = kWidth;
752*fb1b10abSAndroid Build Coastguard Worker     cfg.g_h = kHeight;
753*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_enc_init(&enc, codec.iface, &cfg, 0), VPX_CODEC_OK);
754*fb1b10abSAndroid Build Coastguard Worker 
755*fb1b10abSAndroid Build Coastguard Worker     vpx_roi_map_t roi = {};
756*fb1b10abSAndroid Build Coastguard Worker     uint8_t roi_map[kWidth * kHeight] = {};
757*fb1b10abSAndroid Build Coastguard Worker     if (IsVP9(codec.iface)) {
758*fb1b10abSAndroid Build Coastguard Worker       roi.rows = (cfg.g_w + 7) >> 3;
759*fb1b10abSAndroid Build Coastguard Worker       roi.cols = (cfg.g_h + 7) >> 3;
760*fb1b10abSAndroid Build Coastguard Worker     } else {
761*fb1b10abSAndroid Build Coastguard Worker       roi.rows = (cfg.g_w + 15) >> 4;
762*fb1b10abSAndroid Build Coastguard Worker       roi.cols = (cfg.g_h + 15) >> 4;
763*fb1b10abSAndroid Build Coastguard Worker     }
764*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), VPX_CODEC_OK);
765*fb1b10abSAndroid Build Coastguard Worker 
766*fb1b10abSAndroid Build Coastguard Worker     roi.roi_map = roi_map;
767*fb1b10abSAndroid Build Coastguard Worker     // VP8 only. This value isn't range checked.
768*fb1b10abSAndroid Build Coastguard Worker     roi.static_threshold[1] = 1000;
769*fb1b10abSAndroid Build Coastguard Worker     roi.static_threshold[2] = UINT_MAX / 2 + 1;
770*fb1b10abSAndroid Build Coastguard Worker     roi.static_threshold[3] = UINT_MAX;
771*fb1b10abSAndroid Build Coastguard Worker 
772*fb1b10abSAndroid Build Coastguard Worker     for (const auto delta : { -63, -1, 0, 1, 63 }) {
773*fb1b10abSAndroid Build Coastguard Worker       for (int i = 0; i < 8; ++i) {
774*fb1b10abSAndroid Build Coastguard Worker         roi.delta_q[i] = delta;
775*fb1b10abSAndroid Build Coastguard Worker         roi.delta_lf[i] = delta;
776*fb1b10abSAndroid Build Coastguard Worker         // VP9 only.
777*fb1b10abSAndroid Build Coastguard Worker         roi.skip[i] ^= 1;
778*fb1b10abSAndroid Build Coastguard Worker         roi.ref_frame[i] = (roi.ref_frame[i] + 1) % 4;
779*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), VPX_CODEC_OK);
780*fb1b10abSAndroid Build Coastguard Worker       }
781*fb1b10abSAndroid Build Coastguard Worker     }
782*fb1b10abSAndroid Build Coastguard Worker 
783*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_err_t expected_error;
784*fb1b10abSAndroid Build Coastguard Worker     for (const auto delta : { -64, 64, INT_MIN, INT_MAX }) {
785*fb1b10abSAndroid Build Coastguard Worker       expected_error = VPX_CODEC_INVALID_PARAM;
786*fb1b10abSAndroid Build Coastguard Worker       for (int i = 0; i < 8; ++i) {
787*fb1b10abSAndroid Build Coastguard Worker         roi.delta_q[i] = delta;
788*fb1b10abSAndroid Build Coastguard Worker         // The max segment count for VP8 is 4, the remainder of the entries are
789*fb1b10abSAndroid Build Coastguard Worker         // ignored.
790*fb1b10abSAndroid Build Coastguard Worker         if (i >= 4 && !IsVP9(codec.iface)) expected_error = VPX_CODEC_OK;
791*fb1b10abSAndroid Build Coastguard Worker 
792*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), expected_error)
793*fb1b10abSAndroid Build Coastguard Worker             << "delta_q[" << i << "]: " << delta;
794*fb1b10abSAndroid Build Coastguard Worker         roi.delta_q[i] = 0;
795*fb1b10abSAndroid Build Coastguard Worker 
796*fb1b10abSAndroid Build Coastguard Worker         roi.delta_lf[i] = delta;
797*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), expected_error)
798*fb1b10abSAndroid Build Coastguard Worker             << "delta_lf[" << i << "]: " << delta;
799*fb1b10abSAndroid Build Coastguard Worker         roi.delta_lf[i] = 0;
800*fb1b10abSAndroid Build Coastguard Worker       }
801*fb1b10abSAndroid Build Coastguard Worker     }
802*fb1b10abSAndroid Build Coastguard Worker 
803*fb1b10abSAndroid Build Coastguard Worker     // VP8 should ignore skip[] and ref_frame[] values.
804*fb1b10abSAndroid Build Coastguard Worker     expected_error =
805*fb1b10abSAndroid Build Coastguard Worker         IsVP9(codec.iface) ? VPX_CODEC_INVALID_PARAM : VPX_CODEC_OK;
806*fb1b10abSAndroid Build Coastguard Worker     for (const auto skip : { -2, 2, INT_MIN, INT_MAX }) {
807*fb1b10abSAndroid Build Coastguard Worker       for (int i = 0; i < 8; ++i) {
808*fb1b10abSAndroid Build Coastguard Worker         roi.skip[i] = skip;
809*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), expected_error)
810*fb1b10abSAndroid Build Coastguard Worker             << "skip[" << i << "]: " << skip;
811*fb1b10abSAndroid Build Coastguard Worker         roi.skip[i] = 0;
812*fb1b10abSAndroid Build Coastguard Worker       }
813*fb1b10abSAndroid Build Coastguard Worker     }
814*fb1b10abSAndroid Build Coastguard Worker 
815*fb1b10abSAndroid Build Coastguard Worker     // VP9 allows negative values to be used to disable segmentation.
816*fb1b10abSAndroid Build Coastguard Worker     for (int ref_frame = -3; ref_frame < 0; ++ref_frame) {
817*fb1b10abSAndroid Build Coastguard Worker       for (int i = 0; i < 8; ++i) {
818*fb1b10abSAndroid Build Coastguard Worker         roi.ref_frame[i] = ref_frame;
819*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), VPX_CODEC_OK)
820*fb1b10abSAndroid Build Coastguard Worker             << "ref_frame[" << i << "]: " << ref_frame;
821*fb1b10abSAndroid Build Coastguard Worker         roi.ref_frame[i] = 0;
822*fb1b10abSAndroid Build Coastguard Worker       }
823*fb1b10abSAndroid Build Coastguard Worker     }
824*fb1b10abSAndroid Build Coastguard Worker 
825*fb1b10abSAndroid Build Coastguard Worker     for (const auto ref_frame : { 4, INT_MIN, INT_MAX }) {
826*fb1b10abSAndroid Build Coastguard Worker       for (int i = 0; i < 8; ++i) {
827*fb1b10abSAndroid Build Coastguard Worker         roi.ref_frame[i] = ref_frame;
828*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), expected_error)
829*fb1b10abSAndroid Build Coastguard Worker             << "ref_frame[" << i << "]: " << ref_frame;
830*fb1b10abSAndroid Build Coastguard Worker         roi.ref_frame[i] = 0;
831*fb1b10abSAndroid Build Coastguard Worker       }
832*fb1b10abSAndroid Build Coastguard Worker     }
833*fb1b10abSAndroid Build Coastguard Worker 
834*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
835*fb1b10abSAndroid Build Coastguard Worker   }
836*fb1b10abSAndroid Build Coastguard Worker }
837*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,ConfigChangeThreadCount)838*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, ConfigChangeThreadCount) {
839*fb1b10abSAndroid Build Coastguard Worker   constexpr int kWidth = 1920;
840*fb1b10abSAndroid Build Coastguard Worker   constexpr int kHeight = 1080;
841*fb1b10abSAndroid Build Coastguard Worker 
842*fb1b10abSAndroid Build Coastguard Worker   for (const auto *iface : kCodecIfaces) {
843*fb1b10abSAndroid Build Coastguard Worker     SCOPED_TRACE(vpx_codec_iface_name(iface));
844*fb1b10abSAndroid Build Coastguard Worker     for (int i = 0; i < (IsVP9(iface) ? 2 : 1); ++i) {
845*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_enc_cfg_t cfg = {};
846*fb1b10abSAndroid Build Coastguard Worker       struct Encoder {
847*fb1b10abSAndroid Build Coastguard Worker         ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); }
848*fb1b10abSAndroid Build Coastguard Worker         vpx_codec_ctx_t ctx = {};
849*fb1b10abSAndroid Build Coastguard Worker       } enc;
850*fb1b10abSAndroid Build Coastguard Worker 
851*fb1b10abSAndroid Build Coastguard Worker       ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
852*fb1b10abSAndroid Build Coastguard Worker       EXPECT_NO_FATAL_FAILURE(
853*fb1b10abSAndroid Build Coastguard Worker           InitCodec(*iface, kWidth, kHeight, &enc.ctx, &cfg));
854*fb1b10abSAndroid Build Coastguard Worker       if (IsVP9(iface)) {
855*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc.ctx, VP9E_SET_TILE_COLUMNS, 6),
856*fb1b10abSAndroid Build Coastguard Worker                   VPX_CODEC_OK);
857*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc.ctx, VP9E_SET_ROW_MT, i),
858*fb1b10abSAndroid Build Coastguard Worker                   VPX_CODEC_OK);
859*fb1b10abSAndroid Build Coastguard Worker       }
860*fb1b10abSAndroid Build Coastguard Worker 
861*fb1b10abSAndroid Build Coastguard Worker       for (const auto threads : { 1, 4, 8, 6, 2, 1 }) {
862*fb1b10abSAndroid Build Coastguard Worker         cfg.g_threads = threads;
863*fb1b10abSAndroid Build Coastguard Worker         EXPECT_NO_FATAL_FAILURE(EncodeWithConfig(cfg, &enc.ctx))
864*fb1b10abSAndroid Build Coastguard Worker             << "iteration: " << i << " threads: " << threads;
865*fb1b10abSAndroid Build Coastguard Worker       }
866*fb1b10abSAndroid Build Coastguard Worker     }
867*fb1b10abSAndroid Build Coastguard Worker   }
868*fb1b10abSAndroid Build Coastguard Worker }
869*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,ConfigResizeChangeThreadCount)870*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, ConfigResizeChangeThreadCount) {
871*fb1b10abSAndroid Build Coastguard Worker   constexpr int kInitWidth = 1024;
872*fb1b10abSAndroid Build Coastguard Worker   constexpr int kInitHeight = 1024;
873*fb1b10abSAndroid Build Coastguard Worker 
874*fb1b10abSAndroid Build Coastguard Worker   for (const auto *iface : kCodecIfaces) {
875*fb1b10abSAndroid Build Coastguard Worker     SCOPED_TRACE(vpx_codec_iface_name(iface));
876*fb1b10abSAndroid Build Coastguard Worker     for (int i = 0; i < (IsVP9(iface) ? 2 : 1); ++i) {
877*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_enc_cfg_t cfg = {};
878*fb1b10abSAndroid Build Coastguard Worker       struct Encoder {
879*fb1b10abSAndroid Build Coastguard Worker         ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); }
880*fb1b10abSAndroid Build Coastguard Worker         vpx_codec_ctx_t ctx = {};
881*fb1b10abSAndroid Build Coastguard Worker       } enc;
882*fb1b10abSAndroid Build Coastguard Worker 
883*fb1b10abSAndroid Build Coastguard Worker       ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
884*fb1b10abSAndroid Build Coastguard Worker       // Start in threaded mode to ensure resolution and thread related
885*fb1b10abSAndroid Build Coastguard Worker       // allocations are updated correctly across changes in resolution and
886*fb1b10abSAndroid Build Coastguard Worker       // thread counts. See https://crbug.com/1486441.
887*fb1b10abSAndroid Build Coastguard Worker       cfg.g_threads = 4;
888*fb1b10abSAndroid Build Coastguard Worker       EXPECT_NO_FATAL_FAILURE(
889*fb1b10abSAndroid Build Coastguard Worker           InitCodec(*iface, kInitWidth, kInitHeight, &enc.ctx, &cfg));
890*fb1b10abSAndroid Build Coastguard Worker       if (IsVP9(iface)) {
891*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc.ctx, VP9E_SET_TILE_COLUMNS, 6),
892*fb1b10abSAndroid Build Coastguard Worker                   VPX_CODEC_OK);
893*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(vpx_codec_control_(&enc.ctx, VP9E_SET_ROW_MT, i),
894*fb1b10abSAndroid Build Coastguard Worker                   VPX_CODEC_OK);
895*fb1b10abSAndroid Build Coastguard Worker       }
896*fb1b10abSAndroid Build Coastguard Worker 
897*fb1b10abSAndroid Build Coastguard Worker       cfg.g_w = 1000;
898*fb1b10abSAndroid Build Coastguard Worker       cfg.g_h = 608;
899*fb1b10abSAndroid Build Coastguard Worker       EXPECT_EQ(vpx_codec_enc_config_set(&enc.ctx, &cfg), VPX_CODEC_OK)
900*fb1b10abSAndroid Build Coastguard Worker           << vpx_codec_error_detail(&enc.ctx);
901*fb1b10abSAndroid Build Coastguard Worker 
902*fb1b10abSAndroid Build Coastguard Worker       cfg.g_w = 1000;
903*fb1b10abSAndroid Build Coastguard Worker       cfg.g_h = 720;
904*fb1b10abSAndroid Build Coastguard Worker 
905*fb1b10abSAndroid Build Coastguard Worker       for (const auto threads : { 1, 4, 8, 6, 2, 1 }) {
906*fb1b10abSAndroid Build Coastguard Worker         cfg.g_threads = threads;
907*fb1b10abSAndroid Build Coastguard Worker         EXPECT_NO_FATAL_FAILURE(EncodeWithConfig(cfg, &enc.ctx))
908*fb1b10abSAndroid Build Coastguard Worker             << "iteration: " << i << " threads: " << threads;
909*fb1b10abSAndroid Build Coastguard Worker       }
910*fb1b10abSAndroid Build Coastguard Worker     }
911*fb1b10abSAndroid Build Coastguard Worker   }
912*fb1b10abSAndroid Build Coastguard Worker }
913*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,ConfigResizeBiggerAfterInit)914*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, ConfigResizeBiggerAfterInit) {
915*fb1b10abSAndroid Build Coastguard Worker   for (const auto *iface : kCodecIfaces) {
916*fb1b10abSAndroid Build Coastguard Worker     SCOPED_TRACE(vpx_codec_iface_name(iface));
917*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_enc_cfg_t cfg;
918*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_ctx_t enc;
919*fb1b10abSAndroid Build Coastguard Worker 
920*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
921*fb1b10abSAndroid Build Coastguard Worker     EXPECT_NO_FATAL_FAILURE(InitCodec(*iface, 1, 1, &enc, &cfg));
922*fb1b10abSAndroid Build Coastguard Worker 
923*fb1b10abSAndroid Build Coastguard Worker     cfg.g_w = 1920;
924*fb1b10abSAndroid Build Coastguard Worker     cfg.g_h = 1;
925*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_enc_config_set(&enc, &cfg),
926*fb1b10abSAndroid Build Coastguard Worker               IsVP9(iface) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM);
927*fb1b10abSAndroid Build Coastguard Worker 
928*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
929*fb1b10abSAndroid Build Coastguard Worker   }
930*fb1b10abSAndroid Build Coastguard Worker }
931*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,ConfigResizeBiggerAfterEncode)932*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, ConfigResizeBiggerAfterEncode) {
933*fb1b10abSAndroid Build Coastguard Worker   for (const auto *iface : kCodecIfaces) {
934*fb1b10abSAndroid Build Coastguard Worker     SCOPED_TRACE(vpx_codec_iface_name(iface));
935*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_enc_cfg_t cfg;
936*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_ctx_t enc;
937*fb1b10abSAndroid Build Coastguard Worker 
938*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
939*fb1b10abSAndroid Build Coastguard Worker     EXPECT_NO_FATAL_FAILURE(InitCodec(*iface, 1, 1, &enc, &cfg));
940*fb1b10abSAndroid Build Coastguard Worker     EXPECT_NO_FATAL_FAILURE(EncodeWithConfig(cfg, &enc));
941*fb1b10abSAndroid Build Coastguard Worker 
942*fb1b10abSAndroid Build Coastguard Worker     cfg.g_w = 1920;
943*fb1b10abSAndroid Build Coastguard Worker     cfg.g_h = 1;
944*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_enc_config_set(&enc, &cfg),
945*fb1b10abSAndroid Build Coastguard Worker               IsVP9(iface) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM);
946*fb1b10abSAndroid Build Coastguard Worker 
947*fb1b10abSAndroid Build Coastguard Worker     cfg.g_w = 1920;
948*fb1b10abSAndroid Build Coastguard Worker     cfg.g_h = 1080;
949*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_enc_config_set(&enc, &cfg),
950*fb1b10abSAndroid Build Coastguard Worker               IsVP9(iface) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM);
951*fb1b10abSAndroid Build Coastguard Worker 
952*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
953*fb1b10abSAndroid Build Coastguard Worker   }
954*fb1b10abSAndroid Build Coastguard Worker }
955*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,PtsSmallerThanInitialPts)956*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, PtsSmallerThanInitialPts) {
957*fb1b10abSAndroid Build Coastguard Worker   for (const auto *iface : kCodecIfaces) {
958*fb1b10abSAndroid Build Coastguard Worker     // Initialize libvpx encoder.
959*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_ctx_t enc;
960*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_enc_cfg_t cfg;
961*fb1b10abSAndroid Build Coastguard Worker 
962*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
963*fb1b10abSAndroid Build Coastguard Worker 
964*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
965*fb1b10abSAndroid Build Coastguard Worker 
966*fb1b10abSAndroid Build Coastguard Worker     // Create input image.
967*fb1b10abSAndroid Build Coastguard Worker     vpx_image_t *const image =
968*fb1b10abSAndroid Build Coastguard Worker         CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h);
969*fb1b10abSAndroid Build Coastguard Worker     ASSERT_NE(image, nullptr);
970*fb1b10abSAndroid Build Coastguard Worker 
971*fb1b10abSAndroid Build Coastguard Worker     // Encode frame.
972*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, image, 12, 1, 0, VPX_DL_BEST_QUALITY),
973*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_OK);
974*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, image, 13, 1, 0, VPX_DL_BEST_QUALITY),
975*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_OK);
976*fb1b10abSAndroid Build Coastguard Worker     // pts (10) is smaller than the initial pts (12).
977*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, image, 10, 1, 0, VPX_DL_BEST_QUALITY),
978*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_INVALID_PARAM);
979*fb1b10abSAndroid Build Coastguard Worker 
980*fb1b10abSAndroid Build Coastguard Worker     // Free resources.
981*fb1b10abSAndroid Build Coastguard Worker     vpx_img_free(image);
982*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
983*fb1b10abSAndroid Build Coastguard Worker   }
984*fb1b10abSAndroid Build Coastguard Worker }
985*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,PtsOrDurationTooBig)986*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, PtsOrDurationTooBig) {
987*fb1b10abSAndroid Build Coastguard Worker   for (const auto *iface : kCodecIfaces) {
988*fb1b10abSAndroid Build Coastguard Worker     // Initialize libvpx encoder.
989*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_ctx_t enc;
990*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_enc_cfg_t cfg;
991*fb1b10abSAndroid Build Coastguard Worker 
992*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
993*fb1b10abSAndroid Build Coastguard Worker 
994*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
995*fb1b10abSAndroid Build Coastguard Worker 
996*fb1b10abSAndroid Build Coastguard Worker     // Create input image.
997*fb1b10abSAndroid Build Coastguard Worker     vpx_image_t *const image =
998*fb1b10abSAndroid Build Coastguard Worker         CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h);
999*fb1b10abSAndroid Build Coastguard Worker     ASSERT_NE(image, nullptr);
1000*fb1b10abSAndroid Build Coastguard Worker 
1001*fb1b10abSAndroid Build Coastguard Worker     // Encode frame.
1002*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, image, 0, 1, 0, VPX_DL_BEST_QUALITY),
1003*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_OK);
1004*fb1b10abSAndroid Build Coastguard Worker #if ULONG_MAX > INT64_MAX
1005*fb1b10abSAndroid Build Coastguard Worker     // duration is too big.
1006*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, image, 0, (1ul << 63), 0, 2),
1007*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_INVALID_PARAM);
1008*fb1b10abSAndroid Build Coastguard Worker #endif
1009*fb1b10abSAndroid Build Coastguard Worker     // pts, when converted to ticks, is too big.
1010*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, image, INT64_MAX / 1000000 + 1, 1, 0,
1011*fb1b10abSAndroid Build Coastguard Worker                                VPX_DL_BEST_QUALITY),
1012*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_INVALID_PARAM);
1013*fb1b10abSAndroid Build Coastguard Worker #if ULONG_MAX > INT64_MAX
1014*fb1b10abSAndroid Build Coastguard Worker     // duration is too big.
1015*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(
1016*fb1b10abSAndroid Build Coastguard Worker         vpx_codec_encode(&enc, image, 0, (1ul << 63), 0, VPX_DL_BEST_QUALITY),
1017*fb1b10abSAndroid Build Coastguard Worker         VPX_CODEC_INVALID_PARAM);
1018*fb1b10abSAndroid Build Coastguard Worker     // pts + duration is too big.
1019*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(
1020*fb1b10abSAndroid Build Coastguard Worker         vpx_codec_encode(&enc, image, 1, INT64_MAX, 0, VPX_DL_BEST_QUALITY),
1021*fb1b10abSAndroid Build Coastguard Worker         VPX_CODEC_INVALID_PARAM);
1022*fb1b10abSAndroid Build Coastguard Worker #endif
1023*fb1b10abSAndroid Build Coastguard Worker     // pts + duration, when converted to ticks, is too big.
1024*fb1b10abSAndroid Build Coastguard Worker #if ULONG_MAX > INT64_MAX
1025*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, image, 0, 0xbd6b566b15c7, 0,
1026*fb1b10abSAndroid Build Coastguard Worker                                VPX_DL_BEST_QUALITY),
1027*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_INVALID_PARAM);
1028*fb1b10abSAndroid Build Coastguard Worker #endif
1029*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_encode(&enc, image, INT64_MAX / 1000000, 1, 0,
1030*fb1b10abSAndroid Build Coastguard Worker                                VPX_DL_BEST_QUALITY),
1031*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_INVALID_PARAM);
1032*fb1b10abSAndroid Build Coastguard Worker 
1033*fb1b10abSAndroid Build Coastguard Worker     // Free resources.
1034*fb1b10abSAndroid Build Coastguard Worker     vpx_img_free(image);
1035*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
1036*fb1b10abSAndroid Build Coastguard Worker   }
1037*fb1b10abSAndroid Build Coastguard Worker }
1038*fb1b10abSAndroid Build Coastguard Worker 
1039*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_ENCODER
1040*fb1b10abSAndroid Build Coastguard Worker // Frame size needed to trigger the overflow exceeds the max buffer allowed on
1041*fb1b10abSAndroid Build Coastguard Worker // 32-bit systems defined by VPX_MAX_ALLOCABLE_MEMORY
1042*fb1b10abSAndroid Build Coastguard Worker #if VPX_ARCH_X86_64 || VPX_ARCH_AARCH64
TEST(EncodeAPI,ConfigLargeTargetBitrateVp9)1043*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, ConfigLargeTargetBitrateVp9) {
1044*fb1b10abSAndroid Build Coastguard Worker #ifdef CHROMIUM
1045*fb1b10abSAndroid Build Coastguard Worker   GTEST_SKIP() << "Under Chromium's configuration the allocator is unable"
1046*fb1b10abSAndroid Build Coastguard Worker                   "to provide the space required for the frames below.";
1047*fb1b10abSAndroid Build Coastguard Worker #else
1048*fb1b10abSAndroid Build Coastguard Worker   constexpr int kWidth = 12383;
1049*fb1b10abSAndroid Build Coastguard Worker   constexpr int kHeight = 8192;
1050*fb1b10abSAndroid Build Coastguard Worker   constexpr auto *iface = &vpx_codec_vp9_cx_algo;
1051*fb1b10abSAndroid Build Coastguard Worker   SCOPED_TRACE(vpx_codec_iface_name(iface));
1052*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg = {};
1053*fb1b10abSAndroid Build Coastguard Worker   struct Encoder {
1054*fb1b10abSAndroid Build Coastguard Worker     ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); }
1055*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_ctx_t ctx = {};
1056*fb1b10abSAndroid Build Coastguard Worker   } enc;
1057*fb1b10abSAndroid Build Coastguard Worker 
1058*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
1059*fb1b10abSAndroid Build Coastguard Worker   // The following setting will cause avg_frame_bandwidth in rate control to be
1060*fb1b10abSAndroid Build Coastguard Worker   // larger than INT_MAX
1061*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = INT_MAX;
1062*fb1b10abSAndroid Build Coastguard Worker   // Framerate 0.1 (equivalent to timebase 10) is the smallest framerate allowed
1063*fb1b10abSAndroid Build Coastguard Worker   // by libvpx
1064*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.den = 1;
1065*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.num = 10;
1066*fb1b10abSAndroid Build Coastguard Worker   EXPECT_NO_FATAL_FAILURE(InitCodec(*iface, kWidth, kHeight, &enc.ctx, &cfg))
1067*fb1b10abSAndroid Build Coastguard Worker       << "target bitrate: " << cfg.rc_target_bitrate << " framerate: "
1068*fb1b10abSAndroid Build Coastguard Worker       << static_cast<double>(cfg.g_timebase.den) / cfg.g_timebase.num;
1069*fb1b10abSAndroid Build Coastguard Worker #endif  // defined(CHROMIUM)
1070*fb1b10abSAndroid Build Coastguard Worker }
1071*fb1b10abSAndroid Build Coastguard Worker #endif  // VPX_ARCH_X86_64 || VPX_ARCH_AARCH64
1072*fb1b10abSAndroid Build Coastguard Worker 
1073*fb1b10abSAndroid Build Coastguard Worker // Emulates the WebCodecs VideoEncoder interface.
1074*fb1b10abSAndroid Build Coastguard Worker class VP9Encoder {
1075*fb1b10abSAndroid Build Coastguard Worker  public:
VP9Encoder(int speed)1076*fb1b10abSAndroid Build Coastguard Worker   explicit VP9Encoder(int speed)
1077*fb1b10abSAndroid Build Coastguard Worker       : speed_(speed), row_mt_(0), bit_depth_(VPX_BITS_8),
1078*fb1b10abSAndroid Build Coastguard Worker         fmt_(VPX_IMG_FMT_I420) {}
1079*fb1b10abSAndroid Build Coastguard Worker   // The image format `fmt` must not have the VPX_IMG_FMT_HIGHBITDEPTH bit set.
1080*fb1b10abSAndroid Build Coastguard Worker   // If bit_depth > 8, we will set the VPX_IMG_FMT_HIGHBITDEPTH bit before
1081*fb1b10abSAndroid Build Coastguard Worker   // passing the image format to vpx_img_alloc().
VP9Encoder(int speed,unsigned int row_mt,vpx_bit_depth_t bit_depth,vpx_img_fmt_t fmt)1082*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder(int speed, unsigned int row_mt, vpx_bit_depth_t bit_depth,
1083*fb1b10abSAndroid Build Coastguard Worker              vpx_img_fmt_t fmt)
1084*fb1b10abSAndroid Build Coastguard Worker       : speed_(speed), row_mt_(row_mt), bit_depth_(bit_depth), fmt_(fmt) {}
1085*fb1b10abSAndroid Build Coastguard Worker   ~VP9Encoder();
1086*fb1b10abSAndroid Build Coastguard Worker 
1087*fb1b10abSAndroid Build Coastguard Worker   void Configure(unsigned int threads, unsigned int width, unsigned int height,
1088*fb1b10abSAndroid Build Coastguard Worker                  vpx_rc_mode end_usage, vpx_enc_deadline_t deadline);
1089*fb1b10abSAndroid Build Coastguard Worker   void Encode(bool key_frame);
1090*fb1b10abSAndroid Build Coastguard Worker 
1091*fb1b10abSAndroid Build Coastguard Worker  private:
1092*fb1b10abSAndroid Build Coastguard Worker   const int speed_;
1093*fb1b10abSAndroid Build Coastguard Worker   const unsigned int row_mt_;
1094*fb1b10abSAndroid Build Coastguard Worker   const vpx_bit_depth_t bit_depth_;
1095*fb1b10abSAndroid Build Coastguard Worker   const vpx_img_fmt_t fmt_;
1096*fb1b10abSAndroid Build Coastguard Worker   bool initialized_ = false;
1097*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg_;
1098*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc_;
1099*fb1b10abSAndroid Build Coastguard Worker   int frame_index_ = 0;
1100*fb1b10abSAndroid Build Coastguard Worker   vpx_enc_deadline_t deadline_ = 0;
1101*fb1b10abSAndroid Build Coastguard Worker };
1102*fb1b10abSAndroid Build Coastguard Worker 
~VP9Encoder()1103*fb1b10abSAndroid Build Coastguard Worker VP9Encoder::~VP9Encoder() {
1104*fb1b10abSAndroid Build Coastguard Worker   if (initialized_) {
1105*fb1b10abSAndroid Build Coastguard Worker     EXPECT_EQ(vpx_codec_destroy(&enc_), VPX_CODEC_OK);
1106*fb1b10abSAndroid Build Coastguard Worker   }
1107*fb1b10abSAndroid Build Coastguard Worker }
1108*fb1b10abSAndroid Build Coastguard Worker 
Configure(unsigned int threads,unsigned int width,unsigned int height,vpx_rc_mode end_usage,vpx_enc_deadline_t deadline)1109*fb1b10abSAndroid Build Coastguard Worker void VP9Encoder::Configure(unsigned int threads, unsigned int width,
1110*fb1b10abSAndroid Build Coastguard Worker                            unsigned int height, vpx_rc_mode end_usage,
1111*fb1b10abSAndroid Build Coastguard Worker                            vpx_enc_deadline_t deadline) {
1112*fb1b10abSAndroid Build Coastguard Worker   deadline_ = deadline;
1113*fb1b10abSAndroid Build Coastguard Worker 
1114*fb1b10abSAndroid Build Coastguard Worker   if (!initialized_) {
1115*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(fmt_ & VPX_IMG_FMT_HIGHBITDEPTH, 0);
1116*fb1b10abSAndroid Build Coastguard Worker     const bool high_bit_depth = bit_depth_ > VPX_BITS_8;
1117*fb1b10abSAndroid Build Coastguard Worker     const bool is_420 = fmt_ == VPX_IMG_FMT_I420;
1118*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_iface_t *const iface = vpx_codec_vp9_cx();
1119*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg_, /*usage=*/0),
1120*fb1b10abSAndroid Build Coastguard Worker               VPX_CODEC_OK);
1121*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_threads = threads;
1122*fb1b10abSAndroid Build Coastguard Worker     // In profiles 0 and 2, only 4:2:0 format is allowed. In profiles 1 and 3,
1123*fb1b10abSAndroid Build Coastguard Worker     // all other subsampling formats are allowed. In profiles 0 and 1, only bit
1124*fb1b10abSAndroid Build Coastguard Worker     // depth 8 is allowed. In profiles 2 and 3, only bit depths 10 and 12 are
1125*fb1b10abSAndroid Build Coastguard Worker     // allowed.
1126*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_profile = 2 * high_bit_depth + !is_420;
1127*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_w = width;
1128*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_h = height;
1129*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_bit_depth = bit_depth_;
1130*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_input_bit_depth = bit_depth_;
1131*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_timebase.num = 1;
1132*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_timebase.den = 1000 * 1000;  // microseconds
1133*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_pass = VPX_RC_ONE_PASS;
1134*fb1b10abSAndroid Build Coastguard Worker     cfg_.g_lag_in_frames = 0;
1135*fb1b10abSAndroid Build Coastguard Worker     cfg_.rc_end_usage = end_usage;
1136*fb1b10abSAndroid Build Coastguard Worker     cfg_.rc_min_quantizer = 2;
1137*fb1b10abSAndroid Build Coastguard Worker     cfg_.rc_max_quantizer = 58;
1138*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(
1139*fb1b10abSAndroid Build Coastguard Worker         vpx_codec_enc_init(&enc_, iface, &cfg_,
1140*fb1b10abSAndroid Build Coastguard Worker                            high_bit_depth ? VPX_CODEC_USE_HIGHBITDEPTH : 0),
1141*fb1b10abSAndroid Build Coastguard Worker         VPX_CODEC_OK);
1142*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_control(&enc_, VP8E_SET_CPUUSED, speed_), VPX_CODEC_OK);
1143*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(vpx_codec_control(&enc_, VP9E_SET_ROW_MT, row_mt_), VPX_CODEC_OK);
1144*fb1b10abSAndroid Build Coastguard Worker     initialized_ = true;
1145*fb1b10abSAndroid Build Coastguard Worker     return;
1146*fb1b10abSAndroid Build Coastguard Worker   }
1147*fb1b10abSAndroid Build Coastguard Worker 
1148*fb1b10abSAndroid Build Coastguard Worker   cfg_.g_threads = threads;
1149*fb1b10abSAndroid Build Coastguard Worker   cfg_.g_w = width;
1150*fb1b10abSAndroid Build Coastguard Worker   cfg_.g_h = height;
1151*fb1b10abSAndroid Build Coastguard Worker   cfg_.rc_end_usage = end_usage;
1152*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_set(&enc_, &cfg_), VPX_CODEC_OK)
1153*fb1b10abSAndroid Build Coastguard Worker       << vpx_codec_error_detail(&enc_);
1154*fb1b10abSAndroid Build Coastguard Worker }
1155*fb1b10abSAndroid Build Coastguard Worker 
Encode(bool key_frame)1156*fb1b10abSAndroid Build Coastguard Worker void VP9Encoder::Encode(bool key_frame) {
1157*fb1b10abSAndroid Build Coastguard Worker   assert(initialized_);
1158*fb1b10abSAndroid Build Coastguard Worker   const vpx_codec_cx_pkt_t *pkt;
1159*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *image = CreateImage(bit_depth_, fmt_, cfg_.g_w, cfg_.g_h);
1160*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
1161*fb1b10abSAndroid Build Coastguard Worker   const vpx_enc_frame_flags_t frame_flags = key_frame ? VPX_EFLAG_FORCE_KF : 0;
1162*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(
1163*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_encode(&enc_, image, frame_index_, 1, frame_flags, deadline_),
1164*fb1b10abSAndroid Build Coastguard Worker       VPX_CODEC_OK);
1165*fb1b10abSAndroid Build Coastguard Worker   ++frame_index_;
1166*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iter_t iter = nullptr;
1167*fb1b10abSAndroid Build Coastguard Worker   while ((pkt = vpx_codec_get_cx_data(&enc_, &iter)) != nullptr) {
1168*fb1b10abSAndroid Build Coastguard Worker     ASSERT_EQ(pkt->kind, VPX_CODEC_CX_FRAME_PKT);
1169*fb1b10abSAndroid Build Coastguard Worker   }
1170*fb1b10abSAndroid Build Coastguard Worker   vpx_img_free(image);
1171*fb1b10abSAndroid Build Coastguard Worker }
1172*fb1b10abSAndroid Build Coastguard Worker 
1173*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz.
TEST(EncodeAPI,PrevMiCheckNullptr)1174*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, PrevMiCheckNullptr) {
1175*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(0);
1176*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1554, 644, VPX_VBR, VPX_DL_REALTIME);
1177*fb1b10abSAndroid Build Coastguard Worker 
1178*fb1b10abSAndroid Build Coastguard Worker   // First step: encode, without forcing KF.
1179*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1180*fb1b10abSAndroid Build Coastguard Worker   // Second step: change config
1181*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1131, 644, VPX_CBR, VPX_DL_GOOD_QUALITY);
1182*fb1b10abSAndroid Build Coastguard Worker   // Third step: encode, without forcing KF
1183*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1184*fb1b10abSAndroid Build Coastguard Worker }
1185*fb1b10abSAndroid Build Coastguard Worker 
1186*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/310477034.
1187*fb1b10abSAndroid Build Coastguard Worker // Encode a few frames with multiple change config calls
1188*fb1b10abSAndroid Build Coastguard Worker // with different frame sizes.
TEST(EncodeAPI,MultipleChangeConfigResize)1189*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, MultipleChangeConfigResize) {
1190*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(3);
1191*fb1b10abSAndroid Build Coastguard Worker 
1192*fb1b10abSAndroid Build Coastguard Worker   // Set initial config.
1193*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(3, 41, 1, VPX_VBR, VPX_DL_REALTIME);
1194*fb1b10abSAndroid Build Coastguard Worker 
1195*fb1b10abSAndroid Build Coastguard Worker   // Encode first frame.
1196*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1197*fb1b10abSAndroid Build Coastguard Worker 
1198*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1199*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 31, 1, VPX_VBR, VPX_DL_GOOD_QUALITY);
1200*fb1b10abSAndroid Build Coastguard Worker 
1201*fb1b10abSAndroid Build Coastguard Worker   // Change config again.
1202*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 17, 1, VPX_CBR, VPX_DL_REALTIME);
1203*fb1b10abSAndroid Build Coastguard Worker 
1204*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame with new config, set delta frame.
1205*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1206*fb1b10abSAndroid Build Coastguard Worker 
1207*fb1b10abSAndroid Build Coastguard Worker   // Encode 3rd frame with same config, set delta frame.
1208*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1209*fb1b10abSAndroid Build Coastguard Worker }
1210*fb1b10abSAndroid Build Coastguard Worker 
1211*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/310663186.
1212*fb1b10abSAndroid Build Coastguard Worker // Encode set of frames while varying the deadline on the fly from
1213*fb1b10abSAndroid Build Coastguard Worker // good to realtime to best and back to realtime.
TEST(EncodeAPI,DynamicDeadlineChange)1214*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, DynamicDeadlineChange) {
1215*fb1b10abSAndroid Build Coastguard Worker   // Use realtime speed: 5 to 9.
1216*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(5);
1217*fb1b10abSAndroid Build Coastguard Worker 
1218*fb1b10abSAndroid Build Coastguard Worker   // Set initial config, in particular set deadline to GOOD mode.
1219*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_GOOD_QUALITY);
1220*fb1b10abSAndroid Build Coastguard Worker 
1221*fb1b10abSAndroid Build Coastguard Worker   // Encode 1st frame.
1222*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1223*fb1b10abSAndroid Build Coastguard Worker 
1224*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame, delta frame.
1225*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1226*fb1b10abSAndroid Build Coastguard Worker 
1227*fb1b10abSAndroid Build Coastguard Worker   // Change config: change deadline to REALTIME.
1228*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_REALTIME);
1229*fb1b10abSAndroid Build Coastguard Worker 
1230*fb1b10abSAndroid Build Coastguard Worker   // Encode 3rd frame with new config, set key frame.
1231*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1232*fb1b10abSAndroid Build Coastguard Worker 
1233*fb1b10abSAndroid Build Coastguard Worker   // Encode 4th frame with same config, delta frame.
1234*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1235*fb1b10abSAndroid Build Coastguard Worker 
1236*fb1b10abSAndroid Build Coastguard Worker   // Encode 5th frame with same config, key frame.
1237*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1238*fb1b10abSAndroid Build Coastguard Worker 
1239*fb1b10abSAndroid Build Coastguard Worker   // Change config: change deadline to BEST.
1240*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_BEST_QUALITY);
1241*fb1b10abSAndroid Build Coastguard Worker 
1242*fb1b10abSAndroid Build Coastguard Worker   // Encode 6th frame with new config, set delta frame.
1243*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1244*fb1b10abSAndroid Build Coastguard Worker 
1245*fb1b10abSAndroid Build Coastguard Worker   // Change config: change deadline to REALTIME.
1246*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_REALTIME);
1247*fb1b10abSAndroid Build Coastguard Worker 
1248*fb1b10abSAndroid Build Coastguard Worker   // Encode 7th frame with new config, set delta frame.
1249*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1250*fb1b10abSAndroid Build Coastguard Worker 
1251*fb1b10abSAndroid Build Coastguard Worker   // Encode 8th frame with new config, set key frame.
1252*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1253*fb1b10abSAndroid Build Coastguard Worker 
1254*fb1b10abSAndroid Build Coastguard Worker   // Encode 9th frame with new config, set delta frame.
1255*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1256*fb1b10abSAndroid Build Coastguard Worker }
1257*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer310340241)1258*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer310340241) {
1259*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(-6);
1260*fb1b10abSAndroid Build Coastguard Worker 
1261*fb1b10abSAndroid Build Coastguard Worker   // Set initial config, in particular set deadline to GOOD mode.
1262*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_GOOD_QUALITY);
1263*fb1b10abSAndroid Build Coastguard Worker 
1264*fb1b10abSAndroid Build Coastguard Worker   // Encode 1st frame.
1265*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1266*fb1b10abSAndroid Build Coastguard Worker 
1267*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame, delta frame.
1268*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1269*fb1b10abSAndroid Build Coastguard Worker 
1270*fb1b10abSAndroid Build Coastguard Worker   // Change config: change deadline to REALTIME.
1271*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_REALTIME);
1272*fb1b10abSAndroid Build Coastguard Worker 
1273*fb1b10abSAndroid Build Coastguard Worker   // Encode 3rd frame with new config, set key frame.
1274*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1275*fb1b10abSAndroid Build Coastguard Worker }
1276*fb1b10abSAndroid Build Coastguard Worker 
1277*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/312517065.
TEST(EncodeAPI,Buganizer312517065)1278*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer312517065) {
1279*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(4);
1280*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1060, 437, VPX_CBR, VPX_DL_REALTIME);
1281*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1282*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(10, 33, 437, VPX_VBR, VPX_DL_GOOD_QUALITY);
1283*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1284*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(6, 327, 269, VPX_VBR, VPX_DL_GOOD_QUALITY);
1285*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(15, 1060, 437, VPX_CBR, VPX_DL_REALTIME);
1286*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1287*fb1b10abSAndroid Build Coastguard Worker }
1288*fb1b10abSAndroid Build Coastguard Worker 
1289*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/311489136.
1290*fb1b10abSAndroid Build Coastguard Worker // Encode a few frames with multiple change config calls
1291*fb1b10abSAndroid Build Coastguard Worker // with different frame sizes.
TEST(EncodeAPI,Buganizer311489136)1292*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer311489136) {
1293*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(1);
1294*fb1b10abSAndroid Build Coastguard Worker 
1295*fb1b10abSAndroid Build Coastguard Worker   // Set initial config.
1296*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(12, 1678, 620, VPX_VBR, VPX_DL_GOOD_QUALITY);
1297*fb1b10abSAndroid Build Coastguard Worker 
1298*fb1b10abSAndroid Build Coastguard Worker   // Encode first frame.
1299*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1300*fb1b10abSAndroid Build Coastguard Worker 
1301*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1302*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(3, 1678, 202, VPX_CBR, VPX_DL_GOOD_QUALITY);
1303*fb1b10abSAndroid Build Coastguard Worker 
1304*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame with new config, set delta frame.
1305*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1306*fb1b10abSAndroid Build Coastguard Worker 
1307*fb1b10abSAndroid Build Coastguard Worker   // Change config again.
1308*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(8, 1037, 476, VPX_CBR, VPX_DL_REALTIME);
1309*fb1b10abSAndroid Build Coastguard Worker 
1310*fb1b10abSAndroid Build Coastguard Worker   // Encode 3rd frame with new config, set delta frame.
1311*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1312*fb1b10abSAndroid Build Coastguard Worker 
1313*fb1b10abSAndroid Build Coastguard Worker   // Change config again.
1314*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 580, 620, VPX_CBR, VPX_DL_GOOD_QUALITY);
1315*fb1b10abSAndroid Build Coastguard Worker 
1316*fb1b10abSAndroid Build Coastguard Worker   // Encode 4th frame with same config, set delta frame.
1317*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1318*fb1b10abSAndroid Build Coastguard Worker }
1319*fb1b10abSAndroid Build Coastguard Worker 
1320*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/312656387.
1321*fb1b10abSAndroid Build Coastguard Worker // Encode a few frames with multiple change config calls
1322*fb1b10abSAndroid Build Coastguard Worker // with different frame sizes.
TEST(EncodeAPI,Buganizer312656387)1323*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer312656387) {
1324*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(1);
1325*fb1b10abSAndroid Build Coastguard Worker 
1326*fb1b10abSAndroid Build Coastguard Worker   // Set initial config.
1327*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 1, 1024, VPX_CBR, VPX_DL_REALTIME);
1328*fb1b10abSAndroid Build Coastguard Worker 
1329*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1330*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(15, 1, 1024, VPX_VBR, VPX_DL_REALTIME);
1331*fb1b10abSAndroid Build Coastguard Worker 
1332*fb1b10abSAndroid Build Coastguard Worker   // Encode first frame.
1333*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1334*fb1b10abSAndroid Build Coastguard Worker 
1335*fb1b10abSAndroid Build Coastguard Worker   // Change config again.
1336*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(14, 1, 595, VPX_VBR, VPX_DL_GOOD_QUALITY);
1337*fb1b10abSAndroid Build Coastguard Worker 
1338*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame with new config.
1339*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1340*fb1b10abSAndroid Build Coastguard Worker 
1341*fb1b10abSAndroid Build Coastguard Worker   // Change config again.
1342*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(2, 1, 1024, VPX_VBR, VPX_DL_GOOD_QUALITY);
1343*fb1b10abSAndroid Build Coastguard Worker 
1344*fb1b10abSAndroid Build Coastguard Worker   // Encode 3rd frame with new config, set delta frame.
1345*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1346*fb1b10abSAndroid Build Coastguard Worker }
1347*fb1b10abSAndroid Build Coastguard Worker 
1348*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/310329177.
1349*fb1b10abSAndroid Build Coastguard Worker // Encode a few frames with multiple change config calls
1350*fb1b10abSAndroid Build Coastguard Worker // with different frame sizes.
TEST(EncodeAPI,Buganizer310329177)1351*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer310329177) {
1352*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(6);
1353*fb1b10abSAndroid Build Coastguard Worker 
1354*fb1b10abSAndroid Build Coastguard Worker   // Set initial config.
1355*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(10, 41, 1, VPX_VBR, VPX_DL_REALTIME);
1356*fb1b10abSAndroid Build Coastguard Worker 
1357*fb1b10abSAndroid Build Coastguard Worker   // Encode first frame.
1358*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1359*fb1b10abSAndroid Build Coastguard Worker 
1360*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1361*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 1, 1, VPX_VBR, VPX_DL_REALTIME);
1362*fb1b10abSAndroid Build Coastguard Worker 
1363*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame with new config, set delta frame.
1364*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1365*fb1b10abSAndroid Build Coastguard Worker }
1366*fb1b10abSAndroid Build Coastguard Worker 
1367*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/311394513.
1368*fb1b10abSAndroid Build Coastguard Worker // Encode a few frames with multiple change config calls
1369*fb1b10abSAndroid Build Coastguard Worker // with different frame sizes.
TEST(EncodeAPI,Buganizer311394513)1370*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer311394513) {
1371*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(-7);
1372*fb1b10abSAndroid Build Coastguard Worker 
1373*fb1b10abSAndroid Build Coastguard Worker   // Set initial config.
1374*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 5, 9, VPX_VBR, VPX_DL_REALTIME);
1375*fb1b10abSAndroid Build Coastguard Worker 
1376*fb1b10abSAndroid Build Coastguard Worker   // Encode first frame.
1377*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1378*fb1b10abSAndroid Build Coastguard Worker 
1379*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1380*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(5, 2, 1, VPX_VBR, VPX_DL_REALTIME);
1381*fb1b10abSAndroid Build Coastguard Worker 
1382*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame with new config.
1383*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1384*fb1b10abSAndroid Build Coastguard Worker }
1385*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer311985118)1386*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer311985118) {
1387*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(0);
1388*fb1b10abSAndroid Build Coastguard Worker 
1389*fb1b10abSAndroid Build Coastguard Worker   // Set initial config, in particular set deadline to GOOD mode.
1390*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(12, 1678, 620, VPX_VBR, VPX_DL_GOOD_QUALITY);
1391*fb1b10abSAndroid Build Coastguard Worker 
1392*fb1b10abSAndroid Build Coastguard Worker   // Encode 1st frame.
1393*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1394*fb1b10abSAndroid Build Coastguard Worker 
1395*fb1b10abSAndroid Build Coastguard Worker   // Change config: change threads and width.
1396*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1574, 620, VPX_VBR, VPX_DL_GOOD_QUALITY);
1397*fb1b10abSAndroid Build Coastguard Worker 
1398*fb1b10abSAndroid Build Coastguard Worker   // Change config: change threads, width and height.
1399*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 837, 432, VPX_VBR, VPX_DL_GOOD_QUALITY);
1400*fb1b10abSAndroid Build Coastguard Worker 
1401*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame.
1402*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1403*fb1b10abSAndroid Build Coastguard Worker }
1404*fb1b10abSAndroid Build Coastguard Worker 
1405*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/314857577.
1406*fb1b10abSAndroid Build Coastguard Worker // Encode a few frames with multiple change config calls
1407*fb1b10abSAndroid Build Coastguard Worker // with different frame sizes.
TEST(EncodeAPI,Buganizer314857577)1408*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer314857577) {
1409*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(4);
1410*fb1b10abSAndroid Build Coastguard Worker 
1411*fb1b10abSAndroid Build Coastguard Worker   // Set initial config.
1412*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(12, 1060, 437, VPX_VBR, VPX_DL_REALTIME);
1413*fb1b10abSAndroid Build Coastguard Worker 
1414*fb1b10abSAndroid Build Coastguard Worker   // Encode first frame.
1415*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1416*fb1b10abSAndroid Build Coastguard Worker 
1417*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1418*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 1060, 1, VPX_CBR, VPX_DL_REALTIME);
1419*fb1b10abSAndroid Build Coastguard Worker 
1420*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame with new config.
1421*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1422*fb1b10abSAndroid Build Coastguard Worker 
1423*fb1b10abSAndroid Build Coastguard Worker   // Encode 3rd frame with new config.
1424*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1425*fb1b10abSAndroid Build Coastguard Worker 
1426*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1427*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(15, 33, 437, VPX_VBR, VPX_DL_GOOD_QUALITY);
1428*fb1b10abSAndroid Build Coastguard Worker 
1429*fb1b10abSAndroid Build Coastguard Worker   // Encode 4th frame with new config.
1430*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1431*fb1b10abSAndroid Build Coastguard Worker 
1432*fb1b10abSAndroid Build Coastguard Worker   // Encode 5th frame with new config.
1433*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1434*fb1b10abSAndroid Build Coastguard Worker 
1435*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1436*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(5, 327, 269, VPX_VBR, VPX_DL_REALTIME);
1437*fb1b10abSAndroid Build Coastguard Worker 
1438*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1439*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(15, 1060, 437, VPX_CBR, VPX_DL_REALTIME);
1440*fb1b10abSAndroid Build Coastguard Worker 
1441*fb1b10abSAndroid Build Coastguard Worker   // Encode 6th frame with new config.
1442*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1443*fb1b10abSAndroid Build Coastguard Worker 
1444*fb1b10abSAndroid Build Coastguard Worker   // Encode 7th frame with new config.
1445*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1446*fb1b10abSAndroid Build Coastguard Worker 
1447*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1448*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(4, 1060, 437, VPX_VBR, VPX_DL_REALTIME);
1449*fb1b10abSAndroid Build Coastguard Worker 
1450*fb1b10abSAndroid Build Coastguard Worker   // Encode 8th frame with new config.
1451*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1452*fb1b10abSAndroid Build Coastguard Worker }
1453*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer312875957PredBufferStride)1454*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer312875957PredBufferStride) {
1455*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(-1);
1456*fb1b10abSAndroid Build Coastguard Worker 
1457*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(12, 1678, 620, VPX_VBR, VPX_DL_REALTIME);
1458*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1459*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1460*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 456, 486, VPX_VBR, VPX_DL_REALTIME);
1461*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1462*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1678, 620, VPX_CBR, 1000000);
1463*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1464*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1465*fb1b10abSAndroid Build Coastguard Worker }
1466*fb1b10abSAndroid Build Coastguard Worker 
1467*fb1b10abSAndroid Build Coastguard Worker // This is a test case from clusterfuzz: based on b/311294795
1468*fb1b10abSAndroid Build Coastguard Worker // Encode a few frames with multiple change config calls
1469*fb1b10abSAndroid Build Coastguard Worker // with different frame sizes.
TEST(EncodeAPI,Buganizer311294795)1470*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer311294795) {
1471*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(1);
1472*fb1b10abSAndroid Build Coastguard Worker 
1473*fb1b10abSAndroid Build Coastguard Worker   // Set initial config.
1474*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(12, 1678, 620, VPX_VBR, VPX_DL_REALTIME);
1475*fb1b10abSAndroid Build Coastguard Worker 
1476*fb1b10abSAndroid Build Coastguard Worker   // Encode first frame.
1477*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1478*fb1b10abSAndroid Build Coastguard Worker 
1479*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1480*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 632, 620, VPX_VBR, VPX_DL_GOOD_QUALITY);
1481*fb1b10abSAndroid Build Coastguard Worker 
1482*fb1b10abSAndroid Build Coastguard Worker   // Encode 2nd frame with new config
1483*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1484*fb1b10abSAndroid Build Coastguard Worker 
1485*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1486*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 1678, 342, VPX_VBR, VPX_DL_GOOD_QUALITY);
1487*fb1b10abSAndroid Build Coastguard Worker 
1488*fb1b10abSAndroid Build Coastguard Worker   // Encode 3rd frame with new config.
1489*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1490*fb1b10abSAndroid Build Coastguard Worker 
1491*fb1b10abSAndroid Build Coastguard Worker   // Change config.
1492*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1574, 618, VPX_VBR, VPX_DL_REALTIME);
1493*fb1b10abSAndroid Build Coastguard Worker   // Encode more frames with new config.
1494*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1495*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1496*fb1b10abSAndroid Build Coastguard Worker }
1497*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer317105128)1498*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer317105128) {
1499*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(-9);
1500*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_CBR, VPX_DL_GOOD_QUALITY);
1501*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 1920, 1, VPX_CBR, VPX_DL_REALTIME);
1502*fb1b10abSAndroid Build Coastguard Worker }
1503*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer319964497)1504*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer319964497) {
1505*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(7);
1506*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/1, /*width=*/320, /*height=*/240, VPX_VBR,
1507*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1508*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1509*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1510*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1511*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/1, /*width=*/1, /*height=*/1, VPX_VBR,
1512*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1513*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1514*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/1, /*width=*/2, /*height=*/2, VPX_CBR,
1515*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1516*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1517*fb1b10abSAndroid Build Coastguard Worker }
1518*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer329088759RowMT0)1519*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer329088759RowMT0) {
1520*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(8, 0, VPX_BITS_8, VPX_IMG_FMT_I444);
1521*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/8, /*width=*/1686, /*height=*/398, VPX_VBR,
1522*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1523*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1524*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1525*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/0, /*width=*/1686, /*height=*/1, VPX_VBR,
1526*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1527*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1528*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/0, /*width=*/1482, /*height=*/113, VPX_CBR,
1529*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1530*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1531*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/0, /*width=*/881, /*height=*/59, VPX_CBR,
1532*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1533*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/13, /*width=*/1271, /*height=*/385, VPX_CBR,
1534*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1535*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1536*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/2, /*width=*/1, /*height=*/62, VPX_VBR,
1537*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1538*fb1b10abSAndroid Build Coastguard Worker }
1539*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer329088759RowMT1)1540*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer329088759RowMT1) {
1541*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(8, 1, VPX_BITS_8, VPX_IMG_FMT_I444);
1542*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/8, /*width=*/1686, /*height=*/398, VPX_VBR,
1543*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1544*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1545*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1546*fb1b10abSAndroid Build Coastguard Worker   // Needs to set threads to non-zero to repro the issue.
1547*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/2, /*width=*/1686, /*height=*/1, VPX_VBR,
1548*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1549*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1550*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/2, /*width=*/1482, /*height=*/113, VPX_CBR,
1551*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1552*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1553*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/2, /*width=*/881, /*height=*/59, VPX_CBR,
1554*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1555*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/13, /*width=*/1271, /*height=*/385, VPX_CBR,
1556*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1557*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1558*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/2, /*width=*/1, /*height=*/62, VPX_VBR,
1559*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1560*fb1b10abSAndroid Build Coastguard Worker }
1561*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer331086799)1562*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer331086799) {
1563*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(6, 1, VPX_BITS_8, VPX_IMG_FMT_I420);
1564*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1385, 1, VPX_CBR, VPX_DL_REALTIME);
1565*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_REALTIME);
1566*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1567*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(16, 1385, 1, VPX_VBR, VPX_DL_GOOD_QUALITY);
1568*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1569*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1570*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1, 1, VPX_CBR, VPX_DL_REALTIME);
1571*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1572*fb1b10abSAndroid Build Coastguard Worker }
1573*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer331108729)1574*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer331108729) {
1575*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(1, 1, VPX_BITS_8, VPX_IMG_FMT_I422);
1576*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(0, 1919, 260, VPX_VBR, VPX_DL_REALTIME);
1577*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(9, 440, 1, VPX_CBR, VPX_DL_GOOD_QUALITY);
1578*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(true);
1579*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(8, 1919, 260, VPX_VBR, VPX_DL_REALTIME);
1580*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(false);
1581*fb1b10abSAndroid Build Coastguard Worker }
1582*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer331108922BitDepth8)1583*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer331108922BitDepth8) {
1584*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(9, 1, VPX_BITS_8, VPX_IMG_FMT_I420);
1585*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/1, /*width=*/1, /*height=*/1080, VPX_VBR,
1586*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1587*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1588*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/0, /*width=*/1, /*height=*/1080, VPX_CBR,
1589*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_GOOD_QUALITY);
1590*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/1, /*height=*/394, VPX_CBR,
1591*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1592*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1593*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1594*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/1, /*height=*/798, VPX_CBR,
1595*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1596*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1597*fb1b10abSAndroid Build Coastguard Worker }
1598*fb1b10abSAndroid Build Coastguard Worker 
1599*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
TEST(EncodeAPI,Buganizer329674887RowMT0BitDepth12)1600*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer329674887RowMT0BitDepth12) {
1601*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(8, 0, VPX_BITS_12, VPX_IMG_FMT_I444);
1602*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/2, /*width=*/1030, /*height=*/583, VPX_VBR,
1603*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1604*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1605*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/0, /*width=*/1030, /*height=*/1, VPX_CBR,
1606*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1607*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1608*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/0, /*width=*/548, /*height=*/322, VPX_VBR,
1609*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1610*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1611*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/24, /*height=*/583, VPX_CBR,
1612*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_GOOD_QUALITY);
1613*fb1b10abSAndroid Build Coastguard Worker }
1614*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer329179808RowMT0BitDepth10)1615*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer329179808RowMT0BitDepth10) {
1616*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(4, 0, VPX_BITS_10, VPX_IMG_FMT_I444);
1617*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/1488, /*height=*/5, VPX_VBR,
1618*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1619*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1620*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/839, /*height=*/1, VPX_CBR,
1621*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1622*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1623*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/11, /*width=*/657, /*height=*/5, VPX_CBR,
1624*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1625*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1626*fb1b10abSAndroid Build Coastguard Worker }
1627*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer329179808RowMT1BitDepth10)1628*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer329179808RowMT1BitDepth10) {
1629*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(4, 1, VPX_BITS_10, VPX_IMG_FMT_I444);
1630*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/1488, /*height=*/5, VPX_VBR,
1631*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1632*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1633*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/839, /*height=*/1, VPX_CBR,
1634*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1635*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1636*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/11, /*width=*/657, /*height=*/5, VPX_CBR,
1637*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1638*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1639*fb1b10abSAndroid Build Coastguard Worker }
1640*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer331108922BitDepth12)1641*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer331108922BitDepth12) {
1642*fb1b10abSAndroid Build Coastguard Worker   VP9Encoder encoder(9, 1, VPX_BITS_12, VPX_IMG_FMT_I444);
1643*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/1, /*width=*/1, /*height=*/1080, VPX_VBR,
1644*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1645*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1646*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/0, /*width=*/1, /*height=*/1080, VPX_CBR,
1647*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_GOOD_QUALITY);
1648*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/1, /*height=*/394, VPX_CBR,
1649*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1650*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1651*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/true);
1652*fb1b10abSAndroid Build Coastguard Worker   encoder.Configure(/*threads=*/16, /*width=*/1, /*height=*/798, VPX_CBR,
1653*fb1b10abSAndroid Build Coastguard Worker                     VPX_DL_REALTIME);
1654*fb1b10abSAndroid Build Coastguard Worker   encoder.Encode(/*key_frame=*/false);
1655*fb1b10abSAndroid Build Coastguard Worker }
1656*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
1657*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,VP9GlobalHeaders)1658*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, VP9GlobalHeaders) {
1659*fb1b10abSAndroid Build Coastguard Worker   constexpr int kWidth = 320;
1660*fb1b10abSAndroid Build Coastguard Worker   constexpr int kHeight = 240;
1661*fb1b10abSAndroid Build Coastguard Worker 
1662*fb1b10abSAndroid Build Coastguard Worker   libvpx_test::DummyVideoSource video;
1663*fb1b10abSAndroid Build Coastguard Worker   video.SetSize(kWidth, kHeight);
1664*fb1b10abSAndroid Build Coastguard Worker 
1665*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1666*fb1b10abSAndroid Build Coastguard Worker   const int profiles[] = { 0, 1, 2, 3 };
1667*fb1b10abSAndroid Build Coastguard Worker #else
1668*fb1b10abSAndroid Build Coastguard Worker   const int profiles[] = { 0, 1 };
1669*fb1b10abSAndroid Build Coastguard Worker #endif
1670*fb1b10abSAndroid Build Coastguard Worker   char str[80];
1671*fb1b10abSAndroid Build Coastguard Worker   for (const int profile : profiles) {
1672*fb1b10abSAndroid Build Coastguard Worker     std::vector<vpx_bit_depth_t> bitdepths;
1673*fb1b10abSAndroid Build Coastguard Worker     std::vector<vpx_img_fmt_t> formats;
1674*fb1b10abSAndroid Build Coastguard Worker     switch (profile) {
1675*fb1b10abSAndroid Build Coastguard Worker       case 0:
1676*fb1b10abSAndroid Build Coastguard Worker         bitdepths = { VPX_BITS_8 };
1677*fb1b10abSAndroid Build Coastguard Worker         formats = { VPX_IMG_FMT_I420 };
1678*fb1b10abSAndroid Build Coastguard Worker         break;
1679*fb1b10abSAndroid Build Coastguard Worker       case 1:
1680*fb1b10abSAndroid Build Coastguard Worker         bitdepths = { VPX_BITS_8 };
1681*fb1b10abSAndroid Build Coastguard Worker         formats = { VPX_IMG_FMT_I422, VPX_IMG_FMT_I444 };
1682*fb1b10abSAndroid Build Coastguard Worker         break;
1683*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1684*fb1b10abSAndroid Build Coastguard Worker       case 2:
1685*fb1b10abSAndroid Build Coastguard Worker         bitdepths = { VPX_BITS_10, VPX_BITS_12 };
1686*fb1b10abSAndroid Build Coastguard Worker         formats = { VPX_IMG_FMT_I42016 };
1687*fb1b10abSAndroid Build Coastguard Worker         break;
1688*fb1b10abSAndroid Build Coastguard Worker       case 3:
1689*fb1b10abSAndroid Build Coastguard Worker         bitdepths = { VPX_BITS_10, VPX_BITS_12 };
1690*fb1b10abSAndroid Build Coastguard Worker         formats = { VPX_IMG_FMT_I42216, VPX_IMG_FMT_I44416 };
1691*fb1b10abSAndroid Build Coastguard Worker         break;
1692*fb1b10abSAndroid Build Coastguard Worker #endif
1693*fb1b10abSAndroid Build Coastguard Worker     }
1694*fb1b10abSAndroid Build Coastguard Worker 
1695*fb1b10abSAndroid Build Coastguard Worker     for (const auto format : formats) {
1696*fb1b10abSAndroid Build Coastguard Worker       for (const auto bitdepth : bitdepths) {
1697*fb1b10abSAndroid Build Coastguard Worker         snprintf(str, sizeof(str), "profile: %d bitdepth: %d format: %d",
1698*fb1b10abSAndroid Build Coastguard Worker                  profile, bitdepth, format);
1699*fb1b10abSAndroid Build Coastguard Worker         SCOPED_TRACE(str);
1700*fb1b10abSAndroid Build Coastguard Worker 
1701*fb1b10abSAndroid Build Coastguard Worker         vpx_codec_enc_cfg_t cfg = {};
1702*fb1b10abSAndroid Build Coastguard Worker         struct Encoder {
1703*fb1b10abSAndroid Build Coastguard Worker           ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); }
1704*fb1b10abSAndroid Build Coastguard Worker           vpx_codec_ctx_t ctx = {};
1705*fb1b10abSAndroid Build Coastguard Worker         } enc;
1706*fb1b10abSAndroid Build Coastguard Worker         vpx_codec_ctx_t *const ctx = &enc.ctx;
1707*fb1b10abSAndroid Build Coastguard Worker 
1708*fb1b10abSAndroid Build Coastguard Worker         ASSERT_EQ(vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &cfg, 0),
1709*fb1b10abSAndroid Build Coastguard Worker                   VPX_CODEC_OK);
1710*fb1b10abSAndroid Build Coastguard Worker         cfg.g_w = kWidth;
1711*fb1b10abSAndroid Build Coastguard Worker         cfg.g_h = kHeight;
1712*fb1b10abSAndroid Build Coastguard Worker         cfg.g_lag_in_frames = 0;
1713*fb1b10abSAndroid Build Coastguard Worker         cfg.g_pass = VPX_RC_ONE_PASS;
1714*fb1b10abSAndroid Build Coastguard Worker         cfg.g_profile = profile;
1715*fb1b10abSAndroid Build Coastguard Worker         cfg.g_bit_depth = bitdepth;
1716*fb1b10abSAndroid Build Coastguard Worker         ASSERT_EQ(
1717*fb1b10abSAndroid Build Coastguard Worker             vpx_codec_enc_init(ctx, vpx_codec_vp9_cx(), &cfg,
1718*fb1b10abSAndroid Build Coastguard Worker                                bitdepth == 8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH),
1719*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
1720*fb1b10abSAndroid Build Coastguard Worker         ASSERT_EQ(vpx_codec_control_(ctx, VP8E_SET_CPUUSED, 2), VPX_CODEC_OK);
1721*fb1b10abSAndroid Build Coastguard Worker         ASSERT_EQ(vpx_codec_control_(ctx, VP9E_SET_TARGET_LEVEL, 62),
1722*fb1b10abSAndroid Build Coastguard Worker                   VPX_CODEC_OK);
1723*fb1b10abSAndroid Build Coastguard Worker 
1724*fb1b10abSAndroid Build Coastguard Worker         vpx_fixed_buf_t *global_headers = vpx_codec_get_global_headers(ctx);
1725*fb1b10abSAndroid Build Coastguard Worker         EXPECT_NE(global_headers, nullptr);
1726*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(global_headers->sz, size_t{ 9 });
1727*fb1b10abSAndroid Build Coastguard Worker 
1728*fb1b10abSAndroid Build Coastguard Worker         video.SetImageFormat(format);
1729*fb1b10abSAndroid Build Coastguard Worker         video.Begin();
1730*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(
1731*fb1b10abSAndroid Build Coastguard Worker             vpx_codec_encode(ctx, video.img(), video.pts(), video.duration(),
1732*fb1b10abSAndroid Build Coastguard Worker                              /*flags=*/0, VPX_DL_GOOD_QUALITY),
1733*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK)
1734*fb1b10abSAndroid Build Coastguard Worker             << vpx_codec_error_detail(ctx);
1735*fb1b10abSAndroid Build Coastguard Worker 
1736*fb1b10abSAndroid Build Coastguard Worker         global_headers = vpx_codec_get_global_headers(ctx);
1737*fb1b10abSAndroid Build Coastguard Worker         EXPECT_NE(global_headers, nullptr);
1738*fb1b10abSAndroid Build Coastguard Worker         EXPECT_EQ(global_headers->sz, size_t{ 12 });
1739*fb1b10abSAndroid Build Coastguard Worker         uint8_t chroma_subsampling;
1740*fb1b10abSAndroid Build Coastguard Worker         if ((format & VPX_IMG_FMT_I420) == VPX_IMG_FMT_I420) {
1741*fb1b10abSAndroid Build Coastguard Worker           chroma_subsampling = 1;
1742*fb1b10abSAndroid Build Coastguard Worker         } else if ((format & VPX_IMG_FMT_I422) == VPX_IMG_FMT_I422) {
1743*fb1b10abSAndroid Build Coastguard Worker           chroma_subsampling = 2;
1744*fb1b10abSAndroid Build Coastguard Worker         } else {  // VPX_IMG_FMT_I444
1745*fb1b10abSAndroid Build Coastguard Worker           chroma_subsampling = 3;
1746*fb1b10abSAndroid Build Coastguard Worker         }
1747*fb1b10abSAndroid Build Coastguard Worker         const uint8_t expected_headers[] = { 1,
1748*fb1b10abSAndroid Build Coastguard Worker                                              1,
1749*fb1b10abSAndroid Build Coastguard Worker                                              static_cast<uint8_t>(profile),
1750*fb1b10abSAndroid Build Coastguard Worker                                              2,
1751*fb1b10abSAndroid Build Coastguard Worker                                              1,
1752*fb1b10abSAndroid Build Coastguard Worker                                              /*level,*/ 3,
1753*fb1b10abSAndroid Build Coastguard Worker                                              1,
1754*fb1b10abSAndroid Build Coastguard Worker                                              static_cast<uint8_t>(bitdepth),
1755*fb1b10abSAndroid Build Coastguard Worker                                              4,
1756*fb1b10abSAndroid Build Coastguard Worker                                              1,
1757*fb1b10abSAndroid Build Coastguard Worker                                              chroma_subsampling };
1758*fb1b10abSAndroid Build Coastguard Worker         const uint8_t *actual_headers =
1759*fb1b10abSAndroid Build Coastguard Worker             reinterpret_cast<const uint8_t *>(global_headers->buf);
1760*fb1b10abSAndroid Build Coastguard Worker         for (int i = 0; i < 5; ++i) {
1761*fb1b10abSAndroid Build Coastguard Worker           EXPECT_EQ(expected_headers[i], actual_headers[i]) << "index: " << i;
1762*fb1b10abSAndroid Build Coastguard Worker         }
1763*fb1b10abSAndroid Build Coastguard Worker         EXPECT_NE(actual_headers[6], 0);  // level
1764*fb1b10abSAndroid Build Coastguard Worker         for (int i = 5; i < 11; ++i) {
1765*fb1b10abSAndroid Build Coastguard Worker           EXPECT_EQ(expected_headers[i], actual_headers[i + 1])
1766*fb1b10abSAndroid Build Coastguard Worker               << "index: " << i + 1;
1767*fb1b10abSAndroid Build Coastguard Worker         }
1768*fb1b10abSAndroid Build Coastguard Worker       }
1769*fb1b10abSAndroid Build Coastguard Worker     }
1770*fb1b10abSAndroid Build Coastguard Worker   }
1771*fb1b10abSAndroid Build Coastguard Worker }
1772*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,AomediaIssue3509VbrMinSection2PercentVP9)1773*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, AomediaIssue3509VbrMinSection2PercentVP9) {
1774*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder.
1775*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp9_cx();
1776*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
1777*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
1778*fb1b10abSAndroid Build Coastguard Worker 
1779*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
1780*fb1b10abSAndroid Build Coastguard Worker 
1781*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 1920;
1782*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 1080;
1783*fb1b10abSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 0;
1784*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1000000;
1785*fb1b10abSAndroid Build Coastguard Worker   // Set this to more than 1 percent to cause a signed integer overflow in the
1786*fb1b10abSAndroid Build Coastguard Worker   // multiplication rc->avg_frame_bandwidth * oxcf->rc_cfg.vbrmin_section in
1787*fb1b10abSAndroid Build Coastguard Worker   // vp9_rc_update_framerate() if the multiplication is done in the `int` type.
1788*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_2pass_vbr_minsection_pct = 2;
1789*fb1b10abSAndroid Build Coastguard Worker 
1790*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
1791*fb1b10abSAndroid Build Coastguard Worker 
1792*fb1b10abSAndroid Build Coastguard Worker   // Create input image.
1793*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *const image =
1794*fb1b10abSAndroid Build Coastguard Worker       CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h);
1795*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
1796*fb1b10abSAndroid Build Coastguard Worker 
1797*fb1b10abSAndroid Build Coastguard Worker   // Encode frame.
1798*fb1b10abSAndroid Build Coastguard Worker   // `duration` can go as high as 300, but the UBSan error is gone if
1799*fb1b10abSAndroid Build Coastguard Worker   // `duration` is 301 or higher.
1800*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(
1801*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_encode(&enc, image, 0, /*duration=*/300, 0, VPX_DL_REALTIME),
1802*fb1b10abSAndroid Build Coastguard Worker       VPX_CODEC_OK);
1803*fb1b10abSAndroid Build Coastguard Worker 
1804*fb1b10abSAndroid Build Coastguard Worker   // Free resources.
1805*fb1b10abSAndroid Build Coastguard Worker   vpx_img_free(image);
1806*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
1807*fb1b10abSAndroid Build Coastguard Worker }
1808*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,AomediaIssue3509VbrMinSection101PercentVP9)1809*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, AomediaIssue3509VbrMinSection101PercentVP9) {
1810*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder.
1811*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp9_cx();
1812*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
1813*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
1814*fb1b10abSAndroid Build Coastguard Worker 
1815*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
1816*fb1b10abSAndroid Build Coastguard Worker 
1817*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 1920;
1818*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 1080;
1819*fb1b10abSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 0;
1820*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1000000;
1821*fb1b10abSAndroid Build Coastguard Worker   // Set this to more than 100 percent to cause an error when vbr_min_bits is
1822*fb1b10abSAndroid Build Coastguard Worker   // cast to `int` in vp9_rc_update_framerate() if vbr_min_bits is not clamped
1823*fb1b10abSAndroid Build Coastguard Worker   // to INT_MAX.
1824*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_2pass_vbr_minsection_pct = 101;
1825*fb1b10abSAndroid Build Coastguard Worker 
1826*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
1827*fb1b10abSAndroid Build Coastguard Worker 
1828*fb1b10abSAndroid Build Coastguard Worker   // Create input image.
1829*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *const image =
1830*fb1b10abSAndroid Build Coastguard Worker       CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h);
1831*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
1832*fb1b10abSAndroid Build Coastguard Worker 
1833*fb1b10abSAndroid Build Coastguard Worker   // Encode frame.
1834*fb1b10abSAndroid Build Coastguard Worker   // `duration` can go as high as 300, but the UBSan error is gone if
1835*fb1b10abSAndroid Build Coastguard Worker   // `duration` is 301 or higher.
1836*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(
1837*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_encode(&enc, image, 0, /*duration=*/300, 0, VPX_DL_REALTIME),
1838*fb1b10abSAndroid Build Coastguard Worker       VPX_CODEC_OK);
1839*fb1b10abSAndroid Build Coastguard Worker 
1840*fb1b10abSAndroid Build Coastguard Worker   // Free resources.
1841*fb1b10abSAndroid Build Coastguard Worker   vpx_img_free(image);
1842*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
1843*fb1b10abSAndroid Build Coastguard Worker }
1844*fb1b10abSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Chromium352414650)1845*fb1b10abSAndroid Build Coastguard Worker TEST(EncodeAPI, Chromium352414650) {
1846*fb1b10abSAndroid Build Coastguard Worker   // Initialize libvpx encoder.
1847*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_iface_t *const iface = vpx_codec_vp9_cx();
1848*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_ctx_t enc;
1849*fb1b10abSAndroid Build Coastguard Worker   vpx_codec_enc_cfg_t cfg;
1850*fb1b10abSAndroid Build Coastguard Worker 
1851*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK);
1852*fb1b10abSAndroid Build Coastguard Worker 
1853*fb1b10abSAndroid Build Coastguard Worker   cfg.g_w = 1024;
1854*fb1b10abSAndroid Build Coastguard Worker   cfg.g_h = 1024;
1855*fb1b10abSAndroid Build Coastguard Worker   cfg.g_profile = 0;
1856*fb1b10abSAndroid Build Coastguard Worker   cfg.g_pass = VPX_RC_ONE_PASS;
1857*fb1b10abSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 0;
1858*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_max_quantizer = 58;
1859*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_min_quantizer = 2;
1860*fb1b10abSAndroid Build Coastguard Worker   cfg.g_threads = 4;
1861*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_resize_allowed = 0;
1862*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_dropframe_thresh = 0;
1863*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.num = 1;
1864*fb1b10abSAndroid Build Coastguard Worker   cfg.g_timebase.den = 1000000;
1865*fb1b10abSAndroid Build Coastguard Worker   cfg.kf_min_dist = 0;
1866*fb1b10abSAndroid Build Coastguard Worker   cfg.kf_max_dist = 10000;
1867*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_end_usage = VPX_CBR;
1868*fb1b10abSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 754974;
1869*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_number_layers = 3;
1870*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_periodicity = 4;
1871*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_layer_id[0] = 0;
1872*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_layer_id[1] = 2;
1873*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_layer_id[2] = 1;
1874*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_layer_id[3] = 2;
1875*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_rate_decimator[0] = 4;
1876*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_rate_decimator[1] = 2;
1877*fb1b10abSAndroid Build Coastguard Worker   cfg.ts_rate_decimator[2] = 1;
1878*fb1b10abSAndroid Build Coastguard Worker   cfg.layer_target_bitrate[0] = 2147483;
1879*fb1b10abSAndroid Build Coastguard Worker   cfg.layer_target_bitrate[1] = 3006476;
1880*fb1b10abSAndroid Build Coastguard Worker   cfg.layer_target_bitrate[2] = 4294967;
1881*fb1b10abSAndroid Build Coastguard Worker   cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_0212;
1882*fb1b10abSAndroid Build Coastguard Worker   cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
1883*fb1b10abSAndroid Build Coastguard Worker 
1884*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK);
1885*fb1b10abSAndroid Build Coastguard Worker 
1886*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, 7), VPX_CODEC_OK);
1887*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_TILE_COLUMNS, 2), VPX_CODEC_OK);
1888*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_ROW_MT, 1), VPX_CODEC_OK);
1889*fb1b10abSAndroid Build Coastguard Worker 
1890*fb1b10abSAndroid Build Coastguard Worker   vpx_svc_extra_cfg_t svc_cfg = {};
1891*fb1b10abSAndroid Build Coastguard Worker   svc_cfg.max_quantizers[0] = svc_cfg.max_quantizers[1] =
1892*fb1b10abSAndroid Build Coastguard Worker       svc_cfg.max_quantizers[2] = 58;
1893*fb1b10abSAndroid Build Coastguard Worker   svc_cfg.min_quantizers[0] = svc_cfg.min_quantizers[1] =
1894*fb1b10abSAndroid Build Coastguard Worker       svc_cfg.min_quantizers[2] = 2;
1895*fb1b10abSAndroid Build Coastguard Worker   svc_cfg.scaling_factor_num[0] = svc_cfg.scaling_factor_num[1] =
1896*fb1b10abSAndroid Build Coastguard Worker       svc_cfg.scaling_factor_num[2] = 1;
1897*fb1b10abSAndroid Build Coastguard Worker   svc_cfg.scaling_factor_den[0] = svc_cfg.scaling_factor_den[1] =
1898*fb1b10abSAndroid Build Coastguard Worker       svc_cfg.scaling_factor_den[2] = 1;
1899*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_SVC_PARAMETERS, &svc_cfg),
1900*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
1901*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_SVC, 1), VPX_CODEC_OK);
1902*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_AQ_MODE, 3), VPX_CODEC_OK);
1903*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_STATIC_THRESHOLD, 1),
1904*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
1905*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_COLOR_SPACE, VPX_CS_SMPTE_170),
1906*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
1907*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_COLOR_RANGE, VPX_CR_STUDIO_RANGE),
1908*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
1909*fb1b10abSAndroid Build Coastguard Worker 
1910*fb1b10abSAndroid Build Coastguard Worker   // Create input image.
1911*fb1b10abSAndroid Build Coastguard Worker   vpx_image_t *const image =
1912*fb1b10abSAndroid Build Coastguard Worker       CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h);
1913*fb1b10abSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
1914*fb1b10abSAndroid Build Coastguard Worker 
1915*fb1b10abSAndroid Build Coastguard Worker   // Encode frame.
1916*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_encode(&enc, image, 0, /*duration=*/500000,
1917*fb1b10abSAndroid Build Coastguard Worker                              VPX_EFLAG_FORCE_KF, VPX_DL_REALTIME),
1918*fb1b10abSAndroid Build Coastguard Worker             VPX_CODEC_OK);
1919*fb1b10abSAndroid Build Coastguard Worker 
1920*fb1b10abSAndroid Build Coastguard Worker   // Free resources.
1921*fb1b10abSAndroid Build Coastguard Worker   vpx_img_free(image);
1922*fb1b10abSAndroid Build Coastguard Worker   ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK);
1923*fb1b10abSAndroid Build Coastguard Worker }
1924*fb1b10abSAndroid Build Coastguard Worker 
1925*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_ENCODER
1926*fb1b10abSAndroid Build Coastguard Worker 
1927*fb1b10abSAndroid Build Coastguard Worker }  // namespace
1928