"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
ffmpeg重采样resample包含AVAudioFifo(三) - 朱韦刚(zhuweigangzwg)的技术博客
- 博客频道 - CSDN.NET
朱韦刚(zhuweigangzwg)的技术博客
QQ:379969650 QQ技术群: 62054820
 
【5月书讯】流畅的Python,终于等到你!
 
CSDN日报20170522 ——《从个人习惯到真正的好方法》
 
如何看待 Kotlin 成为 Android 官方支持开发语言?
[置顶]
ffmpeg重采样resample包含AVAudioFifo(三)
2017-05-22 11:29
130人阅读
评论(0)
收藏
举报
本文章已收录于:
.embody{
padding:10px 10px 10px;
margin:0 -20px;
border-bottom:solid 1px #ededed;
}
.embody_b{
margin:0 ;
padding:10px 0;
}
.embody .embody_t,.embody .embody_c{
display: inline-block;
margin-right:10px;
}
.embody_t{
font-size: 12px;
color:#999;
}
.embody_c{
font-size: 12px;
}
.embody_c img,.embody_c em{
display: inline-block;
vertical-align: middle;
}
.embody_c img{
width:30px;
height:30px;
}
.embody_c em{
margin: 0 20px 0 10px;
color:#333;
font-style: normal;
}
分类:
ffmpeg(25)
版权声明:本文为博主原创文章,未经博主允许不得转载。
本篇文章记录ffmpeg重采样和AVAudioFifo一起用的实现,如果看完整的流程请看这边文章:http://blog.csdn.net/zhuweigangzwg/article/details/72481966,本文只讲重采样和AVAudioFifo的用法,具体看代码注释。
SwrContext * ffmpeg_init_pcm_resample(Out_stream_info * out_stream_info,AVFrame *in_frame, AVFrame *out_frame) { SwrContext * swr_ctx = NULL; swr_ctx = swr_alloc(); if (!swr_ctx) { printf("swr_alloc error \n"); return NULL; } AVCodecContext * audio_dec_ctx = m_icodec->streams[m_in_audio_stream_idx]->codec; AVSampleFormat sample_fmt; sample_fmt = (AVSampleFormat)out_stream_info->m_dwBitsPerSample; //样本 int out_channel_layout = av_get_default_channel_layout(out_stream_info->m_dwChannelCount); if (audio_dec_ctx->channel_layout == 0) { audio_dec_ctx->channel_layout = av_get_default_channel_layout(m_icodec->streams[m_in_audio_stream_idx]->codec->channels); } /* set options */ av_opt_set_int(swr_ctx, "in_channel_layout", audio_dec_ctx->channel_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", out_channel_layout, 0); av_opt_set_int(swr_ctx, "out_sample_rate", out_stream_info->m_dwFrequency, 0); av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", sample_fmt, 0); swr_init(swr_ctx); int64_t src_nb_samples = in_frame->nb_samples; //计算输出的samples 和采样率有关 例如:48000转44100,samples则是从1152转为1059,除法 out_frame->nb_samples = av_rescale_rnd(src_nb_samples, out_stream_info->m_dwFrequency, audio_dec_ctx->sample_rate, AV_ROUND_UP); int ret = av_samples_alloc(out_frame->data, &out_frame->linesize[0], out_stream_info->m_dwChannelCount, out_frame->nb_samples,out_stream_info->m_oaudio_st->codec->sample_fmt,1); if (ret < 0) { return NULL; } out_stream_info->m_audiofifo = av_audio_fifo_alloc(out_stream_info->m_oaudio_st->codec->sample_fmt, out_stream_info->m_oaudio_st->codec->channels, out_frame->nb_samples); return swr_ctx; } int ffmpeg_preform_pcm_resample(Out_stream_info * out_stream_info,SwrContext * pSwrCtx,AVFrame *in_frame, AVFrame *out_frame) { int ret = 0; int samples_out_per_size = 0; //转换之后的samples大小 if (pSwrCtx != NULL) { //这里注意下samples_out_per_size这个值和 out_frame->nb_samples这个值有时候不一样,ffmpeg里面做了策略不是问题。 samples_out_per_size = swr_convert(pSwrCtx, out_frame->data, out_frame->nb_samples, (const uint8_t**)in_frame->data, in_frame->nb_samples); if (samples_out_per_size < 0) { return -1; } AVCodecContext * audio_dec_ctx = m_icodec->streams[m_in_audio_stream_idx]->codec; int buffersize_in = av_samples_get_buffer_size(&in_frame->linesize[0],audio_dec_ctx->channels, in_frame->nb_samples, audio_dec_ctx->sample_fmt, 1); //修改分包内存 int buffersize_out = av_samples_get_buffer_size(&out_frame->linesize[0], out_stream_info->m_oaudio_st->codec->channels, samples_out_per_size, out_stream_info->m_oaudio_st->codec->sample_fmt, 1); int fifo_size = av_audio_fifo_size(out_stream_info->m_audiofifo); fifo_size = av_audio_fifo_realloc(out_stream_info->m_audiofifo, av_audio_fifo_size(out_stream_info->m_audiofifo) + out_frame->nb_samples); av_audio_fifo_write(out_stream_info->m_audiofifo,(void **)out_frame->data,samples_out_per_size); fifo_size = av_audio_fifo_size(out_stream_info->m_audiofifo); out_frame->pkt_pts = in_frame->pkt_pts; out_frame->pkt_dts = in_frame->pkt_dts; //有时pkt_pts和pkt_dts不同,并且pkt_pts是编码前的dts,这里要给avframe传入pkt_dts而不能用pkt_pts //out_frame->pts = out_frame->pkt_pts; out_frame->pts = in_frame->pkt_dts; //测试用 if (out_stream_info->user_stream_id ==11) { if (pcm_file == NULL) { pcm_file = fopen("11.pcm","wb"); } int wtiresize = fwrite(out_frame->data[0],buffersize_out,1, pcm_file); fflush(pcm_file); } } ret = 1; return ret; } void ffmpeg_uinit_pcm_resample(SwrContext * swr_ctx,AVAudioFifo * audiofifo) { if (swr_ctx) { swr_free(&swr_ctx); swr_ctx = NULL; } if(audiofifo) { av_audio_fifo_free(audiofifo); audiofifo = NULL; } }
存储的声音波形pcm如下:
运行后转码文件如下效果:
如有错误请指正:交流请加QQ群:62054820QQ:379969650.