FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/opt.c
Date: 2026-07-18 19:31:15
Exec Total Coverage
Lines: 1259 1678 75.0%
Functions: 84 101 83.2%
Branches: 821 1306 62.9%

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