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