/* 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_MGA_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Audio/File_Mga.h" #if defined(MEDIAINFO_ADM_YES) #include "MediaInfo/Audio/File_Adm.h" #endif #if defined(MEDIAINFO_ADM_YES) #include #endif #include using namespace std; //--------------------------------------------------------------------------- namespace MediaInfoLib { //*************************************************************************** // Info //*************************************************************************** //--------------------------------------------------------------------------- static const char* Mga_Section_Names[]= { "Audio Essence", "Audio Metadata Pack", "Audio Metadata Payload", "UL-defined metadata", }; static const size_t Mga_Section_Names_Size=sizeof(Mga_Section_Names)/sizeof(*Mga_Section_Names); //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_Mga::File_Mga() :File__Analyze() { //Configuration #if MEDIAINFO_TRACE Trace_Layers_Update(8); //Stream #endif //MEDIAINFO_TRACE StreamSource=IsStream; //In Frame_Count_Valid=5; // Needed for catching 1.001 frame rates in ADM //Temp Parser=nullptr; } //--------------------------------------------------------------------------- File_Mga::~File_Mga() { delete Parser; } //*************************************************************************** // Streams management //*************************************************************************** //--------------------------------------------------------------------------- void File_Mga::Streams_Accept() { //Filling Stream_Prepare(Stream_Audio); Fill(Stream_Audio, 0, Audio_Format, "MGA"); } void File_Mga::Streams_Finish() { //Filling if (Parser) { Finish(Parser); Merge(*Parser, Stream_Audio, 0, 0); } } //*************************************************************************** // Buffer - Per element //*************************************************************************** //--------------------------------------------------------------------------- void File_Mga::Header_Parse() { //Temp Accept(); //Parsing int8u SectionCount; Get_B1 (SectionCount, "Section Count"); for (int8u i=0; iElement_Size || Element_Size-Element_Offset<6) { Element_WaitForMoreData(); return; } Element_Offset+=2; Element_Offset+=4+BigEndian2int32u(Buffer+Buffer_Offset+(size_t)Element_Offset); } //Filling Header_Fill_Size(Element_Offset); Header_Fill_Code(SectionCount, "MGA Frame"); Element_Offset=1; } //--------------------------------------------------------------------------- void File_Mga::Data_Parse() { int8u SectionCount=(int8u)Element_Code; //Parsing for (int8u i=0; i=Frame_Count_Valid) { Fill(); Finish(); } FILLING_END() } //*************************************************************************** // Elements //*************************************************************************** //--------------------------------------------------------------------------- void File_Mga::AudioMetadataPayload() { //Parsing Element_Begin1("Audio Metadata Payload"); Element_Begin1("Header"); int64u Tag, Length; Get_BER(Tag, "Tag"); Get_BER(Length, "Length"); Element_End0(); auto End=Element_Offset+Length; switch (Tag) { case 0x12 : SerialAudioDefinitionModelMetadataPayload(Length); break; default : Element_Name(to_string(Tag).c_str()); break; } if (Element_Offset1) return; int8u* UncompressedData=NULL; size_t UncompressedData_Size=0; if (Format==1) { //Uncompress init z_stream strm; strm.next_in=(Bytef*)Buffer+Buffer_Offset+(size_t)Element_Offset; strm.avail_in=(int)(Length-2); strm.next_out=NULL; strm.avail_out=0; strm.total_out=0; strm.zalloc=Z_NULL; strm.zfree=Z_NULL; inflateInit2(&strm, 15+16); // 15 + 16 are magic values for gzip //Prepare out strm.avail_out=0x10000; //Blocks of 64 KiB, arbitrary chosen, as a begin strm.next_out=(Bytef*)new Bytef[strm.avail_out]; //Parse compressed data, with handling of the case the output buffer is not big enough for (;;) { //inflate int inflate_Result=inflate(&strm, Z_NO_FLUSH); if (inflate_Result<0) break; //Check if we need to stop if (strm.avail_out || inflate_Result) break; //Need to increase buffer size_t UncompressedData_NewMaxSize=strm.total_out*4; int8u* UncompressedData_New=new int8u[UncompressedData_NewMaxSize]; memcpy(UncompressedData_New, strm.next_out-strm.total_out, strm.total_out); delete[](strm.next_out - strm.total_out); strm.next_out=UncompressedData_New; strm.next_out=strm.next_out+strm.total_out; strm.avail_out=UncompressedData_NewMaxSize-strm.total_out; } UncompressedData=strm.next_out-strm.total_out; UncompressedData_Size=strm.total_out; inflateEnd(&strm); } #if defined(MEDIAINFO_ADM_YES) { if (UncompressedData || Element_OffsetMuxingMode="SMPTE ST 2127-1 / SMPTE ST 2109 / SMPTE ST 2127-10"; Open_Buffer_Init(Parser); } } #else { //Filling if (!Parser) { Parser=new File_Unknown(); Open_Buffer_Init(Parser); Parser->Accept(); Parser->Stream_Prepare(Stream_Audio); Parser->Fill(Stream_Audio, 0, "Metadata_Format", "ADM"); Parser->Finish(); } } #endif } if (Parser) { if (UncompressedData) { Open_Buffer_Continue(Parser, UncompressedData, UncompressedData_Size); delete[] UncompressedData; } else { Open_Buffer_Continue(Parser, Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Length-2)); } } Element_End0(); } //*************************************************************************** // Helpers //*************************************************************************** //--------------------------------------------------------------------------- void File_Mga::Get_BER(int64u &Value, const char* Name) { int8u Length; Get_B1(Length, Name); if (Length<0x80) { Value=Length; //1-byte return; } Length&=0x7F; switch (Length) { case 1 : { int8u Length1; Get_B1(Length1, Name); Value=Length1; break; } case 2 : { int16u Length2; Get_B2(Length2, Name); Value=Length2; break; } case 3 : { int32u Length3; Get_B3(Length3, Name); Value=Length3; break; } case 4 : { int32u Length4; Get_B4(Length4, Name); Value=Length4; break; } case 5 : { int64u Length5; Get_B5(Length5, Name); Value=Length5; break; } case 6 : { int64u Length6; Get_B6(Length6, Name); Value=Length6; break; } case 7 : { int64u Length7; Get_B7(Length7, Name); Value=Length7; break; } case 8 : { int64u Length8; Get_B8(Length8, Name); Value=Length8; break; } default:Value=(int64u)-1; //Problem } } } //NameSpace #endif //MEDIAINFO_MGA_YES