【FFmpeg】AVPacket结构体

【FFmpeg】AVPacket结构体

示例工程:
【FFmpeg】调用ffmpeg库实现264软编
【FFmpeg】调用ffmpeg库实现264软解
【FFmpeg】调用ffmpeg库进行RTMP推流和拉流
【FFmpeg】调用ffmpeg库进行SDL2解码后渲染

流程分析:
【FFmpeg】编码链路上主要函数的简单分析
【FFmpeg】解码链路上主要函数的简单分析

结构体分析:
【FFmpeg】AVCodec结构体
【FFmpeg】AVCodecContext结构体
【FFmpeg】AVStream结构体
【FFmpeg】AVFormatContext结构体
【FFmpeg】AVIOContext结构体

1.AVPacket结构体的定义

AVPacket结构体定义在libavcodec\codec.h中,通常用于存储已编码之后的数据,例如264格式的视频数据

c 复制代码
/**
 * 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
 */
// 1.该结构存储压缩数据。它通常由解复用器导出,然后作为输入传递给解码器,或者作为编码器的输出接收,然后传递给解码器
// 
// 2.对于视频,它通常应该包含一个压缩帧。对于音频,它可能包含几个压缩帧。编码器允许输出空数据包,没有压缩数据,只包含侧数据(例如,在编码结束时更新一些流参数)
// 
// 3.数据所有权的语义取决于buf字段。如果设置了该值,则数据包数据将被动态分配并无限期有效,直到调用av_packet_unref()将引用计数减少为0
// 
// 4.如果没有设置buf字段,av_packet_ref()将复制而不是增加引用计数
//
// 5.辅助数据总是由av_malloc()分配,由av_packet_ref()复制,由av_packet_unref()释放。
// 
// 6.不赞成将sizeof(AVPacket)作为公共ABI的一部分。一旦av_init_packet()被删除,新的数据包将只能用av_packet_alloc()分配,新的字段可能会添加到结构体的末尾
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.
     */
    // AVStream->time_base单位表示时间戳;解压后的数据包呈现给用户的时间
    // 可以AV_NOPTS_VALUE,如果它不是存储在文件
    // pts必须大于或等于dts,因为在解压缩之前无法显示,除非想要查看十六进制转储。有些格式误用术语dts和pts/cts来表示不同的含义。这样的时间戳必须转换为真正的pts/dts,然后才能存储在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.
     */
    // 解压时间戳在AVStream->time_base单位;数据包被解压的时间
    // 可以AV_NOPTS_VALUE,如果它不是存储在文件
    int64_t dts;
    // 存储已压缩的数据
    uint8_t *data;
    // 数据大小
    int   size;
    // 流索引号
    int   stream_index;
    /**
     * A combination of AV_PKT_FLAG values
     */
    // 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
		#define AV_PKT_FLAG_DISCARD   0x0004 ///< 标志用于丢弃需要保持有效解码器状态但不需要输出的数据包,并且在解码后应该丢弃
		#define AV_PKT_FLAG_TRUSTED   0x0008 ///< 数据包来自可信来源,否则,可能会遵循不安全的结构,例如指向数据包外部数据的任意指针
		#define AV_PKT_FLAG_DISPOSABLE 0x0010 /// <标志用于指示包含可被解码器丢弃的帧的数据包。即非参考系
	*/
    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.
     */
    // 该数据包在AVStream->time_base单位中的持续时间,如果未知则为0。按表示顺序等于next_pts - this_pts
    int64_t duration;
	// 码流中字节的位置,如果不知道则设置为-1
    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.
     */
    // 1.AVBufferRef供API用户免费使用。FFmpeg永远不会检查缓冲区ref的内容。当数据包未被引用时,
    // FFmpeg会对其调用av_buffer_unref()。Av_packet_copy_props()调用用av_buffer_ref()为目标包的opaque字段创建一个新的引用
    // 
    // 2.这与opaque字段无关,尽管它的目的相似
    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;

AVPacket结构体的定义与老版本相似,基本没有大的改动,其中比较关键的内容包括:

(1)uint8_t *data:存储压缩数据的变量

(2)int size:数据大小

(3)int stream_index:流的索引号

(4)int flags:描述当前pkt的使用情况

(5)int64_t pts:解压后的数据包呈现给用户的时间

(6)int64_t dts:数据包被解压的时间

CSDN : https://blog.csdn.net/weixin_42877471
Github : https://github.com/DoFulangChen

相关推荐
捕鲸叉15 分钟前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer19 分钟前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq21 分钟前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
青花瓷2 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode
幺零九零零3 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
捕鲸叉3 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
岁月小龙3 小时前
如何让ffmpeg运行时从当前目录加载库,而不是从/lib64
ffmpeg·origin·ffprobe·rpath
Dola_Pan4 小时前
C++算法和竞赛:哈希算法、动态规划DP算法、贪心算法、博弈算法
c++·算法·哈希算法
yanlou2334 小时前
KMP算法,next数组详解(c++)
开发语言·c++·kmp算法
小林熬夜学编程4 小时前
【Linux系统编程】第四十一弹---线程深度解析:从地址空间到多线程实践
linux·c语言·开发语言·c++·算法