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