FFmpeg中AVPacket和AVFrame关系

        最近在研究ffplay3.2.4的源码,ffplay中有两个队列一个PacketQueue, 一个FrameQueue,对这两个队列之间的关系不是很清楚。于是对这两个结构仔细研究一下。

1、数据结构含义

AVPacket

        用于存储压缩的数据,分别包括有音频压缩数据,视频压缩数据和字幕压缩数据。它通常在解复用操作后存储压缩数据,然后作为输入传给解码器。或者由编码器输出然后传递给复用器。

        对于视频压缩数据,一个AVPacket通常包括一个视频帧。对于音频压缩数据,可能包括几个压缩的音频帧。

AVFrame

         用于存储解码后的音频或者视频数据。AVFrame必须通过av_frame_alloc进行分配,通过av_frame_free释放。

两者之间的关系

        av_read_frame得到压缩的数据包AVPacket,一般有三种压缩的数据包(视频、音频和字幕),都用AVPacket表示。然后调用avcodec_decode_video2对AVPacket进行解码得到AVFrame。

2、队列关系

        ffplay中有三种PacketQueue,分别为视频包队列(videoq)、音频包队列(audioq)和字幕包队列(subtitleq)。相应地,也有三种FrameQueue,视频帧队列(pictq)、音频帧队列(sampq)和字幕帧队列(subpq)。
        队列的初始化工作是在stream_open函数中进行,分别通过packet_queue_init和frame_queue_init执行初始化操作。需要注意的是,初始化中PacketQueue没有手动分配AVPacket结构,而是直接使用解码过程中的AVPacket。FrameQueue中则是通过av_frame_alloc手动分配了AVFrame结构。

        在read_thread函数中,通过av_read_frame函数读取数据包,然后调用packet_queue_put将AVPacket添加到PacketQueue中。

        在video_thread函数中,通过get_video_frame函数读取数据帧,然后调用queue_picture将AVFrame添加到FrameQueue中。

        那么两个队列是怎么联系起来的呢?让我们分析read_thread函数。read_thread函数的主要工作:首先,创建解复用和解码所需要的数据结构。其次,分别通过stream_component_open函数打开三种数据流。最后,通过av_read_frame将解复用后的数据包分别添加到对应的PacketQueue中。在stream_component_open函数主要负责解码工作,ffplay中为解码工作专门设置了一个数据结构Decoder,Decoder结构中有一个成员queue,这个queue就是指的输入的PacketQueue,通过decoder_init函数来指定PacketQueue。这个工作就是在stream_component_open中执行的。指定PacketQueue之后通过get_video_frame函数从PacketQueue中解码出AVFrame结构,最后通过queue_picture函数将解码得到的帧添加到FrameQueue。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值