2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
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.
15 #include "third_party/googletest/src/googletest/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/md5_helper.h"
20 #include "test/util.h"
23 // The number of frames to be encoded/decoded
25 // Skip 1 frame to check the frame decoding independency.
27 const int kTileSize
= 1;
28 const int kTIleSizeInPixels
= (kTileSize
<< 6);
29 // Fake width and height so that they can be multiples of the tile size.
30 const int kImgWidth
= 704;
31 const int kImgHeight
= 576;
33 // This test tests large scale tile coding case. Non-large-scale tile coding
34 // is tested by the tile_independence test.
36 : public ::libaom_test::CodecTestWith2Params
<libaom_test::TestMode
, int>,
37 public ::libaom_test::EncoderTest
{
40 : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
41 set_cpu_used_(GET_PARAM(2)) {
42 init_flags_
= AOM_CODEC_USE_PSNR
;
43 aom_codec_dec_cfg_t cfg
= aom_codec_dec_cfg_t();
46 cfg
.allow_lowbitdepth
= 1;
48 decoder_
= codec_
->CreateDecoder(cfg
, 0);
49 decoder_
->Control(AV1_SET_TILE_MODE
, 1);
50 decoder_
->Control(AV1D_EXT_TILE_DEBUG
, 1);
51 decoder_
->Control(AV1_SET_DECODE_TILE_ROW
, -1);
52 decoder_
->Control(AV1_SET_DECODE_TILE_COL
, -1);
54 // Allocate buffer to store tile image.
55 aom_img_alloc(&tile_img_
, AOM_IMG_FMT_I420
, kImgWidth
, kImgHeight
, 32);
61 virtual ~AV1ExtTileTest() {
62 aom_img_free(&tile_img_
);
66 virtual void SetUp() {
68 SetMode(encoding_mode_
);
70 cfg_
.g_lag_in_frames
= 0;
71 cfg_
.rc_end_usage
= AOM_VBR
;
72 cfg_
.g_error_resilient
= 1;
74 cfg_
.rc_max_quantizer
= 56;
75 cfg_
.rc_min_quantizer
= 0;
78 virtual void PreEncodeFrameHook(::libaom_test::VideoSource
*video
,
79 ::libaom_test::Encoder
*encoder
) {
80 if (video
->frame() == 0) {
82 encoder
->Control(AOME_SET_CPUUSED
, set_cpu_used_
);
83 encoder
->Control(AOME_SET_ENABLEAUTOALTREF
, 0);
84 encoder
->Control(AV1E_SET_FRAME_PARALLEL_DECODING
, 1);
86 // TODO(yunqingwang): test single_tile_decoding = 0.
87 encoder
->Control(AV1E_SET_SINGLE_TILE_DECODING
, 1);
88 // Always use 64x64 max partition.
89 encoder
->Control(AV1E_SET_SUPERBLOCK_SIZE
, AOM_SUPERBLOCK_SIZE_64X64
);
90 // Set tile_columns and tile_rows to MAX values, which guarantees the tile
91 // size of 64 x 64 pixels(i.e. 1 SB) for <= 4k resolution.
92 encoder
->Control(AV1E_SET_TILE_COLUMNS
, 6);
93 encoder
->Control(AV1E_SET_TILE_ROWS
, 6);
96 if (video
->frame() == 1) {
98 AOM_EFLAG_NO_UPD_LAST
| AOM_EFLAG_NO_UPD_GF
| AOM_EFLAG_NO_UPD_ARF
;
102 virtual void DecompressedFrameHook(const aom_image_t
&img
,
103 aom_codec_pts_t pts
) {
104 // Skip 1 already decoded frame to be consistent with the decoder in this
106 if (pts
== (aom_codec_pts_t
)kSkip
) return;
108 // Calculate MD5 as the reference.
109 ::libaom_test::MD5 md5_res
;
111 md5_
.push_back(md5_res
.Get());
114 virtual void FramePktHook(const aom_codec_cx_pkt_t
*pkt
) {
115 // Skip decoding 1 frame.
116 if (pkt
->data
.frame
.pts
== (aom_codec_pts_t
)kSkip
) return;
118 bool IsLastFrame
= (pkt
->data
.frame
.pts
== (aom_codec_pts_t
)(kLimit
- 1));
120 // Decode the first (kLimit - 1) frames as whole frame, and decode the last
121 // frame in single tiles.
122 for (int r
= 0; r
< kImgHeight
/ kTIleSizeInPixels
; ++r
) {
123 for (int c
= 0; c
< kImgWidth
/ kTIleSizeInPixels
; ++c
) {
125 decoder_
->Control(AV1_SET_DECODE_TILE_ROW
, -1);
126 decoder_
->Control(AV1_SET_DECODE_TILE_COL
, -1);
128 decoder_
->Control(AV1_SET_DECODE_TILE_ROW
, r
);
129 decoder_
->Control(AV1_SET_DECODE_TILE_COL
, c
);
132 const aom_codec_err_t res
= decoder_
->DecodeFrame(
133 reinterpret_cast<uint8_t *>(pkt
->data
.frame
.buf
),
135 if (res
!= AOM_CODEC_OK
) {
137 ASSERT_EQ(AOM_CODEC_OK
, res
);
139 const aom_image_t
*img
= decoder_
->GetDxData().Next();
143 ::libaom_test::MD5 md5_res
;
145 tile_md5_
.push_back(md5_res
.Get());
150 const int kMaxMBPlane
= 3;
151 for (int plane
= 0; plane
< kMaxMBPlane
; ++plane
) {
152 const int shift
= (plane
== 0) ? 0 : 1;
153 int tile_height
= kTIleSizeInPixels
>> shift
;
154 int tile_width
= kTIleSizeInPixels
>> shift
;
156 for (int tr
= 0; tr
< tile_height
; ++tr
) {
157 memcpy(tile_img_
.planes
[plane
] +
158 tile_img_
.stride
[plane
] * (r
* tile_height
+ tr
) +
160 img
->planes
[plane
] + img
->stride
[plane
] * tr
, tile_width
);
165 if (!IsLastFrame
) break;
169 ::libaom_test::MD5 md5_res
;
170 md5_res
.Add(&tile_img_
);
171 tile_md5_
.push_back(md5_res
.Get());
175 void TestRoundTrip() {
176 ::libaom_test::I420VideoSource
video(
177 "hantro_collage_w352h288.yuv", kImgWidth
, kImgHeight
, 30, 1, 0, kLimit
);
178 cfg_
.rc_target_bitrate
= 500;
179 cfg_
.g_error_resilient
= AOM_ERROR_RESILIENT_DEFAULT
;
180 cfg_
.large_scale_tile
= 1;
181 cfg_
.g_lag_in_frames
= 0;
185 init_flags_
= AOM_CODEC_USE_PSNR
;
186 ASSERT_NO_FATAL_FAILURE(RunLoop(&video
));
188 // Compare to check if two vectors are equal.
189 ASSERT_EQ(md5_
, tile_md5_
);
192 ::libaom_test::TestMode encoding_mode_
;
194 ::libaom_test::Decoder
*decoder_
;
195 aom_image_t tile_img_
;
196 std::vector
<std::string
> md5_
;
197 std::vector
<std::string
> tile_md5_
;
200 TEST_P(AV1ExtTileTest
, DecoderResultTest
) { TestRoundTrip(); }
202 AV1_INSTANTIATE_TEST_CASE(
203 // Now only test 2-pass mode.
204 AV1ExtTileTest
, ::testing::Values(::libaom_test::kTwoPassGood
),
205 ::testing::Range(1, 4));
207 class AV1ExtTileTestLarge
: public AV1ExtTileTest
{};
209 TEST_P(AV1ExtTileTestLarge
, DecoderResultTest
) { TestRoundTrip(); }
211 AV1_INSTANTIATE_TEST_CASE(
212 // Now only test 2-pass mode.
213 AV1ExtTileTestLarge
, ::testing::Values(::libaom_test::kTwoPassGood
),
214 ::testing::Range(0, 1));