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

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

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

cpp 复制代码
/**
 * @}
 */

/**
 * @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数据未被引用计数。关于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的组合。值有如下选择:

cpp 复制代码
#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_elems: side_data的数量。

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

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

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

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

相关推荐
EasyCVR1 小时前
萤石设备视频接入平台EasyCVR多品牌摄像机视频平台海康ehome平台(ISUP)接入EasyCVR不在线如何排查?
运维·服务器·网络·人工智能·ffmpeg·音视频
runing_an_min1 小时前
ffmpeg 视频滤镜:屏蔽边框杂色- fillborders
ffmpeg·音视频·fillborders
岁月小龙12 小时前
如何让ffmpeg运行时从当前目录加载库,而不是从/lib64
ffmpeg·origin·ffprobe·rpath
行者记2 天前
ffmpeg命令——从wireshark包中的rtp包中分离h264
测试工具·ffmpeg·wireshark
EasyCVR2 天前
国标GB28181视频平台EasyCVR私有化视频平台工地防盗视频监控系统方案
运维·科技·ffmpeg·音视频·1024程序员节·监控视频接入
hypoqqq2 天前
使用ffmpeg播放rtsp视频流
ffmpeg
cuijiecheng20182 天前
音视频入门基础:FLV专题(24)——FFmpeg源码中,获取FLV文件视频信息的实现
ffmpeg·音视频
QMCY_jason2 天前
黑豹X2 armbian 编译rkmpp ffmpeg 实现CPU视频转码
ffmpeg
苍天饶过谁?2 天前
SDL基本使用
ffmpeg
HZ355722 天前
ffmpeg视频解码
ffmpeg·音视频