首页 > 代码库 > FFmpeg总结(六)AV系列结构体之AVPacket

FFmpeg总结(六)AV系列结构体之AVPacket

AVPacket位置:libavcodec/avcodec.h下:

技术分享

AVPacket:

  • 通常通过demuxer导出的data packet作为解码器的input data
  • 或是收到来自编码器的data packet,通过muxer进入输出的output data

看如下图,更易理解:
技术分享

对于视频来说,它通常应该包含一个压缩的帧,对于音频,可能包含多个压缩帧,允许编码器输出为空的packet,没有压缩数据,只包含数据(如一些更新参数的编码)

AVPacket 是FFmpeg中为数不多的结构体,它的size是public ABI的一部分,因此它没有libavcodec及libavformat主块中获得分配栈空间及添加新字段。

数据所有权的的语义决于buf字段,如果是组,分组数据是动态分配的,在调用av_packet_unref()把引用计数降到0之前,都是有效定义的。

如果buf字段没有设置av_packet_ref()将拷贝一份代替增加的引用计数

  • 数据分配总是分配通过av_malloc()
  • 数据拷贝总是通过av_packet_ref()
  • 数据释放总是通过av_packet_unref()
typedef struct AVPacket {

    AVBufferRef *buf; //一个引用指向packet数据存储的buffer的引用计数,如果为NULL,packet数据没有引用计数

    int64_t pts; //显示时间戳(AVStream->time_base units)pts主要用于度量解码后的视频帧什么时候被显示出来

    int64_t dts; //解码时间戳(AVStream->time_base units)
    //DTS主要用于视频的解码,在解码阶段使用.PTS主要用于视频的同步和输出.
    //在display的时候使用.在没有B frame的情况下.DTS和PTS的输出顺序是一样的.
    uint8_t *data;
    int   size;
    int   stream_index;

    int   flags; //AV_PKT_FLAG标识

    AVPacketSideData *side_data; //容器中能提供的其他packet数据,packet中包含一些具体信息
    int side_data_elems;

    int64_t duration; // packet的时长(AVStream->time_base units)

    int64_t pos;  //< byte position in stream, -1 if unknown

#if FF_API_CONVERGENCE_DURATION
    /**
     * @deprecated Same as the duration field, but as int64_t. This was required
     * for Matroska subtitles, whose duration values could overflow when the
     * duration field was still an int.
     */
    attribute_deprecated
    int64_t convergence_duration;
#endif
} AVPacket;
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    FFmpeg总结(六)AV系列结构体之AVPacket