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