AVOption用于描述结构体中的成员变量。它最主要的作用可以概括为两个字:“赋值”。
一个AVOption结构体包含了变量名称,简短的帮助,取值等信息。

所有和AVOption有关的数据都存储在AVClass结构体中。如果一个结构体(例如AVFormatContext或者AVCodecContext)想要支持AVOption的话,它的第一个成员变量必须是一个指向AVClass结构体的指针。该AVClass中的成员变量option必须指向一个AVOption类型的静态数组。



何为AVOption?

AVOption是用来设置FFmpeg中变量值的结构体。特点就在于它赋值的灵活性。AVOption可以使用字符串为任何类型的变量赋值。统一使用字符串赋值。例如给int型变量qp设定值为20,通过AVOption需要传递进去一个内容为“20”的字符串。

此外,AVOption中变量的名称也使用字符串来表示。传递两个字符串(一个是变量的名称,一个是变量的值)就可以改变系统中变量的值。

对于从外部系统中调用FFmpeg的人来说,作用就很大了:从外部系统中只可以传递字符串给内部系统。比如说对于直接调用ffmpeg.exe的人来说,他们是无法修改FFmpeg内部各个变量的数值的,这种情况下只能通过输入“名称”和“值”这样的字符串,通过AVOption改变FFmpeg内部变量的值。由此可见,使用AVOption可以使FFmpeg更加适应多种多样的外部系统。如互联网上只可以传输字符串。

其实除了可以对FFmpeg常用结构体AVFormatContext,AVCodecContext等进行赋值之外,还可以对它们的私有数据priv_data进行赋值。例如使用libx264进行编码的时候,通过AVCodecContext的priv_data字段可以对X264Context结构体中的变量进行赋值,设置preset,profile等。使用libx265进行编码的时候,通过AVCodecContext的priv_data字段可以对libx265Context结构体中的变量进行赋值,设置preset,tune等。

何为AVClass?

AVClass最主要的作用就是给结构体(例如AVFormatContext等)增加AVOption功能的支持。AVClass就是AVOption和目标结构体之间的“桥梁”。AVClass要求必须声明为目标结构体的第一个变量。

AVClass中有一个option数组用于存储目标结构体的所有的AVOption。举个例子,AVFormatContext结构体,AVClass和AVOption之间的关系如下图所示。

static const AVClass av_format_context_class = {

    .class_name     = "AVFormatContext",
    .item_name      = format_to_name,
    .option         = avformat_options,
    .version        = LIBAVUTIL_VERSION_INT,
    .child_next     = format_child_next,
    .child_class_next = format_child_class_next,
    .category       = AV_CLASS_CATEGORY_MUXER,
    .get_category   = get_category,
};
static const AVOption avformat_options[] = {
{"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"},
{"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"},
{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT64, {.i64 = 5000000 }, 32, INT64_MAX, D},


AVOption

  1. /** 
  2.  * AVOption 
  3.  */  
  4. typedef struct AVOption {  
  5.     const char *name;  名称。
  6.   
  7.     /** 
  8.      * short English help text 
  9.      * @todo What about other languages? 
  10.      */  
  11.     const char *help;  简短的帮助。
  12.   
  13.     /** 
  14.      * The offset relative to the context structure where the option 
  15.      * value is stored. It should be 0 for named constants. 
  16.      */  
  17.     int offset;  选项相对结构体首部地址的偏移量(这个很重要)。
  18.     enum AVOptionType type;  选项的类型
  19.   
  20.     /** 
  21.      * the default value for scalar options 
  22.      */  
  23.     union {  
  24.         int64_t i64;  
  25.         double dbl;  
  26.         const char *str;  
  27.         /* TODO those are unused now */  
  28.         AVRational q;  
  29.     } default_val;  选项的默认值。
  30.     double min;                 ///< minimum valid value for the option  选项的最小值。
  31.     double max;                 ///< maximum valid value for the option  选项的最大值。
  32.   
  33.     int flags;  一些标记。
  34.   
  35.     /** 
  36.      * The logical unit to which the option belongs. Non-constant 
  37.      * options and corresponding named constants share the same 
  38.      * unit. May be NULL. 
  39.      */  
  40.     const char *unit;  该选项所属的逻辑单元,可以为空。
  41. } AVOption;  
其中,default_val是一个union类型的变量,可以根据选项数据类型的不同,取int,double,char*,AVRational(表示分数)几种类型。



AVClass

AVClass中存储了AVOption类型的数组option,用于存储选项信息。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;  AVClass名称。
  12.   
  13.     /** 
  14.      * A pointer to a function which returns the name of a context 
  15.      * instance ctx associated with the class. 
  16.      */  
  17.     const char* (*item_name)(void* ctx);函数,获取与AVClass相关联的结构体实例的名称。
  18.   
  19.     /** 
  20.      * a pointer to the first option specified in the class if any or NULL 
  21.      * 
  22.      * @see av_set_default_options() 
  23.      */  
  24.     const struct AVOption *option;  AVOption类型的数组(最重要)。
  25.   
  26.     /** 
  27.      * LIBAVUTIL_VERSION with which this structure was created. 
  28.      * This is used to allow fields to be added without requiring major 
  29.      * version bumps everywhere. 
  30.      */  
  31.   
  32.     int version;  完成该AVClass的时候的LIBAVUTIL_VERSION。
  33.   
  34.     /** 
  35.      * Offset in the structure where log_level_offset is stored. 
  36.      * 0 means there is no such variable 
  37.      */  
  38.     int log_level_offset_offset;  
  39.   
  40.     /** 
  41.      * Offset in the structure where a pointer to the parent context for 
  42.      * logging is stored. For example a decoder could pass its AVCodecContext 
  43.      * to eval as such a parent context, which an av_log() implementation 
  44.      * could then leverage to display the parent context. 
  45.      * The offset can be NULL. 
  46.      */  
  47.     int parent_log_context_offset;  
  48.   
  49.     /** 
  50.      * Return next AVOptions-enabled child or NULL 
  51.      */  
  52.     void* (*child_next)(void *obj, void *prev);  
  53.   
  54.     /** 
  55.      * Return an AVClass corresponding to the next potential 
  56.      * AVOptions-enabled child. 
  57.      * 
  58.      * The difference between child_next and this is that 
  59.      * child_next iterates over _already existing_ objects, while 
  60.      * child_class_next iterates over _all possible_ children. 
  61.      */  
  62.     const struct AVClass* (*child_class_next)(const struct AVClass *prev);  
  63.   
  64.     /** 
  65.      * Category used for visualization (like color) 
  66.      * This is only set if the category is equal for all objects using this class. 
  67.      * available since version (51 << 16 | 56 << 8 | 100) 
  68.      */  
  69.     AVClassCategory category;  AVClass的类型,是一个类型为AVClassCategory的枚举型变量。
  70.   
  71.     /** 
  72.      * Callback to return the category. 
  73.      * available since version (51 << 16 | 59 << 8 | 100) 
  74.      */  
  75.     AVClassCategory (*get_category)(void* ctx);  
  76.   
  77.     /** 
  78.      * Callback to return the supported/allowed ranges. 
  79.      * available since version (52.12) 
  80.      */  
  81.     int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags);  
  82. } AVClass;  


下面通过具体的例子看一下AVClass这个结构体。我们看几个具体的例子:

  • AVFormatContext中的AVClass
  • AVCodecContext中的AVClass
  • AVFrame中的AVClass
  • 各种组件(libRTMP,libx264,libx265)里面特有的AVClass。


AVFormatContext

AVFormatContext 中的AVClass定义位于libavformat\options.c中,是一个名称为av_format_context_class的静态结构体。如下所示。

相关文章:

  • 2021-07-07
  • 2021-10-06
  • 2021-07-27
  • 2021-10-13
  • 2021-10-14
  • 2021-06-23
猜你喜欢
  • 2021-12-21
  • 2022-12-23
  • 2022-12-23
  • 2021-06-15
  • 2021-10-29
  • 2022-12-23
  • 2021-12-02
相关资源
相似解决方案