FFmpeg
segment.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, Luca Barbato
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
8  * License 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file generic segmenter
23  * M3U8 specification can be find here:
24  * @url{http://tools.ietf.org/id/draft-pantos-http-live-streaming}
25  */
26 
27 #include "config_components.h"
28 
29 #include <time.h>
30 
31 #include "avformat.h"
32 #include "internal.h"
33 #include "mux.h"
34 
35 #include "libavutil/avassert.h"
36 #include "libavutil/internal.h"
37 #include "libavutil/log.h"
38 #include "libavutil/opt.h"
39 #include "libavutil/avstring.h"
40 #include "libavutil/parseutils.h"
41 #include "libavutil/mathematics.h"
42 #include "libavutil/time.h"
43 #include "libavutil/timecode.h"
45 #include "libavutil/timestamp.h"
46 
47 typedef struct SegmentListEntry {
48  int index;
50  int64_t start_pts;
51  int64_t offset_pts;
52  char *filename;
54  int64_t last_duration;
56 
57 typedef enum {
62  LIST_TYPE_EXT, ///< deprecated
65 } ListType;
66 
67 #define SEGMENT_LIST_FLAG_CACHE 1
68 #define SEGMENT_LIST_FLAG_LIVE 2
69 
70 typedef struct SegmentContext {
71  const AVClass *class; /**< Class for private options. */
72  int segment_idx; ///< index of the segment file to write, starting from 0
73  int segment_idx_wrap; ///< number after which the index wraps
74  int segment_idx_wrap_nb; ///< number of time the index has wraped
75  int segment_count; ///< number of segment files already written
78  char *format; ///< format to use for output segment files
80  char *list; ///< filename for the segment list file
81  int list_flags; ///< flags affecting list generation
82  int list_size; ///< number of entries for the segment list file
83 
84  int is_nullctx; ///< whether avf->pb is a nullctx
85  int use_clocktime; ///< flag to cut segments at regular clock time
86  int64_t clocktime_offset; //< clock offset for cutting the segments at regular clock time
87  int64_t clocktime_wrap_duration; //< wrapping duration considered for starting a new segment
88  int64_t last_val; ///< remember last time for wrap around detection
90  int header_written; ///< whether we've already called avformat_write_header
91 
92  char *entry_prefix; ///< prefix to add to list entry filenames
93  int list_type; ///< set the list type
94  AVIOContext *list_pb; ///< list file put-byte context
95  int64_t time; ///< segment duration
96  int use_strftime; ///< flag to expand filename with strftime
97  int increment_tc; ///< flag to increment timecode if found
98 
99  char *times_str; ///< segment times specification string
100  int64_t *times; ///< list of segment interval specification
101  int nb_times; ///< number of elments in the times array
102 
103  char *frames_str; ///< segment frame numbers specification string
104  int *frames; ///< list of frame number specification
105  int nb_frames; ///< number of elments in the frames array
106  int frame_count; ///< total number of reference frames
107  int segment_frame_count; ///< number of reference frames in the segment
108 
109  int64_t time_delta;
110  int individual_header_trailer; /**< Set by a private option. */
111  int write_header_trailer; /**< Set by a private option. */
112  char *header_filename; ///< filename to write the output header to
113 
114  int reset_timestamps; ///< reset timestamps at the beginning of each segment
115  int64_t initial_offset; ///< initial timestamps offset, expressed in microseconds
116  char *reference_stream_specifier; ///< reference stream specifier
120 
122  char temp_list_filename[1024];
123 
128 
129 static void print_csv_escaped_str(AVIOContext *ctx, const char *str)
130 {
131  int needs_quoting = !!str[strcspn(str, "\",\n\r")];
132 
133  if (needs_quoting)
134  avio_w8(ctx, '"');
135 
136  for (; *str; str++) {
137  if (*str == '"')
138  avio_w8(ctx, '"');
139  avio_w8(ctx, *str);
140  }
141  if (needs_quoting)
142  avio_w8(ctx, '"');
143 }
144 
146 {
147  SegmentContext *seg = s->priv_data;
148  AVFormatContext *oc;
149  int i;
150  int ret;
151 
153  if (ret < 0)
154  return ret;
155  oc = seg->avf;
156 
157  oc->interrupt_callback = s->interrupt_callback;
158  oc->max_delay = s->max_delay;
159  av_dict_copy(&oc->metadata, s->metadata, 0);
160  oc->opaque = s->opaque;
161  oc->io_close = s->io_close;
162  oc->io_close2 = s->io_close2;
163  oc->io_open = s->io_open;
164  oc->flags = s->flags;
165 
166  for (i = 0; i < s->nb_streams; i++) {
167  AVStream *st, *ist = s->streams[i];
168  AVCodecParameters *ipar = ist->codecpar, *opar;
169 
170  if (!(st = avformat_new_stream(oc, NULL)))
171  return AVERROR(ENOMEM);
173  if (ret < 0)
174  return ret;
175  opar = st->codecpar;
176  if (!oc->oformat->codec_tag ||
177  av_codec_get_id (oc->oformat->codec_tag, ipar->codec_tag) == opar->codec_id ||
178  av_codec_get_tag(oc->oformat->codec_tag, ipar->codec_id) <= 0) {
179  opar->codec_tag = ipar->codec_tag;
180  } else {
181  opar->codec_tag = 0;
182  }
183  }
184 
185  return 0;
186 }
187 
189 {
190  SegmentContext *seg = s->priv_data;
191  AVFormatContext *oc = seg->avf;
192  size_t size;
193  int ret;
194  char buf[1024];
195  char *new_name;
196 
197  if (seg->segment_idx_wrap)
198  seg->segment_idx %= seg->segment_idx_wrap;
199  if (seg->use_strftime) {
200  time_t now0;
201  struct tm *tm, tmpbuf;
202  time(&now0);
203  tm = localtime_r(&now0, &tmpbuf);
204  if (!strftime(buf, sizeof(buf), s->url, tm)) {
205  av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
206  return AVERROR(EINVAL);
207  }
208  } else if (av_get_frame_filename(buf, sizeof(buf),
209  s->url, seg->segment_idx) < 0) {
210  av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->url);
211  return AVERROR(EINVAL);
212  }
213  new_name = av_strdup(buf);
214  if (!new_name)
215  return AVERROR(ENOMEM);
216  ff_format_set_url(oc, new_name);
217 
218  /* copy modified name in list entry */
219  size = strlen(av_basename(oc->url)) + 1;
220  if (seg->entry_prefix)
221  size += strlen(seg->entry_prefix);
222 
223  if ((ret = av_reallocp(&seg->cur_entry.filename, size)) < 0)
224  return ret;
225  snprintf(seg->cur_entry.filename, size, "%s%s",
226  seg->entry_prefix ? seg->entry_prefix : "",
227  av_basename(oc->url));
228 
229  return 0;
230 }
231 
233 {
234  SegmentContext *seg = s->priv_data;
235  AVFormatContext *oc = seg->avf;
236  int err = 0;
237 
238  if (write_header) {
240  seg->avf = NULL;
241  if ((err = segment_mux_init(s)) < 0)
242  return err;
243  oc = seg->avf;
244  }
245 
246  seg->segment_idx++;
247  if ((seg->segment_idx_wrap) && (seg->segment_idx % seg->segment_idx_wrap == 0))
248  seg->segment_idx_wrap_nb++;
249 
250  if ((err = set_segment_filename(s)) < 0)
251  return err;
252 
253  if ((err = s->io_open(s, &oc->pb, oc->url, AVIO_FLAG_WRITE, NULL)) < 0) {
254  av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->url);
255  return err;
256  }
257  if (!seg->individual_header_trailer)
258  oc->pb->seekable = 0;
259 
260  if (oc->oformat->priv_class && oc->priv_data)
261  av_opt_set(oc->priv_data, "mpegts_flags", "+resend_headers", 0);
262 
263  if (write_header) {
266  av_dict_set(&options, "fflags", "-autobsf", 0);
267  err = avformat_write_header(oc, &options);
269  if (err < 0)
270  return err;
271  }
272 
273  seg->segment_frame_count = 0;
274  return 0;
275 }
276 
278 {
279  SegmentContext *seg = s->priv_data;
280  int ret;
281 
282  snprintf(seg->temp_list_filename, sizeof(seg->temp_list_filename), seg->use_rename ? "%s.tmp" : "%s", seg->list);
283  ret = s->io_open(s, &seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE, NULL);
284  if (ret < 0) {
285  av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list);
286  return ret;
287  }
288 
289  if (seg->list_type == LIST_TYPE_M3U8 && seg->segment_list_entries) {
290  SegmentListEntry *entry;
291  double max_duration = 0;
292 
293  avio_printf(seg->list_pb, "#EXTM3U\n");
294  avio_printf(seg->list_pb, "#EXT-X-VERSION:3\n");
295  avio_printf(seg->list_pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", seg->segment_list_entries->index);
296  avio_printf(seg->list_pb, "#EXT-X-ALLOW-CACHE:%s\n",
297  seg->list_flags & SEGMENT_LIST_FLAG_CACHE ? "YES" : "NO");
298 
299  av_log(s, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%d\n",
301 
302  for (entry = seg->segment_list_entries; entry; entry = entry->next)
303  max_duration = FFMAX(max_duration, entry->end_time - entry->start_time);
304  avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%"PRId64"\n", (int64_t)ceil(max_duration));
305  } else if (seg->list_type == LIST_TYPE_FFCONCAT) {
306  avio_printf(seg->list_pb, "ffconcat version 1.0\n");
307  }
308 
309  return ret;
310 }
311 
312 static void segment_list_print_entry(AVIOContext *list_ioctx,
313  ListType list_type,
314  const SegmentListEntry *list_entry,
315  void *log_ctx)
316 {
317  switch (list_type) {
318  case LIST_TYPE_FLAT:
319  avio_printf(list_ioctx, "%s\n", list_entry->filename);
320  break;
321  case LIST_TYPE_CSV:
322  case LIST_TYPE_EXT:
323  print_csv_escaped_str(list_ioctx, list_entry->filename);
324  avio_printf(list_ioctx, ",%f,%f\n", list_entry->start_time, list_entry->end_time);
325  break;
326  case LIST_TYPE_M3U8:
327  avio_printf(list_ioctx, "#EXTINF:%f,\n%s\n",
328  list_entry->end_time - list_entry->start_time, list_entry->filename);
329  break;
330  case LIST_TYPE_FFCONCAT:
331  {
332  char *buf;
333  if (av_escape(&buf, list_entry->filename, NULL, AV_ESCAPE_MODE_AUTO, AV_ESCAPE_FLAG_WHITESPACE) < 0) {
334  av_log(log_ctx, AV_LOG_WARNING,
335  "Error writing list entry '%s' in list file\n", list_entry->filename);
336  return;
337  }
338  avio_printf(list_ioctx, "file %s\n", buf);
339  av_free(buf);
340  break;
341  }
342  default:
343  av_assert0(!"Invalid list type");
344  }
345 }
346 
347 static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
348 {
349  SegmentContext *seg = s->priv_data;
350  AVFormatContext *oc = seg->avf;
351  int ret = 0;
352  AVTimecode tc;
353  AVRational rate;
354  AVDictionaryEntry *tcr;
355  char buf[AV_TIMECODE_STR_SIZE];
356  int i;
357  int err;
358 
359  if (!oc || !oc->pb)
360  return AVERROR(EINVAL);
361 
362  av_write_frame(oc, NULL); /* Flush any buffered data (fragmented mp4) */
363  if (write_trailer)
364  ret = av_write_trailer(oc);
365 
366  if (ret < 0)
367  av_log(s, AV_LOG_ERROR, "Failure occurred when ending segment '%s'\n",
368  oc->url);
369 
370  if (seg->list) {
371  if (seg->list_size || seg->list_type == LIST_TYPE_M3U8) {
372  SegmentListEntry *entry = av_mallocz(sizeof(*entry));
373  if (!entry) {
374  ret = AVERROR(ENOMEM);
375  goto end;
376  }
377 
378  /* append new element */
379  memcpy(entry, &seg->cur_entry, sizeof(*entry));
380  entry->filename = av_strdup(entry->filename);
381  if (!seg->segment_list_entries)
383  else
384  seg->segment_list_entries_end->next = entry;
385  seg->segment_list_entries_end = entry;
386 
387  /* drop first item */
388  if (seg->list_size && seg->segment_count >= seg->list_size) {
389  entry = seg->segment_list_entries;
391  av_freep(&entry->filename);
392  av_freep(&entry);
393  }
394 
395  if ((ret = segment_list_open(s)) < 0)
396  goto end;
397  for (entry = seg->segment_list_entries; entry; entry = entry->next)
398  segment_list_print_entry(seg->list_pb, seg->list_type, entry, s);
399  if (seg->list_type == LIST_TYPE_M3U8 && is_last)
400  avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n");
401  ff_format_io_close(s, &seg->list_pb);
402  if (seg->use_rename)
403  ff_rename(seg->temp_list_filename, seg->list, s);
404  } else {
406  avio_flush(seg->list_pb);
407  }
408  }
409 
410  av_log(s, AV_LOG_VERBOSE, "segment:'%s' count:%d ended\n",
411  seg->avf->url, seg->segment_count);
412  seg->segment_count++;
413 
414  if (seg->increment_tc) {
415  tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
416  if (tcr) {
417  /* search the first video stream */
418  for (i = 0; i < s->nb_streams; i++) {
419  if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
420  rate = s->streams[i]->avg_frame_rate;/* Get fps from the video stream */
421  err = av_timecode_init_from_string(&tc, rate, tcr->value, s);
422  if (err < 0) {
423  av_log(s, AV_LOG_WARNING, "Could not increment global timecode, error occurred during timecode creation.\n");
424  break;
425  }
426  tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(rate));/* increment timecode */
427  av_dict_set(&s->metadata, "timecode",
428  av_timecode_make_string(&tc, buf, 0), 0);
429  break;
430  }
431  }
432  } else {
433  av_log(s, AV_LOG_WARNING, "Could not increment global timecode, no global timecode metadata found.\n");
434  }
435  for (i = 0; i < s->nb_streams; i++) {
436  if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
437  char st_buf[AV_TIMECODE_STR_SIZE];
438  AVTimecode st_tc;
439  AVRational st_rate = s->streams[i]->avg_frame_rate;
440  AVDictionaryEntry *st_tcr = av_dict_get(s->streams[i]->metadata, "timecode", NULL, 0);
441  if (st_tcr) {
442  if ((av_timecode_init_from_string(&st_tc, st_rate, st_tcr->value, s) < 0)) {
443  av_log(s, AV_LOG_WARNING, "Could not increment stream %d timecode, error occurred during timecode creation.\n", i);
444  continue;
445  }
446  st_tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(st_rate)); // increment timecode
447  av_dict_set(&s->streams[i]->metadata, "timecode", av_timecode_make_string(&st_tc, st_buf, 0), 0);
448  }
449  }
450  }
451  }
452 
453 end:
454  ff_format_io_close(oc, &oc->pb);
455 
456  return ret;
457 }
458 
459 static int parse_times(void *log_ctx, int64_t **times, int *nb_times,
460  const char *times_str)
461 {
462  char *p;
463  int i, ret = 0;
464  char *times_str1 = av_strdup(times_str);
465  char *saveptr = NULL;
466 
467  if (!times_str1)
468  return AVERROR(ENOMEM);
469 
470 #define FAIL(err) ret = err; goto end
471 
472  *nb_times = 1;
473  for (p = times_str1; *p; p++)
474  if (*p == ',')
475  (*nb_times)++;
476 
477  *times = av_malloc_array(*nb_times, sizeof(**times));
478  if (!*times) {
479  av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced times array\n");
480  FAIL(AVERROR(ENOMEM));
481  }
482 
483  p = times_str1;
484  for (i = 0; i < *nb_times; i++) {
485  int64_t t;
486  char *tstr = av_strtok(p, ",", &saveptr);
487  p = NULL;
488 
489  if (!tstr || !tstr[0]) {
490  av_log(log_ctx, AV_LOG_ERROR, "Empty time specification in times list %s\n",
491  times_str);
492  FAIL(AVERROR(EINVAL));
493  }
494 
495  ret = av_parse_time(&t, tstr, 1);
496  if (ret < 0) {
497  av_log(log_ctx, AV_LOG_ERROR,
498  "Invalid time duration specification '%s' in times list %s\n", tstr, times_str);
499  FAIL(AVERROR(EINVAL));
500  }
501  (*times)[i] = t;
502 
503  /* check on monotonicity */
504  if (i && (*times)[i-1] > (*times)[i]) {
505  av_log(log_ctx, AV_LOG_ERROR,
506  "Specified time %f is smaller than the last time %f\n",
507  (float)((*times)[i])/1000000, (float)((*times)[i-1])/1000000);
508  FAIL(AVERROR(EINVAL));
509  }
510  }
511 
512 end:
513  av_free(times_str1);
514  return ret;
515 }
516 
517 static int parse_frames(void *log_ctx, int **frames, int *nb_frames,
518  const char *frames_str)
519 {
520  const char *p;
521  int i;
522 
523  *nb_frames = 1;
524  for (p = frames_str; *p; p++)
525  if (*p == ',')
526  (*nb_frames)++;
527 
528  *frames = av_malloc_array(*nb_frames, sizeof(**frames));
529  if (!*frames) {
530  av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced frames array\n");
531  return AVERROR(ENOMEM);
532  }
533 
534  p = frames_str;
535  for (i = 0; i < *nb_frames; i++) {
536  long int f;
537  char *tailptr;
538 
539  if (*p == '\0' || *p == ',') {
540  av_log(log_ctx, AV_LOG_ERROR, "Empty frame specification in frame list %s\n",
541  frames_str);
542  return AVERROR(EINVAL);
543  }
544  f = strtol(p, &tailptr, 10);
545  if (*tailptr != '\0' && *tailptr != ',' || f <= 0 || f >= INT_MAX) {
546  av_log(log_ctx, AV_LOG_ERROR,
547  "Invalid argument '%s', must be a positive integer < INT_MAX\n",
548  p);
549  return AVERROR(EINVAL);
550  }
551  if (*tailptr == ',')
552  tailptr++;
553  p = tailptr;
554  (*frames)[i] = f;
555 
556  /* check on monotonicity */
557  if (i && (*frames)[i-1] > (*frames)[i]) {
558  av_log(log_ctx, AV_LOG_ERROR,
559  "Specified frame %d is smaller than the last frame %d\n",
560  (*frames)[i], (*frames)[i-1]);
561  return AVERROR(EINVAL);
562  }
563  }
564 
565  return 0;
566 }
567 
569 {
570  int buf_size = 32768;
571  uint8_t *buf = av_malloc(buf_size);
572  if (!buf)
573  return AVERROR(ENOMEM);
574  *ctx = avio_alloc_context(buf, buf_size, 1, NULL, NULL, NULL, NULL);
575  if (!*ctx) {
576  av_free(buf);
577  return AVERROR(ENOMEM);
578  }
579  return 0;
580 }
581 
582 static void close_null_ctxp(AVIOContext **pb)
583 {
584  av_freep(&(*pb)->buffer);
585  avio_context_free(pb);
586 }
587 
589 {
590  SegmentContext *seg = s->priv_data;
591  int ret, i;
592 
593  seg->reference_stream_index = -1;
594  if (!strcmp(seg->reference_stream_specifier, "auto")) {
595  /* select first index of type with highest priority */
596  int type_index_map[AVMEDIA_TYPE_NB];
597  static const enum AVMediaType type_priority_list[] = {
603  };
604  enum AVMediaType type;
605 
606  for (i = 0; i < AVMEDIA_TYPE_NB; i++)
607  type_index_map[i] = -1;
608 
609  /* select first index for each type */
610  for (i = 0; i < s->nb_streams; i++) {
611  type = s->streams[i]->codecpar->codec_type;
612  if ((unsigned)type < AVMEDIA_TYPE_NB && type_index_map[type] == -1
613  /* ignore attached pictures/cover art streams */
614  && !(s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC))
615  type_index_map[type] = i;
616  }
617 
618  for (i = 0; i < FF_ARRAY_ELEMS(type_priority_list); i++) {
619  type = type_priority_list[i];
620  if ((seg->reference_stream_index = type_index_map[type]) >= 0)
621  break;
622  }
623  } else {
624  for (i = 0; i < s->nb_streams; i++) {
625  ret = avformat_match_stream_specifier(s, s->streams[i],
627  if (ret < 0)
628  return ret;
629  if (ret > 0) {
630  seg->reference_stream_index = i;
631  break;
632  }
633  }
634  }
635 
636  if (seg->reference_stream_index < 0) {
637  av_log(s, AV_LOG_ERROR, "Could not select stream matching identifier '%s'\n",
639  return AVERROR(EINVAL);
640  }
641 
642  return 0;
643 }
644 
646 {
647  SegmentContext *seg = s->priv_data;
648  SegmentListEntry *cur;
649 
650  ff_format_io_close(s, &seg->list_pb);
651  if (seg->avf) {
652  if (seg->is_nullctx)
653  close_null_ctxp(&seg->avf->pb);
654  else
655  ff_format_io_close(s, &seg->avf->pb);
657  seg->avf = NULL;
658  }
659  av_freep(&seg->times);
660  av_freep(&seg->frames);
661  av_freep(&seg->cur_entry.filename);
662 
663  cur = seg->segment_list_entries;
664  while (cur) {
665  SegmentListEntry *next = cur->next;
666  av_freep(&cur->filename);
667  av_free(cur);
668  cur = next;
669  }
670 }
671 
673 {
674  SegmentContext *seg = s->priv_data;
675  AVFormatContext *oc = seg->avf;
677  int ret;
678  int i;
679 
680  seg->segment_count = 0;
681  if (!seg->write_header_trailer)
682  seg->individual_header_trailer = 0;
683 
684  if (seg->header_filename) {
685  seg->write_header_trailer = 1;
686  seg->individual_header_trailer = 0;
687  }
688 
689  if (seg->initial_offset > 0) {
690  av_log(s, AV_LOG_WARNING, "NOTE: the option initial_offset is deprecated,"
691  "you can use output_ts_offset instead of it\n");
692  }
693 
694  if ((seg->time != 2000000) + !!seg->times_str + !!seg->frames_str > 1) {
696  "segment_time, segment_times, and segment_frames options "
697  "are mutually exclusive, select just one of them\n");
698  return AVERROR(EINVAL);
699  }
700 
701  if (seg->times_str) {
702  if ((ret = parse_times(s, &seg->times, &seg->nb_times, seg->times_str)) < 0)
703  return ret;
704  } else if (seg->frames_str) {
705  if ((ret = parse_frames(s, &seg->frames, &seg->nb_frames, seg->frames_str)) < 0)
706  return ret;
707  } else {
708  if (seg->use_clocktime) {
709  if (seg->time <= 0) {
710  av_log(s, AV_LOG_ERROR, "Invalid negative segment_time with segment_atclocktime option set\n");
711  return AVERROR(EINVAL);
712  }
713  seg->clocktime_offset = seg->time - (seg->clocktime_offset % seg->time);
714  }
715  }
716 
717  if (seg->list) {
718  if (seg->list_type == LIST_TYPE_UNDEFINED) {
719  if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
720  else if (av_match_ext(seg->list, "ext" )) seg->list_type = LIST_TYPE_EXT;
721  else if (av_match_ext(seg->list, "m3u8")) seg->list_type = LIST_TYPE_M3U8;
722  else if (av_match_ext(seg->list, "ffcat,ffconcat")) seg->list_type = LIST_TYPE_FFCONCAT;
723  else seg->list_type = LIST_TYPE_FLAT;
724  }
725  if (!seg->list_size && seg->list_type != LIST_TYPE_M3U8) {
726  if ((ret = segment_list_open(s)) < 0)
727  return ret;
728  } else {
729  const char *proto = avio_find_protocol_name(seg->list);
730  seg->use_rename = proto && !strcmp(proto, "file");
731  }
732  }
733 
734  if (seg->list_type == LIST_TYPE_EXT)
735  av_log(s, AV_LOG_WARNING, "'ext' list type option is deprecated in favor of 'csv'\n");
736 
737  if ((ret = select_reference_stream(s)) < 0)
738  return ret;
739  av_log(s, AV_LOG_VERBOSE, "Selected stream id:%d type:%s\n",
741  av_get_media_type_string(s->streams[seg->reference_stream_index]->codecpar->codec_type));
742 
743  seg->oformat = av_guess_format(seg->format, s->url, NULL);
744 
745  if (!seg->oformat)
747  if (seg->oformat->flags & AVFMT_NOFILE) {
748  av_log(s, AV_LOG_ERROR, "format %s not supported.\n",
749  seg->oformat->name);
750  return AVERROR(EINVAL);
751  }
752 
753  if ((ret = segment_mux_init(s)) < 0)
754  return ret;
755 
756  if ((ret = set_segment_filename(s)) < 0)
757  return ret;
758  oc = seg->avf;
759 
760  if (seg->write_header_trailer) {
761  if ((ret = s->io_open(s, &oc->pb,
762  seg->header_filename ? seg->header_filename : oc->url,
763  AVIO_FLAG_WRITE, NULL)) < 0) {
764  av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->url);
765  return ret;
766  }
767  if (!seg->individual_header_trailer)
768  oc->pb->seekable = 0;
769  } else {
770  if ((ret = open_null_ctx(&oc->pb)) < 0)
771  return ret;
772  seg->is_nullctx = 1;
773  }
774 
776  av_dict_set(&options, "fflags", "-autobsf", 0);
778  if (av_dict_count(options)) {
780  "Some of the provided format options are not recognized\n");
782  return AVERROR(EINVAL);
783  }
785 
786  if (ret < 0) {
787  return ret;
788  }
789  seg->segment_frame_count = 0;
790 
791  av_assert0(s->nb_streams == oc->nb_streams);
794  if (ret < 0)
795  return ret;
796  seg->header_written = 1;
797  }
798 
799  for (i = 0; i < s->nb_streams; i++) {
800  AVStream *inner_st = oc->streams[i];
801  AVStream *outer_st = s->streams[i];
802  avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
803  }
804 
805  if (oc->avoid_negative_ts > 0 && s->avoid_negative_ts < 0)
806  s->avoid_negative_ts = 1;
807 
808  return ret;
809 }
810 
812 {
813  SegmentContext *seg = s->priv_data;
814  AVFormatContext *oc = seg->avf;
815  int ret;
816 
817  if (!seg->header_written) {
819  if (ret < 0)
820  return ret;
821  }
822 
823  if (!seg->write_header_trailer || seg->header_filename) {
824  if (seg->header_filename) {
825  av_write_frame(oc, NULL);
826  ff_format_io_close(oc, &oc->pb);
827  } else {
828  close_null_ctxp(&oc->pb);
829  seg->is_nullctx = 0;
830  }
831  if ((ret = oc->io_open(oc, &oc->pb, oc->url, AVIO_FLAG_WRITE, NULL)) < 0)
832  return ret;
833  if (!seg->individual_header_trailer)
834  oc->pb->seekable = 0;
835  }
836 
837  return 0;
838 }
839 
841 {
842  SegmentContext *seg = s->priv_data;
843  AVStream *st = s->streams[pkt->stream_index];
844  int64_t end_pts = INT64_MAX, offset;
845  int start_frame = INT_MAX;
846  int ret;
847  struct tm ti;
848  int64_t usecs;
849  int64_t wrapped_val;
850 
851  if (!seg->avf || !seg->avf->pb)
852  return AVERROR(EINVAL);
853 
854  if (!st->codecpar->extradata_size) {
855  size_t pkt_extradata_size;
856  uint8_t *pkt_extradata = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &pkt_extradata_size);
857  if (pkt_extradata && pkt_extradata_size > 0) {
858  ret = ff_alloc_extradata(st->codecpar, pkt_extradata_size);
859  if (ret < 0) {
860  av_log(s, AV_LOG_WARNING, "Unable to add extradata to stream. Output segments may be invalid.\n");
861  goto calc_times;
862  }
863  memcpy(st->codecpar->extradata, pkt_extradata, pkt_extradata_size);
864  }
865  }
866 
867 calc_times:
868  if (seg->times) {
869  end_pts = seg->segment_count < seg->nb_times ?
870  seg->times[seg->segment_count] : INT64_MAX;
871  } else if (seg->frames) {
872  start_frame = seg->segment_count < seg->nb_frames ?
873  seg->frames[seg->segment_count] : INT_MAX;
874  } else {
875  if (seg->use_clocktime) {
876  int64_t avgt = av_gettime();
877  time_t sec = avgt / 1000000;
878  localtime_r(&sec, &ti);
879  usecs = (int64_t)(ti.tm_hour * 3600 + ti.tm_min * 60 + ti.tm_sec) * 1000000 + (avgt % 1000000);
880  wrapped_val = (usecs + seg->clocktime_offset) % seg->time;
881  if (wrapped_val < seg->last_val && wrapped_val < seg->clocktime_wrap_duration)
882  seg->cut_pending = 1;
883  seg->last_val = wrapped_val;
884  } else {
885  end_pts = seg->time * (seg->segment_count + 1);
886  }
887  }
888 
889  ff_dlog(s, "packet stream:%d pts:%s pts_time:%s duration_time:%s is_key:%d frame:%d\n",
893  pkt->stream_index == seg->reference_stream_index ? seg->frame_count : -1);
894 
895  if (pkt->stream_index == seg->reference_stream_index &&
897  (seg->segment_frame_count > 0 || seg->write_empty) &&
898  (seg->cut_pending || seg->frame_count >= start_frame ||
899  (pkt->pts != AV_NOPTS_VALUE &&
901  end_pts - seg->time_delta, AV_TIME_BASE_Q) >= 0))) {
902  /* sanitize end time in case last packet didn't have a defined duration */
903  if (seg->cur_entry.last_duration == 0)
904  seg->cur_entry.end_time = (double)pkt->pts * av_q2d(st->time_base);
905 
906  if ((ret = segment_end(s, seg->individual_header_trailer, 0)) < 0)
907  goto fail;
908 
909  if ((ret = segment_start(s, seg->individual_header_trailer)) < 0)
910  goto fail;
911 
912  seg->cut_pending = 0;
917 
918  if (seg->times || (!seg->frames && !seg->use_clocktime) && seg->write_empty)
919  goto calc_times;
920  }
921 
922  if (pkt->stream_index == seg->reference_stream_index) {
923  if (pkt->pts != AV_NOPTS_VALUE)
924  seg->cur_entry.end_time =
925  FFMAX(seg->cur_entry.end_time, (double)(pkt->pts + pkt->duration) * av_q2d(st->time_base));
927  }
928 
929  if (seg->segment_frame_count == 0) {
930  av_log(s, AV_LOG_VERBOSE, "segment:'%s' starts with packet stream:%d pts:%s pts_time:%s frame:%d\n",
931  seg->avf->url, pkt->stream_index,
933  }
934 
935  av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s pts_time:%s dts:%s dts_time:%s",
936  pkt->stream_index,
940 
941  /* compute new timestamps */
944  if (pkt->pts != AV_NOPTS_VALUE)
945  pkt->pts += offset;
946  if (pkt->dts != AV_NOPTS_VALUE)
947  pkt->dts += offset;
948 
949  av_log(s, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
952 
955 
956 fail:
957  /* Use st->index here as the packet returned from ff_write_chained()
958  * is blank if interleaving has been used. */
959  if (st->index == seg->reference_stream_index) {
960  seg->frame_count++;
961  seg->segment_frame_count++;
962  }
963 
964  return ret;
965 }
966 
968 {
969  SegmentContext *seg = s->priv_data;
970  AVFormatContext *oc = seg->avf;
971  int ret;
972 
973  if (!oc)
974  return 0;
975 
976  if (!seg->write_header_trailer) {
977  if ((ret = segment_end(s, 0, 1)) < 0)
978  return ret;
979  if ((ret = open_null_ctx(&oc->pb)) < 0)
980  return ret;
981  seg->is_nullctx = 1;
982  ret = av_write_trailer(oc);
983  } else {
984  ret = segment_end(s, 1, 1);
985  }
986  return ret;
987 }
988 
990  const AVPacket *pkt)
991 {
992  SegmentContext *seg = s->priv_data;
993  AVFormatContext *oc = seg->avf;
994  if (oc->oformat->check_bitstream) {
995  AVStream *const ost = oc->streams[st->index];
996  int ret = oc->oformat->check_bitstream(oc, ost, pkt);
997  if (ret == 1) {
998  FFStream *const sti = ffstream(st);
999  FFStream *const osti = ffstream(ost);
1000  sti->bsfc = osti->bsfc;
1001  osti->bsfc = NULL;
1002  }
1003  return ret;
1004  }
1005  return 1;
1006 }
1007 
1008 #define OFFSET(x) offsetof(SegmentContext, x)
1009 #define E AV_OPT_FLAG_ENCODING_PARAM
1010 static const AVOption options[] = {
1011  { "reference_stream", "set reference stream", OFFSET(reference_stream_specifier), AV_OPT_TYPE_STRING, {.str = "auto"}, 0, 0, E },
1012  { "segment_format", "set container format used for the segments", OFFSET(format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
1013  { "segment_format_options", "set list of options for the container format used for the segments", OFFSET(format_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E },
1014  { "segment_list", "set the segment list filename", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
1015  { "segment_header_filename", "write a single file containing the header", OFFSET(header_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
1016 
1017  { "segment_list_flags","set flags affecting segment list generation", OFFSET(list_flags), AV_OPT_TYPE_FLAGS, {.i64 = SEGMENT_LIST_FLAG_CACHE }, 0, UINT_MAX, E, "list_flags"},
1018  { "cache", "allow list caching", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_CACHE }, INT_MIN, INT_MAX, E, "list_flags"},
1019  { "live", "enable live-friendly list generation (useful for HLS)", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_LIVE }, INT_MIN, INT_MAX, E, "list_flags"},
1020 
1021  { "segment_list_size", "set the maximum number of playlist entries", OFFSET(list_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
1022 
1023  { "segment_list_type", "set the segment list type", OFFSET(list_type), AV_OPT_TYPE_INT, {.i64 = LIST_TYPE_UNDEFINED}, -1, LIST_TYPE_NB-1, E, "list_type" },
1024  { "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, "list_type" },
1025  { "csv", "csv format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_CSV }, INT_MIN, INT_MAX, E, "list_type" },
1026  { "ext", "extended format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_EXT }, INT_MIN, INT_MAX, E, "list_type" },
1027  { "ffconcat", "ffconcat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FFCONCAT }, INT_MIN, INT_MAX, E, "list_type" },
1028  { "m3u8", "M3U8 format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" },
1029  { "hls", "Apple HTTP Live Streaming compatible", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" },
1030 
1031  { "segment_atclocktime", "set segment to be cut at clocktime", OFFSET(use_clocktime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
1032  { "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E},
1033  { "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E},
1034  { "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, INT64_MIN, INT64_MAX, E },
1035  { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
1036  { "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
1037  { "segment_frames", "set segment split frame numbers", OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
1038  { "segment_wrap", "set number after which the index wraps", OFFSET(segment_idx_wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
1039  { "segment_list_entry_prefix", "set base url prefix for segments", OFFSET(entry_prefix), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
1040  { "segment_start_number", "set the sequence number of the first segment", OFFSET(segment_idx), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
1041  { "segment_wrap_number", "set the number of wrap before the first segment", OFFSET(segment_idx_wrap_nb), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
1042  { "strftime", "set filename expansion with strftime at segment creation", OFFSET(use_strftime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
1043  { "increment_tc", "increment timecode between each segment", OFFSET(increment_tc), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
1044  { "break_non_keyframes", "allow breaking segments on non-keyframes", OFFSET(break_non_keyframes), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
1045 
1046  { "individual_header_trailer", "write header/trailer to each segment", OFFSET(individual_header_trailer), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, E },
1047  { "write_header_trailer", "write a header to the first segment and a trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, E },
1048  { "reset_timestamps", "reset timestamps at the beginning of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
1049  { "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
1050  { "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
1051  { NULL },
1052 };
1053 
1054 static const AVClass seg_class = {
1055  .class_name = "(stream) segment muxer",
1056  .item_name = av_default_item_name,
1057  .option = options,
1058  .version = LIBAVUTIL_VERSION_INT,
1059 };
1060 
1061 #if CONFIG_SEGMENT_MUXER
1063  .name = "segment",
1064  .long_name = NULL_IF_CONFIG_SMALL("segment"),
1065  .priv_data_size = sizeof(SegmentContext),
1067  .init = seg_init,
1071  .deinit = seg_free,
1073  .priv_class = &seg_class,
1074 };
1075 #endif
1076 
1077 #if CONFIG_STREAM_SEGMENT_MUXER
1079  .name = "stream_segment,ssegment",
1080  .long_name = NULL_IF_CONFIG_SMALL("streaming segment muxer"),
1081  .priv_data_size = sizeof(SegmentContext),
1082  .flags = AVFMT_NOFILE,
1083  .init = seg_init,
1087  .deinit = seg_free,
1089  .priv_class = &seg_class,
1090 };
1091 #endif
SEGMENT_LIST_FLAG_LIVE
#define SEGMENT_LIST_FLAG_LIVE
Definition: segment.c:68
SegmentContext::write_header_trailer
int write_header_trailer
Set by a private option.
Definition: segment.c:111
SegmentListEntry::index
int index
Definition: segment.c:48
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
av_codec_get_id
enum AVCodecID av_codec_get_id(const struct AVCodecTag *const *tags, unsigned int tag)
Get the AVCodecID for the given codec tag tag.
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
LIST_TYPE_UNDEFINED
@ LIST_TYPE_UNDEFINED
Definition: segment.c:58
AV_TIMECODE_STR_SIZE
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
SegmentContext::clocktime_wrap_duration
int64_t clocktime_wrap_duration
Definition: segment.c:87
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:75
SegmentContext::avf
AVFormatContext * avf
Definition: segment.c:77
AVOutputFormat::name
const char * name
Definition: avformat.h:510
AVSTREAM_INIT_IN_WRITE_HEADER
#define AVSTREAM_INIT_IN_WRITE_HEADER
stream parameters initialized in avformat_write_header
Definition: avformat.h:2299
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: options.c:237
SegmentContext::list_pb
AVIOContext * list_pb
list file put-byte context
Definition: segment.c:94
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
FFStream::bsfc
struct AVBSFContext * bsfc
bitstream filter to run on stream
Definition: internal.h:214
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:53
segment_start
static int segment_start(AVFormatContext *s, int write_header)
Definition: segment.c:232
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:879
av_dict_count
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:35
LIST_TYPE_CSV
@ LIST_TYPE_CSV
Definition: segment.c:60
SegmentContext::use_clocktime
int use_clocktime
flag to cut segments at regular clock time
Definition: segment.c:85
avio_context_free
void avio_context_free(AVIOContext **s)
Free the supplied IO context and everything associated with it.
Definition: aviobuf.c:152
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
check_bitstream
static int check_bitstream(AVFormatContext *s, FFStream *sti, AVPacket *pkt)
Definition: mux.c:1069
SegmentContext::list_type
int list_type
set the list type
Definition: segment.c:93
SegmentContext::nb_frames
int nb_frames
number of elments in the frames array
Definition: segment.c:105
SegmentContext::segment_idx_wrap
int segment_idx_wrap
number after which the index wraps
Definition: segment.c:73
ff_stream_encode_params_copy
int ff_stream_encode_params_copy(AVStream *dst, const AVStream *src)
Copy encoding parameters from source to destination stream.
Definition: mux_utils.c:124
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1281
deinit
static void deinit(AVFormatContext *s)
Definition: chromaprint.c:49
segment_mux_init
static int segment_mux_init(AVFormatContext *s)
Definition: segment.c:145
AVOption
AVOption.
Definition: opt.h:251
SegmentContext::segment_count
int segment_count
number of segment files already written
Definition: segment.c:75
SegmentContext::times_str
char * times_str
segment times specification string
Definition: segment.c:99
ff_stream_segment_muxer
const AVOutputFormat ff_stream_segment_muxer
SegmentContext::break_non_keyframes
int break_non_keyframes
Definition: segment.c:118
AV_OPT_TYPE_DURATION
@ AV_OPT_TYPE_DURATION
Definition: opt.h:239
SegmentContext::frames_str
char * frames_str
segment frame numbers specification string
Definition: segment.c:103
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:392
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:65
mathematics.h
AVDictionary
Definition: dict.c:30
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
FAIL
#define FAIL(err)
avformat_init_output
av_warn_unused_result int avformat_init_output(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and initialize the codec, but do not write the header.
Definition: mux.c:428
SegmentContext::cur_entry
SegmentListEntry cur_entry
Definition: segment.c:124
SegmentContext::list
char * list
filename for the segment list file
Definition: segment.c:80
av_get_frame_filename
int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
Definition: utils.c:352
SegmentListEntry::next
struct SegmentListEntry * next
Definition: segment.c:53
ost
static AVStream * ost
Definition: vaapi_transcode.c:45
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:429
av_basename
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:263
SegmentContext::time
int64_t time
segment duration
Definition: segment.c:95
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
SegmentContext::use_rename
int use_rename
Definition: segment.c:121
init
static int init
Definition: av_tx.c:47
SegmentContext::temp_list_filename
char temp_list_filename[1024]
Definition: segment.c:122
SegmentContext::is_nullctx
int is_nullctx
whether avf->pb is a nullctx
Definition: segment.c:84
segment_end
static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
Definition: segment.c:347
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1480
ff_segment_muxer
const AVOutputFormat ff_segment_muxer
SegmentListEntry
Definition: segment.c:47
SegmentContext::nb_times
int nb_times
number of elments in the times array
Definition: segment.c:101
parse_frames
static int parse_frames(void *log_ctx, int **frames, int *nb_frames, const char *frames_str)
Definition: segment.c:517
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:697
seg_write_header
static int seg_write_header(AVFormatContext *s)
Definition: segment.c:811
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:407
av_escape
int av_escape(char **dst, const char *src, const char *special_chars, enum AVEscapeMode mode, int flags)
Escape string in src, and put the escaped string in an allocated string in *dst, which must be freed ...
Definition: avstring.c:338
fail
#define fail()
Definition: checkasm.h:130
frames
if it could not because there are no more frames
Definition: filter_design.txt:266
timecode.h
SegmentContext::reference_stream_index
int reference_stream_index
Definition: segment.c:117
AVTimecode::start
int start
timecode frame start (first base frame number)
Definition: timecode.h:42
av_timecode_make_string
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
Load timecode string in buf.
Definition: timecode.c:103
SegmentContext::oformat
const AVOutputFormat * oformat
Definition: segment.c:76
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:487
close_null_ctxp
static void close_null_ctxp(AVIOContext **pb)
Definition: segment.c:582
SegmentContext::cut_pending
int cut_pending
Definition: segment.c:89
AV_ESCAPE_FLAG_WHITESPACE
#define AV_ESCAPE_FLAG_WHITESPACE
Consider spaces special and escape them even in the middle of the string.
Definition: avstring.h:338
ff_rename
int ff_rename(const char *url_src, const char *url_dst, void *logctx)
Wrap ffurl_move() and log if error happens.
Definition: avio.c:665
AVRational::num
int num
Numerator.
Definition: rational.h:59
select_reference_stream
static int select_reference_stream(AVFormatContext *s)
Definition: segment.c:588
seg_check_bitstream
static int seg_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Definition: segment.c:989
SegmentContext::use_strftime
int use_strftime
flag to expand filename with strftime
Definition: segment.c:96
avassert.h
SegmentContext::reset_timestamps
int reset_timestamps
reset timestamps at the beginning of each segment
Definition: segment.c:114
ceil
static __device__ float ceil(float a)
Definition: cuda_runtime.h:176
SegmentContext::frame_count
int frame_count
total number of reference frames
Definition: segment.c:106
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVFormatContext::metadata
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1442
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
SegmentListEntry::offset_pts
int64_t offset_pts
Definition: segment.c:51
SegmentContext::format
char * format
format to use for output segment files
Definition: segment.c:78
seg_write_trailer
static int seg_write_trailer(struct AVFormatContext *s)
Definition: segment.c:967
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
s
#define s(width, name)
Definition: cbs_vp9.c:256
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1331
format
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
av_strtok
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition: avstring.c:189
av_match_ext
int av_match_ext(const char *filename, const char *extensions)
Return a positive value if the given filename has one of the given extensions, 0 otherwise.
Definition: format.c:40
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AVMEDIA_TYPE_NB
@ AVMEDIA_TYPE_NB
Definition: avutil.h:206
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:623
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
SegmentContext::write_empty
int write_empty
Definition: segment.c:119
SegmentListEntry::last_duration
int64_t last_duration
Definition: segment.c:54
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
AVOutputFormat::codec_tag
const struct AVCodecTag *const * codec_tag
List of supported codec_id-codec_tag pairs, ordered by "better choice first".
Definition: avformat.h:535
AVFormatContext::opaque
void * opaque
User data.
Definition: avformat.h:1719
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:203
avformat_write_header
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition: mux.c:449
SegmentListEntry::start_pts
int64_t start_pts
Definition: segment.c:50
time_internal.h
if
if(ret)
Definition: filter_design.txt:179
seg_init
static int seg_init(AVFormatContext *s)
Definition: segment.c:672
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:252
AVFormatContext
Format I/O context.
Definition: avformat.h:1213
internal.h
SegmentContext::format_options
AVDictionary * format_options
Definition: segment.c:79
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1108
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:978
NULL
#define NULL
Definition: coverity.c:32
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:100
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
LIST_TYPE_EXT
@ LIST_TYPE_EXT
deprecated
Definition: segment.c:62
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Definition: opt.h:232
SegmentContext::frames
int * frames
list of frame number specification
Definition: segment.c:104
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1255
parseutils.h
list
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 list
Definition: filter_design.txt:25
double
double
Definition: af_crystalizer.c:132
av_parse_time
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
Definition: parseutils.c:589
time.h
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:210
set_segment_filename
static int set_segment_filename(AVFormatContext *s)
Definition: segment.c:188
AVOutputFormat::priv_class
const AVClass * priv_class
AVClass for the private context.
Definition: avformat.h:538
av_write_frame
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:1188
AV_ESCAPE_MODE_AUTO
@ AV_ESCAPE_MODE_AUTO
Use auto-selected escaping mode.
Definition: avstring.h:324
ff_write_chained
int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, AVFormatContext *src, int interleave)
Write a packet to another muxer than the one the user originally intended.
Definition: mux.c:1350
seg_write_packet
static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: segment.c:840
segment_list_open
static int segment_list_open(AVFormatContext *s)
Definition: segment.c:277
SegmentContext::clocktime_offset
int64_t clocktime_offset
Definition: segment.c:86
OFFSET
#define OFFSET(x)
Definition: segment.c:1008
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:79
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1269
AVOutputFormat::flags
int flags
can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS,...
Definition: avformat.h:529
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
SegmentContext::entry_prefix
char * entry_prefix
prefix to add to list entry filenames
Definition: segment.c:92
LIST_TYPE_FLAT
@ LIST_TYPE_FLAT
Definition: segment.c:59
SegmentContext::increment_tc
int increment_tc
flag to increment timecode if found
Definition: segment.c:97
print_csv_escaped_str
static void print_csv_escaped_str(AVIOContext *ctx, const char *str)
Definition: segment.c:129
SegmentContext::segment_list_entries_end
SegmentListEntry * segment_list_entries_end
Definition: segment.c:126
f
f
Definition: af_crystalizer.c:122
AVIOContext
Bytestream IO Context.
Definition: avio.h:162
av_ts2timestr
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:76
AVMediaType
AVMediaType
Definition: avutil.h:199
avformat_match_stream_specifier
int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
Check if the stream st contained in s is matched by the stream specifier spec.
Definition: avformat.c:545
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:116
av_codec_get_tag
unsigned int av_codec_get_tag(const struct AVCodecTag *const *tags, enum AVCodecID id)
Get the codec tag for the given codec id id.
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:263
FFStream
Definition: internal.h:197
localtime_r
#define localtime_r
Definition: time_internal.h:46
SegmentContext::time_delta
int64_t time_delta
Definition: segment.c:109
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1296
size
int size
Definition: twinvq_data.h:10344
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:186
SegmentContext
Definition: f_segment.c:37
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
seg_free
static void seg_free(AVFormatContext *s)
Definition: segment.c:645
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:470
LIST_TYPE_NB
@ LIST_TYPE_NB
Definition: segment.c:64
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:779
SegmentContext::header_written
int header_written
whether we've already called avformat_write_header
Definition: segment.c:90
ListType
ListType
Definition: segment.c:57
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:373
SegmentContext::segment_frame_count
int segment_frame_count
number of reference frames in the segment
Definition: segment.c:107
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:380
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:203
LIST_TYPE_M3U8
@ LIST_TYPE_M3U8
Definition: segment.c:61
SegmentContext::segment_idx_wrap_nb
int segment_idx_wrap_nb
number of time the index has wraped
Definition: segment.c:74
AVOutputFormat::interleave_packet
int(* interleave_packet)(struct AVFormatContext *s, AVPacket *pkt, int flush, int has_packet)
A format-specific function for interleavement.
Definition: avformat.h:583
SegmentListEntry::end_time
double end_time
Definition: segment.c:49
SegmentContext::last_val
int64_t last_val
remember last time for wrap around detection
Definition: segment.c:88
av_write_trailer
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1250
SegmentContext::segment_idx
int segment_idx
index of the segment file to write, starting from 0
Definition: segment.c:72
SegmentContext::reference_stream_specifier
char * reference_stream_specifier
reference stream specifier
Definition: segment.c:116
log.h
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:480
AVOutputFormat
Definition: avformat.h:509
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:367
SegmentListEntry::start_time
double start_time
Definition: segment.c:49
av_packet_get_side_data
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition: avpacket.c:251
internal.h
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:62
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AVFormatContext::avoid_negative_ts
int avoid_negative_ts
Avoid negative timestamps during muxing.
Definition: avformat.h:1545
AVMEDIA_TYPE_ATTACHMENT
@ AVMEDIA_TYPE_ATTACHMENT
Opaque data information usually sparse.
Definition: avutil.h:205
avio_alloc_context
AVIOContext * avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Allocate and initialize an AVIOContext for buffered I/O.
Definition: aviobuf.c:135
AVFormatContext::max_delay
int max_delay
Definition: avformat.h:1325
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:264
SegmentContext::list_size
int list_size
number of entries for the segment list file
Definition: segment.c:82
SegmentContext::segment_list_entries
SegmentListEntry * segment_list_entries
Definition: segment.c:125
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:948
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
AVFormatContext::oformat
const struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1232
avformat.h
E
#define E
Definition: segment.c:1009
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:956
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
AVRational::den
int den
Denominator.
Definition: rational.h:60
options
static const AVOption options[]
Definition: segment.c:1010
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
segment_list_print_entry
static void segment_list_print_entry(AVIOContext *list_ioctx, ListType list_type, const SegmentListEntry *list_entry, void *log_ctx)
Definition: segment.c:312
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:95
SegmentContext::header_filename
char * header_filename
filename to write the output header to
Definition: segment.c:112
AVFormatContext::io_close
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1779
AVFormatContext::io_open
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
Definition: avformat.h:1773
SegmentContext::individual_header_trailer
int individual_header_trailer
Set by a private option.
Definition: segment.c:110
SegmentContext::list_flags
int list_flags
flags affecting list generation
Definition: segment.c:81
AVPacket::stream_index
int stream_index
Definition: packet.h:376
seg_class
static const AVClass seg_class
Definition: segment.c:1054
SegmentContext::times
int64_t * times
list of segment interval specification
Definition: segment.c:100
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
tc
#define tc
Definition: regdef.h:69
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:280
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
av_guess_format
const AVOutputFormat * av_guess_format(const char *short_name, const char *filename, const char *mime_type)
Return the output format in the list of registered output formats which best matches the provided par...
Definition: format.c:53
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:79
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:61
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:217
SEGMENT_LIST_FLAG_CACHE
#define SEGMENT_LIST_FLAG_CACHE
Definition: segment.c:67
AVFormatContext::io_close2
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1820
parse_times
static int parse_times(void *log_ctx, int64_t **times, int *nb_times, const char *times_str)
Definition: segment.c:459
avio_find_protocol_name
const char * avio_find_protocol_name(const char *url)
Return the name of the protocol that will handle the passed URL.
Definition: avio.c:467
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:224
convert_header.str
string str
Definition: convert_header.py:20
timestamp.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
SegmentContext::initial_offset
int64_t initial_offset
initial timestamps offset, expressed in microseconds
Definition: segment.c:115
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
av_timecode_init_from_string
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
Parse timecode representation (hh:mm:ss[:;.
Definition: timecode.c:252
AVDictionaryEntry::value
char * value
Definition: dict.h:81
write_packet
static int write_packet(AVFormatContext *s1, AVPacket *pkt)
Definition: v4l2enc.c:92
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:347
AVTimecode
Definition: timecode.h:41
avformat_alloc_output_context2
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:91
AVStream::pts_wrap_bits
int pts_wrap_bits
Number of bits in timestamps.
Definition: avformat.h:1117
int
int
Definition: ffmpeg_filter.c:153
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
snprintf
#define snprintf
Definition: snprintf.h:34
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1241
ff_format_set_url
void ff_format_set_url(AVFormatContext *s, char *url)
Set AVFormatContext url field to the provided pointer.
Definition: avformat.c:772
AVOutputFormat::check_bitstream
int(* check_bitstream)(struct AVFormatContext *s, struct AVStream *st, const AVPacket *pkt)
Set up any necessary bitstream filtering and extract any extra data needed for the global header.
Definition: avformat.h:645
open_null_ctx
static int open_null_ctx(AVIOContext **ctx)
Definition: segment.c:568
LIST_TYPE_FFCONCAT
@ LIST_TYPE_FFCONCAT
Definition: segment.c:63
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:238
mux.h
SegmentListEntry::filename
char * filename
Definition: segment.c:52