ffmpeg重采样resample包含AVAudioFifo(三)

"-//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

【活动】2017 CSDN博客专栏评选

&nbsp

【5月书讯】流畅的Python,终于等到你!
   &nbsp

CSDN日报20170522 ——《从个人习惯到真正的好方法》

   &nbsp

如何看待 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)

作者同类文章X

版权声明:本文为博主原创文章,未经博主允许不得转载。

本篇文章记录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.

时间: 2024-10-11 02:58:58

ffmpeg重采样resample包含AVAudioFifo(三)的相关文章

使用ffmpeg合并视频文件的三种方法

ffmpeg合并视频的方法有三种.国内大多数仅介绍了其中之一.于是觉得有必要翻译一下.其实在ffmpeg的 FAQ文档中有比较详细的说明. 使用concat协议进行视频文件的合并 这种方式的适用场景是:视频容器是MPEG-1, MPEG-2 PS或DV等可以直接进行合并的.换句话说,其实可以直接用cat或者copy之类的命令来对视频直接进行合并.很多文章介绍了这种方法,但适用性却没有提及.这并不是一个通用的方法.典型的命令示例如下: ffmpeg -i concat:"intermediate1

ffmpeg文档34-音频滤镜

34 音频滤镜 当你配置编译FFmpeg时,先采用--disable-filters可以禁止所有的滤镜,然后显式配置想要支持的滤镜. 下面是当前可用的音频滤镜 adelay 延迟一个或者多个音频通道 它接受如下选项: delays 参数是以|分隔的列表字符串,分别用于指明对应各个通道延迟的微秒(milliseconds)数.应提供至少一个大于0的延迟.未使用的延迟将被静默忽略.如果延迟值数量小于通道数量,则剩余通道不会被延迟. adelay例子 第一通道延迟1.5秒,第三通道0.5秒(其它通道均

(转载)[FFmpeg]使用ffmpeg从各种视频文件中直接截取视频图片

你曾想过从一个视频文件中提取图片吗?在Linux下就可以,在这个教程中我将使用ffmpeg来从视频中获取图片. 什么是ffmpeg?What is ffmpeg? ffmpeg是一个非常有用的命令行程序,它可以用来转码媒体文件.它是领先的多媒体框架FFmpeg的一部分,其有很多功能,比如解码.编码.转码.混流.分离.转化为流.过滤以及播放几乎所有的由人和机器创建的媒体文件. 在这个框架中包含有各种工具,每一个用于完成特定的功能.例如,ffserver能够将多媒体文件转化为用于实时广播的流,ffp

FFMPEG视音频编解码零基础学习方法-b

感谢大神分享,虽然现在还看不懂,留着大家一起看啦 PS:有不少人不清楚“FFmpeg”应该怎么读.它读作“ef ef em peg” 0. 背景知识 本章主要介绍一下FFMPEG都用在了哪里(在这里仅列几个我所知的,其实远比这个多).说白了就是为了说明:FFMPEG是非常重要的. 使用FFMPEG作为内核视频播放器: Mplayer,ffplay,射手播放器,暴风影音,KMPlayer,QQ影音... 使用FFMPEG作为内核的Directshow Filter: ffdshow,lav fil

FFMPEG视音频编解码零基础学习方法

在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“大神”和初学者之间好像有一个不可逾越的鸿沟.“大神”们水平高超,探讨着深奥的问题:而初学者们还停留在入门阶段.究竟是什么原因造成的这种“两极分化”呢?最后,我发现了问题的关键:FFMPEG难度比较大,却没有一个循序渐进,由简单到复杂的教程.现在网上的有关FFMPEG的教程多半难度比较大,不太适合刚接

ffmpeg转码MPEG2-TS的音视频同步机制分析

http://blog.chinaunix.net/uid-26000296-id-3483782.html 一.FFmpeg忽略了adaptation_field()数据FFmpeg忽略了包含PCR值的adaptation_filed数据; 代码(libavformat/mpegts.c)分析如下: /* 解析TS包 */int handle_packet(MpegTSContext *ts, const uint8_t *packet){  ...   pid = AV_RB16(packe

[总结]FFMPEG视音频编解码零基础学习方法

转至 http://my.oschina.net/leixiaohua1020/blog/302174 在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“大神”和初学者之间好像有一个不可逾越的鸿沟.“大神”们水平高超,探讨着深奥的问题:而初学者们还停留在入门阶段.究竟是什么原因造成的这种“两极分化”呢?最后,我发现了问题的关键:FFMPEG难度比较

转[总结]FFMPEG视音频编解码零基础学习方法 .

http://blog.csdn.net/leixiaohua1020/article/details/15811977 在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“大神”和初学者之间好像有一个不可逾越的鸿沟.“大神”们水平高超,探讨着深奥的问题:而初学者们还停留在入门阶段.究竟是什么原因造成的这种“两极分化”呢?最后,我发现了问题的关键:F

ffmpeg使用转码学习

ffmpeg在官网上描述自身:是一个对视频和音频进行记录,转换,流化的完整的跨平台解决方案.事实上,现在有很多工具都是基于ffmpeg来进行视频音频的处理工具的.比如鼎鼎大名的格式工厂,就是使用ffmpeg来作为内核的转码工具. 理解一些音视频的编码知识. 我们平时看的视频文件格式:mp4/rmvb/mkv/avi其实是一个容器.这个容器中装的东西分为两大类:音频和视频.对于视频这部分,它包含的编码格式有:H264/H265/VP8/VC1等.对于音频这个部分,它包含的编码格式有:AAC/MP3