stream: replace STREAM_SET_POSITION control with dedicated pf_seek
authorRémi Denis-Courmont <remi@remlab.net>
Tue, 1 Sep 2015 20:39:53 +0000 (23:39 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Wed, 2 Sep 2015 17:02:03 +0000 (20:02 +0300)
Also:
 - zip: fix seeking to end of file
 - accesstweaks: fix segmentation fault when (inhibiting) seeking
 - decomp: set callbacks only on successful init

17 files changed:
include/vlc_stream.h
modules/access/archive/stream.c
modules/access/rar/stream.c
modules/access/zip/zipstream.c
modules/stream_filter/accesstweaks.c
modules/stream_filter/aribcam.c
modules/stream_filter/cache_block.c
modules/stream_filter/cache_read.c
modules/stream_filter/decomp.c
modules/stream_filter/hds/hds.c
modules/stream_filter/prefetch.c
modules/stream_filter/record.c
modules/stream_filter/smooth/smooth.c
src/input/access.c
src/input/stream.c
src/input/stream_demux.c
src/input/stream_memory.c

index 44d3297..ba642ff 100644 (file)
@@ -58,6 +58,7 @@ struct stream_t
     /* */
     ssize_t     (*pf_read)(stream_t *, void *, size_t);
     input_item_t *(*pf_readdir)( stream_t * );
+    int         (*pf_seek)(stream_t *, uint64_t);
     int         (*pf_control)( stream_t *, int i_query, va_list );
 
     /* */
index 6a93809..ae3997c 100644 (file)
@@ -54,7 +54,6 @@ static int Control(stream_t *p_stream, int i_query, va_list args)
         case STREAM_CAN_SEEK:
         case STREAM_CAN_FASTSEEK:
         case STREAM_GET_SIZE:
-        case STREAM_SET_POSITION:
         case STREAM_SET_RECORD_STATE:
         case STREAM_GET_CONTENT_TYPE:
             return VLC_EGENERIC;
@@ -200,6 +199,7 @@ int StreamOpen(vlc_object_t *p_object)
     }
 
     p_stream->pf_read = NULL;
+    p_stream->pf_seek = NULL;
     p_stream->pf_control = Control;
     p_stream->pf_readdir = Browse;
 
index 399634e..ba77131 100644 (file)
@@ -44,6 +44,11 @@ static ssize_t Read(stream_t *s, void *data, size_t size)
     return stream_Read(s->p_sys->payload, data, size);
 }
 
+static int Seek(stream_t *s, uint64_t offset)
+{
+    return stream_Seek(s->p_sys->payload, offset);
+}
+
 static int Control(stream_t *s, int query, va_list args)
 {
     switch (query) {
@@ -138,6 +143,7 @@ int RarStreamOpen(vlc_object_t *object)
     }
 
     s->pf_read = Read;
+    s->pf_seek = Seek;
     s->pf_control = Control;
 
     stream_sys_t *sys = s->p_sys = malloc(sizeof(*sys));
index 9a496ed..f26f74f 100644 (file)
@@ -54,6 +54,7 @@ vlc_module_end()
  * Local prototypes
  ****************************************************************************/
 static ssize_t Read( stream_t *, void *p_read, size_t i_read );
+static int Seek( stream_t *s, uint64_t );
 static int Control( stream_t *, int i_query, va_list );
 
 typedef struct node node;
@@ -221,6 +222,7 @@ int StreamOpen( vlc_object_t *p_this )
     free(s->psz_url);
     s->psz_url = psz_tmp;
     s->pf_read = Read;
+    s->pf_seek = Seek;
     s->pf_control = Control;
     return VLC_SUCCESS;
 error:
@@ -269,6 +271,17 @@ static ssize_t Read( stream_t *s, void *p_read, size_t i_read )
     return i_len;
 }
 
+static int Seek( stream_t *s, uint64_t i_position )
+{
+    stream_sys_t *p_sys = s->p_sys;
+
+    if( i_position > p_sys->i_len )
+        i_position = p_sys->i_len;
+
+    p_sys->i_pos = i_position;
+    return VLC_SUCCESS;
+}
+
 /** *************************************************************************
  * Control
  ****************************************************************************/
@@ -278,18 +291,6 @@ static int Control( stream_t *s, int i_query, va_list args )
 
     switch( i_query )
     {
-        case STREAM_SET_POSITION:
-        {
-            uint64_t i_position = va_arg( args, uint64_t );
-            if( i_position >= p_sys->i_len )
-                return VLC_EGENERIC;
-            else
-            {
-                p_sys->i_pos = (size_t) i_position;
-                return VLC_SUCCESS;
-            }
-        }
-
         case STREAM_GET_SIZE:
         {
             uint64_t *pi_size = va_arg( args, uint64_t* );
index ce51f95..61f0c86 100644 (file)
@@ -71,7 +71,6 @@ static int Control( stream_t *p_stream, int i_query, va_list args )
         }
         break;
     case STREAM_CAN_SEEK:
-    case STREAM_SET_POSITION:
         if( !p_sys->b_seek )
         {
             *((bool*)va_arg( args, bool* )) = false;
@@ -91,6 +90,14 @@ static ssize_t Read( stream_t *s, void *buffer, size_t i_read )
     return stream_Read( s->p_source, buffer, i_read );
 }
 
+static int Seek( stream_t *s, uint64_t offset )
+{
+    stream_sys_t *p_sys = p_stream->p_sys;
+
+    assert( p_sys->b_seek );
+    return stream_Seek( s->p_source, offset );
+}
+
 static int Open( vlc_object_t *p_object )
 {
     stream_t *p_stream = (stream_t *) p_object;
@@ -103,6 +110,7 @@ static int Open( vlc_object_t *p_object )
     p_sys->b_fastseek = var_InheritBool( p_stream, "fastseek" );
 
     p_stream->pf_read = Read;
+    p_stream->pf_seek = p_sys->b_seek ? Seek : NULL;
     p_stream->pf_control = Control;
 
     return VLC_SUCCESS;
index 552c79a..3c5f014 100644 (file)
@@ -275,13 +275,7 @@ static int Seek( stream_t *p_stream, uint64_t i_pos )
  */
 static int Control( stream_t *p_stream, int i_query, va_list args )
 {
-    switch( i_query )
-    {
-    case STREAM_SET_POSITION:
-        return Seek( p_stream, va_arg( args, uint64_t ) );
-    default:
-        return stream_vaControl( p_stream->p_source, i_query, args );
-    }
+    return stream_vaControl( p_stream->p_source, i_query, args );
 }
 
 static int Open( vlc_object_t *p_object )
@@ -355,6 +349,7 @@ static int Open( vlc_object_t *p_object )
     }
 
     p_stream->pf_read = Read;
+    p_stream->pf_seek = Seek;
     p_stream->pf_control = Control;
 
     return VLC_SUCCESS;
index 8ac7a06..4f01c91 100644 (file)
@@ -434,12 +434,6 @@ static int AStreamControl(stream_t *s, int i_query, va_list args)
         case STREAM_GET_PRIVATE_ID_STATE:
             return stream_vaControl(s->p_source, i_query, args);
 
-        case STREAM_SET_POSITION:
-        {
-            uint64_t offset = va_arg(args, uint64_t);
-            return AStreamSeekBlock(s, offset);
-        }
-
         case STREAM_SET_TITLE:
         case STREAM_SET_SEEKPOINT:
         {
@@ -495,6 +489,7 @@ static int Open(vlc_object_t *obj)
     }
 
     s->pf_read = AStreamReadBlock;
+    s->pf_seek = AStreamSeekBlock;
     s->pf_control = AStreamControl;
     return VLC_SUCCESS;
 }
index c34566b..7a96053 100644 (file)
@@ -485,12 +485,6 @@ static int AStreamControl(stream_t *s, int i_query, va_list args)
         case STREAM_GET_PRIVATE_ID_STATE:
             return stream_vaControl(s->p_source, i_query, args);
 
-        case STREAM_SET_POSITION:
-        {
-            uint64_t offset = va_arg(args, uint64_t);
-            return AStreamSeekStream(s, offset);
-        }
-
         case STREAM_SET_TITLE:
         case STREAM_SET_SEEKPOINT:
         {
@@ -564,6 +558,7 @@ static int Open(vlc_object_t *obj)
     }
 
     s->pf_read = AStreamReadStream;
+    s->pf_seek = AStreamSeekStream;
     s->pf_control = AStreamControl;
     return VLC_SUCCESS;
 }
index 4dc7dbe..fe6c997 100644 (file)
@@ -263,9 +263,6 @@ static int Open (stream_t *stream, const char *path)
     if (p_sys == NULL)
         return VLC_ENOMEM;
 
-    stream->pf_read = Read;
-    stream->pf_control = Control;
-
     vlc_cond_init (&p_sys->wait);
     vlc_mutex_init (&p_sys->lock);
     p_sys->paused = false;
@@ -339,15 +336,20 @@ static int Open (stream_t *stream, const char *path)
             close (comp[1]);
     }
 
-    if (ret == VLC_SUCCESS)
-        return VLC_SUCCESS;
+    if (ret != VLC_SUCCESS)
+    {
+        if (p_sys->pid != -1)
+            while (waitpid (p_sys->pid, &(int){ 0 }, 0) == -1);
+        vlc_mutex_destroy (&p_sys->lock);
+        vlc_cond_destroy (&p_sys->wait);
+        free (p_sys);
+        return ret;
+    }
 
-    if (p_sys->pid != -1)
-        while (waitpid (p_sys->pid, &(int){ 0 }, 0) == -1);
-    vlc_mutex_destroy (&p_sys->lock);
-    vlc_cond_destroy (&p_sys->wait);
-    free (p_sys);
-    return ret;
+    stream->pf_read = Read;
+    stream->pf_seek = NULL;
+    stream->pf_control = Control;
+    return VLC_SUCCESS;
 }
 
 
index b50bf6a..62f19ea 100644 (file)
@@ -1663,6 +1663,7 @@ static int Open( vlc_object_t *p_this )
     }
 
     s->pf_read = Read;
+    s->pf_seek = NULL;
     s->pf_control = Control;
 
     if( vlc_clone( &p_sys->dl_thread, download_thread, s, VLC_THREAD_PRIORITY_INPUT ) )
index aa40613..2b97513 100644 (file)
@@ -336,8 +336,6 @@ static int Control(stream_t *stream, int query, va_list args)
         case STREAM_CAN_CONTROL_PACE:
             *va_arg (args, bool *) = sys->can_pace;
             break;
-        case STREAM_SET_POSITION:
-            return Seek(stream, va_arg(args, uint64_t));
         case STREAM_IS_DIRECTORY:
             return VLC_EGENERIC;
         case STREAM_GET_SIZE:
@@ -407,6 +405,7 @@ static int Open(vlc_object_t *obj)
         return VLC_ENOMEM;
 
     stream->pf_read = Read;
+    stream->pf_seek = Seek;
     stream->pf_control = Control;
 
     stream_Control(stream->p_source, STREAM_CAN_SEEK, &sys->can_seek);
index d2ccbf2..c0c8b68 100644 (file)
@@ -65,6 +65,7 @@ struct stream_sys_t
  * Local prototypes
  ****************************************************************************/
 static ssize_t Read( stream_t *, void *p_read, size_t i_read );
+static int  Seek   ( stream_t *, uint64_t );
 static int  Control( stream_t *, int i_query, va_list );
 
 static int  Start  ( stream_t *, const char *psz_extension );
@@ -88,6 +89,7 @@ static int Open ( vlc_object_t *p_this )
 
     /* */
     s->pf_read = Read;
+    s->pf_seek = Seek;
     s->pf_control = Control;
     stream_FilterSetDefaultReadDir( s );
 
@@ -135,6 +137,11 @@ static ssize_t Read( stream_t *s, void *p_read, size_t i_read )
     return i_record;
 }
 
+static int Seek( stream_t *s, uint64_t offset )
+{
+    return stream_Seek( s->p_source, offset );
+}
+
 static int Control( stream_t *s, int i_query, va_list args )
 {
     if( i_query != STREAM_SET_RECORD_STATE )
index e3c808e..86efe1d 100644 (file)
@@ -60,6 +60,7 @@ vlc_module_begin()
 vlc_module_end()
 
 static ssize_t Read( stream_t *, void *, size_t );
+static int chunk_Seek( stream_t *, uint64_t );
 static int   Control( stream_t *, int , va_list );
 
 static bool isSmoothStreaming( stream_t *s )
@@ -535,6 +536,7 @@ static int Open( vlc_object_t *p_this )
 
     /* */
     s->pf_read = Read;
+    s->pf_seek = chunk_Seek;
     s->pf_control = Control;
 
     if( vlc_clone( &p_sys->download.thread, sms_Thread, s, VLC_THREAD_PRIORITY_INPUT ) )
@@ -779,7 +781,7 @@ static ssize_t Read( stream_t *s, void *buffer, size_t i_read )
 
 /* Normaly a stream_filter is not able to provide *time* seeking, since a
  * stream_filter operates on a byte stream. Thus, in order to circumvent this
- * limitation, I treat a STREAM_SET_POSITION request which value "pos" is less
+ * limitation, I treat a seek request which value "pos" is less
  * than FAKE_STREAM_SIZE as a *time* seek request, and more precisely a request
  * to jump at time position: pos / FAKE_STREAM_SIZE * total_video_duration.
  * For exemple, it pos == 500, it would be interpreted as a request to jump at
@@ -790,7 +792,7 @@ static ssize_t Read( stream_t *s, void *buffer, size_t i_read )
  * Of course this a bit hack-ish, but if Smooth Streaming doesn't die, its
  * implementation will be moved to a access_demux module, and this hack won't
  * be needed anymore (among others). */
-static int chunk_Seek( stream_t *s, const uint64_t pos )
+static int chunk_Seek( stream_t *s, uint64_t pos )
 {
     stream_sys_t *p_sys = s->p_sys;
 
@@ -874,15 +876,6 @@ static int Control( stream_t *s, int i_query, va_list args )
         case STREAM_CAN_CONTROL_PACE:
             *(va_arg( args, bool * )) = true;
             break;
-        case STREAM_SET_POSITION:
-            {
-                uint64_t pos = (uint64_t)va_arg(args, uint64_t);
-                int ret = chunk_Seek(s, pos);
-                if( ret == VLC_SUCCESS )
-                    break;
-                else
-                    return VLC_EGENERIC;
-            }
         case STREAM_GET_SIZE:
             *(va_arg( args, uint64_t * )) = FAKE_STREAM_SIZE;
             break;
index 8d4de79..fdfb808 100644 (file)
@@ -248,6 +248,19 @@ static input_item_t *AStreamReadDir(stream_t *s)
 }
 
 /* Common */
+static int AStreamSeek(stream_t *s, uint64_t offset)
+{
+    stream_sys_t *sys = s->p_sys;
+
+    if (sys->block != NULL)
+    {
+        block_Release(sys->block);
+        sys->block = NULL;
+    }
+
+    return vlc_access_Seek(sys->access, offset);
+}
+
 #define static_control_match(foo) \
     static_assert((unsigned) STREAM_##foo == ACCESS_##foo, "Mismatch")
 
@@ -311,18 +324,6 @@ static int AStreamControl(stream_t *s, int cmd, va_list args)
             break;
         }
 
-        case STREAM_SET_POSITION:
-        {
-            uint64_t pos = va_arg(args, uint64_t);
-
-            if (sys->block != NULL)
-            {
-                block_Release(sys->block);
-                sys->block = NULL;
-            }
-            return vlc_access_Seek(sys->access, pos);
-        }
-
         case STREAM_GET_PRIVATE_BLOCK:
         {
             block_t **b = va_arg(args, block_t **);
@@ -396,6 +397,7 @@ stream_t *stream_AccessNew(vlc_object_t *parent, input_thread_t *input,
     else
         s->pf_readdir = AStreamNoReadDir;
 
+    s->pf_seek    = AStreamSeek;
     s->pf_control = AStreamControl;
     s->pf_destroy = AStreamDestroy;
     s->p_sys      = sys;
index a260fbe..c098a88 100644 (file)
@@ -471,7 +471,10 @@ int stream_vaControl(stream_t *s, int cmd, va_list args)
         {
             uint64_t pos = va_arg(args, uint64_t);
 
-            int ret = stream_ControlInternal(s, STREAM_SET_POSITION, pos);
+            if (s->pf_seek == NULL)
+                return VLC_EGENERIC;
+
+            int ret = s->pf_seek(s, pos);
             if (ret != VLC_SUCCESS)
                 return ret;
 
index f738dce..a571b9f 100644 (file)
@@ -73,6 +73,7 @@ stream_t *stream_DemuxNew( demux_t *p_demux, const char *psz_demux, es_out_t *ou
         return NULL;
     s->p_input = p_demux->p_input;
     s->pf_read   = DStreamRead;
+    s->pf_seek   = NULL;
     s->pf_control= DStreamControl;
     s->pf_destroy= DStreamDelete;
 
@@ -223,7 +224,6 @@ static int DStreamControl( stream_t *s, int i_query, va_list args )
             *va_arg( args, int64_t * ) = DEFAULT_PTS_DELAY;
             return VLC_SUCCESS;
 
-        case STREAM_SET_POSITION:
         case STREAM_GET_TITLE_INFO:
         case STREAM_GET_TITLE:
         case STREAM_GET_SEEKPOINT:
index 6955600..f0814db 100644 (file)
 struct stream_sys_t
 {
     bool  i_preserve_memory;
-    uint64_t    i_pos;      /* Current reading offset */
-    uint64_t    i_size;
-    uint8_t    *p_buffer;
+    size_t    i_pos;      /* Current reading offset */
+    size_t    i_size;
+    uint8_t  *p_buffer;
 
 };
 
 static ssize_t Read( stream_t *, void *p_read, size_t i_read );
+static int Seek( stream_t *, uint64_t );
 static int  Control( stream_t *, int i_query, va_list );
 static void Delete ( stream_t * );
 
@@ -71,6 +72,7 @@ stream_t *stream_MemoryNew( vlc_object_t *p_this, uint8_t *p_buffer,
     p_sys->i_preserve_memory = i_preserve_memory;
 
     s->pf_read    = Read;
+    s->pf_seek    = Seek;
     s->pf_control = Control;
     s->pf_destroy = Delete;
     s->p_input = NULL;
@@ -91,7 +93,7 @@ static int Control( stream_t *s, int i_query, va_list args )
 {
     stream_sys_t *p_sys = s->p_sys;
 
-    uint64_t   *pi_64, i_64;
+    uint64_t   *pi_64;
 
     switch( i_query )
     {
@@ -107,12 +109,6 @@ static int Control( stream_t *s, int i_query, va_list args )
             *va_arg( args, bool * ) = true;
             break;
 
-        case STREAM_SET_POSITION:
-            i_64 = va_arg( args, uint64_t );
-            i_64 = __MIN( i_64, s->p_sys->i_size );
-            p_sys->i_pos = i_64;
-            break;
-
         case STREAM_GET_PTS_DELAY:
             *va_arg( args, int64_t * ) = 0;
             break;
@@ -155,3 +151,14 @@ static ssize_t Read( stream_t *s, void *p_read, size_t i_read )
     p_sys->i_pos += i_read;
     return i_read;
 }
+
+static int Seek( stream_t *s, uint64_t offset )
+{
+    stream_sys_t *p_sys = s->p_sys;
+
+    if( offset > p_sys->i_size )
+        offset = p_sys->i_size;
+
+    p_sys->i_pos = offset;
+    return VLC_SUCCESS;
+}