ffmpeg实现音频resample(重采样)

来源:互联网 发布:耽美网络剧百度云链接 编辑:程序博客网 时间:2024/05/26 09:54

ffmpeg实现音频resample(重采样)

下面代码是实现将音频的三大要素:声道,样本,采样率变更的demo
例如双声道变成单声道,44100->48000,float->s16等等。 


int AudioResampling(AVCodecContext * audio_dec_ctx,AVFrame * pAudioDecodeFrame,int out_sample_fmt,int out_channels ,int out_sample_rate , uint8_t * out_buf){//////////////////////////////////////////////////////////////////////////SwrContext * swr_ctx = NULL;int data_size = 0;int ret = 0;int64_t src_ch_layout = AV_CH_LAYOUT_STEREO; //初始化这样根据不同文件做调整int64_t dst_ch_layout = AV_CH_LAYOUT_STEREO; //这里设定okint dst_nb_channels = 0;int dst_linesize = 0;int src_nb_samples = 0;int dst_nb_samples = 0;int max_dst_nb_samples = 0;uint8_t **dst_data = NULL;int resampled_data_size = 0;//重新采样if (swr_ctx){swr_free(&swr_ctx);}swr_ctx = swr_alloc();if (!swr_ctx){printf("swr_alloc error \n");return -1;}src_ch_layout = (audio_dec_ctx->channel_layout && audio_dec_ctx->channels == av_get_channel_layout_nb_channels(audio_dec_ctx->channel_layout)) ? audio_dec_ctx->channel_layout : av_get_default_channel_layout(audio_dec_ctx->channels);if (out_channels == 1){dst_ch_layout = AV_CH_LAYOUT_MONO;}else if(out_channels == 2){dst_ch_layout = AV_CH_LAYOUT_STEREO;}else{//可扩展}if (src_ch_layout <= 0){printf("src_ch_layout error \n");return -1;}src_nb_samples = pAudioDecodeFrame->nb_samples;if (src_nb_samples <= 0){printf("src_nb_samples error \n");return -1;}/* set options */av_opt_set_int(swr_ctx, "in_channel_layout",    src_ch_layout, 0);av_opt_set_int(swr_ctx, "in_sample_rate",       audio_dec_ctx->sample_rate, 0);av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", audio_dec_ctx->sample_fmt, 0);av_opt_set_int(swr_ctx, "out_channel_layout",    dst_ch_layout, 0);av_opt_set_int(swr_ctx, "out_sample_rate",       out_sample_rate, 0);av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", (AVSampleFormat)out_sample_fmt, 0);swr_init(swr_ctx);max_dst_nb_samples = dst_nb_samples =av_rescale_rnd(src_nb_samples, out_sample_rate, audio_dec_ctx->sample_rate, AV_ROUND_UP);if (max_dst_nb_samples <= 0){printf("av_rescale_rnd error \n");return -1;}dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,dst_nb_samples, (AVSampleFormat)out_sample_fmt, 0);if (ret < 0){printf("av_samples_alloc_array_and_samples error \n");return -1;}dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, audio_dec_ctx->sample_rate) +src_nb_samples, out_sample_rate, audio_dec_ctx->sample_rate,AV_ROUND_UP);if (dst_nb_samples <= 0){printf("av_rescale_rnd error \n");return -1;}if (dst_nb_samples > max_dst_nb_samples){av_free(dst_data[0]);ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,dst_nb_samples, (AVSampleFormat)out_sample_fmt, 1);max_dst_nb_samples = dst_nb_samples;}data_size = av_samples_get_buffer_size(NULL, audio_dec_ctx->channels,pAudioDecodeFrame->nb_samples,audio_dec_ctx->sample_fmt, 1);if (data_size <= 0){printf("av_samples_get_buffer_size error \n");return -1;}resampled_data_size = data_size;if (swr_ctx){ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)pAudioDecodeFrame->data, pAudioDecodeFrame->nb_samples);if (ret <= 0){printf("swr_convert error \n");return -1;}resampled_data_size = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,ret, (AVSampleFormat)out_sample_fmt, 1);if (resampled_data_size <= 0){printf("av_samples_get_buffer_size error \n");return -1;}}else {printf("swr_ctx null error \n");return -1;}//将值返回去memcpy(out_buf,dst_data[0],resampled_data_size);if (dst_data){av_freep(&dst_data[0]);}av_freep(&dst_data);dst_data = NULL;if (swr_ctx){swr_free(&swr_ctx);}return resampled_data_size;}

交流请加QQ群:62054820
QQ:379969650

0 0
原创粉丝点击