diff options
author | Stefano Sabatini <stefasab@gmail.com> | 2013-02-21 19:33:26 +0100 |
---|---|---|
committer | Stefano Sabatini <stefasab@gmail.com> | 2013-03-07 01:44:59 +0100 |
commit | d95143ec82a026967e10a4521a5de78fb5cb2ec1 (patch) | |
tree | 87dd075a84afae7053c4b0121e7df0bc9a933b9b | |
parent | 9167db3829f360f241255d4240ba6b7135ab4111 (diff) | |
download | ffmpeg-d95143ec82a026967e10a4521a5de78fb5cb2ec1.tar.gz |
lavf/segment: add support to ffconcat segment list
-rw-r--r-- | doc/demuxers.texi | 1 | ||||
-rw-r--r-- | doc/muxers.texi | 7 | ||||
-rw-r--r-- | libavformat/segment.c | 24 | ||||
-rw-r--r-- | libavformat/version.h | 2 |
4 files changed, 30 insertions, 4 deletions
diff --git a/doc/demuxers.texi b/doc/demuxers.texi index f9c86e76c7..0861287e76 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -29,6 +29,7 @@ the caller can decide which variant streams to actually receive. The total bitrate of the variant that the stream belongs to is available in a metadata key named "variant_bitrate". +@anchor{concat} @section concat Virtual concatenation script demuxer. diff --git a/doc/muxers.texi b/doc/muxers.texi index 5ba92c3adf..9d119c39a1 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -579,6 +579,13 @@ auto-select this format. @code{ext} is deprecated in favor or @code{csv}. +@item ffconcat +Generate an ffconcat file for the created segments. The resulting file +can be read using the FFmpeg @ref{concat} demuxer. + +A list file with the suffix @code{".ffcat"} or @code{".ffconcat"} will +auto-select this format. + @item m3u8 Generate an extended M3U8 file, version 3, compliant with @url{http://tools.ietf.org/id/draft-pantos-http-live-streaming}. diff --git a/libavformat/segment.c b/libavformat/segment.c index 13d8c43589..124a09fa41 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -53,6 +53,7 @@ typedef enum { LIST_TYPE_CSV, LIST_TYPE_M3U8, LIST_TYPE_EXT, ///< deprecated + LIST_TYPE_FFCONCAT, LIST_TYPE_NB, } ListType; @@ -225,6 +226,8 @@ static int segment_list_open(AVFormatContext *s) for (entry = seg->segment_list_entries; entry; entry = entry->next) max_duration = FFMAX(max_duration, entry->end_time - entry->start_time); avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%"PRId64"\n", (int64_t)ceil(max_duration)); + } else if (seg->list_type == LIST_TYPE_FFCONCAT) { + avio_printf(seg->list_pb, "ffconcat version 1.0\n"); } return ret; @@ -232,7 +235,8 @@ static int segment_list_open(AVFormatContext *s) static void segment_list_print_entry(AVIOContext *list_ioctx, ListType list_type, - const SegmentListEntry *list_entry) + const SegmentListEntry *list_entry, + void *log_ctx) { switch (list_type) { case LIST_TYPE_FLAT: @@ -247,6 +251,18 @@ static void segment_list_print_entry(AVIOContext *list_ioctx, avio_printf(list_ioctx, "#EXTINF:%f,\n%s\n", list_entry->end_time - list_entry->start_time, list_entry->filename); break; + case LIST_TYPE_FFCONCAT: + { + char *buf; + if (av_escape(&buf, list_entry->filename, NULL, AV_ESCAPE_MODE_AUTO, AV_ESCAPE_FLAG_WHITESPACE) < 0) { + av_log(log_ctx, AV_LOG_WARNING, + "Error writing list entry '%s' in list file\n", list_entry->filename); + return; + } + avio_printf(list_ioctx, "file %s\n", buf); + av_free(buf); + break; + } default: av_assert0(!"Invalid list type"); } @@ -293,11 +309,11 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) if ((ret = segment_list_open(s)) < 0) goto end; for (entry = seg->segment_list_entries; entry; entry = entry->next) - segment_list_print_entry(seg->list_pb, seg->list_type, entry); + segment_list_print_entry(seg->list_pb, seg->list_type, entry, s); if (seg->list_type == LIST_TYPE_M3U8 && is_last) avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n"); } else { - segment_list_print_entry(seg->list_pb, seg->list_type, &seg->cur_entry); + segment_list_print_entry(seg->list_pb, seg->list_type, &seg->cur_entry, s); } avio_flush(seg->list_pb); } @@ -551,6 +567,7 @@ static int seg_write_header(AVFormatContext *s) if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV; else if (av_match_ext(seg->list, "ext" )) seg->list_type = LIST_TYPE_EXT; else if (av_match_ext(seg->list, "m3u8")) seg->list_type = LIST_TYPE_M3U8; + else if (av_match_ext(seg->list, "ffcat,ffconcat")) seg->list_type = LIST_TYPE_FFCONCAT; else seg->list_type = LIST_TYPE_FLAT; } if ((ret = segment_list_open(s)) < 0) @@ -761,6 +778,7 @@ static const AVOption options[] = { { "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, "list_type" }, { "csv", "csv format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_CSV }, INT_MIN, INT_MAX, E, "list_type" }, { "ext", "extended format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_EXT }, INT_MIN, INT_MAX, E, "list_type" }, + { "ffconcat", "ffconcat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FFCONCAT }, INT_MIN, INT_MAX, E, "list_type" }, { "m3u8", "M3U8 format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" }, { "hls", "Apple HTTP Live Streaming compatible", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" }, diff --git a/libavformat/version.h b/libavformat/version.h index 3779bb6d12..672b9003bf 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MINOR 63 -#define LIBAVFORMAT_VERSION_MICRO 103 +#define LIBAVFORMAT_VERSION_MICRO 104 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ |