xref: /aosp_15_r20/external/libaom/test/metadata_test.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1 /*
2  * Copyright (c) 2019, 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 "gtest/gtest.h"
13 
14 #include "aom/aom_codec.h"
15 #include "aom/aom_image.h"
16 #include "aom/internal/aom_image_internal.h"
17 #include "aom_scale/yv12config.h"
18 #include "test/codec_factory.h"
19 #include "test/encode_test_driver.h"
20 #include "test/i420_video_source.h"
21 #include "test/util.h"
22 #include "test/video_source.h"
23 
24 namespace {
25 const size_t kMetadataPayloadSizeT35 = 24;
26 // 0xB5 stands for the itut t35 metadata country code for the Unites States
27 const uint8_t kMetadataPayloadT35[kMetadataPayloadSizeT35] = {
28   0xB5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
29   0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
30 };
31 
32 #if !CONFIG_REALTIME_ONLY
33 const size_t kMetadataPayloadSizeCll = 4;
34 const uint8_t kMetadataPayloadCll[kMetadataPayloadSizeCll] = { 0xB5, 0x01, 0x02,
35                                                                0x03 };
36 
37 const size_t kMetadataObuSizeT35 = 28;
38 const uint8_t kMetadataObuT35[kMetadataObuSizeT35] = {
39   0x2A, 0x1A, 0x02, 0xB5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
40   0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
41   0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x80
42 };
43 const size_t kMetadataObuSizeMdcv = 28;
44 const uint8_t kMetadataObuMdcv[kMetadataObuSizeMdcv] = {
45   0x2A, 0x1A, 0x02, 0xB5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
46   0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
47   0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x80
48 };
49 const size_t kMetadataObuSizeCll = 8;
50 const uint8_t kMetadataObuCll[kMetadataObuSizeCll] = { 0x2A, 0x06, 0x01, 0xB5,
51                                                        0x01, 0x02, 0x03, 0x80 };
52 
53 class MetadataEncodeTest
54     : public ::libaom_test::CodecTestWithParam<libaom_test::TestMode>,
55       public ::libaom_test::EncoderTest {
56  protected:
MetadataEncodeTest()57   MetadataEncodeTest() : EncoderTest(GET_PARAM(0)) {}
58 
59   ~MetadataEncodeTest() override = default;
60 
SetUp()61   void SetUp() override { InitializeConfig(GET_PARAM(1)); }
62 
PreEncodeFrameHook(::libaom_test::VideoSource * video,::libaom_test::Encoder *)63   void PreEncodeFrameHook(::libaom_test::VideoSource *video,
64                           ::libaom_test::Encoder * /*encoder*/) override {
65     aom_image_t *current_frame = video->img();
66     if (current_frame) {
67       if (current_frame->metadata) aom_img_remove_metadata(current_frame);
68       ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
69                                      kMetadataPayloadT35, 0, AOM_MIF_ANY_FRAME),
70                 -1);
71       ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
72                                      nullptr, kMetadataPayloadSizeT35,
73                                      AOM_MIF_ANY_FRAME),
74                 -1);
75       ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
76                                      nullptr, 0, AOM_MIF_ANY_FRAME),
77                 -1);
78       ASSERT_EQ(
79           aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
80                                kMetadataPayloadT35, kMetadataPayloadSizeT35,
81                                AOM_MIF_ANY_FRAME),
82           0);
83 
84       ASSERT_EQ(
85           aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_HDR_MDCV,
86                                kMetadataPayloadT35, kMetadataPayloadSizeT35,
87                                AOM_MIF_KEY_FRAME),
88           0);
89 
90       ASSERT_EQ(
91           aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_HDR_CLL,
92                                kMetadataPayloadCll, kMetadataPayloadSizeCll,
93                                AOM_MIF_KEY_FRAME),
94           0);
95     }
96   }
97 
FramePktHook(const aom_codec_cx_pkt_t * pkt)98   void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
99     if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
100       const size_t bitstream_size = pkt->data.frame.sz;
101       const uint8_t *bitstream =
102           static_cast<const uint8_t *>(pkt->data.frame.buf);
103       // look for valid metadatas in bitstream
104       bool itut_t35_metadata_found = false;
105       if (bitstream_size >= kMetadataObuSizeT35) {
106         for (size_t i = 0; i <= bitstream_size - kMetadataObuSizeT35; ++i) {
107           if (memcmp(bitstream + i, kMetadataObuT35, kMetadataObuSizeT35) ==
108               0) {
109             itut_t35_metadata_found = true;
110           }
111         }
112       }
113       ASSERT_EQ(itut_t35_metadata_found, 1u);
114 
115       // Testing for HDR MDCV metadata
116       bool hdr_mdcv_metadata_found = false;
117       if (bitstream_size >= kMetadataObuSizeMdcv) {
118         for (size_t i = 0; i <= bitstream_size - kMetadataObuSizeMdcv; ++i) {
119           if (memcmp(bitstream + i, kMetadataObuMdcv, kMetadataObuSizeMdcv) ==
120               0) {
121             hdr_mdcv_metadata_found = true;
122           }
123         }
124       }
125       ASSERT_TRUE(hdr_mdcv_metadata_found);
126 
127       // Testing for HDR CLL metadata
128       bool hdr_cll_metadata_found = false;
129       if (bitstream_size >= kMetadataObuSizeCll) {
130         for (size_t i = 0; i <= bitstream_size - kMetadataObuSizeCll; ++i) {
131           if (memcmp(bitstream + i, kMetadataObuCll, kMetadataObuSizeCll) ==
132               0) {
133             hdr_cll_metadata_found = true;
134           }
135         }
136       }
137       ASSERT_TRUE(hdr_cll_metadata_found);
138     }
139   }
140 
DecompressedFrameHook(const aom_image_t & img,aom_codec_pts_t)141   void DecompressedFrameHook(const aom_image_t &img,
142                              aom_codec_pts_t /*pts*/) override {
143     ASSERT_NE(img.metadata, nullptr);
144 
145     ASSERT_EQ(img.metadata->sz, 3u);
146 
147     for (size_t i = 0; i < img.metadata->sz - 1; ++i) {
148       ASSERT_EQ(kMetadataPayloadSizeT35, img.metadata->metadata_array[i]->sz);
149       EXPECT_EQ(
150           memcmp(kMetadataPayloadT35, img.metadata->metadata_array[i]->payload,
151                  kMetadataPayloadSizeT35),
152           0);
153     }
154 
155     ASSERT_EQ(kMetadataPayloadSizeCll, img.metadata->metadata_array[2]->sz);
156     EXPECT_EQ(
157         memcmp(kMetadataPayloadCll, img.metadata->metadata_array[2]->payload,
158                kMetadataPayloadSizeCll),
159         0);
160   }
161 };
162 
TEST_P(MetadataEncodeTest,TestMetadataEncoding)163 TEST_P(MetadataEncodeTest, TestMetadataEncoding) {
164   ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
165                                        30, 1, 0, 5);
166   init_flags_ = AOM_CODEC_USE_PSNR;
167 
168   cfg_.g_w = 352;
169   cfg_.g_h = 288;
170 
171   cfg_.rc_buf_initial_sz = 500;
172   cfg_.rc_buf_optimal_sz = 600;
173   cfg_.rc_buf_sz = 1000;
174   cfg_.rc_min_quantizer = 2;
175   cfg_.rc_max_quantizer = 56;
176   cfg_.rc_undershoot_pct = 50;
177   cfg_.rc_overshoot_pct = 50;
178   cfg_.rc_end_usage = AOM_CBR;
179   cfg_.kf_mode = AOM_KF_AUTO;
180   cfg_.g_lag_in_frames = 1;
181   cfg_.kf_min_dist = cfg_.kf_max_dist = 3000;
182   // Enable dropped frames.
183   cfg_.rc_dropframe_thresh = 1;
184   // Disable error_resilience mode.
185   cfg_.g_error_resilient = 0;
186   // Run at low bitrate.
187   cfg_.rc_target_bitrate = 40;
188 
189   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
190 }
191 
192 AV1_INSTANTIATE_TEST_SUITE(MetadataEncodeTest,
193                            ::testing::Values(::libaom_test::kOnePassGood));
194 #endif  // !CONFIG_REALTIME_ONLY
195 }  // namespace
196 
TEST(MetadataTest,MetadataAllocation)197 TEST(MetadataTest, MetadataAllocation) {
198   aom_metadata_t *metadata =
199       aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
200                              kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME);
201   ASSERT_NE(metadata, nullptr);
202   aom_img_metadata_free(metadata);
203 }
204 
TEST(MetadataTest,MetadataArrayAllocation)205 TEST(MetadataTest, MetadataArrayAllocation) {
206   aom_metadata_array_t *metadata_array = aom_img_metadata_array_alloc(2);
207   ASSERT_NE(metadata_array, nullptr);
208 
209   metadata_array->metadata_array[0] =
210       aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
211                              kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME);
212   metadata_array->metadata_array[1] =
213       aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
214                              kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME);
215 
216   aom_img_metadata_array_free(metadata_array);
217 }
218 
TEST(MetadataTest,AddMetadataToImage)219 TEST(MetadataTest, AddMetadataToImage) {
220   aom_image_t image;
221   image.metadata = nullptr;
222 
223   ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35,
224                                  kMetadataPayloadT35, kMetadataPayloadSizeT35,
225                                  AOM_MIF_ANY_FRAME),
226             0);
227   aom_img_metadata_array_free(image.metadata);
228   EXPECT_EQ(aom_img_add_metadata(nullptr, OBU_METADATA_TYPE_ITUT_T35,
229                                  kMetadataPayloadT35, kMetadataPayloadSizeT35,
230                                  AOM_MIF_ANY_FRAME),
231             -1);
232 }
233 
TEST(MetadataTest,RemoveMetadataFromImage)234 TEST(MetadataTest, RemoveMetadataFromImage) {
235   aom_image_t image;
236   image.metadata = nullptr;
237 
238   ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35,
239                                  kMetadataPayloadT35, kMetadataPayloadSizeT35,
240                                  AOM_MIF_ANY_FRAME),
241             0);
242   aom_img_remove_metadata(&image);
243   aom_img_remove_metadata(nullptr);
244 }
245 
TEST(MetadataTest,CopyMetadataToFrameBuffer)246 TEST(MetadataTest, CopyMetadataToFrameBuffer) {
247   YV12_BUFFER_CONFIG yvBuf;
248   yvBuf.metadata = nullptr;
249 
250   aom_metadata_array_t *metadata_array = aom_img_metadata_array_alloc(1);
251   ASSERT_NE(metadata_array, nullptr);
252 
253   metadata_array->metadata_array[0] =
254       aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
255                              kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME);
256 
257   // Metadata_array
258   int status = aom_copy_metadata_to_frame_buffer(&yvBuf, metadata_array);
259   EXPECT_EQ(status, 0);
260   status = aom_copy_metadata_to_frame_buffer(nullptr, metadata_array);
261   EXPECT_EQ(status, -1);
262   aom_img_metadata_array_free(metadata_array);
263 
264   // Metadata_array_2
265   aom_metadata_array_t *metadata_array_2 = aom_img_metadata_array_alloc(0);
266   ASSERT_NE(metadata_array_2, nullptr);
267   status = aom_copy_metadata_to_frame_buffer(&yvBuf, metadata_array_2);
268   EXPECT_EQ(status, -1);
269   aom_img_metadata_array_free(metadata_array_2);
270 
271   // YV12_BUFFER_CONFIG
272   status = aom_copy_metadata_to_frame_buffer(&yvBuf, nullptr);
273   EXPECT_EQ(status, -1);
274   aom_remove_metadata_from_frame_buffer(&yvBuf);
275   aom_remove_metadata_from_frame_buffer(nullptr);
276 }
277 
TEST(MetadataTest,GetMetadataFromImage)278 TEST(MetadataTest, GetMetadataFromImage) {
279   aom_image_t image;
280   image.metadata = nullptr;
281 
282   ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35,
283                                  kMetadataPayloadT35, kMetadataPayloadSizeT35,
284                                  AOM_MIF_ANY_FRAME),
285             0);
286 
287   EXPECT_EQ(aom_img_get_metadata(nullptr, 0), nullptr);
288   EXPECT_EQ(aom_img_get_metadata(&image, 1u), nullptr);
289   EXPECT_EQ(aom_img_get_metadata(&image, 10u), nullptr);
290 
291   const aom_metadata_t *metadata = aom_img_get_metadata(&image, 0);
292   ASSERT_NE(metadata, nullptr);
293   ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35);
294   EXPECT_EQ(
295       memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35),
296       0);
297 
298   aom_img_metadata_array_free(image.metadata);
299 }
300 
TEST(MetadataTest,ReadMetadatasFromImage)301 TEST(MetadataTest, ReadMetadatasFromImage) {
302   aom_image_t image;
303   image.metadata = nullptr;
304 
305   uint32_t types[3];
306   types[0] = OBU_METADATA_TYPE_ITUT_T35;
307   types[1] = OBU_METADATA_TYPE_HDR_CLL;
308   types[2] = OBU_METADATA_TYPE_HDR_MDCV;
309 
310   ASSERT_EQ(aom_img_add_metadata(&image, types[0], kMetadataPayloadT35,
311                                  kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME),
312             0);
313   ASSERT_EQ(aom_img_add_metadata(&image, types[1], kMetadataPayloadT35,
314                                  kMetadataPayloadSizeT35, AOM_MIF_KEY_FRAME),
315             0);
316   ASSERT_EQ(aom_img_add_metadata(&image, types[2], kMetadataPayloadT35,
317                                  kMetadataPayloadSizeT35, AOM_MIF_KEY_FRAME),
318             0);
319 
320   size_t number_metadata = aom_img_num_metadata(&image);
321   ASSERT_EQ(number_metadata, 3u);
322   for (size_t i = 0; i < number_metadata; ++i) {
323     const aom_metadata_t *metadata = aom_img_get_metadata(&image, i);
324     ASSERT_NE(metadata, nullptr);
325     ASSERT_EQ(metadata->type, types[i]);
326     ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35);
327     EXPECT_EQ(
328         memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35),
329         0);
330   }
331   aom_img_metadata_array_free(image.metadata);
332 }
333