/***************************************************************** | | AP4 - Sample Description Objects | | Copyright 2002-2008 Axiomatic Systems, LLC | | | This file is part of Bento4/AP4 (MP4 Atom Processing Library). | | Unless you have obtained Bento4 under a difference license, | this version of Bento4 is Bento4|GPL. | Bento4|GPL is free software; you can redistribute it and/or modify | it under the terms of the GNU General Public License as published by | the Free Software Foundation; either version 2, or (at your option) | any later version. | | Bento4|GPL is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU General Public License | along with Bento4|GPL; see the file COPYING. If not, write to the | Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA | 02111-1307, USA. | ****************************************************************/ /*---------------------------------------------------------------------- | includes +---------------------------------------------------------------------*/ #include "Ap4SampleDescription.h" #include "Ap4EsDescriptor.h" #include "Ap4SLConfigDescriptor.h" #include "Ap4SampleEntry.h" #include "Ap4AvccAtom.h" #include "Ap4HvccAtom.h" #include "Ap4VpccAtom.h" #include "Ap4Av1cAtom.h" #include "Ap4Utils.h" #include "Ap4Mp4AudioInfo.h" /*---------------------------------------------------------------------- | dynamic cast support +---------------------------------------------------------------------*/ AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_SampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_UnknownSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_AudioSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_VideoSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_GenericAudioSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_GenericVideoSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MpegSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MpegAudioSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MpegVideoSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_MpegSystemSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_AvcSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_HevcSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_Av1SampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_SubtitleSampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_Ac3SampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_Eac3SampleDescription) AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_Ac4SampleDescription) /*---------------------------------------------------------------------- | AP4_GetFormatName +---------------------------------------------------------------------*/ const char* AP4_GetFormatName(AP4_UI32 format) { switch (format) { case AP4_SAMPLE_FORMAT_MP4A: return "MPEG-4 Audio"; case AP4_SAMPLE_FORMAT_MP4V: return "MPEG-4 Video"; case AP4_SAMPLE_FORMAT_MP4S: return "MPEG-4 Systems"; case AP4_SAMPLE_FORMAT_ALAC: return "Apple Lossless Audio"; case AP4_SAMPLE_FORMAT_AVC1: return "H.264"; case AP4_SAMPLE_FORMAT_AVC2: return "H.264"; case AP4_SAMPLE_FORMAT_AVC3: return "H.264"; case AP4_SAMPLE_FORMAT_AVC4: return "H.264"; case AP4_SAMPLE_FORMAT_DVAV: return "Dolby Vision (H.264)"; case AP4_SAMPLE_FORMAT_DVA1: return "Dolby Vision (H.264)"; case AP4_SAMPLE_FORMAT_HEV1: return "H.265"; case AP4_SAMPLE_FORMAT_HVC1: return "H.265"; case AP4_SAMPLE_FORMAT_DVH1: return "Dolby Vision (H.265)"; case AP4_SAMPLE_FORMAT_DVHE: return "Dolby Vision (H.265)"; case AP4_SAMPLE_FORMAT_AV01: return "AV1"; case AP4_SAMPLE_FORMAT_OVC1: return "VC-1"; case AP4_SAMPLE_FORMAT_OWMA: return "WMA"; case AP4_SAMPLE_FORMAT_AC_3: return "Dolby Digital (AC-3)"; case AP4_SAMPLE_FORMAT_EC_3: return "Dolby Digital Plus (Enhanced AC-3)"; case AP4_SAMPLE_FORMAT_AC_4: return "Dolby AC-4"; case AP4_SAMPLE_FORMAT_DTSC: return "DTS"; case AP4_SAMPLE_FORMAT_DTSH: return "DTS-HD"; case AP4_SAMPLE_FORMAT_DTSL: return "DTS-HD Lossless"; case AP4_SAMPLE_FORMAT_DTSE: return "DTS Low Bitrate"; case AP4_SAMPLE_FORMAT_AVCP: return "Advanced Video Coding Parameters"; case AP4_SAMPLE_FORMAT_DRAC: return "Dirac"; case AP4_SAMPLE_FORMAT_DRA1: return "DRA Audio"; case AP4_SAMPLE_FORMAT_G726: return "G726"; case AP4_SAMPLE_FORMAT_MJP2: return "Motion JPEG 2000"; case AP4_SAMPLE_FORMAT_OKSD: return "OMA Keys"; case AP4_SAMPLE_FORMAT_RAW_: return "Uncompressed Audio"; case AP4_SAMPLE_FORMAT_RTP_: return "RTP Hints"; case AP4_SAMPLE_FORMAT_S263: return "H.263"; case AP4_SAMPLE_FORMAT_SAMR: return "Narrowband AMR"; case AP4_SAMPLE_FORMAT_SAWB: return "Wideband AMR"; case AP4_SAMPLE_FORMAT_SAWP: return "Extended AMR"; case AP4_SAMPLE_FORMAT_SEVC: return "EVRC Voice"; case AP4_SAMPLE_FORMAT_SQCP: return "13K Voice"; case AP4_SAMPLE_FORMAT_SRTP: return "SRTP Hints"; case AP4_SAMPLE_FORMAT_SSMV: return "SMV Voice"; case AP4_SAMPLE_FORMAT_TEXT: return "Textual Metadata"; case AP4_SAMPLE_FORMAT_TWOS: return "Uncompressed 16-bit Audio"; case AP4_SAMPLE_FORMAT_TX3G: return "Timed Text"; case AP4_SAMPLE_FORMAT_VC_1: return "SMPTE VC-1"; case AP4_SAMPLE_FORMAT_XML_: return "XML Metadata"; case AP4_SAMPLE_FORMAT_STPP: return "Timed Text"; case AP4_SAMPLE_FORMAT_VP8: return "VP8"; case AP4_SAMPLE_FORMAT_VP9: return "VP9"; case AP4_SAMPLE_FORMAT_VP10: return "VP10"; default: return NULL; } } /*---------------------------------------------------------------------- | AP4_SampleDescription::AP4_SampleDescription +---------------------------------------------------------------------*/ AP4_SampleDescription::AP4_SampleDescription(Type type, AP4_UI32 format, AP4_AtomParent* details) : m_Type(type), m_Format(format) { if (details) { for (AP4_List::Item* item = details->GetChildren().FirstItem(); item; item = item->GetNext()) { AP4_Atom* atom = item->GetData(); if (atom) { AP4_Atom* clone = atom->Clone(); if (clone) m_Details.AddChild(clone); } } } } /*---------------------------------------------------------------------- | AP4_SampleDescription::Clone +---------------------------------------------------------------------*/ AP4_SampleDescription* AP4_SampleDescription::Clone(AP4_Result* result) { if (result) *result = AP4_SUCCESS; AP4_Atom* atom = ToAtom(); if (atom == NULL) { if (result) *result = AP4_FAILURE; return NULL; } // serialize the atom to a buffer AP4_MemoryByteStream* mbs = new AP4_MemoryByteStream((AP4_UI32)atom->GetSize()); atom->Write(*mbs); delete atom; atom = NULL; // parse the buffer back to an atom mbs->Seek(0); AP4_AtomFactory* factory = new AP4_AtomFactory(); factory->PushContext(AP4_ATOM_TYPE_STSD); AP4_Atom* atom_clone = NULL; AP4_Result lresult = factory->CreateAtomFromStream(*mbs, atom_clone); factory->PopContext(); delete factory; if (result) *result = lresult; mbs->Release(); if (AP4_FAILED(lresult)) return NULL; // convert the atom clone to a sample description AP4_SampleEntry* sample_entry = AP4_DYNAMIC_CAST(AP4_SampleEntry, atom_clone); if (sample_entry == NULL) { if (result) *result = AP4_ERROR_INTERNAL; delete atom_clone; return NULL; } AP4_SampleDescription* clone = sample_entry->ToSampleDescription(); if (clone == NULL) { if (result) *result = AP4_ERROR_INTERNAL; } delete atom_clone; return clone; } /*---------------------------------------------------------------------- | AP4_SampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_SampleDescription::ToAtom() const { return new AP4_SampleEntry(m_Format); } /*---------------------------------------------------------------------- | AP4_SampleDescription::GetCodecString +---------------------------------------------------------------------*/ AP4_Result AP4_SampleDescription::GetCodecString(AP4_String& codec) { char coding[5]; AP4_FormatFourChars(coding, m_Format); codec.Assign(coding, 4); return AP4_SUCCESS; } /*---------------------------------------------------------------------- | AP4_UnknownSampleDescription::AP4_UnknownSampleDescription +---------------------------------------------------------------------*/ AP4_UnknownSampleDescription::AP4_UnknownSampleDescription(AP4_Atom* atom) : AP4_SampleDescription(AP4_SampleDescription::TYPE_UNKNOWN, atom->GetType(), NULL), m_Atom(atom->Clone()) { } /*---------------------------------------------------------------------- | AP4_UnknownSampleDescription::~AP4_UnknownSampleDescription +---------------------------------------------------------------------*/ AP4_UnknownSampleDescription::~AP4_UnknownSampleDescription() { delete m_Atom; } /*---------------------------------------------------------------------- | AP4_UnknownSampleDescription::Clone +---------------------------------------------------------------------*/ AP4_SampleDescription* AP4_UnknownSampleDescription::Clone(AP4_Result* result) { AP4_Atom* atom_clone = NULL; if (m_Atom) { atom_clone = m_Atom->Clone(); } if (atom_clone == NULL) { if (result) *result = AP4_FAILURE; return NULL; } if (result) *result = AP4_SUCCESS; return new AP4_UnknownSampleDescription(atom_clone); } /*---------------------------------------------------------------------- | AP4_UnknownSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_UnknownSampleDescription::ToAtom() const { if (m_Atom) { return m_Atom->Clone(); } else { return NULL; } } /*---------------------------------------------------------------------- | AP4_GenericAudioSampleDescription +---------------------------------------------------------------------*/ AP4_Atom* AP4_GenericAudioSampleDescription::ToAtom() const { AP4_AudioSampleEntry* sample_entry = new AP4_AudioSampleEntry(m_Format, m_SampleRate<<16, m_SampleSize, m_ChannelCount); AP4_AtomParent& details = const_cast(m_Details); for (AP4_List::Item* item = details.GetChildren().FirstItem(); item; item = item->GetNext()) { AP4_Atom* child = item->GetData(); sample_entry->AddChild(child->Clone()); } return sample_entry; } /*---------------------------------------------------------------------- | AP4_GenericVideoSampleDescription::GetCodecString +---------------------------------------------------------------------*/ AP4_Result AP4_GenericVideoSampleDescription::GetCodecString(AP4_String& codec) { // VPx override AP4_VpccAtom* vpcc = AP4_DYNAMIC_CAST(AP4_VpccAtom, m_Details.GetChild(AP4_ATOM_TYPE_VPCC)); if (vpcc) { return vpcc->GetCodecString(GetFormat(), codec); } return AP4_SampleDescription::GetCodecString(codec); } /*---------------------------------------------------------------------- | AP4_GenericVideoSampleDescription +---------------------------------------------------------------------*/ AP4_Atom* AP4_GenericVideoSampleDescription::ToAtom() const { AP4_VisualSampleEntry* sample_entry = new AP4_VisualSampleEntry(m_Format, m_Width, m_Height, m_Depth, m_CompressorName.GetChars()); AP4_AtomParent& details = const_cast(m_Details); for (AP4_List::Item* item = details.GetChildren().FirstItem(); item; item = item->GetNext()) { AP4_Atom* child = item->GetData(); sample_entry->AddChild(child->Clone()); } return sample_entry; } /*---------------------------------------------------------------------- | AP4_AvcSampleDescription::AP4_AvcSampleDescription +---------------------------------------------------------------------*/ AP4_AvcSampleDescription::AP4_AvcSampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_UI08 profile, AP4_UI08 level, AP4_UI08 profile_compatibility, AP4_UI08 length_size, AP4_UI08 chroma_format, AP4_UI08 bit_depth_luma_minus8, AP4_UI08 bit_depth_chroma_minus8, const AP4_Array& sequence_parameters, const AP4_Array& picture_parameters) : AP4_SampleDescription(TYPE_AVC, format, NULL), AP4_VideoSampleDescription(width, height, depth, compressor_name) { m_AvccAtom = new AP4_AvccAtom(profile, level, profile_compatibility, length_size, chroma_format, bit_depth_luma_minus8, bit_depth_chroma_minus8, sequence_parameters, picture_parameters); m_Details.AddChild(m_AvccAtom); } /*---------------------------------------------------------------------- | AP4_AvcSampleDescription::AP4_AvcSampleDescription +---------------------------------------------------------------------*/ AP4_AvcSampleDescription::AP4_AvcSampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, const AP4_AvccAtom* avcc) : AP4_SampleDescription(TYPE_AVC, format, NULL), AP4_VideoSampleDescription(width, height, depth, compressor_name) { if (avcc) { m_AvccAtom = new AP4_AvccAtom(*avcc); } else { // should never happen m_AvccAtom = new AP4_AvccAtom(); } m_Details.AddChild(m_AvccAtom); } /*---------------------------------------------------------------------- | AP4_AvcSampleDescription::AP4_AvcSampleDescription +---------------------------------------------------------------------*/ AP4_AvcSampleDescription::AP4_AvcSampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_AtomParent* details) : AP4_SampleDescription(TYPE_AVC, format, details), AP4_VideoSampleDescription(width, height, depth, compressor_name), m_AvccAtom(NULL) { AP4_AvccAtom* avcc = AP4_DYNAMIC_CAST(AP4_AvccAtom, m_Details.GetChild(AP4_ATOM_TYPE_AVCC)); if (avcc) { m_AvccAtom = avcc; } else { // shoud never happen m_AvccAtom = new AP4_AvccAtom(); m_Details.AddChild(m_AvccAtom); } } /*---------------------------------------------------------------------- | AP4_AvcSampleDescription::GetCodecString +---------------------------------------------------------------------*/ AP4_Result AP4_AvcSampleDescription::GetCodecString(AP4_String& codec) { char coding[5]; AP4_FormatFourChars(coding, GetFormat()); char workspace[64]; AP4_FormatString(workspace, sizeof(workspace), "%s.%02X%02X%02X", coding, GetProfile(), GetProfileCompatibility(), GetLevel()); // Dolby Vision override AP4_DvccAtom* dvcc = AP4_DYNAMIC_CAST(AP4_DvccAtom, m_Details.GetChild(AP4_ATOM_TYPE_DVCC)); if (dvcc) { return dvcc->GetCodecString(workspace, GetFormat(), codec); } codec = workspace; return AP4_SUCCESS; } /*---------------------------------------------------------------------- | AP4_AvcSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_AvcSampleDescription::ToAtom() const { return new AP4_AvcSampleEntry(m_Format, m_Width, m_Height, m_Depth, m_CompressorName.GetChars(), &m_Details); } /*---------------------------------------------------------------------- | AP4_AvcDoviSampleDescription::AP4_AvcDoviSampleDescription +---------------------------------------------------------------------*/ AP4_AvcDoviSampleDescription::AP4_AvcDoviSampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_UI08 profile, AP4_UI08 level, AP4_UI08 profile_compatibility, AP4_UI08 length_size, const AP4_Array& sequence_parameters, const AP4_Array& picture_parameters, AP4_UI08 chroma_format, AP4_UI08 bit_depth_luma_minus8, AP4_UI08 bit_depth_chroma_minus8, AP4_UI08 dv_version_major, AP4_UI08 dv_version_minor, AP4_UI08 dv_profile, AP4_UI08 dv_level, bool rpu_present_flag, bool el_present_flag, bool bl_present_flag, AP4_UI08 dv_bl_signal_compatibility_id) : AP4_AvcSampleDescription(format, width, height, depth, compressor_name, profile, level, profile_compatibility, length_size, chroma_format, bit_depth_luma_minus8, bit_depth_chroma_minus8, sequence_parameters, picture_parameters) { m_DvccAtom = new AP4_DvccAtom(dv_version_major, dv_version_minor, dv_profile, dv_level, rpu_present_flag, el_present_flag, bl_present_flag, dv_bl_signal_compatibility_id); m_Details.AddChild(m_DvccAtom); } /*---------------------------------------------------------------------- | AP4_HevcSampleDescription::AP4_HevcSampleDescription +---------------------------------------------------------------------*/ AP4_HevcSampleDescription::AP4_HevcSampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, const AP4_HvccAtom* hvcc) : AP4_SampleDescription(TYPE_HEVC, format, NULL), AP4_VideoSampleDescription(width, height, depth, compressor_name) { if (hvcc) { m_HvccAtom = new AP4_HvccAtom(*hvcc); } else { // should never happen m_HvccAtom = new AP4_HvccAtom(); } m_Details.AddChild(m_HvccAtom); } /*---------------------------------------------------------------------- | AP4_HevcSampleDescription::AP4_HevcSampleDescription +---------------------------------------------------------------------*/ AP4_HevcSampleDescription::AP4_HevcSampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_AtomParent* details) : AP4_SampleDescription(TYPE_HEVC, format, details), AP4_VideoSampleDescription(width, height, depth, compressor_name), m_HvccAtom(NULL) { AP4_HvccAtom* hvcc = AP4_DYNAMIC_CAST(AP4_HvccAtom, m_Details.GetChild(AP4_ATOM_TYPE_HVCC)); if (hvcc) { m_HvccAtom = hvcc; } else { // shoud never happen m_HvccAtom = new AP4_HvccAtom(); m_Details.AddChild(m_HvccAtom); } } /*---------------------------------------------------------------------- | AP4_HevcSampleDescription::AP4_HevcSampleDescription +---------------------------------------------------------------------*/ AP4_HevcSampleDescription::AP4_HevcSampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_UI08 general_profile_space, AP4_UI08 general_tier_flag, AP4_UI08 general_profile, AP4_UI32 general_profile_compatibility_flags, AP4_UI64 general_constraint_indicator_flags, AP4_UI08 general_level, AP4_UI32 min_spatial_segmentation, AP4_UI08 parallelism_type, AP4_UI08 chroma_format, AP4_UI08 luma_bit_depth, AP4_UI08 chroma_bit_depth, AP4_UI16 average_frame_rate, AP4_UI08 constant_frame_rate, AP4_UI08 num_temporal_layers, AP4_UI08 temporal_id_nested, AP4_UI08 nalu_length_size, const AP4_Array& video_parameters, AP4_UI08 video_parameters_completeness, const AP4_Array& sequence_parameters, AP4_UI08 sequence_parameters_completeness, const AP4_Array& picture_parameters, AP4_UI08 picture_parameters_completeness) : AP4_SampleDescription(TYPE_HEVC, format, NULL), AP4_VideoSampleDescription(width, height, depth, compressor_name) { m_HvccAtom = new AP4_HvccAtom(general_profile_space, general_tier_flag, general_profile, general_profile_compatibility_flags, general_constraint_indicator_flags, general_level, min_spatial_segmentation, parallelism_type, chroma_format, luma_bit_depth, chroma_bit_depth, average_frame_rate, constant_frame_rate, num_temporal_layers, temporal_id_nested, nalu_length_size, video_parameters, video_parameters_completeness, sequence_parameters, sequence_parameters_completeness, picture_parameters, picture_parameters_completeness); m_Details.AddChild(m_HvccAtom); } /*---------------------------------------------------------------------- | ReverseBits +---------------------------------------------------------------------*/ static AP4_UI32 ReverseBits(AP4_UI32 bits) { unsigned int count = sizeof(bits) * 8; AP4_UI32 reverse_bits = 0; while (bits) { reverse_bits = (reverse_bits << 1) | (bits & 1); bits >>= 1; count--; } return (count < 32) ? (reverse_bits << count) : 0; } /*---------------------------------------------------------------------- | AP4_HevcSampleDescription:GetCodecString +---------------------------------------------------------------------*/ AP4_Result AP4_HevcSampleDescription::GetCodecString(AP4_String& codec) { char coding[5]; AP4_FormatFourChars(coding, GetFormat()); char profile_space[2] = {0,0}; if (GetGeneralProfileSpace() > 0 && GetGeneralProfileSpace() <= 3) { profile_space[0] = 'A'+GetGeneralProfileSpace()-1; } AP4_UI64 constraints = GetGeneralConstraintIndicatorFlags(); while (constraints && ((constraints & 0xFF) == 0)) { constraints >>= 8; } char workspace[64]; AP4_FormatString(workspace, sizeof(workspace), "%s.%s%d.%X.%c%d.%llx", coding, profile_space, GetGeneralProfile(), ReverseBits(GetGeneralProfileCompatibilityFlags()), GetGeneralTierFlag()?'H':'L', GetGeneralLevel(), constraints); // Dolby Vision override AP4_DvccAtom* dvcc = AP4_DYNAMIC_CAST(AP4_DvccAtom, m_Details.GetChild(AP4_ATOM_TYPE_DVCC)); if (dvcc) { return dvcc->GetCodecString(workspace, GetFormat(), codec); } codec = workspace; return AP4_SUCCESS; } /*---------------------------------------------------------------------- | AP4_HevcSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_HevcSampleDescription::ToAtom() const { return new AP4_HevcSampleEntry(m_Format, m_Width, m_Height, m_Depth, m_CompressorName.GetChars(), &m_Details); } /*---------------------------------------------------------------------- | AP4_HevcDoviSampleDescription::AP4_HevcDoviSampleDescription +---------------------------------------------------------------------*/ AP4_HevcDoviSampleDescription::AP4_HevcDoviSampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_UI08 general_profile_space, AP4_UI08 general_tier_flag, AP4_UI08 general_profile, AP4_UI32 general_profile_compatibility_flags, AP4_UI64 general_constraint_indicator_flags, AP4_UI08 general_level, AP4_UI32 min_spatial_segmentation, AP4_UI08 parallelism_type, AP4_UI08 chroma_format, AP4_UI08 luma_bit_depth, AP4_UI08 chroma_bit_depth, AP4_UI16 average_frame_rate, AP4_UI08 constant_frame_rate, AP4_UI08 num_temporal_layers, AP4_UI08 temporal_id_nested, AP4_UI08 nalu_length_size, const AP4_Array& video_parameters, AP4_UI08 video_parameters_completeness, const AP4_Array& sequence_parameters, AP4_UI08 sequence_parameters_completeness, const AP4_Array& picture_parameters, AP4_UI08 picture_parameters_completeness, AP4_UI08 dv_version_major, AP4_UI08 dv_version_minor, AP4_UI08 dv_profile, AP4_UI08 dv_level, bool rpu_present_flag, bool el_present_flag, bool bl_present_flag, AP4_UI08 dv_bl_signal_compatibility_id) : AP4_HevcSampleDescription(format, width, height, depth, compressor_name, general_profile_space, general_tier_flag, general_profile, general_profile_compatibility_flags, general_constraint_indicator_flags, general_level, min_spatial_segmentation, parallelism_type, chroma_format, luma_bit_depth, chroma_bit_depth, average_frame_rate, constant_frame_rate, num_temporal_layers, temporal_id_nested, nalu_length_size, video_parameters, video_parameters_completeness, sequence_parameters, sequence_parameters_completeness, picture_parameters, picture_parameters_completeness) { m_DvccAtom = new AP4_DvccAtom(dv_version_major, dv_version_minor, dv_profile, dv_level, rpu_present_flag, el_present_flag, bl_present_flag, dv_bl_signal_compatibility_id); m_Details.AddChild(m_DvccAtom); } /*---------------------------------------------------------------------- | AP4_Av1SampleDescription::AP4_Av1SampleDescription +---------------------------------------------------------------------*/ AP4_Av1SampleDescription::AP4_Av1SampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_UI08 version, AP4_UI08 seq_profile, AP4_UI08 seq_level_idx_0, AP4_UI08 seq_tier_0, AP4_UI08 high_bitdepth, AP4_UI08 twelve_bit, AP4_UI08 monochrome, AP4_UI08 chroma_subsampling_x, AP4_UI08 chroma_subsampling_y, AP4_UI08 chroma_sample_position, AP4_UI08 initial_presentation_delay_present, AP4_UI08 initial_presentation_delay_minus_one, const AP4_UI08* config_obus, AP4_Size config_obus_size) : AP4_SampleDescription(TYPE_AV1, format, NULL), AP4_VideoSampleDescription(width, height, depth, compressor_name) { m_Av1cAtom = new AP4_Av1cAtom(version, seq_profile, seq_level_idx_0, seq_tier_0, high_bitdepth, twelve_bit, monochrome, chroma_subsampling_x, chroma_subsampling_y, chroma_sample_position, initial_presentation_delay_present, initial_presentation_delay_minus_one, config_obus, config_obus_size); m_Details.AddChild(m_Av1cAtom); } /*---------------------------------------------------------------------- | AP4_Av1SampleDescription::AP4_Av1SampleDescription +---------------------------------------------------------------------*/ AP4_Av1SampleDescription::AP4_Av1SampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, const AP4_Av1cAtom* av1c) : AP4_SampleDescription(TYPE_AV1, format, NULL), AP4_VideoSampleDescription(width, height, depth, compressor_name) { if (av1c) { m_Av1cAtom = new AP4_Av1cAtom(*av1c); } else { // should never happen m_Av1cAtom = new AP4_Av1cAtom(); } m_Details.AddChild(m_Av1cAtom); } /*---------------------------------------------------------------------- | AP4_Av1SampleDescription::AP4_Av1SampleDescription +---------------------------------------------------------------------*/ AP4_Av1SampleDescription::AP4_Av1SampleDescription(AP4_UI32 format, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_AtomParent* details) : AP4_SampleDescription(TYPE_AV1, format, details), AP4_VideoSampleDescription(width, height, depth, compressor_name), m_Av1cAtom(NULL) { AP4_Av1cAtom* av1c = AP4_DYNAMIC_CAST(AP4_Av1cAtom, m_Details.GetChild(AP4_ATOM_TYPE_AV1C)); if (av1c) { m_Av1cAtom = av1c; } else { // shoud never happen m_Av1cAtom = new AP4_Av1cAtom(); m_Details.AddChild(m_Av1cAtom); } } /*---------------------------------------------------------------------- | AP4_Av1cSampleDescription::GetCodecString +---------------------------------------------------------------------*/ AP4_Result AP4_Av1SampleDescription::GetCodecString(AP4_String& codec) { AP4_UI08 bit_depth = 10; AP4_UI08 color_primaries = 1; AP4_UI08 transfer_characteristics = 1; AP4_UI08 matrix_coefficients = 1; AP4_UI08 video_full_range_flag = 0; char coding[5]; AP4_FormatFourChars(coding, GetFormat()); char workspace[64]; AP4_FormatString(workspace, sizeof(workspace), "%s.%d.%02d%c.%02d.%d.%d%d%d.%02d.%02d.%02d.%d", coding, this->GetSeqProfile(), this->GetSeqLevelIdx0() >> 4, this->GetSeqTier0() == 0 ? 'M' : 'H', bit_depth, this->GetMonochrome(), this->GetChromaSubsamplingX(), this->GetChromaSubsamplingY(), (this->GetChromaSubsamplingX() == 1 && this->GetChromaSubsamplingY() == 1) ? this->GetChromaSamplePosition() : 0, color_primaries, transfer_characteristics, matrix_coefficients, video_full_range_flag); codec = workspace; return AP4_SUCCESS; } /*---------------------------------------------------------------------- | AP4_Av1SampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_Av1SampleDescription::ToAtom() const { return new AP4_Av1SampleEntry(m_Format, m_Width, m_Height, m_Depth, m_CompressorName.GetChars(), &m_Details); } /*---------------------------------------------------------------------- | AP4_MpegSampleDescription::AP4_MpegSampleDescription +---------------------------------------------------------------------*/ AP4_MpegSampleDescription::AP4_MpegSampleDescription(AP4_UI32 format, AP4_EsdsAtom* esds) : AP4_SampleDescription(TYPE_MPEG, format, NULL), m_StreamType(0), m_ObjectTypeId(0), m_BufferSize(0), m_MaxBitrate(0), m_AvgBitrate(0) { if (esds) { // get the es descriptor const AP4_EsDescriptor* es_desc = esds->GetEsDescriptor(); if (es_desc == NULL) return; // get the decoder config descriptor const AP4_DecoderConfigDescriptor* dc_desc = es_desc->GetDecoderConfigDescriptor(); if (dc_desc) { m_StreamType = dc_desc->GetStreamType(); m_ObjectTypeId = dc_desc->GetObjectTypeIndication(); m_BufferSize = dc_desc->GetBufferSize(); m_MaxBitrate = dc_desc->GetMaxBitrate(); m_AvgBitrate = dc_desc->GetAvgBitrate(); const AP4_DecoderSpecificInfoDescriptor* dsi_desc = dc_desc->GetDecoderSpecificInfoDescriptor(); if (dsi_desc != NULL) { m_DecoderInfo.SetData(dsi_desc->GetDecoderSpecificInfo().GetData(), dsi_desc->GetDecoderSpecificInfo().GetDataSize()); } } } } /*---------------------------------------------------------------------- | AP4_MpegSampleDescription::AP4_MpegSampleDescription +---------------------------------------------------------------------*/ AP4_MpegSampleDescription::AP4_MpegSampleDescription( AP4_UI32 format, StreamType stream_type, OTI oti, const AP4_DataBuffer* decoder_info, AP4_UI32 buffer_size, AP4_UI32 max_bitrate, AP4_UI32 avg_bitrate) : AP4_SampleDescription(TYPE_MPEG, format, NULL), m_StreamType(stream_type), m_ObjectTypeId(oti), m_BufferSize(buffer_size), m_MaxBitrate(max_bitrate), m_AvgBitrate(avg_bitrate) { if (decoder_info != NULL) { m_DecoderInfo.SetData(decoder_info->GetData(), decoder_info->GetDataSize()); } } /*---------------------------------------------------------------------- | AP4_MpegSampleDescription::CreateEsDescriptor +---------------------------------------------------------------------*/ AP4_EsDescriptor* AP4_MpegSampleDescription::CreateEsDescriptor() const { AP4_EsDescriptor* desc = new AP4_EsDescriptor(0); AP4_DecoderSpecificInfoDescriptor* dsi_desc; if (m_DecoderInfo.GetDataSize() != 0) { dsi_desc = new AP4_DecoderSpecificInfoDescriptor(m_DecoderInfo); } else { dsi_desc = NULL; } AP4_DecoderConfigDescriptor* decoder_config = new AP4_DecoderConfigDescriptor(m_StreamType, m_ObjectTypeId, m_BufferSize, m_MaxBitrate, m_AvgBitrate, dsi_desc); desc->AddSubDescriptor(decoder_config); // add a fixed SL Config desc->AddSubDescriptor(new AP4_SLConfigDescriptor()); return desc; } /*---------------------------------------------------------------------- | AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription +---------------------------------------------------------------------*/ AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription(AP4_EsdsAtom* esds) : AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4S, esds) { } /*---------------------------------------------------------------------- | AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription +---------------------------------------------------------------------*/ AP4_MpegSystemSampleDescription::AP4_MpegSystemSampleDescription( StreamType stream_type, OTI oti, const AP4_DataBuffer* decoder_info, AP4_UI32 buffer_size, AP4_UI32 max_bitrate, AP4_UI32 avg_bitrate) : AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4S, stream_type, oti, decoder_info, buffer_size, max_bitrate, avg_bitrate) { } /*---------------------------------------------------------------------- | AP4_MpegSystemSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_MpegSystemSampleDescription::ToAtom() const { return new AP4_Mp4sSampleEntry(CreateEsDescriptor()); } /*---------------------------------------------------------------------- | AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription +---------------------------------------------------------------------*/ AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription( AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, AP4_EsdsAtom* esds) : AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4A, esds), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { } /*---------------------------------------------------------------------- | AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription +---------------------------------------------------------------------*/ AP4_MpegAudioSampleDescription::AP4_MpegAudioSampleDescription( OTI oti, AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, const AP4_DataBuffer* decoder_info, AP4_UI32 buffer_size, AP4_UI32 max_bitrate, AP4_UI32 avg_bitrate) : AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4A, AP4_STREAM_TYPE_AUDIO, oti, decoder_info, buffer_size, max_bitrate, avg_bitrate), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { } /*---------------------------------------------------------------------- | AP4_MpegAudioSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_MpegAudioSampleDescription::ToAtom() const { return new AP4_Mp4aSampleEntry(m_SampleRate<<16, m_SampleSize, m_ChannelCount, CreateEsDescriptor()); } /*---------------------------------------------------------------------- | AP4_MpegAudioSampleDescription::GetCodecString +---------------------------------------------------------------------*/ AP4_Result AP4_MpegAudioSampleDescription::GetCodecString(AP4_String& codec) { char coding[5]; AP4_FormatFourChars(coding, GetFormat()); char workspace[64]; workspace[0] = 0; if (GetFormat() == AP4_SAMPLE_FORMAT_MP4A) { if (GetObjectTypeId() == AP4_OTI_MPEG4_AUDIO) { Mpeg4AudioObjectType object_type = GetMpeg4AudioObjectType(); if (object_type == AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_LC) { const AP4_DataBuffer& dsi = GetDecoderInfo(); if (dsi.GetDataSize()) { AP4_Mp4AudioDecoderConfig dec_config; AP4_Result result = dec_config.Parse(dsi.GetData(), dsi.GetDataSize()); if (AP4_SUCCEEDED(result)) { if (dec_config.m_Extension.m_PsPresent) { object_type = AP4_MPEG4_AUDIO_OBJECT_TYPE_PS; } else if (dec_config.m_Extension.m_SbrPresent) { object_type = AP4_MPEG4_AUDIO_OBJECT_TYPE_SBR; } } } } AP4_FormatString(workspace, sizeof(workspace), "%s.%02X.%d", coding, (int)GetObjectTypeId(), object_type); } else { AP4_FormatString(workspace, sizeof(workspace), "%s.%02X", coding, (int)GetObjectTypeId()); } } codec = workspace; return AP4_SUCCESS; } /*---------------------------------------------------------------------- | AP4_MpegAudioSampleDescription::GetMpeg4AudioObjectType +---------------------------------------------------------------------*/ AP4_MpegAudioSampleDescription::Mpeg4AudioObjectType AP4_MpegAudioSampleDescription::GetMpeg4AudioObjectType() const { if (m_ObjectTypeId == AP4_OTI_MPEG4_AUDIO && m_DecoderInfo.GetDataSize() >= 1) { AP4_UI08 type = m_DecoderInfo.GetData()[0]>>3; if (type == 31) { if (m_DecoderInfo.GetDataSize() < 2) return 0; type = 32+(((m_DecoderInfo.GetData()[0]&0x07)<<3) | ((m_DecoderInfo.GetData()[1]&0xE0)>>5)); } return type; } else { return 0; } } /*---------------------------------------------------------------------- | AP4_Ac3SampleDescription::AP4_Ac3SampleDescription +---------------------------------------------------------------------*/ AP4_Ac3SampleDescription::AP4_Ac3SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, const AP4_Dac3Atom* dac3): AP4_SampleDescription(TYPE_AC3, AP4_SAMPLE_FORMAT_AC_3, NULL), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { if (dac3) { m_Dac3Atom = new AP4_Dac3Atom(*dac3); } else { // TODO: add default construtor, m_Dac3Atom = new AP4_Dac3Atom() / should never happen m_Dac3Atom = NULL; } m_Details.AddChild(m_Dac3Atom); } /*---------------------------------------------------------------------- | AP4_Ac3SampleDescription::AP4_Ac3SampleDescription +---------------------------------------------------------------------*/ AP4_Ac3SampleDescription::AP4_Ac3SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, AP4_AtomParent* details) : AP4_SampleDescription(TYPE_AC3, AP4_SAMPLE_FORMAT_AC_3, details), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count), m_Dac3Atom(NULL) { AP4_Dac3Atom* ac3 = AP4_DYNAMIC_CAST(AP4_Dac3Atom, m_Details.GetChild(AP4_SAMPLE_FORMAT_AC_3)); if (ac3) { m_Dac3Atom = ac3; } else { // TODO: add default construtor, m_Dac3Atom = new AP4_Dac3Atom() / should never happen m_Dac3Atom = NULL; m_Details.AddChild(m_Dac3Atom); } } /*---------------------------------------------------------------------- | AP4_Ac3SampleDescription::AP4_Ac3SampleDescription +---------------------------------------------------------------------*/ AP4_Ac3SampleDescription::AP4_Ac3SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, AP4_UI32 size, const AP4_Dac3Atom::StreamInfo* ac3_stream_info): AP4_SampleDescription(TYPE_AC3, AP4_SAMPLE_FORMAT_AC_3, NULL), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { m_Dac3Atom = new AP4_Dac3Atom(ac3_stream_info); m_Details.AddChild(m_Dac3Atom); } /*---------------------------------------------------------------------- | AP4_Ac3SampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_Ac3SampleDescription::ToAtom() const { return new AP4_Ac3SampleEntry(m_Format, m_SampleRate<<16, m_SampleSize, m_ChannelCount, &m_Details); } /*---------------------------------------------------------------------- | AP4_Eac3SampleDescription::AP4_Eac3SampleDescription +---------------------------------------------------------------------*/ AP4_Eac3SampleDescription::AP4_Eac3SampleDescription(): AP4_SampleDescription(TYPE_EAC3, AP4_SAMPLE_FORMAT_EC_3, NULL), AP4_AudioSampleDescription(48000, 16, 2) { m_Details.AddChild(new AP4_Dec3Atom()); } /*---------------------------------------------------------------------- | AP4_Eac3SampleDescription::AP4_Eac3SampleDescription +---------------------------------------------------------------------*/ AP4_Eac3SampleDescription::AP4_Eac3SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, const AP4_Dec3Atom* dec3): AP4_SampleDescription(TYPE_EAC3, AP4_SAMPLE_FORMAT_EC_3, NULL), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { if (dec3) { m_Dec3Atom = new AP4_Dec3Atom(*dec3); } else { // shoud never happen m_Dec3Atom = new AP4_Dec3Atom(); } m_Details.AddChild(m_Dec3Atom); } /*---------------------------------------------------------------------- | AP4_Eac3SampleDescription::AP4_Eac3SampleDescription +---------------------------------------------------------------------*/ AP4_Eac3SampleDescription::AP4_Eac3SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, AP4_AtomParent* details) : AP4_SampleDescription(TYPE_EAC3, AP4_SAMPLE_FORMAT_EC_3, details), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count), m_Dec3Atom(NULL) { AP4_Dec3Atom* eac3 = AP4_DYNAMIC_CAST(AP4_Dec3Atom, m_Details.GetChild(AP4_SAMPLE_FORMAT_EC_3)); if (eac3) { m_Dec3Atom = eac3; } else { // shoud never happen m_Dec3Atom = new AP4_Dec3Atom(); m_Details.AddChild(m_Dec3Atom); } } /*---------------------------------------------------------------------- | AP4_Eac3SampleDescription::AP4_Eac3SampleDescription +---------------------------------------------------------------------*/ AP4_Eac3SampleDescription::AP4_Eac3SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, AP4_UI32 size, const AP4_Dec3Atom::SubStream* subStream, const AP4_UI32 complexity_index_type_a): AP4_SampleDescription(TYPE_EAC3, AP4_SAMPLE_FORMAT_EC_3, NULL), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { m_Dec3Atom = new AP4_Dec3Atom(size, subStream, complexity_index_type_a); m_Details.AddChild(m_Dec3Atom); } /*---------------------------------------------------------------------- | AP4_Eac3SampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_Eac3SampleDescription::ToAtom() const { return new AP4_Eac3SampleEntry(m_Format, m_SampleRate<<16, m_SampleSize, m_ChannelCount, &m_Details); } /*---------------------------------------------------------------------- | AP4_Ac4SampleDescription::AP4_Ac4SampleDescription +---------------------------------------------------------------------*/ AP4_Ac4SampleDescription::AP4_Ac4SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, const AP4_Dac4Atom* dac4): AP4_SampleDescription(TYPE_AC4, AP4_SAMPLE_FORMAT_AC_4, NULL), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { if (dac4) { m_Dac4Atom = dac4->CloneConst(); ; } else { // TODO: add default construtor, m_Dac4Atom = new AP4_Dac4Atom() / should never happen m_Dac4Atom = NULL; } m_Details.AddChild(m_Dac4Atom); } /*---------------------------------------------------------------------- | AP4_Ac4SampleDescription::AP4_Ac4SampleDescription +---------------------------------------------------------------------*/ AP4_Ac4SampleDescription::AP4_Ac4SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, AP4_AtomParent* details) : AP4_SampleDescription(TYPE_AC4, AP4_SAMPLE_FORMAT_AC_4, details), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count), m_Dac4Atom(NULL) { AP4_Dac4Atom* ac4 = AP4_DYNAMIC_CAST(AP4_Dac4Atom, m_Details.GetChild(AP4_ATOM_TYPE_AC_4)); if (ac4) { m_Dac4Atom = ac4; } else { // TODO: add default construtor, m_Dac4Atom = new AP4_Dac4Atom() / should never happen m_Dac4Atom = NULL; m_Details.AddChild(m_Dac4Atom); } } /*---------------------------------------------------------------------- | AP4_Ac4SampleDescription::AP4_Ac4SampleDescription +---------------------------------------------------------------------*/ AP4_Ac4SampleDescription::AP4_Ac4SampleDescription(AP4_UI32 sample_rate, AP4_UI16 sample_size, AP4_UI16 channel_count, AP4_UI32 size, const AP4_Dac4Atom::Ac4Dsi* ac4Dsi): AP4_SampleDescription(TYPE_AC4, AP4_SAMPLE_FORMAT_AC_4, NULL), AP4_AudioSampleDescription(sample_rate, sample_size, channel_count) { m_Dac4Atom = new AP4_Dac4Atom(size, ac4Dsi); m_Details.AddChild(m_Dac4Atom); } /*---------------------------------------------------------------------- | AP4_Ac4SampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_Ac4SampleDescription::ToAtom() const { return new AP4_Ac4SampleEntry(m_Format, m_SampleRate<<16, m_SampleSize, m_ChannelCount, &m_Details); } /*---------------------------------------------------------------------- | AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription +---------------------------------------------------------------------*/ AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription( AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, AP4_EsdsAtom* esds) : AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4V, esds), AP4_VideoSampleDescription(width, height, depth, compressor_name) { } /*---------------------------------------------------------------------- | AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription +---------------------------------------------------------------------*/ AP4_MpegVideoSampleDescription::AP4_MpegVideoSampleDescription( OTI oti, AP4_UI16 width, AP4_UI16 height, AP4_UI16 depth, const char* compressor_name, const AP4_DataBuffer* decoder_info, AP4_UI32 buffer_size, AP4_UI32 max_bitrate, AP4_UI32 avg_bitrate) : AP4_MpegSampleDescription(AP4_ATOM_TYPE_MP4V, AP4_STREAM_TYPE_VISUAL, oti, decoder_info, buffer_size, max_bitrate, avg_bitrate), AP4_VideoSampleDescription(width, height, depth, compressor_name) { } /*---------------------------------------------------------------------- | AP4_MpegVideoSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_MpegVideoSampleDescription::ToAtom() const { return new AP4_Mp4vSampleEntry(m_Width, m_Height, m_Depth, m_CompressorName.GetChars(), CreateEsDescriptor()); } /*---------------------------------------------------------------------- | AP4_MpegSampleDescription::GetStreamTypeString +---------------------------------------------------------------------*/ const char* AP4_MpegSampleDescription::GetStreamTypeString(StreamType type) { switch (type) { case AP4_STREAM_TYPE_FORBIDDEN: return "INVALID"; case AP4_STREAM_TYPE_OD: return "Object Descriptor"; case AP4_STREAM_TYPE_CR: return "CR"; case AP4_STREAM_TYPE_BIFS: return "BIFS"; case AP4_STREAM_TYPE_VISUAL: return "Visual"; case AP4_STREAM_TYPE_AUDIO: return "Audio"; case AP4_STREAM_TYPE_MPEG7: return "MPEG-7"; case AP4_STREAM_TYPE_IPMP: return "IPMP"; case AP4_STREAM_TYPE_OCI: return "OCI"; case AP4_STREAM_TYPE_MPEGJ: return "MPEG-J"; default: return "UNKNOWN"; } } /*---------------------------------------------------------------------- | AP4_MpegSampleDescription::GetObjectTypeString +---------------------------------------------------------------------*/ const char* AP4_MpegSampleDescription::GetObjectTypeString(OTI oti) { switch (oti) { case AP4_OTI_MPEG4_SYSTEM: return "MPEG-4 System"; case AP4_OTI_MPEG4_SYSTEM_COR: return "MPEG-4 System COR"; case AP4_OTI_MPEG4_VISUAL: return "MPEG-4 Video"; case AP4_OTI_MPEG4_AUDIO: return "MPEG-4 Audio"; case AP4_OTI_MPEG2_VISUAL_SIMPLE: return "MPEG-2 Video Simple Profile"; case AP4_OTI_MPEG2_VISUAL_MAIN: return "MPEG-2 Video Main Profile"; case AP4_OTI_MPEG2_VISUAL_SNR: return "MPEG-2 Video SNR"; case AP4_OTI_MPEG2_VISUAL_SPATIAL: return "MPEG-2 Video Spatial"; case AP4_OTI_MPEG2_VISUAL_HIGH: return "MPEG-2 Video High"; case AP4_OTI_MPEG2_VISUAL_422: return "MPEG-2 Video 4:2:2"; case AP4_OTI_MPEG2_AAC_AUDIO_MAIN: return "MPEG-2 Audio AAC Main Profile"; case AP4_OTI_MPEG2_AAC_AUDIO_LC: return "MPEG-2 Audio AAC Low Complexity"; case AP4_OTI_MPEG2_AAC_AUDIO_SSRP: return "MPEG-2 Audio AAC SSRP"; case AP4_OTI_MPEG2_PART3_AUDIO: return "MPEG-2 Audio Part-3"; case AP4_OTI_MPEG1_VISUAL: return "MPEG-1 Video"; case AP4_OTI_MPEG1_AUDIO: return "MPEG-1 Audio"; case AP4_OTI_JPEG: return "JPEG"; case AP4_OTI_JPEG2000: return "JPEG-2000"; case AP4_OTI_EVRC_VOICE: return "EVRC Voice"; case AP4_OTI_SMV_VOICE: return "SMV Voice"; case AP4_OTI_3GPP2_CMF: return "3GPP2 CMF"; case AP4_OTI_SMPTE_VC1: return "SMPTE VC1 Video"; case AP4_OTI_DIRAC_VIDEO: return "Dirac Video"; case AP4_OTI_AC3_AUDIO: return "AC3 Audio"; case AP4_OTI_EAC3_AUDIO: return "E-AC3 Audio"; case AP4_OTI_DRA_AUDIO: return "DRA Audio"; case AP4_OTI_G719_AUDIO: return "G.719 Audio"; case AP4_OTI_DTS_AUDIO: return "DTS Audio"; case AP4_OTI_DTS_HIRES_AUDIO: return "DTS High Resolution Audio"; case AP4_OTI_DTS_MASTER_AUDIO: return "DTS Master Audio"; case AP4_OTI_DTS_EXPRESS_AUDIO: return "DTS Express/LBR Audio"; case AP4_OTI_OPUS_AUDIO: return "Opus Audio"; case AP4_OTI_VP9_VIDEO: return "VP9 Video"; case AP4_OTI_VORBIS_AUDIO: return "Vorbis Audio"; case AP4_OTI_13K_VOICE: return "13K Voice"; default: return "UNKNOWN"; } } /*---------------------------------------------------------------------- | AP4_MpegAudioSampleDescription::GetMpeg4AudioObjectTypeString +---------------------------------------------------------------------*/ const char* AP4_MpegAudioSampleDescription::GetMpeg4AudioObjectTypeString(Mpeg4AudioObjectType type) { switch (type) { case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_MAIN: return "AAC Main Profile"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_LC: return "AAC Low Complexity"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_SSR: return "AAC Scalable Sample Rate"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_LTP: return "AAC Long Term Predictor"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_SBR: return "Spectral Band Replication"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_AAC_SCALABLE: return "AAC Scalable"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_TWINVQ: return "Twin VQ"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_CELP: return "CELP"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_HVXC: return "HVXC"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_TTSI: return "TTSI"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_MAIN_SYNTHETIC: return "Main Synthetic"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_WAVETABLE_SYNTHESIS: return "Wavetable Synthesis"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_GENERAL_MIDI: return "General MIDI"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ALGORITHMIC_SYNTHESIS: return "Algorithmic Synthesis"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LC: return "Error Resilient AAC Low Complexity"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LTP: return "Error Resilient AAC Long Term Prediction"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_SCALABLE: return "Error Resilient AAC Scalable"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_TWINVQ: return "Error Resilient Twin VQ"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_BSAC: return "Error Resilient Bit Sliced Arithmetic Coding"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_LD: return "Error Resilient AAC Low Delay"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_CELP: return "Error Resilient CELP"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_HVXC: return "Error Resilient HVXC"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_HILN: return "Error Resilient HILN"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_PARAMETRIC: return "Error Resilient Parametric"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_SSC: return "SSC"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_PS: return "Parametric Stereo"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_MPEG_SURROUND: return "MPEG Surround"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_1: return "MPEG Layer 1"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_2: return "MPEG Layer 2"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_LAYER_3: return "MPEG Layer 3"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_DST: return "Direct Stream Transfer"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ALS: return "ALS Lossless Coding"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_SLS: return "SLS Scalable Lossless Coding"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_SLS_NON_CORE: return "SLS Scalable Lossless Coding (Non Core)"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_ER_AAC_ELD: return "Error Resilient AAC ELD"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_SMR_SIMPLE: return "SMR Simple"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_SMR_MAIN: return "SMR Main"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_USAC: return "USAC"; case AP4_MPEG4_AUDIO_OBJECT_TYPE_SAOC: return "SAOC"; default: return "UNKNOWN"; } } /*---------------------------------------------------------------------- | AP4_SubtitleSampleDescription::AP4_SubtitleSampleDescription +---------------------------------------------------------------------*/ AP4_SubtitleSampleDescription::AP4_SubtitleSampleDescription(AP4_UI32 format, const char* namespce, const char* schema_location, const char* image_mime_type) : AP4_SampleDescription(AP4_SampleDescription::TYPE_SUBTITLES, format, NULL), m_Namespace(namespce), m_SchemaLocation(schema_location), m_ImageMimeType(image_mime_type) { } /*---------------------------------------------------------------------- | AP4_SubtitleSampleDescription::Clone +---------------------------------------------------------------------*/ AP4_SampleDescription* AP4_SubtitleSampleDescription::Clone(AP4_Result* result) { if (result) *result = AP4_SUCCESS; return new AP4_SubtitleSampleDescription(m_Format, m_Namespace.GetChars(), m_SchemaLocation.GetChars(), m_ImageMimeType.GetChars()); } /*---------------------------------------------------------------------- | AP4_SubtitleSampleDescription::ToAtom +---------------------------------------------------------------------*/ AP4_Atom* AP4_SubtitleSampleDescription::ToAtom() const { return new AP4_SubtitleSampleEntry(m_Format, m_Namespace.GetChars(), m_SchemaLocation.GetChars(), m_ImageMimeType.GetChars()); }