[FFmpeg-devel] [PATCH] lavf/segment: add support to concat segment list
Stefano Sabatini
stefasab at gmail.com
Thu Mar 7 01:49:02 CET 2013
On date Tuesday 2013-03-05 16:05:42 +0100, Nicolas George encoded:
> 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.
Pushed in order to avoid to delay too much the patch (feel free to
propose such a patch yourself). What's the benefit of such approach?
>
> > >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.
Changed.
> > + 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...
Indeed...
>
> > + 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.
Pushed, thanks.
--
FFmpeg = Fundamental & Fierce Minimalistic Pitiful Earthshaking Guru
More information about the ffmpeg-devel
mailing list