ffmpeg的AVOption模块API使用演示

查找选项

1、av_opt_next/av_opt_find函数可以直接在AVClass对象上查找选项:

// 1、API直接操作AVClass结构体

// 通过av_opt_next查找AVClass中的所有选项
const AVClass *test_c = &test_class;
const AVOption *ret_c = NULL;
while ((ret_c = av_opt_next(&test_c, ret_c))) {
    printf("av_opt_next->AVClass option name: %s
", ret_c->name);
}
printf("
");

// 通过av_opt_find查找AVClass中的某个选项 包括子结构体中的选项
// serach_flags需要设置为AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ
const AVOption *find_c = av_opt_find(&test_c, "test_flags", NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
if (find_c) {
    printf("av_opt_find->AVClass option name: %s
", find_c->name);
}
printf("
");

2、查找结构体中子结构体的AVClass并遍历子结构体的所有选项:

// 查找结构体中子结构体的AVClass并遍历子结构体的所有选项
void *iter = NULL;
const AVClass *child_c = av_opt_child_class_iterate(test_c, &iter);
if (child_c) {
    const AVOption *ret_c = NULL;
    while ((ret_c = av_opt_next(&child_c, ret_c))) {
        printf("av_opt_child_class_iterate->av_opt_next->AVClass option name: %s
", ret_c->name);
    }
}
printf("
");

3、API操作结构体对象

test_struct *obj = alloc_test_struct();

// 演示av_opt_child_next和av_opt_next用法
void *child = NULL;
child = av_opt_child_next(obj, child);
if (child) {
    child_struct *child_obj = (child_struct *)child;

    const AVOption *ret = NULL;
    while ((ret = av_opt_next(child_obj, ret))) {
        printf("av_opt_child_next->av_opt_next->obj option name: %s
", ret->name);
    }
}
printf("
");

// 演示av_opt_find用法
const AVOption *find = av_opt_find(obj, "test_flags", NULL, 0, AV_OPT_SEARCH_CHILDREN);
if (find) {
    printf("av_opt_find->obj option name: %s
", find->name);
}
printf("
");

读写选项

通过av_opt_get获取某个选项的值,通过av_opt_set设置某个选项的值:

/*************************
 * 二、读写选项
 * **********************/
int res = -1;
uint8_t *buf = NULL;
res = av_opt_get(obj, "test_int", AV_OPT_SEARCH_CHILDREN, &buf);
if (res >= 0) {
    printf("before test_int value: %s
", buf);
    av_free(buf);
}
res = av_opt_set(obj, "test_int", "100", AV_OPT_SEARCH_CHILDREN);
res = av_opt_get(obj, "test_int", AV_OPT_SEARCH_CHILDREN, &buf);
if (res >= 0) {
    printf("after test_int value: %s
", buf);
    av_free(buf);
}

完整演示代码:

#include 
#include 

void *child_next(void *obj, void *prev);
const AVClass* child_class_iterate(void **iter);

typedef struct child_struct {
  const AVClass *class;
  int flags_opt;
} child_struct;

static const AVOption child_opts[] = {
  { "test_flags", "This is a test option of flags type.",
   offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX },
  { NULL },
};

static const AVClass child_class = {
  .class_name = "child class",
  .item_name  = av_default_item_name,
  .option     = child_opts,
  .version    = LIBAVUTIL_VERSION_INT,
};

typedef struct test_struct {
  const AVClass *class;
  int      int_opt;
  char    *str_opt;
  uint8_t *bin_opt;
  int      bin_len;
  struct child_struct *child_struct;
} test_struct;

static const AVOption test_options[] = {
  {"test_int", "This is a test option of int type.", offsetof(test_struct, int_opt),
    AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX},
  {"test_str", "This is a test option of string type.", offsetof(test_struct, str_opt),
    AV_OPT_TYPE_STRING },
  {"test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt),
  AV_OPT_TYPE_BINARY},
  {NULL},
};

static const AVClass test_class = {
  .class_name          = "test class",
  .item_name           = av_default_item_name,
  .option              = test_options,
  .child_next          = child_next,
  .child_class_iterate = child_class_iterate,
  .version             = LIBAVUTIL_VERSION_INT,
 };

void *child_next(void *obj, void *prev)
{
  test_struct *t = obj;
  if (!prev && t->child_struct)
    return t->child_struct;
  return NULL;
}

const AVClass* child_class_iterate(void **iter)
{
  const AVClass *c = *iter ? NULL : &child_class;
  *iter = (void*)(uintptr_t)c;
  return c;
}

test_struct *alloc_test_struct(void)
{
  test_struct *ret = av_mallocz(sizeof(*ret));
  ret->class = &test_class;
  ret->child_struct = av_mallocz(sizeof(*ret->child_struct));
  ret->child_struct->class = &child_class;
  av_opt_set_defaults(ret->child_struct);
  av_opt_set_defaults(ret);
  return ret;
}

void free_test_struct(test_struct **foo)
{
  av_opt_free((*foo)->child_struct);
  av_opt_free(*foo);

  av_freep(&((*foo)->child_struct));
  av_freep(foo);
}

int main()
{
    /*************************
     * 一、查找选项
     * **********************/
    // 1、API直接操作AVClass结构体

    // 通过av_opt_next查找AVClass中的所有选项
    const AVClass *test_c = &test_class;
    const AVOption *ret_c = NULL;
    while ((ret_c = av_opt_next(&test_c, ret_c))) {
        printf("av_opt_next->AVClass option name: %s
", ret_c->name);
    }
    printf("
");

    // 通过av_opt_find查找AVClass中的某个选项 包括子结构体中的选项
    // serach_flags需要设置为AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ
    const AVOption *find_c = av_opt_find(&test_c, "test_flags", NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
    if (find_c) {
        printf("av_opt_find->AVClass option name: %s
", find_c->name);
    }
    printf("
");

    // 查找结构体中子结构体的AVClass并遍历子结构体的所有选项
    void *iter = NULL;
    const AVClass *child_c = av_opt_child_class_iterate(test_c, &iter);
    if (child_c) {
        const AVOption *ret_c = NULL;
        while ((ret_c = av_opt_next(&child_c, ret_c))) {
            printf("av_opt_child_class_iterate->av_opt_next->AVClass option name: %s
", ret_c->name);
        }
    }
    printf("
");

    // 2、API操作结构体对象
    test_struct *obj = alloc_test_struct();

    // 演示av_opt_child_next和av_opt_next用法
    void *child = NULL;
    child = av_opt_child_next(obj, child);
    if (child) {
        child_struct *child_obj = (child_struct *)child;

        const AVOption *ret = NULL;
        while ((ret = av_opt_next(child_obj, ret))) {
            printf("av_opt_child_next->av_opt_next->obj option name: %s
", ret->name);
        }
    }
    printf("
");

    // 演示av_opt_find用法
    const AVOption *find = av_opt_find(obj, "test_flags", NULL, 0, AV_OPT_SEARCH_CHILDREN);
    if (find) {
        printf("av_opt_find->obj option name: %s
", find->name);
    }
    printf("
");

    /*************************
     * 二、读写选项
     * **********************/
    int res = -1;
    uint8_t *buf = NULL;
    res = av_opt_get(obj, "test_int", AV_OPT_SEARCH_CHILDREN, &buf);
    if (res >= 0) {
        printf("before test_int value: %s
", buf);
        av_free(buf);
    }
    res = av_opt_set(obj, "test_int", "100", AV_OPT_SEARCH_CHILDREN);
    res = av_opt_get(obj, "test_int", AV_OPT_SEARCH_CHILDREN, &buf);
    if (res >= 0) {
        printf("after test_int value: %s
", buf);
        av_free(buf);
    }
    free_test_struct(&obj);

    return 0;
}

打印输出:

演示代码打印

展开阅读全文

页面更新:2024-04-07

标签:演示   中子   遍历   函数   模块   选项   对象   完整   结构   操作   代码

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top