使用ffmpeg的解码器对多种类型的编码进行解码为pcm,分析各种类型写入decoder之前的数据,如何获取该类型的一个帧。
-
AAC
:aac文件的每一个帧有一个adts头,需要对其进行解析,获得每个aac frame的大小frameSize,再每一次进行读文件时,读取frameSize大小的数据作为aac的一个帧内容。adtsheader的大小为7个字节。-
adts_header_t *adts = (adts_header_t *) aac_frame; if (adts->syncword_0_to_8 != 0xff || adts->syncword_9_to_12 != 0xf) { W_LOG("demux adts fail, adts header wrong!"); break; } int aac_frame_size = adts->frame_length_0_to_1 << 11 | adts->frame_length_2_to_9 << 3 | adts->frame_length_10_to_12;
-
Decoder in out:
-
in.setInfo(32000, (AVSampleFormat)AV_SAMPLE_FMT_FLTP, 1);
-
out.*setInfo*(16000, (AVSampleFormat)AV_SAMPLE_FMT_S16, 1);
-
-
-
PCMA
: 在PCMA编解码中有一个pcmaTimeSeg,这个相当于pcma的取包间隔。需要进行手动设置,同时在读文件的时候设置chrono的毫秒间隔略大于pcmaTimeSeg,这个原因还不清楚,如果等于pcmaTimeSeg会出现BufferOverFlow的情况。同时读取的大小也要略大于frameSize才可以。-
frameSize = sample_rate / frame_rate (单位:sample)
-
eg: 16000 / (1000ms / 30ms) = 480 samples;
-
-
Decoder in out:
-
in.setInfo(16000, (AVSampleFormat)AV_SAMPLE_FMT_S16, 1, 30.0);
-
out.setInfo(16000, (AVSampleFormat)AV_SAMPLE_FMT_S16, 1);
-
-
frameSize = sample_rate / frame_rate (单位:sample)
-
AMRNB
: 有6个字节的文件头”#!AMR\n”,每个帧又有一个字节的帧头,在读的时候只需要去掉文件头,后面都是连续的音频数据。-
frameSize = bit_rate / frame_rate (单位bit)
- eg: 12200kbit/s / (1000ms / 20ms) = 244bit 约为 31Byte , 加上一个字节的帧头等于32Byte
-
Decoder in out:
-
in.setInfo(8000, (AVSampleFormat)AV_SAMPLE_FMT_FLT, 1, 12200);
-
out.setInfo(8000, (AVSampleFormat)AV_SAMPLE_FMT_S16, 1, 12200);
-
-
frameSize = bit_rate / frame_rate (单位bit)
-
AMRWB
: 与AMRNB有很多相似的地方,它的文件头为9个字节的”#!AMR-WB\n“,同样每个帧有一个帧头,在计算的时候需要将其加上。-
Decoder in out:
-
in.setInfo(16000, (AVSampleFormat)AV_SAMPLE_FMT_FLT, 1, 23850);
-
out.setInfo(16000, (AVSampleFormat)AV_SAMPLE_FMT_S16, 1);
-
-
Decoder in out: