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

vcd: keep list of byte offsets rather than dummy titles/seekpoints

Also fix leaks of the above and on-error NULL dereference.
parent 2fb0cee8
...@@ -70,9 +70,13 @@ struct access_sys_t ...@@ -70,9 +70,13 @@ struct access_sys_t
/* Title infos */ /* Title infos */
int i_titles; int i_titles;
input_title_t *title[99]; /* No more that 99 track in a vcd ? */ struct
{
uint64_t *seekpoints;
size_t count;
} titles[99]; /* No more that 99 track in a vcd ? */
int i_current_title; int i_current_title;
int i_current_seekpoint; unsigned i_current_seekpoint;
int i_sector; /* Current Sector */ int i_sector; /* Current Sector */
int *p_sectors; /* Track sectors */ int *p_sectors; /* Track sectors */
...@@ -144,6 +148,9 @@ static int Open( vlc_object_t *p_this ) ...@@ -144,6 +148,9 @@ static int Open( vlc_object_t *p_this )
p_sys->vcddev = vcddev; p_sys->vcddev = vcddev;
p_sys->offset = 0; p_sys->offset = 0;
for( size_t i = 0; i < ARRAY_SIZE(p_sys->titles); i++ )
p_sys->titles[i].seekpoints = NULL;
/* 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),
p_sys->vcddev, &p_sys->p_sectors ); p_sys->vcddev, &p_sys->p_sectors );
...@@ -163,8 +170,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -163,8 +170,6 @@ static int Open( vlc_object_t *p_this )
for( int i = 0; i < p_sys->i_titles; i++ ) for( int i = 0; i < p_sys->i_titles; i++ )
{ {
p_sys->title[i] = vlc_input_title_New();
msg_Dbg( p_access, "title[%d] start=%d", i, p_sys->p_sectors[1+i] ); msg_Dbg( p_access, "title[%d] start=%d", i, p_sys->p_sectors[1+i] );
msg_Dbg( p_access, "title[%d] end=%d", i, p_sys->p_sectors[i+2] ); msg_Dbg( p_access, "title[%d] end=%d", i, p_sys->p_sectors[i+2] );
} }
...@@ -178,15 +183,13 @@ static int Open( vlc_object_t *p_this ) ...@@ -178,15 +183,13 @@ static int Open( vlc_object_t *p_this )
/* Starting title/chapter and sector */ /* Starting title/chapter and sector */
if( i_title >= p_sys->i_titles ) if( i_title >= p_sys->i_titles )
i_title = 0; i_title = 0;
if( i_chapter >= p_sys->title[i_title]->i_seekpoint ) if( (unsigned)i_chapter >= p_sys->titles[i_title].count )
i_chapter = 0; i_chapter = 0;
p_sys->i_sector = p_sys->p_sectors[1+i_title]; p_sys->i_sector = p_sys->p_sectors[1+i_title];
if( i_chapter > 0 ) if( i_chapter > 0 )
{ p_sys->i_sector += p_sys->titles[i_title].seekpoints[i_chapter]
p_sys->i_sector += ( p_sys->title[i_title]->seekpoint[i_chapter]->i_byte_offset / / VCD_DATA_SIZE;
VCD_DATA_SIZE );
}
/* p_access */ /* p_access */
p_access->pf_read = NULL; p_access->pf_read = NULL;
...@@ -217,6 +220,9 @@ static void Close( vlc_object_t *p_this ) ...@@ -217,6 +220,9 @@ static void Close( vlc_object_t *p_this )
access_t *p_access = (access_t *)p_this; access_t *p_access = (access_t *)p_this;
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
for( size_t i = 0; i < ARRAY_SIZE(p_sys->titles); i++ )
free( p_sys->titles[i].seekpoints );
ioctl_Close( p_this, p_sys->vcddev ); ioctl_Close( p_this, p_sys->vcddev );
free( p_sys ); free( p_sys );
} }
...@@ -264,9 +270,9 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -264,9 +270,9 @@ static int Control( access_t *p_access, int i_query, va_list args )
*va_arg( args, int* ) = p_sys->i_titles; *va_arg( args, int* ) = p_sys->i_titles;
/* Duplicate title infos */ /* Duplicate title infos */
*ppp_title = malloc( sizeof(input_title_t *) * p_sys->i_titles ); *ppp_title = xmalloc( sizeof(input_title_t *) * p_sys->i_titles );
for( int i = 0; i < p_sys->i_titles; i++ ) for( int i = 0; i < p_sys->i_titles; i++ )
(*ppp_title)[i] = vlc_input_title_Duplicate( p_sys->title[i] ); (*ppp_title)[i] = vlc_input_title_New();
break; break;
case ACCESS_GET_TITLE: case ACCESS_GET_TITLE:
...@@ -301,14 +307,13 @@ static int Control( access_t *p_access, int i_query, va_list args ) ...@@ -301,14 +307,13 @@ static int Control( access_t *p_access, int i_query, va_list args )
{ {
int i = va_arg( args, int ); int i = va_arg( args, int );
unsigned i_title = p_sys->i_current_title; unsigned i_title = p_sys->i_current_title;
input_title_t *t = p_sys->title[i_title];
if( t->i_seekpoint > 0 ) if( p_sys->titles[i_title].count > 0 )
{ {
p_sys->i_current_seekpoint = i; p_sys->i_current_seekpoint = i;
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; p_sys->titles[i_title].seekpoints[i] / VCD_DATA_SIZE;
p_sys->offset = (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;
...@@ -378,13 +383,12 @@ static block_t *Block( access_t *p_access ) ...@@ -378,13 +383,12 @@ static block_t *Block( access_t *p_access )
/* Update seekpoints */ /* Update seekpoints */
for( int i_read = 0; i_read < i_blocks; i_read++ ) for( int i_read = 0; i_read < i_blocks; i_read++ )
{ {
input_title_t *t = p_sys->title[p_sys->i_current_title]; int i_title = p_sys->i_current_title;
if( t->i_seekpoint > 0 && if( p_sys->titles[i_title].count > 0 &&
p_sys->i_current_seekpoint + 1 < t->i_seekpoint && p_sys->i_current_seekpoint + 1 < p_sys->titles[i_title].count &&
(int64_t) /* Unlikely to go over 8192 PetaB */
(p_sys->offset + i_read * VCD_DATA_SIZE) >= (p_sys->offset + i_read * VCD_DATA_SIZE) >=
t->seekpoint[p_sys->i_current_seekpoint + 1]->i_byte_offset ) p_sys->titles[i_title].seekpoints[p_sys->i_current_seekpoint + 1] )
{ {
msg_Dbg( p_access, "seekpoint change" ); msg_Dbg( p_access, "seekpoint change" );
p_sys->i_current_seekpoint++; p_sys->i_current_seekpoint++;
...@@ -404,20 +408,19 @@ static block_t *Block( access_t *p_access ) ...@@ -404,20 +408,19 @@ static block_t *Block( access_t *p_access )
static int Seek( access_t *p_access, uint64_t i_pos ) static int Seek( access_t *p_access, uint64_t i_pos )
{ {
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
input_title_t *t = p_sys->title[p_sys->i_current_title]; int i_title = p_sys->i_current_title;
int i_seekpoint; unsigned i_seekpoint;
/* Next sector to read */ /* Next sector to read */
p_sys->offset = 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[i_title + 1];
p_sys->p_sectors[p_sys->i_current_title + 1];
/* Update current seekpoint */ /* Update current seekpoint */
for( i_seekpoint = 0; i_seekpoint < t->i_seekpoint; i_seekpoint++ ) for( i_seekpoint = 0; i_seekpoint < p_sys->titles[i_title].count; i_seekpoint++ )
{ {
if( i_seekpoint + 1 >= t->i_seekpoint ) break; if( i_seekpoint + 1 >= p_sys->titles[i_title].count ) break;
if( 0 < t->seekpoint[i_seekpoint + 1]->i_byte_offset && if( 0 < p_sys->titles[i_title].seekpoints[i_seekpoint + 1] &&
i_pos < (uint64_t)t->seekpoint[i_seekpoint + 1]->i_byte_offset ) break; i_pos < p_sys->titles[i_title].seekpoints[i_seekpoint + 1] ) break;
} }
if( i_seekpoint != p_sys->i_current_seekpoint ) if( i_seekpoint != p_sys->i_current_seekpoint )
...@@ -473,20 +476,17 @@ static int EntryPoints( access_t *p_access ) ...@@ -473,20 +476,17 @@ static int EntryPoints( access_t *p_access )
(MSF_TO_LBA2( BCD_TO_BIN( entries.entry[i].msf.minute ), (MSF_TO_LBA2( BCD_TO_BIN( entries.entry[i].msf.minute ),
BCD_TO_BIN( entries.entry[i].msf.second ), BCD_TO_BIN( entries.entry[i].msf.second ),
BCD_TO_BIN( entries.entry[i].msf.frame ) )); BCD_TO_BIN( entries.entry[i].msf.frame ) ));
seekpoint_t *s;
if( i_title < 0 ) continue; /* Should not occur */ if( i_title < 0 ) continue; /* Should not occur */
if( i_title >= p_sys->i_titles ) continue; if( i_title >= p_sys->i_titles ) continue;
msg_Dbg( p_access, "Entry[%d] title=%d sector=%d", msg_Dbg( p_access, "Entry[%d] title=%d sector=%d",
i, i_title, i_sector ); i, i_title, i_sector );
s = vlc_seekpoint_New(); p_sys->titles[i_title].seekpoints = xrealloc(
s->i_byte_offset = (i_sector - p_sys->p_sectors[i_title+1]) * p_sys->titles[i_title].seekpoints,
VCD_DATA_SIZE; sizeof( uint64_t ) * (p_sys->titles[i_title].count + 1) );
p_sys->titles[i_title].seekpoints[p_sys->titles[i_title].count++] =
TAB_APPEND( p_sys->title[i_title]->i_seekpoint, (i_sector - p_sys->p_sectors[i_title+1]) * VCD_DATA_SIZE;
p_sys->title[i_title]->seekpoint, s );
} }
return VLC_SUCCESS; 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