xref: /aosp_15_r20/external/libaom/test/tile_independence_test.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1 /*
2  * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 #include <cstdio>
13 #include <cstdlib>
14 #include <string>
15 #include "gtest/gtest.h"
16 #include "test/codec_factory.h"
17 #include "test/encode_test_driver.h"
18 #include "test/i420_video_source.h"
19 #include "test/util.h"
20 #include "test/md5_helper.h"
21 #include "aom_mem/aom_mem.h"
22 
23 namespace {
24 class TileIndependenceTest
25     : public ::libaom_test::CodecTestWith3Params<int, int, int>,
26       public ::libaom_test::EncoderTest {
27  protected:
TileIndependenceTest()28   TileIndependenceTest()
29       : EncoderTest(GET_PARAM(0)), md5_fw_order_(), md5_inv_order_(),
30         n_tile_cols_(GET_PARAM(1)), n_tile_rows_(GET_PARAM(2)),
31         n_tile_groups_(GET_PARAM(3)) {
32     init_flags_ = AOM_CODEC_USE_PSNR;
33     aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
34     cfg.w = 704;
35     cfg.h = 576;
36     cfg.threads = 1;
37     cfg.allow_lowbitdepth = 1;
38     fw_dec_ = codec_->CreateDecoder(cfg, 0);
39     inv_dec_ = codec_->CreateDecoder(cfg, 0);
40     inv_dec_->Control(AV1_INVERT_TILE_DECODE_ORDER, 1);
41 
42     if (fw_dec_->IsAV1() && inv_dec_->IsAV1()) {
43       fw_dec_->Control(AV1_SET_DECODE_TILE_ROW, -1);
44       fw_dec_->Control(AV1_SET_DECODE_TILE_COL, -1);
45       inv_dec_->Control(AV1_SET_DECODE_TILE_ROW, -1);
46       inv_dec_->Control(AV1_SET_DECODE_TILE_COL, -1);
47     }
48   }
49 
~TileIndependenceTest()50   ~TileIndependenceTest() override {
51     delete fw_dec_;
52     delete inv_dec_;
53   }
54 
SetUp()55   void SetUp() override { InitializeConfig(libaom_test::kTwoPassGood); }
56 
PreEncodeFrameHook(libaom_test::VideoSource * video,libaom_test::Encoder * encoder)57   void PreEncodeFrameHook(libaom_test::VideoSource *video,
58                           libaom_test::Encoder *encoder) override {
59     if (video->frame() == 0) {
60       encoder->Control(AV1E_SET_TILE_COLUMNS, n_tile_cols_);
61       encoder->Control(AV1E_SET_TILE_ROWS, n_tile_rows_);
62       SetCpuUsed(encoder);
63     } else if (video->frame() == 3) {
64       encoder->Control(AV1E_SET_NUM_TG, n_tile_groups_);
65     }
66   }
67 
SetCpuUsed(libaom_test::Encoder * encoder)68   virtual void SetCpuUsed(libaom_test::Encoder *encoder) {
69     static const int kCpuUsed = 3;
70     encoder->Control(AOME_SET_CPUUSED, kCpuUsed);
71   }
72 
UpdateMD5(::libaom_test::Decoder * dec,const aom_codec_cx_pkt_t * pkt,::libaom_test::MD5 * md5)73   void UpdateMD5(::libaom_test::Decoder *dec, const aom_codec_cx_pkt_t *pkt,
74                  ::libaom_test::MD5 *md5) {
75     const aom_codec_err_t res = dec->DecodeFrame(
76         reinterpret_cast<uint8_t *>(pkt->data.frame.buf), pkt->data.frame.sz);
77     if (res != AOM_CODEC_OK) {
78       abort_ = true;
79       ASSERT_EQ(AOM_CODEC_OK, res);
80     }
81     const aom_image_t *img = dec->GetDxData().Next();
82     md5->Add(img);
83   }
84 
FramePktHook(const aom_codec_cx_pkt_t * pkt)85   void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
86     UpdateMD5(fw_dec_, pkt, &md5_fw_order_);
87     UpdateMD5(inv_dec_, pkt, &md5_inv_order_);
88   }
89 
DoTest()90   void DoTest() {
91     const aom_rational timebase = { 33333333, 1000000000 };
92     cfg_.g_timebase = timebase;
93     cfg_.rc_target_bitrate = 500;
94     cfg_.g_lag_in_frames = 12;
95     cfg_.rc_end_usage = AOM_VBR;
96 
97     libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 704, 576,
98                                        timebase.den, timebase.num, 0, 5);
99     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
100 
101     const char *md5_fw_str = md5_fw_order_.Get();
102     const char *md5_inv_str = md5_inv_order_.Get();
103     ASSERT_STREQ(md5_fw_str, md5_inv_str);
104   }
105 
106   ::libaom_test::MD5 md5_fw_order_, md5_inv_order_;
107   ::libaom_test::Decoder *fw_dec_, *inv_dec_;
108 
109  private:
110   int n_tile_cols_;
111   int n_tile_rows_;
112   int n_tile_groups_;
113 };
114 
115 // run an encode with 2 or 4 tiles, and do the decode both in normal and
116 // inverted tile ordering. Ensure that the MD5 of the output in both cases
117 // is identical. If so, tiles are considered independent and the test passes.
TEST_P(TileIndependenceTest,MD5Match)118 TEST_P(TileIndependenceTest, MD5Match) {
119   cfg_.large_scale_tile = 0;
120   fw_dec_->Control(AV1_SET_TILE_MODE, 0);
121   inv_dec_->Control(AV1_SET_TILE_MODE, 0);
122   DoTest();
123 }
124 
125 class TileIndependenceTestLarge : public TileIndependenceTest {
SetCpuUsed(libaom_test::Encoder * encoder)126   void SetCpuUsed(libaom_test::Encoder *encoder) override {
127     static const int kCpuUsed = 0;
128     encoder->Control(AOME_SET_CPUUSED, kCpuUsed);
129   }
130 };
131 
TEST_P(TileIndependenceTestLarge,MD5Match)132 TEST_P(TileIndependenceTestLarge, MD5Match) {
133   cfg_.large_scale_tile = 0;
134   fw_dec_->Control(AV1_SET_TILE_MODE, 0);
135   inv_dec_->Control(AV1_SET_TILE_MODE, 0);
136   DoTest();
137 }
138 
139 AV1_INSTANTIATE_TEST_SUITE(TileIndependenceTest, ::testing::Values(0, 1),
140                            ::testing::Values(0, 1), ::testing::Values(1, 2, 4));
141 AV1_INSTANTIATE_TEST_SUITE(TileIndependenceTestLarge, ::testing::Values(0, 1),
142                            ::testing::Values(0, 1), ::testing::Values(1, 2, 4));
143 
144 class TileIndependenceLSTest : public TileIndependenceTest {};
145 
TEST_P(TileIndependenceLSTest,MD5Match)146 TEST_P(TileIndependenceLSTest, MD5Match) {
147   cfg_.large_scale_tile = 1;
148   fw_dec_->Control(AV1_SET_TILE_MODE, 1);
149   fw_dec_->Control(AV1D_EXT_TILE_DEBUG, 1);
150   inv_dec_->Control(AV1_SET_TILE_MODE, 1);
151   inv_dec_->Control(AV1D_EXT_TILE_DEBUG, 1);
152   DoTest();
153 }
154 
155 class TileIndependenceLSTestLarge : public TileIndependenceTestLarge {};
156 
TEST_P(TileIndependenceLSTestLarge,MD5Match)157 TEST_P(TileIndependenceLSTestLarge, MD5Match) {
158   cfg_.large_scale_tile = 1;
159   fw_dec_->Control(AV1_SET_TILE_MODE, 1);
160   fw_dec_->Control(AV1D_EXT_TILE_DEBUG, 1);
161   inv_dec_->Control(AV1_SET_TILE_MODE, 1);
162   inv_dec_->Control(AV1D_EXT_TILE_DEBUG, 1);
163   DoTest();
164 }
165 
166 AV1_INSTANTIATE_TEST_SUITE(TileIndependenceLSTest, ::testing::Values(6),
167                            ::testing::Values(6), ::testing::Values(1));
168 AV1_INSTANTIATE_TEST_SUITE(TileIndependenceLSTestLarge, ::testing::Values(6),
169                            ::testing::Values(6), ::testing::Values(1));
170 }  // namespace
171