首先引入音频帧的概念:
ffmpeg音频转码:
由于不同格式音频帧数的不同,在使用ffmpeg作音频转码时需要作音频fifo来缓存解码数据,依据编码音频帧需要给对应的大小。
音频fifo可使用ffmpeg中已写好的fifo,定义在libavutil/audio_fifo.h下。
AVAudioFifo,SwrContext定义及初始化:
AVAudioFifo *af = NULL;
SwrContext *resample_context = NULL;
long long pts = 0;
for(int i=0; i<1; i++){
printf(" samplerate input = %d , samplerate output = %d\n",pAudioCodecCtx[i]->sample_rate, AudioEncodeCtx[i]->sample_rate);
resample_context = swr_alloc_set_opts(NULL, av_get_default_channel_layout(AudioEncodeCtx[i]->channels),
AudioEncodeCtx[i]->sample_fmt,
AudioEncodeCtx[i]->sample_rate,
av_get_default_channel_layout(pAudioCodecCtx[i]->channels),
pAudioCodecCtx[i]->sample_fmt,
pAudioCodecCtx[i]->sample_rate,
0, NULL);
swr_init(resample_context);
}
af = av_audio_fifo_alloc(AudioEncodeCtx[0]->sample_fmt, AudioEncodeCtx[0]->channels, 1);
if(af == NULL)
{
printf("error af \n");
return -1;
}
if (avcodec_decode_audio4(pAudioCodecCtx[i], pAudioframe[i], &frame_size, &pkt) >= 0) {
if (i == 0){
uint8_t *converted_input_samples = NULL;
converted_input_samples = (uint8_t *)calloc(AudioEncodeCtx[i]->channels, sizeof(*converted_input_samples));
av_samples_alloc(&converted_input_samples, NULL, AudioEncodeCtx[i]->channels, pAudioframe[i]->nb_samples, AudioEncodeCtx[i]->sample_fmt, 0);
int error = 0;
if((error = swr_convert(resample_context, &converted_input_samples, pAudioframe[i]->nb_samples,
(const uint8_t**)pAudioframe[i]->extended_data, pAudioframe[i]->nb_samples))<0){
printf("error : %d\n",error);
}
av_audio_fifo_write(af, (void **)&converted_input_samples, pAudioframe[i]->nb_samples);
int got_frame=0;
//Encode
while(av_audio_fifo_size(af) >= AudioEncodeCtx[i]->frame_size){
int frame_size = FFMIN(av_audio_fifo_size(af),AudioEncodeCtx[i]->frame_size);
pOutAudioframe[i]->nb_samples = frame_size;
pOutAudioframe[i]->channel_layout = AudioEncodeCtx[i]->channel_layout;
pOutAudioframe[i]->sample_rate = AudioEncodeCtx[i]->sample_rate;
pOutAudioframe[i]->format = AudioEncodeCtx[i]->sample_fmt;
av_frame_get_buffer(pOutAudioframe[i], 0);
av_audio_fifo_read(af, (void **)&pOutAudioframe[i]->data, frame_size);
pOutAudioframe[i]->pts=pts;
pts += pOutAudioframe[i]->nb_samples;
audio_pkt.data = NULL;
audio_pkt.size = 0;
av_init_packet(&audio_pkt);
avcodec_encode_audio2(AudioEncodeCtx[i], &audio_pkt, pOutAudioframe[i], &got_frame);
}
}
break;
}