Commit b1082a5c authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

stream: replace STREAM_SET_POSITION control with dedicated pf_seek

Also:
 - zip: fix seeking to end of file
 - accesstweaks: fix segmentation fault when (inhibiting) seeking
 - decomp: set callbacks only on successful init
parent a1059708
......@@ -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 );
/* */
......
......@@ -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;
......
......@@ -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));
......
......@@ -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* );
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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 ) )
......
......@@ -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);
......
......@@ -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 )
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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:
......
......@@ -30,13 +30,14 @@
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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment