【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