/* 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_SMPTEST0302_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Audio/File_SmpteSt0302.h" #if defined(MEDIAINFO_PCM_YES) #include "MediaInfo/Audio/File_Pcm.h" #endif #if defined(MEDIAINFO_SMPTEST0337_YES) #include "MediaInfo/Audio/File_SmpteSt0337.h" #endif #if MEDIAINFO_EVENTS #include "MediaInfo/MediaInfo_Events.h" #endif //MEDIAINFO_EVENTS #if MEDIAINFO_DEMUX #include "MediaInfo/MediaInfo_Config_MediaInfo.h" #endif //MEDIAINFO_EVENTS //--------------------------------------------------------------------------- namespace MediaInfoLib { //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_SmpteSt0302::File_SmpteSt0302() :File__Analyze() { //Configuration #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_Aes3; #endif //MEDIAINFO_EVENTS PTS_DTS_Needed=true; StreamSource=IsStream; } //--------------------------------------------------------------------------- File_SmpteSt0302::~File_SmpteSt0302() { for (size_t Pos=0; PosBitDepth=(4+bits_per_sample)*4; SmpteSt0337->Endianness='L'; SmpteSt0337->Aligned=true; #if MEDIAINFO_DEMUX if (Config->Demux_Unpacketize_Get()) { Demux_Level=4; //Intermediate SmpteSt0337->Demux_Level=2; //Container SmpteSt0337->Demux_UnpacketizeContainer=true; } #endif //MEDIAINFO_DEMUX Parsers.push_back(SmpteSt0337); } #endif // MEDIAINFO_SMPTEST0337_YES #ifdef MEDIAINFO_PCM_YES // Raw PCM { File_Pcm* Pcm=new File_Pcm(); Pcm->Codec.From_UTF8("SMPTE ST 302"); Pcm->BitDepth=(4+bits_per_sample)*4; Pcm->Channels=(1+number_channels)*2; Pcm->SamplingRate=48000; Pcm->Endianness='L'; #if MEDIAINFO_DEMUX if (Config->Demux_Unpacketize_Get()) { Demux_Level=4; //Intermediate Pcm->Demux_Level=2; //Container Pcm->Demux_UnpacketizeContainer=true; } #endif //MEDIAINFO_DEMUX Parsers.push_back(Pcm); } // Init for (size_t Pos=0; PosStatus[IsAccepted]) { Fill(Parsers[0]); Merge(*Parsers[0]); } for (size_t Pos=0; PosStatus[IsAccepted]) { Finish(Parsers[0]); for (size_t Pos=0; PosRetrieve(Stream_Audio, Pos, Audio_Duration).empty()) Fill(Stream_Audio, Pos, Audio_Duration, Parsers[0]->Retrieve(Stream_Audio, Pos, Audio_Duration), true); if (!Parsers[0]->Retrieve(Stream_Audio, Pos, Audio_FrameCount).empty()) Fill(Stream_Audio, Pos, Audio_FrameCount, Parsers[0]->Retrieve(Stream_Audio, Pos, Audio_FrameCount), true); } } } //*************************************************************************** // Buffer - Global //*************************************************************************** //--------------------------------------------------------------------------- static inline int8u Reverse8(int n) { // Input: bit order is 76543210 //Output: bit order is 45670123 n=((n>>1)&0x55) | ((n<<1) & 0xaa); n=((n>>2)&0x33) | ((n<<2) & 0xcc); n=((n>>4)&0x0f) | ((n<<4) & 0xf0); return (int8u)n; } //--------------------------------------------------------------------------- void File_SmpteSt0302::Read_Buffer_Continue() { //Parsing Get_B2 (audio_packet_size, "audio_packet_size"); BS_Begin(); Get_S1 (2, number_channels, "number_channels"); Param_Info2((1+number_channels)*2, " channels"); Info_S1(8, channel_identification, "channel_identification"); Get_S1 (2, bits_per_sample, "bits_per_sample"); Param_Info2((4+bits_per_sample)*4, " bits"); Info_S1(4, alignment_bits, "alignment_bits"); BS_End(); //Enough data if (Element_Size<4+(int64u)audio_packet_size) { Element_Offset=0; Element_WaitForMoreData(); return; } //Cohenrancy test if (Element_Size!=4+(int64u)audio_packet_size || bits_per_sample==3 || audio_packet_size%((1+number_channels)*(5+bits_per_sample))) { Trusted_IsNot("Wrong size"); Skip_XX(Element_Size-4, "Problem?"); return; } if (!Status[IsAccepted]) Accept("SMPTE ST 302"); //Decyphering size_t PcmSize=0; float64 Ratio=0; switch (bits_per_sample) { case 0 : PcmSize=audio_packet_size*4/5; Ratio=4.0/5.0; break; case 1 : PcmSize=audio_packet_size*5/6; Ratio=5.0/6.0; break; case 2 : PcmSize=audio_packet_size*6/7; Ratio=6.0/7.0; break; case 3 : Reject(); return; default: ; } int8u* Info=new int8u[PcmSize]; size_t Info_Offset=0; while (Element_Offset>4 ); Info[Info_Offset+3]=(Reverse8(Buffer[Buffer_Pos+4])<<4 ) | (Reverse8(Buffer[Buffer_Pos+3])>>4 ); Info_Offset+=4; Element_Offset+=5; break; case 1 : //20 bits // Source: L1L0 L3L2 XXL4 R1R0 R3R2 XXR4 // Dest : 20LE / L1L0 L3L2 R0L4 R2R1 R4R3 Info[Info_Offset+0]= Reverse8(Buffer[Buffer_Pos+0]) ; Info[Info_Offset+1]= Reverse8(Buffer[Buffer_Pos+1]) ; Info[Info_Offset+2]=(Reverse8(Buffer[Buffer_Pos+3])<<4 ) | (Reverse8(Buffer[Buffer_Pos+2])&0x0F); Info[Info_Offset+3]=(Reverse8(Buffer[Buffer_Pos+4])<<4 ) | (Reverse8(Buffer[Buffer_Pos+3])>>4 ); Info[Info_Offset+4]=(Reverse8(Buffer[Buffer_Pos+5])<<4 ) | (Reverse8(Buffer[Buffer_Pos+4])>>4 ); Info_Offset+=5; Element_Offset+=6; break; case 2 : //24 bits // Source: L1L0 L3L2 L5L4 R0XX R2R1 R4R3 XXR5 // Dest : 16LE / L1L0 L3L2 L5L4 R1R0 R3R2 R5R4 Info[Info_Offset+0] = Reverse8(Buffer[Buffer_Pos+0]) ; Info[Info_Offset+1] = Reverse8(Buffer[Buffer_Pos+1]) ; Info[Info_Offset+2] = Reverse8(Buffer[Buffer_Pos+2]) ; Info[Info_Offset+3] =(Reverse8(Buffer[Buffer_Pos+4])<<4 ) | (Reverse8(Buffer[Buffer_Pos+3])>>4 ); Info[Info_Offset+4] =(Reverse8(Buffer[Buffer_Pos+5])<<4 ) | (Reverse8(Buffer[Buffer_Pos+4])>>4 ); Info[Info_Offset+5] =(Reverse8(Buffer[Buffer_Pos+6])<<4 ) | (Reverse8(Buffer[Buffer_Pos+5])>>4 ); Info_Offset+=6; Element_Offset+=7; break; default : ; } } Element_Offset=4; FrameInfo.PTS=FrameInfo.DTS; FrameInfo.DUR=((int64u)audio_packet_size)*1000000000/((1+number_channels)*(5+bits_per_sample)*48000); #if MEDIAINFO_DEMUX Demux_random_access=true; Demux(Info, Info_Offset, ContentType_MainStream); #endif //MEDIAINFO_DEMUX //Parsers for (size_t Pos=0; PosFrameInfo=FrameInfo; Open_Buffer_Continue(Parsers[Pos], Info, Info_Offset, true, Ratio); if (Parsers.size()>1 && Parsers[Pos]->Status[IsAccepted]) { for (size_t Pos2=0; Pos21 && Frame_Count>=2) { for (size_t Pos=0; PosStatus[IsFinished]) { //Filling Finish("SMPTE ST 302"); } } //*************************************************************************** // C++ //*************************************************************************** } //NameSpace #endif //MEDIAINFO_SMPTEST0302_YES