FFmpeg coverage


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