FFmpeg采坑记录——aformat过滤器输出的linesize大小和音频编码后stream_index

本文详细介绍了在使用FFmpeg处理音频流时遇到的三个问题:音频过滤器输出帧的linesize不正确,编码器输出stream_index需要手动设置,以及AVFrame内存分配的特殊性。同时,解释了`channels`和`channel_layout`字段的含义,展示了不同音频通道布局的对应关系。

1. 流程图
代码流程如图,视频流不做解码,音频流解码为pcm(FLIP,44.1K,MONO),通过aresample和aformat Filter转换采样率和采样格式,Filter输出为pcm(S16,16K,MONO)。
流程图

音频解码后的frame数据格式如下图:
frame
2. 遇到的问题
2.1 如下图,音频过滤器输出frameFilter的linesize大小不是真实数据长度。linesize[0]=832,而根据nb_sample计算的长度为nb_sample*sizeof(short)=355*2=710,应当使用后者。
frameFilter
2.2 编码器输出pktEncode的srream_index默认为0,如果是音频流,则需要手动改为1,再送mux,否则会报错[AVBSFContext @ 00918400] Failed to send packet to filter h264_mp4toannexb for stream 0
pktEncode
2.3 使用av_frame_get_buffer接口为AVFrame申请yuv420p格式内存,内存分布在frame.data[0]、frame.data[1]、frame.data[2],但只有frame.buf[0].data合法,都在这一块内存上。如下图。
这个情况我在自己的台式机上遇见过,另一台虚拟机上buf[]和data[]是对应的,ffmpeg版本也是一样的,比较奇怪。所以,尽量还是用data[]字段,不要用buf[].data字段。
av_frame_get_buffer

3. channels和channel_layout字段说明
channels:表示几个音频通道;
channel_layout:表示通道格式类型。
eg.frame->channels=2;frame->channel_layout=3,表示2个音频通道,为立体声;
eg.
frameFilter->channels=1;frameFilter->channel_layout=4,表示1个音频通道,为单声道。

详见源码channel_layout.h头文件中:

#define AV_CH_FRONT_LEFT             0x00000001
#define AV_CH_FRONT_RIGHT            0x00000002
#define AV_CH_FRONT_CENTER           0x00000004

#define AV_CH_LAYOUT_MONO              (AV_CH_FRONT_CENTER)
#define AV_CH_LAYOUT_STEREO            (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)

单声道mono为4,立体声stereo为3。

更多的对应关系:

channel_layout_map[]
	{ "mono",        1,  AV_CH_LAYOUT_MONO },
	{ "stereo",      2,  AV_CH_LAYOUT_STEREO },
	{ "2.1",         3,  AV_CH_LAYOUT_2POINT1 },
	{ "3.0",         3,  AV_CH_LAYOUT_SURROUND },
	{ "3.0(back)",   3,  AV_CH_LAYOUT_2_1 },
	{ "4.0",         4,  AV_CH_LAYOUT_4POINT0 },
	{ "quad",        4,  AV_CH_LAYOUT_QUAD },
	{ "quad(side)",  4,  AV_CH_LAYOUT_2_2 },
	{ "3.1",         4,  AV_CH_LAYOUT_3POINT1 },
	{ "5.0",         5,  AV_CH_LAYOUT_5POINT0_BACK },
	{ "5.0(side)",   5,  AV_CH_LAYOUT_5POINT0 },
	{ "4.1",         5,  AV_CH_LAYOUT_4POINT1 },
	{ "5.1",         6,  AV_CH_LAYOUT_5POINT1_BACK },
	{ "5.1(side)",   6,  AV_CH_LAYOUT_5POINT1 },
	{ "6.0",         6,  AV_CH_LAYOUT_6POINT0 },
	{ "6.0(front)",  6,  AV_CH_LAYOUT_6POINT0_FRONT },
	{ "hexagonal",   6,  AV_CH_LAYOUT_HEXAGONAL },
	{ "6.1",         7,  AV_CH_LAYOUT_6POINT1 },
	{ "6.1",         7,  AV_CH_LAYOUT_6POINT1_BACK },
	{ "6.1(front)",  7,  AV_CH_LAYOUT_6POINT1_FRONT },
	{ "7.0",         7,  AV_CH_LAYOUT_7POINT0 },
	{ "7.0(front)",  7,  AV_CH_LAYOUT_7POINT0_FRONT },
	{ "7.1",         8,  AV_CH_LAYOUT_7POINT1 },
	{ "7.1(wide)",   8,  AV_CH_LAYOUT_7POINT1_WIDE },
	{ "octagonal",   8,  AV_CH_LAYOUT_OCTAGONAL },
	{ "downmix",     2,  AV_CH_LAYOUT_STEREO_DOWNMIX, },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值