#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "media/formats/mp4/box_definitions.h"
#include <bitset>
#include <memory>
#include <utility>
#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/containers/span_writer.h"
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
#include "media/base/media_switches.h"
#include "media/base/media_util.h"
#include "media/base/video_types.h"
#include "media/base/video_util.h"
#include "media/formats/common/opus_constants.h"
#include "media/formats/mp4/es_descriptor.h"
#include "media/formats/mp4/rcheck.h"
#include "media/media_buildflags.h"
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
#include <optional>
#include "media/formats/mp4/avc.h"
#include "media/formats/mp4/dolby_vision.h"
#include "media/parsers/h264_parser.h"
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
#include "media/formats/mp4/hevc.h"
#endif
#endif
namespace media {
namespace mp4 {
namespace {
const size_t kKeyIdSize = …;
const size_t kFlacMetadataBlockStreaminfoSize = …;
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
std::tuple<CodecProfileLevel, std::optional<CodecProfileLevel>> MaybeParseDOVI(
BoxReader* reader,
CodecProfileLevel video_info) {
std::optional<DOVIDecoderConfigurationRecord> dovi_config;
{
DolbyVisionConfiguration dvcc;
if (reader->HasChild(&dvcc) && reader->ReadChild(&dvcc)) {
DVLOG(2) << __func__ << " reading DolbyVisionConfiguration (dvcC)";
DCHECK_LE(dvcc.dovi_config.dv_profile, 7);
dovi_config = dvcc.dovi_config;
}
}
{
DolbyVisionConfiguration8 dvvc;
if (reader->HasChild(&dvvc) && reader->ReadChild(&dvvc)) {
DVLOG(2) << __func__ << " reading DolbyVisionConfiguration (dvvC)";
DCHECK_GT(dvvc.dovi_config.dv_profile, 7);
dovi_config = dvvc.dovi_config;
}
}
if (!dovi_config.has_value()) {
return {video_info, std::nullopt};
}
constexpr int kHDR10CompatibilityId = 1;
constexpr int kSDRCompatibilityId = 2;
constexpr int kHLGCompatibilityId = 4;
CodecProfileLevel dv_info = {VideoCodec::kDolbyVision,
dovi_config->codec_profile,
dovi_config->dv_level};
if (dovi_config->dv_bl_signal_compatibility_id == kHDR10CompatibilityId ||
dovi_config->dv_bl_signal_compatibility_id == kSDRCompatibilityId ||
dovi_config->dv_bl_signal_compatibility_id == kHLGCompatibilityId) {
return {video_info, dv_info};
}
return {dv_info, std::nullopt};
}
#endif
bool ReadMdcvColorCoordinate(BoxReader* reader,
float* normalized_value_in_float) { … }
bool ReadFixedPoint16(float fixed_point_divisor,
BoxReader* reader,
float* normalized_value_in_float) { … }
bool ReadFixedPoint32(float fixed_point_divisor,
BoxReader* reader,
float* normalized_value_in_float) { … }
gfx::HdrMetadataSmpteSt2086 ConvertMdcvToColorVolumeMetadata(
const MasteringDisplayColorVolume& mdcv) { … }
}
FileType::FileType() = default;
FileType::FileType(const FileType& other) = default;
FileType::~FileType() = default;
FourCC FileType::BoxType() const { … }
bool FileType::Parse(BoxReader* reader) { … }
ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() = default;
ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader(
const ProtectionSystemSpecificHeader& other) = default;
ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() = default;
FourCC ProtectionSystemSpecificHeader::BoxType() const { … }
bool ProtectionSystemSpecificHeader::Parse(BoxReader* reader) { … }
FullProtectionSystemSpecificHeader::FullProtectionSystemSpecificHeader() =
default;
FullProtectionSystemSpecificHeader::FullProtectionSystemSpecificHeader(
const FullProtectionSystemSpecificHeader& other) = default;
FullProtectionSystemSpecificHeader::~FullProtectionSystemSpecificHeader() =
default;
FourCC FullProtectionSystemSpecificHeader::BoxType() const { … }
bool FullProtectionSystemSpecificHeader::Parse(mp4::BoxReader* reader) { … }
SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() = default;
SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset(
const SampleAuxiliaryInformationOffset& other) = default;
SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() = default;
FourCC SampleAuxiliaryInformationOffset::BoxType() const { … }
bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) { … }
SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
: … { … }
SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize(
const SampleAuxiliaryInformationSize& other) = default;
SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() = default;
FourCC SampleAuxiliaryInformationSize::BoxType() const { … }
bool SampleAuxiliaryInformationSize::Parse(BoxReader* reader) { … }
SampleEncryptionEntry::SampleEncryptionEntry() = default;
SampleEncryptionEntry::SampleEncryptionEntry(
const SampleEncryptionEntry& other) = default;
SampleEncryptionEntry::~SampleEncryptionEntry() = default;
bool SampleEncryptionEntry::Parse(BufferReader* reader,
uint8_t iv_size,
bool has_subsamples) { … }
bool SampleEncryptionEntry::GetTotalSizeOfSubsamples(size_t* total_size) const { … }
SampleEncryption::SampleEncryption() : … { … }
SampleEncryption::SampleEncryption(const SampleEncryption& other) = default;
SampleEncryption::~SampleEncryption() = default;
FourCC SampleEncryption::BoxType() const { … }
bool SampleEncryption::Parse(BoxReader* reader) { … }
OriginalFormat::OriginalFormat() : … { … }
OriginalFormat::OriginalFormat(const OriginalFormat& other) = default;
OriginalFormat::~OriginalFormat() = default;
FourCC OriginalFormat::BoxType() const { … }
bool OriginalFormat::Parse(BoxReader* reader) { … }
SchemeType::SchemeType() : … { … }
SchemeType::SchemeType(const SchemeType& other) = default;
SchemeType::~SchemeType() = default;
FourCC SchemeType::BoxType() const { … }
bool SchemeType::Parse(BoxReader* reader) { … }
TrackEncryption::TrackEncryption()
: … { … }
TrackEncryption::TrackEncryption(const TrackEncryption& other) = default;
TrackEncryption::~TrackEncryption() = default;
FourCC TrackEncryption::BoxType() const { … }
bool TrackEncryption::Parse(BoxReader* reader) { … }
SchemeInfo::SchemeInfo() = default;
SchemeInfo::SchemeInfo(const SchemeInfo& other) = default;
SchemeInfo::~SchemeInfo() = default;
FourCC SchemeInfo::BoxType() const { … }
bool SchemeInfo::Parse(BoxReader* reader) { … }
ProtectionSchemeInfo::ProtectionSchemeInfo() = default;
ProtectionSchemeInfo::ProtectionSchemeInfo(const ProtectionSchemeInfo& other) =
default;
ProtectionSchemeInfo::~ProtectionSchemeInfo() = default;
FourCC ProtectionSchemeInfo::BoxType() const { … }
bool ProtectionSchemeInfo::Parse(BoxReader* reader) { … }
bool ProtectionSchemeInfo::HasSupportedScheme() const { … }
bool ProtectionSchemeInfo::IsCbcsEncryptionScheme() const { … }
MovieHeader::MovieHeader()
: … { … }
MovieHeader::MovieHeader(const MovieHeader& other) = default;
MovieHeader::~MovieHeader() = default;
FourCC MovieHeader::BoxType() const { … }
bool MovieHeader::Parse(BoxReader* reader) { … }
TrackHeader::TrackHeader()
: … { … }
TrackHeader::TrackHeader(const TrackHeader& other) = default;
TrackHeader::~TrackHeader() = default;
FourCC TrackHeader::BoxType() const { … }
bool TrackHeader::Parse(BoxReader* reader) { … }
SampleDescription::SampleDescription() : … { … }
SampleDescription::SampleDescription(const SampleDescription& other) = default;
SampleDescription::~SampleDescription() = default;
FourCC SampleDescription::BoxType() const { … }
bool SampleDescription::Parse(BoxReader* reader) { … }
SampleTable::SampleTable() = default;
SampleTable::SampleTable(const SampleTable& other) = default;
SampleTable::~SampleTable() = default;
FourCC SampleTable::BoxType() const { … }
bool SampleTable::Parse(BoxReader* reader) { … }
EditList::EditList() = default;
EditList::EditList(const EditList& other) = default;
EditList::~EditList() = default;
FourCC EditList::BoxType() const { … }
bool EditList::Parse(BoxReader* reader) { … }
Edit::Edit() = default;
Edit::Edit(const Edit& other) = default;
Edit::~Edit() = default;
FourCC Edit::BoxType() const { … }
bool Edit::Parse(BoxReader* reader) { … }
HandlerReference::HandlerReference() : … { … }
HandlerReference::HandlerReference(const HandlerReference& other) = default;
HandlerReference::~HandlerReference() = default;
FourCC HandlerReference::BoxType() const { … }
bool HandlerReference::Parse(BoxReader* reader) { … }
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord()
: version(0),
profile_indication(0),
profile_compatibility(0),
avc_level(0),
length_size(0) {}
AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord(
const AVCDecoderConfigurationRecord& other) = default;
AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() = default;
FourCC AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC; }
bool AVCDecoderConfigurationRecord::Parse(BoxReader* reader) {
return ParseInternal(reader, reader->media_log());
}
bool AVCDecoderConfigurationRecord::Parse(const uint8_t* data, int data_size) {
BufferReader reader(data, data_size);
NullMediaLog media_log;
return ParseInternal(&reader, &media_log);
}
bool AVCDecoderConfigurationRecord::ParseInternal(BufferReader* reader,
MediaLog* media_log) {
RCHECK(reader->Read1(&version) && version == 1 &&
reader->Read1(&profile_indication) &&
reader->Read1(&profile_compatibility) &&
reader->Read1(&avc_level));
uint8_t length_size_minus_one;
RCHECK(reader->Read1(&length_size_minus_one));
length_size = (length_size_minus_one & 0x3) + 1;
RCHECK(length_size != 3);
uint8_t num_sps;
RCHECK(reader->Read1(&num_sps));
num_sps &= 0x1f;
sps_list.resize(num_sps);
for (int i = 0; i < num_sps; i++) {
uint16_t sps_length;
RCHECK(reader->Read2(&sps_length) &&
reader->ReadVec(&sps_list[i], sps_length));
RCHECK(sps_list[i].size() > 4);
}
uint8_t num_pps;
RCHECK(reader->Read1(&num_pps));
pps_list.resize(num_pps);
for (int i = 0; i < num_pps; i++) {
uint16_t pps_length;
RCHECK(reader->Read2(&pps_length) &&
reader->ReadVec(&pps_list[i], pps_length));
}
if (profile_indication == 100 || profile_indication == 110 ||
profile_indication == 122 || profile_indication == 144) {
if (!ParseREXT(reader, media_log)) {
DVLOG(2) << __func__ << ": avcC REXT is missing or invalid";
chroma_format = 0;
bit_depth_luma_minus8 = 0;
bit_depth_chroma_minus8 = 0;
sps_ext_list.resize(0);
}
}
return true;
}
bool AVCDecoderConfigurationRecord::ParseREXT(BufferReader* reader,
MediaLog* media_log) {
RCHECK(reader->Read1(&chroma_format));
chroma_format &= 0x3;
RCHECK(reader->Read1(&bit_depth_luma_minus8));
bit_depth_luma_minus8 &= 0x7;
RCHECK(bit_depth_luma_minus8 <= 4);
RCHECK(reader->Read1(&bit_depth_chroma_minus8));
bit_depth_chroma_minus8 &= 0x7;
RCHECK(bit_depth_chroma_minus8 <= 4);
uint8_t num_sps_ext;
RCHECK(reader->Read1(&num_sps_ext));
sps_ext_list.resize(num_sps_ext);
for (int i = 0; i < num_sps_ext; i++) {
uint16_t sps_ext_length;
RCHECK(reader->Read2(&sps_ext_length) &&
reader->ReadVec(&sps_ext_list[i], sps_ext_length));
}
return true;
}
bool AVCDecoderConfigurationRecord::Serialize(
std::vector<uint8_t>& output) const {
if (sps_list.size() > 0x1f) {
return false;
}
if (pps_list.size() > 0xff) {
return false;
}
if (length_size != 1 && length_size != 2 && length_size != 4) {
return false;
}
size_t expected_size =
1 +
1 +
1 +
1 +
1 +
1 +
1;
for (auto& sps : sps_list) {
expected_size += 2;
if (sps.size() > 0xffff) {
return false;
}
expected_size += sps.size();
}
for (auto& pps : pps_list) {
expected_size += 2;
if (pps.size() > 0xffff) {
return false;
}
expected_size += pps.size();
}
if (profile_indication == 100 || profile_indication == 110 ||
profile_indication == 122 || profile_indication == 144) {
if (chroma_format > 0x3) {
return false;
}
if (bit_depth_luma_minus8 > 4) {
return false;
}
if (bit_depth_chroma_minus8 > 4) {
return false;
}
if (sps_ext_list.size() > 0xff) {
return false;
}
expected_size += 1 +
1 +
1 +
1;
for (auto& sps_ext : sps_ext_list) {
expected_size += 2;
if (sps_ext.size() > 0xffff) {
return false;
}
expected_size += sps_ext.size();
}
}
output.clear();
output.resize(expected_size);
auto writer = base::SpanWriter(base::span(output));
bool result = true;
result &= writer.WriteU8BigEndian(version);
result &= writer.WriteU8BigEndian(profile_indication);
result &= writer.WriteU8BigEndian(profile_compatibility);
result &= writer.WriteU8BigEndian(avc_level);
uint8_t length_size_minus_one = (length_size - 1) | 0xfc;
result &= writer.WriteU8BigEndian(length_size_minus_one);
uint8_t sps_size = sps_list.size() | 0xe0;
result &= writer.WriteU8BigEndian(sps_size);
for (auto& sps : sps_list) {
result &= writer.WriteU16BigEndian(sps.size());
result &= writer.Write(sps);
}
uint8_t pps_size = pps_list.size();
result &= writer.WriteU8BigEndian(pps_size);
for (auto& pps : pps_list) {
result &= writer.WriteU16BigEndian(pps.size());
result &= writer.Write(pps);
}
if (profile_indication == 100 || profile_indication == 110 ||
profile_indication == 122 || profile_indication == 144) {
result &= writer.WriteU8BigEndian(chroma_format | 0xfc);
result &= writer.WriteU8BigEndian(bit_depth_luma_minus8 | 0xf8);
result &= writer.WriteU8BigEndian(bit_depth_chroma_minus8 | 0xf8);
uint8_t sps_ext_size = sps_ext_list.size();
result &= writer.WriteU8BigEndian(sps_ext_size);
for (auto& sps_ext : sps_ext_list) {
result &= writer.WriteU16BigEndian(sps_ext.size());
result &= writer.Write(sps_ext);
}
}
return result;
}
#endif
VPCodecConfigurationRecord::VPCodecConfigurationRecord()
: … { … }
VPCodecConfigurationRecord::VPCodecConfigurationRecord(
const VPCodecConfigurationRecord& other) = default;
VPCodecConfigurationRecord::~VPCodecConfigurationRecord() = default;
FourCC VPCodecConfigurationRecord::BoxType() const { … }
bool VPCodecConfigurationRecord::Parse(BoxReader* reader) { … }
#if BUILDFLAG(ENABLE_AV1_DECODER)
AV1CodecConfigurationRecord::AV1CodecConfigurationRecord() = default;
AV1CodecConfigurationRecord::AV1CodecConfigurationRecord(
const AV1CodecConfigurationRecord& other) = default;
AV1CodecConfigurationRecord::~AV1CodecConfigurationRecord() = default;
FourCC AV1CodecConfigurationRecord::BoxType() const { … }
bool AV1CodecConfigurationRecord::Parse(BoxReader* reader) { … }
bool AV1CodecConfigurationRecord::Parse(const uint8_t* data, int data_size) { … }
bool AV1CodecConfigurationRecord::ParseInternal(BufferReader* reader,
MediaLog* media_log) { … }
#endif
PixelAspectRatioBox::PixelAspectRatioBox() : … { … }
PixelAspectRatioBox::PixelAspectRatioBox(const PixelAspectRatioBox& other) =
default;
PixelAspectRatioBox::~PixelAspectRatioBox() = default;
FourCC PixelAspectRatioBox::BoxType() const { … }
bool PixelAspectRatioBox::Parse(BoxReader* reader) { … }
ColorParameterInformation::ColorParameterInformation() = default;
ColorParameterInformation::ColorParameterInformation(
const ColorParameterInformation& other) = default;
ColorParameterInformation::~ColorParameterInformation() = default;
FourCC ColorParameterInformation::BoxType() const { … }
bool ColorParameterInformation::Parse(BoxReader* reader) { … }
MasteringDisplayColorVolume::MasteringDisplayColorVolume() = default;
MasteringDisplayColorVolume::MasteringDisplayColorVolume(
const MasteringDisplayColorVolume& other) = default;
MasteringDisplayColorVolume::~MasteringDisplayColorVolume() = default;
FourCC MasteringDisplayColorVolume::BoxType() const { … }
bool MasteringDisplayColorVolume::Parse(BoxReader* reader) { … }
FourCC SMPTE2086MasteringDisplayMetadataBox::BoxType() const { … }
bool SMPTE2086MasteringDisplayMetadataBox::Parse(BoxReader* reader) { … }
ContentLightLevelInformation::ContentLightLevelInformation() = default;
ContentLightLevelInformation::ContentLightLevelInformation(
const ContentLightLevelInformation& other) = default;
ContentLightLevelInformation::~ContentLightLevelInformation() = default;
FourCC ContentLightLevelInformation::BoxType() const { … }
bool ContentLightLevelInformation::Parse(BoxReader* reader) { … }
bool ContentLightLevel::Parse(BoxReader* reader) { … }
FourCC ContentLightLevel::BoxType() const { … }
VideoSampleEntry::VideoSampleEntry()
: … { … }
VideoSampleEntry::VideoSampleEntry(const VideoSampleEntry& other) = default;
VideoSampleEntry::~VideoSampleEntry() = default;
FourCC VideoSampleEntry::BoxType() const { … }
VideoColorSpace VideoSampleEntry::ConvertColorParameterInformationToColorSpace(
const ColorParameterInformation& info) { … }
bool VideoSampleEntry::Parse(BoxReader* reader) { … }
bool VideoSampleEntry::IsFormatValid() const { … }
ElementaryStreamDescriptor::ElementaryStreamDescriptor()
: … { … }
ElementaryStreamDescriptor::ElementaryStreamDescriptor(
const ElementaryStreamDescriptor& other) = default;
ElementaryStreamDescriptor::~ElementaryStreamDescriptor() = default;
FourCC ElementaryStreamDescriptor::BoxType() const { … }
bool ElementaryStreamDescriptor::Parse(BoxReader* reader) { … }
FlacSpecificBox::FlacSpecificBox()
: … { … }
FlacSpecificBox::FlacSpecificBox(const FlacSpecificBox& other) = default;
FlacSpecificBox::~FlacSpecificBox() = default;
FourCC FlacSpecificBox::BoxType() const { … }
bool FlacSpecificBox::Parse(BoxReader* reader) { … }
OpusSpecificBox::OpusSpecificBox()
: … { … }
OpusSpecificBox::OpusSpecificBox(const OpusSpecificBox& other) = default;
OpusSpecificBox::~OpusSpecificBox() = default;
FourCC OpusSpecificBox::BoxType() const { … }
bool OpusSpecificBox::Parse(BoxReader* reader) { … }
#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
DtsSpecificBox::DtsSpecificBox() {}
DtsSpecificBox::DtsSpecificBox(const DtsSpecificBox& other) = default;
DtsSpecificBox::~DtsSpecificBox() = default;
FourCC DtsSpecificBox::BoxType() const {
return FOURCC_DDTS;
}
bool DtsSpecificBox::Parse(BoxReader* reader) {
std::vector<uint8_t> dts_data;
RCHECK(reader->ReadVec(&dts_data, reader->box_size() - reader->pos()));
RCHECK(dts.Parse(dts_data, reader->media_log()));
return true;
}
DtsUhdSpecificBox::DtsUhdSpecificBox() {}
DtsUhdSpecificBox::DtsUhdSpecificBox(const DtsUhdSpecificBox& other) = default;
DtsUhdSpecificBox::~DtsUhdSpecificBox() = default;
FourCC DtsUhdSpecificBox::BoxType() const {
return FOURCC_UDTS;
}
bool DtsUhdSpecificBox::Parse(BoxReader* reader) {
std::vector<uint8_t> dtsx_data;
RCHECK(reader->ReadVec(&dtsx_data, reader->box_size() - reader->pos()));
RCHECK(dtsx.Parse(dtsx_data, reader->media_log()));
return true;
}
#endif
#if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
EC3SpecificBox::EC3SpecificBox() {}
EC3SpecificBox::EC3SpecificBox(const EC3SpecificBox& other) = default;
EC3SpecificBox::~EC3SpecificBox() = default;
FourCC EC3SpecificBox::BoxType() const {
return FOURCC_DEC3;
}
bool EC3SpecificBox::Parse(BoxReader* reader) {
std::vector<uint8_t> eac3_data;
RCHECK(reader->ReadVec(&eac3_data, reader->box_size() - reader->pos()));
RCHECK(dec3.Parse(eac3_data, reader->media_log()));
return true;
}
AC3SpecificBox::AC3SpecificBox() {}
AC3SpecificBox::AC3SpecificBox(const AC3SpecificBox& other) = default;
AC3SpecificBox::~AC3SpecificBox() = default;
FourCC AC3SpecificBox::BoxType() const {
return FOURCC_DAC3;
}
bool AC3SpecificBox::Parse(BoxReader* reader) {
std::vector<uint8_t> ac3_data;
RCHECK(reader->ReadVec(&ac3_data, reader->box_size() - reader->pos()));
RCHECK(dac3.Parse(ac3_data, reader->media_log()));
return true;
}
#endif
#if BUILDFLAG(ENABLE_PLATFORM_AC4_AUDIO)
AC4SpecificBox::AC4SpecificBox() {}
AC4SpecificBox::AC4SpecificBox(const AC4SpecificBox& other) = default;
AC4SpecificBox::~AC4SpecificBox() = default;
FourCC AC4SpecificBox::BoxType() const {
return FOURCC_DAC4;
}
bool AC4SpecificBox::Parse(BoxReader* reader) {
std::vector<uint8_t> ac4_data;
RCHECK(reader->ReadVec(&ac4_data, reader->box_size() - reader->pos()));
RCHECK(dac4.Parse(ac4_data, reader->media_log()));
return true;
}
#endif
#if BUILDFLAG(ENABLE_PLATFORM_IAMF_AUDIO)
enum IamfConfigObuType {
kIamfConfigObuTypeCodecConfig = 0,
kIamfConfigObuTypeAudioElement = 1,
kIamfConfigObuTypeMixPresentation = 2,
kIamfConfigObuTypeSequenceHeader = 31,
};
IamfSpecificBox::IamfSpecificBox() = default;
IamfSpecificBox::IamfSpecificBox(const IamfSpecificBox& other) = default;
IamfSpecificBox::~IamfSpecificBox() = default;
FourCC IamfSpecificBox::BoxType() const {
return FOURCC_IACB;
}
bool IamfSpecificBox::Parse(BoxReader* reader) {
uint8_t configuration_version;
RCHECK(reader->Read1(&configuration_version));
RCHECK(configuration_version == 0x01);
uint32_t config_obus_size;
RCHECK(ReadLeb128Value(reader, &config_obus_size));
base::span<const uint8_t> buffer =
reader->buffer().subspan(reader->pos(), config_obus_size);
ia_descriptors.assign(buffer.begin(), buffer.end());
RCHECK(reader->SkipBytes(config_obus_size));
BufferReader config_reader(ia_descriptors.data(), ia_descriptors.size());
while (config_reader.pos() < config_reader.buffer().size()) {
RCHECK(ReadOBU(&config_reader));
}
return true;
}
bool IamfSpecificBox::ReadOBU(BufferReader* reader) {
uint8_t obu_type;
uint32_t obu_size;
RCHECK(ReadOBUHeader(reader, &obu_type, &obu_size));
const size_t read_stop_pos = reader->pos() + obu_size;
switch (static_cast<int>(obu_type)) {
case kIamfConfigObuTypeCodecConfig:
case kIamfConfigObuTypeAudioElement:
case kIamfConfigObuTypeMixPresentation:
break;
case kIamfConfigObuTypeSequenceHeader:
uint32_t ia_code;
RCHECK(reader->Read4(&ia_code));
RCHECK(ia_code == FOURCC_IAMF);
RCHECK(reader->Read1(&profile));
RCHECK(profile <= 1);
break;
default:
DVLOG(1) << "Unhandled IAMF OBU type " << static_cast<int>(obu_type);
return false;
}
const size_t remaining_size = read_stop_pos - reader->pos();
RCHECK(reader->SkipBytes(remaining_size));
return true;
}
bool IamfSpecificBox::ReadOBUHeader(BufferReader* reader,
uint8_t* obu_type,
uint32_t* obu_size) {
uint8_t header_flags;
RCHECK(reader->Read1(&header_flags));
*obu_type = (header_flags >> 3) & 0x1f;
const bool obu_redundant_copy = (header_flags >> 2) & 1;
const bool obu_trimming_status_flag = (header_flags >> 1) & 1;
const bool obu_extension_flag = header_flags & 1;
redundant_copy |= obu_redundant_copy;
RCHECK(ReadLeb128Value(reader, obu_size));
RCHECK(reader->HasBytes(*obu_size));
RCHECK(!obu_trimming_status_flag);
if (obu_extension_flag) {
uint32_t extension_header_size;
const int last_reader_pos = reader->pos();
RCHECK(ReadLeb128Value(reader, &extension_header_size));
const int num_leb128_bytes_read = reader->pos() - last_reader_pos;
RCHECK(reader->SkipBytes(extension_header_size));
obu_size -= (num_leb128_bytes_read + extension_header_size);
}
return true;
}
bool IamfSpecificBox::ReadLeb128Value(BufferReader* reader,
uint32_t* value) const {
DCHECK(reader);
DCHECK(value);
*value = 0;
bool error = true;
for (size_t i = 0; i < sizeof(uint32_t); ++i) {
uint8_t byte;
RCHECK(reader->Read1(&byte));
*value |= ((byte & 0x7f) << (i * 7));
if (!(byte & 0x80)) {
error = false;
break;
}
}
return !error;
}
#endif
AudioSampleEntry::AudioSampleEntry()
: … { … }
AudioSampleEntry::AudioSampleEntry(const AudioSampleEntry& other) = default;
AudioSampleEntry::~AudioSampleEntry() = default;
FourCC AudioSampleEntry::BoxType() const { … }
bool AudioSampleEntry::Parse(BoxReader* reader) { … }
MediaHeader::MediaHeader()
: … { … }
MediaHeader::MediaHeader(const MediaHeader& other) = default;
MediaHeader::~MediaHeader() = default;
FourCC MediaHeader::BoxType() const { … }
bool MediaHeader::Parse(BoxReader* reader) { … }
std::string MediaHeader::language() const { … }
MediaInformation::MediaInformation() = default;
MediaInformation::MediaInformation(const MediaInformation& other) = default;
MediaInformation::~MediaInformation() = default;
FourCC MediaInformation::BoxType() const { … }
bool MediaInformation::Parse(BoxReader* reader) { … }
Media::Media() = default;
Media::Media(const Media& other) = default;
Media::~Media() = default;
FourCC Media::BoxType() const { … }
bool Media::Parse(BoxReader* reader) { … }
Track::Track() = default;
Track::Track(const Track& other) = default;
Track::~Track() = default;
FourCC Track::BoxType() const { … }
bool Track::Parse(BoxReader* reader) { … }
MovieExtendsHeader::MovieExtendsHeader() : … { … }
MovieExtendsHeader::MovieExtendsHeader(const MovieExtendsHeader& other) =
default;
MovieExtendsHeader::~MovieExtendsHeader() = default;
FourCC MovieExtendsHeader::BoxType() const { … }
bool MovieExtendsHeader::Parse(BoxReader* reader) { … }
TrackExtends::TrackExtends()
: … { … }
TrackExtends::TrackExtends(const TrackExtends& other) = default;
TrackExtends::~TrackExtends() = default;
FourCC TrackExtends::BoxType() const { … }
bool TrackExtends::Parse(BoxReader* reader) { … }
MovieExtends::MovieExtends() = default;
MovieExtends::MovieExtends(const MovieExtends& other) = default;
MovieExtends::~MovieExtends() = default;
FourCC MovieExtends::BoxType() const { … }
bool MovieExtends::Parse(BoxReader* reader) { … }
Movie::Movie() : … { … }
Movie::Movie(const Movie& other) = default;
Movie::~Movie() = default;
FourCC Movie::BoxType() const { … }
bool Movie::Parse(BoxReader* reader) { … }
TrackFragmentDecodeTime::TrackFragmentDecodeTime() : … { … }
TrackFragmentDecodeTime::TrackFragmentDecodeTime(
const TrackFragmentDecodeTime& other) = default;
TrackFragmentDecodeTime::~TrackFragmentDecodeTime() = default;
FourCC TrackFragmentDecodeTime::BoxType() const { … }
bool TrackFragmentDecodeTime::Parse(BoxReader* reader) { … }
MovieFragmentHeader::MovieFragmentHeader() : … { … }
MovieFragmentHeader::MovieFragmentHeader(const MovieFragmentHeader& other) =
default;
MovieFragmentHeader::~MovieFragmentHeader() = default;
FourCC MovieFragmentHeader::BoxType() const { … }
bool MovieFragmentHeader::Parse(BoxReader* reader) { … }
TrackFragmentHeader::TrackFragmentHeader()
: … { … }
TrackFragmentHeader::TrackFragmentHeader(const TrackFragmentHeader& other) =
default;
TrackFragmentHeader::~TrackFragmentHeader() = default;
FourCC TrackFragmentHeader::BoxType() const { … }
bool TrackFragmentHeader::Parse(BoxReader* reader) { … }
TrackFragmentRun::TrackFragmentRun()
: … { … }
TrackFragmentRun::TrackFragmentRun(const TrackFragmentRun& other) = default;
TrackFragmentRun::~TrackFragmentRun() = default;
FourCC TrackFragmentRun::BoxType() const { … }
bool TrackFragmentRun::Parse(BoxReader* reader) { … }
SampleToGroup::SampleToGroup() : … { … }
SampleToGroup::SampleToGroup(const SampleToGroup& other) = default;
SampleToGroup::~SampleToGroup() = default;
FourCC SampleToGroup::BoxType() const { … }
bool SampleToGroup::Parse(BoxReader* reader) { … }
CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
: … { … }
CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry(
const CencSampleEncryptionInfoEntry& other) = default;
CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() = default;
bool CencSampleEncryptionInfoEntry::Parse(BoxReader* reader) { … }
SampleGroupDescription::SampleGroupDescription() : … { … }
SampleGroupDescription::SampleGroupDescription(
const SampleGroupDescription& other) = default;
SampleGroupDescription::~SampleGroupDescription() = default;
FourCC SampleGroupDescription::BoxType() const { … }
bool SampleGroupDescription::Parse(BoxReader* reader) { … }
TrackFragment::TrackFragment() = default;
TrackFragment::TrackFragment(const TrackFragment& other) = default;
TrackFragment::~TrackFragment() = default;
FourCC TrackFragment::BoxType() const { … }
bool TrackFragment::Parse(BoxReader* reader) { … }
MovieFragment::MovieFragment() = default;
MovieFragment::MovieFragment(const MovieFragment& other) = default;
MovieFragment::~MovieFragment() = default;
FourCC MovieFragment::BoxType() const { … }
bool MovieFragment::Parse(BoxReader* reader) { … }
IndependentAndDisposableSamples::IndependentAndDisposableSamples() = default;
IndependentAndDisposableSamples::IndependentAndDisposableSamples(
const IndependentAndDisposableSamples& other) = default;
IndependentAndDisposableSamples::~IndependentAndDisposableSamples() = default;
FourCC IndependentAndDisposableSamples::BoxType() const { … }
bool IndependentAndDisposableSamples::Parse(BoxReader* reader) { … }
SampleDependsOn IndependentAndDisposableSamples::sample_depends_on(
size_t i) const { … }
}
}