7#include <packager/media/codecs/iamf_audio_util.h>
15#include <absl/log/log.h>
17#include <packager/media/base/bit_reader.h>
18#include <packager/media/base/fourccs.h>
19#include <packager/media/base/rcheck.h>
20#include <packager/media/base/stream_info.h>
27const uint8_t kMaxIamfProfile = 2;
33 OBU_IA_Codec_Config = 0,
34 OBU_IA_Sequence_Header = 31,
39bool ReadLeb128(BitReader& reader,
size_t* size,
size_t* leb128_bytes) {
41 size_t bytes_read = 0;
42 for (
int i = 0; i < 8; i++) {
43 size_t leb128_byte = 0;
44 RCHECK(reader.ReadBits(8, &leb128_byte));
45 value |= (leb128_byte & 0x7f) << (i * 7);
47 if (!(leb128_byte & 0x80))
52 RCHECK(value <= ((1ull << 32) - 1));
53 if (size !=
nullptr) {
56 if (leb128_bytes !=
nullptr) {
57 *leb128_bytes = bytes_read;
62bool ParseObuHeader(BitReader& reader,
int& obu_type,
size_t& obu_size) {
64 bool obu_trimming_status_flag;
65 bool obu_extension_flag;
67 RCHECK(reader.ReadBits(5, &obu_type));
68 RCHECK(reader.SkipBits(1));
69 RCHECK(reader.ReadBits(1, &obu_trimming_status_flag));
70 RCHECK(reader.ReadBits(1, &obu_extension_flag));
72 RCHECK(ReadLeb128(reader, &obu_size, &leb128_bytes));
74 if (obu_trimming_status_flag) {
76 RCHECK(ReadLeb128(reader,
nullptr, &leb128_bytes));
77 obu_size -= leb128_bytes;
79 RCHECK(ReadLeb128(reader,
nullptr, &leb128_bytes));
80 obu_size -= leb128_bytes;
83 if (obu_extension_flag) {
84 size_t extension_header_size;
85 RCHECK(ReadLeb128(reader, &extension_header_size, &leb128_bytes));
86 obu_size -= leb128_bytes;
87 RCHECK(reader.SkipBits(extension_header_size * 8));
88 obu_size -= extension_header_size * 8;
94bool ParseSequenceHeaderObu(BitReader& reader,
95 uint8_t& primary_profile,
96 uint8_t& additional_profile) {
99 RCHECK(reader.ReadBits(32, &ia_code));
100 if (ia_code != FOURCC_iamf) {
101 LOG(WARNING) <<
"Unknown ia_code= " << std::setfill(
'0') << std::setw(8)
102 << std::hex << ia_code;
106 RCHECK(reader.ReadBits(8, &primary_profile));
107 if (primary_profile > kMaxIamfProfile) {
108 LOG(WARNING) <<
"Unknown primary_profile= " << primary_profile;
112 RCHECK(reader.ReadBits(8, &additional_profile));
113 if (additional_profile > kMaxIamfProfile) {
114 LOG(WARNING) <<
"Unknown additional_profile= " << additional_profile;
121bool ParseCodecConfigObu(BitReader& reader,
size_t obu_size, Codec& codec) {
126 RCHECK(ReadLeb128(reader,
nullptr, &leb128_bytes));
127 obu_size -= leb128_bytes;
129 RCHECK(reader.ReadBits(32, &codec_id));
133 RCHECK(reader.SkipBits(obu_size * 8));
149 LOG(WARNING) <<
"Unknown codec_id= " << std::setfill(
'0') << std::setw(8)
150 << std::hex << codec_id;
158bool GetIamfCodecStringInfo(
const std::vector<uint8_t>& iacb,
159 uint8_t& codec_string_info) {
160 uint8_t primary_profile = 0;
161 uint8_t additional_profile = 0;
163 Codec iamf_codec = Codec::kUnknownCodec;
168 BitReader reader(iacb.data(), iacb.size());
171 RCHECK(reader.SkipBits(8));
174 RCHECK(ReadLeb128(reader, &obu_size,
nullptr));
176 while (reader.bits_available() > 0) {
177 RCHECK(ParseObuHeader(reader, obu_type, obu_size));
180 case OBU_IA_Sequence_Header:
181 RCHECK(ParseSequenceHeaderObu(reader, primary_profile,
182 additional_profile));
184 case OBU_IA_Codec_Config:
185 RCHECK(ParseCodecConfigObu(reader, obu_size, iamf_codec));
189 RCHECK(reader.SkipBits(obu_size * 8));
210 ((primary_profile << 6) | ((additional_profile << 4) & 0x3F) |
211 ((iamf_codec - kCodecAudio) & 0xF));
All the methods that are virtual are virtual for mocking.