2 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 * This file is part of FFmpeg.
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.
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.
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
21 #include "avformat_internal.h"
22 #include "avio_internal.h"
26 #include "libavcodec/avcodec.h"
27 #include "libavcodec/codec_par.h"
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"
38 * Options definition for AVFormatContext.
41 FF_DISABLE_DEPRECATION_WARNINGS
42 #include "options_table.h"
43 FF_ENABLE_DEPRECATION_WARNINGS
45 static const char* format_to_name(void* ptr
)
47 AVFormatContext
* fc
= (AVFormatContext
*) ptr
;
48 if(fc
->iformat
) return fc
->iformat
->name
;
49 else if(fc
->oformat
) return fc
->oformat
->name
;
50 else return fc
->av_class
->class_name
;
53 static void *format_child_next(void *obj
, void *prev
)
55 AVFormatContext
*s
= obj
;
56 if (!prev
&& s
->priv_data
&&
57 ((s
->iformat
&& s
->iformat
->priv_class
) ||
58 s
->oformat
&& s
->oformat
->priv_class
))
60 if (s
->pb
&& s
->pb
->av_class
&& prev
!= s
->pb
)
66 CHILD_CLASS_ITER_AVIO
= 0,
68 CHILD_CLASS_ITER_DEMUX
,
69 CHILD_CLASS_ITER_DONE
,
73 #define ITER_STATE_SHIFT 16
75 static const AVClass
*format_child_class_iterate(void **iter
)
77 // we use the low 16 bits of iter as the value to be passed to
78 // av_(de)muxer_iterate()
79 void *val
= (void*)(((uintptr_t)*iter
) & ((1 << ITER_STATE_SHIFT
) - 1));
80 unsigned int state
= ((uintptr_t)*iter
) >> ITER_STATE_SHIFT
;
81 const AVClass
*ret
= NULL
;
83 if (state
== CHILD_CLASS_ITER_AVIO
) {
89 if (state
== CHILD_CLASS_ITER_MUX
) {
90 const AVOutputFormat
*ofmt
;
92 while ((ofmt
= av_muxer_iterate(&val
))) {
93 ret
= ofmt
->priv_class
;
102 if (state
== CHILD_CLASS_ITER_DEMUX
) {
103 const AVInputFormat
*ifmt
;
105 while ((ifmt
= av_demuxer_iterate(&val
))) {
106 ret
= ifmt
->priv_class
;
115 // make sure none av_(de)muxer_iterate does not set the high bits of val
116 av_assert0(!((uintptr_t)val
>> ITER_STATE_SHIFT
));
117 *iter
= (void*)((uintptr_t)val
| (state
<< ITER_STATE_SHIFT
));
121 static AVClassCategory
get_category(void *ptr
)
123 AVFormatContext
* s
= ptr
;
124 if(s
->iformat
) return AV_CLASS_CATEGORY_DEMUXER
;
125 else return AV_CLASS_CATEGORY_MUXER
;
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
,
139 static int io_open_default(AVFormatContext
*s
, AVIOContext
**pb
,
140 const char *url
, int flags
, AVDictionary
**options
)
144 if (!strcmp(url
, s
->url
) ||
145 s
->iformat
&& !strcmp(s
->iformat
->name
, "image2") ||
146 s
->oformat
&& !strcmp(s
->oformat
->name
, "image2")
148 loglevel
= AV_LOG_DEBUG
;
150 loglevel
= AV_LOG_INFO
;
152 av_log(s
, loglevel
, "Opening \'%s\' for %s\n", url
, flags
& AVIO_FLAG_WRITE
? "writing" : "reading");
154 return ffio_open_whitelist(pb
, url
, flags
, &s
->interrupt_callback
, options
, s
->protocol_whitelist
, s
->protocol_blacklist
);
157 static int io_close2_default(AVFormatContext
*s
, AVIOContext
*pb
)
159 return avio_close(pb
);
162 AVFormatContext
*avformat_alloc_context(void)
164 FormatContextInternal
*fci
;
168 fci
= av_mallocz(sizeof(*fci
));
174 s
->av_class
= &av_format_context_class
;
175 s
->io_open
= io_open_default
;
176 s
->io_close2
= io_close2_default
;
178 av_opt_set_defaults(s
);
180 si
->pkt
= av_packet_alloc();
181 si
->parse_pkt
= av_packet_alloc();
182 if (!si
->pkt
|| !si
->parse_pkt
) {
183 avformat_free_context(s
);
190 const AVClass
*avformat_get_class(void)
192 return &av_format_context_class
;
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" }
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" },
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
,
239 const AVClass
*av_stream_get_class(void)
241 return &stream_class
;
244 AVStream
*avformat_new_stream(AVFormatContext
*s
, const AVCodec
*c
)
250 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",
256 streams
= av_realloc_array(s
->streams
, s
->nb_streams
+ 1, sizeof(*streams
));
259 s
->streams
= streams
;
261 sti
= av_mallocz(sizeof(*sti
));
266 st
->av_class
= &stream_class
;
267 st
->codecpar
= avcodec_parameters_alloc();
274 sti
->avctx
= avcodec_alloc_context3(NULL
);
278 sti
->info
= av_mallocz(sizeof(*sti
->info
));
282 #if FF_API_R_FRAME_RATE
283 sti
->info
->last_dts
= AV_NOPTS_VALUE
;
285 sti
->info
->fps_first_dts
= AV_NOPTS_VALUE
;
286 sti
->info
->fps_last_dts
= AV_NOPTS_VALUE
;
288 /* default pts setting is MPEG-like */
289 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 sti
->cur_dts
= RELATIVE_TS_BASE
;
296 sti
->cur_dts
= AV_NOPTS_VALUE
;
299 st
->index
= s
->nb_streams
;
300 st
->start_time
= AV_NOPTS_VALUE
;
301 st
->duration
= AV_NOPTS_VALUE
;
302 sti
->first_dts
= AV_NOPTS_VALUE
;
303 sti
->probe_packets
= s
->max_probe_packets
;
304 sti
->pts_wrap_reference
= AV_NOPTS_VALUE
;
305 sti
->pts_wrap_behavior
= AV_PTS_WRAP_IGNORE
;
307 sti
->last_IP_pts
= AV_NOPTS_VALUE
;
308 sti
->last_dts_for_order_check
= AV_NOPTS_VALUE
;
309 for (int i
= 0; i
< MAX_REORDER_DELAY
+ 1; i
++)
310 sti
->pts_buffer
[i
] = AV_NOPTS_VALUE
;
312 st
->sample_aspect_ratio
= (AVRational
) { 0, 1 };
313 #if FF_API_INTERNAL_TIMING
314 sti
->transferred_mux_tb
= (AVRational
) { 0, 1 };;
317 sti
->need_context_update
= 1;
319 s
->streams
[s
->nb_streams
++] = st
;
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
},
341 static const AVClass tile_grid_class
= {
342 .class_name
= "AVStreamGroupTileGrid",
343 .version
= LIBAVUTIL_VERSION_INT
,
344 .option
= tile_grid_options
,
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
},
355 static const AVClass lcevc_class
= {
356 .class_name
= "AVStreamGroupLCEVC",
357 .version
= LIBAVUTIL_VERSION_INT
,
358 .option
= lcevc_options
,
361 static void *stream_group_child_next(void *obj
, void *prev
)
363 AVStreamGroup
*stg
= obj
;
366 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
:
367 return stg
->params
.iamf_audio_element
;
368 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
:
369 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
;
383 static const AVClass
*stream_group_child_iterate(void **opaque
)
385 uintptr_t i
= (uintptr_t)*opaque
;
386 const AVClass
*ret
= NULL
;
389 case AV_STREAM_GROUP_PARAMS_NONE
:
392 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
:
393 ret
= av_iamf_audio_element_get_class();
395 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
:
396 ret
= av_iamf_mix_presentation_get_class();
398 case AV_STREAM_GROUP_PARAMS_TILE_GRID
:
399 ret
= &tile_grid_class
;
401 case AV_STREAM_GROUP_PARAMS_LCEVC
:
409 *opaque
= (void*)(i
+ 1);
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
},
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
,
428 const AVClass
*av_stream_group_get_class(void)
430 return &stream_group_class
;
433 AVStreamGroup
*avformat_stream_group_create(AVFormatContext
*s
,
434 enum AVStreamGroupParamsType type
,
435 AVDictionary
**options
)
437 AVStreamGroup
**stream_groups
;
441 stream_groups
= av_realloc_array(s
->stream_groups
, s
->nb_stream_groups
+ 1,
442 sizeof(*stream_groups
));
445 s
->stream_groups
= stream_groups
;
447 stgi
= av_mallocz(sizeof(*stgi
));
452 stg
->av_class
= &stream_group_class
;
453 av_opt_set_defaults(stg
);
456 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
:
457 stg
->params
.iamf_audio_element
= av_iamf_audio_element_alloc();
458 if (!stg
->params
.iamf_audio_element
)
461 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
:
462 stg
->params
.iamf_mix_presentation
= av_iamf_mix_presentation_alloc();
463 if (!stg
->params
.iamf_mix_presentation
)
466 case AV_STREAM_GROUP_PARAMS_TILE_GRID
:
467 stg
->params
.tile_grid
= av_mallocz(sizeof(*stg
->params
.tile_grid
));
468 if (!stg
->params
.tile_grid
)
470 stg
->params
.tile_grid
->av_class
= &tile_grid_class
;
471 av_opt_set_defaults(stg
->params
.tile_grid
);
473 case AV_STREAM_GROUP_PARAMS_LCEVC
:
474 stg
->params
.lcevc
= av_mallocz(sizeof(*stg
->params
.lcevc
));
475 if (!stg
->params
.lcevc
)
477 stg
->params
.lcevc
->av_class
= &lcevc_class
;
478 av_opt_set_defaults(stg
->params
.lcevc
);
485 if (av_opt_set_dict2(stg
, options
, AV_OPT_SEARCH_CHILDREN
))
490 stg
->index
= s
->nb_stream_groups
;
492 s
->stream_groups
[s
->nb_stream_groups
++] = stg
;
496 ff_free_stream_group(&stg
);
500 static int stream_group_add_stream(AVStreamGroup
*stg
, AVStream
*st
)
502 AVStream
**streams
= av_realloc_array(stg
->streams
, stg
->nb_streams
+ 1,
503 sizeof(*stg
->streams
));
505 return AVERROR(ENOMEM
);
507 stg
->streams
= streams
;
508 stg
->streams
[stg
->nb_streams
++] = st
;
513 int avformat_stream_group_add_stream(AVStreamGroup
*stg
, AVStream
*st
)
515 const FFStreamGroup
*stgi
= cffstreamgroup(stg
);
516 const FFStream
*sti
= cffstream(st
);
518 if (stgi
->fmtctx
!= sti
->fmtctx
)
519 return AVERROR(EINVAL
);
521 for (int i
= 0; i
< stg
->nb_streams
; i
++)
522 if (stg
->streams
[i
]->index
== st
->index
)
523 return AVERROR(EEXIST
);
525 return stream_group_add_stream(stg
, st
);
528 static int option_is_disposition(const AVOption
*opt
)
530 return opt
->type
== AV_OPT_TYPE_CONST
&&
531 opt
->unit
&& !strcmp(opt
->unit
, "disposition");
534 int av_disposition_from_string(const char *disp
)
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
);
542 const char *av_disposition_to_string(int disposition
)
546 if (disposition
<= 0)
549 val
= 1 << ff_ctz(disposition
);
550 for (const AVOption
*opt
= stream_options
; opt
->name
; opt
++)
551 if (option_is_disposition(opt
) && opt
->default_val
.i64
== val
)