[FFmpeg-devel] [PATCH] lavf/segment: add M3U8 list support

Stefano Sabatini stefasab at gmail.com
Wed Aug 15 11:09:59 CEST 2012


Address trac ticket #1642.
---
 libavformat/segment.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/libavformat/segment.c b/libavformat/segment.c
index 744c147..35363b5 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -34,6 +34,7 @@
 typedef enum {
     LIST_TYPE_FLAT = 0,
     LIST_TYPE_EXT,
+    LIST_TYPE_M3U8,
     LIST_TYPE_NB,
 } ListType;
 
@@ -119,6 +120,10 @@ static int segment_end(AVFormatContext *s)
 
     if (seg->list) {
         if (seg->list_size && !(seg->number % seg->list_size)) {
+            if (seg->list_type == LIST_TYPE_M3U8) {
+                avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n");
+                avio_flush(seg->list_pb);
+            }
             avio_close(seg->list_pb);
             if ((ret = avio_open2(&seg->list_pb, seg->list, AVIO_FLAG_WRITE,
                                   &s->interrupt_callback, NULL)) < 0)
@@ -129,7 +134,17 @@ static int segment_end(AVFormatContext *s)
             avio_printf(seg->list_pb, "%s\n", oc->filename);
         } else if (seg->list_type == LIST_TYPE_EXT) {
             avio_printf(seg->list_pb, "%s,%f,%f\n", oc->filename, seg->start_time, seg->end_time);
+        } else if (seg->list_type == LIST_TYPE_M3U8) {
+            if (seg->number == 1) {
+                avio_printf(seg->list_pb, "#EXTM3U\n");
+                if (seg->time_str)
+                    avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%f\n",
+                                (double)seg->time/1000000);
+            }
+            avio_printf(seg->list_pb, "#EXTINF:%f\n%s\n",
+                        seg->end_time - seg->start_time, oc->filename);
         }
+
         avio_flush(seg->list_pb);
     }
 
@@ -348,8 +363,13 @@ static int seg_write_trailer(struct AVFormatContext *s)
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
     int ret = segment_end(s);
-    if (seg->list)
+    if (seg->list) {
+        if (seg->list_type == LIST_TYPE_M3U8) {
+            avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n");
+            avio_flush(seg->list_pb);
+        }
         avio_close(seg->list_pb);
+    }
 
     av_opt_free(seg);
     av_freep(&seg->times);
@@ -369,6 +389,8 @@ static const AVOption options[] = {
     { "segment_list_type", "set the segment list type",                  OFFSET(list_type), AV_OPT_TYPE_INT,  {.dbl = LIST_TYPE_FLAT}, 0, LIST_TYPE_NB-1, E, "list_type" },
     { "flat", "flat format",     0, AV_OPT_TYPE_CONST, {.dbl=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, 0, "list_type" },
     { "ext",  "extended format", 0, AV_OPT_TYPE_CONST, {.dbl=LIST_TYPE_EXT  }, INT_MIN, INT_MAX, 0, "list_type" },
+    { "m3u8", "M3U8 format",     0, AV_OPT_TYPE_CONST, {.dbl=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, 0, "list_type" },
+
     { "segment_time",      "set segment duration",                       OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
     { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta_str), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, E },
     { "segment_times",     "set segment split time points",              OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
-- 
1.7.5.4



More information about the ffmpeg-devel mailing list