/* Copyright (c) MediaArea.net SARL. All Rights Reserved. * * Use of this source code is governed by a BSD-style license that can * be found in the License.html file in the root of the source tree. */ //--------------------------------------------------------------------------- // Pre-compilation #include "MediaInfo/PreComp.h" #ifdef __BORLANDC__ #pragma hdrstop #endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Setup.h" //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #if defined(MEDIAINFO_MPEGH3DA_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Audio/File_Mpegh3da.h" #include "MediaInfo/MediaInfo_Config_MediaInfo.h" #include using namespace ZenLib; using namespace std; //--------------------------------------------------------------------------- namespace MediaInfoLib { //*************************************************************************** // Info //*************************************************************************** extern const int32u Aac_sampling_frequency[]; struct coreSbrFrameLengthIndex_mapping { int8u sbrRatioIndex; int16u coreCoderFrameLength; int8u outputFrameLengthDivided256; }; extern const size_t coreSbrFrameLengthIndex_Mapping_Size; extern coreSbrFrameLengthIndex_mapping coreSbrFrameLengthIndex_Mapping[]; extern int8u Aac_Channels_Get(int8u ChannelLayout); extern string Aac_Channels_GetString(int8u ChannelLayout); extern string Aac_ChannelConfiguration_GetString(int8u ChannelLayout); extern string Aac_ChannelConfiguration2_GetString(int8u ChannelLayout); extern string Aac_ChannelLayout_GetString(const Aac_OutputChannel* const OutputChannels, size_t OutputChannels_Size); extern string Aac_ChannelLayout_GetString(int8u ChannelLayout, bool IsMpegh3da=false, bool IsTip=false); extern string Aac_ChannelLayout_GetString(const vector& OutputChannels); extern string Aac_ChannelMode_GetString(int8u ChannelLayout, bool IsMpegh3da=false); extern string Aac_ChannelMode_GetString(const vector& OutputChannels); extern string Aac_OutputChannelPosition_GetString(int8u OutputChannelPosition); //--------------------------------------------------------------------------- static const char* const Mpegh3da_Profile[]= { "Main", "High", "LC", "BL", }; static size_t Mpegh3da_Profile_Size=sizeof(Mpegh3da_Profile)/sizeof(const char* const); extern string Mpegh3da_Profile_Get(int8u mpegh3daProfileLevelIndication) { if (!mpegh3daProfileLevelIndication) return string(); if (mpegh3daProfileLevelIndication>=5*Mpegh3da_Profile_Size) return Ztring::ToZtring(mpegh3daProfileLevelIndication).To_UTF8(); // Raw value return string(Mpegh3da_Profile[(mpegh3daProfileLevelIndication-1)/5])+"@L"+char('1'+((mpegh3daProfileLevelIndication-1)%5)); } //--------------------------------------------------------------------------- static const char* const Mpegh3da_MHASPacketType[]= { "FILLDATA", "MPEGH3DACFG", "MPEGH3DAFRAME", "AUDIOSCENEINFO", "", "", "SYNC", "SYNCGAP", "MARKER", "CRC16", "CRC32", "DESCRIPTOR", "USERINTERACTION", "LOUDNESS_DRC", "BUFFERINFO", "GLOBAL_CRC16", "GLOBAL_CRC32", "AUDIOTRUNCATION", "GENDATA", }; static const size_t Mpegh3da_MHASPacketType_Size=sizeof(Mpegh3da_MHASPacketType)/sizeof(const char* const); //--------------------------------------------------------------------------- static const char* const Mpegh3da_contentKind[]= { "", "Complete Main", "Dialogue", "Music", "Effect", "Mixed", "LFE", "Voiceover", "Spoken Subtitle", "Visually Impaired or Audio Description", "Commentary", "Hearing Impaired", "Emergency", }; static const size_t Mpegh3da_contentKind_Size=sizeof(Mpegh3da_contentKind)/sizeof(const char* const); //--------------------------------------------------------------------------- static const char* const Mpegh3da_groupPresetKind[]= { "", "Integrated TV Loudspeaker", "High Quality Loudspeaker", "Mobile Loudspeakers", "Mobile Headphones", "Hearing Impaired (light)", "Hearing Impaired (heavy)", "Visually Impaired or Audio Description", "Spoken Subtitles", "Loudness or DRC", }; static const size_t Mpegh3da_groupPresetKind_Size=sizeof(Mpegh3da_groupPresetKind)/sizeof(const char* const); //--------------------------------------------------------------------------- static const char* const Mpegh3da_signalGroupType[]= { "Channels", "Object", "SAOC", "HOA", }; static const size_t Mpegh3da_signalGroupType_Size=sizeof(Mpegh3da_signalGroupType)/sizeof(const char* const); //--------------------------------------------------------------------------- static const char* const Mpegh3da_marker_byte[]= { "", "Configuration change marker", "Random access or Immediate playout marker", "Program boundary marker", }; static const size_t Mpegh3da_marker_byte_Size=sizeof(Mpegh3da_marker_byte)/sizeof(const char* const); //--------------------------------------------------------------------------- static const char* const Mpegh3da_usacElementType[4]= { "SCE", "CPE", "LFE", "EXT", }; //--------------------------------------------------------------------------- static const char* const Mpegh3da_usacExtElementType[]= { "FILL", "MPEGS", "SAOC", "AUDIOPREROLL", "UNI_DRC", "OBJ_METADATA", "SAOC_3D", "HOA", "FMT_CNVRTR", "MCT", "TCC", "HOA_ENH_LAYER", "HREP", "ENHANCED_OBJ_METADATA", }; static const size_t Mpegh3da_usacExtElementType_Size=sizeof(Mpegh3da_usacExtElementType)/sizeof(const char* const); //--------------------------------------------------------------------------- static const char* const Mpegh3da_usacConfigExtType[]= { "FILL", "DOWNMIX", "LOUDNESS_INFO", "AUDIOSCENE_INFO", "HOA_MATRIX", "ICG", "SIG_GROUP_INFO", "COMPATIBLE_PROFILE_LEVEL_SET", }; static const size_t Mpegh3da_usacConfigExtType_Size=sizeof(Mpegh3da_usacConfigExtType)/sizeof(const char* const); //--------------------------------------------------------------------------- static const size_t Mpegh3da_SpeakerInfo_Size=43; static const speaker_info Mpegh3da_SpeakerInfo[Mpegh3da_SpeakerInfo_Size]= { {CH_M_L030, 30, false, 0, false, false}, {CH_M_R030, 30, true , 0, false, false}, {CH_M_000 , 0, false, 0, false, false}, {CH_LFE , 0, false, 15, true , true}, {CH_M_L110, 110, false, 0, false, false}, {CH_M_R110, 110, true , 0, false, false}, {CH_M_L022, 22, false, 0, false, false}, {CH_M_R022, 22, true , 0, false, false}, {CH_M_L135, 135, false, 0, false, false}, {CH_M_R135, 135, true , 0, false, false}, {CH_M_180 , 180, false, 0, false, false}, {CH_M_LSD , 135, false, 0, false, false}, {CH_M_RSD , 135, true , 0, false, false}, {CH_M_L090, 90, false, 0, false, false}, {CH_M_R090, 90, true , 0, false, false}, {CH_M_L060, 60, false, 0, false, false}, {CH_M_R060, 60, true , 0, false, false}, {CH_U_L030, 30, false, 35, false, false}, {CH_U_R030, 30, true , 35, false, false}, {CH_U_000 , 0, false, 35, false, false}, {CH_U_L135, 135, false, 35, false, false}, {CH_U_R135, 135, true , 35, false, false}, {CH_U_180 , 180, false, 35, false, false}, {CH_U_L090, 90, false, 35, false, false}, {CH_U_R090, 90, true , 35, false, false}, {CH_T_000 , 0, false, 90, false, false}, {CH_LFE2 , 45, false, 15, true , true}, {CH_L_L045, 45, false, 15, true , false}, {CH_L_R045, 45, true , 15, true , false}, {CH_L_000 , 0, false, 15, true , false}, {CH_U_L110, 110, false, 35, false, false}, {CH_U_R110, 110, true , 35, false, false}, {CH_U_L045, 45, false, 35, false, false}, {CH_U_R045, 45, true , 35, false, false}, {CH_M_L045, 45, false, 0, false, false}, {CH_M_R045, 45, true , 0, false, false}, {CH_LFE3 , 45, true , 15, true , true}, {CH_M_LSCR, 2, false, 0, false, false}, {CH_M_RSCR, 2, true , 0, false, false}, {CH_M_LSCH, 1, false, 0, false, false}, {CH_M_RSCH, 1, true , 0, false, false}, {CH_M_L150, 150, false, 0, false, false}, {CH_M_R150, 150, true , 0, false, false}, }; //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_Mpegh3da::File_Mpegh3da() :File_Usac() { //Configuration #if MEDIAINFO_TRACE Trace_Layers_Update(8); //Stream #endif //MEDIAINFO_TRACE //In MustParse_mhaC=false; MustParse_mpegh3daFrame=false; #if MEDIAINFO_CONFORMANCE ConformanceFlags.set(MpegH); #endif //Temp audioSceneInfoID=0; isMainStream=(int8u)-1; } //*************************************************************************** // Streams management //*************************************************************************** //--------------------------------------------------------------------------- void File_Mpegh3da::Streams_Fill() { Stream_Prepare(Stream_Audio); Fill(Stream_Audio, 0, Audio_Format, "MPEG-H 3D Audio"); string Format_Profile=Mpegh3da_Profile_Get(mpegh3daProfileLevelIndication); for (size_t Pos=0; Pos::iterator Label=MHASPacketLabels.begin(); Label!=MHASPacketLabels.end(); ++Label) Fill(Stream_Audio, 0, "Label", *Label); Fill_SetOptions(Stream_Audio, 0, "Label", "N NTY"); Ztring LabelString=Retrieve(Stream_Audio, 0, "Label"); const Ztring& Type=Retrieve_Const(Stream_Audio, 0, "Type"); if (!LabelString.empty() && !Type.empty()) { if (!LabelString.empty()) LabelString+=__T(' '); LabelString+=__T('(')+Type+__T(')'); } if (LabelString.empty()) Fill(Stream_Audio, 0, "Label/String", LabelString); Fill_SetOptions(Stream_Audio, 0, "Label/String", "Y NTN"); if (audioSceneInfoID) Fill(Stream_Audio, 0, "AudioSceneInfoID", audioSceneInfoID); Streams_Fill_ChannelLayout(string(), referenceLayout); if (!GroupPresets.empty()) { Fill(Stream_Audio, 0, "GroupPresetCount", GroupPresets.size()); Fill_SetOptions(Stream_Audio, 0, "GroupPresetCount", "N NIY"); } if (!SwitchGroups.empty()) { Fill(Stream_Audio, 0, "SwitchGroupCount", SwitchGroups.size()); Fill_SetOptions(Stream_Audio, 0, "SwitchGroupCount", "N NIY"); } if (!Groups.empty()) { Fill(Stream_Audio, 0, "GroupCount", Groups.size()); Fill_SetOptions(Stream_Audio, 0, "GroupCount", "N NIY"); } if (!SignalGroups.empty()) { Fill(Stream_Audio, 0, "SignalGroupCount", SignalGroups.size()); Fill_SetOptions(Stream_Audio, 0, "SignalGroupCount", "N NIY"); } // Filling if (!Mpegh3da_drcInstructionsUniDrc_Data[0].empty()) { C.drcInstructionsUniDrc_Data=Mpegh3da_drcInstructionsUniDrc_Data[0].begin()->second; Fill_DRC(); C.drcInstructionsUniDrc_Data.clear(); } /* if (!Mpegh3da_loudnessInfo_Data[0].empty() && !GroupPresets.empty()) { int8u ID=(int8u)-1; for (size_t i=0; isecond.Data[0]; Mpegh3da_loudnessInfo_Data[0].begin()->second.Data[0].clear(); } } } */ bool NoLoudnesConch; if (!Mpegh3da_loudnessInfo_Data[0].empty()) { C.IFrameParsed=true; C.Reset(false, true); C.loudnessInfo_Data[0]=Mpegh3da_loudnessInfo_Data[0].begin()->second.Data[0]; C.loudnessInfo_Data[1]=Mpegh3da_loudnessInfo_Data[0].begin()->second.Data[1]; Fill_Loudness(NULL); C.loudnessInfo_Data[0].clear(); C.loudnessInfo_Data[1].clear(); NoLoudnesConch=true; } else NoLoudnesConch=false; for (size_t i=0; isecond; if (Summary.empty()) Summary="Yes"; string p=string("GroupPreset")+Ztring::ToZtring(i).To_UTF8(); Fill(Stream_Audio, 0, p.c_str(), Summary); Fill(Stream_Audio, 0, (p+" Pos").c_str(), i); Fill_SetOptions(Stream_Audio, 0, (p+" Pos").c_str(), "N NIY"); Fill(Stream_Audio, 0, (p+" ID").c_str(), P.ID); for (map::const_iterator Desc=P.Description.begin(); Desc!=P.Description.end(); ++Desc) { Ztring Language=MediaInfoLib::Config.Iso639_1_Get(Ztring().From_UTF8(Desc->first)); if (Language.empty()) Language=Ztring().From_UTF8(Desc->first); Fill(Stream_Audio, 0, (p+" Title").c_str(), '('+MediaInfoLib::Config.Language_Get_Translate(__T("Language_"), Language).To_UTF8() + ") "+Desc->second); } if (P.Kindsecond; Fill_DRC(p.c_str()); C.drcInstructionsUniDrc_Data.clear(); } } if (!Mpegh3da_loudnessInfo_Data[3].empty()) { std::map::iterator Loudness=Mpegh3da_loudnessInfo_Data[3].find(P.ID); if (Loudness!=Mpegh3da_loudnessInfo_Data[3].end()) { C.IFrameParsed=true; C.Reset(false, true); C.loudnessInfo_Data[0]=Loudness->second.Data[0]; Fill_Loudness(p.c_str(), NoLoudnesConch); C.loudnessInfo_Data[0].clear(); } } /* Disabled for the moment, need more details about how to show it ZtringList IDs; if (P.Conditions.size()==1 && P.Conditions[0].ReferenceID==127 && !P.Conditions[0].ConditionOnOff) { Fill(Stream_Audio, 0, (p+" LinkedTo_Group_Pos").c_str(), "Full user interactivity"); Fill_SetOptions(Stream_Audio, 0, (p+" LinkedTo_Group_Pos").c_str(), "N NTY"); Fill(Stream_Audio, 0, (p+" LinkedTo_Group_Pos/String").c_str(), "Full user interactivity"); Fill_SetOptions(Stream_Audio, 0, (p+" LinkedTo_Group_Pos/String").c_str(), "Y NTN"); } else { ZtringList GroupPos, GroupNum; for (size_t i=0; isecond; if (Summary.empty()) Summary="Yes"; string s=string("SwitchGroup")+Ztring::ToZtring(i).To_UTF8(); Fill(Stream_Audio, 0, s.c_str(), Summary); Fill(Stream_Audio, 0, (s+" Pos").c_str(), i); Fill_SetOptions(Stream_Audio, 0, (s+" Pos").c_str(), "N NIY"); Fill(Stream_Audio, 0, (s+" ID").c_str(), S.ID); for (map::const_iterator Desc=S.Description.begin(); Desc!=S.Description.end(); ++Desc) { Ztring Language=MediaInfoLib::Config.Iso639_1_Get(Ztring().From_UTF8(Desc->first)); if (Language.empty()) Language=Ztring().From_UTF8(Desc->first); Fill(Stream_Audio, 0, (s+" Title").c_str(), '('+MediaInfoLib::Config.Language_Get_Translate(__T("Language_"), Language).To_UTF8() + ") "+Desc->second); } Fill(Stream_Audio, 0, (s+" Allow").c_str(), S.allowOnOff?"Yes":"No"); if (S.allowOnOff) Fill(Stream_Audio, 0, (s+" Default").c_str(), S.defaultOnOff?"Yes":"No"); Fill(Stream_Audio, 0, (s+" DefaultGroupID").c_str(), S.DefaultGroupID); ZtringList GroupPos, GroupNum; for (size_t i=0; isecond; if (Summary.empty()) Summary="Yes"; string g=string("Group")+Ztring::ToZtring(i).To_UTF8(); Fill(Stream_Audio, 0, g.c_str(), Summary); Fill(Stream_Audio, 0, (g+" Pos").c_str(), i); Fill_SetOptions(Stream_Audio, 0, (g+" Pos").c_str(), "N NIY"); Fill(Stream_Audio, 0, (g+" ID").c_str(), G.ID); for (map::const_iterator Desc=G.Description.begin(); Desc!=G.Description.end(); ++Desc) { Ztring Language=MediaInfoLib::Config.Iso639_1_Get(Ztring().From_UTF8(Desc->first)); if (Language.empty()) Language=Ztring().From_UTF8(Desc->first); Fill(Stream_Audio, 0, (g+" Title").c_str(), '('+MediaInfoLib::Config.Language_Get_Translate(__T("Language_"), Language).To_UTF8() + ") "+Desc->second); } if (!G.Language.empty()) { Fill(Stream_Audio, 0, (g+" Language").c_str(), G.Language); Fill(Stream_Audio, 0, (g+" Language/String").c_str(), MediaInfoLib::Config.Iso639_Translate(Ztring().From_UTF8(G.Language))); Fill_SetOptions(Stream_Audio, 0, (g+" Language").c_str(), "N NTY"); Fill_SetOptions(Stream_Audio, 0, (g+" Language/String").c_str(), "Y NTN"); } if (G.Kindsecond; Fill_DRC(g.c_str()); C.drcInstructionsUniDrc_Data.clear(); } } if (!Mpegh3da_loudnessInfo_Data[1].empty()) { std::map::iterator Loudness=Mpegh3da_loudnessInfo_Data[1].find(G.ID); if (Loudness!=Mpegh3da_loudnessInfo_Data[1].end()) { C.IFrameParsed=true; C.Reset(false, true); C.loudnessInfo_Data[0]=Loudness->second.Data[0]; Fill_Loudness(g.c_str(), NoLoudnesConch); C.loudnessInfo_Data[0].clear(); } } if (!Mpegh3da_drcInstructionsUniDrc_Data[2].empty()) // Not sure { auto drcInstructionsUniDrc=Mpegh3da_drcInstructionsUniDrc_Data[2].find(G.ID); if (drcInstructionsUniDrc!=Mpegh3da_drcInstructionsUniDrc_Data[2].end()) { C.drcInstructionsUniDrc_Data=drcInstructionsUniDrc->second; Fill_DRC(g.c_str()); C.drcInstructionsUniDrc_Data.clear(); } } if (!Mpegh3da_loudnessInfo_Data[2].empty()) // Not sure { std::map::iterator Loudness=Mpegh3da_loudnessInfo_Data[2].find(G.ID); if (Loudness!=Mpegh3da_loudnessInfo_Data[2].end()) { C.IFrameParsed=true; C.Reset(false, true); C.loudnessInfo_Data[0]=Loudness->second.Data[0]; Fill_Loudness(g.c_str(), NoLoudnesConch); C.loudnessInfo_Data[0].clear(); } } ZtringList GroupPos, GroupNum; for (size_t i=0; iRemain(); switch (usacExtElementType) { case ID_EXT_ELE_FILL: break; // No configuration element //case ID_EXT_ELE_MPEGS: //TODO: SpatialSpecificConfig(); //break; //case ID_EXT_ELE_SAOC: //TODO: SAOCSpecificConfig(); //break; case ID_EXT_ELE_AUDIOPREROLL: break; // No configuration element case ID_EXT_ELE_UNI_DRC: //if (referenceLayout.ChannelLayout!=19) //TEMP mpegh3daUniDrcConfig(); break; case ID_EXT_ELE_OBJ_METADATA: ObjectMetadataConfig(); break; //case ID_EXT_ELE_SAOC_3D: // SAOC3DSpecificConfig(); // break; //case ID_EXT_ELE_HOA: //HOAConfig(); //break; case ID_EXT_ELE_FMT_CNVRTR: break; // No configuration element //case ID_EXT_ELE_MCT: //MCTConfig(); //break; case ID_EXT_ELE_TCC: TccConfig(); break; //case ID_EXT_ELE_HOA_ENH_LAYER: //HOAEnhConfig(); //break; //case ID_EXT_ELE_HREP: //HREPConfig(current_signal_group); //break; //case ID_EXT_ELE_ENHANCED_OBJ_METADATA: //EnhancedObjectMetadataConfig(); //break; break; default: if (usacExtElementConfigLength) Skip_BS(usacExtElementConfigLength*8, "reserved"); break; } if (BS->Remain()+usacExtElementConfigLength*8>Remain_Before) { size_t Size=BS->Remain()+usacExtElementConfigLength*8-Remain_Before; int8u Padding=1; if (Size<8) Peek_S1((int8u)Size, Padding); if (Padding && Remain_Before!=BS->Remain() && usacExtElementType!=ID_EXT_ELE_OBJ_METADATA) Fill(Stream_Audio, 0, "NOK", "NOK", Unlimited, true, true); Skip_BS(Size, Padding?"(Unknown)":"Padding"); } Element_End0(); } //--------------------------------------------------------------------------- bool File_Mpegh3da::mpegh3daCoreConfig() { bool enhancedNoiseFilling; Element_Begin1("mpegh3daCoreConfig"); Skip_SB( "tw_mdct"); Skip_SB( "fullbandLpd"); Skip_SB( "noiseFilling"); TEST_SB_GET(enhancedNoiseFilling, "enhancedNoiseFilling"); Skip_SB( "igfUseEnf"); Skip_SB( "igfUseHighRes"); Skip_SB( "igfUseWhitening"); Skip_SB( "igfAfterTnsSynth"); Skip_S1(5, "igfStartIndex"); Skip_S1(4, "igfStopIndex"); TEST_SB_END(); Element_End0(); return enhancedNoiseFilling; } //--------------------------------------------------------------------------- void File_Mpegh3da::mpegh3daUniDrcConfig() { Element_Begin1("mpegh3daUniDrcConfig"); int8u drcCoefficientsUniDrcCount; Get_S1(3, drcCoefficientsUniDrcCount, "drcCoefficientsUniDrcCount"); int8u drcInstructionsUniDrcCount; Get_S1(6, drcInstructionsUniDrcCount, "drcInstructionsUniDrcCount"); Element_Begin1("mpegh3daUniDrcChannelLayout"); Get_S1 (7, C.baseChannelCount, "baseChannelCount"); Element_End0(); if (!drcCoefficientsUniDrcCount) Fill(Stream_Audio, 0, "TEMP_drcCoefficientsUniDrcCount", drcCoefficientsUniDrcCount); //TEMP for (int8u Pos=0; Posfirst]=C.drcInstructionsUniDrc_Data.begin()->second; C.drcInstructionsUniDrc_Data.clear(); } TEST_SB_SKIP( "uniDrcConfigExtPresent"); uniDrcConfigExtension(); // in File_USAC.cpp TEST_SB_END(); TEST_SB_SKIP( "loudnessInfoSetPresent"); mpegh3daLoudnessInfoSet(); TEST_SB_END(); Element_End0(); } //--------------------------------------------------------------------------- void File_Mpegh3da::downmixConfig() { Element_Begin1("downmixConfig"); int8u downmixConfigType; Get_S1 (2, downmixConfigType, "downmixConfigType"); switch (downmixConfigType) { case 0: case 2: { bool passiveDownmixFlag; Get_SB (passiveDownmixFlag, "passiveDownmixFlag"); if (!passiveDownmixFlag) Skip_S1(3, "phaseAlignStrength"); Skip_SB( "immersiveDownmixFlag"); } break; } switch (downmixConfigType) { case 1: case 2: { Skip_S1(5, "DownmixMatrixSet - TODO"); } break; } Element_End0(); } //--------------------------------------------------------------------------- void File_Mpegh3da::mpegh3daLoudnessInfoSet() { Element_Begin1("mpegh3daLoudnessInfoSet"); int8u loudnessInfoCount; Get_S1(6, loudnessInfoCount, "loudnessInfoCount"); for(int8u Pos=0; Posfirst]=C.loudnessInfo_Data[0].begin()->second; C.loudnessInfo_Data[0].clear(); if (IsNOK) { Element_End0(); return; } } TEST_SB_SKIP( "loudnessInfoAlbumPresent"); int8u loudnessInfoAlbumCount; Get_S1(6, loudnessInfoAlbumCount, "loudnessInfoAlbumCount"); for (int8u Pos=0; Posfirst]=C.loudnessInfo_Data[1].begin()->second; C.loudnessInfo_Data[1].clear(); } TEST_SB_END(); TEST_SB_SKIP( "loudnessInfoSetExtensionPresent"); loudnessInfoSetExtension(); // in File_USAC.cpp TEST_SB_END(); Element_End0(); } //--------------------------------------------------------------------------- void File_Mpegh3da::ObjectMetadataConfig() { Element_Begin1("ObjectMetadataConfig"); Skip_SB( "lowDelayMetadataCoding"); TESTELSE_SB_SKIP( "hasCoreLength"); TESTELSE_SB_ELSE( "hasCoreLength"); Skip_S1(6, "frameLength"); TESTELSE_SB_END(); TEST_SB_SKIP("hasScreenRelativeObjects"); size_t num_objects=num_objects_Get(); for (int16u Pos=0; PosRemain()%8, "byte_align"); //TODO: SAOC3DExtensionConfig(); Element_End0(); } //--------------------------------------------------------------------------- int32u File_Mpegh3da::SAOC3DgetNumChannels(speaker_layout Layout) { int32u ToReturn=Layout.numSpeakers; for (int32u Pos=0; PosPos && Layout.SpeakersInfo[Pos].isLFE) ToReturn--; } return ToReturn; } //--------------------------------------------------------------------------- void File_Mpegh3da::MCTConfig() { Element_Begin1("MCTConfig"); for(int32u chan=0; chanPos && (Elements[Pos].Type==ID_USAC_SCE || Elements[Pos].Type==ID_USAC_CPE)) Skip_S1(2, "tccMode"); } Element_End0(); } //--------------------------------------------------------------------------- void File_Mpegh3da::EnhancedObjectMetadataConfig() { Element_Begin1("EnhancedObjectMetadataConfig"); bool hasCommonGroupExcludedSectors=false; TEST_SB_SKIP( "hasDiffuseness"); Skip_SB( "hasCommonGroupDiffuseness"); TEST_SB_END(); TEST_SB_SKIP( "hasExcludedSectors"); TEST_SB_GET(hasCommonGroupExcludedSectors, "hasCommonGroupExcludedSectors"); Skip_SB( "useOnlyPredefinedSectors"); TEST_SB_END(); TEST_SB_END(); TEST_SB_SKIP( "hasClosestSpeakerCondition"); Skip_S1(7, "closestSpeakerThresholdAngle"); TEST_SB_END(); size_t num_objects=num_objects_Get(); for (int8u Pos=0; PosRemain(); switch ((UsacConfigExtType)usacConfigExtType) { case ID_CONFIG_EXT_FILL: while (usacConfigExtLength) { usacConfigExtLength--; Skip_S1(8, "fill_byte"); // should be '10100101' } break; case ID_CONFIG_EXT_DOWNMIX: downmixConfig(); break; case ID_CONFIG_EXT_LOUDNESS_INFO: mpegh3daLoudnessInfoSet(); break; case ID_CONFIG_EXT_AUDIOSCENE_INFO: mae_AudioSceneInfo(); break; //case ID_CONFIG_EXT_HOA_MATRIX: // HoaRenderingMatrixSet(); // break; case ID_CONFIG_EXT_ICG: ICGConfig(); break; case ID_CONFIG_EXT_SIG_GROUP_INFO: SignalGroupInformation(); break; case ID_CONFIG_EXT_COMPATIBLE_PROFILE_LEVEL_SET: CompatibleProfileLevelSet(); break; default: Skip_BS(usacConfigExtLength*8, "reserved"); } if (BS->Remain()+usacConfigExtLength*8>Remain_Before) { size_t Size=BS->Remain()+usacConfigExtLength*8-Remain_Before; int8u Padding=1; if (Size<8) Peek_S1((int8u)Size, Padding); if (Padding && Remain_Before!=BS->Remain() && usacConfigExtType!=ID_CONFIG_EXT_DOWNMIX && usacConfigExtType!=ID_CONFIG_EXT_HOA_MATRIX) Fill(Stream_Audio, 0, "NOK", "NOK", Unlimited, true, true); Skip_BS(Size, Padding?"(Unknown)":"Padding"); } Element_End0(); } Element_End0(); } //--------------------------------------------------------------------------- void File_Mpegh3da::SignalGroupInformation() { Element_Begin1("SignalGroupInformation"); for (int8u Pos=0; PosPos && Elements[Pos].Type==ID_USAC_CPE) Skip_SB( "ICinCPE"); } TEST_SB_SKIP( "ICGPreAppliedPresent"); for (int32u Pos=0; PosPos && Elements[Pos].Type==ID_USAC_CPE) Skip_SB( "ICGPreAppliedCPE"); } TEST_SB_END(); TEST_SB_END(); Element_End0(); } //--------------------------------------------------------------------------- void File_Mpegh3da::mae_AudioSceneInfo() { Groups.clear(); SwitchGroups.clear(); GroupPresets.clear(); Element_Begin1("mae_AudioSceneInfo"); bool mae_isMainStream; TESTELSE_SB_GET (mae_isMainStream, "mae_isMainStream"); TEST_SB_SKIP( "mae_audioSceneInfoIDPresent"); Get_S1 (8, audioSceneInfoID, "mae_audioSceneInfoID"); TEST_SB_END(); int8u mae_numGroups; Get_S1(7, mae_numGroups, "mae_numGroups"); mae_GroupDefinition(mae_numGroups); int8u mae_numSwitchGroups; Get_S1(5, mae_numSwitchGroups, "mae_numSwitchGroups"); mae_SwitchGroupDefinition(mae_numSwitchGroups); int8u mae_numGroupPresets; Get_S1(5, mae_numGroupPresets, "mae_numGroupPresets"); mae_GroupPresetDefinition(mae_numGroupPresets); mae_Data(mae_numGroups, mae_numGroupPresets); Skip_S1(7, "mae_metaDataElementIDmaxAvail"); TESTELSE_SB_ELSE( "mae_isMainStream"); Skip_S1(7, "mae_bsMetaDataElementIDoffset"); Skip_S1(7, "mae_metaDataElementIDmaxAvail"); TESTELSE_SB_END(); Element_End0(); isMainStream=mae_isMainStream; } //--------------------------------------------------------------------------- void File_Mpegh3da::mae_GroupDefinition(int8u numGroups) { Element_Begin1("mae_GroupDefinition"); Groups.resize(numGroups); for (int8u Pos=0; PosRemain(); switch ((MaeDataType)mae_dataType) { case ID_MAE_GROUP_DESCRIPTION: case ID_MAE_SWITCHGROUP_DESCRIPTION: case ID_MAE_GROUP_PRESET_DESCRIPTION: mae_Description((MaeDataType)mae_dataType); break; case ID_MAE_GROUP_CONTENT: mae_ContentData(); break; case ID_MAE_GROUP_COMPOSITE: mae_CompositePair(); break; case ID_MAE_SCREEN_SIZE: mae_ProductionScreenSizeData(); break; case ID_MAE_DRC_UI_INFO: mae_DrcUserInterfaceInfo(mae_dataLength); break; case ID_MAE_SCREEN_SIZE_EXTENSION: mae_ProductionScreenSizeDataExtension(); break; case ID_MAE_GROUP_PRESET_EXTENSION: mae_GroupPresetDefinitionExtension(numGroupPresets); break; case ID_MAE_LOUDNESS_COMPENSATION: mae_LoudnessCompensationData(numGroups, numGroupPresets); break; default: Skip_BS(mae_dataLength*8, "reserved"); } if (BS->Remain()+mae_dataLength*8>Remain_Before) { size_t Size=BS->Remain()+mae_dataLength*8-Remain_Before; int8u Padding=1; if (Size<8) Peek_S1((int8u)Size, Padding); if (Padding) Fill(Stream_Audio, 0, "NOK", "NOK", Unlimited, true, true); Skip_BS(Size, Padding?"(Unknown)":"Padding"); } Element_End0(); } Element_End0(); } //--------------------------------------------------------------------------- void File_Mpegh3da::mae_Description(MaeDataType type) { Element_Info1("mae_Description"); Element_Begin1("mae_Description"); int8u mae_bsNumDescriptionBlocks; Get_S1(7, mae_bsNumDescriptionBlocks, "mae_bsNumDescriptionBlocks"); mae_bsNumDescriptionBlocks++; for (int8u Pos=0; Pos=0; i-=8) { char LanguageChar=char(mae_bsDescriptionLanguage>>i); if (LanguageChar) Language+=LanguageChar; } Param_Info1(Language); Element_Info1(Language); int8u mae_bsDescriptionDataLength; Get_S1(8, mae_bsDescriptionDataLength, "mae_bsDescriptionDataLength"); mae_bsDescriptionDataLength++; string Description; Description.reserve(mae_bsDescriptionDataLength); for (int8u Pos3=0; Pos3=0; i-=8) { char LanguageChar=char(mae_contentLanguage>>i); if (LanguageChar) Language+=LanguageChar; } Param_Info1(Language); Element_Info1(Language); TEST_SB_END(); for (size_t i=0; i2) bsNumTargetLoudnessConditions_Real=(dataLength*8-(2+3))/(6+16); else bsNumTargetLoudnessConditions_Real=0; if (bsNumTargetLoudnessConditions!=bsNumTargetLoudnessConditions_Real) Param_Info1("Error"); for (int16u Pos=0; Pos3 || (ChannelMode.size()==3 && ChannelMode[2]!='0')) ChannelString+=" ("+Aac_ChannelMode_GetString(Layout.ChannelLayout, true)+")"; Fill(Stream_Audio, 0, (Prefix+"Channel(s)/String").c_str(), ChannelString); Fill_SetOptions(Stream_Audio, 0, (Prefix + "Channel(s)/String").c_str(), "Y NTN"); } Fill(Stream_Audio, 0, (Prefix+"ChannelPositions").c_str(), Aac_ChannelConfiguration_GetString(Layout.ChannelLayout)); if (!Prefix.empty()) Fill_SetOptions(Stream_Audio, 0, (Prefix+"ChannelPositions").c_str(), "N YTY"); Fill(Stream_Audio, 0, (Prefix+"ChannelPositions/String2").c_str(), Aac_ChannelConfiguration2_GetString(Layout.ChannelLayout)); if (!Prefix.empty()) Fill_SetOptions(Stream_Audio, 0, (Prefix+"ChannelPositions/String2").c_str(), "N YTY"); Fill(Stream_Audio, 0, (Prefix+"ChannelMode").c_str(), Aac_ChannelMode_GetString(Layout.ChannelLayout, true)); Fill_SetOptions(Stream_Audio, 0, (Prefix+"ChannelMode").c_str(), "N NTY"); Fill(Stream_Audio, 0, (Prefix+"ChannelLayout").c_str(), Aac_ChannelLayout_GetString(Layout.ChannelLayout, true)); } else if (Layout.numSpeakers) { if (speakerLayoutType==1) // Objects { Fill(Stream_Audio, 0, (Prefix+"NumberOfObjects").c_str(), Layout.numSpeakers); Fill_SetOptions(Stream_Audio, 0, (Prefix+"NumberOfObjects").c_str(), "N YTY"); Fill(Stream_Audio, 0, (Prefix + "NumberOfObjects/String").c_str(), MediaInfoLib::Config.Language_Get(Ztring::ToZtring(Layout.numSpeakers), __T(" object"))); Fill_SetOptions(Stream_Audio, 0, (Prefix+"NumberOfObjects/String").c_str(), "Y YTN"); } else { Fill(Stream_Audio, 0, (Prefix+"Channel(s)").c_str(), Layout.numSpeakers); Fill_SetOptions(Stream_Audio, 0, (Prefix+"Channel(s)").c_str(), "N YTY"); Fill(Stream_Audio, 0, (Prefix + "Channel(s)/String").c_str(), MediaInfoLib::Config.Language_Get(Ztring::ToZtring(Layout.numSpeakers), __T(" channel"))); Fill_SetOptions(Stream_Audio, 0, (Prefix+"Channel(s)/String").c_str(), "Y YTN"); } if (!Layout.CICPspeakerIdxs.empty()) { Fill(Stream_Audio, 0, (Prefix+"ChannelMode").c_str(), Aac_ChannelMode_GetString(Layout.CICPspeakerIdxs)); Fill(Stream_Audio, 0, (Prefix+"ChannelLayout").c_str(), Aac_ChannelLayout_GetString(Layout.CICPspeakerIdxs)); } else { vector CICPspeakerIdxs; string ChannelLayout; for (size_t i=0; i