aac的格式, 以及faad解码raw数据解码

一. ADTS 格式
ADTS全称是(AudioData Transport Stream),是AAC的一种十分常见的传输格式。
一般的AAC解码器都需要把AAC的ES流打包成ADTS的格式,一般是在AAC ES流前添加7个字节的ADTSheader。也就是说你可以吧ADTS这个头看作是AAC的frameheader。

 

ADTS AAC
ADTS_header AAC ES ADTS_header AAC ES
...
ADTS_header AAC ES

ADTS内容及结构

ADTS头中相对有用的信息 采样率、声道数、帧长度。想想也是,我要是解码器的话,你给我一堆得AAC音频ES流我也解不出来。每一个带ADTS头信息的AAC流会清晰的告送解码器他需要的这些信息。

一般情况下ADTS的头信息都是7个字节,分为2部分:

adts_fixed_header();

adts_variable_header();

aac的格式, 以及faad解码raw数据解码_第1张图片


syncword :同步头 总是0xFFF, all bitsmust be 1,代表着一个ADTS帧的开始

ID:MPEG Version: 0 for MPEG-4, 1 for MPEG-2

Layer:always: '00'

profile:表示使用哪个级别的AAC,有些芯片只支持AAC LC 。在MPEG-2AAC中定义了3种:

aac的格式, 以及faad解码raw数据解码_第2张图片

sampling_frequency_index:表示使用的采样率下标,通过这个下标在 SamplingFrequencies[ ]数组中查找得知采样率的值。

 

There are 13 supported frequencies:

  • 0: 96000 Hz
  • 1: 88200 Hz
  • 2: 64000 Hz
  • 3: 48000 Hz
  • 4: 44100 Hz
  • 5: 32000 Hz
  • 6: 24000 Hz
  • 7: 22050 Hz
  • 8: 16000 Hz
  • 9: 12000 Hz
  • 10: 11025 Hz
  • 11: 8000 Hz
  • 12: 7350 Hz
  • 13: Reserved
  • 14: Reserved
  • 15: frequency is written explictly
channel_configuration:  表示声道数 

 

  • 0: Defined in AOT Specifc Config
  • 1: 1 channel: front-center
  • 2: 2 channels: front-left, front-right
  • 3: 3 channels: front-center, front-left, front-right
  • 4: 4 channels: front-center, front-left, front-right,back-center
  • 5: 5 channels: front-center, front-left, front-right,back-left, back-right
  • 6: 6 channels: front-center, front-left, front-right,back-left, back-right, LFE-channel
  • 7: 8 channels: front-center, front-left, front-right,side-left, side-right, back-left, back-right, LFE-channel
  • 8-15: Reserved
aac的格式, 以及faad解码raw数据解码_第3张图片

frame_length :一个ADTS帧的长度包括ADTS头和AAC原始流.

adts_buffer_fullness:0x7FF 说明是码率可变的码流

将AAC打包成ADTS格式

通过对ADTS格式的了解,很容易就能把AAC打包成ADTS。我们只需得到封装格式里面关于音频采样率、声道数、元数据长度、aac格式类型等信息。然后在每个AAC原始流前面加上个ADTS头就OK了。

附上ffmpeg添加ADTS头的代码:

static int adts_write_packet(AVFormatContext*s, AVPacket *pkt)

{

   ADTSContext *adts = s->priv_data;

   AVIOContext *pb = s->pb;

    uint8_tbuf[ADTS_HEADER_SIZE];


    if(!pkt->size)

       return 0;

    if(adts->write_adts) {

      ff_adts_write_frame_header(adts, buf, pkt->size,adts->pce_size);

       avio_write(pb, buf,ADTS_HEADER_SIZE);

       if (adts->pce_size){

          avio_write(pb, adts->pce_data,adts->pce_size);

          adts->pce_size = 0;

       }

   }

   avio_write(pb, pkt->data, pkt->size);

   avio_flush(pb);


    return0;

}

int ff_adts_write_frame_header(ADTSContext*ctx,

                          uint8_t *buf, int size, intpce_size)

{

   PutBitContext pb;


   init_put_bits(&pb, buf, ADTS_HEADER_SIZE);


  

   put_bits(&pb, 12, 0xfff);  

   put_bits(&pb, 1, 0);       

   put_bits(&pb, 2, 0);       

   put_bits(&pb, 1, 1);       

   put_bits(&pb, 2, ctx->objecttype);

   put_bits(&pb, 4, ctx->sample_rate_index);

   put_bits(&pb, 1, 0);       

   put_bits(&pb, 3, ctx->channel_conf);

   put_bits(&pb, 1, 0);       

   put_bits(&pb, 1, 0);       


  

   put_bits(&pb, 1, 0);       

   put_bits(&pb, 1, 0);       

   put_bits(&pb, 13, ADTS_HEADER_SIZE + size +pce_size);

   put_bits(&pb, 11, 0x7ff);  

   put_bits(&pb, 2, 0);       


   flush_put_bits(&pb);


    return0;

 

}



二.ADIF

Audio Data InterchangeFormat 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。

AACADIF格式见下图:

      


三.faad解码aac

 iRet= pcmRender.init(2, 44100, 16, NULL);

static unsigned charframe[FRAME_MAX_LEN];

 

unsigned longsamplerate;

unsigned charchannels;

NeAACDecHandle decoder =0;


size_t data_size =0;

size_t size =0;


NeAACDecFrameInfoframe_info;

unsigned char* input_data= buffer;

unsigned char* pcm_data =NULL;

static int iFlag =0;

int iRead =0;


while (m_iThreadFlag&& (data_size = ReadData(NULL, buffer+iRead,BUFFER_MAX_LEN-iRead)))

{

#if1

data_size +=iRead;

if (0 ==iFlag)

{

if(get_one_ADTS_frame(buffer,data_size, frame, &size, &iRead) <0)

{

continue;

}


decoder = NeAACDecOpen();   

//initializedecoder

NeAACDecInit(decoder,frame, size, &samplerate, &channels);

printf("samplerate %d,channels %d\n", samplerate, channels);

iFlag =1;


}

input_data =buffer;

while(m_iThreadFlag&& get_one_ADTS_frame(input_data, data_size, frame,&size, &iRead) == 0)

{

//decode ADTSframe

pcm_data = (unsignedchar*)NeAACDecDecode(decoder, &frame_info, frame,size); 


if(frame_info.error >0)

{

printf("%s\n",NeAACDecGetErrorMessage(frame_info.error));         


}

else if(pcm_data&& frame_info.samples > 0)

{

static FILE *fp1 =NULL;

if (NULL ==fp1)

{

fp1 = fopen("F:\\6.pcm","wb");

}

if(fp1)

{

fwrite(pcm_data, 1,frame_info.samples * frame_info.channels,fp1);

fflush(fp1);

}

Player((char*)pcm_data,frame_info.samples * frame_info.channels);

}      

data_size -=size;

input_data +=size;

#endif

}

NeAACDecClose(decoder);

你可能感兴趣的:(aac的格式, 以及faad解码raw数据解码)