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(AV1_SET_DECODE_TILE_ROW
, -1);
51 decoder_
->Control(AV1_SET_DECODE_TILE_COL
, -1);
53 // Allocate buffer to store tile image.
54 aom_img_alloc(&tile_img_
, AOM_IMG_FMT_I420
, kImgWidth
, kImgHeight
, 32);
60 virtual ~AV1ExtTileTest() {
61 aom_img_free(&tile_img_
);
65 virtual void SetUp() {
67 SetMode(encoding_mode_
);
69 cfg_
.g_lag_in_frames
= 0;
70 cfg_
.rc_end_usage
= AOM_VBR
;
71 cfg_
.g_error_resilient
= 1;
73 cfg_
.rc_max_quantizer
= 56;
74 cfg_
.rc_min_quantizer
= 0;
77 virtual void PreEncodeFrameHook(::libaom_test::VideoSource
*video
,
78 ::libaom_test::Encoder
*encoder
) {
79 if (video
->frame() == 0) {
81 encoder
->Control(AOME_SET_CPUUSED
, set_cpu_used_
);
82 encoder
->Control(AOME_SET_ENABLEAUTOALTREF
, 0);
83 encoder
->Control(AV1E_SET_FRAME_PARALLEL_DECODING
, 1);
85 // The tile size is 64x64.
86 encoder
->Control(AV1E_SET_TILE_COLUMNS
, kTileSize
);
87 encoder
->Control(AV1E_SET_TILE_ROWS
, kTileSize
);
88 // TODO(yunqingwang): test single_tile_decoding = 0.
89 encoder
->Control(AV1E_SET_SINGLE_TILE_DECODING
, 1);
90 // Always use 64x64 max partition.
91 encoder
->Control(AV1E_SET_SUPERBLOCK_SIZE
, AOM_SUPERBLOCK_SIZE_64X64
);
94 if (video
->frame() == 1) {
96 AOM_EFLAG_NO_UPD_LAST
| AOM_EFLAG_NO_UPD_GF
| AOM_EFLAG_NO_UPD_ARF
;
100 virtual void DecompressedFrameHook(const aom_image_t
&img
,
101 aom_codec_pts_t pts
) {
102 // Skip 1 already decoded frame to be consistent with the decoder in this
104 if (pts
== (aom_codec_pts_t
)kSkip
) return;
106 // Calculate MD5 as the reference.
107 ::libaom_test::MD5 md5_res
;
109 md5_
.push_back(md5_res
.Get());
112 virtual void FramePktHook(const aom_codec_cx_pkt_t
*pkt
) {
113 // Skip decoding 1 frame.
114 if (pkt
->data
.frame
.pts
== (aom_codec_pts_t
)kSkip
) return;
116 bool IsLastFrame
= (pkt
->data
.frame
.pts
== (aom_codec_pts_t
)(kLimit
- 1));
118 // Decode the first (kLimit - 1) frames as whole frame, and decode the last
119 // frame in single tiles.
120 for (int r
= 0; r
< kImgHeight
/ kTIleSizeInPixels
; ++r
) {
121 for (int c
= 0; c
< kImgWidth
/ kTIleSizeInPixels
; ++c
) {
123 decoder_
->Control(AV1_SET_DECODE_TILE_ROW
, -1);
124 decoder_
->Control(AV1_SET_DECODE_TILE_COL
, -1);
126 decoder_
->Control(AV1_SET_DECODE_TILE_ROW
, r
);
127 decoder_
->Control(AV1_SET_DECODE_TILE_COL
, c
);
130 const aom_codec_err_t res
= decoder_
->DecodeFrame(
131 reinterpret_cast<uint8_t *>(pkt
->data
.frame
.buf
),
133 if (res
!= AOM_CODEC_OK
) {
135 ASSERT_EQ(AOM_CODEC_OK
, res
);
137 const aom_image_t
*img
= decoder_
->GetDxData().Next();
141 ::libaom_test::MD5 md5_res
;
143 tile_md5_
.push_back(md5_res
.Get());
148 const int kMaxMBPlane
= 3;
149 for (int plane
= 0; plane
< kMaxMBPlane
; ++plane
) {
150 const int shift
= (plane
== 0) ? 0 : 1;
151 int tile_height
= kTIleSizeInPixels
>> shift
;
152 int tile_width
= kTIleSizeInPixels
>> shift
;
154 for (int tr
= 0; tr
< tile_height
; ++tr
) {
155 memcpy(tile_img_
.planes
[plane
] +
156 tile_img_
.stride
[plane
] * (r
* tile_height
+ tr
) +
158 img
->planes
[plane
] + img
->stride
[plane
] * tr
, tile_width
);
163 if (!IsLastFrame
) break;
167 ::libaom_test::MD5 md5_res
;
168 md5_res
.Add(&tile_img_
);
169 tile_md5_
.push_back(md5_res
.Get());
173 void TestRoundTrip() {
174 ::libaom_test::I420VideoSource
video(
175 "hantro_collage_w352h288.yuv", kImgWidth
, kImgHeight
, 30, 1, 0, kLimit
);
176 cfg_
.rc_target_bitrate
= 500;
177 cfg_
.g_error_resilient
= AOM_ERROR_RESILIENT_DEFAULT
;
178 cfg_
.large_scale_tile
= 1;
179 cfg_
.g_lag_in_frames
= 0;
183 init_flags_
= AOM_CODEC_USE_PSNR
;
184 ASSERT_NO_FATAL_FAILURE(RunLoop(&video
));
186 // Compare to check if two vectors are equal.
187 ASSERT_EQ(md5_
, tile_md5_
);
190 ::libaom_test::TestMode encoding_mode_
;
192 ::libaom_test::Decoder
*decoder_
;
193 aom_image_t tile_img_
;
194 std::vector
<std::string
> md5_
;
195 std::vector
<std::string
> tile_md5_
;
198 TEST_P(AV1ExtTileTest
, DISABLED_DecoderResultTest
) { TestRoundTrip(); }
200 AV1_INSTANTIATE_TEST_CASE(
201 // Now only test 2-pass mode.
202 AV1ExtTileTest
, ::testing::Values(::libaom_test::kTwoPassGood
),
203 ::testing::Range(1, 4));
205 class AV1ExtTileTestLarge
: public AV1ExtTileTest
{};
207 TEST_P(AV1ExtTileTestLarge
, DISABLED_DecoderResultTest
) { TestRoundTrip(); }
209 AV1_INSTANTIATE_TEST_CASE(
210 // Now only test 2-pass mode.
211 AV1ExtTileTestLarge
, ::testing::Values(::libaom_test::kTwoPassGood
),
212 ::testing::Range(0, 1));