FFmpeg
Loading...
Searching...
No Matches
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/mem.h"
39#include "libavutil/opt.h"
40#include "libavutil/avstring.h"
41#include "libavutil/bprint.h"
44#include "libavutil/time.h"
45#include "libavutil/timecode.h"
47#include "libavutil/timestamp.h"
48
58
68
69#define SEGMENT_LIST_FLAG_CACHE 1
70#define SEGMENT_LIST_FLAG_LIVE 2
71
72typedef struct SegmentContext {
73 const AVClass *class; /**< Class for private options. */
74 int segment_idx; ///< index of the segment file to write, starting from 0
75 int segment_idx_wrap; ///< number after which the index wraps
76 int segment_idx_wrap_nb; ///< number of time the index has wrapped
77 int segment_count; ///< number of segment files already written
80 char *format; ///< format to use for output segment files
82 char *list; ///< filename for the segment list file
83 int list_flags; ///< flags affecting list generation
84 int list_size; ///< number of entries for the segment list file
85
86 int is_nullctx; ///< whether avf->pb is a nullctx
87 int use_clocktime; ///< flag to cut segments at regular clock time
88 int64_t clocktime_offset; //< clock offset for cutting the segments at regular clock time
89 int64_t clocktime_wrap_duration; //< wrapping duration considered for starting a new segment
90 int64_t last_val; ///< remember last time for wrap around detection
92 int header_written; ///< whether we've already called avformat_write_header
93
94 char *entry_prefix; ///< prefix to add to list entry filenames
95 int list_type; ///< set the list type
96 AVIOContext *list_pb; ///< list file put-byte context
97 int64_t time; ///< segment duration
98 int64_t min_seg_duration; ///< minimum segment duration
99 int use_strftime; ///< flag to expand filename with strftime
100 int increment_tc; ///< flag to increment timecode if found
101
102 char *times_str; ///< segment times specification string
103 int64_t *times; ///< list of segment interval specification
104 int nb_times; ///< number of elements in the times array
105
106 char *frames_str; ///< segment frame numbers specification string
107 int *frames; ///< list of frame number specification
108 int nb_frames; ///< number of elements in the frames array
109 int frame_count; ///< total number of reference frames
110 int segment_frame_count; ///< number of reference frames in the segment
111
113 int individual_header_trailer; /**< Set by a private option. */
114 int write_header_trailer; /**< Set by a private option. */
115 char *header_filename; ///< filename to write the output header to
116
117 int reset_timestamps; ///< reset timestamps at the beginning of each segment
118 int64_t initial_offset; ///< initial timestamps offset, expressed in microseconds
119 char *reference_stream_specifier; ///< reference stream specifier
121 int64_t reference_stream_first_pts; ///< initial timestamp, expressed in microseconds
124
127
132
133static void print_csv_escaped_str(AVIOContext *ctx, const char *str)
134{
135 int needs_quoting = !!str[strcspn(str, "\",\n\r")];
136
137 if (needs_quoting)
138 avio_w8(ctx, '"');
139
140 for (; *str; str++) {
141 if (*str == '"')
142 avio_w8(ctx, '"');
143 avio_w8(ctx, *str);
144 }
145 if (needs_quoting)
146 avio_w8(ctx, '"');
147}
148
150{
151 SegmentContext *seg = s->priv_data;
152 AVFormatContext *oc;
153 int i;
154 int ret;
155
157 if (ret < 0)
158 return ret;
159 oc = seg->avf;
160
161 oc->interrupt_callback = s->interrupt_callback;
162 oc->max_delay = s->max_delay;
163 av_dict_copy(&oc->metadata, s->metadata, 0);
164 oc->opaque = s->opaque;
165 oc->io_close2 = s->io_close2;
166 oc->io_open = s->io_open;
167 oc->flags = s->flags;
168
169 for (i = 0; i < s->nb_streams; i++) {
170 AVStream *st, *ist = s->streams[i];
171 AVCodecParameters *ipar = ist->codecpar, *opar;
172
173 st = ff_stream_clone(oc, ist);
174 if (!st)
175 return AVERROR(ENOMEM);
176 opar = st->codecpar;
177 if (!oc->oformat->codec_tag ||
178 av_codec_get_id (oc->oformat->codec_tag, ipar->codec_tag) == opar->codec_id ||
179 av_codec_get_tag(oc->oformat->codec_tag, ipar->codec_id) <= 0) {
180 opar->codec_tag = ipar->codec_tag;
181 } else {
182 opar->codec_tag = 0;
183 }
184 }
185
186 for (i = 0; i < s->nb_programs; i++) {
187 ret = av_program_copy(oc, (const AVFormatContext *)s, s->programs[i]->id, 0);
188 if (ret < 0) {
189 av_log(s, AV_LOG_ERROR, "unable to transfer program %d to child muxer\n", s->programs[i]->id);
190 return ret;
191 }
192 }
193
194 return 0;
195}
196
198{
199 SegmentContext *seg = s->priv_data;
200 AVFormatContext *oc = seg->avf;
201 size_t size;
202 int ret;
203 AVBPrint filename;
204 char *new_name;
205
207 if (seg->segment_idx_wrap)
208 seg->segment_idx %= seg->segment_idx_wrap;
209 if (seg->use_strftime) {
210 time_t now0;
211 struct tm *tm, tmpbuf;
212 time(&now0);
213 tm = localtime_r(&now0, &tmpbuf);
214 av_bprint_strftime(&filename, s->url, tm);
215 if (!av_bprint_is_complete(&filename)) {
216 av_bprint_finalize(&filename, NULL);
217 return AVERROR(ENOMEM);
218 }
219 } else {
220 ret = ff_bprint_get_frame_filename(&filename, s->url, seg->segment_idx, 0);
221 if (ret < 0) {
222 av_bprint_finalize(&filename, NULL);
223 av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->url);
224 return ret;
225 }
226 }
227 ret = av_bprint_finalize(&filename, &new_name);
228 if (ret < 0)
229 return ret;
230 ff_format_set_url(oc, new_name);
231
232 /* copy modified name in list entry */
233 size = strlen(av_basename(oc->url)) + 1;
234 if (seg->entry_prefix)
235 size += strlen(seg->entry_prefix);
236
237 if ((ret = av_reallocp(&seg->cur_entry.filename, size)) < 0)
238 return ret;
239 snprintf(seg->cur_entry.filename, size, "%s%s",
240 seg->entry_prefix ? seg->entry_prefix : "",
241 av_basename(oc->url));
242
243 return 0;
244}
245
247{
248 SegmentContext *seg = s->priv_data;
249 AVFormatContext *oc = seg->avf;
250 int err = 0;
251
252 if (write_header) {
254 seg->avf = NULL;
255 if ((err = segment_mux_init(s)) < 0)
256 return err;
257 oc = seg->avf;
258 }
259
260 seg->segment_idx++;
261 if ((seg->segment_idx_wrap) && (seg->segment_idx % seg->segment_idx_wrap == 0))
262 seg->segment_idx_wrap_nb++;
263
264 if ((err = set_segment_filename(s)) < 0)
265 return err;
266
267 if ((err = s->io_open(s, &oc->pb, oc->url, AVIO_FLAG_WRITE, NULL)) < 0) {
268 av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->url);
269 return err;
270 }
272 oc->pb->seekable = 0;
273
274 if (oc->oformat->priv_class && oc->priv_data)
275 av_opt_set(oc->priv_data, "mpegts_flags", "+resend_headers", 0);
276
277 if (write_header) {
280 av_dict_set(&options, "fflags", "-autobsf", 0);
281 err = avformat_write_header(oc, &options);
283 if (err < 0)
284 return err;
285 }
286
287 seg->segment_frame_count = 0;
288 return 0;
289}
290
292{
293 SegmentContext *seg = s->priv_data;
294 int ret;
295
297 seg->temp_list_filename = av_asprintf(seg->use_rename ? "%s.tmp" : "%s", seg->list);
298 if (!seg->temp_list_filename)
299 return AVERROR(ENOMEM);
300 ret = s->io_open(s, &seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE, NULL);
301 if (ret < 0) {
302 av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list);
303 return ret;
304 }
305
306 if (seg->list_type == LIST_TYPE_M3U8 && seg->segment_list_entries) {
308 double max_duration = 0;
309
310 avio_printf(seg->list_pb, "#EXTM3U\n");
311 avio_printf(seg->list_pb, "#EXT-X-VERSION:3\n");
312 avio_printf(seg->list_pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", seg->segment_list_entries->index);
313 avio_printf(seg->list_pb, "#EXT-X-ALLOW-CACHE:%s\n",
314 seg->list_flags & SEGMENT_LIST_FLAG_CACHE ? "YES" : "NO");
315
316 av_log(s, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%d\n",
318
319 for (entry = seg->segment_list_entries; entry; entry = entry->next)
320 max_duration = FFMAX(max_duration, entry->end_time - entry->start_time);
321 avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%"PRId64"\n", (int64_t)ceil(max_duration));
322 } else if (seg->list_type == LIST_TYPE_FFCONCAT) {
323 avio_printf(seg->list_pb, "ffconcat version 1.0\n");
324 }
325
326 return ret;
327}
328
329static void segment_list_print_entry(AVIOContext *list_ioctx,
330 ListType list_type,
331 const SegmentListEntry *list_entry,
332 void *log_ctx)
333{
334 switch (list_type) {
335 case LIST_TYPE_FLAT:
336 avio_printf(list_ioctx, "%s\n", list_entry->filename);
337 break;
338 case LIST_TYPE_CSV:
339 case LIST_TYPE_EXT:
340 print_csv_escaped_str(list_ioctx, list_entry->filename);
341 avio_printf(list_ioctx, ",%f,%f\n", list_entry->start_time, list_entry->end_time);
342 break;
343 case LIST_TYPE_M3U8:
344 avio_printf(list_ioctx, "#EXTINF:%f,\n%s\n",
345 list_entry->end_time - list_entry->start_time, list_entry->filename);
346 break;
348 {
349 char *buf;
351 av_log(log_ctx, AV_LOG_WARNING,
352 "Error writing list entry '%s' in list file\n", list_entry->filename);
353 return;
354 }
355 avio_printf(list_ioctx, "file %s\n", buf);
356 av_free(buf);
357 break;
358 }
359 default:
360 av_assert0(!"Invalid list type");
361 }
362}
363
364static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
365{
366 SegmentContext *seg = s->priv_data;
367 AVFormatContext *oc = seg->avf;
368 int ret = 0;
369 AVTimecode tc;
370 AVRational rate;
372 char buf[AV_TIMECODE_STR_SIZE];
373 int i;
374 int err;
375
376 if (!oc || !oc->pb)
377 return AVERROR(EINVAL);
378
379 av_write_frame(oc, NULL); /* Flush any buffered data (fragmented mp4) */
380 if (write_trailer)
381 ret = av_write_trailer(oc);
382
383 if (ret < 0)
384 av_log(s, AV_LOG_ERROR, "Failure occurred when ending segment '%s'\n",
385 oc->url);
386
387 if (seg->list) {
388 if (seg->list_size || seg->list_type == LIST_TYPE_M3U8) {
390 if (!entry) {
391 ret = AVERROR(ENOMEM);
392 goto end;
393 }
394
395 /* append new element */
396 memcpy(entry, &seg->cur_entry, sizeof(*entry));
397 entry->filename = av_strdup(entry->filename);
398 if (!seg->segment_list_entries)
400 else
403
404 /* drop first item */
405 if (seg->list_size && seg->segment_count >= seg->list_size) {
408 av_freep(&entry->filename);
409 av_freep(&entry);
410 }
411
412 if ((ret = segment_list_open(s)) < 0)
413 goto end;
414 for (entry = seg->segment_list_entries; entry; entry = entry->next)
416 if (seg->list_type == LIST_TYPE_M3U8 && is_last)
417 avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n");
419 if (seg->use_rename)
420 ff_rename(seg->temp_list_filename, seg->list, s);
421 } else {
423 avio_flush(seg->list_pb);
424 }
425 }
426
427 av_log(s, AV_LOG_VERBOSE, "segment:'%s' count:%d ended\n",
428 seg->avf->url, seg->segment_count);
429 seg->segment_count++;
430
431 if (seg->increment_tc) {
432 tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
433 if (tcr) {
434 /* search the first video stream */
435 for (i = 0; i < s->nb_streams; i++) {
436 if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
437 rate = s->streams[i]->avg_frame_rate;/* Get fps from the video stream */
438 err = av_timecode_init_from_string(&tc, rate, tcr->value, s);
439 if (err < 0) {
440 av_log(s, AV_LOG_WARNING, "Could not increment global timecode, error occurred during timecode creation.\n");
441 break;
442 }
443 tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(rate));/* increment timecode */
444 av_dict_set(&s->metadata, "timecode",
445 av_timecode_make_string(&tc, buf, 0), 0);
446 break;
447 }
448 }
449 } else {
450 av_log(s, AV_LOG_WARNING, "Could not increment global timecode, no global timecode metadata found.\n");
451 }
452 for (i = 0; i < s->nb_streams; i++) {
453 if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
454 char st_buf[AV_TIMECODE_STR_SIZE];
455 AVTimecode st_tc;
456 AVRational st_rate = s->streams[i]->avg_frame_rate;
457 AVDictionaryEntry *st_tcr = av_dict_get(s->streams[i]->metadata, "timecode", NULL, 0);
458 if (st_tcr) {
459 if ((av_timecode_init_from_string(&st_tc, st_rate, st_tcr->value, s) < 0)) {
460 av_log(s, AV_LOG_WARNING, "Could not increment stream %d timecode, error occurred during timecode creation.\n", i);
461 continue;
462 }
463 st_tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(st_rate)); // increment timecode
464 av_dict_set(&s->streams[i]->metadata, "timecode", av_timecode_make_string(&st_tc, st_buf, 0), 0);
465 }
466 }
467 }
468 }
469
470end:
471 ff_format_io_close(oc, &oc->pb);
472
473 return ret;
474}
475
476static int parse_times(void *log_ctx, int64_t **times, int *nb_times,
477 const char *times_str)
478{
479 char *p;
480 int i, ret = 0;
481 char *times_str1 = av_strdup(times_str);
482 char *saveptr = NULL;
483
484 if (!times_str1)
485 return AVERROR(ENOMEM);
486
487#define FAIL(err) ret = err; goto end
488
489 *nb_times = 1;
490 for (p = times_str1; *p; p++)
491 if (*p == ',')
492 (*nb_times)++;
493
494 *times = av_malloc_array(*nb_times, sizeof(**times));
495 if (!*times) {
496 av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced times array\n");
497 FAIL(AVERROR(ENOMEM));
498 }
499
500 p = times_str1;
501 for (i = 0; i < *nb_times; i++) {
502 int64_t t;
503 char *tstr = av_strtok(p, ",", &saveptr);
504 p = NULL;
505
506 if (!tstr || !tstr[0]) {
507 av_log(log_ctx, AV_LOG_ERROR, "Empty time specification in times list %s\n",
508 times_str);
509 FAIL(AVERROR(EINVAL));
510 }
511
512 ret = av_parse_time(&t, tstr, 1);
513 if (ret < 0) {
514 av_log(log_ctx, AV_LOG_ERROR,
515 "Invalid time duration specification '%s' in times list %s\n", tstr, times_str);
516 FAIL(AVERROR(EINVAL));
517 }
518 (*times)[i] = t;
519
520 /* check on monotonicity */
521 if (i && (*times)[i-1] > (*times)[i]) {
522 av_log(log_ctx, AV_LOG_ERROR,
523 "Specified time %f is smaller than the last time %f\n",
524 (float)((*times)[i])/1000000, (float)((*times)[i-1])/1000000);
525 FAIL(AVERROR(EINVAL));
526 }
527 }
528
529end:
530 av_free(times_str1);
531 return ret;
532}
533
534static int parse_frames(void *log_ctx, int **frames, int *nb_frames,
535 const char *frames_str)
536{
537 const char *p;
538 int i;
539
540 *nb_frames = 1;
541 for (p = frames_str; *p; p++)
542 if (*p == ',')
543 (*nb_frames)++;
544
545 *frames = av_malloc_array(*nb_frames, sizeof(**frames));
546 if (!*frames) {
547 av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced frames array\n");
548 return AVERROR(ENOMEM);
549 }
550
551 p = frames_str;
552 for (i = 0; i < *nb_frames; i++) {
553 long int f;
554 char *tailptr;
555
556 if (*p == '\0' || *p == ',') {
557 av_log(log_ctx, AV_LOG_ERROR, "Empty frame specification in frame list %s\n",
558 frames_str);
559 return AVERROR(EINVAL);
560 }
561 f = strtol(p, &tailptr, 10);
562 if (*tailptr != '\0' && *tailptr != ',' || f <= 0 || f >= INT_MAX) {
563 av_log(log_ctx, AV_LOG_ERROR,
564 "Invalid argument '%s', must be a positive integer < INT_MAX\n",
565 p);
566 return AVERROR(EINVAL);
567 }
568 if (*tailptr == ',')
569 tailptr++;
570 p = tailptr;
571 (*frames)[i] = f;
572
573 /* check on monotonicity */
574 if (i && (*frames)[i-1] > (*frames)[i]) {
575 av_log(log_ctx, AV_LOG_ERROR,
576 "Specified frame %d is smaller than the last frame %d\n",
577 (*frames)[i], (*frames)[i-1]);
578 return AVERROR(EINVAL);
579 }
580 }
581
582 return 0;
583}
584
586{
587 int buf_size = 32768;
588 uint8_t *buf = av_malloc(buf_size);
589 if (!buf)
590 return AVERROR(ENOMEM);
591 *ctx = avio_alloc_context(buf, buf_size, 1, NULL, NULL, NULL, NULL);
592 if (!*ctx) {
593 av_free(buf);
594 return AVERROR(ENOMEM);
595 }
596 return 0;
597}
598
600{
601 av_freep(&(*pb)->buffer);
603}
604
606{
607 SegmentContext *seg = s->priv_data;
608 int ret, i;
609
610 seg->reference_stream_index = -1;
611 if (!strcmp(seg->reference_stream_specifier, "auto")) {
612 /* select first index of type with highest priority */
613 int type_index_map[AVMEDIA_TYPE_NB];
614 static const enum AVMediaType type_priority_list[] = {
620 };
621 enum AVMediaType type;
622
623 for (i = 0; i < AVMEDIA_TYPE_NB; i++)
624 type_index_map[i] = -1;
625
626 /* select first index for each type */
627 for (i = 0; i < s->nb_streams; i++) {
628 type = s->streams[i]->codecpar->codec_type;
629 if ((unsigned)type < AVMEDIA_TYPE_NB && type_index_map[type] == -1
630 /* ignore attached pictures/cover art streams */
631 && !(s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC))
632 type_index_map[type] = i;
633 }
634
635 for (i = 0; i < FF_ARRAY_ELEMS(type_priority_list); i++) {
636 type = type_priority_list[i];
637 if ((seg->reference_stream_index = type_index_map[type]) >= 0)
638 break;
639 }
640 } else {
641 for (i = 0; i < s->nb_streams; i++) {
642 ret = avformat_match_stream_specifier(s, s->streams[i],
644 if (ret < 0)
645 return ret;
646 if (ret > 0) {
648 break;
649 }
650 }
651 }
652
653 if (seg->reference_stream_index < 0) {
654 av_log(s, AV_LOG_ERROR, "Could not select stream matching identifier '%s'\n",
656 return AVERROR(EINVAL);
657 }
658
659 return 0;
660}
661
663{
664 SegmentContext *seg = s->priv_data;
665 SegmentListEntry *cur;
666
668 if (seg->avf) {
669 if (seg->is_nullctx)
670 close_null_ctxp(&seg->avf->pb);
671 else
672 ff_format_io_close(s, &seg->avf->pb);
674 seg->avf = NULL;
675 }
676 av_freep(&seg->times);
677 av_freep(&seg->frames);
680
681 cur = seg->segment_list_entries;
682 while (cur) {
683 SegmentListEntry *next = cur->next;
684 av_freep(&cur->filename);
685 av_free(cur);
686 cur = next;
687 }
688}
689
691{
692 SegmentContext *seg = s->priv_data;
693 AVFormatContext *oc = seg->avf;
695 int ret;
696 int i;
697
698 seg->segment_count = 0;
699 if (!seg->write_header_trailer)
701
702 if (seg->header_filename) {
703 seg->write_header_trailer = 1;
705 }
706
707 if (seg->initial_offset > 0) {
708 av_log(s, AV_LOG_WARNING, "NOTE: the option initial_offset is deprecated,"
709 "you can use output_ts_offset instead of it\n");
710 }
711
712 if ((seg->time != 2000000) + !!seg->times_str + !!seg->frames_str > 1) {
714 "segment_time, segment_times, and segment_frames options "
715 "are mutually exclusive, select just one of them\n");
716 return AVERROR(EINVAL);
717 }
718
719 if (seg->times_str || seg->frames_str)
720 seg->min_seg_duration = 0;
721
722 if (seg->times_str) {
723 if ((ret = parse_times(s, &seg->times, &seg->nb_times, seg->times_str)) < 0)
724 return ret;
725 } else if (seg->frames_str) {
726 if ((ret = parse_frames(s, &seg->frames, &seg->nb_frames, seg->frames_str)) < 0)
727 return ret;
728 } else {
729 if (seg->use_clocktime) {
730 if (seg->time <= 0) {
731 av_log(s, AV_LOG_ERROR, "Invalid negative segment_time with segment_atclocktime option set\n");
732 return AVERROR(EINVAL);
733 }
734 seg->clocktime_offset = seg->time - (seg->clocktime_offset % seg->time);
735 }
736 if (seg->min_seg_duration > seg->time) {
737 av_log(s, AV_LOG_ERROR, "min_seg_duration cannot be greater than segment_time\n");
738 return AVERROR(EINVAL);
739 }
740 }
741
742 if (seg->list) {
743 if (seg->list_type == LIST_TYPE_UNDEFINED) {
744 if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
745 else if (av_match_ext(seg->list, "ext" )) seg->list_type = LIST_TYPE_EXT;
746 else if (av_match_ext(seg->list, "m3u8")) seg->list_type = LIST_TYPE_M3U8;
747 else if (av_match_ext(seg->list, "ffcat,ffconcat")) seg->list_type = LIST_TYPE_FFCONCAT;
748 else seg->list_type = LIST_TYPE_FLAT;
749 }
750 if (!seg->list_size && seg->list_type != LIST_TYPE_M3U8) {
751 if ((ret = segment_list_open(s)) < 0)
752 return ret;
753 } else {
754 const char *proto = avio_find_protocol_name(seg->list);
755 seg->use_rename = proto && !strcmp(proto, "file");
756 }
757 }
758
759 if (seg->list_type == LIST_TYPE_EXT)
760 av_log(s, AV_LOG_WARNING, "'ext' list type option is deprecated in favor of 'csv'\n");
761
762 if ((ret = select_reference_stream(s)) < 0)
763 return ret;
764 av_log(s, AV_LOG_VERBOSE, "Selected stream id:%d type:%s\n",
766 av_get_media_type_string(s->streams[seg->reference_stream_index]->codecpar->codec_type));
767
769
770 seg->oformat = av_guess_format(seg->format, s->url, NULL);
771
772 if (!seg->oformat)
774 if (seg->oformat->flags & AVFMT_NOFILE) {
775 av_log(s, AV_LOG_ERROR, "format %s not supported.\n",
776 seg->oformat->name);
777 return AVERROR(EINVAL);
778 }
779
780 if ((ret = segment_mux_init(s)) < 0)
781 return ret;
782
783 if ((ret = set_segment_filename(s)) < 0)
784 return ret;
785 oc = seg->avf;
786
787 if (seg->write_header_trailer) {
788 if ((ret = s->io_open(s, &oc->pb,
789 seg->header_filename ? seg->header_filename : oc->url,
790 AVIO_FLAG_WRITE, NULL)) < 0) {
791 av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->url);
792 return ret;
793 }
795 oc->pb->seekable = 0;
796 } else {
797 if ((ret = open_null_ctx(&oc->pb)) < 0)
798 return ret;
799 seg->is_nullctx = 1;
800 }
801
803 av_dict_set(&options, "fflags", "-autobsf", 0);
804 ret = avformat_init_output(oc, &options);
805 if (av_dict_count(options)) {
807 "Some of the provided format options are not recognized\n");
809 return AVERROR(EINVAL);
810 }
812
813 if (ret < 0) {
814 return ret;
815 }
816 seg->segment_frame_count = 0;
817
818 av_assert0(s->nb_streams == oc->nb_streams);
820 ret = avformat_write_header(oc, NULL);
821 if (ret < 0)
822 return ret;
823 seg->header_written = 1;
824 }
825
826 for (i = 0; i < s->nb_streams; i++) {
827 AVStream *inner_st = oc->streams[i];
828 AVStream *outer_st = s->streams[i];
829 avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
830 }
831
832 if (oc->avoid_negative_ts > 0 && s->avoid_negative_ts < 0)
833 s->avoid_negative_ts = 1;
834
835 return ret;
836}
837
839{
840 SegmentContext *seg = s->priv_data;
841 AVFormatContext *oc = seg->avf;
842 int ret;
843
844 if (!seg->header_written) {
845 ret = avformat_write_header(oc, NULL);
846 if (ret < 0)
847 return ret;
848 }
849
850 if (!seg->write_header_trailer || seg->header_filename) {
851 if (seg->header_filename) {
852 av_write_frame(oc, NULL);
853 ff_format_io_close(oc, &oc->pb);
854 } else {
855 close_null_ctxp(&oc->pb);
856 seg->is_nullctx = 0;
857 }
858 if ((ret = oc->io_open(oc, &oc->pb, oc->url, AVIO_FLAG_WRITE, NULL)) < 0)
859 return ret;
861 oc->pb->seekable = 0;
862 }
863
864 return 0;
865}
866
868{
869 SegmentContext *seg = s->priv_data;
870 AVStream *st = s->streams[pkt->stream_index];
871 int64_t end_pts = INT64_MAX, offset, pkt_pts_avtb;
872 int start_frame = INT_MAX;
873 int ret;
874 struct tm ti;
875 int64_t usecs;
876 int64_t wrapped_val;
877
878 if (!seg->avf || !seg->avf->pb)
879 return AVERROR(EINVAL);
880
881 if (!st->codecpar->extradata_size) {
882 size_t pkt_extradata_size;
883 uint8_t *pkt_extradata = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &pkt_extradata_size);
884 if (pkt_extradata && pkt_extradata_size > 0) {
885 ret = ff_alloc_extradata(st->codecpar, pkt_extradata_size);
886 if (ret < 0) {
887 av_log(s, AV_LOG_WARNING, "Unable to add extradata to stream. Output segments may be invalid.\n");
888 goto calc_times;
889 }
890 memcpy(st->codecpar->extradata, pkt_extradata, pkt_extradata_size);
891 }
892 }
893
894calc_times:
895 if (seg->times) {
896 end_pts = seg->segment_count < seg->nb_times ?
897 seg->times[seg->segment_count] : INT64_MAX;
898 } else if (seg->frames) {
899 start_frame = seg->segment_count < seg->nb_frames ?
900 seg->frames[seg->segment_count] : INT_MAX;
901 } else {
902 if (seg->use_clocktime) {
903 int64_t avgt = av_gettime();
904 time_t sec = avgt / 1000000;
905 localtime_r(&sec, &ti);
906 usecs = (int64_t)(ti.tm_hour * 3600 + ti.tm_min * 60 + ti.tm_sec) * 1000000 + (avgt % 1000000);
907 wrapped_val = (usecs + seg->clocktime_offset) % seg->time;
908 if (wrapped_val < seg->last_val && wrapped_val < seg->clocktime_wrap_duration)
909 seg->cut_pending = 1;
910 seg->last_val = wrapped_val;
911 } else {
912 end_pts = seg->time * (seg->segment_count + 1);
913 }
914 }
915
916 ff_dlog(s, "packet stream:%d pts:%s pts_time:%s duration_time:%s is_key:%d frame:%d\n",
917 pkt->stream_index, av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
918 av_ts2timestr(pkt->duration, &st->time_base),
919 pkt->flags & AV_PKT_FLAG_KEY,
920 pkt->stream_index == seg->reference_stream_index ? seg->frame_count : -1);
921
923 pkt->stream_index == seg->reference_stream_index &&
924 pkt->pts != AV_NOPTS_VALUE) {
926 }
927
929 end_pts += (INT64_MAX - end_pts >= seg->reference_stream_first_pts) ?
931 INT64_MAX - end_pts;
932 }
933
934 if (pkt->pts != AV_NOPTS_VALUE)
935 pkt_pts_avtb = av_rescale_q(pkt->pts, st->time_base, AV_TIME_BASE_Q);
936
937 if (pkt->stream_index == seg->reference_stream_index &&
938 (pkt->flags & AV_PKT_FLAG_KEY || seg->break_non_keyframes) &&
939 (seg->segment_frame_count > 0 || seg->write_empty) &&
940 (seg->cut_pending || seg->frame_count >= start_frame ||
941 (pkt->pts != AV_NOPTS_VALUE &&
942 pkt_pts_avtb - seg->cur_entry.start_pts >= seg->min_seg_duration &&
943 av_compare_ts(pkt->pts, st->time_base,
944 end_pts - seg->time_delta, AV_TIME_BASE_Q) >= 0))) {
945 /* sanitize end time in case last packet didn't have a defined duration */
946 if (seg->cur_entry.last_duration == 0)
947 seg->cur_entry.end_time = (double)pkt->pts * av_q2d(st->time_base);
948
949 if ((ret = segment_end(s, seg->individual_header_trailer, 0)) < 0)
950 goto fail;
951
952 if ((ret = segment_start(s, seg->individual_header_trailer)) < 0)
953 goto fail;
954
955 seg->cut_pending = 0;
957 seg->cur_entry.start_time = (double)pkt->pts * av_q2d(st->time_base);
960
961 if (seg->times || (!seg->frames && !seg->use_clocktime) && seg->write_empty)
962 goto calc_times;
963 }
964
965 if (pkt->stream_index == seg->reference_stream_index) {
966 if (pkt->pts != AV_NOPTS_VALUE)
967 seg->cur_entry.end_time =
968 FFMAX(seg->cur_entry.end_time, (double)(pkt->pts + pkt->duration) * av_q2d(st->time_base));
969 seg->cur_entry.last_duration = pkt->duration;
970 }
971
972 if (seg->segment_frame_count == 0) {
973 av_log(s, AV_LOG_VERBOSE, "segment:'%s' starts with packet stream:%d pts:%s pts_time:%s frame:%d\n",
974 seg->avf->url, pkt->stream_index,
975 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base), seg->frame_count);
976 }
977
978 av_log(s, AV_LOG_DEBUG, "stream:%d start_pts_time:%s pts:%s pts_time:%s dts:%s dts_time:%s",
979 pkt->stream_index,
981 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
982 av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
983
984 /* compute new timestamps */
987 if (pkt->pts != AV_NOPTS_VALUE)
988 pkt->pts += offset;
989 if (pkt->dts != AV_NOPTS_VALUE)
990 pkt->dts += offset;
991
992 av_log(s, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
993 av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
994 av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
995
996 ret = ff_write_chained(seg->avf, pkt->stream_index, pkt, s,
997 seg->initial_offset || seg->reset_timestamps ||
998 ffofmt(seg->avf->oformat)->interleave_packet);
999
1000fail:
1001 /* Use st->index here as the packet returned from ff_write_chained()
1002 * is blank if interleaving has been used. */
1003 if (st->index == seg->reference_stream_index) {
1004 seg->frame_count++;
1005 seg->segment_frame_count++;
1006 }
1007
1008 return ret;
1009}
1010
1012{
1013 SegmentContext *seg = s->priv_data;
1014 AVFormatContext *oc = seg->avf;
1015 int ret;
1016
1017 if (!oc)
1018 return 0;
1019
1020 if (!seg->write_header_trailer) {
1021 if ((ret = segment_end(s, 0, 1)) < 0)
1022 return ret;
1023 if ((ret = open_null_ctx(&oc->pb)) < 0)
1024 return ret;
1025 seg->is_nullctx = 1;
1026 ret = av_write_trailer(oc);
1027 } else {
1028 ret = segment_end(s, 1, 1);
1029 }
1030 return ret;
1031}
1032
1034 const AVPacket *pkt)
1035{
1036 SegmentContext *seg = s->priv_data;
1037 AVFormatContext *oc = seg->avf;
1038 if (ffofmt(oc->oformat)->check_bitstream) {
1039 AVStream *const ost = oc->streams[st->index];
1040 int ret = ffofmt(oc->oformat)->check_bitstream(oc, ost, pkt);
1041 if (ret == 1) {
1042 FFStream *const sti = ffstream(st);
1043 FFStream *const osti = ffstream(ost);
1044 sti->bsfc = osti->bsfc;
1045 osti->bsfc = NULL;
1046 }
1047 return ret;
1048 }
1049 return 1;
1050}
1051
1052#define OFFSET(x) offsetof(SegmentContext, x)
1053#define E AV_OPT_FLAG_ENCODING_PARAM
1054static const AVOption options[] = {
1055 { "reference_stream", "set reference stream", OFFSET(reference_stream_specifier), AV_OPT_TYPE_STRING, {.str = "auto"}, 0, 0, E },
1056 { "segment_format", "set container format used for the segments", OFFSET(format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
1057 { "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 },
1058 { "segment_list", "set the segment list filename", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
1059 { "segment_header_filename", "write a single file containing the header", OFFSET(header_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
1060
1061 { "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, .unit = "list_flags"},
1062 { "cache", "allow list caching", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_CACHE }, INT_MIN, INT_MAX, E, .unit = "list_flags"},
1063 { "live", "enable live-friendly list generation (useful for HLS)", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_LIVE }, INT_MIN, INT_MAX, E, .unit = "list_flags"},
1064
1065 { "segment_list_size", "set the maximum number of playlist entries", OFFSET(list_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
1066
1067 { "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, .unit = "list_type" },
1068 { "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, .unit = "list_type" },
1069 { "csv", "csv format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_CSV }, INT_MIN, INT_MAX, E, .unit = "list_type" },
1070 { "ext", "extended format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_EXT }, INT_MIN, INT_MAX, E, .unit = "list_type" },
1071 { "ffconcat", "ffconcat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FFCONCAT }, INT_MIN, INT_MAX, E, .unit = "list_type" },
1072 { "m3u8", "M3U8 format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, .unit = "list_type" },
1073 { "hls", "Apple HTTP Live Streaming compatible", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, .unit = "list_type" },
1074
1075 { "segment_atclocktime", "set segment to be cut at clocktime", OFFSET(use_clocktime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
1076 { "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E},
1077 { "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E},
1078 { "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, INT64_MIN, INT64_MAX, E },
1079 { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
1080 { "min_seg_duration", "set minimum segment duration", OFFSET(min_seg_duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
1081 { "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
1082 { "segment_frames", "set segment split frame numbers", OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
1083 { "segment_wrap", "set number after which the index wraps", OFFSET(segment_idx_wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
1084 { "segment_list_entry_prefix", "set base url prefix for segments", OFFSET(entry_prefix), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
1085 { "segment_start_number", "set the sequence number of the first segment", OFFSET(segment_idx), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
1086 { "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 },
1087 { "strftime", "set filename expansion with strftime at segment creation", OFFSET(use_strftime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
1088 { "increment_tc", "increment timecode between each segment", OFFSET(increment_tc), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
1089 { "break_non_keyframes", "allow breaking segments on non-keyframes", OFFSET(break_non_keyframes), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
1090
1091 { "individual_header_trailer", "write header/trailer to each segment", OFFSET(individual_header_trailer), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, E },
1092 { "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 },
1093 { "reset_timestamps", "reset timestamps at the beginning of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
1094 { "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
1095 { "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
1096 { NULL },
1097};
1098
1099static const AVClass seg_class = {
1100 .class_name = "(stream) segment muxer",
1101 .item_name = av_default_item_name,
1102 .option = options,
1103 .version = LIBAVUTIL_VERSION_INT,
1104};
1105
1106#if CONFIG_SEGMENT_MUXER
1108 .p.name = "segment",
1109 .p.long_name = NULL_IF_CONFIG_SMALL("segment"),
1111 .p.priv_class = &seg_class,
1112 .priv_data_size = sizeof(SegmentContext),
1113 .init = seg_init,
1117 .deinit = seg_free,
1119};
1120#endif
1121
1122#if CONFIG_STREAM_SEGMENT_MUXER
1124 .p.name = "stream_segment,ssegment",
1125 .p.long_name = NULL_IF_CONFIG_SMALL("streaming segment muxer"),
1126 .p.flags = AVFMT_NOFILE,
1127 .p.priv_class = &seg_class,
1128 .priv_data_size = sizeof(SegmentContext),
1129 .init = seg_init,
1133 .deinit = seg_free,
1135};
1136#endif
static const char *const format[]
Definition af_aiir.c:444
const FFOutputFormat ff_segment_muxer
const FFOutputFormat ff_stream_segment_muxer
#define entry
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define E
Definition avdct.c:34
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition avformat.c:961
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:834
void ff_format_set_url(AVFormatContext *s, char *url)
Set AVFormatContext url field to the provided pointer.
Definition avformat.c:923
AVStream * ff_stream_clone(AVFormatContext *dst_ctx, const AVStream *src)
Create a new stream and copy to it all parameters from a source stream, with the exception of the ind...
Definition avformat.c:251
Main libavformat public API header.
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition avformat.h:488
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition avformat.h:497
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition avformat.h:692
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:95
const char * avio_find_protocol_name(const char *url)
Return the name of the protocol that will handle the passed URL.
Definition avio.c:725
int ff_rename(const char *url_src, const char *url_dst, void *logctx)
Wrap ffurl_move() and log if error happens.
Definition avio.c:929
void avio_w8(AVIOContext *s, int b)
Definition aviobuf.c:184
#define AVIO_FLAG_WRITE
write-only
Definition avio.h:618
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the 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, const 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:109
void avio_context_free(AVIOContext **s)
Free the supplied IO context and everything associated with it.
Definition aviobuf.c:126
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition aviobuf.c:228
char * av_asprintf(const char *fmt,...)
Definition avstring.c:115
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define s(width, name)
Definition cbs_vp9.c:198
static void deinit(AVFormatContext *s)
Definition chromaprint.c:53
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static __device__ float ceil(float a)
static AVPacket * pkt
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition ffmpeg_mux.c:204
static void write_header(FFV1Context *f)
Definition ffv1enc.c:384
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_DURATION
Underlying C type is int64_t.
Definition opt.h:318
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition opt.h:254
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition opt.h:289
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
@ 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
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition packet.c:252
int av_program_copy(AVFormatContext *dst, const AVFormatContext *src, int progid, int flags)
Copy an AVProgram from one AVFormatContext to another.
Definition avformat.c:349
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition avformat.c:150
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:446
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:467
#define AVSTREAM_INIT_IN_WRITE_HEADER
stream parameters initialized in avformat_write_header
Definition avformat.h:2626
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition mux.c:1238
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:79
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition mux.c:1176
unsigned int av_codec_get_tag(const struct AVCodecTag *const *tags, enum AVCodecID id)
Get the codec tag for the given codec id id.
enum AVCodecID av_codec_get_id(const struct AVCodecTag *const *tags, unsigned int tag)
Get the AVCodecID for the given codec tag tag.
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:742
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:41
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition bprint.h:218
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm)
Append a formatted date and time to a print buffer.
Definition bprint.c:166
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
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:60
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
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
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition dict.c:37
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition error.h:62
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
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.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
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:188
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
AVMediaType
Definition avutil.h:198
@ AVMEDIA_TYPE_ATTACHMENT
Opaque data information usually sparse.
Definition avutil.h:204
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_NB
Definition avutil.h:205
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
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:179
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:323
#define AV_ESCAPE_FLAG_WHITESPACE
Consider spaces special and escape them even in the middle of the string.
Definition avstring.h:329
const char * av_basename(const char *path)
Thread safe basename.
Definition avstring.c:253
@ AV_ESCAPE_MODE_AUTO
Use auto-selected escaping mode.
Definition avstring.h:315
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:887
cl_device_type type
unsigned offset
Definition libaomenc.c:763
int ff_bprint_get_frame_filename(struct AVBPrint *buf, const char *path, int64_t number, int flags)
Return in 'buf' the path with 'd' replaced by a number.
Definition utils.c:293
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
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
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:1337
static int check_bitstream(AVFormatContext *s, FFStream *sti, AVPacket *pkt)
Definition mux.c:1056
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define FFMAX(a, b)
Definition macros.h:47
Memory handling functions.
static const FFOutputFormat * ffofmt(const AVOutputFormat *fmt)
Definition mux.h:167
#define av_strdup(s)
Definition ops_static.c:55
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
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
misc parsing utilities
#define SEGMENT_LIST_FLAG_LIVE
Definition segment.c:70
static int parse_times(void *log_ctx, int64_t **times, int *nb_times, const char *times_str)
Definition segment.c:476
static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
Definition segment.c:364
static const AVClass seg_class
Definition segment.c:1099
static int segment_start(AVFormatContext *s, int write_header)
Definition segment.c:246
static void segment_list_print_entry(AVIOContext *list_ioctx, ListType list_type, const SegmentListEntry *list_entry, void *log_ctx)
Definition segment.c:329
ListType
Definition segment.c:59
@ LIST_TYPE_CSV
Definition segment.c:62
@ LIST_TYPE_NB
Definition segment.c:66
@ LIST_TYPE_FLAT
Definition segment.c:61
@ LIST_TYPE_M3U8
Definition segment.c:63
@ LIST_TYPE_EXT
deprecated
Definition segment.c:64
@ LIST_TYPE_FFCONCAT
Definition segment.c:65
@ LIST_TYPE_UNDEFINED
Definition segment.c:60
static int seg_init(AVFormatContext *s)
Definition segment.c:690
static int select_reference_stream(AVFormatContext *s)
Definition segment.c:605
static void print_csv_escaped_str(AVIOContext *ctx, const char *str)
Definition segment.c:133
static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition segment.c:867
#define SEGMENT_LIST_FLAG_CACHE
Definition segment.c:69
static int seg_write_header(AVFormatContext *s)
Definition segment.c:838
static int segment_mux_init(AVFormatContext *s)
Definition segment.c:149
static int segment_list_open(AVFormatContext *s)
Definition segment.c:291
static int seg_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Definition segment.c:1033
static int open_null_ctx(AVIOContext **ctx)
Definition segment.c:585
static int set_segment_filename(AVFormatContext *s)
Definition segment.c:197
#define OFFSET(x)
Definition segment.c:1052
static void seg_free(AVFormatContext *s)
Definition segment.c:662
#define FAIL(err)
static void close_null_ctxp(AVIOContext **pb)
Definition segment.c:599
static int seg_write_trailer(struct AVFormatContext *s)
Definition segment.c:1011
static int parse_frames(void *log_ctx, int **frames, int *nb_frames, const char *frames_str)
Definition segment.c:534
#define FF_ARRAY_ELEMS(a)
#define snprintf
Definition snprintf.h:34
Describe the class of an AVClass context structure.
Definition log.h:76
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition codec_par.h:61
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
char * value
Definition dict.h:92
Format I/O context.
Definition avformat.h:1333
int avoid_negative_ts
Avoid negative timestamps during muxing.
Definition avformat.h:1737
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition avformat.h:1389
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition avformat.h:1963
AVIOContext * pb
I/O context.
Definition avformat.h:1375
AVDictionary * metadata
Metadata that applies to the whole file.
Definition avformat.h:1580
int flags
Flags modifying the (de)muxer behaviour.
Definition avformat.h:1484
const struct AVOutputFormat * oformat
The output container format.
Definition avformat.h:1352
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition avformat.h:1618
char * url
input or output URL.
Definition avformat.h:1449
void * opaque
User data.
Definition avformat.h:1912
void * priv_data
Format private data.
Definition avformat.h:1361
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1401
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:1953
Bytestream IO Context.
Definition avio.h:160
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition avio.h:261
AVOption.
Definition opt.h:428
int flags
can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_EXPERIMENTAL, AVFMT_GLOBALHEADER,...
Definition avformat.h:546
const char * name
Definition avformat.h:527
const struct AVCodecTag *const * codec_tag
List of supported codec_id-codec_tag pairs, ordered by "betterchoice first".
Definition avformat.h:552
const AVClass * priv_class
AVClass for the private context.
Definition avformat.h:555
This structure stores compressed data.
Definition packet.h:580
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int index
stream index in AVFormatContext
Definition avformat.h:772
int pts_wrap_bits
Number of bits in timestamps.
Definition avformat.h:909
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:805
int start
timecode frame start (first base frame number)
Definition timecode.h:42
int(* check_bitstream)(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Set up any necessary bitstream filtering and extract any extra data needed for the global header.
Definition mux.h:163
struct AVBSFContext * bsfc
bitstream filter to run on stream
Definition internal.h:153
AVIOContext * list_pb
list file put-byte context
Definition segment.c:96
char * reference_stream_specifier
reference stream specifier
Definition segment.c:119
int individual_header_trailer
Set by a private option.
Definition segment.c:113
int64_t time_delta
Definition segment.c:112
int64_t time
segment duration
Definition segment.c:97
int use_clocktime
flag to cut segments at regular clock time
Definition segment.c:87
int use_strftime
flag to expand filename with strftime
Definition segment.c:99
char * times_str
segment times specification string
Definition segment.c:102
int list_flags
flags affecting list generation
Definition segment.c:83
int header_written
whether we've already called avformat_write_header
Definition segment.c:92
int segment_frame_count
number of reference frames in the segment
Definition segment.c:110
int frame_count
total number of reference frames
Definition segment.c:109
AVFormatContext * avf
Definition segment.c:79
int nb_frames
number of elements in the frames array
Definition segment.c:108
int list_type
set the list type
Definition segment.c:95
int64_t reference_stream_first_pts
initial timestamp, expressed in microseconds
Definition segment.c:121
const AVOutputFormat * oformat
Definition segment.c:78
int segment_idx_wrap
number after which the index wraps
Definition segment.c:75
char * temp_list_filename
Definition segment.c:126
int write_header_trailer
Set by a private option.
Definition segment.c:114
int64_t clocktime_wrap_duration
Definition segment.c:89
AVDictionary * format_options
Definition segment.c:81
int nb_times
number of elements in the times array
Definition segment.c:104
int64_t last_val
remember last time for wrap around detection
Definition segment.c:90
SegmentListEntry * segment_list_entries
Definition segment.c:129
int reset_timestamps
reset timestamps at the beginning of each segment
Definition segment.c:117
int cut_pending
Definition segment.c:91
SegmentListEntry * segment_list_entries_end
Definition segment.c:130
int * frames
list of frame number specification
Definition segment.c:107
int segment_count
number of segment files already written
Definition segment.c:77
int64_t initial_offset
initial timestamps offset, expressed in microseconds
Definition segment.c:118
int segment_idx
index of the segment file to write, starting from 0
Definition segment.c:74
char * header_filename
filename to write the output header to
Definition segment.c:115
int is_nullctx
whether avf->pb is a nullctx
Definition segment.c:86
int list_size
number of entries for the segment list file
Definition segment.c:84
char * list
filename for the segment list file
Definition segment.c:82
char * frames_str
segment frame numbers specification string
Definition segment.c:106
char * format
format to use for output segment files
Definition segment.c:80
int reference_stream_index
Definition segment.c:120
int64_t * times
list of segment interval specification
Definition segment.c:103
int break_non_keyframes
Definition segment.c:122
int segment_idx_wrap_nb
number of time the index has wrapped
Definition segment.c:76
char * entry_prefix
prefix to add to list entry filenames
Definition segment.c:94
int increment_tc
flag to increment timecode if found
Definition segment.c:100
SegmentListEntry cur_entry
Definition segment.c:128
int64_t clocktime_offset
Definition segment.c:88
int64_t min_seg_duration
minimum segment duration
Definition segment.c:98
int64_t start_pts
Definition segment.c:52
int64_t last_duration
Definition segment.c:56
int64_t offset_pts
Definition segment.c:53
double start_time
Definition segment.c:51
char * filename
Definition segment.c:54
double end_time
Definition segment.c:51
struct SegmentListEntry * next
Definition segment.c:55
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define ff_dlog(a,...)
#define av_freep(p)
#define av_log(a,...)
static int frames
Definition movenc.c:67
static AVFormatContext * ctx
Definition movenc.c:49
int64_t av_gettime(void)
Get the current time in microseconds.
Definition time.c:40
#define localtime_r
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:241
char * av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum_arg)
Load timecode string in buf.
Definition timecode.c:104
Timecode helpers header.
#define AV_TIMECODE_STR_SIZE
Definition timecode.h:33
timestamp utils, mostly useful for debugging/logging purposes
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition timestamp.h:54
#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
int size
static int write_trailer(AVFormatContext *s1)
Definition v4l2enc.c:101
static AVStream * ost