/* 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_AAC_YES)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/Audio/File_Aac.h"
#include "MediaInfo/MediaInfo_Config_MediaInfo.h"
//---------------------------------------------------------------------------
namespace MediaInfoLib
{
//***************************************************************************
// Infos
//***************************************************************************
extern const size_t Aac_sampling_frequency_Size;
//***************************************************************************
// Constructor/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
File_Aac::File_Aac()
:File_Usac(), File__Tags_Helper()
{
//Config
#if MEDIAINFO_EVENTS
ParserIDs[0]=MediaInfo_Parser_Aac;
StreamIDs_Width[0]=0;
#endif //MEDIAINFO_EVENTS
//File__Tags_Helper
Base=this;
//Configuration
#if MEDIAINFO_TRACE
Trace_Layers_Update(8); //Stream
#endif //MEDIAINFO_TRACE
MustSynchronize=true;
Buffer_TotalBytes_FirstSynched_Max=64*1024;
PTS_DTS_Needed=true;
StreamSource=IsStream;
//In
Frame_Count_Valid=0;
FrameIsAlwaysComplete=false;
Mode=Mode_Unknown;
audioObjectType=(int8u)-1;
extensionAudioObjectType=(int8u)-1;
frame_length=1024;
extension_sampling_frequency=(int32u)-1;
aacSpectralDataResilienceFlag=false;
aacSectionDataResilienceFlag=false;
aacScalefactorDataResilienceFlag=false;
FrameSize_Min=(int64u)-1;
FrameSize_Max=0;
adts_buffer_fullness_Is7FF=false;
#if MEDIAINFO_ADVANCED
aac_frame_length_Total=0;
#endif //MEDIAINFO_ADVANCED
//Temp - Main
muxConfigPresent=true;
audioMuxVersionA=false;
//Temp - General Audio
sbr=NULL;
ps=NULL;
raw_data_block_Pos=0;
//Temp
CanFill=true;
}
//---------------------------------------------------------------------------
File_Aac::~File_Aac()
{
for (size_t i=0; i<sbrs.size(); i++)
delete sbrs[i];
for (size_t i=0; i<pss.size(); i++)
delete pss[i];
}
//***************************************************************************
// Streams management
//***************************************************************************
//---------------------------------------------------------------------------
void File_Aac::Streams_Accept()
{
switch (Mode)
{
case Mode_ADTS :
if (!IsSub)
TestContinuousFileNames();
default : ;
}
}
//---------------------------------------------------------------------------
void File_Aac::Streams_Fill()
{
switch(Mode)
{
case Mode_LATM : Fill(Stream_General, 0, General_Format, "LATM"); if (IsSub) Fill(Stream_Audio, 0, Audio_MuxingMode, "LATM"); break;
default : ;
}
for (std::map<std::string, Ztring>::iterator Info=Infos_General.begin(); Info!=Infos_General.end(); ++Info)
Fill(Stream_General, 0, Info->first.c_str(), Info->second);
File__Tags_Helper::Stream_Prepare(Stream_Audio);
for (std::map<std::string, Ztring>::iterator Info_AudioSpecificConfig=Infos_AudioSpecificConfig.begin(); Info_AudioSpecificConfig!=Infos_AudioSpecificConfig.end(); ++Info_AudioSpecificConfig)
if (Infos.find(Info_AudioSpecificConfig->first)==Infos.end())
Infos[Info_AudioSpecificConfig->first]=Info_AudioSpecificConfig->second; // Use AudioSpecificConfig info if info not present in stream itself
for (std::map<std::string, Ztring>::iterator Info=Infos.begin(); Info!=Infos.end(); ++Info)
Fill(Stream_Audio, StreamPos_Last, Info->first.c_str(), Info->second);
switch(Mode)
{
case Mode_ADTS : File__Tags_Helper::Streams_Fill(); break;
default : ;
}
if (Retrieve_Const(Stream_Audio, StreamPos_Last, Audio_SamplesPerFrame).empty())
{
int16u frame_length_Multiplier=1;
if (!MediaInfoLib::Config.LegacyStreamDisplay_Get() && Retrieve_Const(Stream_Audio, StreamPos_Last, Audio_Format).find(__T("AAC"))==0 && Retrieve_Const(Stream_Audio, StreamPos_Last, Audio_Format_Settings_SBR).find(__T("Yes"))==0)
frame_length_Multiplier=2;
Fill(Stream_Audio, StreamPos_Last, Audio_SamplesPerFrame, frame_length*frame_length_Multiplier);
}
}
//---------------------------------------------------------------------------
void File_Aac::Streams_Update()
{
if (Frame_Count)
{
if (Mode==Mode_ADTS)
Infos["BitRate_Mode"].From_UTF8(adts_buffer_fullness_Is7FF?"VBR":"CBR");
#if MEDIAINFO_ADVANCED
switch(Mode)
{
case Mode_ADTS :
case Mode_LATM : if (Config->File_RiskyBitRateEstimation_Get() && !adts_buffer_fullness_Is7FF && (Config->ParseSpeed<1.0 || File_Offset+Buffer_Offset<File_Size))
{
float64 BitRate=((float64)Frequency_b)/frame_length;
BitRate*=aac_frame_length_Total*8;
BitRate/=Frame_Count;
Fill(Stream_Audio, 0, Audio_BitRate, BitRate, 10, true);
Fill(Stream_Audio, 0, Audio_Duration, (File_Size-Buffer_TotalBytes_FirstSynched)/BitRate*8*1000, 0, true);
}
break;
default : ;
}
#endif //MEDIAINFO_ADVANCED
}
}
//---------------------------------------------------------------------------
void File_Aac::Streams_Finish()
{
switch(Mode)
{
case Mode_ADIF :
case Mode_ADTS : File__Tags_Helper::Streams_Finish(); break;
default : ;
}
if (FrameSize_Min!=(int32u)-1 && FrameSize_Max)
{
if (FrameSize_Max>FrameSize_Min*1.02)
{
Fill(Stream_Audio, 0, Audio_BitRate_Mode, "VBR", Unlimited, true, true);
if (Config->ParseSpeed>=1.0)
{
Fill(Stream_Audio, 0, Audio_BitRate_Minimum, ((float64)FrameSize_Min)/frame_length*Frequency_b*8, 0);
Fill(Stream_Audio, 0, Audio_BitRate_Maximum, ((float64)FrameSize_Max)/frame_length*Frequency_b*8, 0);
Fill(Stream_Audio, 0, Audio_SamplingCount, Frame_Count*frame_length);
Fill(Stream_Audio, 0, Audio_Duration, ((float64)Frame_Count)*frame_length/Frequency_b*1000, 0);
}
}
else if (Config->ParseSpeed>=1.0)
{
Fill(Stream_Audio, 0, Audio_BitRate_Mode, "CBR");
}
}
}
//***************************************************************************
// Buffer - File header
//***************************************************************************
//---------------------------------------------------------------------------
bool File_Aac::FileHeader_Begin()
{
if (!Frame_Count_Valid)
Frame_Count_Valid=Config->ParseSpeed>=0.5?128:(Config->ParseSpeed>=0.3?32:8);
switch(Mode)
{
case Mode_AudioSpecificConfig :
case Mode_ADIF :
MustSynchronize=false; break;
default : ; //Synchronization is requested, and this is the default
}
switch(Mode)
{
case Mode_Unknown :
case Mode_ADIF :
case Mode_ADTS :
break;
default : return true; //no file header test with other modes
}
//Tags
if (!File__Tags_Helper::FileHeader_Begin())
return false;
//Testing
if (Buffer_Size<4)
return false;
if (Buffer[0]==0x41 //"ADIF"
&& Buffer[1]==0x44
&& Buffer[2]==0x49
&& Buffer[3]==0x46)
{
Mode=Mode_ADIF;
File__Tags_Helper::Accept("ADIF");
MustSynchronize=false;
}
return true;
}
//---------------------------------------------------------------------------
void File_Aac::FileHeader_Parse()
{
switch (Mode)
{
case Mode_ADIF : FileHeader_Parse_ADIF(); break;
default : ; //no file header test with other modes
}
}
//---------------------------------------------------------------------------
void File_Aac::FileHeader_Parse_ADIF()
{
adif_header();
BS_Begin();
raw_data_block();
BS_End();
FILLING_BEGIN();
File__Tags_Helper::Finish();
FILLING_END();
}
//***************************************************************************
// Buffer - Global
//***************************************************************************
//---------------------------------------------------------------------------
void File_Aac::Read_Buffer_Continue()
{
if (Element_Size==0)
return;
if (Frame_Count==0)
PTS_Begin=FrameInfo.PTS;
switch(Mode)
{
case Mode_AudioSpecificConfig : Read_Buffer_Continue_AudioSpecificConfig(); break;
case Mode_raw_data_block : Read_Buffer_Continue_raw_data_block(); break;
case Mode_ADIF :
case Mode_ADTS : File__Tags_Helper::Read_Buffer_Continue(); break;
default : ;
}
}
//---------------------------------------------------------------------------
void File_Aac::Read_Buffer_Continue_AudioSpecificConfig()
{
File__Analyze::Accept(); //We automaticly trust it
BS_Begin();
AudioSpecificConfig(0); //Up to the end of the block
BS_End();
Infos_AudioSpecificConfig=Infos;
Mode=Mode_raw_data_block; //Mode_AudioSpecificConfig only once
}
//---------------------------------------------------------------------------
void File_Aac::Read_Buffer_Continue_raw_data_block()
{
if (Frame_Count>Frame_Count_Valid)
{
Skip_XX(Element_Size, "Data");
return; //Parsing completely only the 1st frame
}
BS_Begin();
raw_data_block();
BS_End();
if (FrameIsAlwaysComplete && Element_Offset<Element_Size)
Skip_XX(Element_Size-Element_Offset, "Unknown");
FILLING_BEGIN();
//Counting
Frame_Count++;
if (Frame_Count_NotParsedIncluded!=(int64u)-1)
Frame_Count_NotParsedIncluded++;
Element_Info1(Ztring::ToZtring(Frame_Count));
//Filling
if (!Status[IsAccepted])
File__Analyze::Accept();
if (Frame_Count>=Frame_Count_Valid)
{
//No more need data
if (Mode==Mode_LATM)
File__Analyze::Accept();
File__Analyze::Finish();
}
FILLING_ELSE();
Infos=Infos_AudioSpecificConfig;
FILLING_END();
}
//***************************************************************************
// Buffer - Synchro
//***************************************************************************
//---------------------------------------------------------------------------
bool File_Aac::Synchronize()
{
switch (Mode)
{
case Mode_Unknown : if (Synchronize_LATM()) return true; Buffer_Offset=0; return Synchronize_ADTS();
case Mode_ADTS : return Synchronize_ADTS();
case Mode_LATM : return Synchronize_LATM();
default : return true; //No synchro
}
}
//---------------------------------------------------------------------------
bool File_Aac::Synchronize_ADTS()
{
//Tags
bool Tag_Found;
if (!File__Tags_Helper::Synchronize(Tag_Found))
return false;
if (Tag_Found)
return true;
//Synchronizing
while (Buffer_Offset+6<=Buffer_Size)
{
while (Buffer_Offset+6<=Buffer_Size && (Buffer[Buffer_Offset ]!=0xFF
|| (Buffer[Buffer_Offset+1]&0xF6)!=0xF0))
Buffer_Offset++;
if (Buffer_Offset+6<=Buffer_Size)//Testing if size is coherant
{
//Testing next start, to be sure
int8u sampling_frequency_index=(CC1(Buffer+Buffer_Offset+2)>>2)&0xF;
if (sampling_frequency_index>=Aac_sampling_frequency_Size)
{
Buffer_Offset++;
continue;
}
int16u aac_frame_length=(CC3(Buffer+Buffer_Offset+3)>>5)&0x1FFF;
if (IsSub && Buffer_Offset+aac_frame_length==Buffer_Size)
break;
if (File_Offset+Buffer_Offset+aac_frame_length!=File_Size-File_EndTagSize)
{
//Padding
while (Buffer_Offset+aac_frame_length+2<=Buffer_Size && Buffer[Buffer_Offset+aac_frame_length]==0x00)
aac_frame_length++;
if (IsSub && Buffer_Offset+aac_frame_length==Buffer_Size)
break; //while()
if (Buffer_Offset+aac_frame_length+2>Buffer_Size)
return false; //Need more data
//Testing
if (aac_frame_length<=7 || (CC2(Buffer+Buffer_Offset+aac_frame_length)&0xFFF6)!=0xFFF0)
Buffer_Offset++;
else
{
//Testing next start, to be sure
if (Buffer_Offset+aac_frame_length+3+3>Buffer_Size)
return false; //Need more data
sampling_frequency_index=(CC1(Buffer+Buffer_Offset+aac_frame_length+2)>>2)&0xF;
if (sampling_frequency_index>=Aac_sampling_frequency_Size)
{
Buffer_Offset++;
continue;
}
int16u aac_frame_length2=(CC3(Buffer+Buffer_Offset+aac_frame_length+3)>>5)&0x1FFF;
if (File_Offset+Buffer_Offset+aac_frame_length+aac_frame_length2!=File_Size-File_EndTagSize)
{
//Padding
while (Buffer_Offset+aac_frame_length+aac_frame_length2+2<=Buffer_Size && Buffer[Buffer_Offset+aac_frame_length+aac_frame_length2]==0x00)
aac_frame_length2++;
if (IsSub && Buffer_Offset+aac_frame_length+aac_frame_length2==Buffer_Size)
break; //while()
if (Buffer_Offset+aac_frame_length+aac_frame_length2+2>Buffer_Size)
return false; //Need more data
//Testing
if (aac_frame_length2<=7 || (CC2(Buffer+Buffer_Offset+aac_frame_length+aac_frame_length2)&0xFFF6)!=0xFFF0)
Buffer_Offset++;
else
{
//Testing next start, to be sure
if (Buffer_Offset+aac_frame_length+aac_frame_length2+3+3>Buffer_Size)
return false; //Need more data
sampling_frequency_index=(CC1(Buffer+Buffer_Offset+aac_frame_length+aac_frame_length2+2)>>2)&0xF;
if (sampling_frequency_index>=Aac_sampling_frequency_Size)
{
Buffer_Offset++;
continue;
}
int16u aac_frame_length3=(CC3(Buffer+Buffer_Offset+aac_frame_length+aac_frame_length2+3)>>5)&0x1FFF;
if (File_Offset+Buffer_Offset+aac_frame_length+aac_frame_length2+aac_frame_length3!=File_Size-File_EndTagSize)
{
//Padding
while (Buffer_Offset+aac_frame_length+aac_frame_length2+aac_frame_length3+2<=Buffer_Size && Buffer[Buffer_Offset+aac_frame_length+aac_frame_length2+aac_frame_length3]==0x00)
aac_frame_length3++;
if (IsSub && Buffer_Offset+aac_frame_length+aac_frame_length2+aac_frame_length3==Buffer_Size)
break; //while()
if (Buffer_Offset+aac_frame_length+aac_frame_length2+aac_frame_length3+2>Buffer_Size)
return false; //Need more data
//Testing
if (aac_frame_length3<=7 || (CC2(Buffer+Buffer_Offset+aac_frame_length+aac_frame_length2+aac_frame_length3)&0xFFF6)!=0xFFF0)
Buffer_Offset++;
else
break; //while()
}
else
break; //while()
}
}
else
break; //while()
}
}
else
break; //while()
}
}
//Parsing last bytes if needed
if (Buffer_Offset+6>Buffer_Size)
{
if (Buffer_Offset+5==Buffer_Size && (CC2(Buffer+Buffer_Offset)&0xFFF6)!=0xFFF0)
Buffer_Offset++;
if (Buffer_Offset+4==Buffer_Size && (CC2(Buffer+Buffer_Offset)&0xFFF6)!=0xFFF0)
Buffer_Offset++;
if (Buffer_Offset+3==Buffer_Size && (CC2(Buffer+Buffer_Offset)&0xFFF6)!=0xFFF0)
Buffer_Offset++;
if (Buffer_Offset+2==Buffer_Size && (CC2(Buffer+Buffer_Offset)&0xFFF6)!=0xFFF0)
Buffer_Offset++;
if (Buffer_Offset+1==Buffer_Size && CC1(Buffer+Buffer_Offset)!=0xFF)
Buffer_Offset++;
return false;
}
//Synched is OK
Mode=Mode_ADTS;
File__Analyze::Accept();
return true;
}
//---------------------------------------------------------------------------
bool File_Aac::Synchronize_LATM()
{
//Synchronizing
while (Buffer_Offset+3<=Buffer_Size)
{
while (Buffer_Offset+3<=Buffer_Size && (Buffer[Buffer_Offset ]!=0x56
|| (Buffer[Buffer_Offset+1]&0xE0)!=0xE0))
Buffer_Offset++;
if (Buffer_Offset+3<=Buffer_Size)//Testing if size is coherant
{
//Testing next start, to be sure
int16u audioMuxLengthBytes=CC2(Buffer+Buffer_Offset+1)&0x1FFF;
if (IsSub && Buffer_Offset+3+audioMuxLengthBytes==Buffer_Size)
break;
if (File_Offset+Buffer_Offset+3+audioMuxLengthBytes!=File_Size)
{
if (Buffer_Offset+3+audioMuxLengthBytes+3>Buffer_Size)
return false; //Need more data
//Testing
if ((CC2(Buffer+Buffer_Offset+3+audioMuxLengthBytes)&0xFFE0)!=0x56E0)
Buffer_Offset++;
else
{
//Testing next start, to be sure
int16u audioMuxLengthBytes2=CC2(Buffer+Buffer_Offset+3+audioMuxLengthBytes+1)&0x1FFF;
if (File_Offset+Buffer_Offset+3+audioMuxLengthBytes+3+audioMuxLengthBytes2!=File_Size)
{
if (Buffer_Offset+3+audioMuxLengthBytes+3+audioMuxLengthBytes2+3>Buffer_Size)
return false; //Need more data
//Testing
if ((CC2(Buffer+Buffer_Offset+3+audioMuxLengthBytes+3+audioMuxLengthBytes2)&0xFFE0)!=0x56E0)
Buffer_Offset++;
else
break; //while()
}
else
break; //while()
}
}
else
break; //while()
}
}
//Synchronizing
while (Buffer_Offset+2<=Buffer_Size && (Buffer[Buffer_Offset ]!=0x56
|| (Buffer[Buffer_Offset+1]&0xE0)!=0xE0))
Buffer_Offset++;
if (Buffer_Offset+2>=Buffer_Size)
return false;
//Synched is OK
Mode=Mode_LATM;
return true;
}
//---------------------------------------------------------------------------
bool File_Aac::Synched_Test()
{
switch (Mode)
{
case Mode_ADTS : return Synched_Test_ADTS();
case Mode_LATM : return Synched_Test_LATM();
default : return true; //No synchro
}
}
//---------------------------------------------------------------------------
bool File_Aac::Synched_Test_ADTS()
{
//Tags
if (!File__Tags_Helper::Synched_Test())
return false;
//Null padding
while (Buffer_Offset+2<=Buffer_Size && Buffer[Buffer_Offset]==0x00)
Buffer_Offset++;
//Must have enough buffer for having header
if (Buffer_Offset+2>Buffer_Size)
return false;
//Quick test of synchro
if ((CC2(Buffer+Buffer_Offset)&0xFFF6)!=0xFFF0)
Synched=false;
//We continue
return true;
}
//---------------------------------------------------------------------------
bool File_Aac::Synched_Test_LATM()
{
//Must have enough buffer for having header
if (Buffer_Offset+2>Buffer_Size)
return false;
//Quick test of synchro
if ((CC2(Buffer+Buffer_Offset)&0xFFE0)!=0x56E0)
Synched=false;
//We continue
return true;
}
//***************************************************************************
// Buffer - Demux
//***************************************************************************
//---------------------------------------------------------------------------
#if MEDIAINFO_DEMUX
bool File_Aac::Demux_UnpacketizeContainer_Test()
{
switch (Mode)
{
case Mode_ADTS : return Demux_UnpacketizeContainer_Test_ADTS();
case Mode_LATM : return Demux_UnpacketizeContainer_Test_LATM();
default : return true; //No header
}
}
bool File_Aac::Demux_UnpacketizeContainer_Test_ADTS()
{
int16u aac_frame_length=(BigEndian2int24u(Buffer+Buffer_Offset+3)>>5)&0x1FFF; //13 bits
Demux_Offset=Buffer_Offset+aac_frame_length;
if (Demux_Offset>Buffer_Size && File_Offset+Buffer_Size!=File_Size)
return false; //No complete frame
Demux_UnpacketizeContainer_Demux();
return true;
}
bool File_Aac::Demux_UnpacketizeContainer_Test_LATM()
{
int16u audioMuxLengthBytes=BigEndian2int16u(Buffer+Buffer_Offset+1)&0x1FFF; //13 bits
Demux_Offset=Buffer_Offset+3+audioMuxLengthBytes;
if (Demux_Offset>Buffer_Size && File_Offset+Buffer_Size!=File_Size)
return false; //No complete frame
Demux_UnpacketizeContainer_Demux();
return true;
}
#endif //MEDIAINFO_DEMUX
//***************************************************************************
// Buffer - Per element
//***************************************************************************
//---------------------------------------------------------------------------
bool File_Aac::Header_Begin()
{
switch (Mode)
{
case Mode_ADTS : return Header_Begin_ADTS();
case Mode_LATM : return Header_Begin_LATM();
default : return true; //No header
}
}
//---------------------------------------------------------------------------
bool File_Aac::Header_Begin_ADTS()
{
//There is no real header in ADTS, retrieving only the frame length
if (Buffer_Offset+8>Buffer_Size) //size of adts_fixed_header + adts_variable_header
return false;
return true;
}
//---------------------------------------------------------------------------
bool File_Aac::Header_Begin_LATM()
{
if (Buffer_Offset+3>Buffer_Size) //fixed 24-bit header
return false;
return true;
}
//---------------------------------------------------------------------------
void File_Aac::Header_Parse()
{
switch (Mode)
{
case Mode_ADTS : Header_Parse_ADTS(); break;
case Mode_LATM : Header_Parse_LATM(); break;
default : ; //No header
}
}
//---------------------------------------------------------------------------
void File_Aac::Header_Parse_ADTS()
{
//There is no "header" in ADTS, retrieving only the frame length
int16u aac_frame_length=(BigEndian2int24u(Buffer+Buffer_Offset+3)>>5)&0x1FFF; //13 bits
//Filling
Header_Fill_Size(aac_frame_length);
Header_Fill_Code(0, "adts_frame");
}
//---------------------------------------------------------------------------
void File_Aac::Header_Parse_LATM()
{
int16u audioMuxLengthBytes;
BS_Begin();
Skip_S2(11, "syncword");
Get_S2 (13, audioMuxLengthBytes, "audioMuxLengthBytes");
BS_End();
//Filling
Header_Fill_Size(3+audioMuxLengthBytes);
Header_Fill_Code(0, "LATM");
}
//---------------------------------------------------------------------------
void File_Aac::Data_Parse()
{
if (FrameSize_Min>Header_Size+Element_Size)
FrameSize_Min=Header_Size+Element_Size;
if (FrameSize_Max<Header_Size+Element_Size)
FrameSize_Max=Header_Size+Element_Size;
switch (Mode)
{
case Mode_ADTS : Data_Parse_ADTS(); break;
case Mode_LATM : Data_Parse_LATM(); break;
default : ; //No header
}
FILLING_BEGIN();
//Counting
if (File_Offset+Buffer_Offset+Element_Size==File_Size)
Frame_Count_Valid=Frame_Count; //Finish frames in case of there are less than Frame_Count_Valid frames
#if MEDIAINFO_ADVANCED
switch(Mode)
{
case Mode_LATM :
aac_frame_length_Total+=Element_Size;
break;
default : ;
}
#endif //MEDIAINFO_ADVANCED
if (!Status[IsAccepted])
File__Analyze::Accept();
//Filling
if (Frame_Count>=Frame_Count_Valid && Config->ParseSpeed<1.0)
{
//No more need data
switch (Mode)
{
case Mode_ADTS :
case Mode_LATM :
if (!Status[IsFilled])
{
Fill();
if (!IsSub)
File__Tags_Helper::Finish();
}
break;
default : ; //No header
}
}
TS_Add(frame_length);
FILLING_END();
}
//---------------------------------------------------------------------------
void File_Aac::Data_Parse_ADTS()
{
//Parsing
BS_Begin();
adts_frame();
BS_End();
}
//---------------------------------------------------------------------------
void File_Aac::Data_Parse_LATM()
{
BS_Begin();
AudioMuxElement();
BS_End();
}
//***************************************************************************
// C++
//***************************************************************************
} //NameSpace
#endif //MEDIAINFO_AAC_YES
↑ V688 The 'sampling_frequency_index' local variable possesses the same name as one of the class members, which can result in a confusion.
↑ V525 The code contains the collection of similar blocks. Check items 'Synchronize_ADTS', 'Synchronize_ADTS', 'Synchronize_LATM' in lines 363, 364, 365.
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: numSubFrames, numProgram, numLayer, numChunk, streamID, progSIndx, ...