热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ffmpegAVFrame结构体及其相关函数

0.简介AVFrame中存储的是原始数据(例如视频的YUV,RGB,音频的PCM),此外还包含了一些相关的信息,例如:解码的时候存储了宏块类型表,QP表,运动矢量等数据.编码的时候

0. 简介

AVFrame中存储的是原始数据(例如视频的YUV, RGB, 音频的PCM), 此外还包含了一些相关的信息, 例如: 解码的时候存储了宏块类型表, QP表, 运动矢量等数据. 编码的时候也存储了相关的数据.

 

1. AVFrame 数据结构定义

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;



  • 带有#if ...  #end包含的字段, 都是将要被弃用或已经弃用的. 不再进行解释.

 


  • 必须使用av_frame_alloc()分配AVFrame, 这只是分配AVFram本身.

  • 必须使用av_frame_free()释放.

 


  • uint8_t *data[AV_NUM_DATA_POINTERS];

原始数据(对视频来说是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

 


  • int linesize[AV_NUM_DATA_POINTERS];

对于视频来说, linesize是每行图像的大小(字节数, 有字节对齐).

对于音频来说, linesize是每个plane的大小(字节数). 音频只是用linesize[0]. 对于planar音频来说, 每个plane的大小必须一样.

linesize可能会因为性能上的考虑而填充一些额外的数据, 因此linesize可能比实际对应的音视频数据尺寸要大.

 


  • uint8_t **extended_data;

  指向数据plane

 

 


  • int width, height;

视频帧像素宽和高.

 


  • int nb_samples;

音频帧中单个声道包含的采样点数.

 


  • int format;

帧格式. 如果是未知格式或未设置, 值为-1.

对于视频帧, 值对应enum AVPixelFormat结构:

1 enum AVPixelFormat {
2 AV_PIX_FMT_NOnE= -1,
3 AV_PIX_FMT_YUV420P, ///4 AV_PIX_FMT_YUYV422, ///5 AV_PIX_FMT_RGB24, ///6 AV_PIX_FMT_BGR24, ///7 AV_PIX_FMT_YUV422P, ///8 AV_PIX_FMT_YUV444P, /// ... ...
};

 

对于音频帧, 值对应于enum AVSampleFormat结构:

1 enum AVSampleFormat {
2 AV_SAMPLE_FMT_NOnE= -1,
3 AV_SAMPLE_FMT_U8, /// 4 AV_SAMPLE_FMT_S16, /// 5 AV_SAMPLE_FMT_S32, /// 6 AV_SAMPLE_FMT_FLT, /// 7 AV_SAMPLE_FMT_DBL, /// 8
9 AV_SAMPLE_FMT_U8P, ///10 AV_SAMPLE_FMT_S16P, ///11 AV_SAMPLE_FMT_S32P, ///12 AV_SAMPLE_FMT_FLTP, ///13 AV_SAMPLE_FMT_DBLP, ///14 AV_SAMPLE_FMT_S64, ///15 AV_SAMPLE_FMT_S64P, ///16
17 AV_SAMPLE_FMT_NB ///18 };

 

 


  • int key_frame;

视频帧是否是关键帧的标识, 1: 关键帧; 0: 非关键帧.

 


  • enum AVPictureType pict_type;

视频帧类型(I, B, P等)

enum AVPictureType结构:

1 enum AVPictureType {
2 AV_PICTURE_TYPE_NOnE= 0, /// 3 AV_PICTURE_TYPE_I, /// 4 AV_PICTURE_TYPE_P, /// 5 AV_PICTURE_TYPE_B, /// 6 AV_PICTURE_TYPE_S, /// 7 AV_PICTURE_TYPE_SI, /// 8 AV_PICTURE_TYPE_SP, /// 9 AV_PICTURE_TYPE_BI, ///10 };

 

 


  • AVRational sample_aspect_ratio;

视频帧的宽高比.

 


  • int64_t pts;

显示时间戳. 单位是time_base.

 


  • int64_t pkt_dts;

对应packet中的解码时间戳. 是从对应pacekt中拷贝得到此值.

如果对应的packet中只有dts而未设置pts, 则此值也是frame的pts.

 


  • int coded_picture_number;

编码帧序号.

 


  • int display_picture_number;

显示帧序号

 


  • int quality;

品质(介于1(最好)和FF_LAMBDA_MAX(坏)之间)

 


  • void *opaque;

用户私有信息.

 


  • int repeat_pict;

解码时, 每帧图片的延迟时间.

extra_delay = repeat_pict / (2*fps)

 


  • int interlaced_frame;

是否是隔行扫描.

 


  • int top_field_first;

图像的top field first变量. 如果内容是隔行的, 则首先显示顶部字段.

 


  • int palette_has_changed;

告诉用户应用程序调色板已从上一帧更改

 


  • int sample_rate;

音频采样率.

 


  • uint64_t channel_layout;

音频声道布局. 每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 *buf[AV_NUM_DATA_POINTERS];

此帧的数据可以由AVBufferRef管理, AVBufferRef提供AVBuffer引用机制.

如果buf[]的所有元素都为NULL, 则此帧不会被引用计数.

必须连续填充buf[], 如果buf[i]为非NULL, 则对所有的j

对于视频来说, buf[]包含所有的AVBufferRef指针.

对于具有多于AV_NUM_DATA_POINTERS个声道的planar音频来说, 可能buf[]存不下所有的AVBufferRef指针, 多出的AVBufferRef指针存储在extended_buf数组中.

 


  • AVBufferRef **extended_buf;

对于具有多于AV_NUM_DATA_POINTERS个声道的planar音频来说, 可能buf[]存不下所有的AVBufferRef指针, 多出的AVBufferRef指针存储在extended_buf数组中.

 


  • int nb_extended_buf;

extended_buf中元素的数目.

 


  • AVFrameSideData **side_data;

边缘数据

 


  • int nb_side_data;

边缘数据的数目

 


  • int64_t best_effort_timestamp;

在流时间基中估计帧时间戳.

编码时未使用

解码时由解码器设置. 用户读取.

 


  • int64_t pkt_pos;

记录最后一个扔进解码器的packet在输入文件中的位置偏移量.

 


  • int64_t pkt_duration;

对应packet的时长, 单位是AVStream->time_base.

 


  • int channels;

音频声道数量.

 


  • int pkt_size;

对应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;

 

2. 相关函数 



  • AVFrame *av_frame_alloc(void);

构造一个AVFrame, 对象成员被设为默认值.

此函数只分配AVFrame对象本身, 而不分配AVFrame中的数据缓存区.

 


  • void av_frame_free(AVFrame **frame);

释放AVFrame.

 


  • int av_frame_ref(AVFrame *dst, const AVFrame *src);

为src中的数据建立一个新的引用.

将src中帧的各属性拷到dst中, 并且为src中每个AVBufferRef创建一个新的引用.

如果src未使用引用计数, 则dst中会分配新的数据缓存区, 将src中缓存区的数据拷贝到dst中的缓存区.

 


  • AVFrame *av_frame_clone(const AVFrame *src);

创建一个新的AVFrame, 新的AVFrame和src使用统一数据缓存区, 缓存区管理使用引用计数机制.

 


  • void av_frame_unref(AVFrame *frame);

解除本AVFrame对AVFrame中所有缓存区的引用, 并复位AVFrame中的各成员.

 


  • void av_frame_move_ref(AVFrame *dst, AVFrame *src);

将src中所有数据拷贝到dst中, 并复位src.

为避免内存泄漏, 在调用av_frame_move_ref(dst, src)之前应先调用av_frame_unref(dst);

 


  • int av_frame_get_buffer(AVFrame *frame, int align); 

为音频或视频数据分配新的缓冲区.

调用本函数前, 帧中的以下成员必须先设置好:




    • format

    • width, height

    • nb_samples, channel_layout



本函数会填充AVFrame.data和AVFrame.buf数组, 如果有需要, 还会分配和填充AVFrame.extended_data和AVFrame.extended_buf.

对于planar格式, 回味每个plane分配一个缓冲区.

 


  • int av_frame_copy(AVFrame *dst, const AVFrame *src);

将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

 


推荐阅读
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • 实现一个通讯录系统,可添加、删除、修改、查找、显示、清空、排序通讯录信息
    本文介绍了如何实现一个通讯录系统,该系统可以实现添加、删除、修改、查找、显示、清空、排序通讯录信息的功能。通过定义结构体LINK和PEOPLE来存储通讯录信息,使用相关函数来实现各项功能。详细介绍了每个功能的实现方法。 ... [详细]
  • Linux环境变量$PATH的作用及使用方法
    本文介绍了Linux环境变量$PATH的作用及使用方法。$PATH是一个由多个目录组成的变量,用冒号分隔。当执行一个指令时,系统会按照$PATH定义的目录顺序搜索同名的可执行文件,如果有多个同名指令,则先找到的会被执行。通过设置$PATH变量,可以在任何地方执行指令,无需输入绝对路径。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • 在project.properties添加#Projecttarget.targetandroid-19android.library.reference.1..Sliding ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
author-avatar
用巛户khm8pcnjp9
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有