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
40
41 #include <float.h>
42
43 #if FF_API_FIND_OPT
44 //FIXME order them and do a bin search
46 {
48
50 if (!strcmp(o->
name, name) && (!unit || (o->
unit && !strcmp(o->
unit, unit))) && (o->
flags & mask) == flags)
51 return o;
52 }
53 return NULL;
54 }
55 #endif
56
57 #if FF_API_OLD_AVOPTIONS
59 {
61 }
62 #endif
63
65 {
67 if (!last &&
class &&
class->option &&
class->option[0].name)
69 if (last && last[1].
name)
70 return ++last;
71 return NULL;
72 }
73
75 {
88 return 0;
90 }
92 }
93
95 {
96 if (o->
max*den < num*intnum || o->
min*den > num*intnum) {
100 }
101
115 break;
116 default:
118 }
119 return 0;
120 }
121
126 0
127 };
128
130 "PI",
131 "E",
132 "QP2LAMBDA",
133 0
134 };
135
137 if (c >= '0' && c <= '9') return c - '0';
138 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
139 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
140 return -1;
141 }
142
144 {
145 int *lendst = (int *)(dst + 1);
147 int len = strlen(val);
148
150 *lendst = 0;
151
152 if (len & 1)
154 len /= 2;
155
157 while (*val) {
160 if (a < 0 || b < 0) {
163 }
164 *ptr++ = (a << 4) | b;
165 }
166 *dst = bin;
168
169 return 0;
170 }
171
173 {
176 return 0;
177 }
178
179 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
180 opt->type == AV_OPT_TYPE_CONST || \
181 opt->type == AV_OPT_TYPE_FLAGS || \
182 opt->type == AV_OPT_TYPE_INT) ? \
183 opt->default_val.i64 : opt->default_val.dbl)
184
186 {
187 int ret = 0, notfirst = 0;
188 for (;;) {
189 int i, den = 1;
191 int cmd = 0;
192 double d, num = 1;
193 int64_t intnum = 1;
194
195 i = 0;
196 if (*val == '+' || *val == '-') {
198 cmd = *(val++);
199 else if (!notfirst)
201 }
202
203 for (; i <
sizeof(
buf) - 1 && val[i] && val[i] !=
'+' && val[i] !=
'-'; i++)
204 buf[i] = val[i];
205 buf[i] = 0;
206
207 {
212 else if (!strcmp(buf,
"max" )) d = o->
max;
213 else if (!strcmp(buf,
"min" )) d = o->
min;
214 else if (!strcmp(buf, "none" )) d = 0;
215 else if (!strcmp(buf, "all" )) d = ~0;
216 else {
217 int res =
av_expr_parse_and_eval(&d, buf,
const_names,
const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
218 if (res < 0) {
221 }
222 }
223 }
226 if (cmd == '+') d = intnum | (int64_t)d;
227 else if (cmd == '-') d = intnum &~(int64_t)d;
228 } else {
230 if (cmd == '+') d = notfirst*num*intnum/den + d;
231 else if (cmd == '-') d = notfirst*num*intnum/den - d;
232 }
233
236 val += i;
237 if (!*val)
238 return 0;
239 notfirst = 1;
240 }
241
242 return 0;
243 }
244
245 #if FF_API_OLD_AVOPTIONS
247 {
249 if (o_out)
250 *o_out = o;
252 }
253 #endif
254
256 {
258 void *dst, *target_obj;
260 if (!o || !target_obj)
268
280 if (!val || !strcmp(val, "none")) {
281 *(int *)dst = *((int *)dst + 1) = 0;
282 return 0;
283 }
285 if (ret < 0)
286 av_log(obj,
AV_LOG_ERROR,
"Unable to parse option value \"%s\" as image size\n", val);
289 if (!val) {
291 } else {
293 }
294 if (ret < 0)
295 av_log(obj,
AV_LOG_ERROR,
"Unable to parse option value \"%s\" as video rate\n", val);
298 if (!val || !strcmp(val, "none")) {
300 } else {
303 char *tail;
304 ret = strtol(val, &tail, 0);
306 av_log(obj,
AV_LOG_ERROR,
"Unable to parse option value \"%s\" as pixel format\n", val);
308 }
309 }
310 }
312 return 0;
314 if (!val || !strcmp(val, "none")) {
316 } else {
319 char *tail;
320 ret = strtol(val, &tail, 0);
322 av_log(obj,
AV_LOG_ERROR,
"Unable to parse option value \"%s\" as sample format\n", val);
324 }
325 }
326 }
328 return 0;
330 if (!val) {
331 *(int64_t *)dst = 0;
332 return 0;
333 } else {
337 }
338 break;
340 if (!val) {
341 return 0;
342 } else {
344 if (ret < 0)
347 }
348 break;
350 if (!val || !strcmp(val, "none")) {
351 *(int64_t *)dst = 0;
352 } else {
353 #if FF_API_GET_CHANNEL_LAYOUT_COMPAT
355 #else
357 #endif
358 if (!cl) {
359 av_log(obj,
AV_LOG_ERROR,
"Unable to parse option value \"%s\" as channel layout\n", val);
361 }
362 *(int64_t *)dst = cl;
364 }
365 break;
366 }
367
370 }
371
372 #define OPT_EVAL_NUMBER(name, opttype, vartype)\
373 int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\
374 {\
375 if (!o || o->type != opttype)\
376 return AVERROR(EINVAL);\
377 return set_string_number(obj, obj, o, val, name ## _out);\
378 }
379
386
387 static
int set_number(
void *obj, const
char *
name,
double num,
int den, int64_t intnum,
388 int search_flags)
389 {
390 void *dst, *target_obj;
392
393 if (!o || !target_obj)
395
398 }
399
400 #if FF_API_OLD_AVOPTIONS
402 {
405 return NULL;
406 return o;
407 }
408
410 {
413 return NULL;
414 return o;
415 }
416
418 {
421 return NULL;
422 return o;
423 }
424 #endif
425
427 {
428 return set_number(obj, name, 1, 1, val, search_flags);
429 }
430
432 {
433 return set_number(obj, name, val, 1, 1, search_flags);
434 }
435
437 {
439 }
440
442 {
443 void *target_obj;
447 int *lendst;
448
449 if (!o || !target_obj)
451
454
456 if (len && !ptr)
458
460 lendst = (int *)(dst + 1);
461
463 *dst = ptr;
465 if (len)
466 memcpy(ptr, val, len);
467
468 return 0;
469 }
470
472 {
473 void *target_obj;
475
476 if (!o || !target_obj)
480 "The value set by option '%s' is not an image size.\n", o->
name);
482 }
483 if (w<0 || h<0) {
485 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->
name);
487 }
489 *(
int *)(((
uint8_t *)target_obj+
sizeof(int)) + o->
offset) = h;
490 return 0;
491 }
492
494 {
495 void *target_obj;
497
498 if (!o || !target_obj)
502 "The value set by option '%s' is not a video rate.\n", o->
name);
504 }
505 if (val.
num <= 0 || val.
den <= 0)
508 }
509
512 {
513 void *target_obj;
515 search_flags, &target_obj);
518
519 if (!o || !target_obj)
521 if (o->
type != type) {
523 "The value set by option '%s' is not a %s format", name, desc);
525 }
526
527 #if LIBAVUTIL_VERSION_MAJOR < 53
529 min = -1;
530 max = nb_fmts-1;
531 } else
532 #endif
533 {
536 }
537 if (fmt < min || fmt > max) {
539 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
540 fmt, name, desc, min, max);
542 }
544 return 0;
545 }
546
548 {
550 }
551
553 {
555 }
556
558 {
559 void *target_obj;
561
562 if (!o || !target_obj)
566 "The value set by option '%s' is not a channel layout.\n", o->
name);
568 }
569 *(
int *)(((int64_t *)target_obj) + o->
offset) = cl;
570 return 0;
571 }
572
573 #if FF_API_OLD_AVOPTIONS
574 /**
575 *
576 * @param buf a buffer which is used for returning non string values as strings, can be NULL
577 * @param buf_len allocated length in bytes of buf
578 */
580 {
582 void *dst;
585 if (!o)
586 return NULL;
588 return NULL;
589
591 if (o_out) *o_out= o;
592
604 if (len >= (buf_len + 1)/2) return NULL;
606 for (i = 0; i <
len; i++)
snprintf(buf + i*2, 3,
"%02X", bin[i]);
607 break;
608 default: return NULL;
609 }
611 }
612 #endif
613
615 {
616 void *dst, *target_obj;
620 int64_t i64;
621
624
626
627 buf[0] = 0;
640 else
642 return 0;
645 if ((uint64_t)len*2 + 1 > INT_MAX)
650 for (i = 0; i <
len; i++)
651 snprintf(*out_val + i*2, 3,
"%02X", bin[i]);
652 return 0;
654 ret =
snprintf(buf,
sizeof(buf),
"%dx%d", ((
int *)dst)[0], ((
int *)dst)[1]);
655 break;
658 break;
661 break;
663 i64 = *(int64_t *)dst;
664 ret =
snprintf(buf,
sizeof(buf),
"%"PRIi64
"d:%02d:%02d.%06d",
665 i64 / 3600000000, (int)((i64 / 60000000) % 60),
666 (int)((i64 / 1000000) % 60), (int)(i64 % 1000000));
667 break;
669 ret =
snprintf(buf,
sizeof(buf),
"0x%02x%02x%02x%02x", ((
int *)dst)[0], ((
int *)dst)[1], ((
int *)dst)[2], ((
int *)dst)[3]);
670 break;
672 i64 = *(int64_t *)dst;
673 ret =
snprintf(buf,
sizeof(buf),
"0x%"PRIx64, i64);
674 break;
675 default:
677 }
678
679 if (ret >= sizeof(buf))
682 return 0;
683 }
684
686 int search_flags)
687 {
688 void *dst, *target_obj;
690 if (!o || !target_obj)
691 goto error;
692
694
695 if (o_out) *o_out= o;
696
698
699 error:
700 *den=*intnum=0;
701 return -1;
702 }
703
704 #if FF_API_OLD_AVOPTIONS
706 {
707 int64_t intnum=1;
708 double num=1;
709 int den=1;
710
711 if (
get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
713 return num*intnum/den;
714 }
715
717 {
718 int64_t intnum=1;
719 double num=1;
720 int den=1;
721
722 if (
get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
724 if (num == 1.0 && (int)intnum == intnum)
726 else
727 return av_d2q(num*intnum/den, 1<<24);
728 }
729
731 {
732 int64_t intnum=1;
733 double num=1;
734 int den=1;
735
736 if (
get_number(obj, name, o_out, &num, &den, &intnum, 0) < 0)
737 return -1;
738 return num*intnum/den;
739 }
740 #endif
741
743 {
744 int64_t intnum = 1;
745 double num = 1;
747
748 if ((ret =
get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
750 *out_val = num*intnum/den;
751 return 0;
752 }
753
755 {
756 int64_t intnum = 1;
757 double num = 1;
759
760 if ((ret =
get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
762 *out_val = num*intnum/den;
763 return 0;
764 }
765
767 {
768 int64_t intnum = 1;
769 double num = 1;
771
772 if ((ret =
get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
774
775 if (num == 1.0 && (int)intnum == intnum)
777 else
778 *out_val =
av_d2q(num*intnum/den, 1<<24);
779 return 0;
780 }
781
783 {
784 void *dst, *target_obj;
786 if (!o || !target_obj)
790 "The value for option '%s' is not an image size.\n", name);
792 }
793
795 if (w_out) *w_out = *(int *)dst;
796 if (h_out) *h_out = *((int *)dst+1);
797 return 0;
798 }
799
801 {
802 int64_t intnum = 1;
803 double num = 1;
805
806 if ((ret =
get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
808
809 if (num == 1.0 && (int)intnum == intnum)
811 else
812 *out_val =
av_d2q(num*intnum/den, 1<<24);
813 return 0;
814 }
815
816 static int get_format(
void *obj,
const char *
name,
int search_flags,
int *out_fmt,
818 {
819 void *dst, *target_obj;
821 if (!o || !target_obj)
823 if (o->
type != type) {
825 "The value for option '%s' is not a %s format.\n", desc, name);
827 }
828
830 *out_fmt = *(int *)dst;
831 return 0;
832 }
833
835 {
837 }
838
840 {
842 }
843
845 {
846 void *dst, *target_obj;
848 if (!o || !target_obj)
852 "The value for option '%s' is not a channel layout.\n", name);
854 }
855
857 *cl = *(int64_t *)dst;
858 return 0;
859 }
860
862 {
865 field ? field->
unit : NULL, 0, 0);
867
870 return 0;
872 }
873
875 {
876 if (d == INT_MAX) {
877 av_log(av_log_obj, level,
"INT_MAX");
878 } else if (d == INT_MIN) {
879 av_log(av_log_obj, level,
"INT_MIN");
880 } else if (d == (double)INT64_MAX) {
881 av_log(av_log_obj, level,
"I64_MAX");
882 } else if (d == INT64_MIN) {
883 av_log(av_log_obj, level,
"I64_MIN");
884 } else if (d == FLT_MAX) {
885 av_log(av_log_obj, level,
"FLT_MAX");
886 } else if (d == FLT_MIN) {
887 av_log(av_log_obj, level,
"FLT_MIN");
888 } else {
889 av_log(av_log_obj, level,
"%g", d);
890 }
891 }
892
893 static void opt_list(
void *obj,
void *av_log_obj,
const char *unit,
894 int req_flags, int rej_flags)
895 {
898 int i;
899
901 if (!(opt->
flags & req_flags) || (opt->
flags & rej_flags))
902 continue;
903
904 /* Don't print CONST's on level one.
905 * Don't print anything but CONST's on level two.
906 * Only print items from the requested unit.
907 */
909 continue;
911 continue;
913 continue;
916 else
920
924 break;
927 break;
930 break;
933 break;
936 break;
939 break;
942 break;
945 break;
948 break;
951 break;
954 break;
957 break;
960 break;
963 break;
966 break;
968 default:
970 break;
971 }
978
981
995 }
996 break;
997 }
999 }
1000
1009 switch (opt->
type) {
1012 break;
1017 break;
1021 break;
1025 break;
1028 break;
1031 break;
1037 break;
1040 break;
1041 }
1043 }
1044
1047 opt_list(obj, av_log_obj, opt->
unit, req_flags, rej_flags);
1048 }
1049 }
1050 }
1051
1052 int av_opt_show2(
void *obj,
void *av_log_obj,
int req_flags,
int rej_flags)
1053 {
1054 if (!obj)
1055 return -1;
1056
1058
1059 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
1060
1061 return 0;
1062 }
1063
1065 {
1066 #if FF_API_OLD_AVOPTIONS
1068 }
1069
1071 {
1072 #endif
1076 #if FF_API_OLD_AVOPTIONS
1078 continue;
1079 #endif
1080 switch (opt->
type) {
1082 /* Nothing to be done here */
1083 break;
1090 break;
1096 }
1097 break;
1102 }
1103 break;
1109 break;
1111 #if LIBAVUTIL_VERSION_MAJOR < 53
1114 else
1115 #endif
1117 break;
1119 #if LIBAVUTIL_VERSION_MAJOR < 53
1122 else
1123 #endif
1125 break;
1127 /* Cannot set default for binary */
1128 break;
1129 default:
1131 }
1132 }
1133 }
1134
1135 /**
1136 * Store the value in the field in ctx that is named like key.
1137 * ctx must be an AVClass context, storing is done using AVOptions.
1138 *
1139 * @param buf the string to parse, buf will be updated to point at the
1140 * separator just after the parsed key/value pair
1141 * @param key_val_sep a 0-terminated list of characters used to
1142 * separate key from value
1143 * @param pairs_sep a 0-terminated list of characters used to separate
1144 * two pairs from each other
1145 * @return 0 if the key/value pair has been successfully parsed and
1146 * set, or a negative value corresponding to an AVERROR code in case
1147 * of error:
1148 * AVERROR(EINVAL) if the key/value pair cannot be parsed,
1149 * the error code issued by av_opt_set() if the key/value pair
1150 * cannot be set
1151 */
1153 const char *key_val_sep, const char *pairs_sep)
1154 {
1158
1159 if (!key)
1161
1162 if (*key && strspn(*buf, key_val_sep)) {
1163 (*buf)++;
1165 if (!val) {
1168 }
1169 } else {
1170 av_log(ctx,
AV_LOG_ERROR,
"Missing key or no key/value separator found after key '%s'\n", key);
1173 }
1174
1176
1180
1184 }
1185
1187 const char *key_val_sep, const char *pairs_sep)
1188 {
1190
1191 if (!opts)
1192 return 0;
1193
1194 while (*opts) {
1197 count++;
1198
1199 if (*opts)
1200 opts++;
1201 }
1202
1204 }
1205
1206 #define WHITESPACES " \n\t"
1207
1209 {
1210 return (unsigned)((c | 32) - 'a') < 26 ||
1211 (unsigned)(c - '0') < 10 ||
1212 c == '-' || c == '_' || c == '/' || c == '.';
1213 }
1214
1215 /**
1216 * Read a key from a string.
1217 *
1218 * The key consists of is_key_char characters and must be terminated by a
1219 * character from the delim string; spaces are ignored.
1220 *
1221 * @return 0 for success (even with ellipsis), <0 for failure
1222 */
1223 static int get_key(
const char **ropts,
const char *delim,
char **rkey)
1224 {
1225 const char *opts = *ropts;
1226 const char *key_start, *key_end;
1227
1230 opts++;
1231 key_end = opts;
1233 if (!*opts || !strchr(delim, *opts))
1235 opts++;
1236 if (!(*rkey =
av_malloc(key_end - key_start + 1)))
1238 memcpy(*rkey, key_start, key_end - key_start);
1239 (*rkey)[key_end - key_start] = 0;
1240 *ropts = opts;
1241 return 0;
1242 }
1243
1245 const char *key_val_sep, const char *pairs_sep,
1247 char **rkey, char **rval)
1248 {
1250 char *key = NULL, *
val;
1251 const char *opts = *ropts;
1252
1253 if ((ret =
get_key(&opts, key_val_sep, &key)) < 0 &&
1259 }
1260 *ropts = opts;
1261 *rkey = key;
1263 return 0;
1264 }
1265
1267 const char *const *shorthand,
1268 const char *key_val_sep, const char *pairs_sep)
1269 {
1271 const char *dummy_shorthand = NULL;
1273 const char *key;
1274
1275 if (!opts)
1276 return 0;
1277 if (!shorthand)
1278 shorthand = &dummy_shorthand;
1279
1280 while (*opts) {
1283 &parsed_key, &
value);
1284 if (ret < 0) {
1287 else
1291 }
1292 if (*opts)
1293 opts++;
1294 if (parsed_key) {
1295 key = parsed_key;
1296 while (*shorthand) /* discard all remaining shorthand */
1297 shorthand++;
1298 } else {
1299 key = *(shorthand++);
1300 }
1301
1309 }
1310
1313 count++;
1314 }
1316 }
1317
1319 {
1324 }
1325
1327 {
1331
1336 else if (ret < 0) {
1338 break;
1339 }
1340 ret = 0;
1341 }
1343 *options = tmp;
1345 }
1346
1348 int opt_flags, int search_flags)
1349 {
1350 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
1351 }
1352
1354 int opt_flags, int search_flags, void **target_obj)
1355 {
1358
1359 if(!obj)
1360 return NULL;
1361
1363
1364 if (!c)
1365 return NULL;
1366
1371 if (o =
av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
1372 return o;
1373 } else {
1376 if (o =
av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
1377 return o;
1378 }
1379 }
1380
1382 if (!strcmp(o->
name, name) && (o->
flags & opt_flags) == opt_flags &&
1385 if (target_obj) {
1387 *target_obj = obj;
1388 else
1389 *target_obj = NULL;
1390 }
1391 return o;
1392 }
1393 }
1394 return NULL;
1395 }
1396
1398 {
1402 return NULL;
1403 }
1404
1406 {
1409 return NULL;
1410 }
1411
1413 {
1415 if(!opt)
1416 return NULL;
1418 }
1419
1421 {
1424
1425 if (c->
version > (52 << 16 | 11 << 8))
1427
1430
1431 return callback(ranges_arg, obj, key, flags);
1432 }
1433
1435 {
1441
1442 *ranges_arg = NULL;
1443
1444 if (!ranges || !range || !range_array || !field) {
1446 goto fail;
1447 }
1448
1449 ranges->
range = range_array;
1450 ranges->
range[0] = range;
1455
1456 switch (field->
type) {
1466 break;
1472 break;
1476 break;
1482 break;
1488 break;
1489 default:
1491 goto fail;
1492 }
1493
1494 *ranges_arg = ranges;
1495 return 0;
1496 fail:
1501 }
1502
1504 {
1505 int i;
1507
1508 for (i = 0; i < ranges->
nb_ranges; i++) {
1512 }
1515 }
1516
1517 #ifdef TEST
1518
1519 typedef struct TestContext
1520 {
1522 int num;
1523 int toggle;
1524 char *string;
1528 int w, h;
1533 int64_t channel_layout;
1534 } TestContext;
1535
1536 #define OFFSET(x) offsetof(TestContext, x)
1537
1538 #define TEST_FLAG_COOL 01
1539 #define TEST_FLAG_LAME 02
1540 #define TEST_FLAG_MU 04
1541
1542 static const AVOption test_options[]= {
1548 {
"cool",
"set cool flag ", 0,
AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0,
"flags" },
1549 {
"lame",
"set lame flag ", 0,
AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0,
"flags" },
1550 {
"mu",
"set mu flag ", 0,
AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0,
"flags" },
1558 {NULL},
1559 };
1560
1561 static const char *test_get_name(void *ctx)
1562 {
1563 return "test";
1564 }
1565
1566 static const AVClass test_class = {
1567 "TestContext",
1568 test_get_name,
1569 test_options
1570 };
1571
1573 {
1574 int i;
1575
1576 printf("\nTesting av_set_options_string()\n");
1577 {
1578 TestContext test_ctx = { 0 };
1579 static const char *
const options[] = {
1580 "",
1581 ":",
1582 "=",
1583 "foo=:",
1584 ":=foo",
1585 "=foo",
1586 "foo=",
1587 "foo",
1588 "foo=val",
1589 "foo==val",
1590 "toggle=:",
1591 "string=:",
1592 "toggle=1 : foo",
1593 "toggle=100",
1594 "toggle==1",
1595 "flags=+mu-lame : num=42: toggle=0",
1596 "num=42 : string=blahblah",
1597 "rational=0 : rational=1/2 : rational=1/-1",
1598 "rational=-1/0",
1599 "size=1024x768",
1600 "size=pal",
1601 "size=bogus",
1602 "pix_fmt=yuv420p",
1603 "pix_fmt=2",
1604 "pix_fmt=bogus",
1605 "sample_fmt=s16",
1606 "sample_fmt=2",
1607 "sample_fmt=bogus",
1608 "video_rate=pal",
1609 "video_rate=25",
1610 "video_rate=30000/1001",
1611 "video_rate=30/1.001",
1612 "video_rate=bogus",
1613 "duration=bogus",
1614 "duration=123.45",
1615 "duration=1\\:23\\:45.67",
1616 "color=blue",
1617 "color=0x223300",
1618 "color=0x42FF07AA",
1619 "cl=stereo+downmix",
1620 "cl=foo",
1621 };
1622
1623 test_ctx.class = &test_class;
1625
1627
1632 printf("\n");
1633 }
1635 }
1636
1637 printf("\nTesting av_opt_set_from_string()\n");
1638 {
1639 TestContext test_ctx = { 0 };
1640 static const char * const options[] = {
1641 "",
1642 "5",
1643 "5:hello",
1644 "5:hello:size=pal",
1645 "5:size=pal:hello",
1646 ":",
1647 "=",
1648 " 5 : hello : size = pal ",
1649 "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
1650 };
1651 static const char * const shorthand[] = { "num", "string", NULL };
1652
1653 test_ctx.class = &test_class;
1655
1657
1662 printf("\n");
1663 }
1665 }
1666
1667 return 0;
1668 }
1669
1670 #endif