ffmpeg结构体解析-AVClass 和 AVOption

AVClass

先来看 AVClass 的结构如下:

/**
 * Describe the class of an AVClass context structure. That is an
 * arbitrary struct of which the first field is a pointer to an
 * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
 */
typedef struct AVClass {
    /**
     * The name of the class; usually it is the same name as the
     * context structure type to which the AVClass is associated.
     */
    const char* class_name;

    /**
     * A pointer to a function which returns the name of a context
     * instance ctx associated with the class.
     */
    const char* (*item_name)(void* ctx);

    /**
     * a pointer to the first option specified in the class if any or NULL
     *
     * @see av_set_default_options()
     */
    const struct AVOption *option;

    /**
     * LIBAVUTIL_VERSION with which this structure was created.
     * This is used to allow fields to be added without requiring major
     * version bumps everywhere.
     */

    int version;

    /**
     * Offset in the structure where log_level_offset is stored.
     * 0 means there is no such variable
     */
    int log_level_offset_offset;

    /**
     * Offset in the structure where a pointer to the parent context for
     * logging is stored. For example a decoder could pass its AVCodecContext
     * to eval as such a parent context, which an av_log() implementation
     * could then leverage to display the parent context.
     * The offset can be NULL.
     */
    int parent_log_context_offset;

    /**
     * Return next AVOptions-enabled child or NULL
     */
    void* (*child_next)(void *obj, void *prev);

    /**
     * Return an AVClass corresponding to the next potential
     * AVOptions-enabled child.
     *
     * The difference between child_next and this is that
     * child_next iterates over _already existing_ objects, while
     * child_class_next iterates over _all possible_ children.
     */
    const struct AVClass* (*child_class_next)(const struct AVClass *prev);

    /**
     * Category used for visualization (like color)
     * This is only set if the category is equal for all objects using this class.
     * available since version (51 << 16 | 56 << 8 | 100)
     */
    AVClassCategory category;

    /**
     * Callback to return the category.
     * available since version (51 << 16 | 59 << 8 | 100)
     */
    AVClassCategory (*get_category)(void* ctx);

    /**
     * Callback to return the supported/allowed ranges.
     * available since version (52.12)
     */
    int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags);
} AVClass;

根据 API 的意思,AVClass 就是用于描述任意包含 AVClass 的一个 Context 的信息类,并且会出现在该 Context 类的第一个字段。然后看下 AVClass 结构体的字段如下:

  • const char* class_name:表示Context 类的名称,一般和描述的 Context 类的类名/结构体名一致

  • const char* (item_name)(void ctx):可以返回该 Context 类实例的一个函数

  • const struct AVOption *option:AcOption 数组

  • version:创建该结构体的版本号

  • log_level_offset_offset:表示 level_offset_offset 字段在这个结构体的偏移量,如果没有这个字段则为0

  • parent_log_context_offset:同上,表示的是 Parent Context 的 level_offset_offset 字段在这个结构体的偏移量

  • void* (*child_next)(void *obj, void *prev):一个返回下一个 AVOption 的函数指针

  • const struct AVClass* (*child_class_next)(const struct AVClass *prev)

  • AVClassCategory category:表示 AVClass 的类型,是一组枚举类型的值,见后面备注。

  • AVClassCategory (get_category)(void ctx):

  • int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags):

 

在 AVFormatContext 或者 AVCodecContext 等类里面,第一个字段都是 AVClass 指针,以AVFormatContext示例,如下:


//avformat.h
typedef struct AVFormatContext {
/**
* A class for logging and @ref avoptions. Set by avformat_alloc_context().
* Exports (de)muxer private options if they exist.
*/
const AVClass *av_class;
//省略其它代码

根据API的介绍,AVClass 就是一个用于打印log 和AVOption的引用,由avformat_alloc_context() 函数创建。怎么理解这个引用呢?

就是说,AVClass 建立起了 AVOption 和 Context 之间的桥梁。

AVOption 结构体
那么这样一说,必须先来看下 AVOption 这个结构体。

先看 API 对 AVOption 结构体的说明,如下:

* AVOptions provide a generic system to declare options on arbitrary structs
* ("objects"). An option can have a help text, a type and a range of possible
* values. Options may then be enumerated, read and written to.
*
* @section avoptions_implement Implementing AVOptions
* This section describes how to add AVOptions capabilities to a struct.
*
* All AVOptions-related information is stored in an AVClass. Therefore
* the first member of the struct should be a pointer to an AVClass describing it.
* The option field of the AVClass must be set to a NULL-terminated static array
* of AVOptions. Each AVOption must have a non-empty name, a type, a default
* value and for number-type AVOptions also a range of allowed values. It must
* also declare an offset in bytes from the start of the struct, where the field
* associated with this AVOption is located. Other fields in the AVOption struct
* should also be set when applicable, but are not required.

AVOption 提供了一种泛型系统用于描述任意结构体的 Option。所有 AVOption 相关的信息都是存储在 AVClass 里面的。因此所以AVOption 描述的结构体的第一个字段必定是 AVClass,其次AVClass 必须包含一个静态的 AVOption 数组。

AVOption 的定义在 libutils/opts.h 头文件中,如下:

/**
 * AVOption
 */
typedef struct AVOption {
    const char *name;

    /**
     * short English help text
     * @todo What about other languages?
     */
    const char *help;

    /**
     * The offset relative to the context structure where the option
     * value is stored. It should be 0 for named constants.
     */
    int offset;
    enum AVOptionType type;

    /**
     * the default value for scalar options
     */
    union {
        int64_t i64;
        double dbl;
        const char *str;
        /* TODO those are unused now */
        AVRational q;
    } default_val;
    double min;                 ///< minimum valid value for the option
    double max;                 ///< maximum valid value for the option

    int flags;
#define AV_OPT_FLAG_ENCODING_PARAM  1   ///< a generic parameter which can be set by the user for muxing or encoding
#define AV_OPT_FLAG_DECODING_PARAM  2   ///< a generic parameter which can be set by the user for demuxing or decoding
#define AV_OPT_FLAG_AUDIO_PARAM     8
#define AV_OPT_FLAG_VIDEO_PARAM     16
#define AV_OPT_FLAG_SUBTITLE_PARAM  32
/**
 * The option is intended for exporting values to the caller.
 */
#define AV_OPT_FLAG_EXPORT          64
/**
 * The option may not be set through the AVOptions API, only read.
 * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set.
 */
#define AV_OPT_FLAG_READONLY        128
#define AV_OPT_FLAG_BSF_PARAM       (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering
#define AV_OPT_FLAG_RUNTIME_PARAM   (1<<15) ///< a generic parameter which can be set by the user at runtime
#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
#define AV_OPT_FLAG_DEPRECATED      (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information
#define AV_OPT_FLAG_CHILD_CONSTS    (1<<18) ///< set if option constants can also reside in child objects
//FIXME think about enc-audio, ... style flags

    /**
     * The logical unit to which the option belongs. Non-constant
     * options and corresponding named constants share the same
     * unit. May be NULL.
     */
    const char *unit;
} AVOption;

来看下 AVOption 结构体的字段:

const char *name:Context Struc 结构体的字段名称

const char *help:帮助说明

int offset:表示该字段在结构体中的偏移量,一般可以使用 C标准库的 offsetof(type, member-designator) 计算该字体在结构体中的偏移量

enum AVOptionType type:枚举值,表示该字段的类型,后面讲解

default_val: 默认数值,可以是 int,double,字符串任意类型。

min max:这两个字段表示取值范围,限定了该字段的取值范围

int flags:类型标记位,取值如描述

const char *unit:该选项所属的逻辑单元,可以为空



作者:kotlon
链接:https://www.jianshu.com/p/25a087619b7c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


posted on 2024-06-06 16:24  粒子少爷  阅读(5)  评论(0编辑  收藏  举报