• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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