Ticket #1642: 0008-lavf-segment-add-segment_list_live-option-allow-live.patch

File 0008-lavf-segment-add-segment_list_live-option-allow-live.patch, 3.7 KB (added by saste, 4 years ago)
  • libavformat/segment.c

    From 74177c1919558e6ea8e0bc9adeca60fcd19c9ccd Mon Sep 17 00:00:00 2001
    From: Stefano Sabatini <stefasab@gmail.com>
    Date: Sat, 1 Sep 2012 18:01:51 +0200
    Subject: [PATCH] lavf/segment: add segment_list_live option, allow
     live-friendly M3U8 list format generation
    
    Allow to create M3U8 list which are HLS-friendly. In particular, write a
    fake EXT-X-TARGETDURATION duration field based on the specified
    segment_time.
    
    For a full discussion read trac ticket #1492:
    http://ffmpeg.org/trac/ffmpeg/ticket/1642
    ---
     libavformat/segment.c |   17 +++++++++++++++--
     1 files changed, 15 insertions(+), 2 deletions(-)
    
    diff --git a/libavformat/segment.c b/libavformat/segment.c
    index c695761..b25ee48 100644
    a b typedef struct { 
    5555    char *format;          ///< format to use for output segment files 
    5656    char *list;            ///< filename for the segment list file 
    5757    int   list_count;      ///< list counter 
     58    int   list_live;       ///< force live-friendly list generation 
    5859    int   list_size;       ///< number of entries for the segment list file 
    5960    double list_max_segment_time; ///< max segment time in the current list 
    6061    ListType list_type;    ///< set the list type 
    static int segment_list_open(AVFormatContext *s) 
    154155        avio_printf(seg->list_pb, "#EXTM3U\n"); 
    155156        avio_printf(seg->list_pb, "#EXT-X-VERSION:3\n"); 
    156157        avio_printf(seg->list_pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", seg->list_count); 
     158        if (seg->list_live) 
     159            avio_printf(seg->list_pb, 
     160                        "#EXT-X-TARGETDURATION:%"PRId64"\n", seg->time / 1000000); 
    157161    } 
    158162 
    159163    return ret; 
    static void segment_list_close(AVFormatContext *s) 
    164168    SegmentContext *seg = s->priv_data; 
    165169 
    166170    if (seg->list_type == LIST_TYPE_M3U8) { 
    167         avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%d\n", 
    168                     (int)ceil(seg->list_max_segment_time)); 
     171        if (!seg->list_live) 
     172            avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%d\n", 
     173                        (int)ceil(seg->list_max_segment_time)); 
    169174        avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n"); 
    170175    } 
    171176    seg->list_count++; 
    static int seg_write_header(AVFormatContext *s) 
    282287        return AVERROR(EINVAL); 
    283288    } 
    284289 
     290    if (seg->list_live && seg->times_str) { 
     291        av_log(s, AV_LOG_ERROR, 
     292               "segment_live set to 1 and segment_times options are mutually exclusive:" 
     293               "specify -segment_time if you want a live-friendly list\n"); 
     294        return AVERROR(EINVAL); 
     295    } 
     296 
    285297    if (seg->times_str) { 
    286298        if ((ret = parse_times(s, &seg->times, &seg->nb_times, seg->times_str)) < 0) 
    287299            return ret; 
    static int seg_write_trailer(struct AVFormatContext *s) 
    448460static const AVOption options[] = { 
    449461    { "segment_format",    "set container format used for the segments", OFFSET(format),  AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E }, 
    450462    { "segment_list",      "set the segment list filename",              OFFSET(list),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E }, 
     463    { "segment_list_live", "enable live-friendly list generation (useful for HLS)", OFFSET(list_live), AV_OPT_TYPE_INT, {.dbl = 0},  0, 1, E }, 
    451464    { "segment_list_size", "set the maximum number of playlist entries", OFFSET(list_size), AV_OPT_TYPE_INT,  {.dbl = 0},     0, INT_MAX, E }, 
    452465    { "segment_list_type", "set the segment list type",                  OFFSET(list_type), AV_OPT_TYPE_INT,  {.dbl = LIST_TYPE_UNDEFINED}, -1, LIST_TYPE_NB-1, E, "list_type" }, 
    453466    { "flat", "flat format",     0, AV_OPT_TYPE_CONST, {.dbl=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, 0, "list_type" },