住房和城乡建设部网站建筑电工,ppt模板制作教程步骤,wordpress H1 title,淮安涟水网站建设参考链接
FFmpeg源代码简单分析#xff1a;结构体成员管理系统-AVClass_雷霄骅的博客-CSDN博客FFmpeg源代码简单分析#xff1a;结构体成员管理系统-AVOption_雷霄骅的博客-CSDN博客
概述
AVOption用于在FFmpeg中描述结构体中的成员变量。它最主要的作用可以概括为两个字结构体成员管理系统-AVClass_雷霄骅的博客-CSDN博客FFmpeg源代码简单分析结构体成员管理系统-AVOption_雷霄骅的博客-CSDN博客
概述
AVOption用于在FFmpeg中描述结构体中的成员变量。它最主要的作用可以概括为两个字“赋值”。一个AVOption结构体包含了变量名称简短的帮助取值等等信息。所有和AVOption有关的数据都存储在AVClass结构体中。如果一个结构体例如AVFormatContext或者AVCodecContext想要支持AVOption的话它的第一个成员变量必须是一个指向AVClass结构体的指针。该AVClass中的成员变量option必须指向一个AVOption类型的静态数组。AVOption AVOption是用来设置FFmpeg中变量的值的结构体。可能说到这个作用有的人会奇怪设置系统中变量的值直接使用等于号“”就可以为什么还要专门定义一个结构体呢其实AVOption的特点就在于它赋值时候的灵活性。AVOption可以使用字符串为任何类型的变量赋值。传统意义上如果变量类型为int则需要使用整数来赋值如果变量为double则需要使用小数来赋值如果变量类型为char *才需要使用字符串来赋值。而AVOption将这些赋值“归一化”了统一使用字符串赋值。例如给int型变量qp设定值为20通过AVOption需要传递进去一个内容为“20”的字符串。此外AVOption中变量的名称也使用字符串来表示。结合上面提到的使用字符串赋值的特性我们可以发现使用AVOption之后传递两个字符串一个是变量的名称一个是变量的值就可以改变系统中变量的值。上文提到的这种方法的意义在哪里我个人感觉对于直接使用C语言进行开发的人来说作用不是很明显完全可以使用等于号“”就可以进行各种变量的赋值。但是对于从外部系统中调用FFmpeg的人来说作用就很大了从外部系统中只可以传递字符串给内部系统。比如说对于直接调用ffmpeg.exe的人来说他们是无法修改FFmpeg内部各个变量的数值的这种情况下只能通过输入“名称”和“值”这样的字符串通过AVOption改变FFmpeg内部变量的值。由此可见使用AVOption可以使FFmpeg更加适应多种多样的外部系统。 可以对FFmpeg常用结构体AVFormatContextAVCodecContext等进行赋值之外还可以对它们的私有数据priv_data进行赋值。这个字段里通常存储了各种编码器特有的结构体。而这些结构体的定义在FFmpeg的SDK中是找不到的。例如使用libx264进行编码的时候通过AVCodecContext的priv_data字段可以对X264Context结构体中的变量进行赋值设置presetprofile等。使用libx265进行编码的时候通过AVCodecContext的priv_data字段可以对libx265Context结构体中的变量进行赋值设置presettune等。
结构体定义
/*** AVOption*/
typedef struct AVOption {const char *name;/*** short English help text* todo What about other languages?*/const char *help;/*** The offset relative to the context structure where the option* value is stored. It should be 0 for named constants.*/int offset;enum AVOptionType type;/*** the default value for scalar options*/union {int64_t i64;double dbl;const char *str;/* TODO those are unused now */AVRational q;} default_val;double min; /// minimum valid value for the optiondouble max; /// maximum valid value for the optionint flags;
#define AV_OPT_FLAG_ENCODING_PARAM 1 /// a generic parameter which can be set by the user for muxing or encoding
#define AV_OPT_FLAG_DECODING_PARAM 2 /// a generic parameter which can be set by the user for demuxing or decoding
#define AV_OPT_FLAG_AUDIO_PARAM 8
#define AV_OPT_FLAG_VIDEO_PARAM 16
#define AV_OPT_FLAG_SUBTITLE_PARAM 32
/*** The option is intended for exporting values to the caller.*/
#define AV_OPT_FLAG_EXPORT 64
/*** The option may not be set through the AVOptions API, only read.* This flag only makes sense when AV_OPT_FLAG_EXPORT is also set.*/
#define AV_OPT_FLAG_READONLY 128
#define AV_OPT_FLAG_BSF_PARAM (18) /// a generic parameter which can be set by the user for bit stream filtering
#define AV_OPT_FLAG_RUNTIME_PARAM (115) /// a generic parameter which can be set by the user at runtime
#define AV_OPT_FLAG_FILTERING_PARAM (116) /// a generic parameter which can be set by the user for filtering
#define AV_OPT_FLAG_DEPRECATED (117) /// set if option is deprecated, users should refer to AVOption.help text for more information
#define AV_OPT_FLAG_CHILD_CONSTS (118) /// set if option constants can also reside in child objects
//FIXME think about enc-audio, ... style flags/*** The logical unit to which the option belongs. Non-constant* options and corresponding named constants share the same* unit. May be NULL.*/const char *unit;
} AVOption;
下面简单解释一下AVOption的几个成员变量 name名称。help简短的帮助。offset选项相对结构体首部地址的偏移量这个很重要。type选项的类型。default_val选项的默认值。min选项的最小值。max选项的最大值。flags一些标记。unit该选项所属的逻辑单元可以为空。 其中default_val是一个union类型的变量可以根据选项数据类型的不同取intdoublechar*AVRational表示分数几种类型。type是一个AVOptionType类型的变量。AVOptionType是一个枚举类型定义如下。
/*** defgroup avoptions AVOptions* ingroup lavu_data* {* AVOptions provide a generic system to declare options on arbitrary structs* (objects). An option can have a help text, a type and a range of possible* values. Options may then be enumerated, read and written to.** section avoptions_implement Implementing AVOptions* This section describes how to add AVOptions capabilities to a struct.** All AVOptions-related information is stored in an AVClass. Therefore* the first member of the struct should be a pointer to an AVClass describing it.* The option field of the AVClass must be set to a NULL-terminated static array* of AVOptions. Each AVOption must have a non-empty name, a type, a default* value and for number-type AVOptions also a range of allowed values. It must* also declare an offset in bytes from the start of the struct, where the field* associated with this AVOption is located. Other fields in the AVOption struct* should also be set when applicable, but are not required.** The following example illustrates an AVOptions-enabled struct:* code* typedef struct test_struct {* const AVClass *class;* int int_opt;* char *str_opt;* uint8_t *bin_opt;* int bin_len;* } test_struct;** static const AVOption test_options[] {* { test_int, This is a test option of int type., offsetof(test_struct, int_opt),* AV_OPT_TYPE_INT, { .i64 -1 }, INT_MIN, INT_MAX },* { test_str, This is a test option of string type., offsetof(test_struct, str_opt),* AV_OPT_TYPE_STRING },* { test_bin, This is a test option of binary type., offsetof(test_struct, bin_opt),* AV_OPT_TYPE_BINARY },* { NULL },* };** static const AVClass test_class {* .class_name test class,* .item_name av_default_item_name,* .option test_options,* .version LIBAVUTIL_VERSION_INT,* };* endcode** Next, when allocating your struct, you must ensure that the AVClass pointer* is set to the correct value. Then, av_opt_set_defaults() can be called to* initialize defaults. After that the struct is ready to be used with the* AVOptions API.** When cleaning up, you may use the av_opt_free() function to automatically* free all the allocated string and binary options.** Continuing with the above example:** code* test_struct *alloc_test_struct(void)* {* test_struct *ret av_mallocz(sizeof(*ret));* ret-class test_class;* av_opt_set_defaults(ret);* return ret;* }* void free_test_struct(test_struct **foo)* {* av_opt_free(*foo);* av_freep(foo);* }* endcode** subsection avoptions_implement_nesting Nesting* It may happen that an AVOptions-enabled struct contains another* AVOptions-enabled struct as a member (e.g. AVCodecContext in* libavcodec exports generic options, while its priv_data field exports* codec-specific options). In such a case, it is possible to set up the* parent struct to export a childs options. To do that, simply* implement AVClass.child_next() and AVClass.child_class_iterate() in the* parent structs AVClass.* Assuming that the test_struct from above now also contains a* child_struct field:** code* typedef struct child_struct {* AVClass *class;* int flags_opt;* } child_struct;* static const AVOption child_opts[] {* { test_flags, This is a test option of flags type.,* offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 0 }, INT_MIN, INT_MAX },* { NULL },* };* static const AVClass child_class {* .class_name child class,* .item_name av_default_item_name,* .option child_opts,* .version LIBAVUTIL_VERSION_INT,* };** void *child_next(void *obj, void *prev)* {* test_struct *t obj;* if (!prev t-child_struct)* return t-child_struct;* return NULL* }* const AVClass child_class_iterate(void **iter)* {* const AVClass *c *iter ? NULL : child_class;* *iter (void*)(uintptr_t)c;* return c;* }* endcode* Putting child_next() and child_class_iterate() as defined above into* test_class will now make child_structs options accessible through* test_struct (again, proper setup as described above needs to be done on* child_struct right after it is created).** From the above example it might not be clear why both child_next()* and child_class_iterate() are needed. The distinction is that child_next()* iterates over actually existing objects, while child_class_iterate()* iterates over all possible child classes. E.g. if an AVCodecContext* was initialized to use a codec which has private options, then its* child_next() will return AVCodecContext.priv_data and finish* iterating. OTOH child_class_iterate() on AVCodecContext.av_class will* iterate over all available codecs with private options.** subsection avoptions_implement_named_constants Named constants* It is possible to create named constants for options. Simply set the unit* field of the option the constants should apply to a string and* create the constants themselves as options of type AV_OPT_TYPE_CONST* with their unit field set to the same string.* Their default_val field should contain the value of the named* constant.* For example, to add some named constants for the test_flags option* above, put the following into the child_opts array:* code* { test_flags, This is a test option of flags type.,* offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 0 }, INT_MIN, INT_MAX, test_unit },* { flag1, This is a flag with value 16, 0, AV_OPT_TYPE_CONST, { .i64 16 }, 0, 0, test_unit },* endcode** section avoptions_use Using AVOptions* This section deals with accessing options in an AVOptions-enabled struct.* Such structs in FFmpeg are e.g. AVCodecContext in libavcodec or* AVFormatContext in libavformat.** subsection avoptions_use_examine Examining AVOptions* The basic functions for examining options are av_opt_next(), which iterates* over all options defined for one object, and av_opt_find(), which searches* for an option with the given name.** The situation is more complicated with nesting. An AVOptions-enabled struct* may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag* to av_opt_find() will make the function search children recursively.** For enumerating there are basically two cases. The first is when you want to* get all options that may potentially exist on the struct and its children* (e.g. when constructing documentation). In that case you should call* av_opt_child_class_iterate() recursively on the parent structs AVClass. The* second case is when you have an already initialized struct with all its* children and you want to get all options that can be actually written or read* from it. In that case you should call av_opt_child_next() recursively (and* av_opt_next() on each result).** subsection avoptions_use_get_set Reading and writing AVOptions* When setting options, you often have a string read directly from the* user. In such a case, simply passing it to av_opt_set() is enough. For* non-string type options, av_opt_set() will parse the string according to the* option type.** Similarly av_opt_get() will read any option type and convert it to a string* which will be returned. Do not forget that the string is allocated, so you* have to free it with av_free().** In some cases it may be more convenient to put all options into an* AVDictionary and call av_opt_set_dict() on it. A specific case of this* are the format/codec open functions in lavf/lavc which take a dictionary* filled with option as a parameter. This makes it possible to set some options* that cannot be set otherwise, since e.g. the input file format is not known* before the file is actually opened.*/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, /// offset must point to a pointer immediately followed by an int for the lengthAV_OPT_TYPE_DICT,AV_OPT_TYPE_UINT64,AV_OPT_TYPE_CONST,AV_OPT_TYPE_IMAGE_SIZE, /// offset must point to two consecutive integersAV_OPT_TYPE_PIXEL_FMT,AV_OPT_TYPE_SAMPLE_FMT,AV_OPT_TYPE_VIDEO_RATE, /// offset must point to AVRationalAV_OPT_TYPE_DURATION,AV_OPT_TYPE_COLOR,
#if FF_API_OLD_CHANNEL_LAYOUTAV_OPT_TYPE_CHANNEL_LAYOUT,
#endifAV_OPT_TYPE_BOOL,AV_OPT_TYPE_CHLAYOUT,
};补充 突然想到了JavaEE开发中也有这种类似的机制。互联网上只可以传输字符串即是没有方法传输整形、浮点型这种的数据。而Java系统中却包含整形、浮点型等各种数据类型。因此开发JSP中的Servlet的时候经常需要将整数字符串手工转化成一个整型的变量。使用最多的一个函数就是Integer.parseInt()方法。例如下面代码可以将字符串“123”转化成整数123。int aInteger.parseInt(123); 而在使用JavaEE中的Struts2进行开发的时候就不需要进行手动转换处理了。Struts2中包含了类似AVOption的这种数据类型自动转换机制可以将互联网上收到的字符串“名称”和“值”的组合自动赋值给相应名称的变量。由此发现了一个结论编程语言之间真的是相通的
AVOption有关的API AVOption常用的API可以分成两类用于设置参数的API和用于读取参数的API。其中最有代表性的用于设置参数的API就是av_opt_set()而最有代表性的用于读取参数的API就是av_opt_get()。除了记录以上两个函数之外本文再记录一个在FFmpeg的结构体初始化代码中最常用的用于设置默认值的函数av_opt_set_defaults()。
av_opt_set() 通过AVOption设置参数最常用的函数就是av_opt_set()了。该函数通过字符串的方式传入的参数是变量名称的字符串和变量值的字符串设置一个AVOption的值。此外还包含了它的一系列“兄弟”函数av_opt_set_XXX()其中“XXX”代表了intdouble这些数据类型。使用这些函数的时候可以指定intdouble这些类型的变量而不是字符串作为输入设定相应的AVOption的值。
/*** defgroup opt_set_funcs Option setting functions* {* Those functions set the field of obj with the given name to value.** param[in] obj A struct whose first element is a pointer to an AVClass.* param[in] name the name of the field to set* param[in] val The value to set. In case of av_opt_set() if the field is not* of a string type, then the given string is parsed.* SI postfixes and some named scalars are supported.* If the field is of a numeric type, it has to be a numeric or named* scalar. Behavior with more than one scalar and - infix operators* is undefined.* If the field is of a flags type, it has to be a sequence of numeric* scalars or named flags separated by or -. Prefixing a flag* with causes it to be set without affecting the other flags;* similarly, - unsets a flag.* If the field is of a dictionary type, it has to be a : separated list of* keyvalue parameters. Values containing : special characters must be* escaped.* param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN* is passed here, then the option may be set on a child of obj.** return 0 if the value has been set, or an AVERROR code in case of* error:* AVERROR_OPTION_NOT_FOUND if no matching option exists* AVERROR(ERANGE) if the value is out of range* AVERROR(EINVAL) if the value is not valid*/
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 av_opt_set_double (void *obj, const char *name, double val, int search_flags);
int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags);
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);
int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
#if FF_API_OLD_CHANNEL_LAYOUT
attribute_deprecated
int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
#endif
int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *layout, int search_flags);
/*** note Any old dictionary present is discarded and replaced with a copy of the new one. The* caller still owns val is and responsible for freeing it.*/
int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags);/*** Set a binary option to an integer list.** param obj AVClass object to set options on* param name name of the binary option* param val pointer to an integer list (must have the correct type with* regard to the contents of the list)* param term list terminator (usually 0 or -1)* param flags search flags*/
#define av_opt_set_int_list(obj, name, val, term, flags) \(av_int_list_length(val, term) INT_MAX / sizeof(*(val)) ? \AVERROR(EINVAL) : \av_opt_set_bin(obj, name, (const uint8_t *)(val), \av_int_list_length(val, term) * sizeof(*(val)), flags))
函数调用关系图如下所示。av_opt_set()的定义位于libavutil\opt.c如下所示。
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
{int ret 0;void *dst, *target_obj;const AVOption *o av_opt_find2(obj, name, NULL, 0, search_flags, target_obj);if (!o || !target_obj)return AVERROR_OPTION_NOT_FOUND;
FF_DISABLE_DEPRECATION_WARNINGSif (!val (o-type ! AV_OPT_TYPE_STRING o-type ! AV_OPT_TYPE_PIXEL_FMT o-type ! AV_OPT_TYPE_SAMPLE_FMT o-type ! AV_OPT_TYPE_IMAGE_SIZE o-type ! AV_OPT_TYPE_DURATION o-type ! AV_OPT_TYPE_COLOR
#if FF_API_OLD_CHANNEL_LAYOUTo-type ! AV_OPT_TYPE_CHANNEL_LAYOUT
#endifo-type ! AV_OPT_TYPE_BOOL))return AVERROR(EINVAL);
FF_ENABLE_DEPRECATION_WARNINGSif (o-flags AV_OPT_FLAG_READONLY)return AVERROR(EINVAL);if (o-flags AV_OPT_FLAG_DEPRECATED)av_log(obj, AV_LOG_WARNING, The \%s\ option is deprecated: %s\n, name, o-help);dst ((uint8_t *)target_obj) o-offset;switch (o-type) {case AV_OPT_TYPE_BOOL:return set_string_bool(obj, o, val, dst);case AV_OPT_TYPE_STRING:return set_string(obj, o, val, dst);case AV_OPT_TYPE_BINARY:return set_string_binary(obj, o, val, dst);case AV_OPT_TYPE_FLAGS:case AV_OPT_TYPE_INT:case AV_OPT_TYPE_INT64:case AV_OPT_TYPE_UINT64:case AV_OPT_TYPE_FLOAT:case AV_OPT_TYPE_DOUBLE:case AV_OPT_TYPE_RATIONAL:return set_string_number(obj, target_obj, o, val, dst);case AV_OPT_TYPE_IMAGE_SIZE:return set_string_image_size(obj, o, val, dst);case AV_OPT_TYPE_VIDEO_RATE: {AVRational tmp;ret set_string_video_rate(obj, o, val, tmp);if (ret 0)return ret;return write_number(obj, o, dst, 1, tmp.den, tmp.num);}case AV_OPT_TYPE_PIXEL_FMT:return set_string_pixel_fmt(obj, o, val, dst);case AV_OPT_TYPE_SAMPLE_FMT:return set_string_sample_fmt(obj, o, val, dst);case AV_OPT_TYPE_DURATION:{int64_t usecs 0;if (val) {if ((ret av_parse_time(usecs, val, 1)) 0) {av_log(obj, AV_LOG_ERROR, Unable to parse option value \%s\ as duration\n, val);return ret;}}if (usecs o-min || usecs o-max) {av_log(obj, AV_LOG_ERROR, Value %f for parameter %s out of range [%g - %g]\n,usecs / 1000000.0, o-name, o-min / 1000000.0, o-max / 1000000.0);return AVERROR(ERANGE);}*(int64_t *)dst usecs;return 0;}case AV_OPT_TYPE_COLOR:return set_string_color(obj, o, val, dst);
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGScase AV_OPT_TYPE_CHANNEL_LAYOUT:if (!val || !strcmp(val, none)) {*(int64_t *)dst 0;} else {int64_t cl av_get_channel_layout(val);if (!cl) {av_log(obj, AV_LOG_ERROR, Unable to parse option value \%s\ as channel layout\n, val);ret AVERROR(EINVAL);}*(int64_t *)dst cl;return ret;}break;
FF_ENABLE_DEPRECATION_WARNINGS
#endifcase AV_OPT_TYPE_CHLAYOUT:ret set_string_channel_layout(obj, o, val, dst);if (ret 0) {av_log(obj, AV_LOG_ERROR, Unable to parse option value \%s\ as channel layout\n, val);ret AVERROR(EINVAL);}return ret;case AV_OPT_TYPE_DICT:return set_string_dict(obj, o, val, dst);}av_log(obj, AV_LOG_ERROR, Invalid option type.\n);return AVERROR(EINVAL);
} 从源代码可以看出av_opt_set()首先调用av_opt_find2()查找AVOption。如果找到了则根据AVOption的type调用不同的函数set_string()set_string_number()set_string_image_size()等等将输入的字符串转化为相应type的数据并对该AVOption进行赋值。如果没有找到则立即返回“没有找到AVOption”的错误。 现在再回到刚才的av_opt_set()函数。该函数有一个void型的变量dst用于确定需要设定的AVOption对应的变量的位置。具体的方法就是将输入的AVClass结构体的首地址加上该AVOption的偏移量offset。确定了AVOption对应的变量的位置之后就可以根据该AVOption的类型type的不同调用不同的字符串转换函数设置相应的值了。
av_opt_find2() / av_opt_find()
av_opt_find2()本身也是一个API函数用于查找AVOption。它的声明位于libavutil\opt.h中如下所示。
/*** Look for an option in an object. Consider only options which* have all the specified flags set.** param[in] obj A pointer to a struct whose first element is a* pointer to an AVClass.* Alternatively a double pointer to an AVClass, if* AV_OPT_SEARCH_FAKE_OBJ search flag is set.* param[in] name The name of the option to look for.* param[in] unit When searching for named constants, name of the unit* it belongs to.* param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG).* param search_flags A combination of AV_OPT_SEARCH_*.* param[out] target_obj if non-NULL, an object to which the option belongs will be* written here. It may be different from obj if AV_OPT_SEARCH_CHILDREN is present* in search_flags. This parameter is ignored if search_flags contain* AV_OPT_SEARCH_FAKE_OBJ.** return A pointer to the option found, or NULL if no option* was found.*/
const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,int opt_flags, int search_flags, void **target_obj);
此外还有一个和av_opt_find2()“长得很像”的API函数av_opt_find()功能与av_opt_find2()基本类似与av_opt_find2()相比少了最后一个参数。从源代码中可以看出它只是简单调用了av_opt_find2()并把所有的输入参数原封不动的传递过去并把最后一个参数设置成NULL。
const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,int opt_flags, int search_flags, void **target_obj)
{const AVClass *c;const AVOption *o NULL;if(!obj)return NULL;c *(AVClass**)obj;if (!c)return NULL;if (search_flags AV_OPT_SEARCH_CHILDREN) {if (search_flags AV_OPT_SEARCH_FAKE_OBJ) {void *iter NULL;const AVClass *child;while (child av_opt_child_class_iterate(c, iter))if (o av_opt_find2(child, name, unit, opt_flags, search_flags, NULL))return o;} else {void *child NULL;while (child av_opt_child_next(obj, child))if (o av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))return o;}}while (o av_opt_next(obj, o)) {if (!strcmp(o-name, name) (o-flags opt_flags) opt_flags ((!unit o-type ! AV_OPT_TYPE_CONST) ||(unit o-type AV_OPT_TYPE_CONST o-unit !strcmp(o-unit, unit)))) {if (target_obj) {if (!(search_flags AV_OPT_SEARCH_FAKE_OBJ))*target_obj obj;else*target_obj NULL;}return o;}}return NULL;
}const AVOption *av_opt_find(void *obj, const char *name, const char *unit,int opt_flags, int search_flags)
{return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
} 这段代码的前半部分暂时不关注前半部分的if()语句中的内容只有在search_flags指定为AV_OPT_SEARCH_CHILDREN的时候才会执行。后半部分代码是重点。后半部分代码是一个while()循环该循环的条件是一个函数av_opt_next()。 现在再回到av_opt_find2()函数。我们发现在while()循环中有一个strcmp()函数正是这个函数比较输入的AVOption的name和AVClass的option数组中每个元素的name当上述两个name相等的时候就代表查找到了AVOption接着就可以返回获得的AVOption。
av_opt_next()
av_opt_next()也是一个FFmpeg的API函数。使用它可以循环遍历目标结构体的所有AVOption它的声明如下。
/*** Iterate over all AVOptions belonging to obj.** param obj an AVOptions-enabled struct or a double pointer to an* AVClass describing it.* param prev result of the previous call to av_opt_next() on this object* or NULL* return next AVOption or NULL*/
const AVOption *av_opt_next(const void *obj, const AVOption *prev);
av_opt_next()的定义如下所示。
const AVOption *av_opt_next(const void *obj, const AVOption *last)
{const AVClass *class;if (!obj)return NULL;class *(const AVClass**)obj;if (!last class class-option class-option[0].name)return class-option;if (last last[1].name)return last;return NULL;
} 从av_opt_next()的代码可以看出输入的AVOption类型的last变量为空的时候会返回该AVClass的option数组的第一个元素否则会返回数组的下一个元素。
我们可以看几个设置值的的简单例子
1. AV_OPT_TYPE_STRING
当AVOption的type为AV_OPT_TYPE_STRING的时候调用set_string()方法设置相应的值。set_string()的定义如下
static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
{av_freep(dst);*dst av_strdup(val);return *dst ? 0 : AVERROR(ENOMEM);
}其中又调用了一个函数av_strdup()这是一个FFmpeg的API函数用于拷贝字符串。它的代码如下所示其中调用了memcpy()。
char *av_strdup(const char *s)
{char *ptr NULL;if (s) {size_t len strlen(s) 1;ptr av_realloc(NULL, len);if (ptr)memcpy(ptr, s, len);}return ptr;
}2. AV_OPT_TYPE_IMAGE_SIZE
当AVOption的type为AV_OPT_TYPE_IMAGE_SIZE的时候调用set_string_image_size ()方法设置相应的值。set_string_image_size()的定义如下。
static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst)
{int ret;if (!val || !strcmp(val, none)) {dst[0] dst[1] 0;return 0;}ret av_parse_video_size(dst, dst 1, val);if (ret 0)av_log(obj, AV_LOG_ERROR, Unable to parse option value \%s\ as image size\n, val);return ret;
} 可见其中调用了另一个函数av_parse_video_size()。
av_parse_video_size() av_parse_video_size()是一个FFmpeg的API函数用于解析出输入的分辨率字符串的宽高信息。例如输入的字符串为“1920x1080”或者“1920*1080”经过av_parse_video_size()的处理之后可以得到宽度为1920高度为1080此外输入一个“特定分辨率”字符串例如“vga”也可以得到宽度为640高度为480。该函数不属于AVOption这部分的内容而是整个FFmpeg通用的一个字符串解析函数。声明位于libavutil\parseutils.h中如下所示。
/*** Parse str and put in width_ptr and height_ptr the detected values.** param[in,out] width_ptr pointer to the variable which will contain the detected* width value* param[in,out] height_ptr pointer to the variable which will contain the detected* height value* param[in] str the string to parse: it has to be a string in the format* width x height or a valid video size abbreviation.* return 0 on success, a negative error code otherwise*/
int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str);av_parse_video_size()定义位于libavutil\parseutils.c中代码如下。
//解析分辨率
int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
{int i;int n FF_ARRAY_ELEMS(video_size_abbrs);const char *p;int width 0, height 0;//先看看有没有“分辨率简称”相同的例如vgaqcif等for (i 0; i n; i) {if (!strcmp(video_size_abbrs[i].abbr, str)) {width video_size_abbrs[i].width;height video_size_abbrs[i].height;break;}}//如果没有使用“分辨率简称”而是使用具体的数值例如“1920x1080”则执行下面的步骤if (i n) {//strtol()字符串转换成整型遇到非数字则停止width strtol(str, (void*)p, 10);if (*p)p;height strtol(p, (void*)p, 10);/* trailing extraneous data detected, like in 123x345foobar */if (*p)return AVERROR(EINVAL);}//检查一下正确性if (width 0 || height 0)return AVERROR(EINVAL);*width_ptr width;*height_ptr height;return 0;
}
从声明中可以看出该函数输入一个字符串str输出结果保存在width_ptr和height_ptr所指向的内存中。上述代码中包含了FFmpeg中两种解析视频分辨率的方法。FFmpeg中包含两种设定视频分辨率的方法通过已经定义好的“分辨率简称”或者通过具体的数值。代码中首先遍历“特定分辨率”的数组video_size_abbrs。该数组定义如下所示。
static const VideoSizeAbbr video_size_abbrs[] {{ ntsc, 720, 480 },{ pal, 720, 576 },{ qntsc, 352, 240 }, /* VCD compliant NTSC */{ qpal, 352, 288 }, /* VCD compliant PAL */{ sntsc, 640, 480 }, /* square pixel NTSC */{ spal, 768, 576 }, /* square pixel PAL */{ film, 352, 240 },{ ntsc-film, 352, 240 },{ sqcif, 128, 96 },{ qcif, 176, 144 },{ cif, 352, 288 },{ 4cif, 704, 576 },{ 16cif, 1408,1152 },{ qqvga, 160, 120 },{ qvga, 320, 240 },{ vga, 640, 480 },{ svga, 800, 600 },{ xga, 1024, 768 },{ uxga, 1600,1200 },{ qxga, 2048,1536 },{ sxga, 1280,1024 },{ qsxga, 2560,2048 },{ hsxga, 5120,4096 },{ wvga, 852, 480 },{ wxga, 1366, 768 },{ wsxga, 1600,1024 },{ wuxga, 1920,1200 },{ woxga, 2560,1600 },{ wqhd, 2560,1440 },{ wqsxga, 3200,2048 },{ wquxga, 3840,2400 },{ whsxga, 6400,4096 },{ whuxga, 7680,4800 },{ cga, 320, 200 },{ ega, 640, 350 },{ hd480, 852, 480 },{ hd720, 1280, 720 },{ hd1080, 1920,1080 },{ quadhd, 2560,1440 },{ 2k, 2048,1080 }, /* Digital Cinema System Specification */{ 2kdci, 2048,1080 },{ 2kflat, 1998,1080 },{ 2kscope, 2048, 858 },{ 4k, 4096,2160 }, /* Digital Cinema System Specification */{ 4kdci, 4096,2160 },{ 4kflat, 3996,2160 },{ 4kscope, 4096,1716 },{ nhd, 640,360 },{ hqvga, 240,160 },{ wqvga, 400,240 },{ fwqvga, 432,240 },{ hvga, 480,320 },{ qhd, 960,540 },{ uhd2160, 3840,2160 },{ uhd4320, 7680,4320 },
};通过调用strcmp()方法比对输入字符串的值与video_size_abbrs数组中每个VideoSizeAbbr元素的abbr字段的值判断输入的字符串是否指定了这些标准的分辨率。如果指定了的话则返回该分辨率的宽和高。 如果从上述列表中没有找到相应的“特定分辨率”则说明输入的字符串应该是一个具体的分辨率的值形如“1920*1020”“1280x720”这样的字符串。这个时候就需要对这个字符串进行解析并从中提取出数字信息。通过两次调用strtol()方法从字符串中提取出宽高信息第一次提取出宽第二次提取出高。PS1strtol()用于将字符串转换成整型遇到非数字则停止。PS2从这种解析方法可以得到一个信息——FFmpeg并不管“宽{X}高”中间的那个{X}是什么字符也就是说中间那个字符不一定非得是“*”或者“x”。后来试了一下中间那个字符使用其他字母也是可以的。
av_opt_get()
函数调用关系图如下所示 av_opt_get()用于获取一个AVOption变量的值。需要注意的是不论是何种类型的变量通过av_opt_get()取出来的值都是字符串类型的。此外还包含了它的一系列“兄弟”函数av_opt_get_XXX()其中“XXX”代表了intdouble这些数据类型。通过这些“兄弟”函数可以直接取出intdouble类型的数值。av_opt_get()的声明如下所示。
/*** defgroup opt_get_funcs Option getting functions* {* Those functions get a value of the option with the given name from an object.** param[in] obj a struct whose first element is a pointer to an AVClass.* param[in] name name of the option to get.* param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN* is passed here, then the option may be found in a child of obj.* param[out] out_val value of the option will be written here* return 0 on success, a negative error code otherwise*/
/*** note the returned string will be av_malloc()ed and must be av_free()ed by the caller** note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the* option is of type AV_OPT_TYPE_STRING, AV_OPT_TYPE_BINARY or AV_OPT_TYPE_DICT* and is set to NULL, *out_val will be set to NULL instead of an allocated* empty string.*/
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);
#if FF_API_OLD_CHANNEL_LAYOUT
attribute_deprecated
int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
#endif
int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *layout);
/*** param[out] out_val The returned dictionary is a copy of the actual value and must* be freed with av_dict_free() by the caller*/
int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val);
下面我们看一下av_opt_get()的定义如下所示。从av_opt_get()的定义可以看出该函数首先通过av_opt_find2()查相应的AVOption然后取出该变量的值最后通过snprintf()将变量的值转化为字符串各种各样类型的变量都这样处理并且输出出来。至此FFmpeg中和AVOption相关的源代码基本上就分析完毕了。
int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
{void *dst, *target_obj;const AVOption *o av_opt_find2(obj, name, NULL, 0, search_flags, target_obj);uint8_t *bin, buf[128];int len, i, ret;int64_t i64;if (!o || !target_obj || (o-offset0 o-type ! AV_OPT_TYPE_CONST))return AVERROR_OPTION_NOT_FOUND;if (o-flags AV_OPT_FLAG_DEPRECATED)av_log(obj, AV_LOG_WARNING, The \%s\ option is deprecated: %s\n, name, o-help);dst (uint8_t *)target_obj o-offset;buf[0] 0;switch (o-type) {case AV_OPT_TYPE_BOOL:ret snprintf(buf, sizeof(buf), %s, (char *)av_x_if_null(get_bool_name(*(int *)dst), invalid));break;case AV_OPT_TYPE_FLAGS:ret snprintf(buf, sizeof(buf), 0x%08X, *(int *)dst);break;case AV_OPT_TYPE_INT:ret snprintf(buf, sizeof(buf), %d, *(int *)dst);break;case AV_OPT_TYPE_INT64:ret snprintf(buf, sizeof(buf), %PRId64, *(int64_t *)dst);break;case AV_OPT_TYPE_UINT64:ret snprintf(buf, sizeof(buf), %PRIu64, *(uint64_t *)dst);break;case AV_OPT_TYPE_FLOAT:ret snprintf(buf, sizeof(buf), %f, *(float *)dst);break;case AV_OPT_TYPE_DOUBLE:ret snprintf(buf, sizeof(buf), %f, *(double *)dst);break;case AV_OPT_TYPE_VIDEO_RATE:case AV_OPT_TYPE_RATIONAL:ret snprintf(buf, sizeof(buf), %d/%d, ((AVRational *)dst)-num, ((AVRational *)dst)-den);break;case AV_OPT_TYPE_CONST:ret snprintf(buf, sizeof(buf), %f, o-default_val.dbl);break;case AV_OPT_TYPE_STRING:if (*(uint8_t **)dst) {*out_val av_strdup(*(uint8_t **)dst);} else if (search_flags AV_OPT_ALLOW_NULL) {*out_val NULL;return 0;} else {*out_val av_strdup();}return *out_val ? 0 : AVERROR(ENOMEM);case AV_OPT_TYPE_BINARY:if (!*(uint8_t **)dst (search_flags AV_OPT_ALLOW_NULL)) {*out_val NULL;return 0;}len *(int *)(((uint8_t *)dst) sizeof(uint8_t *));if ((uint64_t)len * 2 1 INT_MAX)return AVERROR(EINVAL);if (!(*out_val av_malloc(len * 2 1)))return AVERROR(ENOMEM);if (!len) {*out_val[0] \0;return 0;}bin *(uint8_t **)dst;for (i 0; i len; i)snprintf(*out_val i * 2, 3, %02X, bin[i]);return 0;case AV_OPT_TYPE_IMAGE_SIZE:ret snprintf(buf, sizeof(buf), %dx%d, ((int *)dst)[0], ((int *)dst)[1]);break;case AV_OPT_TYPE_PIXEL_FMT:ret snprintf(buf, sizeof(buf), %s, (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), none));break;case AV_OPT_TYPE_SAMPLE_FMT:ret snprintf(buf, sizeof(buf), %s, (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), none));break;case AV_OPT_TYPE_DURATION:i64 *(int64_t *)dst;format_duration(buf, sizeof(buf), i64);ret strlen(buf); // no overflow possible, checked by an assertbreak;case AV_OPT_TYPE_COLOR:ret snprintf(buf, sizeof(buf), 0x%02x%02x%02x%02x,(int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],(int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);break;
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGScase AV_OPT_TYPE_CHANNEL_LAYOUT:i64 *(int64_t *)dst;ret snprintf(buf, sizeof(buf), 0x%PRIx64, i64);break;
FF_ENABLE_DEPRECATION_WARNINGS
#endifcase AV_OPT_TYPE_CHLAYOUT:ret av_channel_layout_describe(dst, buf, sizeof(buf));break;case AV_OPT_TYPE_DICT:if (!*(AVDictionary **)dst (search_flags AV_OPT_ALLOW_NULL)) {*out_val NULL;return 0;}return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, , :);default:return AVERROR(EINVAL);}if (ret sizeof(buf))return AVERROR(EINVAL);*out_val av_strdup(buf);return *out_val ? 0 : AVERROR(ENOMEM);
} av_opt_set_defaults()
函数调用关系图如下所示。av_opt_set_defaults()是一个FFmpeg的API作用是给一个结构体的成员变量设定默认值。在FFmpeg初始化其各种结构体AVFormatContextAVCodecContext等的时候通常会调用该函数设置结构体中的默认值。av_opt_set_defaults()的声明如下所示。
/*** Set the values of all AVOption fields to their default values.** param s an AVOption-enabled struct (its first member must be a pointer to AVClass)*/
void av_opt_set_defaults(void *s);
可见只需要把包含AVOption功能的结构体第一个变量是一个AVClass类型的指针的指针提供给av_opt_set_defaults()就可以初始化该结构体的默认值了。下面看一下av_opt_set_defaults()的源代码位于libavutil\opt.c如下所示。
void av_opt_set_defaults(void *s)
{av_opt_set_defaults2(s, 0, 0);
}void av_opt_set_defaults2(void *s, int mask, int flags)
{const AVOption *opt NULL;while ((opt av_opt_next(s, opt))) {void *dst ((uint8_t*)s) opt-offset;if ((opt-flags mask) ! flags)continue;if (opt-flags AV_OPT_FLAG_READONLY)continue;switch (opt-type) {case AV_OPT_TYPE_CONST:/* Nothing to be done here */break;case AV_OPT_TYPE_BOOL:case AV_OPT_TYPE_FLAGS:case AV_OPT_TYPE_INT:case AV_OPT_TYPE_INT64:case AV_OPT_TYPE_UINT64:case AV_OPT_TYPE_DURATION:
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGScase AV_OPT_TYPE_CHANNEL_LAYOUT:
FF_ENABLE_DEPRECATION_WARNINGS
#endifcase AV_OPT_TYPE_PIXEL_FMT:case AV_OPT_TYPE_SAMPLE_FMT:write_number(s, opt, dst, 1, 1, opt-default_val.i64);break;case AV_OPT_TYPE_DOUBLE:case AV_OPT_TYPE_FLOAT: {double val;val opt-default_val.dbl;write_number(s, opt, dst, val, 1, 1);}break;case AV_OPT_TYPE_RATIONAL: {AVRational val;val av_d2q(opt-default_val.dbl, INT_MAX);write_number(s, opt, dst, 1, val.den, val.num);}break;case AV_OPT_TYPE_COLOR:set_string_color(s, opt, opt-default_val.str, dst);break;case AV_OPT_TYPE_STRING:set_string(s, opt, opt-default_val.str, dst);break;case AV_OPT_TYPE_IMAGE_SIZE:set_string_image_size(s, opt, opt-default_val.str, dst);break;case AV_OPT_TYPE_VIDEO_RATE:set_string_video_rate(s, opt, opt-default_val.str, dst);break;case AV_OPT_TYPE_BINARY:set_string_binary(s, opt, opt-default_val.str, dst);break;case AV_OPT_TYPE_CHLAYOUT:set_string_channel_layout(s, opt, opt-default_val.str, dst);break;case AV_OPT_TYPE_DICT:set_string_dict(s, opt, opt-default_val.str, dst);break;default:av_log(s, AV_LOG_DEBUG, AVOption type %d of option %s not implemented yet\n,opt-type, opt-name);}}
} av_opt_set_defaults()主体部分是一个while()循环。该循环的判断条件是一个av_opt_next()其作用是获得下一个AVOption。该函数的定义在前文中已经做过分析这里不再重复。下面简单解读一下av_opt_set_defaults()中while()循环语句里面的内容。有一个void类型的指针dst用于确定当前AVOption代表的变量的位置。该指针的位置有结构体的首地址和变量的偏移量offset确定。然后根据AVOption代表的变量的类型type调用不同的函数设定相应的值。例如type为AV_OPT_TYPE_INT的话则会调用write_number()type为AV_OPT_TYPE_STRING的时候则会调用set_string()type为AV_OPT_TYPE_IMAGE_SIZE的时候则会调用set_string_image_size()。有关这些设置值的函数在前文中已经有所叙述不再重复。需要注意的是该函数中设置的值都是AVOption中的default_val变量的值。
结构体成员管理系统-AVClass AVClass最主要的作用就是给结构体例如AVFormatContext等增加AVOption功能的支持。换句话说AVClass就是AVOption和目标结构体之间的“桥梁”。AVClass要求必须声明为目标结构体的第一个变量。 AVClass中有一个option数组用于存储目标结构体的所有的AVOption。举个例子AVFormatContext结构体AVClass和AVOption之间的关系如下图所示。图中AVFormatContext结构体的第一个变量为AVClass类型的指针av_class它在AVFormatContext结构体初始化的时候被赋值指向了全局静态变量av_format_context_class结构体定义位于libavformat\options.c。而AVClass类型的av_format_context_class结构体中的option变量指向了全局静态数组avformat_options定义位于libavformat\options_table.h AVClass中存储了AVOption类型的数组option用于存储选项信息。AVClass有一个特点就是它必须位于其支持的结构体的第一个位置。例如AVFormatContext和AVCodecContext都支持AVClass观察它们结构体的定义可以发现他们结构体的第一个变量都是AVClass。截取一小段AVFormatContext的定义的开头部分如下所示。
typedef struct AVFormatContext {/*** A class for logging and ref avoptions. Set by avformat_alloc_context().* Exports (de)muxer private options if they exist.*/const AVClass *av_class;/*** The input container format.** Demuxing only, set by avformat_open_input().*/struct AVInputFormat *iformat;/*** The output container format.** Muxing only, must be set by the caller before avformat_write_header().*/
struct AVOutputFormat *oformat;
//后文略
截取一小段AVCodecContext的定义的开头部分如下所示。
typedef struct AVCodecContext {/*** information on struct for av_log* - set by avcodec_alloc_context3*/const AVClass *av_class;int log_level_offset;enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */const struct AVCodec *codec;//后文略
下面来看一下AVClass的定义如下所示。
/*** Describe the class of an AVClass context structure. That is an* arbitrary struct of which the first field is a pointer to an* AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).*/
typedef struct AVClass {/*** The name of the class; usually it is the same name as the* context structure type to which the AVClass is associated.*/const char* class_name;/*** A pointer to a function which returns the name of a context* instance ctx associated with the class.*/const char* (*item_name)(void* ctx);/*** a pointer to the first option specified in the class if any or NULL** see av_set_default_options()*/const struct AVOption *option;/*** LIBAVUTIL_VERSION with which this structure was created.* This is used to allow fields to be added without requiring major* version bumps everywhere.*/int version;/*** Offset in the structure where log_level_offset is stored.* 0 means there is no such variable*/int log_level_offset_offset;/*** Offset in the structure where a pointer to the parent context for* logging is stored. For example a decoder could pass its AVCodecContext* to eval as such a parent context, which an av_log() implementation* could then leverage to display the parent context.* The offset can be NULL.*/int parent_log_context_offset;/*** Category used for visualization (like color)* This is only set if the category is equal for all objects using this class.* available since version (51 16 | 56 8 | 100)*/AVClassCategory category;/*** Callback to return the category.* available since version (51 16 | 59 8 | 100)*/AVClassCategory (*get_category)(void* ctx);/*** Callback to return the supported/allowed ranges.* available since version (52.12)*/int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags);/*** Return next AVOptions-enabled child or NULL*/void* (*child_next)(void *obj, void *prev);/*** Iterate over the AVClasses corresponding to potential AVOptions-enabled* children.** param iter pointer to opaque iteration state. The caller must initialize* *iter to NULL before the first call.* return AVClass for the next AVOptions-enabled child or NULL if there are* no more such children.** note The difference between child_next and this is that child_next* iterates over _already existing_ objects, while child_class_iterate* iterates over _all possible_ children.*/const struct AVClass* (*child_class_iterate)(void **iter);
} AVClass;
下面简单解释一下AVClass的几个已经理解的成员变量class_nameAVClass名称。item_name函数获取与AVClass相关联的结构体实例的名称。optionAVOption类型的数组最重要。version完成该AVClass的时候的LIBAVUTIL_VERSION。categoryAVClass的类型是一个类型为AVClassCategory的枚举型变量。 其中AVClassCategory定义如下。
typedef enum {AV_CLASS_CATEGORY_NA 0,AV_CLASS_CATEGORY_INPUT,AV_CLASS_CATEGORY_OUTPUT,AV_CLASS_CATEGORY_MUXER,AV_CLASS_CATEGORY_DEMUXER,AV_CLASS_CATEGORY_ENCODER,AV_CLASS_CATEGORY_DECODER,AV_CLASS_CATEGORY_FILTER,AV_CLASS_CATEGORY_BITSTREAM_FILTER,AV_CLASS_CATEGORY_SWSCALER,AV_CLASS_CATEGORY_SWRESAMPLER,AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT 40,AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT,AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT,AV_CLASS_CATEGORY_DEVICE_OUTPUT,AV_CLASS_CATEGORY_DEVICE_INPUT,AV_CLASS_CATEGORY_NB /// not part of ABI/API
}AVClassCategory; 上面解释字段还是比较抽象的下面通过具体的例子看一下AVClass这个结构体。我们看几个具体的例子 AVFormatContext中的AVClassAVCodecContext中的AVClassAVFrame中的AVClass各种组件libRTMPlibx264libx265里面特有的AVClass。
AVFormatContext中的AVClass
AVFormatContext 中的AVClass定义位于libavformat\options.c中是一个名称为av_format_context_class的静态结构体。如下所示。
static const AVClass av_format_context_class {.class_name AVFormatContext,.item_name format_to_name,.option avformat_options,.version LIBAVUTIL_VERSION_INT,.child_next format_child_next,.child_class_iterate format_child_class_iterate,.category AV_CLASS_CATEGORY_MUXER,.get_category get_category,
};
从源代码可以看出以下几点 1class_name该AVClass名称是“AVFormatContext”。 2item_nameitem_name指向一个函数format_to_name()该函数定义如下所示。
static const char* format_to_name(void* ptr)
{AVFormatContext* fc (AVFormatContext*) ptr;if(fc-iformat) return fc-iformat-name;else if(fc-oformat) return fc-oformat-name;else return NULL;
}
从函数的定义可以看出如果AVFormatContext结构体中的AVInputFormat结构体不为空则返回AVInputFormat的name然后尝试返回AVOutputFormat的name如果AVOutputFormat也为空则返回“NULL”。3optionoption字段则指向一个元素个数很多的静态数组avformat_options。该数组单独定义于libavformat\options_table.h中。其中包含了AVFormatContext支持的所有的AVOption如下所示。
/** Copyright (c) 2000, 2001, 2002 Fabrice Bellard** This file is part of FFmpeg.** FFmpeg is free software; you can redistribute it and/or* modify it under the terms of the GNU Lesser General Public* License as published by the Free Software Foundation; either* version 2.1 of the License, or (at your option) any later version.** FFmpeg is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with FFmpeg; if not, write to the Free Software* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/#ifndef AVFORMAT_OPTIONS_TABLE_H
#define AVFORMAT_OPTIONS_TABLE_H#include limits.h#include libavutil/opt.h
#include avformat.h
#include internal.h#define OFFSET(x) offsetof(AVFormatContext,x)
#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
//these names are too long to be readable
#define E AV_OPT_FLAG_ENCODING_PARAM
#define D AV_OPT_FLAG_DECODING_PARAMstatic const AVOption avformat_options[] {
{avioflags, NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 DEFAULT }, INT_MIN, INT_MAX, D|E, avioflags},
{direct, reduce buffering, 0, AV_OPT_TYPE_CONST, {.i64 AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, avioflags},
{probesize, set probing size, OFFSET(probesize), AV_OPT_TYPE_INT64, {.i64 5000000 }, 32, INT64_MAX, D},
{formatprobesize, number of bytes to probe file format, OFFSET(format_probesize), AV_OPT_TYPE_INT, {.i64 PROBE_BUF_MAX}, 0, INT_MAX-1, D},
{packetsize, set packet size, OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX, E},
{fflags, NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 AVFMT_FLAG_AUTO_BSF }, INT_MIN, INT_MAX, D|E, fflags},
{flush_packets, reduce the latency by flushing out packets immediately, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_FLUSH_PACKETS }, INT_MIN, INT_MAX, E, fflags},
{ignidx, ignore index, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, fflags},
{genpts, generate pts, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_GENPTS }, INT_MIN, INT_MAX, D, fflags},
{nofillin, do not fill in missing values that can be exactly calculated, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_NOFILLIN }, INT_MIN, INT_MAX, D, fflags},
{noparse, disable AVParsers, this needs nofillin too, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_NOPARSE }, INT_MIN, INT_MAX, D, fflags},
{igndts, ignore dts, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, fflags},
{discardcorrupt, discard corrupted frames, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, fflags},
{sortdts, try to interleave outputted packets by dts, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, fflags},
{fastseek, fast but inaccurate seeks, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_FAST_SEEK }, INT_MIN, INT_MAX, D, fflags},
{nobuffer, reduce the latency introduced by optional buffering, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, fflags},
{bitexact, do not write random/volatile data, 0, AV_OPT_TYPE_CONST, { .i64 AVFMT_FLAG_BITEXACT }, 0, 0, E, fflags },
{shortest, stop muxing with the shortest stream, 0, AV_OPT_TYPE_CONST, { .i64 AVFMT_FLAG_SHORTEST }, 0, 0, E, fflags },
{autobsf, add needed bsfs automatically, 0, AV_OPT_TYPE_CONST, { .i64 AVFMT_FLAG_AUTO_BSF }, 0, 0, E, fflags },
{seek2any, allow seeking to non-keyframes on demuxer level when supported, OFFSET(seek2any), AV_OPT_TYPE_BOOL, {.i64 0 }, 0, 1, D},
{analyzeduration, specify how many microseconds are analyzed to probe the input, OFFSET(max_analyze_duration), AV_OPT_TYPE_INT64, {.i64 0 }, 0, INT64_MAX, D},
{cryptokey, decryption key, OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl 0}, 0, 0, D},
{indexmem, max memory used for timestamp index (per stream), OFFSET(max_index_size), AV_OPT_TYPE_INT, {.i64 120 }, 0, INT_MAX, D},
{rtbufsize, max memory used for buffering real-time frames, OFFSET(max_picture_buffer), AV_OPT_TYPE_INT, {.i64 3041280 }, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
{fdebug, print specific debug info, OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 DEFAULT }, 0, INT_MAX, E|D, fdebug},
{ts, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, fdebug},
{max_delay, maximum muxing or demuxing delay in microseconds, OFFSET(max_delay), AV_OPT_TYPE_INT, {.i64 -1 }, -1, INT_MAX, E|D},
{start_time_realtime, wall-clock time when stream begins (PTS0), OFFSET(start_time_realtime), AV_OPT_TYPE_INT64, {.i64 AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX, E},
{fpsprobesize, number of frames used to probe fps, OFFSET(fps_probe_size), AV_OPT_TYPE_INT, {.i64 -1}, -1, INT_MAX-1, D},
{audio_preload, microseconds by which audio packets should be interleaved earlier, OFFSET(audio_preload), AV_OPT_TYPE_INT, {.i64 0}, 0, INT_MAX-1, E},
{chunk_duration, microseconds for each chunk, OFFSET(max_chunk_duration), AV_OPT_TYPE_INT, {.i64 0}, 0, INT_MAX-1, E},
{chunk_size, size in bytes for each chunk, OFFSET(max_chunk_size), AV_OPT_TYPE_INT, {.i64 0}, 0, INT_MAX-1, E},
/* this is a crutch for avconv, since it cannot deal with identically named options in different contexts.* to be removed when avconv is fixed */
{f_err_detect, set error detection flags (deprecated; use err_detect, save via avconv), OFFSET(error_recognition), AV_OPT_TYPE_FLAGS, {.i64 AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, err_detect},
{err_detect, set error detection flags, OFFSET(error_recognition), AV_OPT_TYPE_FLAGS, {.i64 AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, err_detect},
{crccheck, verify embedded CRCs, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, err_detect},
{bitstream, detect bitstream specification deviations, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_BITSTREAM }, INT_MIN, INT_MAX, D, err_detect},
{buffer, detect improper bitstream length, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_BUFFER }, INT_MIN, INT_MAX, D, err_detect},
{explode, abort decoding on minor error detection, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_EXPLODE }, INT_MIN, INT_MAX, D, err_detect},
{ignore_err, ignore errors, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, D, err_detect},
{careful, consider things that violate the spec, are fast to check and have not been seen in the wild as errors, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_CAREFUL }, INT_MIN, INT_MAX, D, err_detect},
{compliant, consider all spec non compliancies as errors, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_COMPLIANT | AV_EF_CAREFUL }, INT_MIN, INT_MAX, D, err_detect},
{aggressive, consider things that a sane encoder shouldnt do as an error, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_AGGRESSIVE | AV_EF_COMPLIANT | AV_EF_CAREFUL}, INT_MIN, INT_MAX, D, err_detect},
{use_wallclock_as_timestamps, use wallclock as timestamps, OFFSET(use_wallclock_as_timestamps), AV_OPT_TYPE_BOOL, {.i64 0}, 0, 1, D},
{skip_initial_bytes, set number of bytes to skip before reading header and frames, OFFSET(skip_initial_bytes), AV_OPT_TYPE_INT64, {.i64 0}, 0, INT64_MAX-1, D},
{correct_ts_overflow, correct single timestamp overflows, OFFSET(correct_ts_overflow), AV_OPT_TYPE_BOOL, {.i64 1}, 0, 1, D},
{flush_packets, enable flushing of the I/O context after each packet, OFFSET(flush_packets), AV_OPT_TYPE_INT, {.i64 -1}, -1, 1, E},
{metadata_header_padding, set number of bytes to be written as padding in a metadata header, OFFSET(metadata_header_padding), AV_OPT_TYPE_INT, {.i64 -1}, -1, INT_MAX, E},
{output_ts_offset, set output timestamp offset, OFFSET(output_ts_offset), AV_OPT_TYPE_DURATION, {.i64 0}, -INT64_MAX, INT64_MAX, E},
{max_interleave_delta, maximum buffering duration for interleaving, OFFSET(max_interleave_delta), AV_OPT_TYPE_INT64, { .i64 10000000 }, 0, INT64_MAX, E },
{f_strict, how strictly to follow the standards (deprecated; use strict, save via avconv), OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, D|E, strict},
{strict, how strictly to follow the standards, OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, D|E, strict},
{very, strictly conform to a older more strict version of the spec or reference software, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, D|E, strict},
{strict, strictly conform to all the things in the spec no matter what the consequences, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, D|E, strict},
{normal, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, D|E, strict},
{unofficial, allow unofficial extensions, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, D|E, strict},
{experimental, allow non-standardized experimental variants, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, D|E, strict},
{max_ts_probe, maximum number of packets to read while waiting for the first timestamp, OFFSET(max_ts_probe), AV_OPT_TYPE_INT, { .i64 50 }, 0, INT_MAX, D },
{avoid_negative_ts, shift timestamps so they start at 0, OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 -1}, -1, 2, E, avoid_negative_ts},
{auto, enabled when required by target format, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_AVOID_NEG_TS_AUTO }, INT_MIN, INT_MAX, E, avoid_negative_ts},
{disabled, do not change timestamps, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_AVOID_NEG_TS_DISABLED }, INT_MIN, INT_MAX, E, avoid_negative_ts},
{make_non_negative, shift timestamps so they are non negative, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE }, INT_MIN, INT_MAX, E, avoid_negative_ts},
{make_zero, shift timestamps so they start at 0, 0, AV_OPT_TYPE_CONST, {.i64 AVFMT_AVOID_NEG_TS_MAKE_ZERO }, INT_MIN, INT_MAX, E, avoid_negative_ts},
{dump_separator, set information dump field separator, OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str , }, 0, 0, D|E},
{codec_whitelist, List of decoders that are allowed to be used, OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str NULL }, 0, 0, D },
{format_whitelist, List of demuxers that are allowed to be used, OFFSET(format_whitelist), AV_OPT_TYPE_STRING, { .str NULL }, 0, 0, D },
{protocol_whitelist, List of protocols that are allowed to be used, OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str NULL }, 0, 0, D },
{protocol_blacklist, List of protocols that are not allowed to be used, OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str NULL }, 0, 0, D },
{max_streams, maximum number of streams, OFFSET(max_streams), AV_OPT_TYPE_INT, { .i64 1000 }, 0, INT_MAX, D },
{skip_estimate_duration_from_pts, skip duration calculation in estimate_timings_from_pts, OFFSET(skip_estimate_duration_from_pts), AV_OPT_TYPE_BOOL, {.i64 0}, 0, 1, D},
{max_probe_packets, Maximum number of packets to probe a codec, OFFSET(max_probe_packets), AV_OPT_TYPE_INT, { .i64 2500 }, 0, INT_MAX, D },
{NULL},
};#undef E
#undef D
#undef DEFAULT
#undef OFFSET#endif /* AVFORMAT_OPTIONS_TABLE_H */AVCodecContext中的AVClass
AVFormatContext 中的AVClass定义位于libavcodec\options.c中是一个名称为av_codec_context_class的静态结构体。如下所示。
static const AVClass av_codec_context_class {.class_name AVCodecContext,.item_name context_to_name,.option avcodec_options,.version LIBAVUTIL_VERSION_INT,.log_level_offset_offset offsetof(AVCodecContext, log_level_offset),.child_next codec_child_next,.child_class_iterate codec_child_class_iterate,.category AV_CLASS_CATEGORY_ENCODER,.get_category get_category,
};
从源代码可以看出1class_name 该AVClass名称是“AVCodecContext”。2item_name item_name指向一个函数context_to_name ()该函数定义如下所示。
static const char* context_to_name(void* ptr) {AVCodecContext *avc ptr;if (avc avc-codec)return avc-codec-name;elsereturn NULL;
} 从函数的定义可以看出如果AVCodecContext中的Codec结构体不为空则返回Codec的name否则返回“NULL”。3categoryoption字段则指向一个元素个数极多的静态数组avcodec_options。该数组单独定义于libavcodec\options_table.h中。其中包含了AVCodecContext支持的所有的AVOption。由于该数组定义实在是太多了在这里仅贴出它前面的一小部分。
/** Copyright (c) 2001 Fabrice Bellard* Copyright (c) 2002-2004 Michael Niedermayer michaelnigmx.at** This file is part of FFmpeg.** FFmpeg is free software; you can redistribute it and/or* modify it under the terms of the GNU Lesser General Public* License as published by the Free Software Foundation; either* version 2.1 of the License, or (at your option) any later version.** FFmpeg is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with FFmpeg; if not, write to the Free Software* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/#ifndef AVCODEC_OPTIONS_TABLE_H
#define AVCODEC_OPTIONS_TABLE_H#include config_components.h#include float.h
#include limits.h
#include stdint.h#include libavutil/opt.h
#include avcodec.h
#include version_major.h#define OFFSET(x) offsetof(AVCodecContext,x)
#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
//these names are too long to be readable
#define V AV_OPT_FLAG_VIDEO_PARAM
#define A AV_OPT_FLAG_AUDIO_PARAM
#define S AV_OPT_FLAG_SUBTITLE_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
#define D AV_OPT_FLAG_DECODING_PARAM
#define CC AV_OPT_FLAG_CHILD_CONSTS#define AV_CODEC_DEFAULT_BITRATE 200*1000static const AVOption avcodec_options[] {
{b, set bitrate (in bits/s), OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E},
{ab, set bitrate (in bits/s), OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 128*1000 }, 0, INT_MAX, A|E},
{bt, Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far ratecontrol is willing to deviate from the target average bitrate value. This is not related to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.,OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
{flags, NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 DEFAULT }, 0, UINT_MAX, V|A|S|E|D, flags},
{unaligned, allow decoders to produce unaligned output, 0, AV_OPT_TYPE_CONST, { .i64 AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, flags },
{mv4, use four motion vectors per macroblock (MPEG-4), 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, flags},
{qpel, use 1/4-pel motion compensation, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, flags},
{loop, use loop filter, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, flags},
{qscale, use fixed qscale, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, flags},
{pass1, use internal 2-pass ratecontrol in first pass mode, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, flags},
{pass2, use internal 2-pass ratecontrol in second pass mode, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, flags},
{gray, only decode/encode grayscale, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, flags},
{psnr, error[?] variables will be set during encoding, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, flags},
#if FF_API_FLAG_TRUNCATED
{truncated, (Deprecated, use parsers instead.) Input bitstream might be randomly truncated, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, V|D | AV_OPT_FLAG_DEPRECATED, flags},
#endif
{ildct, use interlaced DCT, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, flags},
{low_delay, force low delay, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, flags},
{global_header, place global headers in extradata instead of every keyframe, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, flags},
{bitexact, use only bitexact functions (except (I)DCT), 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, flags},
{aic, H.263 advanced intra coding / MPEG-4 AC prediction, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, flags},
{ilme, interlaced motion estimation, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, flags},
{cgop, closed GOP, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, flags},
{output_corrupt, Output even potentially corrupted frames, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, flags},
{drop_changed, Drop frames whose parameters differ from first decoded frame, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG_DROPCHANGED }, INT_MIN, INT_MAX, A|V|D, flags},
{flags2, NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 DEFAULT}, 0, UINT_MAX, V|A|E|D|S, flags2},
{fast, allow non-spec-compliant speedup tricks, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, flags2},
{noout, skip bitstream encoding, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, flags2},
{ignorecrop, ignore cropping information from sps, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, flags2},
{local_header, place global headers at every keyframe instead of in extradata, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, flags2},
{chunks, Frame data might be split into multiple chunks, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, flags2},
{showall, Show all frames before the first keyframe, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, flags2},
{export_mvs, export motion vectors through frame side data, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, flags2},
{skip_manual, do not skip samples and export skip information as frame side data, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, A|D, flags2},
{ass_ro_flush_noop, do not reset ASS ReadOrder field on flush, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_FLAG2_RO_FLUSH_NOOP}, INT_MIN, INT_MAX, S|D, flags2},
{export_side_data, Export metadata as side data, OFFSET(export_side_data), AV_OPT_TYPE_FLAGS, {.i64 DEFAULT}, 0, UINT_MAX, A|V|S|D|E, export_side_data},
{mvs, export motion vectors through frame side data, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_EXPORT_DATA_MVS}, INT_MIN, INT_MAX, V|D, export_side_data},
{prft, export Producer Reference Time through packet side data, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_EXPORT_DATA_PRFT}, INT_MIN, INT_MAX, A|V|S|E, export_side_data},
{venc_params, export video encoding parameters through frame side data, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS}, INT_MIN, INT_MAX, V|D, export_side_data},
{film_grain, export film grain parameters through frame side data, 0, AV_OPT_TYPE_CONST, {.i64 AV_CODEC_EXPORT_DATA_FILM_GRAIN}, INT_MIN, INT_MAX, V|D, export_side_data},
{time_base, NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl 0}, 0, INT_MAX},
{g, set the group of picture (GOP) size, OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 12 }, INT_MIN, INT_MAX, V|E},
{ar, set audio sampling rate (in Hz), OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX, A|D|E},
#if FF_API_OLD_CHANNEL_LAYOUT
{ac, set number of audio channels, OFFSET(channels), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX, A|D|E},
#endif
{cutoff, set cutoff bandwidth, OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, A|E},
{frame_size, NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX, A|E},
{frame_number, NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX},
{delay, NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX},
{qcomp, video quantizer scale compression (VBR). Constant of ratecontrol equation. Recommended range for default rc_eq: 0.0-1.0,OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl 0.5 }, -FLT_MAX, FLT_MAX, V|E},
{qblur, video quantizer scale blur (VBR), OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl 0.5 }, -1, FLT_MAX, V|E},
{qmin, minimum video quantizer scale (VBR), OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 2 }, -1, 69, V|E},
{qmax, maximum video quantizer scale (VBR), OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 31 }, -1, 1024, V|E},
{qdiff, maximum difference between the quantizer scales (VBR), OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 3 }, INT_MIN, INT_MAX, V|E},
{bf, set maximum number of B-frames between non-B-frames, OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 DEFAULT }, -1, INT_MAX, V|E},
{b_qfactor, QP factor between P- and B-frames, OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl 1.25 }, -FLT_MAX, FLT_MAX, V|E},
{codec_tag, NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX},
{bug, work around not autodetected encoder bugs, OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, bug},
{autodetect, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, bug},
{xvid_ilace, Xvid interlacing bug (autodetected if FOURCC XVIX), 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, bug},
{ump4, (autodetected if FOURCC UMP4), 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, bug},
{no_padding, padding bug (autodetected), 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, bug},
{amv, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, bug},
{qpel_chroma, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, bug},
{std_qpel, old standard qpel (autodetected per FOURCC/version), 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, bug},
{qpel_chroma2, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, bug},
{direct_blocksize, direct-qpel-blocksize bug (autodetected per FOURCC/version), 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, bug},
{edge, edge padding bug (autodetected per FOURCC/version), 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, bug},
{hpel_chroma, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, bug},
{dc_clip, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, bug},
{ms, work around various bugs in Microsofts broken decoders, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_MS }, INT_MIN, INT_MAX, V|D, bug},
{trunc, truncated frames, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, bug},
{iedge, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_BUG_IEDGE }, INT_MIN, INT_MAX, V|D, bug},
{strict, how strictly to follow the standards, OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, strict},
{very, strictly conform to a older more strict version of the spec or reference software, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, A|V|D|E, strict},
{strict, strictly conform to all the things in the spec no matter what the consequences, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, A|V|D|E, strict},
{normal, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, A|V|D|E, strict},
{unofficial, allow unofficial extensions, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, strict},
{experimental, allow non-standardized experimental things, 0, AV_OPT_TYPE_CONST, {.i64 FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|V|D|E, strict},
{b_qoffset, QP offset between P- and B-frames, OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl 1.25 }, -FLT_MAX, FLT_MAX, V|E},
{err_detect, set error detection flags, OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 0 }, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{crccheck, verify embedded CRCs, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{bitstream, detect bitstream specification deviations, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{buffer, detect improper bitstream length, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{explode, abort decoding on minor error detection, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{ignore_err, ignore errors, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{careful, consider things that violate the spec, are fast to check and have not been seen in the wild as errors, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{compliant, consider all spec non compliancies as errors, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_COMPLIANT | AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{aggressive, consider things that a sane encoder should not do as an error, 0, AV_OPT_TYPE_CONST, {.i64 AV_EF_AGGRESSIVE | AV_EF_COMPLIANT | AV_EF_CAREFUL}, INT_MIN, INT_MAX, A|V|S|D|E, err_detect},
{has_b_frames, NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX},
{block_align, NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX},
{rc_override_count, NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX},
{maxrate, maximum bitrate (in bits/s). Used for VBV together with bufsize., OFFSET(rc_max_rate), AV_OPT_TYPE_INT64, {.i64 DEFAULT }, 0, INT_MAX, V|A|E},
{minrate, minimum bitrate (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.,OFFSET(rc_min_rate), AV_OPT_TYPE_INT64, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|A|E},
{bufsize, set ratecontrol buffer size (in bits), OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, A|V|E},
{i_qfactor, QP factor between P- and I-frames, OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl -0.8 }, -FLT_MAX, FLT_MAX, V|E},
{i_qoffset, QP offset between P- and I-frames, OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl 0.0 }, -FLT_MAX, FLT_MAX, V|E},
{dct, DCT algorithm, OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX, V|E, dct},
{auto, autoselect a good one, 0, AV_OPT_TYPE_CONST, {.i64 FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, dct},
{fastint, fast integer, 0, AV_OPT_TYPE_CONST, {.i64 FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, dct},
{int, accurate integer, 0, AV_OPT_TYPE_CONST, {.i64 FF_DCT_INT }, INT_MIN, INT_MAX, V|E, dct},
{mmx, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, dct},
{altivec, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, dct},
{faan, floating point AAN DCT, 0, AV_OPT_TYPE_CONST, {.i64 FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, dct},
{lumi_mask, compresses bright areas stronger than medium ones, OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl 0 }, -FLT_MAX, FLT_MAX, V|E},
{tcplx_mask, temporal complexity masking, OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl 0 }, -FLT_MAX, FLT_MAX, V|E},
{scplx_mask, spatial complexity masking, OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl 0 }, -FLT_MAX, FLT_MAX, V|E},
{p_mask, inter masking, OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl 0 }, -FLT_MAX, FLT_MAX, V|E},
{dark_mask, compresses dark areas stronger than medium ones, OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl 0 }, -FLT_MAX, FLT_MAX, V|E},
{idct, select IDCT implementation, OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX, V|E|D, idct},
{auto, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, idct},
{int, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, idct},
{simple, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, idct},
{simplemmx, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, idct},
{arm, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, idct},
{altivec, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, idct},
{simplearm, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, idct},
{simplearmv5te, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, idct},
{simplearmv6, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, idct},
{simpleneon, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, idct},
{xvid, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, idct},
{xvidmmx, deprecated, for compatibility only, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, idct},
{faani, floating point AAN IDCT, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, idct},
{simpleauto, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, idct},
{slice_count, NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX},
{ec, set error concealment strategy, OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 3 }, INT_MIN, INT_MAX, V|D, ec},
{guess_mvs, iterative motion vector (MV) search (slow), 0, AV_OPT_TYPE_CONST, {.i64 FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, ec},
{deblock, use strong deblock filter for damaged MBs, 0, AV_OPT_TYPE_CONST, {.i64 FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, ec},
{favor_inter, favor predicting from the previous frame, 0, AV_OPT_TYPE_CONST, {.i64 FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, ec},
{bits_per_coded_sample, NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX},
{aspect, sample aspect ratio, OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl 0}, 0, 10, V|E},
{sar, sample aspect ratio, OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl 0}, 0, 10, V|E},
{debug, print specific debug info, OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 DEFAULT }, 0, INT_MAX, V|A|S|E|D, debug},
{pict, picture info, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, debug},
{rc, rate control, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, debug},
{bitstream, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, debug},
{mb_type, macroblock (MB) type, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, debug},
{qp, per-block quantization parameter (QP), 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, debug},
{dct_coeff, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, debug},
{green_metadata, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, debug},
{skip, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, debug},
{startcode, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, debug},
{er, error recognition, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, debug},
{mmco, memory management control operations (H.264), 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, debug},
{bugs, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, debug},
{buffers, picture buffer allocations, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, debug},
{thread_ops, threading operations, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, debug},
{nomc, skip motion compensation, 0, AV_OPT_TYPE_CONST, {.i64 FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, debug},
{dia_size, diamond type size for motion estimation, OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E},
{last_pred, amount of motion predictors from the previous frame, OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E},
{pre_dia_size, diamond type size for motion estimation pre-pass, OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E},
{subq, sub-pel motion estimation quality, OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 8 }, INT_MIN, INT_MAX, V|E},
{me_range, limit motion vectors range (1023 for DivX player), OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E},
{global_quality, NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|A|E},
{slice_flags, NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX},
{mbd, macroblock decision algorithm (high quality mode), OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, 2, V|E, mbd},
{simple, use mbcmp, 0, AV_OPT_TYPE_CONST, {.i64 FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, mbd},
{bits, use fewest bits, 0, AV_OPT_TYPE_CONST, {.i64 FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, mbd},
{rd, use best rate distortion, 0, AV_OPT_TYPE_CONST, {.i64 FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, mbd},
{rc_init_occupancy, number of bits which should be loaded into the rc buffer before decoding starts, OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E},
{threads, set the number of threads, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 1 }, 0, INT_MAX, V|A|E|D, threads},
{auto, autodetect a suitable number of threads to use, 0, AV_OPT_TYPE_CONST, {.i64 0 }, INT_MIN, INT_MAX, V|E|D, threads},
{dc, intra_dc_precision, OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 0 }, -8, 16, V|E},
{nssew, nsse weight, OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 8 }, INT_MIN, INT_MAX, V|E},
{skip_top, number of macroblock rows at the top which are skipped, OFFSET(skip_top), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|D},
{skip_bottom, number of macroblock rows at the bottom which are skipped, OFFSET(skip_bottom), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|D},
{profile, NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, avctx.profile},
{unknown, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, avctx.profile},
{main10, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, V|E, avctx.profile},
{level, NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, avctx.level},
{unknown, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, avctx.level},
{lowres, decode at 1 1/2, 21/4, 31/8 resolutions, OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 0 }, 0, INT_MAX, V|A|D},
{cmp, full-pel ME compare function, OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E, cmp_func},
{subcmp, sub-pel ME compare function, OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E, cmp_func},
{mbcmp, macroblock compare function, OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E, cmp_func},
{ildctcmp, interlaced DCT compare function, OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, cmp_func},
{precmp, pre motion estimation compare function, OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|E, cmp_func},
{sad, sum of absolute differences, fast, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, cmp_func},
{sse, sum of squared errors, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, cmp_func},
{satd, sum of absolute Hadamard transformed differences, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, cmp_func},
{dct, sum of absolute DCT transformed differences, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, cmp_func},
{psnr, sum of squared quantization errors (avoid, low quality), 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, cmp_func},
{bit, number of bits needed for the block, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, cmp_func},
{rd, rate distortion optimal, slow, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_RD }, INT_MIN, INT_MAX, V|E, cmp_func},
{zero, 0, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, cmp_func},
{vsad, sum of absolute vertical differences, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, cmp_func},
{vsse, sum of squared vertical differences, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, cmp_func},
{nsse, noise preserving sum of squared differences, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, cmp_func},
#if CONFIG_SNOW_ENCODER
{w53, 5/3 wavelet, only used in snow, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, cmp_func},
{w97, 9/7 wavelet, only used in snow, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, cmp_func},
#endif
{dctmax, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, cmp_func},
{chroma, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, cmp_func},
{msad, sum of absolute differences, median predicted, 0, AV_OPT_TYPE_CONST, {.i64 FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, V|E, cmp_func},
{mblmin, minimum macroblock Lagrange factor (VBR), OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
{mblmax, maximum macroblock Lagrange factor (VBR), OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
{skip_loop_filter, skip loop filtering process for the selected frames, OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, avdiscard},
{skip_idct , skip IDCT/dequantization for the selected frames, OFFSET(skip_idct), AV_OPT_TYPE_INT, {.i64 AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, avdiscard},
{skip_frame , skip decoding for the selected frames, OFFSET(skip_frame), AV_OPT_TYPE_INT, {.i64 AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, avdiscard},
{none , discard no frame, 0, AV_OPT_TYPE_CONST, {.i64 AVDISCARD_NONE }, INT_MIN, INT_MAX, V|D, avdiscard},
{default , discard useless frames, 0, AV_OPT_TYPE_CONST, {.i64 AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, avdiscard},
{noref , discard all non-reference frames, 0, AV_OPT_TYPE_CONST, {.i64 AVDISCARD_NONREF }, INT_MIN, INT_MAX, V|D, avdiscard},
{bidir , discard all bidirectional frames, 0, AV_OPT_TYPE_CONST, {.i64 AVDISCARD_BIDIR }, INT_MIN, INT_MAX, V|D, avdiscard},
{nokey , discard all frames except keyframes, 0, AV_OPT_TYPE_CONST, {.i64 AVDISCARD_NONKEY }, INT_MIN, INT_MAX, V|D, avdiscard},
{nointra , discard all frames except I frames, 0, AV_OPT_TYPE_CONST, {.i64 AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, avdiscard},
{all , discard all frames, 0, AV_OPT_TYPE_CONST, {.i64 AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, avdiscard},
{bidir_refine, refine the two motion vectors used in bidirectional macroblocks, OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 1 }, 0, 4, V|E},
{keyint_min, minimum interval between IDR-frames, OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 25 }, INT_MIN, INT_MAX, V|E},
{refs, reference frames to consider for motion compensation, OFFSET(refs), AV_OPT_TYPE_INT, {.i64 1 }, INT_MIN, INT_MAX, V|E},
{trellis, rate-distortion optimal quantization, OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 DEFAULT }, INT_MIN, INT_MAX, V|A|E},
{mv0_threshold, NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 256 }, 0, INT_MAX, V|E},
{compression_level, NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
{bits_per_raw_sample, NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 DEFAULT }, 0, INT_MAX},
{ch_layout, NULL, OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str NULL }, 0, 0, A|E|D, ch_layout},
#if FF_API_OLD_CHANNEL_LAYOUT
{channel_layout, NULL, OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 DEFAULT }, 0, UINT64_MAX, A|E|D, channel_layout},
{request_channel_layout, NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 DEFAULT }, 0, UINT64_MAX, A|D, request_channel_layout},
#endif
{rc_max_vbv_use, NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl 0 }, 0.0, FLT_MAX, V|E},
{rc_min_vbv_use, NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl 3 }, 0.0, FLT_MAX, V|E},
{ticks_per_frame, NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 1 }, 1, INT_MAX, A|V|E|D},
{color_primaries, color primaries, OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 AVCOL_PRI_UNSPECIFIED }, 1, INT_MAX, V|E|D, color_primaries_type},
{bt709, BT.709, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_BT709 }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{unknown, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{bt470m, BT.470 M, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_BT470M }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{bt470bg, BT.470 BG, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_BT470BG }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{smpte170m, SMPTE 170 M, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{smpte240m, SMPTE 240 M, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{film, Film, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_FILM }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{bt2020, BT.2020, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_BT2020 }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{smpte428, SMPTE 428-1, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{smpte428_1, SMPTE 428-1, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{smpte431, SMPTE 431-2, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_SMPTE431 }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{smpte432, SMPTE 422-1, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_SMPTE432 }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{jedec-p22, JEDEC P22, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_JEDEC_P22 }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{ebu3213, EBU 3213-E, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_EBU3213 }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{unspecified, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, color_primaries_type},
{color_trc, color transfer characteristics, OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 AVCOL_TRC_UNSPECIFIED }, 1, INT_MAX, V|E|D, color_trc_type},
{bt709, BT.709, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{unknown, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{gamma22, BT.470 M, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{gamma28, BT.470 BG, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{smpte170m, SMPTE 170 M, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{smpte240m, SMPTE 240 M, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{linear, Linear, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_LINEAR }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{log100, Log, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{log316, Log square root, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{iec61966-2-4, IEC 61966-2-4, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{bt1361e, BT.1361, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{iec61966-2-1, IEC 61966-2-1, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{bt2020-10, BT.2020 - 10 bit, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{bt2020-12, BT.2020 - 12 bit, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{smpte2084, SMPTE 2084, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_SMPTE2084 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{smpte428, SMPTE 428-1, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{arib-std-b67, ARIB STD-B67, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_ARIB_STD_B67 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{unspecified, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{log, Log, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{log_sqrt, Log square root, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{iec61966_2_4, IEC 61966-2-4, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{bt1361, BT.1361, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{iec61966_2_1, IEC 61966-2-1, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{bt2020_10bit, BT.2020 - 10 bit, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{bt2020_12bit, BT.2020 - 12 bit, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{smpte428_1, SMPTE 428-1, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, color_trc_type},
{colorspace, color space, OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, V|E|D, colorspace_type},
{rgb, RGB, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{bt709, BT.709, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{unknown, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{fcc, FCC, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{bt470bg, BT.470 BG, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{smpte170m, SMPTE 170 M, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{smpte240m, SMPTE 240 M, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{ycgco, YCGCO, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{bt2020nc, BT.2020 NCL, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{bt2020c, BT.2020 CL, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{smpte2085, SMPTE 2085, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_SMPTE2085 }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{chroma-derived-nc, Chroma-derived NCL, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_CHROMA_DERIVED_NCL }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{chroma-derived-c, Chroma-derived CL, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_CHROMA_DERIVED_CL }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{ictcp, ICtCp, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_ICTCP }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{unspecified, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{ycocg, YCGCO, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{bt2020_ncl, BT.2020 NCL, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{bt2020_cl, BT.2020 CL, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, colorspace_type},
{color_range, color range, OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, color_range_type},
{unknown, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, color_range_type},
{tv, MPEG (219*2^(n-8)), 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, color_range_type},
{pc, JPEG (2^n-1), 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, color_range_type},
{unspecified, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, color_range_type},
{mpeg, MPEG (219*2^(n-8)), 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, color_range_type},
{jpeg, JPEG (2^n-1), 0, AV_OPT_TYPE_CONST, {.i64 AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, color_range_type},
{chroma_sample_location, chroma sample location, OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX, V|E|D, chroma_sample_location_type},
{unknown, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, chroma_sample_location_type},
{left, Left, 0, AV_OPT_TYPE_CONST, {.i64 AVCHROMA_LOC_LEFT }, INT_MIN, INT_MAX, V|E|D, chroma_sample_location_type},
{center, Center, 0, AV_OPT_TYPE_CONST, {.i64 AVCHROMA_LOC_CENTER }, INT_MIN, INT_MAX, V|E|D, chroma_sample_location_type},
{topleft, Top-left, 0, AV_OPT_TYPE_CONST, {.i64 AVCHROMA_LOC_TOPLEFT }, INT_MIN, INT_MAX, V|E|D, chroma_sample_location_type},
{top, Top, 0, AV_OPT_TYPE_CONST, {.i64 AVCHROMA_LOC_TOP }, INT_MIN, INT_MAX, V|E|D, chroma_sample_location_type},
{bottomleft, Bottom-left, 0, AV_OPT_TYPE_CONST, {.i64 AVCHROMA_LOC_BOTTOMLEFT }, INT_MIN, INT_MAX, V|E|D, chroma_sample_location_type},
{bottom, Bottom, 0, AV_OPT_TYPE_CONST, {.i64 AVCHROMA_LOC_BOTTOM }, INT_MIN, INT_MAX, V|E|D, chroma_sample_location_type},
{unspecified, Unspecified, 0, AV_OPT_TYPE_CONST, {.i64 AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, chroma_sample_location_type},
{log_level_offset, set the log level offset, OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 0 }, INT_MIN, INT_MAX },
{slices, set the number of slices, used in parallelized encoding, OFFSET(slices), AV_OPT_TYPE_INT, {.i64 0 }, 0, INT_MAX, V|E},
{thread_type, select multithreading type, OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, thread_type},
{slice, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, thread_type},
{frame, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, thread_type},
{audio_service_type, audio service type, OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, audio_service_type},
{ma, Main Audio Service, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, audio_service_type},
{ef, Effects, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, audio_service_type},
{vi, Visually Impaired, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, audio_service_type},
{hi, Hearing Impaired, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, INT_MIN, INT_MAX, A|E, audio_service_type},
{di, Dialogue, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_DIALOGUE }, INT_MIN, INT_MAX, A|E, audio_service_type},
{co, Commentary, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_COMMENTARY }, INT_MIN, INT_MAX, A|E, audio_service_type},
{em, Emergency, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, audio_service_type},
{vo, Voice Over, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, audio_service_type},
{ka, Karaoke, 0, AV_OPT_TYPE_CONST, {.i64 AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, audio_service_type},
{request_sample_fmt, sample format audio decoders should prefer, OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, request_sample_fmt},
{pkt_timebase, NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl 0 }, 0, INT_MAX, 0},
{sub_charenc, set input text subtitles character encoding, OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str NULL}, 0, 0, S|D},
{sub_charenc_mode, set input text subtitles character encoding mode, OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, sub_charenc_mode},
{do_nothing, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_SUB_CHARENC_MODE_DO_NOTHING}, INT_MIN, INT_MAX, S|D, sub_charenc_mode},
{auto, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, sub_charenc_mode},
{pre_decoder, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, sub_charenc_mode},
{ignore, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_SUB_CHARENC_MODE_IGNORE}, INT_MIN, INT_MAX, S|D, sub_charenc_mode},
#if FF_API_SUB_TEXT_FORMAT
{sub_text_format, Deprecated, does nothing, OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 FF_SUB_TEXT_FMT_ASS}, 0, 1, S|D | AV_OPT_FLAG_DEPRECATED, sub_text_format},
{ass, NULL, 0, AV_OPT_TYPE_CONST, {.i64 FF_SUB_TEXT_FMT_ASS}, INT_MIN, INT_MAX, S|D, sub_text_format},
#endif
{apply_cropping, NULL, OFFSET(apply_cropping), AV_OPT_TYPE_BOOL, { .i64 1 }, 0, 1, V | D },
{skip_alpha, Skip processing alpha, OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 0 }, 0, 1, V|D },
{field_order, Field order, OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 AV_FIELD_UNKNOWN }, 0, 5, V|D|E, field_order },
{progressive, NULL, 0, AV_OPT_TYPE_CONST, {.i64 AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, field_order },
{tt, NULL, 0, AV_OPT_TYPE_CONST, {.i64 AV_FIELD_TT }, 0, 0, V|D|E, field_order },
{bb, NULL, 0, AV_OPT_TYPE_CONST, {.i64 AV_FIELD_BB }, 0, 0, V|D|E, field_order },
{tb, NULL, 0, AV_OPT_TYPE_CONST, {.i64 AV_FIELD_TB }, 0, 0, V|D|E, field_order },
{bt, NULL, 0, AV_OPT_TYPE_CONST, {.i64 AV_FIELD_BT }, 0, 0, V|D|E, field_order },
{dump_separator, set information dump field separator, OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str NULL}, 0, 0, A|V|S|D|E},
{codec_whitelist, List of decoders that are allowed to be used, OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str NULL }, 0, 0, A|V|S|D },
{pixel_format, set pixel format, OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64AV_PIX_FMT_NONE}, -1, INT_MAX, 0 },
{video_size, set video size, OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.strNULL}, 0, INT_MAX, 0 },
{max_pixels, Maximum number of pixels, OFFSET(max_pixels), AV_OPT_TYPE_INT64, {.i64 INT_MAX }, 0, INT_MAX, A|V|S|D|E },
{max_samples, Maximum number of samples, OFFSET(max_samples), AV_OPT_TYPE_INT64, {.i64 INT_MAX }, 0, INT_MAX, A|D|E },
{hwaccel_flags, NULL, OFFSET(hwaccel_flags), AV_OPT_TYPE_FLAGS, {.i64 AV_HWACCEL_FLAG_IGNORE_LEVEL }, 0, UINT_MAX, V|D, hwaccel_flags},
{ignore_level, ignore level even if the codec level used is unknown or higher than the maximum supported level reported by the hardware driver, 0, AV_OPT_TYPE_CONST, { .i64 AV_HWACCEL_FLAG_IGNORE_LEVEL }, INT_MIN, INT_MAX, V | D, hwaccel_flags },
{allow_high_depth, allow to output YUV pixel formats with a different chroma sampling than 4:2:0 and/or other than 8 bits per component, 0, AV_OPT_TYPE_CONST, {.i64 AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, INT_MAX, V | D, hwaccel_flags},
{allow_profile_mismatch, attempt to decode anyway if HW accelerated decoders supported profiles do not exactly match the stream, 0, AV_OPT_TYPE_CONST, {.i64 AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, INT_MAX, V | D, hwaccel_flags},
{extra_hw_frames, Number of extra hardware frames to allocate for the user, OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, V|D },
{discard_damaged_percentage, Percentage of damaged samples to discard a frame, OFFSET(discard_damaged_percentage), AV_OPT_TYPE_INT, {.i64 95 }, 0, 100, V|D },
{NULL},
};#undef A
#undef V
#undef S
#undef E
#undef D
#undef CC
#undef DEFAULT
#undef OFFSET#endif /* AVCODEC_OPTIONS_TABLE_H */AVFrame中的AVClass
AVFrame 中的AVClass定义位于libavcodec\options.c中是一个名称为av_frame_class的静态结构体。如下所示。
static const AVClass av_frame_class {.class_name AVFrame,.item_name NULL,.option frame_options,.version LIBAVUTIL_VERSION_INT,
};option字段则指向一个元素个数极多的静态数组frame_options。frame_options定义如下所示。
static const AVOption frame_options[]{
{best_effort_timestamp, , FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0},
{pkt_pos, , FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 -1 }, INT64_MIN, INT64_MAX, 0},
{pkt_size, , FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 -1 }, INT64_MIN, INT64_MAX, 0},
{sample_aspect_ratio, , FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl 0 }, 0, INT_MAX, 0},
{width, , FOFFSET(width), AV_OPT_TYPE_INT, {.i64 0 }, 0, INT_MAX, 0},
{height, , FOFFSET(height), AV_OPT_TYPE_INT, {.i64 0 }, 0, INT_MAX, 0},
{format, , FOFFSET(format), AV_OPT_TYPE_INT, {.i64 -1 }, 0, INT_MAX, 0},
#if FF_API_OLD_CHANNEL_LAYOUT
{channel_layout, , FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 0 }, 0, INT64_MAX, 0},
#endif
{sample_rate, , FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 0 }, 0, INT_MAX, 0},
{NULL},
}; 可以看出AVFrame的选项数组中包含了“width”“height”这类用于视频帧的选项以及“channel_layout”“sample_rate”这类用于音频帧的选项。
各种组件特有的AVClass
除了FFmpeg中通用的AVFormatContextAVCodecContextAVFrame这类的结构体之外每种特定的组件也包含自己的AVClass。各种组件libRTMPlibx264libx265里面特有的AVClass。下面举例几个。
LibRTMP
libRTMP中根据协议类型的不同定义了多种的AVClass。由于这些AVClass除了名字不一样之外其他的字段一模一样所以AVClass的声明写成了一个名称为RTMP_CLASS的宏。
#define RTMP_CLASS(flavor)\
static const AVClass lib ## flavor ## _class {\.class_name lib #flavor protocol,\.item_name av_default_item_name,\.option options,\.version LIBAVUTIL_VERSION_INT,\
}; 而后定义了多种AVCLass RTMP_CLASS(rtmp)RTMP_CLASS(rtmpt)RTMP_CLASS(rtmpe)RTMP_CLASS(rtmpte)RTMP_CLASS(rtmps)
RTMP_CLASS(rtmp)
const URLProtocol ff_librtmp_protocol {.name rtmp,.url_open rtmp_open,.url_read rtmp_read,.url_write rtmp_write,.url_close rtmp_close,.url_read_pause rtmp_read_pause,.url_read_seek rtmp_read_seek,.url_get_file_handle rtmp_get_file_handle,.priv_data_size sizeof(LibRTMPContext),.priv_data_class librtmp_class,.flags URL_PROTOCOL_FLAG_NETWORK,
};RTMP_CLASS(rtmpt)
const URLProtocol ff_librtmpt_protocol {.name rtmpt,.url_open rtmp_open,.url_read rtmp_read,.url_write rtmp_write,.url_close rtmp_close,.url_read_pause rtmp_read_pause,.url_read_seek rtmp_read_seek,.url_get_file_handle rtmp_get_file_handle,.priv_data_size sizeof(LibRTMPContext),.priv_data_class librtmpt_class,.flags URL_PROTOCOL_FLAG_NETWORK,
};RTMP_CLASS(rtmpe)
const URLProtocol ff_librtmpe_protocol {.name rtmpe,.url_open rtmp_open,.url_read rtmp_read,.url_write rtmp_write,.url_close rtmp_close,.url_read_pause rtmp_read_pause,.url_read_seek rtmp_read_seek,.url_get_file_handle rtmp_get_file_handle,.priv_data_size sizeof(LibRTMPContext),.priv_data_class librtmpe_class,.flags URL_PROTOCOL_FLAG_NETWORK,
};RTMP_CLASS(rtmpte)
const URLProtocol ff_librtmpte_protocol {.name rtmpte,.url_open rtmp_open,.url_read rtmp_read,.url_write rtmp_write,.url_close rtmp_close,.url_read_pause rtmp_read_pause,.url_read_seek rtmp_read_seek,.url_get_file_handle rtmp_get_file_handle,.priv_data_size sizeof(LibRTMPContext),.priv_data_class librtmpte_class,.flags URL_PROTOCOL_FLAG_NETWORK,
};RTMP_CLASS(rtmps)
const URLProtocol ff_librtmps_protocol {.name rtmps,.url_open rtmp_open,.url_read rtmp_read,.url_write rtmp_write,.url_close rtmp_close,.url_read_pause rtmp_read_pause,.url_read_seek rtmp_read_seek,.url_get_file_handle rtmp_get_file_handle,.priv_data_size sizeof(LibRTMPContext),.priv_data_class librtmps_class,.flags URL_PROTOCOL_FLAG_NETWORK,
};这些AVClass的option字段指向的数组是一样的如下所示。
#define OFFSET(x) offsetof(LibRTMPContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
#define ENC AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] {{rtmp_app, Name of application to connect to on the RTMP server, OFFSET(app), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC|ENC},{rtmp_buffer, Set buffer time in milliseconds. The default is 3000., OFFSET(client_buffer_time), AV_OPT_TYPE_STRING, {.str 3000}, 0, 0, DEC|ENC},{rtmp_conn, Append arbitrary AMF data to the Connect message, OFFSET(conn), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC|ENC},{rtmp_flashver, Version of the Flash plugin used to run the SWF player., OFFSET(flashver), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC|ENC},{rtmp_live, Specify that the media is a live stream., OFFSET(live), AV_OPT_TYPE_INT, {.i64 0}, INT_MIN, INT_MAX, DEC, rtmp_live},{any, both, 0, AV_OPT_TYPE_CONST, {.i64 -2}, 0, 0, DEC, rtmp_live},{live, live stream, 0, AV_OPT_TYPE_CONST, {.i64 -1}, 0, 0, DEC, rtmp_live},{recorded, recorded stream, 0, AV_OPT_TYPE_CONST, {.i64 0}, 0, 0, DEC, rtmp_live},{rtmp_pageurl, URL of the web page in which the media was embedded. By default no value will be sent., OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC},{rtmp_playpath, Stream identifier to play or to publish, OFFSET(playpath), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC|ENC},{rtmp_subscribe, Name of live stream to subscribe to. Defaults to rtmp_playpath., OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC},{rtmp_swfurl, URL of the SWF player. By default no value will be sent, OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC|ENC},{rtmp_swfverify, URL to player swf file, compute hash/size automatically. (unimplemented), OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC},{rtmp_tcurl, URL of the target stream. Defaults to proto://host[:port]/app., OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str NULL }, 0, 0, DEC|ENC},
#if CONFIG_NETWORK{rtmp_buffer_size, set buffer size in bytes, OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64 -1}, -1, INT_MAX, DEC|ENC },
#endif{ NULL },
};
Libx264
Libx264的AVClass定义如下所示。
#if CONFIG_LIBX264_ENCODER
static const AVClass x264_class {.class_name libx264,.item_name av_default_item_name,.option options,.version LIBAVUTIL_VERSION_INT,
};
其中option字段指向的数组定义如下所示。这些option的使用频率还是比较高的。
static const AVOption options[] {{ preset, Set the encoding preset (cf. x264 --fullhelp), OFFSET(preset), AV_OPT_TYPE_STRING, { .str medium }, 0, 0, VE},{ tune, Tune the encoding params (cf. x264 --fullhelp), OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},{ profile, Set profile restrictions (cf. x264 --fullhelp) , OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},{ fastfirstpass, Use fast settings when encoding first pass, OFFSET(fastfirstpass), AV_OPT_TYPE_BOOL, { .i64 1 }, 0, 1, VE},{level, Specify level (as defined by Annex A), OFFSET(level), AV_OPT_TYPE_STRING, {.strNULL}, 0, 0, VE},{passlogfile, Filename for 2 pass stats, OFFSET(stats), AV_OPT_TYPE_STRING, {.strNULL}, 0, 0, VE},{wpredp, Weighted prediction for P-frames, OFFSET(wpredp), AV_OPT_TYPE_STRING, {.strNULL}, 0, 0, VE},{a53cc, Use A53 Closed Captions (if available), OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 1}, 0, 1, VE},{x264opts, x264 options, OFFSET(x264opts), AV_OPT_TYPE_STRING, {.strNULL}, 0, 0, VE},{ crf, Select the quality for constant quality mode, OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl -1 }, -1, FLT_MAX, VE },{ crf_max, In CRF mode, prevents VBV from lowering quality beyond this point.,OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {.dbl -1 }, -1, FLT_MAX, VE },{ qp, Constant quantization parameter rate control method,OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE },{ aq-mode, AQ method, OFFSET(aq_mode), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE, aq_mode},{ none, NULL, 0, AV_OPT_TYPE_CONST, {.i64 X264_AQ_NONE}, INT_MIN, INT_MAX, VE, aq_mode },{ variance, Variance AQ (complexity mask), 0, AV_OPT_TYPE_CONST, {.i64 X264_AQ_VARIANCE}, INT_MIN, INT_MAX, VE, aq_mode },{ autovariance, Auto-variance AQ, 0, AV_OPT_TYPE_CONST, {.i64 X264_AQ_AUTOVARIANCE}, INT_MIN, INT_MAX, VE, aq_mode },
#if X264_BUILD 144{ autovariance-biased, Auto-variance AQ with bias to dark scenes, 0, AV_OPT_TYPE_CONST, {.i64 X264_AQ_AUTOVARIANCE_BIASED}, INT_MIN, INT_MAX, VE, aq_mode },
#endif{ aq-strength, AQ strength. Reduces blocking and blurring in flat and textured areas., OFFSET(aq_strength), AV_OPT_TYPE_FLOAT, {.dbl -1}, -1, FLT_MAX, VE},{ psy, Use psychovisual optimizations., OFFSET(psy), AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE },{ psy-rd, Strength of psychovisual optimization, in psy-rd:psy-trellis format., OFFSET(psy_rd), AV_OPT_TYPE_STRING, {0 }, 0, 0, VE},{ rc-lookahead, Number of frames to look ahead for frametype and ratecontrol, OFFSET(rc_lookahead), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE },{ weightb, Weighted prediction for B-frames., OFFSET(weightb), AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE },{ weightp, Weighted prediction analysis method., OFFSET(weightp), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE, weightp },{ none, NULL, 0, AV_OPT_TYPE_CONST, {.i64 X264_WEIGHTP_NONE}, INT_MIN, INT_MAX, VE, weightp },{ simple, NULL, 0, AV_OPT_TYPE_CONST, {.i64 X264_WEIGHTP_SIMPLE}, INT_MIN, INT_MAX, VE, weightp },{ smart, NULL, 0, AV_OPT_TYPE_CONST, {.i64 X264_WEIGHTP_SMART}, INT_MIN, INT_MAX, VE, weightp },{ ssim, Calculate and print SSIM stats., OFFSET(ssim), AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE },{ intra-refresh, Use Periodic Intra Refresh instead of IDR frames.,OFFSET(intra_refresh),AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE },{ bluray-compat, Bluray compatibility workarounds., OFFSET(bluray_compat) ,AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE },{ b-bias, Influences how often B-frames are used, OFFSET(b_bias), AV_OPT_TYPE_INT, { .i64 INT_MIN}, INT_MIN, INT_MAX, VE },{ b-pyramid, Keep some B-frames as references., OFFSET(b_pyramid), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE, b_pyramid },{ none, NULL, 0, AV_OPT_TYPE_CONST, {.i64 X264_B_PYRAMID_NONE}, INT_MIN, INT_MAX, VE, b_pyramid },{ strict, Strictly hierarchical pyramid, 0, AV_OPT_TYPE_CONST, {.i64 X264_B_PYRAMID_STRICT}, INT_MIN, INT_MAX, VE, b_pyramid },{ normal, Non-strict (not Blu-ray compatible), 0, AV_OPT_TYPE_CONST, {.i64 X264_B_PYRAMID_NORMAL}, INT_MIN, INT_MAX, VE, b_pyramid },{ mixed-refs, One reference per partition, as opposed to one reference per macroblock, OFFSET(mixed_refs), AV_OPT_TYPE_BOOL, { .i64 -1}, -1, 1, VE },{ 8x8dct, High profile 8x8 transform., OFFSET(dct8x8), AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE},{ fast-pskip, NULL, OFFSET(fast_pskip), AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE},{ aud, Use access unit delimiters., OFFSET(aud), AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE},{ mbtree, Use macroblock tree ratecontrol., OFFSET(mbtree), AV_OPT_TYPE_BOOL, { .i64 -1 }, -1, 1, VE},{ deblock, Loop filter parameters, in alpha:beta form., OFFSET(deblock), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},{ cplxblur, Reduce fluctuations in QP (before curve compression), OFFSET(cplxblur), AV_OPT_TYPE_FLOAT, {.dbl -1 }, -1, FLT_MAX, VE},{ partitions, A comma-separated list of partitions to consider. Possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all, OFFSET(partitions), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},{ direct-pred, Direct MV prediction mode, OFFSET(direct_pred), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE, direct-pred },{ none, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_DIRECT_PRED_NONE }, 0, 0, VE, direct-pred },{ spatial, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_DIRECT_PRED_SPATIAL }, 0, 0, VE, direct-pred },{ temporal, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_DIRECT_PRED_TEMPORAL }, 0, 0, VE, direct-pred },{ auto, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_DIRECT_PRED_AUTO }, 0, 0, VE, direct-pred },{ slice-max-size,Limit the size of each slice in bytes, OFFSET(slice_max_size),AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE },{ stats, Filename for 2 pass stats, OFFSET(stats), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },{ nal-hrd, Signal HRD information (requires vbv-bufsize; cbr not allowed in .mp4), OFFSET(nal_hrd), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE, nal-hrd },{ none, NULL, 0, AV_OPT_TYPE_CONST, {.i64 X264_NAL_HRD_NONE}, INT_MIN, INT_MAX, VE, nal-hrd },{ vbr, NULL, 0, AV_OPT_TYPE_CONST, {.i64 X264_NAL_HRD_VBR}, INT_MIN, INT_MAX, VE, nal-hrd },{ cbr, NULL, 0, AV_OPT_TYPE_CONST, {.i64 X264_NAL_HRD_CBR}, INT_MIN, INT_MAX, VE, nal-hrd },{ avcintra-class,AVC-Intra class 50/100/200/300/480, OFFSET(avcintra_class),AV_OPT_TYPE_INT, { .i64 -1 }, -1, 480 , VE},{ me_method, Set motion estimation method, OFFSET(motion_est), AV_OPT_TYPE_INT, { .i64 -1 }, -1, X264_ME_TESA, VE, motion-est},{ motion-est, Set motion estimation method, OFFSET(motion_est), AV_OPT_TYPE_INT, { .i64 -1 }, -1, X264_ME_TESA, VE, motion-est},{ dia, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_ME_DIA }, INT_MIN, INT_MAX, VE, motion-est },{ hex, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_ME_HEX }, INT_MIN, INT_MAX, VE, motion-est },{ umh, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_ME_UMH }, INT_MIN, INT_MAX, VE, motion-est },{ esa, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_ME_ESA }, INT_MIN, INT_MAX, VE, motion-est },{ tesa, NULL, 0, AV_OPT_TYPE_CONST, { .i64 X264_ME_TESA }, INT_MIN, INT_MAX, VE, motion-est },{ forced-idr, If forcing keyframes, force them as IDR frames., OFFSET(forced_idr), AV_OPT_TYPE_BOOL, { .i64 0 }, -1, 1, VE },{ coder, Coder type, OFFSET(coder), AV_OPT_TYPE_INT, { .i64 -1 }, -1, 1, VE, coder },{ default, NULL, 0, AV_OPT_TYPE_CONST, { .i64 -1 }, INT_MIN, INT_MAX, VE, coder },{ cavlc, NULL, 0, AV_OPT_TYPE_CONST, { .i64 0 }, INT_MIN, INT_MAX, VE, coder },{ cabac, NULL, 0, AV_OPT_TYPE_CONST, { .i64 1 }, INT_MIN, INT_MAX, VE, coder },{ vlc, NULL, 0, AV_OPT_TYPE_CONST, { .i64 0 }, INT_MIN, INT_MAX, VE, coder },{ ac, NULL, 0, AV_OPT_TYPE_CONST, { .i64 1 }, INT_MIN, INT_MAX, VE, coder },{ b_strategy, Strategy to choose between I/P/B-frames, OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, { .i64 -1 }, -1, 2, VE },{ chromaoffset, QP difference between chroma and luma, OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 0 }, INT_MIN, INT_MAX, VE },{ sc_threshold, Scene change threshold, OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 -1 }, INT_MIN, INT_MAX, VE },{ noise_reduction, Noise reduction, OFFSET(noise_reduction), AV_OPT_TYPE_INT, { .i64 -1 }, INT_MIN, INT_MAX, VE },{ udu_sei, Use user data unregistered SEI if available, OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 0 }, 0, 1, VE },{ x264-params, Override the x264 configuration using a :-separated list of keyvalue parameters, OFFSET(x264_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },{ NULL },
};Libx265
Libx265的AVClass定义如下所示。
static const AVClass class {.class_name libx265,.item_name av_default_item_name,.option options,.version LIBAVUTIL_VERSION_INT,
};
其中option字段指向的数组定义如下所示。
static const AVOption options[] {{ crf, set the x265 crf, OFFSET(crf), AV_OPT_TYPE_FLOAT, { .dbl -1 }, -1, FLT_MAX, VE },{ qp, set the x265 qp, OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 -1 }, -1, INT_MAX, VE },{ forced-idr, if forcing keyframes, force them as IDR frames, OFFSET(forced_idr),AV_OPT_TYPE_BOOL, { .i64 0 }, 0, 1, VE },{ preset, set the x265 preset, OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },{ tune, set the x265 tune parameter, OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },{ profile, set the x265 profile, OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },{ udu_sei, Use user data unregistered SEI if available, OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 0 }, 0, 1, VE },{ x265-params, set the x265 configuration using a :-separated list of keyvalue parameters, OFFSET(x265_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },{ NULL }
};
官方代码中有关AVClass和AVOption的示例
官方代码中给出了一小段示例代码演示了如何给一个普通的结构体添加AVOption的支持。如下所示。
typedef struct test_struct {AVClass *class;int int_opt;char str_opt;uint8_t bin_opt;int bin_len;
} test_struct;static const AVOption test_options[] {{ test_int, This is a test option of int type., offsetof(test_struct, int_opt),AV_OPT_TYPE_INT, { .i64 -1 }, INT_MIN, INT_MAX },{ test_str, This is a test option of string type., offsetof(test_struct, str_opt),AV_OPT_TYPE_STRING },{ test_bin, This is a test option of binary type., offsetof(test_struct, bin_opt),AV_OPT_TYPE_BINARY },{ NULL },
};static const AVClass test_class {.class_name test class,.item_name av_default_item_name,.option test_options,.version LIBAVUTIL_VERSION_INT,
};
AVClass有关的API
与AVClass相关的API很少。AVFormatContext提供了一个获取当前AVClass的函数avformat_get_class()。它的代码很简单直接返回全局静态变量av_format_context_class。定义如下所示。
const AVClass *avformat_get_class(void)
{return av_format_context_class;
}
同样AVCodecContext也提供了一个获取当前AVClass的函数avcodec_get_class()。它直接返回静态变量av_codec_context_class。定义如下所示。
const AVClass *avcodec_get_class(void)
{return av_codec_context_class;
}