FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/options.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 173 244 70.9%
Functions: 16 19 84.2%
Branches: 95 138 68.8%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 #include "avformat.h"
21 #include "avformat_internal.h"
22 #include "avio_internal.h"
23 #include "demux.h"
24 #include "internal.h"
25
26 #include "libavcodec/avcodec.h"
27 #include "libavcodec/codec_par.h"
28
29 #include "libavutil/avassert.h"
30 #include "libavutil/iamf.h"
31 #include "libavutil/internal.h"
32 #include "libavutil/intmath.h"
33 #include "libavutil/mem.h"
34 #include "libavutil/opt.h"
35
36 /**
37 * @file
38 * Options definition for AVFormatContext.
39 */
40
41 FF_DISABLE_DEPRECATION_WARNINGS
42 #include "options_table.h"
43 FF_ENABLE_DEPRECATION_WARNINGS
44
45 2608 static const char* format_to_name(void* ptr)
46 {
47 2608 AVFormatContext* fc = (AVFormatContext*) ptr;
48
2/2
✓ Branch 0 taken 1690 times.
✓ Branch 1 taken 918 times.
2608 if(fc->iformat) return fc->iformat->name;
49
1/2
✓ Branch 0 taken 918 times.
✗ Branch 1 not taken.
918 else if(fc->oformat) return fc->oformat->name;
50 else return fc->av_class->class_name;
51 }
52
53 56050 static void *format_child_next(void *obj, void *prev)
54 {
55 56050 AVFormatContext *s = obj;
56
4/4
✓ Branch 0 taken 22858 times.
✓ Branch 1 taken 33192 times.
✓ Branch 2 taken 22390 times.
✓ Branch 3 taken 468 times.
56050 if (!prev && s->priv_data &&
57
4/4
✓ Branch 0 taken 22388 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2511 times.
✓ Branch 3 taken 19877 times.
22390 ((s->iformat && s->iformat->priv_class) ||
58
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2511 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2513 s->oformat && s->oformat->priv_class))
59 19879 return s->priv_data;
60
6/6
✓ Branch 0 taken 26994 times.
✓ Branch 1 taken 9177 times.
✓ Branch 2 taken 26982 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 13491 times.
✓ Branch 5 taken 13491 times.
36171 if (s->pb && s->pb->av_class && prev != s->pb)
61 13491 return s->pb;
62 22680 return NULL;
63 }
64
65 enum {
66 CHILD_CLASS_ITER_AVIO = 0,
67 CHILD_CLASS_ITER_MUX,
68 CHILD_CLASS_ITER_DEMUX,
69 CHILD_CLASS_ITER_DONE,
70
71 };
72
73 #define ITER_STATE_SHIFT 16
74
75 27139578 static const AVClass *format_child_class_iterate(void **iter)
76 {
77 // we use the low 16 bits of iter as the value to be passed to
78 // av_(de)muxer_iterate()
79 27139578 void *val = (void*)(((uintptr_t)*iter) & ((1 << ITER_STATE_SHIFT) - 1));
80 27139578 unsigned int state = ((uintptr_t)*iter) >> ITER_STATE_SHIFT;
81 27139578 const AVClass *ret = NULL;
82
83
2/2
✓ Branch 0 taken 115118 times.
✓ Branch 1 taken 27024460 times.
27139578 if (state == CHILD_CLASS_ITER_AVIO) {
84 115118 ret = &ff_avio_class;
85 115118 state++;
86 115118 goto finish;
87 }
88
89
2/2
✓ Branch 0 taken 8398057 times.
✓ Branch 1 taken 18626403 times.
27024460 if (state == CHILD_CLASS_ITER_MUX) {
90 const AVOutputFormat *ofmt;
91
92
2/2
✓ Branch 1 taken 21283307 times.
✓ Branch 2 taken 114992 times.
21398299 while ((ofmt = av_muxer_iterate(&val))) {
93 21283307 ret = ofmt->priv_class;
94
2/2
✓ Branch 0 taken 8283065 times.
✓ Branch 1 taken 13000242 times.
21283307 if (ret)
95 8283065 goto finish;
96 }
97
98 114992 val = NULL;
99 114992 state++;
100 }
101
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18741395 times.
18741395 if (state == CHILD_CLASS_ITER_DEMUX) {
103 const AVInputFormat *ifmt;
104
105
2/2
✓ Branch 1 taken 41507633 times.
✓ Branch 2 taken 114962 times.
41622595 while ((ifmt = av_demuxer_iterate(&val))) {
106 41507633 ret = ifmt->priv_class;
107
2/2
✓ Branch 0 taken 18626433 times.
✓ Branch 1 taken 22881200 times.
41507633 if (ret)
108 18626433 goto finish;
109 }
110 114962 val = NULL;
111 114962 state++;
112 }
113
114 finish:
115 // make sure none av_(de)muxer_iterate does not set the high bits of val
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27139578 times.
27139578 av_assert0(!((uintptr_t)val >> ITER_STATE_SHIFT));
117 27139578 *iter = (void*)((uintptr_t)val | (state << ITER_STATE_SHIFT));
118 27139578 return ret;
119 }
120
121 2608 static AVClassCategory get_category(void *ptr)
122 {
123 2608 AVFormatContext* s = ptr;
124
2/2
✓ Branch 0 taken 1690 times.
✓ Branch 1 taken 918 times.
2608 if(s->iformat) return AV_CLASS_CATEGORY_DEMUXER;
125 918 else return AV_CLASS_CATEGORY_MUXER;
126 }
127
128 static const AVClass av_format_context_class = {
129 .class_name = "AVFormatContext",
130 .item_name = format_to_name,
131 .option = avformat_options,
132 .version = LIBAVUTIL_VERSION_INT,
133 .child_next = format_child_next,
134 .child_class_iterate = format_child_class_iterate,
135 .category = AV_CLASS_CATEGORY_MUXER,
136 .get_category = get_category,
137 };
138
139 104999 static int io_open_default(AVFormatContext *s, AVIOContext **pb,
140 const char *url, int flags, AVDictionary **options)
141 {
142 int loglevel;
143
144
2/2
✓ Branch 0 taken 100455 times.
✓ Branch 1 taken 4544 times.
104999 if (!strcmp(url, s->url) ||
145
4/4
✓ Branch 0 taken 99646 times.
✓ Branch 1 taken 809 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 99584 times.
100455 s->iformat && !strcmp(s->iformat->name, "image2") ||
146
4/4
✓ Branch 0 taken 809 times.
✓ Branch 1 taken 62 times.
✓ Branch 2 taken 663 times.
✓ Branch 3 taken 146 times.
871 s->oformat && !strcmp(s->oformat->name, "image2")
147 ) {
148 104791 loglevel = AV_LOG_DEBUG;
149 } else
150 208 loglevel = AV_LOG_INFO;
151
152
2/2
✓ Branch 0 taken 819 times.
✓ Branch 1 taken 104180 times.
104999 av_log(s, loglevel, "Opening \'%s\' for %s\n", url, flags & AVIO_FLAG_WRITE ? "writing" : "reading");
153
154 104999 return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist);
155 }
156
157 100478 static int io_close2_default(AVFormatContext *s, AVIOContext *pb)
158 {
159 100478 return avio_close(pb);
160 }
161
162 15895 AVFormatContext *avformat_alloc_context(void)
163 {
164 FormatContextInternal *fci;
165 FFFormatContext *si;
166 AVFormatContext *s;
167
168 15895 fci = av_mallocz(sizeof(*fci));
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15895 times.
15895 if (!fci)
170 return NULL;
171
172 15895 si = &fci->fc;
173 15895 s = &si->pub;
174 15895 s->av_class = &av_format_context_class;
175 15895 s->io_open = io_open_default;
176 15895 s->io_close2= io_close2_default;
177
178 15895 av_opt_set_defaults(s);
179
180 15895 si->pkt = av_packet_alloc();
181 15895 si->parse_pkt = av_packet_alloc();
182
2/4
✓ Branch 0 taken 15895 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15895 times.
15895 if (!si->pkt || !si->parse_pkt) {
183 avformat_free_context(s);
184 return NULL;
185 }
186
187 15895 return s;
188 }
189
190 129755 const AVClass *avformat_get_class(void)
191 {
192 129755 return &av_format_context_class;
193 }
194
195 #define DISPOSITION_OPT(ctx) \
196 { "disposition", NULL, offsetof(ctx, disposition), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, \
197 .flags = AV_OPT_FLAG_ENCODING_PARAM, .unit = "disposition" }, \
198 { "default", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEFAULT }, .unit = "disposition" }, \
199 { "dub", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DUB }, .unit = "disposition" }, \
200 { "original", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ORIGINAL }, .unit = "disposition" }, \
201 { "comment", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_COMMENT }, .unit = "disposition" }, \
202 { "lyrics", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_LYRICS }, .unit = "disposition" }, \
203 { "karaoke", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_KARAOKE }, .unit = "disposition" }, \
204 { "forced", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_FORCED }, .unit = "disposition" }, \
205 { "hearing_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_HEARING_IMPAIRED }, .unit = "disposition" }, \
206 { "visual_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_VISUAL_IMPAIRED }, .unit = "disposition" }, \
207 { "clean_effects", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CLEAN_EFFECTS }, .unit = "disposition" }, \
208 { "attached_pic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ATTACHED_PIC }, .unit = "disposition" }, \
209 { "timed_thumbnails", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_TIMED_THUMBNAILS }, .unit = "disposition" }, \
210 { "non_diegetic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_NON_DIEGETIC }, .unit = "disposition" }, \
211 { "captions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .unit = "disposition" }, \
212 { "descriptions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "disposition" }, \
213 { "metadata", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .unit = "disposition" }, \
214 { "dependent", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEPENDENT }, .unit = "disposition" }, \
215 { "still_image", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_STILL_IMAGE }, .unit = "disposition" }, \
216 { "multilayer", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_MULTILAYER }, .unit = "disposition" }
217
218 static const AVOption stream_options[] = {
219 DISPOSITION_OPT(AVStream),
220 { "discard", NULL, offsetof(AVStream, discard), AV_OPT_TYPE_INT, { .i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX,
221 .flags = AV_OPT_FLAG_DECODING_PARAM, .unit = "avdiscard" },
222 { "none", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, .unit = "avdiscard" },
223 { "default", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, .unit = "avdiscard" },
224 { "noref", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF }, .unit = "avdiscard" },
225 { "bidir", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR }, .unit = "avdiscard" },
226 { "nointra", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA }, .unit = "avdiscard" },
227 { "nokey", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY }, .unit = "avdiscard" },
228 { "all", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL }, .unit = "avdiscard" },
229 { NULL }
230 };
231
232 static const AVClass stream_class = {
233 .class_name = "AVStream",
234 .item_name = av_default_item_name,
235 .version = LIBAVUTIL_VERSION_INT,
236 .option = stream_options,
237 };
238
239 1 const AVClass *av_stream_get_class(void)
240 {
241 1 return &stream_class;
242 }
243
244 17218 AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
245 {
246 FFStream *sti;
247 AVStream *st;
248 AVStream **streams;
249
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17218 times.
17218 if (s->nb_streams >= s->max_streams) {
251 av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter"
252 " (%d), see the documentation if you wish to increase it\n",
253 s->max_streams);
254 return NULL;
255 }
256 17218 streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17218 times.
17218 if (!streams)
258 return NULL;
259 17218 s->streams = streams;
260
261 17218 sti = av_mallocz(sizeof(*sti));
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17218 times.
17218 if (!sti)
263 return NULL;
264 17218 st = &sti->pub;
265
266 17218 st->av_class = &stream_class;
267 17218 st->codecpar = avcodec_parameters_alloc();
268
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17218 times.
17218 if (!st->codecpar)
269 goto fail;
270
271 17218 sti->fmtctx = s;
272
273
2/2
✓ Branch 0 taken 8407 times.
✓ Branch 1 taken 8811 times.
17218 if (s->iformat) {
274 8407 sti->avctx = avcodec_alloc_context3(NULL);
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8407 times.
8407 if (!sti->avctx)
276 goto fail;
277
278 8407 sti->info = av_mallocz(sizeof(*sti->info));
279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8407 times.
8407 if (!sti->info)
280 goto fail;
281
282 #if FF_API_R_FRAME_RATE
283 8407 sti->info->last_dts = AV_NOPTS_VALUE;
284 #endif
285 8407 sti->info->fps_first_dts = AV_NOPTS_VALUE;
286 8407 sti->info->fps_last_dts = AV_NOPTS_VALUE;
287
288 /* default pts setting is MPEG-like */
289 8407 avpriv_set_pts_info(st, 33, 1, 90000);
290 /* we set the current DTS to 0 so that formats without any timestamps
291 * but durations get some timestamps, formats with some unknown
292 * timestamps have their first few packets buffered and the
293 * timestamps corrected before they are returned to the user */
294 8407 sti->cur_dts = RELATIVE_TS_BASE;
295 } else {
296 8811 sti->cur_dts = AV_NOPTS_VALUE;
297 }
298
299 17218 st->index = s->nb_streams;
300 17218 st->start_time = AV_NOPTS_VALUE;
301 17218 st->duration = AV_NOPTS_VALUE;
302 17218 sti->first_dts = AV_NOPTS_VALUE;
303 17218 sti->probe_packets = s->max_probe_packets;
304 17218 sti->pts_wrap_reference = AV_NOPTS_VALUE;
305 17218 sti->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
306
307 17218 sti->last_IP_pts = AV_NOPTS_VALUE;
308 17218 sti->last_dts_for_order_check = AV_NOPTS_VALUE;
309
2/2
✓ Branch 0 taken 292706 times.
✓ Branch 1 taken 17218 times.
309924 for (int i = 0; i < MAX_REORDER_DELAY + 1; i++)
310 292706 sti->pts_buffer[i] = AV_NOPTS_VALUE;
311
312 17218 st->sample_aspect_ratio = (AVRational) { 0, 1 };
313 #if FF_API_INTERNAL_TIMING
314 17218 sti->transferred_mux_tb = (AVRational) { 0, 1 };;
315 #endif
316
317 17218 sti->need_context_update = 1;
318
319 17218 s->streams[s->nb_streams++] = st;
320 17218 return st;
321 fail:
322 ff_free_stream(&st);
323 return NULL;
324 }
325
326 #define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
327 #define OFFSET(x) offsetof(AVStreamGroupTileGrid, x)
328 static const AVOption tile_grid_options[] = {
329 { "grid_size", "size of the output canvas", OFFSET(coded_width),
330 AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, INT_MAX, FLAGS },
331 { "output_size", "size of valid pixels in output image meant for presentation", OFFSET(width),
332 AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, INT_MAX, FLAGS },
333 { "background_color", "set a background color for unused pixels",
334 OFFSET(background), AV_OPT_TYPE_COLOR, { .str = "black"}, 0, 0, FLAGS },
335 { "horizontal_offset", NULL, OFFSET(horizontal_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
336 { "vertical_offset", NULL, OFFSET(vertical_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
337 { NULL },
338 };
339 #undef OFFSET
340
341 static const AVClass tile_grid_class = {
342 .class_name = "AVStreamGroupTileGrid",
343 .version = LIBAVUTIL_VERSION_INT,
344 .option = tile_grid_options,
345 };
346
347 #define OFFSET(x) offsetof(AVStreamGroupLCEVC, x)
348 static const AVOption lcevc_options[] = {
349 { "video_size", "size of video after LCEVC enhancement has been applied", OFFSET(width),
350 AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, INT_MAX, FLAGS },
351 { NULL },
352 };
353 #undef OFFSET
354
355 static const AVClass lcevc_class = {
356 .class_name = "AVStreamGroupLCEVC",
357 .version = LIBAVUTIL_VERSION_INT,
358 .option = lcevc_options,
359 };
360
361 168 static void *stream_group_child_next(void *obj, void *prev)
362 {
363 168 AVStreamGroup *stg = obj;
364
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 73 times.
168 if (!prev) {
365
2/5
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
95 switch(stg->type) {
366 49 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT:
367 49 return stg->params.iamf_audio_element;
368 46 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION:
369 46 return stg->params.iamf_mix_presentation;
370 case AV_STREAM_GROUP_PARAMS_TILE_GRID:
371 return stg->params.tile_grid;
372 case AV_STREAM_GROUP_PARAMS_LCEVC:
373 return stg->params.lcevc;
374 default:
375 break;
376 }
377 }
378 73 return NULL;
379 }
380
381 #undef FLAGS
382
383 static const AVClass *stream_group_child_iterate(void **opaque)
384 {
385 uintptr_t i = (uintptr_t)*opaque;
386 const AVClass *ret = NULL;
387
388 switch(i) {
389 case AV_STREAM_GROUP_PARAMS_NONE:
390 i++;
391 // fall-through
392 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT:
393 ret = av_iamf_audio_element_get_class();
394 break;
395 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION:
396 ret = av_iamf_mix_presentation_get_class();
397 break;
398 case AV_STREAM_GROUP_PARAMS_TILE_GRID:
399 ret = &tile_grid_class;
400 break;
401 case AV_STREAM_GROUP_PARAMS_LCEVC:
402 ret = &lcevc_class;
403 break;
404 default:
405 break;
406 }
407
408 if (ret)
409 *opaque = (void*)(i + 1);
410 return ret;
411 }
412
413 static const AVOption stream_group_options[] = {
414 DISPOSITION_OPT(AVStreamGroup),
415 {"id", "Set group id", offsetof(AVStreamGroup, id), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
416 { NULL }
417 };
418
419 static const AVClass stream_group_class = {
420 .class_name = "AVStreamGroup",
421 .item_name = av_default_item_name,
422 .version = LIBAVUTIL_VERSION_INT,
423 .option = stream_group_options,
424 .child_next = stream_group_child_next,
425 .child_class_iterate = stream_group_child_iterate,
426 };
427
428 const AVClass *av_stream_group_get_class(void)
429 {
430 return &stream_group_class;
431 }
432
433 85 AVStreamGroup *avformat_stream_group_create(AVFormatContext *s,
434 enum AVStreamGroupParamsType type,
435 AVDictionary **options)
436 {
437 AVStreamGroup **stream_groups;
438 AVStreamGroup *stg;
439 FFStreamGroup *stgi;
440
441 85 stream_groups = av_realloc_array(s->stream_groups, s->nb_stream_groups + 1,
442 sizeof(*stream_groups));
443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 85 times.
85 if (!stream_groups)
444 return NULL;
445 85 s->stream_groups = stream_groups;
446
447 85 stgi = av_mallocz(sizeof(*stgi));
448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 85 times.
85 if (!stgi)
449 return NULL;
450 85 stg = &stgi->pub;
451
452 85 stg->av_class = &stream_group_class;
453 85 av_opt_set_defaults(stg);
454 85 stg->type = type;
455
3/5
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
85 switch (type) {
456 41 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT:
457 41 stg->params.iamf_audio_element = av_iamf_audio_element_alloc();
458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (!stg->params.iamf_audio_element)
459 goto fail;
460 41 break;
461 38 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION:
462 38 stg->params.iamf_mix_presentation = av_iamf_mix_presentation_alloc();
463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!stg->params.iamf_mix_presentation)
464 goto fail;
465 38 break;
466 6 case AV_STREAM_GROUP_PARAMS_TILE_GRID:
467 6 stg->params.tile_grid = av_mallocz(sizeof(*stg->params.tile_grid));
468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!stg->params.tile_grid)
469 goto fail;
470 6 stg->params.tile_grid->av_class = &tile_grid_class;
471 6 av_opt_set_defaults(stg->params.tile_grid);
472 6 break;
473 case AV_STREAM_GROUP_PARAMS_LCEVC:
474 stg->params.lcevc = av_mallocz(sizeof(*stg->params.lcevc));
475 if (!stg->params.lcevc)
476 goto fail;
477 stg->params.lcevc->av_class = &lcevc_class;
478 av_opt_set_defaults(stg->params.lcevc);
479 break;
480 default:
481 goto fail;
482 }
483
484
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 62 times.
85 if (options) {
485
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
23 if (av_opt_set_dict2(stg, options, AV_OPT_SEARCH_CHILDREN))
486 goto fail;
487 }
488
489 85 stgi->fmtctx = s;
490 85 stg->index = s->nb_stream_groups;
491
492 85 s->stream_groups[s->nb_stream_groups++] = stg;
493
494 85 return stg;
495 fail:
496 ff_free_stream_group(&stg);
497 return NULL;
498 }
499
500 383 static int stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
501 {
502 383 AVStream **streams = av_realloc_array(stg->streams, stg->nb_streams + 1,
503 sizeof(*stg->streams));
504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 383 times.
383 if (!streams)
505 return AVERROR(ENOMEM);
506
507 383 stg->streams = streams;
508 383 stg->streams[stg->nb_streams++] = st;
509
510 383 return 0;
511 }
512
513 389 int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
514 {
515 389 const FFStreamGroup *stgi = cffstreamgroup(stg);
516 389 const FFStream *sti = cffstream(st);
517
518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (stgi->fmtctx != sti->fmtctx)
519 return AVERROR(EINVAL);
520
521
2/2
✓ Branch 0 taken 956 times.
✓ Branch 1 taken 383 times.
1339 for (int i = 0; i < stg->nb_streams; i++)
522
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 950 times.
956 if (stg->streams[i]->index == st->index)
523 6 return AVERROR(EEXIST);
524
525 383 return stream_group_add_stream(stg, st);
526 }
527
528 142790 static int option_is_disposition(const AVOption *opt)
529 {
530 274314 return opt->type == AV_OPT_TYPE_CONST &&
531
5/6
✓ Branch 0 taken 131524 times.
✓ Branch 1 taken 11266 times.
✓ Branch 2 taken 131524 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 109516 times.
✓ Branch 5 taken 22008 times.
142790 opt->unit && !strcmp(opt->unit, "disposition");
532 }
533
534 int av_disposition_from_string(const char *disp)
535 {
536 for (const AVOption *opt = stream_options; opt->name; opt++)
537 if (option_is_disposition(opt) && !strcmp(disp, opt->name))
538 return opt->default_val.i64;
539 return AVERROR(EINVAL);
540 }
541
542 8384 const char *av_disposition_to_string(int disposition)
543 {
544 int val;
545
546
2/2
✓ Branch 0 taken 262 times.
✓ Branch 1 taken 8122 times.
8384 if (disposition <= 0)
547 262 return NULL;
548
549 8122 val = 1 << ff_ctz(disposition);
550
2/2
✓ Branch 0 taken 142790 times.
✓ Branch 1 taken 3144 times.
145934 for (const AVOption *opt = stream_options; opt->name; opt++)
551
4/4
✓ Branch 1 taken 109516 times.
✓ Branch 2 taken 33274 times.
✓ Branch 3 taken 4978 times.
✓ Branch 4 taken 104538 times.
142790 if (option_is_disposition(opt) && opt->default_val.i64 == val)
552 4978 return opt->name;
553
554 3144 return NULL;
555 }
556