FFmpeg
Loading...
Searching...
No Matches
concatdec.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012 Nicolas George
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 License
8 * 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
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
22#include "libavutil/avstring.h"
23#include "libavutil/avassert.h"
24#include "libavutil/bprint.h"
26#include "libavutil/mem.h"
27#include "libavutil/opt.h"
29#include "libavutil/timestamp.h"
31#include "libavcodec/bsf.h"
32#include "avformat.h"
33#include "avio_internal.h"
34#include "demux.h"
35#include "internal.h"
36#include "url.h"
37
42
47
63
64typedef struct {
65 AVClass *class;
68 unsigned nb_files;
70 int safe;
72 int eof;
74 unsigned auto_convert;
78
79static int concat_probe(const AVProbeData *probe)
80{
81 return memcmp(probe->buf, "ffconcat version 1.0", 20) ?
83}
84
85static char *get_keyword(uint8_t **cursor)
86{
87 char *ret = *cursor += strspn(*cursor, SPACE_CHARS);
88 *cursor += strcspn(*cursor, SPACE_CHARS);
89 if (**cursor) {
90 *((*cursor)++) = 0;
91 *cursor += strspn(*cursor, SPACE_CHARS);
92 }
93 return ret;
94}
95
96static int safe_filename(const char *f)
97{
98 const char *start = f;
99
100 for (; *f; f++) {
101 /* A-Za-z0-9_- */
102 if (!((unsigned)((*f | 32) - 'a') < 26 ||
103 (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) {
104 if (f == start)
105 return 0;
106 else if (*f == '/')
107 start = f + 1;
108 else if (*f != '.')
109 return 0;
110 }
111 }
112 return 1;
113}
114
115#define FAIL(retcode) do { ret = (retcode); goto fail; } while(0)
116
117static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
118 unsigned *nb_files_alloc)
119{
121 ConcatFile *file;
122 char *url = NULL;
123 const char *proto;
124 const char *ptr;
125 size_t url_len;
126 int ret;
127
128 if (cat->safe && !safe_filename(filename)) {
129 av_log(avf, AV_LOG_ERROR, "Unsafe file name '%s'\n", filename);
130 FAIL(AVERROR(EPERM));
131 }
132
133 proto = avio_find_protocol_name(filename);
134 if (proto && av_strstart(filename, proto, &ptr) &&
135 (*ptr == ':' || *ptr == ',')) {
136 url = filename;
137 filename = NULL;
138 } else {
139 url_len = strlen(avf->url) + strlen(filename) + 16;
140 if (!(url = av_malloc(url_len)))
141 FAIL(AVERROR(ENOMEM));
142 ff_make_absolute_url(url, url_len, avf->url, filename);
143 av_freep(&filename);
144 }
145
146 if (cat->nb_files >= *nb_files_alloc) {
147 size_t n = FFMAX(*nb_files_alloc * 2, 16);
148 ConcatFile *new_files;
149 if (n <= cat->nb_files || n > SIZE_MAX / sizeof(*cat->files) ||
150 !(new_files = av_realloc(cat->files, n * sizeof(*cat->files))))
151 FAIL(AVERROR(ENOMEM));
152 cat->files = new_files;
153 *nb_files_alloc = n;
154 }
155
156 file = &cat->files[cat->nb_files++];
157 memset(file, 0, sizeof(*file));
158 *rfile = file;
159
160 file->url = url;
162 file->duration = AV_NOPTS_VALUE;
163 file->next_dts = AV_NOPTS_VALUE;
164 file->inpoint = AV_NOPTS_VALUE;
165 file->outpoint = AV_NOPTS_VALUE;
167
168 return 0;
169
170fail:
171 av_free(url);
172 av_free(filename);
173 return ret;
174}
175
176static int copy_stream_props(AVStream *st, AVStream *source_st)
177{
178 int ret;
179
180 if (st->codecpar->codec_id || !source_st->codecpar->codec_id) {
181 if (st->codecpar->extradata_size < source_st->codecpar->extradata_size) {
183 source_st->codecpar->extradata_size);
184 if (ret < 0)
185 return ret;
186 }
187 if (source_st->codecpar->extradata_size)
188 memcpy(st->codecpar->extradata, source_st->codecpar->extradata,
189 source_st->codecpar->extradata_size);
190 return 0;
191 }
192 if ((ret = avcodec_parameters_copy(st->codecpar, source_st->codecpar)) < 0)
193 return ret;
194 st->r_frame_rate = source_st->r_frame_rate;
195 st->avg_frame_rate = source_st->avg_frame_rate;
197 avpriv_set_pts_info(st, 64, source_st->time_base.num, source_st->time_base.den);
198
199 av_dict_copy(&st->metadata, source_st->metadata, 0);
200 return 0;
201}
202
204{
206 AVStream *st = cat->avf->streams[idx];
207 ConcatStream *cs = &cat->cur_file->streams[idx];
209 AVBSFContext *bsf;
210 int ret;
211
212 if (cat->auto_convert && st->codecpar->codec_id == AV_CODEC_ID_H264) {
213 if (!st->codecpar->extradata_size ||
214 (st->codecpar->extradata_size >= 3 && AV_RB24(st->codecpar->extradata) == 1) ||
215 (st->codecpar->extradata_size >= 4 && AV_RB32(st->codecpar->extradata) == 1))
216 return 0;
217 av_log(cat->avf, AV_LOG_INFO,
218 "Auto-inserting h264_mp4toannexb bitstream filter\n");
219 filter = av_bsf_get_by_name("h264_mp4toannexb");
220 if (!filter) {
221 av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb bitstream filter "
222 "required for H.264 streams\n");
224 }
225 ret = av_bsf_alloc(filter, &bsf);
226 if (ret < 0)
227 return ret;
228 cs->bsf = bsf;
229
230 ret = avcodec_parameters_copy(bsf->par_in, st->codecpar);
231 if (ret < 0)
232 return ret;
233
234 ret = av_bsf_init(bsf);
235 if (ret < 0)
236 return ret;
237
239 if (ret < 0)
240 return ret;
241 }
242 return 0;
243}
244
246{
248 AVStream *st;
249 int i, ret;
250
251 for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
253 st = avf->streams[i];
254 } else {
255 if (!(st = avformat_new_stream(avf, NULL)))
256 return AVERROR(ENOMEM);
257 }
258 if ((ret = copy_stream_props(st, cat->avf->streams[i])) < 0)
259 return ret;
260 cat->cur_file->streams[i].out_stream_index = i;
261 }
262 return 0;
263}
264
266{
268 AVStream *st;
269 int i, j, ret;
270
271 for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
272 st = cat->avf->streams[i];
273 for (j = 0; j < avf->nb_streams; j++) {
274 if (avf->streams[j]->id == st->id) {
276 "Match slave stream #%d with stream #%d id 0x%x\n",
277 i, j, st->id);
278 if ((ret = copy_stream_props(avf->streams[j], st)) < 0)
279 return ret;
280 cat->cur_file->streams[i].out_stream_index = j;
281 }
282 }
283 }
284 return 0;
285}
286
288{
291 int i, ret;
292
293 if (cat->cur_file->nb_streams >= cat->avf->nb_streams)
294 return 0;
295 map = av_realloc(cat->cur_file->streams,
296 cat->avf->nb_streams * sizeof(*map));
297 if (!map)
298 return AVERROR(ENOMEM);
299 cat->cur_file->streams = map;
300 memset(map + cat->cur_file->nb_streams, 0,
301 (cat->avf->nb_streams - cat->cur_file->nb_streams) * sizeof(*map));
302
303 for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
304 map[i].out_stream_index = -1;
305 if ((ret = detect_stream_specific(avf, i)) < 0)
306 return ret;
307 }
308 switch (cat->stream_match_mode) {
309 case MATCH_ONE_TO_ONE:
310 ret = match_streams_one_to_one(avf);
311 break;
312 case MATCH_EXACT_ID:
313 ret = match_streams_exact_id(avf);
314 break;
315 default:
316 ret = AVERROR_BUG;
317 }
318 if (ret < 0)
319 return ret;
320 cat->cur_file->nb_streams = cat->avf->nb_streams;
321 return 0;
322}
323
325{
326 if (file->user_duration != AV_NOPTS_VALUE)
327 return file->user_duration;
328 if (file->outpoint != AV_NOPTS_VALUE)
329 return av_sat_sub64(file->outpoint, file->file_inpoint);
330 if (avf->duration > 0)
331 return av_sat_sub64(avf->duration, file->file_inpoint - file->file_start_time);
332 if (file->next_dts != AV_NOPTS_VALUE)
333 return file->next_dts - file->file_inpoint;
334 return AV_NOPTS_VALUE;
335}
336
337/* opens the file and places it on the timeline, leaving the output streams alone */
338static int probe_file(AVFormatContext *avf, unsigned fileno)
339{
341 ConcatFile *file = &cat->files[fileno];
343 int ret;
344
345 if (cat->avf)
347
349 if (!cat->avf)
350 return AVERROR(ENOMEM);
351
352 cat->avf->flags |= avf->flags & ~AVFMT_FLAG_CUSTOM_IO;
353 cat->avf->interrupt_callback = avf->interrupt_callback;
354
355 if ((ret = ff_copy_whiteblacklists(cat->avf, avf)) < 0)
356 return ret;
357
358 ret = av_dict_copy(&options, file->options, 0);
359 if (ret < 0)
360 return ret;
361
362 if ((ret = avformat_open_input(&cat->avf, file->url, NULL, &options)) < 0 ||
363 (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
364 av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url);
367 return ret;
368 }
369 if (options) {
370 av_log(avf, AV_LOG_WARNING, "Unused options for '%s'.\n", file->url);
371 /* TODO log unused options once we have a proper string API */
373 }
374 cat->cur_file = file;
375 file->start_time = !fileno ? 0 :
376 cat->files[fileno - 1].start_time +
377 cat->files[fileno - 1].duration;
378 file->file_start_time = (cat->avf->start_time == AV_NOPTS_VALUE) ? 0 : cat->avf->start_time;
379 file->file_inpoint = (file->inpoint == AV_NOPTS_VALUE) ? file->file_start_time : file->inpoint;
380 file->duration = get_best_effort_duration(file, cat->avf);
381 return 0;
382}
383
384static int open_file(AVFormatContext *avf, unsigned fileno)
385{
387 ConcatFile *file = &cat->files[fileno];
388 int ret = probe_file(avf, fileno);
389
390 if (ret < 0)
391 return ret;
392 if (cat->segment_time_metadata) {
393 av_dict_set_int(&file->metadata, "lavf.concatdec.start_time", file->start_time, 0);
394 if (file->duration != AV_NOPTS_VALUE)
395 av_dict_set_int(&file->metadata, "lavf.concatdec.duration", file->duration, 0);
396 }
397
398 if ((ret = match_streams(avf)) < 0)
399 return ret;
400 if (file->inpoint != AV_NOPTS_VALUE) {
401 if ((ret = avformat_seek_file(cat->avf, -1, INT64_MIN, file->inpoint, file->inpoint, 0)) < 0)
402 return ret;
403 }
404 return 0;
405}
406
408{
410 unsigned i, j;
411
412 for (i = 0; i < cat->nb_files; i++) {
413 av_freep(&cat->files[i].url);
414 for (j = 0; j < cat->files[i].nb_streams; j++) {
415 if (cat->files[i].streams[j].bsf)
416 av_bsf_free(&cat->files[i].streams[j].bsf);
417 }
418 av_freep(&cat->files[i].streams);
419 av_dict_free(&cat->files[i].metadata);
420 av_dict_free(&cat->files[i].options);
421 }
422 if (cat->avf)
424 av_freep(&cat->files);
425 return 0;
426}
427
428#define MAX_ARGS 3
429#define NEEDS_UNSAFE (1 << 0)
430#define NEEDS_FILE (1 << 1)
431#define NEEDS_STREAM (1 << 2)
432
433typedef struct ParseSyntax {
434 const char *keyword;
436 uint8_t flags;
438
455
456static const ParseSyntax syntax[] = {
457 [DIR_FFCONCAT ] = { "ffconcat", "kk", 0 },
458 [DIR_FILE ] = { "file", "s", 0 },
459 [DIR_DURATION ] = { "duration", "d", NEEDS_FILE },
460 [DIR_INPOINT ] = { "inpoint", "d", NEEDS_FILE },
461 [DIR_OUTPOINT ] = { "outpoint", "d", NEEDS_FILE },
462 [DIR_FPMETA ] = { "file_packet_meta", "ks", NEEDS_FILE },
463 [DIR_FPMETAS ] = { "file_packet_metadata", "s", NEEDS_FILE },
464 [DIR_OPTION ] = { "option", "ks", NEEDS_FILE | NEEDS_UNSAFE },
465 [DIR_STREAM ] = { "stream", "", 0 },
466 [DIR_EXSID ] = { "exact_stream_id", "i", NEEDS_STREAM },
467 [DIR_STMETA ] = { "stream_meta", "ks", NEEDS_STREAM },
468 [DIR_STCODEC ] = { "stream_codec", "k", NEEDS_STREAM },
469 [DIR_STEDATA ] = { "stream_extradata", "k", NEEDS_STREAM },
470 [DIR_CHAPTER ] = { "chapter", "idd", 0 },
471};
472
474{
476 unsigned nb_files_alloc = 0;
477 AVBPrint bp;
478 uint8_t *cursor, *keyword;
479 ConcatFile *file = NULL;
480 AVStream *stream = NULL;
481 AVChapter *chapter = NULL;
482 unsigned line = 0, arg;
483 const ParseSyntax *dir;
484 char *arg_kw[MAX_ARGS];
485 char *arg_str[MAX_ARGS] = { 0 };
486 int64_t arg_int[MAX_ARGS];
487 int ret;
488
490
491 while ((ret = ff_read_line_to_bprint_overwrite(avf->pb, &bp)) >= 0) {
492 line++;
493 cursor = bp.str;
494 keyword = get_keyword(&cursor);
495 if (!*keyword || *keyword == '#')
496 continue;
497 for (dir = syntax; dir < syntax + FF_ARRAY_ELEMS(syntax); dir++)
498 if (!strcmp(dir->keyword, keyword))
499 break;
500 if (dir >= syntax + FF_ARRAY_ELEMS(syntax)) {
501 av_log(avf, AV_LOG_ERROR, "Line %d: unknown keyword '%s'\n",
502 line, keyword);
504 }
505
506 /* Flags check */
507 if ((dir->flags & NEEDS_UNSAFE) && cat->safe) {
508 av_log(avf, AV_LOG_ERROR, "Line %d: %s not allowed if safe\n", line, keyword);
510 }
511 if ((dir->flags & NEEDS_FILE) && !cat->nb_files) {
512 av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n", line, keyword);
514 }
515 if ((dir->flags & NEEDS_STREAM) && !avf->nb_streams) {
516 av_log(avf, AV_LOG_ERROR, "Line %d: %s without stream\n", line, keyword);
518 }
519
520 /* Arguments parsing */
521 for (arg = 0; arg < FF_ARRAY_ELEMS(dir->args) && dir->args[arg]; arg++) {
522 switch (dir->args[arg]) {
523 case 'd': /* duration */
524 arg_kw[arg] = get_keyword(&cursor);
525 ret = av_parse_time(&arg_int[arg], arg_kw[arg], 1);
526 if (ret < 0) {
527 av_log(avf, AV_LOG_ERROR, "Line %d: invalid duration '%s'\n",
528 line, arg_kw[arg]);
529 goto fail;
530 }
531 break;
532 case 'i': /* integer */
533 arg_int[arg] = strtol(get_keyword(&cursor), NULL, 0);
534 break;
535 case 'k': /* keyword */
536 arg_kw[arg] = get_keyword(&cursor);
537 break;
538 case 's': /* string */
539 av_assert0(!arg_str[arg]);
540 arg_str[arg] = av_get_token((const char **)&cursor, SPACE_CHARS);
541 if (!arg_str[arg])
542 FAIL(AVERROR(ENOMEM));
543 if (!*arg_str[arg]) {
544 av_log(avf, AV_LOG_ERROR, "Line %d: string required\n", line);
546 }
547 break;
548 default:
550 }
551 }
552
553 /* Directive action */
554 switch ((ParseDirective)(dir - syntax)) {
555
556 case DIR_FFCONCAT:
557 if (strcmp(arg_kw[0], "version") || strcmp(arg_kw[1], "1.0")) {
558 av_log(avf, AV_LOG_ERROR, "Line %d: invalid version\n", line);
560 }
561 break;
562
563 case DIR_FILE:
564 ret = add_file(avf, arg_str[0], &file, &nb_files_alloc);
565 arg_str[0] = NULL;
566 if (ret < 0)
567 goto fail;
568 break;
569
570 case DIR_DURATION:
571 file->user_duration = arg_int[0];
572 break;
573
574 case DIR_INPOINT:
575 file->inpoint = arg_int[0];
576 break;
577
578 case DIR_OUTPOINT:
579 file->outpoint = arg_int[0];
580 break;
581
582 case DIR_FPMETA:
583 ret = av_dict_set(&file->metadata, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
584 arg_str[1] = NULL;
585 if (ret < 0)
586 FAIL(ret);
587 break;
588
589 case DIR_FPMETAS:
590 if ((ret = av_dict_parse_string(&file->metadata, arg_str[0], "=", "", 0)) < 0) {
591 av_log(avf, AV_LOG_ERROR, "Line %d: failed to parse metadata string\n", line);
593 }
595 "'file_packet_metadata key=value:key=value' is deprecated, "
596 "use multiple 'file_packet_meta key value' instead\n");
597 av_freep(&arg_str[0]);
598 break;
599
600 case DIR_OPTION:
601 ret = av_dict_set(&file->options, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
602 arg_str[1] = NULL;
603 if (ret < 0)
604 FAIL(ret);
605 break;
606
607 case DIR_STREAM:
608 stream = avformat_new_stream(avf, NULL);
609 if (!stream)
610 FAIL(AVERROR(ENOMEM));
611 break;
612
613 case DIR_EXSID:
614 stream->id = arg_int[0];
615 break;
616 case DIR_STMETA:
617 ret = av_dict_set(&stream->metadata, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
618 arg_str[1] = NULL;
619 if (ret < 0)
620 FAIL(ret);
621 break;
622
623 case DIR_STCODEC: {
624 const AVCodecDescriptor *codec = avcodec_descriptor_get_by_name(arg_kw[0]);
625 if (!codec) {
626 av_log(avf, AV_LOG_ERROR, "Line %d: codec '%s' not found\n", line, arg_kw[0]);
628 }
629 stream->codecpar->codec_type = codec->type;
630 stream->codecpar->codec_id = codec->id;
631 break;
632 }
633
634 case DIR_STEDATA: {
635 int size = ff_hex_to_data(NULL, arg_kw[0]);
636 ret = ff_alloc_extradata(stream->codecpar, size);
637 if (ret < 0)
638 FAIL(ret);
639 ff_hex_to_data(stream->codecpar->extradata, arg_kw[0]);
640 break;
641 }
642
643 case DIR_CHAPTER:
644 chapter = avpriv_new_chapter(avf, arg_int[0], AV_TIME_BASE_Q,
645 arg_int[1], arg_int[2], NULL);
646 if (!chapter)
647 FAIL(ENOMEM);
648 break;
649
650 default:
652 }
653 }
654
655 if (!file) {
657 goto fail;
658 }
659
660 if (file->inpoint != AV_NOPTS_VALUE && file->outpoint != AV_NOPTS_VALUE) {
661 if (file->inpoint > file->outpoint ||
662 file->outpoint - (uint64_t)file->inpoint > INT64_MAX)
664 }
665
666fail:
667 for (arg = 0; arg < MAX_ARGS; arg++)
668 av_freep(&arg_str[arg]);
670 return ret == AVERROR_EOF ? 0 : ret;
671}
672
673static int compare_chapter_starts(const void *a, const void *b)
674{
675 const AVChapter *ca = *(const AVChapter *const *)a, *cb = *(const AVChapter *const *)b;
676
677 return av_compare_ts(ca->start, ca->time_base, cb->start, cb->time_base);
678}
679
681{
683 int64_t id = 0;
684
685 for (unsigned i = 0; i < avf->nb_chapters; i++)
686 id = FFMAX(id, av_sat_add64(avf->chapters[i]->id, 1));
687 for (unsigned i = 0; i < cat->nb_files; i++) {
688 ConcatFile *file = &cat->files[i];
689 AVDictionaryEntry *title;
690 AVChapter *chapter;
692 int ret = probe_file(avf, i);
693
694 if (ret < 0)
695 return ret;
696 if (file->duration != AV_NOPTS_VALUE)
697 end = av_sat_add64(file->start_time, file->duration);
698 if (end == INT64_MAX || id == INT64_MAX || (end != AV_NOPTS_VALUE && end < file->start_time))
699 return AVERROR_INVALIDDATA;
700 file->user_duration = file->duration;
701 title = av_dict_get(cat->avf->metadata, "title", NULL, 0);
702 chapter = avpriv_new_chapter(avf, id++, AV_TIME_BASE_Q, file->start_time, end,
703 title ? title->value : av_basename(file->url));
704 if (!chapter || (ret = av_dict_copy(&chapter->metadata, cat->avf->metadata, AV_DICT_DONT_OVERWRITE)) < 0)
705 return chapter ? ret : AVERROR(ENOMEM);
706 if (end == AV_NOPTS_VALUE) {
707 av_log(avf, AV_LOG_WARNING, "Duration of '%s' unknown, no chapters for the files after it\n", file->url);
708 break;
709 }
710 }
711 qsort(avf->chapters, avf->nb_chapters, sizeof(*avf->chapters), compare_chapter_starts);
712 return 0;
713}
714
716{
718 int64_t time = 0;
719 unsigned i;
720 int ret;
721
722 ret = concat_parse_script(avf);
723 if (ret < 0)
724 return ret;
725 if (!cat->nb_files) {
726 av_log(avf, AV_LOG_ERROR, "No files to concat\n");
727 return AVERROR_INVALIDDATA;
728 }
729 cat->stream_match_mode = avf->nb_streams ? MATCH_EXACT_ID :
731 if (cat->chapter_per_file && (ret = add_file_chapters(avf)) < 0)
732 return ret;
733
734 for (i = 0; i < cat->nb_files; i++) {
735 if (cat->files[i].start_time == AV_NOPTS_VALUE)
736 cat->files[i].start_time = time;
737 else
738 time = cat->files[i].start_time;
739 if (cat->files[i].user_duration == AV_NOPTS_VALUE) {
740 if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE ||
741 cat->files[i].outpoint - (uint64_t)cat->files[i].inpoint != av_sat_sub64(cat->files[i].outpoint, cat->files[i].inpoint)
742 )
743 break;
744 cat->files[i].user_duration = cat->files[i].outpoint - cat->files[i].inpoint;
745 }
746 cat->files[i].duration = cat->files[i].user_duration;
747 if (time + (uint64_t)cat->files[i].user_duration > INT64_MAX)
748 return AVERROR_INVALIDDATA;
749 time += cat->files[i].user_duration;
750 }
751 if (i == cat->nb_files) {
752 avf->duration = time;
753 cat->seekable = 1;
754 }
755
756 if ((ret = open_file(avf, 0)) < 0)
757 return ret;
758
759 return 0;
760}
761
763{
765 unsigned fileno = cat->cur_file - cat->files;
766
767 cat->cur_file->duration = get_best_effort_duration(cat->cur_file, cat->avf);
768
769 if (++fileno >= cat->nb_files) {
770 cat->eof = 1;
771 return AVERROR_EOF;
772 }
773 return open_file(avf, fileno);
774}
775
777{
778 int ret;
779
780 if (cs->bsf) {
781 ret = av_bsf_send_packet(cs->bsf, pkt);
782 if (ret < 0) {
783 av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb filter "
784 "failed to send input packet\n");
785 return ret;
786 }
787
788 while (!ret)
789 ret = av_bsf_receive_packet(cs->bsf, pkt);
790
791 if (ret < 0 && (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)) {
792 av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb filter "
793 "failed to receive output packet\n");
794 return ret;
795 }
796 }
797 return 0;
798}
799
800/* Returns true if the packet dts is greater or equal to the specified outpoint. */
802{
803 if (cat->cur_file->outpoint != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE) {
804 return av_compare_ts(pkt->dts, cat->avf->streams[pkt->stream_index]->time_base,
805 cat->cur_file->outpoint, AV_TIME_BASE_Q) >= 0;
806 }
807 return 0;
808}
809
811{
813 int ret;
815 ConcatStream *cs;
816 AVStream *st;
817 FFStream *sti;
818
819 if (cat->eof)
820 return AVERROR_EOF;
821
822 if (!cat->avf)
823 return AVERROR(EIO);
824
825 while (1) {
826 ret = av_read_frame(cat->avf, pkt);
827 if (ret == AVERROR_EOF) {
828 if ((ret = open_next_file(avf)) < 0)
829 return ret;
830 continue;
831 }
832 if (ret < 0)
833 return ret;
834 if ((ret = match_streams(avf)) < 0) {
835 return ret;
836 }
839 if ((ret = open_next_file(avf)) < 0)
840 return ret;
841 continue;
842 }
843 cs = &cat->cur_file->streams[pkt->stream_index];
844 if (cs->out_stream_index < 0) {
846 continue;
847 }
848 break;
849 }
850 if ((ret = filter_packet(avf, cs, pkt)) < 0)
851 return ret;
852
853 st = cat->avf->streams[pkt->stream_index];
854 sti = ffstream(st);
855 av_log(avf, AV_LOG_DEBUG, "file:%d stream:%d pts:%s pts_time:%s dts:%s dts_time:%s",
856 (unsigned)(cat->cur_file - cat->files), pkt->stream_index,
857 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
858 av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
859
860 delta = av_rescale_q(cat->cur_file->start_time - cat->cur_file->file_inpoint,
862 cat->avf->streams[pkt->stream_index]->time_base);
863 if (pkt->pts != AV_NOPTS_VALUE)
864 pkt->pts += delta;
865 if (pkt->dts != AV_NOPTS_VALUE)
866 pkt->dts += delta;
867 av_log(avf, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
868 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
869 av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
870 if (cat->cur_file->metadata) {
871 size_t metadata_len;
872 char* packed_metadata = av_packet_pack_dictionary(cat->cur_file->metadata, &metadata_len);
873 if (!packed_metadata)
874 return AVERROR(ENOMEM);
876 packed_metadata, metadata_len);
877 if (ret < 0) {
878 av_freep(&packed_metadata);
879 return ret;
880 }
881 }
882
883 if (cat->cur_file->duration == AV_NOPTS_VALUE && sti->cur_dts != AV_NOPTS_VALUE) {
884 int64_t next_dts = av_rescale_q(sti->cur_dts, st->time_base, AV_TIME_BASE_Q);
885 if (cat->cur_file->next_dts == AV_NOPTS_VALUE || next_dts > cat->cur_file->next_dts) {
886 cat->cur_file->next_dts = next_dts;
887 }
888 }
889
890 pkt->stream_index = cs->out_stream_index;
891 return 0;
892}
893
894static int try_seek(AVFormatContext *avf, int stream,
895 int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
896{
898 int64_t t0 = cat->cur_file->start_time - cat->cur_file->file_inpoint;
899
900 ts -= t0;
901 min_ts = min_ts == INT64_MIN ? INT64_MIN : min_ts - t0;
902 max_ts = max_ts == INT64_MAX ? INT64_MAX : max_ts - t0;
903 if (stream >= 0) {
904 if (stream >= cat->avf->nb_streams)
905 return AVERROR(EIO);
906 ff_rescale_interval(AV_TIME_BASE_Q, cat->avf->streams[stream]->time_base,
907 &min_ts, &ts, &max_ts);
908 }
909 return avformat_seek_file(cat->avf, stream, min_ts, ts, max_ts, flags);
910}
911
912static int real_seek(AVFormatContext *avf, int stream,
913 int64_t min_ts, int64_t ts, int64_t max_ts, int flags, AVFormatContext *cur_avf)
914{
916 int ret, left, right;
917
918 if (stream >= 0) {
919 if (stream >= avf->nb_streams)
920 return AVERROR(EINVAL);
922 &min_ts, &ts, &max_ts);
923 }
924
925 left = 0;
926 right = cat->nb_files;
927
928 /* Always support seek to start */
929 if (ts <= 0)
930 right = 1;
931 else if (!cat->seekable)
932 return AVERROR(ESPIPE); /* XXX: can we use it? */
933
934 while (right - left > 1) {
935 int mid = (left + right) / 2;
936 if (ts < cat->files[mid].start_time)
937 right = mid;
938 else
939 left = mid;
940 }
941
942 if (cat->cur_file != &cat->files[left]) {
943 if ((ret = open_file(avf, left)) < 0)
944 return ret;
945 } else {
946 cat->avf = cur_avf;
947 }
948
949 ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
950 if (ret < 0 &&
951 left < cat->nb_files - 1 &&
952 cat->files[left + 1].start_time < max_ts) {
953 if (cat->cur_file == &cat->files[left])
954 cat->avf = NULL;
955 if ((ret = open_file(avf, left + 1)) < 0)
956 return ret;
957 ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
958 }
959 return ret;
960}
961
962static int concat_seek(AVFormatContext *avf, int stream,
963 int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
964{
966 ConcatFile *cur_file_saved = cat->cur_file;
967 AVFormatContext *cur_avf_saved = cat->avf;
968 int ret;
969
971 return AVERROR(ENOSYS);
972 cat->avf = NULL;
973 if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags, cur_avf_saved)) < 0) {
974 if (cat->cur_file != cur_file_saved) {
975 if (cat->avf)
977 }
978 cat->avf = cur_avf_saved;
979 cat->cur_file = cur_file_saved;
980 } else {
981 if (cat->cur_file != cur_file_saved) {
982 avformat_close_input(&cur_avf_saved);
983 }
984 cat->eof = 0;
985 }
986 return ret;
987}
988
989#define OFFSET(x) offsetof(ConcatContext, x)
990#define DEC AV_OPT_FLAG_DECODING_PARAM
991
992static const AVOption options[] = {
993 { "safe", "enable safe mode",
994 OFFSET(safe), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
995 { "auto_convert", "automatically convert bitstream format",
996 OFFSET(auto_convert), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
997 { "segment_time_metadata", "output file segment start time and duration as packet metadata",
998 OFFSET(segment_time_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
999 { "chapter_per_file", "add a chapter for each file, opening them all up front to learn their durations",
1000 OFFSET(chapter_per_file), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
1001 { NULL }
1002};
1003
1004static const AVClass concat_class = {
1005 .class_name = "concat demuxer",
1006 .item_name = av_default_item_name,
1007 .option = options,
1008 .version = LIBAVUTIL_VERSION_INT,
1009};
1010
1011
1013 .p.name = "concat",
1014 .p.long_name = NULL_IF_CONFIG_SMALL("Virtual concatenation script"),
1015 .p.priv_class = &concat_class,
1016 .priv_data_size = sizeof(ConcatContext),
1017 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
1022 .read_seek2 = concat_seek,
1023};
static int probe(const AVProbeData *p)
Definition act.c:39
const FFInputFormat ff_concat_demuxer
Definition concatdec.c:1012
#define attribute_nonstring
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src)
Copies the whilelists from one context to the other.
Definition avformat.c:884
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:839
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:485
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition avformat.h:2621
#define AVSEEK_FLAG_FRAME
seeking based on frame number
Definition avformat.h:2623
#define AVFMT_FLAG_CUSTOM_IO
The caller has supplied a custom AVIOContext, don't avio_close() it.
Definition avformat.h:1496
const char * avio_find_protocol_name(const char *url)
Return the name of the protocol that will handle the passed URL.
Definition avio.c:732
int64_t ff_read_line_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp)
Read a whole line of text from AVIOContext to an AVBPrint buffer overwriting its contents.
Definition aviobuf.c:825
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:68
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Definition codec_par.c:107
#define av_sat_sub64
Definition common.h:142
#define av_sat_add64
Definition common.h:139
static int64_t concat_seek(URLContext *h, int64_t pos, int whence)
Definition concat.c:168
static int concat_read_header(AVFormatContext *avf)
Definition concatdec.c:715
#define NEEDS_FILE
Definition concatdec.c:430
static int match_streams(AVFormatContext *avf)
Definition concatdec.c:287
static int safe_filename(const char *f)
Definition concatdec.c:96
static const ParseSyntax syntax[]
Definition concatdec.c:456
static char * get_keyword(uint8_t **cursor)
Definition concatdec.c:85
#define MAX_ARGS
Definition concatdec.c:428
static int concat_probe(const AVProbeData *probe)
Definition concatdec.c:79
#define NEEDS_STREAM
Definition concatdec.c:431
ParseDirective
Definition concatdec.c:439
@ DIR_FPMETA
Definition concatdec.c:445
@ DIR_STCODEC
Definition concatdec.c:451
@ DIR_INPOINT
Definition concatdec.c:443
@ DIR_FPMETAS
Definition concatdec.c:446
@ DIR_STMETA
Definition concatdec.c:450
@ DIR_OUTPOINT
Definition concatdec.c:444
@ DIR_EXSID
Definition concatdec.c:449
@ DIR_FFCONCAT
Definition concatdec.c:440
@ DIR_STREAM
Definition concatdec.c:448
@ DIR_OPTION
Definition concatdec.c:447
@ DIR_STEDATA
Definition concatdec.c:452
@ DIR_DURATION
Definition concatdec.c:442
@ DIR_FILE
Definition concatdec.c:441
@ DIR_CHAPTER
Definition concatdec.c:453
static int copy_stream_props(AVStream *st, AVStream *source_st)
Definition concatdec.c:176
static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
Definition concatdec.c:810
static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile, unsigned *nb_files_alloc)
Definition concatdec.c:117
static int packet_after_outpoint(ConcatContext *cat, AVPacket *pkt)
Definition concatdec.c:801
static const AVClass concat_class
Definition concatdec.c:1004
static int try_seek(AVFormatContext *avf, int stream, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Definition concatdec.c:894
static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
Definition concatdec.c:776
#define NEEDS_UNSAFE
Definition concatdec.c:429
static int open_next_file(AVFormatContext *avf)
Definition concatdec.c:762
#define FAIL(retcode)
Definition concatdec.c:115
static int add_file_chapters(AVFormatContext *avf)
Definition concatdec.c:680
static int concat_seek(AVFormatContext *avf, int stream, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Definition concatdec.c:962
static int match_streams_exact_id(AVFormatContext *avf)
Definition concatdec.c:265
static int concat_read_close(AVFormatContext *avf)
Definition concatdec.c:407
static int probe_file(AVFormatContext *avf, unsigned fileno)
Definition concatdec.c:338
static int concat_parse_script(AVFormatContext *avf)
Definition concatdec.c:473
#define OFFSET(x)
Definition concatdec.c:989
static int open_file(AVFormatContext *avf, unsigned fileno)
Definition concatdec.c:384
static int real_seek(AVFormatContext *avf, int stream, int64_t min_ts, int64_t ts, int64_t max_ts, int flags, AVFormatContext *cur_avf)
Definition concatdec.c:912
static int detect_stream_specific(AVFormatContext *avf, int idx)
Definition concatdec.c:203
static int compare_chapter_starts(const void *a, const void *b)
Definition concatdec.c:673
static int64_t get_best_effort_duration(ConcatFile *file, AVFormatContext *avf)
Definition concatdec.c:324
static int match_streams_one_to_one(AVFormatContext *avf)
Definition concatdec.c:245
ConcatMatchMode
Definition concatdec.c:38
@ MATCH_EXACT_ID
Definition concatdec.c:40
@ MATCH_ONE_TO_ONE
Definition concatdec.c:39
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition demux_utils.c:46
void ff_rescale_interval(AVRational tb_in, AVRational tb_out, int64_t *min_ts, int64_t *ts, int64_t *max_ts)
Rescales a timestamp and the endpoints of an interval to which the temstamp belongs,...
Definition seek.c:752
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition demux.h:35
static AVPacket * pkt
#define SPACE_CHARS
static int safe_filename(const char *f, int allow_subdir)
static int64_t start_time
Definition ffplay.c:398
static unsigned int nb_streams
Definition ffprobe.c:353
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
#define fail
Definition test.h:479
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
void av_bsf_free(AVBSFContext **pctx)
Free a bitstream filter context and everything associated with it; write NULL into the supplied point...
Definition bsf.c:47
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set.
Definition bsf.c:147
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
Allocate a context for a given bitstream filter.
Definition bsf.c:99
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition bsf.c:228
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition bsf.c:200
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
const AVCodecDescriptor * avcodec_descriptor_get_by_name(const char *name)
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_PKT_DATA_STRINGS_METADATA
A list of zero terminated key/value strings.
Definition packet.h:169
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
uint8_t * av_packet_pack_dictionary(const AVDictionary *dict, size_t *size)
Pack a dictionary for use in side_data.
Definition packet.c:319
int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t *data, size_t size)
Wrap an existing array as a packet side data.
Definition packet.c:197
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition options.c:165
int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Seek to timestamp ts.
Definition seek.c:664
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition demux.c:1588
int avformat_open_input(AVFormatContext **ps, const char *url, const AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
Definition demux.c:231
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information.
Definition demux.c:2616
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition demux.c:377
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:234
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition dict.h:81
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition dict.c:210
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition dict.c:177
#define AVERROR_DECODER_NOT_FOUND
Decoder not found.
Definition error.h:54
#define AVERROR_BSF_NOT_FOUND
Bitstream filter not found.
Definition error.h:51
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare two timestamps each in its own time base.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
char * av_get_token(const char **buf, const char *term)
Unescape the given string until a non escaped terminating char, and return the token corresponding to...
Definition avstring.c:143
const char * av_basename(const char *path)
Thread safe basename.
Definition avstring.c:253
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
int a
const VDPAUPixFmtMap * map
#define b
Definition input.c:43
#define AV_RB32(p)
#define AV_RB24(x)
const char * arg
Definition jacosubdec.c:65
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition utils.c:495
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition utils.c:237
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:97
static av_cold int read_close(AVFormatContext *ctx)
Definition libcdio.c:143
#define DEC
Definition librsvgdec.c:149
#define FFMAX(a, b)
Definition macros.h:47
Memory handling functions.
#define av_realloc(p, s)
Definition ops_static.c:54
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
Definition parseutils.c:592
misc parsing utilities
#define FF_ARRAY_ELEMS(a)
The bitstream filter state.
Definition bsf.h:68
AVCodecParameters * par_in
Parameters of the input stream.
Definition bsf.h:90
AVCodecParameters * par_out
Parameters of the output stream.
Definition bsf.h:96
int64_t id
unique ID to identify the chapter
Definition avformat.h:1297
int64_t start
Definition avformat.h:1299
AVDictionary * metadata
Definition avformat.h:1300
AVRational time_base
time base in which the start/end timestamps are specified
Definition avformat.h:1298
Describe the class of an AVClass context structure.
Definition log.h:76
This struct describes the properties of a single codec described by an AVCodecID.
Definition codec_desc.h:38
enum AVCodecID id
Definition codec_desc.h:39
enum AVMediaType type
Definition codec_desc.h:40
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
char * value
Definition dict.h:92
Format I/O context.
Definition avformat.h:1337
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition avformat.h:1393
AVIOContext * pb
I/O context.
Definition avformat.h:1379
int flags
Flags modifying the (de)muxer behaviour.
Definition avformat.h:1488
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition avformat.h:1622
char * url
input or output URL.
Definition avformat.h:1453
unsigned int nb_chapters
Number of chapters in AVChapter array.
Definition avformat.h:1437
AVChapter ** chapters
Definition avformat.h:1438
void * priv_data
Format private data.
Definition avformat.h:1365
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1405
int64_t duration
Duration of the stream, in AV_TIME_BASE fractional seconds.
Definition avformat.h:1472
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:473
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:846
AVDictionary * metadata
Definition avformat.h:848
int id
Format-specific stream ID.
Definition avformat.h:780
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:857
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:807
AVRational r_frame_rate
Real base framerate of the stream.
Definition avformat.h:902
ConcatFile * cur_file
Definition concatdec.c:67
ConcatMatchMode stream_match_mode
Definition concatdec.c:73
int chapter_per_file
Definition concatdec.c:76
ConcatFile * files
Definition concatdec.c:66
unsigned nb_files
Definition concatdec.c:68
int segment_time_metadata
Definition concatdec.c:75
AVFormatContext * avf
Definition concatdec.c:69
unsigned auto_convert
Definition concatdec.c:74
int64_t file_start_time
Definition concatdec.c:51
int64_t outpoint
Definition concatdec.c:58
char * url
Definition concatdec.c:49
int64_t next_dts
Definition concatdec.c:55
int64_t user_duration
Definition concatdec.c:54
int64_t inpoint
Definition concatdec.c:57
ConcatStream * streams
Definition concatdec.c:56
AVDictionary * metadata
Definition concatdec.c:59
int64_t duration
Definition concatdec.c:53
int64_t start_time
Definition concatdec.c:50
int64_t file_inpoint
Definition concatdec.c:52
AVDictionary * options
Definition concatdec.c:60
int nb_streams
Definition concatdec.c:61
AVBSFContext * bsf
Definition concatdec.c:44
int out_stream_index
Definition concatdec.c:45
int64_t cur_dts
Definition internal.h:360
const char * keyword
Definition concatdec.c:434
uint8_t flags
Definition concatdec.c:436
attribute_nonstring char args[MAX_ARGS]
Definition concatdec.c:435
#define av_free(p)
#define av_freep(p)
#define av_log(a,...)
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
timestamp utils, mostly useful for debugging/logging purposes
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition timestamp.h:54
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition timestamp.h:83
int size
int ff_make_absolute_url(char *buf, int size, const char *base, const char *rel)
Convert a relative url into an absolute url, given a base url.
Definition url.c:321
unbuffered private I/O API
static double cb(void *priv, double x, double y)
Definition vf_geq.c:247
float delta
#define cat(a, bpp, b)
Definition vp9dsp_init.h:32