This article is mainly about the Raytheon analysis of AAC, the article links are as follows:
Getting Started with AV data processing: AAC audio bitstream parsing
http://blog.csdn.net/leixiaohua1020/article/details/50535042 Introduction:
The decoding of AAC files is that the AAC stream is decomposed into AAC source stream (bare stream), and the bare stream is encoded and decoded as the input of the codec library.
AAC source stream is what we call the data frame, there are two main formats: Adts frame, adif frame. Here the main analysis Adts frame. Adts Frame Analysis
This analysis, a lot of articles are described in detail, the following article:
"AAC Adts Format Analysis"
http://blog.csdn.net/bsplover/article/details/7426476
Each Adts frame contains a header, which accounts for 7 bytes, mainly recording frame format information.
Each of these Adts frames is separated by a syncword (synchronous word). The synchronized word is 0xFFF (binary "111111111111"). The process of the AAC stream parsing is to first search the 0x0fff from the bitstream, separate the Adts frame, and then analyze the header fields of the Adts frame. (7 bytes.) )
Adts content and structure are described as follows:
ADTS header is divided into two parts, variable head, non-variable head. The sampling rate, channel number, frame length and other information are recorded. A total of 7 bytes, i.e. 56bit
Adts_fixed_header ();
High 28bit non-variable header, information, record AAC level, sample rate, number of channels
Adts_variable_header ();
Low 28bit, variable header information, record frame length and other information. Code rate variable, etc.
Vim./LIBAVFORMAT/ADTSENC.C the middle of the operation can refer to
Thor Blog Code Learning and Analysis:
The following code snippet, from the AAC stream analysis to get its basic unit Adts frame, and simply parse the field of Adts frame header
int getadtsframe (unsigned char* buffer, int buf_size, unsigned char* data, int* data_size) {int size = 0;
if (!buffer | |!data | |!data_size) {return-1;
} while (1) {if (Buf_size < 7) {return-1;
//sync words//Here The decision filter is based on the Adts frame head synchronization Word, in order to determine the beginning of each frame, the entire loop is processing each frame of the first 7 bytes (header), before the judgment encountered 0xfff is the beginning of a new frame. if ((buffer[0] = = 0xff) && ((buffer[1] & 0xf0) = = 0xf0) {//Under the assignment operation of size, the essence is to read from the encounter Adts synchronization Word to start the calculation, read buf
FER[3] of the low two-bit to buffer[5] High 3 bits, these 11 bits record the frame length, which belongs to the variable head section. Size |= ((buffer[3] & 0x03) <<11); High 2 bit size |= buffer[4]<<3; Middle 8 bit size |= ((buffer[5] & 0xe0) >>5); Low 3bit break;//Find a new Adts frame, get the size and jump out of the loop}--buf_size;//can traverse buf reduce one byte ++buffer;//check
Find the next byte, look for the Adts sync Word, that is, the new frame} if (Buf_size < size) {//Current frame is invalid frame, discard return 1; } memcpy (data, buffer, size);
*data_size = size;
return 0;
} int Simplest_aac_parser (char *url) {int data_size = 0;
int size = 0;
int cnt=0;
int offset=0;
FILE *myout=fopen ("Output_log.txt", "wb+");
FILE *myout=stdout;
unsigned char *aacframe= (unsigned char *) malloc (1024*5);
unsigned char *aacbuffer= (unsigned char *) malloc (1024*1024);
FILE *ifile = fopen (URL, "RB");
if (!ifile) {printf ("Open file Error");
return-1;
} printf ("-----+-ADTS Frame Table-+------+\n"); printf ("NUM | Profile | frequency|
Size |\n ");
printf ("-----+---------+----------+------+\n"); while (!feof (ifile)) {data_size = Fread (Aacbuffer+offset, 1, 1024*1024-offset, ifile);//Offset settings, the following analysis unsigned
char* input_data = Aacbuffer;
while (1) {int ret=getadtsframe (input_data, Data_size, Aacframe, &size); if (ret==-1) {break;//argument is not valid causes return}else if (ret==1) {Memcpy (aacbuffer,input_data,data_size); offset=data_size;//the process is complete.
Re-fread data to the specified address from the offset position, parsing and processing break;
} Char profile_str[10]={0};
Char frequence_str[10]={0};
Unsigned the level of Char PROFILE=AACFRAME[2]&0XC0;//AAC, which is the value of 16~17bit profile=profile>>6;
Switch (profile) {case 0:sprintf (profile_str, "Main");
Case 1:sprintf (profile_str, "LC");
Case 2:sprintf (profile_str, "SSR");
default:sprintf (Profile_str, "unknown"); } unsigned char sampling_frequency_index=aacframe[2]&0x3c;//sample rate, 18~21bit sampling_frequency_i
ndex=sampling_frequency_index>>2;
Switch (sampling_frequency_index) {case 0:sprintf (frequence_str, "96000Hz");
Case 1:sprintf (frequence_str, "88200Hz");
Case 2:sprintf (frequence_str, "64000Hz"); Case 3:sprintf (frequence_str, "48000Hz");
Case 4:sprintf (frequence_str, "44100Hz");
Case 5:sprintf (frequence_str, "32000Hz");
Case 6:sprintf (frequence_str, "24000Hz");
Case 7:sprintf (frequence_str, "22050Hz");
Case 8:sprintf (frequence_str, "16000Hz");
Case 9:sprintf (frequence_str, "12000Hz");
Case 10:sprintf (frequence_str, "11025Hz");
Case 11:sprintf (frequence_str, "8000Hz");
default:sprintf (Frequence_str, "unknown"); } fprintf (Myout, "%5d|%8s| %8s|
%5d|\n ", Cnt,profile_str, frequence_str,size);
Data_size-= size;
Input_data + = size;
cnt++;
}} fclose (IFile);
Free (aacbuffer);
Free (aacframe);
return 0;
}