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