1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2023, 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 <cstddef>
13*77c1e3ccSAndroid Build Coastguard Worker #include <cstdint>
14*77c1e3ccSAndroid Build Coastguard Worker #include <vector>
15*77c1e3ccSAndroid Build Coastguard Worker
16*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aomcx.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_codec.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_encoder.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_image.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
21*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
22*77c1e3ccSAndroid Build Coastguard Worker
23*77c1e3ccSAndroid Build Coastguard Worker namespace {
24*77c1e3ccSAndroid Build Coastguard Worker
25*77c1e3ccSAndroid Build Coastguard Worker /*
26*77c1e3ccSAndroid Build Coastguard Worker Reproduces https://crbug.com/aomedia/3376. Emulates the command line:
27*77c1e3ccSAndroid Build Coastguard Worker
28*77c1e3ccSAndroid Build Coastguard Worker ./aomenc --cpu-used=6 --threads=10 --cq-level=14 --passes=1 --limit=1 \
29*77c1e3ccSAndroid Build Coastguard Worker --lag-in-frames=0 --end-usage=q --deltaq-mode=3 --min-q=0 --max-q=63 \
30*77c1e3ccSAndroid Build Coastguard Worker -o output.av1 niklas_1280_720_30.y4m
31*77c1e3ccSAndroid Build Coastguard Worker */
TEST(DeltaqModeTest,DeltaqMode3MultiThread)32*77c1e3ccSAndroid Build Coastguard Worker TEST(DeltaqModeTest, DeltaqMode3MultiThread) {
33*77c1e3ccSAndroid Build Coastguard Worker constexpr int kWidth = 1280;
34*77c1e3ccSAndroid Build Coastguard Worker constexpr int kHeight = 720;
35*77c1e3ccSAndroid Build Coastguard Worker // Dummy buffer of neutral gray samples.
36*77c1e3ccSAndroid Build Coastguard Worker constexpr size_t kBufferSize = kWidth * kHeight + kWidth * kHeight / 2;
37*77c1e3ccSAndroid Build Coastguard Worker std::vector<unsigned char> buffer(kBufferSize,
38*77c1e3ccSAndroid Build Coastguard Worker static_cast<unsigned char>(128));
39*77c1e3ccSAndroid Build Coastguard Worker
40*77c1e3ccSAndroid Build Coastguard Worker aom_image_t img;
41*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(&img, aom_img_wrap(&img, AOM_IMG_FMT_I420, kWidth, kHeight, 1,
42*77c1e3ccSAndroid Build Coastguard Worker buffer.data()));
43*77c1e3ccSAndroid Build Coastguard Worker
44*77c1e3ccSAndroid Build Coastguard Worker aom_codec_iface_t *iface = aom_codec_av1_cx();
45*77c1e3ccSAndroid Build Coastguard Worker aom_codec_enc_cfg_t cfg;
46*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY),
47*77c1e3ccSAndroid Build Coastguard Worker AOM_CODEC_OK);
48*77c1e3ccSAndroid Build Coastguard Worker cfg.g_w = kWidth;
49*77c1e3ccSAndroid Build Coastguard Worker cfg.g_h = kHeight;
50*77c1e3ccSAndroid Build Coastguard Worker cfg.g_threads = 10;
51*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_end_usage = AOM_Q;
52*77c1e3ccSAndroid Build Coastguard Worker cfg.g_profile = 0;
53*77c1e3ccSAndroid Build Coastguard Worker cfg.g_bit_depth = AOM_BITS_8;
54*77c1e3ccSAndroid Build Coastguard Worker cfg.g_input_bit_depth = 8;
55*77c1e3ccSAndroid Build Coastguard Worker cfg.g_lag_in_frames = 0;
56*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_min_quantizer = 0;
57*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_max_quantizer = 63;
58*77c1e3ccSAndroid Build Coastguard Worker cfg.g_pass = AOM_RC_ONE_PASS;
59*77c1e3ccSAndroid Build Coastguard Worker cfg.g_limit = 1;
60*77c1e3ccSAndroid Build Coastguard Worker aom_codec_ctx_t enc;
61*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
62*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 6), AOM_CODEC_OK);
63*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 14), AOM_CODEC_OK);
64*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_DELTAQ_MODE, 3), AOM_CODEC_OK);
65*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_set_option(&enc, "passes", "1"), AOM_CODEC_OK);
66*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_STUDIO_RANGE),
67*77c1e3ccSAndroid Build Coastguard Worker AOM_CODEC_OK);
68*77c1e3ccSAndroid Build Coastguard Worker
69*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
70*77c1e3ccSAndroid Build Coastguard Worker aom_codec_iter_t iter = nullptr;
71*77c1e3ccSAndroid Build Coastguard Worker const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
72*77c1e3ccSAndroid Build Coastguard Worker ASSERT_NE(pkt, nullptr);
73*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
74*77c1e3ccSAndroid Build Coastguard Worker // pkt->data.frame.flags is 0x1f0011.
75*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
76*77c1e3ccSAndroid Build Coastguard Worker pkt = aom_codec_get_cx_data(&enc, &iter);
77*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt, nullptr);
78*77c1e3ccSAndroid Build Coastguard Worker
79*77c1e3ccSAndroid Build Coastguard Worker // Flush encoder
80*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
81*77c1e3ccSAndroid Build Coastguard Worker iter = nullptr;
82*77c1e3ccSAndroid Build Coastguard Worker pkt = aom_codec_get_cx_data(&enc, &iter);
83*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt, nullptr);
84*77c1e3ccSAndroid Build Coastguard Worker
85*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
86*77c1e3ccSAndroid Build Coastguard Worker }
87*77c1e3ccSAndroid Build Coastguard Worker
88*77c1e3ccSAndroid Build Coastguard Worker // The implementation of multi-threading for deltaq-mode=3 in allintra
89*77c1e3ccSAndroid Build Coastguard Worker // mode is based on row multi-threading.
90*77c1e3ccSAndroid Build Coastguard Worker // The test ensures that When row mt is turned off,
91*77c1e3ccSAndroid Build Coastguard Worker // deltaq-mode = 3 can still properly encode and decode.
TEST(DeltaqModeTest,DeltaqMode3MultiThreadNoRowMT)92*77c1e3ccSAndroid Build Coastguard Worker TEST(DeltaqModeTest, DeltaqMode3MultiThreadNoRowMT) {
93*77c1e3ccSAndroid Build Coastguard Worker constexpr int kWidth = 1280;
94*77c1e3ccSAndroid Build Coastguard Worker constexpr int kHeight = 720;
95*77c1e3ccSAndroid Build Coastguard Worker // Dummy buffer of neutral gray samples.
96*77c1e3ccSAndroid Build Coastguard Worker constexpr size_t kBufferSize = kWidth * kHeight + kWidth * kHeight / 2;
97*77c1e3ccSAndroid Build Coastguard Worker std::vector<unsigned char> buffer(kBufferSize,
98*77c1e3ccSAndroid Build Coastguard Worker static_cast<unsigned char>(128));
99*77c1e3ccSAndroid Build Coastguard Worker
100*77c1e3ccSAndroid Build Coastguard Worker aom_image_t img;
101*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(&img, aom_img_wrap(&img, AOM_IMG_FMT_I420, kWidth, kHeight, 1,
102*77c1e3ccSAndroid Build Coastguard Worker buffer.data()));
103*77c1e3ccSAndroid Build Coastguard Worker
104*77c1e3ccSAndroid Build Coastguard Worker aom_codec_iface_t *iface = aom_codec_av1_cx();
105*77c1e3ccSAndroid Build Coastguard Worker aom_codec_enc_cfg_t cfg;
106*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY),
107*77c1e3ccSAndroid Build Coastguard Worker AOM_CODEC_OK);
108*77c1e3ccSAndroid Build Coastguard Worker cfg.g_w = kWidth;
109*77c1e3ccSAndroid Build Coastguard Worker cfg.g_h = kHeight;
110*77c1e3ccSAndroid Build Coastguard Worker cfg.g_threads = 10;
111*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_end_usage = AOM_Q;
112*77c1e3ccSAndroid Build Coastguard Worker cfg.g_profile = 0;
113*77c1e3ccSAndroid Build Coastguard Worker cfg.g_bit_depth = AOM_BITS_8;
114*77c1e3ccSAndroid Build Coastguard Worker cfg.g_input_bit_depth = 8;
115*77c1e3ccSAndroid Build Coastguard Worker cfg.g_lag_in_frames = 0;
116*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_min_quantizer = 0;
117*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_max_quantizer = 63;
118*77c1e3ccSAndroid Build Coastguard Worker cfg.g_pass = AOM_RC_ONE_PASS;
119*77c1e3ccSAndroid Build Coastguard Worker cfg.g_limit = 1;
120*77c1e3ccSAndroid Build Coastguard Worker aom_codec_ctx_t enc;
121*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
122*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_ROW_MT, 0), AOM_CODEC_OK);
123*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 6), AOM_CODEC_OK);
124*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 14), AOM_CODEC_OK);
125*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_DELTAQ_MODE, 3), AOM_CODEC_OK);
126*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_set_option(&enc, "passes", "1"), AOM_CODEC_OK);
127*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_STUDIO_RANGE),
128*77c1e3ccSAndroid Build Coastguard Worker AOM_CODEC_OK);
129*77c1e3ccSAndroid Build Coastguard Worker
130*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
131*77c1e3ccSAndroid Build Coastguard Worker aom_codec_iter_t iter = nullptr;
132*77c1e3ccSAndroid Build Coastguard Worker const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
133*77c1e3ccSAndroid Build Coastguard Worker ASSERT_NE(pkt, nullptr);
134*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
135*77c1e3ccSAndroid Build Coastguard Worker // pkt->data.frame.flags is 0x1f0011.
136*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
137*77c1e3ccSAndroid Build Coastguard Worker pkt = aom_codec_get_cx_data(&enc, &iter);
138*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt, nullptr);
139*77c1e3ccSAndroid Build Coastguard Worker
140*77c1e3ccSAndroid Build Coastguard Worker // Flush encoder
141*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
142*77c1e3ccSAndroid Build Coastguard Worker iter = nullptr;
143*77c1e3ccSAndroid Build Coastguard Worker pkt = aom_codec_get_cx_data(&enc, &iter);
144*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt, nullptr);
145*77c1e3ccSAndroid Build Coastguard Worker
146*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
147*77c1e3ccSAndroid Build Coastguard Worker }
148*77c1e3ccSAndroid Build Coastguard Worker
149*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
150*77c1e3ccSAndroid Build Coastguard Worker // 10-bit version of the DeltaqMode3MultiThread test.
TEST(DeltaqModeTest,DeltaqMode3MultiThreadHighbd)151*77c1e3ccSAndroid Build Coastguard Worker TEST(DeltaqModeTest, DeltaqMode3MultiThreadHighbd) {
152*77c1e3ccSAndroid Build Coastguard Worker constexpr int kWidth = 1280;
153*77c1e3ccSAndroid Build Coastguard Worker constexpr int kHeight = 720;
154*77c1e3ccSAndroid Build Coastguard Worker // Dummy buffer of 10-bit neutral gray samples.
155*77c1e3ccSAndroid Build Coastguard Worker constexpr size_t kBufferSize = kWidth * kHeight + kWidth * kHeight / 2;
156*77c1e3ccSAndroid Build Coastguard Worker std::vector<uint16_t> buffer(kBufferSize, 512);
157*77c1e3ccSAndroid Build Coastguard Worker
158*77c1e3ccSAndroid Build Coastguard Worker aom_image_t img;
159*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(&img,
160*77c1e3ccSAndroid Build Coastguard Worker aom_img_wrap(&img, AOM_IMG_FMT_I42016, kWidth, kHeight, 1,
161*77c1e3ccSAndroid Build Coastguard Worker reinterpret_cast<unsigned char *>(buffer.data())));
162*77c1e3ccSAndroid Build Coastguard Worker
163*77c1e3ccSAndroid Build Coastguard Worker aom_codec_iface_t *iface = aom_codec_av1_cx();
164*77c1e3ccSAndroid Build Coastguard Worker aom_codec_enc_cfg_t cfg;
165*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY),
166*77c1e3ccSAndroid Build Coastguard Worker AOM_CODEC_OK);
167*77c1e3ccSAndroid Build Coastguard Worker cfg.g_w = kWidth;
168*77c1e3ccSAndroid Build Coastguard Worker cfg.g_h = kHeight;
169*77c1e3ccSAndroid Build Coastguard Worker cfg.g_threads = 10;
170*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_end_usage = AOM_Q;
171*77c1e3ccSAndroid Build Coastguard Worker cfg.g_profile = 0;
172*77c1e3ccSAndroid Build Coastguard Worker cfg.g_bit_depth = AOM_BITS_10;
173*77c1e3ccSAndroid Build Coastguard Worker cfg.g_input_bit_depth = 10;
174*77c1e3ccSAndroid Build Coastguard Worker cfg.g_lag_in_frames = 0;
175*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_min_quantizer = 0;
176*77c1e3ccSAndroid Build Coastguard Worker cfg.rc_max_quantizer = 63;
177*77c1e3ccSAndroid Build Coastguard Worker cfg.g_pass = AOM_RC_ONE_PASS;
178*77c1e3ccSAndroid Build Coastguard Worker cfg.g_limit = 1;
179*77c1e3ccSAndroid Build Coastguard Worker aom_codec_ctx_t enc;
180*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH),
181*77c1e3ccSAndroid Build Coastguard Worker AOM_CODEC_OK);
182*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 6), AOM_CODEC_OK);
183*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 14), AOM_CODEC_OK);
184*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_DELTAQ_MODE, 3), AOM_CODEC_OK);
185*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_set_option(&enc, "passes", "1"), AOM_CODEC_OK);
186*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_STUDIO_RANGE),
187*77c1e3ccSAndroid Build Coastguard Worker AOM_CODEC_OK);
188*77c1e3ccSAndroid Build Coastguard Worker
189*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
190*77c1e3ccSAndroid Build Coastguard Worker aom_codec_iter_t iter = nullptr;
191*77c1e3ccSAndroid Build Coastguard Worker const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
192*77c1e3ccSAndroid Build Coastguard Worker ASSERT_NE(pkt, nullptr);
193*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
194*77c1e3ccSAndroid Build Coastguard Worker // pkt->data.frame.flags is 0x1f0011.
195*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
196*77c1e3ccSAndroid Build Coastguard Worker pkt = aom_codec_get_cx_data(&enc, &iter);
197*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt, nullptr);
198*77c1e3ccSAndroid Build Coastguard Worker
199*77c1e3ccSAndroid Build Coastguard Worker // Flush encoder
200*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
201*77c1e3ccSAndroid Build Coastguard Worker iter = nullptr;
202*77c1e3ccSAndroid Build Coastguard Worker pkt = aom_codec_get_cx_data(&enc, &iter);
203*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(pkt, nullptr);
204*77c1e3ccSAndroid Build Coastguard Worker
205*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
206*77c1e3ccSAndroid Build Coastguard Worker }
207*77c1e3ccSAndroid Build Coastguard Worker #endif // CONFIG_AV1_HIGHBITDEPTH
208*77c1e3ccSAndroid Build Coastguard Worker
209*77c1e3ccSAndroid Build Coastguard Worker } // namespace
210