//--------------------------------------------------------------------------- bool File_DolbyE::Descramble_20bit () { int32u ScrambleMask; Get_S3 (20, ScrambleMask, "Scramble mask"); int16u Size=((BigEndian2int16u(Buffer+Buffer_Offset+(size_t)Element_Size-Data_BS_Remain()/8)^(ScrambleMask>>4))>>2)&0x3FF; if (Data_BS_Remain()<(size_t)((Size+1)*BitDepth)) //+1 for additional unknown word return false; //There is a problem int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8; int64u ScrambleMasks=(((int64u)ScrambleMask)<<20)|ScrambleMask; bool Half; if (Data_BS_Remain()%8) { Temp--; int24u2BigEndian(Temp, BigEndian2int24u(Temp)^(ScrambleMask)); Half=true; } else Half=false; for (int16u Pos=0; Pos<Size-(Half?1:0); Pos+=2) int40u2BigEndian(Temp+(Half?3:0)+Pos*5/2, BigEndian2int40u(Temp+(Half?3:0)+Pos*5/2)^ScrambleMasks); if ((Size-((Size && Half)?1:0))%2==0) int24u2BigEndian(Temp+(Half?3:0)+(Size-((Size && Half)?1:0))*5/2, BigEndian2int24u(Temp+(Half?3:0)+(Size-((Size && Half)?1:0))*5/2)^(((int32u)ScrambleMasks)<<4)); return true; }
//--------------------------------------------------------------------------- bool File_DolbyE::Descramble_24bit () { int32u ScrambleMask; Get_S3 (24, ScrambleMask, "Scramble mask"); int32u Size=((BigEndian2int24u(Buffer+Buffer_Offset+(size_t)Element_Size-Data_BS_Remain()/8)^ScrambleMask)>>2)&0x3FF; if (Data_BS_Remain()<(size_t)((Size+1)*BitDepth)) //+1 for additional unknown word return false; //There is a problem int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8; for (int16u Pos=0; Pos<Size; Pos++) int24u2BigEndian(Temp+Pos*2, BigEndian2int24u(Temp+Pos*2)^ScrambleMask); return true; }
//--------------------------------------------------------------------------- void File_Aac::ALSSpecificConfig() { //Not in spec, but something weird in the example I have int32u Junk; while (Data_BS_Remain()) { Peek_S4(32, Junk); if (Junk!=0x414C5300) { Skip_SB( "Unknown"); } else break; } if (Data_BS_Remain()==0) return; //There is a problem Element_Begin1("ALSSpecificConfig"); bool chan_config,chan_sort,crc_enabled,aux_data_enabled; int32u samp_freq, samples; int16u channels,frame_length; int8u ra_flag,random_access, file_type; Skip_BS(32,"als_id"); Get_BS (32, samp_freq, "samp_freq"); Get_BS (32, samples, "samples"); Get_S2 (16, channels, "channels"); Param_Info2(channels+1, " channel(s)"); Get_S1 (3, file_type, "file_type"); Skip_S1(3,"resolution"); Skip_SB("floating"); Skip_SB("msb_first"); Get_S2 (16,frame_length,"frame_length"); Get_S1 (8,random_access,"random_access"); Get_S1 (2,ra_flag,"ra_flag"); Skip_SB("adapt_order"); Skip_S1(2,"coef_table"); Skip_SB("long_term_prediction"); Skip_S2(10,"max_order"); Skip_S1(2,"block_switching"); Skip_SB("bgmc_mode"); Skip_SB("sb_part"); Skip_SB("joint_stereo"); Skip_SB("mc_coding"); Get_SB (chan_config,"chan_config"); Get_SB (chan_sort,"chan_sort"); Get_SB (crc_enabled,"crc_enabled"); Skip_SB("RLSLMS"); Skip_BS(5,"(reserved)"); Get_SB (aux_data_enabled,"aux_data_enabled"); if (chan_config) Skip_S2(16,"chan_config_info"); if (chan_sort) { int16u ChBits=(int16u)ceil(log((double)(channels+1))/log((double)2)); for (int8u c=0; c<=channels; c++) Skip_BS(ChBits, "chan_pos[c]"); } if(Data_BS_Remain()%8) Skip_S1(Data_BS_Remain()%8, "byte_align"); BS_End(); int32u header_size,trailer_size; Get_B4(header_size, "header_size"); Get_B4(trailer_size, "trailer_size"); #ifdef MEDIAINFO_RIFF_YES if (file_type==1) //WAVE file { Element_Begin1("orig_header"); File_Riff MI; Open_Buffer_Init(&MI); Open_Buffer_Continue(&MI, Buffer+Buffer_Offset+(size_t)Element_Offset, header_size); Element_Offset+=header_size; File__Analyze::Finish(&MI); //No merge of data, only for trace information, because this is the data about the decoded stream, not the encoded stream Element_End0(); } else #endif //MEDIAINFO_RIFF_YES Skip_XX(header_size, "orig_header[]"); Skip_XX(trailer_size, "orig_trailer[]"); if (crc_enabled) Skip_B4( "crc"); if ((ra_flag == 2) && (random_access > 0)) for (int32u f=0; f<((samples-1)/(frame_length+1))+1; f++) Skip_B4( "ra_unit_size[f]"); if (aux_data_enabled) { int32u aux_size; Get_B4(aux_size, "aux_size"); Skip_XX(aux_size, "aux_data[]"); } Element_End0(); BS_Begin(); //To be in sync with other objectTypes FILLING_BEGIN(); //Filling File__Analyze::Stream_Prepare(Stream_Audio); Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, channels+1); //Forcing default confignuration (something weird in the example I have) channelConfiguration=0; sampling_frequency_index=(int8u)-1; sampling_frequency=samp_freq; FILLING_END(); }
//--------------------------------------------------------------------------- // AAC in ES, 2+ bytes void File_Mpeg4_AudioSpecificConfig::Read_Buffer_Continue() { //Parsing Element_Offset=0; Element_Size=Buffer_Size; int8u samplingFrequencyIndex; BS_Begin(); Get_S1 (5, audioObjectType, "audioObjectType"); Param_Info(MP4_Profile(audioObjectType)); if (audioObjectType==31) { int8u audioObjectTypeExt; Get_S1 (6, audioObjectTypeExt, "audioObjectTypeExt"); audioObjectType=32+audioObjectTypeExt; Param_Info(audioObjectType); Param_Info(MP4_Profile(audioObjectType)); } if (audioObjectType==36) { ALS(); return; } Get_S1 (4, samplingFrequencyIndex, "samplingFrequencyIndex"); Param_Info(MP4_SamplingRate[samplingFrequencyIndex]); if (samplingFrequencyIndex>=0xF) { Get_S3 (24, samplingFrequency, "samplingFrequency"); } else samplingFrequency=MP4_SamplingRate[samplingFrequencyIndex]; Get_S1 (4, channelConfiguration, "channelConfiguration"); Param_Info(MP4_ChannelConfiguration[channelConfiguration]); sbrPresentFlag=false; psPresentFlag=false; if (audioObjectType==0x05 || audioObjectType==0x29) { extensionAudioObjectType=audioObjectType; sbrPresentFlag=true; if (audioObjectType==0x29) psPresentFlag=false; Get_S1 (4, samplingFrequencyIndex, "extensionSamplingFrequencyIndex"); Param_Info(MP4_SamplingRate[samplingFrequencyIndex]); if (samplingFrequencyIndex==0xF) { Get_S3 (24, samplingFrequency, "extensionSamplingFrequency"); } else samplingFrequency=MP4_SamplingRate[samplingFrequencyIndex]; Get_S1 (5, audioObjectType, "audioObjectType"); Param_Info(MP4_Profile(audioObjectType)); if (audioObjectType==31) { int8u audioObjectTypeExt; Get_S1 (6, audioObjectTypeExt, "audioObjectTypeExt"); audioObjectType=32+audioObjectTypeExt; Param_Info(MP4_Profile(audioObjectType)); } if (audioObjectType==22) //BSAC Skip_S1(4, "extensionChannelConfiguration"); } else extensionAudioObjectType=0x00; switch(audioObjectType) { case 1: case 2: case 3: case 4: case 6: case 7: case 17: case 19: case 20: case 21: case 22: case 23: GASpecificConfig(); break; case 8: //CelpSpecificConfig(); break; case 9: //HvxcSpecificConfig(); break; case 12: //TTSSpecificConfig(); break; case 13: case 14: case 15: case 16: //StructuredAudioSpecificConfig(); break; case 24: //ErrorResilientCelpSpecificConfig(); break; case 25: //ErrorResilientHvxcSpecificConfig(); break; case 26: case 27: //ParametricSpecificConfig(); break; case 28: //SSCSpecificConfig(); break; case 32: case 33: case 34: //MPEG_1_2_SpecificConfig(); break; case 35: //DSTSpecificConfig(); break; default: ; } switch (audioObjectType) { case 17: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: { int8u epConfig; Get_S1 (2, epConfig, "epConfig"); if (epConfig==2 || epConfig==3) { //ErrorProtectionSpecificConfig(); } if (epConfig==3) { bool directMapping; Get_SB (directMapping, "directMapping"); if (directMapping) { //tbd } } } default : ; } if (extensionAudioObjectType!=0x05 && Data_BS_Remain()>=16) SBR(); BS_End(); //Handling implicit SBR and PS bool Is3GP=false; for (size_t Pos=0; Pos<ftyps.size(); Pos++) if ((ftyps[Pos]&0xFFFFFF00)==0x33677000) Is3GP=true; if (!Is3GP) //If this is not a 3GP file { if (!sbrPresentFlag && samplingFrequency<=24000) { samplingFrequency*=2; sbrPresentFlag=true; } if (!psPresentFlag && channelConfiguration<=1) //1 channel psPresentFlag=true; } FILLING_BEGIN() Accept("AudioSpecificConfig"); if (Count_Get(Stream_Audio)==0) //May be done elsewhere Stream_Prepare(Stream_Audio); Fill(Stream_Audio, StreamPos_Last, Audio_Format, MP4_Format(audioObjectType)); Fill(Stream_Audio, StreamPos_Last, Audio_Format_Version, "Version 4"); Fill(Stream_Audio, StreamPos_Last, Audio_Format_Profile, MP4_Format_Profile(audioObjectType)); if (audioObjectType==2) //LC Fill(Stream_Audio, StreamPos_Last, Audio_Format_Settings_SBR, "No"); if (!sbrPresentFlag && !psPresentFlag) Fill(Stream_Audio, StreamPos_Last, Audio_Codec, MP4_Profile(audioObjectType)); Fill(Stream_Audio, StreamPos_Last, Audio_SamplingRate, samplingFrequency); if (channelConfiguration && channelConfiguration<8) { Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, MP4_Channels[channelConfiguration]); Fill(Stream_Audio, StreamPos_Last, Audio_ChannelPositions, MP4_ChannelConfiguration[channelConfiguration]); Fill(Stream_Audio, StreamPos_Last, Audio_ChannelPositions_String2, MP4_ChannelConfiguration2[channelConfiguration]); } if (sbrPresentFlag) { Fill(Stream_Audio, StreamPos_Last, Audio_Format_Settings, "SBR"); Fill(Stream_Audio, StreamPos_Last, Audio_Format_Settings_SBR, "Yes", Unlimited, true, true); Fill(Stream_Audio, StreamPos_Last, Audio_Format_Settings_PS, "No"); Fill(Stream_Audio, StreamPos_Last, Audio_Codec, Ztring().From_Local(MP4_Profile(audioObjectType))+_T("/SBR"), true); Fill(Stream_Audio, StreamPos_Last, Audio_SamplingRate, samplingFrequency, 10, true); } if (psPresentFlag) { Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, 2, 10, true); Fill(Stream_Audio, StreamPos_Last, Audio_Format_Settings, "PS"); Fill(Stream_Audio, StreamPos_Last, Audio_Format_Settings_PS, "Yes", Unlimited, true, true); Ztring Codec=Retrieve(Stream_Audio, StreamPos_Last, Audio_Codec); Fill(Stream_Audio, StreamPos_Last, Audio_Codec, Ztring().From_Local(MP4_Profile(audioObjectType))+(sbrPresentFlag?_T("/SBR"):_T(""))+_T("/PS"), true); Fill(Stream_Audio, StreamPos_Last, Audio_ChannelPositions, "Front: L R", Unlimited, true, true); } }
//--------------------------------------------------------------------------- void File_DolbyE::Block() { //Parsing Skip_S3(BitDepth, "Synchro"); if (ScrambledBitStream) { //We must change the buffer switch (BitDepth) { case 16 : if (!Descramble_16bit()) return; break; case 20 : if (!Descramble_20bit()) return; break; case 24 : if (!Descramble_24bit()) return; break; default : ; } } Skip_S2(14, "Unknown"); Get_S1 ( 6, ProgramConfiguration, "Program configuration"); Param_Info1(DolbyE_ChannelPositions[ProgramConfiguration]); Get_S1 ( 4, FrameRate, "Frame rate 1"); Param_Info3(Mpegv_frame_rate[FrameRate], 3, " fps"); Skip_S1( 4, "Frame rate 2? Always same as Frame rate 1"); Skip_S2(16, "Frame number?"); Element_Begin1("SMPTE time code?"); int8u Frames_Units, Frames_Tens, Seconds_Units, Seconds_Tens, Minutes_Units, Minutes_Tens, Hours_Units, Hours_Tens; bool DropFrame; Skip_S1(4, "BG8"); Skip_S1(4, "BG7"); Skip_SB( "BGF2 / Field Phase"); Skip_SB( "BGF1"); Get_S1 (2, Hours_Tens, "Hours (Tens)"); Get_S1 (4, Hours_Units, "Hours (Units)"); Skip_S1(4, "BG6"); Skip_S1(4, "BG5"); Skip_SB( "BGF0 / BGF2"); Get_S1 (3, Minutes_Tens, "Minutes (Tens)"); Get_S1 (4, Minutes_Units, "Minutes (Units)"); Skip_S1(4, "BG4"); Skip_S1(4, "BG3"); Skip_SB( "FP - Field Phase / BGF0"); Get_S1 (3, Seconds_Tens, "Seconds (Tens)"); Get_S1 (4, Seconds_Units, "Seconds (Units)"); Skip_S1(4, "BG2"); Skip_S1(4, "BG1"); Skip_SB( "CF - Color fame"); Get_SB ( DropFrame, "DP - Drop frame"); Get_S1 (2, Frames_Tens, "Frames (Tens)"); Get_S1 (4, Frames_Units, "Frames (Units)"); Skip_BS(Data_BS_Remain(), "Unknown"); if (Hours_Tens<3) { int64u TimeCode=(int64u)(Hours_Tens *10*60*60*1000 + Hours_Units *60*60*1000 + Minutes_Tens *10*60*1000 + Minutes_Units *60*1000 + Seconds_Tens *10*1000 + Seconds_Units *1000 + (Mpegv_frame_rate[FrameRate]?float64_int32s((Frames_Tens*10+Frames_Units)*1000/Mpegv_frame_rate[FrameRate]):0)); Element_Info1(Ztring().Duration_From_Milliseconds(TimeCode)); //TimeCode if (SMPTE_time_code_StartTimecode==(int64u)-1) SMPTE_time_code_StartTimecode=TimeCode; } }