AVFrame中存储的是原始数据(例如视频的YUV, RGB, 音频的PCM), 此外还包含了一些相关的信息, 例如: 解码的时候存储了宏块类型表, QP表, 运动矢量等数据. 编码的时候也存储了相关的数据.
FFmpeg 版本3.4.1
struct AVFrame 定义于
结构体源码(我去除了注释):
1 typedef struct AVFrame {
2 #define AV_NUM_DATA_POINTERS 8
3
4 uint8_t *data[AV_NUM_DATA_POINTERS];
5
6 int linesize[AV_NUM_DATA_POINTERS];
7
8 uint8_t **extended_data;
9
10 int width, height;
11
12 int nb_samples;
13
14 int format;
15
16 int key_frame;
17
18 enum AVPictureType pict_type;
19
20 AVRational sample_aspect_ratio;
21
22 int64_t pts;
23
24 #if FF_API_PKT_PTS
25
26 attribute_deprecated
27 int64_t pkt_pts;
28 #endif
29
30 int64_t pkt_dts;
31
32 int coded_picture_number;
33
34 int display_picture_number;
35
36 int quality;
37
38 void *opaque;
39
40 #if FF_API_ERROR_FRAME
41
42 attribute_deprecated
43 uint64_t error[AV_NUM_DATA_POINTERS];
44 #endif
45
46 int repeat_pict;
47
48 int interlaced_frame;
49
50 int top_field_first;
51
52 int palette_has_changed;
53
54 int64_t reordered_opaque;
55
56 int sample_rate;
57
58 uint64_t channel_layout;
59
60 AVBufferRef *buf[AV_NUM_DATA_POINTERS];
61
62 AVBufferRef **extended_buf;
63
64 int nb_extended_buf;
65
66 AVFrameSideData **side_data;
67 int nb_side_data;
68
69 #define AV_FRAME_FLAG_CORRUPT (1 <<0)
70
71 #define AV_FRAME_FLAG_DISCARD (1 <<2)
72
73 int flags;
74
75 enum AVColorRange color_range;
76
77 enum AVColorPrimaries color_primaries;
78
79 enum AVColorTransferCharacteristic color_trc;
80
81 enum AVColorSpace colorspace;
82
83 enum AVChromaLocation chroma_location;
84
85 int64_t best_effort_timestamp;
86
87 int64_t pkt_pos;
88
89 int64_t pkt_duration;
90
91 AVDictionary *metadata;
92
93 int decode_error_flags;
94 #define FF_DECODE_ERROR_INVALID_BITSTREAM 1
95 #define FF_DECODE_ERROR_MISSING_REFERENCE 2
96
97 int channels;
98
99 int pkt_size;
100
101 #if FF_API_FRAME_QP
102 attribute_deprecated
103 int8_t *qscale_table;
104
105 attribute_deprecated
106 int qstride;
107
108 attribute_deprecated
109 int qscale_type;
110
111 AVBufferRef *qp_table_buf;
112 #endif
113
114 AVBufferRef *hw_frames_ctx;
115
116 AVBufferRef *opaque_ref;
117
118 size_t crop_top;
119 size_t crop_bottom;
120 size_t crop_left;
121 size_t crop_right;
122 } AVFrame;
原始数据(对视频来说是YUB, RGB, 对音频来说是PCM)
data是一个指针数组, 数组的每一个元素都是一个指针. 指向视频中图像的某一plane或者音频中某一声道的plane.
对于packed格式, 一个YUV图像的Y, U, V交织存储在一个plane中, 例如: YUVYUVYUV... ..., data[0]指向这个plane;
一个双声道的音频帧有左声道L和右声道R, 它们交织存储在一个plane中, 例如: LRLRLR... ..., data[0]指向这个plane.
对于planar格式, 一个YUV图像有Y, U, V三个plane, data[0]指向Y plane, data[1]质量U plane, data[2]指向V plane.
一个双声道的音频帧有左声道L和右声道R两个plane, data[0]指向L plane, data[1]指向R plane
对于视频来说, linesize是每行图像的大小(字节数, 有字节对齐).
对于音频来说, linesize是每个plane的大小(字节数). 音频只是用linesize[0]. 对于planar音频来说, 每个plane的大小必须一样.
linesize可能会因为性能上的考虑而填充一些额外的数据, 因此linesize可能比实际对应的音视频数据尺寸要大.
指向数据plane
视频帧像素宽和高.
音频帧中单个声道包含的采样点数.
帧格式. 如果是未知格式或未设置, 值为-1.
对于视频帧, 值对应enum AVPixelFormat结构:
1 enum AVPixelFormat {
2 AV_PIX_FMT_NOnE= -1,
3 AV_PIX_FMT_YUV420P, ///
};
对于音频帧, 值对应于enum AVSampleFormat结构:
1 enum AVSampleFormat {
2 AV_SAMPLE_FMT_NOnE= -1,
3 AV_SAMPLE_FMT_U8, ///
9 AV_SAMPLE_FMT_U8P, ///
17 AV_SAMPLE_FMT_NB ///
视频帧是否是关键帧的标识, 1: 关键帧; 0: 非关键帧.
视频帧类型(I, B, P等)
enum AVPictureType结构:
1 enum AVPictureType {
2 AV_PICTURE_TYPE_NOnE= 0, /// 7 AV_PICTURE_TYPE_SI, ///
视频帧的宽高比.
显示时间戳. 单位是time_base.
对应packet中的解码时间戳. 是从对应pacekt中拷贝得到此值.
如果对应的packet中只有dts而未设置pts, 则此值也是frame的pts.
编码帧序号.
显示帧序号
品质(介于1(最好)和FF_LAMBDA_MAX(坏)之间)
用户私有信息.
解码时, 每帧图片的延迟时间.
extra_delay = repeat_pict / (2*fps)
是否是隔行扫描.
图像的top field first变量. 如果内容是隔行的, 则首先显示顶部字段.
告诉用户应用程序调色板已从上一帧更改
音频采样率.
音频声道布局. 每bit代表一个特定的声道.
参考源码channel_layout.h中定义:
1 #define AV_CH_FRONT_LEFT 0x00000001
2 #define AV_CH_FRONT_RIGHT 0x00000002
3 #define AV_CH_FRONT_CENTER 0x00000004
4 #define AV_CH_LOW_FREQUENCY 0x00000008
5 #define AV_CH_BACK_LEFT 0x00000010
6 ... ...
7
8 #define AV_CH_LAYOUT_MONO (AV_CH_FRONT_CENTER)
9 #define AV_CH_LAYOUT_STEREO (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)
10 #define AV_CH_LAYOUT_2POINT1 (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY)
11 #define AV_CH_LAYOUT_2_1 (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER)
12 #define AV_CH_LAYOUT_SURROUND (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER)
13 #define AV_CH_LAYOUT_3POINT1 (AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY)
14 ... ...
此帧的数据可以由AVBufferRef管理, AVBufferRef提供AVBuffer引用机制.
如果buf[]的所有元素都为NULL, 则此帧不会被引用计数.
必须连续填充buf[], 如果buf[i]为非NULL, 则对所有的j
对于视频来说, buf[]包含所有的AVBufferRef指针.
对于具有多于AV_NUM_DATA_POINTERS个声道的planar音频来说, 可能buf[]存不下所有的AVBufferRef指针, 多出的AVBufferRef指针存储在extended_buf数组中.
对于具有多于AV_NUM_DATA_POINTERS个声道的planar音频来说, 可能buf[]存不下所有的AVBufferRef指针, 多出的AVBufferRef指针存储在extended_buf数组中.
extended_buf中元素的数目.
边缘数据
边缘数据的数目
在流时间基中估计帧时间戳.
编码时未使用
解码时由解码器设置. 用户读取.
记录最后一个扔进解码器的packet在输入文件中的位置偏移量.
对应packet的时长, 单位是AVStream->time_base.
音频声道数量.
对应packet的大小.
size_t crop_top;
size_t crop_bottom;
size_t crop_left;
size_t crop_right;
用于视频帧图像裁切. 四个值分别为从frame的上/下/左/右边界裁切的像素数.
int flags;
enum AVColorRange color_range;
enum AVColorPrimaries color_primaries;
enum AVColorTransferCharacteristic color_trc;
enum AVColorSpace colorspace;
enum AVChromaLocation chroma_location;
AVDictionary *metadata;
int decode_error_flags;
AVBufferRef *hw_frames_ctx;
AVBufferRef *opaque_ref;
构造一个AVFrame, 对象成员被设为默认值.
此函数只分配AVFrame对象本身, 而不分配AVFrame中的数据缓存区.
释放AVFrame.
为src中的数据建立一个新的引用.
将src中帧的各属性拷到dst中, 并且为src中每个AVBufferRef创建一个新的引用.
如果src未使用引用计数, 则dst中会分配新的数据缓存区, 将src中缓存区的数据拷贝到dst中的缓存区.
创建一个新的AVFrame, 新的AVFrame和src使用统一数据缓存区, 缓存区管理使用引用计数机制.
解除本AVFrame对AVFrame中所有缓存区的引用, 并复位AVFrame中的各成员.
将src中所有数据拷贝到dst中, 并复位src.
为避免内存泄漏, 在调用av_frame_move_ref(dst, src)之前应先调用av_frame_unref(dst);
为音频或视频数据分配新的缓冲区.
调用本函数前, 帧中的以下成员必须先设置好:
本函数会填充AVFrame.data和AVFrame.buf数组, 如果有需要, 还会分配和填充AVFrame.extended_data和AVFrame.extended_buf.
对于planar格式, 回味每个plane分配一个缓冲区.
将src中的帧数据拷贝到dst中.
本函数并不会有任何分配缓冲区的动作, 调用此函数前dst必须已经使用了和src同样的参数完成了初始化.
本函数只拷贝帧中的数据缓冲区的内容, 而不涉及帧中的其它属性.
[1] 雷霄骅博士结构体分析:AVFrame https://blog.csdn.net/leixiaohua1020/article/details/14214577
[2] 叶余 FFmpeg数据结构AVFrame https://www.cnblogs.com/leisure_chn/p/10404502.html
[3]YelloLayne FFmpeg结构体:AVFrame https://www.jianshu.com/p/25a329b20078