1 /*
2 * Copyright (c) 2023, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 3-Clause Clear License
5 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6 * License was not distributed with this source code in the LICENSE file, you
7 * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8 * Alliance for Open Media Patent License 1.0 was not distributed with this
9 * source code in the PATENTS file, you can obtain it at
10 * www.aomedia.org/license/patent.
11 */
12 #include "iamf/obu/decoder_config/lpcm_decoder_config.h"
13
14 #include <cstdint>
15 #include <limits>
16 #include <vector>
17
18 #include "absl/status/status.h"
19 #include "absl/status/status_matchers.h"
20 #include "absl/types/span.h"
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "iamf/common/read_bit_buffer.h"
24 #include "iamf/common/utils/tests/test_utils.h"
25 #include "iamf/common/write_bit_buffer.h"
26
27 namespace iamf_tools {
28 namespace {
29
30 using ::absl_testing::IsOk;
31
32 constexpr int16_t kAudioRollDistance = 0;
33
TEST(GetRequiredAudioRollDistance,ReturnsFixedValue)34 TEST(GetRequiredAudioRollDistance, ReturnsFixedValue) {
35 EXPECT_EQ(LpcmDecoderConfig::GetRequiredAudioRollDistance(),
36 kAudioRollDistance);
37 }
38
TEST(LpcmDecoderConfigTest,IsLittleEndian_True)39 TEST(LpcmDecoderConfigTest, IsLittleEndian_True) {
40 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
41 16, 48000};
42
43 EXPECT_TRUE(lpcm_decoder_config.IsLittleEndian());
44 }
45
TEST(LpcmDecoderConfigTest,IsLittleEndian_False)46 TEST(LpcmDecoderConfigTest, IsLittleEndian_False) {
47 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmBigEndian,
48 16, 48000};
49
50 EXPECT_FALSE(lpcm_decoder_config.IsLittleEndian());
51 }
52
TEST(LpcmDecoderConfigTest,Validate_ValidLittleEndian)53 TEST(LpcmDecoderConfigTest, Validate_ValidLittleEndian) {
54 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
55 16, 48000};
56 std::vector<uint8_t> expected_decoder_config_payload_ = {
57 1, // sample_format_flags
58 16, // sample_size
59 0x00, 0x00, 0xbb, 0x80 // sample_rate
60 };
61 int16_t audio_roll_distance = 0;
62 WriteBitBuffer wb(expected_decoder_config_payload_.size());
63
64 EXPECT_THAT(lpcm_decoder_config.Validate(audio_roll_distance), IsOk());
65 }
66
TEST(LpcmDecoderConfigTest,Validate_ValidBigEndian)67 TEST(LpcmDecoderConfigTest, Validate_ValidBigEndian) {
68 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmBigEndian,
69 16, 48000};
70 std::vector<uint8_t> expected_decoder_config_payload_ = {
71 0, // sample_format_flags
72 16, // sample_size
73 0x00, 0x00, 0xbb, 0x80 // sample_rate
74 };
75 int16_t audio_roll_distance = 0;
76
77 EXPECT_THAT(lpcm_decoder_config.Validate(audio_roll_distance), IsOk());
78 }
79
TEST(LpcmDecoderConfigTest,Validate_InvalidSampleFormatFlagsMin)80 TEST(LpcmDecoderConfigTest, Validate_InvalidSampleFormatFlagsMin) {
81 LpcmDecoderConfig lpcm_decoder_config = {
82 LpcmDecoderConfig::kLpcmBeginReserved, 16, 48000};
83 int16_t audio_roll_distance = 0;
84
85 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
86 }
87
TEST(LpcmDecoderConfigTest,Validate_IllegalSampleFormatFlagsMax)88 TEST(LpcmDecoderConfigTest, Validate_IllegalSampleFormatFlagsMax) {
89 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmEndReserved,
90 16, 48000};
91 int16_t audio_roll_distance = 0;
92
93 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
94 }
95
TEST(LpcmDecoderConfigTest,Validate_SampleSize24)96 TEST(LpcmDecoderConfigTest, Validate_SampleSize24) {
97 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
98 24, 48000};
99 std::vector<uint8_t> expected_decoder_config_payload_ = {
100 1, // sample_format_flags
101 24, // sample_size
102 0x00, 0x00, 0xbb, 0x80 // sample_rate
103 };
104 int16_t audio_roll_distance = 0;
105 WriteBitBuffer wb(expected_decoder_config_payload_.size());
106
107 EXPECT_THAT(lpcm_decoder_config.Validate(audio_roll_distance), IsOk());
108 }
109
TEST(LpcmDecoderConfigTest,Validate_SampleSize32)110 TEST(LpcmDecoderConfigTest, Validate_SampleSize32) {
111 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
112 32, 48000};
113 std::vector<uint8_t> expected_decoder_config_payload_ = {
114 1, // sample_format_flags
115 32, // sample_size
116 0x00, 0x00, 0xbb, 0x80 // sample_rate
117 };
118 int16_t audio_roll_distance = 0;
119 WriteBitBuffer wb(expected_decoder_config_payload_.size());
120
121 EXPECT_THAT(lpcm_decoder_config.Validate(audio_roll_distance), IsOk());
122 }
123
TEST(LpcmDecoderConfigTest,Validate_AudioRollDistanceMustBeZero_A)124 TEST(LpcmDecoderConfigTest, Validate_AudioRollDistanceMustBeZero_A) {
125 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
126 16, 48000};
127 int16_t audio_roll_distance = -1;
128
129 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
130 }
131
TEST(LpcmDecoderConfigTest,Validate_AudioRollDistanceMustBeZero_B)132 TEST(LpcmDecoderConfigTest, Validate_AudioRollDistanceMustBeZero_B) {
133 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
134 16, 48000};
135 int16_t audio_roll_distance = 1;
136
137 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
138 }
139
TEST(LpcmDecoderConfigTest,Validate_InvalidSampleSizeZero)140 TEST(LpcmDecoderConfigTest, Validate_InvalidSampleSizeZero) {
141 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
142 0, 48000};
143 int16_t audio_roll_distance = 0;
144
145 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
146 }
147
TEST(LpcmDecoderConfigTest,Validate_InvalidSampleSizeEight)148 TEST(LpcmDecoderConfigTest, Validate_InvalidSampleSizeEight) {
149 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
150 8, 48000};
151 int16_t audio_roll_distance = 0;
152
153 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
154 }
155
TEST(LpcmDecoderConfigTest,Validate_InvalidSampleSizeOverMax)156 TEST(LpcmDecoderConfigTest, Validate_InvalidSampleSizeOverMax) {
157 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
158 40, 48000};
159 int16_t audio_roll_distance = 0;
160
161 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
162 }
163
TEST(LpcmDecoderConfigTest,Validate_SampleRateMin_16kHz)164 TEST(LpcmDecoderConfigTest, Validate_SampleRateMin_16kHz) {
165 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
166 32, 16000};
167 std::vector<uint8_t> expected_decoder_config_payload_ = {
168 1, // sample_format_flags
169 32, // sample_size
170 0x00, 0x00, 0x3e, 0x80 // sample_rate
171 };
172 int16_t audio_roll_distance = 0;
173 WriteBitBuffer wb(expected_decoder_config_payload_.size());
174
175 EXPECT_THAT(lpcm_decoder_config.Validate(audio_roll_distance), IsOk());
176 }
177
TEST(LpcmDecoderConfigTest,Validate_SampleRate44_1kHz)178 TEST(LpcmDecoderConfigTest, Validate_SampleRate44_1kHz) {
179 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
180 32, 44100};
181 std::vector<uint8_t> expected_decoder_config_payload_ = {
182 1, // sample_format_flags
183 32, // sample_size
184 0x00, 0x00, 0xac, 0x44 // sample_rate
185 };
186 int16_t audio_roll_distance = 0;
187 WriteBitBuffer wb(expected_decoder_config_payload_.size());
188
189 EXPECT_THAT(lpcm_decoder_config.Validate(audio_roll_distance), IsOk());
190 }
191
TEST(LpcmDecoderConfigTest,Validate_SampleRateMax_96kHz)192 TEST(LpcmDecoderConfigTest, Validate_SampleRateMax_96kHz) {
193 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
194 32, 96000};
195 std::vector<uint8_t> expected_decoder_config_payload_ = {
196 1, // sample_format_flags
197 32, // sample_size
198 0x00, 0x01, 0x77, 0x00 // sample_rate
199 };
200 int16_t audio_roll_distance = 0;
201 WriteBitBuffer wb(expected_decoder_config_payload_.size());
202
203 EXPECT_THAT(lpcm_decoder_config.Validate(audio_roll_distance), IsOk());
204 }
205
TEST(LpcmDecoderConfigTest,Validate_InvalidSampleRateZero)206 TEST(LpcmDecoderConfigTest, Validate_InvalidSampleRateZero) {
207 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
208 16, 0};
209 int16_t audio_roll_distance = 0;
210
211 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
212 }
213
TEST(LpcmDecoderConfigTest,Validate_InvalidSampleRate192kHz)214 TEST(LpcmDecoderConfigTest, Validate_InvalidSampleRate192kHz) {
215 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
216 16, 192000};
217 int16_t audio_roll_distance = 0;
218
219 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
220 }
221
TEST(LpcmDecoderConfigTest,Validate_InvalidSampleRateMax)222 TEST(LpcmDecoderConfigTest, Validate_InvalidSampleRateMax) {
223 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
224 16,
225 std::numeric_limits<int16_t>::max()};
226 int16_t audio_roll_distance = 0;
227
228 EXPECT_FALSE(lpcm_decoder_config.Validate(audio_roll_distance).ok());
229 }
230
TEST(LpcmDecoderConfigTest,Write_AllValid)231 TEST(LpcmDecoderConfigTest, Write_AllValid) {
232 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
233 16, 48000};
234 std::vector<uint8_t> expected_decoder_config_payload_ = {
235 1, // sample_format_flags
236 16, // sample_size
237 0x00, 0x00, 0xbb, 0x80 // sample_rate
238 };
239 int16_t audio_roll_distance = 0;
240 WriteBitBuffer wb(expected_decoder_config_payload_.size());
241
242 EXPECT_THAT(lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb),
243 IsOk());
244 ValidateWriteResults(wb, expected_decoder_config_payload_);
245 }
246
TEST(LpcmDecoderConfigTest,Write_InvalidDoesNotWrite)247 TEST(LpcmDecoderConfigTest, Write_InvalidDoesNotWrite) {
248 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
249 8, 48000};
250 int16_t audio_roll_distance = 0;
251 WriteBitBuffer wb(48); // Arbitrary size. We'll fail before writing.
252
253 EXPECT_FALSE(
254 lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
255 }
256
TEST(LpcmDecoderConfigTest,Write_InvalidRollDistance)257 TEST(LpcmDecoderConfigTest, Write_InvalidRollDistance) {
258 LpcmDecoderConfig lpcm_decoder_config = {LpcmDecoderConfig::kLpcmLittleEndian,
259 16, 48000};
260 std::vector<uint8_t> expected_decoder_config_payload_ = {
261 1, // sample_format_flags
262 16, // sample_size
263 0x00, 0x00, 0xbb, 0x80 // sample_rate
264 };
265 int16_t audio_roll_distance = 1;
266 WriteBitBuffer wb(expected_decoder_config_payload_.size());
267
268 EXPECT_FALSE(
269 lpcm_decoder_config.ValidateAndWrite(audio_roll_distance, wb).ok());
270 }
271
TEST(ReadAndValidateTest,ReadAllFields)272 TEST(ReadAndValidateTest, ReadAllFields) {
273 std::vector<uint8_t> source = {
274 1, // sample_format_flags
275 16, // sample_size
276 0x00, 0x00, 0xbb, 0x80 // sample_rate
277 };
278 int16_t audio_roll_distance = 0;
279 auto read_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
280 1024, absl::MakeConstSpan(source));
281 LpcmDecoderConfig lpcm_decoder_config;
282 EXPECT_THAT(
283 lpcm_decoder_config.ReadAndValidate(audio_roll_distance, *read_buffer),
284 IsOk());
285 LpcmDecoderConfig expected_lpcm_decoder_config = {
286 LpcmDecoderConfig::kLpcmLittleEndian, 16, 48000};
287 EXPECT_EQ(lpcm_decoder_config, expected_lpcm_decoder_config);
288 }
289
TEST(ReadAndValidateTest,RejectInvalidAudioRollDistance)290 TEST(ReadAndValidateTest, RejectInvalidAudioRollDistance) {
291 std::vector<uint8_t> source = {
292 1, // sample_format_flags
293 16, // sample_size
294 0x00, 0x00, 0xbb, 0x80 // sample_rate
295 };
296 int16_t audio_roll_distance = 1;
297 auto read_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
298 1024, absl::MakeConstSpan(source));
299 LpcmDecoderConfig lpcm_decoder_config;
300 EXPECT_FALSE(
301 lpcm_decoder_config.ReadAndValidate(audio_roll_distance, *read_buffer)
302 .ok());
303 }
304
305 } // namespace
306 } // namespace iamf_tools
307