音视频解码流程详解


1、解码整体流程

(1) 音频解码整体流程

在这里插入图片描述

(2)视频解码整体流程
在这里插入图片描述


2、FFmpeg音视频解码详细流程

在这里插入图片描述


3、关键数据结构

AVCodecParser:⽤于解析输⼊的数据流并把它分成⼀帧⼀帧的压缩编码数据。⽐较形象
的说法就是把⻓⻓的⼀段连续的数据“切割”成⼀段段的数据。

比如:ffmpeg-4.2.1\libavcodec\aac_parser.c

 AVCodecParser ff_aac_parser = {
	codec_ids = { AV_CODEC_ID_AAC },
	priv_data_size = sizeof(AACAC3ParseContext),
	parser_init = aac_parse_init,
	parser_parse = ff_aac_ac3_parse,
	parser_close = ff_parse_close,
};

从AVCodecParser结构的实例化我们可以看出来,不同编码类型的parser是和CODE_ID进⾏绑定的。所以也就可以解释:parser = av_parser_init(codec->id);


4、关键函数说明

(1)avcodec_find_decoder:根据指定的AVCodecID查找注册的解码器。

(2)av_parser_init:初始化AVCodecParserContext。

(3)avcodec_alloc_context3:为AVCodecContext分配内存。

(4)avcodec_open2:打开解码器。

(5)av_parser_parse2:解析获得⼀个Packet。

(6)av_get_bytes_per_sample: 获取每个sample中的字节数。

(7)avcodec_send_packet:将AVPacket压缩数据给解码器。
原型: int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);

作用: ⽀持将裸流数据包送给解码器。

参数:
1)avctx:解码上下⽂;
2)avpkt:输⼊AVPakcet.通常情况下,输⼊数据是⼀个单⼀的视频帧或者⼏个完整的⾳频帧。调⽤者保留包的原有属性,解码器不会修改包的内容。解码器可能创建对包的引用。如果包没有引⽤计数将拷贝⼀份。跟以往的API不⼀样,输⼊的包的数据将被完全地消耗,如果包含有多个帧,要求多次调⽤avcodec_recvive_frame,直到avcodec_recvive_frame返回 VERROR(EAGAIN)或AVERROR_EOF 。输⼊参数可以为NULL,或者AVPacket的data域设置为NULL或者size域设置为0,表示将刷新所有的包,意味着数据流已经结束了。第⼀次发送刷新会总会成功,第⼆次发送刷新包是没有必要的,并且返回AVERROR_EOF,如果×××缓存了⼀些帧,返回⼀个刷新包,将会返回所有的解码包。

返回值:
1)0:表示成功;
2)AVERROR(EAGAIN):当前状态不接受输⼊,⽤户必须先使⽤ avcodec_receive_frame() 读取数据帧;
3)AVERROR_EOF:解码器已刷新,不能再向其发送新包;
4)AVERROR(EINVAL):没有打开解码器,或者这是⼀个编码器,或者要求刷新;
5)AVERRO(ENOMEN):⽆法将数据包添加到内部队列。

注意:
输⼊的avpkt-data缓冲区必须⼤于AV_INPUT_PADDING_SIZE,因为优化的字节流读取器必须⼀次读取32或者64⽐特的数据。
不能跟之前的API(例如avcodec_decode_video2)混⽤,否则会返回不可预知的错误。
在将包发送给解码器的时候,AVCodecContext必须已经通过avcodec_open2打开


(8)avcodec_receive_frame:获取到解码后的AVFrame数据。
函数:int avcodec_receive_frame ( AVCodecContext * avctx, AVFrame * frame )

作用:从解码器返回已解码的输出数据。

参数:
1)avctx: 编解码器上下⽂。
2)frame: 获取使⽤reference-counted机制的audio或者video帧(取决于解码器类型)。请注意,在执⾏其他操作之前,函数内部将始终先调⽤av_frame_unref(frame)。

返回值:
1)0: 成功,返回⼀个帧;
2)AVERROR(EAGAIN): 该状态下没有帧输出,需要使⽤avcodec_send_packet发送新的packet到解码器;
3)AVERROR_EOF: 解码器已经被完全刷新,不再有输出帧;
4)AVERROR(EINVAL): 编解码器没打开;
5)其他<0的值: 具体查看对应的错误码。

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值