FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/options.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 176 249 70.7%
Functions: 16 20 80.0%
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 2613 static const char* format_to_name(void* ptr)
46 {
47 2613 AVFormatContext* fc = (AVFormatContext*) ptr;
48
2/2
✓ Branch 0 taken 1705 times.
✓ Branch 1 taken 908 times.
2613 if(fc->iformat) return fc->iformat->name;
49
1/2
✓ Branch 0 taken 908 times.
✗ Branch 1 not taken.
908 else if(fc->oformat) return fc->oformat->name;
50 else return fc->av_class->class_name;
51 }
52
53 55716 static void *format_child_next(void *obj, void *prev)
54 {
55 55716 AVFormatContext *s = obj;
56
4/4
✓ Branch 0 taken 22721 times.
✓ Branch 1 taken 32995 times.
✓ Branch 2 taken 22253 times.
✓ Branch 3 taken 468 times.
55716 if (!prev && s->priv_data &&
57
4/4
✓ Branch 0 taken 22251 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2503 times.
✓ Branch 3 taken 19748 times.
22253 ((s->iformat && s->iformat->priv_class) ||
58
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2503 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2505 s->oformat && s->oformat->priv_class))
59 19750 return s->priv_data;
60
6/6
✓ Branch 0 taken 26858 times.
✓ Branch 1 taken 9108 times.
✓ Branch 2 taken 26846 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 13423 times.
✓ Branch 5 taken 13423 times.
35966 if (s->pb && s->pb->av_class && prev != s->pb)
61 13423 return s->pb;
62 22543 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 26057009 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 26057009 void *val = (void*)(((uintptr_t)*iter) & ((1 << ITER_STATE_SHIFT) - 1));
80 26057009 unsigned int state = ((uintptr_t)*iter) >> ITER_STATE_SHIFT;
81 26057009 const AVClass *ret = NULL;
82
83
2/2
✓ Branch 0 taken 110065 times.
✓ Branch 1 taken 25946944 times.
26057009 if (state == CHILD_CLASS_ITER_AVIO) {
84 110065 ret = &ff_avio_class;
85 110065 state++;
86 110065 goto finish;
87 }
88
89
2/2
✓ Branch 0 taken 8139127 times.
✓ Branch 1 taken 17807817 times.
25946944 if (state == CHILD_CLASS_ITER_MUX) {
90 const AVOutputFormat *ofmt;
91
92
2/2
✓ Branch 1 taken 20458441 times.
✓ Branch 2 taken 109939 times.
20568380 while ((ofmt = av_muxer_iterate(&val))) {
93 20458441 ret = ofmt->priv_class;
94
2/2
✓ Branch 0 taken 8029188 times.
✓ Branch 1 taken 12429253 times.
20458441 if (ret)
95 8029188 goto finish;
96 }
97
98 109939 val = NULL;
99 109939 state++;
100 }
101
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17917756 times.
17917756 if (state == CHILD_CLASS_ITER_DEMUX) {
103 const AVInputFormat *ifmt;
104
105
2/2
✓ Branch 1 taken 39683500 times.
✓ Branch 2 taken 109909 times.
39793409 while ((ifmt = av_demuxer_iterate(&val))) {
106 39683500 ret = ifmt->priv_class;
107
2/2
✓ Branch 0 taken 17807847 times.
✓ Branch 1 taken 21875653 times.
39683500 if (ret)
108 17807847 goto finish;
109 }
110 109909 val = NULL;
111 109909 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 26057009 times.
26057009 av_assert0(!((uintptr_t)val >> ITER_STATE_SHIFT));
117 26057009 *iter = (void*)((uintptr_t)val | (state << ITER_STATE_SHIFT));
118 26057009 return ret;
119 }
120
121 2613 static AVClassCategory get_category(void *ptr)
122 {
123 2613 AVFormatContext* s = ptr;
124
2/2
✓ Branch 0 taken 1705 times.
✓ Branch 1 taken 908 times.
2613 if(s->iformat) return AV_CLASS_CATEGORY_DEMUXER;
125 908 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 104221 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 99700 times.
✓ Branch 1 taken 4521 times.
104221 if (!strcmp(url, s->url) ||
145
4/4
✓ Branch 0 taken 98891 times.
✓ Branch 1 taken 809 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 98829 times.
99700 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 104013 loglevel = AV_LOG_DEBUG;
149 } else
150 208 loglevel = AV_LOG_INFO;
151
152
2/2
✓ Branch 0 taken 819 times.
✓ Branch 1 taken 103402 times.
104221 av_log(s, loglevel, "Opening \'%s\' for %s\n", url, flags & AVIO_FLAG_WRITE ? "writing" : "reading");
153
154 104221 return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist);
155 }
156
157 99723 static int io_close2_default(AVFormatContext *s, AVIOContext *pb)
158 {
159 99723 return avio_close(pb);
160 }
161
162 15526 AVFormatContext *avformat_alloc_context(void)
163 {
164 FormatContextInternal *fci;
165 FFFormatContext *si;
166 AVFormatContext *s;
167
168 15526 fci = av_mallocz(sizeof(*fci));
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15526 times.
15526 if (!fci)
170 return NULL;
171
172 15526 si = &fci->fc;
173 15526 s = &si->pub;
174 15526 s->av_class = &av_format_context_class;
175 15526 s->io_open = io_open_default;
176 15526 s->io_close2= io_close2_default;
177
178 15526 av_opt_set_defaults(s);
179
180 15526 si->pkt = av_packet_alloc();
181 15526 si->parse_pkt = av_packet_alloc();
182
2/4
✓ Branch 0 taken 15526 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15526 times.
15526 if (!si->pkt || !si->parse_pkt) {
183 avformat_free_context(s);
184 return NULL;
185 }
186
187 #if FF_API_LAVF_SHORTEST
188 15526 fci->shortest_end = AV_NOPTS_VALUE;
189 #endif
190
191 15526 return s;
192 }
193
194 #if FF_API_GET_DUR_ESTIMATE_METHOD
195 enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx)
196 {
197 return ctx->duration_estimation_method;
198 }
199 #endif
200
201 124340 const AVClass *avformat_get_class(void)
202 {
203 124340 return &av_format_context_class;
204 }
205
206 #define DISPOSITION_OPT(ctx) \
207 { "disposition", NULL, offsetof(ctx, disposition), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, \
208 .flags = AV_OPT_FLAG_ENCODING_PARAM, .unit = "disposition" }, \
209 { "default", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEFAULT }, .unit = "disposition" }, \
210 { "dub", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DUB }, .unit = "disposition" }, \
211 { "original", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ORIGINAL }, .unit = "disposition" }, \
212 { "comment", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_COMMENT }, .unit = "disposition" }, \
213 { "lyrics", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_LYRICS }, .unit = "disposition" }, \
214 { "karaoke", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_KARAOKE }, .unit = "disposition" }, \
215 { "forced", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_FORCED }, .unit = "disposition" }, \
216 { "hearing_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_HEARING_IMPAIRED }, .unit = "disposition" }, \
217 { "visual_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_VISUAL_IMPAIRED }, .unit = "disposition" }, \
218 { "clean_effects", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CLEAN_EFFECTS }, .unit = "disposition" }, \
219 { "attached_pic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ATTACHED_PIC }, .unit = "disposition" }, \
220 { "timed_thumbnails", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_TIMED_THUMBNAILS }, .unit = "disposition" }, \
221 { "non_diegetic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_NON_DIEGETIC }, .unit = "disposition" }, \
222 { "captions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .unit = "disposition" }, \
223 { "descriptions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "disposition" }, \
224 { "metadata", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .unit = "disposition" }, \
225 { "dependent", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEPENDENT }, .unit = "disposition" }, \
226 { "still_image", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_STILL_IMAGE }, .unit = "disposition" }, \
227 { "multilayer", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_MULTILAYER }, .unit = "disposition" }
228
229 static const AVOption stream_options[] = {
230 DISPOSITION_OPT(AVStream),
231 { "discard", NULL, offsetof(AVStream, discard), AV_OPT_TYPE_INT, { .i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX,
232 .flags = AV_OPT_FLAG_DECODING_PARAM, .unit = "avdiscard" },
233 { "none", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE }, .unit = "avdiscard" },
234 { "default", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, .unit = "avdiscard" },
235 { "noref", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF }, .unit = "avdiscard" },
236 { "bidir", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR }, .unit = "avdiscard" },
237 { "nointra", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA }, .unit = "avdiscard" },
238 { "nokey", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY }, .unit = "avdiscard" },
239 { "all", .type = AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL }, .unit = "avdiscard" },
240 { NULL }
241 };
242
243 static const AVClass stream_class = {
244 .class_name = "AVStream",
245 .item_name = av_default_item_name,
246 .version = LIBAVUTIL_VERSION_INT,
247 .option = stream_options,
248 };
249
250 1 const AVClass *av_stream_get_class(void)
251 {
252 1 return &stream_class;
253 }
254
255 16768 AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
256 {
257 16768 FFFormatContext *const si = ffformatcontext(s);
258 FFStream *sti;
259 AVStream *st;
260 AVStream **streams;
261
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16768 times.
16768 if (s->nb_streams >= s->max_streams) {
263 av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter"
264 " (%d), see the documentation if you wish to increase it\n",
265 s->max_streams);
266 return NULL;
267 }
268 16768 streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16768 times.
16768 if (!streams)
270 return NULL;
271 16768 s->streams = streams;
272
273 16768 sti = av_mallocz(sizeof(*sti));
274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16768 times.
16768 if (!sti)
275 return NULL;
276 16768 st = &sti->pub;
277
278 16768 st->av_class = &stream_class;
279 16768 st->codecpar = avcodec_parameters_alloc();
280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16768 times.
16768 if (!st->codecpar)
281 goto fail;
282
283 16768 sti->fmtctx = s;
284
285
2/2
✓ Branch 0 taken 8316 times.
✓ Branch 1 taken 8452 times.
16768 if (s->iformat) {
286 8316 sti->avctx = avcodec_alloc_context3(NULL);
287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8316 times.
8316 if (!sti->avctx)
288 goto fail;
289
290 8316 sti->info = av_mallocz(sizeof(*sti->info));
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8316 times.
8316 if (!sti->info)
292 goto fail;
293
294 #if FF_API_R_FRAME_RATE
295 8316 sti->info->last_dts = AV_NOPTS_VALUE;
296 #endif
297 8316 sti->info->fps_first_dts = AV_NOPTS_VALUE;
298 8316 sti->info->fps_last_dts = AV_NOPTS_VALUE;
299
300 /* default pts setting is MPEG-like */
301 8316 avpriv_set_pts_info(st, 33, 1, 90000);
302 /* we set the current DTS to 0 so that formats without any timestamps
303 * but durations get some timestamps, formats with some unknown
304 * timestamps have their first few packets buffered and the
305 * timestamps corrected before they are returned to the user */
306 8316 sti->cur_dts = RELATIVE_TS_BASE;
307 } else {
308 8452 sti->cur_dts = AV_NOPTS_VALUE;
309 }
310
311 16768 st->index = s->nb_streams;
312 16768 st->start_time = AV_NOPTS_VALUE;
313 16768 st->duration = AV_NOPTS_VALUE;
314 16768 sti->first_dts = AV_NOPTS_VALUE;
315 16768 sti->probe_packets = s->max_probe_packets;
316 16768 sti->pts_wrap_reference = AV_NOPTS_VALUE;
317 16768 sti->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
318
319 16768 sti->last_IP_pts = AV_NOPTS_VALUE;
320 16768 sti->last_dts_for_order_check = AV_NOPTS_VALUE;
321
2/2
✓ Branch 0 taken 285056 times.
✓ Branch 1 taken 16768 times.
301824 for (int i = 0; i < MAX_REORDER_DELAY + 1; i++)
322 285056 sti->pts_buffer[i] = AV_NOPTS_VALUE;
323
324 16768 st->sample_aspect_ratio = (AVRational) { 0, 1 };
325 #if FF_API_INTERNAL_TIMING
326 16768 sti->transferred_mux_tb = (AVRational) { 0, 1 };;
327 #endif
328
329 #if FF_API_AVSTREAM_SIDE_DATA
330 16768 sti->inject_global_side_data = si->inject_global_side_data;
331 #endif
332
333 16768 sti->need_context_update = 1;
334
335 16768 s->streams[s->nb_streams++] = st;
336 16768 return st;
337 fail:
338 ff_free_stream(&st);
339 return NULL;
340 }
341
342 #define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
343 #define OFFSET(x) offsetof(AVStreamGroupTileGrid, x)
344 static const AVOption tile_grid_options[] = {
345 { "grid_size", "size of the output canvas", OFFSET(coded_width),
346 AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, INT_MAX, FLAGS },
347 { "output_size", "size of valid pixels in output image meant for presentation", OFFSET(width),
348 AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, INT_MAX, FLAGS },
349 { "background_color", "set a background color for unused pixels",
350 OFFSET(background), AV_OPT_TYPE_COLOR, { .str = "black"}, 0, 0, FLAGS },
351 { "horizontal_offset", NULL, OFFSET(horizontal_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
352 { "vertical_offset", NULL, OFFSET(vertical_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
353 { NULL },
354 };
355 #undef OFFSET
356
357 static const AVClass tile_grid_class = {
358 .class_name = "AVStreamGroupTileGrid",
359 .version = LIBAVUTIL_VERSION_INT,
360 .option = tile_grid_options,
361 };
362
363 #define OFFSET(x) offsetof(AVStreamGroupLCEVC, x)
364 static const AVOption lcevc_options[] = {
365 { "video_size", "size of video after LCEVC enhancement has been applied", OFFSET(width),
366 AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, INT_MAX, FLAGS },
367 { NULL },
368 };
369 #undef OFFSET
370
371 static const AVClass lcevc_class = {
372 .class_name = "AVStreamGroupLCEVC",
373 .version = LIBAVUTIL_VERSION_INT,
374 .option = lcevc_options,
375 };
376
377 147 static void *stream_group_child_next(void *obj, void *prev)
378 {
379 147 AVStreamGroup *stg = obj;
380
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 64 times.
147 if (!prev) {
381
2/5
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
83 switch(stg->type) {
382 41 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT:
383 41 return stg->params.iamf_audio_element;
384 42 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION:
385 42 return stg->params.iamf_mix_presentation;
386 case AV_STREAM_GROUP_PARAMS_TILE_GRID:
387 return stg->params.tile_grid;
388 case AV_STREAM_GROUP_PARAMS_LCEVC:
389 return stg->params.lcevc;
390 default:
391 break;
392 }
393 }
394 64 return NULL;
395 }
396
397 #undef FLAGS
398
399 static const AVClass *stream_group_child_iterate(void **opaque)
400 {
401 uintptr_t i = (uintptr_t)*opaque;
402 const AVClass *ret = NULL;
403
404 switch(i) {
405 case AV_STREAM_GROUP_PARAMS_NONE:
406 i++;
407 // fall-through
408 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT:
409 ret = av_iamf_audio_element_get_class();
410 break;
411 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION:
412 ret = av_iamf_mix_presentation_get_class();
413 break;
414 case AV_STREAM_GROUP_PARAMS_TILE_GRID:
415 ret = &tile_grid_class;
416 break;
417 case AV_STREAM_GROUP_PARAMS_LCEVC:
418 ret = &lcevc_class;
419 break;
420 default:
421 break;
422 }
423
424 if (ret)
425 *opaque = (void*)(i + 1);
426 return ret;
427 }
428
429 static const AVOption stream_group_options[] = {
430 DISPOSITION_OPT(AVStreamGroup),
431 {"id", "Set group id", offsetof(AVStreamGroup, id), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
432 { NULL }
433 };
434
435 static const AVClass stream_group_class = {
436 .class_name = "AVStreamGroup",
437 .item_name = av_default_item_name,
438 .version = LIBAVUTIL_VERSION_INT,
439 .option = stream_group_options,
440 .child_next = stream_group_child_next,
441 .child_class_iterate = stream_group_child_iterate,
442 };
443
444 const AVClass *av_stream_group_get_class(void)
445 {
446 return &stream_group_class;
447 }
448
449 76 AVStreamGroup *avformat_stream_group_create(AVFormatContext *s,
450 enum AVStreamGroupParamsType type,
451 AVDictionary **options)
452 {
453 AVStreamGroup **stream_groups;
454 AVStreamGroup *stg;
455 FFStreamGroup *stgi;
456
457 76 stream_groups = av_realloc_array(s->stream_groups, s->nb_stream_groups + 1,
458 sizeof(*stream_groups));
459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if (!stream_groups)
460 return NULL;
461 76 s->stream_groups = stream_groups;
462
463 76 stgi = av_mallocz(sizeof(*stgi));
464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if (!stgi)
465 return NULL;
466 76 stg = &stgi->pub;
467
468 76 stg->av_class = &stream_group_class;
469 76 av_opt_set_defaults(stg);
470 76 stg->type = type;
471
3/5
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
76 switch (type) {
472 35 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT:
473 35 stg->params.iamf_audio_element = av_iamf_audio_element_alloc();
474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (!stg->params.iamf_audio_element)
475 goto fail;
476 35 break;
477 35 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION:
478 35 stg->params.iamf_mix_presentation = av_iamf_mix_presentation_alloc();
479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (!stg->params.iamf_mix_presentation)
480 goto fail;
481 35 break;
482 6 case AV_STREAM_GROUP_PARAMS_TILE_GRID:
483 6 stg->params.tile_grid = av_mallocz(sizeof(*stg->params.tile_grid));
484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!stg->params.tile_grid)
485 goto fail;
486 6 stg->params.tile_grid->av_class = &tile_grid_class;
487 6 av_opt_set_defaults(stg->params.tile_grid);
488 6 break;
489 case AV_STREAM_GROUP_PARAMS_LCEVC:
490 stg->params.lcevc = av_mallocz(sizeof(*stg->params.lcevc));
491 if (!stg->params.lcevc)
492 goto fail;
493 stg->params.lcevc->av_class = &lcevc_class;
494 av_opt_set_defaults(stg->params.lcevc);
495 break;
496 default:
497 goto fail;
498 }
499
500
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 56 times.
76 if (options) {
501
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
20 if (av_opt_set_dict2(stg, options, AV_OPT_SEARCH_CHILDREN))
502 goto fail;
503 }
504
505 76 stgi->fmtctx = s;
506 76 stg->index = s->nb_stream_groups;
507
508 76 s->stream_groups[s->nb_stream_groups++] = stg;
509
510 76 return stg;
511 fail:
512 ff_free_stream_group(&stg);
513 return NULL;
514 }
515
516 324 static int stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
517 {
518 324 AVStream **streams = av_realloc_array(stg->streams, stg->nb_streams + 1,
519 sizeof(*stg->streams));
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 324 times.
324 if (!streams)
521 return AVERROR(ENOMEM);
522
523 324 stg->streams = streams;
524 324 stg->streams[stg->nb_streams++] = st;
525
526 324 return 0;
527 }
528
529 330 int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
530 {
531 330 const FFStreamGroup *stgi = cffstreamgroup(stg);
532 330 const FFStream *sti = cffstream(st);
533
534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 330 times.
330 if (stgi->fmtctx != sti->fmtctx)
535 return AVERROR(EINVAL);
536
537
2/2
✓ Branch 0 taken 722 times.
✓ Branch 1 taken 324 times.
1046 for (int i = 0; i < stg->nb_streams; i++)
538
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 716 times.
722 if (stg->streams[i]->index == st->index)
539 6 return AVERROR(EEXIST);
540
541 324 return stream_group_add_stream(stg, st);
542 }
543
544 131890 static int option_is_disposition(const AVOption *opt)
545 {
546 253374 return opt->type == AV_OPT_TYPE_CONST &&
547
5/6
✓ Branch 0 taken 121484 times.
✓ Branch 1 taken 10406 times.
✓ Branch 2 taken 121484 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 101156 times.
✓ Branch 5 taken 20328 times.
131890 opt->unit && !strcmp(opt->unit, "disposition");
548 }
549
550 int av_disposition_from_string(const char *disp)
551 {
552 for (const AVOption *opt = stream_options; opt->name; opt++)
553 if (option_is_disposition(opt) && !strcmp(disp, opt->name))
554 return opt->default_val.i64;
555 return AVERROR(EINVAL);
556 }
557
558 7744 const char *av_disposition_to_string(int disposition)
559 {
560 int val;
561
562
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 7502 times.
7744 if (disposition <= 0)
563 242 return NULL;
564
565 7502 val = 1 << ff_ctz(disposition);
566
2/2
✓ Branch 0 taken 131890 times.
✓ Branch 1 taken 2904 times.
134794 for (const AVOption *opt = stream_options; opt->name; opt++)
567
4/4
✓ Branch 1 taken 101156 times.
✓ Branch 2 taken 30734 times.
✓ Branch 3 taken 4598 times.
✓ Branch 4 taken 96558 times.
131890 if (option_is_disposition(opt) && opt->default_val.i64 == val)
568 4598 return opt->name;
569
570 2904 return NULL;
571 }
572