FFmpeg
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 
21 #include "libavutil/avstring.h"
22 #include "libavutil/avassert.h"
23 #include "libavutil/bprint.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/parseutils.h"
27 #include "libavutil/timestamp.h"
28 #include "libavcodec/codec_desc.h"
29 #include "libavcodec/bsf.h"
30 #include "avformat.h"
31 #include "avio_internal.h"
32 #include "demux.h"
33 #include "internal.h"
34 #include "url.h"
35 
36 typedef enum ConcatMatchMode {
40 
41 typedef struct ConcatStream {
44 } ConcatStream;
45 
46 typedef struct {
47  char *url;
48  int64_t start_time;
49  int64_t file_start_time;
50  int64_t file_inpoint;
51  int64_t duration;
52  int64_t user_duration;
53  int64_t next_dts;
55  int64_t inpoint;
56  int64_t outpoint;
60 } ConcatFile;
61 
62 typedef struct {
63  AVClass *class;
66  unsigned nb_files;
68  int safe;
69  int seekable;
70  int eof;
72  unsigned auto_convert;
75 
76 static int concat_probe(const AVProbeData *probe)
77 {
78  return memcmp(probe->buf, "ffconcat version 1.0", 20) ?
80 }
81 
82 static char *get_keyword(uint8_t **cursor)
83 {
84  char *ret = *cursor += strspn(*cursor, SPACE_CHARS);
85  *cursor += strcspn(*cursor, SPACE_CHARS);
86  if (**cursor) {
87  *((*cursor)++) = 0;
88  *cursor += strspn(*cursor, SPACE_CHARS);
89  }
90  return ret;
91 }
92 
93 static int safe_filename(const char *f)
94 {
95  const char *start = f;
96 
97  for (; *f; f++) {
98  /* A-Za-z0-9_- */
99  if (!((unsigned)((*f | 32) - 'a') < 26 ||
100  (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) {
101  if (f == start)
102  return 0;
103  else if (*f == '/')
104  start = f + 1;
105  else if (*f != '.')
106  return 0;
107  }
108  }
109  return 1;
110 }
111 
112 #define FAIL(retcode) do { ret = (retcode); goto fail; } while(0)
113 
114 static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
115  unsigned *nb_files_alloc)
116 {
117  ConcatContext *cat = avf->priv_data;
118  ConcatFile *file;
119  char *url = NULL;
120  const char *proto;
121  const char *ptr;
122  size_t url_len;
123  int ret;
124 
125  if (cat->safe && !safe_filename(filename)) {
126  av_log(avf, AV_LOG_ERROR, "Unsafe file name '%s'\n", filename);
127  FAIL(AVERROR(EPERM));
128  }
129 
130  proto = avio_find_protocol_name(filename);
131  if (proto && av_strstart(filename, proto, &ptr) &&
132  (*ptr == ':' || *ptr == ',')) {
133  url = filename;
134  filename = NULL;
135  } else {
136  url_len = strlen(avf->url) + strlen(filename) + 16;
137  if (!(url = av_malloc(url_len)))
138  FAIL(AVERROR(ENOMEM));
139  ff_make_absolute_url(url, url_len, avf->url, filename);
140  av_freep(&filename);
141  }
142 
143  if (cat->nb_files >= *nb_files_alloc) {
144  size_t n = FFMAX(*nb_files_alloc * 2, 16);
145  ConcatFile *new_files;
146  if (n <= cat->nb_files || n > SIZE_MAX / sizeof(*cat->files) ||
147  !(new_files = av_realloc(cat->files, n * sizeof(*cat->files))))
148  FAIL(AVERROR(ENOMEM));
149  cat->files = new_files;
150  *nb_files_alloc = n;
151  }
152 
153  file = &cat->files[cat->nb_files++];
154  memset(file, 0, sizeof(*file));
155  *rfile = file;
156 
157  file->url = url;
158  file->start_time = AV_NOPTS_VALUE;
159  file->duration = AV_NOPTS_VALUE;
160  file->next_dts = AV_NOPTS_VALUE;
161  file->inpoint = AV_NOPTS_VALUE;
162  file->outpoint = AV_NOPTS_VALUE;
164 
165  return 0;
166 
167 fail:
168  av_free(url);
169  av_free(filename);
170  return ret;
171 }
172 
173 static int copy_stream_props(AVStream *st, AVStream *source_st)
174 {
175  int ret;
176 
177  if (st->codecpar->codec_id || !source_st->codecpar->codec_id) {
178  if (st->codecpar->extradata_size < source_st->codecpar->extradata_size) {
180  source_st->codecpar->extradata_size);
181  if (ret < 0)
182  return ret;
183  }
184  if (source_st->codecpar->extradata_size)
185  memcpy(st->codecpar->extradata, source_st->codecpar->extradata,
186  source_st->codecpar->extradata_size);
187  return 0;
188  }
189  if ((ret = avcodec_parameters_copy(st->codecpar, source_st->codecpar)) < 0)
190  return ret;
191  st->r_frame_rate = source_st->r_frame_rate;
192  st->avg_frame_rate = source_st->avg_frame_rate;
193  st->sample_aspect_ratio = source_st->sample_aspect_ratio;
194  avpriv_set_pts_info(st, 64, source_st->time_base.num, source_st->time_base.den);
195 
196  av_dict_copy(&st->metadata, source_st->metadata, 0);
197  return 0;
198 }
199 
200 static int detect_stream_specific(AVFormatContext *avf, int idx)
201 {
202  ConcatContext *cat = avf->priv_data;
203  AVStream *st = cat->avf->streams[idx];
204  ConcatStream *cs = &cat->cur_file->streams[idx];
205  const AVBitStreamFilter *filter;
206  AVBSFContext *bsf;
207  int ret;
208 
209  if (cat->auto_convert && st->codecpar->codec_id == AV_CODEC_ID_H264) {
210  if (!st->codecpar->extradata_size ||
211  (st->codecpar->extradata_size >= 3 && AV_RB24(st->codecpar->extradata) == 1) ||
212  (st->codecpar->extradata_size >= 4 && AV_RB32(st->codecpar->extradata) == 1))
213  return 0;
214  av_log(cat->avf, AV_LOG_INFO,
215  "Auto-inserting h264_mp4toannexb bitstream filter\n");
216  filter = av_bsf_get_by_name("h264_mp4toannexb");
217  if (!filter) {
218  av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb bitstream filter "
219  "required for H.264 streams\n");
220  return AVERROR_BSF_NOT_FOUND;
221  }
222  ret = av_bsf_alloc(filter, &bsf);
223  if (ret < 0)
224  return ret;
225  cs->bsf = bsf;
226 
228  if (ret < 0)
229  return ret;
230 
231  ret = av_bsf_init(bsf);
232  if (ret < 0)
233  return ret;
234 
236  if (ret < 0)
237  return ret;
238  }
239  return 0;
240 }
241 
243 {
244  ConcatContext *cat = avf->priv_data;
245  AVStream *st;
246  int i, ret;
247 
248  for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
249  if (i < avf->nb_streams) {
250  st = avf->streams[i];
251  } else {
252  if (!(st = avformat_new_stream(avf, NULL)))
253  return AVERROR(ENOMEM);
254  }
255  if ((ret = copy_stream_props(st, cat->avf->streams[i])) < 0)
256  return ret;
257  cat->cur_file->streams[i].out_stream_index = i;
258  }
259  return 0;
260 }
261 
263 {
264  ConcatContext *cat = avf->priv_data;
265  AVStream *st;
266  int i, j, ret;
267 
268  for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
269  st = cat->avf->streams[i];
270  for (j = 0; j < avf->nb_streams; j++) {
271  if (avf->streams[j]->id == st->id) {
272  av_log(avf, AV_LOG_VERBOSE,
273  "Match slave stream #%d with stream #%d id 0x%x\n",
274  i, j, st->id);
275  if ((ret = copy_stream_props(avf->streams[j], st)) < 0)
276  return ret;
277  cat->cur_file->streams[i].out_stream_index = j;
278  }
279  }
280  }
281  return 0;
282 }
283 
285 {
286  ConcatContext *cat = avf->priv_data;
287  ConcatStream *map;
288  int i, ret;
289 
290  if (cat->cur_file->nb_streams >= cat->avf->nb_streams)
291  return 0;
292  map = av_realloc(cat->cur_file->streams,
293  cat->avf->nb_streams * sizeof(*map));
294  if (!map)
295  return AVERROR(ENOMEM);
296  cat->cur_file->streams = map;
297  memset(map + cat->cur_file->nb_streams, 0,
298  (cat->avf->nb_streams - cat->cur_file->nb_streams) * sizeof(*map));
299 
300  for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
301  map[i].out_stream_index = -1;
302  if ((ret = detect_stream_specific(avf, i)) < 0)
303  return ret;
304  }
305  switch (cat->stream_match_mode) {
306  case MATCH_ONE_TO_ONE:
308  break;
309  case MATCH_EXACT_ID:
311  break;
312  default:
313  ret = AVERROR_BUG;
314  }
315  if (ret < 0)
316  return ret;
317  cat->cur_file->nb_streams = cat->avf->nb_streams;
318  return 0;
319 }
320 
322 {
323  if (file->user_duration != AV_NOPTS_VALUE)
324  return file->user_duration;
325  if (file->outpoint != AV_NOPTS_VALUE)
326  return av_sat_sub64(file->outpoint, file->file_inpoint);
327  if (avf->duration > 0)
328  return avf->duration - (file->file_inpoint - file->file_start_time);
329  if (file->next_dts != AV_NOPTS_VALUE)
330  return file->next_dts - file->file_inpoint;
331  return AV_NOPTS_VALUE;
332 }
333 
334 static int open_file(AVFormatContext *avf, unsigned fileno)
335 {
336  ConcatContext *cat = avf->priv_data;
337  ConcatFile *file = &cat->files[fileno];
339  int ret;
340 
341  if (cat->avf)
342  avformat_close_input(&cat->avf);
343 
344  cat->avf = avformat_alloc_context();
345  if (!cat->avf)
346  return AVERROR(ENOMEM);
347 
348  cat->avf->flags |= avf->flags & ~AVFMT_FLAG_CUSTOM_IO;
349  cat->avf->interrupt_callback = avf->interrupt_callback;
350 
351  if ((ret = ff_copy_whiteblacklists(cat->avf, avf)) < 0)
352  return ret;
353 
354  ret = av_dict_copy(&options, file->options, 0);
355  if (ret < 0)
356  return ret;
357 
358  if ((ret = avformat_open_input(&cat->avf, file->url, NULL, &options)) < 0 ||
359  (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
360  av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url);
362  avformat_close_input(&cat->avf);
363  return ret;
364  }
365  if (options) {
366  av_log(avf, AV_LOG_WARNING, "Unused options for '%s'.\n", file->url);
367  /* TODO log unused options once we have a proper string API */
369  }
370  cat->cur_file = file;
371  file->start_time = !fileno ? 0 :
372  cat->files[fileno - 1].start_time +
373  cat->files[fileno - 1].duration;
374  file->file_start_time = (cat->avf->start_time == AV_NOPTS_VALUE) ? 0 : cat->avf->start_time;
375  file->file_inpoint = (file->inpoint == AV_NOPTS_VALUE) ? file->file_start_time : file->inpoint;
376  file->duration = get_best_effort_duration(file, cat->avf);
377 
378  if (cat->segment_time_metadata) {
379  av_dict_set_int(&file->metadata, "lavf.concatdec.start_time", file->start_time, 0);
380  if (file->duration != AV_NOPTS_VALUE)
381  av_dict_set_int(&file->metadata, "lavf.concatdec.duration", file->duration, 0);
382  }
383 
384  if ((ret = match_streams(avf)) < 0)
385  return ret;
386  if (file->inpoint != AV_NOPTS_VALUE) {
387  if ((ret = avformat_seek_file(cat->avf, -1, INT64_MIN, file->inpoint, file->inpoint, 0)) < 0)
388  return ret;
389  }
390  return 0;
391 }
392 
394 {
395  ConcatContext *cat = avf->priv_data;
396  unsigned i, j;
397 
398  for (i = 0; i < cat->nb_files; i++) {
399  av_freep(&cat->files[i].url);
400  for (j = 0; j < cat->files[i].nb_streams; j++) {
401  if (cat->files[i].streams[j].bsf)
402  av_bsf_free(&cat->files[i].streams[j].bsf);
403  }
404  av_freep(&cat->files[i].streams);
405  av_dict_free(&cat->files[i].metadata);
406  av_dict_free(&cat->files[i].options);
407  }
408  if (cat->avf)
409  avformat_close_input(&cat->avf);
410  av_freep(&cat->files);
411  return 0;
412 }
413 
414 #define MAX_ARGS 3
415 #define NEEDS_UNSAFE (1 << 0)
416 #define NEEDS_FILE (1 << 1)
417 #define NEEDS_STREAM (1 << 2)
418 
419 typedef struct ParseSyntax {
420  const char *keyword;
421  char args[MAX_ARGS];
422  uint8_t flags;
423 } ParseSyntax;
424 
425 typedef enum ParseDirective {
441 
442 static const ParseSyntax syntax[] = {
443  [DIR_FFCONCAT ] = { "ffconcat", "kk", 0 },
444  [DIR_FILE ] = { "file", "s", 0 },
445  [DIR_DURATION ] = { "duration", "d", NEEDS_FILE },
446  [DIR_INPOINT ] = { "inpoint", "d", NEEDS_FILE },
447  [DIR_OUTPOINT ] = { "outpoint", "d", NEEDS_FILE },
448  [DIR_FPMETA ] = { "file_packet_meta", "ks", NEEDS_FILE },
449  [DIR_FPMETAS ] = { "file_packet_metadata", "s", NEEDS_FILE },
450  [DIR_OPTION ] = { "option", "ks", NEEDS_FILE | NEEDS_UNSAFE },
451  [DIR_STREAM ] = { "stream", "", 0 },
452  [DIR_EXSID ] = { "exact_stream_id", "i", NEEDS_STREAM },
453  [DIR_STMETA ] = { "stream_meta", "ks", NEEDS_STREAM },
454  [DIR_STCODEC ] = { "stream_codec", "k", NEEDS_STREAM },
455  [DIR_STEDATA ] = { "stream_extradata", "k", NEEDS_STREAM },
456  [DIR_CHAPTER ] = { "chapter", "idd", 0 },
457 };
458 
460 {
461  ConcatContext *cat = avf->priv_data;
462  unsigned nb_files_alloc = 0;
463  AVBPrint bp;
464  uint8_t *cursor, *keyword;
465  ConcatFile *file = NULL;
466  AVStream *stream = NULL;
467  AVChapter *chapter = NULL;
468  unsigned line = 0, arg;
469  const ParseSyntax *dir;
470  char *arg_kw[MAX_ARGS];
471  char *arg_str[MAX_ARGS] = { 0 };
472  int64_t arg_int[MAX_ARGS];
473  int ret;
474 
476 
477  while ((ret = ff_read_line_to_bprint_overwrite(avf->pb, &bp)) >= 0) {
478  line++;
479  cursor = bp.str;
480  keyword = get_keyword(&cursor);
481  if (!*keyword || *keyword == '#')
482  continue;
483  for (dir = syntax; dir < syntax + FF_ARRAY_ELEMS(syntax); dir++)
484  if (!strcmp(dir->keyword, keyword))
485  break;
486  if (dir >= syntax + FF_ARRAY_ELEMS(syntax)) {
487  av_log(avf, AV_LOG_ERROR, "Line %d: unknown keyword '%s'\n",
488  line, keyword);
490  }
491 
492  /* Flags check */
493  if ((dir->flags & NEEDS_UNSAFE) && cat->safe) {
494  av_log(avf, AV_LOG_ERROR, "Line %d: %s not allowed if safe\n", line, keyword);
496  }
497  if ((dir->flags & NEEDS_FILE) && !cat->nb_files) {
498  av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n", line, keyword);
500  }
501  if ((dir->flags & NEEDS_STREAM) && !avf->nb_streams) {
502  av_log(avf, AV_LOG_ERROR, "Line %d: %s without stream\n", line, keyword);
504  }
505 
506  /* Arguments parsing */
507  for (arg = 0; arg < FF_ARRAY_ELEMS(dir->args) && dir->args[arg]; arg++) {
508  switch (dir->args[arg]) {
509  case 'd': /* duration */
510  arg_kw[arg] = get_keyword(&cursor);
511  ret = av_parse_time(&arg_int[arg], arg_kw[arg], 1);
512  if (ret < 0) {
513  av_log(avf, AV_LOG_ERROR, "Line %d: invalid duration '%s'\n",
514  line, arg_kw[arg]);
515  goto fail;
516  }
517  break;
518  case 'i': /* integer */
519  arg_int[arg] = strtol(get_keyword(&cursor), NULL, 0);
520  break;
521  case 'k': /* keyword */
522  arg_kw[arg] = get_keyword(&cursor);
523  break;
524  case 's': /* string */
525  av_assert0(!arg_str[arg]);
526  arg_str[arg] = av_get_token((const char **)&cursor, SPACE_CHARS);
527  if (!arg_str[arg])
528  FAIL(AVERROR(ENOMEM));
529  if (!*arg_str[arg]) {
530  av_log(avf, AV_LOG_ERROR, "Line %d: string required\n", line);
532  }
533  break;
534  default:
535  FAIL(AVERROR_BUG);
536  }
537  }
538 
539  /* Directive action */
540  switch ((ParseDirective)(dir - syntax)) {
541 
542  case DIR_FFCONCAT:
543  if (strcmp(arg_kw[0], "version") || strcmp(arg_kw[1], "1.0")) {
544  av_log(avf, AV_LOG_ERROR, "Line %d: invalid version\n", line);
546  }
547  break;
548 
549  case DIR_FILE:
550  ret = add_file(avf, arg_str[0], &file, &nb_files_alloc);
551  arg_str[0] = NULL;
552  if (ret < 0)
553  goto fail;
554  break;
555 
556  case DIR_DURATION:
557  file->user_duration = arg_int[0];
558  break;
559 
560  case DIR_INPOINT:
561  file->inpoint = arg_int[0];
562  break;
563 
564  case DIR_OUTPOINT:
565  file->outpoint = arg_int[0];
566  break;
567 
568  case DIR_FPMETA:
569  ret = av_dict_set(&file->metadata, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
570  arg_str[1] = NULL;
571  if (ret < 0)
572  FAIL(ret);
573  break;
574 
575  case DIR_FPMETAS:
576  if ((ret = av_dict_parse_string(&file->metadata, arg_str[0], "=", "", 0)) < 0) {
577  av_log(avf, AV_LOG_ERROR, "Line %d: failed to parse metadata string\n", line);
579  }
580  av_log(avf, AV_LOG_WARNING,
581  "'file_packet_metadata key=value:key=value' is deprecated, "
582  "use multiple 'file_packet_meta key value' instead\n");
583  av_freep(&arg_str[0]);
584  break;
585 
586  case DIR_OPTION:
587  ret = av_dict_set(&file->options, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
588  arg_str[1] = NULL;
589  if (ret < 0)
590  FAIL(ret);
591  break;
592 
593  case DIR_STREAM:
594  stream = avformat_new_stream(avf, NULL);
595  if (!stream)
596  FAIL(AVERROR(ENOMEM));
597  break;
598 
599  case DIR_EXSID:
600  stream->id = arg_int[0];
601  break;
602  case DIR_STMETA:
603  ret = av_dict_set(&stream->metadata, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
604  arg_str[1] = NULL;
605  if (ret < 0)
606  FAIL(ret);
607  break;
608 
609  case DIR_STCODEC: {
610  const AVCodecDescriptor *codec = avcodec_descriptor_get_by_name(arg_kw[0]);
611  if (!codec) {
612  av_log(avf, AV_LOG_ERROR, "Line %d: codec '%s' not found\n", line, arg_kw[0]);
614  }
615  stream->codecpar->codec_type = codec->type;
616  stream->codecpar->codec_id = codec->id;
617  break;
618  }
619 
620  case DIR_STEDATA: {
621  int size = ff_hex_to_data(NULL, arg_kw[0]);
622  ret = ff_alloc_extradata(stream->codecpar, size);
623  if (ret < 0)
624  FAIL(ret);
625  ff_hex_to_data(stream->codecpar->extradata, arg_kw[0]);
626  break;
627  }
628 
629  case DIR_CHAPTER:
630  chapter = avpriv_new_chapter(avf, arg_int[0], AV_TIME_BASE_Q,
631  arg_int[1], arg_int[2], NULL);
632  if (!chapter)
633  FAIL(ENOMEM);
634  break;
635 
636  default:
637  FAIL(AVERROR_BUG);
638  }
639  }
640 
641  if (file->inpoint != AV_NOPTS_VALUE && file->outpoint != AV_NOPTS_VALUE) {
642  if (file->inpoint > file->outpoint ||
643  file->outpoint - (uint64_t)file->inpoint > INT64_MAX)
645  }
646 
647 fail:
648  for (arg = 0; arg < MAX_ARGS; arg++)
649  av_freep(&arg_str[arg]);
650  av_bprint_finalize(&bp, NULL);
651  return ret == AVERROR_EOF ? 0 : ret;
652 }
653 
655 {
656  ConcatContext *cat = avf->priv_data;
657  int64_t time = 0;
658  unsigned i;
659  int ret;
660 
661  ret = concat_parse_script(avf);
662  if (ret < 0)
663  return ret;
664  if (!cat->nb_files) {
665  av_log(avf, AV_LOG_ERROR, "No files to concat\n");
666  return AVERROR_INVALIDDATA;
667  }
668 
669  for (i = 0; i < cat->nb_files; i++) {
670  if (cat->files[i].start_time == AV_NOPTS_VALUE)
671  cat->files[i].start_time = time;
672  else
673  time = cat->files[i].start_time;
674  if (cat->files[i].user_duration == AV_NOPTS_VALUE) {
675  if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE ||
676  cat->files[i].outpoint - (uint64_t)cat->files[i].inpoint != av_sat_sub64(cat->files[i].outpoint, cat->files[i].inpoint)
677  )
678  break;
679  cat->files[i].user_duration = cat->files[i].outpoint - cat->files[i].inpoint;
680  }
681  cat->files[i].duration = cat->files[i].user_duration;
682  if (time + (uint64_t)cat->files[i].user_duration > INT64_MAX)
683  return AVERROR_INVALIDDATA;
684  time += cat->files[i].user_duration;
685  }
686  if (i == cat->nb_files) {
687  avf->duration = time;
688  cat->seekable = 1;
689  }
690 
691  cat->stream_match_mode = avf->nb_streams ? MATCH_EXACT_ID :
693  if ((ret = open_file(avf, 0)) < 0)
694  return ret;
695 
696  return 0;
697 }
698 
700 {
701  ConcatContext *cat = avf->priv_data;
702  unsigned fileno = cat->cur_file - cat->files;
703 
704  cat->cur_file->duration = get_best_effort_duration(cat->cur_file, cat->avf);
705 
706  if (++fileno >= cat->nb_files) {
707  cat->eof = 1;
708  return AVERROR_EOF;
709  }
710  return open_file(avf, fileno);
711 }
712 
714 {
715  int ret;
716 
717  if (cs->bsf) {
718  ret = av_bsf_send_packet(cs->bsf, pkt);
719  if (ret < 0) {
720  av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb filter "
721  "failed to send input packet\n");
722  return ret;
723  }
724 
725  while (!ret)
727 
728  if (ret < 0 && (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)) {
729  av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb filter "
730  "failed to receive output packet\n");
731  return ret;
732  }
733  }
734  return 0;
735 }
736 
737 /* Returns true if the packet dts is greater or equal to the specified outpoint. */
739 {
740  if (cat->cur_file->outpoint != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE) {
741  return av_compare_ts(pkt->dts, cat->avf->streams[pkt->stream_index]->time_base,
742  cat->cur_file->outpoint, AV_TIME_BASE_Q) >= 0;
743  }
744  return 0;
745 }
746 
748 {
749  ConcatContext *cat = avf->priv_data;
750  int ret;
751  int64_t delta;
752  ConcatStream *cs;
753  AVStream *st;
754  FFStream *sti;
755 
756  if (cat->eof)
757  return AVERROR_EOF;
758 
759  if (!cat->avf)
760  return AVERROR(EIO);
761 
762  while (1) {
763  ret = av_read_frame(cat->avf, pkt);
764  if (ret == AVERROR_EOF) {
765  if ((ret = open_next_file(avf)) < 0)
766  return ret;
767  continue;
768  }
769  if (ret < 0)
770  return ret;
771  if ((ret = match_streams(avf)) < 0) {
772  return ret;
773  }
774  if (packet_after_outpoint(cat, pkt)) {
776  if ((ret = open_next_file(avf)) < 0)
777  return ret;
778  continue;
779  }
780  cs = &cat->cur_file->streams[pkt->stream_index];
781  if (cs->out_stream_index < 0) {
783  continue;
784  }
785  break;
786  }
787  if ((ret = filter_packet(avf, cs, pkt)) < 0)
788  return ret;
789 
790  st = cat->avf->streams[pkt->stream_index];
791  sti = ffstream(st);
792  av_log(avf, AV_LOG_DEBUG, "file:%d stream:%d pts:%s pts_time:%s dts:%s dts_time:%s",
793  (unsigned)(cat->cur_file - cat->files), pkt->stream_index,
796 
797  delta = av_rescale_q(cat->cur_file->start_time - cat->cur_file->file_inpoint,
799  cat->avf->streams[pkt->stream_index]->time_base);
800  if (pkt->pts != AV_NOPTS_VALUE)
801  pkt->pts += delta;
802  if (pkt->dts != AV_NOPTS_VALUE)
803  pkt->dts += delta;
804  av_log(avf, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
807  if (cat->cur_file->metadata) {
808  size_t metadata_len;
809  char* packed_metadata = av_packet_pack_dictionary(cat->cur_file->metadata, &metadata_len);
810  if (!packed_metadata)
811  return AVERROR(ENOMEM);
813  packed_metadata, metadata_len);
814  if (ret < 0) {
815  av_freep(&packed_metadata);
816  return ret;
817  }
818  }
819 
820  if (cat->cur_file->duration == AV_NOPTS_VALUE && sti->cur_dts != AV_NOPTS_VALUE) {
821  int64_t next_dts = av_rescale_q(sti->cur_dts, st->time_base, AV_TIME_BASE_Q);
822  if (cat->cur_file->next_dts == AV_NOPTS_VALUE || next_dts > cat->cur_file->next_dts) {
823  cat->cur_file->next_dts = next_dts;
824  }
825  }
826 
828  return 0;
829 }
830 
831 static int try_seek(AVFormatContext *avf, int stream,
832  int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
833 {
834  ConcatContext *cat = avf->priv_data;
835  int64_t t0 = cat->cur_file->start_time - cat->cur_file->file_inpoint;
836 
837  ts -= t0;
838  min_ts = min_ts == INT64_MIN ? INT64_MIN : min_ts - t0;
839  max_ts = max_ts == INT64_MAX ? INT64_MAX : max_ts - t0;
840  if (stream >= 0) {
841  if (stream >= cat->avf->nb_streams)
842  return AVERROR(EIO);
843  ff_rescale_interval(AV_TIME_BASE_Q, cat->avf->streams[stream]->time_base,
844  &min_ts, &ts, &max_ts);
845  }
846  return avformat_seek_file(cat->avf, stream, min_ts, ts, max_ts, flags);
847 }
848 
849 static int real_seek(AVFormatContext *avf, int stream,
850  int64_t min_ts, int64_t ts, int64_t max_ts, int flags, AVFormatContext *cur_avf)
851 {
852  ConcatContext *cat = avf->priv_data;
853  int ret, left, right;
854 
855  if (stream >= 0) {
856  if (stream >= avf->nb_streams)
857  return AVERROR(EINVAL);
859  &min_ts, &ts, &max_ts);
860  }
861 
862  left = 0;
863  right = cat->nb_files;
864 
865  /* Always support seek to start */
866  if (ts <= 0)
867  right = 1;
868  else if (!cat->seekable)
869  return AVERROR(ESPIPE); /* XXX: can we use it? */
870 
871  while (right - left > 1) {
872  int mid = (left + right) / 2;
873  if (ts < cat->files[mid].start_time)
874  right = mid;
875  else
876  left = mid;
877  }
878 
879  if (cat->cur_file != &cat->files[left]) {
880  if ((ret = open_file(avf, left)) < 0)
881  return ret;
882  } else {
883  cat->avf = cur_avf;
884  }
885 
886  ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
887  if (ret < 0 &&
888  left < cat->nb_files - 1 &&
889  cat->files[left + 1].start_time < max_ts) {
890  if (cat->cur_file == &cat->files[left])
891  cat->avf = NULL;
892  if ((ret = open_file(avf, left + 1)) < 0)
893  return ret;
894  ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
895  }
896  return ret;
897 }
898 
899 static int concat_seek(AVFormatContext *avf, int stream,
900  int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
901 {
902  ConcatContext *cat = avf->priv_data;
903  ConcatFile *cur_file_saved = cat->cur_file;
904  AVFormatContext *cur_avf_saved = cat->avf;
905  int ret;
906 
908  return AVERROR(ENOSYS);
909  cat->avf = NULL;
910  if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags, cur_avf_saved)) < 0) {
911  if (cat->cur_file != cur_file_saved) {
912  if (cat->avf)
913  avformat_close_input(&cat->avf);
914  }
915  cat->avf = cur_avf_saved;
916  cat->cur_file = cur_file_saved;
917  } else {
918  if (cat->cur_file != cur_file_saved) {
919  avformat_close_input(&cur_avf_saved);
920  }
921  cat->eof = 0;
922  }
923  return ret;
924 }
925 
926 #define OFFSET(x) offsetof(ConcatContext, x)
927 #define DEC AV_OPT_FLAG_DECODING_PARAM
928 
929 static const AVOption options[] = {
930  { "safe", "enable safe mode",
931  OFFSET(safe), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
932  { "auto_convert", "automatically convert bitstream format",
933  OFFSET(auto_convert), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
934  { "segment_time_metadata", "output file segment start time and duration as packet metadata",
935  OFFSET(segment_time_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
936  { NULL }
937 };
938 
939 static const AVClass concat_class = {
940  .class_name = "concat demuxer",
941  .item_name = av_default_item_name,
942  .option = options,
943  .version = LIBAVUTIL_VERSION_INT,
944 };
945 
946 
948  .name = "concat",
949  .long_name = NULL_IF_CONFIG_SMALL("Virtual concatenation script"),
950  .priv_data_size = sizeof(ConcatContext),
951  .flags_internal = FF_FMT_INIT_CLEANUP,
956  .read_seek2 = concat_seek,
957  .priv_class = &concat_class,
958 };
avpriv_new_chapter
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:42
add_file
static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile, unsigned *nb_files_alloc)
Definition: concatdec.c:114
real_seek
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:849
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:423
AVBSFContext::par_in
AVCodecParameters * par_in
Parameters of the input stream.
Definition: bsf.h:90
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
DIR_FPMETA
@ DIR_FPMETA
Definition: concatdec.c:431
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
OFFSET
#define OFFSET(x)
Definition: concatdec.c:926
FF_FMT_INIT_CLEANUP
#define FF_FMT_INIT_CLEANUP
For an AVInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: internal.h:46
packet_after_outpoint
static int packet_after_outpoint(ConcatContext *cat, AVPacket *pkt)
Definition: concatdec.c:738
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
ConcatFile::duration
int64_t duration
Definition: concatdec.c:51
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
NEEDS_FILE
#define NEEDS_FILE
Definition: concatdec.c:416
av_compare_ts
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.
Definition: mathematics.c:147
AVSEEK_FLAG_FRAME
#define AVSEEK_FLAG_FRAME
seeking based on frame number
Definition: avformat.h:2227
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ConcatContext::segment_time_metadata
int segment_time_metadata
Definition: concatdec.c:73
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
ConcatFile::next_dts
int64_t next_dts
Definition: concatdec.c:53
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
get_best_effort_duration
static int64_t get_best_effort_duration(ConcatFile *file, AVFormatContext *avf)
Definition: concatdec.c:321
ConcatFile::file_inpoint
int64_t file_inpoint
Definition: concatdec.c:50
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1183
ff_read_line_to_bprint_overwrite
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:902
AVOption
AVOption.
Definition: opt.h:251
t0
#define t0
Definition: regdef.h:28
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:930
AVFMT_FLAG_CUSTOM_IO
#define AVFMT_FLAG_CUSTOM_IO
The caller has supplied a custom AVIOContext, don't avio_close() it.
Definition: avformat.h:1241
ConcatContext::stream_match_mode
ConcatMatchMode stream_match_mode
Definition: concatdec.c:71
AVSEEK_FLAG_BYTE
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition: avformat.h:2225
open_next_file
static int open_next_file(AVFormatContext *avf)
Definition: concatdec.c:699
DIR_FFCONCAT
@ DIR_FFCONCAT
Definition: concatdec.c:426
concat_parse_script
static int concat_parse_script(AVFormatContext *avf)
Definition: concatdec.c:459
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
concat_probe
static int concat_probe(const AVProbeData *probe)
Definition: concatdec.c:76
cat
#define cat(a, bpp, b)
Definition: vp9dsp_init.h:32
ConcatContext::nb_files
unsigned nb_files
Definition: concatdec.c:66
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
AVDictionary
Definition: dict.c:34
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MAX_ARGS
#define MAX_ARGS
Definition: concatdec.c:414
av_read_frame
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition: demux.c:1462
DIR_OPTION
@ DIR_OPTION
Definition: concatdec.c:433
av_bsf_free
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:52
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:464
avformat_close_input
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition: demux.c:374
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1381
avpriv_set_pts_info
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:761
bsf.h
av_packet_add_side_data
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: avpacket.c:197
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:420
fail
#define fail()
Definition: checkasm.h:138
concat_read_header
static int concat_read_header(AVFormatContext *avf)
Definition: concatdec.c:654
match_streams_exact_id
static int match_streams_exact_id(AVFormatContext *avf)
Definition: concatdec.c:262
ParseSyntax::keyword
const char * keyword
Definition: concatdec.c:420
filter_packet
static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
Definition: concatdec.c:713
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
ConcatFile::outpoint
int64_t outpoint
Definition: concatdec.c:56
AVChapter
Definition: avformat.h:1074
AVBSFContext::par_out
AVCodecParameters * par_out
Parameters of the output stream.
Definition: bsf.h:96
concat_read_packet
static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
Definition: concatdec.c:747
AVRational::num
int num
Numerator.
Definition: rational.h:59
SPACE_CHARS
#define SPACE_CHARS
Definition: dnn_backend_tf.c:364
DIR_FPMETAS
@ DIR_FPMETAS
Definition: concatdec.c:432
AV_DICT_DONT_STRDUP_VAL
#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
ConcatFile::streams
ConcatStream * streams
Definition: concatdec.c:54
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVInputFormat
Definition: avformat.h:549
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
get_keyword
static char * get_keyword(uint8_t **cursor)
Definition: concatdec.c:82
ConcatFile::file_start_time
int64_t file_start_time
Definition: concatdec.c:49
avformat_open_input
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:226
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:41
AVCodecDescriptor
This struct describes the properties of a single codec described by an AVCodecID.
Definition: codec_desc.h:38
intreadwrite.h
copy_stream_props
static int copy_stream_props(AVStream *st, AVStream *source_st)
Definition: concatdec.c:173
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1233
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:554
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AVCodecDescriptor::type
enum AVMediaType type
Definition: codec_desc.h:40
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
nb_streams
static int nb_streams
Definition: ffprobe.c:328
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
av_bsf_alloc
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
Allocate a context for a given bitstream filter.
Definition: bsf.c:104
ConcatFile::inpoint
int64_t inpoint
Definition: concatdec.c:55
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
ff_hex_to_data
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition: utils.c:476
arg
const char * arg
Definition: jacosubdec.c:67
MATCH_ONE_TO_ONE
@ MATCH_ONE_TO_ONE
Definition: concatdec.c:37
ParseSyntax
Definition: concatdec.c:419
NEEDS_UNSAFE
#define NEEDS_UNSAFE
Definition: concatdec.c:415
AVFormatContext
Format I/O context.
Definition: avformat.h:1115
internal.h
options
static const AVOption options[]
Definition: concatdec.c:929
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:864
open_file
static int open_file(AVFormatContext *avf, unsigned fileno)
Definition: concatdec.c:334
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_bsf_init
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set.
Definition: bsf.c:149
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:550
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:880
NULL
#define NULL
Definition: coverity.c:32
av_bsf_receive_packet
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition: bsf.c:230
ff_copy_whiteblacklists
int ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src)
Copies the whilelists from one context to the other.
Definition: avformat.c:805
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1157
AVERROR_BSF_NOT_FOUND
#define AVERROR_BSF_NOT_FOUND
Bitstream filter not found.
Definition: error.h:51
parseutils.h
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:452
ff_rescale_interval
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:763
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:921
av_parse_time
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:589
DIR_STEDATA
@ DIR_STEDATA
Definition: concatdec.c:438
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1171
av_sat_sub64
#define av_sat_sub64
Definition: common.h:141
avformat_find_stream_info
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information.
Definition: demux.c:2436
ConcatContext::avf
AVFormatContext * avf
Definition: concatdec.c:67
f
f
Definition: af_crystalizer.c:121
DIR_EXSID
@ DIR_EXSID
Definition: concatdec.c:435
av_ts2timestr
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:76
NEEDS_STREAM
#define NEEDS_STREAM
Definition: concatdec.c:417
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:166
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
FFStream
Definition: internal.h:199
ConcatStream
Definition: concatdec.c:41
av_bsf_send_packet
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition: bsf.c:202
try_seek
static int try_seek(AVFormatContext *avf, int stream, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Definition: concatdec.c:831
ParseSyntax::args
char args[MAX_ARGS]
Definition: concatdec.c:421
start_time
static int64_t start_time
Definition: ffplay.c:328
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1198
size
int size
Definition: twinvq_data.h:10344
DIR_OUTPOINT
@ DIR_OUTPOINT
Definition: concatdec.c:430
ConcatStream::out_stream_index
int out_stream_index
Definition: concatdec.c:43
avformat_seek_file
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:662
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
ConcatContext::auto_convert
unsigned auto_convert
Definition: concatdec.c:72
match_streams_one_to_one
static int match_streams_one_to_one(AVFormatContext *avf)
Definition: concatdec.c:242
DIR_STMETA
@ DIR_STMETA
Definition: concatdec.c:436
concat_class
static const AVClass concat_class
Definition: concatdec.c:939
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:919
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:490
FAIL
#define FAIL(retcode)
Definition: concatdec.c:112
line
Definition: graph2dot.c:48
av_packet_pack_dictionary
uint8_t * av_packet_pack_dictionary(AVDictionary *dict, size_t *size)
Pack a dictionary for use in side_data.
Definition: avpacket.c:308
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:225
av_strstart
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
DIR_DURATION
@ DIR_DURATION
Definition: concatdec.c:428
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
safe_filename
static int safe_filename(const char *f)
Definition: concatdec.c:93
AV_PKT_DATA_STRINGS_METADATA
@ AV_PKT_DATA_STRINGS_METADATA
A list of zero terminated key/value strings.
Definition: packet.h:173
bprint.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:484
avio_internal.h
ConcatFile::start_time
int64_t start_time
Definition: concatdec.c:48
ConcatContext::cur_file
ConcatFile * cur_file
Definition: concatdec.c:65
MATCH_EXACT_ID
@ MATCH_EXACT_ID
Definition: concatdec.c:38
delta
float delta
Definition: vorbis_enc_data.h:430
url.h
demux.h
ConcatContext::eof
int eof
Definition: concatdec.c:70
ConcatContext
Definition: avf_concat.c:38
files
Writing a table generator This documentation is preliminary Parts of the API are not good and should be changed Basic concepts A table generator consists of two files
Definition: tablegen.txt:8
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:853
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:841
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
ConcatStream::bsf
AVBSFContext * bsf
Definition: concatdec.c:42
ConcatFile
Definition: concatdec.c:46
avformat.h
DIR_FILE
@ DIR_FILE
Definition: concatdec.c:427
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
syntax
static const ParseSyntax syntax[]
Definition: concatdec.c:442
probe
static int probe(const AVProbeData *p)
Definition: act.c:38
ConcatFile::url
char * url
Definition: concatdec.c:47
AVBitStreamFilter
Definition: bsf.h:111
ConcatContext::seekable
int seekable
Definition: concatdec.c:69
DEC
#define DEC
Definition: concatdec.c:927
AVRational::den
int den
Denominator.
Definition: rational.h:60
av_get_token
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
av_dict_parse_string
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:202
ConcatContext::files
ConcatFile * files
Definition: concatdec.c:64
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:1007
ParseSyntax::flags
uint8_t flags
Definition: concatdec.c:422
AVFormatContext::duration
int64_t duration
Duration of the stream, in AV_TIME_BASE fractional seconds.
Definition: avformat.h:1217
AVPacket::stream_index
int stream_index
Definition: packet.h:493
DIR_INPOINT
@ DIR_INPOINT
Definition: concatdec.c:429
ConcatFile::nb_streams
int nb_streams
Definition: concatdec.c:59
DIR_STREAM
@ DIR_STREAM
Definition: concatdec.c:434
ConcatFile::options
AVDictionary * options
Definition: concatdec.c:58
AVERROR_DECODER_NOT_FOUND
#define AVERROR_DECODER_NOT_FOUND
Decoder not found.
Definition: error.h:54
av_dict_set_int
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:169
detect_stream_specific
static int detect_stream_specific(AVFormatContext *avf, int idx)
Definition: concatdec.c:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:29
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
ff_make_absolute_url
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
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:468
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
ParseDirective
ParseDirective
Definition: concatdec.c:425
ff_concat_demuxer
const AVInputFormat ff_concat_demuxer
Definition: concatdec.c:947
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
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:88
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:239
FFStream::cur_dts
int64_t cur_dts
Definition: internal.h:415
avio_find_protocol_name
const char * avio_find_protocol_name(const char *url)
Return the name of the protocol that will handle the passed URL.
Definition: avio.c:468
AVCodecDescriptor::id
enum AVCodecID id
Definition: codec_desc.h:39
timestamp.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
ConcatContext::safe
int safe
Definition: concatdec.c:68
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
av_ts2str
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:54
concat_seek
static int concat_seek(AVFormatContext *avf, int stream, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
Definition: concatdec.c:899
avstring.h
ConcatFile::metadata
AVDictionary * metadata
Definition: concatdec.c:57
DIR_CHAPTER
@ DIR_CHAPTER
Definition: concatdec.c:439
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:97
avcodec_descriptor_get_by_name
const AVCodecDescriptor * avcodec_descriptor_get_by_name(const char *name)
Definition: codec_desc.c:3737
match_streams
static int match_streams(AVFormatContext *avf)
Definition: concatdec.c:284
codec_desc.h
ConcatMatchMode
ConcatMatchMode
Definition: concatdec.c:36
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1143
ConcatFile::user_duration
int64_t user_duration
Definition: concatdec.c:52
concat_read_close
static int concat_read_close(AVFormatContext *avf)
Definition: concatdec.c:393
DIR_STCODEC
@ DIR_STCODEC
Definition: concatdec.c:437
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:153
ff_alloc_extradata
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:239
av_bsf_get_by_name
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
Definition: bitstream_filters.c:86