FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/opt.c
Date: 2026-04-24 15:23:18
Exec Total Coverage
Lines: 1247 1683 74.1%
Functions: 81 102 79.4%
Branches: 816 1310 62.3%

Line Branch Exec Source
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
28 #include "avutil.h"
29 #include "avassert.h"
30 #include "avstring.h"
31 #include "channel_layout.h"
32 #include "dict.h"
33 #include "eval.h"
34 #include "log.h"
35 #include "mem.h"
36 #include "parseutils.h"
37 #include "pixdesc.h"
38 #include "mathematics.h"
39 #include "opt.h"
40 #include "samplefmt.h"
41 #include "bprint.h"
42 #include "version.h"
43
44 #include <float.h>
45
46 #define TYPE_BASE(type) ((type) & ~AV_OPT_TYPE_FLAG_ARRAY)
47
48 630991249 const AVOption *av_opt_next(const void *obj, const AVOption *last)
49 {
50 const AVClass *class;
51
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 630991249 times.
630991249 if (!obj)
52 return NULL;
53 630991249 class = *(const AVClass**)obj;
54
8/8
✓ Branch 0 taken 50496953 times.
✓ Branch 1 taken 580494296 times.
✓ Branch 2 taken 50496951 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 50136676 times.
✓ Branch 5 taken 360275 times.
✓ Branch 6 taken 50016586 times.
✓ Branch 7 taken 120090 times.
630991249 if (!last && class && class->option && class->option[0].name)
55 50016586 return class->option;
56
4/4
✓ Branch 0 taken 580494296 times.
✓ Branch 1 taken 480367 times.
✓ Branch 2 taken 531069846 times.
✓ Branch 3 taken 49424450 times.
580974663 if (last && last[1].name)
57 531069846 return ++last;
58 49904817 return NULL;
59 }
60
61 static const struct {
62 size_t size;
63 const char *name;
64 } opt_type_desc[] = {
65 [AV_OPT_TYPE_FLAGS] = { sizeof(unsigned), "<flags>" },
66 [AV_OPT_TYPE_INT] = { sizeof(int), "<int>" },
67 [AV_OPT_TYPE_INT64] = { sizeof(int64_t), "<int64>" },
68 [AV_OPT_TYPE_UINT] = { sizeof(unsigned), "<unsigned>" },
69 [AV_OPT_TYPE_UINT64] = { sizeof(uint64_t), "<uint64>" },
70 [AV_OPT_TYPE_DOUBLE] = { sizeof(double), "<double>" },
71 [AV_OPT_TYPE_FLOAT] = { sizeof(float), "<float>" },
72 [AV_OPT_TYPE_STRING] = { sizeof(char *), "<string>" },
73 [AV_OPT_TYPE_RATIONAL] = { sizeof(AVRational), "<rational>" },
74 [AV_OPT_TYPE_BINARY] = { sizeof(uint8_t *), "<binary>" },
75 [AV_OPT_TYPE_DICT] = { sizeof(AVDictionary *), "<dictionary>" },
76 [AV_OPT_TYPE_IMAGE_SIZE] = { sizeof(int[2]), "<image_size>" },
77 [AV_OPT_TYPE_VIDEO_RATE] = { sizeof(AVRational), "<video_rate>" },
78 [AV_OPT_TYPE_PIXEL_FMT] = { sizeof(int), "<pix_fmt>" },
79 [AV_OPT_TYPE_SAMPLE_FMT] = { sizeof(int), "<sample_fmt>" },
80 [AV_OPT_TYPE_DURATION] = { sizeof(int64_t), "<duration>" },
81 [AV_OPT_TYPE_COLOR] = { sizeof(uint8_t[4]), "<color>" },
82 [AV_OPT_TYPE_CHLAYOUT] = { sizeof(AVChannelLayout),"<channel_layout>" },
83 [AV_OPT_TYPE_BOOL] = { sizeof(int), "<boolean>" },
84 };
85
86 // option is plain old data
87 1907698 static int opt_is_pod(enum AVOptionType type)
88 {
89
1/2
✓ Branch 0 taken 1907698 times.
✗ Branch 1 not taken.
1907698 switch (type) {
90 1907698 case AV_OPT_TYPE_FLAGS:
91 case AV_OPT_TYPE_INT:
92 case AV_OPT_TYPE_INT64:
93 case AV_OPT_TYPE_DOUBLE:
94 case AV_OPT_TYPE_FLOAT:
95 case AV_OPT_TYPE_RATIONAL:
96 case AV_OPT_TYPE_UINT64:
97 case AV_OPT_TYPE_IMAGE_SIZE:
98 case AV_OPT_TYPE_PIXEL_FMT:
99 case AV_OPT_TYPE_SAMPLE_FMT:
100 case AV_OPT_TYPE_VIDEO_RATE:
101 case AV_OPT_TYPE_DURATION:
102 case AV_OPT_TYPE_COLOR:
103 case AV_OPT_TYPE_BOOL:
104 case AV_OPT_TYPE_UINT:
105 1907698 return 1;
106 }
107 return 0;
108 }
109
110 112924 static uint8_t opt_array_sep(const AVOption *o)
111 {
112 112924 const AVOptionArrayDef *d = o->default_val.arr;
113 av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY);
114
4/4
✓ Branch 0 taken 14402 times.
✓ Branch 1 taken 98522 times.
✓ Branch 2 taken 14377 times.
✓ Branch 3 taken 25 times.
112924 return (d && d->sep) ? d->sep : ',';
115 }
116
117 6702 static void *opt_array_pelem(const AVOption *o, void *array, unsigned idx)
118 {
119 av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY);
120 6702 return (uint8_t *)array + idx * opt_type_desc[TYPE_BASE(o->type)].size;
121 }
122
123 170664 static unsigned *opt_array_pcount(const void *parray)
124 {
125 170664 return (unsigned *)((const void * const *)parray + 1);
126 }
127
128 27796076 static void opt_free_elem(enum AVOptionType type, void *ptr)
129 {
130
4/4
✓ Branch 0 taken 1029852 times.
✓ Branch 1 taken 822 times.
✓ Branch 2 taken 67698 times.
✓ Branch 3 taken 26697704 times.
27796076 switch (TYPE_BASE(type)) {
131 1029852 case AV_OPT_TYPE_STRING:
132 case AV_OPT_TYPE_BINARY:
133 1029852 av_freep(ptr);
134 1029852 break;
135
136 822 case AV_OPT_TYPE_DICT:
137 822 av_dict_free((AVDictionary **)ptr);
138 822 break;
139
140 67698 case AV_OPT_TYPE_CHLAYOUT:
141 67698 av_channel_layout_uninit((AVChannelLayout *)ptr);
142 67698 break;
143
144 26697704 default:
145 26697704 break;
146 }
147 27796076 }
148
149 128012 static void opt_free_array(const AVOption *o, void *parray, unsigned *count)
150 {
151
2/2
✓ Branch 0 taken 3385 times.
✓ Branch 1 taken 128012 times.
131397 for (unsigned i = 0; i < *count; i++)
152 3385 opt_free_elem(o->type, opt_array_pelem(o, *(void **)parray, i));
153
154 128012 av_freep(parray);
155 128012 *count = 0;
156 128012 }
157
158 /**
159 * Perform common setup for option-setting functions.
160 *
161 * @param require_type when non-0, require the option to be of this type
162 * @param ptgt target object is written here
163 * @param po the option is written here
164 * @param pdst pointer to option value is written here
165 */
166 281455 static int opt_set_init(void *obj, const char *name, int search_flags,
167 int require_type,
168 void **ptgt, const AVOption **po, void **pdst)
169 {
170 const AVOption *o;
171 void *tgt;
172
173 281455 o = av_opt_find2(obj, name, NULL, 0, search_flags, &tgt);
174
3/4
✓ Branch 0 taken 216381 times.
✓ Branch 1 taken 65074 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 216381 times.
281455 if (!o || !tgt)
175 65074 return AVERROR_OPTION_NOT_FOUND;
176
177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216381 times.
216381 if (o->flags & AV_OPT_FLAG_READONLY)
178 return AVERROR(EINVAL);
179
180
3/4
✓ Branch 0 taken 3354 times.
✓ Branch 1 taken 213027 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3354 times.
216381 if (require_type && (o->type != require_type)) {
181 av_log(obj, AV_LOG_ERROR,
182 "Tried to set option '%s' of type %s from value of type %s, "
183 "this is not supported\n", o->name, opt_type_desc[o->type].name,
184 opt_type_desc[require_type].name);
185 return AVERROR(EINVAL);
186 }
187
188
2/2
✓ Branch 0 taken 189866 times.
✓ Branch 1 taken 26515 times.
216381 if (!(o->flags & AV_OPT_FLAG_RUNTIME_PARAM)) {
189 189866 unsigned *state_flags = NULL;
190 const AVClass *class;
191
192 // try state flags first from the target (child), then from its parent
193 189866 class = *(const AVClass**)tgt;
194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 189866 times.
189866 if (class->state_flags_offset)
195 state_flags = (unsigned*)((uint8_t*)tgt + class->state_flags_offset);
196
197
3/4
✓ Branch 0 taken 189866 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50179 times.
✓ Branch 3 taken 139687 times.
189866 if (!state_flags && obj != tgt) {
198 50179 class = *(const AVClass**)obj;
199
2/2
✓ Branch 0 taken 49333 times.
✓ Branch 1 taken 846 times.
50179 if (class->state_flags_offset)
200 49333 state_flags = (unsigned*)((uint8_t*)obj + class->state_flags_offset);
201 }
202
203
3/4
✓ Branch 0 taken 49333 times.
✓ Branch 1 taken 140533 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49333 times.
189866 if (state_flags && (*state_flags & AV_CLASS_STATE_INITIALIZED)) {
204 av_log(obj, AV_LOG_ERROR, "Option '%s' is not a runtime option and "
205 "so cannot be set after the object has been initialized\n",
206 o->name);
207 return AVERROR(EINVAL);
208 }
209 }
210
211
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 216379 times.
216381 if (o->flags & AV_OPT_FLAG_DEPRECATED)
212 2 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
213
214
2/2
✓ Branch 0 taken 213027 times.
✓ Branch 1 taken 3354 times.
216381 if (po)
215 213027 *po = o;
216
2/2
✓ Branch 0 taken 199954 times.
✓ Branch 1 taken 16427 times.
216381 if (ptgt)
217 199954 *ptgt = tgt;
218
1/2
✓ Branch 0 taken 216381 times.
✗ Branch 1 not taken.
216381 if (pdst)
219 216381 *pdst = ((uint8_t *)tgt) + o->offset;
220
221 216381 return 0;
222 }
223
224 static AVRational double_to_rational(double d)
225 {
226 AVRational r = av_d2q(d, 1 << 24);
227 if ((!r.num || !r.den) && d)
228 r = av_d2q(d, INT_MAX);
229 return r;
230 }
231
232 24823 static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
233 {
234
6/11
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 24626 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
24823 switch (TYPE_BASE(o->type)) {
235 13 case AV_OPT_TYPE_FLAGS:
236 13 *intnum = *(unsigned int*)dst;
237 13 return 0;
238 3 case AV_OPT_TYPE_PIXEL_FMT:
239 3 *intnum = *(enum AVPixelFormat *)dst;
240 3 return 0;
241 138 case AV_OPT_TYPE_SAMPLE_FMT:
242 138 *intnum = *(enum AVSampleFormat *)dst;
243 138 return 0;
244 24626 case AV_OPT_TYPE_BOOL:
245 case AV_OPT_TYPE_INT:
246 24626 *intnum = *(int *)dst;
247 24626 return 0;
248 32 case AV_OPT_TYPE_UINT:
249 32 *intnum = *(unsigned int *)dst;
250 32 return 0;
251 11 case AV_OPT_TYPE_DURATION:
252 case AV_OPT_TYPE_INT64:
253 case AV_OPT_TYPE_UINT64:
254 11 *intnum = *(int64_t *)dst;
255 11 return 0;
256 case AV_OPT_TYPE_FLOAT:
257 *num = *(float *)dst;
258 return 0;
259 case AV_OPT_TYPE_DOUBLE:
260 *num = *(double *)dst;
261 return 0;
262 case AV_OPT_TYPE_RATIONAL:
263 *intnum = ((AVRational *)dst)->num;
264 *den = ((AVRational *)dst)->den;
265 return 0;
266 case AV_OPT_TYPE_CONST:
267 *intnum = o->default_val.i64;
268 return 0;
269 }
270 return AVERROR(EINVAL);
271 }
272
273 9670248 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
274 {
275 9670248 const enum AVOptionType type = TYPE_BASE(o->type);
276
277
4/4
✓ Branch 0 taken 8714930 times.
✓ Branch 1 taken 955318 times.
✓ Branch 2 taken 8714929 times.
✓ Branch 3 taken 1 times.
9670248 if (type != AV_OPT_TYPE_FLAGS &&
278
4/4
✓ Branch 0 taken 8714921 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 8714914 times.
8714929 (!den || o->max * den < num * intnum || o->min * den > num * intnum)) {
279
4/6
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
16 num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN);
280 16 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
281 16 num, o->name, o->min, o->max);
282 16 return AVERROR(ERANGE);
283 }
284
2/2
✓ Branch 0 taken 955318 times.
✓ Branch 1 taken 8714914 times.
9670232 if (type == AV_OPT_TYPE_FLAGS) {
285 955318 double d = num*intnum/den;
286
3/6
✓ Branch 0 taken 955318 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 955318 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 955318 times.
955318 if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
287 av_log(obj, AV_LOG_ERROR,
288 "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
289 num*intnum/den, o->name);
290 return AVERROR(ERANGE);
291 }
292 }
293
294
7/9
✓ Branch 0 taken 186184 times.
✓ Branch 1 taken 51981 times.
✓ Branch 2 taken 7726715 times.
✓ Branch 3 taken 498595 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 816456 times.
✓ Branch 6 taken 186530 times.
✓ Branch 7 taken 203771 times.
✗ Branch 8 not taken.
9670232 switch (type) {
295 186184 case AV_OPT_TYPE_PIXEL_FMT:
296 186184 *(enum AVPixelFormat *)dst = llrint(num / den) * intnum;
297 186184 break;
298 51981 case AV_OPT_TYPE_SAMPLE_FMT:
299 51981 *(enum AVSampleFormat *)dst = llrint(num / den) * intnum;
300 51981 break;
301 7726715 case AV_OPT_TYPE_BOOL:
302 case AV_OPT_TYPE_FLAGS:
303 case AV_OPT_TYPE_INT:
304 case AV_OPT_TYPE_UINT:
305 7726715 *(int *)dst = llrint(num / den) * intnum;
306 7726715 break;
307 498595 case AV_OPT_TYPE_DURATION:
308 case AV_OPT_TYPE_INT64:{
309 498595 double d = num / den;
310
3/4
✓ Branch 0 taken 1185 times.
✓ Branch 1 taken 497410 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1185 times.
498595 if (intnum == 1 && d == (double)INT64_MAX) {
311 *(int64_t *)dst = INT64_MAX;
312 } else
313 498595 *(int64_t *)dst = llrint(d) * intnum;
314 498595 break;}
315 case AV_OPT_TYPE_UINT64:{
316 double d = num / den;
317 // We must special case uint64_t here as llrint() does not support values
318 // outside the int64_t range and there is no portable function which does
319 // "INT64_MAX + 1ULL" is used as it is representable exactly as IEEE double
320 // while INT64_MAX is not
321 if (intnum == 1 && d == (double)UINT64_MAX) {
322 *(uint64_t *)dst = UINT64_MAX;
323 } else if (d > INT64_MAX + 1ULL) {
324 *(uint64_t *)dst = (llrint(d - (INT64_MAX + 1ULL)) + (INT64_MAX + 1ULL))*intnum;
325 } else {
326 *(uint64_t *)dst = llrint(d) * intnum;
327 }
328 break;}
329 816456 case AV_OPT_TYPE_FLOAT:
330 816456 *(float *)dst = num * intnum / den;
331 816456 break;
332 186530 case AV_OPT_TYPE_DOUBLE:
333 186530 *(double *)dst = num * intnum / den;
334 186530 break;
335 203771 case AV_OPT_TYPE_RATIONAL:
336 case AV_OPT_TYPE_VIDEO_RATE:
337
1/2
✓ Branch 0 taken 203771 times.
✗ Branch 1 not taken.
203771 if ((int) num == num)
338 203771 *(AVRational *)dst = (AVRational) { num *intnum, den };
339 else
340 *(AVRational *)dst = double_to_rational(num * intnum / den);
341 203771 break;
342 default:
343 return AVERROR(EINVAL);
344 }
345 9670232 return 0;
346 }
347
348 17038 static int hexchar2int(char c) {
349
3/4
✓ Branch 0 taken 17038 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12289 times.
✓ Branch 3 taken 4749 times.
17038 if (c >= '0' && c <= '9')
350 12289 return c - '0';
351
4/4
✓ Branch 0 taken 4747 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4746 times.
✓ Branch 3 taken 1 times.
4749 if (c >= 'a' && c <= 'f')
352 4746 return c - 'a' + 10;
353
3/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
3 if (c >= 'A' && c <= 'F')
354 2 return c - 'A' + 10;
355 1 return -1;
356 }
357
358 43288 static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
359 {
360 43288 int *lendst = (int *)(dst + 1);
361 uint8_t *bin, *ptr;
362 int len;
363
364 43288 av_freep(dst);
365 43288 *lendst = 0;
366
367
4/4
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 42734 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 543 times.
43288 if (!val || !(len = strlen(val)))
368 42745 return 0;
369
370
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 542 times.
543 if (len & 1)
371 1 return AVERROR(EINVAL);
372 542 len /= 2;
373
374 542 ptr = bin = av_malloc(len);
375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 542 times.
542 if (!ptr)
376 return AVERROR(ENOMEM);
377
2/2
✓ Branch 0 taken 8519 times.
✓ Branch 1 taken 541 times.
9060 while (*val) {
378 8519 int a = hexchar2int(*val++);
379 8519 int b = hexchar2int(*val++);
380
3/4
✓ Branch 0 taken 8519 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 8518 times.
8519 if (a < 0 || b < 0) {
381 1 av_free(bin);
382 1 return AVERROR(EINVAL);
383 }
384 8518 *ptr++ = (a << 4) | b;
385 }
386 541 *dst = bin;
387 541 *lendst = len;
388
389 541 return 0;
390 }
391
392 557853 static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
393 {
394 557853 av_freep(dst);
395
2/2
✓ Branch 0 taken 457851 times.
✓ Branch 1 taken 100002 times.
557853 if (!val)
396 457851 return 0;
397 100002 *dst = av_strdup(val);
398
1/2
✓ Branch 0 taken 100002 times.
✗ Branch 1 not taken.
100002 return *dst ? 0 : AVERROR(ENOMEM);
399 }
400
401 #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
402 opt->type == AV_OPT_TYPE_UINT64 || \
403 opt->type == AV_OPT_TYPE_CONST || \
404 opt->type == AV_OPT_TYPE_FLAGS || \
405 opt->type == AV_OPT_TYPE_UINT || \
406 opt->type == AV_OPT_TYPE_INT) \
407 ? opt->default_val.i64 \
408 : opt->default_val.dbl)
409
410 129697 static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
411 {
412 129697 const enum AVOptionType type = TYPE_BASE(o->type);
413 129697 int ret = 0;
414
415
3/4
✓ Branch 0 taken 128307 times.
✓ Branch 1 taken 1390 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 128307 times.
129697 if (type == AV_OPT_TYPE_RATIONAL || type == AV_OPT_TYPE_VIDEO_RATE) {
416 int num, den;
417 char c;
418
2/2
✓ Branch 0 taken 1370 times.
✓ Branch 1 taken 20 times.
1390 if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
419
2/2
✓ Branch 1 taken 1368 times.
✓ Branch 2 taken 2 times.
1370 if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0)
420 1368 return ret;
421 2 ret = 0;
422 }
423 }
424
425 47308 for (;;) {
426 175637 int i = 0;
427 char buf[256];
428 175637 int cmd = 0;
429 double d;
430 175637 int64_t intnum = 1;
431
432
2/2
✓ Branch 0 taken 109727 times.
✓ Branch 1 taken 65910 times.
175637 if (type == AV_OPT_TYPE_FLAGS) {
433
4/4
✓ Branch 0 taken 23350 times.
✓ Branch 1 taken 86377 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 23326 times.
109727 if (*val == '+' || *val == '-')
434 86401 cmd = *(val++);
435
7/8
✓ Branch 0 taken 920513 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 858094 times.
✓ Branch 3 taken 62419 times.
✓ Branch 4 taken 810787 times.
✓ Branch 5 taken 47307 times.
✓ Branch 6 taken 810786 times.
✓ Branch 7 taken 1 times.
920513 for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
436 810786 buf[i] = val[i];
437 109727 buf[i] = 0;
438 }
439
440 {
441 int res;
442 175637 int ci = 0;
443 double const_values[64];
444 const char * const_names[64];
445 175637 int search_flags = (o->flags & AV_OPT_FLAG_CHILD_CONSTS) ? AV_OPT_SEARCH_CHILDREN : 0;
446
2/2
✓ Branch 0 taken 109727 times.
✓ Branch 1 taken 65910 times.
175637 const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, search_flags);
447
3/4
✓ Branch 0 taken 130091 times.
✓ Branch 1 taken 45546 times.
✓ Branch 2 taken 130091 times.
✗ Branch 3 not taken.
175637 if (o_named && o_named->type == AV_OPT_TYPE_CONST) {
448
3/12
✓ Branch 0 taken 130091 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 130091 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 130091 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
130091 d = DEFAULT_NUMVAL(o_named);
449
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 130091 times.
130091 if (o_named->flags & AV_OPT_FLAG_DEPRECATED)
450 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n",
451 o_named->name, o_named->help);
452 } else {
453
2/2
✓ Branch 0 taken 30868 times.
✓ Branch 1 taken 14678 times.
45546 if (o->unit) {
454
2/2
✓ Branch 1 taken 8111942 times.
✓ Branch 2 taken 30868 times.
8142810 for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) {
455
2/2
✓ Branch 0 taken 5713860 times.
✓ Branch 1 taken 2398082 times.
8111942 if (o_named->type == AV_OPT_TYPE_CONST &&
456
1/2
✓ Branch 0 taken 5713860 times.
✗ Branch 1 not taken.
5713860 o_named->unit &&
457
2/2
✓ Branch 0 taken 329573 times.
✓ Branch 1 taken 5384287 times.
5713860 !strcmp(o_named->unit, o->unit)) {
458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 329573 times.
329573 if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) {
459 av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit);
460 8 return AVERROR_PATCHWELCOME;
461 }
462 329573 const_names [ci ] = o_named->name;
463
3/12
✓ Branch 0 taken 329573 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 329573 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 329573 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
329573 const_values[ci++] = DEFAULT_NUMVAL(o_named);
464 }
465 }
466 }
467 45546 const_names [ci ] = "default";
468
10/12
✓ Branch 0 taken 44358 times.
✓ Branch 1 taken 1188 times.
✓ Branch 2 taken 44358 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 44358 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 35836 times.
✓ Branch 7 taken 8522 times.
✓ Branch 8 taken 35733 times.
✓ Branch 9 taken 103 times.
✓ Branch 10 taken 34795 times.
✓ Branch 11 taken 938 times.
45546 const_values[ci++] = DEFAULT_NUMVAL(o);
469 45546 const_names [ci ] = "max";
470 45546 const_values[ci++] = o->max;
471 45546 const_names [ci ] = "min";
472 45546 const_values[ci++] = o->min;
473 45546 const_names [ci ] = "none";
474 45546 const_values[ci++] = 0;
475 45546 const_names [ci ] = "all";
476 45546 const_values[ci++] = ~0;
477 45546 const_names [ci] = NULL;
478 45546 const_values[ci] = 0;
479
480
2/2
✓ Branch 0 taken 8522 times.
✓ Branch 1 taken 37024 times.
45546 res = av_expr_parse_and_eval(&d, i ? buf : val, const_names,
481 const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
482
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 45538 times.
45546 if (res < 0) {
483 8 av_log(obj, AV_LOG_ERROR, "Unable to parse \"%s\" option value \"%s\"\n", o->name, val);
484 8 return res;
485 }
486 }
487 }
488
2/2
✓ Branch 0 taken 109727 times.
✓ Branch 1 taken 65902 times.
175629 if (type == AV_OPT_TYPE_FLAGS) {
489 109727 intnum = *(unsigned int*)dst;
490
2/2
✓ Branch 0 taken 86377 times.
✓ Branch 1 taken 23350 times.
109727 if (cmd == '+')
491 86377 d = intnum | (int64_t)d;
492
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 23326 times.
23350 else if (cmd == '-')
493 24 d = intnum &~(int64_t)d;
494 }
495
496
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 175615 times.
175629 if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
497 14 return ret;
498 175615 val += i;
499
4/4
✓ Branch 0 taken 109727 times.
✓ Branch 1 taken 65888 times.
✓ Branch 2 taken 62419 times.
✓ Branch 3 taken 47308 times.
175615 if (!i || !*val)
500 128307 return 0;
501 }
502 }
503
504 44715 static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst)
505 {
506 int ret;
507
508
3/4
✓ Branch 0 taken 7707 times.
✓ Branch 1 taken 37008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7707 times.
44715 if (!val || !strcmp(val, "none")) {
509 37008 dst[0] =
510 37008 dst[1] = 0;
511 37008 return 0;
512 }
513 7707 ret = av_parse_video_size(dst, dst + 1, val);
514
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7706 times.
7707 if (ret < 0)
515 1 av_log(obj, AV_LOG_ERROR, "Unable to parse \"%s\" option value \"%s\" as image size\n", o->name, val);
516 7707 return ret;
517 }
518
519 9768 static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst)
520 {
521 9768 int ret = av_parse_video_rate(dst, val);
522
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9767 times.
9768 if (ret < 0)
523 1 av_log(obj, AV_LOG_ERROR, "Unable to parse \"%s\" option value \"%s\" as video rate\n", o->name, val);
524 9768 return ret;
525 }
526
527 362 static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst)
528 {
529 int ret;
530
531
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 362 times.
362 if (!val) {
532 return 0;
533 } else {
534 362 ret = av_parse_color(dst, val, -1, obj);
535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 362 times.
362 if (ret < 0)
536 av_log(obj, AV_LOG_ERROR, "Unable to parse \"%s\" option value \"%s\" as color\n", o->name, val);
537 362 return ret;
538 }
539 return 0;
540 }
541
542 38 static const char *get_bool_name(int val)
543 {
544
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 33 times.
38 if (val < 0)
545 5 return "auto";
546
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 11 times.
33 return val ? "true" : "false";
547 }
548
549 9864 static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst)
550 {
551 int n;
552
553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9864 times.
9864 if (!val)
554 return 0;
555
556
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9861 times.
9864 if (!strcmp(val, "auto")) {
557 3 n = -1;
558
2/2
✓ Branch 1 taken 1269 times.
✓ Branch 2 taken 8592 times.
9861 } else if (av_match_name(val, "true,y,yes,enable,enabled,on")) {
559 1269 n = 1;
560
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 8578 times.
8592 } else if (av_match_name(val, "false,n,no,disable,disabled,off")) {
561 14 n = 0;
562 } else {
563 8578 char *end = NULL;
564 8578 n = strtol(val, &end, 10);
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8578 times.
8578 if (val + strlen(val) != end)
566 goto fail;
567 }
568
569
2/4
✓ Branch 0 taken 9864 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9864 times.
9864 if (n < o->min || n > o->max)
570 goto fail;
571
572 9864 *dst = n;
573 9864 return 0;
574
575 fail:
576 av_log(obj, AV_LOG_ERROR, "Unable to parse \"%s\" option value \"%s\" as boolean\n", o->name, val);
577 return AVERROR(EINVAL);
578 }
579
580 5284 static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst,
581 int fmt_nb, int ((*get_fmt)(const char *)), const char *desc)
582 {
583 int fmt, min, max;
584
585
2/4
✓ Branch 0 taken 5284 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5284 times.
5284 if (!val || !strcmp(val, "none")) {
586 fmt = -1;
587 } else {
588 5284 fmt = get_fmt(val);
589
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5280 times.
5284 if (fmt == -1) {
590 char *tail;
591 4 fmt = strtol(val, &tail, 0);
592
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
4 if (*tail || (unsigned)fmt >= fmt_nb) {
593 2 av_log(obj, AV_LOG_ERROR,
594 2 "Unable to parse \"%s\" option value \"%s\" as %s\n", o->name, val, desc);
595 2 return AVERROR(EINVAL);
596 }
597 }
598 }
599
600
2/2
✓ Branch 0 taken 2687 times.
✓ Branch 1 taken 2595 times.
5282 min = FFMAX(o->min, -1);
601
2/2
✓ Branch 0 taken 3166 times.
✓ Branch 1 taken 2116 times.
5282 max = FFMIN(o->max, fmt_nb-1);
602
603 // hack for compatibility with old ffmpeg
604
4/4
✓ Branch 0 taken 2687 times.
✓ Branch 1 taken 2595 times.
✓ Branch 2 taken 2116 times.
✓ Branch 3 taken 571 times.
5282 if(min == 0 && max == 0) {
605 2116 min = -1;
606 2116 max = fmt_nb-1;
607 }
608
609
2/4
✓ Branch 0 taken 5282 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5282 times.
5282 if (fmt < min || fmt > max) {
610 av_log(obj, AV_LOG_ERROR,
611 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
612 fmt, o->name, desc, min, max);
613 return AVERROR(ERANGE);
614 }
615
616 5282 *(int *)dst = fmt;
617 5282 return 0;
618 }
619
620 576 static int get_pix_fmt(const char *name)
621 {
622 576 return av_get_pix_fmt(name);
623 }
624
625 576 static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
626 {
627 576 return set_string_fmt(obj, o, val, dst,
628 AV_PIX_FMT_NB, get_pix_fmt, "pixel format");
629 }
630
631 4708 static int get_sample_fmt(const char *name)
632 {
633 4708 return av_get_sample_fmt(name);
634 }
635
636 4708 static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
637 {
638 4708 return set_string_fmt(obj, o, val, dst,
639 AV_SAMPLE_FMT_NB, get_sample_fmt, "sample format");
640 }
641
642 861 static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst)
643 {
644 861 AVDictionary *options = NULL;
645
646
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 793 times.
861 if (val) {
647 68 int ret = av_dict_parse_string(&options, val, "=", ":", 0);
648
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 if (ret < 0) {
649 av_dict_free(&options);
650 return ret;
651 }
652 }
653
654 861 av_dict_free((AVDictionary **)dst);
655 861 *dst = (uint8_t *)options;
656
657 861 return 0;
658 }
659
660 51532 static int set_string_channel_layout(void *obj, const AVOption *o,
661 const char *val, void *dst)
662 {
663 51532 AVChannelLayout *channel_layout = dst;
664 51532 av_channel_layout_uninit(channel_layout);
665
2/2
✓ Branch 0 taken 49414 times.
✓ Branch 1 taken 2118 times.
51532 if (!val)
666 49414 return 0;
667 2118 return av_channel_layout_from_string(channel_layout, val);
668 }
669
670 200761 static int opt_set_elem(void *obj, void *target_obj, const AVOption *o,
671 const char *val, void *dst)
672 {
673 200761 const enum AVOptionType type = TYPE_BASE(o->type);
674 int ret;
675
676
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 200761 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
200761 if (!val && (type != AV_OPT_TYPE_STRING &&
677 type != AV_OPT_TYPE_PIXEL_FMT && type != AV_OPT_TYPE_SAMPLE_FMT &&
678 type != AV_OPT_TYPE_IMAGE_SIZE &&
679 type != AV_OPT_TYPE_DURATION && type != AV_OPT_TYPE_COLOR &&
680 type != AV_OPT_TYPE_BOOL))
681 return AVERROR(EINVAL);
682
683
12/13
✓ Branch 0 taken 9864 times.
✓ Branch 1 taken 64573 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 115470 times.
✓ Branch 4 taken 2855 times.
✓ Branch 5 taken 234 times.
✓ Branch 6 taken 576 times.
✓ Branch 7 taken 4708 times.
✓ Branch 8 taken 338 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 2029 times.
✓ Branch 11 taken 61 times.
✗ Branch 12 not taken.
200761 switch (type) {
684 9864 case AV_OPT_TYPE_BOOL:
685 9864 return set_string_bool(obj, o, val, dst);
686 64573 case AV_OPT_TYPE_STRING:
687 64573 return set_string(obj, o, val, dst);
688 14 case AV_OPT_TYPE_BINARY:
689 14 return set_string_binary(obj, o, val, dst);
690 115470 case AV_OPT_TYPE_FLAGS:
691 case AV_OPT_TYPE_INT:
692 case AV_OPT_TYPE_UINT:
693 case AV_OPT_TYPE_INT64:
694 case AV_OPT_TYPE_UINT64:
695 case AV_OPT_TYPE_FLOAT:
696 case AV_OPT_TYPE_DOUBLE:
697 case AV_OPT_TYPE_RATIONAL:
698 115470 return set_string_number(obj, target_obj, o, val, dst);
699 2855 case AV_OPT_TYPE_IMAGE_SIZE:
700 2855 return set_string_image_size(obj, o, val, dst);
701 234 case AV_OPT_TYPE_VIDEO_RATE: {
702 AVRational tmp;
703 234 ret = set_string_video_rate(obj, o, val, &tmp);
704
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 233 times.
234 if (ret < 0)
705 1 return ret;
706 233 return write_number(obj, o, dst, 1, tmp.den, tmp.num);
707 }
708 576 case AV_OPT_TYPE_PIXEL_FMT:
709 576 return set_string_pixel_fmt(obj, o, val, dst);
710 4708 case AV_OPT_TYPE_SAMPLE_FMT:
711 4708 return set_string_sample_fmt(obj, o, val, dst);
712 338 case AV_OPT_TYPE_DURATION:
713 {
714 338 int64_t usecs = 0;
715
1/2
✓ Branch 0 taken 338 times.
✗ Branch 1 not taken.
338 if (val) {
716
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 337 times.
338 if ((ret = av_parse_time(&usecs, val, 1)) < 0) {
717 1 av_log(obj, AV_LOG_ERROR, "Unable to parse \"%s\" option value \"%s\" as duration\n", o->name, val);
718 1 return ret;
719 }
720 }
721
2/4
✓ Branch 0 taken 337 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 337 times.
337 if (usecs < o->min || usecs > o->max) {
722 av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
723 usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0);
724 return AVERROR(ERANGE);
725 }
726 337 *(int64_t *)dst = usecs;
727 337 return 0;
728 }
729 39 case AV_OPT_TYPE_COLOR:
730 39 return set_string_color(obj, o, val, dst);
731 2029 case AV_OPT_TYPE_CHLAYOUT:
732 2029 ret = set_string_channel_layout(obj, o, val, dst);
733
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2028 times.
2029 if (ret < 0) {
734 1 av_log(obj, AV_LOG_ERROR, "Unable to parse \"%s\" option value \"%s\" as channel layout\n", o->name, val);
735 1 ret = AVERROR(EINVAL);
736 }
737 2029 return ret;
738 61 case AV_OPT_TYPE_DICT:
739 61 return set_string_dict(obj, o, val, dst);
740 }
741
742 av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
743 return AVERROR(EINVAL);
744 }
745
746 2238 static int opt_set_array(void *obj, void *target_obj, const AVOption *o,
747 const char *val, void *dst)
748 {
749 2238 const AVOptionArrayDef *arr = o->default_val.arr;
750 2238 const size_t elem_size = opt_type_desc[TYPE_BASE(o->type)].size;
751 2238 const uint8_t sep = opt_array_sep(o);
752 2238 uint8_t *str = NULL;
753
754 2238 void *elems = NULL;
755 2238 unsigned nb_elems = 0;
756 int ret;
757
758
4/4
✓ Branch 0 taken 2226 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 2224 times.
✓ Branch 3 taken 2 times.
2238 if (val && *val) {
759 2224 str = av_malloc(strlen(val) + 1);
760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2224 times.
2224 if (!str)
761 return AVERROR(ENOMEM);
762 }
763
764 // split and unescape the string
765
4/4
✓ Branch 0 taken 5294 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 3069 times.
✓ Branch 3 taken 2225 times.
5306 while (val && *val) {
766 3069 uint8_t *p = str;
767 void *tmp;
768
769
5/6
✓ Branch 0 taken 3056 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 3024 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
3069 if (arr && arr->size_max && nb_elems >= arr->size_max) {
770 av_log(obj, AV_LOG_ERROR,
771 "Cannot assign more than %u elements to array option %s\n",
772 arr->size_max, o->name);
773 ret = AVERROR(EINVAL);
774 goto fail;
775 }
776
777
2/2
✓ Branch 0 taken 13439 times.
✓ Branch 1 taken 2224 times.
15663 for (; *val; val++, p++) {
778
3/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 13376 times.
✓ Branch 2 taken 63 times.
✗ Branch 3 not taken.
13439 if (*val == '\\' && val[1])
779 63 val++;
780
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 12531 times.
13376 else if (*val == sep) {
781 845 val++;
782 845 break;
783 }
784 12594 *p = *val;
785 }
786 3069 *p = 0;
787
788 3069 tmp = av_realloc_array(elems, nb_elems + 1, elem_size);
789
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069 times.
3069 if (!tmp) {
790 ret = AVERROR(ENOMEM);
791 goto fail;
792 }
793 3069 elems = tmp;
794
795 3069 tmp = opt_array_pelem(o, elems, nb_elems);
796 3069 memset(tmp, 0, elem_size);
797
798 3069 ret = opt_set_elem(obj, target_obj, o, str, tmp);
799
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3068 times.
3069 if (ret < 0)
800 1 goto fail;
801 3068 nb_elems++;
802 }
803 2237 av_freep(&str);
804
805 2237 opt_free_array(o, dst, opt_array_pcount(dst));
806
807
3/4
✓ Branch 0 taken 2218 times.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2218 times.
2237 if (arr && nb_elems < arr->size_min) {
808 av_log(obj, AV_LOG_ERROR,
809 "Cannot assign fewer than %u elements to array option %s\n",
810 arr->size_min, o->name);
811 ret = AVERROR(EINVAL);
812 goto fail;
813 }
814
815 2237 *((void **)dst) = elems;
816 2237 *opt_array_pcount(dst) = nb_elems;
817
818 2237 return 0;
819 1 fail:
820 1 av_freep(&str);
821 1 opt_free_array(o, &elems, &nb_elems);
822 1 return ret;
823 }
824
825 249322 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
826 {
827 void *dst, *target_obj;
828 const AVOption *o;
829 int ret;
830
831 249322 ret = opt_set_init(obj, name, search_flags, 0, &target_obj, &o, &dst);
832
2/2
✓ Branch 0 taken 49406 times.
✓ Branch 1 taken 199916 times.
249322 if (ret < 0)
833 49406 return ret;
834
835 199916 return ((o->type & AV_OPT_TYPE_FLAG_ARRAY) ?
836
2/2
✓ Branch 0 taken 2224 times.
✓ Branch 1 taken 197692 times.
199916 opt_set_array : opt_set_elem)(obj, target_obj, o, val, dst);
837 }
838
839 #define OPT_EVAL_NUMBER(name, opttype, vartype) \
840 int av_opt_eval_ ## name(void *obj, const AVOption *o, \
841 const char *val, vartype *name ## _out) \
842 { \
843 if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY) \
844 return AVERROR(EINVAL); \
845 return set_string_number(obj, obj, o, val, name ## _out); \
846 }
847
848
3/6
✓ Branch 0 taken 14199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14199 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14199 times.
14199 OPT_EVAL_NUMBER(flags, AV_OPT_TYPE_FLAGS, int)
849
3/6
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
28 OPT_EVAL_NUMBER(int, AV_OPT_TYPE_INT, int)
850 OPT_EVAL_NUMBER(uint, AV_OPT_TYPE_UINT, unsigned)
851 OPT_EVAL_NUMBER(int64, AV_OPT_TYPE_INT64, int64_t)
852 OPT_EVAL_NUMBER(float, AV_OPT_TYPE_FLOAT, float)
853 OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE, double)
854 OPT_EVAL_NUMBER(q, AV_OPT_TYPE_RATIONAL, AVRational)
855
856 28741 static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
857 int search_flags, int require_type)
858 {
859 void *dst;
860 const AVOption *o;
861 int ret;
862
863 28741 ret = opt_set_init(obj, name, search_flags, require_type, NULL, &o, &dst);
864
2/2
✓ Branch 0 taken 15668 times.
✓ Branch 1 taken 13073 times.
28741 if (ret < 0)
865 15668 return ret;
866
867 13073 return write_number(obj, o, dst, num, den, intnum);
868 }
869
870 28726 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
871 {
872 28726 return set_number(obj, name, 1, 1, val, search_flags, 0);
873 }
874
875 15 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
876 {
877 15 return set_number(obj, name, val, 1, 1, search_flags, 0);
878 }
879
880 int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
881 {
882 return set_number(obj, name, val.num, val.den, 1, search_flags, 0);
883 }
884
885 int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
886 {
887 uint8_t *ptr;
888 uint8_t **dst;
889 int *lendst;
890 int ret;
891
892 ret = opt_set_init(obj, name, search_flags, AV_OPT_TYPE_BINARY,
893 NULL, NULL, (void**)&dst);
894 if (ret < 0)
895 return ret;
896
897 ptr = len ? av_malloc(len) : NULL;
898 if (len && !ptr)
899 return AVERROR(ENOMEM);
900
901 lendst = (int *)(dst + 1);
902
903 av_free(*dst);
904 *dst = ptr;
905 *lendst = len;
906 if (len)
907 memcpy(ptr, val, len);
908
909 return 0;
910 }
911
912 int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags)
913 {
914 const AVOption *o;
915 int *dst;
916 int ret;
917
918 ret = opt_set_init(obj, name, search_flags, AV_OPT_TYPE_IMAGE_SIZE,
919 NULL, &o, (void**)&dst);
920 if (ret < 0)
921 return ret;
922
923 if (w<0 || h<0) {
924 av_log(obj, AV_LOG_ERROR,
925 "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name);
926 return AVERROR(EINVAL);
927 }
928
929 dst[0] = w;
930 dst[1] = h;
931
932 return 0;
933 }
934
935 int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags)
936 {
937 return set_number(obj, name, val.num, val.den, 1, search_flags, AV_OPT_TYPE_VIDEO_RATE);
938 }
939
940 static int set_format(void *obj, const char *name, int fmt, int search_flags,
941 enum AVOptionType type, const char *desc, int nb_fmts)
942 {
943 const AVOption *o;
944 int *dst;
945 int min, max, ret;
946
947 ret = opt_set_init(obj, name, search_flags, type, NULL, &o, (void**)&dst);
948 if (ret < 0)
949 return ret;
950
951 min = FFMAX(o->min, -1);
952 max = FFMIN(o->max, nb_fmts-1);
953
954 if (fmt < min || fmt > max) {
955 av_log(obj, AV_LOG_ERROR,
956 "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
957 fmt, name, desc, min, max);
958 return AVERROR(ERANGE);
959 }
960 *dst = fmt;
961 return 0;
962 }
963
964 int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags)
965 {
966 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
967 }
968
969 int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
970 {
971 return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
972 }
973
974 int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val,
975 int search_flags)
976 {
977 AVDictionary **dst;
978 int ret;
979
980 ret = opt_set_init(obj, name, search_flags, AV_OPT_TYPE_DICT, NULL, NULL,
981 (void**)&dst);
982 if (ret < 0)
983 return ret;
984
985 av_dict_free(dst);
986
987 return av_dict_copy(dst, val, 0);
988 }
989
990 3354 int av_opt_set_chlayout(void *obj, const char *name,
991 const AVChannelLayout *channel_layout,
992 int search_flags)
993 {
994 AVChannelLayout *dst;
995 int ret;
996
997 3354 ret = opt_set_init(obj, name, search_flags, AV_OPT_TYPE_CHLAYOUT, NULL, NULL,
998 (void**)&dst);
999
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3354 times.
3354 if (ret < 0)
1000 return ret;
1001
1002 3354 return av_channel_layout_copy(dst, channel_layout);
1003 }
1004
1005 5 static void format_duration(char *buf, size_t size, int64_t d)
1006 {
1007 char *e;
1008
1009
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 av_assert0(size >= 25);
1010
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5 if (d < 0 && d != INT64_MIN) {
1011 *(buf++) = '-';
1012 size--;
1013 d = -d;
1014 }
1015
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (d == INT64_MAX)
1016 snprintf(buf, size, "INT64_MAX");
1017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 else if (d == INT64_MIN)
1018 snprintf(buf, size, "INT64_MIN");
1019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 else if (d > (int64_t)3600*1000000)
1020 snprintf(buf, size, "%"PRId64":%02d:%02d.%06d", d / 3600000000,
1021 (int)((d / 60000000) % 60),
1022 (int)((d / 1000000) % 60),
1023 (int)(d % 1000000));
1024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 else if (d > 60*1000000)
1025 snprintf(buf, size, "%d:%02d.%06d",
1026 (int)(d / 60000000),
1027 (int)((d / 1000000) % 60),
1028 (int)(d % 1000000));
1029 else
1030 5 snprintf(buf, size, "%d.%06d",
1031 5 (int)(d / 1000000),
1032 5 (int)(d % 1000000));
1033 5 e = buf + strlen(buf);
1034
3/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 5 times.
20 while (e > buf && e[-1] == '0')
1035 15 *(--e) = 0;
1036
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 if (e > buf && e[-1] == '.')
1037 *(--e) = 0;
1038 5 }
1039
1040 7060 static int opt_get_elem(const AVOption *o, uint8_t **pbuf, size_t buf_len,
1041 const void *dst, int search_flags)
1042 {
1043 int ret;
1044
1045
17/20
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 6682 times.
✓ Branch 2 taken 95 times.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 61 times.
✓ Branch 7 taken 5 times.
✓ Branch 8 taken 45 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 26 times.
✓ Branch 11 taken 12 times.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 10 times.
✓ Branch 18 taken 24 times.
✗ Branch 19 not taken.
7060 switch (TYPE_BASE(o->type)) {
1046 35 case AV_OPT_TYPE_BOOL:
1047 35 ret = snprintf(*pbuf, buf_len, "%s", get_bool_name(*(int *)dst));
1048 35 break;
1049 6682 case AV_OPT_TYPE_FLAGS:
1050 6682 ret = snprintf(*pbuf, buf_len, "0x%08X", *(int *)dst);
1051 6682 break;
1052 95 case AV_OPT_TYPE_INT:
1053 95 ret = snprintf(*pbuf, buf_len, "%d", *(int *)dst);
1054 95 break;
1055 23 case AV_OPT_TYPE_UINT:
1056 23 ret = snprintf(*pbuf, buf_len, "%u", *(unsigned *)dst);
1057 23 break;
1058 22 case AV_OPT_TYPE_INT64:
1059 22 ret = snprintf(*pbuf, buf_len, "%"PRId64, *(int64_t *)dst);
1060 22 break;
1061 case AV_OPT_TYPE_UINT64:
1062 ret = snprintf(*pbuf, buf_len, "%"PRIu64, *(uint64_t *)dst);
1063 break;
1064 61 case AV_OPT_TYPE_FLOAT:
1065 61 ret = snprintf(*pbuf, buf_len, "%f", *(float *)dst);
1066 61 break;
1067 5 case AV_OPT_TYPE_DOUBLE:
1068 5 ret = snprintf(*pbuf, buf_len, "%f", *(double *)dst);
1069 5 break;
1070 45 case AV_OPT_TYPE_VIDEO_RATE:
1071 case AV_OPT_TYPE_RATIONAL:
1072 45 ret = snprintf(*pbuf, buf_len, "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den);
1073 45 break;
1074 case AV_OPT_TYPE_CONST:
1075 ret = snprintf(*pbuf, buf_len, "%"PRId64, o->default_val.i64);
1076 break;
1077 26 case AV_OPT_TYPE_STRING:
1078
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (*(uint8_t **)dst) {
1079 26 *pbuf = av_strdup(*(uint8_t **)dst);
1080 } else if (search_flags & AV_OPT_ALLOW_NULL) {
1081 *pbuf = NULL;
1082 return 0;
1083 } else {
1084 *pbuf = av_strdup("");
1085 }
1086
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 return *pbuf ? 0 : AVERROR(ENOMEM);
1087 12 case AV_OPT_TYPE_BINARY: {
1088 const uint8_t *bin;
1089 int len;
1090
1091
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
12 if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
1092 *pbuf = NULL;
1093 return 0;
1094 }
1095 12 len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *));
1096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if ((uint64_t)len * 2 + 1 > INT_MAX)
1097 return AVERROR(EINVAL);
1098
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 if (!(*pbuf = av_malloc(len * 2 + 1)))
1099 return AVERROR(ENOMEM);
1100
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 if (!len) {
1101 8 *pbuf[0] = '\0';
1102 8 return 0;
1103 }
1104 4 bin = *(uint8_t **)dst;
1105
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 for (int i = 0; i < len; i++)
1106 16 snprintf(*pbuf + i * 2, 3, "%02X", bin[i]);
1107 4 return 0;
1108 }
1109 4 case AV_OPT_TYPE_IMAGE_SIZE:
1110 4 ret = snprintf(*pbuf, buf_len, "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
1111 4 break;
1112 4 case AV_OPT_TYPE_PIXEL_FMT:
1113 4 ret = snprintf(*pbuf, buf_len, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
1114 4 break;
1115 4 case AV_OPT_TYPE_SAMPLE_FMT:
1116 4 ret = snprintf(*pbuf, buf_len, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
1117 4 break;
1118 4 case AV_OPT_TYPE_DURATION: {
1119 4 int64_t i64 = *(int64_t *)dst;
1120 4 format_duration(*pbuf, buf_len, i64);
1121 4 ret = strlen(*pbuf); // no overflow possible, checked by an assert
1122 4 break;
1123 }
1124 4 case AV_OPT_TYPE_COLOR:
1125 4 ret = snprintf(*pbuf, buf_len, "0x%02x%02x%02x%02x",
1126 4 (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
1127 4 (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
1128 4 break;
1129 10 case AV_OPT_TYPE_CHLAYOUT:
1130 10 ret = av_channel_layout_describe(dst, *pbuf, buf_len);
1131 10 break;
1132 24 case AV_OPT_TYPE_DICT:
1133
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
24 if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
1134 *pbuf = NULL;
1135 return 0;
1136 }
1137 24 return av_dict_get_string(*(AVDictionary **)dst, (char **)pbuf, '=', ':');
1138 default:
1139 return AVERROR(EINVAL);
1140 }
1141
1142 6998 return ret;
1143 }
1144
1145 70 static int opt_get_array(const AVOption *o, void *dst, uint8_t **out_val)
1146 {
1147 70 const unsigned count = *opt_array_pcount(dst);
1148 70 const uint8_t sep = opt_array_sep(o);
1149
1150 70 uint8_t *str = NULL;
1151 70 size_t str_len = 0;
1152 int ret;
1153
1154 70 *out_val = NULL;
1155
1156
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 70 times.
132 for (unsigned i = 0; i < count; i++) {
1157 62 uint8_t buf[128], *out = buf;
1158 size_t out_len;
1159
1160 62 ret = opt_get_elem(o, &out, sizeof(buf),
1161 62 opt_array_pelem(o, *(void **)dst, i), 0);
1162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (ret < 0)
1163 goto fail;
1164
1165 62 out_len = strlen(out);
1166
3/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 62 times.
✗ Branch 3 not taken.
62 if (out_len > SIZE_MAX / 2 - !!i ||
1167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 !!i + out_len * 2 > SIZE_MAX - str_len - 1) {
1168 ret = AVERROR(ERANGE);
1169 goto fail;
1170 }
1171
1172 // terminator escaping separator
1173 // ↓ ↓ ↓
1174 62 ret = av_reallocp(&str, str_len + 1 + out_len * 2 + !!i);
1175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (ret < 0)
1176 goto fail;
1177
1178 // add separator if needed
1179
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 14 times.
62 if (i)
1180 48 str[str_len++] = sep;
1181
1182 // escape the element
1183
2/2
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 62 times.
576 for (unsigned j = 0; j < out_len; j++) {
1184 514 uint8_t val = out[j];
1185
4/4
✓ Branch 0 taken 502 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 472 times.
514 if (val == sep || val == '\\')
1186 42 str[str_len++] = '\\';
1187 514 str[str_len++] = val;
1188 }
1189 62 str[str_len] = 0;
1190
1191 62 fail:
1192
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 32 times.
62 if (out != buf)
1193 30 av_freep(&out);
1194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (ret < 0) {
1195 av_freep(&str);
1196 return ret;
1197 }
1198 }
1199
1200 70 *out_val = str;
1201
1202 70 return 0;
1203 }
1204
1205 11452 int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
1206 {
1207 void *dst, *target_obj;
1208 11452 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1209 uint8_t *out, buf[128];
1210 int ret;
1211
1212
4/8
✓ Branch 0 taken 7051 times.
✓ Branch 1 taken 4401 times.
✓ Branch 2 taken 7051 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7051 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
11452 if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
1213 4401 return AVERROR_OPTION_NOT_FOUND;
1214
1215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7051 times.
7051 if (o->flags & AV_OPT_FLAG_DEPRECATED)
1216 av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
1217
1218 7051 dst = (uint8_t *)target_obj + o->offset;
1219
1220
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 6993 times.
7051 if (o->type & AV_OPT_TYPE_FLAG_ARRAY) {
1221 58 ret = opt_get_array(o, dst, out_val);
1222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if (ret < 0)
1223 return ret;
1224
4/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 1 times.
58 if (!*out_val && !(search_flags & AV_OPT_ALLOW_NULL)) {
1225 48 *out_val = av_strdup("");
1226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (!*out_val)
1227 return AVERROR(ENOMEM);
1228 }
1229 58 return 0;
1230 }
1231
1232 6993 buf[0] = 0;
1233 6993 out = buf;
1234 6993 ret = opt_get_elem(o, &out, sizeof(buf), dst, search_flags);
1235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6993 times.
6993 if (ret < 0)
1236 return ret;
1237
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 6961 times.
6993 if (out != buf) {
1238 32 *out_val = out;
1239 32 return 0;
1240 }
1241
1242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6961 times.
6961 if (ret >= sizeof(buf))
1243 return AVERROR(EINVAL);
1244 6961 *out_val = av_strdup(out);
1245
1/2
✓ Branch 0 taken 6961 times.
✗ Branch 1 not taken.
6961 return *out_val ? 0 : AVERROR(ENOMEM);
1246 }
1247
1248 24593 static int get_number(void *obj, const char *name, double *num, int *den, int64_t *intnum,
1249 int search_flags)
1250 {
1251 void *dst, *target_obj;
1252 24593 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1253
3/4
✓ Branch 0 taken 24579 times.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24579 times.
24593 if (!o || !target_obj)
1254 14 return AVERROR_OPTION_NOT_FOUND;
1255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24579 times.
24579 if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
1256 return AVERROR(EINVAL);
1257
1258 24579 dst = ((uint8_t *)target_obj) + o->offset;
1259
1260 24579 return read_number(o, dst, num, den, intnum);
1261 }
1262
1263 24593 int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
1264 {
1265 24593 int64_t intnum = 1;
1266 24593 double num = 1;
1267 24593 int ret, den = 1;
1268
1269
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 24579 times.
24593 if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
1270 14 return ret;
1271
1/2
✓ Branch 0 taken 24579 times.
✗ Branch 1 not taken.
24579 if (num == den)
1272 24579 *out_val = intnum;
1273 else
1274 *out_val = num * intnum / den;
1275 24579 return 0;
1276 }
1277
1278 int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
1279 {
1280 int64_t intnum = 1;
1281 double num = 1;
1282 int ret, den = 1;
1283
1284 if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
1285 return ret;
1286 *out_val = num * intnum / den;
1287 return 0;
1288 }
1289
1290 int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
1291 {
1292 int64_t intnum = 1;
1293 double num = 1;
1294 int ret, den = 1;
1295
1296 if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
1297 return ret;
1298
1299 if (num == 1.0 && (int)intnum == intnum)
1300 *out_val = (AVRational){intnum, den};
1301 else
1302 *out_val = double_to_rational(num*intnum/den);
1303 return 0;
1304 }
1305
1306 int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
1307 {
1308 void *dst, *target_obj;
1309 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1310 if (!o || !target_obj)
1311 return AVERROR_OPTION_NOT_FOUND;
1312 if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
1313 av_log(obj, AV_LOG_ERROR,
1314 "The value for option '%s' is not a image size.\n", name);
1315 return AVERROR(EINVAL);
1316 }
1317
1318 dst = ((uint8_t*)target_obj) + o->offset;
1319 if (w_out) *w_out = *(int *)dst;
1320 if (h_out) *h_out = *((int *)dst+1);
1321 return 0;
1322 }
1323
1324 int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val)
1325 {
1326 return av_opt_get_q(obj, name, search_flags, out_val);
1327 }
1328
1329 3014 static int get_format(void *obj, const char *name, int search_flags, void *out_fmt,
1330 enum AVOptionType type, const char *desc)
1331 {
1332 void *dst, *target_obj;
1333 3014 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1334
2/4
✓ Branch 0 taken 3014 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3014 times.
3014 if (!o || !target_obj)
1335 return AVERROR_OPTION_NOT_FOUND;
1336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3014 times.
3014 if (o->type != type) {
1337 av_log(obj, AV_LOG_ERROR,
1338 "The value for option '%s' is not a %s format.\n", desc, name);
1339 return AVERROR(EINVAL);
1340 }
1341
1342 3014 dst = ((uint8_t*)target_obj) + o->offset;
1343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3014 times.
3014 if (type == AV_OPT_TYPE_PIXEL_FMT)
1344 *(enum AVPixelFormat *)out_fmt = *(enum AVPixelFormat *)dst;
1345 else
1346 3014 *(enum AVSampleFormat*)out_fmt = *(enum AVSampleFormat*)dst;
1347
1348 3014 return 0;
1349 }
1350
1351 int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt)
1352 {
1353 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
1354 }
1355
1356 3014 int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
1357 {
1358 3014 return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
1359 }
1360
1361 3014 int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *cl)
1362 {
1363 void *dst, *target_obj;
1364 3014 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1365
2/4
✓ Branch 0 taken 3014 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3014 times.
3014 if (!o || !target_obj)
1366 return AVERROR_OPTION_NOT_FOUND;
1367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3014 times.
3014 if (o->type != AV_OPT_TYPE_CHLAYOUT) {
1368 av_log(obj, AV_LOG_ERROR,
1369 "The value for option '%s' is not a channel layout.\n", name);
1370 return AVERROR(EINVAL);
1371 }
1372
1373 3014 dst = ((uint8_t*)target_obj) + o->offset;
1374 3014 return av_channel_layout_copy(cl, dst);
1375 }
1376
1377 7857 int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val)
1378 {
1379 void *target_obj;
1380 AVDictionary *src;
1381 7857 const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
1382
1383
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7857 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7857 if (!o || !target_obj)
1384 7857 return AVERROR_OPTION_NOT_FOUND;
1385 if (o->type != AV_OPT_TYPE_DICT)
1386 return AVERROR(EINVAL);
1387
1388 src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset);
1389
1390 return av_dict_copy(out_val, src, 0);
1391 }
1392
1393 int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
1394 {
1395 const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
1396 const AVOption *flag = av_opt_find(obj, flag_name,
1397 field ? field->unit : NULL, 0, 0);
1398 int64_t res;
1399
1400 if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
1401 av_opt_get_int(obj, field_name, 0, &res) < 0)
1402 return 0;
1403 return res & flag->default_val.i64;
1404 }
1405
1406 4 static void log_int_value(void *av_log_obj, int level, int64_t i)
1407 {
1408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (i == INT_MAX) {
1409 av_log(av_log_obj, level, "INT_MAX");
1410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (i == INT_MIN) {
1411 av_log(av_log_obj, level, "INT_MIN");
1412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (i == UINT32_MAX) {
1413 av_log(av_log_obj, level, "UINT32_MAX");
1414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (i == INT64_MAX) {
1415 av_log(av_log_obj, level, "I64_MAX");
1416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (i == INT64_MIN) {
1417 av_log(av_log_obj, level, "I64_MIN");
1418 } else {
1419 4 av_log(av_log_obj, level, "%"PRId64, i);
1420 }
1421 4 }
1422
1423 16 static void log_value(void *av_log_obj, int level, double d)
1424 {
1425
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (d == INT_MAX) {
1426 av_log(av_log_obj, level, "INT_MAX");
1427
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == INT_MIN) {
1428 av_log(av_log_obj, level, "INT_MIN");
1429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == UINT32_MAX) {
1430 av_log(av_log_obj, level, "UINT32_MAX");
1431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == (double)INT64_MAX) {
1432 av_log(av_log_obj, level, "I64_MAX");
1433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == INT64_MIN) {
1434 av_log(av_log_obj, level, "I64_MIN");
1435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == FLT_MAX) {
1436 av_log(av_log_obj, level, "FLT_MAX");
1437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == FLT_MIN) {
1438 av_log(av_log_obj, level, "FLT_MIN");
1439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == -FLT_MAX) {
1440 av_log(av_log_obj, level, "-FLT_MAX");
1441
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == -FLT_MIN) {
1442 av_log(av_log_obj, level, "-FLT_MIN");
1443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == DBL_MAX) {
1444 av_log(av_log_obj, level, "DBL_MAX");
1445
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == DBL_MIN) {
1446 av_log(av_log_obj, level, "DBL_MIN");
1447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == -DBL_MAX) {
1448 av_log(av_log_obj, level, "-DBL_MAX");
1449
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (d == -DBL_MIN) {
1450 av_log(av_log_obj, level, "-DBL_MIN");
1451 } else {
1452 16 av_log(av_log_obj, level, "%g", d);
1453 }
1454 16 }
1455
1456 4 static const char *get_opt_const_name(void *obj, const char *unit, int64_t value)
1457 {
1458 4 const AVOption *opt = NULL;
1459
1460
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!unit)
1461 4 return NULL;
1462 while ((opt = av_opt_next(obj, opt)))
1463 if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) &&
1464 opt->default_val.i64 == value)
1465 return opt->name;
1466 return NULL;
1467 }
1468
1469 1 static char *get_opt_flags_string(void *obj, const char *unit, int64_t value)
1470 {
1471 1 const AVOption *opt = NULL;
1472 char flags[512];
1473
1474 1 flags[0] = 0;
1475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!unit)
1476 return NULL;
1477
2/2
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 1 times.
32 while ((opt = av_opt_next(obj, opt))) {
1478
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
31 if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) &&
1479
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 opt->default_val.i64 & value) {
1480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (flags[0])
1481 av_strlcatf(flags, sizeof(flags), "+");
1482 1 av_strlcatf(flags, sizeof(flags), "%s", opt->name);
1483 }
1484 }
1485
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (flags[0])
1486 1 return av_strdup(flags);
1487 return NULL;
1488 }
1489
1490 31 static void log_type(void *av_log_obj, const AVOption *o,
1491 enum AVOptionType parent_type)
1492 {
1493 31 const enum AVOptionType type = TYPE_BASE(o->type);
1494
1495
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
31 if (o->type == AV_OPT_TYPE_CONST && (TYPE_BASE(parent_type) == AV_OPT_TYPE_INT || TYPE_BASE(parent_type) == AV_OPT_TYPE_INT64))
1496 av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", o->default_val.i64);
1497
3/4
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 3 times.
31 else if (type < FF_ARRAY_ELEMS(opt_type_desc) && opt_type_desc[type].name) {
1498
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 25 times.
28 if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
1499 3 av_log(av_log_obj, AV_LOG_INFO, "[%-10s]", opt_type_desc[type].name);
1500 else
1501 25 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", opt_type_desc[type].name);
1502 }
1503 else
1504 3 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
1505 31 }
1506
1507 31 static void log_default(void *obj, void *av_log_obj, const AVOption *opt)
1508 {
1509
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 25 times.
31 if (opt->type == AV_OPT_TYPE_CONST || opt->type == AV_OPT_TYPE_BINARY)
1510 6 return;
1511
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1 times.
25 if ((opt->type == AV_OPT_TYPE_COLOR ||
1512
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1 times.
24 opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
1513
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2 times.
23 opt->type == AV_OPT_TYPE_STRING ||
1514
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 2 times.
21 opt->type == AV_OPT_TYPE_DICT ||
1515
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
19 opt->type == AV_OPT_TYPE_CHLAYOUT ||
1516
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 17 times.
18 opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
1517
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 !opt->default_val.str)
1518 1 return;
1519
1520
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 21 times.
24 if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) {
1521 3 const AVOptionArrayDef *arr = opt->default_val.arr;
1522
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
3 if (arr && arr->def)
1523 2 av_log(av_log_obj, AV_LOG_INFO, " (default %s)", arr->def);
1524 3 return;
1525 }
1526
1527 21 av_log(av_log_obj, AV_LOG_INFO, " (default ");
1528
9/10
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 7 times.
✗ Branch 9 not taken.
21 switch (opt->type) {
1529 3 case AV_OPT_TYPE_BOOL:
1530 3 av_log(av_log_obj, AV_LOG_INFO, "%s", get_bool_name(opt->default_val.i64));
1531 3 break;
1532 1 case AV_OPT_TYPE_FLAGS: {
1533 1 char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64);
1534
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (def_flags) {
1535 1 av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags);
1536 1 av_freep(&def_flags);
1537 } else {
1538 av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
1539 }
1540 1 break;
1541 }
1542 1 case AV_OPT_TYPE_DURATION: {
1543 char buf[25];
1544 1 format_duration(buf, sizeof(buf), opt->default_val.i64);
1545 1 av_log(av_log_obj, AV_LOG_INFO, "%s", buf);
1546 1 break;
1547 }
1548 4 case AV_OPT_TYPE_UINT:
1549 case AV_OPT_TYPE_INT:
1550 case AV_OPT_TYPE_UINT64:
1551 case AV_OPT_TYPE_INT64: {
1552 4 const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64);
1553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (def_const)
1554 av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
1555 else
1556 4 log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
1557 4 break;
1558 }
1559 2 case AV_OPT_TYPE_DOUBLE:
1560 case AV_OPT_TYPE_FLOAT:
1561 2 log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
1562 2 break;
1563 1 case AV_OPT_TYPE_RATIONAL: {
1564 1 AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
1565 1 av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
1566 1 break;
1567 1 case AV_OPT_TYPE_PIXEL_FMT:
1568 1 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
1569 1 break;
1570 1 case AV_OPT_TYPE_SAMPLE_FMT:
1571 1 av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
1572 1 break;
1573 7 case AV_OPT_TYPE_COLOR:
1574 case AV_OPT_TYPE_IMAGE_SIZE:
1575 case AV_OPT_TYPE_STRING:
1576 case AV_OPT_TYPE_DICT:
1577 case AV_OPT_TYPE_VIDEO_RATE:
1578 case AV_OPT_TYPE_CHLAYOUT:
1579 7 av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
1580 7 break;
1581 }
1582 21 av_log(av_log_obj, AV_LOG_INFO, ")");
1583 }
1584
1585 2 static void opt_list(void *obj, void *av_log_obj, const char *unit,
1586 int req_flags, int rej_flags, enum AVOptionType parent_type)
1587 {
1588 2 const AVOption *opt = NULL;
1589 AVOptionRanges *r;
1590 int i;
1591
1592
2/2
✓ Branch 1 taken 62 times.
✓ Branch 2 taken 2 times.
64 while ((opt = av_opt_next(obj, opt))) {
1593
2/4
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 62 times.
62 if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
1594 continue;
1595
1596 /* Don't print CONST's on level one.
1597 * Don't print anything but CONST's on level two.
1598 * Only print items from the requested unit.
1599 */
1600
4/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 28 times.
62 if (!unit && opt->type == AV_OPT_TYPE_CONST)
1601 3 continue;
1602
4/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 3 times.
59 else if (unit && opt->type != AV_OPT_TYPE_CONST)
1603 28 continue;
1604
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
31 else if (unit && opt->type == AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
1605 continue;
1606
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
31 else if (unit && opt->type == AV_OPT_TYPE_CONST)
1607 3 av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name);
1608 else
1609 28 av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ",
1610 28 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? " " : "-",
1611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 opt->name);
1612
1613 31 log_type(av_log_obj, opt, parent_type);
1614
1615 341 av_log(av_log_obj, AV_LOG_INFO, "%c%c%c%c%c%c%c%c%c%c%c",
1616
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 3 times.
31 (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.',
1617
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.',
1618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? 'F' : '.',
1619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_VIDEO_PARAM) ? 'V' : '.',
1620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_AUDIO_PARAM) ? 'A' : '.',
1621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.',
1622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.',
1623
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.',
1624
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_BSF_PARAM) ? 'B' : '.',
1625
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 28 times.
31 (opt->flags & AV_OPT_FLAG_RUNTIME_PARAM) ? 'T' : '.',
1626
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 (opt->flags & AV_OPT_FLAG_DEPRECATED) ? 'P' : '.');
1627
1628
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (opt->help)
1629 31 av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
1630
1631
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 13 times.
31 if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
1632
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 11 times.
18 switch (opt->type) {
1633 7 case AV_OPT_TYPE_INT:
1634 case AV_OPT_TYPE_UINT:
1635 case AV_OPT_TYPE_INT64:
1636 case AV_OPT_TYPE_UINT64:
1637 case AV_OPT_TYPE_DOUBLE:
1638 case AV_OPT_TYPE_FLOAT:
1639 case AV_OPT_TYPE_RATIONAL:
1640
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 for (i = 0; i < r->nb_ranges; i++) {
1641 7 av_log(av_log_obj, AV_LOG_INFO, " (from ");
1642 7 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
1643 7 av_log(av_log_obj, AV_LOG_INFO, " to ");
1644 7 log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
1645 7 av_log(av_log_obj, AV_LOG_INFO, ")");
1646 }
1647 7 break;
1648 }
1649 18 av_opt_freep_ranges(&r);
1650 }
1651
1652 31 log_default(obj, av_log_obj, opt);
1653
1654 31 av_log(av_log_obj, AV_LOG_INFO, "\n");
1655
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
31 if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
1656 1 opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags, opt->type);
1657 }
1658 2 }
1659
1660 1 int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
1661 {
1662
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!obj)
1663 return -1;
1664
1665 1 av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name);
1666
1667 1 opt_list(obj, av_log_obj, NULL, req_flags, rej_flags, -1);
1668
1669 1 return 0;
1670 }
1671
1672 431490 void av_opt_set_defaults(void *s)
1673 {
1674 431490 av_opt_set_defaults2(s, 0, 0);
1675 431490 }
1676
1677 496528 void av_opt_set_defaults2(void *s, int mask, int flags)
1678 {
1679 496528 const AVOption *opt = NULL;
1680
2/2
✓ Branch 1 taken 32433438 times.
✓ Branch 2 taken 496528 times.
32929966 while ((opt = av_opt_next(s, opt))) {
1681 32433438 void *dst = ((uint8_t*)s) + opt->offset;
1682
1683
2/2
✓ Branch 0 taken 3278037 times.
✓ Branch 1 taken 29155401 times.
32433438 if ((opt->flags & mask) != flags)
1684 3278037 continue;
1685
1686
2/2
✓ Branch 0 taken 3137 times.
✓ Branch 1 taken 29152264 times.
29155401 if (opt->flags & AV_OPT_FLAG_READONLY)
1687 3137 continue;
1688
1689
2/2
✓ Branch 0 taken 110616 times.
✓ Branch 1 taken 29041648 times.
29152264 if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) {
1690 110616 const AVOptionArrayDef *arr = opt->default_val.arr;
1691 110616 const char sep = opt_array_sep(opt);
1692
1693
11/16
✓ Branch 0 taken 110616 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 110616 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12158 times.
✓ Branch 5 taken 98458 times.
✓ Branch 6 taken 12158 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 12158 times.
✓ Branch 9 taken 98458 times.
✓ Branch 10 taken 12158 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 12158 times.
✓ Branch 13 taken 98458 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 12158 times.
110616 av_assert0(sep && sep != '\\' &&
1694 (sep < 'a' || sep > 'z') &&
1695 (sep < 'A' || sep > 'Z') &&
1696 (sep < '0' || sep > '9'));
1697
1698
4/4
✓ Branch 0 taken 12165 times.
✓ Branch 1 taken 98451 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 12151 times.
110616 if (arr && arr->def)
1699 14 opt_set_array(s, s, opt, arr->def, dst);
1700
1701 110616 continue;
1702 }
1703
1704
11/12
✓ Branch 0 taken 18923133 times.
✓ Branch 1 taken 8275337 times.
✓ Branch 2 taken 1002456 times.
✓ Branch 3 taken 202150 times.
✓ Branch 4 taken 323 times.
✓ Branch 5 taken 493280 times.
✓ Branch 6 taken 41860 times.
✓ Branch 7 taken 9534 times.
✓ Branch 8 taken 43272 times.
✓ Branch 9 taken 49503 times.
✓ Branch 10 taken 800 times.
✗ Branch 11 not taken.
29041648 switch (opt->type) {
1705 18923133 case AV_OPT_TYPE_CONST:
1706 /* Nothing to be done here */
1707 18923133 break;
1708 8275337 case AV_OPT_TYPE_BOOL:
1709 case AV_OPT_TYPE_FLAGS:
1710 case AV_OPT_TYPE_INT:
1711 case AV_OPT_TYPE_UINT:
1712 case AV_OPT_TYPE_INT64:
1713 case AV_OPT_TYPE_UINT64:
1714 case AV_OPT_TYPE_DURATION:
1715 case AV_OPT_TYPE_PIXEL_FMT:
1716 case AV_OPT_TYPE_SAMPLE_FMT:
1717 8275337 write_number(s, opt, dst, 1, 1, opt->default_val.i64);
1718 8275337 break;
1719 1002456 case AV_OPT_TYPE_DOUBLE:
1720 case AV_OPT_TYPE_FLOAT: {
1721 double val;
1722 1002456 val = opt->default_val.dbl;
1723 1002456 write_number(s, opt, dst, val, 1, 1);
1724 }
1725 1002456 break;
1726 202150 case AV_OPT_TYPE_RATIONAL: {
1727 AVRational val;
1728 202150 val = av_d2q(opt->default_val.dbl, INT_MAX);
1729 202150 write_number(s, opt, dst, 1, val.den, val.num);
1730 }
1731 202150 break;
1732 323 case AV_OPT_TYPE_COLOR:
1733 323 set_string_color(s, opt, opt->default_val.str, dst);
1734 323 break;
1735 493280 case AV_OPT_TYPE_STRING:
1736 493280 set_string(s, opt, opt->default_val.str, dst);
1737 493280 break;
1738 41860 case AV_OPT_TYPE_IMAGE_SIZE:
1739 41860 set_string_image_size(s, opt, opt->default_val.str, dst);
1740 41860 break;
1741 9534 case AV_OPT_TYPE_VIDEO_RATE:
1742 9534 set_string_video_rate(s, opt, opt->default_val.str, dst);
1743 9534 break;
1744 43272 case AV_OPT_TYPE_BINARY:
1745 43272 set_string_binary(s, opt, opt->default_val.str, dst);
1746 43272 break;
1747 49503 case AV_OPT_TYPE_CHLAYOUT:
1748 49503 set_string_channel_layout(s, opt, opt->default_val.str, dst);
1749 49503 break;
1750 800 case AV_OPT_TYPE_DICT:
1751 800 set_string_dict(s, opt, opt->default_val.str, dst);
1752 800 break;
1753 default:
1754 av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n",
1755 opt->type, opt->name);
1756 }
1757 }
1758 496528 }
1759
1760 /**
1761 * Store the value in the field in ctx that is named like key.
1762 * ctx must be an AVClass context, storing is done using AVOptions.
1763 *
1764 * @param buf the string to parse, buf will be updated to point at the
1765 * separator just after the parsed key/value pair
1766 * @param key_val_sep a 0-terminated list of characters used to
1767 * separate key from value
1768 * @param pairs_sep a 0-terminated list of characters used to separate
1769 * two pairs from each other
1770 * @return 0 if the key/value pair has been successfully parsed and
1771 * set, or a negative value corresponding to an AVERROR code in case
1772 * of error:
1773 * AVERROR(EINVAL) if the key/value pair cannot be parsed,
1774 * the error code issued by av_opt_set() if the key/value pair
1775 * cannot be set
1776 */
1777 3256 static int parse_key_value_pair(void *ctx, const char **buf,
1778 const char *key_val_sep, const char *pairs_sep)
1779 {
1780 3256 char *key = av_get_token(buf, key_val_sep);
1781 char *val;
1782 int ret;
1783
1784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3256 times.
3256 if (!key)
1785 return AVERROR(ENOMEM);
1786
1787
4/4
✓ Branch 0 taken 3254 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3251 times.
✓ Branch 3 taken 3 times.
3256 if (*key && strspn(*buf, key_val_sep)) {
1788 3251 (*buf)++;
1789 3251 val = av_get_token(buf, pairs_sep);
1790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3251 times.
3251 if (!val) {
1791 av_freep(&key);
1792 return AVERROR(ENOMEM);
1793 }
1794 } else {
1795 5 av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
1796 5 av_free(key);
1797 5 return AVERROR(EINVAL);
1798 }
1799
1800 3251 av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
1801
1802 3251 ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN);
1803
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3246 times.
3251 if (ret == AVERROR_OPTION_NOT_FOUND)
1804 5 av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
1805
1806 3251 av_free(key);
1807 3251 av_free(val);
1808 3251 return ret;
1809 }
1810
1811 3223 int av_set_options_string(void *ctx, const char *opts,
1812 const char *key_val_sep, const char *pairs_sep)
1813 {
1814 3223 int ret, count = 0;
1815
1816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3223 times.
3223 if (!opts)
1817 return 0;
1818
1819
2/2
✓ Branch 0 taken 3256 times.
✓ Branch 1 taken 3184 times.
6440 while (*opts) {
1820
2/2
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 3217 times.
3256 if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
1821 39 return ret;
1822 3217 count++;
1823
1824
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 3182 times.
3217 if (*opts)
1825 35 opts++;
1826 }
1827
1828 3184 return count;
1829 }
1830
1831 #define WHITESPACES " \n\t\r"
1832
1833 458671 static int is_key_char(char c)
1834 {
1835 594889 return (unsigned)((c | 32) - 'a') < 26 ||
1836
4/4
✓ Branch 0 taken 79759 times.
✓ Branch 1 taken 56459 times.
✓ Branch 2 taken 79684 times.
✓ Branch 3 taken 75 times.
136218 (unsigned)(c - '0') < 10 ||
1837
8/8
✓ Branch 0 taken 136218 times.
✓ Branch 1 taken 322453 times.
✓ Branch 2 taken 53099 times.
✓ Branch 3 taken 26585 times.
✓ Branch 4 taken 53003 times.
✓ Branch 5 taken 96 times.
✓ Branch 6 taken 80 times.
✓ Branch 7 taken 52923 times.
594889 c == '-' || c == '_' || c == '/' || c == '.';
1838 }
1839
1840 /**
1841 * Read a key from a string.
1842 *
1843 * The key consists of is_key_char characters and must be terminated by a
1844 * character from the delim string; spaces are ignored.
1845 *
1846 * @return 0 for success (even with ellipsis), <0 for failure
1847 */
1848 52923 static int get_key(const char **ropts, const char *delim, char **rkey)
1849 {
1850 52923 const char *opts = *ropts;
1851 const char *key_start, *key_end;
1852
1853 52923 key_start = opts += strspn(opts, WHITESPACES);
1854
2/2
✓ Branch 1 taken 405748 times.
✓ Branch 2 taken 52923 times.
458671 while (is_key_char(*opts))
1855 405748 opts++;
1856 52923 key_end = opts;
1857 52923 opts += strspn(opts, WHITESPACES);
1858
4/4
✓ Branch 0 taken 39052 times.
✓ Branch 1 taken 13871 times.
✓ Branch 2 taken 7448 times.
✓ Branch 3 taken 31604 times.
52923 if (!*opts || !strchr(delim, *opts))
1859 21319 return AVERROR(EINVAL);
1860 31604 opts++;
1861
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 31604 times.
31604 if (!(*rkey = av_malloc(key_end - key_start + 1)))
1862 return AVERROR(ENOMEM);
1863 31604 memcpy(*rkey, key_start, key_end - key_start);
1864 31604 (*rkey)[key_end - key_start] = 0;
1865 31604 *ropts = opts;
1866 31604 return 0;
1867 }
1868
1869 52923 int av_opt_get_key_value(const char **ropts,
1870 const char *key_val_sep, const char *pairs_sep,
1871 unsigned flags,
1872 char **rkey, char **rval)
1873 {
1874 int ret;
1875 52923 char *key = NULL, *val;
1876 52923 const char *opts = *ropts;
1877
1878
2/2
✓ Branch 1 taken 21319 times.
✓ Branch 2 taken 31604 times.
52923 if ((ret = get_key(&opts, key_val_sep, &key)) < 0 &&
1879
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 21318 times.
21319 !(flags & AV_OPT_FLAG_IMPLICIT_KEY))
1880 1 return AVERROR(EINVAL);
1881
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 52922 times.
52922 if (!(val = av_get_token(&opts, pairs_sep))) {
1882 av_free(key);
1883 return AVERROR(ENOMEM);
1884 }
1885 52922 *ropts = opts;
1886 52922 *rkey = key;
1887 52922 *rval = val;
1888 52922 return 0;
1889 }
1890
1891 41 int av_opt_set_from_string(void *ctx, const char *opts,
1892 const char *const *shorthand,
1893 const char *key_val_sep, const char *pairs_sep)
1894 {
1895 41 int ret, count = 0;
1896 41 const char *dummy_shorthand = NULL;
1897 const char *key;
1898
1899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (!opts)
1900 return 0;
1901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (!shorthand)
1902 shorthand = &dummy_shorthand;
1903
1904
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 37 times.
97 while (*opts) {
1905 char *parsed_key, *value;
1906 60 ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
1907 60 *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
1908 &parsed_key, &value);
1909
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 59 times.
60 if (ret < 0) {
1910
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ret == AVERROR(EINVAL))
1911 1 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
1912 else
1913 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
1914 av_err2str(ret));
1915 4 return ret;
1916 }
1917
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 38 times.
59 if (*opts)
1918 21 opts++;
1919
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 14 times.
59 if (parsed_key) {
1920 45 key = parsed_key;
1921
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 45 times.
77 while (*shorthand) /* discard all remaining shorthand */
1922 32 shorthand++;
1923 } else {
1924 14 key = *(shorthand++);
1925 }
1926
1927 59 av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
1928
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 56 times.
59 if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
1929
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (ret == AVERROR_OPTION_NOT_FOUND)
1930 2 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
1931 3 av_free(value);
1932 3 av_free(parsed_key);
1933 3 return ret;
1934 }
1935
1936 56 av_free(value);
1937 56 av_free(parsed_key);
1938 56 count++;
1939 }
1940 37 return count;
1941 }
1942
1943 691750 void av_opt_free(void *obj)
1944 {
1945 691750 const AVOption *o = NULL;
1946
2/2
✓ Branch 1 taken 27904939 times.
✓ Branch 2 taken 691750 times.
28596689 while ((o = av_opt_next(obj, o))) {
1947 27904939 void *pitem = (uint8_t *)obj + o->offset;
1948
1949
2/2
✓ Branch 0 taken 112248 times.
✓ Branch 1 taken 27792691 times.
27904939 if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
1950 112248 opt_free_array(o, pitem, opt_array_pcount(pitem));
1951 else
1952 27792691 opt_free_elem(o->type, pitem);
1953 }
1954 691750 }
1955
1956 288062 int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags)
1957 {
1958 288062 const AVDictionaryEntry *t = NULL;
1959 288062 AVDictionary *tmp = NULL;
1960 int ret;
1961
1962
2/2
✓ Branch 0 taken 71792 times.
✓ Branch 1 taken 216270 times.
288062 if (!options)
1963 71792 return 0;
1964
1965
2/2
✓ Branch 1 taken 173734 times.
✓ Branch 2 taken 216270 times.
390004 while ((t = av_dict_iterate(*options, t))) {
1966 173734 ret = av_opt_set(obj, t->key, t->value, search_flags);
1967
2/2
✓ Branch 0 taken 49395 times.
✓ Branch 1 taken 124339 times.
173734 if (ret == AVERROR_OPTION_NOT_FOUND)
1968 49395 ret = av_dict_set(&tmp, t->key, t->value, AV_DICT_MULTIKEY);
1969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 173734 times.
173734 if (ret < 0) {
1970 av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
1971 av_dict_free(&tmp);
1972 return ret;
1973 }
1974 }
1975 216270 av_dict_free(options);
1976 216270 *options = tmp;
1977 216270 return 0;
1978 }
1979
1980 166422 int av_opt_set_dict(void *obj, AVDictionary **options)
1981 {
1982 166422 return av_opt_set_dict2(obj, options, 0);
1983 }
1984
1985 584657 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
1986 int opt_flags, int search_flags)
1987 {
1988 584657 return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
1989 }
1990
1991 49277685 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
1992 int opt_flags, int search_flags, void **target_obj)
1993 {
1994 const AVClass *c;
1995 49277685 const AVOption *o = NULL;
1996
1997
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49277685 times.
49277685 if(!obj)
1998 return NULL;
1999
2000 49277685 c= *(AVClass**)obj;
2001
2002
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49277685 times.
49277685 if (!c)
2003 return NULL;
2004
2005
2/2
✓ Branch 0 taken 48844976 times.
✓ Branch 1 taken 432709 times.
49277685 if (search_flags & AV_OPT_SEARCH_CHILDREN) {
2006
2/2
✓ Branch 0 taken 48493913 times.
✓ Branch 1 taken 351063 times.
48844976 if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
2007 48493913 void *iter = NULL;
2008 const AVClass *child;
2009
2/2
✓ Branch 1 taken 48186732 times.
✓ Branch 2 taken 48493283 times.
96680015 while (child = av_opt_child_class_iterate(c, &iter))
2010
2/2
✓ Branch 1 taken 630 times.
✓ Branch 2 taken 48186102 times.
48186732 if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
2011 630 return o;
2012 } else {
2013 351063 void *child = NULL;
2014
2/2
✓ Branch 1 taken 174813 times.
✓ Branch 2 taken 281715 times.
456528 while (child = av_opt_child_next(obj, child))
2015
2/2
✓ Branch 1 taken 69348 times.
✓ Branch 2 taken 105465 times.
174813 if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
2016 69348 return o;
2017 }
2018 }
2019
2020
2/2
✓ Branch 1 taken 506319753 times.
✓ Branch 2 taken 48646687 times.
554966440 while (o = av_opt_next(obj, o)) {
2021
6/6
✓ Branch 0 taken 658859 times.
✓ Branch 1 taken 505660894 times.
✓ Branch 2 taken 655609 times.
✓ Branch 3 taken 3250 times.
✓ Branch 4 taken 524142 times.
✓ Branch 5 taken 131467 times.
506319753 if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
2022
4/4
✓ Branch 0 taken 93213 times.
✓ Branch 1 taken 430929 times.
✓ Branch 2 taken 131467 times.
✓ Branch 3 taken 93213 times.
655609 ((!unit && o->type != AV_OPT_TYPE_CONST) ||
2023
4/6
✓ Branch 0 taken 131467 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 131467 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 130091 times.
✓ Branch 5 taken 1376 times.
131467 (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
2024
2/2
✓ Branch 0 taken 254131 times.
✓ Branch 1 taken 306889 times.
561020 if (target_obj) {
2025
1/2
✓ Branch 0 taken 254131 times.
✗ Branch 1 not taken.
254131 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
2026 254131 *target_obj = obj;
2027 else
2028 *target_obj = NULL;
2029 }
2030 561020 return o;
2031 }
2032 }
2033 48646687 return NULL;
2034 }
2035
2036 456565 void *av_opt_child_next(void *obj, void *prev)
2037 {
2038 456565 const AVClass *c = *(AVClass **)obj;
2039
2/2
✓ Branch 0 taken 332453 times.
✓ Branch 1 taken 124112 times.
456565 if (c->child_next)
2040 332453 return c->child_next(obj, prev);
2041 124112 return NULL;
2042 }
2043
2044 96680015 const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter)
2045 {
2046
2/2
✓ Branch 0 taken 48666398 times.
✓ Branch 1 taken 48013617 times.
96680015 if (parent->child_class_iterate)
2047 48666398 return parent->child_class_iterate(iter);
2048 48013617 return NULL;
2049 }
2050
2051 #if FF_API_OPT_PTR
2052 void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
2053 {
2054 const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
2055
2056 // no direct access to array-type options
2057 if (!opt || (opt->type & AV_OPT_TYPE_FLAG_ARRAY))
2058 return NULL;
2059 return (uint8_t*)obj + opt->offset;
2060 }
2061 #endif
2062
2063 6254425 static int opt_copy_elem(void *logctx, enum AVOptionType type,
2064 void *dst, const void *src)
2065 {
2066
2/2
✓ Branch 0 taken 41163 times.
✓ Branch 1 taken 6213262 times.
6254425 if (type == AV_OPT_TYPE_STRING) {
2067 41163 const char *src_str = *(const char *const *)src;
2068 41163 char **dstp = (char **)dst;
2069
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 41157 times.
41163 if (*dstp != src_str)
2070 6 av_freep(dstp);
2071
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 41157 times.
41163 if (src_str) {
2072 6 *dstp = av_strdup(src_str);
2073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!*dstp)
2074 return AVERROR(ENOMEM);
2075 }
2076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6213262 times.
6213262 } else if (type == AV_OPT_TYPE_BINARY) {
2077 const uint8_t *const *src8 = (const uint8_t *const *)src;
2078 uint8_t **dst8 = (uint8_t **)dst;
2079 int len = *(const int *)(src8 + 1);
2080 if (*dst8 != *src8)
2081 av_freep(dst8);
2082 *dst8 = av_memdup(*src8, len);
2083 if (len && !*dst8) {
2084 *(int *)(dst8 + 1) = 0;
2085 return AVERROR(ENOMEM);
2086 }
2087 *(int *)(dst8 + 1) = len;
2088
2/2
✓ Branch 0 taken 1921144 times.
✓ Branch 1 taken 4292118 times.
6213262 } else if (type == AV_OPT_TYPE_CONST) {
2089 // do nothing
2090
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1921142 times.
1921144 } else if (type == AV_OPT_TYPE_DICT) {
2091 2 const AVDictionary *sdict = *(const AVDictionary * const *)src;
2092 2 AVDictionary **ddictp = (AVDictionary **)dst;
2093
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (sdict != *ddictp)
2094 2 av_dict_free(ddictp);
2095 2 *ddictp = NULL;
2096 2 return av_dict_copy(ddictp, sdict, 0);
2097
2/2
✓ Branch 0 taken 13444 times.
✓ Branch 1 taken 1907698 times.
1921142 } else if (type == AV_OPT_TYPE_CHLAYOUT) {
2098
1/2
✓ Branch 0 taken 13444 times.
✗ Branch 1 not taken.
13444 if (dst != src)
2099 13444 return av_channel_layout_copy(dst, src);
2100
1/2
✓ Branch 1 taken 1907698 times.
✗ Branch 2 not taken.
1907698 } else if (opt_is_pod(type)) {
2101 1907698 size_t size = opt_type_desc[type].size;
2102 1907698 memcpy(dst, src, size);
2103 } else {
2104 av_log(logctx, AV_LOG_ERROR, "Unhandled option type: %d\n", type);
2105 return AVERROR(EINVAL);
2106 }
2107
2108 6240979 return 0;
2109 }
2110
2111 13450 static int opt_copy_array(void *logctx, const AVOption *o,
2112 void **pdst, const void * const *psrc)
2113 {
2114 13450 unsigned nb_elems = *opt_array_pcount(psrc);
2115 13450 void *dst = NULL;
2116 int ret;
2117
2118
1/2
✓ Branch 0 taken 13450 times.
✗ Branch 1 not taken.
13450 if (*pdst == *psrc) {
2119 13450 *pdst = NULL;
2120 13450 *opt_array_pcount(pdst) = 0;
2121 }
2122
2123 13450 opt_free_array(o, pdst, opt_array_pcount(pdst));
2124
2125 13450 dst = av_calloc(nb_elems, opt_type_desc[TYPE_BASE(o->type)].size);
2126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13450 times.
13450 if (!dst)
2127 return AVERROR(ENOMEM);
2128
2129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13450 times.
13450 for (unsigned i = 0; i < nb_elems; i++) {
2130 ret = opt_copy_elem(logctx, TYPE_BASE(o->type),
2131 opt_array_pelem(o, dst, i),
2132 opt_array_pelem(o, *(void**)psrc, i));
2133 if (ret < 0) {
2134 opt_free_array(o, &dst, &nb_elems);
2135 return ret;
2136 }
2137 }
2138
2139 13450 *pdst = dst;
2140 13450 *opt_array_pcount(pdst) = nb_elems;
2141
2142 13450 return 0;
2143 }
2144
2145 37179 int av_opt_copy(void *dst, const void *src)
2146 {
2147 37179 const AVOption *o = NULL;
2148 const AVClass *c;
2149 37179 int ret = 0;
2150
2151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37179 times.
37179 if (!src)
2152 return AVERROR(EINVAL);
2153
2154 37179 c = *(AVClass **)src;
2155
2/4
✓ Branch 0 taken 37179 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 37179 times.
37179 if (!c || c != *(AVClass **)dst)
2156 return AVERROR(EINVAL);
2157
2158
2/2
✓ Branch 1 taken 6267696 times.
✓ Branch 2 taken 37179 times.
6304875 while ((o = av_opt_next(src, o))) {
2159 6267696 void *field_dst = (uint8_t *)dst + o->offset;
2160 6267696 void *field_src = (uint8_t *)src + o->offset;
2161
2162 12535392 int err = (o->type & AV_OPT_TYPE_FLAG_ARRAY) ?
2163
2/2
✓ Branch 0 taken 13450 times.
✓ Branch 1 taken 6254246 times.
6267696 opt_copy_array(dst, o, field_dst, field_src) :
2164 6254246 opt_copy_elem (dst, o->type, field_dst, field_src);
2165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6267696 times.
6267696 if (err < 0)
2166 ret = err;
2167 }
2168 37179 return ret;
2169 }
2170
2171 20 int av_opt_get_array_size(void *obj, const char *name, int search_flags,
2172 unsigned int *out_val)
2173 {
2174 void *target_obj, *parray;
2175 const AVOption *o;
2176
2177 20 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
2178
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
20 if (!o || !target_obj)
2179 return AVERROR_OPTION_NOT_FOUND;
2180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (!(o->type & AV_OPT_TYPE_FLAG_ARRAY))
2181 return AVERROR(EINVAL);
2182
2183 20 parray = (uint8_t *)target_obj + o->offset;
2184 20 *out_val = *opt_array_pcount(parray);
2185
2186 20 return 0;
2187 }
2188
2189 14 int av_opt_get_array(void *obj, const char *name, int search_flags,
2190 unsigned int start_elem, unsigned int nb_elems,
2191 enum AVOptionType out_type, void *out_val)
2192 {
2193 14 const size_t elem_size_out = opt_type_desc[TYPE_BASE(out_type)].size;
2194
2195 const AVOption *o;
2196 void *target_obj;
2197
2198 const void *parray;
2199 unsigned array_size;
2200
2201 int ret;
2202
2203 14 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
2204
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if (!o || !target_obj)
2205 return AVERROR_OPTION_NOT_FOUND;
2206
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (!(o->type & AV_OPT_TYPE_FLAG_ARRAY) ||
2207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 (out_type & AV_OPT_TYPE_FLAG_ARRAY))
2208 return AVERROR(EINVAL);
2209
2210 14 parray = (uint8_t *)target_obj + o->offset;
2211 14 array_size = *opt_array_pcount(parray);
2212
2213
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (start_elem >= array_size ||
2214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 array_size - start_elem < nb_elems)
2215 return AVERROR(EINVAL);
2216
2217
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 14 times.
46 for (unsigned i = 0; i < nb_elems; i++) {
2218 32 const void *src = opt_array_pelem(o, *(void**)parray, start_elem + i);
2219 32 void *dst = (uint8_t*)out_val + i * elem_size_out;
2220
2221
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 7 times.
32 if (out_type == TYPE_BASE(o->type)) {
2222 25 ret = opt_copy_elem(obj, out_type, dst, src);
2223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (ret < 0)
2224 goto fail;
2225
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 } else if (out_type == AV_OPT_TYPE_STRING) {
2226 5 uint8_t buf[128], *out = buf;
2227
2228 5 ret = opt_get_elem(o, &out, sizeof(buf), src, search_flags);
2229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (ret < 0)
2230 goto fail;
2231
2232
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (out == buf) {
2233 5 out = av_strdup(buf);
2234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!out) {
2235 ret = AVERROR(ENOMEM);
2236 goto fail;
2237 }
2238 }
2239
2240 5 *(uint8_t**)dst = out;
2241
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 } else if (out_type == AV_OPT_TYPE_INT64 ||
2242 out_type == AV_OPT_TYPE_DOUBLE ||
2243 2 out_type == AV_OPT_TYPE_RATIONAL) {
2244 2 double num = 1.0;
2245 2 int den = 1;
2246 2 int64_t intnum = 1;
2247
2248 2 ret = read_number(o, src, &num, &den, &intnum);
2249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
2250 goto fail;
2251
2252
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 switch (out_type) {
2253 case AV_OPT_TYPE_INT64:
2254 *(int64_t*)dst = (num == den) ? intnum : num * intnum / den;
2255 2 break;
2256 2 case AV_OPT_TYPE_DOUBLE:
2257 2 *(double*)dst = num * intnum / den;
2258 2 break;
2259 case AV_OPT_TYPE_RATIONAL:
2260 *(AVRational*)dst = (num == 1.0 && (int)intnum == intnum) ?
2261 (AVRational){ intnum, den } :
2262 double_to_rational(num * intnum / den);
2263 break;
2264 default: av_assert0(0);
2265 }
2266 } else
2267 return AVERROR(ENOSYS);
2268 }
2269
2270 14 return 0;
2271 fail:
2272 for (unsigned i = 0; i < nb_elems; i++)
2273 opt_free_elem(out_type, (uint8_t*)out_val + i * elem_size_out);
2274 return ret;
2275 }
2276
2277 38 int av_opt_set_array(void *obj, const char *name, int search_flags,
2278 unsigned int start_elem, unsigned int nb_elems,
2279 enum AVOptionType val_type, const void *val)
2280 {
2281 38 const size_t elem_size_val = opt_type_desc[TYPE_BASE(val_type)].size;
2282
2283 const AVOption *o;
2284 const AVOptionArrayDef *arr;
2285 void *target_obj;
2286
2287 void *parray;
2288 void *new_elems;
2289 unsigned *array_size, new_size;
2290 size_t elem_size;
2291
2292 38 int ret = 0;
2293
2294 38 ret = opt_set_init(obj, name, search_flags, 0, &target_obj, &o, &parray);
2295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (ret < 0)
2296 return ret;
2297
2298
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 if (!(o->type & AV_OPT_TYPE_FLAG_ARRAY) ||
2299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 (val_type & AV_OPT_TYPE_FLAG_ARRAY))
2300 return AVERROR(EINVAL);
2301
2302 38 arr = o->default_val.arr;
2303 38 array_size = opt_array_pcount(parray);
2304 38 elem_size = opt_type_desc[TYPE_BASE(o->type)].size;
2305
2306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (start_elem > *array_size)
2307 return AVERROR(EINVAL);
2308
2309 // compute new array size
2310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!val) {
2311 if (*array_size - start_elem < nb_elems)
2312 return AVERROR(EINVAL);
2313
2314 new_size = *array_size - nb_elems;
2315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 } else if (search_flags & AV_OPT_ARRAY_REPLACE) {
2316 if (start_elem >= UINT_MAX - nb_elems)
2317 return AVERROR(EINVAL);
2318
2319 new_size = FFMAX(*array_size, start_elem + nb_elems);
2320 } else {
2321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (nb_elems >= UINT_MAX - *array_size)
2322 return AVERROR(EINVAL);
2323
2324 38 new_size = *array_size + nb_elems;
2325 }
2326
2327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (arr &&
2328 ((arr->size_max && new_size > arr->size_max) ||
2329 (arr->size_min && new_size < arr->size_min)))
2330 return AVERROR(EINVAL);
2331
2332 // desired operation is shrinking the array
2333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!val) {
2334 void *array = *(void**)parray;
2335
2336 for (unsigned i = 0; i < nb_elems; i++) {
2337 opt_free_elem(o->type,
2338 opt_array_pelem(o, array, start_elem + i));
2339 }
2340
2341 if (new_size > 0) {
2342 memmove(opt_array_pelem(o, array, start_elem),
2343 opt_array_pelem(o, array, start_elem + nb_elems),
2344 elem_size * (*array_size - start_elem - nb_elems));
2345
2346 array = av_realloc_array(array, new_size, elem_size);
2347 if (!array)
2348 return AVERROR(ENOMEM);
2349
2350 *(void**)parray = array;
2351 } else
2352 av_freep(parray);
2353
2354 *array_size = new_size;
2355
2356 return 0;
2357 }
2358
2359 // otherwise, desired operation is insert/replace;
2360 // first, store new elements in a separate array to simplify
2361 // rollback on failure
2362 38 new_elems = av_calloc(nb_elems, elem_size);
2363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!new_elems)
2364 return AVERROR(ENOMEM);
2365
2366 // convert/validate each new element
2367
2/2
✓ Branch 0 taken 154 times.
✓ Branch 1 taken 38 times.
192 for (unsigned i = 0; i < nb_elems; i++) {
2368 154 void *dst = opt_array_pelem(o, new_elems, i);
2369 154 const void *src = (uint8_t*)val + i * elem_size_val;
2370
2371 154 double num = 1.0;
2372 154 int den = 1;
2373 154 int64_t intnum = 1;
2374
2375
1/2
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
154 if (val_type == TYPE_BASE(o->type)) {
2376 int err;
2377
2378 154 ret = opt_copy_elem(obj, val_type, dst, src);
2379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 154 times.
154 if (ret < 0)
2380 goto fail;
2381
2382 // validate the range for numeric options
2383 154 err = read_number(o, dst, &num, &den, &intnum);
2384
2/4
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 154 times.
✗ Branch 3 not taken.
154 if (err >= 0 && TYPE_BASE(o->type) != AV_OPT_TYPE_FLAGS &&
2385
3/6
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 154 times.
154 (!den || o->max * den < num * intnum || o->min * den > num * intnum)) {
2386 num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN);
2387 av_log(obj, AV_LOG_ERROR, "Cannot set array element %u for "
2388 "parameter '%s': value %f out of range [%g - %g]\n",
2389 start_elem + i, o->name, num, o->min, o->max);
2390 ret = AVERROR(ERANGE);
2391 goto fail;
2392 }
2393 } else if (val_type == AV_OPT_TYPE_STRING) {
2394 ret = opt_set_elem(obj, target_obj, o, *(const char **)src, dst);
2395 if (ret < 0)
2396 goto fail;
2397 } else if (val_type == AV_OPT_TYPE_INT ||
2398 val_type == AV_OPT_TYPE_INT64 ||
2399 val_type == AV_OPT_TYPE_FLOAT ||
2400 val_type == AV_OPT_TYPE_DOUBLE ||
2401 val_type == AV_OPT_TYPE_RATIONAL) {
2402
2403 switch (val_type) {
2404 case AV_OPT_TYPE_INT: intnum = *(int*)src; break;
2405 case AV_OPT_TYPE_INT64: intnum = *(int64_t*)src; break;
2406 case AV_OPT_TYPE_FLOAT: num = *(float*)src; break;
2407 case AV_OPT_TYPE_DOUBLE: num = *(double*)src; break;
2408 case AV_OPT_TYPE_RATIONAL: intnum = ((AVRational*)src)->num;
2409 den = ((AVRational*)src)->den; break;
2410 default: av_assert0(0);
2411 }
2412
2413 ret = write_number(obj, o, dst, num, den, intnum);
2414 if (ret < 0)
2415 goto fail;
2416 } else {
2417 ret = AVERROR(ENOSYS);
2418 goto fail;
2419 }
2420 }
2421
2422 // commit new elements to the array
2423
2/4
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
38 if (start_elem == 0 && nb_elems == new_size) {
2424 // replacing the existing array entirely
2425 38 opt_free_array(o, parray, array_size);
2426 38 *(void**)parray = new_elems;
2427 38 *array_size = nb_elems;
2428
2429 38 new_elems = NULL;
2430 38 nb_elems = 0;
2431 } else {
2432 void *array = av_realloc_array(*(void**)parray, new_size, elem_size);
2433 if (!array) {
2434 ret = AVERROR(ENOMEM);
2435 goto fail;
2436 }
2437
2438 if (search_flags & AV_OPT_ARRAY_REPLACE) {
2439 // free the elements being overwritten
2440 for (unsigned i = start_elem; i < FFMIN(start_elem + nb_elems, *array_size); i++)
2441 opt_free_elem(o->type, opt_array_pelem(o, array, i));
2442 } else {
2443 // shift existing elements to the end
2444 memmove(opt_array_pelem(o, array, start_elem + nb_elems),
2445 opt_array_pelem(o, array, start_elem),
2446 elem_size * (*array_size - start_elem));
2447 }
2448
2449 memcpy((uint8_t*)array + elem_size * start_elem, new_elems, elem_size * nb_elems);
2450
2451 av_freep(&new_elems);
2452 nb_elems = 0;
2453
2454 *(void**)parray = array;
2455 *array_size = new_size;
2456 }
2457
2458 38 fail:
2459 38 opt_free_array(o, &new_elems, &nb_elems);
2460
2461 38 return ret;
2462 }
2463
2464 31 int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
2465 {
2466 int ret;
2467 31 const AVClass *c = *(AVClass**)obj;
2468 31 int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = c->query_ranges;
2469
2470
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (!callback)
2471 31 callback = av_opt_query_ranges_default;
2472
2473 31 ret = callback(ranges_arg, obj, key, flags);
2474
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 13 times.
31 if (ret >= 0) {
2475
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE))
2476 18 ret = 1;
2477 18 (*ranges_arg)->nb_components = ret;
2478 }
2479 31 return ret;
2480 }
2481
2482 31 int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
2483 {
2484 31 AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
2485 31 AVOptionRange **range_array = av_mallocz(sizeof(void*));
2486 31 AVOptionRange *range = av_mallocz(sizeof(*range));
2487 31 const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
2488 int ret;
2489
2490 31 *ranges_arg = NULL;
2491
2492
5/8
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 31 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 28 times.
31 if (!ranges || !range || !range_array || !field) {
2493 3 ret = AVERROR(ENOMEM);
2494 3 goto fail;
2495 }
2496
2497 28 ranges->range = range_array;
2498 28 ranges->range[0] = range;
2499 28 ranges->nb_ranges = 1;
2500 28 ranges->nb_components = 1;
2501 28 range->is_range = 1;
2502 28 range->value_min = field->min;
2503 28 range->value_max = field->max;
2504
2505
6/6
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 10 times.
28 switch (field->type) {
2506 13 case AV_OPT_TYPE_BOOL:
2507 case AV_OPT_TYPE_INT:
2508 case AV_OPT_TYPE_UINT:
2509 case AV_OPT_TYPE_INT64:
2510 case AV_OPT_TYPE_UINT64:
2511 case AV_OPT_TYPE_PIXEL_FMT:
2512 case AV_OPT_TYPE_SAMPLE_FMT:
2513 case AV_OPT_TYPE_FLOAT:
2514 case AV_OPT_TYPE_DOUBLE:
2515 case AV_OPT_TYPE_DURATION:
2516 case AV_OPT_TYPE_COLOR:
2517 13 break;
2518 2 case AV_OPT_TYPE_STRING:
2519 2 range->component_min = 0;
2520 2 range->component_max = 0x10FFFF; // max unicode value
2521 2 range->value_min = -1;
2522 2 range->value_max = INT_MAX;
2523 2 break;
2524 1 case AV_OPT_TYPE_RATIONAL:
2525 1 range->component_min = INT_MIN;
2526 1 range->component_max = INT_MAX;
2527 1 break;
2528 1 case AV_OPT_TYPE_IMAGE_SIZE:
2529 1 range->component_min = 0;
2530 1 range->component_max = INT_MAX/128/8;
2531 1 range->value_min = 0;
2532 1 range->value_max = INT_MAX/8;
2533 1 break;
2534 1 case AV_OPT_TYPE_VIDEO_RATE:
2535 1 range->component_min = 1;
2536 1 range->component_max = INT_MAX;
2537 1 range->value_min = 1;
2538 1 range->value_max = INT_MAX;
2539 1 break;
2540 10 default:
2541 10 ret = AVERROR(ENOSYS);
2542 10 goto fail;
2543 }
2544
2545 18 *ranges_arg = ranges;
2546 18 return 1;
2547 13 fail:
2548 13 av_free(ranges);
2549 13 av_free(range);
2550 13 av_free(range_array);
2551 13 return ret;
2552 }
2553
2554 18 void av_opt_freep_ranges(AVOptionRanges **rangesp)
2555 {
2556 int i;
2557 18 AVOptionRanges *ranges = *rangesp;
2558
2559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (!ranges)
2560 return;
2561
2562
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
36 for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) {
2563 18 AVOptionRange *range = ranges->range[i];
2564
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (range) {
2565 18 av_freep(&range->str);
2566 18 av_freep(&ranges->range[i]);
2567 }
2568 }
2569 18 av_freep(&ranges->range);
2570 18 av_freep(rangesp);
2571 }
2572
2573 174 int av_opt_is_set_to_default(void *obj, const AVOption *o)
2574 {
2575 int64_t i64;
2576 double d;
2577 AVRational q;
2578 int ret, w, h;
2579 char *str;
2580 void *dst;
2581
2582
2/4
✓ Branch 0 taken 174 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 174 times.
174 if (!o || !obj)
2583 return AVERROR(EINVAL);
2584
2585 174 dst = ((uint8_t*)obj) + o->offset;
2586
2587
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 162 times.
174 if (o->type & AV_OPT_TYPE_FLAG_ARRAY) {
2588
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 const char *def = o->default_val.arr ? o->default_val.arr->def : NULL;
2589 uint8_t *val;
2590
2591 12 ret = opt_get_array(o, dst, &val);
2592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (ret < 0)
2593 return ret;
2594
2595
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
12 if (!!val != !!def)
2596 3 ret = 0;
2597
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
9 else if (val)
2598 4 ret = !strcmp(val, def);
2599 else
2600 5 ret = 1;
2601
2602 12 av_freep(&val);
2603
2604 12 return ret;
2605 }
2606
2607
11/13
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 25 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
162 switch (o->type) {
2608 case AV_OPT_TYPE_CONST:
2609 162 return 1;
2610 88 case AV_OPT_TYPE_BOOL:
2611 case AV_OPT_TYPE_FLAGS:
2612 case AV_OPT_TYPE_PIXEL_FMT:
2613 case AV_OPT_TYPE_SAMPLE_FMT:
2614 case AV_OPT_TYPE_INT:
2615 case AV_OPT_TYPE_UINT:
2616 case AV_OPT_TYPE_DURATION:
2617 case AV_OPT_TYPE_INT64:
2618 case AV_OPT_TYPE_UINT64:
2619 88 read_number(o, dst, NULL, NULL, &i64);
2620 88 return o->default_val.i64 == i64;
2621 9 case AV_OPT_TYPE_CHLAYOUT: {
2622 9 AVChannelLayout ch_layout = { 0 };
2623
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
9 if (o->default_val.str) {
2624
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if ((ret = av_channel_layout_from_string(&ch_layout, o->default_val.str)) < 0)
2625 return ret;
2626 }
2627 9 ret = !av_channel_layout_compare((AVChannelLayout *)dst, &ch_layout);
2628 9 av_channel_layout_uninit(&ch_layout);
2629 9 return ret;
2630 }
2631 6 case AV_OPT_TYPE_STRING:
2632 6 str = *(char **)dst;
2633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (str == o->default_val.str) //2 NULLs
2634 return 1;
2635
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
6 if (!str || !o->default_val.str) //1 NULL
2636 2 return 0;
2637 4 return !strcmp(str, o->default_val.str);
2638 3 case AV_OPT_TYPE_DOUBLE:
2639 3 d = *(double *)dst;
2640 3 return o->default_val.dbl == d;
2641 3 case AV_OPT_TYPE_FLOAT:
2642 3 d = *(float *)dst;
2643 3 return (float)o->default_val.dbl == d;
2644 25 case AV_OPT_TYPE_RATIONAL:
2645 25 q = av_d2q(o->default_val.dbl, INT_MAX);
2646 25 return !av_cmp_q(*(AVRational*)dst, q);
2647 9 case AV_OPT_TYPE_BINARY: {
2648 struct {
2649 uint8_t *data;
2650 int size;
2651 9 } tmp = {0};
2652 9 int opt_size = *(int *)((void **)dst + 1);
2653 9 void *opt_ptr = *(void **)dst;
2654
6/6
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
9 if (!opt_size && (!o->default_val.str || !strlen(o->default_val.str)))
2655 6 return 1;
2656
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
3 if (!opt_size || !o->default_val.str || !strlen(o->default_val.str ))
2657 1 return 0;
2658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (opt_size != strlen(o->default_val.str) / 2)
2659 return 0;
2660 2 ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data);
2661
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!ret)
2662 2 ret = !memcmp(opt_ptr, tmp.data, tmp.size);
2663 2 av_free(tmp.data);
2664 2 return ret;
2665 }
2666 10 case AV_OPT_TYPE_DICT: {
2667 10 AVDictionary *dict1 = NULL;
2668 10 AVDictionary *dict2 = *(AVDictionary **)dst;
2669 10 const AVDictionaryEntry *en1 = NULL;
2670 10 const AVDictionaryEntry *en2 = NULL;
2671 10 ret = av_dict_parse_string(&dict1, o->default_val.str, "=", ":", 0);
2672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (ret < 0) {
2673 av_dict_free(&dict1);
2674 return ret;
2675 }
2676 do {
2677 12 en1 = av_dict_iterate(dict1, en1);
2678 12 en2 = av_dict_iterate(dict2, en2);
2679
6/8
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
12 } while (en1 && en2 && !strcmp(en1->key, en2->key) && !strcmp(en1->value, en2->value));
2680 10 av_dict_free(&dict1);
2681
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
10 return (!en1 && !en2);
2682 }
2683 3 case AV_OPT_TYPE_IMAGE_SIZE:
2684
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if (!o->default_val.str || !strcmp(o->default_val.str, "none"))
2685 w = h = 0;
2686
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0)
2687 return ret;
2688
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
3 return (w == *(int *)dst) && (h == *((int *)dst+1));
2689 3 case AV_OPT_TYPE_VIDEO_RATE:
2690 3 q = (AVRational){0, 0};
2691
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (o->default_val.str) {
2692
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if ((ret = av_parse_video_rate(&q, o->default_val.str)) < 0)
2693 return ret;
2694 }
2695 3 return !av_cmp_q(*(AVRational*)dst, q);
2696 3 case AV_OPT_TYPE_COLOR: {
2697 3 uint8_t color[4] = {0, 0, 0, 0};
2698
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (o->default_val.str) {
2699
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if ((ret = av_parse_color(color, o->default_val.str, -1, NULL)) < 0)
2700 return ret;
2701 }
2702 3 return !memcmp(color, dst, sizeof(color));
2703 }
2704 default:
2705 av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name);
2706 break;
2707 }
2708 return AVERROR_PATCHWELCOME;
2709 }
2710
2711 62 int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags)
2712 {
2713 const AVOption *o;
2714 void *target;
2715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (!obj)
2716 return AVERROR(EINVAL);
2717 62 o = av_opt_find2(obj, name, NULL, 0, search_flags, &target);
2718
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 56 times.
62 if (!o)
2719 6 return AVERROR_OPTION_NOT_FOUND;
2720 56 return av_opt_is_set_to_default(target, o);
2721 }
2722
2723 30 static int opt_serialize(void *obj, int opt_flags, int flags, int *cnt,
2724 AVBPrint *bprint, const char key_val_sep, const char pairs_sep)
2725 {
2726 30 const AVOption *o = NULL;
2727 30 void *child = NULL;
2728 uint8_t *buf;
2729 int ret;
2730 30 const char special_chars[] = {pairs_sep, key_val_sep, '\0'};
2731
2732
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 2 times.
30 if (flags & AV_OPT_SERIALIZE_SEARCH_CHILDREN)
2733
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 28 times.
37 while (child = av_opt_child_next(obj, child)) {
2734 9 ret = opt_serialize(child, opt_flags, flags, cnt, bprint,
2735 key_val_sep, pairs_sep);
2736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ret < 0)
2737 return ret;
2738 }
2739
2740
2/2
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 30 times.
330 while (o = av_opt_next(obj, o)) {
2741
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 174 times.
300 if (o->type == AV_OPT_TYPE_CONST)
2742 126 continue;
2743
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 174 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
174 if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags)
2744 continue;
2745
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 174 times.
174 else if (((o->flags & opt_flags) != opt_flags))
2746 continue;
2747
4/4
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 56 times.
✓ Branch 3 taken 73 times.
✓ Branch 4 taken 45 times.
174 if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0)
2748 73 continue;
2749
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
101 if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) {
2750 av_bprint_finalize(bprint, NULL);
2751 return ret;
2752 }
2753
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 if (buf) {
2754
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 21 times.
101 if ((*cnt)++)
2755 80 av_bprint_append_data(bprint, &pairs_sep, 1);
2756 101 av_bprint_escape(bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
2757 101 av_bprint_append_data(bprint, &key_val_sep, 1);
2758 101 av_bprint_escape(bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
2759 101 av_freep(&buf);
2760 }
2761 }
2762
2763 30 return 0;
2764 }
2765
2766 21 int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
2767 const char key_val_sep, const char pairs_sep)
2768 {
2769 AVBPrint bprint;
2770 21 int ret, cnt = 0;
2771
2772
4/8
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 21 times.
✗ Branch 7 not taken.
21 if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
2773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 pairs_sep == '\\' || key_val_sep == '\\') {
2774 av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found.");
2775 return AVERROR(EINVAL);
2776 }
2777
2778
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
21 if (!obj || !buffer)
2779 return AVERROR(EINVAL);
2780
2781 21 *buffer = NULL;
2782 21 av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
2783
2784 21 ret = opt_serialize(obj, opt_flags, flags, &cnt, &bprint,
2785 key_val_sep, pairs_sep);
2786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
2787 return ret;
2788
2789 21 ret = av_bprint_finalize(&bprint, buffer);
2790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
2791 return ret;
2792 21 return 0;
2793 }
2794