You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1681 lines
55KB

  1. /*
  2. * AVOptions
  3. * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file
  23. * AVOptions
  24. * @author Michael Niedermayer <michaelni@gmx.at>
  25. */
  26. #include "avutil.h"
  27. #include "avstring.h"
  28. #include "channel_layout.h"
  29. #include "common.h"
  30. #include "opt.h"
  31. #include "eval.h"
  32. #include "dict.h"
  33. #include "log.h"
  34. #include "parseutils.h"
  35. #include "pixdesc.h"
  36. #include "mathematics.h"
  37. #include "samplefmt.h"
  38. #include <float.h>
  39. #if FF_API_FIND_OPT
  40. //FIXME order them and do a bin search
  41. const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
  42. {
  43. const AVOption *o = NULL;
  44. while ((o = av_next_option(v, o))) {
  45. if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags)
  46. return o;
  47. }
  48. return NULL;
  49. }
  50. #endif
  51. #if FF_API_OLD_AVOPTIONS
  52. const AVOption *av_next_option(void *obj, const AVOption *last)
  53. {
  54. return av_opt_next(obj, last);
  55. }
  56. #endif
  57. const AVOption *av_opt_next(void *obj, const AVOption *last)
  58. {
  59. AVClass *class = *(AVClass**)obj;
  60. if (!last && class && class->option && class->option[0].name)
  61. return class->option;
  62. if (last && last[1].name)
  63. return ++last;
  64. return NULL;
  65. }
  66. static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum)
  67. {
  68. switch (o->type) {
  69. case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0;
  70. case AV_OPT_TYPE_PIXEL_FMT:
  71. case AV_OPT_TYPE_SAMPLE_FMT:
  72. case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0;
  73. case AV_OPT_TYPE_CHANNEL_LAYOUT:
  74. case AV_OPT_TYPE_DURATION:
  75. case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0;
  76. case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0;
  77. case AV_OPT_TYPE_DOUBLE: *num = *(double *)dst;return 0;
  78. case AV_OPT_TYPE_RATIONAL: *intnum = ((AVRational*)dst)->num;
  79. *den = ((AVRational*)dst)->den;
  80. return 0;
  81. case AV_OPT_TYPE_CONST: *num = o->default_val.dbl; return 0;
  82. }
  83. return AVERROR(EINVAL);
  84. }
  85. static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
  86. {
  87. if (o->type != AV_OPT_TYPE_FLAGS &&
  88. (o->max * den < num * intnum || o->min * den > num * intnum)) {
  89. av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
  90. num*intnum/den, o->name, o->min, o->max);
  91. return AVERROR(ERANGE);
  92. }
  93. if (o->type == AV_OPT_TYPE_FLAGS) {
  94. double d = num*intnum/den;
  95. if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
  96. av_log(obj, AV_LOG_ERROR,
  97. "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
  98. num*intnum/den, o->name);
  99. return AVERROR(ERANGE);
  100. }
  101. }
  102. switch (o->type) {
  103. case AV_OPT_TYPE_FLAGS:
  104. case AV_OPT_TYPE_PIXEL_FMT:
  105. case AV_OPT_TYPE_SAMPLE_FMT:
  106. case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
  107. case AV_OPT_TYPE_DURATION:
  108. case AV_OPT_TYPE_CHANNEL_LAYOUT:
  109. case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break;
  110. case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break;
  111. case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break;
  112. case AV_OPT_TYPE_RATIONAL:
  113. if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
  114. else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
  115. break;
  116. default:
  117. return AVERROR(EINVAL);
  118. }
  119. return 0;
  120. }
  121. static const double const_values[] = {
  122. M_PI,
  123. M_E,
  124. FF_QP2LAMBDA,
  125. 0
  126. };
  127. static const char * const const_names[] = {
  128. "PI",
  129. "E",
  130. "QP2LAMBDA",
  131. 0
  132. };
  133. static int hexchar2int(char c) {
  134. if (c >= '0' && c <= '9') return c - '0';
  135. if (c >= 'a' && c <= 'f') return c - 'a' + 10;
  136. if (c >= 'A' && c <= 'F') return c - 'A' + 10;
  137. return -1;
  138. }
  139. static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
  140. {
  141. int *lendst = (int *)(dst + 1);
  142. uint8_t *bin, *ptr;
  143. int len = strlen(val);
  144. av_freep(dst);
  145. *lendst = 0;
  146. if (len & 1)
  147. return AVERROR(EINVAL);
  148. len /= 2;
  149. ptr = bin = av_malloc(len);
  150. while (*val) {
  151. int a = hexchar2int(*val++);
  152. int b = hexchar2int(*val++);
  153. if (a < 0 || b < 0) {
  154. av_free(bin);
  155. return AVERROR(EINVAL);
  156. }
  157. *ptr++ = (a << 4) | b;
  158. }
  159. *dst = bin;
  160. *lendst = len;
  161. return 0;
  162. }
  163. static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
  164. {
  165. av_freep(dst);
  166. *dst = av_strdup(val);
  167. return 0;
  168. }
  169. #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
  170. opt->type == AV_OPT_TYPE_CONST || \
  171. opt->type == AV_OPT_TYPE_FLAGS || \
  172. opt->type == AV_OPT_TYPE_INT) ? \
  173. opt->default_val.i64 : opt->default_val.dbl)
  174. static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
  175. {
  176. int ret = 0, notfirst = 0;
  177. for (;;) {
  178. int i, den = 1;
  179. char buf[256];
  180. int cmd = 0;
  181. double d, num = 1;
  182. int64_t intnum = 1;
  183. i = 0;
  184. if (*val == '+' || *val == '-') {
  185. if (o->type == AV_OPT_TYPE_FLAGS)
  186. cmd = *(val++);
  187. else if (!notfirst)
  188. buf[i++] = *val;
  189. }
  190. for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
  191. buf[i] = val[i];
  192. buf[i] = 0;
  193. {
  194. const AVOption *o_named = av_opt_find(target_obj, buf, o->unit, 0, 0);
  195. if (o_named && o_named->type == AV_OPT_TYPE_CONST)
  196. d = DEFAULT_NUMVAL(o_named);
  197. else if (!strcmp(buf, "default")) d = DEFAULT_NUMVAL(o);
  198. else if (!strcmp(buf, "max" )) d = o->max;
  199. else if (!strcmp(buf, "min" )) d = o->min;
  200. else if (!strcmp(buf, "none" )) d = 0;
  201. else if (!strcmp(buf, "all" )) d = ~0;
  202. else {
  203. int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
  204. if (res < 0) {
  205. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
  206. return res;
  207. }
  208. }
  209. }
  210. if (o->type == AV_OPT_TYPE_FLAGS) {
  211. read_number(o, dst, NULL, NULL, &intnum);
  212. if (cmd == '+') d = intnum | (int64_t)d;
  213. else if (cmd == '-') d = intnum &~(int64_t)d;
  214. } else {
  215. read_number(o, dst, &num, &den, &intnum);
  216. if (cmd == '+') d = notfirst*num*intnum/den + d;
  217. else if (cmd == '-') d = notfirst*num*intnum/den - d;
  218. }
  219. if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
  220. return ret;
  221. val += i;
  222. if (!*val)
  223. return 0;
  224. notfirst = 1;
  225. }
  226. return 0;
  227. }
  228. #if FF_API_OLD_AVOPTIONS
  229. int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
  230. {
  231. const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
  232. if (o_out)
  233. *o_out = o;
  234. return av_opt_set(obj, name, val, 0);
  235. }
  236. #endif
  237. int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
  238. {
  239. int ret = 0;
  240. void *dst, *target_obj;
  241. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  242. if (!o || !target_obj)
  243. return AVERROR_OPTION_NOT_FOUND;
  244. if (!val && (o->type != AV_OPT_TYPE_STRING &&
  245. o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
  246. o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
  247. o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
  248. o->type != AV_OPT_TYPE_CHANNEL_LAYOUT))
  249. return AVERROR(EINVAL);
  250. dst = ((uint8_t*)target_obj) + o->offset;
  251. switch (o->type) {
  252. case AV_OPT_TYPE_STRING: return set_string(obj, o, val, dst);
  253. case AV_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst);
  254. case AV_OPT_TYPE_FLAGS:
  255. case AV_OPT_TYPE_INT:
  256. case AV_OPT_TYPE_INT64:
  257. case AV_OPT_TYPE_FLOAT:
  258. case AV_OPT_TYPE_DOUBLE:
  259. case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, target_obj, o, val, dst);
  260. case AV_OPT_TYPE_IMAGE_SIZE:
  261. if (!val || !strcmp(val, "none")) {
  262. *(int *)dst = *((int *)dst + 1) = 0;
  263. return 0;
  264. }
  265. ret = av_parse_video_size(dst, ((int *)dst) + 1, val);
  266. if (ret < 0)
  267. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
  268. return ret;
  269. case AV_OPT_TYPE_VIDEO_RATE:
  270. if (!val) {
  271. ret = AVERROR(EINVAL);
  272. } else {
  273. ret = av_parse_video_rate(dst, val);
  274. }
  275. if (ret < 0)
  276. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
  277. return ret;
  278. case AV_OPT_TYPE_PIXEL_FMT:
  279. if (!val || !strcmp(val, "none")) {
  280. ret = AV_PIX_FMT_NONE;
  281. } else {
  282. ret = av_get_pix_fmt(val);
  283. if (ret == AV_PIX_FMT_NONE) {
  284. char *tail;
  285. ret = strtol(val, &tail, 0);
  286. if (*tail || (unsigned)ret >= AV_PIX_FMT_NB) {
  287. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as pixel format\n", val);
  288. return AVERROR(EINVAL);
  289. }
  290. }
  291. }
  292. *(enum AVPixelFormat *)dst = ret;
  293. return 0;
  294. case AV_OPT_TYPE_SAMPLE_FMT:
  295. if (!val || !strcmp(val, "none")) {
  296. ret = AV_SAMPLE_FMT_NONE;
  297. } else {
  298. ret = av_get_sample_fmt(val);
  299. if (ret == AV_SAMPLE_FMT_NONE) {
  300. char *tail;
  301. ret = strtol(val, &tail, 0);
  302. if (*tail || (unsigned)ret >= AV_SAMPLE_FMT_NB) {
  303. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as sample format\n", val);
  304. return AVERROR(EINVAL);
  305. }
  306. }
  307. }
  308. *(enum AVSampleFormat *)dst = ret;
  309. return 0;
  310. case AV_OPT_TYPE_DURATION:
  311. if (!val) {
  312. *(int64_t *)dst = 0;
  313. return 0;
  314. } else {
  315. if ((ret = av_parse_time(dst, val, 1)) < 0)
  316. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
  317. return ret;
  318. }
  319. break;
  320. case AV_OPT_TYPE_COLOR:
  321. if (!val) {
  322. return 0;
  323. } else {
  324. ret = av_parse_color(dst, val, -1, obj);
  325. if (ret < 0)
  326. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
  327. return ret;
  328. }
  329. break;
  330. case AV_OPT_TYPE_CHANNEL_LAYOUT:
  331. if (!val || !strcmp(val, "none")) {
  332. *(int64_t *)dst = 0;
  333. } else {
  334. #if FF_API_GET_CHANNEL_LAYOUT_COMPAT
  335. int64_t cl = ff_get_channel_layout(val, 0);
  336. #else
  337. int64_t cl = av_get_channel_layout(val);
  338. #endif
  339. if (!cl) {
  340. av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
  341. ret = AVERROR(EINVAL);
  342. }
  343. *(int64_t *)dst = cl;
  344. return ret;
  345. }
  346. break;
  347. }
  348. av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
  349. return AVERROR(EINVAL);
  350. }
  351. #define OPT_EVAL_NUMBER(name, opttype, vartype)\
  352. int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
  353. {\
  354. if (!o || o->type != opttype)\
  355. return AVERROR(EINVAL);\
  356. return set_string_number(obj, obj, o, val, name ## _out);\
  357. }
  358. OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int)
  359. OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int)
  360. OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t)
  361. OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float)
  362. OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double)
  363. OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational)
  364. static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
  365. int search_flags)
  366. {
  367. void *dst, *target_obj;
  368. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  369. if (!o || !target_obj)
  370. return AVERROR_OPTION_NOT_FOUND;
  371. dst = ((uint8_t*)target_obj) + o->offset;
  372. return write_number(obj, o, dst, num, den, intnum);
  373. }
  374. #if FF_API_OLD_AVOPTIONS
  375. const AVOption *av_set_double(void *obj, const char *name, double n)
  376. {
  377. const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
  378. if (set_number(obj, name, n, 1, 1, 0) < 0)
  379. return NULL;
  380. return o;
  381. }
  382. const AVOption *av_set_q(void *obj, const char *name, AVRational n)
  383. {
  384. const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
  385. if (set_number(obj, name, n.num, n.den, 1, 0) < 0)
  386. return NULL;
  387. return o;
  388. }
  389. const AVOption *av_set_int(void *obj, const char *name, int64_t n)
  390. {
  391. const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
  392. if (set_number(obj, name, 1, 1, n, 0) < 0)
  393. return NULL;
  394. return o;
  395. }
  396. #endif
  397. int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
  398. {
  399. return set_number(obj, name, 1, 1, val, search_flags);
  400. }
  401. int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
  402. {
  403. return set_number(obj, name, val, 1, 1, search_flags);
  404. }
  405. int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
  406. {
  407. return set_number(obj, name, val.num, val.den, 1, search_flags);
  408. }
  409. int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
  410. {
  411. void *target_obj;
  412. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  413. uint8_t *ptr;
  414. uint8_t **dst;
  415. int *lendst;
  416. if (!o || !target_obj)
  417. return AVERROR_OPTION_NOT_FOUND;
  418. if (o->type != AV_OPT_TYPE_BINARY)
  419. return AVERROR(EINVAL);
  420. ptr = len ? av_malloc(len) : NULL;
  421. if (len && !ptr)
  422. return AVERROR(ENOMEM);
  423. dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
  424. lendst = (int *)(dst + 1);
  425. av_free(*dst);
  426. *dst = ptr;
  427. *lendst = len;
  428. if (len)
  429. memcpy(ptr, val, len);
  430. return 0;
  431. }
  432. int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags)
  433. {
  434. void *target_obj;
  435. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  436. if (!o || !target_obj)
  437. return AVERROR_OPTION_NOT_FOUND;
  438. if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
  439. av_log(obj, AV_LOG_ERROR,
  440. "The value set by option '%s' is not an image size.\n", o->name);
  441. return AVERROR(EINVAL);
  442. }
  443. if (w<0 || h<0) {
  444. av_log(obj, AV_LOG_ERROR,
  445. "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name);
  446. return AVERROR(EINVAL);
  447. }
  448. *(int *)(((uint8_t *)target_obj) + o->offset) = w;
  449. *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h;
  450. return 0;
  451. }
  452. int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags)
  453. {
  454. void *target_obj;
  455. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  456. if (!o || !target_obj)
  457. return AVERROR_OPTION_NOT_FOUND;
  458. if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
  459. av_log(obj, AV_LOG_ERROR,
  460. "The value set by option '%s' is not a video rate.\n", o->name);
  461. return AVERROR(EINVAL);
  462. }
  463. if (val.num <= 0 || val.den <= 0)
  464. return AVERROR(EINVAL);
  465. return set_number(obj, name, val.num, val.den, 1, search_flags);
  466. }
  467. static int set_format(void *obj, const char *name, int fmt, int search_flags,
  468. enum AVOptionType type, const char *desc, int nb_fmts)
  469. {
  470. void *target_obj;
  471. const AVOption *o = av_opt_find2(obj, name, NULL, 0,
  472. search_flags, &target_obj);
  473. int min, max;
  474. const AVClass *class = *(AVClass **)obj;
  475. if (!o || !target_obj)
  476. return AVERROR_OPTION_NOT_FOUND;
  477. if (o->type != type) {
  478. av_log(obj, AV_LOG_ERROR,
  479. "The value set by option '%s' is not a %s format", name, desc);
  480. return AVERROR(EINVAL);
  481. }
  482. #if LIBAVUTIL_VERSION_MAJOR < 53
  483. if (class->version && class->version < AV_VERSION_INT(52, 11, 100)) {
  484. min = -1;
  485. max = nb_fmts-1;
  486. } else
  487. #endif
  488. {
  489. min = FFMIN(o->min, -1);
  490. max = FFMAX(o->max, nb_fmts-1);
  491. }
  492. if (fmt < min || fmt > max) {
  493. av_log(obj, AV_LOG_ERROR,
  494. "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
  495. fmt, name, desc, min, max);
  496. return AVERROR(ERANGE);
  497. }
  498. *(int *)(((uint8_t *)target_obj) + o->offset) = fmt;
  499. return 0;
  500. }
  501. int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags)
  502. {
  503. return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
  504. }
  505. int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
  506. {
  507. return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
  508. }
  509. int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
  510. {
  511. void *target_obj;
  512. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  513. if (!o || !target_obj)
  514. return AVERROR_OPTION_NOT_FOUND;
  515. if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
  516. av_log(obj, AV_LOG_ERROR,
  517. "The value set by option '%s' is not a channel layout.\n", o->name);
  518. return AVERROR(EINVAL);
  519. }
  520. *(int *)(((int64_t *)target_obj) + o->offset) = cl;
  521. return 0;
  522. }
  523. #if FF_API_OLD_AVOPTIONS
  524. /**
  525. *
  526. * @param buf a buffer which is used for returning non string values as strings, can be NULL
  527. * @param buf_len allocated length in bytes of buf
  528. */
  529. const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
  530. {
  531. const AVOption *o = av_opt_find(obj, name, NULL, 0, AV_OPT_SEARCH_CHILDREN);
  532. void *dst;
  533. uint8_t *bin;
  534. int len, i;
  535. if (!o)
  536. return NULL;
  537. if (o->type != AV_OPT_TYPE_STRING && (!buf || !buf_len))
  538. return NULL;
  539. dst= ((uint8_t*)obj) + o->offset;
  540. if (o_out) *o_out= o;
  541. switch (o->type) {
  542. case AV_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break;
  543. case AV_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break;
  544. case AV_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break;
  545. case AV_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break;
  546. case AV_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break;
  547. case AV_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
  548. case AV_OPT_TYPE_CONST: snprintf(buf, buf_len, "%f" , o->default_val.dbl);break;
  549. case AV_OPT_TYPE_STRING: return *(void**)dst;
  550. case AV_OPT_TYPE_BINARY:
  551. len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
  552. if (len >= (buf_len + 1)/2) return NULL;
  553. bin = *(uint8_t**)dst;
  554. for (i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
  555. break;
  556. default: return NULL;
  557. }
  558. return buf;
  559. }
  560. #endif
  561. int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
  562. {
  563. void *dst, *target_obj;
  564. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  565. uint8_t *bin, buf[128];
  566. int len, i, ret;
  567. int64_t i64;
  568. if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
  569. return AVERROR_OPTION_NOT_FOUND;
  570. dst = (uint8_t*)target_obj + o->offset;
  571. buf[0] = 0;
  572. switch (o->type) {
  573. case AV_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break;
  574. case AV_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break;
  575. case AV_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
  576. case AV_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break;
  577. case AV_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break;
  578. case AV_OPT_TYPE_VIDEO_RATE:
  579. case AV_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
  580. case AV_OPT_TYPE_CONST: ret = snprintf(buf, sizeof(buf), "%f" , o->default_val.dbl);break;
  581. case AV_OPT_TYPE_STRING:
  582. if (*(uint8_t**)dst)
  583. *out_val = av_strdup(*(uint8_t**)dst);
  584. else
  585. *out_val = av_strdup("");
  586. return 0;
  587. case AV_OPT_TYPE_BINARY:
  588. len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
  589. if ((uint64_t)len*2 + 1 > INT_MAX)
  590. return AVERROR(EINVAL);
  591. if (!(*out_val = av_malloc(len*2 + 1)))
  592. return AVERROR(ENOMEM);
  593. bin = *(uint8_t**)dst;
  594. for (i = 0; i < len; i++)
  595. snprintf(*out_val + i*2, 3, "%02X", bin[i]);
  596. return 0;
  597. case AV_OPT_TYPE_IMAGE_SIZE:
  598. ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
  599. break;
  600. case AV_OPT_TYPE_PIXEL_FMT:
  601. ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
  602. break;
  603. case AV_OPT_TYPE_SAMPLE_FMT:
  604. ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
  605. break;
  606. case AV_OPT_TYPE_DURATION:
  607. i64 = *(int64_t *)dst;
  608. ret = snprintf(buf, sizeof(buf), "%"PRIi64"d:%02d:%02d.%06d",
  609. i64 / 3600000000, (int)((i64 / 60000000) % 60),
  610. (int)((i64 / 1000000) % 60), (int)(i64 % 1000000));
  611. break;
  612. case AV_OPT_TYPE_COLOR:
  613. ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]);
  614. break;
  615. case AV_OPT_TYPE_CHANNEL_LAYOUT:
  616. i64 = *(int64_t *)dst;
  617. ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
  618. break;
  619. default:
  620. return AVERROR(EINVAL);
  621. }
  622. if (ret >= sizeof(buf))
  623. return AVERROR(EINVAL);
  624. *out_val = av_strdup(buf);
  625. return 0;
  626. }
  627. static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
  628. int search_flags)
  629. {
  630. void *dst, *target_obj;
  631. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  632. if (!o || !target_obj)
  633. goto error;
  634. dst = ((uint8_t*)target_obj) + o->offset;
  635. if (o_out) *o_out= o;
  636. return read_number(o, dst, num, den, intnum);
  637. error:
  638. *den=*intnum=0;
  639. return -1;
  640. }
  641. #if FF_API_OLD_AVOPTIONS
  642. double av_get_double(void *obj, const char *name, const AVOption **o_out)
  643. {
  644. int64_t intnum=1;
  645. double num=1;
  646. int den=1;
  647. if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
  648. return NAN;
  649. return num*intnum/den;
  650. }
  651. AVRational av_get_q(void *obj, const char *name, const AVOption **o_out)
  652. {
  653. int64_t intnum=1;
  654. double num=1;
  655. int den=1;
  656. if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
  657. return (AVRational){0, 0};
  658. if (num == 1.0 && (int)intnum == intnum)
  659. return (AVRational){intnum, den};
  660. else
  661. return av_d2q(num*intnum/den, 1<<24);
  662. }
  663. int64_t av_get_int(void *obj, const char *name, const AVOption **o_out)
  664. {
  665. int64_t intnum=1;
  666. double num=1;
  667. int den=1;
  668. if (get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
  669. return -1;
  670. return num*intnum/den;
  671. }
  672. #endif
  673. int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
  674. {
  675. int64_t intnum = 1;
  676. double num = 1;
  677. int ret, den = 1;
  678. if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
  679. return ret;
  680. *out_val = num*intnum/den;
  681. return 0;
  682. }
  683. int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
  684. {
  685. int64_t intnum = 1;
  686. double num = 1;
  687. int ret, den = 1;
  688. if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
  689. return ret;
  690. *out_val = num*intnum/den;
  691. return 0;
  692. }
  693. int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
  694. {
  695. int64_t intnum = 1;
  696. double num = 1;
  697. int ret, den = 1;
  698. if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
  699. return ret;
  700. if (num == 1.0 && (int)intnum == intnum)
  701. *out_val = (AVRational){intnum, den};
  702. else
  703. *out_val = av_d2q(num*intnum/den, 1<<24);
  704. return 0;
  705. }
  706. int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
  707. {
  708. void *dst, *target_obj;
  709. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  710. if (!o || !target_obj)
  711. return AVERROR_OPTION_NOT_FOUND;
  712. if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
  713. av_log(obj, AV_LOG_ERROR,
  714. "The value for option '%s' is not an image size.\n", name);
  715. return AVERROR(EINVAL);
  716. }
  717. dst = ((uint8_t*)target_obj) + o->offset;
  718. if (w_out) *w_out = *(int *)dst;
  719. if (h_out) *h_out = *((int *)dst+1);
  720. return 0;
  721. }
  722. int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val)
  723. {
  724. int64_t intnum = 1;
  725. double num = 1;
  726. int ret, den = 1;
  727. if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
  728. return ret;
  729. if (num == 1.0 && (int)intnum == intnum)
  730. *out_val = (AVRational){intnum, den};
  731. else
  732. *out_val = av_d2q(num*intnum/den, 1<<24);
  733. return 0;
  734. }
  735. static int get_format(void *obj, const char *name, int search_flags, int *out_fmt,
  736. enum AVOptionType type, const char *desc)
  737. {
  738. void *dst, *target_obj;
  739. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  740. if (!o || !target_obj)
  741. return AVERROR_OPTION_NOT_FOUND;
  742. if (o->type != type) {
  743. av_log(obj, AV_LOG_ERROR,
  744. "The value for option '%s' is not a %s format.\n", desc, name);
  745. return AVERROR(EINVAL);
  746. }
  747. dst = ((uint8_t*)target_obj) + o->offset;
  748. *out_fmt = *(int *)dst;
  749. return 0;
  750. }
  751. int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt)
  752. {
  753. return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
  754. }
  755. int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
  756. {
  757. return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
  758. }
  759. int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
  760. {
  761. void *dst, *target_obj;
  762. const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
  763. if (!o || !target_obj)
  764. return AVERROR_OPTION_NOT_FOUND;
  765. if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
  766. av_log(obj, AV_LOG_ERROR,
  767. "The value for option '%s' is not a channel layout.\n", name);
  768. return AVERROR(EINVAL);
  769. }
  770. dst = ((uint8_t*)target_obj) + o->offset;
  771. *cl = *(int64_t *)dst;
  772. return 0;
  773. }
  774. int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
  775. {
  776. const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
  777. const AVOption *flag = av_opt_find(obj, flag_name,
  778. field ? field->unit : NULL, 0, 0);
  779. int64_t res;
  780. if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
  781. av_opt_get_int(obj, field_name, 0, &res) < 0)
  782. return 0;
  783. return res & flag->default_val.i64;
  784. }
  785. static void log_value(void *av_log_obj, int level, double d)
  786. {
  787. if (d == INT_MAX) {
  788. av_log(av_log_obj, level, "INT_MAX");
  789. } else if (d == INT_MIN) {
  790. av_log(av_log_obj, level, "INT_MIN");
  791. } else if (d == (double)INT64_MAX) {
  792. av_log(av_log_obj, level, "I64_MAX");
  793. } else if (d == INT64_MIN) {
  794. av_log(av_log_obj, level, "I64_MIN");
  795. } else if (d == FLT_MAX) {
  796. av_log(av_log_obj, level, "FLT_MAX");
  797. } else if (d == FLT_MIN) {
  798. av_log(av_log_obj, level, "FLT_MIN");
  799. } else {
  800. av_log(av_log_obj, level, "%g", d);
  801. }
  802. }
  803. static void opt_list(void *obj, void *av_log_obj, const char *unit,
  804. int req_flags, int rej_flags)
  805. {
  806. const AVOption *opt=NULL;
  807. AVOptionRanges *r;
  808. int i;
  809. while ((opt = av_opt_next(obj, opt))) {
  810. if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
  811. continue;
  812. /* Don't print CONST's on level one.
  813. * Don't print anything but CONST's on level two.
  814. * Only print items from the requested unit.
  815. */
  816. if (!unit && opt->type==AV_OPT_TYPE_CONST)
  817. continue;
  818. else if (unit && opt->type!=AV_OPT_TYPE_CONST)
  819. continue;
  820. else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
  821. continue;
  822. else if (unit && opt->type == AV_OPT_TYPE_CONST)
  823. av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
  824. else
  825. av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ",
  826. (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? "" : "-",
  827. opt->name);
  828. switch (opt->type) {
  829. case AV_OPT_TYPE_FLAGS:
  830. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
  831. break;
  832. case AV_OPT_TYPE_INT:
  833. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
  834. break;
  835. case AV_OPT_TYPE_INT64:
  836. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
  837. break;
  838. case AV_OPT_TYPE_DOUBLE:
  839. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
  840. break;
  841. case AV_OPT_TYPE_FLOAT:
  842. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
  843. break;
  844. case AV_OPT_TYPE_STRING:
  845. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
  846. break;
  847. case AV_OPT_TYPE_RATIONAL:
  848. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
  849. break;
  850. case AV_OPT_TYPE_BINARY:
  851. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
  852. break;
  853. case AV_OPT_TYPE_IMAGE_SIZE:
  854. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
  855. break;
  856. case AV_OPT_TYPE_VIDEO_RATE:
  857. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
  858. break;
  859. case AV_OPT_TYPE_PIXEL_FMT:
  860. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
  861. break;
  862. case AV_OPT_TYPE_SAMPLE_FMT:
  863. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
  864. break;
  865. case AV_OPT_TYPE_DURATION:
  866. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
  867. break;
  868. case AV_OPT_TYPE_COLOR:
  869. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
  870. break;
  871. case AV_OPT_TYPE_CHANNEL_LAYOUT:
  872. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
  873. break;
  874. case AV_OPT_TYPE_CONST:
  875. default:
  876. av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
  877. break;
  878. }
  879. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
  880. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
  881. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
  882. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.');
  883. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.');
  884. av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
  885. if (opt->help)
  886. av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
  887. if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
  888. switch (opt->type) {
  889. case AV_OPT_TYPE_INT:
  890. case AV_OPT_TYPE_INT64:
  891. case AV_OPT_TYPE_DOUBLE:
  892. case AV_OPT_TYPE_FLOAT:
  893. case AV_OPT_TYPE_RATIONAL:
  894. for (i = 0; i < r->nb_ranges; i++) {
  895. av_log(av_log_obj, AV_LOG_INFO, " (from ");
  896. log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
  897. av_log(av_log_obj, AV_LOG_INFO, " to ");
  898. log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
  899. av_log(av_log_obj, AV_LOG_INFO, ")");
  900. }
  901. break;
  902. }
  903. av_opt_freep_ranges(&r);
  904. }
  905. if (opt->type != AV_OPT_TYPE_CONST &&
  906. opt->type != AV_OPT_TYPE_BINARY &&
  907. !((opt->type == AV_OPT_TYPE_COLOR ||
  908. opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
  909. opt->type == AV_OPT_TYPE_STRING ||
  910. opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
  911. !opt->default_val.str)) {
  912. av_log(av_log_obj, AV_LOG_INFO, " (default ");
  913. switch (opt->type) {
  914. case AV_OPT_TYPE_FLAGS:
  915. av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
  916. break;
  917. case AV_OPT_TYPE_DURATION:
  918. case AV_OPT_TYPE_INT:
  919. case AV_OPT_TYPE_INT64:
  920. log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
  921. break;
  922. case AV_OPT_TYPE_DOUBLE:
  923. case AV_OPT_TYPE_FLOAT:
  924. log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
  925. break;
  926. case AV_OPT_TYPE_RATIONAL: {
  927. AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
  928. av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
  929. break;
  930. case AV_OPT_TYPE_PIXEL_FMT:
  931. av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
  932. break;
  933. case AV_OPT_TYPE_SAMPLE_FMT:
  934. av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
  935. break;
  936. case AV_OPT_TYPE_COLOR:
  937. case AV_OPT_TYPE_IMAGE_SIZE:
  938. case AV_OPT_TYPE_STRING:
  939. case AV_OPT_TYPE_VIDEO_RATE:
  940. av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
  941. break;
  942. case AV_OPT_TYPE_CHANNEL_LAYOUT:
  943. av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
  944. break;
  945. }
  946. av_log(av_log_obj, AV_LOG_INFO, ")");
  947. }
  948. av_log(av_log_obj, AV_LOG_INFO, "\n");
  949. if (opt->unit && opt->type != AV_OPT_TYPE_CONST) {
  950. opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
  951. }
  952. }
  953. }
  954. int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
  955. {
  956. if (!obj)
  957. return -1;
  958. av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name);
  959. opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
  960. return 0;
  961. }
  962. void av_opt_set_defaults(void *s)
  963. {
  964. #if FF_API_OLD_AVOPTIONS
  965. av_opt_set_defaults2(s, 0, 0);
  966. }
  967. void av_opt_set_defaults2(void *s, int mask, int flags)
  968. {
  969. #endif
  970. const AVClass *class = *(AVClass **)s;
  971. const AVOption *opt = NULL;
  972. while ((opt = av_opt_next(s, opt)) != NULL) {
  973. #if FF_API_OLD_AVOPTIONS
  974. if ((opt->flags & mask) != flags)
  975. continue;
  976. #endif
  977. switch (opt->type) {
  978. case AV_OPT_TYPE_CONST:
  979. /* Nothing to be done here */
  980. break;
  981. case AV_OPT_TYPE_FLAGS:
  982. case AV_OPT_TYPE_INT:
  983. case AV_OPT_TYPE_INT64:
  984. case AV_OPT_TYPE_DURATION:
  985. case AV_OPT_TYPE_CHANNEL_LAYOUT:
  986. av_opt_set_int(s, opt->name, opt->default_val.i64, 0);
  987. break;
  988. case AV_OPT_TYPE_DOUBLE:
  989. case AV_OPT_TYPE_FLOAT: {
  990. double val;
  991. val = opt->default_val.dbl;
  992. av_opt_set_double(s, opt->name, val, 0);
  993. }
  994. break;
  995. case AV_OPT_TYPE_RATIONAL: {
  996. AVRational val;
  997. val = av_d2q(opt->default_val.dbl, INT_MAX);
  998. av_opt_set_q(s, opt->name, val, 0);
  999. }
  1000. break;
  1001. case AV_OPT_TYPE_COLOR:
  1002. case AV_OPT_TYPE_STRING:
  1003. case AV_OPT_TYPE_IMAGE_SIZE:
  1004. case AV_OPT_TYPE_VIDEO_RATE:
  1005. av_opt_set(s, opt->name, opt->default_val.str, 0);
  1006. break;
  1007. case AV_OPT_TYPE_PIXEL_FMT:
  1008. #if LIBAVUTIL_VERSION_MAJOR < 53
  1009. if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
  1010. av_opt_set(s, opt->name, opt->default_val.str, 0);
  1011. else
  1012. #endif
  1013. av_opt_set_pixel_fmt(s, opt->name, opt->default_val.i64, 0);
  1014. break;
  1015. case AV_OPT_TYPE_SAMPLE_FMT:
  1016. #if LIBAVUTIL_VERSION_MAJOR < 53
  1017. if (class->version && class->version < AV_VERSION_INT(52, 10, 100))
  1018. av_opt_set(s, opt->name, opt->default_val.str, 0);
  1019. else
  1020. #endif
  1021. av_opt_set_sample_fmt(s, opt->name, opt->default_val.i64, 0);
  1022. break;
  1023. case AV_OPT_TYPE_BINARY:
  1024. /* Cannot set default for binary */
  1025. break;
  1026. default:
  1027. av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name);
  1028. }
  1029. }
  1030. }
  1031. /**
  1032. * Store the value in the field in ctx that is named like key.
  1033. * ctx must be an AVClass context, storing is done using AVOptions.
  1034. *
  1035. * @param buf the string to parse, buf will be updated to point at the
  1036. * separator just after the parsed key/value pair
  1037. * @param key_val_sep a 0-terminated list of characters used to
  1038. * separate key from value
  1039. * @param pairs_sep a 0-terminated list of characters used to separate
  1040. * two pairs from each other
  1041. * @return 0 if the key/value pair has been successfully parsed and
  1042. * set, or a negative value corresponding to an AVERROR code in case
  1043. * of error:
  1044. * AVERROR(EINVAL) if the key/value pair cannot be parsed,
  1045. * the error code issued by av_opt_set() if the key/value pair
  1046. * cannot be set
  1047. */
  1048. static int parse_key_value_pair(void *ctx, const char **buf,
  1049. const char *key_val_sep, const char *pairs_sep)
  1050. {
  1051. char *key = av_get_token(buf, key_val_sep);
  1052. char *val;
  1053. int ret;
  1054. if (!key)
  1055. return AVERROR(ENOMEM);
  1056. if (*key && strspn(*buf, key_val_sep)) {
  1057. (*buf)++;
  1058. val = av_get_token(buf, pairs_sep);
  1059. if (!val) {
  1060. av_freep(&key);
  1061. return AVERROR(ENOMEM);
  1062. }
  1063. } else {
  1064. av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
  1065. av_free(key);
  1066. return AVERROR(EINVAL);
  1067. }
  1068. av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
  1069. ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN);
  1070. if (ret == AVERROR_OPTION_NOT_FOUND)
  1071. av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
  1072. av_free(key);
  1073. av_free(val);
  1074. return ret;
  1075. }
  1076. int av_set_options_string(void *ctx, const char *opts,
  1077. const char *key_val_sep, const char *pairs_sep)
  1078. {
  1079. int ret, count = 0;
  1080. if (!opts)
  1081. return 0;
  1082. while (*opts) {
  1083. if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
  1084. return ret;
  1085. count++;
  1086. if (*opts)
  1087. opts++;
  1088. }
  1089. return count;
  1090. }
  1091. #define WHITESPACES " \n\t"
  1092. static int is_key_char(char c)
  1093. {
  1094. return (unsigned)((c | 32) - 'a') < 26 ||
  1095. (unsigned)(c - '0') < 10 ||
  1096. c == '-' || c == '_' || c == '/' || c == '.';
  1097. }
  1098. /**
  1099. * Read a key from a string.
  1100. *
  1101. * The key consists of is_key_char characters and must be terminated by a
  1102. * character from the delim string; spaces are ignored.
  1103. *
  1104. * @return 0 for success (even with ellipsis), <0 for failure
  1105. */
  1106. static int get_key(const char **ropts, const char *delim, char **rkey)
  1107. {
  1108. const char *opts = *ropts;
  1109. const char *key_start, *key_end;
  1110. key_start = opts += strspn(opts, WHITESPACES);
  1111. while (is_key_char(*opts))
  1112. opts++;
  1113. key_end = opts;
  1114. opts += strspn(opts, WHITESPACES);
  1115. if (!*opts || !strchr(delim, *opts))
  1116. return AVERROR(EINVAL);
  1117. opts++;
  1118. if (!(*rkey = av_malloc(key_end - key_start + 1)))
  1119. return AVERROR(ENOMEM);
  1120. memcpy(*rkey, key_start, key_end - key_start);
  1121. (*rkey)[key_end - key_start] = 0;
  1122. *ropts = opts;
  1123. return 0;
  1124. }
  1125. int av_opt_get_key_value(const char **ropts,
  1126. const char *key_val_sep, const char *pairs_sep,
  1127. unsigned flags,
  1128. char **rkey, char **rval)
  1129. {
  1130. int ret;
  1131. char *key = NULL, *val;
  1132. const char *opts = *ropts;
  1133. if ((ret = get_key(&opts, key_val_sep, &key)) < 0 &&
  1134. !(flags & AV_OPT_FLAG_IMPLICIT_KEY))
  1135. return AVERROR(EINVAL);
  1136. if (!(val = av_get_token(&opts, pairs_sep))) {
  1137. av_free(key);
  1138. return AVERROR(ENOMEM);
  1139. }
  1140. *ropts = opts;
  1141. *rkey = key;
  1142. *rval = val;
  1143. return 0;
  1144. }
  1145. int av_opt_set_from_string(void *ctx, const char *opts,
  1146. const char *const *shorthand,
  1147. const char *key_val_sep, const char *pairs_sep)
  1148. {
  1149. int ret, count = 0;
  1150. const char *dummy_shorthand = NULL;
  1151. char *av_uninit(parsed_key), *av_uninit(value);
  1152. const char *key;
  1153. if (!opts)
  1154. return 0;
  1155. if (!shorthand)
  1156. shorthand = &dummy_shorthand;
  1157. while (*opts) {
  1158. ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
  1159. *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
  1160. &parsed_key, &value);
  1161. if (ret < 0) {
  1162. if (ret == AVERROR(EINVAL))
  1163. av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
  1164. else
  1165. av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
  1166. av_err2str(ret));
  1167. return ret;
  1168. }
  1169. if (*opts)
  1170. opts++;
  1171. if (parsed_key) {
  1172. key = parsed_key;
  1173. while (*shorthand) /* discard all remaining shorthand */
  1174. shorthand++;
  1175. } else {
  1176. key = *(shorthand++);
  1177. }
  1178. av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
  1179. if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
  1180. if (ret == AVERROR_OPTION_NOT_FOUND)
  1181. av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
  1182. av_free(value);
  1183. av_free(parsed_key);
  1184. return ret;
  1185. }
  1186. av_free(value);
  1187. av_free(parsed_key);
  1188. count++;
  1189. }
  1190. return count;
  1191. }
  1192. void av_opt_free(void *obj)
  1193. {
  1194. const AVOption *o = NULL;
  1195. while ((o = av_opt_next(obj, o)))
  1196. if (o->type == AV_OPT_TYPE_STRING || o->type == AV_OPT_TYPE_BINARY)
  1197. av_freep((uint8_t *)obj + o->offset);
  1198. }
  1199. int av_opt_set_dict(void *obj, AVDictionary **options)
  1200. {
  1201. AVDictionaryEntry *t = NULL;
  1202. AVDictionary *tmp = NULL;
  1203. int ret = 0;
  1204. while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
  1205. ret = av_opt_set(obj, t->key, t->value, 0);
  1206. if (ret == AVERROR_OPTION_NOT_FOUND)
  1207. av_dict_set(&tmp, t->key, t->value, 0);
  1208. else if (ret < 0) {
  1209. av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
  1210. break;
  1211. }
  1212. ret = 0;
  1213. }
  1214. av_dict_free(options);
  1215. *options = tmp;
  1216. return ret;
  1217. }
  1218. const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
  1219. int opt_flags, int search_flags)
  1220. {
  1221. return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
  1222. }
  1223. const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
  1224. int opt_flags, int search_flags, void **target_obj)
  1225. {
  1226. const AVClass *c;
  1227. const AVOption *o = NULL;
  1228. if(!obj)
  1229. return NULL;
  1230. c= *(AVClass**)obj;
  1231. if (!c)
  1232. return NULL;
  1233. if (search_flags & AV_OPT_SEARCH_CHILDREN) {
  1234. if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
  1235. const AVClass *child = NULL;
  1236. while (child = av_opt_child_class_next(c, child))
  1237. if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
  1238. return o;
  1239. } else {
  1240. void *child = NULL;
  1241. while (child = av_opt_child_next(obj, child))
  1242. if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
  1243. return o;
  1244. }
  1245. }
  1246. while (o = av_opt_next(obj, o)) {
  1247. if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
  1248. ((!unit && o->type != AV_OPT_TYPE_CONST) ||
  1249. (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
  1250. if (target_obj) {
  1251. if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
  1252. *target_obj = obj;
  1253. else
  1254. *target_obj = NULL;
  1255. }
  1256. return o;
  1257. }
  1258. }
  1259. return NULL;
  1260. }
  1261. void *av_opt_child_next(void *obj, void *prev)
  1262. {
  1263. const AVClass *c = *(AVClass**)obj;
  1264. if (c->child_next)
  1265. return c->child_next(obj, prev);
  1266. return NULL;
  1267. }
  1268. const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
  1269. {
  1270. if (parent->child_class_next)
  1271. return parent->child_class_next(prev);
  1272. return NULL;
  1273. }
  1274. void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
  1275. {
  1276. const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
  1277. if(!opt)
  1278. return NULL;
  1279. return (uint8_t*)obj + opt->offset;
  1280. }
  1281. int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
  1282. {
  1283. const AVClass *c = *(AVClass**)obj;
  1284. int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL;
  1285. if (c->version > (52 << 16 | 11 << 8))
  1286. callback = c->query_ranges;
  1287. if (!callback)
  1288. callback = av_opt_query_ranges_default;
  1289. return callback(ranges_arg, obj, key, flags);
  1290. }
  1291. int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
  1292. {
  1293. AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
  1294. AVOptionRange **range_array = av_mallocz(sizeof(void*));
  1295. AVOptionRange *range = av_mallocz(sizeof(*range));
  1296. const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
  1297. int ret;
  1298. *ranges_arg = NULL;
  1299. if (!ranges || !range || !range_array || !field) {
  1300. ret = AVERROR(ENOMEM);
  1301. goto fail;
  1302. }
  1303. ranges->range = range_array;
  1304. ranges->range[0] = range;
  1305. ranges->nb_ranges = 1;
  1306. range->is_range = 1;
  1307. range->value_min = field->min;
  1308. range->value_max = field->max;
  1309. switch (field->type) {
  1310. case AV_OPT_TYPE_INT:
  1311. case AV_OPT_TYPE_INT64:
  1312. case AV_OPT_TYPE_PIXEL_FMT:
  1313. case AV_OPT_TYPE_SAMPLE_FMT:
  1314. case AV_OPT_TYPE_FLOAT:
  1315. case AV_OPT_TYPE_DOUBLE:
  1316. case AV_OPT_TYPE_DURATION:
  1317. case AV_OPT_TYPE_COLOR:
  1318. case AV_OPT_TYPE_CHANNEL_LAYOUT:
  1319. break;
  1320. case AV_OPT_TYPE_STRING:
  1321. range->component_min = 0;
  1322. range->component_max = 0x10FFFF; // max unicode value
  1323. range->value_min = -1;
  1324. range->value_max = INT_MAX;
  1325. break;
  1326. case AV_OPT_TYPE_RATIONAL:
  1327. range->component_min = INT_MIN;
  1328. range->component_max = INT_MAX;
  1329. break;
  1330. case AV_OPT_TYPE_IMAGE_SIZE:
  1331. range->component_min = 0;
  1332. range->component_max = INT_MAX/128/8;
  1333. range->value_min = 0;
  1334. range->value_max = INT_MAX/8;
  1335. break;
  1336. case AV_OPT_TYPE_VIDEO_RATE:
  1337. range->component_min = 1;
  1338. range->component_max = INT_MAX;
  1339. range->value_min = 1;
  1340. range->value_max = INT_MAX;
  1341. break;
  1342. default:
  1343. ret = AVERROR(ENOSYS);
  1344. goto fail;
  1345. }
  1346. *ranges_arg = ranges;
  1347. return 0;
  1348. fail:
  1349. av_free(ranges);
  1350. av_free(range);
  1351. av_free(range_array);
  1352. return ret;
  1353. }
  1354. void av_opt_freep_ranges(AVOptionRanges **rangesp)
  1355. {
  1356. int i;
  1357. AVOptionRanges *ranges = *rangesp;
  1358. for (i = 0; i < ranges->nb_ranges; i++) {
  1359. AVOptionRange *range = ranges->range[i];
  1360. av_freep(&range->str);
  1361. av_freep(&ranges->range[i]);
  1362. }
  1363. av_freep(&ranges->range);
  1364. av_freep(rangesp);
  1365. }
  1366. #ifdef TEST
  1367. typedef struct TestContext
  1368. {
  1369. const AVClass *class;
  1370. int num;
  1371. int toggle;
  1372. char *string;
  1373. int flags;
  1374. AVRational rational;
  1375. AVRational video_rate;
  1376. int w, h;
  1377. enum AVPixelFormat pix_fmt;
  1378. enum AVSampleFormat sample_fmt;
  1379. int64_t duration;
  1380. uint8_t color[4];
  1381. int64_t channel_layout;
  1382. } TestContext;
  1383. #define OFFSET(x) offsetof(TestContext, x)
  1384. #define TEST_FLAG_COOL 01
  1385. #define TEST_FLAG_LAME 02
  1386. #define TEST_FLAG_MU 04
  1387. static const AVOption test_options[]= {
  1388. {"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100 },
  1389. {"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1 },
  1390. {"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10 },
  1391. {"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, {.str = "default"}, CHAR_MIN, CHAR_MAX },
  1392. {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
  1393. {"cool", "set cool flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0, "flags" },
  1394. {"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" },
  1395. {"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" },
  1396. {"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{0}, 0, 0 },
  1397. {"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, AV_PIX_FMT_NB-1},
  1398. {"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1},
  1399. {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0 },
  1400. {"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX},
  1401. {"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0},
  1402. {"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX},
  1403. {NULL},
  1404. };
  1405. static const char *test_get_name(void *ctx)
  1406. {
  1407. return "test";
  1408. }
  1409. static const AVClass test_class = {
  1410. "TestContext",
  1411. test_get_name,
  1412. test_options
  1413. };
  1414. int main(void)
  1415. {
  1416. int i;
  1417. printf("\nTesting av_set_options_string()\n");
  1418. {
  1419. TestContext test_ctx = { 0 };
  1420. static const char * const options[] = {
  1421. "",
  1422. ":",
  1423. "=",
  1424. "foo=:",
  1425. ":=foo",
  1426. "=foo",
  1427. "foo=",
  1428. "foo",
  1429. "foo=val",
  1430. "foo==val",
  1431. "toggle=:",
  1432. "string=:",
  1433. "toggle=1 : foo",
  1434. "toggle=100",
  1435. "toggle==1",
  1436. "flags=+mu-lame : num=42: toggle=0",
  1437. "num=42 : string=blahblah",
  1438. "rational=0 : rational=1/2 : rational=1/-1",
  1439. "rational=-1/0",
  1440. "size=1024x768",
  1441. "size=pal",
  1442. "size=bogus",
  1443. "pix_fmt=yuv420p",
  1444. "pix_fmt=2",
  1445. "pix_fmt=bogus",
  1446. "sample_fmt=s16",
  1447. "sample_fmt=2",
  1448. "sample_fmt=bogus",
  1449. "video_rate=pal",
  1450. "video_rate=25",
  1451. "video_rate=30000/1001",
  1452. "video_rate=30/1.001",
  1453. "video_rate=bogus",
  1454. "duration=bogus",
  1455. "duration=123.45",
  1456. "duration=1\\:23\\:45.67",
  1457. "color=blue",
  1458. "color=0x223300",
  1459. "color=0x42FF07AA",
  1460. "cl=stereo+downmix",
  1461. "cl=foo",
  1462. };
  1463. test_ctx.class = &test_class;
  1464. av_opt_set_defaults(&test_ctx);
  1465. av_log_set_level(AV_LOG_DEBUG);
  1466. for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
  1467. av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
  1468. if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
  1469. av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
  1470. printf("\n");
  1471. }
  1472. av_opt_free(&test_ctx);
  1473. }
  1474. printf("\nTesting av_opt_set_from_string()\n");
  1475. {
  1476. TestContext test_ctx = { 0 };
  1477. static const char * const options[] = {
  1478. "",
  1479. "5",
  1480. "5:hello",
  1481. "5:hello:size=pal",
  1482. "5:size=pal:hello",
  1483. ":",
  1484. "=",
  1485. " 5 : hello : size = pal ",
  1486. "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
  1487. };
  1488. static const char * const shorthand[] = { "num", "string", NULL };
  1489. test_ctx.class = &test_class;
  1490. av_opt_set_defaults(&test_ctx);
  1491. av_log_set_level(AV_LOG_DEBUG);
  1492. for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
  1493. av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
  1494. if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0)
  1495. av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
  1496. printf("\n");
  1497. }
  1498. av_opt_free(&test_ctx);
  1499. }
  1500. return 0;
  1501. }
  1502. #endif