1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2018, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker *
4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker */
11*77c1e3ccSAndroid Build Coastguard Worker #include <string.h>
12*77c1e3ccSAndroid Build Coastguard Worker
13*77c1e3ccSAndroid Build Coastguard Worker #include "common/av1_config.h"
14*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
15*77c1e3ccSAndroid Build Coastguard Worker #include "test/util.h"
16*77c1e3ccSAndroid Build Coastguard Worker
17*77c1e3ccSAndroid Build Coastguard Worker namespace {
18*77c1e3ccSAndroid Build Coastguard Worker
19*77c1e3ccSAndroid Build Coastguard Worker //
20*77c1e3ccSAndroid Build Coastguard Worker // Input buffers containing exactly one Sequence Header OBU.
21*77c1e3ccSAndroid Build Coastguard Worker //
22*77c1e3ccSAndroid Build Coastguard Worker // Each buffer is named according to the OBU storage format (Annex-B vs Low
23*77c1e3ccSAndroid Build Coastguard Worker // Overhead Bitstream Format) and the type of Sequence Header OBU ("Full"
24*77c1e3ccSAndroid Build Coastguard Worker // Sequence Header OBUs vs Sequence Header OBUs with the
25*77c1e3ccSAndroid Build Coastguard Worker // reduced_still_image_flag set).
26*77c1e3ccSAndroid Build Coastguard Worker //
27*77c1e3ccSAndroid Build Coastguard Worker const uint8_t kAnnexBFullSequenceHeaderObu[] = { 0x0c, 0x08, 0x00, 0x00, 0x00,
28*77c1e3ccSAndroid Build Coastguard Worker 0x04, 0x45, 0x7e, 0x3e, 0xff,
29*77c1e3ccSAndroid Build Coastguard Worker 0xfc, 0xc0, 0x20 };
30*77c1e3ccSAndroid Build Coastguard Worker const uint8_t kAnnexBReducedStillImageSequenceHeaderObu[] = {
31*77c1e3ccSAndroid Build Coastguard Worker 0x08, 0x08, 0x18, 0x22, 0x2b, 0xf1, 0xfe, 0xc0, 0x20
32*77c1e3ccSAndroid Build Coastguard Worker };
33*77c1e3ccSAndroid Build Coastguard Worker
34*77c1e3ccSAndroid Build Coastguard Worker const uint8_t kLobfFullSequenceHeaderObu[] = { 0x0a, 0x0b, 0x00, 0x00, 0x00,
35*77c1e3ccSAndroid Build Coastguard Worker 0x04, 0x45, 0x7e, 0x3e, 0xff,
36*77c1e3ccSAndroid Build Coastguard Worker 0xfc, 0xc0, 0x20 };
37*77c1e3ccSAndroid Build Coastguard Worker
38*77c1e3ccSAndroid Build Coastguard Worker const uint8_t kLobfReducedStillImageSequenceHeaderObu[] = { 0x0a, 0x07, 0x18,
39*77c1e3ccSAndroid Build Coastguard Worker 0x22, 0x2b, 0xf1,
40*77c1e3ccSAndroid Build Coastguard Worker 0xfe, 0xc0, 0x20 };
41*77c1e3ccSAndroid Build Coastguard Worker
42*77c1e3ccSAndroid Build Coastguard Worker const uint8_t kAv1cAllZero[] = { 0, 0, 0, 0 };
43*77c1e3ccSAndroid Build Coastguard Worker
44*77c1e3ccSAndroid Build Coastguard Worker // The size of AV1 config when no configOBUs are present at the end of the
45*77c1e3ccSAndroid Build Coastguard Worker // configuration structure.
46*77c1e3ccSAndroid Build Coastguard Worker const size_t kAv1cNoConfigObusSize = 4;
47*77c1e3ccSAndroid Build Coastguard Worker
VerifyAv1c(const uint8_t * const obu_buffer,size_t obu_buffer_length,bool is_annexb)48*77c1e3ccSAndroid Build Coastguard Worker bool VerifyAv1c(const uint8_t *const obu_buffer, size_t obu_buffer_length,
49*77c1e3ccSAndroid Build Coastguard Worker bool is_annexb) {
50*77c1e3ccSAndroid Build Coastguard Worker Av1Config av1_config;
51*77c1e3ccSAndroid Build Coastguard Worker memset(&av1_config, 0, sizeof(av1_config));
52*77c1e3ccSAndroid Build Coastguard Worker bool parse_ok = get_av1config_from_obu(obu_buffer, obu_buffer_length,
53*77c1e3ccSAndroid Build Coastguard Worker is_annexb, &av1_config) == 0;
54*77c1e3ccSAndroid Build Coastguard Worker if (parse_ok) {
55*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(1, av1_config.marker);
56*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(1, av1_config.version);
57*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.seq_profile);
58*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.seq_level_idx_0);
59*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.seq_tier_0);
60*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.high_bitdepth);
61*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.twelve_bit);
62*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.monochrome);
63*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(1, av1_config.chroma_subsampling_x);
64*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(1, av1_config.chroma_subsampling_y);
65*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.chroma_sample_position);
66*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.initial_presentation_delay_present);
67*77c1e3ccSAndroid Build Coastguard Worker EXPECT_EQ(0, av1_config.initial_presentation_delay_minus_one);
68*77c1e3ccSAndroid Build Coastguard Worker }
69*77c1e3ccSAndroid Build Coastguard Worker return parse_ok && ::testing::Test::HasFailure() == false;
70*77c1e3ccSAndroid Build Coastguard Worker }
71*77c1e3ccSAndroid Build Coastguard Worker
TEST(Av1Config,ObuInvalidInputs)72*77c1e3ccSAndroid Build Coastguard Worker TEST(Av1Config, ObuInvalidInputs) {
73*77c1e3ccSAndroid Build Coastguard Worker Av1Config av1_config;
74*77c1e3ccSAndroid Build Coastguard Worker memset(&av1_config, 0, sizeof(av1_config));
75*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, get_av1config_from_obu(nullptr, 0, 0, nullptr));
76*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0], 0, 0,
77*77c1e3ccSAndroid Build Coastguard Worker nullptr));
78*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0],
79*77c1e3ccSAndroid Build Coastguard Worker sizeof(kLobfFullSequenceHeaderObu), 0,
80*77c1e3ccSAndroid Build Coastguard Worker nullptr));
81*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, get_av1config_from_obu(
82*77c1e3ccSAndroid Build Coastguard Worker nullptr, sizeof(kLobfFullSequenceHeaderObu), 0, nullptr));
83*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, get_av1config_from_obu(&kLobfFullSequenceHeaderObu[0], 0, 0,
84*77c1e3ccSAndroid Build Coastguard Worker &av1_config));
85*77c1e3ccSAndroid Build Coastguard Worker }
86*77c1e3ccSAndroid Build Coastguard Worker
TEST(Av1Config,ReadInvalidInputs)87*77c1e3ccSAndroid Build Coastguard Worker TEST(Av1Config, ReadInvalidInputs) {
88*77c1e3ccSAndroid Build Coastguard Worker Av1Config av1_config;
89*77c1e3ccSAndroid Build Coastguard Worker memset(&av1_config, 0, sizeof(av1_config));
90*77c1e3ccSAndroid Build Coastguard Worker size_t bytes_read = 0;
91*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, read_av1config(nullptr, 0, nullptr, nullptr));
92*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, read_av1config(nullptr, 4, nullptr, nullptr));
93*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, read_av1config(&kAv1cAllZero[0], 0, nullptr, nullptr));
94*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, read_av1config(&kAv1cAllZero[0], 4, &bytes_read, nullptr));
95*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, read_av1config(nullptr, 4, &bytes_read, &av1_config));
96*77c1e3ccSAndroid Build Coastguard Worker }
97*77c1e3ccSAndroid Build Coastguard Worker
TEST(Av1Config,WriteInvalidInputs)98*77c1e3ccSAndroid Build Coastguard Worker TEST(Av1Config, WriteInvalidInputs) {
99*77c1e3ccSAndroid Build Coastguard Worker Av1Config av1_config;
100*77c1e3ccSAndroid Build Coastguard Worker memset(&av1_config, 0, sizeof(av1_config));
101*77c1e3ccSAndroid Build Coastguard Worker size_t bytes_written = 0;
102*77c1e3ccSAndroid Build Coastguard Worker uint8_t av1c_buffer[4] = { 0 };
103*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, write_av1config(nullptr, 0, nullptr, nullptr));
104*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, write_av1config(&av1_config, 0, nullptr, nullptr));
105*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, write_av1config(&av1_config, 0, &bytes_written, nullptr));
106*77c1e3ccSAndroid Build Coastguard Worker
107*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1,
108*77c1e3ccSAndroid Build Coastguard Worker write_av1config(&av1_config, 0, &bytes_written, &av1c_buffer[0]));
109*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(-1, write_av1config(&av1_config, 4, &bytes_written, nullptr));
110*77c1e3ccSAndroid Build Coastguard Worker }
111*77c1e3ccSAndroid Build Coastguard Worker
TEST(Av1Config,GetAv1ConfigFromLobfObu)112*77c1e3ccSAndroid Build Coastguard Worker TEST(Av1Config, GetAv1ConfigFromLobfObu) {
113*77c1e3ccSAndroid Build Coastguard Worker // Test parsing of a Sequence Header OBU with the reduced_still_picture_header
114*77c1e3ccSAndroid Build Coastguard Worker // unset-- aka a full Sequence Header OBU.
115*77c1e3ccSAndroid Build Coastguard Worker ASSERT_TRUE(VerifyAv1c(kLobfFullSequenceHeaderObu,
116*77c1e3ccSAndroid Build Coastguard Worker sizeof(kLobfFullSequenceHeaderObu), false));
117*77c1e3ccSAndroid Build Coastguard Worker
118*77c1e3ccSAndroid Build Coastguard Worker // Test parsing of a reduced still image Sequence Header OBU.
119*77c1e3ccSAndroid Build Coastguard Worker ASSERT_TRUE(VerifyAv1c(kLobfReducedStillImageSequenceHeaderObu,
120*77c1e3ccSAndroid Build Coastguard Worker sizeof(kLobfReducedStillImageSequenceHeaderObu),
121*77c1e3ccSAndroid Build Coastguard Worker false));
122*77c1e3ccSAndroid Build Coastguard Worker }
123*77c1e3ccSAndroid Build Coastguard Worker
TEST(Av1Config,GetAv1ConfigFromAnnexBObu)124*77c1e3ccSAndroid Build Coastguard Worker TEST(Av1Config, GetAv1ConfigFromAnnexBObu) {
125*77c1e3ccSAndroid Build Coastguard Worker // Test parsing of a Sequence Header OBU with the reduced_still_picture_header
126*77c1e3ccSAndroid Build Coastguard Worker // unset-- aka a full Sequence Header OBU.
127*77c1e3ccSAndroid Build Coastguard Worker ASSERT_TRUE(VerifyAv1c(kAnnexBFullSequenceHeaderObu,
128*77c1e3ccSAndroid Build Coastguard Worker sizeof(kAnnexBFullSequenceHeaderObu), true));
129*77c1e3ccSAndroid Build Coastguard Worker
130*77c1e3ccSAndroid Build Coastguard Worker // Test parsing of a reduced still image Sequence Header OBU.
131*77c1e3ccSAndroid Build Coastguard Worker ASSERT_TRUE(VerifyAv1c(kAnnexBReducedStillImageSequenceHeaderObu,
132*77c1e3ccSAndroid Build Coastguard Worker sizeof(kAnnexBReducedStillImageSequenceHeaderObu),
133*77c1e3ccSAndroid Build Coastguard Worker true));
134*77c1e3ccSAndroid Build Coastguard Worker }
135*77c1e3ccSAndroid Build Coastguard Worker
TEST(Av1Config,ReadWriteConfig)136*77c1e3ccSAndroid Build Coastguard Worker TEST(Av1Config, ReadWriteConfig) {
137*77c1e3ccSAndroid Build Coastguard Worker Av1Config av1_config;
138*77c1e3ccSAndroid Build Coastguard Worker memset(&av1_config, 0, sizeof(av1_config));
139*77c1e3ccSAndroid Build Coastguard Worker
140*77c1e3ccSAndroid Build Coastguard Worker // Test writing out the AV1 config.
141*77c1e3ccSAndroid Build Coastguard Worker size_t bytes_written = 0;
142*77c1e3ccSAndroid Build Coastguard Worker uint8_t av1c_buffer[4] = { 0 };
143*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(0, write_av1config(&av1_config, sizeof(av1c_buffer), &bytes_written,
144*77c1e3ccSAndroid Build Coastguard Worker &av1c_buffer[0]));
145*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(kAv1cNoConfigObusSize, bytes_written);
146*77c1e3ccSAndroid Build Coastguard Worker for (size_t i = 0; i < kAv1cNoConfigObusSize; ++i) {
147*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(kAv1cAllZero[i], av1c_buffer[i])
148*77c1e3ccSAndroid Build Coastguard Worker << "Mismatch in output Av1Config at offset=" << i;
149*77c1e3ccSAndroid Build Coastguard Worker }
150*77c1e3ccSAndroid Build Coastguard Worker
151*77c1e3ccSAndroid Build Coastguard Worker // Test reading the AV1 config.
152*77c1e3ccSAndroid Build Coastguard Worker size_t bytes_read = 0;
153*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(0, read_av1config(&kAv1cAllZero[0], sizeof(kAv1cAllZero),
154*77c1e3ccSAndroid Build Coastguard Worker &bytes_read, &av1_config));
155*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(kAv1cNoConfigObusSize, bytes_read);
156*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(0, write_av1config(&av1_config, sizeof(av1c_buffer), &bytes_written,
157*77c1e3ccSAndroid Build Coastguard Worker &av1c_buffer[0]));
158*77c1e3ccSAndroid Build Coastguard Worker for (size_t i = 0; i < kAv1cNoConfigObusSize; ++i) {
159*77c1e3ccSAndroid Build Coastguard Worker ASSERT_EQ(kAv1cAllZero[i], av1c_buffer[i])
160*77c1e3ccSAndroid Build Coastguard Worker << "Mismatch in output Av1Config at offset=" << i;
161*77c1e3ccSAndroid Build Coastguard Worker }
162*77c1e3ccSAndroid Build Coastguard Worker }
163*77c1e3ccSAndroid Build Coastguard Worker
164*77c1e3ccSAndroid Build Coastguard Worker } // namespace
165