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 /**
23 * @file
24 * AVOptions
25 * @author Michael Niedermayer <michaelni@gmx.at>
26 */
27
41
43
44 #if FF_API_OLD_AVOPTIONS
46 {
48 }
49 #endif
50
52 {
54 if (!obj)
57 if (!last &&
class &&
class->option &&
class->option[0].name)
58 return class->option;
59 if (last && last[1].
name)
60 return ++last;
62 }
63
65 {
78 return 0;
80 }
82 }
83
85 {
87 (o->
max * den < num * intnum || o->
min * den > num * intnum)) {
91 }
93 double d = num*intnum/den;
94 if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (
llrint(d*256) & 255)) {
96 "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
97 num*intnum/den, o->
name);
99 }
100 }
101
115 break;
116 default:
118 }
119 return 0;
120 }
121
123 if (c >= '0' && c <= '9') return c - '0';
124 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
125 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
126 return -1;
127 }
128
130 {
131 int *lendst = (int *)(dst + 1);
134
136 *lendst = 0;
137
138 if (!val || !(len = strlen(val)))
139 return 0;
140
141 if (len & 1)
143 len /= 2;
144
146 if (!ptr)
148 while (*val) {
151 if (a < 0 || b < 0) {
154 }
155 *ptr++ = (a << 4) | b;
156 }
157 *dst = bin;
159
160 return 0;
161 }
162
164 {
167 return *dst ? 0 :
AVERROR(ENOMEM);
168 }
169
170 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
171 opt->type == AV_OPT_TYPE_CONST || \
172 opt->type == AV_OPT_TYPE_FLAGS || \
173 opt->type == AV_OPT_TYPE_INT) ? \
174 opt->default_val.i64 : opt->default_val.dbl)
175
177 {
179 int num, den;
181
182 if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
183 if ((ret =
write_number(obj, o, dst, 1, den, num)) >= 0)
185 ret = 0;
186 }
187
188 for (;;) {
189 int i = 0;
191 int cmd = 0;
192 double d;
193 int64_t intnum = 1;
194
196 if (*val == '+' || *val == '-')
197 cmd = *(val++);
198 for (; i <
sizeof(
buf) - 1 && val[i] && val[i] !=
'+' && val[i] !=
'-'; i++)
199 buf[i] = val[i];
200 buf[i] = 0;
201 }
202
203 {
205 int res;
206 int ci = 0;
207 double const_values[64];
208 const char * const_names[64];
211 else {
220 }
221 const_names [ci ] = o_named->
name;
223 }
224 }
225 }
226 const_names [ci ] = "default";
228 const_names [ci ] = "max";
229 const_values[ci++] = o->
max;
230 const_names [ci ] = "min";
231 const_values[ci++] = o->
min;
232 const_names [ci ] = "none";
233 const_values[ci++] = 0;
234 const_names [ci ] = "all";
235 const_values[ci++] = ~0;
236 const_names [ci] =
NULL;
237 const_values[ci] = 0;
238
241 if (res < 0) {
243 return res;
244 }
245 }
246 }
249 if (cmd == '+') d = intnum | (int64_t)d;
250 else if (cmd == '-') d = intnum &~(int64_t)d;
251 }
252
255 val += i;
256 if (!i || !*val)
257 return 0;
258 }
259
260 return 0;
261 }
262
264 {
266
267 if (!val || !strcmp(val, "none")) {
268 dst[0] =
269 dst[1] = 0;
270 return 0;
271 }
273 if (ret < 0)
274 av_log(obj,
AV_LOG_ERROR,
"Unable to parse option value \"%s\" as image size\n", val);
276 }
277
279 {
281 if (!val) {
283 } else {
285 }
286 if (ret < 0)
287 av_log(obj,
AV_LOG_ERROR,
"Unable to parse option value \"%s\" as video rate\n", val);
289 }
290
292 {
294
295 if (!val) {
296 return 0;
297 } else {
299 if (ret < 0)
302 }
303 return 0;
304 }
305
307 int fmt_nb, int ((*get_fmt)(const char *)), const char *desc)
308 {
310
311 if (!val || !strcmp(val, "none")) {
312 fmt = -1;
313 } else {
314 fmt = get_fmt(val);
315 if (fmt == -1) {
316 char *tail;
317 fmt = strtol(val, &tail, 0);
318 if (*tail || (unsigned)fmt >= fmt_nb) {
320 "Unable to parse option value \"%s\" as %s\n", val, desc);
322 }
323 }
324 }
325
328
329 // hack for compatibility with old ffmpeg
330 if(min == 0 && max == 0) {
331 min = -1;
332 max = fmt_nb-1;
333 }
334
335 if (fmt < min || fmt > max) {
337 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
338 fmt, o->
name, desc, min, max);
340 }
341
342 *(int *)dst = fmt;
343 return 0;
344 }
345
347 {
350 }
351
353 {
356 }
357
358 #if FF_API_OLD_AVOPTIONS
360 {
362 if (o_out)
363 *o_out = o;
365 }
366 #endif
367
369 {
371 void *dst, *target_obj;
373 if (!o || !target_obj)
381
384
400 if (!val) {
401 *(int64_t *)dst = 0;
402 return 0;
403 } else {
407 }
408 break;
411 if (!val || !strcmp(val, "none")) {
412 *(int64_t *)dst = 0;
413 } else {
414 #if FF_API_GET_CHANNEL_LAYOUT_COMPAT
416 #else
418 #endif
419 if (!cl) {
420 av_log(obj,
AV_LOG_ERROR,
"Unable to parse option value \"%s\" as channel layout\n", val);
422 }
423 *(int64_t *)dst = cl;
425 }
426 break;
427 }
428
431 }
432
433 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
434 int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
435 {\
436 if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY)\
437 return AVERROR(EINVAL);\
438 return set_string_number(obj, obj, o, val, name ## _out);\
439 }
440
447
448 static
int set_number(
void *obj, const
char *
name,
double num,
int den, int64_t intnum,
449 int search_flags)
450 {
451 void *dst, *target_obj;
453
454 if (!o || !target_obj)
456
459
462 }
463
464 #if FF_API_OLD_AVOPTIONS
466 {
470 return o;
471 }
472
474 {
478 return o;
479 }
480
482 {
486 return o;
487 }
488 #endif
489
491 {
492 return set_number(obj, name, 1, 1, val, search_flags);
493 }
494
496 {
497 return set_number(obj, name, val, 1, 1, search_flags);
498 }
499
501 {
503 }
504
506 {
507 void *target_obj;
511 int *lendst;
512
513 if (!o || !target_obj)
515
518
520 if (len && !ptr)
522
524 lendst = (int *)(dst + 1);
525
527 *dst = ptr;
529 if (len)
530 memcpy(ptr, val, len);
531
532 return 0;
533 }
534
536 {
537 void *target_obj;
539
540 if (!o || !target_obj)
544 "The value set by option '%s' is not an image size.\n", o->
name);
546 }
547 if (w<0 || h<0) {
549 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->
name);
551 }
553 *(
int *)(((
uint8_t *)target_obj+
sizeof(int)) + o->
offset) = h;
554 return 0;
555 }
556
558 {
559 void *target_obj;
561
562 if (!o || !target_obj)
566 "The value set by option '%s' is not a video rate.\n", o->
name);
568 }
569 if (val.
num <= 0 || val.
den <= 0)
572 }
573
576 {
577 void *target_obj;
579 search_flags, &target_obj);
581
582 if (!o || !target_obj)
584 if (o->
type != type) {
586 "The value set by option '%s' is not a %s format", name, desc);
588 }
589
592
593 if (fmt < min || fmt > max) {
595 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
596 fmt, name, desc, min, max);
598 }
600 return 0;
601 }
602
604 {
606 }
607
609 {
611 }
612
614 {
615 void *target_obj;
617
618 if (!o || !target_obj)
622 "The value set by option '%s' is not a channel layout.\n", o->
name);
624 }
626 return 0;
627 }
628
629 #if FF_API_OLD_AVOPTIONS
630 /**
631 *
632 * @param buf a buffer which is used for returning non string values as strings, can be NULL
633 * @param buf_len allocated length in bytes of buf
634 */
636 {
638 void *dst;
641 if (!o)
645
647 if (o_out) *o_out= o;
648
660 if (len >= (buf_len + 1)/2)
return NULL;
662 for (i = 0; i <
len; i++)
snprintf(buf + i*2, 3,
"%02X", bin[i]);
663 break;
664 default:
return NULL;
665 }
667 }
668 #endif
669
671 {
672 void *target_obj;
675
676 if (!o || !target_obj)
680
684
685 return 0;
686 }
687
689 {
690 void *dst, *target_obj;
694 int64_t i64;
695
698
700
701 buf[0] = 0;
714 else
716 return *out_val ? 0 :
AVERROR(ENOMEM);
719 if ((uint64_t)len*2 + 1 > INT_MAX)
723 if (!len) {
724 *out_val[0] = '0円';
725 return 0;
726 }
728 for (i = 0; i <
len; i++)
729 snprintf(*out_val + i*2, 3,
"%02X", bin[i]);
730 return 0;
732 ret =
snprintf(buf,
sizeof(buf),
"%dx%d", ((
int *)dst)[0], ((
int *)dst)[1]);
733 break;
736 break;
739 break;
741 i64 = *(int64_t *)dst;
742 ret =
snprintf(buf,
sizeof(buf),
"%"PRIi64
":%02d:%02d.%06d",
743 i64 / 3600000000, (int)((i64 / 60000000) % 60),
744 (int)((i64 / 1000000) % 60), (int)(i64 % 1000000));
745 break;
747 ret =
snprintf(buf,
sizeof(buf),
"0x%02x%02x%02x%02x",
750 break;
752 i64 = *(int64_t *)dst;
753 ret =
snprintf(buf,
sizeof(buf),
"0x%"PRIx64, i64);
754 break;
755 default:
757 }
758
759 if (ret >= sizeof(buf))
762 return *out_val ? 0 :
AVERROR(ENOMEM);
763 }
764
766 int search_flags)
767 {
768 void *dst, *target_obj;
770 if (!o || !target_obj)
771 goto error;
772
774
775 if (o_out) *o_out= o;
776
778
779 error:
780 *den=*intnum=0;
781 return -1;
782 }
783
784 #if FF_API_OLD_AVOPTIONS
786 {
787 int64_t intnum=1;
788 double num=1;
789 int den=1;
790
791 if (
get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
793 return num*intnum/den;
794 }
795
797 {
798 int64_t intnum=1;
799 double num=1;
800 int den=1;
801
802 if (
get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
804 if (num == 1.0 && (int)intnum == intnum)
806 else
807 return av_d2q(num*intnum/den, 1<<24);
808 }
809
811 {
812 int64_t intnum=1;
813 double num=1;
814 int den=1;
815
816 if (
get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
817 return -1;
818 return num*intnum/den;
819 }
820 #endif
821
823 {
824 int64_t intnum = 1;
825 double num = 1;
827
828 if ((ret =
get_number(obj, name,
NULL, &num, &den, &intnum, search_flags)) < 0)
830 *out_val = num*intnum/den;
831 return 0;
832 }
833
835 {
836 int64_t intnum = 1;
837 double num = 1;
839
840 if ((ret =
get_number(obj, name,
NULL, &num, &den, &intnum, search_flags)) < 0)
842 *out_val = num*intnum/den;
843 return 0;
844 }
845
847 {
848 int64_t intnum = 1;
849 double num = 1;
851
852 if ((ret =
get_number(obj, name,
NULL, &num, &den, &intnum, search_flags)) < 0)
854
855 if (num == 1.0 && (int)intnum == intnum)
857 else
858 *out_val =
av_d2q(num*intnum/den, 1<<24);
859 return 0;
860 }
861
863 {
864 void *dst, *target_obj;
866 if (!o || !target_obj)
870 "The value for option '%s' is not an image size.\n", name);
872 }
873
875 if (w_out) *w_out = *(int *)dst;
876 if (h_out) *h_out = *((int *)dst+1);
877 return 0;
878 }
879
881 {
882 int64_t intnum = 1;
883 double num = 1;
885
886 if ((ret =
get_number(obj, name,
NULL, &num, &den, &intnum, search_flags)) < 0)
888
889 if (num == 1.0 && (int)intnum == intnum)
891 else
892 *out_val =
av_d2q(num*intnum/den, 1<<24);
893 return 0;
894 }
895
896 static int get_format(
void *obj,
const char *
name,
int search_flags,
int *out_fmt,
898 {
899 void *dst, *target_obj;
901 if (!o || !target_obj)
903 if (o->
type != type) {
905 "The value for option '%s' is not a %s format.\n", desc, name);
907 }
908
910 *out_fmt = *(int *)dst;
911 return 0;
912 }
913
915 {
917 }
918
920 {
922 }
923
925 {
926 void *dst, *target_obj;
928 if (!o || !target_obj)
932 "The value for option '%s' is not a channel layout.\n", name);
934 }
935
937 *cl = *(int64_t *)dst;
938 return 0;
939 }
940
942 {
943 void *target_obj;
946
947 if (!o || !target_obj)
951
954
955 return 0;
956 }
957
959 {
963 int64_t res;
964
967 return 0;
969 }
970
972 {
973 if (d == INT_MAX) {
974 av_log(av_log_obj, level,
"INT_MAX");
975 } else if (d == INT_MIN) {
976 av_log(av_log_obj, level,
"INT_MIN");
977 } else if (d == UINT32_MAX) {
978 av_log(av_log_obj, level,
"UINT32_MAX");
979 } else if (d == (double)INT64_MAX) {
980 av_log(av_log_obj, level,
"I64_MAX");
981 } else if (d == INT64_MIN) {
982 av_log(av_log_obj, level,
"I64_MIN");
983 } else if (d == FLT_MAX) {
984 av_log(av_log_obj, level,
"FLT_MAX");
985 } else if (d == FLT_MIN) {
986 av_log(av_log_obj, level,
"FLT_MIN");
987 } else if (d == -FLT_MAX) {
988 av_log(av_log_obj, level,
"-FLT_MAX");
989 } else if (d == -FLT_MIN) {
990 av_log(av_log_obj, level,
"-FLT_MIN");
991 } else if (d == DBL_MAX) {
992 av_log(av_log_obj, level,
"DBL_MAX");
993 } else if (d == DBL_MIN) {
994 av_log(av_log_obj, level,
"DBL_MIN");
995 } else if (d == -DBL_MAX) {
996 av_log(av_log_obj, level,
"-DBL_MAX");
997 } else if (d == -DBL_MIN) {
998 av_log(av_log_obj, level,
"-DBL_MIN");
999 } else {
1000 av_log(av_log_obj, level,
"%g", d);
1001 }
1002 }
1003
1004 static void opt_list(
void *obj,
void *av_log_obj,
const char *unit,
1005 int req_flags, int rej_flags)
1006 {
1009 int i;
1010
1012 if (!(opt->
flags & req_flags) || (opt->
flags & rej_flags))
1013 continue;
1014
1015 /* Don't print CONST's on level one.
1016 * Don't print anything but CONST's on level two.
1017 * Only print items from the requested unit.
1018 */
1020 continue;
1022 continue;
1024 continue;
1027 else
1031
1032 switch (opt->
type) {
1035 break;
1038 break;
1041 break;
1044 break;
1047 break;
1050 break;
1053 break;
1056 break;
1059 break;
1062 break;
1065 break;
1068 break;
1071 break;
1074 break;
1077 break;
1079 default:
1081 break;
1082 }
1091
1094
1096 switch (opt->
type) {
1108 }
1109 break;
1110 }
1112 }
1113
1122 switch (opt->
type) {
1125 break;
1130 break;
1134 break;
1138 break;
1141 break;
1144 break;
1150 break;
1153 break;
1154 }
1156 }
1157
1160 opt_list(obj, av_log_obj, opt->
unit, req_flags, rej_flags);
1161 }
1162 }
1163 }
1164
1165 int av_opt_show2(
void *obj,
void *av_log_obj,
int req_flags,
int rej_flags)
1166 {
1167 if (!obj)
1168 return -1;
1169
1171
1173
1174 return 0;
1175 }
1176
1178 {
1179 #if FF_API_OLD_AVOPTIONS
1181 }
1182
1184 {
1185 #endif
1189 #if FF_API_OLD_AVOPTIONS
1191 continue;
1192 #endif
1193
1195 continue;
1196
1197 switch (opt->
type) {
1199 /* Nothing to be done here */
1200 break;
1207 break;
1213 }
1214 break;
1219 }
1220 break;
1223 break;
1226 break;
1229 break;
1232 break;
1235 break;
1238 break;
1241 break;
1243 /* Cannot set defaults for these types */
1244 break;
1245 default:
1247 }
1248 }
1249 }
1250
1251 /**
1252 * Store the value in the field in ctx that is named like key.
1253 * ctx must be an AVClass context, storing is done using AVOptions.
1254 *
1255 * @param buf the string to parse, buf will be updated to point at the
1256 * separator just after the parsed key/value pair
1257 * @param key_val_sep a 0-terminated list of characters used to
1258 * separate key from value
1259 * @param pairs_sep a 0-terminated list of characters used to separate
1260 * two pairs from each other
1261 * @return 0 if the key/value pair has been successfully parsed and
1262 * set, or a negative value corresponding to an AVERROR code in case
1263 * of error:
1264 * AVERROR(EINVAL) if the key/value pair cannot be parsed,
1265 * the error code issued by av_opt_set() if the key/value pair
1266 * cannot be set
1267 */
1269 const char *key_val_sep, const char *pairs_sep)
1270 {
1274
1275 if (!key)
1277
1278 if (*key && strspn(*buf, key_val_sep)) {
1279 (*buf)++;
1281 if (!val) {
1284 }
1285 } else {
1286 av_log(ctx,
AV_LOG_ERROR,
"Missing key or no key/value separator found after key '%s'\n", key);
1289 }
1290
1292
1296
1300 }
1301
1303 const char *key_val_sep, const char *pairs_sep)
1304 {
1306
1307 if (!opts)
1308 return 0;
1309
1310 while (*opts) {
1313 count++;
1314
1315 if (*opts)
1316 opts++;
1317 }
1318
1320 }
1321
1322 #define WHITESPACES " \n\t"
1323
1325 {
1326 return (unsigned)((c | 32) - 'a') < 26 ||
1327 (unsigned)(c - '0') < 10 ||
1328 c == '-' || c == '_' || c == '/' || c == '.';
1329 }
1330
1331 /**
1332 * Read a key from a string.
1333 *
1334 * The key consists of is_key_char characters and must be terminated by a
1335 * character from the delim string; spaces are ignored.
1336 *
1337 * @return 0 for success (even with ellipsis), <0 for failure
1338 */
1339 static int get_key(
const char **ropts,
const char *delim,
char **rkey)
1340 {
1341 const char *opts = *ropts;
1342 const char *key_start, *key_end;
1343
1346 opts++;
1347 key_end = opts;
1349 if (!*opts || !strchr(delim, *opts))
1351 opts++;
1352 if (!(*rkey =
av_malloc(key_end - key_start + 1)))
1354 memcpy(*rkey, key_start, key_end - key_start);
1355 (*rkey)[key_end - key_start] = 0;
1356 *ropts = opts;
1357 return 0;
1358 }
1359
1361 const char *key_val_sep, const char *pairs_sep,
1363 char **rkey, char **rval)
1364 {
1367 const char *opts = *ropts;
1368
1369 if ((ret =
get_key(&opts, key_val_sep, &key)) < 0 &&
1375 }
1376 *ropts = opts;
1377 *rkey = key;
1379 return 0;
1380 }
1381
1383 const char *const *shorthand,
1384 const char *key_val_sep, const char *pairs_sep)
1385 {
1387 const char *dummy_shorthand =
NULL;
1389 const char *key;
1390
1391 if (!opts)
1392 return 0;
1393 if (!shorthand)
1394 shorthand = &dummy_shorthand;
1395
1396 while (*opts) {
1399 &parsed_key, &
value);
1400 if (ret < 0) {
1403 else
1407 }
1408 if (*opts)
1409 opts++;
1410 if (parsed_key) {
1411 key = parsed_key;
1412 while (*shorthand) /* discard all remaining shorthand */
1413 shorthand++;
1414 } else {
1415 key = *(shorthand++);
1416 }
1417
1425 }
1426
1429 count++;
1430 }
1432 }
1433
1435 {
1442 break;
1443
1446 break;
1447
1448 default:
1449 break;
1450 }
1451 }
1452 }
1453
1455 {
1459
1460 if (!options)
1461 return 0;
1462
1467 else if (ret < 0) {
1469 break;
1470 }
1471 ret = 0;
1472 }
1474 *options = tmp;
1476 }
1477
1479 {
1481 }
1482
1484 int opt_flags, int search_flags)
1485 {
1487 }
1488
1490 int opt_flags, int search_flags, void **target_obj)
1491 {
1494
1495 if(!obj)
1497
1499
1500 if (!c)
1502
1508 return o;
1509 } else {
1512 if (o =
av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
1513 return o;
1514 }
1515 }
1516
1518 if (!strcmp(o->
name, name) && (o->
flags & opt_flags) == opt_flags &&
1521 if (target_obj) {
1523 *target_obj = obj;
1524 else
1526 }
1527 return o;
1528 }
1529 }
1531 }
1532
1534 {
1539 }
1540
1542 {
1546 }
1547
1549 {
1551 if(!opt)
1554 }
1555
1557 {
1558 switch(type) {
1574 }
1575 return 0;
1576 }
1577
1579 {
1583
1584 if (!src)
1585 return 0;
1586
1590
1596
1598 if (*field_dst8 != *field_src8)
1601 if (*field_src8 && !*field_dst8)
1604 int len = *(
int*)(field_src8 + 1);
1605 if (*field_dst8 != *field_src8)
1607 *field_dst8 =
av_memdup(*field_src8, len);
1608 if (len && !*field_dst8) {
1610 len = 0;
1611 }
1612 *(
int*)(field_dst8 + 1) =
len;
1614 // do nothing
1618 if (*sdict != *ddict)
1624 } else {
1626 }
1627 }
1629 }
1630
1632 {
1636
1637 if (c->
version > (52 << 16 | 11 << 8))
1639
1642
1643 ret =
callback(ranges_arg, obj, key, flags);
1644 if (ret >= 0) {
1646 ret = 1;
1647 (*ranges_arg)->nb_components =
ret;
1648 }
1650 }
1651
1653 {
1659
1661
1662 if (!ranges || !range || !range_array || !field) {
1664 goto fail;
1665 }
1666
1667 ranges->
range = range_array;
1668 ranges->
range[0] = range;
1674
1675 switch (field->
type) {
1685 break;
1691 break;
1695 break;
1701 break;
1707 break;
1708 default:
1710 goto fail;
1711 }
1712
1713 *ranges_arg = ranges;
1714 return 1;
1715 fail:
1720 }
1721
1723 {
1724 int i;
1726
1727 if (!ranges)
1728 return;
1729
1732 if (range) {
1735 }
1736 }
1739 }
1740
1742 {
1743 int64_t i64;
1744 double d, d2;
1745 float f;
1748 char *str;
1749 void *dst;
1750
1751 if (!o || !obj)
1753
1755
1758 return 1;
1769 str = *(char **)dst;
1771 return 1;
1773 return 0;
1781 d2 = f;
1782 return d2 == d;
1787 struct {
1790 } tmp = {0};
1791 int opt_size = *(
int *)((
void **)dst + 1);
1792 void *opt_ptr = *(void **)dst;
1794 return 1;
1796 return 0;
1798 return 0;
1800 if (!ret)
1801 ret = !memcmp(opt_ptr, tmp.data, tmp.size);
1804 }
1806 /* Binary and dict have not default support yet. Any pointer is not default. */
1807 return !!(*(void **)dst);
1810 w = h = 0;
1813 return (w == *(int *)dst) && (h == *((int *)dst+1));
1819 }
1826 }
1827 return !memcmp(color, dst, sizeof(color));
1828 }
1829 default:
1831 break;
1832 }
1834 }
1835
1837 {
1839 void *target;
1840 if (!obj)
1843 if (!o)
1846 }
1847
1849 const char key_val_sep, const char pairs_sep)
1850 {
1853 AVBPrint bprint;
1855 const char special_chars[] = {pairs_sep, key_val_sep, '0円'};
1856
1857 if (pairs_sep == '0円' || key_val_sep == '0円' || pairs_sep == key_val_sep ||
1858 pairs_sep == '\\' || key_val_sep == '\\') {
1861 }
1862
1863 if (!obj || !buffer)
1865
1868
1871 continue;
1873 continue;
1874 else if (((o->
flags & opt_flags) != opt_flags))
1875 continue;
1877 continue;
1881 }
1882 if (buf) {
1883 if (cnt++)
1889 }
1890 }
1892 return 0;
1893 }
1894
1895 #ifdef TEST
1896
1897 typedef struct TestContext
1898 {
1900 int num;
1901 int toggle;
1906 int w, h;
1911 int64_t channel_layout;
1912 void *binary;
1913 int binary_size;
1914 void *binary1;
1915 int binary_size1;
1916 void *binary2;
1917 int binary_size2;
1918 int64_t num64;
1919 float flt;
1920 double dbl;
1921 char *escape;
1922 } TestContext;
1923
1924 #define OFFSET(x) offsetof(TestContext, x)
1925
1926 #define TEST_FLAG_COOL 01
1927 #define TEST_FLAG_LAME 02
1928 #define TEST_FLAG_MU 04
1929
1930 static const AVOption test_options[]= {
1937 {
"cool",
"set cool flag", 0,
AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 1,
"flags" },
1938 {
"lame",
"set lame flag", 0,
AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 1,
"flags" },
1939 {
"mu",
"set mu flag", 0,
AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 1,
"flags" },
1954 };
1955
1956 static const char *test_get_name(void *ctx)
1957 {
1958 return "test";
1959 }
1960
1961 static const AVClass test_class = {
1962 "TestContext",
1963 test_get_name,
1964 test_options
1965 };
1966
1968 {
1969 vfprintf(stdout, fmt, vl);
1970 }
1971
1973 {
1974 int i;
1975
1978
1979 printf("Testing default values\n");
1980 {
1981 TestContext test_ctx = { 0 };
1982 test_ctx.class = &test_class;
1984
1985 printf("num=%d\n", test_ctx.num);
1986 printf("toggle=%d\n", test_ctx.toggle);
1987 printf("string=%s\n", test_ctx.string);
1988 printf("escape=%s\n", test_ctx.escape);
1989 printf("flags=%d\n", test_ctx.flags);
1990 printf("rational=%d/%d\n", test_ctx.rational.num, test_ctx.rational.den);
1991 printf("video_rate=%d/%d\n", test_ctx.video_rate.num, test_ctx.video_rate.den);
1992 printf("width=%d height=%d\n", test_ctx.w, test_ctx.h);
1995 printf("duration=%"PRId64"\n", test_ctx.duration);
1996 printf("color=%d %d %d %d\n", test_ctx.color[0], test_ctx.color[1], test_ctx.color[2], test_ctx.color[3]);
1997 printf(
"channel_layout=%"PRId64
"=%"PRId64
"\n", test_ctx.channel_layout, (int64_t)
AV_CH_LAYOUT_HEXAGONAL);
1998 if (test_ctx.binary)
1999 printf(
"binary=%x %x %x %x\n", ((
uint8_t*)test_ctx.binary)[0], ((
uint8_t*)test_ctx.binary)[1], ((
uint8_t*)test_ctx.binary)[2], ((
uint8_t*)test_ctx.binary)[3]);
2000 printf("binary_size=%d\n", test_ctx.binary_size);
2001 printf("num64=%"PRId64"\n", test_ctx.num64);
2002 printf("flt=%.6f\n", test_ctx.flt);
2003 printf("dbl=%.6f\n", test_ctx.dbl);
2004
2006
2008 }
2009
2010 printf("\nTesting av_opt_is_set_to_default()\n");
2011 {
2013 TestContext test_ctx = { 0 };
2015 test_ctx.class = &test_class;
2016
2018
2021 printf(
"name:%10s default:%d error:%s\n", o->
name, !!ret, ret < 0 ?
av_err2str(ret) :
"");
2022 }
2026 printf(
"name:%10s default:%d error:%s\n", o->
name, !!ret, ret < 0 ?
av_err2str(ret) :
"");
2027 }
2029 }
2030
2031 printf("\nTest av_opt_serialize()\n");
2032 {
2033 TestContext test_ctx = { 0 };
2035 test_ctx.class = &test_class;
2036
2038
2041 printf("%s\n", buf);
2043 memset(&test_ctx, 0, sizeof(test_ctx));
2044 test_ctx.class = &test_class;
2048 printf("%s\n", buf);
2050 }
2051 }
2053 }
2054
2055 printf("\nTesting av_set_options_string()\n");
2056 {
2057 TestContext test_ctx = { 0 };
2058 static const char *
const options[] = {
2059 "",
2060 ":",
2061 "=",
2062 "foo=:",
2063 ":=foo",
2064 "=foo",
2065 "foo=",
2066 "foo",
2067 "foo=val",
2068 "foo==val",
2069 "toggle=:",
2070 "string=:",
2071 "toggle=1 : foo",
2072 "toggle=100",
2073 "toggle==1",
2074 "flags=+mu-lame : num=42: toggle=0",
2075 "num=42 : string=blahblah",
2076 "rational=0 : rational=1/2 : rational=1/-1",
2077 "rational=-1/0",
2078 "size=1024x768",
2079 "size=pal",
2080 "size=bogus",
2081 "pix_fmt=yuv420p",
2082 "pix_fmt=2",
2083 "pix_fmt=bogus",
2084 "sample_fmt=s16",
2085 "sample_fmt=2",
2086 "sample_fmt=bogus",
2087 "video_rate=pal",
2088 "video_rate=25",
2089 "video_rate=30000/1001",
2090 "video_rate=30/1.001",
2091 "video_rate=bogus",
2092 "duration=bogus",
2093 "duration=123.45",
2094 "duration=1\\:23\\:45.67",
2095 "color=blue",
2096 "color=0x223300",
2097 "color=0x42FF07AA",
2098 "cl=stereo+downmix",
2099 "cl=foo",
2100 "bin=boguss",
2101 "bin=111",
2102 "bin=ffff",
2103 "num64=bogus",
2104 "num64=44",
2105 "num64=44.4",
2106 "num64=-1",
2107 "num64=101",
2108 "flt=bogus",
2109 "flt=2",
2110 "flt=2.2",
2111 "flt=-1",
2112 "flt=101",
2113 "dbl=bogus",
2114 "dbl=2",
2115 "dbl=2.2",
2116 "dbl=-1",
2117 "dbl=101",
2118 };
2119
2120 test_ctx.class = &test_class;
2122
2124
2126 int silence_log = !strcmp(options[i], "rational=-1/0"); // inf formating differs between platforms
2128 if (silence_log)
2131 printf("Error '%s'\n", options[i]);
2132 else
2133 printf("OK '%s'\n", options[i]);
2135 }
2137 }
2138
2139 printf("\nTesting av_opt_set_from_string()\n");
2140 {
2141 TestContext test_ctx = { 0 };
2142 static const char * const options[] = {
2143 "",
2144 "5",
2145 "5:hello",
2146 "5:hello:size=pal",
2147 "5:size=pal:hello",
2148 ":",
2149 "=",
2150 " 5 : hello : size = pal ",
2151 "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
2152 };
2153 static const char *
const shorthand[] = {
"num",
"string",
NULL };
2154
2155 test_ctx.class = &test_class;
2157
2159
2163 printf("Error '%s'\n", options[i]);
2164 else
2165 printf("OK '%s'\n", options[i]);
2166 }
2168 }
2169
2170 return 0;
2171 }
2172
2173 #endif