• 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/obu_header.h"
13 
14 #include <cstdint>
15 #include <limits>
16 #include <memory>
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/leb_generator.h"
25 #include "iamf/common/read_bit_buffer.h"
26 #include "iamf/common/utils/tests/test_utils.h"
27 #include "iamf/common/write_bit_buffer.h"
28 
29 namespace iamf_tools {
30 namespace {
31 
32 using ::absl::StatusCode::kResourceExhausted;
33 using ::absl_testing::IsOk;
34 using ::absl_testing::StatusIs;
35 using ::testing::Not;
36 
37 // Max value of a decoded ULEB128.
38 constexpr uint32_t kMaxUlebDecoded = UINT32_MAX;
39 
40 // The spec serializes several fields into the first byte of the OBU header.
41 // `obu type` (5 bits), `obu_redundant_copy` (1 bit), `obu_trimming_status_flag`
42 // (1 bit), `obu_extension_flag` (1 bit).
43 constexpr uint8_t kUnimportantFirstByte = 0x00;
44 constexpr uint8_t kAudioFrameId0WithTrim = 0b00110010;
45 
46 class ObuHeaderTest : public testing::Test {
47  public:
ObuHeaderTest()48   ObuHeaderTest()
49       : obu_header_({.obu_type = kObuIaTemporalDelimiter}),
50         payload_serialized_size_(0),
51         expected_data_({}) {}
52 
TestGenerateAndWrite(absl::StatusCode expected_status_code=absl::StatusCode::kOk)53   void TestGenerateAndWrite(
54       absl::StatusCode expected_status_code = absl::StatusCode::kOk) {
55     // Usually OBU Headers are small. The internal buffer will resize if this is
56     // not large enough.
57     ASSERT_NE(leb_generator_, nullptr);
58     WriteBitBuffer wb(1024, *leb_generator_);
59 
60     ASSERT_NE(leb_generator_, nullptr);
61     EXPECT_EQ(obu_header_.ValidateAndWrite(payload_serialized_size_, wb).code(),
62               expected_status_code);
63     if (expected_status_code == absl::StatusCode::kOk) {
64       ValidateWriteResults(wb, expected_data_);
65     };
66   }
67 
68   std::unique_ptr<LebGenerator> leb_generator_ =
69       LebGenerator::Create(LebGenerator::GenerationMode::kMinimum);
70 
71   ObuHeader obu_header_;
72   int64_t payload_serialized_size_;
73 
74   std::vector<uint8_t> expected_data_;
75 };
76 
77 const int kObuTypeBitShift = 3;
78 const int kObuRedundantCopyBitMask = 4;
79 const int kObuTrimFlagBitMask = 2;
80 const int kObuExtensionFlagBitMask = 1;
81 
TEST_F(ObuHeaderTest,DefaultTemporalDelimiter)82 TEST_F(ObuHeaderTest, DefaultTemporalDelimiter) {
83   expected_data_ = {kObuIaTemporalDelimiter << kObuTypeBitShift, 0};
84   TestGenerateAndWrite();
85 }
86 
TEST_F(ObuHeaderTest,ObuTypeAndPayloadSizeIaSequenceHeader)87 TEST_F(ObuHeaderTest, ObuTypeAndPayloadSizeIaSequenceHeader) {
88   obu_header_.obu_type = kObuIaSequenceHeader;
89   payload_serialized_size_ = 6;
90   expected_data_ = {// `obu_type`, `obu_redundant_copy`,
91                     // `obu_trimming_status_flag, `obu_extension_flag`.
92                     kObuIaSequenceHeader << kObuTypeBitShift,
93                     // `obu_size`.
94                     6};
95   TestGenerateAndWrite();
96 }
97 
TEST_F(ObuHeaderTest,ExplicitAudioFrame)98 TEST_F(ObuHeaderTest, ExplicitAudioFrame) {
99   obu_header_.obu_type = kObuIaAudioFrame;
100   payload_serialized_size_ = 64;
101   expected_data_ = {// `obu_type`, `obu_redundant_copy`,
102                     // `obu_trimming_status_flag, `obu_extension_flag`.
103                     kObuIaAudioFrame << kObuTypeBitShift,
104                     // `obu_size`.
105                     64};
106   TestGenerateAndWrite();
107 }
108 
TEST_F(ObuHeaderTest,ImplicitAudioFrameId17)109 TEST_F(ObuHeaderTest, ImplicitAudioFrameId17) {
110   obu_header_.obu_type = kObuIaAudioFrameId17;
111   payload_serialized_size_ = 64;
112   expected_data_ = {// `obu_type`, `obu_redundant_copy`,
113                     // `obu_trimming_status_flag, `obu_extension_flag`.
114                     kObuIaAudioFrameId17 << kObuTypeBitShift,
115                     // `obu_size`.
116                     64};
117   TestGenerateAndWrite();
118 }
119 
TEST_F(ObuHeaderTest,RedundantCopy)120 TEST_F(ObuHeaderTest, RedundantCopy) {
121   obu_header_.obu_type = kObuIaSequenceHeader;
122   obu_header_.obu_redundant_copy = true;
123   expected_data_ = {
124       // `obu_type`, `obu_redundant_copy`,
125       // `obu_trimming_status_flag, `obu_extension_flag`.
126       kObuIaSequenceHeader << kObuTypeBitShift | kObuRedundantCopyBitMask,
127       // `obu_size`.
128       0};
129   TestGenerateAndWrite();
130 }
131 
TEST_F(ObuHeaderTest,IllegalRedundantCopyFlagIaSequenceHeader)132 TEST_F(ObuHeaderTest, IllegalRedundantCopyFlagIaSequenceHeader) {
133   obu_header_.obu_type = kObuIaTemporalDelimiter;
134   obu_header_.obu_redundant_copy = true;
135 
136   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
137 }
138 
TEST_F(ObuHeaderTest,IllegalRedundantCopyFlagParameterBlock)139 TEST_F(ObuHeaderTest, IllegalRedundantCopyFlagParameterBlock) {
140   // Parameter blocks cannot be redundant in simple or base profile.
141   obu_header_.obu_type = kObuIaParameterBlock;
142   obu_header_.obu_redundant_copy = true;
143 
144   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
145 }
146 
TEST_F(ObuHeaderTest,IllegalRedundantCopyFlagAudioFrame)147 TEST_F(ObuHeaderTest, IllegalRedundantCopyFlagAudioFrame) {
148   obu_header_.obu_type = kObuIaAudioFrame;
149   obu_header_.obu_redundant_copy = true;
150 
151   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
152 }
153 
TEST_F(ObuHeaderTest,UpperEdgeObuSizeOneByteLeb128)154 TEST_F(ObuHeaderTest, UpperEdgeObuSizeOneByteLeb128) {
155   obu_header_.obu_type = kObuIaCodecConfig;
156   payload_serialized_size_ = 0x7f;
157   expected_data_ = {// `obu_type`, `obu_redundant_copy`,
158                     // `obu_trimming_status_flag, `obu_extension_flag`.
159                     kObuIaCodecConfig << kObuTypeBitShift,
160                     // `obu_size`.
161                     0x7f};
162   TestGenerateAndWrite();
163 }
164 
TEST_F(ObuHeaderTest,LowerEdgeObuSizeTwoByteLeb128)165 TEST_F(ObuHeaderTest, LowerEdgeObuSizeTwoByteLeb128) {
166   obu_header_.obu_type = kObuIaCodecConfig;
167   payload_serialized_size_ = (1 << 7);
168   expected_data_ = {// `obu_type`, `obu_redundant_copy`,
169                     // `obu_trimming_status_flag, `obu_extension_flag`.
170                     kObuIaCodecConfig << kObuTypeBitShift,
171                     // `obu_size`.
172                     0x80, 0x01};
173   TestGenerateAndWrite();
174 }
175 
176 constexpr uint32_t kMaxObuSizeIamfV1_1_0WithMinimalLeb = 2097148;
177 constexpr uint32_t kMaxObuSizeIamfV1_1_0WithFixedSizeLebEight = 2097143;
178 
TEST_F(ObuHeaderTest,TwoMegaByteObuWithMinimalLebIamfV1_1_0)179 TEST_F(ObuHeaderTest, TwoMegaByteObuWithMinimalLebIamfV1_1_0) {
180   obu_header_.obu_type = kObuIaCodecConfig;
181   payload_serialized_size_ = kMaxObuSizeIamfV1_1_0WithMinimalLeb;
182   expected_data_ = {// `obu_type`, `obu_redundant_copy`,
183                     // `obu_trimming_status_flag, `obu_extension_flag`.
184                     kObuIaCodecConfig << kObuTypeBitShift,
185                     // `obu_size`.
186                     0xfc, 0xff, 0x7f};
187   TestGenerateAndWrite();
188 }
189 
TEST_F(ObuHeaderTest,InvalidOverTwoMegaByteObuWithMinimalLebIamfV1_1_0)190 TEST_F(ObuHeaderTest, InvalidOverTwoMegaByteObuWithMinimalLebIamfV1_1_0) {
191   obu_header_.obu_type = kObuIaCodecConfig;
192   payload_serialized_size_ = kMaxObuSizeIamfV1_1_0WithMinimalLeb + 1;
193 
194   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
195 }
196 
TEST_F(ObuHeaderTest,TwoMegaByteObuWithFixedSizeLeb8IamfV1_1_0)197 TEST_F(ObuHeaderTest, TwoMegaByteObuWithFixedSizeLeb8IamfV1_1_0) {
198   obu_header_.obu_type = kObuIaCodecConfig;
199   payload_serialized_size_ = kMaxObuSizeIamfV1_1_0WithFixedSizeLebEight;
200   leb_generator_ =
201       LebGenerator::Create(LebGenerator::GenerationMode::kFixedSize, 8);
202 
203   expected_data_ = {// `obu_type`, `obu_redundant_copy`,
204                     // `obu_trimming_status_flag, `obu_extension_flag`.
205                     kObuIaCodecConfig << kObuTypeBitShift,
206                     // `obu_size`.
207                     0xf7, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x00};
208 
209   TestGenerateAndWrite();
210 }
211 
TEST_F(ObuHeaderTest,InvalidOverTwoMegaByteObuWithFixedSizeLeb8IamfV1_1_0)212 TEST_F(ObuHeaderTest, InvalidOverTwoMegaByteObuWithFixedSizeLeb8IamfV1_1_0) {
213   obu_header_.obu_type = kObuIaCodecConfig;
214   payload_serialized_size_ = kMaxObuSizeIamfV1_1_0WithFixedSizeLebEight + 1;
215   leb_generator_ =
216       LebGenerator::Create(LebGenerator::GenerationMode::kFixedSize, 8);
217 
218   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
219 }
220 
TEST_F(ObuHeaderTest,MaxObuSizeWithMinimalTrim)221 TEST_F(ObuHeaderTest, MaxObuSizeWithMinimalTrim) {
222   obu_header_.obu_type = kObuIaAudioFrameId0;
223   obu_header_.obu_trimming_status_flag = true;
224   obu_header_.num_samples_to_trim_at_end = 0;
225   obu_header_.num_samples_to_trim_at_start = 0;
226   payload_serialized_size_ = kMaxObuSizeIamfV1_1_0WithMinimalLeb - 2;
227 
228   expected_data_ = {
229       // `obu_type`, `obu_redundant_copy`,
230       // `obu_trimming_status_flag, `obu_extension_flag`.
231       kObuIaAudioFrameId0 << kObuTypeBitShift | kObuTrimFlagBitMask,
232       // `obu_size`.
233       0xfc, 0xff, 0x7f,
234       // `num_samples_to_trim_at_end`.
235       0x00,
236       // `num_samples_to_trim_at_start`.
237       0x00};
238   TestGenerateAndWrite();
239 }
240 
TEST_F(ObuHeaderTest,MaxObuSizeWithTrimUsingGenerationModeFixedSizeWithEightBytes)241 TEST_F(ObuHeaderTest,
242        MaxObuSizeWithTrimUsingGenerationModeFixedSizeWithEightBytes) {
243   obu_header_.obu_type = kObuIaAudioFrameId0;
244   obu_header_.obu_trimming_status_flag = true;
245   leb_generator_ =
246       LebGenerator::Create(LebGenerator::GenerationMode::kFixedSize, 8);
247   obu_header_.num_samples_to_trim_at_end = 0;
248   obu_header_.num_samples_to_trim_at_start = 0;
249 
250   // Obu size includes the trim fields. This reduce the maximum payload.
251   payload_serialized_size_ = kMaxObuSizeIamfV1_1_0WithFixedSizeLebEight - 16;
252 
253   expected_data_ = {
254       // `obu_type`, `obu_redundant_copy`,
255       // `obu_trimming_status_flag, `obu_extension_flag`.
256       kObuIaAudioFrameId0 << kObuTypeBitShift | kObuTrimFlagBitMask,
257       // `obu_size`.
258       0xf7, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x00,
259       // `num_samples_to_trim_at_end`.
260       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
261       // `num_samples_to_trim_at_start`.
262       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00};
263   TestGenerateAndWrite();
264 }
265 
TEST_F(ObuHeaderTest,InvalidArgumentOver32Bits)266 TEST_F(ObuHeaderTest, InvalidArgumentOver32Bits) {
267   payload_serialized_size_ =
268       static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) + 1;
269   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
270 }
271 
TEST_F(ObuHeaderTest,PayloadSizeOverflow)272 TEST_F(ObuHeaderTest, PayloadSizeOverflow) {
273   obu_header_.obu_type = kObuIaAudioFrameId0;
274   obu_header_.obu_trimming_status_flag = true;
275   payload_serialized_size_ = std::numeric_limits<uint32_t>::max() - 1;
276 
277   // `obu_size` includes the 2 bytes of trim flags and the payload. The sum
278   // surpasses the maximum value of a ULEB128.
279   obu_header_.num_samples_to_trim_at_end = 0;
280   obu_header_.num_samples_to_trim_at_start = 0;
281 
282   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
283 }
284 
TEST_F(ObuHeaderTest,ValidateAndWriteFailsWhenTrimmingIsSetForIaSequenceHeader)285 TEST_F(ObuHeaderTest,
286        ValidateAndWriteFailsWhenTrimmingIsSetForIaSequenceHeader) {
287   ObuHeader header(
288       {.obu_type = kObuIaSequenceHeader, .obu_trimming_status_flag = true});
289   WriteBitBuffer unused_wb(0);
290 
291   EXPECT_FALSE(
292       header.ValidateAndWrite(payload_serialized_size_, unused_wb).ok());
293 }
294 
TEST_F(ObuHeaderTest,TrimmingStatusFlagZeroTrim)295 TEST_F(ObuHeaderTest, TrimmingStatusFlagZeroTrim) {
296   obu_header_.obu_type = kObuIaAudioFrameId0;
297   obu_header_.obu_trimming_status_flag = true;
298   obu_header_.num_samples_to_trim_at_end = 0;
299   obu_header_.num_samples_to_trim_at_start = 0;
300   expected_data_ = {
301       // `obu_type`, `obu_redundant_copy`,
302       // `obu_trimming_status_flag, `obu_extension_flag`.
303       kObuIaAudioFrameId0 << kObuTypeBitShift | kObuTrimFlagBitMask,
304       // `obu_size`.
305       2,
306       // `num_samples_to_trim_at_end`.
307       0x00,
308       // `num_samples_to_trim_at_start`.
309       0x00};
310   TestGenerateAndWrite();
311 }
312 
TEST_F(ObuHeaderTest,TrimmingStatusFlagNonZeroTrimAtEnd)313 TEST_F(ObuHeaderTest, TrimmingStatusFlagNonZeroTrimAtEnd) {
314   obu_header_.obu_type = kObuIaAudioFrameId0;
315   obu_header_.obu_trimming_status_flag = true;
316   obu_header_.num_samples_to_trim_at_end = 1;
317   obu_header_.num_samples_to_trim_at_start = 0;
318   expected_data_ = {
319       // `obu_type`, `obu_redundant_copy`,
320       // `obu_trimming_status_flag, `obu_extension_flag`.
321       kObuIaAudioFrameId0 << kObuTypeBitShift | kObuTrimFlagBitMask,
322       // `obu_size`.
323       2,
324       // `num_samples_to_trim_at_end`.
325       0x01,
326       // `num_samples_to_trim_at_start`.
327       0x00};
328   TestGenerateAndWrite();
329 }
330 
TEST_F(ObuHeaderTest,TrimmingStatusFlagNonZeroTrimAtStart)331 TEST_F(ObuHeaderTest, TrimmingStatusFlagNonZeroTrimAtStart) {
332   obu_header_.obu_type = kObuIaAudioFrameId0;
333   obu_header_.obu_trimming_status_flag = true;
334   obu_header_.num_samples_to_trim_at_end = 0;
335   obu_header_.num_samples_to_trim_at_start = 2;
336   expected_data_ = {
337       // `obu_type`, `obu_redundant_copy`,
338       // `obu_trimming_status_flag, `obu_extension_flag`.
339       kObuIaAudioFrameId0 << kObuTypeBitShift | kObuTrimFlagBitMask,
340       // `obu_size`.
341       2,
342       // `num_samples_to_trim_at_end`.
343       0x00,
344       // `num_samples_to_trim_at_start`.
345       0x02};
346   TestGenerateAndWrite();
347 }
348 
TEST_F(ObuHeaderTest,TrimmingStatusFlagNonZeroBothTrims)349 TEST_F(ObuHeaderTest, TrimmingStatusFlagNonZeroBothTrims) {
350   obu_header_.obu_type = kObuIaAudioFrameId0;
351   obu_header_.obu_trimming_status_flag = true;
352   obu_header_.num_samples_to_trim_at_end = 1;
353   obu_header_.num_samples_to_trim_at_start = 2;
354   expected_data_ = {
355       // `obu_type`, `obu_redundant_copy`,
356       // `obu_trimming_status_flag, `obu_extension_flag`.
357       kObuIaAudioFrameId0 << kObuTypeBitShift | kObuTrimFlagBitMask,
358       // `obu_size`.
359       2,
360       // `num_samples_to_trim_at_end`.
361       0x01,
362       // `num_samples_to_trim_at_start`.
363       0x02};
364   TestGenerateAndWrite();
365 }
366 
TEST_F(ObuHeaderTest,NonMinimalLebGeneratorAffectsAllLeb128s)367 TEST_F(ObuHeaderTest, NonMinimalLebGeneratorAffectsAllLeb128s) {
368   obu_header_.obu_type = kObuIaAudioFrameId0;
369   obu_header_.obu_trimming_status_flag = true;
370   obu_header_.obu_extension_flag = true;
371   leb_generator_ =
372       LebGenerator::Create(LebGenerator::GenerationMode::kFixedSize, 8);
373 
374   obu_header_.num_samples_to_trim_at_end = 1;
375   obu_header_.num_samples_to_trim_at_start = 0;
376 
377   obu_header_.extension_header_size = 2;
378   obu_header_.extension_header_bytes = {100, 101};
379 
380   expected_data_ = {// `obu_type`, `obu_redundant_copy`,
381                     // `obu_trimming_status_flag, `obu_extension_flag`.
382                     kObuIaAudioFrameId0 << kObuTypeBitShift |
383                         kObuTrimFlagBitMask | kObuExtensionFlagBitMask,
384                     // `obu_size`.
385                     0x80 | 26, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
386                     // `num_samples_to_trim_at_end`.
387                     0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
388                     // `num_samples_to_trim_at_start`.
389                     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
390                     // `extension_header_size_`.
391                     0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
392                     // `extension_header_bytes_`.
393                     100, 101};
394   TestGenerateAndWrite();
395 }
396 
TEST_F(ObuHeaderTest,UpperEdgeOneByteLeb128ObuSizeIncludesPayloadSizeAndTrim)397 TEST_F(ObuHeaderTest, UpperEdgeOneByteLeb128ObuSizeIncludesPayloadSizeAndTrim) {
398   obu_header_.obu_type = kObuIaAudioFrameId0;
399   obu_header_.obu_trimming_status_flag = true;
400   obu_header_.num_samples_to_trim_at_end = 1;
401   obu_header_.num_samples_to_trim_at_start = 0;
402   payload_serialized_size_ = 125;
403   expected_data_ = {
404       // `obu_type`, `obu_redundant_copy`,
405       // `obu_trimming_status_flag, `obu_extension_flag`.
406       kObuIaAudioFrameId0 << kObuTypeBitShift | kObuTrimFlagBitMask,
407       // `obu_size`.
408       0x7f,
409       // `num_samples_to_trim_at_end`.
410       0x01,
411       // `num_samples_to_trim_at_start`.
412       0x00};
413   TestGenerateAndWrite();
414 }
415 
TEST_F(ObuHeaderTest,LowerEdgeOneByteLeb128ObuSizeIncludesPayloadSizeAndTrim)416 TEST_F(ObuHeaderTest, LowerEdgeOneByteLeb128ObuSizeIncludesPayloadSizeAndTrim) {
417   obu_header_.obu_type = kObuIaAudioFrameId0;
418   obu_header_.obu_trimming_status_flag = true;
419   obu_header_.num_samples_to_trim_at_end = 1;
420   obu_header_.num_samples_to_trim_at_start = 0;
421   payload_serialized_size_ = 126;
422   expected_data_ = {
423       // `obu_type`, `obu_redundant_copy`,
424       // `obu_trimming_status_flag, `obu_extension_flag`.
425       kObuIaAudioFrameId0 << kObuTypeBitShift | kObuTrimFlagBitMask,
426       // `obu_size`.
427       0x80, 0x01,
428       // `num_samples_to_trim_at_end`.
429       0x01,
430       // `num_samples_to_trim_at_start`.
431       0x00};
432   TestGenerateAndWrite();
433 }
434 
TEST_F(ObuHeaderTest,SerializedSizeTooBig)435 TEST_F(ObuHeaderTest, SerializedSizeTooBig) {
436   obu_header_.obu_type = kObuIaAudioFrameId0;
437   obu_header_.obu_trimming_status_flag = true;
438   leb_generator_ =
439       LebGenerator::Create(LebGenerator::GenerationMode::kFixedSize, 8);
440 
441   obu_header_.num_samples_to_trim_at_end = 0;
442   obu_header_.num_samples_to_trim_at_start = 0;
443   payload_serialized_size_ = kMaxUlebDecoded - 15;
444 
445   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
446 }
447 
TEST_F(ObuHeaderTest,ExtensionHeaderSizeZero)448 TEST_F(ObuHeaderTest, ExtensionHeaderSizeZero) {
449   obu_header_.extension_header_size = 0;
450   obu_header_.obu_extension_flag = true;
451   expected_data_ = {
452       kObuIaTemporalDelimiter << kObuTypeBitShift | kObuExtensionFlagBitMask, 1,
453       0};
454   TestGenerateAndWrite();
455 }
456 
TEST_F(ObuHeaderTest,ExtensionHeaderSizeNonzero)457 TEST_F(ObuHeaderTest, ExtensionHeaderSizeNonzero) {
458   obu_header_.obu_extension_flag = true;
459   obu_header_.extension_header_size = 3;
460   obu_header_.extension_header_bytes = {100, 101, 102};
461   expected_data_ = {
462       kObuIaTemporalDelimiter << kObuTypeBitShift | kObuExtensionFlagBitMask,
463       // `obu_size`.
464       4,
465       // `extension_header_size`.
466       3,
467       // `extension_header_bytes`.
468       100, 101, 102};
469   TestGenerateAndWrite();
470 }
471 
TEST_F(ObuHeaderTest,InconsistentExtensionHeader)472 TEST_F(ObuHeaderTest, InconsistentExtensionHeader) {
473   obu_header_.obu_extension_flag = false;
474   obu_header_.extension_header_size = 1;
475   obu_header_.extension_header_bytes = {100};
476 
477   TestGenerateAndWrite(absl::StatusCode::kInvalidArgument);
478 }
479 
TEST_F(ObuHeaderTest,ExtensionHeaderIaSequenceHeader)480 TEST_F(ObuHeaderTest, ExtensionHeaderIaSequenceHeader) {
481   obu_header_.obu_type = kObuIaSequenceHeader;
482   obu_header_.obu_extension_flag = true;
483   obu_header_.extension_header_size = 3;
484   obu_header_.extension_header_bytes = {100, 101, 102};
485   payload_serialized_size_ = 6;
486   expected_data_ = {
487       kObuIaSequenceHeader << kObuTypeBitShift | kObuExtensionFlagBitMask,
488       // `obu_size`.
489       10,
490       // `extension_header_size`.
491       3,
492       // `extension_header_bytes`.
493       100, 101, 102};
494   TestGenerateAndWrite();
495 }
496 
TEST_F(ObuHeaderTest,ObuSizeIncludesAllConditionalFields)497 TEST_F(ObuHeaderTest, ObuSizeIncludesAllConditionalFields) {
498   obu_header_.obu_type = kObuIaAudioFrameId1;
499   obu_header_.obu_trimming_status_flag = true;
500   obu_header_.obu_extension_flag = true;
501   obu_header_.num_samples_to_trim_at_end = 128;
502   obu_header_.num_samples_to_trim_at_start = 128;
503   obu_header_.extension_header_size = 3;
504   obu_header_.extension_header_bytes = {100, 101, 102};
505   payload_serialized_size_ = 1016;
506 
507   expected_data_ = {kObuIaAudioFrameId1 << kObuTypeBitShift |
508                         kObuTrimFlagBitMask | kObuExtensionFlagBitMask,
509                     // `obu_size == 1024`.
510                     0x80, 0x08,
511                     // `num_samples_to_trim_at_end`.
512                     0x80, 0x01,
513                     // `num_samples_to_trim_at_start`.
514                     0x80, 0x01,
515                     // `extension_header_size`.
516                     3,
517                     // `extension_header_bytes`.
518                     100, 101, 102};
519   TestGenerateAndWrite();
520 }
521 
522 // --- Begin ReadAndValidate Tests ---
TEST_F(ObuHeaderTest,ReadAndValidateIncludeAllConditionalFields)523 TEST_F(ObuHeaderTest, ReadAndValidateIncludeAllConditionalFields) {
524   std::vector<uint8_t> source_data = {
525       // `obu type`, `obu_redundant_copy`, `obu_trimming_status_flag`,
526       // `obu_extension_flag`
527       0b00111011,
528       // `obu_size == 1024`
529       0x80, 0x08,
530       // `num_samples_to_trim_at_end`
531       0x80, 0x01,
532       // `num_samples_to_trim_at_start`
533       0x80, 0x01,
534       // `extension_header_size`
535       0x03,
536       // `extension_header_bytes`
537       100, 101, 102};
538   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
539       1024, absl::MakeConstSpan(source_data));
540   EXPECT_THAT(
541       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
542       IsOk());
543 
544   // Validate all OBU Header fields.
545   EXPECT_EQ(obu_header_.obu_type, kObuIaAudioFrameId1);
546 
547   // 1024 - (2 + 2 + 1 + 3) = 1016.
548   EXPECT_EQ(payload_serialized_size_, 1016);
549 
550   EXPECT_EQ(obu_header_.obu_redundant_copy, false);
551   EXPECT_EQ(obu_header_.obu_trimming_status_flag, true);
552   EXPECT_EQ(obu_header_.obu_extension_flag, true);
553 
554   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 128);
555   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 128);
556   EXPECT_EQ(obu_header_.extension_header_size, 3);
557   std::vector<uint8_t> expected_extension_header_bytes = {100, 101, 102};
558   for (int i = 0; i < obu_header_.extension_header_bytes.size(); ++i) {
559     EXPECT_EQ(obu_header_.extension_header_bytes[i],
560               expected_extension_header_bytes[i]);
561   }
562 }
563 
TEST_F(ObuHeaderTest,ReadAndValidateImplicitAudioFrameId17)564 TEST_F(ObuHeaderTest, ReadAndValidateImplicitAudioFrameId17) {
565   std::vector<uint8_t> source_data = {
566       // `obu type`, `obu_redundant_copy`, `obu_trimming_status_flag`,
567       // `obu_extension_flag`
568       0b10111000,
569       // `obu_size == 1024`
570       0x80, 0x08};
571   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
572       1024, absl::MakeConstSpan(source_data));
573   EXPECT_THAT(
574       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
575       IsOk());
576 
577   // Validate all OBU Header fields.
578   EXPECT_EQ(obu_header_.obu_type, kObuIaAudioFrameId17);
579 
580   // 1024 - (0) = 1024.
581   EXPECT_EQ(payload_serialized_size_, 1024);
582 
583   EXPECT_EQ(obu_header_.obu_redundant_copy, false);
584   EXPECT_EQ(obu_header_.obu_trimming_status_flag, false);
585   EXPECT_EQ(obu_header_.obu_extension_flag, false);
586 
587   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 0);
588   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 0);
589   EXPECT_EQ(obu_header_.extension_header_size, 0);
590   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
591 }
592 
TEST_F(ObuHeaderTest,ReadAndValidateIaSequenceHeaderNoConditionalFields)593 TEST_F(ObuHeaderTest, ReadAndValidateIaSequenceHeaderNoConditionalFields) {
594   std::vector<uint8_t> source_data = {
595       // `obu type`, `obu_redundant_copy`, `obu_trimming_status_flag`,
596       // `obu_extension_flag`
597       0b11111000,
598       // `obu_size == 1024`
599       0x80, 0x08};
600   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
601       1024, absl::MakeConstSpan(source_data));
602   EXPECT_THAT(
603       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
604       IsOk());
605 
606   // Validate all OBU Header fields.
607   EXPECT_EQ(obu_header_.obu_type, kObuIaSequenceHeader);
608 
609   // 1024 - (0) = 1024.
610   EXPECT_EQ(payload_serialized_size_, 1024);
611 
612   EXPECT_EQ(obu_header_.obu_redundant_copy, false);
613   EXPECT_EQ(obu_header_.obu_trimming_status_flag, false);
614   EXPECT_EQ(obu_header_.obu_extension_flag, false);
615 
616   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 0);
617   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 0);
618   EXPECT_EQ(obu_header_.extension_header_size, 0);
619   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
620 }
621 
TEST_F(ObuHeaderTest,ReadAndValidateIaSequenceHeaderRedundantCopy)622 TEST_F(ObuHeaderTest, ReadAndValidateIaSequenceHeaderRedundantCopy) {
623   std::vector<uint8_t> source_data = {
624       // `obu type`, `obu_redundant_copy`, `obu_trimming_status_flag`,
625       // `obu_extension_flag`
626       0b11111100,
627       // `obu_size == 1024`
628       0x80, 0x08};
629   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
630       1024, absl::MakeConstSpan(source_data));
631   EXPECT_THAT(
632       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
633       IsOk());
634 
635   // Validate all OBU Header fields.
636   EXPECT_EQ(obu_header_.obu_type, kObuIaSequenceHeader);
637 
638   // 1024 - (0) = 1024.
639   EXPECT_EQ(payload_serialized_size_, 1024);
640 
641   EXPECT_EQ(obu_header_.obu_redundant_copy, true);
642   EXPECT_EQ(obu_header_.obu_trimming_status_flag, false);
643   EXPECT_EQ(obu_header_.obu_extension_flag, false);
644 
645   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 0);
646   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 0);
647   EXPECT_EQ(obu_header_.extension_header_size, 0);
648   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
649 }
650 
TEST_F(ObuHeaderTest,ReadAndValidateUpperEdgeObuSizeOneByteLeb128)651 TEST_F(ObuHeaderTest, ReadAndValidateUpperEdgeObuSizeOneByteLeb128) {
652   std::vector<uint8_t> source_data = {
653       // `obu type`, `obu_redundant_copy`, `obu_trimming_status_flag`,
654       // `obu_extension_flag`
655       0b00000000,
656       // `obu_size == 127`
657       0x7f};
658   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
659       1024, absl::MakeConstSpan(source_data));
660   EXPECT_THAT(
661       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
662       IsOk());
663 
664   // Validate all OBU Header fields.
665   EXPECT_EQ(obu_header_.obu_type, kObuIaCodecConfig);
666 
667   // 127 - (0) = 127.
668   EXPECT_EQ(payload_serialized_size_, 127);
669 
670   EXPECT_EQ(obu_header_.obu_redundant_copy, false);
671   EXPECT_EQ(obu_header_.obu_trimming_status_flag, false);
672   EXPECT_EQ(obu_header_.obu_extension_flag, false);
673 
674   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 0);
675   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 0);
676   EXPECT_EQ(obu_header_.extension_header_size, 0);
677   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
678 }
679 
TEST_F(ObuHeaderTest,ReadAndValidateLowerEdgeObuSizeTwoByteLeb128)680 TEST_F(ObuHeaderTest, ReadAndValidateLowerEdgeObuSizeTwoByteLeb128) {
681   std::vector<uint8_t> source_data = {
682       // `obu type`, `obu_redundant_copy`, `obu_trimming_status_flag`,
683       // `obu_extension_flag`
684       0b00000000,
685       // `obu_size == 128`
686       0x80, 0x01};
687   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
688       1024, absl::MakeConstSpan(source_data));
689   EXPECT_THAT(
690       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
691       IsOk());
692 
693   // Validate all OBU Header fields.
694   EXPECT_EQ(obu_header_.obu_type, kObuIaCodecConfig);
695 
696   // 128 - (0) = 128.
697   EXPECT_EQ(payload_serialized_size_, 128);
698 
699   EXPECT_EQ(obu_header_.obu_redundant_copy, false);
700   EXPECT_EQ(obu_header_.obu_trimming_status_flag, false);
701   EXPECT_EQ(obu_header_.obu_extension_flag, false);
702 
703   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 0);
704   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 0);
705   EXPECT_EQ(obu_header_.extension_header_size, 0);
706   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
707 }
708 
TEST_F(ObuHeaderTest,InvalidWhenObuWouldExceedTwoMegabytes_FourByteObuSize)709 TEST_F(ObuHeaderTest, InvalidWhenObuWouldExceedTwoMegabytes_FourByteObuSize) {
710   std::vector<uint8_t> source_data = {kUnimportantFirstByte,
711                                       // `obu_size == 268435456 - 1`
712                                       0xff, 0xff, 0xff, 0x7f};
713   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
714       1024, absl::MakeConstSpan(source_data));
715   EXPECT_FALSE(
716       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_)
717           .ok());
718 }
719 
TEST_F(ObuHeaderTest,InvalidWhenObuWouldExceedTwoMegabytes_FiveByteObuSize)720 TEST_F(ObuHeaderTest, InvalidWhenObuWouldExceedTwoMegabytes_FiveByteObuSize) {
721   std::vector<uint8_t> source_data = {kUnimportantFirstByte,
722                                       // `obu_size == 268435456`
723                                       0x80, 0x80, 0x80, 0x80, 0x01};
724   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
725       1024, absl::MakeConstSpan(source_data));
726   EXPECT_FALSE(
727       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_)
728           .ok());
729 }
730 
TEST_F(ObuHeaderTest,InvalidWhenObuWouldExceedTwoMegabytes_MaxByteObuSize)731 TEST_F(ObuHeaderTest, InvalidWhenObuWouldExceedTwoMegabytes_MaxByteObuSize) {
732   std::vector<uint8_t> source_data = {kUnimportantFirstByte,
733                                       // `obu_size == 4294967295`
734                                       0xff, 0xff, 0xff, 0xff, 0x0f};
735   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
736       1024, absl::MakeConstSpan(source_data));
737   EXPECT_FALSE(
738       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_)
739           .ok());
740 }
741 
TEST_F(ObuHeaderTest,MaxObuSizeWithMinimalLeb128)742 TEST_F(ObuHeaderTest, MaxObuSizeWithMinimalLeb128) {
743   // When the size field is encoded using three bytes, the maximum value it can
744   // represent is (2 megabytes - 4 bytes).
745   std::vector<uint8_t> source_data = {kUnimportantFirstByte,
746                                       // `obu_size == 2 megabytes - 4`
747                                       0xfc, 0xff, 0x7f};
748   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
749       1024, absl::MakeConstSpan(source_data));
750   EXPECT_THAT(
751       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
752       IsOk());
753 
754   // Validate all OBU Header fields.
755 
756   EXPECT_EQ(payload_serialized_size_, kMaxObuSizeIamfV1_1_0WithMinimalLeb);
757 }
758 
TEST_F(ObuHeaderTest,InvalidEdgeOverMaxSizeWithMinimalLeb128)759 TEST_F(ObuHeaderTest, InvalidEdgeOverMaxSizeWithMinimalLeb128) {
760   std::vector<uint8_t> source_data = {kUnimportantFirstByte,
761                                       // `obu_size == 2 megabytes - 3`
762                                       0xfd, 0xff, 0x7f};
763   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
764       1024, absl::MakeConstSpan(source_data));
765 
766   EXPECT_FALSE(
767       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_)
768           .ok());
769 }
770 
TEST_F(ObuHeaderTest,MaxObuSizeWithFixesSizeLebEightBytes)771 TEST_F(ObuHeaderTest, MaxObuSizeWithFixesSizeLebEightBytes) {
772   // When the size field is encoded using eight bytes, the maximum value it can
773   // represent is (2 megabytes - 9 bytes).
774   std::vector<uint8_t> source_data = {kUnimportantFirstByte,
775                                       // `obu_size == 2 megabytes - 9`
776                                       0xf7, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80,
777                                       0x00};
778   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
779       1024, absl::MakeConstSpan(source_data));
780   EXPECT_THAT(
781       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
782       IsOk());
783 
784   // Validate all OBU Header fields.
785 
786   EXPECT_EQ(payload_serialized_size_,
787             kMaxObuSizeIamfV1_1_0WithFixedSizeLebEight);
788 }
789 
TEST_F(ObuHeaderTest,InvalidEdgeOverMaxSizeWithFixedSizeLebEightBytes)790 TEST_F(ObuHeaderTest, InvalidEdgeOverMaxSizeWithFixedSizeLebEightBytes) {
791   std::vector<uint8_t> source_data = {kUnimportantFirstByte,
792                                       // `obu_size == 2 megabytes - 8`
793                                       0xf8, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80,
794                                       0x00};
795   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
796       1024, absl::MakeConstSpan(source_data));
797 
798   EXPECT_FALSE(
799       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_)
800           .ok());
801 }
802 
TEST_F(ObuHeaderTest,ReadAndValidateMaxObuSizeWithMinimalTrim)803 TEST_F(ObuHeaderTest, ReadAndValidateMaxObuSizeWithMinimalTrim) {
804   std::vector<uint8_t> source_data = {
805       // `obu type`, `obu_redundant_copy`, `obu_trimming_status_flag`,
806       // `obu_extension_flag`
807       0b00110010,
808       // `obu_size`
809       2,
810       // `num_samples_to_trim_at_end`.
811       0x00,
812       // `num_samples_to_trim_at_start`.
813       0x00};
814   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
815       1024, absl::MakeConstSpan(source_data));
816   EXPECT_THAT(
817       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
818       IsOk());
819 
820   // Validate all OBU Header fields.
821   EXPECT_EQ(obu_header_.obu_type, kObuIaAudioFrameId0);
822 
823   // The obu header consumes the two bytes of the `obu_size` field.
824   EXPECT_EQ(payload_serialized_size_, 0);
825 
826   EXPECT_EQ(obu_header_.obu_redundant_copy, false);
827   EXPECT_EQ(obu_header_.obu_trimming_status_flag, true);
828   EXPECT_EQ(obu_header_.obu_extension_flag, false);
829 
830   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 0);
831   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 0);
832   EXPECT_EQ(obu_header_.extension_header_size, 0);
833   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
834 }
835 
TEST_F(ObuHeaderTest,ReadAndValidateIllegalTrimmingStatusFlagIaSequenceHeader)836 TEST_F(ObuHeaderTest,
837        ReadAndValidateIllegalTrimmingStatusFlagIaSequenceHeader) {
838   std::vector<uint8_t> source_data = {
839       // `obu type`, `obu_redundant_copy`, `obu_trimming_status_flag`,
840       // `obu_extension_flag`
841       0b11111010,
842       // `obu_size`
843       2,
844       // `num_samples_to_trim_at_end`.
845       0x00,
846       // `num_samples_to_trim_at_start`.
847       0x00};
848   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
849       1024, absl::MakeConstSpan(source_data));
850   EXPECT_FALSE(
851       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_)
852           .ok());
853 }
854 
ValidateAudioFrameId0WithTrim(const ObuHeader & header)855 void ValidateAudioFrameId0WithTrim(const ObuHeader& header) {
856   EXPECT_EQ(header.obu_type, kObuIaAudioFrameId0);
857   EXPECT_EQ(header.obu_redundant_copy, false);
858   EXPECT_EQ(header.obu_trimming_status_flag, true);
859   EXPECT_EQ(header.obu_extension_flag, false);
860 }
861 
TEST_F(ObuHeaderTest,ReadAndValidateTrimmingStatusFlagNonZeroTrimAtEnd)862 TEST_F(ObuHeaderTest, ReadAndValidateTrimmingStatusFlagNonZeroTrimAtEnd) {
863   std::vector<uint8_t> source_data = {kAudioFrameId0WithTrim,
864                                       // `obu_size`
865                                       2,
866                                       // `num_samples_to_trim_at_end`.
867                                       0x01,
868                                       // `num_samples_to_trim_at_start`.
869                                       0x00};
870   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
871       1024, absl::MakeConstSpan(source_data));
872   EXPECT_THAT(
873       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
874       IsOk());
875 
876   // Validate all OBU Header fields.
877   ValidateAudioFrameId0WithTrim(obu_header_);
878   EXPECT_EQ(payload_serialized_size_, 0);
879   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 1);
880   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 0);
881   EXPECT_EQ(obu_header_.extension_header_size, 0);
882   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
883 }
884 
TEST_F(ObuHeaderTest,ReadAndValidateTrimmingStatusFlagNonZeroTrimAtStart)885 TEST_F(ObuHeaderTest, ReadAndValidateTrimmingStatusFlagNonZeroTrimAtStart) {
886   std::vector<uint8_t> source_data = {kAudioFrameId0WithTrim,
887                                       // `obu_size`
888                                       2,
889                                       // `num_samples_to_trim_at_end`.
890                                       0x00,
891                                       // `num_samples_to_trim_at_start`.
892                                       0x02};
893   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
894       1024, absl::MakeConstSpan(source_data));
895   EXPECT_THAT(
896       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
897       IsOk());
898 
899   // Validate all OBU Header fields.
900   ValidateAudioFrameId0WithTrim(obu_header_);
901   EXPECT_EQ(payload_serialized_size_, 0);
902   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 0);
903   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 2);
904   EXPECT_EQ(obu_header_.extension_header_size, 0);
905   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
906 }
907 
TEST_F(ObuHeaderTest,ReadAndValidateTrimmingStatusFlagNonZeroBothTrims)908 TEST_F(ObuHeaderTest, ReadAndValidateTrimmingStatusFlagNonZeroBothTrims) {
909   std::vector<uint8_t> source_data = {kAudioFrameId0WithTrim,
910                                       // `obu_size`
911                                       2,
912                                       // `num_samples_to_trim_at_end`.
913                                       0x01,
914                                       // `num_samples_to_trim_at_start`.
915                                       0x02};
916   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
917       1024, absl::MakeConstSpan(source_data));
918   EXPECT_THAT(
919       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
920       IsOk());
921 
922   // Validate all OBU Header fields.
923   ValidateAudioFrameId0WithTrim(obu_header_);
924   EXPECT_EQ(payload_serialized_size_, 0);
925   EXPECT_EQ(obu_header_.num_samples_to_trim_at_end, 1);
926   EXPECT_EQ(obu_header_.num_samples_to_trim_at_start, 2);
927   EXPECT_EQ(obu_header_.extension_header_size, 0);
928   EXPECT_TRUE(obu_header_.extension_header_bytes.empty());
929 }
930 
TEST_F(ObuHeaderTest,NegativePayloadSizeNotAcceptable)931 TEST_F(ObuHeaderTest, NegativePayloadSizeNotAcceptable) {
932   std::vector<uint8_t> source_data = {kAudioFrameId0WithTrim,
933                                       // `obu_size`
934                                       2,
935                                       // `num_samples_to_trim_at_end`.
936                                       0x80, 0x01,
937                                       // `num_samples_to_trim_at_start`.
938                                       0x02};
939   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
940       1024, absl::MakeConstSpan(source_data));
941   EXPECT_THAT(
942       obu_header_.ReadAndValidate(*read_bit_buffer, payload_serialized_size_),
943       Not(IsOk()));
944 }
945 
TEST(PeekObuTypeAndTotalObuSize,Success)946 TEST(PeekObuTypeAndTotalObuSize, Success) {
947   std::vector<uint8_t> source_data = {kAudioFrameId0WithTrim,
948                                       // `obu_size`
949                                       2};
950   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
951       1024, absl::MakeConstSpan(source_data));
952   auto start_position = read_bit_buffer->Tell();
953 
954   auto header_metadata =
955       ObuHeader::PeekObuTypeAndTotalObuSize(*read_bit_buffer);
956 
957   EXPECT_THAT(header_metadata, IsOk());
958   EXPECT_EQ(header_metadata->obu_type, kObuIaAudioFrameId0);
959   // obu_size + size_of(obu_size) + 1, 2 + 1 + 1 = 4.
960   EXPECT_EQ(header_metadata->total_obu_size, 4);
961   EXPECT_EQ(read_bit_buffer->Tell(), start_position);
962 }
963 
TEST(PeekObuTypeAndTotalObuSize,SuccessWithMaxSizedObuSize)964 TEST(PeekObuTypeAndTotalObuSize, SuccessWithMaxSizedObuSize) {
965   std::vector<uint8_t> source_data = {kAudioFrameId0WithTrim,
966                                       // `obu_size == 2 megabytes - 9`
967                                       0xf7, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80,
968                                       0x00};
969   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
970       1024, absl::MakeConstSpan(source_data));
971   auto start_position = read_bit_buffer->Tell();
972 
973   auto header_metadata =
974       ObuHeader::PeekObuTypeAndTotalObuSize(*read_bit_buffer);
975 
976   EXPECT_THAT(header_metadata, IsOk());
977   EXPECT_EQ(header_metadata->obu_type, kObuIaAudioFrameId0);
978   // obu_size + size_of(obu_size) + 1.
979   EXPECT_EQ(header_metadata->total_obu_size,
980             kMaxObuSizeIamfV1_1_0WithFixedSizeLebEight + 8 + 1);
981   EXPECT_EQ(read_bit_buffer->Tell(), start_position);
982 }
983 
TEST(PeekObuTypeAndTotalObuSize,EmptyBitBufferResourceExhausted)984 TEST(PeekObuTypeAndTotalObuSize, EmptyBitBufferResourceExhausted) {
985   std::vector<uint8_t> source_data = {};
986   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
987       1024, absl::MakeConstSpan(source_data));
988   auto start_position = read_bit_buffer->Tell();
989 
990   auto header_metadata =
991       ObuHeader::PeekObuTypeAndTotalObuSize(*read_bit_buffer);
992 
993   EXPECT_THAT(header_metadata, Not(IsOk()));
994   EXPECT_THAT(header_metadata, StatusIs(kResourceExhausted));
995   EXPECT_EQ(read_bit_buffer->Tell(), start_position);
996 }
997 
TEST(PeekObuTypeAndTotalObuSize,NoObuSizeResourceExhausted)998 TEST(PeekObuTypeAndTotalObuSize, NoObuSizeResourceExhausted) {
999   std::vector<uint8_t> source_data = {kObuIaAudioFrameId0};
1000   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
1001       1024, absl::MakeConstSpan(source_data));
1002   auto start_position = read_bit_buffer->Tell();
1003   auto header_metadata =
1004       ObuHeader::PeekObuTypeAndTotalObuSize(*read_bit_buffer);
1005   EXPECT_THAT(header_metadata, Not(IsOk()));
1006   EXPECT_THAT(header_metadata,
1007               absl_testing::StatusIs(absl::StatusCode::kResourceExhausted));
1008   EXPECT_EQ(read_bit_buffer->Tell(), start_position);
1009 }
1010 
TEST(PeekObuTypeAndTotalObuSize,ReturnsResourceExhaustedForPartialObuSize)1011 TEST(PeekObuTypeAndTotalObuSize, ReturnsResourceExhaustedForPartialObuSize) {
1012   std::vector<uint8_t> source_data = {kObuIaAudioFrameId0, 0x80};
1013   auto read_bit_buffer = MemoryBasedReadBitBuffer::CreateFromSpan(
1014       1024, absl::MakeConstSpan(source_data));
1015   auto start_position = read_bit_buffer->Tell();
1016 
1017   auto header_metadata =
1018       ObuHeader::PeekObuTypeAndTotalObuSize(*read_bit_buffer);
1019 
1020   EXPECT_THAT(header_metadata, Not(IsOk()));
1021   EXPECT_THAT(header_metadata,
1022               absl_testing::StatusIs(absl::StatusCode::kResourceExhausted));
1023   EXPECT_EQ(read_bit_buffer->Tell(), start_position);
1024 }
1025 
1026 }  // namespace
1027 }  // namespace iamf_tools
1028