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);
static int Seek(access_t *, uint64_t);
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)
{
......@@ -67,23 +73,30 @@ static int Open(vlc_object_t *object)
if (!input)
return VLC_EGENERIC;
input_attachment_t *a;
if (input_Control(input, INPUT_GET_ATTACHMENT, &a, access->psz_location))
a = NULL;
access_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == 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'",
access->psz_location);
free(sys);
return VLC_EGENERIC;
}
sys->offset = 0;
/* */
access_InitFields(access);
access->pf_read = Read;
access->pf_block = NULL;
access->pf_control = Control;
access->pf_seek = Seek;
access->p_sys = (void *)a;
access->p_sys = sys;
return VLC_SUCCESS;
}
......@@ -91,30 +104,38 @@ static int Open(vlc_object_t *object)
static void Close(vlc_object_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)
{
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)
return 0;
const size_t copy = __MIN(size, a->i_data - access->info.i_pos);
memcpy(buffer, (uint8_t *)a->p_data + access->info.i_pos, copy);
access->info.i_pos += copy;
const size_t copy = __MIN(size, a->i_data - sys->offset);
memcpy(buffer, (uint8_t *)a->p_data + sys->offset, copy);
sys->offset += copy;
return copy;
}
/* */
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;
return VLC_SUCCESS;
}
......@@ -122,7 +143,7 @@ static int Seek(access_t *access, uint64_t position)
/* */
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)
{
......@@ -133,7 +154,7 @@ static int Control(access_t *access, int query, va_list args)
*va_arg(args, bool *) = true;
break;
case ACCESS_GET_SIZE:
*va_arg(args, uint64_t *) = a->i_data;
*va_arg(args, uint64_t *) = sys->attachment->i_data;
break;
case ACCESS_GET_PTS_DELAY:
*va_arg(args, int64_t *) = DEFAULT_PTS_DELAY;
......
......@@ -143,6 +143,7 @@ struct access_sys_t
char sz_epsv_ip[NI_MAXNUMERICHOST];
bool out;
uint64_t offset;
uint64_t size;
};
#define GET_OUT_SYS( p_this ) \
......@@ -632,6 +633,7 @@ static int InOpen( vlc_object_t *p_this )
return VLC_ENOMEM;
p_sys->data.fd = -1;
p_sys->out = false;
p_sys->offset = 0;
p_sys->size = UINT64_MAX;
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 )
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 )
return val;
p_access->info.b_eof = false;
p_access->info.i_pos = i_pos;
p_sys->offset = i_pos;
return VLC_SUCCESS;
}
......@@ -833,10 +837,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
else
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;
else if( i_read > 0 )
p_access->info.i_pos += i_read;
else if( errno != EINTR && errno != EAGAIN )
{
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 )
case ACCESS_SET_PAUSE_STATE:
pb_bool = (bool*)va_arg( args, bool* );
if ( !pb_bool )
return Seek( p_access, p_access->info.i_pos );
return Seek( p_access, p_access->p_sys->offset );
break;
default:
......
......@@ -174,6 +174,7 @@ struct access_sys_t
char *psz_icy_title;
uint64_t i_remaining;
uint64_t offset;
uint64_t size;
/* cookie jar borrowed from playlist, do not free */
......@@ -270,8 +271,8 @@ static int OpenRedirected( vlc_object_t *p_this, const char *psz_access,
p_sys->i_remaining = 0;
p_sys->b_persist = false;
p_sys->b_has_size = false;
p_sys->offset = 0;
p_sys->size = 0;
p_access->info.i_pos = 0;
p_access->info.b_eof = false;
/* 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 )
if( p_sys->b_has_size )
{
/* 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 )
i_len = remainder;
......@@ -669,10 +670,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if( i_len == 0 )
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 -
(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 )
{
......@@ -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 )
{
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" );
}
......@@ -728,10 +729,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
}
assert( i_read >= 0 );
p_access->info.i_pos += i_read;
p_sys->offset += i_read;
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 );
p_sys->i_remaining -= i_read;
}
......@@ -1015,8 +1016,8 @@ static int Connect( access_t *p_access, uint64_t i_tell )
p_sys->i_remaining = 0;
p_sys->b_persist = false;
p_sys->b_has_size = false;
p_sys->offset = i_tell;
p_sys->size = 0;
p_access->info.i_pos = i_tell;
p_access->info.b_eof = false;
/* Open connection */
......@@ -1296,7 +1297,7 @@ static int Request( access_t *p_access, uint64_t i_tell )
uint64_t i_nsize = p_sys->size;
sscanf(p,"bytes %"SCNu64"-%"SCNu64"/%"SCNu64,&i_ntell,&i_nend,&i_nsize);
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_remaining = i_nend+1-i_ntell;
uint64_t i_size = (i_nsize > i_nend) ? i_nsize : (i_nend + 1);
......
......@@ -84,6 +84,7 @@ int MMSHOpen( access_t *p_access )
p_sys->i_proto= MMS_PROTO_HTTP;
p_sys->fd = -1;
p_sys->i_position = 0;
/* Handle proxy */
p_sys->b_proxy = false;
......@@ -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;
Stop( p_access );
Seek( p_access, p_access->info.i_pos );
Seek( p_access, p_sys->i_position );
return VLC_SUCCESS;
}
......@@ -305,7 +306,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
if( b_bool )
Stop( p_access );
else
Seek( p_access, p_access->info.i_pos );
Seek( p_access, p_sys->i_position );
break;
default:
......@@ -344,7 +345,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
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_sys->i_packet_used += i_offset;
......@@ -368,9 +369,9 @@ static block_t *Block( access_t *p_access )
access_sys_t *p_sys = p_access->p_sys;
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;
block_t *p_block = block_Alloc( i_copy );
......@@ -378,7 +379,7 @@ static block_t *Block( access_t *p_access )
return NULL;
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;
}
else if( p_sys->i_packet_length > 0 &&
......@@ -402,7 +403,7 @@ static block_t *Block( access_t *p_access )
memset( &p_block->p_buffer[i_copy], 0, 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;
}
......@@ -440,7 +441,7 @@ static int Restart( access_t *p_access )
char *psz_location = NULL;
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" );
......@@ -470,7 +471,7 @@ static int Reset( access_t *p_access )
int i;
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;
......
......@@ -65,6 +65,7 @@ struct access_sys_t
unsigned int i_packet_length;
uint64_t i_start;
uint64_t i_position;
asf_header_t asfh;
guid_t guid;
......
......@@ -277,7 +277,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
else
{
KeepAliveStop( p_access );
Seek( p_access, p_access->info.i_pos );
Seek( p_access, p_sys->i_position );
}
break;
......@@ -299,11 +299,11 @@ static int Seek( access_t * p_access, uint64_t i_pos )
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
* or no stream was yet read */
p_access->info.i_pos = i_pos;
p_sys->i_position = i_pos;
return VLC_SUCCESS;
}
else
......@@ -381,7 +381,7 @@ static int Seek( access_t * p_access, uint64_t i_pos )
msg_Dbg( p_access, "Streaming restarted" );
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;
return VLC_SUCCESS;
......@@ -397,16 +397,16 @@ static block_t *Block( access_t *p_access )
if( p_access->info.b_eof )
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 );
if( !p_block )
return NULL;
memcpy( p_block->p_buffer, &p_sys->p_header[p_access->info.i_pos], i_copy );
p_access->info.i_pos += i_copy;
memcpy( p_block->p_buffer, &p_sys->p_header[p_sys->i_position], i_copy );
p_sys->i_position += i_copy;
return p_block;
}
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 )
memset( &p_block->p_buffer[i_copy], 0, 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;
}
......@@ -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_used = 0;
p_access->info.i_pos = 0;
p_sys->i_position = 0;
p_sys->i_buffer_tcp = 0;
p_sys->i_buffer_udp = 0;
p_sys->p_cmd = NULL;
......
......@@ -43,6 +43,7 @@ struct access_sys_t
char sz_bind_addr[NI_MAXNUMERICHOST]; /* used by udp */
vlc_url_t url;
uint64_t i_position;
uint64_t i_size;
asf_header_t asfh;
......
......@@ -40,6 +40,7 @@ struct access_sys_t {
stream_t *s;
rar_file_t *file;
const rar_file_chunk_t *chunk;
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)
if (position > file->real_size)
position = file->real_size;
sys->position = position;
/* Search the chunk */
const rar_file_chunk_t *old_chunk = sys->chunk;
......@@ -57,7 +59,6 @@ static int Seek(access_t *access, uint64_t position)
if (position < sys->chunk->cummulated_size + sys->chunk->size)
break;
}
access->info.i_pos = position;
access->info.b_eof = false;
const uint64_t offset = sys->chunk->offset +
......@@ -78,7 +79,7 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size)
size_t total = 0;
while (total < 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)
break;
......@@ -89,9 +90,9 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size)
total += r;
if( data )
data += r;
access->info.i_pos += r;
if (access->info.i_pos >= chunk_end &&
Seek(access, access->info.i_pos))
sys->position += r;
if (sys->position >= chunk_end &&
Seek(access, sys->position))
break;
}
if (size > 0 && total <= 0)
......
......@@ -66,6 +66,7 @@ vlc_module_end ()
struct access_sys_t
{
vcddev_t *vcddev; /* vcd device descriptor */
uint64_t offset;
/* Title infos */
int i_titles;
......@@ -141,6 +142,7 @@ static int Open( vlc_object_t *p_this )
if( unlikely(!p_sys ))
goto error;
p_sys->vcddev = vcddev;
p_sys->offset = 0;
/* We read the Table Of Content information */
p_sys->i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
......@@ -200,8 +202,8 @@ static int Open( vlc_object_t *p_this )
p_sys->i_current_title = i_title;
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] ) *
VCD_DATA_SIZE;
p_sys->offset = (uint64_t)(p_sys->i_sector - p_sys->p_sectors[1+i_title]) *
VCD_DATA_SIZE;
return VLC_SUCCESS;
......@@ -284,9 +286,9 @@ static int Control( access_t *p_access, int i_query, va_list args )
if( i != p_sys->i_current_title )
{
/* Update info */
p_sys->offset = 0;
p_sys->i_current_title = i;
p_sys->i_current_seekpoint = 0;
p_access->info.i_pos = 0;
/* Next sector to read */
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 )
p_sys->i_sector = p_sys->p_sectors[1 + i_title] +
t->seekpoint[i]->i_byte_offset / VCD_DATA_SIZE;
p_access->info.i_pos = (uint64_t)(p_sys->i_sector -
p_sys->p_sectors[1 + i_title]) *VCD_DATA_SIZE;
p_sys->offset = (uint64_t)(p_sys->i_sector -
p_sys->p_sectors[1 + i_title]) * VCD_DATA_SIZE;
}
break;
}
......@@ -342,7 +344,7 @@ static block_t *Block( access_t *p_access )
p_sys->i_current_title++;
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 */
......@@ -367,8 +369,8 @@ static block_t *Block( access_t *p_access )
block_Release( p_block );
/* Try to skip one sector (in case of bad sectors) */
p_sys->offset += VCD_DATA_SIZE;
p_sys->i_sector++;
p_access->info.i_pos += VCD_DATA_SIZE;
return NULL;
}
......@@ -380,7 +382,7 @@ static block_t *Block( access_t *p_access )
if( t->i_seekpoint > 0 &&
p_sys->i_current_seekpoint + 1 < t->i_seekpoint &&
(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 )
{
msg_Dbg( p_access, "seekpoint change" );
......@@ -389,8 +391,8 @@ static block_t *Block( access_t *p_access )
}
/* Update a few values */
p_sys->offset += p_block->i_buffer;
p_sys->i_sector += i_blocks;
p_access->info.i_pos += p_block->i_buffer;
return p_block;
}
......@@ -405,7 +407,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
int i_seekpoint;
/* 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->p_sectors[p_sys->i_current_title + 1];
......
......@@ -110,6 +110,7 @@ struct access_sys_t
{
/* file sizes of all parts */
size_array_t file_sizes;
uint64_t offset;
uint64_t size; /* total size */
/* 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 )
if( i_ret > 0 )
{
/* success */
p_access->info.i_pos += i_ret;
p_sys->offset += i_ret;
UpdateFileSize( p_access );
FindSeekpoint( p_access );
return i_ret;
......@@ -392,7 +393,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
/* might happen if called by ACCESS_SET_SEEKPOINT */
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;
/* find correct chapter */
......@@ -424,7 +425,7 @@ static void FindSeekpoint( access_t *p_access )
return;
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 )
{
/* i_pos moved backwards, start fresh */
......@@ -433,7 +434,7 @@ static void FindSeekpoint( access_t *p_access )
/* only need to check the following seekpoints */
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 )
{
new_seekpoint++;
......@@ -579,7 +580,7 @@ static void UpdateFileSize( access_t *p_access )
access_sys_t *p_sys = p_access->p_sys;
struct stat st;
if( p_sys->size >= p_access->info.i_pos )
if( p_sys->size >= p_sys->offset )
return;
/* 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