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