Re: [libav-devel] [PATCH] segment: support hls style playlist

2012-10-06 Thread Luca Barbato
On 10/06/2012 01:23 PM, Martin Storsjö wrote:
> This doesn't look right. The #EXT-X-MEDIA-SEQUENCE tag indicates the
> index in the sequence for the first entry in the list. So as long as you
> just add more entries to the end of the list, this value should stay
> unchanged - you should increment it only when you remove elements from
> the start.

You are right.

> To do this properly for live stuff, you probably also want to change
> writing of the playlists to rewrite the full playlist each time, instead
> of keeping the playlist file open and just appending one line. And not
> empty the playlist when you reach the target size, but just remove the
> first element from it.

I overlooked the whole sliding window thing, not sure how good it is btw...

lu
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


Re: [libav-devel] [PATCH] segment: support hls style playlist

2012-10-06 Thread Martin Storsjö

On Sat, 6 Oct 2012, Luca Barbato wrote:


---
libavformat/segment.c | 27 +++
1 file changed, 27 insertions(+)

diff --git a/libavformat/segment.c b/libavformat/segment.c
index 8ac04e2..07bb675 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -37,6 +37,7 @@ typedef struct {
AVFormatContext *avf;
char *format;  /**< Set by a private option. */
char *list;/**< Set by a private option. */
+int  list_type;/**< Set by a private option. */
float time;/**< Set by a private option. */
int  size; /**< Set by a private option. */
int  wrap; /**< Set by a private option. */
@@ -48,6 +49,11 @@ typedef struct {
AVIOContext *pb;
} SegmentContext;

+enum {
+LIST_FLAT,
+LIST_HLS
+};
+
static int segment_mux_init(AVFormatContext *s)
{
SegmentContext *seg = s->priv_data;
@@ -72,6 +78,17 @@ static int segment_mux_init(AVFormatContext *s)
return 0;
}

+static void segment_hls_header(SegmentContext *seg)
+{
+avio_printf(seg->pb, "#EXTM3U\n");
+
+avio_printf(seg->pb, "#EXT-X-VERSION:3\n");
+
+avio_printf(seg->pb, "#EXT-X-TARGETDURATION:%d\n", (int)seg->time);
+
+avio_printf(seg->pb, "#EXT-X-MEDIA-SEQUENCE:%d)", seg->number % seg->size);


This doesn't look right. The #EXT-X-MEDIA-SEQUENCE tag indicates the 
index in the sequence for the first entry in the list. So as long as you 
just add more entries to the end of the list, this value should stay 
unchanged - you should increment it only when you remove elements from 
the start.


To do this properly for live stuff, you probably also want to change 
writing of the playlists to rewrite the full playlist each time, instead 
of keeping the playlist file open and just appending one line. And not 
empty the playlist when you reach the target size, but just remove the 
first element from it.


// Martin
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


[libav-devel] [PATCH] segment: support hls style playlist

2012-10-06 Thread Luca Barbato
---
 libavformat/segment.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/libavformat/segment.c b/libavformat/segment.c
index 8ac04e2..07bb675 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -37,6 +37,7 @@ typedef struct {
 AVFormatContext *avf;
 char *format;  /**< Set by a private option. */
 char *list;/**< Set by a private option. */
+int  list_type;/**< Set by a private option. */
 float time;/**< Set by a private option. */
 int  size; /**< Set by a private option. */
 int  wrap; /**< Set by a private option. */
@@ -48,6 +49,11 @@ typedef struct {
 AVIOContext *pb;
 } SegmentContext;
 
+enum {
+LIST_FLAT,
+LIST_HLS
+};
+
 static int segment_mux_init(AVFormatContext *s)
 {
 SegmentContext *seg = s->priv_data;
@@ -72,6 +78,17 @@ static int segment_mux_init(AVFormatContext *s)
 return 0;
 }
 
+static void segment_hls_header(SegmentContext *seg)
+{
+avio_printf(seg->pb, "#EXTM3U\n");
+
+avio_printf(seg->pb, "#EXT-X-VERSION:3\n");
+
+avio_printf(seg->pb, "#EXT-X-TARGETDURATION:%d\n", (int)seg->time);
+
+avio_printf(seg->pb, "#EXT-X-MEDIA-SEQUENCE:%d)", seg->number % seg->size);
+}
+
 static int segment_start(AVFormatContext *s, int write_header)
 {
 SegmentContext *c = s->priv_data;
@@ -211,6 +228,10 @@ static int seg_write_header(AVFormatContext *s)
 }
 
 if (seg->list) {
+if (seg->list_type == LIST_HLS) {
+segment_hls_header(seg);
+avio_printf(seg->pb, "#EXTINF:%d,\n", (int)seg->time);
+}
 avio_printf(seg->pb, "%s\n", oc->filename);
 avio_flush(seg->pb);
 }
@@ -252,6 +273,8 @@ static int seg_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 oc = seg->avf;
 
 if (seg->list) {
+if (seg->list_type == LIST_HLS)
+avio_printf(seg->pb, "#EXTINF:%d,\n", (int)seg->time);
 avio_printf(seg->pb, "%s\n", oc->filename);
 avio_flush(seg->pb);
 if (seg->size && !(seg->number % seg->size)) {
@@ -259,6 +282,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,
   &s->interrupt_callback, NULL)) < 0)
 goto fail;
+segment_hls_header(seg);
 }
 }
 }
@@ -301,6 +325,9 @@ static const AVOption options[] = {
 { "segment_time",  "segment length in seconds",   
OFFSET(time),AV_OPT_TYPE_FLOAT,  {.dbl = 2}, 0, FLT_MAX, E },
 { "segment_list",  "output the segment list", 
OFFSET(list),AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,   E },
 { "segment_list_size", "maximum number of playlist entries",  
OFFSET(size),AV_OPT_TYPE_INT,{.i64 = 5}, 0, INT_MAX, E },
+{ "segment_list_type", "segment list format", 
OFFSET(list_type),AV_OPT_TYPE_INT,{.i64 = 0}, 0, 2, E, "list_type" 
},
+{   "flat","plain list (default)",0,   
AV_OPT_TYPE_CONST,  {.i64 = LIST_FLAT}, 0, 0, E, "list_type" },
+{   "hls", "Apple HTTP Live Streaming compatible",0,   
AV_OPT_TYPE_CONST,  {.i64 = LIST_HLS},  0, 0, E, "list_type" },
 { "segment_wrap",  "number after which the index wraps",  
OFFSET(wrap),AV_OPT_TYPE_INT,{.i64 = 0}, 0, INT_MAX, E },
 { "individual_header_trailer", "write header/trailer to each segment", 
OFFSET(individual_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
 { "write_header_trailer", "write a header to the first segment and a 
trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_INT, {.i64 
= 1}, 0, 1, E },
-- 
1.7.12

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel