AVPacket
基本介绍
AVPacket
是 FFmpeg 库中的一个重要结构体,用于表示音频、视频或字幕等媒体数据的一个数据包(packet)。在多媒体处理流程中,AVPacket
是最基本的传输和处理单元,它包含了编解码数据以及与数据相关的元信息,如时间戳、数据大小等。
AVPacket
的作用
AVPacket
是在解复用(demuxing)和复用(muxing)过程中传递音视频数据的结构体。解复用器从多媒体文件中提取出 AVPacket
,解码器处理 AVPacket
中的数据,并生成帧(AVFrame
)。同样,编码器会将帧编码成 AVPacket
,复用器会将这些 AVPacket
写入多媒体文件。
AVPacket
结构体的主要成员
以下是 AVPacket
结构体中一些关键的成员变量及其作用:
uint8_t *data
:指向数据包的实际数据。它包含了经过编码的音频或视频数据,通常是压缩的格式(如 H.264 视频或 AAC 音频)。int size
:表示数据包的大小,以字节为单位。这个值表示data
指针指向的数据区域的大小。int64_t pts
:表示显示时间戳(Presentation Timestamp)。PTS 用于确定该数据包中的数据在播放时应该何时显示,确保音视频同步。int64_t dts
:表示解码时间戳(Decoding Timestamp)。DTS 用于指示解码器何时解码这个数据包。对于一些复杂的编码格式,如包含 B 帧的视频,DTS 和 PTS 可能不一样。int64_t duration
:表示该数据包在时间轴上的持续时间。这个值用于计算帧之间的显示间隔。int stream_index
:表示该数据包所属的流的索引。一个多媒体文件可能包含多个流(音频流、视频流、字幕流等),这个索引用于标识AVPacket
属于哪个流。int64_t pos
:表示数据包在输入文件中的字节位置。这个值在某些情况下用于回溯或者调试。int flags
:用于指示数据包的特殊属性,如是否是关键帧(AV_PKT_FLAG_KEY
)等。AVBufferRef *buf
:引用计数的缓冲区指针,用于管理AVPacket
的数据内存。如果你复制或分配了AVPacket
,它帮助管理数据的生命周期。
PTS、DTS、duration介绍
- PTS(Presentation Timestamp)
- 含义:PTS 表示帧应该在什么时候被显示出来。它是控制视频或音频在播放时的显示顺序和时间的关键参数。
- 作用:PTS 用于确保帧在正确的时间被显示,从而保持音视频的同步。
- DTS(Decoding Timestamp)
- 含义:DTS 表示帧应该在什么时候被解码。与 PTS 不同,DTS 用于控制帧的解码顺序。DTS 通常用于处理包含 B 帧(双向预测帧)的流,因为这些帧的解码顺序和显示顺序可能不同。
- 作用:DTS 确保解码器按正确的顺序处理帧,从而生成正确的图像序列。
duration
(持续时间)
- 含义:
duration
表示帧的持续时间,即在没有下一个帧到达之前,这个帧应该保持显示多长时间。 - 作用:它用于确定帧之间的间隔,以维持正确的帧率。
关于duration * num / den
duration * num / den
是将时间长度从一个时间基转换为另一个时间基的常用计算方式。- 它确保在进行时间戳操作时,
duration
的单位能够正确匹配新的时间基,使得时间轴上的所有操作(如解码、显示等)都能够正确同步。
【duration举例】
假设:
duration = 5000
(表示 5000 个时间单位)- 源时间基
time_base = {1, 1000}
(表示单位是毫秒)
那么:
1 | duration * num / den = 5000 * 1 / 1000 |
这意味着在新的时间基下,duration
对应的时间长度是 5
秒。
【注意】:在编码的时候$PTS >= DTS$
AVPacket
的生命周期
- 分配:在处理前,
AVPacket
需要被分配内存。你可以使用av_init_packet()
函数初始化AVPacket
结构,或者使用av_packet_alloc()
动态分配一个新的AVPacket
。 - 填充数据:在解复用时,
AVPacket
由解复用器填充数据,并将数据传递给解码器。或者,在编码时,编码器将生成的数据填充到AVPacket
中,然后传递给复用器。 - 释放:当一个
AVPacket
使用完毕后,需要释放它占用的内存。你可以使用av_packet_unref()
来释放AVPacket
持有的数据,并将其重置为默认状态。这样可以重复使用该AVPacket
。或者使用av_packet_free()
来释放整个AVPacket
结构体及其数据。
总结
AVPacket
是 FFmpeg 中用于表示媒体数据包的重要结构体,它封装了音频、视频或字幕数据以及相关的元数据。在媒体处理过程中,AVPacket
是数据传递的基本单元,广泛应用于解复用、解码、编码和复用等过程中。了解并正确使用 AVPacket
对于有效地处理多媒体数据至关重要。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 JasonQian's Blog!