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