• FFmpeg源代码简单分析-其他-AVClass和AVoption


    参考链接

    概述

    • 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常用结构体AVFormatContext,AVCodecContext等进行赋值之外,还可以对它们的私有数据priv_data进行赋值。这个字段里通常存储了各种编码器特有的结构体。而这些结构体的定义在FFmpeg的SDK中是找不到的。例如使用libx264进行编码的时候,通过AVCodecContext的priv_data字段可以对X264Context结构体中的变量进行赋值,设置preset,profile等。使用libx265进行编码的时候,通过AVCodecContext的priv_data字段可以对libx265Context结构体中的变量进行赋值,设置preset,tune等。

    结构体定义

    1. /**
    2. * AVOption
    3. */
    4. typedef struct AVOption {
    5. const char *name;
    6. /**
    7. * short English help text
    8. * @todo What about other languages?
    9. */
    10. const char *help;
    11. /**
    12. * The offset relative to the context structure where the option
    13. * value is stored. It should be 0 for named constants.
    14. */
    15. int offset;
    16. enum AVOptionType type;
    17. /**
    18. * the default value for scalar options
    19. */
    20. union {
    21. int64_t i64;
    22. double dbl;
    23. const char *str;
    24. /* TODO those are unused now */
    25. AVRational q;
    26. } default_val;
    27. double min; ///< minimum valid value for the option
    28. double max; ///< maximum valid value for the option
    29. int flags;
    30. #define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding
    31. #define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding
    32. #define AV_OPT_FLAG_AUDIO_PARAM 8
    33. #define AV_OPT_FLAG_VIDEO_PARAM 16
    34. #define AV_OPT_FLAG_SUBTITLE_PARAM 32
    35. /**
    36. * The option is intended for exporting values to the caller.
    37. */
    38. #define AV_OPT_FLAG_EXPORT 64
    39. /**
    40. * The option may not be set through the AVOptions API, only read.
    41. * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set.
    42. */
    43. #define AV_OPT_FLAG_READONLY 128
    44. #define AV_OPT_FLAG_BSF_PARAM (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering
    45. #define AV_OPT_FLAG_RUNTIME_PARAM (1<<15) ///< a generic parameter which can be set by the user at runtime
    46. #define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
    47. #define AV_OPT_FLAG_DEPRECATED (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information
    48. #define AV_OPT_FLAG_CHILD_CONSTS (1<<18) ///< set if option constants can also reside in child objects
    49. //FIXME think about enc-audio, ... style flags
    50. /**
    51. * The logical unit to which the option belongs. Non-constant
    52. * options and corresponding named constants share the same
    53. * unit. May be NULL.
    54. */
    55. const char *unit;
    56. } AVOption;
    • 下面简单解释一下AVOption的几个成员变量:
      • name:名称。
      • help:简短的帮助。
      • offset:选项相对结构体首部地址的偏移量(这个很重要)。
      • type:选项的类型。
      • default_val:选项的默认值。
      • min:选项的最小值。
      • max:选项的最大值。
      • flags:一些标记。
      • unit:该选项所属的逻辑单元,可以为空。
    •  其中,default_val是一个union类型的变量,可以根据选项数据类型的不同,取int,double,char*,AVRational(表示分数)几种类型。
    • type是一个AVOptionType类型的变量。
    • AVOptionType是一个枚举类型,定义如下。 
    1. /**
    2. * @defgroup avoptions AVOptions
    3. * @ingroup lavu_data
    4. * @{
    5. * AVOptions provide a generic system to declare options on arbitrary structs
    6. * ("objects"). An option can have a help text, a type and a range of possible
    7. * values. Options may then be enumerated, read and written to.
    8. *
    9. * @section avoptions_implement Implementing AVOptions
    10. * This section describes how to add AVOptions capabilities to a struct.
    11. *
    12. * All AVOptions-related information is stored in an AVClass. Therefore
    13. * the first member of the struct should be a pointer to an AVClass describing it.
    14. * The option field of the AVClass must be set to a NULL-terminated static array
    15. * of AVOptions. Each AVOption must have a non-empty name, a type, a default
    16. * value and for number-type AVOptions also a range of allowed values. It must
    17. * also declare an offset in bytes from the start of the struct, where the field
    18. * associated with this AVOption is located. Other fields in the AVOption struct
    19. * should also be set when applicable, but are not required.
    20. *
    21. * The following example illustrates an AVOptions-enabled struct:
    22. * @code
    23. * typedef struct test_struct {
    24. * const AVClass *class;
    25. * int int_opt;
    26. * char *str_opt;
    27. * uint8_t *bin_opt;
    28. * int bin_len;
    29. * } test_struct;
    30. *
    31. * static const AVOption test_options[] = {
    32. * { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt),
    33. * AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX },
    34. * { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt),
    35. * AV_OPT_TYPE_STRING },
    36. * { "test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt),
    37. * AV_OPT_TYPE_BINARY },
    38. * { NULL },
    39. * };
    40. *
    41. * static const AVClass test_class = {
    42. * .class_name = "test class",
    43. * .item_name = av_default_item_name,
    44. * .option = test_options,
    45. * .version = LIBAVUTIL_VERSION_INT,
    46. * };
    47. * @endcode
    48. *
    49. * Next, when allocating your struct, you must ensure that the AVClass pointer
    50. * is set to the correct value. Then, av_opt_set_defaults() can be called to
    51. * initialize defaults. After that the struct is ready to be used with the
    52. * AVOptions API.
    53. *
    54. * When cleaning up, you may use the av_opt_free() function to automatically
    55. * free all the allocated string and binary options.
    56. *
    57. * Continuing with the above example:
    58. *
    59. * @code
    60. * test_struct *alloc_test_struct(void)
    61. * {
    62. * test_struct *ret = av_mallocz(sizeof(*ret));
    63. * ret->class = &test_class;
    64. * av_opt_set_defaults(ret);
    65. * return ret;
    66. * }
    67. * void free_test_struct(test_struct **foo)
    68. * {
    69. * av_opt_free(*foo);
    70. * av_freep(foo);
    71. * }
    72. * @endcode
    73. *
    74. * @subsection avoptions_implement_nesting Nesting
    75. * It may happen that an AVOptions-enabled struct contains another
    76. * AVOptions-enabled struct as a member (e.g. AVCodecContext in
    77. * libavcodec exports generic options, while its priv_data field exports
    78. * codec-specific options). In such a case, it is possible to set up the
    79. * parent struct to export a child's options. To do that, simply
    80. * implement AVClass.child_next() and AVClass.child_class_iterate() in the
    81. * parent struct's AVClass.
    82. * Assuming that the test_struct from above now also contains a
    83. * child_struct field:
    84. *
    85. * @code
    86. * typedef struct child_struct {
    87. * AVClass *class;
    88. * int flags_opt;
    89. * } child_struct;
    90. * static const AVOption child_opts[] = {
    91. * { "test_flags", "This is a test option of flags type.",
    92. * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX },
    93. * { NULL },
    94. * };
    95. * static const AVClass child_class = {
    96. * .class_name = "child class",
    97. * .item_name = av_default_item_name,
    98. * .option = child_opts,
    99. * .version = LIBAVUTIL_VERSION_INT,
    100. * };
    101. *
    102. * void *child_next(void *obj, void *prev)
    103. * {
    104. * test_struct *t = obj;
    105. * if (!prev && t->child_struct)
    106. * return t->child_struct;
    107. * return NULL
    108. * }
    109. * const AVClass child_class_iterate(void **iter)
    110. * {
    111. * const AVClass *c = *iter ? NULL : &child_class;
    112. * *iter = (void*)(uintptr_t)c;
    113. * return c;
    114. * }
    115. * @endcode
    116. * Putting child_next() and child_class_iterate() as defined above into
    117. * test_class will now make child_struct's options accessible through
    118. * test_struct (again, proper setup as described above needs to be done on
    119. * child_struct right after it is created).
    120. *
    121. * From the above example it might not be clear why both child_next()
    122. * and child_class_iterate() are needed. The distinction is that child_next()
    123. * iterates over actually existing objects, while child_class_iterate()
    124. * iterates over all possible child classes. E.g. if an AVCodecContext
    125. * was initialized to use a codec which has private options, then its
    126. * child_next() will return AVCodecContext.priv_data and finish
    127. * iterating. OTOH child_class_iterate() on AVCodecContext.av_class will
    128. * iterate over all available codecs with private options.
    129. *
    130. * @subsection avoptions_implement_named_constants Named constants
    131. * It is possible to create named constants for options. Simply set the unit
    132. * field of the option the constants should apply to a string and
    133. * create the constants themselves as options of type AV_OPT_TYPE_CONST
    134. * with their unit field set to the same string.
    135. * Their default_val field should contain the value of the named
    136. * constant.
    137. * For example, to add some named constants for the test_flags option
    138. * above, put the following into the child_opts array:
    139. * @code
    140. * { "test_flags", "This is a test option of flags type.",
    141. * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, "test_unit" },
    142. * { "flag1", "This is a flag with value 16", 0, AV_OPT_TYPE_CONST, { .i64 = 16 }, 0, 0, "test_unit" },
    143. * @endcode
    144. *
    145. * @section avoptions_use Using AVOptions
    146. * This section deals with accessing options in an AVOptions-enabled struct.
    147. * Such structs in FFmpeg are e.g. AVCodecContext in libavcodec or
    148. * AVFormatContext in libavformat.
    149. *
    150. * @subsection avoptions_use_examine Examining AVOptions
    151. * The basic functions for examining options are av_opt_next(), which iterates
    152. * over all options defined for one object, and av_opt_find(), which searches
    153. * for an option with the given name.
    154. *
    155. * The situation is more complicated with nesting. An AVOptions-enabled struct
    156. * may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag
    157. * to av_opt_find() will make the function search children recursively.
    158. *
    159. * For enumerating there are basically two cases. The first is when you want to
    160. * get all options that may potentially exist on the struct and its children
    161. * (e.g. when constructing documentation). In that case you should call
    162. * av_opt_child_class_iterate() recursively on the parent struct's AVClass. The
    163. * second case is when you have an already initialized struct with all its
    164. * children and you want to get all options that can be actually written or read
    165. * from it. In that case you should call av_opt_child_next() recursively (and
    166. * av_opt_next() on each result).
    167. *
    168. * @subsection avoptions_use_get_set Reading and writing AVOptions
    169. * When setting options, you often have a string read directly from the
    170. * user. In such a case, simply passing it to av_opt_set() is enough. For
    171. * non-string type options, av_opt_set() will parse the string according to the
    172. * option type.
    173. *
    174. * Similarly av_opt_get() will read any option type and convert it to a string
    175. * which will be returned. Do not forget that the string is allocated, so you
    176. * have to free it with av_free().
    177. *
    178. * In some cases it may be more convenient to put all options into an
    179. * AVDictionary and call av_opt_set_dict() on it. A specific case of this
    180. * are the format/codec open functions in lavf/lavc which take a dictionary
    181. * filled with option as a parameter. This makes it possible to set some options
    182. * that cannot be set otherwise, since e.g. the input file format is not known
    183. * before the file is actually opened.
    184. */
    185. enum AVOptionType{
    186. AV_OPT_TYPE_FLAGS,
    187. AV_OPT_TYPE_INT,
    188. AV_OPT_TYPE_INT64,
    189. AV_OPT_TYPE_DOUBLE,
    190. AV_OPT_TYPE_FLOAT,
    191. AV_OPT_TYPE_STRING,
    192. AV_OPT_TYPE_RATIONAL,
    193. AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length
    194. AV_OPT_TYPE_DICT,
    195. AV_OPT_TYPE_UINT64,
    196. AV_OPT_TYPE_CONST,
    197. AV_OPT_TYPE_IMAGE_SIZE, ///< offset must point to two consecutive integers
    198. AV_OPT_TYPE_PIXEL_FMT,
    199. AV_OPT_TYPE_SAMPLE_FMT,
    200. AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational
    201. AV_OPT_TYPE_DURATION,
    202. AV_OPT_TYPE_COLOR,
    203. #if FF_API_OLD_CHANNEL_LAYOUT
    204. AV_OPT_TYPE_CHANNEL_LAYOUT,
    205. #endif
    206. AV_OPT_TYPE_BOOL,
    207. AV_OPT_TYPE_CHLAYOUT,
    208. };

    补充

    •  突然想到了JavaEE开发中也有这种类似的机制。互联网上只可以传输字符串,即是没有方法传输整形、浮点型这种的数据。而Java系统中却包含整形、浮点型等各种数据类型。因此开发JSP中的Servlet的时候经常需要将整数字符串手工转化成一个整型的变量。使用最多的一个函数就是Integer.parseInt()方法。例如下面代码可以将字符串“123”转化成整数123。
    • int a=Integer.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”代表了int,double这些数据类型。使用这些函数的时候,可以指定int,double这些类型的变量(而不是字符串)作为输入,设定相应的AVOption的值。
    1. /**
    2. * @defgroup opt_set_funcs Option setting functions
    3. * @{
    4. * Those functions set the field of obj with the given name to value.
    5. *
    6. * @param[in] obj A struct whose first element is a pointer to an AVClass.
    7. * @param[in] name the name of the field to set
    8. * @param[in] val The value to set. In case of av_opt_set() if the field is not
    9. * of a string type, then the given string is parsed.
    10. * SI postfixes and some named scalars are supported.
    11. * If the field is of a numeric type, it has to be a numeric or named
    12. * scalar. Behavior with more than one scalar and +- infix operators
    13. * is undefined.
    14. * If the field is of a flags type, it has to be a sequence of numeric
    15. * scalars or named flags separated by '+' or '-'. Prefixing a flag
    16. * with '+' causes it to be set without affecting the other flags;
    17. * similarly, '-' unsets a flag.
    18. * If the field is of a dictionary type, it has to be a ':' separated list of
    19. * key=value parameters. Values containing ':' special characters must be
    20. * escaped.
    21. * @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
    22. * is passed here, then the option may be set on a child of obj.
    23. *
    24. * @return 0 if the value has been set, or an AVERROR code in case of
    25. * error:
    26. * AVERROR_OPTION_NOT_FOUND if no matching option exists
    27. * AVERROR(ERANGE) if the value is out of range
    28. * AVERROR(EINVAL) if the value is not valid
    29. */
    30. int av_opt_set (void *obj, const char *name, const char *val, int search_flags);
    31. int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags);
    32. int av_opt_set_double (void *obj, const char *name, double val, int search_flags);
    33. int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags);
    34. int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags);
    35. int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags);
    36. int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
    37. int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
    38. int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
    39. #if FF_API_OLD_CHANNEL_LAYOUT
    40. attribute_deprecated
    41. int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
    42. #endif
    43. int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *layout, int search_flags);
    44. /**
    45. * @note Any old dictionary present is discarded and replaced with a copy of the new one. The
    46. * caller still owns val is and responsible for freeing it.
    47. */
    48. int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags);
    49. /**
    50. * Set a binary option to an integer list.
    51. *
    52. * @param obj AVClass object to set options on
    53. * @param name name of the binary option
    54. * @param val pointer to an integer list (must have the correct type with
    55. * regard to the contents of the list)
    56. * @param term list terminator (usually 0 or -1)
    57. * @param flags search flags
    58. */
    59. #define av_opt_set_int_list(obj, name, val, term, flags) \
    60. (av_int_list_length(val, term) > INT_MAX / sizeof(*(val)) ? \
    61. AVERROR(EINVAL) : \
    62. av_opt_set_bin(obj, name, (const uint8_t *)(val), \
    63. av_int_list_length(val, term) * sizeof(*(val)), flags))
    • 函数调用关系图如下所示。

    • av_opt_set()的定义位于libavutil\opt.c,如下所示。 
    1. int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
    2. {
    3. int ret = 0;
    4. void *dst, *target_obj;
    5. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
    6. if (!o || !target_obj)
    7. return AVERROR_OPTION_NOT_FOUND;
    8. FF_DISABLE_DEPRECATION_WARNINGS
    9. if (!val && (o->type != AV_OPT_TYPE_STRING &&
    10. o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
    11. o->type != AV_OPT_TYPE_IMAGE_SIZE &&
    12. o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
    13. #if FF_API_OLD_CHANNEL_LAYOUT
    14. o->type != AV_OPT_TYPE_CHANNEL_LAYOUT &&
    15. #endif
    16. o->type != AV_OPT_TYPE_BOOL))
    17. return AVERROR(EINVAL);
    18. FF_ENABLE_DEPRECATION_WARNINGS
    19. if (o->flags & AV_OPT_FLAG_READONLY)
    20. return AVERROR(EINVAL);
    21. if (o->flags & AV_OPT_FLAG_DEPRECATED)
    22. av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
    23. dst = ((uint8_t *)target_obj) + o->offset;
    24. switch (o->type) {
    25. case AV_OPT_TYPE_BOOL:
    26. return set_string_bool(obj, o, val, dst);
    27. case AV_OPT_TYPE_STRING:
    28. return set_string(obj, o, val, dst);
    29. case AV_OPT_TYPE_BINARY:
    30. return set_string_binary(obj, o, val, dst);
    31. case AV_OPT_TYPE_FLAGS:
    32. case AV_OPT_TYPE_INT:
    33. case AV_OPT_TYPE_INT64:
    34. case AV_OPT_TYPE_UINT64:
    35. case AV_OPT_TYPE_FLOAT:
    36. case AV_OPT_TYPE_DOUBLE:
    37. case AV_OPT_TYPE_RATIONAL:
    38. return set_string_number(obj, target_obj, o, val, dst);
    39. case AV_OPT_TYPE_IMAGE_SIZE:
    40. return set_string_image_size(obj, o, val, dst);
    41. case AV_OPT_TYPE_VIDEO_RATE: {
    42. AVRational tmp;
    43. ret = set_string_video_rate(obj, o, val, &tmp);
    44. if (ret < 0)
    45. return ret;
    46. return write_number(obj, o, dst, 1, tmp.den, tmp.num);
    47. }
    48. case AV_OPT_TYPE_PIXEL_FMT:
    49. return set_string_pixel_fmt(obj, o, val, dst);
    50. case AV_OPT_TYPE_SAMPLE_FMT:
    51. return set_string_sample_fmt(obj, o, val, dst);
    52. case AV_OPT_TYPE_DURATION:
    53. {
    54. int64_t usecs = 0;
    55. if (val) {
    56. if ((ret = av_parse_time(&usecs, val, 1)) < 0) {
    57. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
    58. return ret;
    59. }
    60. }
    61. if (usecs < o->min || usecs > o->max) {
    62. av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
    63. usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0);
    64. return AVERROR(ERANGE);
    65. }
    66. *(int64_t *)dst = usecs;
    67. return 0;
    68. }
    69. case AV_OPT_TYPE_COLOR:
    70. return set_string_color(obj, o, val, dst);
    71. #if FF_API_OLD_CHANNEL_LAYOUT
    72. FF_DISABLE_DEPRECATION_WARNINGS
    73. case AV_OPT_TYPE_CHANNEL_LAYOUT:
    74. if (!val || !strcmp(val, "none")) {
    75. *(int64_t *)dst = 0;
    76. } else {
    77. int64_t cl = av_get_channel_layout(val);
    78. if (!cl) {
    79. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
    80. ret = AVERROR(EINVAL);
    81. }
    82. *(int64_t *)dst = cl;
    83. return ret;
    84. }
    85. break;
    86. FF_ENABLE_DEPRECATION_WARNINGS
    87. #endif
    88. case AV_OPT_TYPE_CHLAYOUT:
    89. ret = set_string_channel_layout(obj, o, val, dst);
    90. if (ret < 0) {
    91. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
    92. ret = AVERROR(EINVAL);
    93. }
    94. return ret;
    95. case AV_OPT_TYPE_DICT:
    96. return set_string_dict(obj, o, val, dst);
    97. }
    98. av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
    99. return AVERROR(EINVAL);
    100. }
    •  从源代码可以看出,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中,如下所示。
    1. /**
    2. * Look for an option in an object. Consider only options which
    3. * have all the specified flags set.
    4. *
    5. * @param[in] obj A pointer to a struct whose first element is a
    6. * pointer to an AVClass.
    7. * Alternatively a double pointer to an AVClass, if
    8. * AV_OPT_SEARCH_FAKE_OBJ search flag is set.
    9. * @param[in] name The name of the option to look for.
    10. * @param[in] unit When searching for named constants, name of the unit
    11. * it belongs to.
    12. * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG).
    13. * @param search_flags A combination of AV_OPT_SEARCH_*.
    14. * @param[out] target_obj if non-NULL, an object to which the option belongs will be
    15. * written here. It may be different from obj if AV_OPT_SEARCH_CHILDREN is present
    16. * in search_flags. This parameter is ignored if search_flags contain
    17. * AV_OPT_SEARCH_FAKE_OBJ.
    18. *
    19. * @return A pointer to the option found, or NULL if no option
    20. * was found.
    21. */
    22. const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
    23. 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。 
    1. const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
    2. int opt_flags, int search_flags, void **target_obj)
    3. {
    4. const AVClass *c;
    5. const AVOption *o = NULL;
    6. if(!obj)
    7. return NULL;
    8. c= *(AVClass**)obj;
    9. if (!c)
    10. return NULL;
    11. if (search_flags & AV_OPT_SEARCH_CHILDREN) {
    12. if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
    13. void *iter = NULL;
    14. const AVClass *child;
    15. while (child = av_opt_child_class_iterate(c, &iter))
    16. if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
    17. return o;
    18. } else {
    19. void *child = NULL;
    20. while (child = av_opt_child_next(obj, child))
    21. if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
    22. return o;
    23. }
    24. }
    25. while (o = av_opt_next(obj, o)) {
    26. if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
    27. ((!unit && o->type != AV_OPT_TYPE_CONST) ||
    28. (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
    29. if (target_obj) {
    30. if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
    31. *target_obj = obj;
    32. else
    33. *target_obj = NULL;
    34. }
    35. return o;
    36. }
    37. }
    38. return NULL;
    39. }
    1. const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
    2. int opt_flags, int search_flags)
    3. {
    4. return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
    5. }
    •  这段代码的前半部分暂时不关注,前半部分的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,它的声明如下。
    1. /**
    2. * Iterate over all AVOptions belonging to obj.
    3. *
    4. * @param obj an AVOptions-enabled struct or a double pointer to an
    5. * AVClass describing it.
    6. * @param prev result of the previous call to av_opt_next() on this object
    7. * or NULL
    8. * @return next AVOption or NULL
    9. */
    10. const AVOption *av_opt_next(const void *obj, const AVOption *prev);
    • av_opt_next()的定义如下所示。
    1. const AVOption *av_opt_next(const void *obj, const AVOption *last)
    2. {
    3. const AVClass *class;
    4. if (!obj)
    5. return NULL;
    6. class = *(const AVClass**)obj;
    7. if (!last && class && class->option && class->option[0].name)
    8. return class->option;
    9. if (last && last[1].name)
    10. return ++last;
    11. return NULL;
    12. }
    •  从av_opt_next()的代码可以看出,输入的AVOption类型的last变量为空的时候,会返回该AVClass的option数组的第一个元素,否则会返回数组的下一个元素。

    我们可以看几个设置值的的简单例子: 

    1. AV_OPT_TYPE_STRING

    • 当AVOption的type为AV_OPT_TYPE_STRING的时候,调用set_string()方法设置相应的值。
    • set_string()的定义如下:
    1. static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
    2. {
    3. av_freep(dst);
    4. *dst = av_strdup(val);
    5. return *dst ? 0 : AVERROR(ENOMEM);
    6. }
    • 其中又调用了一个函数av_strdup(),这是一个FFmpeg的API函数,用于拷贝字符串。
    • 它的代码如下所示,其中调用了memcpy()。
    1. char *av_strdup(const char *s)
    2. {
    3. char *ptr = NULL;
    4. if (s) {
    5. size_t len = strlen(s) + 1;
    6. ptr = av_realloc(NULL, len);
    7. if (ptr)
    8. memcpy(ptr, s, len);
    9. }
    10. return ptr;
    11. }

     2. AV_OPT_TYPE_IMAGE_SIZE

    • 当AVOption的type为AV_OPT_TYPE_IMAGE_SIZE的时候,调用set_string_image_size ()方法设置相应的值。
    • set_string_image_size()的定义如下。
    1. static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst)
    2. {
    3. int ret;
    4. if (!val || !strcmp(val, "none")) {
    5. dst[0] =
    6. dst[1] = 0;
    7. return 0;
    8. }
    9. ret = av_parse_video_size(dst, dst + 1, val);
    10. if (ret < 0)
    11. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
    12. return ret;
    13. }
    •  可见其中调用了另一个函数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中,如下所示。
    1. /**
    2. * Parse str and put in width_ptr and height_ptr the detected values.
    3. *
    4. * @param[in,out] width_ptr pointer to the variable which will contain the detected
    5. * width value
    6. * @param[in,out] height_ptr pointer to the variable which will contain the detected
    7. * height value
    8. * @param[in] str the string to parse: it has to be a string in the format
    9. * width x height or a valid video size abbreviation.
    10. * @return >= 0 on success, a negative error code otherwise
    11. */
    12. int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str);
    • av_parse_video_size()定义位于libavutil\parseutils.c中,代码如下。 
    1. //解析分辨率
    2. int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
    3. {
    4. int i;
    5. int n = FF_ARRAY_ELEMS(video_size_abbrs);
    6. const char *p;
    7. int width = 0, height = 0;
    8. //先看看有没有“分辨率简称”相同的(例如vga,qcif等)
    9. for (i = 0; i < n; i++) {
    10. if (!strcmp(video_size_abbrs[i].abbr, str)) {
    11. width = video_size_abbrs[i].width;
    12. height = video_size_abbrs[i].height;
    13. break;
    14. }
    15. }
    16. //如果没有使用“分辨率简称”,而是使用具体的数值(例如“1920x1080”),则执行下面的步骤
    17. if (i == n) {
    18. //strtol():字符串转换成整型,遇到非数字则停止
    19. width = strtol(str, (void*)&p, 10);
    20. if (*p)
    21. p++;
    22. height = strtol(p, (void*)&p, 10);
    23. /* trailing extraneous data detected, like in 123x345foobar */
    24. if (*p)
    25. return AVERROR(EINVAL);
    26. }
    27. //检查一下正确性
    28. if (width <= 0 || height <= 0)
    29. return AVERROR(EINVAL);
    30. *width_ptr = width;
    31. *height_ptr = height;
    32. return 0;
    33. }
    • 从声明中可以看出,该函数输入一个字符串str,输出结果保存在width_ptr和height_ptr所指向的内存中。
    • 上述代码中包含了FFmpeg中两种解析视频分辨率的方法。FFmpeg中包含两种设定视频分辨率的方法:通过已经定义好的“分辨率简称”,或者通过具体的数值。代码中首先遍历“特定分辨率”的数组video_size_abbrs。
    • 该数组定义如下所示。
    1. static const VideoSizeAbbr video_size_abbrs[] = {
    2. { "ntsc", 720, 480 },
    3. { "pal", 720, 576 },
    4. { "qntsc", 352, 240 }, /* VCD compliant NTSC */
    5. { "qpal", 352, 288 }, /* VCD compliant PAL */
    6. { "sntsc", 640, 480 }, /* square pixel NTSC */
    7. { "spal", 768, 576 }, /* square pixel PAL */
    8. { "film", 352, 240 },
    9. { "ntsc-film", 352, 240 },
    10. { "sqcif", 128, 96 },
    11. { "qcif", 176, 144 },
    12. { "cif", 352, 288 },
    13. { "4cif", 704, 576 },
    14. { "16cif", 1408,1152 },
    15. { "qqvga", 160, 120 },
    16. { "qvga", 320, 240 },
    17. { "vga", 640, 480 },
    18. { "svga", 800, 600 },
    19. { "xga", 1024, 768 },
    20. { "uxga", 1600,1200 },
    21. { "qxga", 2048,1536 },
    22. { "sxga", 1280,1024 },
    23. { "qsxga", 2560,2048 },
    24. { "hsxga", 5120,4096 },
    25. { "wvga", 852, 480 },
    26. { "wxga", 1366, 768 },
    27. { "wsxga", 1600,1024 },
    28. { "wuxga", 1920,1200 },
    29. { "woxga", 2560,1600 },
    30. { "wqhd", 2560,1440 },
    31. { "wqsxga", 3200,2048 },
    32. { "wquxga", 3840,2400 },
    33. { "whsxga", 6400,4096 },
    34. { "whuxga", 7680,4800 },
    35. { "cga", 320, 200 },
    36. { "ega", 640, 350 },
    37. { "hd480", 852, 480 },
    38. { "hd720", 1280, 720 },
    39. { "hd1080", 1920,1080 },
    40. { "quadhd", 2560,1440 },
    41. { "2k", 2048,1080 }, /* Digital Cinema System Specification */
    42. { "2kdci", 2048,1080 },
    43. { "2kflat", 1998,1080 },
    44. { "2kscope", 2048, 858 },
    45. { "4k", 4096,2160 }, /* Digital Cinema System Specification */
    46. { "4kdci", 4096,2160 },
    47. { "4kflat", 3996,2160 },
    48. { "4kscope", 4096,1716 },
    49. { "nhd", 640,360 },
    50. { "hqvga", 240,160 },
    51. { "wqvga", 400,240 },
    52. { "fwqvga", 432,240 },
    53. { "hvga", 480,320 },
    54. { "qhd", 960,540 },
    55. { "uhd2160", 3840,2160 },
    56. { "uhd4320", 7680,4320 },
    57. };
    • 通过调用strcmp()方法比对输入字符串的值与video_size_abbrs数组中每个VideoSizeAbbr元素的abbr字段的值,判断输入的字符串是否指定了这些标准的分辨率。如果指定了的话,则返回该分辨率的宽和高。
    •  如果从上述列表中没有找到相应的“特定分辨率”,则说明输入的字符串应该是一个具体的分辨率的值,形如“1920*1020”,“1280x720”这样的字符串。这个时候就需要对这个字符串进行解析,并从中提取出数字信息。通过两次调用strtol()方法,从字符串中提取出宽高信息(第一次提取出宽,第二次提取出高)。
    • PS1:strtol()用于将字符串转换成整型,遇到非数字则停止。
    • PS2:从这种解析方法可以得到一个信息——FFmpeg并不管“宽{X}高”中间的那个{X}是什么字符,也就是说中间那个字符不一定非得是“*”或者“x”。后来试了一下,中间那个字符使用其他字母也是可以的。 

    av_opt_get()

    • 函数调用关系图如下所示 

    • av_opt_get()用于获取一个AVOption变量的值。
    • 需要注意的是,不论是何种类型的变量,通过av_opt_get()取出来的值都是字符串类型的。
    • 此外,还包含了它的一系列“兄弟”函数av_opt_get_XXX()(其中“XXX”代表了int,double这些数据类型)。通过这些“兄弟”函数可以直接取出int,double类型的数值。
    • av_opt_get()的声明如下所示。 
    1. /**
    2. * @defgroup opt_get_funcs Option getting functions
    3. * @{
    4. * Those functions get a value of the option with the given name from an object.
    5. *
    6. * @param[in] obj a struct whose first element is a pointer to an AVClass.
    7. * @param[in] name name of the option to get.
    8. * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN
    9. * is passed here, then the option may be found in a child of obj.
    10. * @param[out] out_val value of the option will be written here
    11. * @return >=0 on success, a negative error code otherwise
    12. */
    13. /**
    14. * @note the returned string will be av_malloc()ed and must be av_free()ed by the caller
    15. *
    16. * @note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the
    17. * option is of type AV_OPT_TYPE_STRING, AV_OPT_TYPE_BINARY or AV_OPT_TYPE_DICT
    18. * and is set to NULL, *out_val will be set to NULL instead of an allocated
    19. * empty string.
    20. */
    21. int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val);
    22. int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val);
    23. int av_opt_get_double (void *obj, const char *name, int search_flags, double *out_val);
    24. int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val);
    25. int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out);
    26. int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
    27. int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
    28. int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
    29. #if FF_API_OLD_CHANNEL_LAYOUT
    30. attribute_deprecated
    31. int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
    32. #endif
    33. int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *layout);
    34. /**
    35. * @param[out] out_val The returned dictionary is a copy of the actual value and must
    36. * be freed with av_dict_free() by the caller
    37. */
    38. 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相关的源代码基本上就分析完毕了。
    1. int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
    2. {
    3. void *dst, *target_obj;
    4. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
    5. uint8_t *bin, buf[128];
    6. int len, i, ret;
    7. int64_t i64;
    8. if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
    9. return AVERROR_OPTION_NOT_FOUND;
    10. if (o->flags & AV_OPT_FLAG_DEPRECATED)
    11. av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
    12. dst = (uint8_t *)target_obj + o->offset;
    13. buf[0] = 0;
    14. switch (o->type) {
    15. case AV_OPT_TYPE_BOOL:
    16. ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid"));
    17. break;
    18. case AV_OPT_TYPE_FLAGS:
    19. ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);
    20. break;
    21. case AV_OPT_TYPE_INT:
    22. ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst);
    23. break;
    24. case AV_OPT_TYPE_INT64:
    25. ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst);
    26. break;
    27. case AV_OPT_TYPE_UINT64:
    28. ret = snprintf(buf, sizeof(buf), "%"PRIu64, *(uint64_t *)dst);
    29. break;
    30. case AV_OPT_TYPE_FLOAT:
    31. ret = snprintf(buf, sizeof(buf), "%f", *(float *)dst);
    32. break;
    33. case AV_OPT_TYPE_DOUBLE:
    34. ret = snprintf(buf, sizeof(buf), "%f", *(double *)dst);
    35. break;
    36. case AV_OPT_TYPE_VIDEO_RATE:
    37. case AV_OPT_TYPE_RATIONAL:
    38. ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den);
    39. break;
    40. case AV_OPT_TYPE_CONST:
    41. ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl);
    42. break;
    43. case AV_OPT_TYPE_STRING:
    44. if (*(uint8_t **)dst) {
    45. *out_val = av_strdup(*(uint8_t **)dst);
    46. } else if (search_flags & AV_OPT_ALLOW_NULL) {
    47. *out_val = NULL;
    48. return 0;
    49. } else {
    50. *out_val = av_strdup("");
    51. }
    52. return *out_val ? 0 : AVERROR(ENOMEM);
    53. case AV_OPT_TYPE_BINARY:
    54. if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
    55. *out_val = NULL;
    56. return 0;
    57. }
    58. len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *));
    59. if ((uint64_t)len * 2 + 1 > INT_MAX)
    60. return AVERROR(EINVAL);
    61. if (!(*out_val = av_malloc(len * 2 + 1)))
    62. return AVERROR(ENOMEM);
    63. if (!len) {
    64. *out_val[0] = '\0';
    65. return 0;
    66. }
    67. bin = *(uint8_t **)dst;
    68. for (i = 0; i < len; i++)
    69. snprintf(*out_val + i * 2, 3, "%02X", bin[i]);
    70. return 0;
    71. case AV_OPT_TYPE_IMAGE_SIZE:
    72. ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
    73. break;
    74. case AV_OPT_TYPE_PIXEL_FMT:
    75. ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
    76. break;
    77. case AV_OPT_TYPE_SAMPLE_FMT:
    78. ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
    79. break;
    80. case AV_OPT_TYPE_DURATION:
    81. i64 = *(int64_t *)dst;
    82. format_duration(buf, sizeof(buf), i64);
    83. ret = strlen(buf); // no overflow possible, checked by an assert
    84. break;
    85. case AV_OPT_TYPE_COLOR:
    86. ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x",
    87. (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
    88. (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
    89. break;
    90. #if FF_API_OLD_CHANNEL_LAYOUT
    91. FF_DISABLE_DEPRECATION_WARNINGS
    92. case AV_OPT_TYPE_CHANNEL_LAYOUT:
    93. i64 = *(int64_t *)dst;
    94. ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
    95. break;
    96. FF_ENABLE_DEPRECATION_WARNINGS
    97. #endif
    98. case AV_OPT_TYPE_CHLAYOUT:
    99. ret = av_channel_layout_describe(dst, buf, sizeof(buf));
    100. break;
    101. case AV_OPT_TYPE_DICT:
    102. if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
    103. *out_val = NULL;
    104. return 0;
    105. }
    106. return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, '=', ':');
    107. default:
    108. return AVERROR(EINVAL);
    109. }
    110. if (ret >= sizeof(buf))
    111. return AVERROR(EINVAL);
    112. *out_val = av_strdup(buf);
    113. return *out_val ? 0 : AVERROR(ENOMEM);
    114. }

     av_opt_set_defaults()

    • 函数调用关系图如下所示。

    • av_opt_set_defaults()是一个FFmpeg的API,作用是给一个结构体的成员变量设定默认值。
    • 在FFmpeg初始化其各种结构体(AVFormatContext,AVCodecContext等)的时候,通常会调用该函数设置结构体中的默认值。
    • av_opt_set_defaults()的声明如下所示。
    1. /**
    2. * Set the values of all AVOption fields to their default values.
    3. *
    4. * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass)
    5. */
    6. void av_opt_set_defaults(void *s);
    • 可见只需要把包含AVOption功能的结构体(第一个变量是一个AVClass类型的指针)的指针提供给av_opt_set_defaults(),就可以初始化该结构体的默认值了。
    • 下面看一下av_opt_set_defaults()的源代码,位于libavutil\opt.c,如下所示。
    1. void av_opt_set_defaults(void *s)
    2. {
    3. av_opt_set_defaults2(s, 0, 0);
    4. }
    5. void av_opt_set_defaults2(void *s, int mask, int flags)
    6. {
    7. const AVOption *opt = NULL;
    8. while ((opt = av_opt_next(s, opt))) {
    9. void *dst = ((uint8_t*)s) + opt->offset;
    10. if ((opt->flags & mask) != flags)
    11. continue;
    12. if (opt->flags & AV_OPT_FLAG_READONLY)
    13. continue;
    14. switch (opt->type) {
    15. case AV_OPT_TYPE_CONST:
    16. /* Nothing to be done here */
    17. break;
    18. case AV_OPT_TYPE_BOOL:
    19. case AV_OPT_TYPE_FLAGS:
    20. case AV_OPT_TYPE_INT:
    21. case AV_OPT_TYPE_INT64:
    22. case AV_OPT_TYPE_UINT64:
    23. case AV_OPT_TYPE_DURATION:
    24. #if FF_API_OLD_CHANNEL_LAYOUT
    25. FF_DISABLE_DEPRECATION_WARNINGS
    26. case AV_OPT_TYPE_CHANNEL_LAYOUT:
    27. FF_ENABLE_DEPRECATION_WARNINGS
    28. #endif
    29. case AV_OPT_TYPE_PIXEL_FMT:
    30. case AV_OPT_TYPE_SAMPLE_FMT:
    31. write_number(s, opt, dst, 1, 1, opt->default_val.i64);
    32. break;
    33. case AV_OPT_TYPE_DOUBLE:
    34. case AV_OPT_TYPE_FLOAT: {
    35. double val;
    36. val = opt->default_val.dbl;
    37. write_number(s, opt, dst, val, 1, 1);
    38. }
    39. break;
    40. case AV_OPT_TYPE_RATIONAL: {
    41. AVRational val;
    42. val = av_d2q(opt->default_val.dbl, INT_MAX);
    43. write_number(s, opt, dst, 1, val.den, val.num);
    44. }
    45. break;
    46. case AV_OPT_TYPE_COLOR:
    47. set_string_color(s, opt, opt->default_val.str, dst);
    48. break;
    49. case AV_OPT_TYPE_STRING:
    50. set_string(s, opt, opt->default_val.str, dst);
    51. break;
    52. case AV_OPT_TYPE_IMAGE_SIZE:
    53. set_string_image_size(s, opt, opt->default_val.str, dst);
    54. break;
    55. case AV_OPT_TYPE_VIDEO_RATE:
    56. set_string_video_rate(s, opt, opt->default_val.str, dst);
    57. break;
    58. case AV_OPT_TYPE_BINARY:
    59. set_string_binary(s, opt, opt->default_val.str, dst);
    60. break;
    61. case AV_OPT_TYPE_CHLAYOUT:
    62. set_string_channel_layout(s, opt, opt->default_val.str, dst);
    63. break;
    64. case AV_OPT_TYPE_DICT:
    65. set_string_dict(s, opt, opt->default_val.str, dst);
    66. break;
    67. default:
    68. av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n",
    69. opt->type, opt->name);
    70. }
    71. }
    72. }
    •  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的定义的开头部分,如下所示。
    1. typedef struct AVFormatContext {
    2. /**
    3. * A class for logging and @ref avoptions. Set by avformat_alloc_context().
    4. * Exports (de)muxer private options if they exist.
    5. */
    6. const AVClass *av_class;
    7. /**
    8. * The input container format.
    9. *
    10. * Demuxing only, set by avformat_open_input().
    11. */
    12. struct AVInputFormat *iformat;
    13. /**
    14. * The output container format.
    15. *
    16. * Muxing only, must be set by the caller before avformat_write_header().
    17. */
    18. struct AVOutputFormat *oformat;
    19. //后文略
    • 截取一小段AVCodecContext的定义的开头部分,如下所示。
    1. typedef struct AVCodecContext {
    2. /**
    3. * information on struct for av_log
    4. * - set by avcodec_alloc_context3
    5. */
    6. const AVClass *av_class;
    7. int log_level_offset;
    8. enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
    9. const struct AVCodec *codec;
    10. //后文略
    • 下面来看一下AVClass的定义,如下所示。
    1. /**
    2. * Describe the class of an AVClass context structure. That is an
    3. * arbitrary struct of which the first field is a pointer to an
    4. * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
    5. */
    6. typedef struct AVClass {
    7. /**
    8. * The name of the class; usually it is the same name as the
    9. * context structure type to which the AVClass is associated.
    10. */
    11. const char* class_name;
    12. /**
    13. * A pointer to a function which returns the name of a context
    14. * instance ctx associated with the class.
    15. */
    16. const char* (*item_name)(void* ctx);
    17. /**
    18. * a pointer to the first option specified in the class if any or NULL
    19. *
    20. * @see av_set_default_options()
    21. */
    22. const struct AVOption *option;
    23. /**
    24. * LIBAVUTIL_VERSION with which this structure was created.
    25. * This is used to allow fields to be added without requiring major
    26. * version bumps everywhere.
    27. */
    28. int version;
    29. /**
    30. * Offset in the structure where log_level_offset is stored.
    31. * 0 means there is no such variable
    32. */
    33. int log_level_offset_offset;
    34. /**
    35. * Offset in the structure where a pointer to the parent context for
    36. * logging is stored. For example a decoder could pass its AVCodecContext
    37. * to eval as such a parent context, which an av_log() implementation
    38. * could then leverage to display the parent context.
    39. * The offset can be NULL.
    40. */
    41. int parent_log_context_offset;
    42. /**
    43. * Category used for visualization (like color)
    44. * This is only set if the category is equal for all objects using this class.
    45. * available since version (51 << 16 | 56 << 8 | 100)
    46. */
    47. AVClassCategory category;
    48. /**
    49. * Callback to return the category.
    50. * available since version (51 << 16 | 59 << 8 | 100)
    51. */
    52. AVClassCategory (*get_category)(void* ctx);
    53. /**
    54. * Callback to return the supported/allowed ranges.
    55. * available since version (52.12)
    56. */
    57. int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags);
    58. /**
    59. * Return next AVOptions-enabled child or NULL
    60. */
    61. void* (*child_next)(void *obj, void *prev);
    62. /**
    63. * Iterate over the AVClasses corresponding to potential AVOptions-enabled
    64. * children.
    65. *
    66. * @param iter pointer to opaque iteration state. The caller must initialize
    67. * *iter to NULL before the first call.
    68. * @return AVClass for the next AVOptions-enabled child or NULL if there are
    69. * no more such children.
    70. *
    71. * @note The difference between child_next and this is that child_next
    72. * iterates over _already existing_ objects, while child_class_iterate
    73. * iterates over _all possible_ children.
    74. */
    75. const struct AVClass* (*child_class_iterate)(void **iter);
    76. } AVClass;
    • 下面简单解释一下AVClass的几个已经理解的成员变量:
    • class_name:AVClass名称。
    • item_name:函数,获取与AVClass相关联的结构体实例的名称。
    • option:AVOption类型的数组(最重要)。
    • version:完成该AVClass的时候的LIBAVUTIL_VERSION。
    • category:AVClass的类型,是一个类型为AVClassCategory的枚举型变量。
    • 其中AVClassCategory定义如下。

    1. typedef enum {
    2. AV_CLASS_CATEGORY_NA = 0,
    3. AV_CLASS_CATEGORY_INPUT,
    4. AV_CLASS_CATEGORY_OUTPUT,
    5. AV_CLASS_CATEGORY_MUXER,
    6. AV_CLASS_CATEGORY_DEMUXER,
    7. AV_CLASS_CATEGORY_ENCODER,
    8. AV_CLASS_CATEGORY_DECODER,
    9. AV_CLASS_CATEGORY_FILTER,
    10. AV_CLASS_CATEGORY_BITSTREAM_FILTER,
    11. AV_CLASS_CATEGORY_SWSCALER,
    12. AV_CLASS_CATEGORY_SWRESAMPLER,
    13. AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT = 40,
    14. AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,
    15. AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT,
    16. AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT,
    17. AV_CLASS_CATEGORY_DEVICE_OUTPUT,
    18. AV_CLASS_CATEGORY_DEVICE_INPUT,
    19. AV_CLASS_CATEGORY_NB ///< not part of ABI/API
    20. }AVClassCategory;
    •  上面解释字段还是比较抽象的,下面通过具体的例子看一下AVClass这个结构体。我们看几个具体的例子:
      • AVFormatContext中的AVClass
      • AVCodecContext中的AVClass
      • AVFrame中的AVClass
      • 各种组件(libRTMP,libx264,libx265)里面特有的AVClass。

    AVFormatContext中的AVClass

    • AVFormatContext 中的AVClass定义位于libavformat\options.c中,是一个名称为av_format_context_class的静态结构体。
    • 如下所示。
    1. static const AVClass av_format_context_class = {
    2. .class_name = "AVFormatContext",
    3. .item_name = format_to_name,
    4. .option = avformat_options,
    5. .version = LIBAVUTIL_VERSION_INT,
    6. .child_next = format_child_next,
    7. .child_class_iterate = format_child_class_iterate,
    8. .category = AV_CLASS_CATEGORY_MUXER,
    9. .get_category = get_category,
    10. };
    • 从源代码可以看出以下几点
      • (1)class_name
    • 该AVClass名称是“AVFormatContext”。
      • (2)item_name
    • item_name指向一个函数format_to_name(),该函数定义如下所示。
    1. static const char* format_to_name(void* ptr)
    2. {
    3. AVFormatContext* fc = (AVFormatContext*) ptr;
    4. if(fc->iformat) return fc->iformat->name;
    5. else if(fc->oformat) return fc->oformat->name;
    6. else return "NULL";
    7. }
    • 从函数的定义可以看出,如果AVFormatContext结构体中的AVInputFormat结构体不为空,则返回AVInputFormat的name,然后尝试返回AVOutputFormat的name,如果AVOutputFormat也为空,则返回“NULL”。
    • (3)option
    • option字段则指向一个元素个数很多的静态数组avformat_options。该数组单独定义于libavformat\options_table.h中。其中包含了AVFormatContext支持的所有的AVOption,如下所示。
    1. /*
    2. * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
    3. *
    4. * This file is part of FFmpeg.
    5. *
    6. * FFmpeg is free software; you can redistribute it and/or
    7. * modify it under the terms of the GNU Lesser General Public
    8. * License as published by the Free Software Foundation; either
    9. * version 2.1 of the License, or (at your option) any later version.
    10. *
    11. * FFmpeg is distributed in the hope that it will be useful,
    12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    14. * Lesser General Public License for more details.
    15. *
    16. * You should have received a copy of the GNU Lesser General Public
    17. * License along with FFmpeg; if not, write to the Free Software
    18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    19. */
    20. #ifndef AVFORMAT_OPTIONS_TABLE_H
    21. #define AVFORMAT_OPTIONS_TABLE_H
    22. #include <limits.h>
    23. #include "libavutil/opt.h"
    24. #include "avformat.h"
    25. #include "internal.h"
    26. #define OFFSET(x) offsetof(AVFormatContext,x)
    27. #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
    28. //these names are too long to be readable
    29. #define E AV_OPT_FLAG_ENCODING_PARAM
    30. #define D AV_OPT_FLAG_DECODING_PARAM
    31. static const AVOption avformat_options[] = {
    32. {"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"},
    33. {"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"},
    34. {"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT64, {.i64 = 5000000 }, 32, INT64_MAX, D},
    35. {"formatprobesize", "number of bytes to probe file format", OFFSET(format_probesize), AV_OPT_TYPE_INT, {.i64 = PROBE_BUF_MAX}, 0, INT_MAX-1, D},
    36. {"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, E},
    37. {"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = AVFMT_FLAG_AUTO_BSF }, INT_MIN, INT_MAX, D|E, "fflags"},
    38. {"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"},
    39. {"ignidx", "ignore index", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"},
    40. {"genpts", "generate pts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_GENPTS }, INT_MIN, INT_MAX, D, "fflags"},
    41. {"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"},
    42. {"noparse", "disable AVParsers, this needs nofillin too", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOPARSE }, INT_MIN, INT_MAX, D, "fflags"},
    43. {"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
    44. {"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"},
    45. {"sortdts", "try to interleave outputted packets by dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"},
    46. {"fastseek", "fast but inaccurate seeks", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_FAST_SEEK }, INT_MIN, INT_MAX, D, "fflags"},
    47. {"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"},
    48. {"bitexact", "do not write random/volatile data", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_BITEXACT }, 0, 0, E, "fflags" },
    49. {"shortest", "stop muxing with the shortest stream", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_SHORTEST }, 0, 0, E, "fflags" },
    50. {"autobsf", "add needed bsfs automatically", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_AUTO_BSF }, 0, 0, E, "fflags" },
    51. {"seek2any", "allow seeking to non-keyframes on demuxer level when supported", OFFSET(seek2any), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, D},
    52. {"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},
    53. {"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
    54. {"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.i64 = 1<<20 }, 0, INT_MAX, D},
    55. {"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 */
    56. {"fdebug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, E|D, "fdebug"},
    57. {"ts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, "fdebug"},
    58. {"max_delay", "maximum muxing or demuxing delay in microseconds", OFFSET(max_delay), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, INT_MAX, E|D},
    59. {"start_time_realtime", "wall-clock time when stream begins (PTS==0)", OFFSET(start_time_realtime), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX, E},
    60. {"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX-1, D},
    61. {"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},
    62. {"chunk_duration", "microseconds for each chunk", OFFSET(max_chunk_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E},
    63. {"chunk_size", "size in bytes for each chunk", OFFSET(max_chunk_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E},
    64. /* this is a crutch for avconv, since it cannot deal with identically named options in different contexts.
    65. * to be removed when avconv is fixed */
    66. {"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"},
    67. {"err_detect", "set error detection flags", OFFSET(error_recognition), AV_OPT_TYPE_FLAGS, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, "err_detect"},
    68. {"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, "err_detect"},
    69. {"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, D, "err_detect"},
    70. {"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, D, "err_detect"},
    71. {"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, D, "err_detect"},
    72. {"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, D, "err_detect"},
    73. {"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"},
    74. {"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"},
    75. {"aggressive", "consider things that a sane encoder shouldn't 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"},
    76. {"use_wallclock_as_timestamps", "use wallclock as timestamps", OFFSET(use_wallclock_as_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, D},
    77. {"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},
    78. {"correct_ts_overflow", "correct single timestamp overflows", OFFSET(correct_ts_overflow), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, D},
    79. {"flush_packets", "enable flushing of the I/O context after each packet", OFFSET(flush_packets), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E},
    80. {"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},
    81. {"output_ts_offset", "set output timestamp offset", OFFSET(output_ts_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E},
    82. {"max_interleave_delta", "maximum buffering duration for interleaving", OFFSET(max_interleave_delta), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT64_MAX, E },
    83. {"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"},
    84. {"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "strict"},
    85. {"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"},
    86. {"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"},
    87. {"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, D|E, "strict"},
    88. {"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, D|E, "strict"},
    89. {"experimental", "allow non-standardized experimental variants", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, D|E, "strict"},
    90. {"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 },
    91. {"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"},
    92. {"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"},
    93. {"disabled", "do not change timestamps", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_DISABLED }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
    94. {"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"},
    95. {"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"},
    96. {"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = ", "}, 0, 0, D|E},
    97. {"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
    98. {"format_whitelist", "List of demuxers that are allowed to be used", OFFSET(format_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
    99. {"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
    100. {"protocol_blacklist", "List of protocols that are not allowed to be used", OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
    101. {"max_streams", "maximum number of streams", OFFSET(max_streams), AV_OPT_TYPE_INT, { .i64 = 1000 }, 0, INT_MAX, D },
    102. {"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},
    103. {"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 },
    104. {NULL},
    105. };
    106. #undef E
    107. #undef D
    108. #undef DEFAULT
    109. #undef OFFSET
    110. #endif /* AVFORMAT_OPTIONS_TABLE_H */

    AVCodecContext中的AVClass

    • AVFormatContext 中的AVClass定义位于libavcodec\options.c中,是一个名称为av_codec_context_class的静态结构体。如下所示。
    1. static const AVClass av_codec_context_class = {
    2. .class_name = "AVCodecContext",
    3. .item_name = context_to_name,
    4. .option = avcodec_options,
    5. .version = LIBAVUTIL_VERSION_INT,
    6. .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
    7. .child_next = codec_child_next,
    8. .child_class_iterate = codec_child_class_iterate,
    9. .category = AV_CLASS_CATEGORY_ENCODER,
    10. .get_category = get_category,
    11. };
    • 从源代码可以看出:
    • (1)class_name
      • 该AVClass名称是“AVCodecContext”。
    • (2)item_name
      • item_name指向一个函数context_to_name (),该函数定义如下所示。
    1. static const char* context_to_name(void* ptr) {
    2. AVCodecContext *avc= ptr;
    3. if (avc && avc->codec)
    4. return avc->codec->name;
    5. else
    6. return "NULL";
    7. }
    •  从函数的定义可以看出,如果AVCodecContext中的Codec结构体不为空,则返回Codec的name,否则返回“NULL”。
    • (3)category
    • option字段则指向一个元素个数极多的静态数组avcodec_options。该数组单独定义于libavcodec\options_table.h中。其中包含了AVCodecContext支持的所有的AVOption。由于该数组定义实在是太多了,在这里仅贴出它前面的一小部分。
    1. /*
    2. * Copyright (c) 2001 Fabrice Bellard
    3. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
    4. *
    5. * This file is part of FFmpeg.
    6. *
    7. * FFmpeg is free software; you can redistribute it and/or
    8. * modify it under the terms of the GNU Lesser General Public
    9. * License as published by the Free Software Foundation; either
    10. * version 2.1 of the License, or (at your option) any later version.
    11. *
    12. * FFmpeg is distributed in the hope that it will be useful,
    13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    15. * Lesser General Public License for more details.
    16. *
    17. * You should have received a copy of the GNU Lesser General Public
    18. * License along with FFmpeg; if not, write to the Free Software
    19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    20. */
    21. #ifndef AVCODEC_OPTIONS_TABLE_H
    22. #define AVCODEC_OPTIONS_TABLE_H
    23. #include "config_components.h"
    24. #include <float.h>
    25. #include <limits.h>
    26. #include <stdint.h>
    27. #include "libavutil/opt.h"
    28. #include "avcodec.h"
    29. #include "version_major.h"
    30. #define OFFSET(x) offsetof(AVCodecContext,x)
    31. #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
    32. //these names are too long to be readable
    33. #define V AV_OPT_FLAG_VIDEO_PARAM
    34. #define A AV_OPT_FLAG_AUDIO_PARAM
    35. #define S AV_OPT_FLAG_SUBTITLE_PARAM
    36. #define E AV_OPT_FLAG_ENCODING_PARAM
    37. #define D AV_OPT_FLAG_DECODING_PARAM
    38. #define CC AV_OPT_FLAG_CHILD_CONSTS
    39. #define AV_CODEC_DEFAULT_BITRATE 200*1000
    40. static const AVOption avcodec_options[] = {
    41. {"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E},
    42. {"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = 128*1000 }, 0, INT_MAX, A|E},
    43. {"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far "
    44. "ratecontrol is willing to deviate from the target average bitrate value. This is not related "
    45. "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.",
    46. OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
    47. {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"},
    48. {"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" },
    49. {"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"},
    50. {"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
    51. {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
    52. {"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
    53. {"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"},
    54. {"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"},
    55. {"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
    56. {"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"},
    57. #if FF_API_FLAG_TRUNCATED
    58. {"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"},
    59. #endif
    60. {"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
    61. {"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"},
    62. {"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"},
    63. {"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"},
    64. {"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"},
    65. {"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
    66. {"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
    67. {"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"},
    68. {"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"},
    69. {"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D|S, "flags2"},
    70. {"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
    71. {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
    72. {"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
    73. {"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"},
    74. {"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"},
    75. {"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"},
    76. {"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"},
    77. {"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"},
    78. {"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"},
    79. {"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"},
    80. {"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"},
    81. {"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"},
    82. {"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"},
    83. {"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"},
    84. {"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, INT_MAX},
    85. {"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
    86. {"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
    87. #if FF_API_OLD_CHANNEL_LAYOUT
    88. {"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
    89. #endif
    90. {"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
    91. {"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|E},
    92. {"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
    93. {"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
    94. {"qcomp", "video quantizer scale compression (VBR). Constant of ratecontrol equation. "
    95. "Recommended range for default rc_eq: 0.0-1.0",
    96. OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E},
    97. {"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E},
    98. {"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E},
    99. {"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E},
    100. {"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E},
    101. {"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},
    102. {"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},
    103. {"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
    104. {"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"},
    105. {"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
    106. {"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"},
    107. {"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
    108. {"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
    109. {"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
    110. {"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
    111. {"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"},
    112. {"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
    113. {"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"},
    114. {"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"},
    115. {"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
    116. {"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"},
    117. {"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
    118. {"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"},
    119. {"iedge", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_IEDGE }, INT_MIN, INT_MAX, V|D, "bug"},
    120. {"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"},
    121. {"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"},
    122. {"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"},
    123. {"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
    124. {"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
    125. {"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
    126. {"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},
    127. {"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"},
    128. {"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
    129. {"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"},
    130. {"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"},
    131. {"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"},
    132. {"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"},
    133. {"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"},
    134. {"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"},
    135. {"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"},
    136. {"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX},
    137. {"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX},
    138. {"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
    139. {"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},
    140. {"minrate", "minimum bitrate (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.",
    141. OFFSET(rc_min_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
    142. {"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|E},
    143. {"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},
    144. {"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},
    145. {"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"},
    146. {"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
    147. {"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
    148. {"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"},
    149. {"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"},
    150. {"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"},
    151. {"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"},
    152. {"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
    153. {"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
    154. {"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
    155. {"p_mask", "inter masking", OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
    156. {"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
    157. {"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"},
    158. {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
    159. {"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
    160. {"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
    161. {"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
    162. {"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
    163. {"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
    164. {"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
    165. {"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
    166. {"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
    167. {"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
    168. {"xvid", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
    169. {"xvidmmx", "deprecated, for compatibility only", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
    170. {"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
    171. {"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
    172. {"slice_count", NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
    173. {"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 = 3 }, INT_MIN, INT_MAX, V|D, "ec"},
    174. {"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"},
    175. {"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"},
    176. {"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"},
    177. {"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX},
    178. {"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
    179. {"sar", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
    180. {"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"},
    181. {"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"},
    182. {"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"},
    183. {"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"},
    184. {"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
    185. {"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"},
    186. {"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"},
    187. {"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, "debug"},
    188. {"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"},
    189. {"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"},
    190. {"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"},
    191. {"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"},
    192. {"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"},
    193. {"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
    194. {"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"},
    195. {"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"},
    196. {"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
    197. {"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},
    198. {"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},
    199. {"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
    200. {"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},
    201. {"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
    202. {"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
    203. {"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"},
    204. {"simple", "use mbcmp", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
    205. {"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
    206. {"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"},
    207. {"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},
    208. {"threads", "set the number of threads", OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"},
    209. {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
    210. {"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, -8, 16, V|E},
    211. {"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
    212. {"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},
    213. {"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},
    214. {"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, "avctx.profile"},
    215. {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "avctx.profile"},
    216. {"main10", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, V|E, "avctx.profile"},
    217. {"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, "avctx.level"},
    218. {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "avctx.level"},
    219. {"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D},
    220. {"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    221. {"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    222. {"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    223. {"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    224. {"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    225. {"sad", "sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    226. {"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    227. {"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    228. {"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    229. {"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"},
    230. {"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"},
    231. {"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    232. {"zero", "0", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    233. {"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    234. {"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    235. {"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    236. #if CONFIG_SNOW_ENCODER
    237. {"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"},
    238. {"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"},
    239. #endif
    240. {"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    241. {"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
    242. {"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"},
    243. {"mblmin", "minimum macroblock Lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
    244. {"mblmax", "maximum macroblock Lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
    245. {"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"},
    246. {"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"},
    247. {"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"},
    248. {"none" , "discard no frame", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, INT_MIN, INT_MAX, V|D, "avdiscard"},
    249. {"default" , "discard useless frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
    250. {"noref" , "discard all non-reference frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF }, INT_MIN, INT_MAX, V|D, "avdiscard"},
    251. {"bidir" , "discard all bidirectional frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR }, INT_MIN, INT_MAX, V|D, "avdiscard"},
    252. {"nokey" , "discard all frames except keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY }, INT_MIN, INT_MAX, V|D, "avdiscard"},
    253. {"nointra" , "discard all frames except I frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, "avdiscard"},
    254. {"all" , "discard all frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, "avdiscard"},
    255. {"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, 4, V|E},
    256. {"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, V|E},
    257. {"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.i64 = 1 }, INT_MIN, INT_MAX, V|E},
    258. {"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
    259. {"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E},
    260. {"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
    261. {"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX},
    262. {"ch_layout", NULL, OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL }, 0, 0, A|E|D, "ch_layout"},
    263. #if FF_API_OLD_CHANNEL_LAYOUT
    264. {"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = DEFAULT }, 0, UINT64_MAX, A|E|D, "channel_layout"},
    265. {"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = DEFAULT }, 0, UINT64_MAX, A|D, "request_channel_layout"},
    266. #endif
    267. {"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E},
    268. {"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT, {.dbl = 3 }, 0.0, FLT_MAX, V|E},
    269. {"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D},
    270. {"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_primaries_type"},
    271. {"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    272. {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    273. {"bt470m", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    274. {"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    275. {"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    276. {"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    277. {"film", "Film", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_FILM }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    278. {"bt2020", "BT.2020", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    279. {"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    280. {"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    281. {"smpte431", "SMPTE 431-2", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE431 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    282. {"smpte432", "SMPTE 422-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE432 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    283. {"jedec-p22", "JEDEC P22", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_JEDEC_P22 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    284. {"ebu3213", "EBU 3213-E", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_EBU3213 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    285. {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
    286. {"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"},
    287. {"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    288. {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    289. {"gamma22", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    290. {"gamma28", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    291. {"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    292. {"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    293. {"linear", "Linear", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    294. {"log100", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    295. {"log316", "Log square root", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    296. {"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"},
    297. {"bt1361e", "BT.1361", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    298. {"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"},
    299. {"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"},
    300. {"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"},
    301. {"smpte2084", "SMPTE 2084", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE2084 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    302. {"smpte428", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    303. {"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"},
    304. {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    305. {"log", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    306. {"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"},
    307. {"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"},
    308. {"bt1361", "BT.1361", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    309. {"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"},
    310. {"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"},
    311. {"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"},
    312. {"smpte428_1", "SMPTE 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
    313. {"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "colorspace_type"},
    314. {"rgb", "RGB", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    315. {"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    316. {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    317. {"fcc", "FCC", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    318. {"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    319. {"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    320. {"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    321. {"ycgco", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    322. {"bt2020nc", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    323. {"bt2020c", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    324. {"smpte2085", "SMPTE 2085", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    325. {"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"},
    326. {"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"},
    327. {"ictcp", "ICtCp", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_ICTCP }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    328. {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    329. {"ycocg", "YCGCO", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    330. {"bt2020_ncl", "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    331. {"bt2020_cl", "BT.2020 CL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
    332. {"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, "color_range_type"},
    333. {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
    334. {"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"},
    335. {"pc", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
    336. {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
    337. {"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"},
    338. {"jpeg", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
    339. {"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"},
    340. {"unknown", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
    341. {"left", "Left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
    342. {"center", "Center", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
    343. {"topleft", "Top-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOPLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
    344. {"top", "Top", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOP }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
    345. {"bottomleft", "Bottom-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOMLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
    346. {"bottom", "Bottom", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOM }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
    347. {"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
    348. {"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX },
    349. {"slices", "set the number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
    350. {"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"},
    351. {"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
    352. {"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
    353. {"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"},
    354. {"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    355. {"ef", "Effects", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EFFECTS }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    356. {"vi", "Visually Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    357. {"hi", "Hearing Impaired", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    358. {"di", "Dialogue", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_DIALOGUE }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    359. {"co", "Commentary", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_COMMENTARY }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    360. {"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    361. {"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    362. {"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
    363. {"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, "request_sample_fmt"},
    364. {"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
    365. {"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, S|D},
    366. {"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"},
    367. {"do_nothing", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
    368. {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
    369. {"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
    370. {"ignore", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_IGNORE}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
    371. #if FF_API_SUB_TEXT_FORMAT
    372. {"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"},
    373. {"ass", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS}, INT_MIN, INT_MAX, S|D, "sub_text_format"},
    374. #endif
    375. {"apply_cropping", NULL, OFFSET(apply_cropping), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, V | D },
    376. {"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, V|D },
    377. {"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" },
    378. {"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" },
    379. {"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, "field_order" },
    380. {"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, "field_order" },
    381. {"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" },
    382. {"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" },
    383. {"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, A|V|S|D|E},
    384. {"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 },
    385. {"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 },
    386. {"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 },
    387. {"max_pixels", "Maximum number of pixels", OFFSET(max_pixels), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|V|S|D|E },
    388. {"max_samples", "Maximum number of samples", OFFSET(max_samples), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|D|E },
    389. {"hwaccel_flags", NULL, OFFSET(hwaccel_flags), AV_OPT_TYPE_FLAGS, {.i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, 0, UINT_MAX, V|D, "hwaccel_flags"},
    390. {"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" },
    391. {"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"},
    392. {"allow_profile_mismatch", "attempt to decode anyway if HW accelerated decoder's 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"},
    393. {"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 },
    394. {"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 },
    395. {NULL},
    396. };
    397. #undef A
    398. #undef V
    399. #undef S
    400. #undef E
    401. #undef D
    402. #undef CC
    403. #undef DEFAULT
    404. #undef OFFSET
    405. #endif /* AVCODEC_OPTIONS_TABLE_H */

    AVFrame中的AVClass

    • AVFrame 中的AVClass定义位于libavcodec\options.c中,是一个名称为av_frame_class的静态结构体。如下所示。
    1. static const AVClass av_frame_class = {
    2. .class_name = "AVFrame",
    3. .item_name = NULL,
    4. .option = frame_options,
    5. .version = LIBAVUTIL_VERSION_INT,
    6. };
    • option字段则指向一个元素个数极多的静态数组frame_options。frame_options定义如下所示。
    1. static const AVOption frame_options[]={
    2. {"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0},
    3. {"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
    4. {"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
    5. {"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
    6. {"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
    7. {"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
    8. {"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0},
    9. #if FF_API_OLD_CHANNEL_LAYOUT
    10. {"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0},
    11. #endif
    12. {"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
    13. {NULL},
    14. };
    • 可以看出AVFrame的选项数组中包含了“width”,“height”这类用于视频帧的选项,以及“channel_layout”,“sample_rate”这类用于音频帧的选项。

    各种组件特有的AVClass

    • 除了FFmpeg中通用的AVFormatContext,AVCodecContext,AVFrame这类的结构体之外,每种特定的组件也包含自己的AVClass。
    • 各种组件(libRTMP,libx264,libx265)里面特有的AVClass。
    • 下面举例几个。

    LibRTMP

    • libRTMP中根据协议类型的不同定义了多种的AVClass。由于这些AVClass除了名字不一样之外,其他的字段一模一样,所以AVClass的声明写成了一个名称为RTMP_CLASS的宏。
    1. #define RTMP_CLASS(flavor)\
    2. static const AVClass lib ## flavor ## _class = {\
    3. .class_name = "lib" #flavor " protocol",\
    4. .item_name = av_default_item_name,\
    5. .option = options,\
    6. .version = LIBAVUTIL_VERSION_INT,\
    7. };

    • 而后定义了多种AVCLass:
      • RTMP_CLASS(rtmp)
      • RTMP_CLASS(rtmpt)
      • RTMP_CLASS(rtmpe)
      • RTMP_CLASS(rtmpte)
      • RTMP_CLASS(rtmps)
    1. RTMP_CLASS(rtmp)
    2. const URLProtocol ff_librtmp_protocol = {
    3. .name = "rtmp",
    4. .url_open = rtmp_open,
    5. .url_read = rtmp_read,
    6. .url_write = rtmp_write,
    7. .url_close = rtmp_close,
    8. .url_read_pause = rtmp_read_pause,
    9. .url_read_seek = rtmp_read_seek,
    10. .url_get_file_handle = rtmp_get_file_handle,
    11. .priv_data_size = sizeof(LibRTMPContext),
    12. .priv_data_class = &librtmp_class,
    13. .flags = URL_PROTOCOL_FLAG_NETWORK,
    14. };
    15. RTMP_CLASS(rtmpt)
    16. const URLProtocol ff_librtmpt_protocol = {
    17. .name = "rtmpt",
    18. .url_open = rtmp_open,
    19. .url_read = rtmp_read,
    20. .url_write = rtmp_write,
    21. .url_close = rtmp_close,
    22. .url_read_pause = rtmp_read_pause,
    23. .url_read_seek = rtmp_read_seek,
    24. .url_get_file_handle = rtmp_get_file_handle,
    25. .priv_data_size = sizeof(LibRTMPContext),
    26. .priv_data_class = &librtmpt_class,
    27. .flags = URL_PROTOCOL_FLAG_NETWORK,
    28. };
    29. RTMP_CLASS(rtmpe)
    30. const URLProtocol ff_librtmpe_protocol = {
    31. .name = "rtmpe",
    32. .url_open = rtmp_open,
    33. .url_read = rtmp_read,
    34. .url_write = rtmp_write,
    35. .url_close = rtmp_close,
    36. .url_read_pause = rtmp_read_pause,
    37. .url_read_seek = rtmp_read_seek,
    38. .url_get_file_handle = rtmp_get_file_handle,
    39. .priv_data_size = sizeof(LibRTMPContext),
    40. .priv_data_class = &librtmpe_class,
    41. .flags = URL_PROTOCOL_FLAG_NETWORK,
    42. };
    43. RTMP_CLASS(rtmpte)
    44. const URLProtocol ff_librtmpte_protocol = {
    45. .name = "rtmpte",
    46. .url_open = rtmp_open,
    47. .url_read = rtmp_read,
    48. .url_write = rtmp_write,
    49. .url_close = rtmp_close,
    50. .url_read_pause = rtmp_read_pause,
    51. .url_read_seek = rtmp_read_seek,
    52. .url_get_file_handle = rtmp_get_file_handle,
    53. .priv_data_size = sizeof(LibRTMPContext),
    54. .priv_data_class = &librtmpte_class,
    55. .flags = URL_PROTOCOL_FLAG_NETWORK,
    56. };
    57. RTMP_CLASS(rtmps)
    58. const URLProtocol ff_librtmps_protocol = {
    59. .name = "rtmps",
    60. .url_open = rtmp_open,
    61. .url_read = rtmp_read,
    62. .url_write = rtmp_write,
    63. .url_close = rtmp_close,
    64. .url_read_pause = rtmp_read_pause,
    65. .url_read_seek = rtmp_read_seek,
    66. .url_get_file_handle = rtmp_get_file_handle,
    67. .priv_data_size = sizeof(LibRTMPContext),
    68. .priv_data_class = &librtmps_class,
    69. .flags = URL_PROTOCOL_FLAG_NETWORK,
    70. };
    • 这些AVClass的option字段指向的数组是一样的,如下所示。
    1. #define OFFSET(x) offsetof(LibRTMPContext, x)
    2. #define DEC AV_OPT_FLAG_DECODING_PARAM
    3. #define ENC AV_OPT_FLAG_ENCODING_PARAM
    4. static const AVOption options[] = {
    5. {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
    6. {"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},
    7. {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
    8. {"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},
    9. {"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"},
    10. {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
    11. {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
    12. {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
    13. {"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},
    14. {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
    15. {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
    16. {"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},
    17. {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically. (unimplemented)", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
    18. {"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},
    19. #if CONFIG_NETWORK
    20. {"rtmp_buffer_size", "set buffer size in bytes", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, DEC|ENC },
    21. #endif
    22. { NULL },
    23. };

    Libx264

    • Libx264的AVClass定义如下所示。
    1. #if CONFIG_LIBX264_ENCODER
    2. static const AVClass x264_class = {
    3. .class_name = "libx264",
    4. .item_name = av_default_item_name,
    5. .option = options,
    6. .version = LIBAVUTIL_VERSION_INT,
    7. };
    • 其中option字段指向的数组定义如下所示。这些option的使用频率还是比较高的。
    1. static const AVOption options[] = {
    2. { "preset", "Set the encoding preset (cf. x264 --fullhelp)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE},
    3. { "tune", "Tune the encoding params (cf. x264 --fullhelp)", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
    4. { "profile", "Set profile restrictions (cf. x264 --fullhelp) ", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
    5. { "fastfirstpass", "Use fast settings when encoding first pass", OFFSET(fastfirstpass), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE},
    6. {"level", "Specify level (as defined by Annex A)", OFFSET(level), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
    7. {"passlogfile", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
    8. {"wpredp", "Weighted prediction for P-frames", OFFSET(wpredp), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
    9. {"a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, VE},
    10. {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
    11. { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE },
    12. { "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 },
    13. { "qp", "Constant quantization parameter rate control method",OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE },
    14. { "aq-mode", "AQ method", OFFSET(aq_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "aq_mode"},
    15. { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_NONE}, INT_MIN, INT_MAX, VE, "aq_mode" },
    16. { "variance", "Variance AQ (complexity mask)", 0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_VARIANCE}, INT_MIN, INT_MAX, VE, "aq_mode" },
    17. { "autovariance", "Auto-variance AQ", 0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_AUTOVARIANCE}, INT_MIN, INT_MAX, VE, "aq_mode" },
    18. #if X264_BUILD >= 144
    19. { "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" },
    20. #endif
    21. { "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},
    22. { "psy", "Use psychovisual optimizations.", OFFSET(psy), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
    23. { "psy-rd", "Strength of psychovisual optimization, in <psy-rd>:<psy-trellis> format.", OFFSET(psy_rd), AV_OPT_TYPE_STRING, {0 }, 0, 0, VE},
    24. { "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 },
    25. { "weightb", "Weighted prediction for B-frames.", OFFSET(weightb), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
    26. { "weightp", "Weighted prediction analysis method.", OFFSET(weightp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "weightp" },
    27. { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_NONE}, INT_MIN, INT_MAX, VE, "weightp" },
    28. { "simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SIMPLE}, INT_MIN, INT_MAX, VE, "weightp" },
    29. { "smart", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SMART}, INT_MIN, INT_MAX, VE, "weightp" },
    30. { "ssim", "Calculate and print SSIM stats.", OFFSET(ssim), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
    31. { "intra-refresh", "Use Periodic Intra Refresh instead of IDR frames.",OFFSET(intra_refresh),AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
    32. { "bluray-compat", "Bluray compatibility workarounds.", OFFSET(bluray_compat) ,AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
    33. { "b-bias", "Influences how often B-frames are used", OFFSET(b_bias), AV_OPT_TYPE_INT, { .i64 = INT_MIN}, INT_MIN, INT_MAX, VE },
    34. { "b-pyramid", "Keep some B-frames as references.", OFFSET(b_pyramid), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "b_pyramid" },
    35. { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NONE}, INT_MIN, INT_MAX, VE, "b_pyramid" },
    36. { "strict", "Strictly hierarchical pyramid", 0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_STRICT}, INT_MIN, INT_MAX, VE, "b_pyramid" },
    37. { "normal", "Non-strict (not Blu-ray compatible)", 0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NORMAL}, INT_MIN, INT_MAX, VE, "b_pyramid" },
    38. { "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 },
    39. { "8x8dct", "High profile 8x8 transform.", OFFSET(dct8x8), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE},
    40. { "fast-pskip", NULL, OFFSET(fast_pskip), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE},
    41. { "aud", "Use access unit delimiters.", OFFSET(aud), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE},
    42. { "mbtree", "Use macroblock tree ratecontrol.", OFFSET(mbtree), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE},
    43. { "deblock", "Loop filter parameters, in <alpha:beta> form.", OFFSET(deblock), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
    44. { "cplxblur", "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE},
    45. { "partitions", "A comma-separated list of partitions to consider. "
    46. "Possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all", OFFSET(partitions), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
    47. { "direct-pred", "Direct MV prediction mode", OFFSET(direct_pred), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "direct-pred" },
    48. { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_NONE }, 0, 0, VE, "direct-pred" },
    49. { "spatial", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_SPATIAL }, 0, 0, VE, "direct-pred" },
    50. { "temporal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" },
    51. { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_AUTO }, 0, 0, VE, "direct-pred" },
    52. { "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 },
    53. { "stats", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
    54. { "nal-hrd", "Signal HRD information (requires vbv-bufsize; "
    55. "cbr not allowed in .mp4)", OFFSET(nal_hrd), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "nal-hrd" },
    56. { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_NONE}, INT_MIN, INT_MAX, VE, "nal-hrd" },
    57. { "vbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_VBR}, INT_MIN, INT_MAX, VE, "nal-hrd" },
    58. { "cbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_CBR}, INT_MIN, INT_MAX, VE, "nal-hrd" },
    59. { "avcintra-class","AVC-Intra class 50/100/200/300/480", OFFSET(avcintra_class),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 480 , VE},
    60. { "me_method", "Set motion estimation method", OFFSET(motion_est), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, X264_ME_TESA, VE, "motion-est"},
    61. { "motion-est", "Set motion estimation method", OFFSET(motion_est), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, X264_ME_TESA, VE, "motion-est"},
    62. { "dia", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_ME_DIA }, INT_MIN, INT_MAX, VE, "motion-est" },
    63. { "hex", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_ME_HEX }, INT_MIN, INT_MAX, VE, "motion-est" },
    64. { "umh", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_ME_UMH }, INT_MIN, INT_MAX, VE, "motion-est" },
    65. { "esa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_ME_ESA }, INT_MIN, INT_MAX, VE, "motion-est" },
    66. { "tesa", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = X264_ME_TESA }, INT_MIN, INT_MAX, VE, "motion-est" },
    67. { "forced-idr", "If forcing keyframes, force them as IDR frames.", OFFSET(forced_idr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, -1, 1, VE },
    68. { "coder", "Coder type", OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE, "coder" },
    69. { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, VE, "coder" },
    70. { "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "coder" },
    71. { "cabac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "coder" },
    72. { "vlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "coder" },
    73. { "ac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "coder" },
    74. { "b_strategy", "Strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 2, VE },
    75. { "chromaoffset", "QP difference between chroma and luma", OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, VE },
    76. { "sc_threshold", "Scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE },
    77. { "noise_reduction", "Noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE },
    78. { "udu_sei", "Use user data unregistered SEI if available", OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
    79. { "x264-params", "Override the x264 configuration using a :-separated list of key=value parameters", OFFSET(x264_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
    80. { NULL },
    81. };

    Libx265

    • Libx265的AVClass定义如下所示。
    1. static const AVClass class = {
    2. .class_name = "libx265",
    3. .item_name = av_default_item_name,
    4. .option = options,
    5. .version = LIBAVUTIL_VERSION_INT,
    6. };
    • 其中option字段指向的数组定义如下所示。
    1. static const AVOption options[] = {
    2. { "crf", "set the x265 crf", OFFSET(crf), AV_OPT_TYPE_FLOAT, { .dbl = -1 }, -1, FLT_MAX, VE },
    3. { "qp", "set the x265 qp", OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE },
    4. { "forced-idr", "if forcing keyframes, force them as IDR frames", OFFSET(forced_idr),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
    5. { "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
    6. { "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
    7. { "profile", "set the x265 profile", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
    8. { "udu_sei", "Use user data unregistered SEI if available", OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
    9. { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
    10. { NULL }
    11. };

    官方代码中有关AVClass和AVOption的示例

    • 官方代码中给出了一小段示例代码,演示了如何给一个普通的结构体添加AVOption的支持。如下所示。
    1. typedef struct test_struct {
    2. AVClass *class;
    3. int int_opt;
    4. char str_opt;
    5. uint8_t bin_opt;
    6. int bin_len;
    7. } test_struct;
    8. static const AVOption test_options[] = {
    9. { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt),
    10. AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX },
    11. { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt),
    12. AV_OPT_TYPE_STRING },
    13. { "test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt),
    14. AV_OPT_TYPE_BINARY },
    15. { NULL },
    16. };
    17. static const AVClass test_class = {
    18. .class_name = "test class",
    19. .item_name = av_default_item_name,
    20. .option = test_options,
    21. .version = LIBAVUTIL_VERSION_INT,
    22. };

    AVClass有关的API

    • 与AVClass相关的API很少。AVFormatContext提供了一个获取当前AVClass的函数avformat_get_class()。
    • 它的代码很简单,直接返回全局静态变量av_format_context_class。
    • 定义如下所示。
    1. const AVClass *avformat_get_class(void)
    2. {
    3. return &av_format_context_class;
    4. }
    • 同样,AVCodecContext也提供了一个获取当前AVClass的函数avcodec_get_class()。
    • 它直接返回静态变量av_codec_context_class。
    • 定义如下所示。
    1. const AVClass *avcodec_get_class(void)
    2. {
    3. return &av_codec_context_class;
    4. }

  • 相关阅读:
    【二叉树】层数最深叶子节点的和
    数据结构-堆排序Java实现
    模型进行MindIR格式文件导出时报错,请问如何定位错误,以及如何解决?
    超800万辆「巨量」市场,谁在进攻智能驾驶「普及型」赛道
    Spring(01)
    ubuntu 通过apt-get快速安装 docker
    idea项目层级不见了
    数字孪生智慧机场三维Web3D可视化运营决策系统
    Android内存优化/内存泄漏排查
    【vue】使用无障碍工具条(详细)
  • 原文地址:https://blog.csdn.net/CHYabc123456hh/article/details/125417650