>From 7a687f505b30d4c86ede4a59c18376f722e6a14a Mon Sep 17 00:00:00 2001
From: Bill C Riemers <briemers@redhat.com>
Date: Fri, 13 Jun 2008 12:05:51 -0400
Subject: [PATCH] Make http seeking to be non-blocking.

---
 modules/access/http.c |   51 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/modules/access/http.c b/modules/access/http.c
index efe91f0..fad1a8b 100644
--- a/modules/access/http.c
+++ b/modules/access/http.c
@@ -189,14 +189,14 @@ struct access_sys_t
 
     bool b_chunked;
     int64_t    i_chunk;
-
     int        i_icy_meta;
     char       *psz_icy_name;
     char       *psz_icy_genre;
     char       *psz_icy_title;
 
-    int64_t i_remaining;
-    int64_t i_blocksize;
+    int64_t i_remaining; /* the number of bytes remaining it the last request */
+    int64_t i_blocksize; /* the number of bytes to request next */ 
+    int64_t i_pos; /* where we the next byte of data is positioned */
 
     bool b_seekable;
     bool b_reconnect;
@@ -213,6 +213,7 @@ static int OpenWithCookies( vlc_object_t *p_this, vlc_array_t *cookies );
 static ssize_t Read( access_t *, uint8_t *, size_t );
 static ssize_t ReadCompressed( access_t *, uint8_t *, size_t );
 static int Seek( access_t *, int64_t );
+static int SeekTo( access_t *);
 static int SkipForward( access_t *, int64_t );
 static int Control( access_t *, int, va_list );
 
@@ -287,6 +288,7 @@ static int OpenWithCookies( vlc_object_t *p_this, vlc_array_t *cookies )
     p_sys->psz_icy_genre = NULL;
     p_sys->psz_icy_title = NULL;
     p_sys->i_remaining = 0;
+    p_sys->i_pos = 0;
     p_sys->i_blocksize = HTTP_MIN_BLOCKSIZE;
     p_sys->cookies = saved_cookies;
 
@@ -600,6 +602,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
     access_sys_t *p_sys = p_access->p_sys;
     int i_read;
 
+    if ( (p_sys->i_pos != p_access->info.i_pos) && (SeekTo( p_access ) != VLC_SUCCESS)) {
+        return 0;
+    }
+
     if( p_sys->fd < 0 )
     {
         p_access->info.b_eof = true;
@@ -705,7 +711,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
 
     if( i_read > 0 )
     {
-        p_access->info.i_pos += i_read;
+        p_sys->i_pos = (p_access->info.i_pos += i_read);
 
         if( p_sys->b_chunked )
         {
@@ -885,13 +891,12 @@ static int SkipForward( access_t *p_access, int64_t i_len ) {
 }
 
 /*****************************************************************************
- * Seek: Attempt to seek by a small read or offseting the position of the
- * next block. If that fails close and re-open a connection at the right place.
+ * Seek: We simply set the p_access->info.i_pos value to where we want to
+ * read from next.  The actual blocking operation won't occur until the
+ * read request.
  *****************************************************************************/
 static int Seek( access_t *p_access, int64_t i_pos )
 {
-    msg_Dbg( p_access, "trying to seek to %"PRId64"/"PRId64, i_pos, p_access->info.i_size );
-
     if( i_pos < 0 )
     {
         msg_Err( p_access, "seeking too early" );
@@ -904,8 +909,26 @@ static int Seek( access_t *p_access, int64_t i_pos )
         // success even when seeking too far.
         return Seek( p_access, p_access->info.i_size );
     }
-    // we can use the skip data to seek forward
+    p_access->info.i_pos = i_pos;
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * SeekTo: Attempt to seek by a small read or offseting the position of the
+ * next block. If that fails close and re-open a connection at the right place.
+ *****************************************************************************/
+static int SeekTo( access_t *p_access)
+{
+    int64_t i_pos = p_access->info.i_pos;
     access_sys_t *p_sys = p_access->p_sys;
+    if(i_pos == p_sys->i_pos) {
+        return VLC_SUCCESS;
+    }
+    p_access->info.i_pos = p_sys->i_pos;
+
+    msg_Dbg( p_access, "trying to seek to %"PRId64"/"PRId64, i_pos, p_access->info.i_size );
+
+    // we can use the skip data to seek forward
     if( i_pos > p_access->info.i_pos) {
         int64_t i_needed = i_pos - p_access->info.i_pos;
         if( (i_needed <= HTTP_SEEK_BLOCKSIZE)||(p_sys->i_remaining <= HTTP_SEEK_BLOCKSIZE) ) {
@@ -1047,7 +1070,7 @@ static int Connect( access_t *p_access, int64_t i_tell )
     p_sys->i_blocksize = HTTP_MIN_BLOCKSIZE;
 
     p_access->info.i_size = 0;
-    p_access->info.i_pos  = i_tell;
+    p_sys->i_pos = p_access->info.i_pos  = i_tell;
     p_access->info.b_eof  = false;
 
 
@@ -1186,7 +1209,7 @@ static int Request( access_t *p_access, int64_t i_tell )
     /* User Agent */
     net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, "User-Agent: %s\r\n",
                 p_sys->psz_user_agent );
-    p_access->info.i_pos = i_tell;
+    p_sys->i_pos = p_access->info.i_pos = i_tell;
     /* Offset */
     if( p_sys->i_version == 1 )
     {
@@ -1337,11 +1360,11 @@ static int Request( access_t *p_access, int64_t i_tell )
                 p_access->info.i_size = -1;
                 msg_Dbg( p_access, "this frame size=%lld", atoll(p ) );
                 p_sys->i_remaining = atoll( p );
-                p_access->info.i_pos = 0;
+                p_sys->i_pos = p_access->info.i_pos = 0;
             }
             else
             {
-                p_access->info.i_pos = i_tell;
+                p_sys->i_pos = p_access->info.i_pos = i_tell;
                 p_sys->i_remaining = atoll( p );
                 if(p_access->info.i_size <= 0) {
                     p_access->info.i_size = i_tell + p_sys->i_remaining;
@@ -1355,7 +1378,7 @@ static int Request( access_t *p_access, int64_t i_tell )
             int64_t j_size = p_access->info.i_size;
             sscanf(p,"bytes %"PRId64"-%"PRId64"/%"PRId64,&j_tell,&j_end,&j_size);
             p_access->info.i_size = j_size;
-            p_access->info.i_pos = j_tell;
+            p_sys->i_pos = p_access->info.i_pos = j_tell;
             p_sys->i_remaining = j_end+1-j_tell;
             msg_Dbg( p_access, "stream size=%"PRId64",position=%"PRId64",remaining=%"PRId64,j_size,j_tell,p_sys->i_remaining);
         }
-- 
1.5.5.1

