tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

metadata_test.cc (21961B)


      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 <cstring>
     15 #include <string>
     16 
     17 #include "config/aom_config.h"
     18 
     19 #include "aom/aom_codec.h"
     20 #include "aom/aom_image.h"
     21 #include "aom/aomcx.h"
     22 #include "aom/internal/aom_image_internal.h"
     23 #include "aom_scale/yv12config.h"
     24 #include "test/codec_factory.h"
     25 #include "test/encode_test_driver.h"
     26 #include "test/i420_video_source.h"
     27 #include "test/util.h"
     28 #include "test/video_source.h"
     29 
     30 namespace {
     31 const size_t kMetadataPayloadSizeT35 = 24;
     32 // 0xB5 stands for the itut t35 metadata country code for the Unites States
     33 const uint8_t kMetadataPayloadT35[kMetadataPayloadSizeT35] = {
     34  0xB5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
     35  0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
     36 };
     37 
     38 const size_t kMetadataPayloadSizeT35Two = 10;
     39 // 0xB5 stands for the itut t35 metadata country code for the Unites States
     40 const uint8_t kMetadataPayloadT35Two[kMetadataPayloadSizeT35] = {
     41  0xB5, 0x01, 0x02, 0x42, 0xff, 0xff, 0x00, 0x07, 0x08, 0x09
     42 };
     43 
     44 const size_t kMetadataPayloadSizeMdcv = 24;
     45 // Arbitrary content.
     46 const uint8_t kMetadataPayloadMdcv[kMetadataPayloadSizeMdcv] = {
     47  0x99, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
     48  0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x99
     49 };
     50 
     51 const size_t kMetadataPayloadSizeCll = 4;
     52 const uint8_t kMetadataPayloadCll[kMetadataPayloadSizeCll] = { 0xB5, 0x01, 0x02,
     53                                                               0x03 };
     54 
     55 const size_t kMetadataObuSizeT35 = 28;
     56 const uint8_t kMetadataObuT35[kMetadataObuSizeT35] = {
     57  0x2A, 0x1A, 0x04, 0xB5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
     58  0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
     59  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x80
     60 };
     61 const size_t kMetadataObuSizeMdcv = 28;
     62 const uint8_t kMetadataObuMdcv[kMetadataObuSizeMdcv] = {
     63  0x2A, 0x1A, 0x02, 0x99, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
     64  0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
     65  0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x99, 0x80
     66 };
     67 const size_t kMetadataObuSizeCll = 8;
     68 const uint8_t kMetadataObuCll[kMetadataObuSizeCll] = { 0x2A, 0x06, 0x01, 0xB5,
     69                                                       0x01, 0x02, 0x03, 0x80 };
     70 
     71 #if !CONFIG_REALTIME_ONLY
     72 class MetadataEncodeTest
     73    : public ::libaom_test::CodecTestWithParam<libaom_test::TestMode>,
     74      public ::libaom_test::EncoderTest {
     75 protected:
     76  MetadataEncodeTest() : EncoderTest(GET_PARAM(0)) {}
     77 
     78  ~MetadataEncodeTest() override = default;
     79 
     80  void SetUp() override { InitializeConfig(GET_PARAM(1)); }
     81 
     82  void PreEncodeFrameHook(::libaom_test::VideoSource *video,
     83                          ::libaom_test::Encoder *encoder) override {
     84    if (video->frame() == 0) {
     85      encoder->Control(AOME_SET_CPUUSED, 6);  // Speed up the test.
     86    }
     87    aom_image_t *current_frame = video->img();
     88    if (!current_frame) {
     89      return;
     90    }
     91    if (current_frame->metadata) aom_img_remove_metadata(current_frame);
     92    // invalid: size is 0
     93    ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
     94                                   kMetadataPayloadT35, 0, AOM_MIF_ANY_FRAME),
     95              -1);
     96    // invalid: data is nullptr
     97    ASSERT_EQ(
     98        aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35, nullptr,
     99                             kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME),
    100        -1);
    101    // invalid: size is 0 and data is nullptr
    102    ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
    103                                   nullptr, 0, AOM_MIF_ANY_FRAME),
    104              -1);
    105 
    106    ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
    107                                   kMetadataPayloadT35, kMetadataPayloadSizeT35,
    108                                   AOM_MIF_ANY_FRAME),
    109              0);
    110 
    111    ASSERT_EQ(
    112        aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
    113                             kMetadataPayloadT35Two, kMetadataPayloadSizeT35Two,
    114                             AOM_MIF_ANY_FRAME_LAYER_SPECIFIC),
    115        0);
    116 
    117    ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_HDR_MDCV,
    118                                   kMetadataPayloadMdcv,
    119                                   kMetadataPayloadSizeMdcv, AOM_MIF_KEY_FRAME),
    120              0);
    121 
    122    ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_HDR_CLL,
    123                                   kMetadataPayloadCll, kMetadataPayloadSizeCll,
    124                                   AOM_MIF_KEY_FRAME),
    125              0);
    126  }
    127 
    128  void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
    129    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
    130      const bool is_key_frame = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
    131 
    132      const std::string bitstream(
    133          static_cast<const char *>(pkt->data.frame.buf), pkt->data.frame.sz);
    134      // Look for valid metadatas in bitstream.
    135      const bool itut_t35_metadata_found =
    136          bitstream.find(reinterpret_cast<const char *>(kMetadataObuT35), 0,
    137                         kMetadataObuSizeT35) != std::string::npos;
    138      const bool hdr_mdcv_metadata_found =
    139          bitstream.find(reinterpret_cast<const char *>(kMetadataObuMdcv), 0,
    140                         kMetadataObuSizeMdcv) != std::string::npos;
    141      const bool hdr_cll_metadata_found =
    142          bitstream.find(reinterpret_cast<const char *>(kMetadataObuCll), 0,
    143                         kMetadataObuSizeCll) != std::string::npos;
    144 
    145      EXPECT_TRUE(itut_t35_metadata_found);
    146      EXPECT_EQ(hdr_mdcv_metadata_found, is_key_frame);
    147      EXPECT_EQ(hdr_cll_metadata_found, is_key_frame);
    148    }
    149  }
    150 
    151  void DecompressedFrameHook(const aom_image_t &img,
    152                             aom_codec_pts_t /*pts*/) override {
    153    const bool is_key_frame =
    154        (num_decompressed_frames_ % cfg_.kf_max_dist) == 0;
    155    ++num_decompressed_frames_;
    156 
    157    ASSERT_NE(img.metadata, nullptr);
    158 
    159    ASSERT_EQ(img.metadata->sz, is_key_frame ? 4 : 2);
    160 
    161    aom_metadata_t *metadata = img.metadata->metadata_array[0];
    162    ASSERT_EQ(metadata->type, OBU_METADATA_TYPE_ITUT_T35);
    163    ASSERT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME);
    164    ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35);
    165    EXPECT_EQ(
    166        memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35),
    167        0);
    168 
    169    metadata = img.metadata->metadata_array[1];
    170    ASSERT_EQ(metadata->type, OBU_METADATA_TYPE_ITUT_T35);
    171    // AOM_MIF_ANY_FRAME and not AOM_MIF_ANY_FRAME_LAYER_SPECIFIC because the
    172    // stream does not contain layers.
    173    ASSERT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME);
    174    ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35Two);
    175    EXPECT_EQ(memcmp(kMetadataPayloadT35Two, metadata->payload,
    176                     kMetadataPayloadSizeT35Two),
    177              0);
    178 
    179    if (is_key_frame) {
    180      metadata = img.metadata->metadata_array[2];
    181      ASSERT_EQ(metadata->type, OBU_METADATA_TYPE_HDR_MDCV);
    182      ASSERT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME);
    183      ASSERT_EQ(metadata->sz, kMetadataPayloadSizeMdcv);
    184      EXPECT_EQ(memcmp(kMetadataPayloadMdcv, metadata->payload,
    185                       kMetadataPayloadSizeMdcv),
    186                0);
    187 
    188      metadata = img.metadata->metadata_array[3];
    189      ASSERT_EQ(metadata->type, OBU_METADATA_TYPE_HDR_CLL);
    190      ASSERT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME);
    191      ASSERT_EQ(metadata->sz, kMetadataPayloadSizeCll);
    192      EXPECT_EQ(memcmp(kMetadataPayloadCll, metadata->payload,
    193                       kMetadataPayloadSizeCll),
    194                0);
    195    }
    196  }
    197 
    198 private:
    199  int num_decompressed_frames_ = 0;
    200 };
    201 
    202 TEST_P(MetadataEncodeTest, TestMetadataEncoding) {
    203  ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
    204                                       30, 1, 0, 10);
    205  init_flags_ = AOM_CODEC_USE_PSNR;
    206 
    207  cfg_.g_w = 352;
    208  cfg_.g_h = 288;
    209 
    210  cfg_.rc_buf_initial_sz = 500;
    211  cfg_.rc_buf_optimal_sz = 600;
    212  cfg_.rc_buf_sz = 1000;
    213  cfg_.rc_min_quantizer = 2;
    214  cfg_.rc_max_quantizer = 56;
    215  cfg_.rc_undershoot_pct = 50;
    216  cfg_.rc_overshoot_pct = 50;
    217  cfg_.kf_mode = AOM_KF_AUTO;
    218  cfg_.g_lag_in_frames = 1;
    219  cfg_.kf_min_dist = cfg_.kf_max_dist = 5;
    220  // Run at low bitrate.
    221  cfg_.rc_target_bitrate = 40;
    222 
    223  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    224 }
    225 
    226 AV1_INSTANTIATE_TEST_SUITE(MetadataEncodeTest,
    227                           ::testing::Values(::libaom_test::kOnePassGood));
    228 #endif  // !CONFIG_REALTIME_ONLY
    229 
    230 class MetadataMultilayerEncodeTest
    231    : public ::libaom_test::CodecTestWithParam<libaom_test::TestMode>,
    232      public ::libaom_test::EncoderTest {
    233 protected:
    234  MetadataMultilayerEncodeTest() : EncoderTest(GET_PARAM(0)) {}
    235 
    236  ~MetadataMultilayerEncodeTest() override = default;
    237 
    238  static const int kNumSpatialLayers = 3;
    239 
    240  void SetUp() override { InitializeConfig(GET_PARAM(1)); }
    241 
    242  int GetNumSpatialLayers() override { return kNumSpatialLayers; }
    243 
    244  void PreEncodeFrameHook(::libaom_test::VideoSource *video,
    245                          ::libaom_test::Encoder *encoder) override {
    246    aom_image_t *current_frame = video->img();
    247    if (!current_frame) {
    248      return;
    249    }
    250 
    251    // One-time initialization only done on the first frame.
    252    if (num_encoded_frames_ == 0) {
    253      encoder->Control(AOME_SET_CPUUSED, 6);  // Speed up the test.
    254      aom_svc_params_t svc_params = GetSvcParams();
    255      encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params);
    256    }
    257 
    258    const int spatial_layer_id = num_encoded_frames_ % 3;
    259    aom_svc_layer_id_t layer_id = { spatial_layer_id, 0 };
    260    encoder->Control(AV1E_SET_SVC_LAYER_ID, &layer_id);
    261 
    262    if (current_frame->metadata) aom_img_remove_metadata(current_frame);
    263 
    264    ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
    265                                   kMetadataPayloadT35, kMetadataPayloadSizeT35,
    266                                   AOM_MIF_ANY_FRAME),
    267              0);
    268 
    269    ASSERT_EQ(
    270        aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_ITUT_T35,
    271                             kMetadataPayloadT35Two, kMetadataPayloadSizeT35Two,
    272                             AOM_MIF_ANY_FRAME_LAYER_SPECIFIC),
    273        0);
    274 
    275    ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_HDR_MDCV,
    276                                   kMetadataPayloadMdcv,
    277                                   kMetadataPayloadSizeMdcv, AOM_MIF_KEY_FRAME),
    278              0);
    279 
    280    ASSERT_EQ(aom_img_add_metadata(current_frame, OBU_METADATA_TYPE_HDR_CLL,
    281                                   kMetadataPayloadCll, kMetadataPayloadSizeCll,
    282                                   AOM_MIF_KEY_FRAME),
    283              0);
    284 
    285    num_encoded_frames_++;
    286  }
    287 
    288  void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
    289    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
    290      const bool is_key_frame = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
    291 
    292      const std::string bitstream(
    293          static_cast<const char *>(pkt->data.frame.buf), pkt->data.frame.sz);
    294 
    295      // Look for valid metadatas in bitstream.
    296      const bool itut_t35_metadata_found =
    297          bitstream.find(reinterpret_cast<const char *>(kMetadataObuT35), 0,
    298                         kMetadataObuSizeT35) != std::string::npos;
    299      const bool hdr_mdcv_metadata_found =
    300          bitstream.find(reinterpret_cast<const char *>(kMetadataObuMdcv), 0,
    301                         kMetadataObuSizeMdcv) != std::string::npos;
    302      const bool hdr_cll_metadata_found =
    303          bitstream.find(reinterpret_cast<const char *>(kMetadataObuCll), 0,
    304                         kMetadataObuSizeCll) != std::string::npos;
    305 
    306      EXPECT_TRUE(itut_t35_metadata_found);
    307      EXPECT_EQ(hdr_mdcv_metadata_found, is_key_frame);
    308      EXPECT_EQ(hdr_cll_metadata_found, is_key_frame);
    309    }
    310  }
    311 
    312  void DecompressedFrameHook(const aom_image_t &img,
    313                             aom_codec_pts_t /*pts*/) override {
    314    const bool is_key_frame = (num_decompressed_frames_ == 0);
    315 
    316    ++num_decompressed_frames_;
    317 
    318    ASSERT_NE(img.metadata, nullptr);
    319 
    320    ASSERT_EQ(img.metadata->sz, is_key_frame ? 4 : 2);
    321 
    322    aom_metadata_t *metadata = img.metadata->metadata_array[0];
    323    ASSERT_EQ(metadata->type, OBU_METADATA_TYPE_ITUT_T35);
    324    ASSERT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME);
    325    ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35);
    326    EXPECT_EQ(
    327        memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35),
    328        0);
    329 
    330    metadata = img.metadata->metadata_array[1];
    331    ASSERT_EQ(metadata->type, OBU_METADATA_TYPE_ITUT_T35);
    332    ASSERT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME_LAYER_SPECIFIC);
    333    ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35Two);
    334    EXPECT_EQ(memcmp(kMetadataPayloadT35Two, metadata->payload,
    335                     kMetadataPayloadSizeT35Two),
    336              0);
    337 
    338    if (is_key_frame) {
    339      metadata = img.metadata->metadata_array[2];
    340      ASSERT_EQ(metadata->type, OBU_METADATA_TYPE_HDR_MDCV);
    341      ASSERT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME);
    342      ASSERT_EQ(metadata->sz, kMetadataPayloadSizeMdcv);
    343      EXPECT_EQ(memcmp(kMetadataPayloadMdcv, metadata->payload,
    344                       kMetadataPayloadSizeMdcv),
    345                0);
    346 
    347      metadata = img.metadata->metadata_array[3];
    348      ASSERT_EQ(metadata->type, OBU_METADATA_TYPE_HDR_CLL);
    349      ASSERT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME);
    350      ASSERT_EQ(metadata->sz, kMetadataPayloadSizeCll);
    351      EXPECT_EQ(memcmp(kMetadataPayloadCll, metadata->payload,
    352                       kMetadataPayloadSizeCll),
    353                0);
    354    }
    355  }
    356 
    357 private:
    358  aom_svc_params_t GetSvcParams() {
    359    aom_svc_params_t svc_params = {};
    360    svc_params.number_spatial_layers = kNumSpatialLayers;
    361    svc_params.number_temporal_layers = 1;
    362    for (int i = 0; i < kNumSpatialLayers; ++i) {
    363      svc_params.max_quantizers[i] = 60;
    364      svc_params.min_quantizers[i] = 2;
    365    }
    366 
    367    svc_params.framerate_factor[0] = 1;
    368 
    369    svc_params.layer_target_bitrate[0] = 30 * cfg_.rc_target_bitrate / 100;
    370    svc_params.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
    371    svc_params.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
    372 
    373    svc_params.scaling_factor_num[0] = 1;
    374    svc_params.scaling_factor_den[0] = 4;
    375    svc_params.scaling_factor_num[1] = 1;
    376    svc_params.scaling_factor_den[1] = 2;
    377    svc_params.scaling_factor_num[2] = 1;
    378    svc_params.scaling_factor_den[2] = 1;
    379 
    380    return svc_params;
    381  }
    382 
    383  int num_encoded_frames_ = 0;
    384  int num_decompressed_frames_ = 0;
    385 };
    386 
    387 }  // namespace
    388 
    389 TEST_P(MetadataMultilayerEncodeTest, Test) {
    390  cfg_.rc_buf_initial_sz = 500;
    391  cfg_.rc_buf_optimal_sz = 500;
    392  cfg_.rc_buf_sz = 1000;
    393  cfg_.g_lag_in_frames = 0;
    394  cfg_.g_error_resilient = 0;
    395  cfg_.rc_target_bitrate = 1200;
    396 
    397  ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
    398                                       30, 1, 0, /*limit=*/10);
    399  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    400 }
    401 
    402 AV1_INSTANTIATE_TEST_SUITE(MetadataMultilayerEncodeTest,
    403                           ::testing::Values(::libaom_test::kRealTime));
    404 
    405 TEST(MetadataTest, MetadataAllocation) {
    406  aom_metadata_t *metadata =
    407      aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
    408                             kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME);
    409  ASSERT_NE(metadata, nullptr);
    410  aom_img_metadata_free(metadata);
    411 }
    412 
    413 TEST(MetadataTest, MetadataArrayAllocation) {
    414  aom_metadata_array_t *metadata_array = aom_img_metadata_array_alloc(2);
    415  ASSERT_NE(metadata_array, nullptr);
    416 
    417  metadata_array->metadata_array[0] =
    418      aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
    419                             kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME);
    420  metadata_array->metadata_array[1] =
    421      aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
    422                             kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME);
    423 
    424  aom_img_metadata_array_free(metadata_array);
    425 }
    426 
    427 TEST(MetadataTest, AddMetadataToImage) {
    428  aom_image_t image;
    429  image.metadata = nullptr;
    430 
    431  ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35,
    432                                 kMetadataPayloadT35, kMetadataPayloadSizeT35,
    433                                 AOM_MIF_ANY_FRAME),
    434            0);
    435  aom_img_metadata_array_free(image.metadata);
    436  EXPECT_EQ(aom_img_add_metadata(nullptr, OBU_METADATA_TYPE_ITUT_T35,
    437                                 kMetadataPayloadT35, kMetadataPayloadSizeT35,
    438                                 AOM_MIF_ANY_FRAME),
    439            -1);
    440 }
    441 
    442 TEST(MetadataTest, AddLayerSpecificMetadataToImage) {
    443  aom_image_t image;
    444  image.metadata = nullptr;
    445 
    446  ASSERT_EQ(
    447      aom_img_add_metadata(
    448          &image, OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
    449          kMetadataPayloadSizeT35,
    450          (aom_metadata_insert_flags_t)(AOM_MIF_ANY_FRAME_LAYER_SPECIFIC)),
    451      0);
    452  aom_img_metadata_array_free(image.metadata);
    453 }
    454 
    455 TEST(MetadataTest, AddLayerSpecificMetadataToImageNotAllowed) {
    456  aom_image_t image;
    457  image.metadata = nullptr;
    458 
    459  // OBU_METADATA_TYPE_SCALABILITY cannot be layer specific.
    460  ASSERT_EQ(
    461      aom_img_add_metadata(
    462          &image, OBU_METADATA_TYPE_SCALABILITY, kMetadataPayloadT35,
    463          kMetadataPayloadSizeT35,
    464          (aom_metadata_insert_flags_t)(AOM_MIF_ANY_FRAME_LAYER_SPECIFIC)),
    465      -1);
    466  aom_img_metadata_array_free(image.metadata);
    467 }
    468 
    469 TEST(MetadataTest, RemoveMetadataFromImage) {
    470  aom_image_t image;
    471  image.metadata = nullptr;
    472 
    473  ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35,
    474                                 kMetadataPayloadT35, kMetadataPayloadSizeT35,
    475                                 AOM_MIF_ANY_FRAME),
    476            0);
    477  aom_img_remove_metadata(&image);
    478  aom_img_remove_metadata(nullptr);
    479 }
    480 
    481 TEST(MetadataTest, CopyMetadataToFrameBuffer) {
    482  YV12_BUFFER_CONFIG yvBuf;
    483  yvBuf.metadata = nullptr;
    484 
    485  aom_metadata_array_t *metadata_array = aom_img_metadata_array_alloc(1);
    486  ASSERT_NE(metadata_array, nullptr);
    487 
    488  metadata_array->metadata_array[0] =
    489      aom_img_metadata_alloc(OBU_METADATA_TYPE_ITUT_T35, kMetadataPayloadT35,
    490                             kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME);
    491 
    492  // Metadata_array
    493  int status = aom_copy_metadata_to_frame_buffer(&yvBuf, metadata_array);
    494  EXPECT_EQ(status, 0);
    495  status = aom_copy_metadata_to_frame_buffer(nullptr, metadata_array);
    496  EXPECT_EQ(status, -1);
    497  aom_img_metadata_array_free(metadata_array);
    498 
    499  // Metadata_array_2
    500  aom_metadata_array_t *metadata_array_2 = aom_img_metadata_array_alloc(0);
    501  ASSERT_NE(metadata_array_2, nullptr);
    502  status = aom_copy_metadata_to_frame_buffer(&yvBuf, metadata_array_2);
    503  EXPECT_EQ(status, -1);
    504  aom_img_metadata_array_free(metadata_array_2);
    505 
    506  // YV12_BUFFER_CONFIG
    507  status = aom_copy_metadata_to_frame_buffer(&yvBuf, nullptr);
    508  EXPECT_EQ(status, -1);
    509  aom_remove_metadata_from_frame_buffer(&yvBuf);
    510  aom_remove_metadata_from_frame_buffer(nullptr);
    511 }
    512 
    513 TEST(MetadataTest, GetMetadataFromImage) {
    514  aom_image_t image;
    515  image.metadata = nullptr;
    516 
    517  ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35,
    518                                 kMetadataPayloadT35, kMetadataPayloadSizeT35,
    519                                 AOM_MIF_ANY_FRAME),
    520            0);
    521  ASSERT_EQ(aom_img_add_metadata(&image, OBU_METADATA_TYPE_ITUT_T35,
    522                                 kMetadataPayloadT35, kMetadataPayloadSizeT35,
    523                                 AOM_MIF_ANY_FRAME_LAYER_SPECIFIC),
    524            0);
    525 
    526  EXPECT_EQ(aom_img_get_metadata(nullptr, 0), nullptr);
    527  EXPECT_EQ(aom_img_get_metadata(&image, 2u), nullptr);
    528  EXPECT_EQ(aom_img_get_metadata(&image, 10u), nullptr);
    529 
    530  const aom_metadata_t *metadata = aom_img_get_metadata(&image, 0);
    531  ASSERT_NE(metadata, nullptr);
    532  ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35);
    533  EXPECT_EQ(
    534      memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35),
    535      0);
    536  EXPECT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME);
    537 
    538  metadata = aom_img_get_metadata(&image, 1);
    539  ASSERT_NE(metadata, nullptr);
    540  ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35);
    541  EXPECT_EQ(
    542      memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35),
    543      0);
    544  EXPECT_EQ(metadata->insert_flag, AOM_MIF_ANY_FRAME_LAYER_SPECIFIC);
    545 
    546  aom_img_metadata_array_free(image.metadata);
    547 }
    548 
    549 TEST(MetadataTest, ReadMetadatasFromImage) {
    550  aom_image_t image;
    551  image.metadata = nullptr;
    552 
    553  uint32_t types[3];
    554  types[0] = OBU_METADATA_TYPE_ITUT_T35;
    555  types[1] = OBU_METADATA_TYPE_HDR_CLL;
    556  types[2] = OBU_METADATA_TYPE_HDR_MDCV;
    557 
    558  ASSERT_EQ(aom_img_add_metadata(&image, types[0], kMetadataPayloadT35,
    559                                 kMetadataPayloadSizeT35, AOM_MIF_ANY_FRAME),
    560            0);
    561  ASSERT_EQ(aom_img_add_metadata(&image, types[1], kMetadataPayloadT35,
    562                                 kMetadataPayloadSizeT35, AOM_MIF_KEY_FRAME),
    563            0);
    564  ASSERT_EQ(aom_img_add_metadata(&image, types[2], kMetadataPayloadT35,
    565                                 kMetadataPayloadSizeT35, AOM_MIF_KEY_FRAME),
    566            0);
    567 
    568  size_t number_metadata = aom_img_num_metadata(&image);
    569  ASSERT_EQ(number_metadata, 3u);
    570  for (size_t i = 0; i < number_metadata; ++i) {
    571    const aom_metadata_t *metadata = aom_img_get_metadata(&image, i);
    572    ASSERT_NE(metadata, nullptr);
    573    ASSERT_EQ(metadata->type, types[i]);
    574    ASSERT_EQ(metadata->sz, kMetadataPayloadSizeT35);
    575    EXPECT_EQ(
    576        memcmp(kMetadataPayloadT35, metadata->payload, kMetadataPayloadSizeT35),
    577        0);
    578  }
    579  aom_img_metadata_array_free(image.metadata);
    580 }