[FFmpeg-devel] [PATCH] lavf/segment: add support to concat segment list
Nicolas George
nicolas.george at normalesup.org
Tue Mar 5 16:05:42 CET 2013
Le quartidi 14 ventôse, an CCXXI, Stefano Sabatini a écrit :
> Seems to work fine after your fix, patch updated.
Adding the durations in the concat file may be a good thing, but that can
come later.
> >From fbe4f6fb86490a76715f9ac0b43b49e6692780fb Mon Sep 17 00:00:00 2001
> From: Stefano Sabatini <stefasab at gmail.com>
> Date: Thu, 21 Feb 2013 19:33:26 +0100
> Subject: [PATCH] lavf/segment: add support to concat segment list
>
> TODO: update docs, bump micro
> ---
> doc/demuxers.texi | 1 +
> doc/muxers.texi | 7 +++++++
> libavformat/segment.c | 24 +++++++++++++++++++++---
> 3 files changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/doc/demuxers.texi b/doc/demuxers.texi
> index c8eec21..899729a 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".
>
> + at anchor{concat}
> @section concat
>
> Virtual concatenation script demuxer.
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index 6aae871..52b88ca 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -560,6 +560,13 @@ The following values are recognized:
> @item flat
> Generate a flat list for the created segments, one segment per line.
>
> + at item concat
> +Generate a ffconcat file for the created segments. The resulting file
> +can be read using the @ref{concat} demuxer.
> +
> +A list file with the suffix @code{".ffcat"} or @code{".ffconcat"} will
> +auto-select this format.
> +
> @item csv, ext
> Generate a list for the created segments, one segment per line,
> each line matching the format (comma-separated values):
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index 13d8c43..6b7d5b0 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_CONCAT,
> 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_CONCAT) {
> + 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_CONCAT:
> + {
> + char *buf;
> + if (av_escape(&buf, list_entry->filename, NULL, AV_ESCAPE_MODE_QUOTE, 0) < 0) {
MODE_DEFAULT, maybe? I have no strong opinion about it.
> + av_log(log_ctx, AV_LOG_WARNING,
> + "Error writing list entry '%s' in list file\n", list_entry->filename);
> + return;
> + }
The error is not reported to the application, this is not good. OTOH, the
same already happens for all errors on avio, so...
> + 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_CONCAT;
> else seg->list_type = LIST_TYPE_FLAT;
> }
> if ((ret = segment_list_open(s)) < 0)
> @@ -759,6 +776,7 @@ static const AVOption options[] = {
>
> { "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" },
> { "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, "list_type" },
> + { "concat", "ffconcat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_CONCAT }, 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" },
> { "m3u8", "M3U8 format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" },
LGTM, thanks.
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130305/9274b99b/attachment.asc>
More information about the ffmpeg-devel
mailing list