FFmpeg libavutil主要功能概述
2017-09-30 20:20
555 查看
[时间:2017-08] [状态:Open]
[关键词:ffmpeg,avutil,avrational,avlog,avbuffer,avoptoin]
从FFmpeg官网的文档-libavutil来看,avutil主要有一下几种功能(顺序做了重排):
数学函数
字符串操作
内存管理相关
数据结构相关
错误码及错误处理
日志输出
其他辅助信息,比如密钥、哈希值、宏、库版本、常量等
本文将逐个介绍比较avutil所提供的比较常用的函数。
注意本文编写时ffmpeg版本为3.3
有理数的定义如下
近似取值的枚举值
其他数学函数如下:
其中定义了如下宏:
定义的宏有:
支持的接口如下:
其中定义了如下结构体
提供了以下函数:
在开始用户可以调用av_buffer_pool_init来创建缓冲池。然后在任何时间都可以调用av_buffer_pool_get()来获得buffer,在该buffer的引用计数为0时,将会返回给缓冲池,这样就可以被循环使用了。
在用户使用完缓冲池之后可以调用av_buffer_pool_uninit()来释放缓冲池。
其中提供的函数包括:
AVFrame必须使用av_frame_alloc()函数进行分配。需要注意的是该函数仅仅常见AVFrame本身,AVFrame中的数据缓冲必须通过其他方式管理。AVFrame必须使用av_frame_free()函数释放。
AVFrame通常是分配一次,然后用于存放不同的数据,例如AVFrame可以保存从decoder中解码出来的数据。在这种情况下 av_frame_unref()将释放所有由frame添加的引用计数并将其重置为初始值。
AVFrame中的数据通常基于AVBuffer API提供的引用计数机制。其中的引用计数是保存在AVFrame.buf/AVFrame.extended_buf中的。
sizeof(AVFrame)并不是公开API的一部分,以保证AVFrame中新添加成员之后可以正常运行。
AVFrame中的成员可以通过AVOptions访问,使用其对应的名称字符串即可。AVFrame的AVClass可以通过avcodec_get_frame_class()函数获得。
它提供的主要函数包括:
Option设置函数-set
Option获取函数-get
结构体定义
支持的宏和枚举值
支持的函数如下:
支持宏如下:
函数如下:
提供以下接口:
宏
函数包括
其中定义的宏如下:
支持的函数接口有:
FFmpeg支持AES、Base64、blowfish等常用的密钥算法,hash函数支持CRC、MD5、SHA、SHA-512等。
字符串处理宏
库版本宏
函数有
时间戳相关的常量宏
同时额外定义了以下结构:
最后一部分是关于AVPicture的用法说明,其中包括像素采样格式、基本图像平面操作等。
枚举量有:
函数有:
整理本文的目的只是为了加强记忆。后续会介绍下AVOption、AVLog、AVBuffer的实现细节。
参考ffmpeg-doxygen
[关键词:ffmpeg,avutil,avrational,avlog,avbuffer,avoptoin]
0 引言
FFmpeg使用很久了,一直没有认真看过FFmpeg内部源码所提供的各种机制和功能。本文的主要目标是能够初步总结FFmpeg的avutil中所提供的功能。从FFmpeg官网的文档-libavutil来看,avutil主要有一下几种功能(顺序做了重排):
数学函数
字符串操作
内存管理相关
数据结构相关
错误码及错误处理
日志输出
其他辅助信息,比如密钥、哈希值、宏、库版本、常量等
本文将逐个介绍比较avutil所提供的比较常用的函数。
注意本文编写时ffmpeg版本为3.3
1 数学函数
顾名思义,这部分主要提供与基本数学概念相关的功能,方便数学调用及处理。有理数的定义如下
struct AVRational{ int num; ///< Numerator 分子 int den; ///< Denominator 分母 };
近似取值的枚举值
enum AVRounding:
enumerator | value | description |
---|---|---|
AV_ROUND_ZERO | 0 | 向零取整 |
AV_ROUND_INF | 1 | 向非零取整 |
AV_ROUND_DOWN | 2 | 向负无穷取整 |
AV_ROUND_UP | 3 | 向正无穷取整 |
AV_ROUND_NEAR_INF | 5 | 向无穷取整,包含中点位置 |
AV_ROUND_PASS_MINMAX | 8192 | 透传INT64_MIN/MAX,避免出现AV_NOPTS_VALUE |
// 获得a和b的最大公约数 int64_t av_gcd (int64_t a, int64_t b); // a * b / c,按照rnd标志取整 int64_t av_rescale (int64_t a, int64_t b, int64_t c); int64_t av_rescale_rnd (int64_t a, int64_t b, int64_t c, enum AVRounding rnd); // a * bq / cq, 涉及有理数,按照rnd标志取整 int64_t av_rescale_q (int64_t a, AVRational bq, AVRational cq); int64_t av_rescale_q_rnd (int64_t a, AVRational bq, AVRational cq, enum AVRounding rnd); // 比较ts_a/tb_a与ts_b/tb_b的大小,-1:前者小,0:相等,1:后者小 int av_compare_ts (int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); // 比较余数大小,即a%mod与b%mod,mod必须是2的倍数。 int64_t av_compare_mod (uint64_t a, uint64_t b, uint64_t mod) // 创建AVRational static AVRational av_make_q (int num, int den); // 比较两个AVRational,0:a==b, 1: a > b, -1: a < b static int av_cmp_q (AVRational a, AVRational b); // 将AVRational转化为double static double av_q2d (AVRational a); // 分数的约分,分子分母需要小于max int av_reduce (int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max) // 分数相乘,return b*c AVRational av_mul_q (AVRational b, AVRational c) av_const // 分数相除,return b/c AVRational av_div_q (AVRational b, AVRational c) av_const // 分数相加,return b + c AVRational av_add_q (AVRational b, AVRational c) av_const // 分数相减,return b - c AVRational av_sub_q (AVRational b, AVRational c) av_const // 求倒数,return 1/q static AVRational av_inv_q (AVRational q) // 浮点转AVRational,分子、分母必须的最大值是max AVRational av_d2q (double d, int max) av_const // 找到离q最近的值,0:等距离,-1:q1离q近,1:q2离q近 int av_nearer_q (AVRational q, AVRational q1, AVRational q2) // 找到指定数组中离q最近的值的索引 int av_find_nearest_q_idx (AVRational q, const AVRational *q_list) // AVRational转float,返回以32位表示的浮点数(float)值 uint32_t av_q2intfloat (AVRational q) // 在特定时间戳上累加一个值,返回为:ts + inc / inc_tb * ts_tb int64_t av_add_stable (AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc)
2 字符串操作
字符串相关函数主要涉及在代码中的字符串操作逻辑。其中定义了如下宏:
// 转译所有空格,包括位于字符串中间的空格 #define AV_ESCAPE_FLAG_WHITESPACE (1 << 0) // 仅对特殊标记字符转译。如果没有该标志,将对av_get_token()返回的特殊字符做转译 #define AV_ESCAPE_FLAG_STRICT (1 << 1) // 支持大于0x10FFFF的codepoints #define AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES 1 // 支持非字符(0xFFFE和0xFFFF) #define AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS 2 // 支持UTF-16的surrogates codes #define AV_UTF8_FLAG_ACCEPT_SURROGATES 4 // 排除不被XML支持的控制码 #define AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES 8 #define AV_UTF8_FLAG_ACCEPT_ALL AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES|AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS|AV_UTF8_FLAG_ACCEPT_SURROGATES
定义的宏有:
Enumerator | value | description |
---|---|---|
AV_ESCAPE_MODE_AUTO | 0 | 使用自动选择的反转移模式 |
AV_ESCAPE_MODE_BACKSLASH | 1 | 使用反斜杠转译 |
AV_ESCAPE_MODE_QUOTE | 2 | 使用单引号转译 |
// 查找匹配子字符串,如果找到,返回非0,否则返回0 // 如果pfx是str的子串,ptr将返回第一匹配字符串的地址 int av_strstart (const char *str, const char *pfx, const char **ptr); // 忽略大小写字母的字符串匹配 int av_stristart (const char *str, const char *pfx, const char **ptr); // 标准库中strstr的替代版本,区分大小写字母的字符串匹配 char * av_stristr (const char *haystack, const char *needle); // 标准库中strstr的替代版本,限制字符串长度 char * av_strnstr (const char *haystack, const char *needle, size_t hay_length); // 与BSD strlcpy功能类似,复制最多size-1个字符,并将dst[size-1]置位'\0' size_t av_strlcpy (char *dst, const char *src, size_t size); // 字符串拼接,该保证dst的总长度不超过size-1 size_t av_strlcat (char *dst, const char *src, size_t size); // 字符串格式化输出 size_t av_strlcatf (char *dst, size_t size, const char *fmt,...); // 返回从字符串开始位置连续的非'\0'字符的数目 size_t av_strnlen (const char *s, size_t len); // 将字符串和参数格式化输出到一个临时缓冲区,正常返回的指针需要通过调用av_free释放 char * av_asprintf (const char *fmt,...) // 将double转化为字符串 char * av_d2str (double d); // 字符串分割 char * av_get_token (const char **buf, const char *term); // 类似POSIX.1中的strtok_r()函数 char * av_strtok (char *s, const char *delim, char **saveptr); // 判断字符类型和转化 int av_isdigit (int c); // ASCII isdigit int av_isgraph (int c); // ASCII isgraph int av_isspace (int c); // ASCII isspace int av_toupper (int c); // ASCII字符转大写 int av_tolower (int c); // ASCII字符转小写 int av_isxdigit (int c); // ASCII isxdigit // ASCII字符串比较,大小写敏感 int av_strcasecmp (const char *a, const char *b); // ASCII字符串比较,大小写不敏感 int av_strncasecmp (const char *a, const char *b, size_t n); // 查找盘符或根目录 const char * av_basename (const char *path); // 获得目录名,此函数会修改path变量的值 const char * av_dirname (char *path); // 在names中查找name,找到返回1;否则,返回0 int av_match_name (const char *name, const char *names); // 路径拼接,添加新的folder char * av_append_path_component (const char *path, const char *component); // 文本转译处理 int av_escape (char **dst, const char *src, const char *special_chars, enum AVEscapeMode mode, int flags); // UTF-8字符读取 int av_utf8_decode (int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, unsigned int flags); // 在list查找name int av_match_list (const char *name, const char *list, char separator);
3. 内存管理相关
内存管理相关函数主要涉及堆管理。其中堆函数包括:// 分配指定大小的内存,功能类似c的malloc void * av_malloc (size_t size); // 分配内存并将该内存初始化为0 void * av_mallocz (size_t size); // 作为c中calloc的替代 void * av_calloc (size_t nmemb, size_t size); // 作为c中realloc的替代 void * av_realloc (void *ptr, size_t size); // 在buffer不足的情况下,重新分配内存,否则不做处理 void * av_fast_realloc (void *ptr, unsigned int *size, size_t min_size); // 在buffer不够是重新分配,够用时直接使用默认的。 void av_fast_malloc (void *ptr, unsigned int *size, size_t min_size); // av_fast_malloc功能类似,只是分配成功之后初始化为0 void av_fast_mallocz (void *ptr, unsigned int *size, size_t min_size); // 释放内存,类似c中的free void av_free (void *ptr); // 释放内存,并将指针置为空 void av_freep (void *ptr); // 字符串复制,并返回一个内存指针,返回值需要通过av_free释放 char * av_strdup (const char *s); char * av_strndup (const char *s, size_t len); // 内存区域复制,并返回一个动态申请的内存 void * av_memdup (const void *p, size_t size); // 支持重叠区域的memcpy实现 void av_memcpy_backptr (uint8_t *dst, int back, int cnt); // 检查a*b是否存在溢出,返回值0表示成功, AVERROR(EINVAL)表示存在溢出 int av_size_mult (size_t a, size_t b, size_t *r);
4. 数据结构相关
avutil中的数据结构包括:AVBuffer
AVBuffer是一系列支持引用计数的数据缓冲的API集合。其中定义了如下结构体
// 基于引用计数的buffer类型,外部不可见,通过AVBufferRef访问 typedef struct AVBuffer AVBuffer; // 对数据buffer的引用,该结构不应该被直接分配 struct AVBufferRef { AVBuffer *buffer; uint8_t *data; // 数据缓冲和长度 int size; };
提供了以下函数:
// 创建指定长度为size的buffer,一般调用av_malloc AVBufferRef * av_buffer_alloc (int size); AVBufferRef * av_buffer_allocz (int size); // 使用data中长度为size的数据创建AVBuffer,并注册释放函数及标志 AVBufferRef * av_buffer_create (uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags); // 使用默认方式释放buffer void av_buffer_default_free (void *opaque, uint8_t *data); // 复制和减少对buffer的引用计数 AVBufferRef * av_buffer_ref (AVBufferRef *buf); void av_buffer_unref (AVBufferRef **buf); // buffer是否可写 int av_buffer_is_writable (const AVBufferRef *buf); // 返回av_buffer_create设置的opaque参数 void * av_buffer_get_opaque (const AVBufferRef *buf); // 返回当前buffer的引用计数值 int av_buffer_get_ref_count (const AVBufferRef *buf); // 创建一个可写的buffer int av_buffer_make_writable (AVBufferRef **buf); // 重新分配buffer大小 int av_buffer_realloc (AVBufferRef **buf, int size);
AVBufferPool
AVBufferPool是一个由AVBuffer构成的、没有线程锁的、线程安全的缓冲池。频繁的分配和释放大量内存缓冲区效率可能会较低。AVBufferPool主要解决用户需要使用同样长度的缓冲区的情况(比如,原始音视频帧)。在开始用户可以调用av_buffer_pool_init来创建缓冲池。然后在任何时间都可以调用av_buffer_pool_get()来获得buffer,在该buffer的引用计数为0时,将会返回给缓冲池,这样就可以被循环使用了。
在用户使用完缓冲池之后可以调用av_buffer_pool_uninit()来释放缓冲池。
其中提供的函数包括:
// 创建缓冲池 AVBufferPool * av_buffer_pool_init (int size, AVBufferRef *(*alloc)(int size)); AVBufferPool * av_buffer_pool_init2 (int size, void *opaque, AVBufferRef *(*alloc)(void *opaque, int size), void(*pool_free)(void *opaque)); // 释放缓冲池 void av_buffer_pool_uninit (AVBufferPool **pool); // 获得buffer AVBufferRef * av_buffer_pool_get (AVBufferPool *pool);
AVFrame
AVFrame是对原始多媒体数据的一个基于引用计数的抽象,比较常用的是音频帧和视频帧。这里不给出AVFrame的定义了,有兴趣的可以参考libavutil/frame.h。AVFrame必须使用av_frame_alloc()函数进行分配。需要注意的是该函数仅仅常见AVFrame本身,AVFrame中的数据缓冲必须通过其他方式管理。AVFrame必须使用av_frame_free()函数释放。
AVFrame通常是分配一次,然后用于存放不同的数据,例如AVFrame可以保存从decoder中解码出来的数据。在这种情况下 av_frame_unref()将释放所有由frame添加的引用计数并将其重置为初始值。
AVFrame中的数据通常基于AVBuffer API提供的引用计数机制。其中的引用计数是保存在AVFrame.buf/AVFrame.extended_buf中的。
sizeof(AVFrame)并不是公开API的一部分,以保证AVFrame中新添加成员之后可以正常运行。
AVFrame中的成员可以通过AVOptions访问,使用其对应的名称字符串即可。AVFrame的AVClass可以通过avcodec_get_frame_class()函数获得。
它提供的主要函数包括:
// 获取和设置AVFrame.best_effort_timestamp值 int64_t av_frame_get_best_effort_timestamp (const AVFrame *frame); void av_frame_set_best_effort_timestamp (AVFrame *frame, int64_t val); // 获取和设置AVFrame.pkt_duration int64_t av_frame_get_pkt_duration (const AVFrame *frame); void av_frame_set_pkt_duration (AVFrame *frame, int64_t val); // 获取和设置AVFrame.pkt_pos int64_t av_frame_get_pkt_pos (const AVFrame *frame); void av_frame_set_pkt_pos (AVFrame *frame, int64_t val); // 获取和设置AVFrame.channel_layout int64_t av_frame_get_channel_layout (const AVFrame *frame); void av_frame_set_channel_layout (AVFrame *frame, int64_t val); // 获取和设置AVFrame.channels int av_frame_get_channels (const AVFrame *frame); void av_frame_set_channels (AVFrame *frame, int val); // 获取和设置AVFrame.sample_rate int av_frame_get_sample_rate (const AVFrame *frame); void av_frame_set_sample_rate (AVFrame *frame, int val); // 获取和设置AVFrame.metadata AVDictionary * av_frame_get_metadata (const AVFrame *frame); void av_frame_set_metadata (AVFrame *frame, AVDictionary *val); // 获取和设置AVFrame.decode_error_flags int av_frame_get_decode_error_flags (const AVFrame *frame); void av_frame_set_decode_error_flags (AVFrame *frame, int val); // 获取和设置AVFrame.pkt_size int av_frame_get_pkt_size (const AVFrame *frame); void av_frame_set_pkt_size (AVFrame *frame, int val); AVDictionary ** avpriv_frame_get_metadatap (AVFrame *frame) // 获取和设置AVFrame.colorspace enum AVColorSpace av_frame_get_colorspace (const AVFrame *frame); void av_frame_set_colorspace (AVFrame *frame, enum AVColorSpace val); // 获取和设置AVFrame.color_range enum AVColorRange av_frame_get_color_range (const AVFrame *frame); void av_frame_set_color_range (AVFrame *frame, enum AVColorRange val) // 获得ColorSpace的名称 const char * av_get_colorspace_name (enum AVColorSpace val); // 创建和释放AVFrame AVFrame * av_frame_alloc (void); void av_frame_free (AVFrame **frame); // 增加引用计数 int av_frame_ref (AVFrame *dst, const AVFrame *src); // AVFrame复制 AVFrame * av_frame_clone (const AVFrame *src); // 去除引用计数 void av_frame_unref (AVFrame *frame); // 引用计数转移 void av_frame_move_ref (AVFrame *dst, AVFrame *src); // 重新分配缓冲区 int av_frame_get_buffer (AVFrame *frame, int align); // AVFrame复制 int av_frame_copy (AVFrame *dst, const AVFrame *src); int av_frame_copy_props (AVFrame *dst, const AVFrame *src); // 获得某个平面的数据 AVBufferRef * av_frame_get_plane_buffer (AVFrame *frame, int plane);
AVOptions
AVOptions提供了通用的option设置和获取机制,可适用于任意struct(通常要求该结构体的第一个成员必须是AVClass指针,该AVClass.options必须指向一个AVOptions的静态数组,以NULL作为结束)。后续会详细介绍其中原理,这里只整理ffmpeg针对AVOptions所提供的函数。Option设置函数-set
int av_opt_set (void *obj, const char *name, const char *val, int search_flags); // 任意字符串 int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags); // int int av_opt_set_double (void *obj, const char *name, double val, int search_flags); // double int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags); // AVRational int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags); // 二进制 int av_opt_set_image_size (void *obj, const char *name, int w, int h, int search_flags); // 图像分辨率 int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags); // PixelFormat int av_opt_set_sample_fmt (void *obj, const char *name, enum AVSampleFormat fmt, int search_flags); // SampleFormat int av_opt_set_video_rate (void *obj, const char *name, AVRational val, int search_flags); // 视频帧率 int av_opt_set_channel_layout (void *obj, const char *name, int64_t ch_layout, int search_flags); // channel_layou int av_opt_set_dict_val (void *obj, const char *name, const AVDictionary *val, int search_flags); // AVDictionary
Option获取函数-get
int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); int av_opt_get_double (void *obj, const char *name, int search_flags, double *out_val); int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val); int av_opt_get_image_size (void *obj, const char *name, int search_flags, int *w_out, int *h_out); int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt); int av_opt_get_sample_fmt (void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt); int av_opt_get_video_rate (void *obj, const char *name, int search_flags, AVRational *out_val); int av_opt_get_channel_layout (void *obj, const char *name, int search_flags, int64_t *ch_layout); int av_opt_get_dict_val (void *obj, const char *name, int search_flags, AVDictionary **out_val);
结构体定义
struct AVOption { const char *name; const char *help; int offset; // 相对于上下文的偏移量,对常量而言,必须是0 enum AVOptionType type; // 类型 // 实际存储数据的共用体 union { int64_t i64; double dbl; const char *str; AVRational q; } default_val; double min; double max; int flags; // AV_OPT_FLAG_XXX const char *unit; // }; struct AVOptionRange { const char *str; double value_min, value_max; // 值范围,对字符串表示长度,对分辨率表示最大最小像素点个数 double component_min, component_max;// 实际数据取值区间,对字符串,表示unicode的取值范围ASCII为[0,127] int is_range;// 是否是一个取值范围,1-是,0-单值 }; struct AVOptionRanges { AVOptionRange **range; int nb_ranges; // range数目 int nb_components; // 组件数目 } AVOptionRanges;
支持的宏和枚举值
// 优先检索给定对象的子对象 #define AV_OPT_SEARCH_CHILDREN (1 << 0) #define AV_OPT_SEARCH_FAKE_OBJ (1 << 1) // 在av_opt_get中支持返回NULL,而不是空字符串 #define AV_OPT_ALLOW_NULL (1 << 2) // 支持多组件范围的Option #define AV_OPT_MULTI_COMPONENT_RANGE (1 << 12) // 只保存非默认值的Option #define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 // 只保存完全符合opt_flags的option #define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 枚举值 enum AVOptionType { AV_OPT_TYPE_FLAGS, AV_OPT_TYPE_INT, AV_OPT_TYPE_INT64, AV_OPT_TYPE_DOUBLE, AV_OPT_TYPE_FLOAT, AV_OPT_TYPE_STRING, AV_OPT_TYPE_RATIONAL, AV_OPT_TYPE_BINARY, AV_OPT_TYPE_DICT, AV_OPT_TYPE_UINT64, AV_OPT_TYPE_CONST = 128, AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), AV_OPT_TYPE_PIXEL_FMT = MKBETAG('P','F','M','T'), AV_OPT_TYPE_SAMPLE_FMT = MKBETAG('S','F','M','T'), AV_OPT_TYPE_VIDEO_RATE = MKBETAG('V','R','A','T'), AV_OPT_TYPE_DURATION = MKBETAG('D','U','R',' '), AV_OPT_TYPE_COLOR = MKBETAG('C','O','L','R'), AV_OPT_TYPE_CHANNEL_LAYOUT = MKBETAG('C','H','L','A'), AV_OPT_TYPE_BOOL = MKBETAG('B','O','O','L') } enum { AV_OPT_FLAG_IMPLICIT_KEY = 1 }
支持的函数如下:
// 显示obj的所有options int av_opt_show2 (void *obj, void *av_log_obj, int req_flags, int rej_flags); // 将s的所有options设置为默认值 void av_opt_set_defaults (void *s); void av_opt_set_defaults2 (void *s, int mask, int flags); // 解析opts中的key/value对,并设置(主要区别是对ctx要求不一样) int av_set_options_string (void *ctx, const char *opts, const char *key_val_sep, const char *pairs_sep); int av_opt_set_from_string (void *ctx, const char *opts, const char *const *shorthand, const char *key_val_sep, const char *pairs_sep); // 释放obj所有分配的options资源 void av_opt_free (void *obj); // 检查obj.flag_name对应的AVOption属性名为filed_name时该值是否设置 int av_opt_flag_is_set (void *obj, const char *field_name, const char *flag_name); // 从AVDictionary读取Option int av_opt_set_dict (void *obj, struct AVDictionary **options); int av_opt_set_dict2 (void *obj, struct AVDictionary **options, int search_flags); // 从ropts开始提取key/value对 int av_opt_get_key_value (const char **ropts, const char *key_val_sep, const char *pairs_sep, unsigned flags, char **rkey, char **rval); // 在obj中查找名字为name的AVOption const AVOption * av_opt_find (void *obj, const char *name, const char *unit, int opt_flags, int search_flags); const AVOption * av_opt_find2 (void *obj, const char *name, const char *unit, int opt_flags, int search_flags, void **target_obj); // 遍历obj中所有AVOption const AVOption * av_opt_next (const void *obj, const AVOption *prev); // 遍历obj中所有使能的子对象 void * av_opt_child_next (void *obj, void *prev); const AVClass * av_opt_child_class_next (const AVClass *parent, const AVClass *prev); // 获取obj中名字为name的属性的指针 void * av_opt_ptr (const AVClass *avclass, void *obj, const char *name); // AVOption复制 int av_opt_copy (void *dest, const void *src); // 释放AVOptionRanges,并置为NULL void av_opt_freep_ranges (AVOptionRanges **ranges); // 获取有效范围的取值 int av_opt_query_ranges (AVOptionRanges **, void *obj, const char *key, int flags); int av_opt_query_ranges_default (AVOptionRanges **, void *obj, const char *key, int flags); // 获取是否所有的AVOption都是默认值 int av_opt_is_set_to_default (void *obj, const AVOption *o); int av_opt_is_set_to_default_by_name (void *obj, const char *name, int search_flags); // 序列化所有的AVOption int av_opt_serialize (void *obj, int opt_flags, int flags, char **buffer, const char key_val_sep, const char pairs_sep); Serialize object's options. More...
AVDictionary
一个简单的键值对的字典集。其中公开的只有以下结构typedef struct AVDictionaryEntry { char *key; char *value; } AVDictionaryEntry; typedef struct AVDictionary AVDictionary;
支持宏如下:
name | value | desc |
---|---|---|
AV_DICT_MATCH_CASE | 1 | 大小写完全匹配的key检索 |
AV_DICT_IGNORE_SUFFIX | 2 | 忽略后缀 |
AV_DICT_DONT_STRDUP_KEY | 4 | 不复制key |
AV_DICT_DONT_STRDUP_VAL | 8 | 不复制value |
AV_DICT_DONT_OVERWRITE | 16 | 不要覆盖原有值 |
AV_DICT_APPEND | 32 | 如果存在,则添加 |
AV_DICT_MULTIKEY | 64 | 支持多重键值 |
// 从prev开始检索m中的键值为key的元素 AVDictionaryEntry * av_dict_get (const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags); // 获得m中元素个数 int av_dict_count (const AVDictionary *m); // 设置*pm中的key:value键值对 int av_dict_set (AVDictionary **pm, const char *key, const char *value, int flags); // 使用int64_t的value类型 int av_dict_set_int (AVDictionary **pm, const char *key, int64_t value, int flags); // 从str中解析键值对,并添加到*pm中 int av_dict_parse_string (AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags); // AVDictionary复制 int av_dict_copy (AVDictionary **dst, const AVDictionary *src, int flags); // 释放AVDictionary void av_dict_free (AVDictionary **m); // 按照字符串格式输出AVDictionary的所有数据 int av_dict_get_string (const AVDictionary *m, char **buffer, const char key_val_sep, const char pairs_sep);
AVTree
低复杂度的树容器。插入、删除、查找等常用操作都是O(log n)复杂度的实现版本。提供以下接口:
// 创建 struct AVTreeNode * av_tree_node_alloc (void); // 元素查找 void * av_tree_find (const struct AVTreeNode *root, void *key, int(*cmp)(const void *key, const void *b), void *next[2]); // 元素插入 void * av_tree_insert (struct AVTreeNode **rootp, void *key, int(*cmp)(const void *key, const void *b), struct AVTreeNode **next); // 销毁 void av_tree_destroy (struct AVTreeNode *t); // 数元素枚举 void av_tree_enumerate (struct AVTreeNode *t, void *opaque, int(*cmp)(void *opaque, void *elem), int(*enu)(void *opaque, void *elem));
5. 错误码及错误处理
这部分主要提供统一的错误处理逻辑,可以参考下。其中提供机制如下:宏
#define AVERROR(e) (e) // 错误值 #define AVUNERROR(e) (e) // 非错误值 #define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d)) // 生成四字节错误码 #define AV_ERROR_MAX_STRING_SIZE 64 // 错误字符的最大长度 // 错误码转字符串,方便使用的宏 #define av_err2str(errnum) av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, AV_ERROR_MAX_STRING_SIZE, errnum)
函数包括
// 根据错误码,将错误信息输出到errbuf中,返回负值表示错误码未找到。 int av_strerror (int errnum, char *errbuf, size_t errbuf_size); // 功能类似,只是返回值不同 static char * av_make_error_string (char *errbuf, size_t errbuf_size, int errnum);
6. 日志模块
日志模块主要提供日志输出的相关接口和宏,通过这些接口外部可以完全控制ffmpeg所有的日志输出。其中定义的宏如下:
name | value | desc |
---|---|---|
AV_LOG_QUIET | -8 | 无任何日志输出 |
AV_LOG_PANIC | 0 | 发生无法处理的错误,程序将崩溃 |
AV_LOG_FATAL | 8 | 发生无法恢复的错误,例如特定格式的文件头没找到 |
AV_LOG_ERROR | 16 | 发生错误,无法无损恢复,但是对后续运行无影响 |
AV_LOG_WARNING | 24 | 警告信息,有些部分不太正确,可能会也可能不会导致问题 |
AV_LOG_INFO | 32 | 标准信息输出,通常可以使用这个 |
AV_LOG_VERBOSE | 40 | 详细信息,通常比较多,频繁输出那种 |
AV_LOG_DEBUG | 48 | 仅用于libav*开发者使用的标志 |
AV_LOG_TRACE | 56 | 特别繁琐的调试信息,仅用在libav*开发中 |
// 最大log级别的跨度 #define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET) #define AV_LOG_C(x) ((x) << 8) // 设置日志输出的颜色,通常用法如下: av_log(ctx, AV_LOG_DEBUG|AV_LOG_C(134), "Message in purple\n"); // 跳过重复的日志 #define AV_LOG_SKIP_REPEATED 1 // 输出日志对应的level #define AV_LOG_PRINT_LEVEL 2
支持的函数接口有:
// 日志输出函数 void av_log (void *avcl, int level, const char *fmt,...); void av_vlog (void *avcl, int level, const char *fmt, va_list vl); // 设置和获取av_log_level int av_log_get_level (void); void av_log_set_level (int level); // 设置日志输出回调函数及默认的日志回调函数 void av_log_set_callback (void(*callback)(void *, int, const char *, va_list)); void av_log_default_callback (void *avcl, int level, const char *fmt, va_list vl); // 获得ctx的名字 const char * av_default_item_name (void *ctx); // 获得AVClassCategory分类 AVClassCategory av_default_get_category (void *ptr) // 使用ffmpeg默认的log输出方式格式化参数 void av_log_format_line (void *ptr, int level, const char *fmt, va_list vl, char *line, int line_size, int *print_prefix); int av_log_format_line2 (void *ptr, int level, const char *fmt, va_list vl, char *line, int line_size, int *print_prefix); // 设置日志输出相关的flag void av_log_set_flags (int arg); int av_log_get_flags (void);
7. 其他辅助信息
包括密钥、哈希值、宏、库版本、常量等。FFmpeg支持AES、Base64、blowfish等常用的密钥算法,hash函数支持CRC、MD5、SHA、SHA-512等。
字符串处理宏
#define AV_STRINGIFY(s) AV_TOSTRING(s) // 转化为字符串 #define AV_TOSTRING(s) #s #define AV_GLUE(a, b) a ## b // 两个变量拼接 #define AV_JOIN(a, b) AV_GLUE(a, b)
库版本宏
// 版本号的两种信息 #define AV_VERSION_INT(a, b, c) ((a)<<16 | (b)<<8 | (c)) #define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) // 主版本、次版本、微版本号 #define AV_VERSION_MAJOR(a) ((a) >> 16) #define AV_VERSION_MINOR(a) (((a) & 0x00FF00) >> 8) #define AV_VERSION_MICRO(a) ((a) & 0xFF) #define LIBAVUTIL_VERSION_MAJOR 55 #define LIBAVUTIL_VERSION_MINOR 74 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT #define LIBAVUTIL_VERSION #define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT
函数有
unsigned avutil_version (void); const char * av_version_info (void); const char * avutil_configuration (void);// 配置字符串 const char * avutil_license (void);
时间戳相关的常量宏
// 未定义的时间戳 #define AV_NOPTS_VALUE ((int64_t)UINT64_C(0x8000000000000000)) // 内部时间基准,通常是us #define AV_TIME_BASE 1000000 #define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}
同时额外定义了以下结构:
#define AV_FOURCC_MAX_STRING_SIZE 32 #define av_fourcc2str(fourcc) av_fourcc_make_string((char[AV_FOURCC_MAX_STRING_SIZE]){0}, fourcc) char * av_fourcc_make_string (char *buf, uint32_t fourcc);// 将fourcc填充到字符串中 enum AVMediaType { AVMEDIA_TYPE_UNKNOWN = -1, AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA, AVMEDIA_TYPE_SUBTITLE, AVMEDIA_TYPE_ATTACHMENT, AVMEDIA_TYPE_NB } // 获得AVMediaType对应的字符串 const char * av_get_media_type_string (enum AVMediaType media_type); // 使用utf8的文件名打开文件 FILE * av_fopen_utf8 (const char *path, const char *mode); // 返回表示内部时间戳的time_base AVRational av_get_time_base_q (void);
最后一部分是关于AVPicture的用法说明,其中包括像素采样格式、基本图像平面操作等。
枚举量有:
// 各种帧类型,I/P/B/S/SI/SP/BI enum AVPictureType { AV_PICTURE_TYPE_NONE = 0, AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, AV_PICTURE_TYPE_S, AV_PICTURE_TYPE_SI, AV_PICTURE_TYPE_SP, AV_PICTURE_TYPE_BI }
函数有:
// 使用单个字符表示图片类型,未知时返回'?' char av_get_picture_type_char (enum AVPictureType pict_type); // 计算给定采样格式和宽度的图像的linesize int av_image_get_linesize (enum AVPixelFormat pix_fmt, int width, int plane); // 填充特定采样格式和宽度的linesize数组 int av_image_fill_linesizes (int linesizes[4], enum AVPixelFormat pix_fmt, int width); // 使用ptr中的数据填充plane中的数组(不申请内存) int av_image_fill_pointers (uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, uint8_t *ptr, const int linesizes[4]); // 根据给定的格式分配Image数组,主要是pointers和linesizes int av_image_alloc (uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align); // 复制特定plane的数据,即将src中数据拷贝到dst中 void av_image_copy_plane (uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height); // 复制Image,将src_data中的数据拷贝到dst_data中 void av_image_copy (uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height); // 将src填充到dst_data中 int av_image_fill_arrays (uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align); // 返回指定格式的图片需要的缓冲区长度 int av_image_get_buffer_size (enum AVPixelFormat pix_fmt, int width, int height, int align); // 将图像填充为黑色 int av_image_fill_black (uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], enum AVPixelFormat pix_fmt, enum AVColorRange range, int width, int height);
8 结语
到此,本文简单的整理了下FFmpeg中libavutil所提供的主要函数和常量,仅仅是为了整理了解,如果大家需要查看具体文档,建议使用FFmpeg官网的doxygen生成的标准文档。整理本文的目的只是为了加强记忆。后续会介绍下AVOption、AVLog、AVBuffer的实现细节。
参考ffmpeg-doxygen
相关文章推荐
- 【ffmpeg + VS2010】编译包含libavutil\common.h后出现找不到inttypes.h的问题
- ndk编译 ffmpeg 1.1.1 出现libavutil/time.h 和系统的time.h 冲突问题 ;
- 【ffmpeg + VS2010】编译包含libavutil\common.h后出现找不到inttypes.h的问题
- 【ffmpeg + VS2010】编译包含libavutil\common.h后出现找不到inttypes.h的问题
- Spring cloud系列六 Ribbon的功能概述、主要组件和属性文件配置
- 一、概述 EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间
- 病毒分析第一讲,分析病毒注意事项,以及简单分析主要功能
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(69)-微信公众平台开发-功能概述
- linux 主要目录概述
- 进销存个主要功能特点
- Nginx主要功能
- libcurl的封装库 libSkyChaserHttp,支持gzip,http,htpps,功能齐全
- 手游包压缩技术和云更新技术主要能实现什么功能?
- 病毒分析第二讲,分析病毒的主要功能
- FFMPEG处理音频时间戳的主要逻辑
- 网络设备规划、配置与管理读书笔记(6)- 交换机概述之交换机的主要参数
- FFmpeg命令行工具系列一------ffmpeg.exe概述
- [置顶] POS 银行卡应用主要功能
- 比较详细的ffmpeg参数功能 分类说明
- 黑马程序员--Java学习日记之功能及类(常见类的概述)