Re: [libav-devel] [PATCH 2/3] applehttp: Restructure the demuxer to use a custom AVIOContext

2011-04-04 Thread Martin Storsjö
On Fri, 1 Apr 2011, Diego Biurrun wrote:

 On Thu, Mar 31, 2011 at 11:19:35PM +0300, Martin Storsjö wrote:
  This avoids issues where EOF at the end of the segment is given
  the variant demuxer. Now the demuxers only see one single data
  stream (as when using the applehttp protocol handler).
 
 .. some nits ..
 
  --- a/libavformat/applehttp.c
  +++ b/libavformat/applehttp.c
  @@ -246,6 +256,74 @@ fail:
   
  +static int read_data(void* opaque, uint8_t *buf, int buf_size)
 
 *opaque
 
  +if (!v-finished) {
  +/* If this is a live stream and target_duration has elapsed 
  since
  + * the last playlist reload, reload the variant playlists now. 
  */
  +int64_t now = av_gettime();
  +if (now - v-last_load_time = v-target_duration*100) {
  +if ((ret = parse_playlist(c, v-url, v, NULL))  0)
  +return ret;
  +}
  +}
 
 I'd merge all of this into one if-statement and drop the variable, i.e.
 
if (!v-finished 
/* If this is a live stream and target_duration has elapsed since
 * the last playlist reload, reload the variant playlists now. */
av_gettime() - v-last_load_time = v-target_duration * 100 
(ret = parse_playlist(c, v-url, v, NULL))  0)
return ret;

Both fixed locally, thanks!

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


Re: [libav-devel] [PATCH 2/3] applehttp: Restructure the demuxer to use a custom AVIOContext

2011-04-01 Thread Diego Biurrun
On Thu, Mar 31, 2011 at 11:19:35PM +0300, Martin Storsjö wrote:
 This avoids issues where EOF at the end of the segment is given
 the variant demuxer. Now the demuxers only see one single data
 stream (as when using the applehttp protocol handler).

.. some nits ..

 --- a/libavformat/applehttp.c
 +++ b/libavformat/applehttp.c
 @@ -246,6 +256,74 @@ fail:
  
 +static int read_data(void* opaque, uint8_t *buf, int buf_size)

*opaque

 +if (!v-finished) {
 +/* If this is a live stream and target_duration has elapsed since
 + * the last playlist reload, reload the variant playlists now. */
 +int64_t now = av_gettime();
 +if (now - v-last_load_time = v-target_duration*100) {
 +if ((ret = parse_playlist(c, v-url, v, NULL))  0)
 +return ret;
 +}
 +}

I'd merge all of this into one if-statement and drop the variable, i.e.

   if (!v-finished 
   /* If this is a live stream and target_duration has elapsed since
* the last playlist reload, reload the variant playlists now. */
   av_gettime() - v-last_load_time = v-target_duration * 100 
   (ret = parse_playlist(c, v-url, v, NULL))  0)
   return ret;

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


[libav-devel] [PATCH 2/3] applehttp: Restructure the demuxer to use a custom AVIOContext

2011-03-31 Thread Martin Storsjö
This avoids issues where EOF at the end of the segment is given
the variant demuxer. Now the demuxers only see one single data
stream (as when using the applehttp protocol handler).
---
 libavformat/applehttp.c |  335 ---
 1 files changed, 169 insertions(+), 166 deletions(-)

diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c
index 815013d..db1dc61 100644
--- a/libavformat/applehttp.c
+++ b/libavformat/applehttp.c
@@ -30,6 +30,9 @@
 #include avformat.h
 #include internal.h
 #include unistd.h
+#include avio_internal.h
+
+#define INITIAL_BUFFER_SIZE 32768
 
 /*
  * An apple http stream consists of a playlist with media segment files,
@@ -56,7 +59,11 @@ struct segment {
 struct variant {
 int bandwidth;
 char url[MAX_URL_SIZE];
-AVIOContext *pb;
+AVIOContext pb;
+uint8_t* read_buffer;
+URLContext *input;
+AVFormatContext *parent;
+int index;
 AVFormatContext *ctx;
 AVPacket pkt;
 int stream_offset;
@@ -66,16 +73,17 @@ struct variant {
 int start_seq_no;
 int n_segments;
 struct segment **segments;
-int needed;
+int needed, cur_needed;
+int cur_seq_no;
+int64_t last_load_time;
 };
 
 typedef struct AppleHTTPContext {
 int n_variants;
 struct variant **variants;
 int cur_seq_no;
-int64_t last_load_time;
-int64_t last_packet_dts;
-int max_start_seq, min_end_seq;
+int end_of_segment;
+int first_packet;
 } AppleHTTPContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -102,8 +110,9 @@ static void free_variant_list(AppleHTTPContext *c)
 struct variant *var = c-variants[i];
 free_segment_list(var);
 av_free_packet(var-pkt);
-if (var-pb)
-avio_close(var-pb);
+av_free(var-pb.buffer);
+if (var-input)
+url_close(var-input);
 if (var-ctx) {
 var-ctx-pb = NULL;
 av_close_input_file(var-ctx);
@@ -238,7 +247,8 @@ static int parse_playlist(AppleHTTPContext *c, const char 
*url,
 }
 }
 }
-c-last_load_time = av_gettime();
+if (var)
+var-last_load_time = av_gettime();
 
 fail:
 if (close_in)
@@ -246,6 +256,74 @@ fail:
 return ret;
 }
 
+static int read_data(void* opaque, uint8_t *buf, int buf_size)
+{
+struct variant *v = opaque;
+AppleHTTPContext *c = v-parent-priv_data;
+int ret, i;
+
+restart:
+if (!v-input) {
+reload:
+if (!v-finished) {
+/* If this is a live stream and target_duration has elapsed since
+ * the last playlist reload, reload the variant playlists now. */
+int64_t now = av_gettime();
+if (now - v-last_load_time = v-target_duration*100) {
+if ((ret = parse_playlist(c, v-url, v, NULL))  0)
+return ret;
+}
+}
+if (v-cur_seq_no  v-start_seq_no) {
+av_log(NULL, AV_LOG_WARNING,
+   skipping %d segments ahead, expired from playlists\n,
+   v-start_seq_no - v-cur_seq_no);
+v-cur_seq_no = v-start_seq_no;
+}
+if (v-cur_seq_no = v-start_seq_no + v-n_segments) {
+if (v-finished)
+return AVERROR_EOF;
+while (av_gettime() - v-last_load_time 
+   v-target_duration*100) {
+if (url_interrupt_cb())
+return AVERROR_EXIT;
+usleep(100*1000);
+}
+/* Enough time has elapsed since the last reload */
+goto reload;
+}
+
+ret = url_open(v-input,
+   v-segments[v-cur_seq_no - v-start_seq_no]-url,
+   URL_RDONLY);
+if (ret  0)
+return ret;
+}
+ret = url_read(v-input, buf, buf_size);
+if (ret  0)
+return ret;
+if (ret  0  ret != AVERROR_EOF)
+return ret;
+url_close(v-input);
+v-input = NULL;
+v-cur_seq_no++;
+
+c-end_of_segment = 1;
+c-cur_seq_no = v-cur_seq_no;
+
+v-needed = 0;
+for (i = v-stream_offset; i  v-stream_offset + v-ctx-nb_streams; i++) 
{
+if (v-parent-streams[i]-discard  AVDISCARD_ALL)
+v-needed = 1;
+}
+if (!v-needed) {
+av_log(v-parent, AV_LOG_INFO, No longer receiving variant %d\n,
+   v-index);
+return AVERROR_EOF;
+}
+goto restart;
+}
+
 static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
 {
 AppleHTTPContext *c = s-priv_data;
@@ -284,20 +362,35 @@ static int applehttp_read_header(AVFormatContext *s, 
AVFormatParameters *ap)
 s-duration = duration * AV_TIME_BASE;
 }
 
-c-min_end_seq = INT_MAX;
 /* Open the demuxer for each variant */
 for (i = 0; i  c-n_variants; i++) {
 struct variant *v = c-variants[i];
+AVInputFormat *in_fmt = NULL;
 if (v-n_segments == 0)

[libav-devel] [PATCH 2/3] applehttp: Restructure the demuxer to use a custom AVIOContext

2011-03-30 Thread Martin Storsjö
This avoids issues where EOF at the end of the segment is given
the variant demuxer. Now the demuxers only see one single data
stream (as when using the applehttp protocol handler).
---
 libavformat/applehttp.c |  335 ---
 1 files changed, 169 insertions(+), 166 deletions(-)

diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c
index 815013d..b9ffded 100644
--- a/libavformat/applehttp.c
+++ b/libavformat/applehttp.c
@@ -30,6 +30,9 @@
 #include avformat.h
 #include internal.h
 #include unistd.h
+#include avio_internal.h
+
+#define INITIAL_BUFFER_SIZE 32768
 
 /*
  * An apple http stream consists of a playlist with media segment files,
@@ -56,7 +59,11 @@ struct segment {
 struct variant {
 int bandwidth;
 char url[MAX_URL_SIZE];
-AVIOContext *pb;
+AVIOContext pb;
+uint8_t* read_buffer;
+URLContext *input;
+AVFormatContext *parent;
+int index;
 AVFormatContext *ctx;
 AVPacket pkt;
 int stream_offset;
@@ -66,16 +73,17 @@ struct variant {
 int start_seq_no;
 int n_segments;
 struct segment **segments;
-int needed;
+int needed, cur_needed;
+int cur_seq_no;
+int64_t last_load_time;
 };
 
 typedef struct AppleHTTPContext {
 int n_variants;
 struct variant **variants;
 int cur_seq_no;
-int64_t last_load_time;
-int64_t last_packet_dts;
-int max_start_seq, min_end_seq;
+int end_of_segment;
+int first_packet;
 } AppleHTTPContext;
 
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -102,8 +110,9 @@ static void free_variant_list(AppleHTTPContext *c)
 struct variant *var = c-variants[i];
 free_segment_list(var);
 av_free_packet(var-pkt);
-if (var-pb)
-avio_close(var-pb);
+av_free(var-pb.buffer);
+if (var-input)
+url_close(var-input);
 if (var-ctx) {
 var-ctx-pb = NULL;
 av_close_input_file(var-ctx);
@@ -238,7 +247,8 @@ static int parse_playlist(AppleHTTPContext *c, const char 
*url,
 }
 }
 }
-c-last_load_time = av_gettime();
+if (var)
+var-last_load_time = av_gettime();
 
 fail:
 if (close_in)
@@ -246,6 +256,74 @@ fail:
 return ret;
 }
 
+static int read_data(void* opaque, uint8_t *buf, int buf_size)
+{
+struct variant *v = opaque;
+AppleHTTPContext *c = v-parent-priv_data;
+int ret, i;
+
+restart:
+if (!v-input) {
+reload:
+if (!v-finished) {
+/* If this is a live stream and target_duration has elapsed since
+ * the last playlist reload, reload the variant playlists now. */
+int64_t now = av_gettime();
+if (now - v-last_load_time = v-target_duration*100) {
+if ((ret = parse_playlist(c, v-url, v, NULL))  0)
+return ret;
+}
+}
+if (v-cur_seq_no  v-start_seq_no) {
+av_log(NULL, AV_LOG_WARNING,
+   skipping %d segments ahead, expired from playlists\n,
+   v-start_seq_no - v-cur_seq_no);
+v-cur_seq_no = v-start_seq_no;
+}
+if (v-cur_seq_no = v-start_seq_no + v-n_segments) {
+if (v-finished)
+return AVERROR_EOF;
+while (av_gettime() - v-last_load_time 
+   v-target_duration*100) {
+if (url_interrupt_cb())
+return AVERROR_EXIT;
+usleep(100*1000);
+}
+/* Enough time has elapsed since the last reload */
+goto reload;
+}
+
+ret = url_open(v-input,
+   v-segments[v-cur_seq_no - v-start_seq_no]-url,
+   URL_RDONLY);
+if (ret  0)
+return ret;
+}
+ret = url_read(v-input, buf, buf_size);
+if (ret  0)
+return ret;
+if (ret  0  ret != AVERROR_EOF)
+return ret;
+url_close(v-input);
+v-input = NULL;
+v-cur_seq_no++;
+
+c-end_of_segment = 1;
+c-cur_seq_no = v-cur_seq_no;
+
+v-needed = 0;
+for (i = v-stream_offset; i  v-stream_offset + v-ctx-nb_streams; i++) 
{
+if (v-parent-streams[i]-discard  AVDISCARD_ALL)
+v-needed = 1;
+}
+if (!v-needed) {
+av_log(v-parent, AV_LOG_INFO, No longer receiving variant %d\n,
+   v-index);
+return AVERROR_EOF;
+}
+goto restart;
+}
+
 static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
 {
 AppleHTTPContext *c = s-priv_data;
@@ -284,20 +362,35 @@ static int applehttp_read_header(AVFormatContext *s, 
AVFormatParameters *ap)
 s-duration = duration * AV_TIME_BASE;
 }
 
-c-min_end_seq = INT_MAX;
 /* Open the demuxer for each variant */
 for (i = 0; i  c-n_variants; i++) {
 struct variant *v = c-variants[i];
+AVInputFormat *in_fmt = NULL;
 if (v-n_segments == 0)