FFmpeg存放压缩后的音视频数据的结构体:AVPacket简介

=================================================================

AVPacket结构体和其相关的函数分析:

FFmpeg存放压缩后的音视频数据的结构体:AVPacket简介

FFmpeg源码:av_init_packet、get_packet_defaults、av_packet_alloc函数分析

FFmpeg源码:av_packet_free_side_data、av_packet_unref、av_packet_free函数分析

FFmpeg源码:packet_alloc、av_new_packet、av_shrink_packet、av_grow_packet函数分析

FFmpeg源码:av_packet_move_ref、av_packet_make_refcounted函数分析

FFmpeg源码:PacketList结构体、avpriv_packet_list_put、avpriv_packet_list_get、avpriv_packet_list_free函数分析

FFmpeg源码:append_packet_chunked、av_get_packet、av_append_packet函数分析

FFmpeg中调用av_read_frame函数导致的内存泄漏问题

使用vs诊断工具检测FFmpeg的内存泄漏问题

=================================================================

FFmpeg源码中通过AVPacket存储压缩后的音视频数据。它通常由解复用器(demuxers)输出,然后作为输入传递给解码器,或者从编码器作为输出接收,然后传递给多路复用器(muxers)。对于视频,它通常包含一个压缩帧;对于音频,它可能包含几个压缩帧。编码器允许输出不包含压缩音视频数据、只包含side data(边数据:例如,在编码结束时更新一些流参数)的空的数据包( empty packets)。

AVPacket结构体声明在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的头文件libavcodec/packet.h中:

/**
 * @}
 */

/**
 * @defgroup lavc_packet AVPacket
 *
 * Types and functions for working with AVPacket.
 * @{
 */

/**
 * 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;

成员变量buf:AVBufferRef类型指针,指向“存储packet(一个数据包的压缩后的音视频)数据的引用计数缓冲区”。如果为NULL,表示该packet数据未被引用计数。AVPacket通过AVBufferRef来管理引用计数缓冲区。通过AVBufferRef结构体里面的AVBuffer里面的成员变量refcount记录资源使用的次数,控制资源的释放。关于AVBufferRef类型可以参考:《FFmpeg引用计数数据缓冲区相关的结构体:AVBuffer、AVBufferRef简介》。

成员变量pts:显示时间戳(presentation time stamp)。即帧显示的时间刻度,用来告诉播放器在哪个时间点显示此帧(可以简单理解为这帧视频或音频数据的播放时间)。其单位不是秒,而是以AVStream->time_base为单位。pts必须大于或等于dts,因为一帧视频或音频数据必须在解码后才能播放,所以一帧视频或音频数据的显示/播放时间必须大于或等于解码时间。

成员变量dts:解码时间戳(Decompression timestamp)。即帧解码的时间刻度,用来告诉播放器在哪个时间点解码此帧。其单位不是秒,而是以AVStream->time_base为单位。

成员变量data:指针,指向“存放压缩后的一帧(对于视频通常包含一个压缩帧,对于音频可能包含几个压缩帧)音视频数据的缓冲区”。

成员变量size:成员变量data指向的缓冲区的大小,单位为字节。

成员变量stream_index:索引,用来标识该AVPacket所属的视频/音频流的序号,表示这是第几路流。注意:它是从0而不是从1开始的。

成员变量flags:AV_PKT_FLAG的组合。值有如下选择:

#define AV_PKT_FLAG_KEY     0x0001 ///< The packet contains a keyframe
#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
/**
 * Flag is used to discard packets which are required to maintain valid
 * decoder state but are not required for output and should be dropped
 * after decoding.
 **/
#define AV_PKT_FLAG_DISCARD   0x0004
/**
 * The packet comes from a trusted source.
 *
 * Otherwise-unsafe constructs such as arbitrary pointers to data
 * outside the packet may be followed.
 */
#define AV_PKT_FLAG_TRUSTED   0x0008
/**
 * Flag is used to indicate packets that contain frames that can
 * be discarded by the decoder.  I.e. Non-reference frames.
 */
#define AV_PKT_FLAG_DISPOSABLE 0x0010

AV_PKT_FLAG_KEY:数据包包含一个关键帧,即当前AVPacket是关键帧。

AV_PKT_FLAG_CORRUPT:数据包内容已损坏。

AV_PKT_FLAG_DISCARD:用于丢弃需要保持有效解码器状态但不需要输出的数据包,并且在解码后应该丢弃。带有该标志的AVPacket所携带的数据为解码器相关的信息,不会被解码出一幅图像。

AV_PKT_FLAG_TRUSTED:该数据包来自一个可信的源。

AV_PKT_FLAG_DISPOSABLE:用于指示包含可以被解码器丢弃的帧的数据包。也就是非参考帧。

成员变量side_data:存放“容器可以提供的额外数据包数据”的数组的首地址。数据包可以包含多种类型的边信息,比如,在编码结束的时候更新一些流的参数。指针side_data指向的空间存储了用于解码、展现或处理编码流的辅助信息,它通常由解复用器和编码器导出,可以以分组为单位提供给解码器和复用器,也可以作为全局侧数据(应用于整个编码流)。

成员变量side_data_elems: side_data的数量。

成员变量duration:该数据包的持续时间,以AVStream->time_base为单位。值为下一个数据包的pts减去当前数据包的pts。如果值为0表示未知。

成员变量pos:该数据包在流中的位置,单位为字节。值为-1表示未知。

成员变量opaque:指针,指向“存放用户使用的私有数据的缓冲区”。

成员变量time_base:AVRational类型,数据包时间戳的时间基准,即pts和dts的时间基。关于AVRational类型可以参考:《FFmpeg有理数相关的源码:AVRational结构体和其相关的函数分析》。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值