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

access: keep read offset in private data

parent 11138293
...@@ -58,6 +58,12 @@ static ssize_t Read(access_t *, uint8_t *, size_t); ...@@ -58,6 +58,12 @@ static ssize_t Read(access_t *, uint8_t *, size_t);
static int Seek(access_t *, uint64_t); static int Seek(access_t *, uint64_t);
static int Control(access_t *, int, va_list); static int Control(access_t *, int, va_list);
struct access_sys_t
{
input_attachment_t *attachment;
size_t offset;
};
/* */ /* */
static int Open(vlc_object_t *object) static int Open(vlc_object_t *object)
{ {
...@@ -67,23 +73,30 @@ static int Open(vlc_object_t *object) ...@@ -67,23 +73,30 @@ static int Open(vlc_object_t *object)
if (!input) if (!input)
return VLC_EGENERIC; return VLC_EGENERIC;
input_attachment_t *a; access_sys_t *sys = malloc(sizeof (*sys));
if (input_Control(input, INPUT_GET_ATTACHMENT, &a, access->psz_location)) if (unlikely(sys == NULL))
a = NULL; return VLC_ENOMEM;
if (input_Control(input, INPUT_GET_ATTACHMENT, &sys->attachment,
access->psz_location))
sys->attachment = NULL;
if (!a) { if (sys->attachment == NULL) {
msg_Err(access, "Failed to find the attachment '%s'", msg_Err(access, "Failed to find the attachment '%s'",
access->psz_location); access->psz_location);
free(sys);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
sys->offset = 0;
/* */ /* */
access_InitFields(access); access_InitFields(access);
access->pf_read = Read; access->pf_read = Read;
access->pf_block = NULL; access->pf_block = NULL;
access->pf_control = Control; access->pf_control = Control;
access->pf_seek = Seek; access->pf_seek = Seek;
access->p_sys = (void *)a; access->p_sys = sys;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -91,30 +104,38 @@ static int Open(vlc_object_t *object) ...@@ -91,30 +104,38 @@ static int Open(vlc_object_t *object)
static void Close(vlc_object_t *object) static void Close(vlc_object_t *object)
{ {
access_t *access = (access_t *)object; access_t *access = (access_t *)object;
input_attachment_t *a = (void *)access->p_sys; access_sys_t *sys = access->p_sys;
vlc_input_attachment_Delete(a); vlc_input_attachment_Delete(sys->attachment);
free(sys);
} }
/* */ /* */
static ssize_t Read(access_t *access, uint8_t *buffer, size_t size) static ssize_t Read(access_t *access, uint8_t *buffer, size_t size)
{ {
input_attachment_t *a = (void *)access->p_sys; access_sys_t *sys = access->p_sys;
input_attachment_t *a = sys->attachment;
access->info.b_eof = access->info.i_pos >= (uint64_t)a->i_data; access->info.b_eof = sys->offset >= (uint64_t)a->i_data;
if (access->info.b_eof) if (access->info.b_eof)
return 0; return 0;
const size_t copy = __MIN(size, a->i_data - access->info.i_pos); const size_t copy = __MIN(size, a->i_data - sys->offset);
memcpy(buffer, (uint8_t *)a->p_data + access->info.i_pos, copy); memcpy(buffer, (uint8_t *)a->p_data + sys->offset, copy);
access->info.i_pos += copy; sys->offset += copy;
return copy; return copy;
} }
/* */ /* */
static int Seek(access_t *access, uint64_t position) static int Seek(access_t *access, uint64_t position)
{ {
access->info.i_pos = position; access_sys_t *sys = access->p_sys;
input_attachment_t *a = sys->attachment;
if (position > a->i_data)
position = a->i_data;
sys->offset = position;
access->info.b_eof = false; access->info.b_eof = false;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -122,7 +143,7 @@ static int Seek(access_t *access, uint64_t position) ...@@ -122,7 +143,7 @@ static int Seek(access_t *access, uint64_t position)
/* */ /* */
static int Control(access_t *access, int query, va_list args) static int Control(access_t *access, int query, va_list args)
{ {
input_attachment_t *a = (void *)access->p_sys; access_sys_t *sys = access->p_sys;
switch (query) switch (query)
{ {
...@@ -133,7 +154,7 @@ static int Control(access_t *access, int query, va_list args) ...@@ -133,7 +154,7 @@ static int Control(access_t *access, int query, va_list args)
*va_arg(args, bool *) = true; *va_arg(args, bool *) = true;
break; break;
case ACCESS_GET_SIZE: case ACCESS_GET_SIZE:
*va_arg(args, uint64_t *) = a->i_data; *va_arg(args, uint64_t *) = sys->attachment->i_data;
break; break;
case ACCESS_GET_PTS_DELAY: case ACCESS_GET_PTS_DELAY:
*va_arg(args, int64_t *) = DEFAULT_PTS_DELAY; *va_arg(args, int64_t *) = DEFAULT_PTS_DELAY;
......
...@@ -143,6 +143,7 @@ struct access_sys_t ...@@ -143,6 +143,7 @@ struct access_sys_t
char sz_epsv_ip[NI_MAXNUMERICHOST]; char sz_epsv_ip[NI_MAXNUMERICHOST];
bool out; bool out;
uint64_t offset;
uint64_t size; uint64_t size;
}; };
#define GET_OUT_SYS( p_this ) \ #define GET_OUT_SYS( p_this ) \
...@@ -632,6 +633,7 @@ static int InOpen( vlc_object_t *p_this ) ...@@ -632,6 +633,7 @@ static int InOpen( vlc_object_t *p_this )
return VLC_ENOMEM; return VLC_ENOMEM;
p_sys->data.fd = -1; p_sys->data.fd = -1;
p_sys->out = false; p_sys->out = false;
p_sys->offset = 0;
p_sys->size = UINT64_MAX; p_sys->size = UINT64_MAX;
readTLSMode( p_sys, p_access->psz_access ); readTLSMode( p_sys, p_access->psz_access );
...@@ -797,12 +799,14 @@ static int _Seek( vlc_object_t *p_access, access_sys_t *p_sys, uint64_t i_pos ) ...@@ -797,12 +799,14 @@ static int _Seek( vlc_object_t *p_access, access_sys_t *p_sys, uint64_t i_pos )
static int Seek( access_t *p_access, uint64_t i_pos ) static int Seek( access_t *p_access, uint64_t i_pos )
{ {
int val = _Seek( (vlc_object_t *)p_access, p_access->p_sys, i_pos ); access_sys_t *p_sys = p_access->p_sys;
int val = _Seek( (vlc_object_t *)p_access, p_sys, i_pos );
if( val ) if( val )
return val; return val;
p_access->info.b_eof = false; p_access->info.b_eof = false;
p_access->info.i_pos = i_pos; p_sys->offset = i_pos;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -833,10 +837,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -833,10 +837,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
else else
i_read = vlc_recv_i11e( p_sys->data.fd, p_buffer, i_len, 0 ); i_read = vlc_recv_i11e( p_sys->data.fd, p_buffer, i_len, 0 );
if( i_read == 0 ) if( i_read > 0 )
p_sys->offset += i_read;
else if( i_read == 0 )
p_access->info.b_eof = true; p_access->info.b_eof = true;
else if( i_read > 0 )
p_access->info.i_pos += i_read;
else if( errno != EINTR && errno != EAGAIN ) else if( errno != EINTR && errno != EAGAIN )
{ {
msg_Err( p_access, "receive error: %s", vlc_strerror_c(errno) ); msg_Err( p_access, "receive error: %s", vlc_strerror_c(errno) );
...@@ -954,7 +958,7 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -954,7 +958,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
case ACCESS_SET_PAUSE_STATE: case ACCESS_SET_PAUSE_STATE:
pb_bool = (bool*)va_arg( args, bool* ); pb_bool = (bool*)va_arg( args, bool* );
if ( !pb_bool ) if ( !pb_bool )
return Seek( p_access, p_access->info.i_pos ); return Seek( p_access, p_access->p_sys->offset );
break; break;
default: default:
......
...@@ -174,6 +174,7 @@ struct access_sys_t ...@@ -174,6 +174,7 @@ struct access_sys_t
char *psz_icy_title; char *psz_icy_title;
uint64_t i_remaining; uint64_t i_remaining;
uint64_t offset;
uint64_t size; uint64_t size;
/* cookie jar borrowed from playlist, do not free */ /* cookie jar borrowed from playlist, do not free */
...@@ -270,8 +271,8 @@ static int OpenRedirected( vlc_object_t *p_this, const char *psz_access, ...@@ -270,8 +271,8 @@ static int OpenRedirected( vlc_object_t *p_this, const char *psz_access,
p_sys->i_remaining = 0; p_sys->i_remaining = 0;
p_sys->b_persist = false; p_sys->b_persist = false;
p_sys->b_has_size = false; p_sys->b_has_size = false;
p_sys->offset = 0;
p_sys->size = 0; p_sys->size = 0;
p_access->info.i_pos = 0;
p_access->info.b_eof = false; p_access->info.b_eof = false;
/* Only forward an store cookies if the corresponding option is activated */ /* Only forward an store cookies if the corresponding option is activated */
...@@ -658,7 +659,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -658,7 +659,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if( p_sys->b_has_size ) if( p_sys->b_has_size )
{ {
/* Remaining bytes in the file */ /* Remaining bytes in the file */
uint64_t remainder = p_sys->size - p_access->info.i_pos; uint64_t remainder = p_sys->size - p_sys->offset;
if( remainder < i_len ) if( remainder < i_len )
i_len = remainder; i_len = remainder;
...@@ -669,10 +670,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -669,10 +670,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if( i_len == 0 ) if( i_len == 0 )
goto fatal; goto fatal;
if( p_sys->i_icy_meta > 0 && p_access->info.i_pos - p_sys->i_icy_offset > 0 ) if( p_sys->i_icy_meta > 0 && p_sys->offset - p_sys->i_icy_offset > 0 )
{ {
int64_t i_next = p_sys->i_icy_meta - int64_t i_next = p_sys->i_icy_meta -
(p_access->info.i_pos - p_sys->i_icy_offset ) % p_sys->i_icy_meta; (p_sys->offset - p_sys->i_icy_offset ) % p_sys->i_icy_meta;
if( i_next == p_sys->i_icy_meta ) if( i_next == p_sys->i_icy_meta )
{ {
...@@ -705,7 +706,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -705,7 +706,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if( p_sys->b_reconnect ) if( p_sys->b_reconnect )
{ {
msg_Dbg( p_access, "got disconnected, trying to reconnect" ); msg_Dbg( p_access, "got disconnected, trying to reconnect" );
if( Connect( p_access, p_access->info.i_pos ) ) if( Connect( p_access, p_sys->offset ) )
{ {
msg_Dbg( p_access, "reconnection failed" ); msg_Dbg( p_access, "reconnection failed" );
} }
...@@ -728,10 +729,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -728,10 +729,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
} }
assert( i_read >= 0 ); assert( i_read >= 0 );
p_access->info.i_pos += i_read; p_sys->offset += i_read;
if( p_sys->b_has_size ) if( p_sys->b_has_size )
{ {
assert( p_access->info.i_pos <= p_sys->size ); assert( p_sys->offset <= p_sys->size );
assert( (unsigned)i_read <= p_sys->i_remaining ); assert( (unsigned)i_read <= p_sys->i_remaining );
p_sys->i_remaining -= i_read; p_sys->i_remaining -= i_read;
} }
...@@ -1015,8 +1016,8 @@ static int Connect( access_t *p_access, uint64_t i_tell ) ...@@ -1015,8 +1016,8 @@ static int Connect( access_t *p_access, uint64_t i_tell )
p_sys->i_remaining = 0; p_sys->i_remaining = 0;
p_sys->b_persist = false; p_sys->b_persist = false;
p_sys->b_has_size = false; p_sys->b_has_size = false;
p_sys->offset = i_tell;
p_sys->size = 0; p_sys->size = 0;
p_access->info.i_pos = i_tell;
p_access->info.b_eof = false; p_access->info.b_eof = false;
/* Open connection */ /* Open connection */
...@@ -1296,7 +1297,7 @@ static int Request( access_t *p_access, uint64_t i_tell ) ...@@ -1296,7 +1297,7 @@ static int Request( access_t *p_access, uint64_t i_tell )
uint64_t i_nsize = p_sys->size; uint64_t i_nsize = p_sys->size;
sscanf(p,"bytes %"SCNu64"-%"SCNu64"/%"SCNu64,&i_ntell,&i_nend,&i_nsize); sscanf(p,"bytes %"SCNu64"-%"SCNu64"/%"SCNu64,&i_ntell,&i_nend,&i_nsize);
if(i_nend > i_ntell ) { if(i_nend > i_ntell ) {
p_access->info.i_pos = i_ntell; p_sys->offset = i_ntell;
p_sys->i_icy_offset = i_ntell; p_sys->i_icy_offset = i_ntell;
p_sys->i_remaining = i_nend+1-i_ntell; p_sys->i_remaining = i_nend+1-i_ntell;
uint64_t i_size = (i_nsize > i_nend) ? i_nsize : (i_nend + 1); uint64_t i_size = (i_nsize > i_nend) ? i_nsize : (i_nend + 1);
......
...@@ -84,6 +84,7 @@ int MMSHOpen( access_t *p_access ) ...@@ -84,6 +84,7 @@ int MMSHOpen( access_t *p_access )
p_sys->i_proto= MMS_PROTO_HTTP; p_sys->i_proto= MMS_PROTO_HTTP;
p_sys->fd = -1; p_sys->fd = -1;
p_sys->i_position = 0;
/* Handle proxy */ /* Handle proxy */
p_sys->b_proxy = false; p_sys->b_proxy = false;
...@@ -296,7 +297,7 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -296,7 +297,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
p_sys->asfh.stream[i_int].i_selected = true; p_sys->asfh.stream[i_int].i_selected = true;
Stop( p_access ); Stop( p_access );
Seek( p_access, p_access->info.i_pos ); Seek( p_access, p_sys->i_position );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -305,7 +306,7 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -305,7 +306,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
if( b_bool ) if( b_bool )
Stop( p_access ); Stop( p_access );
else else
Seek( p_access, p_access->info.i_pos ); Seek( p_access, p_sys->i_position );
break; break;
default: default:
...@@ -344,7 +345,7 @@ static int Seek( access_t *p_access, uint64_t i_pos ) ...@@ -344,7 +345,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
msg_Warn( p_access, "skipping header" ); msg_Warn( p_access, "skipping header" );
} }
p_access->info.i_pos = i_pos; p_sys->i_position = i_pos;
p_access->info.b_eof = false; p_access->info.b_eof = false;
p_sys->i_packet_used += i_offset; p_sys->i_packet_used += i_offset;
...@@ -368,9 +369,9 @@ static block_t *Block( access_t *p_access ) ...@@ -368,9 +369,9 @@ static block_t *Block( access_t *p_access )
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
const unsigned i_packet_min = p_sys->asfh.i_min_data_packet_size; const unsigned i_packet_min = p_sys->asfh.i_min_data_packet_size;
if( p_access->info.i_pos < p_sys->i_start + p_sys->i_header ) if( p_sys->i_position < p_sys->i_start + p_sys->i_header )
{ {
const size_t i_offset = p_access->info.i_pos - p_sys->i_start; const size_t i_offset = p_sys->i_position - p_sys->i_start;
const size_t i_copy = p_sys->i_header - i_offset; const size_t i_copy = p_sys->i_header - i_offset;
block_t *p_block = block_Alloc( i_copy ); block_t *p_block = block_Alloc( i_copy );
...@@ -378,7 +379,7 @@ static block_t *Block( access_t *p_access ) ...@@ -378,7 +379,7 @@ static block_t *Block( access_t *p_access )
return NULL; return NULL;
memcpy( p_block->p_buffer, &p_sys->p_header[i_offset], i_copy ); memcpy( p_block->p_buffer, &p_sys->p_header[i_offset], i_copy );
p_access->info.i_pos += i_copy; p_sys->i_position += i_copy;
return p_block; return p_block;
} }
else if( p_sys->i_packet_length > 0 && else if( p_sys->i_packet_length > 0 &&
...@@ -402,7 +403,7 @@ static block_t *Block( access_t *p_access ) ...@@ -402,7 +403,7 @@ static block_t *Block( access_t *p_access )
memset( &p_block->p_buffer[i_copy], 0, i_padding ); memset( &p_block->p_buffer[i_copy], 0, i_padding );
p_sys->i_packet_used += i_copy + i_padding; p_sys->i_packet_used += i_copy + i_padding;
p_access->info.i_pos += i_copy + i_padding; p_sys->i_position += i_copy + i_padding;
return p_block; return p_block;
} }
...@@ -440,7 +441,7 @@ static int Restart( access_t *p_access ) ...@@ -440,7 +441,7 @@ static int Restart( access_t *p_access )
char *psz_location = NULL; char *psz_location = NULL;
msg_Dbg( p_access, "Restart the stream" ); msg_Dbg( p_access, "Restart the stream" );
p_sys->i_start = p_access->info.i_pos; p_sys->i_start = p_sys->i_position;
/* */ /* */
msg_Dbg( p_access, "stoping the stream" ); msg_Dbg( p_access, "stoping the stream" );
...@@ -470,7 +471,7 @@ static int Reset( access_t *p_access ) ...@@ -470,7 +471,7 @@ static int Reset( access_t *p_access )
int i; int i;
msg_Dbg( p_access, "Reset the stream" ); msg_Dbg( p_access, "Reset the stream" );
p_sys->i_start = p_access->info.i_pos; p_sys->i_start = p_sys->i_position;
/* */ /* */
p_sys->i_packet_sequence = 0; p_sys->i_packet_sequence = 0;
......
...@@ -65,6 +65,7 @@ struct access_sys_t ...@@ -65,6 +65,7 @@ struct access_sys_t
unsigned int i_packet_length; unsigned int i_packet_length;
uint64_t i_start; uint64_t i_start;
uint64_t i_position;
asf_header_t asfh; asf_header_t asfh;
guid_t guid; guid_t guid;
......
...@@ -277,7 +277,7 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -277,7 +277,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
else else
{ {
KeepAliveStop( p_access ); KeepAliveStop( p_access );
Seek( p_access, p_access->info.i_pos ); Seek( p_access, p_sys->i_position );
} }
break; break;
...@@ -299,11 +299,11 @@ static int Seek( access_t * p_access, uint64_t i_pos ) ...@@ -299,11 +299,11 @@ static int Seek( access_t * p_access, uint64_t i_pos )
if( i_pos < p_sys->i_header) if( i_pos < p_sys->i_header)
{ {
if( p_access->info.i_pos < p_sys->i_header ) if( p_sys->i_position < p_sys->i_header )
{ {
/* no need to restart stream, it was already one /* no need to restart stream, it was already one
* or no stream was yet read */ * or no stream was yet read */
p_access->info.i_pos = i_pos; p_sys->i_position = i_pos;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
else else
...@@ -381,7 +381,7 @@ static int Seek( access_t * p_access, uint64_t i_pos ) ...@@ -381,7 +381,7 @@ static int Seek( access_t * p_access, uint64_t i_pos )
msg_Dbg( p_access, "Streaming restarted" ); msg_Dbg( p_access, "Streaming restarted" );
p_sys->i_media_used += i_offset; p_sys->i_media_used += i_offset;
p_access->info.i_pos = i_pos; p_sys->i_position = i_pos;
p_access->info.b_eof = false; p_access->info.b_eof = false;
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -397,16 +397,16 @@ static block_t *Block( access_t *p_access ) ...@@ -397,16 +397,16 @@ static block_t *Block( access_t *p_access )
if( p_access->info.b_eof ) if( p_access->info.b_eof )
return NULL; return NULL;
if( p_access->info.i_pos < p_sys->i_header ) if( p_sys->i_position < p_sys->i_header )
{ {
const size_t i_copy = p_sys->i_header - p_access->info.i_pos; const size_t i_copy = p_sys->i_header - p_sys->i_position;
block_t *p_block = block_Alloc( i_copy ); block_t *p_block = block_Alloc( i_copy );
if( !p_block ) if( !p_block )
return NULL; return NULL;
memcpy( p_block->p_buffer, &p_sys->p_header[p_access->info.i_pos], i_copy ); memcpy( p_block->p_buffer, &p_sys->p_header[p_sys->i_position], i_copy );
p_access->info.i_pos += i_copy; p_sys->i_position += i_copy;
return p_block; return p_block;
} }
else if( p_sys->p_media && p_sys->i_media_used < __MAX( p_sys->i_media, p_sys->i_packet_length ) ) else if( p_sys->p_media && p_sys->i_media_used < __MAX( p_sys->i_media, p_sys->i_packet_length ) )
...@@ -429,7 +429,7 @@ static block_t *Block( access_t *p_access ) ...@@ -429,7 +429,7 @@ static block_t *Block( access_t *p_access )
memset( &p_block->p_buffer[i_copy], 0, i_padding ); memset( &p_block->p_buffer[i_copy], 0, i_padding );
p_sys->i_media_used += i_copy + i_padding; p_sys->i_media_used += i_copy + i_padding;
p_access->info.i_pos += i_copy + i_padding; p_sys->i_position += i_copy + i_padding;
return p_block; return p_block;
} }
...@@ -511,7 +511,7 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto ) ...@@ -511,7 +511,7 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto )
p_sys->i_media = 0; p_sys->i_media = 0;
p_sys->i_media_used = 0; p_sys->i_media_used = 0;
p_access->info.i_pos = 0; p_sys->i_position = 0;
p_sys->i_buffer_tcp = 0; p_sys->i_buffer_tcp = 0;
p_sys->i_buffer_udp = 0; p_sys->i_buffer_udp = 0;
p_sys->p_cmd = NULL; p_sys->p_cmd = NULL;
......
...@@ -43,6 +43,7 @@ struct access_sys_t ...@@ -43,6 +43,7 @@ struct access_sys_t
char sz_bind_addr[NI_MAXNUMERICHOST]; /* used by udp */ char sz_bind_addr[NI_MAXNUMERICHOST]; /* used by udp */
vlc_url_t url; vlc_url_t url;
uint64_t i_position;
uint64_t i_size; uint64_t i_size;
asf_header_t asfh; asf_header_t asfh;
......
...@@ -40,6 +40,7 @@ struct access_sys_t { ...@@ -40,6 +40,7 @@ struct access_sys_t {
stream_t *s; stream_t *s;
rar_file_t *file; rar_file_t *file;
const rar_file_chunk_t *chunk; const rar_file_chunk_t *chunk;
uint64_t position;
}; };
static int Seek(access_t *access, uint64_t position) static int Seek(access_t *access, uint64_t position)
...@@ -49,6 +50,7 @@ static int Seek(access_t *access, uint64_t position) ...@@ -49,6 +50,7 @@ static int Seek(access_t *access, uint64_t position)
if (position > file->real_size) if (position > file->real_size)
position = file->real_size; position = file->real_size;
sys->position = position;
/* Search the chunk */ /* Search the chunk */
const rar_file_chunk_t *old_chunk = sys->chunk; const rar_file_chunk_t *old_chunk = sys->chunk;
...@@ -57,7 +59,6 @@ static int Seek(access_t *access, uint64_t position) ...@@ -57,7 +59,6 @@ static int Seek(access_t *access, uint64_t position)
if (position < sys->chunk->cummulated_size + sys->chunk->size) if (position < sys->chunk->cummulated_size + sys->chunk->size)
break; break;
} }
access->info.i_pos = position;
access->info.b_eof = false; access->info.b_eof = false;
const uint64_t offset = sys->chunk->offset + const uint64_t offset = sys->chunk->offset +
...@@ -78,7 +79,7 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size) ...@@ -78,7 +79,7 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size)
size_t total = 0; size_t total = 0;
while (total < size) { while (total < size) {
const uint64_t chunk_end = sys->chunk->cummulated_size + sys->chunk->size; const uint64_t chunk_end = sys->chunk->cummulated_size + sys->chunk->size;
int max = __MIN(__MIN((int64_t)(size - total), (int64_t)(chunk_end - access->info.i_pos)), INT_MAX); int max = __MIN(__MIN((int64_t)(size - total), (int64_t)(chunk_end - sys->position)), INT_MAX);
if (max <= 0) if (max <= 0)
break; break;
...@@ -89,9 +90,9 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size) ...@@ -89,9 +90,9 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size)
total += r; total += r;
if( data ) if( data )
data += r; data += r;
access->info.i_pos += r; sys->position += r;
if (access->info.i_pos >= chunk_end && if (sys->position >= chunk_end &&
Seek(access, access->info.i_pos)) Seek(access, sys->position))
break; break;
} }
if (size > 0 && total <= 0) if (size > 0 && total <= 0)
......
...@@ -66,6 +66,7 @@ vlc_module_end () ...@@ -66,6 +66,7 @@ vlc_module_end ()
struct access_sys_t struct access_sys_t
{ {
vcddev_t *vcddev; /* vcd device descriptor */ vcddev_t *vcddev; /* vcd device descriptor */
uint64_t offset;
/* Title infos */ /* Title infos */
int i_titles; int i_titles;
...@@ -141,6 +142,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -141,6 +142,7 @@ static int Open( vlc_object_t *p_this )
if( unlikely(!p_sys )) if( unlikely(!p_sys ))
goto error; goto error;
p_sys->vcddev = vcddev; p_sys->vcddev = vcddev;
p_sys->offset = 0;
/* We read the Table Of Content information */ /* We read the Table Of Content information */
p_sys->i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access), p_sys->i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
...@@ -200,7 +202,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -200,7 +202,7 @@ static int Open( vlc_object_t *p_this )
p_sys->i_current_title = i_title; p_sys->i_current_title = i_title;
p_sys->i_current_seekpoint = i_chapter; p_sys->i_current_seekpoint = i_chapter;
p_access->info.i_pos = (uint64_t)( p_sys->i_sector - p_sys->p_sectors[1+i_title] ) * p_sys->offset = (uint64_t)(p_sys->i_sector - p_sys->p_sectors[1+i_title]) *
VCD_DATA_SIZE; VCD_DATA_SIZE;
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -284,9 +286,9 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -284,9 +286,9 @@ static int Control( access_t *p_access, int i_query, va_list args )
if( i != p_sys->i_current_title ) if( i != p_sys->i_current_title )
{ {
/* Update info */ /* Update info */
p_sys->offset = 0;
p_sys->i_current_title = i; p_sys->i_current_title = i;
p_sys->i_current_seekpoint = 0; p_sys->i_current_seekpoint = 0;
p_access->info.i_pos = 0;
/* Next sector to read */ /* Next sector to read */
p_sys->i_sector = p_sys->p_sectors[1+i]; p_sys->i_sector = p_sys->p_sectors[1+i];
...@@ -307,8 +309,8 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -307,8 +309,8 @@ static int Control( access_t *p_access, int i_query, va_list args )
p_sys->i_sector = p_sys->p_sectors[1 + i_title] + p_sys->i_sector = p_sys->p_sectors[1 + i_title] +
t->seekpoint[i]->i_byte_offset / VCD_DATA_SIZE; t->seekpoint[i]->i_byte_offset / VCD_DATA_SIZE;
p_access->info.i_pos = (uint64_t)(p_sys->i_sector - p_sys->offset = (uint64_t)(p_sys->i_sector -
p_sys->p_sectors[1 + i_title]) *VCD_DATA_SIZE; p_sys->p_sectors[1 + i_title]) * VCD_DATA_SIZE;
} }
break; break;
} }
...@@ -342,7 +344,7 @@ static block_t *Block( access_t *p_access ) ...@@ -342,7 +344,7 @@ static block_t *Block( access_t *p_access )
p_sys->i_current_title++; p_sys->i_current_title++;
p_sys->i_current_seekpoint = 0; p_sys->i_current_seekpoint = 0;
p_access->info.i_pos = 0; p_sys->offset = 0;
} }
/* Don't read after the end of a title */ /* Don't read after the end of a title */
...@@ -367,8 +369,8 @@ static block_t *Block( access_t *p_access ) ...@@ -367,8 +369,8 @@ static block_t *Block( access_t *p_access )
block_Release( p_block ); block_Release( p_block );
/* Try to skip one sector (in case of bad sectors) */ /* Try to skip one sector (in case of bad sectors) */
p_sys->offset += VCD_DATA_SIZE;
p_sys->i_sector++; p_sys->i_sector++;
p_access->info.i_pos += VCD_DATA_SIZE;
return NULL; return NULL;
} }
...@@ -380,7 +382,7 @@ static block_t *Block( access_t *p_access ) ...@@ -380,7 +382,7 @@ static block_t *Block( access_t *p_access )
if( t->i_seekpoint > 0 && if( t->i_seekpoint > 0 &&
p_sys->i_current_seekpoint + 1 < t->i_seekpoint && p_sys->i_current_seekpoint + 1 < t->i_seekpoint &&
(int64_t) /* Unlikely to go over 8192 PetaB */ (int64_t) /* Unlikely to go over 8192 PetaB */
(p_access->info.i_pos + i_read * VCD_DATA_SIZE) >= (p_sys->offset + i_read * VCD_DATA_SIZE) >=
t->seekpoint[p_sys->i_current_seekpoint + 1]->i_byte_offset ) t->seekpoint[p_sys->i_current_seekpoint + 1]->i_byte_offset )
{ {
msg_Dbg( p_access, "seekpoint change" ); msg_Dbg( p_access, "seekpoint change" );
...@@ -389,8 +391,8 @@ static block_t *Block( access_t *p_access ) ...@@ -389,8 +391,8 @@ static block_t *Block( access_t *p_access )
} }
/* Update a few values */ /* Update a few values */
p_sys->offset += p_block->i_buffer;
p_sys->i_sector += i_blocks; p_sys->i_sector += i_blocks;
p_access->info.i_pos += p_block->i_buffer;
return p_block; return p_block;
} }
...@@ -405,7 +407,7 @@ static int Seek( access_t *p_access, uint64_t i_pos ) ...@@ -405,7 +407,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
int i_seekpoint; int i_seekpoint;
/* Next sector to read */ /* Next sector to read */
p_access->info.i_pos = i_pos; p_sys->offset = i_pos;
p_sys->i_sector = i_pos / VCD_DATA_SIZE + p_sys->i_sector = i_pos / VCD_DATA_SIZE +
p_sys->p_sectors[p_sys->i_current_title + 1]; p_sys->p_sectors[p_sys->i_current_title + 1];
......
...@@ -110,6 +110,7 @@ struct access_sys_t ...@@ -110,6 +110,7 @@ struct access_sys_t
{ {
/* file sizes of all parts */ /* file sizes of all parts */
size_array_t file_sizes; size_array_t file_sizes;
uint64_t offset;
uint64_t size; /* total size */ uint64_t size; /* total size */
/* index and fd of current open file */ /* index and fd of current open file */
...@@ -351,7 +352,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -351,7 +352,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if( i_ret > 0 ) if( i_ret > 0 )
{ {
/* success */ /* success */
p_access->info.i_pos += i_ret; p_sys->offset += i_ret;
UpdateFileSize( p_access ); UpdateFileSize( p_access );
FindSeekpoint( p_access ); FindSeekpoint( p_access );
return i_ret; return i_ret;
...@@ -392,7 +393,7 @@ static int Seek( access_t *p_access, uint64_t i_pos ) ...@@ -392,7 +393,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
/* might happen if called by ACCESS_SET_SEEKPOINT */ /* might happen if called by ACCESS_SET_SEEKPOINT */
i_pos = __MIN( i_pos, p_sys->size ); i_pos = __MIN( i_pos, p_sys->size );
p_access->info.i_pos = i_pos; p_sys->offset = i_pos;
p_access->info.b_eof = false; p_access->info.b_eof = false;
/* find correct chapter */ /* find correct chapter */
...@@ -424,7 +425,7 @@ static void FindSeekpoint( access_t *p_access ) ...@@ -424,7 +425,7 @@ static void FindSeekpoint( access_t *p_access )
return; return;
int new_seekpoint = p_sys->cur_seekpoint; int new_seekpoint = p_sys->cur_seekpoint;
if( p_access->info.i_pos < (uint64_t)p_sys->p_marks-> if( p_sys->offset < (uint64_t)p_sys->p_marks->
seekpoint[p_sys->cur_seekpoint]->i_byte_offset ) seekpoint[p_sys->cur_seekpoint]->i_byte_offset )
{ {
/* i_pos moved backwards, start fresh */ /* i_pos moved backwards, start fresh */
...@@ -433,7 +434,7 @@ static void FindSeekpoint( access_t *p_access ) ...@@ -433,7 +434,7 @@ static void FindSeekpoint( access_t *p_access )
/* only need to check the following seekpoints */ /* only need to check the following seekpoints */
while( new_seekpoint + 1 < p_sys->p_marks->i_seekpoint && while( new_seekpoint + 1 < p_sys->p_marks->i_seekpoint &&
p_access->info.i_pos >= (uint64_t)p_sys->p_marks-> p_sys->offset >= (uint64_t)p_sys->p_marks->
seekpoint[new_seekpoint + 1]->i_byte_offset ) seekpoint[new_seekpoint + 1]->i_byte_offset )
{ {
new_seekpoint++; new_seekpoint++;
...@@ -579,7 +580,7 @@ static void UpdateFileSize( access_t *p_access ) ...@@ -579,7 +580,7 @@ static void UpdateFileSize( access_t *p_access )
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
struct stat st; struct stat st;
if( p_sys->size >= p_access->info.i_pos ) if( p_sys->size >= p_sys->offset )
return; return;
/* TODO: not sure if this can happen or what to do in this case */ /* TODO: not sure if this can happen or what to do in this case */
......
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