目录
引子
翻译一下官方注释:
成员变量:
AVBufferRef *buf
pts
dts
data
size
stream_index
flag
side_data
side_data_elems
duration
pos
opaque
opaque_ref
time_base
引子
AVPacket是ffmpeg基础且非常重要的数据结构,AVPacket存储着压缩数据(视频帧或者音频帧)及相关的描述信息,通常作为解封装器的输出,解码器的输入,是解封装和解码之间的桥梁。典型场景:比如播放一个本地mp4文件,通常的流程是解封装器解析mp4文件,输出一个一个的AVPacket,再根据AVPacket中存储的是视频还是音频(只能是一种视频或音频)送给对应的解码器解码。
翻译一下官方注释:
定义来自ffmpeg5.1,libavcodec\packet.h
AVPacket存储着压缩数据。典型使用场景:AVPacket被解封装器输出并作为解码器的输入,或作为编码器的输出传递给封装器做输入。
对于视频,一个AVPacket通常包含一个视频帧。对于音频,一个AVPacket通常包含几个完整的音频帧。编码器可能会输出空的AVPacket(指的是数据buf为空,但side data不为空,比如side data包含一些码流参数作为编码结束的标志)。
AVPacket包含的数据取决于成员变量buf(关于AVBufferRef的介绍请看前一篇文章:ffmpeg-AVBuffer、AVBufferRef、引用计数机制_小葫芦写代码的博客-CSDN博客)。如果成员变量buf被使用(就是不为NULL,该AVPacket包含的数据是存储在buf指向的AVBufferRef里),该AVPacket指向的数据一直有效直至其引用计数为0。如果buf没被使用(=NULL),该AVPacket包含的数据是成员变量data,当调用av_packet_ref时,会把原数据拷贝到成员变量data指向的地址。
/*** This structure stores compressed data. It is typically exported by demuxers* and then passed as input to decoders, or received as output from encoders and* then passed to muxers.** For video, it should typically contain one compressed frame. For audio it may* contain several compressed frames. Encoders are allowed to output empty* packets, with no compressed data, containing only side data* (e.g. to update some stream parameters at the end of encoding).** The semantics of data ownership depends on the buf field.* If it is set, the packet data is dynamically allocated and is* valid indefinitely until a call to av_packet_unref() reduces the* reference count to 0.** If the buf field is not set av_packet_ref() would make a copy instead* of increasing the reference count.** The side data is always allocated with av_malloc(), copied by* av_packet_ref() and freed by av_packet_unref().** sizeof(AVPacket) being a part of the public ABI is deprecated. once* av_init_packet() is removed, new packets will only be able to be allocated* with av_packet_alloc(), and new fields may be added to the end of the struct* with a minor bump.** @see av_packet_alloc* @see av_packet_ref* @see av_packet_unref*/
typedef struct AVPacket {/*** A reference to the reference-counted buffer where the packet data is* stored.* May be NULL, then the packet data is not reference-counted.*/AVBufferRef *buf;/*** Presentation timestamp in AVStream->time_base units; the time at which* the decompressed packet will be presented to the user.* Can be AV_NOPTS_VALUE if it is not stored in the file.* pts MUST be larger or equal to dts as presentation cannot happen before* decompression, unless one wants to view hex dumps. Some formats misuse* the terms dts and pts/cts to mean something different. Such timestamps* must be converted to true pts/dts before they are stored in AVPacket.*/int64_t pts;/*** Decompression timestamp in AVStream->time_base units; the time at which* the packet is decompressed.* Can be AV_NOPTS_VALUE if it is not stored in the file.*/int64_t dts;uint8_t *data;int size;int stream_index;/*** A combination of AV_PKT_FLAG values*/int flags;/*** Additional packet data that can be provided by the container.* Packet can contain several types of side information.*/AVPacketSideData *side_data;int side_data_elems;/*** Duration of this packet in AVStream->time_base units, 0 if unknown.* Equals next_pts - this_pts in presentation order.*/int64_t duration;int64_t pos; ///< byte position in stream, -1 if unknown/*** for some private data of the user*/void *opaque;/*** AVBufferRef for free use by the API user. FFmpeg will never check the* contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when* the packet is unreferenced. av_packet_copy_props() calls create a new* reference with av_buffer_ref() for the target packet's opaque_ref field.** This is unrelated to the opaque field, although it serves a similar* purpose.*/AVBufferRef *opaque_ref;/*** Time base of the packet's timestamps.* In the future, this field may be set on packets output by encoders or* demuxers, but its value will be by default ignored on input to decoders* or muxers.*/AVRational time_base;
} AVPacket;
成员变量:
AVBufferRef *buf
在上方官方注释已经解释过。
pts
显示时间戳,单位是AVStream->time_base,比如AVStream->time_base=0.001秒,pts=40,则packet要在0.001*40=0.04秒显示。用来描述该packet的显示时间,默认值是AV_NOPTS_VALUE(如果文件没有描述这个pts,会在av_init_packet中置为AV_NOPTS_VALUE)。pts必须大于等于dts,因为显示不可能在解码之前。
dts
解码时间戳,参考pts,描述该packet解码的时间。默认值AV_NOPTS_VALUE
data
参考AVBufferRef *buf的介绍和av_packet_ref的定义,如果该AVPacket指向的数据不使用引用计数,就使用data指针指向数据。
size
成员变量data使用时对应的data size。
stream_index
流id,可以通过id来区分是视频流、音频流、字幕流。
flag
描述该packet的属性,比如该packet的内容损坏/需要放弃等。
side_data
容器提供的用来描述该packet的辅助信息。
FFmpeg: AVPacket
side_data_elems
side_data的数量。
duration
该packet的播放持续时间,和pts/dts的单位一样。比如duration=40,AVStream->time_base=0.001秒,则该packet的duration=40*0.001=0.04秒。通常duration=下一个packet的pts - 当前packet的pts。
pos
该packet在stream中的位置,单位byte
opaque
用户使用的私有数据。
opaque_ref
和上面的opaque成员没什么关系。看注释也没看明白,但是从ffmpeg源码里面看好像也没用到。
time_base
该packet使用的时间基。