xref: /aosp_15_r20/external/libaom/test/encode_api_test.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker #include <cassert>
13*77c1e3ccSAndroid Build Coastguard Worker #include <climits>
14*77c1e3ccSAndroid Build Coastguard Worker #include <cstdint>
15*77c1e3ccSAndroid Build Coastguard Worker #include <cstdlib>
16*77c1e3ccSAndroid Build Coastguard Worker #include <cstring>
17*77c1e3ccSAndroid Build Coastguard Worker #include <tuple>
18*77c1e3ccSAndroid Build Coastguard Worker 
19*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
20*77c1e3ccSAndroid Build Coastguard Worker 
21*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
22*77c1e3ccSAndroid Build Coastguard Worker 
23*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aomcx.h"
24*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_encoder.h"
25*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_image.h"
26*77c1e3ccSAndroid Build Coastguard Worker 
27*77c1e3ccSAndroid Build Coastguard Worker namespace {
28*77c1e3ccSAndroid Build Coastguard Worker 
29*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY
30*77c1e3ccSAndroid Build Coastguard Worker const unsigned int kUsage = AOM_USAGE_REALTIME;
31*77c1e3ccSAndroid Build Coastguard Worker #else
32*77c1e3ccSAndroid Build Coastguard Worker const unsigned int kUsage = AOM_USAGE_GOOD_QUALITY;
33*77c1e3ccSAndroid Build Coastguard Worker #endif
34*77c1e3ccSAndroid Build Coastguard Worker 
Memset16(void * dest,int val,size_t length)35*77c1e3ccSAndroid Build Coastguard Worker static void *Memset16(void *dest, int val, size_t length) {
36*77c1e3ccSAndroid Build Coastguard Worker   uint16_t *dest16 = (uint16_t *)dest;
37*77c1e3ccSAndroid Build Coastguard Worker   for (size_t i = 0; i < length; ++i) *dest16++ = val;
38*77c1e3ccSAndroid Build Coastguard Worker   return dest;
39*77c1e3ccSAndroid Build Coastguard Worker }
40*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,InvalidParams)41*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, InvalidParams) {
42*77c1e3ccSAndroid Build Coastguard Worker   uint8_t buf[1] = { 0 };
43*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t img;
44*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
45*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
46*77c1e3ccSAndroid Build Coastguard Worker 
47*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(&img, aom_img_wrap(&img, AOM_IMG_FMT_I420, 1, 1, 1, buf));
48*77c1e3ccSAndroid Build Coastguard Worker 
49*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
50*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_init(nullptr, nullptr, nullptr, 0));
51*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
52*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_init(&enc, nullptr, nullptr, 0));
53*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
54*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_encode(nullptr, nullptr, 0, 0, 0));
55*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_encode(nullptr, &img, 0, 0, 0));
56*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_destroy(nullptr));
57*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
58*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_config_default(nullptr, nullptr, 0));
59*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
60*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_config_default(nullptr, &cfg, 0));
61*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_NE(aom_codec_error(nullptr), nullptr);
62*77c1e3ccSAndroid Build Coastguard Worker 
63*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
64*77c1e3ccSAndroid Build Coastguard Worker   SCOPED_TRACE(aom_codec_iface_name(iface));
65*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
66*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_init(nullptr, iface, nullptr, 0));
67*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
68*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_init(&enc, iface, nullptr, 0));
69*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
70*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_config_default(iface, &cfg, 3));
71*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
72*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 1 << 16;
73*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = (1 << 14) + 1;
74*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
75*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
76*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = (1 << 14) + 1;
77*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 1 << 16;
78*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
79*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
80*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_forced_max_frame_width = 1 << 16;
81*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_forced_max_frame_height = (1 << 14) + 1;
82*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
83*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
84*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_forced_max_frame_width = (1 << 14) + 1;
85*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_forced_max_frame_height = 1 << 16;
86*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
87*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
88*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));
89*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, aom_codec_get_global_headers(nullptr));
90*77c1e3ccSAndroid Build Coastguard Worker 
91*77c1e3ccSAndroid Build Coastguard Worker   aom_fixed_buf_t *glob_headers = aom_codec_get_global_headers(&enc);
92*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_NE(glob_headers->buf, nullptr);
93*77c1e3ccSAndroid Build Coastguard Worker   if (glob_headers) {
94*77c1e3ccSAndroid Build Coastguard Worker     free(glob_headers->buf);
95*77c1e3ccSAndroid Build Coastguard Worker     free(glob_headers);
96*77c1e3ccSAndroid Build Coastguard Worker   }
97*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 0, 0));
98*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
99*77c1e3ccSAndroid Build Coastguard Worker }
100*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,InvalidControlId)101*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, InvalidControlId) {
102*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
103*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
104*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
105*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
106*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));
107*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_ERROR, aom_codec_control(&enc, -1, 0));
108*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_control(&enc, 0, 0));
109*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
110*77c1e3ccSAndroid Build Coastguard Worker }
111*77c1e3ccSAndroid Build Coastguard Worker 
EncodeSetSFrameOnFirstFrame(aom_img_fmt fmt,aom_codec_flags_t flag)112*77c1e3ccSAndroid Build Coastguard Worker void EncodeSetSFrameOnFirstFrame(aom_img_fmt fmt, aom_codec_flags_t flag) {
113*77c1e3ccSAndroid Build Coastguard Worker   constexpr int kWidth = 2;
114*77c1e3ccSAndroid Build Coastguard Worker   constexpr int kHeight = 128;
115*77c1e3ccSAndroid Build Coastguard Worker   unsigned char kBuffer[kWidth * kHeight * 3] = { 0 };
116*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t img;
117*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_img_wrap(&img, fmt, kWidth, kHeight, 1, kBuffer), &img);
118*77c1e3ccSAndroid Build Coastguard Worker 
119*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
120*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
121*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, kUsage), AOM_CODEC_OK);
122*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = kWidth;
123*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = kHeight;
124*77c1e3ccSAndroid Build Coastguard Worker 
125*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
126*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, flag), AOM_CODEC_OK);
127*77c1e3ccSAndroid Build Coastguard Worker   // One of these aom_codec_encode() calls should fail.
128*77c1e3ccSAndroid Build Coastguard Worker   if (aom_codec_encode(&enc, &img, 0, 1, AOM_EFLAG_SET_S_FRAME) ==
129*77c1e3ccSAndroid Build Coastguard Worker       AOM_CODEC_OK) {
130*77c1e3ccSAndroid Build Coastguard Worker     EXPECT_NE(aom_codec_encode(&enc, nullptr, 0, 0, 0), AOM_CODEC_OK);
131*77c1e3ccSAndroid Build Coastguard Worker   }
132*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
133*77c1e3ccSAndroid Build Coastguard Worker }
134*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,SetSFrameOnFirstFrame)135*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, SetSFrameOnFirstFrame) {
136*77c1e3ccSAndroid Build Coastguard Worker   EncodeSetSFrameOnFirstFrame(AOM_IMG_FMT_I420, 0);
137*77c1e3ccSAndroid Build Coastguard Worker }
138*77c1e3ccSAndroid Build Coastguard Worker 
139*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
TEST(EncodeAPI,SetSFrameOnFirstFrameHighbd)140*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, SetSFrameOnFirstFrameHighbd) {
141*77c1e3ccSAndroid Build Coastguard Worker   EncodeSetSFrameOnFirstFrame(AOM_IMG_FMT_I42016, AOM_CODEC_USE_HIGHBITDEPTH);
142*77c1e3ccSAndroid Build Coastguard Worker }
143*77c1e3ccSAndroid Build Coastguard Worker #endif  // CONFIG_AV1_HIGHBITDEPTH
144*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,MonochromeInProfiles)145*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, MonochromeInProfiles) {
146*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
147*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
148*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
149*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 128;
150*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 128;
151*77c1e3ccSAndroid Build Coastguard Worker   cfg.monochrome = 1;
152*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
153*77c1e3ccSAndroid Build Coastguard Worker 
154*77c1e3ccSAndroid Build Coastguard Worker   // Test Profile 0
155*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_profile = 0;
156*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));
157*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
158*77c1e3ccSAndroid Build Coastguard Worker 
159*77c1e3ccSAndroid Build Coastguard Worker   // Test Profile 1
160*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_profile = 1;
161*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
162*77c1e3ccSAndroid Build Coastguard Worker 
163*77c1e3ccSAndroid Build Coastguard Worker   // Test Profile 3
164*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_profile = 2;
165*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));
166*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
167*77c1e3ccSAndroid Build Coastguard Worker }
168*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,LowBDEncoderLowBDImage)169*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, LowBDEncoderLowBDImage) {
170*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
171*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
172*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, kUsage), AOM_CODEC_OK);
173*77c1e3ccSAndroid Build Coastguard Worker 
174*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
175*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
176*77c1e3ccSAndroid Build Coastguard Worker 
177*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *image =
178*77c1e3ccSAndroid Build Coastguard Worker       aom_img_alloc(nullptr, AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h, 0);
179*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
180*77c1e3ccSAndroid Build Coastguard Worker 
181*77c1e3ccSAndroid Build Coastguard Worker   // Set the image to two colors so that av1_set_screen_content_options() will
182*77c1e3ccSAndroid Build Coastguard Worker   // call av1_get_perpixel_variance().
183*77c1e3ccSAndroid Build Coastguard Worker   int luma_value = 0;
184*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < image->d_h; ++i) {
185*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[0] + i * image->stride[0], luma_value, image->d_w);
186*77c1e3ccSAndroid Build Coastguard Worker     luma_value = 255 - luma_value;
187*77c1e3ccSAndroid Build Coastguard Worker   }
188*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_h = (image->d_h + 1) / 2;
189*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_w = (image->d_w + 1) / 2;
190*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < uv_h; ++i) {
191*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[1] + i * image->stride[1], 128, uv_w);
192*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[2] + i * image->stride[2], 128, uv_w);
193*77c1e3ccSAndroid Build Coastguard Worker   }
194*77c1e3ccSAndroid Build Coastguard Worker 
195*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
196*77c1e3ccSAndroid Build Coastguard Worker 
197*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
198*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
199*77c1e3ccSAndroid Build Coastguard Worker }
200*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,HighBDEncoderHighBDImage)201*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, HighBDEncoderHighBDImage) {
202*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
203*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
204*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, kUsage), AOM_CODEC_OK);
205*77c1e3ccSAndroid Build Coastguard Worker 
206*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
207*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t init_status =
208*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH);
209*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_AV1_HIGHBITDEPTH
210*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(init_status, AOM_CODEC_INCAPABLE);
211*77c1e3ccSAndroid Build Coastguard Worker #else
212*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(init_status, AOM_CODEC_OK);
213*77c1e3ccSAndroid Build Coastguard Worker 
214*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *image =
215*77c1e3ccSAndroid Build Coastguard Worker       aom_img_alloc(nullptr, AOM_IMG_FMT_I42016, cfg.g_w, cfg.g_h, 0);
216*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
217*77c1e3ccSAndroid Build Coastguard Worker 
218*77c1e3ccSAndroid Build Coastguard Worker   // Set the image to two colors so that av1_set_screen_content_options() will
219*77c1e3ccSAndroid Build Coastguard Worker   // call av1_get_perpixel_variance().
220*77c1e3ccSAndroid Build Coastguard Worker   int luma_value = 0;
221*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < image->d_h; ++i) {
222*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[0] + i * image->stride[0], luma_value, image->d_w);
223*77c1e3ccSAndroid Build Coastguard Worker     luma_value = 255 - luma_value;
224*77c1e3ccSAndroid Build Coastguard Worker   }
225*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_h = (image->d_h + 1) / 2;
226*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_w = (image->d_w + 1) / 2;
227*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < uv_h; ++i) {
228*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[1] + i * image->stride[1], 128, uv_w);
229*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[2] + i * image->stride[2], 128, uv_w);
230*77c1e3ccSAndroid Build Coastguard Worker   }
231*77c1e3ccSAndroid Build Coastguard Worker 
232*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
233*77c1e3ccSAndroid Build Coastguard Worker 
234*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
235*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
236*77c1e3ccSAndroid Build Coastguard Worker #endif
237*77c1e3ccSAndroid Build Coastguard Worker }
238*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,HighBDEncoderLowBDImage)239*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, HighBDEncoderLowBDImage) {
240*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
241*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
242*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, kUsage), AOM_CODEC_OK);
243*77c1e3ccSAndroid Build Coastguard Worker 
244*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
245*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t init_status =
246*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH);
247*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_AV1_HIGHBITDEPTH
248*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(init_status, AOM_CODEC_INCAPABLE);
249*77c1e3ccSAndroid Build Coastguard Worker #else
250*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(init_status, AOM_CODEC_OK);
251*77c1e3ccSAndroid Build Coastguard Worker 
252*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *image =
253*77c1e3ccSAndroid Build Coastguard Worker       aom_img_alloc(nullptr, AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h, 0);
254*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
255*77c1e3ccSAndroid Build Coastguard Worker 
256*77c1e3ccSAndroid Build Coastguard Worker   // Set the image to two colors so that av1_set_screen_content_options() will
257*77c1e3ccSAndroid Build Coastguard Worker   // call av1_get_perpixel_variance().
258*77c1e3ccSAndroid Build Coastguard Worker   int luma_value = 0;
259*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < image->d_h; ++i) {
260*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[0] + i * image->stride[0], luma_value, image->d_w);
261*77c1e3ccSAndroid Build Coastguard Worker     luma_value = 255 - luma_value;
262*77c1e3ccSAndroid Build Coastguard Worker   }
263*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_h = (image->d_h + 1) / 2;
264*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_w = (image->d_w + 1) / 2;
265*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < uv_h; ++i) {
266*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[1] + i * image->stride[1], 128, uv_w);
267*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[2] + i * image->stride[2], 128, uv_w);
268*77c1e3ccSAndroid Build Coastguard Worker   }
269*77c1e3ccSAndroid Build Coastguard Worker 
270*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_INVALID_PARAM);
271*77c1e3ccSAndroid Build Coastguard Worker 
272*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
273*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
274*77c1e3ccSAndroid Build Coastguard Worker #endif
275*77c1e3ccSAndroid Build Coastguard Worker }
276*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,LowBDEncoderHighBDImage)277*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, LowBDEncoderHighBDImage) {
278*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
279*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
280*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, kUsage), AOM_CODEC_OK);
281*77c1e3ccSAndroid Build Coastguard Worker 
282*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
283*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
284*77c1e3ccSAndroid Build Coastguard Worker 
285*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *image =
286*77c1e3ccSAndroid Build Coastguard Worker       aom_img_alloc(nullptr, AOM_IMG_FMT_I42016, cfg.g_w, cfg.g_h, 0);
287*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
288*77c1e3ccSAndroid Build Coastguard Worker 
289*77c1e3ccSAndroid Build Coastguard Worker   // Set the image to two colors so that av1_set_screen_content_options() will
290*77c1e3ccSAndroid Build Coastguard Worker   // call av1_get_perpixel_variance().
291*77c1e3ccSAndroid Build Coastguard Worker   int luma_value = 0;
292*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < image->d_h; ++i) {
293*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[0] + i * image->stride[0], luma_value, image->d_w);
294*77c1e3ccSAndroid Build Coastguard Worker     luma_value = 255 - luma_value;
295*77c1e3ccSAndroid Build Coastguard Worker   }
296*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_h = (image->d_h + 1) / 2;
297*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_w = (image->d_w + 1) / 2;
298*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < uv_h; ++i) {
299*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[1] + i * image->stride[1], 128, uv_w);
300*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[2] + i * image->stride[2], 128, uv_w);
301*77c1e3ccSAndroid Build Coastguard Worker   }
302*77c1e3ccSAndroid Build Coastguard Worker 
303*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_INVALID_PARAM);
304*77c1e3ccSAndroid Build Coastguard Worker 
305*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
306*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
307*77c1e3ccSAndroid Build Coastguard Worker }
308*77c1e3ccSAndroid Build Coastguard Worker 
CreateGrayImage(aom_img_fmt_t fmt,unsigned int w,unsigned int h)309*77c1e3ccSAndroid Build Coastguard Worker aom_image_t *CreateGrayImage(aom_img_fmt_t fmt, unsigned int w,
310*77c1e3ccSAndroid Build Coastguard Worker                              unsigned int h) {
311*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *const image = aom_img_alloc(nullptr, fmt, w, h, 1);
312*77c1e3ccSAndroid Build Coastguard Worker   if (!image) return image;
313*77c1e3ccSAndroid Build Coastguard Worker 
314*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < image->d_h; ++i) {
315*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[0] + i * image->stride[0], 128, image->d_w);
316*77c1e3ccSAndroid Build Coastguard Worker   }
317*77c1e3ccSAndroid Build Coastguard Worker   const unsigned int uv_h = (image->d_h + 1) / 2;
318*77c1e3ccSAndroid Build Coastguard Worker   const unsigned int uv_w = (image->d_w + 1) / 2;
319*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < uv_h; ++i) {
320*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[1] + i * image->stride[1], 128, uv_w);
321*77c1e3ccSAndroid Build Coastguard Worker     memset(image->planes[2] + i * image->stride[2], 128, uv_w);
322*77c1e3ccSAndroid Build Coastguard Worker   }
323*77c1e3ccSAndroid Build Coastguard Worker   return image;
324*77c1e3ccSAndroid Build Coastguard Worker }
325*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer310548198)326*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer310548198) {
327*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *const iface = aom_codec_av1_cx();
328*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
329*77c1e3ccSAndroid Build Coastguard Worker   const unsigned int usage = AOM_USAGE_REALTIME;
330*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, usage), AOM_CODEC_OK);
331*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 1;
332*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 444;
333*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_pass = AOM_RC_ONE_PASS;
334*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 0;
335*77c1e3ccSAndroid Build Coastguard Worker 
336*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
337*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
338*77c1e3ccSAndroid Build Coastguard Worker 
339*77c1e3ccSAndroid Build Coastguard Worker   const int speed = 6;
340*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, speed), AOM_CODEC_OK);
341*77c1e3ccSAndroid Build Coastguard Worker 
342*77c1e3ccSAndroid Build Coastguard Worker   const aom_enc_frame_flags_t flags = 0;
343*77c1e3ccSAndroid Build Coastguard Worker   int frame_index = 0;
344*77c1e3ccSAndroid Build Coastguard Worker 
345*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame.
346*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *image = CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
347*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
348*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, frame_index, 1, flags), AOM_CODEC_OK);
349*77c1e3ccSAndroid Build Coastguard Worker   frame_index++;
350*77c1e3ccSAndroid Build Coastguard Worker   const aom_codec_cx_pkt_t *pkt;
351*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iter_t iter = nullptr;
352*77c1e3ccSAndroid Build Coastguard Worker   while ((pkt = aom_codec_get_cx_data(&enc, &iter)) != nullptr) {
353*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
354*77c1e3ccSAndroid Build Coastguard Worker   }
355*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
356*77c1e3ccSAndroid Build Coastguard Worker 
357*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 1;
358*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 254;
359*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK)
360*77c1e3ccSAndroid Build Coastguard Worker       << aom_codec_error_detail(&enc);
361*77c1e3ccSAndroid Build Coastguard Worker 
362*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 1;
363*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 154;
364*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK)
365*77c1e3ccSAndroid Build Coastguard Worker       << aom_codec_error_detail(&enc);
366*77c1e3ccSAndroid Build Coastguard Worker 
367*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame.
368*77c1e3ccSAndroid Build Coastguard Worker   image = CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
369*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, frame_index, 1, flags), AOM_CODEC_OK);
370*77c1e3ccSAndroid Build Coastguard Worker   frame_index++;
371*77c1e3ccSAndroid Build Coastguard Worker   iter = nullptr;
372*77c1e3ccSAndroid Build Coastguard Worker   while ((pkt = aom_codec_get_cx_data(&enc, &iter)) != nullptr) {
373*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
374*77c1e3ccSAndroid Build Coastguard Worker   }
375*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
376*77c1e3ccSAndroid Build Coastguard Worker 
377*77c1e3ccSAndroid Build Coastguard Worker   // Flush the encoder.
378*77c1e3ccSAndroid Build Coastguard Worker   bool got_data;
379*77c1e3ccSAndroid Build Coastguard Worker   do {
380*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(aom_codec_encode(&enc, nullptr, 0, 0, 0), AOM_CODEC_OK);
381*77c1e3ccSAndroid Build Coastguard Worker     got_data = false;
382*77c1e3ccSAndroid Build Coastguard Worker     iter = nullptr;
383*77c1e3ccSAndroid Build Coastguard Worker     while ((pkt = aom_codec_get_cx_data(&enc, &iter)) != nullptr) {
384*77c1e3ccSAndroid Build Coastguard Worker       ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
385*77c1e3ccSAndroid Build Coastguard Worker       got_data = true;
386*77c1e3ccSAndroid Build Coastguard Worker     }
387*77c1e3ccSAndroid Build Coastguard Worker   } while (got_data);
388*77c1e3ccSAndroid Build Coastguard Worker 
389*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
390*77c1e3ccSAndroid Build Coastguard Worker }
391*77c1e3ccSAndroid Build Coastguard Worker 
392*77c1e3ccSAndroid Build Coastguard Worker // Emulates the WebCodecs VideoEncoder interface.
393*77c1e3ccSAndroid Build Coastguard Worker class AV1Encoder {
394*77c1e3ccSAndroid Build Coastguard Worker  public:
AV1Encoder(int speed)395*77c1e3ccSAndroid Build Coastguard Worker   explicit AV1Encoder(int speed) : speed_(speed) {}
396*77c1e3ccSAndroid Build Coastguard Worker   ~AV1Encoder();
397*77c1e3ccSAndroid Build Coastguard Worker 
398*77c1e3ccSAndroid Build Coastguard Worker   void Configure(unsigned int threads, unsigned int width, unsigned int height,
399*77c1e3ccSAndroid Build Coastguard Worker                  aom_rc_mode end_usage, unsigned int usage);
400*77c1e3ccSAndroid Build Coastguard Worker   void Encode(bool key_frame);
401*77c1e3ccSAndroid Build Coastguard Worker 
402*77c1e3ccSAndroid Build Coastguard Worker  private:
403*77c1e3ccSAndroid Build Coastguard Worker   // Flushes the encoder. Should be called after all the Encode() calls.
404*77c1e3ccSAndroid Build Coastguard Worker   void Flush();
405*77c1e3ccSAndroid Build Coastguard Worker 
406*77c1e3ccSAndroid Build Coastguard Worker   const int speed_;
407*77c1e3ccSAndroid Build Coastguard Worker   bool initialized_ = false;
408*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg_;
409*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc_;
410*77c1e3ccSAndroid Build Coastguard Worker   int frame_index_ = 0;
411*77c1e3ccSAndroid Build Coastguard Worker };
412*77c1e3ccSAndroid Build Coastguard Worker 
~AV1Encoder()413*77c1e3ccSAndroid Build Coastguard Worker AV1Encoder::~AV1Encoder() {
414*77c1e3ccSAndroid Build Coastguard Worker   if (initialized_) {
415*77c1e3ccSAndroid Build Coastguard Worker     Flush();
416*77c1e3ccSAndroid Build Coastguard Worker     EXPECT_EQ(aom_codec_destroy(&enc_), AOM_CODEC_OK);
417*77c1e3ccSAndroid Build Coastguard Worker   }
418*77c1e3ccSAndroid Build Coastguard Worker }
419*77c1e3ccSAndroid Build Coastguard Worker 
Configure(unsigned int threads,unsigned int width,unsigned int height,aom_rc_mode end_usage,unsigned int usage)420*77c1e3ccSAndroid Build Coastguard Worker void AV1Encoder::Configure(unsigned int threads, unsigned int width,
421*77c1e3ccSAndroid Build Coastguard Worker                            unsigned int height, aom_rc_mode end_usage,
422*77c1e3ccSAndroid Build Coastguard Worker                            unsigned int usage) {
423*77c1e3ccSAndroid Build Coastguard Worker   if (!initialized_) {
424*77c1e3ccSAndroid Build Coastguard Worker     aom_codec_iface_t *const iface = aom_codec_av1_cx();
425*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg_, usage), AOM_CODEC_OK);
426*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_threads = threads;
427*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_w = width;
428*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_h = height;
429*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_forced_max_frame_width = cfg_.g_w;
430*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_forced_max_frame_height = cfg_.g_h;
431*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_timebase.num = 1;
432*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_timebase.den = 1000 * 1000;  // microseconds
433*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_pass = AOM_RC_ONE_PASS;
434*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_lag_in_frames = 0;
435*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_end_usage = end_usage;
436*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_min_quantizer = 2;
437*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_max_quantizer = 58;
438*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(aom_codec_enc_init(&enc_, iface, &cfg_, 0), AOM_CODEC_OK);
439*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(aom_codec_control(&enc_, AOME_SET_CPUUSED, speed_), AOM_CODEC_OK);
440*77c1e3ccSAndroid Build Coastguard Worker     initialized_ = true;
441*77c1e3ccSAndroid Build Coastguard Worker     return;
442*77c1e3ccSAndroid Build Coastguard Worker   }
443*77c1e3ccSAndroid Build Coastguard Worker 
444*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(usage, cfg_.g_usage);
445*77c1e3ccSAndroid Build Coastguard Worker   cfg_.g_threads = threads;
446*77c1e3ccSAndroid Build Coastguard Worker   cfg_.g_w = width;
447*77c1e3ccSAndroid Build Coastguard Worker   cfg_.g_h = height;
448*77c1e3ccSAndroid Build Coastguard Worker   cfg_.rc_end_usage = end_usage;
449*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_set(&enc_, &cfg_), AOM_CODEC_OK)
450*77c1e3ccSAndroid Build Coastguard Worker       << aom_codec_error_detail(&enc_);
451*77c1e3ccSAndroid Build Coastguard Worker }
452*77c1e3ccSAndroid Build Coastguard Worker 
Encode(bool key_frame)453*77c1e3ccSAndroid Build Coastguard Worker void AV1Encoder::Encode(bool key_frame) {
454*77c1e3ccSAndroid Build Coastguard Worker   assert(initialized_);
455*77c1e3ccSAndroid Build Coastguard Worker   // TODO(wtc): Support high bit depths and other YUV formats.
456*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *const image =
457*77c1e3ccSAndroid Build Coastguard Worker       CreateGrayImage(AOM_IMG_FMT_I420, cfg_.g_w, cfg_.g_h);
458*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
459*77c1e3ccSAndroid Build Coastguard Worker   const aom_enc_frame_flags_t flags = key_frame ? AOM_EFLAG_FORCE_KF : 0;
460*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc_, image, frame_index_, 1, flags),
461*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
462*77c1e3ccSAndroid Build Coastguard Worker   frame_index_++;
463*77c1e3ccSAndroid Build Coastguard Worker   const aom_codec_cx_pkt_t *pkt;
464*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iter_t iter = nullptr;
465*77c1e3ccSAndroid Build Coastguard Worker   while ((pkt = aom_codec_get_cx_data(&enc_, &iter)) != nullptr) {
466*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
467*77c1e3ccSAndroid Build Coastguard Worker     if (key_frame) {
468*77c1e3ccSAndroid Build Coastguard Worker       ASSERT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
469*77c1e3ccSAndroid Build Coastguard Worker     }
470*77c1e3ccSAndroid Build Coastguard Worker   }
471*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
472*77c1e3ccSAndroid Build Coastguard Worker }
473*77c1e3ccSAndroid Build Coastguard Worker 
Flush()474*77c1e3ccSAndroid Build Coastguard Worker void AV1Encoder::Flush() {
475*77c1e3ccSAndroid Build Coastguard Worker   bool got_data;
476*77c1e3ccSAndroid Build Coastguard Worker   do {
477*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(aom_codec_encode(&enc_, nullptr, 0, 0, 0), AOM_CODEC_OK);
478*77c1e3ccSAndroid Build Coastguard Worker     got_data = false;
479*77c1e3ccSAndroid Build Coastguard Worker     const aom_codec_cx_pkt_t *pkt;
480*77c1e3ccSAndroid Build Coastguard Worker     aom_codec_iter_t iter = nullptr;
481*77c1e3ccSAndroid Build Coastguard Worker     while ((pkt = aom_codec_get_cx_data(&enc_, &iter)) != nullptr) {
482*77c1e3ccSAndroid Build Coastguard Worker       ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
483*77c1e3ccSAndroid Build Coastguard Worker       got_data = true;
484*77c1e3ccSAndroid Build Coastguard Worker     }
485*77c1e3ccSAndroid Build Coastguard Worker   } while (got_data);
486*77c1e3ccSAndroid Build Coastguard Worker }
487*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,Buganizer314858909)488*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer314858909) {
489*77c1e3ccSAndroid Build Coastguard Worker   AV1Encoder encoder(7);
490*77c1e3ccSAndroid Build Coastguard Worker 
491*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(6, 1582, 750, AOM_CBR, AOM_USAGE_REALTIME);
492*77c1e3ccSAndroid Build Coastguard Worker 
493*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame.
494*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
495*77c1e3ccSAndroid Build Coastguard Worker 
496*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(0, 1582, 23, AOM_CBR, AOM_USAGE_REALTIME);
497*77c1e3ccSAndroid Build Coastguard Worker 
498*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame..
499*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
500*77c1e3ccSAndroid Build Coastguard Worker 
501*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(16, 1542, 363, AOM_CBR, AOM_USAGE_REALTIME);
502*77c1e3ccSAndroid Build Coastguard Worker 
503*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame..
504*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
505*77c1e3ccSAndroid Build Coastguard Worker }
506*77c1e3ccSAndroid Build Coastguard Worker 
507*77c1e3ccSAndroid Build Coastguard Worker // Run this test to reproduce the bug in fuzz test: ASSERT: cpi->rec_sse !=
508*77c1e3ccSAndroid Build Coastguard Worker // UINT64_MAX in av1_rc_bits_per_mb.
TEST(EncodeAPI,Buganizer310766628)509*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer310766628) {
510*77c1e3ccSAndroid Build Coastguard Worker   AV1Encoder encoder(7);
511*77c1e3ccSAndroid Build Coastguard Worker 
512*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(16, 759, 383, AOM_CBR, AOM_USAGE_REALTIME);
513*77c1e3ccSAndroid Build Coastguard Worker 
514*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame.
515*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
516*77c1e3ccSAndroid Build Coastguard Worker 
517*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(2, 759, 383, AOM_VBR, AOM_USAGE_REALTIME);
518*77c1e3ccSAndroid Build Coastguard Worker 
519*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame. This will trigger the assertion failure.
520*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
521*77c1e3ccSAndroid Build Coastguard Worker }
522*77c1e3ccSAndroid Build Coastguard Worker 
523*77c1e3ccSAndroid Build Coastguard Worker // This test covers a possible use case where the change of frame sizes and
524*77c1e3ccSAndroid Build Coastguard Worker // thread numbers happens before and after the first frame coding.
TEST(EncodeAPI,Buganizer310455204)525*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer310455204) {
526*77c1e3ccSAndroid Build Coastguard Worker   AV1Encoder encoder(7);
527*77c1e3ccSAndroid Build Coastguard Worker 
528*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(0, 1915, 503, AOM_VBR, AOM_USAGE_REALTIME);
529*77c1e3ccSAndroid Build Coastguard Worker 
530*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(4, 1, 1, AOM_VBR, AOM_USAGE_REALTIME);
531*77c1e3ccSAndroid Build Coastguard Worker 
532*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(6, 559, 503, AOM_CBR, AOM_USAGE_REALTIME);
533*77c1e3ccSAndroid Build Coastguard Worker 
534*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame.
535*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
536*77c1e3ccSAndroid Build Coastguard Worker 
537*77c1e3ccSAndroid Build Coastguard Worker   // Increase the number of threads.
538*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(16, 1915, 503, AOM_CBR, AOM_USAGE_REALTIME);
539*77c1e3ccSAndroid Build Coastguard Worker 
540*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame.
541*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
542*77c1e3ccSAndroid Build Coastguard Worker }
543*77c1e3ccSAndroid Build Coastguard Worker 
544*77c1e3ccSAndroid Build Coastguard Worker // Run this test to reproduce the bug in fuzz test: Float-cast-overflow in
545*77c1e3ccSAndroid Build Coastguard Worker // av1_rc_bits_per_mb.
TEST(EncodeAPI,Buganizer310457427)546*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer310457427) {
547*77c1e3ccSAndroid Build Coastguard Worker   AV1Encoder encoder(7);
548*77c1e3ccSAndroid Build Coastguard Worker 
549*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(12, 896, 1076, AOM_CBR, AOM_USAGE_REALTIME);
550*77c1e3ccSAndroid Build Coastguard Worker 
551*77c1e3ccSAndroid Build Coastguard Worker   encoder.Configure(6, 609, 1076, AOM_VBR, AOM_USAGE_REALTIME);
552*77c1e3ccSAndroid Build Coastguard Worker 
553*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame.
554*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
555*77c1e3ccSAndroid Build Coastguard Worker 
556*77c1e3ccSAndroid Build Coastguard Worker   // Encode a frame. This will trigger the float-cast-overflow bug which was
557*77c1e3ccSAndroid Build Coastguard Worker   // caused by division by zero.
558*77c1e3ccSAndroid Build Coastguard Worker   encoder.Encode(false);
559*77c1e3ccSAndroid Build Coastguard Worker }
560*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,PtsSmallerThanInitialPts)561*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, PtsSmallerThanInitialPts) {
562*77c1e3ccSAndroid Build Coastguard Worker   // Initialize libaom encoder.
563*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *const iface = aom_codec_av1_cx();
564*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
565*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
566*77c1e3ccSAndroid Build Coastguard Worker 
567*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME),
568*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
569*77c1e3ccSAndroid Build Coastguard Worker 
570*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 1280;
571*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 720;
572*77c1e3ccSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1000;
573*77c1e3ccSAndroid Build Coastguard Worker 
574*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
575*77c1e3ccSAndroid Build Coastguard Worker 
576*77c1e3ccSAndroid Build Coastguard Worker   // Create input image.
577*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *const image =
578*77c1e3ccSAndroid Build Coastguard Worker       CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
579*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
580*77c1e3ccSAndroid Build Coastguard Worker 
581*77c1e3ccSAndroid Build Coastguard Worker   // Encode frame.
582*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 12, 1, 0), AOM_CODEC_OK);
583*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 13, 1, 0), AOM_CODEC_OK);
584*77c1e3ccSAndroid Build Coastguard Worker   // pts (10) is smaller than the initial pts (12).
585*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 10, 1, 0), AOM_CODEC_INVALID_PARAM);
586*77c1e3ccSAndroid Build Coastguard Worker 
587*77c1e3ccSAndroid Build Coastguard Worker   // Free resources.
588*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
589*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_destroy(&enc);
590*77c1e3ccSAndroid Build Coastguard Worker }
591*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,PtsOrDurationTooBig)592*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, PtsOrDurationTooBig) {
593*77c1e3ccSAndroid Build Coastguard Worker   // Initialize libaom encoder.
594*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *const iface = aom_codec_av1_cx();
595*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
596*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
597*77c1e3ccSAndroid Build Coastguard Worker 
598*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME),
599*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
600*77c1e3ccSAndroid Build Coastguard Worker 
601*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 1280;
602*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 720;
603*77c1e3ccSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1000;
604*77c1e3ccSAndroid Build Coastguard Worker 
605*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
606*77c1e3ccSAndroid Build Coastguard Worker 
607*77c1e3ccSAndroid Build Coastguard Worker   // Create input image.
608*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *const image =
609*77c1e3ccSAndroid Build Coastguard Worker       CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
610*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
611*77c1e3ccSAndroid Build Coastguard Worker 
612*77c1e3ccSAndroid Build Coastguard Worker   // Encode frame.
613*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
614*77c1e3ccSAndroid Build Coastguard Worker   // pts, when converted to ticks, is too big.
615*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, INT64_MAX / 1000000 + 1, 1, 0),
616*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_INVALID_PARAM);
617*77c1e3ccSAndroid Build Coastguard Worker #if ULONG_MAX > INT64_MAX
618*77c1e3ccSAndroid Build Coastguard Worker   // duration is too big.
619*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, (1ul << 63), 0),
620*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_INVALID_PARAM);
621*77c1e3ccSAndroid Build Coastguard Worker   // pts + duration is too big.
622*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 1, INT64_MAX, 0),
623*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_INVALID_PARAM);
624*77c1e3ccSAndroid Build Coastguard Worker #endif
625*77c1e3ccSAndroid Build Coastguard Worker   // pts + duration, when converted to ticks, is too big.
626*77c1e3ccSAndroid Build Coastguard Worker #if ULONG_MAX > INT64_MAX
627*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 0x1c0a0a1a3232, 0),
628*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_INVALID_PARAM);
629*77c1e3ccSAndroid Build Coastguard Worker #endif
630*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, INT64_MAX / 1000000, 1, 0),
631*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_INVALID_PARAM);
632*77c1e3ccSAndroid Build Coastguard Worker 
633*77c1e3ccSAndroid Build Coastguard Worker   // Free resources.
634*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
635*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_destroy(&enc);
636*77c1e3ccSAndroid Build Coastguard Worker }
637*77c1e3ccSAndroid Build Coastguard Worker 
638*77c1e3ccSAndroid Build Coastguard Worker // Reproduces https://crbug.com/339877165.
TEST(EncodeAPI,Buganizer339877165)639*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, Buganizer339877165) {
640*77c1e3ccSAndroid Build Coastguard Worker   // Initialize libaom encoder.
641*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *const iface = aom_codec_av1_cx();
642*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
643*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
644*77c1e3ccSAndroid Build Coastguard Worker 
645*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME),
646*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
647*77c1e3ccSAndroid Build Coastguard Worker 
648*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 2560;
649*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 1600;
650*77c1e3ccSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 231;
651*77c1e3ccSAndroid Build Coastguard Worker   cfg.rc_end_usage = AOM_CBR;
652*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_threads = 8;
653*77c1e3ccSAndroid Build Coastguard Worker 
654*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
655*77c1e3ccSAndroid Build Coastguard Worker 
656*77c1e3ccSAndroid Build Coastguard Worker   // From libaom_av1_encoder.cc in WebRTC.
657*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 11), AOM_CODEC_OK);
658*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_CDEF, 1), AOM_CODEC_OK);
659*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_TPL_MODEL, 0),
660*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
661*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_DELTAQ_MODE, 0), AOM_CODEC_OK);
662*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_ORDER_HINT, 0),
663*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
664*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_AQ_MODE, 3), AOM_CODEC_OK);
665*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AOME_SET_MAX_INTRA_BITRATE_PCT, 300),
666*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
667*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_COEFF_COST_UPD_FREQ, 3),
668*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
669*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MODE_COST_UPD_FREQ, 3),
670*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
671*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MV_COST_UPD_FREQ, 3),
672*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
673*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN),
674*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
675*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_PALETTE, 1), AOM_CODEC_OK);
676*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 1), AOM_CODEC_OK);
677*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 2), AOM_CODEC_OK);
678*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_OBMC, 0), AOM_CODEC_OK);
679*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_NOISE_SENSITIVITY, 0),
680*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
681*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_WARPED_MOTION, 0),
682*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
683*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_GLOBAL_MOTION, 0),
684*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
685*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_REF_FRAME_MVS, 0),
686*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
687*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SUPERBLOCK_SIZE,
688*77c1e3ccSAndroid Build Coastguard Worker                               AOM_SUPERBLOCK_SIZE_DYNAMIC),
689*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
690*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_CFL_INTRA, 0),
691*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
692*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_SMOOTH_INTRA, 0),
693*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
694*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_ANGLE_DELTA, 0),
695*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
696*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_FILTER_INTRA, 0),
697*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
698*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_INTRA_DEFAULT_TX_ONLY, 1),
699*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
700*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_DISABLE_TRELLIS_QUANT, 1),
701*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
702*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DIST_WTD_COMP, 0),
703*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
704*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DIFF_WTD_COMP, 0),
705*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
706*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DUAL_FILTER, 0),
707*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
708*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTERINTRA_COMP, 0),
709*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
710*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTERINTRA_WEDGE, 0),
711*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
712*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, 0),
713*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
714*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTRABC, 0), AOM_CODEC_OK);
715*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_MASKED_COMP, 0),
716*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
717*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_PAETH_INTRA, 0),
718*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
719*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_QM, 0), AOM_CODEC_OK);
720*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_RECT_PARTITIONS, 0),
721*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
722*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_RESTORATION, 0),
723*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
724*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_SMOOTH_INTERINTRA, 0),
725*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
726*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_TX64, 0), AOM_CODEC_OK);
727*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MAX_REFERENCE_FRAMES, 3),
728*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
729*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK);
730*77c1e3ccSAndroid Build Coastguard Worker 
731*77c1e3ccSAndroid Build Coastguard Worker   aom_svc_params_t svc_params = {};
732*77c1e3ccSAndroid Build Coastguard Worker   svc_params.number_spatial_layers = 2;
733*77c1e3ccSAndroid Build Coastguard Worker   svc_params.number_temporal_layers = 1;
734*77c1e3ccSAndroid Build Coastguard Worker   svc_params.max_quantizers[0] = svc_params.max_quantizers[1] = 56;
735*77c1e3ccSAndroid Build Coastguard Worker   svc_params.min_quantizers[0] = svc_params.min_quantizers[1] = 10;
736*77c1e3ccSAndroid Build Coastguard Worker   svc_params.scaling_factor_num[0] = svc_params.scaling_factor_num[1] = 1;
737*77c1e3ccSAndroid Build Coastguard Worker   svc_params.scaling_factor_den[0] = 2;
738*77c1e3ccSAndroid Build Coastguard Worker   svc_params.scaling_factor_den[1] = 1;
739*77c1e3ccSAndroid Build Coastguard Worker   svc_params.layer_target_bitrate[0] = cfg.rc_target_bitrate;
740*77c1e3ccSAndroid Build Coastguard Worker   svc_params.framerate_factor[0] = 1;
741*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_PARAMS, &svc_params),
742*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
743*77c1e3ccSAndroid Build Coastguard Worker 
744*77c1e3ccSAndroid Build Coastguard Worker   aom_svc_layer_id_t layer_id = {};
745*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_LAYER_ID, &layer_id),
746*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
747*77c1e3ccSAndroid Build Coastguard Worker 
748*77c1e3ccSAndroid Build Coastguard Worker   aom_svc_ref_frame_config_t ref_frame_config = {};
749*77c1e3ccSAndroid Build Coastguard Worker   ref_frame_config.refresh[0] = 1;
750*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(
751*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_control(&enc, AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config),
752*77c1e3ccSAndroid Build Coastguard Worker       AOM_CODEC_OK);
753*77c1e3ccSAndroid Build Coastguard Worker 
754*77c1e3ccSAndroid Build Coastguard Worker   // Create input image.
755*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *const image =
756*77c1e3ccSAndroid Build Coastguard Worker       CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
757*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
758*77c1e3ccSAndroid Build Coastguard Worker 
759*77c1e3ccSAndroid Build Coastguard Worker   // Encode layer 0.
760*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
761*77c1e3ccSAndroid Build Coastguard Worker 
762*77c1e3ccSAndroid Build Coastguard Worker   layer_id.spatial_layer_id = 1;
763*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_LAYER_ID, &layer_id),
764*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
765*77c1e3ccSAndroid Build Coastguard Worker 
766*77c1e3ccSAndroid Build Coastguard Worker   ref_frame_config.refresh[0] = 0;
767*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(
768*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_control(&enc, AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config),
769*77c1e3ccSAndroid Build Coastguard Worker       AOM_CODEC_OK);
770*77c1e3ccSAndroid Build Coastguard Worker 
771*77c1e3ccSAndroid Build Coastguard Worker   // Encode layer 1.
772*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
773*77c1e3ccSAndroid Build Coastguard Worker 
774*77c1e3ccSAndroid Build Coastguard Worker   // Free resources.
775*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
776*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_destroy(&enc);
777*77c1e3ccSAndroid Build Coastguard Worker }
778*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,AomediaIssue3509VbrMinSection2Percent)779*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, AomediaIssue3509VbrMinSection2Percent) {
780*77c1e3ccSAndroid Build Coastguard Worker   // Initialize libaom encoder.
781*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *const iface = aom_codec_av1_cx();
782*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
783*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
784*77c1e3ccSAndroid Build Coastguard Worker 
785*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME),
786*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
787*77c1e3ccSAndroid Build Coastguard Worker 
788*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 1920;
789*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 1080;
790*77c1e3ccSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1000000;
791*77c1e3ccSAndroid Build Coastguard Worker   // Set this to more than 1 percent to cause a signed integer overflow in the
792*77c1e3ccSAndroid Build Coastguard Worker   // multiplication rc->avg_frame_bandwidth * oxcf->rc_cfg.vbrmin_section in
793*77c1e3ccSAndroid Build Coastguard Worker   // av1_rc_update_framerate() if the multiplication is done in the `int` type.
794*77c1e3ccSAndroid Build Coastguard Worker   cfg.rc_2pass_vbr_minsection_pct = 2;
795*77c1e3ccSAndroid Build Coastguard Worker 
796*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
797*77c1e3ccSAndroid Build Coastguard Worker 
798*77c1e3ccSAndroid Build Coastguard Worker   // Create input image.
799*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *const image =
800*77c1e3ccSAndroid Build Coastguard Worker       CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
801*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
802*77c1e3ccSAndroid Build Coastguard Worker 
803*77c1e3ccSAndroid Build Coastguard Worker   // Encode frame.
804*77c1e3ccSAndroid Build Coastguard Worker   // `duration` can go as high as 300, but the UBSan error is gone if
805*77c1e3ccSAndroid Build Coastguard Worker   // `duration` is 301 or higher.
806*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, /*duration=*/300, 0),
807*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
808*77c1e3ccSAndroid Build Coastguard Worker 
809*77c1e3ccSAndroid Build Coastguard Worker   // Free resources.
810*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
811*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
812*77c1e3ccSAndroid Build Coastguard Worker }
813*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,AomediaIssue3509VbrMinSection101Percent)814*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, AomediaIssue3509VbrMinSection101Percent) {
815*77c1e3ccSAndroid Build Coastguard Worker   // Initialize libaom encoder.
816*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *const iface = aom_codec_av1_cx();
817*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
818*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
819*77c1e3ccSAndroid Build Coastguard Worker 
820*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME),
821*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
822*77c1e3ccSAndroid Build Coastguard Worker 
823*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 1920;
824*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 1080;
825*77c1e3ccSAndroid Build Coastguard Worker   cfg.rc_target_bitrate = 1000000;
826*77c1e3ccSAndroid Build Coastguard Worker   // Set this to more than 100 percent to cause an error when vbr_min_bits is
827*77c1e3ccSAndroid Build Coastguard Worker   // cast to `int` in av1_rc_update_framerate() if vbr_min_bits is not clamped
828*77c1e3ccSAndroid Build Coastguard Worker   // to INT_MAX.
829*77c1e3ccSAndroid Build Coastguard Worker   cfg.rc_2pass_vbr_minsection_pct = 101;
830*77c1e3ccSAndroid Build Coastguard Worker 
831*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
832*77c1e3ccSAndroid Build Coastguard Worker 
833*77c1e3ccSAndroid Build Coastguard Worker   // Create input image.
834*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *const image =
835*77c1e3ccSAndroid Build Coastguard Worker       CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
836*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
837*77c1e3ccSAndroid Build Coastguard Worker 
838*77c1e3ccSAndroid Build Coastguard Worker   // Encode frame.
839*77c1e3ccSAndroid Build Coastguard Worker   // `duration` can go as high as 300, but the UBSan error is gone if
840*77c1e3ccSAndroid Build Coastguard Worker   // `duration` is 301 or higher.
841*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, /*duration=*/300, 0),
842*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
843*77c1e3ccSAndroid Build Coastguard Worker 
844*77c1e3ccSAndroid Build Coastguard Worker   // Free resources.
845*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
846*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
847*77c1e3ccSAndroid Build Coastguard Worker }
848*77c1e3ccSAndroid Build Coastguard Worker 
849*77c1e3ccSAndroid Build Coastguard Worker class EncodeAPIParameterized
850*77c1e3ccSAndroid Build Coastguard Worker     : public testing::TestWithParam<std::tuple<
851*77c1e3ccSAndroid Build Coastguard Worker           /*usage=*/unsigned int, /*speed=*/int, /*aq_mode=*/unsigned int>> {};
852*77c1e3ccSAndroid Build Coastguard Worker 
853*77c1e3ccSAndroid Build Coastguard Worker // Encodes two frames at a given usage, speed, and aq_mode setting.
854*77c1e3ccSAndroid Build Coastguard Worker // Reproduces b/303023614
TEST_P(EncodeAPIParameterized,HighBDEncoderHighBDFrames)855*77c1e3ccSAndroid Build Coastguard Worker TEST_P(EncodeAPIParameterized, HighBDEncoderHighBDFrames) {
856*77c1e3ccSAndroid Build Coastguard Worker   const unsigned int usage = std::get<0>(GetParam());
857*77c1e3ccSAndroid Build Coastguard Worker   int speed = std::get<1>(GetParam());
858*77c1e3ccSAndroid Build Coastguard Worker 
859*77c1e3ccSAndroid Build Coastguard Worker   if (speed == 10 && usage != AOM_USAGE_REALTIME) {
860*77c1e3ccSAndroid Build Coastguard Worker     speed = 9;  // 10 is only allowed in AOM_USAGE_REALTIME
861*77c1e3ccSAndroid Build Coastguard Worker   }
862*77c1e3ccSAndroid Build Coastguard Worker 
863*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
864*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
865*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, usage), AOM_CODEC_OK);
866*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_w = 500;
867*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_h = 400;
868*77c1e3ccSAndroid Build Coastguard Worker 
869*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
870*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_err_t init_status =
871*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH);
872*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_AV1_HIGHBITDEPTH
873*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(init_status, AOM_CODEC_INCAPABLE);
874*77c1e3ccSAndroid Build Coastguard Worker #else
875*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(init_status, AOM_CODEC_OK);
876*77c1e3ccSAndroid Build Coastguard Worker 
877*77c1e3ccSAndroid Build Coastguard Worker   const unsigned int aq_mode = std::get<2>(GetParam());
878*77c1e3ccSAndroid Build Coastguard Worker 
879*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, speed), AOM_CODEC_OK);
880*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_AQ_MODE, aq_mode), AOM_CODEC_OK);
881*77c1e3ccSAndroid Build Coastguard Worker 
882*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *image =
883*77c1e3ccSAndroid Build Coastguard Worker       aom_img_alloc(nullptr, AOM_IMG_FMT_I42016, cfg.g_w, cfg.g_h, 0);
884*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
885*77c1e3ccSAndroid Build Coastguard Worker 
886*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < image->d_h; ++i) {
887*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[0] + i * image->stride[0], 128, image->d_w);
888*77c1e3ccSAndroid Build Coastguard Worker   }
889*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_h = (image->d_h + 1) / 2;
890*77c1e3ccSAndroid Build Coastguard Worker   unsigned int uv_w = (image->d_w + 1) / 2;
891*77c1e3ccSAndroid Build Coastguard Worker   for (unsigned int i = 0; i < uv_h; ++i) {
892*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[1] + i * image->stride[1], 128, uv_w);
893*77c1e3ccSAndroid Build Coastguard Worker     Memset16(image->planes[2] + i * image->stride[2], 128, uv_w);
894*77c1e3ccSAndroid Build Coastguard Worker   }
895*77c1e3ccSAndroid Build Coastguard Worker 
896*77c1e3ccSAndroid Build Coastguard Worker   // Encode two frames.
897*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(
898*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_encode(&enc, image, /*pts=*/0, /*duration=*/1, /*flags=*/0),
899*77c1e3ccSAndroid Build Coastguard Worker       AOM_CODEC_OK);
900*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(
901*77c1e3ccSAndroid Build Coastguard Worker       aom_codec_encode(&enc, image, /*pts=*/1, /*duration=*/1, /*flags=*/0),
902*77c1e3ccSAndroid Build Coastguard Worker       AOM_CODEC_OK);
903*77c1e3ccSAndroid Build Coastguard Worker 
904*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
905*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
906*77c1e3ccSAndroid Build Coastguard Worker #endif
907*77c1e3ccSAndroid Build Coastguard Worker }
908*77c1e3ccSAndroid Build Coastguard Worker 
909*77c1e3ccSAndroid Build Coastguard Worker const unsigned int kUsages[] = {
910*77c1e3ccSAndroid Build Coastguard Worker   AOM_USAGE_REALTIME,
911*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
912*77c1e3ccSAndroid Build Coastguard Worker   AOM_USAGE_GOOD_QUALITY,
913*77c1e3ccSAndroid Build Coastguard Worker   AOM_USAGE_ALL_INTRA,
914*77c1e3ccSAndroid Build Coastguard Worker #endif
915*77c1e3ccSAndroid Build Coastguard Worker };
916*77c1e3ccSAndroid Build Coastguard Worker 
917*77c1e3ccSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All, EncodeAPIParameterized,
918*77c1e3ccSAndroid Build Coastguard Worker                          testing::Combine(
919*77c1e3ccSAndroid Build Coastguard Worker                              /*usage=*/testing::ValuesIn(kUsages),
920*77c1e3ccSAndroid Build Coastguard Worker                              /*speed=*/testing::Values(6, 7, 10),
921*77c1e3ccSAndroid Build Coastguard Worker                              /*aq_mode=*/testing::Values(0, 1, 2, 3)));
922*77c1e3ccSAndroid Build Coastguard Worker 
923*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
TEST(EncodeAPI,AllIntraMode)924*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, AllIntraMode) {
925*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
926*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
927*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
928*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK,
929*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA));
930*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));
931*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
932*77c1e3ccSAndroid Build Coastguard Worker 
933*77c1e3ccSAndroid Build Coastguard Worker   // Set g_lag_in_frames to a nonzero value. This should cause
934*77c1e3ccSAndroid Build Coastguard Worker   // aom_codec_enc_init() to fail.
935*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK,
936*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA));
937*77c1e3ccSAndroid Build Coastguard Worker   cfg.g_lag_in_frames = 1;
938*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
939*77c1e3ccSAndroid Build Coastguard Worker 
940*77c1e3ccSAndroid Build Coastguard Worker   // Set kf_max_dist to a nonzero value. This should cause aom_codec_enc_init()
941*77c1e3ccSAndroid Build Coastguard Worker   // to fail.
942*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK,
943*77c1e3ccSAndroid Build Coastguard Worker             aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA));
944*77c1e3ccSAndroid Build Coastguard Worker   cfg.kf_max_dist = 1;
945*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
946*77c1e3ccSAndroid Build Coastguard Worker }
947*77c1e3ccSAndroid Build Coastguard Worker 
TEST(EncodeAPI,AllIntraAndUsePsnr)948*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, AllIntraAndUsePsnr) {
949*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
950*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
951*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA),
952*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
953*77c1e3ccSAndroid Build Coastguard Worker 
954*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
955*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_PSNR),
956*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
957*77c1e3ccSAndroid Build Coastguard Worker 
958*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *image = CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
959*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
960*77c1e3ccSAndroid Build Coastguard Worker 
961*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
962*77c1e3ccSAndroid Build Coastguard Worker   const aom_codec_cx_pkt_t *pkt;
963*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iter_t iter = nullptr;
964*77c1e3ccSAndroid Build Coastguard Worker   while ((pkt = aom_codec_get_cx_data(&enc, &iter)) != nullptr) {
965*77c1e3ccSAndroid Build Coastguard Worker     if (pkt->kind != AOM_CODEC_CX_FRAME_PKT) {
966*77c1e3ccSAndroid Build Coastguard Worker       ASSERT_EQ(pkt->kind, AOM_CODEC_PSNR_PKT);
967*77c1e3ccSAndroid Build Coastguard Worker     }
968*77c1e3ccSAndroid Build Coastguard Worker   }
969*77c1e3ccSAndroid Build Coastguard Worker 
970*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
971*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
972*77c1e3ccSAndroid Build Coastguard Worker }
973*77c1e3ccSAndroid Build Coastguard Worker 
974*77c1e3ccSAndroid Build Coastguard Worker // A test that reproduces bug aomedia:3534.
TEST(EncodeAPI,AllIntraAndNoRefLast)975*77c1e3ccSAndroid Build Coastguard Worker TEST(EncodeAPI, AllIntraAndNoRefLast) {
976*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *iface = aom_codec_av1_cx();
977*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
978*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA),
979*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
980*77c1e3ccSAndroid Build Coastguard Worker 
981*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
982*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
983*77c1e3ccSAndroid Build Coastguard Worker 
984*77c1e3ccSAndroid Build Coastguard Worker   aom_image_t *image = CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
985*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(image, nullptr);
986*77c1e3ccSAndroid Build Coastguard Worker 
987*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, AOM_EFLAG_NO_REF_LAST),
988*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_OK);
989*77c1e3ccSAndroid Build Coastguard Worker 
990*77c1e3ccSAndroid Build Coastguard Worker   aom_img_free(image);
991*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
992*77c1e3ccSAndroid Build Coastguard Worker }
993*77c1e3ccSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
994*77c1e3ccSAndroid Build Coastguard Worker 
995*77c1e3ccSAndroid Build Coastguard Worker }  // namespace
996