[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