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


    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    单声道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, },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    java计算机毕业设计网上拍卖系统源程序+mysql+系统+lw文档+远程调试
    三层神经网络的训练模型,深度神经网络如何训练
    TypeError: copytree() got an unexpected keyword argument ‘dirs_exist_ok‘
    JUC并发编程系列详解篇六(死锁的基本概念)
    量化交易全流程(七)
    前端应用聚合整改
    C/C++多进程高并发框架分享【内附可执行源码注释完整】
    算法44-异或运算|交换int|找出出现奇数次的数|提取右边以一个1
    一卷到底,大明哥带你横扫 Netty
    8. JVM-堆
  • 原文地址:https://blog.csdn.net/SanShuiGeGe/article/details/126430503