xref: /aosp_15_r20/external/libaom/test/decode_multithreaded_test.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2018, 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 <cstdio>
13*77c1e3ccSAndroid Build Coastguard Worker #include <cstdlib>
14*77c1e3ccSAndroid Build Coastguard Worker #include <string>
15*77c1e3ccSAndroid Build Coastguard Worker 
16*77c1e3ccSAndroid Build Coastguard Worker #include "aom_mem/aom_mem.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "test/codec_factory.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "test/encode_test_driver.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "test/i420_video_source.h"
21*77c1e3ccSAndroid Build Coastguard Worker #include "test/md5_helper.h"
22*77c1e3ccSAndroid Build Coastguard Worker #include "test/util.h"
23*77c1e3ccSAndroid Build Coastguard Worker 
24*77c1e3ccSAndroid Build Coastguard Worker namespace {
25*77c1e3ccSAndroid Build Coastguard Worker 
26*77c1e3ccSAndroid Build Coastguard Worker static const int kNumMultiThreadDecoders = 3;
27*77c1e3ccSAndroid Build Coastguard Worker 
28*77c1e3ccSAndroid Build Coastguard Worker class AV1DecodeMultiThreadedTest
29*77c1e3ccSAndroid Build Coastguard Worker     : public ::libaom_test::CodecTestWith5Params<int, int, int, int, int>,
30*77c1e3ccSAndroid Build Coastguard Worker       public ::libaom_test::EncoderTest {
31*77c1e3ccSAndroid Build Coastguard Worker  protected:
AV1DecodeMultiThreadedTest()32*77c1e3ccSAndroid Build Coastguard Worker   AV1DecodeMultiThreadedTest()
33*77c1e3ccSAndroid Build Coastguard Worker       : EncoderTest(GET_PARAM(0)), md5_single_thread_(), md5_multi_thread_(),
34*77c1e3ccSAndroid Build Coastguard Worker         n_tile_cols_(GET_PARAM(1)), n_tile_rows_(GET_PARAM(2)),
35*77c1e3ccSAndroid Build Coastguard Worker         n_tile_groups_(GET_PARAM(3)), set_cpu_used_(GET_PARAM(4)),
36*77c1e3ccSAndroid Build Coastguard Worker         row_mt_(GET_PARAM(5)) {
37*77c1e3ccSAndroid Build Coastguard Worker     init_flags_ = AOM_CODEC_USE_PSNR;
38*77c1e3ccSAndroid Build Coastguard Worker     aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
39*77c1e3ccSAndroid Build Coastguard Worker     cfg.w = 704;
40*77c1e3ccSAndroid Build Coastguard Worker     cfg.h = 576;
41*77c1e3ccSAndroid Build Coastguard Worker     cfg.threads = 1;
42*77c1e3ccSAndroid Build Coastguard Worker     cfg.allow_lowbitdepth = 1;
43*77c1e3ccSAndroid Build Coastguard Worker     single_thread_dec_ = codec_->CreateDecoder(cfg, 0);
44*77c1e3ccSAndroid Build Coastguard Worker 
45*77c1e3ccSAndroid Build Coastguard Worker     // Test cfg.threads == powers of 2.
46*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < kNumMultiThreadDecoders; ++i) {
47*77c1e3ccSAndroid Build Coastguard Worker       cfg.threads <<= 1;
48*77c1e3ccSAndroid Build Coastguard Worker       multi_thread_dec_[i] = codec_->CreateDecoder(cfg, 0);
49*77c1e3ccSAndroid Build Coastguard Worker       multi_thread_dec_[i]->Control(AV1D_SET_ROW_MT, row_mt_);
50*77c1e3ccSAndroid Build Coastguard Worker     }
51*77c1e3ccSAndroid Build Coastguard Worker 
52*77c1e3ccSAndroid Build Coastguard Worker     if (single_thread_dec_->IsAV1()) {
53*77c1e3ccSAndroid Build Coastguard Worker       single_thread_dec_->Control(AV1D_EXT_TILE_DEBUG, 1);
54*77c1e3ccSAndroid Build Coastguard Worker       single_thread_dec_->Control(AV1_SET_DECODE_TILE_ROW, -1);
55*77c1e3ccSAndroid Build Coastguard Worker       single_thread_dec_->Control(AV1_SET_DECODE_TILE_COL, -1);
56*77c1e3ccSAndroid Build Coastguard Worker     }
57*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < kNumMultiThreadDecoders; ++i) {
58*77c1e3ccSAndroid Build Coastguard Worker       if (multi_thread_dec_[i]->IsAV1()) {
59*77c1e3ccSAndroid Build Coastguard Worker         multi_thread_dec_[i]->Control(AV1D_EXT_TILE_DEBUG, 1);
60*77c1e3ccSAndroid Build Coastguard Worker         multi_thread_dec_[i]->Control(AV1_SET_DECODE_TILE_ROW, -1);
61*77c1e3ccSAndroid Build Coastguard Worker         multi_thread_dec_[i]->Control(AV1_SET_DECODE_TILE_COL, -1);
62*77c1e3ccSAndroid Build Coastguard Worker       }
63*77c1e3ccSAndroid Build Coastguard Worker     }
64*77c1e3ccSAndroid Build Coastguard Worker   }
65*77c1e3ccSAndroid Build Coastguard Worker 
~AV1DecodeMultiThreadedTest()66*77c1e3ccSAndroid Build Coastguard Worker   ~AV1DecodeMultiThreadedTest() override {
67*77c1e3ccSAndroid Build Coastguard Worker     delete single_thread_dec_;
68*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < kNumMultiThreadDecoders; ++i)
69*77c1e3ccSAndroid Build Coastguard Worker       delete multi_thread_dec_[i];
70*77c1e3ccSAndroid Build Coastguard Worker   }
71*77c1e3ccSAndroid Build Coastguard Worker 
SetUp()72*77c1e3ccSAndroid Build Coastguard Worker   void SetUp() override { InitializeConfig(libaom_test::kTwoPassGood); }
73*77c1e3ccSAndroid Build Coastguard Worker 
PreEncodeFrameHook(libaom_test::VideoSource * video,libaom_test::Encoder * encoder)74*77c1e3ccSAndroid Build Coastguard Worker   void PreEncodeFrameHook(libaom_test::VideoSource *video,
75*77c1e3ccSAndroid Build Coastguard Worker                           libaom_test::Encoder *encoder) override {
76*77c1e3ccSAndroid Build Coastguard Worker     if (video->frame() == 0) {
77*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_);
78*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_);
79*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AV1E_SET_NUM_TG, n_tile_groups_);
80*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
81*77c1e3ccSAndroid Build Coastguard Worker     }
82*77c1e3ccSAndroid Build Coastguard Worker   }
83*77c1e3ccSAndroid Build Coastguard Worker 
UpdateMD5(::libaom_test::Decoder * dec,const aom_codec_cx_pkt_t * pkt,::libaom_test::MD5 * md5)84*77c1e3ccSAndroid Build Coastguard Worker   void UpdateMD5(::libaom_test::Decoder *dec, const aom_codec_cx_pkt_t *pkt,
85*77c1e3ccSAndroid Build Coastguard Worker                  ::libaom_test::MD5 *md5) {
86*77c1e3ccSAndroid Build Coastguard Worker     const aom_codec_err_t res = dec->DecodeFrame(
87*77c1e3ccSAndroid Build Coastguard Worker         reinterpret_cast<uint8_t *>(pkt->data.frame.buf), pkt->data.frame.sz);
88*77c1e3ccSAndroid Build Coastguard Worker     if (res != AOM_CODEC_OK) {
89*77c1e3ccSAndroid Build Coastguard Worker       abort_ = true;
90*77c1e3ccSAndroid Build Coastguard Worker       ASSERT_EQ(AOM_CODEC_OK, res);
91*77c1e3ccSAndroid Build Coastguard Worker     }
92*77c1e3ccSAndroid Build Coastguard Worker     const aom_image_t *img = dec->GetDxData().Next();
93*77c1e3ccSAndroid Build Coastguard Worker     md5->Add(img);
94*77c1e3ccSAndroid Build Coastguard Worker   }
95*77c1e3ccSAndroid Build Coastguard Worker 
FramePktHook(const aom_codec_cx_pkt_t * pkt)96*77c1e3ccSAndroid Build Coastguard Worker   void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
97*77c1e3ccSAndroid Build Coastguard Worker     UpdateMD5(single_thread_dec_, pkt, &md5_single_thread_);
98*77c1e3ccSAndroid Build Coastguard Worker 
99*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < kNumMultiThreadDecoders; ++i)
100*77c1e3ccSAndroid Build Coastguard Worker       UpdateMD5(multi_thread_dec_[i], pkt, &md5_multi_thread_[i]);
101*77c1e3ccSAndroid Build Coastguard Worker   }
102*77c1e3ccSAndroid Build Coastguard Worker 
DoTest()103*77c1e3ccSAndroid Build Coastguard Worker   void DoTest() {
104*77c1e3ccSAndroid Build Coastguard Worker     const aom_rational timebase = { 33333333, 1000000000 };
105*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_timebase = timebase;
106*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_target_bitrate = 500;
107*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_lag_in_frames = 12;
108*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_end_usage = AOM_VBR;
109*77c1e3ccSAndroid Build Coastguard Worker 
110*77c1e3ccSAndroid Build Coastguard Worker     libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 704, 576,
111*77c1e3ccSAndroid Build Coastguard Worker                                        timebase.den, timebase.num, 0, 2);
112*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
113*77c1e3ccSAndroid Build Coastguard Worker 
114*77c1e3ccSAndroid Build Coastguard Worker     const char *md5_single_thread_str = md5_single_thread_.Get();
115*77c1e3ccSAndroid Build Coastguard Worker 
116*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < kNumMultiThreadDecoders; ++i) {
117*77c1e3ccSAndroid Build Coastguard Worker       const char *md5_multi_thread_str = md5_multi_thread_[i].Get();
118*77c1e3ccSAndroid Build Coastguard Worker       ASSERT_STREQ(md5_single_thread_str, md5_multi_thread_str);
119*77c1e3ccSAndroid Build Coastguard Worker     }
120*77c1e3ccSAndroid Build Coastguard Worker   }
121*77c1e3ccSAndroid Build Coastguard Worker 
122*77c1e3ccSAndroid Build Coastguard Worker   ::libaom_test::MD5 md5_single_thread_;
123*77c1e3ccSAndroid Build Coastguard Worker   ::libaom_test::MD5 md5_multi_thread_[kNumMultiThreadDecoders];
124*77c1e3ccSAndroid Build Coastguard Worker   ::libaom_test::Decoder *single_thread_dec_;
125*77c1e3ccSAndroid Build Coastguard Worker   ::libaom_test::Decoder *multi_thread_dec_[kNumMultiThreadDecoders];
126*77c1e3ccSAndroid Build Coastguard Worker 
127*77c1e3ccSAndroid Build Coastguard Worker  private:
128*77c1e3ccSAndroid Build Coastguard Worker   int n_tile_cols_;
129*77c1e3ccSAndroid Build Coastguard Worker   int n_tile_rows_;
130*77c1e3ccSAndroid Build Coastguard Worker   int n_tile_groups_;
131*77c1e3ccSAndroid Build Coastguard Worker   int set_cpu_used_;
132*77c1e3ccSAndroid Build Coastguard Worker   int row_mt_;
133*77c1e3ccSAndroid Build Coastguard Worker };
134*77c1e3ccSAndroid Build Coastguard Worker 
135*77c1e3ccSAndroid Build Coastguard Worker // run an encode and do the decode both in single thread
136*77c1e3ccSAndroid Build Coastguard Worker // and multi thread. Ensure that the MD5 of the output in both cases
137*77c1e3ccSAndroid Build Coastguard Worker // is identical. If so, the test passes.
TEST_P(AV1DecodeMultiThreadedTest,MD5Match)138*77c1e3ccSAndroid Build Coastguard Worker TEST_P(AV1DecodeMultiThreadedTest, MD5Match) {
139*77c1e3ccSAndroid Build Coastguard Worker   cfg_.large_scale_tile = 0;
140*77c1e3ccSAndroid Build Coastguard Worker   single_thread_dec_->Control(AV1_SET_TILE_MODE, 0);
141*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < kNumMultiThreadDecoders; ++i)
142*77c1e3ccSAndroid Build Coastguard Worker     multi_thread_dec_[i]->Control(AV1_SET_TILE_MODE, 0);
143*77c1e3ccSAndroid Build Coastguard Worker   DoTest();
144*77c1e3ccSAndroid Build Coastguard Worker }
145*77c1e3ccSAndroid Build Coastguard Worker 
146*77c1e3ccSAndroid Build Coastguard Worker class AV1DecodeMultiThreadedTestLarge : public AV1DecodeMultiThreadedTest {};
147*77c1e3ccSAndroid Build Coastguard Worker 
TEST_P(AV1DecodeMultiThreadedTestLarge,MD5Match)148*77c1e3ccSAndroid Build Coastguard Worker TEST_P(AV1DecodeMultiThreadedTestLarge, MD5Match) {
149*77c1e3ccSAndroid Build Coastguard Worker   cfg_.large_scale_tile = 0;
150*77c1e3ccSAndroid Build Coastguard Worker   single_thread_dec_->Control(AV1_SET_TILE_MODE, 0);
151*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < kNumMultiThreadDecoders; ++i)
152*77c1e3ccSAndroid Build Coastguard Worker     multi_thread_dec_[i]->Control(AV1_SET_TILE_MODE, 0);
153*77c1e3ccSAndroid Build Coastguard Worker   DoTest();
154*77c1e3ccSAndroid Build Coastguard Worker }
155*77c1e3ccSAndroid Build Coastguard Worker 
156*77c1e3ccSAndroid Build Coastguard Worker // TODO(ranjit): More tests have to be added using pre-generated MD5.
157*77c1e3ccSAndroid Build Coastguard Worker AV1_INSTANTIATE_TEST_SUITE(AV1DecodeMultiThreadedTest, ::testing::Values(1, 2),
158*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(1, 2), ::testing::Values(1),
159*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(3), ::testing::Values(0, 1));
160*77c1e3ccSAndroid Build Coastguard Worker AV1_INSTANTIATE_TEST_SUITE(AV1DecodeMultiThreadedTestLarge,
161*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(0, 1, 2, 6),
162*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(0, 1, 2, 6),
163*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(1, 4), ::testing::Values(0),
164*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(0, 1));
165*77c1e3ccSAndroid Build Coastguard Worker 
166*77c1e3ccSAndroid Build Coastguard Worker class AV1DecodeMultiThreadedLSTestLarge
167*77c1e3ccSAndroid Build Coastguard Worker     : public AV1DecodeMultiThreadedTestLarge {};
168*77c1e3ccSAndroid Build Coastguard Worker 
TEST_P(AV1DecodeMultiThreadedLSTestLarge,MD5Match)169*77c1e3ccSAndroid Build Coastguard Worker TEST_P(AV1DecodeMultiThreadedLSTestLarge, MD5Match) {
170*77c1e3ccSAndroid Build Coastguard Worker   cfg_.large_scale_tile = 1;
171*77c1e3ccSAndroid Build Coastguard Worker   single_thread_dec_->Control(AV1_SET_TILE_MODE, 1);
172*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < kNumMultiThreadDecoders; ++i)
173*77c1e3ccSAndroid Build Coastguard Worker     multi_thread_dec_[i]->Control(AV1_SET_TILE_MODE, 1);
174*77c1e3ccSAndroid Build Coastguard Worker   DoTest();
175*77c1e3ccSAndroid Build Coastguard Worker }
176*77c1e3ccSAndroid Build Coastguard Worker 
177*77c1e3ccSAndroid Build Coastguard Worker AV1_INSTANTIATE_TEST_SUITE(AV1DecodeMultiThreadedLSTestLarge,
178*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(6), ::testing::Values(6),
179*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(1), ::testing::Values(0, 3),
180*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(0, 1));
181*77c1e3ccSAndroid Build Coastguard Worker 
182*77c1e3ccSAndroid Build Coastguard Worker }  // namespace
183