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/flac_decoder_config.h"
13
14 #include <cstdint>
15 #include <limits>
16 #include <variant>
17 #include <vector>
18
19 #include "absl/status/status.h"
20 #include "absl/status/status_matchers.h"
21 #include "absl/types/span.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "iamf/common/read_bit_buffer.h"
25 #include "iamf/common/utils/tests/test_utils.h"
26 #include "iamf/common/write_bit_buffer.h"
27
28 namespace iamf_tools {
29 namespace {
30
31 using ::absl_testing::IsOk;
32 using ::testing::ElementsAreArray;
33 using ::testing::Eq;
34
35 class FlacTest : public testing::Test {
36 public:
FlacTest()37 FlacTest()
38 : num_samples_per_frame_(16),
39 flac_decoder_config_{
40 {{.header = {.last_metadata_block_flag = true,
41 .block_type = FlacMetaBlockHeader::kFlacStreamInfo,
42 .metadata_data_block_length = 34},
43 .payload =
44 FlacMetaBlockStreamInfo{.minimum_block_size = 16,
45 .maximum_block_size = 16,
46 .sample_rate = 48000,
47 .bits_per_sample = 15,
48 .total_samples_in_stream = 0}}}} {
49 first_stream_info_payload_ = &std::get<FlacMetaBlockStreamInfo>(
50 flac_decoder_config_.metadata_blocks_[0].payload);
51 }
52 ~FlacTest() = default;
53
54 protected:
TestWriteDecoderConfig()55 void TestWriteDecoderConfig() {
56 WriteBitBuffer wb(expected_decoder_config_payload_.size());
57
58 EXPECT_EQ(
59 flac_decoder_config_
60 .ValidateAndWrite(num_samples_per_frame_, audio_roll_distance_, wb)
61 .code(),
62 expected_write_status_code_);
63
64 if (expected_write_status_code_ == absl::StatusCode::kOk) {
65 ValidateWriteResults(wb, expected_decoder_config_payload_);
66 }
67 }
68
69 // `num_samples_per_frame_` would typically come from the associated Codec
70 // Config OBU. Some fields in the decoder config must be consistent with it,
71 uint32_t num_samples_per_frame_;
72
73 // `audio_roll_distance_` would typically come from the associated Codec
74 // Config OBU. The IAMF specification REQUIRES this be 0.
75 int16_t audio_roll_distance_ = 0;
76
77 FlacDecoderConfig flac_decoder_config_;
78 // A pointer which is initialized to point to the `FlacMetaBlockStreamInfo` in
79 // `flac_decoder_config_`.
80 FlacMetaBlockStreamInfo* first_stream_info_payload_;
81
82 absl::StatusCode expected_write_status_code_ = absl::StatusCode::kOk;
83 std::vector<uint8_t> expected_decoder_config_payload_;
84 };
85
86 // ============================================================================
87 // Write Tests
88 // ============================================================================
89
TEST_F(FlacTest,WriteDefault)90 TEST_F(FlacTest, WriteDefault) {
91 expected_decoder_config_payload_ = {
92 // `last_metadata_block_flag` and `block_type` fields.
93 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
94 // `metadata_data_block_length`.
95 0, 0, 34,
96 // `minimum_block_size`.
97 0, 16,
98 // `maximum_block_size`.
99 0, 16,
100 // `minimum_frame_size`.
101 0, 0, 0,
102 // `maximum_frame_size`.
103 0, 0, 0,
104 // `sample_rate` (20 bits)
105 0x0b, 0xb8,
106 (0 << 4) |
107 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
108 (FlacStreamInfoConstraints::kNumberOfChannels << 1),
109 15 << 4 |
110 // `total_samples_in_stream` (36 bits).
111 0,
112 0x00, 0x00, 0x00, 0x00,
113 // MD5 sum.
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00};
116 TestWriteDecoderConfig();
117 }
118
TEST_F(FlacTest,CanContainAdditionalBlocks)119 TEST_F(FlacTest, CanContainAdditionalBlocks) {
120 flac_decoder_config_.metadata_blocks_[0].header.last_metadata_block_flag =
121 false;
122
123 flac_decoder_config_.metadata_blocks_.push_back(FlacMetadataBlock{
124 .header = {.last_metadata_block_flag = false,
125 .block_type = FlacMetaBlockHeader::kFlacPicture,
126 .metadata_data_block_length = 3},
127 .payload = std::vector<uint8_t>{'a', 'b', 'c'}});
128
129 flac_decoder_config_.metadata_blocks_.push_back(FlacMetadataBlock{
130 .header = {.last_metadata_block_flag = true,
131 .block_type = FlacMetaBlockHeader::kFlacApplication,
132 .metadata_data_block_length = 3},
133 .payload = std::vector<uint8_t>{'d', 'e', 'f'}});
134
135 expected_decoder_config_payload_ = {
136 // `last_metadata_block_flag` and `block_type` fields.
137 0 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
138 // `metadata_data_block_length`.
139 0, 0, 34,
140 // `minimum_block_size`.
141 0, 16,
142 // `maximum_block_size`.
143 0, 16,
144 // `minimum_frame_size`.
145 0, 0, 0,
146 // `maximum_frame_size`.
147 0, 0, 0,
148 // `sample_rate` (20 bits)
149 0x0b, 0xb8,
150 (0 << 4) |
151 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
152 (FlacStreamInfoConstraints::kNumberOfChannels << 1),
153 15 << 4 |
154 // `total_samples_in_stream` (36 bits).
155 0,
156 0x00, 0x00, 0x00, 0x00,
157 // MD5 sum.
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00,
160 // `last_metadata_block_flag` and `block_type` fields.
161 0 << 7 | FlacMetaBlockHeader::kFlacPicture,
162 // `metadata_data_block_length`.
163 0, 0, 3,
164 // Payload.
165 'a', 'b', 'c',
166 // `last_metadata_block_flag` and `block_type` fields.
167 1 << 7 | FlacMetaBlockHeader::kFlacApplication,
168 // `metadata_data_block_length`.
169 0, 0, 3,
170 // Payload.
171 'd', 'e', 'f'};
172 TestWriteDecoderConfig();
173 }
174
TEST_F(FlacTest,IllegalMetadataBlockLengthInconsistent)175 TEST_F(FlacTest, IllegalMetadataBlockLengthInconsistent) {
176 flac_decoder_config_.metadata_blocks_[0].header.last_metadata_block_flag =
177 false;
178
179 // `metadata_data_block_length` is inconsistent with the payload.
180 flac_decoder_config_.metadata_blocks_.push_back(FlacMetadataBlock{
181 .header = {.last_metadata_block_flag = true,
182 .block_type = FlacMetaBlockHeader::kFlacPicture,
183 .metadata_data_block_length = 10},
184 .payload = std::vector<uint8_t>{'a', 'b', 'c'}});
185
186 expected_write_status_code_ = absl::StatusCode::kUnknown;
187 TestWriteDecoderConfig();
188 }
189
TEST_F(FlacTest,IllegalExtraneousLastMetadataBlockFlag)190 TEST_F(FlacTest, IllegalExtraneousLastMetadataBlockFlag) {
191 // The final block and only the final block MUST have
192 // `last_metadata_block_flag` set.
193 flac_decoder_config_.metadata_blocks_[0].header.last_metadata_block_flag =
194 true;
195 flac_decoder_config_.metadata_blocks_.push_back(FlacMetadataBlock{
196 .header = {.last_metadata_block_flag = true,
197 .block_type = FlacMetaBlockHeader::kFlacPicture,
198 .metadata_data_block_length = 3},
199 .payload = std::vector<uint8_t>{'a', 'b', 'c'}});
200
201 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
202 TestWriteDecoderConfig();
203 }
204
TEST_F(FlacTest,IllegalStreamInfoMustBeFirstBlock)205 TEST_F(FlacTest, IllegalStreamInfoMustBeFirstBlock) {
206 flac_decoder_config_.metadata_blocks_.insert(
207 flac_decoder_config_.metadata_blocks_.begin(),
208 FlacMetadataBlock{
209 .header = {.last_metadata_block_flag = true,
210 .block_type = FlacMetaBlockHeader::kFlacPicture,
211 .metadata_data_block_length = 3},
212 .payload = std::vector<uint8_t>{'a', 'b', 'c'}});
213
214 ASSERT_EQ(flac_decoder_config_.metadata_blocks_.back().header.block_type,
215 FlacMetaBlockHeader::kFlacStreamInfo);
216 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
217 TestWriteDecoderConfig();
218 }
219
TEST_F(FlacTest,IllegalStreamInfoMustBePresent)220 TEST_F(FlacTest, IllegalStreamInfoMustBePresent) {
221 flac_decoder_config_.metadata_blocks_[0].header = {
222 .last_metadata_block_flag = true,
223 .block_type = FlacMetaBlockHeader::kFlacPadding,
224 .metadata_data_block_length = 0};
225 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
226 TestWriteDecoderConfig();
227 }
228
TEST_F(FlacTest,WriteBitsPerSampleMin)229 TEST_F(FlacTest, WriteBitsPerSampleMin) {
230 first_stream_info_payload_->bits_per_sample =
231 FlacStreamInfoConstraints::kMinBitsPerSample;
232
233 expected_decoder_config_payload_ = {
234 // `last_metadata_block_flag` and `block_type` fields.
235 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
236 // `metadata_data_block_length`.
237 0, 0, 34,
238 // `minimum_block_size`.
239 0, 16,
240 // `maximum_block_size`.
241 0, 16,
242 // `minimum_frame_size`.
243 0, 0, 0,
244 // `maximum_frame_size`.
245 0, 0, 0,
246 // `sample_rate` (20 bits)
247 0x0b, 0xb8,
248 (0 << 4) |
249 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
250 (FlacStreamInfoConstraints::kNumberOfChannels << 1),
251 3 << 4 |
252 // `total_samples_in_stream` (36 bits).
253 0,
254 0x00, 0x00, 0x00, 0x00,
255 // MD5 sum.
256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00};
258 TestWriteDecoderConfig();
259 }
260
TEST_F(FlacTest,WriteBitsPerSampleMax)261 TEST_F(FlacTest, WriteBitsPerSampleMax) {
262 first_stream_info_payload_->bits_per_sample =
263 FlacStreamInfoConstraints::kMaxBitsPerSample;
264
265 expected_decoder_config_payload_ = {
266 // `last_metadata_block_flag` and `block_type` fields.
267 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
268 // `metadata_data_block_length`.
269 0, 0, 34,
270 // `minimum_block_size`.
271 0, 16,
272 // `maximum_block_size`.
273 0, 16,
274 // `minimum_frame_size`.
275 0, 0, 0,
276 // `maximum_frame_size`.
277 0, 0, 0,
278 // `sample_rate` (20 bits)
279 0x0b, 0xb8,
280 (0 << 4) |
281 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
282 (FlacStreamInfoConstraints::kNumberOfChannels << 1) | 1,
283 15 << 4 |
284 // `total_samples_in_stream` (36 bits).
285 0,
286 0x00, 0x00, 0x00, 0x00,
287 // MD5 sum.
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00};
290 TestWriteDecoderConfig();
291 }
292
TEST_F(FlacTest,WriteVaryMostLegalFields)293 TEST_F(FlacTest, WriteVaryMostLegalFields) {
294 num_samples_per_frame_ = 64;
295 flac_decoder_config_.metadata_blocks_[0].payload =
296 FlacMetaBlockStreamInfo{.minimum_block_size = 64,
297 .maximum_block_size = 64,
298 .sample_rate = 48000,
299 .bits_per_sample = 7,
300 .total_samples_in_stream = 100};
301
302 expected_decoder_config_payload_ = {
303 // `last_metadata_block_flag` and `block_type` fields.
304 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
305 // `metadata_data_block_length`.
306 0, 0, 34,
307 // `minimum_block_size`.
308 0, 64,
309 // `maximum_block_size`.
310 0, 64,
311 // `minimum_frame_size`.
312 0, 0, 0,
313 // `maximum_frame_size`.
314 0, 0, 0,
315 // `sample_rate` (20 bits)
316 0x0b, 0xb8,
317 (0 << 4) |
318 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
319 FlacStreamInfoConstraints::kNumberOfChannels << 1,
320 7 << 4 |
321 // `total_samples_in_stream` (36 bits).
322 0,
323 0x00, 0x00, 0x00, 100,
324 // MD5 sum.
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00};
327 TestWriteDecoderConfig();
328 }
329
TEST_F(FlacTest,WriteSampleRateMin)330 TEST_F(FlacTest, WriteSampleRateMin) {
331 first_stream_info_payload_->sample_rate =
332 FlacStreamInfoConstraints::kMinSampleRate;
333
334 expected_decoder_config_payload_ = {
335 // `last_metadata_block_flag` and `block_type` fields.
336 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
337 // `metadata_data_block_length`.
338 0, 0, 34,
339 // `minimum_block_size`.
340 0, 16,
341 // `maximum_block_size`.
342 0, 16,
343 // `minimum_frame_size`.
344 0, 0, 0,
345 // `maximum_frame_size`.
346 0, 0, 0,
347 // `sample_rate` (20 bits)
348 0x00, 0x00,
349 (0x1 << 4) |
350 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
351 (FlacStreamInfoConstraints::kNumberOfChannels << 1),
352 15 << 4 |
353 // `total_samples_in_stream` (36 bits).
354 0,
355 0x00, 0x00, 0x00, 0x00,
356 // MD5 sum.
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00};
359 TestWriteDecoderConfig();
360 }
361
TEST_F(FlacTest,WriteSampleRateMax)362 TEST_F(FlacTest, WriteSampleRateMax) {
363 first_stream_info_payload_->sample_rate =
364 FlacStreamInfoConstraints::kMaxSampleRate;
365
366 expected_decoder_config_payload_ = {
367 // `last_metadata_block_flag` and `block_type` fields.
368 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
369 // `metadata_data_block_length`.
370 0, 0, 34,
371 // `minimum_block_size`.
372 0, 16,
373 // `maximum_block_size`.
374 0, 16,
375 // `minimum_frame_size`.
376 0, 0, 0,
377 // `maximum_frame_size`.
378 0, 0, 0,
379 // `sample_rate` (20 bits)
380 0x9f, 0xff,
381 (0x6 << 4) |
382 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
383 (FlacStreamInfoConstraints::kNumberOfChannels << 1),
384 15 << 4 |
385 // `total_samples_in_stream` (36 bits).
386 0,
387 0x00, 0x00, 0x00, 0x00,
388 // MD5 sum.
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00};
391 TestWriteDecoderConfig();
392 }
393
TEST_F(FlacTest,InvalidSampleRateTooLow)394 TEST_F(FlacTest, InvalidSampleRateTooLow) {
395 first_stream_info_payload_->sample_rate = 0;
396 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
397 TestWriteDecoderConfig();
398 }
399
TEST_F(FlacTest,InvalidSampleRateTooHigh)400 TEST_F(FlacTest, InvalidSampleRateTooHigh) {
401 first_stream_info_payload_->sample_rate = 655351;
402 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
403 TestWriteDecoderConfig();
404 }
405
TEST_F(FlacTest,InvalidBitsPerSampleZero)406 TEST_F(FlacTest, InvalidBitsPerSampleZero) {
407 first_stream_info_payload_->bits_per_sample = 0;
408 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
409 TestWriteDecoderConfig();
410 }
411
TEST_F(FlacTest,InvalidBitsPerSampleTooLow)412 TEST_F(FlacTest, InvalidBitsPerSampleTooLow) {
413 first_stream_info_payload_->bits_per_sample = 2;
414 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
415 TestWriteDecoderConfig();
416 }
417
TEST_F(FlacTest,InvalidLastMetadataFlag)418 TEST_F(FlacTest, InvalidLastMetadataFlag) {
419 flac_decoder_config_.metadata_blocks_[0].header.last_metadata_block_flag =
420 false;
421 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
422 TestWriteDecoderConfig();
423 }
424
TEST_F(FlacTest,WriteMinimumMaximumBlockSizeMax)425 TEST_F(FlacTest, WriteMinimumMaximumBlockSizeMax) {
426 num_samples_per_frame_ = 65535;
427 first_stream_info_payload_->minimum_block_size = 65535;
428 first_stream_info_payload_->maximum_block_size = 65535;
429
430 expected_decoder_config_payload_ = {
431 // `last_metadata_block_flag` and `block_type` fields.
432 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
433 // `metadata_data_block_length`.
434 0, 0, 34,
435 // `minimum_block_size`.
436 0xff, 0xff,
437 // `maximum_block_size`.
438 0xff, 0xff,
439 // `minimum_frame_size`.
440 0, 0, 0,
441 // `maximum_frame_size`.
442 0, 0, 0,
443 // `sample_rate` (20 bits)
444 0x0b, 0xb8,
445 (0 << 4) |
446 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
447 (FlacStreamInfoConstraints::kNumberOfChannels << 1),
448 15 << 4 |
449 // `total_samples_in_stream` (36 bits).
450 0,
451 0x00, 0x00, 0x00, 0x00,
452 // MD5 sum.
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00};
455 TestWriteDecoderConfig();
456 }
457
TEST_F(FlacTest,IllegalAudioRollDistanceMustBeZero)458 TEST_F(FlacTest, IllegalAudioRollDistanceMustBeZero) {
459 audio_roll_distance_ = -1;
460 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
461 TestWriteDecoderConfig();
462 }
463
TEST_F(FlacTest,IllegalMinimumMaximumBlockSizeZero)464 TEST_F(FlacTest, IllegalMinimumMaximumBlockSizeZero) {
465 first_stream_info_payload_->minimum_block_size = 0;
466 first_stream_info_payload_->maximum_block_size = 0;
467 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
468 TestWriteDecoderConfig();
469 }
470
TEST_F(FlacTest,IllegalMinimumMaximumBlockSizeEdge)471 TEST_F(FlacTest, IllegalMinimumMaximumBlockSizeEdge) {
472 first_stream_info_payload_->minimum_block_size = 15;
473 first_stream_info_payload_->maximum_block_size = 15;
474 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
475 TestWriteDecoderConfig();
476 }
477
TEST_F(FlacTest,IllegalMinimumMaximumBlockSizeNotEqualToSamplesInFrame)478 TEST_F(FlacTest, IllegalMinimumMaximumBlockSizeNotEqualToSamplesInFrame) {
479 ASSERT_NE(num_samples_per_frame_, 32);
480
481 first_stream_info_payload_->minimum_block_size = 32;
482 first_stream_info_payload_->maximum_block_size = 32;
483
484 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
485 TestWriteDecoderConfig();
486 }
487
TEST_F(FlacTest,IllegalMinimumMaximumBlockSizeNotEqualToEachOther)488 TEST_F(FlacTest, IllegalMinimumMaximumBlockSizeNotEqualToEachOther) {
489 first_stream_info_payload_->minimum_block_size = 16;
490 first_stream_info_payload_->maximum_block_size = 32;
491 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
492 TestWriteDecoderConfig();
493 }
494
TEST_F(FlacTest,IllegalMinimumFrameSizeNotEqualToZero)495 TEST_F(FlacTest, IllegalMinimumFrameSizeNotEqualToZero) {
496 const uint32_t kInvalidMinimumFrameSize = 16;
497 ASSERT_NE(kInvalidMinimumFrameSize, FlacStreamInfoConstraints::kMinFrameSize);
498 first_stream_info_payload_->minimum_frame_size = kInvalidMinimumFrameSize;
499
500 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
501 TestWriteDecoderConfig();
502 }
503
TEST_F(FlacTest,IllegalMaximumFrameSizeNotEqualToZero)504 TEST_F(FlacTest, IllegalMaximumFrameSizeNotEqualToZero) {
505 const uint32_t kInvalidMaximumFrameSize = 16;
506 ASSERT_NE(kInvalidMaximumFrameSize, FlacStreamInfoConstraints::kMaxFrameSize);
507 first_stream_info_payload_->maximum_frame_size = kInvalidMaximumFrameSize;
508
509 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
510 TestWriteDecoderConfig();
511 }
512
TEST_F(FlacTest,IllegalNumberOfChannelsNotEqualToOne)513 TEST_F(FlacTest, IllegalNumberOfChannelsNotEqualToOne) {
514 const uint8_t kInvalidNumberOfChannels = 2;
515 ASSERT_NE(kInvalidNumberOfChannels,
516 FlacStreamInfoConstraints::kNumberOfChannels);
517 first_stream_info_payload_->number_of_channels = kInvalidNumberOfChannels;
518
519 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
520 TestWriteDecoderConfig();
521 }
522
TEST_F(FlacTest,WriteTotalSamplesInStreamMax)523 TEST_F(FlacTest, WriteTotalSamplesInStreamMax) {
524 first_stream_info_payload_->total_samples_in_stream =
525 FlacStreamInfoConstraints::kMaxTotalSamplesInStream;
526
527 expected_decoder_config_payload_ = {
528 // `last_metadata_block_flag` and `block_type` fields.
529 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
530 // `metadata_data_block_length`.
531 0, 0, 34,
532 // `minimum_block_size`.
533 0, 16,
534 // `maximum_block_size`.
535 0, 16,
536 // `minimum_frame_size`.
537 0, 0, 0,
538 // `maximum_frame_size`.
539 0, 0, 0,
540 // `sample_rate` (20 bits)
541 0x0b, 0xb8,
542 (0 << 4) |
543 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
544 (FlacStreamInfoConstraints::kNumberOfChannels << 1),
545 15 << 4 |
546 // `total_samples_in_stream` (36 bits).
547 0xf,
548 0xff, 0xff, 0xff, 0xff,
549 // MD5 sum.
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00};
552 TestWriteDecoderConfig();
553 }
554
TEST_F(FlacTest,IllegalMd5SumNonZero)555 TEST_F(FlacTest, IllegalMd5SumNonZero) {
556 const uint8_t kInvalidMd5SumFirstByte = 0x01;
557 ASSERT_NE(FlacStreamInfoConstraints::kMd5Signature[0],
558 kInvalidMd5SumFirstByte);
559 first_stream_info_payload_->md5_signature[0] = kInvalidMd5SumFirstByte;
560
561 expected_write_status_code_ = absl::StatusCode::kInvalidArgument;
562 TestWriteDecoderConfig();
563 }
564
565 // ============================================================================
566 // Get Tests
567 // ============================================================================
568
TEST(GetRequiredAudioRollDistance,ReturnsFixedValue)569 TEST(GetRequiredAudioRollDistance, ReturnsFixedValue) {
570 constexpr int16_t kAudioRollDistance = 0;
571 EXPECT_EQ(FlacDecoderConfig::GetRequiredAudioRollDistance(),
572 kAudioRollDistance);
573 }
574
TEST_F(FlacTest,GetOutputSampleRateMin)575 TEST_F(FlacTest, GetOutputSampleRateMin) {
576 first_stream_info_payload_->sample_rate =
577 FlacStreamInfoConstraints::kMinSampleRate;
578
579 uint32_t output_sample_rate;
580 EXPECT_THAT(flac_decoder_config_.GetOutputSampleRate(output_sample_rate),
581 IsOk());
582 EXPECT_EQ(output_sample_rate, FlacStreamInfoConstraints::kMinSampleRate);
583 }
584
TEST_F(FlacTest,GetOutputSampleRateMax)585 TEST_F(FlacTest, GetOutputSampleRateMax) {
586 first_stream_info_payload_->sample_rate =
587 FlacStreamInfoConstraints::kMaxSampleRate;
588
589 uint32_t output_sample_rate;
590 EXPECT_THAT(flac_decoder_config_.GetOutputSampleRate(output_sample_rate),
591 IsOk());
592 EXPECT_EQ(output_sample_rate, FlacStreamInfoConstraints::kMaxSampleRate);
593 }
594
TEST_F(FlacTest,InvalidGetOutputSampleRateTooLow)595 TEST_F(FlacTest, InvalidGetOutputSampleRateTooLow) {
596 ASSERT_GT(FlacStreamInfoConstraints::kMinSampleRate, 0);
597 first_stream_info_payload_->sample_rate =
598 FlacStreamInfoConstraints::kMinSampleRate - 1;
599
600 uint32_t output_sample_rate;
601 EXPECT_FALSE(
602 flac_decoder_config_.GetOutputSampleRate(output_sample_rate).ok());
603 }
604
TEST_F(FlacTest,InvalidGetOutputSampleRateTooHigh)605 TEST_F(FlacTest, InvalidGetOutputSampleRateTooHigh) {
606 ASSERT_LT(FlacStreamInfoConstraints::kMaxSampleRate,
607 std::numeric_limits<uint32_t>::max());
608 first_stream_info_payload_->sample_rate =
609 FlacStreamInfoConstraints::kMaxSampleRate + 1;
610
611 uint32_t output_sample_rate;
612 EXPECT_FALSE(
613 flac_decoder_config_.GetOutputSampleRate(output_sample_rate).ok());
614 }
615
TEST_F(FlacTest,InvalidGetOutputSampleRateWithNoStreamInfo)616 TEST_F(FlacTest, InvalidGetOutputSampleRateWithNoStreamInfo) {
617 flac_decoder_config_.metadata_blocks_.clear();
618
619 uint32_t output_sample_rate;
620 EXPECT_FALSE(
621 flac_decoder_config_.GetOutputSampleRate(output_sample_rate).ok());
622 }
623
TEST_F(FlacTest,GetBitsPerSampleMin)624 TEST_F(FlacTest, GetBitsPerSampleMin) {
625 first_stream_info_payload_->bits_per_sample =
626 FlacStreamInfoConstraints::kMinBitsPerSample;
627
628 uint8_t output_bit_depth;
629 EXPECT_THAT(
630 flac_decoder_config_.GetBitDepthToMeasureLoudness(output_bit_depth),
631 IsOk());
632 EXPECT_EQ(output_bit_depth, FlacStreamInfoConstraints::kMinBitsPerSample + 1);
633 }
634
TEST_F(FlacTest,GetBitsPerSampleMax)635 TEST_F(FlacTest, GetBitsPerSampleMax) {
636 first_stream_info_payload_->bits_per_sample =
637 FlacStreamInfoConstraints::kMaxBitsPerSample;
638
639 uint8_t output_bit_depth;
640 EXPECT_THAT(
641 flac_decoder_config_.GetBitDepthToMeasureLoudness(output_bit_depth),
642 IsOk());
643 EXPECT_EQ(output_bit_depth, FlacStreamInfoConstraints::kMaxBitsPerSample + 1);
644 }
645
TEST_F(FlacTest,GetBitsPerSampleMinTooLow)646 TEST_F(FlacTest, GetBitsPerSampleMinTooLow) {
647 ASSERT_GT(FlacStreamInfoConstraints::kMinBitsPerSample, 0);
648 first_stream_info_payload_->bits_per_sample =
649 FlacStreamInfoConstraints::kMinBitsPerSample - 1;
650 uint8_t unused_output_bit_depth;
651 EXPECT_FALSE(
652 flac_decoder_config_.GetBitDepthToMeasureLoudness(unused_output_bit_depth)
653 .ok());
654 }
655
TEST_F(FlacTest,GetBitsPerSampleMaxTooHigh)656 TEST_F(FlacTest, GetBitsPerSampleMaxTooHigh) {
657 ASSERT_LT(FlacStreamInfoConstraints::kMaxBitsPerSample,
658 std::numeric_limits<uint32_t>::max());
659 first_stream_info_payload_->bits_per_sample =
660 FlacStreamInfoConstraints::kMaxBitsPerSample + 1;
661
662 uint8_t unused_output_bit_depth;
663 EXPECT_FALSE(
664 flac_decoder_config_.GetBitDepthToMeasureLoudness(unused_output_bit_depth)
665 .ok());
666 }
667
TEST_F(FlacTest,InvalidGetBitsPerSampleWithNoStreamInfo)668 TEST_F(FlacTest, InvalidGetBitsPerSampleWithNoStreamInfo) {
669 flac_decoder_config_.metadata_blocks_.clear();
670
671 uint8_t unused_output_bit_depth;
672 EXPECT_FALSE(
673 flac_decoder_config_.GetBitDepthToMeasureLoudness(unused_output_bit_depth)
674 .ok());
675 }
676
TEST_F(FlacTest,GetTotalNumSamplesInStreamMin)677 TEST_F(FlacTest, GetTotalNumSamplesInStreamMin) {
678 first_stream_info_payload_->total_samples_in_stream =
679 FlacStreamInfoConstraints::kMinTotalSamplesInStream;
680
681 uint64_t output_total_samples_in_stream;
682 EXPECT_THAT(flac_decoder_config_.GetTotalSamplesInStream(
683 output_total_samples_in_stream),
684 IsOk());
685 EXPECT_EQ(output_total_samples_in_stream,
686 FlacStreamInfoConstraints::kMinTotalSamplesInStream);
687 }
688
TEST_F(FlacTest,GetTotalNumSamplesInStreamMax)689 TEST_F(FlacTest, GetTotalNumSamplesInStreamMax) {
690 first_stream_info_payload_->total_samples_in_stream =
691 FlacStreamInfoConstraints::kMaxTotalSamplesInStream;
692
693 uint64_t output_total_samples_in_stream;
694 EXPECT_THAT(flac_decoder_config_.GetTotalSamplesInStream(
695 output_total_samples_in_stream),
696 IsOk());
697 EXPECT_EQ(output_total_samples_in_stream,
698 FlacStreamInfoConstraints::kMaxTotalSamplesInStream);
699 }
700
TEST_F(FlacTest,InvalidGetTotalNumSamplesInStreamTooHigh)701 TEST_F(FlacTest, InvalidGetTotalNumSamplesInStreamTooHigh) {
702 ASSERT_LT(FlacStreamInfoConstraints::kMaxTotalSamplesInStream,
703 std::numeric_limits<uint64_t>::max());
704 first_stream_info_payload_->total_samples_in_stream =
705 FlacStreamInfoConstraints::kMaxTotalSamplesInStream + 1;
706
707 uint64_t output_total_samples_in_stream;
708 EXPECT_FALSE(flac_decoder_config_
709 .GetTotalSamplesInStream(output_total_samples_in_stream)
710 .ok());
711 }
712
TEST_F(FlacTest,InvalidGetTotalNumSamplesInStreamWithNoStreamInfo)713 TEST_F(FlacTest, InvalidGetTotalNumSamplesInStreamWithNoStreamInfo) {
714 flac_decoder_config_.metadata_blocks_.clear();
715
716 uint64_t output_total_samples_in_stream;
717 EXPECT_FALSE(flac_decoder_config_
718 .GetTotalSamplesInStream(output_total_samples_in_stream)
719 .ok());
720 }
721
722 // ============================================================================
723 // Read Tests
724 // ============================================================================
725
TEST(ReadAndValidateTest,ReadAndValidateStreamInfoSuccess)726 TEST(ReadAndValidateTest, ReadAndValidateStreamInfoSuccess) {
727 std::vector<uint8_t> payload = {
728 // `last_metadata_block_flag` and `block_type` fields.
729 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
730 // `metadata_data_block_length`.
731 0, 0, 34,
732 // `minimum_block_size`.
733 0, 64,
734 // `maximum_block_size`.
735 0, 64,
736 // `minimum_frame_size`.
737 0, 0, 0,
738 // `maximum_frame_size`.
739 0, 0, 0,
740 // `sample_rate` (20 bits)
741 0x0b, 0xb8,
742 (0 << 4) |
743 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
744 FlacStreamInfoConstraints::kNumberOfChannels << 1,
745 7 << 4 |
746 // `total_samples_in_stream` (36 bits).
747 0,
748 0x00, 0x00, 0x00, 100,
749 // MD5 sum.
750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
751 0x00, 0x00, 0x00, 0x00};
752
753 auto rb = MemoryBasedReadBitBuffer::CreateFromSpan(
754 1024, absl::MakeConstSpan(payload));
755 FlacDecoderConfig decoder_config;
756 EXPECT_THAT(decoder_config.ReadAndValidate(
757 /*num_samples_per_frame=*/64, /*audio_roll_distance=*/0, *rb),
758 IsOk());
759 EXPECT_EQ(decoder_config.metadata_blocks_.size(), 1);
760 FlacMetaBlockHeader header = decoder_config.metadata_blocks_[0].header;
761 EXPECT_EQ(header.block_type, FlacMetaBlockHeader::kFlacStreamInfo);
762 EXPECT_EQ(header.metadata_data_block_length, 34);
763 FlacMetaBlockStreamInfo stream_info = std::get<FlacMetaBlockStreamInfo>(
764 decoder_config.metadata_blocks_[0].payload);
765 EXPECT_EQ(stream_info.minimum_block_size, 64);
766 EXPECT_EQ(stream_info.maximum_block_size, 64);
767 EXPECT_EQ(stream_info.minimum_frame_size, 0);
768 EXPECT_EQ(stream_info.maximum_frame_size, 0);
769 EXPECT_EQ(stream_info.sample_rate, 48000);
770 EXPECT_EQ(stream_info.number_of_channels,
771 FlacStreamInfoConstraints::kNumberOfChannels);
772 EXPECT_EQ(stream_info.bits_per_sample, 7);
773 EXPECT_EQ(stream_info.total_samples_in_stream, 100);
774 EXPECT_EQ(stream_info.md5_signature,
775 FlacStreamInfoConstraints::kMd5Signature);
776 }
777
TEST(ReadAndValidateTest,ReadAndValidateCanReadMultipleMetadataBlocks)778 TEST(ReadAndValidateTest, ReadAndValidateCanReadMultipleMetadataBlocks) {
779 std::vector<uint8_t> payload = {
780 // `last_metadata_block_flag` and `block_type` fields.
781 0 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
782 // `metadata_data_block_length`.
783 0, 0, 34,
784 // `minimum_block_size`.
785 0, 64,
786 // `maximum_block_size`.
787 0, 64,
788 // `minimum_frame_size`.
789 0, 0, 0,
790 // `maximum_frame_size`.
791 0, 0, 0,
792 // `sample_rate` (20 bits)
793 0x0b, 0xb8,
794 (0 << 4) |
795 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
796 (FlacStreamInfoConstraints::kNumberOfChannels << 1),
797 15 << 4 |
798 // `total_samples_in_stream` (36 bits).
799 0,
800 0x00, 0x00, 0x00, 0x00,
801 // MD5 sum.
802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
803 0x00, 0x00, 0x00, 0x00,
804 // `last_metadata_block_flag` and `block_type` fields.
805 0 << 7 | FlacMetaBlockHeader::kFlacPicture,
806 // `metadata_data_block_length`.
807 0, 0, 3,
808 // Payload.
809 'a', 'b', 'c',
810 // `last_metadata_block_flag` and `block_type` fields.
811 1 << 7 | FlacMetaBlockHeader::kFlacApplication,
812 // `metadata_data_block_length`.
813 0, 0, 3,
814 // Payload.
815 'd', 'e', 'f'};
816
817 auto rb = MemoryBasedReadBitBuffer::CreateFromSpan(
818 1024, absl::MakeConstSpan(payload));
819 FlacDecoderConfig decoder_config;
820 EXPECT_THAT(decoder_config.ReadAndValidate(
821 /*num_samples_per_frame=*/64, /*audio_roll_distance=*/0, *rb),
822 IsOk());
823 // The StreamInfo block details are tested in the previous test. Here, we'll
824 // just check that it is not labelled as the last block.
825 EXPECT_THAT(decoder_config.metadata_blocks_[0].header.block_type,
826 Eq(FlacMetaBlockHeader::kFlacStreamInfo));
827 EXPECT_FALSE(
828 decoder_config.metadata_blocks_[0].header.last_metadata_block_flag);
829
830 EXPECT_THAT(decoder_config.metadata_blocks_.size(), Eq(3));
831 auto& picture_block = decoder_config.metadata_blocks_[1];
832 auto& application_block = decoder_config.metadata_blocks_[2];
833
834 // Check that the subsequent blocks have the correct header (block type,
835 // payload length, last block flag).
836 EXPECT_THAT(picture_block.header.block_type,
837 Eq(FlacMetaBlockHeader::kFlacPicture));
838 EXPECT_THAT(application_block.header.block_type,
839 Eq(FlacMetaBlockHeader::kFlacApplication));
840 EXPECT_THAT(picture_block.header.metadata_data_block_length, Eq(3));
841 EXPECT_THAT(application_block.header.metadata_data_block_length, Eq(3));
842 EXPECT_FALSE(picture_block.header.last_metadata_block_flag);
843 EXPECT_TRUE(application_block.header.last_metadata_block_flag);
844
845 // Check that the subsequent blocks have the correct payload variant and
846 // contents.
847 EXPECT_TRUE(
848 std::holds_alternative<std::vector<uint8_t>>(picture_block.payload));
849 EXPECT_TRUE(
850 std::holds_alternative<std::vector<uint8_t>>(application_block.payload));
851 auto picture_payload = std::get<std::vector<uint8_t>>(picture_block.payload);
852 auto application_payload =
853 std::get<std::vector<uint8_t>>(application_block.payload);
854 EXPECT_THAT(picture_payload, ElementsAreArray({'a', 'b', 'c'}));
855 EXPECT_THAT(application_payload, ElementsAreArray({'d', 'e', 'f'}));
856 }
857
TEST(ReadAndValidateTest,ReadAndValidateStreamInfoFailsOnInvalidMd5Signature)858 TEST(ReadAndValidateTest, ReadAndValidateStreamInfoFailsOnInvalidMd5Signature) {
859 std::vector<uint8_t> payload = {
860 // `last_metadata_block_flag` and `block_type` fields.
861 1 << 7 | FlacMetaBlockHeader::kFlacStreamInfo,
862 // `metadata_data_block_length`.
863 0, 0, 34,
864 // `minimum_block_size`.
865 0, 64,
866 // `maximum_block_size`.
867 0, 64,
868 // `minimum_frame_size`.
869 0, 0, 0,
870 // `maximum_frame_size`.
871 0, 0, 0,
872 // `sample_rate` (20 bits)
873 0x0b, 0xb8,
874 (0 << 4) |
875 // `number_of_channels` (3 bits) and `bits_per_sample` (5 bits).
876 FlacStreamInfoConstraints::kNumberOfChannels << 1,
877 7 << 4 |
878 // `total_samples_in_stream` (36 bits).
879 0,
880 0x00, 0x00, 0x00, 100,
881 // MD5 sum (invalid bit at end)
882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
883 0x00, 0x00, 0x00, 0x01};
884
885 auto rb = MemoryBasedReadBitBuffer::CreateFromSpan(
886 1024, absl::MakeConstSpan(payload));
887 FlacDecoderConfig decoder_config;
888 EXPECT_FALSE(
889 decoder_config
890 .ReadAndValidate(
891 /*num_samples_per_frame=*/64, /*audio_roll_distance=*/0, *rb)
892 .ok());
893 }
894
895 } // namespace
896 } // namespace iamf_tools
897