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; }
打印输出:
演示代码打印
有糖尿病的人要长寿,3个习惯要养成,3个错误要避免有糖尿病的人能长寿吗?答案是肯定的,实际生活中可以见到,不少糖尿病人确实比很多正常人更健康更长寿,追根溯源,他们致胜的法宝就是自律,为什么呢?糖尿病是一种可防可治的生活方式病,干预
高圆圆出席时尚活动,穿着性感戴奢华项链出镜,43岁越来越美了近日,高圆圆现身参加品牌活动,作为品牌代言人高圆圆一登场可谓是出尽风头,她一改往日的清新淡雅风走起了性感女神风让人眼前一亮。当天高圆圆身穿一席蓝色紧身丝绒连衣裙把整个身材轮廓勾勒的
中药诠解石膏药材概述石膏为含水硫酸钙纤维状结晶聚合体的矿石。主产于湖北甘肃等地。随时可釆。以块大色白质松半透明纵断面如丝者为佳。生用或煅用。(石膏)性味归经石膏甘辛,大寒。归肺胃经。炮制及功效
时间真的存在吗?头条创作挑战赛宁缺堂主人独处山居,悠闲度日。门外绿树成荫,时有农夫来往墙内菜畦整洁,偶见彩蝶回旋。这日,刚上大学的孙子明明放假归来,与爷爷同坐石几旁,边看书,边品茶聊天。是时,晴空
中医江志峰吃中药的最佳时候是什么?吃中药的最佳时候是什么?传统中医呢认为它是在饭前吃或者饭后吃,还是在凌晨吃,或者是在晚上吃啊,都是很有讲究的。这个呢不但要看我们中药方剂它自己的药性,其实我们还要看这个本身药物开出
世界杯完整时间表(北京时间)世界杯完整时间表(北京时间)日期球队比赛场地北京时间赛果11月21日卡塔尔VS厄瓜多尔阿尔拜特体育场0000011月21日塞内加尔VS荷兰图玛玛体育场18000011月21日英格兰
勇士仁至义尽,库里竭尽全力!你并不是杜兰特,现在也该让位了作为上赛季总冠军,本赛季开打前三周多的时间,勇士整体表现很挣扎,5胜7负的战绩,西部第11名的位置。当勇士内部出现各种各样的问题时,就连裁判都不想让勇士赢球,一些莫须有的吹罚颇具争
智慧矿基本架构定义及建设标智慧矿的基本构架是什么?智慧矿包括了矿的各个,也是绿矿建设的更层级。就其基本构架按照通常的划分法,主要包括三个,就是智慧产系统智慧职业健康与安全系统智慧技术与管理系统。智慧矿的主要
重新思考这个世界的15位年轻创始人(五)阿米拉和时尚电商平台15YoungFoundersRethinkingEverything(5)重新思考这个世界的15位年轻创始人(五)阿米拉热苏尔和TheFolkloreGroup时尚电商平台从留学
发现这个世界的真相(下)我们现在所处的这个世界,全部都是假的!喜怒哀乐,情苦悲愁,都是假的!声望名誉,权势地位,都是假的!即便是你眼睛看到的花花世界,也是经过你的大脑处理过的!那么,什么才是真的?你读过的
16。1。1最省电方法根据最近两天对16。1。1系统的深入研究和体验,我找到了最好的省电方法,果友们不妨试试。首先要关闭后台APP刷新功能,它不会对我们手机运行有影响。后台应用刷新这个概念其实可以跟应用