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之间的关系如下图所示。

图中AVFormatContext结构体的第一个变量为AVClass类型的指针av_class,它在AVFormatContext结构体初始化的时候,被赋值指向了全局静态变量av_format_context_class结构体(定义位于libavformat\options.c)。而AVClass类型的av_format_context_class结构体中的option变量指向了全局静态数组avformat_options(定义位于libavformat\options_table.h)。

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. * 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. /**
  31. * The logical unit to which the option belongs. Non-constant
  32. * options and corresponding named constants share the same
  33. * unit. May be NULL.
  34. */
  35. const char *unit;  该选项所属的逻辑单元,可以为空。
  36. } 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. * 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);函数,获取与AVClass相关联的结构体实例的名称。
  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;  AVOption类型的数组(最重要)。
  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;  完成该AVClass的时候的LIBAVUTIL_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. * Return next AVOptions-enabled child or NULL
  44. */
  45. void* (*child_next)(void *obj, void *prev);
  46. /**
  47. * Return an AVClass corresponding to the next potential
  48. * AVOptions-enabled child.
  49. *
  50. * The difference between child_next and this is that
  51. * child_next iterates over _already existing_ objects, while
  52. * child_class_next iterates over _all possible_ children.
  53. */
  54. const struct AVClass* (*child_class_next)(const struct AVClass *prev);
  55. /**
  56. * Category used for visualization (like color)
  57. * This is only set if the category is equal for all objects using this class.
  58. * available since version (51 << 16 | 56 << 8 | 100)
  59. */
  60. AVClassCategory category;  AVClass的类型,是一个类型为AVClassCategory的枚举型变量。
  61. /**
  62. * Callback to return the category.
  63. * available since version (51 << 16 | 59 << 8 | 100)
  64. */
  65. AVClassCategory (*get_category)(void* ctx);
  66. /**
  67. * Callback to return the supported/allowed ranges.
  68. * available since version (52.12)
  69. */
  70. int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags);
  71. } AVClass;

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

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

AVFormatContext

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_next = format_child_class_next,
  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


AVCodecContext

位于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_next        = codec_child_class_next,
  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 && avc->codec->name)
  4. return avc->codec->name;
  5. else
  6. return "NULL";
  7. }

从函数的定义可以看出,如果AVCodecContext中的Codec结构体不为空,则返回Codec(AVCodec类型的)的name,否则返回“NULL”。
(3)option
option字段则指向一个元素个数极多的静态数组avcodec_options。该数组单独定义于libavcodec\options_table.h中。其中包含了AVCodecContext支持的所有的AVOption

注:编码参数设置估计就是在这里

AVFrame

位于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. {"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0},
  10. {"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
  11. {NULL},
  12. };

可以看出AVFrame的选项数组中包含了“width”,“height”这类用于视频帧的选项,以及“channel_layout”,“sample_rate”这类用于音频帧的选项。


各种组件特有的AVClass

除了FFmpeg中通用的AVFormatContext,AVCodecContext,AVFrame这类的结构体之外,每种特定的组件也包含自己的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:

  1. RTMP_CLASS(rtmp)
  2. RTMP_CLASS(rtmpt)
  3. RTMP_CLASS(rtmpe)
  4. RTMP_CLASS(rtmpte)
  5. RTMP_CLASS(rtmps)

这些AVClass的option字段指向的数组是一样的,如下所示。

  1. static const AVOption options[] = {
  2. {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
  3. {"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},
  4. {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
  5. {"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},
  6. {"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"},
  7. {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
  8. {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
  9. {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
  10. {"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},
  11. {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
  12. {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
  13. {"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},
  14. {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically. (unimplemented)", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
  15. {"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},
  16. { NULL },
  17. };

Libx264

Libx264的AVClass定义如下所示。

  1. static const AVClass x264_class = {
  2. .class_name = "libx264",
  3. .item_name  = av_default_item_name,
  4. .option     = options,
  5. .version    = LIBAVUTIL_VERSION_INT,
  6. };

其中option字段指向的数组定义如下所示。这些option的使用频率还是比较高的。

注:x264编码参数应该通过这里设置吧?
[
  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_INT,    { .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. {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
  10. { "crf",           "Select the quality for constant quality mode",    OFFSET(crf),           AV_OPT_TYPE_FLOAT,  {.dbl = -1 }, -1, FLT_MAX, VE },
  11. { "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 },
  12. { "qp",            "Constant quantization parameter rate control method",OFFSET(cqp),        AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE },
  13. { "aq-mode",       "AQ method",                                       OFFSET(aq_mode),       AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE, "aq_mode"},
  14. { "none",          NULL,                              0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_NONE},         INT_MIN, INT_MAX, VE, "aq_mode" },
  15. { "variance",      "Variance AQ (complexity mask)",   0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_VARIANCE},     INT_MIN, INT_MAX, VE, "aq_mode" },
  16. { "autovariance",  "Auto-variance AQ (experimental)", 0, AV_OPT_TYPE_CONST, {.i64 = X264_AQ_AUTOVARIANCE}, INT_MIN, INT_MAX, VE, "aq_mode" },
  17. { "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},
  18. { "psy",           "Use psychovisual optimizations.",                 OFFSET(psy),           AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
  19. { "psy-rd",        "Strength of psychovisual optimization, in <psy-rd>:<psy-trellis> format.", OFFSET(psy_rd), AV_OPT_TYPE_STRING,  {0 }, 0, 0, VE},
  20. { "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 },
  21. { "weightb",       "Weighted prediction for B-frames.",               OFFSET(weightb),       AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
  22. { "weightp",       "Weighted prediction analysis method.",            OFFSET(weightp),       AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE, "weightp" },
  23. { "none",          NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_NONE},   INT_MIN, INT_MAX, VE, "weightp" },
  24. { "simple",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SIMPLE}, INT_MIN, INT_MAX, VE, "weightp" },
  25. { "smart",         NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SMART},  INT_MIN, INT_MAX, VE, "weightp" },
  26. { "ssim",          "Calculate and print SSIM stats.",                 OFFSET(ssim),          AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
  27. { "intra-refresh", "Use Periodic Intra Refresh instead of IDR frames.",OFFSET(intra_refresh),AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
  28. { "bluray-compat", "Bluray compatibility workarounds.",               OFFSET(bluray_compat) ,AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
  29. { "b-bias",        "Influences how often B-frames are used",          OFFSET(b_bias),        AV_OPT_TYPE_INT,    { .i64 = INT_MIN}, INT_MIN, INT_MAX, VE },
  30. { "b-pyramid",     "Keep some B-frames as references.",               OFFSET(b_pyramid),     AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE, "b_pyramid" },
  31. { "none",          NULL,                                  0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NONE},   INT_MIN, INT_MAX, VE, "b_pyramid" },
  32. { "strict",        "Strictly hierarchical pyramid",       0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_STRICT}, INT_MIN, INT_MAX, VE, "b_pyramid" },
  33. { "normal",        "Non-strict (not Blu-ray compatible)", 0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NORMAL}, INT_MIN, INT_MAX, VE, "b_pyramid" },
  34. { "mixed-refs",    "One reference per partition, as opposed to one reference per macroblock", OFFSET(mixed_refs), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, VE },
  35. { "8x8dct",        "High profile 8x8 transform.",                     OFFSET(dct8x8),        AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE},
  36. { "fast-pskip",    NULL,                                              OFFSET(fast_pskip),    AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE},
  37. { "aud",           "Use access unit delimiters.",                     OFFSET(aud),           AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE},
  38. { "mbtree",        "Use macroblock tree ratecontrol.",                OFFSET(mbtree),        AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE},
  39. { "deblock",       "Loop filter parameters, in <alpha:beta> form.",   OFFSET(deblock),       AV_OPT_TYPE_STRING, { 0 },  0, 0, VE},
  40. { "cplxblur",      "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), AV_OPT_TYPE_FLOAT,  {.dbl = -1 }, -1, FLT_MAX, VE},
  41. { "partitions",    "A comma-separated list of partitions to consider. "
  42. "Possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all", OFFSET(partitions), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
  43. { "direct-pred",   "Direct MV prediction mode",                       OFFSET(direct_pred),   AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE, "direct-pred" },
  44. { "none",          NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_NONE },     0, 0, VE, "direct-pred" },
  45. { "spatial",       NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_SPATIAL },  0, 0, VE, "direct-pred" },
  46. { "temporal",      NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" },
  47. { "auto",          NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = X264_DIRECT_PRED_AUTO },     0, 0, VE, "direct-pred" },
  48. { "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 },
  49. { "stats",         "Filename for 2 pass stats",                       OFFSET(stats),         AV_OPT_TYPE_STRING, { 0 },  0,       0, VE },
  50. { "nal-hrd",       "Signal HRD information (requires vbv-bufsize; "
  51. "cbr not allowed in .mp4)",                        OFFSET(nal_hrd),       AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE, "nal-hrd" },
  52. { "none",          NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_NONE}, INT_MIN, INT_MAX, VE, "nal-hrd" },
  53. { "vbr",           NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_VBR},  INT_MIN, INT_MAX, VE, "nal-hrd" },
  54. { "cbr",           NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_CBR},  INT_MIN, INT_MAX, VE, "nal-hrd" },
  55. { "avcintra-class","AVC-Intra class 50/100/200",                      OFFSET(avcintra_class),AV_OPT_TYPE_INT,     { .i64 = -1 }, -1, 200   , VE},
  56. { "x264-params",  "Override the x264 configuration using a :-separated list of key=value parameters", OFFSET(x264_params), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
  57. { NULL },
  58. };

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. { "preset",      "set the x265 preset",                                                         OFFSET(preset),    AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
  3. { "tune",        "set the x265 tune parameter",                                                 OFFSET(tune),      AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
  4. { "x265-params", "set the x265 configuration using a :-separated list of key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
  5. { NULL }
  6. };

官方代码中有关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. }

参考:

结构体成员管理AVClass AVOption之1AVClass的更多相关文章

  1. 结构体成员管理AVClass AVOption之2AVOption,设置选项值

    AVOption用于在FFmpeg中描述结构体中的成员变量.一个AVOption可以包含名称,简短的帮助信息,取值等. 上篇文章中概括了AVClass,AVOption和目标结构体之间的关系.以AVF ...

  2. FFmpeg源代码简单分析:结构体成员管理系统-AVOption

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  3. FFmpeg源码简单分析:结构体成员管理系统-AVOption

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  4. FFmpeg源代码简单分析:结构体成员管理系统-AVClass

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  5. FFmpeg源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  6. [转载] FFmpeg源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  7. FFmpeg来源简单分析:结构会员管理系统-AVClass

    ===================================================== FFmpeg章列表: [架构图] FFmpeg源码结构图 - 解码 FFmpeg源码结构图 ...

  8. FFmpeg总结(三)AV系列结构体之AVCodecContext

    位置: 描写叙述:主要扩展API的结构体 New fields can be added to the end with minor version bumps. Removal, reorderin ...

  9. FFMPEG结构体分析:AVCodec

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...

随机推荐

  1. 关于JS中原型链中的prototype与_proto_的个人理解与详细总结

    一直认为原型链太过复杂,尤其看过某图后被绕晕了一整子,今天清理硬盘空间(渣电脑),偶然又看到这图,勾起了点回忆,于是索性复习一下原型链相关的内容,表达能力欠缺逻辑混乱别见怪(为了防止新人__(此处指我 ...

  2. ArcMap绘图时,节点显示时的小数点位数

    直接来图吧,省的啰嗦了: 打开选中节点的,节点坐标列表(Edit Sketch Properties):

  3. Java 和 数据库两种方式进行加锁

    java方式: publicstatic synchronized int generate(StringtableName){ Stringsql = "select value from ...

  4. Javascript高级程序设计 -- 第三章 -- 总结

    1.Javascript有几种数据类型 2.变量 Javascript有几种数据类型 JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined.Null.Boolean.Nu ...

  5. C++中的模板学习

    https://www.cnblogs.com/eleclsc/p/5918114.html

  6. linux下GPRS模块的应用程序

    ---------------------------------------------------------------------------------------------------- ...

  7. .NET中的CTS、CLS、CLR

    一.解释1 1.CLR(Common Language Runtime) :公共语言运行库 CLR 是CTS(Common Type System:通用类型系统)的实现, 即是说:CLR是应用程序的执 ...

  8. 小二助手(react应用框架)-概述

    时间想学习一个前端框架,原因是这样的,我本身是做游戏的,但是自己对前端web比较感兴趣. 然后我就选择自己学哪个框架,Angular.react.vue 最后选择了react,选择的理由就不说了 那做 ...

  9. mysql 将查询出来的某一字段组合成字符串

    select GROUP_CONCAT(id) as ids from yii_role_menu where roleId=1;

  10. 【业务自动化】iTop,全面支持ITIL流程的一款ITSM工具

    iTop产品针对的主要应用场景为:内部IT支持.IT外包管理.数据中心运维管理和企业IT资产管理.常青管理从绿象认证产品中选取了iTop作为主要推荐产品,本类别的绿象认证产品还包括:OTRS和RT3等 ...