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/mem.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/parseutils.h"
28 #include "libavutil/timestamp.h"
29 #include "libavcodec/codec_desc.h"
30 #include "libavcodec/bsf.h"
31 #include "avformat.h"
32 #include "avio_internal.h"
33 #include "demux.h"
34 #include "internal.h"
35 #include "url.h"
36 
37 typedef enum ConcatMatchMode {
41 
42 typedef struct ConcatStream {
45 } ConcatStream;
46 
47 typedef struct {
48  char *url;
49  int64_t start_time;
50  int64_t file_start_time;
51  int64_t file_inpoint;
52  int64_t duration;
53  int64_t user_duration;
54  int64_t next_dts;
56  int64_t inpoint;
57  int64_t outpoint;
61 } ConcatFile;
62 
63 typedef struct {
64  AVClass *class;
67  unsigned nb_files;
69  int safe;
70  int seekable;
71  int eof;
73  unsigned auto_convert;
76 
77 static int concat_probe(const AVProbeData *probe)
78 {
79  return memcmp(probe->buf, "ffconcat version 1.0", 20) ?
81 }
82 
83 static char *get_keyword(uint8_t **cursor)
84 {
85  char *ret = *cursor += strspn(*cursor, SPACE_CHARS);
86  *cursor += strcspn(*cursor, SPACE_CHARS);
87  if (**cursor) {
88  *((*cursor)++) = 0;
89  *cursor += strspn(*cursor, SPACE_CHARS);
90  }
91  return ret;
92 }
93 
94 static int safe_filename(const char *f)
95 {
96  const char *start = f;
97 
98  for (; *f; f++) {
99  /* A-Za-z0-9_- */
100  if (!((unsigned)((*f | 32) - 'a') < 26 ||
101  (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) {
102  if (f == start)
103  return 0;
104  else if (*f == '/')
105  start = f + 1;
106  else if (*f != '.')
107  return 0;
108  }
109  }
110  return 1;
111 }
112 
113 #define FAIL(retcode) do { ret = (retcode); goto fail; } while(0)
114 
115 static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
116  unsigned *nb_files_alloc)
117 {
118  ConcatContext *cat = avf->priv_data;
119  ConcatFile *file;
120  char *url = NULL;
121  const char *proto;
122  const char *ptr;
123  size_t url_len;
124  int ret;
125 
126  if (cat->safe && !safe_filename(filename)) {
127  av_log(avf, AV_LOG_ERROR, "Unsafe file name '%s'\n", filename);
128  FAIL(AVERROR(EPERM));
129  }
130 
131  proto = avio_find_protocol_name(filename);
132  if (proto && av_strstart(filename, proto, &ptr) &&
133  (*ptr == ':' || *ptr == ',')) {
134  url = filename;
135  filename = NULL;
136  } else {
137  url_len = strlen(avf->url) + strlen(filename) + 16;
138  if (!(url = av_malloc(url_len)))
139  FAIL(AVERROR(ENOMEM));
140  ff_make_absolute_url(url, url_len, avf->url, filename);
141  av_freep(&filename);
142  }
143 
144  if (cat->nb_files >= *nb_files_alloc) {
145  size_t n = FFMAX(*nb_files_alloc * 2, 16);
146  ConcatFile *new_files;
147  if (n <= cat->nb_files || n > SIZE_MAX / sizeof(*cat->files) ||
148  !(new_files = av_realloc(cat->files, n * sizeof(*cat->files))))
149  FAIL(AVERROR(ENOMEM));
150  cat->files = new_files;
151  *nb_files_alloc = n;
152  }
153 
154  file = &cat->files[cat->nb_files++];
155  memset(file, 0, sizeof(*file));
156  *rfile = file;
157 
158  file->url = url;
159  file->start_time = AV_NOPTS_VALUE;
160  file->duration = AV_NOPTS_VALUE;
161  file->next_dts = AV_NOPTS_VALUE;
162  file->inpoint = AV_NOPTS_VALUE;
163  file->outpoint = AV_NOPTS_VALUE;
165 
166  return 0;
167 
168 fail:
169  av_free(url);
170  av_free(filename);
171  return ret;
172 }
173 
174 static int copy_stream_props(AVStream *st, AVStream *source_st)
175 {
176  int ret;
177 
178  if (st->codecpar->codec_id || !source_st->codecpar->codec_id) {
179  if (st->codecpar->extradata_size < source_st->codecpar->extradata_size) {
181  source_st->codecpar->extradata_size);
182  if (ret < 0)
183  return ret;
184  }
185  if (source_st->codecpar->extradata_size)
186  memcpy(st->codecpar->extradata, source_st->codecpar->extradata,
187  source_st->codecpar->extradata_size);
188  return 0;
189  }
190  if ((ret = avcodec_parameters_copy(st->codecpar, source_st->codecpar)) < 0)
191  return ret;
192  st->r_frame_rate = source_st->r_frame_rate;
193  st->avg_frame_rate = source_st->avg_frame_rate;
194  st->sample_aspect_ratio = source_st->sample_aspect_ratio;
195  avpriv_set_pts_info(st, 64, source_st->time_base.num, source_st->time_base.den);
196 
197  av_dict_copy(&st->metadata, source_st->metadata, 0);
198  return 0;
199 }
200 
201 static int detect_stream_specific(AVFormatContext *avf, int idx)
202 {
203  ConcatContext *cat = avf->priv_data;
204  AVStream *st = cat->avf->streams[idx];
205  ConcatStream *cs = &cat->cur_file->streams[idx];
206  const AVBitStreamFilter *filter;
207  AVBSFContext *bsf;
208  int ret;
209 
210  if (cat->auto_convert && st->codecpar->codec_id == AV_CODEC_ID_H264) {
211  if (!st->codecpar->extradata_size ||
212  (st->codecpar->extradata_size >= 3 && AV_RB24(st->codecpar->extradata) == 1) ||
213  (st->codecpar->extradata_size >= 4 && AV_RB32(st->codecpar->extradata) == 1))
214  return 0;
215  av_log(cat->avf, AV_LOG_INFO,
216  "Auto-inserting h264_mp4toannexb bitstream filter\n");
217  filter = av_bsf_get_by_name("h264_mp4toannexb");
218  if (!filter) {
219  av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb bitstream filter "
220  "required for H.264 streams\n");
221  return AVERROR_BSF_NOT_FOUND;
222  }
223  ret = av_bsf_alloc(filter, &bsf);
224  if (ret < 0)
225  return ret;
226  cs->bsf = bsf;
227 
229  if (ret < 0)
230  return ret;
231 
232  ret = av_bsf_init(bsf);
233  if (ret < 0)
234  return ret;
235 
237  if (ret < 0)
238  return ret;
239  }
240  return 0;
241 }
242 
244 {
245  ConcatContext *cat = avf->priv_data;
246  AVStream *st;
247  int i, ret;
248 
249  for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
250  if (i < avf->nb_streams) {
251  st = avf->streams[i];
252  } else {
253  if (!(st = avformat_new_stream(avf, NULL)))
254  return AVERROR(ENOMEM);
255  }
256  if ((ret = copy_stream_props(st, cat->avf->streams[i])) < 0)
257  return ret;
258  cat->cur_file->streams[i].out_stream_index = i;
259  }
260  return 0;
261 }
262 
264 {
265  ConcatContext *cat = avf->priv_data;
266  AVStream *st;
267  int i, j, ret;
268 
269  for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
270  st = cat->avf->streams[i];
271  for (j = 0; j < avf->nb_streams; j++) {
272  if (avf->streams[j]->id == st->id) {
273  av_log(avf, AV_LOG_VERBOSE,
274  "Match slave stream #%d with stream #%d id 0x%x\n",
275  i, j, st->id);
276  if ((ret = copy_stream_props(avf->streams[j], st)) < 0)
277  return ret;
278  cat->cur_file->streams[i].out_stream_index = j;
279  }
280  }
281  }
282  return 0;
283 }
284 
286 {
287  ConcatContext *cat = avf->priv_data;
288  ConcatStream *map;
289  int i, ret;
290 
291  if (cat->cur_file->nb_streams >= cat->avf->nb_streams)
292  return 0;
293  map = av_realloc(cat->cur_file->streams,
294  cat->avf->nb_streams * sizeof(*map));
295  if (!map)
296  return AVERROR(ENOMEM);
297  cat->cur_file->streams = map;
298  memset(map + cat->cur_file->nb_streams, 0,
299  (cat->avf->nb_streams - cat->cur_file->nb_streams) * sizeof(*map));
300 
301  for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
302  map[i].out_stream_index = -1;
303  if ((ret = detect_stream_specific(avf, i)) < 0)
304  return ret;
305  }
306  switch (cat->stream_match_mode) {
307  case MATCH_ONE_TO_ONE:
309  break;
310  case MATCH_EXACT_ID:
312  break;
313  default:
314  ret = AVERROR_BUG;
315  }
316  if (ret < 0)
317  return ret;
318  cat->cur_file->nb_streams = cat->avf->nb_streams;
319  return 0;
320 }
321 
323 {
324  if (file->user_duration != AV_NOPTS_VALUE)
325  return file->user_duration;
326  if (file->outpoint != AV_NOPTS_VALUE)
327  return av_sat_sub64(file->outpoint, file->file_inpoint);
328  if (avf->duration > 0)
329  return avf->duration - (file->file_inpoint - file->file_start_time);
330  if (file->next_dts != AV_NOPTS_VALUE)
331  return file->next_dts - file->file_inpoint;
332  return AV_NOPTS_VALUE;
333 }
334 
335 static int open_file(AVFormatContext *avf, unsigned fileno)
336 {
337  ConcatContext *cat = avf->priv_data;
338  ConcatFile *file = &cat->files[fileno];
340  int ret;
341 
342  if (cat->avf)
343  avformat_close_input(&cat->avf);
344 
345  cat->avf = avformat_alloc_context();
346  if (!cat->avf)
347  return AVERROR(ENOMEM);
348 
349  cat->avf->flags |= avf->flags & ~AVFMT_FLAG_CUSTOM_IO;
350  cat->avf->interrupt_callback = avf->interrupt_callback;
351 
352  if ((ret = ff_copy_whiteblacklists(cat->avf, avf)) < 0)
353  return ret;
354 
355  ret = av_dict_copy(&options, file->options, 0);
356  if (ret < 0)
357  return ret;
358 
359  if ((ret = avformat_open_input(&cat->avf, file->url, NULL, &options)) < 0 ||
360  (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
361  av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url);
363  avformat_close_input(&cat->avf);
364  return ret;
365  }
366  if (options) {
367  av_log(avf, AV_LOG_WARNING, "Unused options for '%s'.\n", file->url);
368  /* TODO log unused options once we have a proper string API */
370  }
371  cat->cur_file = file;
372  file->start_time = !fileno ? 0 :
373  cat->files[fileno - 1].start_time +
374  cat->files[fileno - 1].duration;
375  file->file_start_time = (cat->avf->start_time == AV_NOPTS_VALUE) ? 0 : cat->avf->start_time;
376  file->file_inpoint = (file->inpoint == AV_NOPTS_VALUE) ? file->file_start_time : file->inpoint;
377  file->duration = get_best_effort_duration(file, cat->avf);
378 
379  if (cat->segment_time_metadata) {
380  av_dict_set_int(&file->metadata, "lavf.concatdec.start_time", file->start_time, 0);
381  if (file->duration != AV_NOPTS_VALUE)
382  av_dict_set_int(&file->metadata, "lavf.concatdec.duration", file->duration, 0);
383  }
384 
385  if ((ret = match_streams(avf)) < 0)
386  return ret;
387  if (file->inpoint != AV_NOPTS_VALUE) {
388  if ((ret = avformat_seek_file(cat->avf, -1, INT64_MIN, file->inpoint, file->inpoint, 0)) < 0)
389  return ret;
390  }
391  return 0;
392 }
393 
395 {
396  ConcatContext *cat = avf->priv_data;
397  unsigned i, j;
398 
399  for (i = 0; i < cat->nb_files; i++) {
400  av_freep(&cat->files[i].url);
401  for (j = 0; j < cat->files[i].nb_streams; j++) {
402  if (cat->files[i].streams[j].bsf)
403  av_bsf_free(&cat->files[i].streams[j].bsf);
404  }
405  av_freep(&cat->files[i].streams);
406  av_dict_free(&cat->files[i].metadata);
407  av_dict_free(&cat->files[i].options);
408  }
409  if (cat->avf)
410  avformat_close_input(&cat->avf);
411  av_freep(&cat->files);
412  return 0;
413 }
414 
415 #define MAX_ARGS 3
416 #define NEEDS_UNSAFE (1 << 0)
417 #define NEEDS_FILE (1 << 1)
418 #define NEEDS_STREAM (1 << 2)
419 
420 typedef struct ParseSyntax {
421  const char *keyword;
422  char args[MAX_ARGS];
423  uint8_t flags;
424 } ParseSyntax;
425 
426 typedef enum ParseDirective {
442 
443 static const ParseSyntax syntax[] = {
444  [DIR_FFCONCAT ] = { "ffconcat", "kk", 0 },
445  [DIR_FILE ] = { "file", "s", 0 },
446  [DIR_DURATION ] = { "duration", "d", NEEDS_FILE },
447  [DIR_INPOINT ] = { "inpoint", "d", NEEDS_FILE },
448  [DIR_OUTPOINT ] = { "outpoint", "d", NEEDS_FILE },
449  [DIR_FPMETA ] = { "file_packet_meta", "ks", NEEDS_FILE },
450  [DIR_FPMETAS ] = { "file_packet_metadata", "s", NEEDS_FILE },
451  [DIR_OPTION ] = { "option", "ks", NEEDS_FILE | NEEDS_UNSAFE },
452  [DIR_STREAM ] = { "stream", "", 0 },
453  [DIR_EXSID ] = { "exact_stream_id", "i", NEEDS_STREAM },
454  [DIR_STMETA ] = { "stream_meta", "ks", NEEDS_STREAM },
455  [DIR_STCODEC ] = { "stream_codec", "k", NEEDS_STREAM },
456  [DIR_STEDATA ] = { "stream_extradata", "k", NEEDS_STREAM },
457  [DIR_CHAPTER ] = { "chapter", "idd", 0 },
458 };
459 
461 {
462  ConcatContext *cat = avf->priv_data;
463  unsigned nb_files_alloc = 0;
464  AVBPrint bp;
465  uint8_t *cursor, *keyword;
466  ConcatFile *file = NULL;
467  AVStream *stream = NULL;
468  AVChapter *chapter = NULL;
469  unsigned line = 0, arg;
470  const ParseSyntax *dir;
471  char *arg_kw[MAX_ARGS];
472  char *arg_str[MAX_ARGS] = { 0 };
473  int64_t arg_int[MAX_ARGS];
474  int ret;
475 
477 
478  while ((ret = ff_read_line_to_bprint_overwrite(avf->pb, &bp)) >= 0) {
479  line++;
480  cursor = bp.str;
481  keyword = get_keyword(&cursor);
482  if (!*keyword || *keyword == '#')
483  continue;
484  for (dir = syntax; dir < syntax + FF_ARRAY_ELEMS(syntax); dir++)
485  if (!strcmp(dir->keyword, keyword))
486  break;
487  if (dir >= syntax + FF_ARRAY_ELEMS(syntax)) {
488  av_log(avf, AV_LOG_ERROR, "Line %d: unknown keyword '%s'\n",
489  line, keyword);
491  }
492 
493  /* Flags check */
494  if ((dir->flags & NEEDS_UNSAFE) && cat->safe) {
495  av_log(avf, AV_LOG_ERROR, "Line %d: %s not allowed if safe\n", line, keyword);
497  }
498  if ((dir->flags & NEEDS_FILE) && !cat->nb_files) {
499  av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n", line, keyword);
501  }
502  if ((dir->flags & NEEDS_STREAM) && !avf->nb_streams) {
503  av_log(avf, AV_LOG_ERROR, "Line %d: %s without stream\n", line, keyword);
505  }
506 
507  /* Arguments parsing */
508  for (arg = 0; arg < FF_ARRAY_ELEMS(dir->args) && dir->args[arg]; arg++) {
509  switch (dir->args[arg]) {
510  case 'd': /* duration */
511  arg_kw[arg] = get_keyword(&cursor);
512  ret = av_parse_time(&arg_int[arg], arg_kw[arg], 1);
513  if (ret < 0) {
514  av_log(avf, AV_LOG_ERROR, "Line %d: invalid duration '%s'\n",
515  line, arg_kw[arg]);
516  goto fail;
517  }
518  break;
519  case 'i': /* integer */
520  arg_int[arg] = strtol(get_keyword(&cursor), NULL, 0);
521  break;
522  case 'k': /* keyword */
523  arg_kw[arg] = get_keyword(&cursor);
524  break;
525  case 's': /* string */
526  av_assert0(!arg_str[arg]);
527  arg_str[arg] = av_get_token((const char **)&cursor, SPACE_CHARS);
528  if (!arg_str[arg])
529  FAIL(AVERROR(ENOMEM));
530  if (!*arg_str[arg]) {
531  av_log(avf, AV_LOG_ERROR, "Line %d: string required\n", line);
533  }
534  break;
535  default:
536  FAIL(AVERROR_BUG);
537  }
538  }
539 
540  /* Directive action */
541  switch ((ParseDirective)(dir - syntax)) {
542 
543  case DIR_FFCONCAT:
544  if (strcmp(arg_kw[0], "version") || strcmp(arg_kw[1], "1.0")) {
545  av_log(avf, AV_LOG_ERROR, "Line %d: invalid version\n", line);
547  }
548  break;
549 
550  case DIR_FILE:
551  ret = add_file(avf, arg_str[0], &file, &nb_files_alloc);
552  arg_str[0] = NULL;
553  if (ret < 0)
554  goto fail;
555  break;
556 
557  case DIR_DURATION:
558  file->user_duration = arg_int[0];
559  break;
560 
561  case DIR_INPOINT:
562  file->inpoint = arg_int[0];
563  break;
564 
565  case DIR_OUTPOINT:
566  file->outpoint = arg_int[0];
567  break;
568 
569  case DIR_FPMETA:
570  ret = av_dict_set(&file->metadata, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
571  arg_str[1] = NULL;
572  if (ret < 0)
573  FAIL(ret);
574  break;
575 
576  case DIR_FPMETAS:
577  if ((ret = av_dict_parse_string(&file->metadata, arg_str[0], "=", "", 0)) < 0) {
578  av_log(avf, AV_LOG_ERROR, "Line %d: failed to parse metadata string\n", line);
580  }
581  av_log(avf, AV_LOG_WARNING,
582  "'file_packet_metadata key=value:key=value' is deprecated, "
583  "use multiple 'file_packet_meta key value' instead\n");
584  av_freep(&arg_str[0]);
585  break;
586 
587  case DIR_OPTION:
588  ret = av_dict_set(&file->options, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
589  arg_str[1] = NULL;
590  if (ret < 0)
591  FAIL(ret);
592  break;
593 
594  case DIR_STREAM:
595  stream = avformat_new_stream(avf, NULL);
596  if (!stream)
597  FAIL(AVERROR(ENOMEM));
598  break;
599 
600  case DIR_EXSID:
601  stream->id = arg_int[0];
602  break;
603  case DIR_STMETA:
604  ret = av_dict_set(&stream->metadata, arg_kw[0], arg_str[1], AV_DICT_DONT_STRDUP_VAL);
605  arg_str[1] = NULL;
606  if (ret < 0)
607  FAIL(ret);
608  break;
609 
610  case DIR_STCODEC: {
611  const AVCodecDescriptor *codec = avcodec_descriptor_get_by_name(arg_kw[0]);
612  if (!codec) {
613  av_log(avf, AV_LOG_ERROR, "Line %d: codec '%s' not found\n", line, arg_kw[0]);
615  }
616  stream->codecpar->codec_type = codec->type;
617  stream->codecpar->codec_id = codec->id;
618  break;
619  }
620 
621  case DIR_STEDATA: {
622  int size = ff_hex_to_data(NULL, arg_kw[0]);
623  ret = ff_alloc_extradata(stream->codecpar, size);
624  if (ret < 0)
625  FAIL(ret);
626  ff_hex_to_data(stream->codecpar->extradata, arg_kw[0]);
627  break;
628  }
629 
630  case DIR_CHAPTER:
631  chapter = avpriv_new_chapter(avf, arg_int[0], AV_TIME_BASE_Q,
632  arg_int[1], arg_int[2], NULL);
633  if (!chapter)
634  FAIL(ENOMEM);
635  break;
636 
637  default:
638  FAIL(AVERROR_BUG);
639  }
640  }
641 
642  if (file->inpoint != AV_NOPTS_VALUE && file->outpoint != AV_NOPTS_VALUE) {
643  if (file->inpoint > file->outpoint ||
644  file->outpoint - (uint64_t)file->inpoint > INT64_MAX)
646  }
647 
648 fail:
649  for (arg = 0; arg < MAX_ARGS; arg++)
650  av_freep(&arg_str[arg]);
651  av_bprint_finalize(&bp, NULL);
652  return ret == AVERROR_EOF ? 0 : ret;
653 }
654 
656 {
657  ConcatContext *cat = avf->priv_data;
658  int64_t time = 0;
659  unsigned i;
660  int ret;
661 
662  ret = concat_parse_script(avf);
663  if (ret < 0)
664  return ret;
665  if (!cat->nb_files) {
666  av_log(avf, AV_LOG_ERROR, "No files to concat\n");
667  return AVERROR_INVALIDDATA;
668  }
669 
670  for (i = 0; i < cat->nb_files; i++) {
671  if (cat->files[i].start_time == AV_NOPTS_VALUE)
672  cat->files[i].start_time = time;
673  else
674  time = cat->files[i].start_time;
675  if (cat->files[i].user_duration == AV_NOPTS_VALUE) {
676  if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE ||
677  cat->files[i].outpoint - (uint64_t)cat->files[i].inpoint != av_sat_sub64(cat->files[i].outpoint, cat->files[i].inpoint)
678  )
679  break;
680  cat->files[i].user_duration = cat->files[i].outpoint - cat->files[i].inpoint;
681  }
682  cat->files[i].duration = cat->files[i].user_duration;
683  if (time + (uint64_t)cat->files[i].user_duration > INT64_MAX)
684  return AVERROR_INVALIDDATA;
685  time += cat->files[i].user_duration;
686  }
687  if (i == cat->nb_files) {
688  avf->duration = time;
689  cat->seekable = 1;
690  }
691 
692  cat->stream_match_mode = avf->nb_streams ? MATCH_EXACT_ID :
694  if ((ret = open_file(avf, 0)) < 0)
695  return ret;
696 
697  return 0;
698 }
699 
701 {
702  ConcatContext *cat = avf->priv_data;
703  unsigned fileno = cat->cur_file - cat->files;
704 
705  cat->cur_file->duration = get_best_effort_duration(cat->cur_file, cat->avf);
706 
707  if (++fileno >= cat->nb_files) {
708  cat->eof = 1;
709  return AVERROR_EOF;
710  }
711  return open_file(avf, fileno);
712 }
713 
715 {
716  int ret;
717 
718  if (cs->bsf) {
719  ret = av_bsf_send_packet(cs->bsf, pkt);
720  if (ret < 0) {
721  av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb filter "
722  "failed to send input packet\n");
723  return ret;
724  }
725 
726  while (!ret)
728 
729  if (ret < 0 && (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)) {
730  av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb filter "
731  "failed to receive output packet\n");
732  return ret;
733  }
734  }
735  return 0;
736 }
737 
738 /* Returns true if the packet dts is greater or equal to the specified outpoint. */
740 {
741  if (cat->cur_file->outpoint != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE) {
742  return av_compare_ts(pkt->dts, cat->avf->streams[pkt->stream_index]->time_base,
743  cat->cur_file->outpoint, AV_TIME_BASE_Q) >= 0;
744  }
745  return 0;
746 }
747 
749 {
750  ConcatContext *cat = avf->priv_data;
751  int ret;
752  int64_t delta;
753  ConcatStream *cs;
754  AVStream *st;
755  FFStream *sti;
756 
757  if (cat->eof)
758  return AVERROR_EOF;
759 
760  if (!cat->avf)
761  return AVERROR(EIO);
762 
763  while (1) {
764  ret = av_read_frame(cat->avf, pkt);
765  if (ret == AVERROR_EOF) {
766  if ((ret = open_next_file(avf)) < 0)
767  return ret;
768  continue;
769  }
770  if (ret < 0)
771  return ret;
772  if ((ret = match_streams(avf)) < 0) {
773  return ret;
774  }
775  if (packet_after_outpoint(cat, pkt)) {
777  if ((ret = open_next_file(avf)) < 0)
778  return ret;
779  continue;
780  }
781  cs = &cat->cur_file->streams[pkt->stream_index];
782  if (cs->out_stream_index < 0) {
784  continue;
785  }
786  break;
787  }
788  if ((ret = filter_packet(avf, cs, pkt)) < 0)
789  return ret;
790 
791  st = cat->avf->streams[pkt->stream_index];
792  sti = ffstream(st);
793  av_log(avf, AV_LOG_DEBUG, "file:%d stream:%d pts:%s pts_time:%s dts:%s dts_time:%s",
794  (unsigned)(cat->cur_file - cat->files), pkt->stream_index,
797 
798  delta = av_rescale_q(cat->cur_file->start_time - cat->cur_file->file_inpoint,
800  cat->avf->streams[pkt->stream_index]->time_base);
801  if (pkt->pts != AV_NOPTS_VALUE)
802  pkt->pts += delta;
803  if (pkt->dts != AV_NOPTS_VALUE)
804  pkt->dts += delta;
805  av_log(avf, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
808  if (cat->cur_file->metadata) {
809  size_t metadata_len;
810  char* packed_metadata = av_packet_pack_dictionary(cat->cur_file->metadata, &metadata_len);
811  if (!packed_metadata)
812  return AVERROR(ENOMEM);
814  packed_metadata, metadata_len);
815  if (ret < 0) {
816  av_freep(&packed_metadata);
817  return ret;
818  }
819  }
820 
821  if (cat->cur_file->duration == AV_NOPTS_VALUE && sti->cur_dts != AV_NOPTS_VALUE) {
822  int64_t next_dts = av_rescale_q(sti->cur_dts, st->time_base, AV_TIME_BASE_Q);
823  if (cat->cur_file->next_dts == AV_NOPTS_VALUE || next_dts > cat->cur_file->next_dts) {
824  cat->cur_file->next_dts = next_dts;
825  }
826  }
827 
829  return 0;
830 }
831 
832 static int try_seek(AVFormatContext *avf, int stream,
833  int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
834 {
835  ConcatContext *cat = avf->priv_data;
836  int64_t t0 = cat->cur_file->start_time - cat->cur_file->file_inpoint;
837 
838  ts -= t0;
839  min_ts = min_ts == INT64_MIN ? INT64_MIN : min_ts - t0;
840  max_ts = max_ts == INT64_MAX ? INT64_MAX : max_ts - t0;
841  if (stream >= 0) {
842  if (stream >= cat->avf->nb_streams)
843  return AVERROR(EIO);
844  ff_rescale_interval(AV_TIME_BASE_Q, cat->avf->streams[stream]->time_base,
845  &min_ts, &ts, &max_ts);
846  }
847  return avformat_seek_file(cat->avf, stream, min_ts, ts, max_ts, flags);
848 }
849 
850 static int real_seek(AVFormatContext *avf, int stream,
851  int64_t min_ts, int64_t ts, int64_t max_ts, int flags, AVFormatContext *cur_avf)
852 {
853  ConcatContext *cat = avf->priv_data;
854  int ret, left, right;
855 
856  if (stream >= 0) {
857  if (stream >= avf->nb_streams)
858  return AVERROR(EINVAL);
860  &min_ts, &ts, &max_ts);
861  }
862 
863  left = 0;
864  right = cat->nb_files;
865 
866  /* Always support seek to start */
867  if (ts <= 0)
868  right = 1;
869  else if (!cat->seekable)
870  return AVERROR(ESPIPE); /* XXX: can we use it? */
871 
872  while (right - left > 1) {
873  int mid = (left + right) / 2;
874  if (ts < cat->files[mid].start_time)
875  right = mid;
876  else
877  left = mid;
878  }
879 
880  if (cat->cur_file != &cat->files[left]) {
881  if ((ret = open_file(avf, left)) < 0)
882  return ret;
883  } else {
884  cat->avf = cur_avf;
885  }
886 
887  ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
888  if (ret < 0 &&
889  left < cat->nb_files - 1 &&
890  cat->files[left + 1].start_time < max_ts) {
891  if (cat->cur_file == &cat->files[left])
892  cat->avf = NULL;
893  if ((ret = open_file(avf, left + 1)) < 0)
894  return ret;
895  ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
896  }
897  return ret;
898 }
899 
900 static int concat_seek(AVFormatContext *avf, int stream,
901  int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
902 {
903  ConcatContext *cat = avf->priv_data;
904  ConcatFile *cur_file_saved = cat->cur_file;
905  AVFormatContext *cur_avf_saved = cat->avf;
906  int ret;
907 
909  return AVERROR(ENOSYS);
910  cat->avf = NULL;
911  if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags, cur_avf_saved)) < 0) {
912  if (cat->cur_file != cur_file_saved) {
913  if (cat->avf)
914  avformat_close_input(&cat->avf);
915  }
916  cat->avf = cur_avf_saved;
917  cat->cur_file = cur_file_saved;
918  } else {
919  if (cat->cur_file != cur_file_saved) {
920  avformat_close_input(&cur_avf_saved);
921  }
922  cat->eof = 0;
923  }
924  return ret;
925 }
926 
927 #define OFFSET(x) offsetof(ConcatContext, x)
928 #define DEC AV_OPT_FLAG_DECODING_PARAM
929 
930 static const AVOption options[] = {
931  { "safe", "enable safe mode",
932  OFFSET(safe), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
933  { "auto_convert", "automatically convert bitstream format",
934  OFFSET(auto_convert), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
935  { "segment_time_metadata", "output file segment start time and duration as packet metadata",
936  OFFSET(segment_time_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
937  { NULL }
938 };
939 
940 static const AVClass concat_class = {
941  .class_name = "concat demuxer",
942  .item_name = av_default_item_name,
943  .option = options,
944  .version = LIBAVUTIL_VERSION_INT,
945 };
946 
947 
949  .p.name = "concat",
950  .p.long_name = NULL_IF_CONFIG_SMALL("Virtual concatenation script"),
951  .p.priv_class = &concat_class,
952  .priv_data_size = sizeof(ConcatContext),
953  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
958  .read_seek2 = concat_seek,
959 };
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:115
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:850
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:427
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:432
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:927
packet_after_outpoint
static int packet_after_outpoint(ConcatContext *cat, AVPacket *pkt)
Definition: concatdec.c:739
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:52
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:417
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:2448
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:74
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:54
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:322
ConcatFile::file_inpoint
int64_t file_inpoint
Definition: concatdec.c:51
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1323
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:855
AVOption
AVOption.
Definition: opt.h:346
t0
#define t0
Definition: regdef.h:28
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:832
AVFMT_FLAG_CUSTOM_IO
#define AVFMT_FLAG_CUSTOM_IO
The caller has supplied a custom AVIOContext, don't avio_close() it.
Definition: avformat.h:1414
ConcatContext::stream_match_mode
ConcatMatchMode stream_match_mode
Definition: concatdec.c:72
AVSEEK_FLAG_BYTE
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition: avformat.h:2446
open_next_file
static int open_next_file(AVFormatContext *avf)
Definition: concatdec.c:700
DIR_FFCONCAT
@ DIR_FFCONCAT
Definition: concatdec.c:427
concat_parse_script
static int concat_parse_script(AVFormatContext *avf)
Definition: concatdec.c:460
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:77
cat
#define cat(a, bpp, b)
Definition: vp9dsp_init.h:32
ConcatContext::nb_files
unsigned nb_files
Definition: concatdec.c:67
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:415
av_read_frame
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition: demux.c:1526
DIR_OPTION
@ DIR_OPTION
Definition: concatdec.c:434
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:463
avformat_close_input
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition: demux.c:363
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1528
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:853
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: packet.c:197
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:417
fail
#define fail()
Definition: checkasm.h:179
concat_read_header
static int concat_read_header(AVFormatContext *avf)
Definition: concatdec.c:655
match_streams_exact_id
static int match_streams_exact_id(AVFormatContext *avf)
Definition: concatdec.c:263
ParseSyntax::keyword
const char * keyword
Definition: concatdec.c:421
filter_packet
static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
Definition: concatdec.c:714
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
ConcatFile::outpoint
int64_t outpoint
Definition: concatdec.c:57
AVChapter
Definition: avformat.h:1214
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:748
AVRational::num
int num
Numerator.
Definition: rational.h:59
SPACE_CHARS
#define SPACE_CHARS
Definition: dnn_backend_tf.c:370
DIR_FPMETAS
@ DIR_FPMETAS
Definition: concatdec.c:433
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:55
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
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:83
ConcatFile::file_start_time
int64_t file_start_time
Definition: concatdec.c:50
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:215
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
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:174
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1406
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
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:384
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:56
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:477
arg
const char * arg
Definition: jacosubdec.c:67
FF_INFMT_FLAG_INIT_CLEANUP
#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
MATCH_ONE_TO_ONE
@ MATCH_ONE_TO_ONE
Definition: concatdec.c:38
ParseSyntax
Definition: concatdec.c:420
NEEDS_UNSAFE
#define NEEDS_UNSAFE
Definition: concatdec.c:416
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
options
static const AVOption options[]
Definition: concatdec.c:930
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
open_file
static int open_file(AVFormatContext *avf, unsigned fileno)
Definition: concatdec.c:335
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:782
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:898
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:1297
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:451
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:764
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:823
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:439
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:1311
av_sat_sub64
#define av_sat_sub64
Definition: common.h:144
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:2503
ConcatContext::avf
AVFormatContext * avf
Definition: concatdec.c:68
f
f
Definition: af_crystalizer.c:121
DIR_EXSID
@ DIR_EXSID
Definition: concatdec.c:436
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:83
NEEDS_STREAM
#define NEEDS_STREAM
Definition: concatdec.c:418
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:94
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:161
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
FFStream
Definition: internal.h:193
ConcatStream
Definition: concatdec.c:42
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:832
ParseSyntax::args
char args[MAX_ARGS]
Definition: concatdec.c:422
start_time
static int64_t start_time
Definition: ffplay.c:326
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1371
size
int size
Definition: twinvq_data.h:10344
DIR_OUTPOINT
@ DIR_OUTPOINT
Definition: concatdec.c:431
ConcatStream::out_stream_index
int out_stream_index
Definition: concatdec.c:44
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:663
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:73
match_streams_one_to_one
static int match_streams_one_to_one(AVFormatContext *avf)
Definition: concatdec.c:243
DIR_STMETA
@ DIR_STMETA
Definition: concatdec.c:437
concat_class
static const AVClass concat_class
Definition: concatdec.c:940
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:821
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:41
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:523
FAIL
#define FAIL(retcode)
Definition: concatdec.c:113
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: packet.c:312
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:223
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:429
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:94
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:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:517
avio_internal.h
ConcatFile::start_time
int64_t start_time
Definition: concatdec.c:49
ConcatContext::cur_file
ConcatFile * cur_file
Definition: concatdec.c:66
MATCH_EXACT_ID
@ MATCH_EXACT_ID
Definition: concatdec.c:39
delta
float delta
Definition: vorbis_enc_data.h:430
url.h
ff_concat_demuxer
const FFInputFormat ff_concat_demuxer
Definition: concatdec.c:948
demux.h
ConcatContext::eof
int eof
Definition: concatdec.c:71
ConcatContext
Definition: avf_concat.c:39
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:755
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
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:43
ConcatFile
Definition: concatdec.c:47
avformat.h
DIR_FILE
@ DIR_FILE
Definition: concatdec.c:428
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:443
probe
static int probe(const AVProbeData *p)
Definition: act.c:39
ConcatFile::url
char * url
Definition: concatdec.c:48
AVBitStreamFilter
Definition: bsf.h:111
ConcatContext::seekable
int seekable
Definition: concatdec.c:70
DEC
#define DEC
Definition: concatdec.c:928
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:200
ConcatContext::files
ConcatFile * files
Definition: concatdec.c:65
AVStream::r_frame_rate
AVRational r_frame_rate
Real base framerate of the stream.
Definition: avformat.h:909
ParseSyntax::flags
uint8_t flags
Definition: concatdec.c:423
AVFormatContext::duration
int64_t duration
Duration of the stream, in AV_TIME_BASE fractional seconds.
Definition: avformat.h:1390
AVPacket::stream_index
int stream_index
Definition: packet.h:526
DIR_INPOINT
@ DIR_INPOINT
Definition: concatdec.c:430
ConcatFile::nb_streams
int nb_streams
Definition: concatdec.c:60
DIR_STREAM
@ DIR_STREAM
Definition: concatdec.c:435
ConcatFile::options
AVDictionary * options
Definition: concatdec.c:59
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:167
detect_stream_specific
static int detect_stream_specific(AVFormatContext *avf, int idx)
Definition: concatdec.c:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
mem.h
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:501
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
ParseDirective
ParseDirective
Definition: concatdec.c:426
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:237
FFStream::cur_dts
int64_t cur_dts
Definition: internal.h:410
FFInputFormat
Definition: demux.h:37
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:657
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:69
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:900
avstring.h
ConcatFile::metadata
AVDictionary * metadata
Definition: concatdec.c:58
DIR_CHAPTER
@ DIR_CHAPTER
Definition: concatdec.c:440
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:3749
match_streams
static int match_streams(AVFormatContext *avf)
Definition: concatdec.c:285
codec_desc.h
ConcatMatchMode
ConcatMatchMode
Definition: concatdec.c:37
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1283
ConcatFile::user_duration
int64_t user_duration
Definition: concatdec.c:53
concat_read_close
static int concat_read_close(AVFormatContext *avf)
Definition: concatdec.c:394
DIR_STCODEC
@ DIR_STCODEC
Definition: concatdec.c:438
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:155
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:240
av_bsf_get_by_name
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
Definition: bitstream_filters.c:86