AVFrame介绍
AVFrame介绍
AVFrame
是 FFmpeg 库中用于存储音视频数据帧的核心结构体。它在处理视频解码、编码、滤镜以及其他音视频处理任务时非常重要。AVFrame
可以表示原始的未压缩音频或视频数据。
AVFrame
的作用:
- 视频帧:在处理视频时,
AVFrame
用于存储解码后的原始视频帧,每个帧包括像素数据、分辨率、格式、时间戳等信息。 - 音频帧:在处理音频时,
AVFrame
用于存储解码后的原始音频数据,包括音频样本、通道布局、采样率等信息。
AVFrame
的结构:
AVFrame
是一个复杂的结构体,包含了大量与音视频数据相关的字段。以下是一些主要字段的介绍:
-
数据和缓冲区相关:
AV_NUM_DATA_POINTERS
是 FFmpeg 库中的一个宏定义,它定义了用于指向数据平面的指针数组的大小。一般被定义为8
,这意味着数据指针数组data[AV_NUM_DATA_POINTERS]
可以存储多达 8 个指向不同数据平面的指针。uint8_t *data[AV_NUM_DATA_POINTERS]
:指向存储数据的指针数组。对于视频,data[0]
通常指向 Y 平面,data[1]
和data[2]
分别指向 U 和 V 平面。对于音频,这些指针指向音频样本数据。int linesize[AV_NUM_DATA_POINTERS]
:表示每行图像数据(对于视频)或每个音频通道的字节数。对于视频帧,这决定了每行像素数据在内存中的跨度。AVBufferRef *buf[AV_NUM_DATA_POINTERS]
:指向AVBufferRef
的引用,管理data
指针的引用计数和生命周期。
-
视频相关:
int width
:视频帧的宽度(以像素为单位)。int height
:视频帧的高度(以像素为单位)。enum AVPixelFormat format
:视频帧的像素格式,如AV_PIX_FMT_YUV420P
或AV_PIX_FMT_RGB24
等。
-
音频相关:
int nb_samples
:音频帧中包含的样本数。int channels
:音频帧的通道数。enum AVSampleFormat format
:音频帧的采样格式,如AV_SAMPLE_FMT_S16
(16位有符号整数)或AV_SAMPLE_FMT_FLTP
(浮点数,平面格式)等。uint64_t channel_layout
:音频通道布局,例如AV_CH_LAYOUT_STEREO
表示立体声。
-
时间相关:
int64_t pts
:表示这个帧的展示时间戳(Presentation Timestamp),通常用来同步音视频。int64_t pkt_dts
:表示解码时间戳(Decoding Timestamp)。
-
引用计数和缓冲区管理:
int *extended_data
:与data
指针类似,但用于扩展通道数的情况,尤其在处理音频数据时。int refcounted
:指示该帧是否使用引用计数。如果为 1,则帧的数据会通过引用计数机制进行管理,多个AVFrame
可以共享同一块数据。
- 常用的
AVFrame
函数:
av_frame_alloc()
:分配一个新的AVFrame
对象,并初始化为默认值。av_frame_free(AVFrame **frame)
:释放AVFrame
对象及其关联的资源。调用后,frame
指针将被置为NULL
。av_frame_get_buffer(AVFrame *frame, int align)
:为AVFrame
的数据缓冲区分配内存。align
参数指定内存的对齐方式。av_frame_unref(AVFrame *frame)
:减少AVFrame
缓冲区的引用计数,并将AVFrame
重置为空。这个函数不会释放AVFrame
对象本身,只是释放其数据缓冲区。av_frame_ref(AVFrame *dst, const AVFrame *src)
:使dst
AVFrame
成为src
AVFrame
的引用,即共享相同的缓冲区。
AVFrame
的应用场景:
- 视频解码:从解码器获得原始视频帧后,可以使用
AVFrame
存储并进一步处理或显示。 - 音频解码:类似地,解码后的音频样本数据也可以存储在
AVFrame
中。 - 过滤:在使用 FFmpeg 过滤器链时,
AVFrame
作为输入和输出数据结构传递和处理。 - 视频编码:将处理后的帧再次封装或编码时,
AVFrame
也是主要的数据结构。
- AVFrame 的生命周期管理:
- 分配:首先,通过
av_frame_alloc()
函数分配一个AVFrame
对象。 - 初始化和填充数据:可以通过
av_frame_get_buffer()
为其数据分配缓冲区,或者通过解码器等接口直接获得填充了数据的AVFrame
。 - 使用:
AVFrame
进行各种处理,比如滤镜、编码、显示等。 - 释放:使用完毕后,通过
av_frame_unref()
或av_frame_free()
释放AVFrame
及其数据。
总结:
AVFrame
是 FFmpeg 中非常重要的数据结构,广泛用于音视频处理的各个阶段。通过引用计数管理缓冲区,AVFrame
提供了高效、安全的内存管理机制,是 FFmpeg 处理多媒体数据的基石。
常用的 AVFrame 函数说明
av_frame_get_buffer(AVFrame *frame, int align)
align
参数。常见的对齐值有 1、16、32、64 等。默认情况下,FFmpeg 一般使用 32 字节对齐,因为这在大多数平台上是一个较好的平衡选择。
如果设置的时候,不是 1、16、32、64 ,系统会自动向上取整为最近的 16 字节对齐。比如align
为12,系统会自动调整为16
查看align
的代码:
1 | void check_alignment(AVFrame *frame, int align) { |
当align
为12的时候,执行main
函数中的代码,会得到
说明:与12有偏差,但是与16没有偏差
代码样例:
引用计数
运行结果:
1 |
|
工程运用
详情看 XSDL
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 JasonQian's Blog!