[vlc-commits] access: cdrom: return TOC struct instead of only sectors
Francois Cartegnie
git at videolan.org
Sat Jun 1 00:23:41 CEST 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon May 27 17:13:21 2019 +0200| [890db4f7e7b04dc1c28bc3ba5eeebf76b102b9d0] | committer: Francois Cartegnie
access: cdrom: return TOC struct instead of only sectors
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=890db4f7e7b04dc1c28bc3ba5eeebf76b102b9d0
---
modules/access/cdda.c | 58 ++++----
modules/access/vcd/cdrom.c | 247 ++++++++++++++++++++++-------------
modules/access/vcd/cdrom.h | 32 ++++-
modules/access/vcd/cdrom_internals.h | 5 +-
modules/access/vcd/vcd.c | 65 +++++----
5 files changed, 253 insertions(+), 154 deletions(-)
diff --git a/modules/access/cdda.c b/modules/access/cdda.c
index d7974e2524..dca1461141 100644
--- a/modules/access/cdda.c
+++ b/modules/access/cdda.c
@@ -230,19 +230,19 @@ static int DemuxOpen(vlc_object_t *obj, vcddev_t *dev, unsigned track)
/* Track number in input item */
if (sys->start == (unsigned)-1 || sys->length == (unsigned)-1)
{
- int *sectors = NULL; /* Track sectors */
- unsigned titles = ioctl_GetTracksMap(obj, dev, §ors);
-
- if (track > titles)
+ vcddev_toc_t *p_toc = ioctl_GetTOC(obj, dev, true);
+ if(p_toc == NULL)
+ goto error;
+ if (track > (unsigned)p_toc->i_tracks)
{
- msg_Err(obj, "invalid track number: %u/%u", track, titles);
- free(sectors);
+ msg_Err(obj, "invalid track number: %u/%i", track, p_toc->i_tracks);
+ vcddev_toc_Free(p_toc);
goto error;
}
- sys->start = sectors[track - 1];
- sys->length = sectors[track] - sys->start;
- free(sectors);
+ sys->start = p_toc->p_sectors[track - 1].i_lba;
+ sys->length = p_toc->p_sectors[track].i_lba - sys->start;
+ vcddev_toc_Free(p_toc);
}
es_format_t fmt;
@@ -271,8 +271,7 @@ error:
typedef struct
{
vcddev_t *vcddev; /* vcd device descriptor */
- int *p_sectors; /* Track sectors */
- int titles;
+ vcddev_toc_t *p_toc; /* Tracks TOC */
int cdtextc;
vlc_meta_t **cdtextv;
#ifdef HAVE_LIBCDDB
@@ -281,7 +280,7 @@ typedef struct
} access_sys_t;
#ifdef HAVE_LIBCDDB
-static cddb_disc_t *GetCDDBInfo( vlc_object_t *obj, int i_titles, int *p_sectors )
+static cddb_disc_t *GetCDDBInfo( vlc_object_t *obj, const vcddev_toc_t *p_toc )
{
if( !var_InheritBool( obj, "metadata-network-access" ) )
{
@@ -337,17 +336,17 @@ static cddb_disc_t *GetCDDBInfo( vlc_object_t *obj, int i_titles, int *p_sectors
}
int64_t i_length = 2000000; /* PreGap */
- for( int i = 0; i < i_titles; i++ )
+ for( int i = 0; i < p_toc->i_tracks; i++ )
{
cddb_track_t *t = cddb_track_new();
- cddb_track_set_frame_offset( t, p_sectors[i] + 150 ); /* Pregap offset */
+ cddb_track_set_frame_offset( t, p_toc->p_sectors[i].i_lba + 150 ); /* Pregap offset */
cddb_disc_add_track( p_disc, t );
- const int64_t i_size = ( p_sectors[i+1] - p_sectors[i] ) *
+ const int64_t i_size = ( p_toc->p_sectors[i+1].i_lba - p_toc->p_sectors[i].i_lba ) *
(int64_t)CDDA_DATA_SIZE;
i_length += INT64_C(1000000) * i_size / 44100 / 4 ;
- msg_Dbg( obj, "Track %i offset: %i", i, p_sectors[i] + 150 );
+ msg_Dbg( obj, "Track %i offset: %i", i, p_toc->p_sectors[i].i_lba + 150 );
}
msg_Dbg( obj, "Total length: %i", (int)(i_length/1000000) );
@@ -426,7 +425,7 @@ static void AccessGetMeta(stream_t *access, vlc_meta_t *meta)
str = cddb_disc_get_artist(sys->cddb);
if (NONEMPTY(str))
{
- for (int i = 0; i < sys->titles; i++)
+ for (int i = 0; i < sys->p_toc->i_tracks; i++)
{
cddb_track_t *t = cddb_disc_get_track(sys->cddb, i);
if (t == NULL)
@@ -453,11 +452,12 @@ static void AccessGetMeta(stream_t *access, vlc_meta_t *meta)
static int ReadDir(stream_t *access, input_item_node_t *node)
{
access_sys_t *sys = access->p_sys;
+ const vcddev_toc_t *p_toc = sys->p_toc;
/* Build title table */
- for (int i = 0; i < sys->titles; i++)
+ for (int i = 0; i < p_toc->i_tracks; i++)
{
- msg_Dbg(access, "track[%d] start=%d", i, sys->p_sectors[i]);
+ msg_Dbg(access, "track[%d] start=%d", i, p_toc->p_sectors[i].i_lba);
/* Initial/default name */
char *name;
@@ -467,7 +467,7 @@ static int ReadDir(stream_t *access, input_item_node_t *node)
/* Create playlist items */
const vlc_tick_t duration =
- (vlc_tick_t)(sys->p_sectors[i + 1] - sys->p_sectors[i])
+ (vlc_tick_t)(p_toc->p_sectors[i + 1].i_lba - p_toc->p_sectors[i].i_lba)
* CDDA_DATA_SIZE * CLOCK_FREQ / 44100 / 2 / 2;
input_item_t *item = input_item_NewDisc(access->psz_url,
@@ -486,14 +486,14 @@ static int ReadDir(stream_t *access, input_item_node_t *node)
}
if (likely(asprintf(&opt, "cdda-first-sector=%i",
- sys->p_sectors[i]) != -1))
+ p_toc->p_sectors[i].i_lba) != -1))
{
input_item_AddOption(item, opt, VLC_INPUT_OPTION_TRUSTED);
free(opt);
}
if (likely(asprintf(&opt, "cdda-last-sector=%i",
- sys->p_sectors[i + 1]) != -1))
+ p_toc->p_sectors[i + 1].i_lba) != -1))
{
input_item_AddOption(item, opt, VLC_INPUT_OPTION_TRUSTED);
free(opt);
@@ -600,25 +600,24 @@ static int AccessOpen(vlc_object_t *obj, vcddev_t *dev)
}
sys->vcddev = dev;
- sys->p_sectors = NULL;
-
- sys->titles = ioctl_GetTracksMap(obj, dev, &sys->p_sectors);
- if (sys->titles < 0)
+ sys->p_toc = ioctl_GetTOC(obj, dev, true);
+ if (sys->p_toc == NULL)
{
msg_Err(obj, "cannot count tracks");
goto error;
}
- if (sys->titles == 0)
+ if (sys->p_toc->i_tracks == 0)
{
msg_Err(obj, "no audio tracks found");
+ vcddev_toc_Free(sys->p_toc);
goto error;
}
#ifdef HAVE_LIBCDDB
msg_Dbg(obj, "retrieving metadata with CDDB");
- sys->cddb = GetCDDBInfo(obj, sys->titles, sys->p_sectors);
+ sys->cddb = GetCDDBInfo(obj, sys->p_toc);
if (sys->cddb != NULL)
msg_Dbg(obj, "disc ID: 0x%08x", cddb_disc_get_discid(sys->cddb));
else
@@ -641,7 +640,6 @@ static int AccessOpen(vlc_object_t *obj, vcddev_t *dev)
return VLC_SUCCESS;
error:
- free(sys->p_sectors);
ioctl_Close(obj, dev);
return VLC_EGENERIC;
}
@@ -661,7 +659,7 @@ static void AccessClose(access_sys_t *sys)
cddb_disc_destroy(sys->cddb);
#endif
- free(sys->p_sectors);
+ vcddev_toc_Free(sys->p_toc);
}
static int Open(vlc_object_t *obj)
diff --git a/modules/access/vcd/cdrom.c b/modules/access/vcd/cdrom.c
index 0639aeb734..8d7a461d3c 100644
--- a/modules/access/vcd/cdrom.c
+++ b/modules/access/vcd/cdrom.c
@@ -139,8 +139,8 @@ exit_free:
# error FIXME
#endif
-#include "cdrom_internals.h"
#include "cdrom.h"
+#include "cdrom_internals.h"
/*****************************************************************************
* ioctl_Open: Opens a VCD device or file and returns an opaque handle
@@ -164,6 +164,7 @@ vcddev_t *ioctl_Open( vlc_object_t *p_this, const char *psz_dev )
return NULL;
p_vcddev->i_vcdimage_handle = -1;
p_vcddev->psz_dev = NULL;
+ memset( &p_vcddev->toc, 0, sizeof(p_vcddev->toc) );
b_is_file = 1;
/*
@@ -256,14 +257,15 @@ void ioctl_Close( vlc_object_t * p_this, vcddev_t *p_vcddev )
}
/*****************************************************************************
- * ioctl_GetTracksMap: Read the Table of Content, fill in the pp_sectors map
- * if pp_sectors is not null and return the number of
- * tracks available.
+ * ioctl_GetTOC: Read the Table of Content, fill in the p_sectors map
+ * if b_fill_sector_info is true.
*****************************************************************************/
-int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
- int **pp_sectors )
+vcddev_toc_t * ioctl_GetTOC( vlc_object_t *p_this, const vcddev_t *p_vcddev,
+ bool b_fill_sectorinfo )
{
- int i_tracks = 0;
+ vcddev_toc_t *p_toc = calloc(1, sizeof(*p_toc));
+ if(!p_toc)
+ return NULL;
if( p_vcddev->i_vcdimage_handle != -1 )
{
@@ -271,18 +273,22 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
* vcd image mode
*/
- i_tracks = p_vcddev->i_tracks;
+ *p_toc = p_vcddev->toc;
+ p_toc->p_sectors = NULL;
- if( pp_sectors )
+ if( b_fill_sectorinfo )
{
- *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
- if( *pp_sectors == NULL )
- return 0;
- memcpy( *pp_sectors, p_vcddev->p_sectors,
- (i_tracks + 1) * sizeof(**pp_sectors) );
+ p_toc->p_sectors = calloc( p_toc->i_tracks + 1, sizeof(*p_toc->p_sectors) );
+ if( p_toc->p_sectors == NULL )
+ {
+ free( p_toc );
+ return NULL;
+ }
+ memcpy( p_toc->p_sectors, p_vcddev->toc.p_sectors,
+ (p_toc->i_tracks + 1) * sizeof(*p_toc->p_sectors) );
}
- return i_tracks;
+ return p_toc;
}
else
{
@@ -299,28 +305,33 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
if( ( pTOC = darwin_getTOC( p_this, p_vcddev ) ) == NULL )
{
msg_Err( p_this, "failed to get the TOC" );
- return 0;
+ vcddev_toc_Free( p_toc );
+ return NULL;
}
i_descriptors = CDTOCGetDescriptorCount( pTOC );
- i_tracks = darwin_getNumberOfTracks( pTOC, i_descriptors );
+ p_toc->i_tracks = darwin_getNumberOfTracks( pTOC, i_descriptors,
+ &p_toc->i_first_track,
+ &p_toc->i_last_track );
- if( pp_sectors )
+ if( b_fill_sectorinfo )
{
int i, i_leadout = -1;
CDTOCDescriptor *pTrackDescriptors;
u_char track;
- *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
- if( *pp_sectors == NULL )
+ p_toc->p_sectors = calloc( p_toc->i_tracks + 1,
+ sizeof(*p_toc->p_sectors) );
+ if( p_toc->p_sectors == NULL )
{
+ vcddev_toc_Free( p_toc );
darwin_freeTOC( pTOC );
- return 0;
+ return NULL;
}
pTrackDescriptors = pTOC->descriptors;
- for( i_tracks = 0, i = 0; i < i_descriptors; i++ )
+ for( p_toc->i_tracks = 0, i = 0; i < i_descriptors; i++ )
{
track = pTrackDescriptors[i].point;
@@ -330,20 +341,21 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
if( track > CD_MAX_TRACK_NO || track < CD_MIN_TRACK_NO )
continue;
- (*pp_sectors)[i_tracks++] =
+ p_toc->p_sectors[p_toc->i_tracks].i_control = pTrackDescriptors[i].control;
+ p_toc->p_sectors[p_toc->i_tracks++].i_lba =
CDConvertMSFToLBA( pTrackDescriptors[i].p );
}
if( i_leadout == -1 )
{
msg_Err( p_this, "leadout not found" );
- free( *pp_sectors );
+ vcddev_toc_Free( p_toc );
darwin_freeTOC( pTOC );
- return 0;
+ return NULL;
}
/* set leadout sector */
- (*pp_sectors)[i_tracks] =
+ p_toc->p_sectors[p_toc->i_tracks].i_lba =
CDConvertMSFToLBA( pTrackDescriptors[i_leadout].p );
}
@@ -358,24 +370,31 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
&dwBytesReturned, NULL ) == 0 )
{
msg_Err( p_this, "could not read TOCHDR" );
- return 0;
+ vcddev_toc_Free( p_toc );
+ return NULL;
}
- i_tracks = cdrom_toc.LastTrack - cdrom_toc.FirstTrack + 1;
+ p_toc->i_tracks = cdrom_toc.LastTrack - cdrom_toc.FirstTrack + 1;
+ p_toc->i_first_track = cdrom_toc.FirstTrack;
+ p_toc->i_last_track = cdrom_toc.LastTrack;
- if( pp_sectors )
+ if( b_fill_sectorinfo )
{
- *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
- if( *pp_sectors == NULL )
- return 0;
+ p_toc->p_sectors = calloc( p_toc->i_tracks + 1, sizeof(p_toc->p_sectors) );
+ if( p_toc->p_sectors == NULL )
+ {
+ vcddev_toc_Free( p_toc );
+ return NULL;
+ }
- for( int i = 0 ; i <= i_tracks ; i++ )
+ for( int i = 0 ; i <= p_toc->i_tracks ; i++ )
{
- (*pp_sectors)[ i ] = MSF_TO_LBA2(
+ p_toc->p_sectors[ i ].i_control = cdrom_toc.TrackData[i].Control;
+ p_toc->p_sectors[ i ].i_lba = MSF_TO_LBA2(
cdrom_toc.TrackData[i].Address[1],
cdrom_toc.TrackData[i].Address[2],
cdrom_toc.TrackData[i].Address[3] );
- msg_Dbg( p_this, "p_sectors: %i, %i", i, (*pp_sectors)[i]);
+ msg_Dbg( p_this, "p_sectors: %i, %i", i, p_toc->p_sectors[i].i_lba);
}
}
@@ -397,19 +416,24 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
return 0;
}
- i_tracks = tochdr.last_track - tochdr.first_track + 1;
+ p_toc->i_tracks = tochdr.last_track - tochdr.first_track + 1;
+ p_toc->i_first_track = tochdr.first_track;
+ p_toc->i_last_track = tochdr.last_track;
- if( pp_sectors )
+ if( b_fill_sectorinfo )
{
cdrom_get_track_t get_track = {{'C', 'D', '0', '1'}, };
cdrom_track_t track;
int i;
- *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
- if( *pp_sectors == NULL )
- return 0;
+ p_toc->p_sectors = calloc( p_toc->i_tracks + 1, sizeof(*p_toc->p_sectors) );
+ if( *p_toc->p_sectors == NULL )
+ {
+ vcddev_toc_Free( p_toc );
+ return NULL;
+ }
- for( i = 0 ; i < i_tracks ; i++ )
+ for( i = 0 ; i < p_toc->i_tracks ; i++ )
{
get_track.track = tochdr.first_track + i;
rc = DosDevIOCtl( p_vcddev->hcd, IOCTL_CDROMAUDIO,
@@ -420,22 +444,23 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
{
msg_Err( p_this, "could not read %d track",
get_track.track );
- return 0;
+ vcddev_toc_Free( p_toc );
+ return NULL;
}
- (*pp_sectors)[ i ] = MSF_TO_LBA2(
+ p_toc->p_sectors[ i ].i_lba = MSF_TO_LBA2(
track.start.minute,
track.start.second,
track.start.frame );
- msg_Dbg( p_this, "p_sectors: %i, %i", i, (*pp_sectors)[i]);
+ msg_Dbg( p_this, "p_sectors: %i, %i", i, p_toc->p_sectors[i].i_lba);
}
/* for lead-out track */
- (*pp_sectors)[ i ] = MSF_TO_LBA2(
+ p_toc->p_sectors[ i ].i_lba = MSF_TO_LBA2(
tochdr.lead_out.minute,
tochdr.lead_out.second,
tochdr.lead_out.frame );
- msg_Dbg( p_this, "p_sectors: %i, %i", i, (*pp_sectors)[i]);
+ msg_Dbg( p_this, "p_sectors: %i, %i", i, p_toc->p_sectors[i].i_lba);
}
#elif defined( HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H ) \
@@ -447,27 +472,33 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
== -1 )
{
msg_Err( p_this, "could not read TOCHDR" );
- return 0;
+ vcddev_toc_Free( p_toc );
+ return NULL;
}
- i_tracks = tochdr.ending_track - tochdr.starting_track + 1;
+ p_toc->i_tracks = tochdr.ending_track - tochdr.starting_track + 1;
+ p_toc->i_first_track = tochdr.starting_track;
+ p_toc->i_last_track = tochdr.ending_track;
- if( pp_sectors )
+ if( b_fill_sectorinfo )
{
- *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
- if( *pp_sectors == NULL )
- return 0;
+ p_toc->p_sectors = calloc( p_toc->i_tracks + 1, sizeof(*p_toc->p_sectors) );
+ if( p_toc->p_sectors == NULL )
+ {
+ vcddev_toc_Free( p_toc );
+ return NULL;
+ }
toc_entries.address_format = CD_LBA_FORMAT;
toc_entries.starting_track = 0;
- toc_entries.data_len = ( i_tracks + 1 ) *
+ toc_entries.data_len = ( p_toc->i_tracks + 1 ) *
sizeof( struct cd_toc_entry );
toc_entries.data = (struct cd_toc_entry *)
malloc( toc_entries.data_len );
if( toc_entries.data == NULL )
{
- free( *pp_sectors );
- return 0;
+ vcddev_toc_Free( p_toc );
+ return NULL;
}
/* Read the TOC */
@@ -475,19 +506,19 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
&toc_entries ) == -1 )
{
msg_Err( p_this, "could not read the TOC" );
- free( *pp_sectors );
free( toc_entries.data );
- return 0;
+ vcddev_toc_Free( p_toc );
+ return NULL;
}
/* Fill the p_sectors structure with the track/sector matches */
- for( int i = 0 ; i <= i_tracks ; i++ )
+ for( int i = 0 ; i <= p_toc->i_tracks ; i++ )
{
#if defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )
/* FIXME: is this ok? */
- (*pp_sectors)[ i ] = toc_entries.data[i].addr.lba;
+ p_toc->p_sectors[ i ].i_lba = toc_entries.data[i].addr.lba;
#else
- (*pp_sectors)[ i ] = ntohl( toc_entries.data[i].addr.lba );
+ p_toc->p_sectors[ i ].i_lba = ntohl( toc_entries.data[i].addr.lba );
#endif
}
}
@@ -500,38 +531,46 @@ int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
== -1 )
{
msg_Err( p_this, "could not read TOCHDR" );
- return 0;
+ free( p_toc );
+ return NULL;
}
- i_tracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
+ p_toc->i_tracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
+ p_toc->i_first_track = tochdr.cdth_trk0;
+ p_toc->i_last_track = tochdr.cdth_trk1;
- if( pp_sectors )
+ if( b_fill_sectorinfo )
{
- *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
- if( *pp_sectors == NULL )
- return 0;
+ p_toc->p_sectors = calloc( p_toc->i_tracks + 1, sizeof(*p_toc->p_sectors) );
+ if( p_toc->p_sectors == NULL )
+ {
+ free( p_toc );
+ return NULL;
+ }
/* Fill the p_sectors structure with the track/sector matches */
- for( int i = 0 ; i <= i_tracks ; i++ )
+ for( int i = 0 ; i <= p_toc->i_tracks ; i++ )
{
tocent.cdte_format = CDROM_LBA;
tocent.cdte_track =
- ( i == i_tracks ) ? CDROM_LEADOUT : tochdr.cdth_trk0 + i;
+ ( i == p_toc->i_tracks ) ? CDROM_LEADOUT : tochdr.cdth_trk0 + i;
if( ioctl( p_vcddev->i_device_handle, CDROMREADTOCENTRY,
&tocent ) == -1 )
{
msg_Err( p_this, "could not read TOCENTRY" );
- free( *pp_sectors );
- return 0;
+ free( p_toc->p_sectors );
+ free( p_toc );
+ return NULL;
}
- (*pp_sectors)[ i ] = tocent.cdte_addr.lba;
+ p_toc->p_sectors[ i ].i_lba = tocent.cdte_addr.lba;
+ p_toc->p_sectors[ i ].i_control = tocent.cdte_ctrl;
}
}
#endif
- return i_tracks;
+ return p_toc;
}
}
@@ -766,7 +805,7 @@ static int OpenVCDImage( vlc_object_t * p_this, const char *psz_dev,
char *psz_vcdfile = NULL;
char *psz_cuefile = NULL;
FILE *cuefile = NULL;
- int *p_sectors = NULL;
+ vcddev_toc_t *p_toc = &p_vcddev->toc;
char line[1024];
bool b_found = false;
@@ -857,9 +896,9 @@ static int OpenVCDImage( vlc_object_t * p_this, const char *psz_dev,
/* Try to parse the i_tracks and p_sectors info so we can just forget
* about the cuefile */
- size_t i_tracks = 0;
+ p_toc->i_tracks = 0;
- while( fgets( line, 1024, cuefile ) && i_tracks < INT_MAX-1 )
+ while( fgets( line, 1024, cuefile ) && p_toc->i_tracks < INT_MAX-1 )
{
/* look for a TRACK line */
char psz_dummy[10];
@@ -875,35 +914,42 @@ static int OpenVCDImage( vlc_object_t * p_this, const char *psz_dev,
&i_min, &i_sec, &i_frame ) != 4) || (i_num != 1) )
continue;
- int *buf = realloc (p_sectors, (i_tracks + 1) * sizeof (*buf));
+ vcddev_sector_t *buf = realloc (p_toc->p_sectors,
+ (p_toc->i_tracks + 1) * sizeof (*buf));
if (buf == NULL)
goto error;
- p_sectors = buf;
- p_sectors[i_tracks] = MSF_TO_LBA(i_min, i_sec, i_frame);
+ p_toc->p_sectors = buf;
+ p_toc->p_sectors[p_toc->i_tracks].i_lba = MSF_TO_LBA(i_min, i_sec, i_frame);
+ p_toc->p_sectors[p_toc->i_tracks].i_control = 0x00;
msg_Dbg( p_this, "vcd track %i begins at sector:%i",
- (int)i_tracks, (int)p_sectors[i_tracks] );
- i_tracks++;
+ p_toc->i_tracks, p_toc->p_sectors[p_toc->i_tracks].i_lba );
+ p_toc->i_tracks++;
break;
}
}
/* fill in the last entry */
- int *buf = realloc (p_sectors, (i_tracks + 1) * sizeof (*buf));
+ vcddev_sector_t *buf = realloc (p_toc->p_sectors,
+ (p_toc->i_tracks + 1) * sizeof (*buf));
if (buf == NULL)
goto error;
- p_sectors = buf;
- p_sectors[i_tracks] = lseek(p_vcddev->i_vcdimage_handle, 0, SEEK_END)
- / VCD_SECTOR_SIZE;
+ p_toc->p_sectors = buf;
+ p_toc->p_sectors[p_toc->i_tracks].i_lba =
+ lseek(p_vcddev->i_vcdimage_handle, 0, SEEK_END) / VCD_SECTOR_SIZE;
+ p_toc->p_sectors[p_toc->i_tracks].i_control = 0x00;
msg_Dbg( p_this, "vcd track %i, begins at sector:%i",
- (int)i_tracks, (int)p_sectors[i_tracks] );
- p_vcddev->i_tracks = ++i_tracks;
- p_vcddev->p_sectors = p_sectors;
- p_sectors = NULL;
+ p_toc->i_tracks, p_toc->p_sectors[p_toc->i_tracks].i_lba );
+ p_toc->i_tracks++;
+ p_toc->i_first_track = 1;
+ p_toc->i_last_track = p_toc->i_tracks;
i_ret = 0;
+ goto end;
error:
+ free( p_toc->p_sectors );
+ memset( p_toc, 0, sizeof(*p_toc) );
+end:
if( cuefile ) fclose( cuefile );
- free( p_sectors );
free( psz_cuefile );
free( psz_vcdfile );
@@ -921,7 +967,7 @@ static void CloseVCDImage( vlc_object_t * p_this, vcddev_t *p_vcddev )
else
return;
- free( p_vcddev->p_sectors );
+ free( p_vcddev->toc.p_sectors );
}
#if defined( __APPLE__ )
@@ -1028,11 +1074,16 @@ static CDTOC *darwin_getTOC( vlc_object_t * p_this, const vcddev_t *p_vcddev )
/****************************************************************************
* darwin_getNumberOfTracks: get number of tracks in TOC
+ * and first and last CDDA ones
****************************************************************************/
-static int darwin_getNumberOfTracks( CDTOC *pTOC, int i_descriptors )
+static int darwin_getNumberOfTracks( CDTOC *pTOC, int i_descriptors,
+ int *pi_first_track,
+ int *pi_last_track )
{
u_char track;
int i, i_tracks = 0;
+ int i_min = CD_MAX_TRACK_NO;
+ int i_max = CD_MIN_TRACK_NO;
CDTOCDescriptor *pTrackDescriptors = NULL;
pTrackDescriptors = (CDTOCDescriptor *)pTOC->descriptors;
@@ -1044,9 +1095,23 @@ static int darwin_getNumberOfTracks( CDTOC *pTOC, int i_descriptors )
if( track > CD_MAX_TRACK_NO || track < CD_MIN_TRACK_NO )
continue;
+ if( pTrackDescriptors[i].adr == 0x01 /* kCDSectorTypeCDDA */ )
+ {
+ i_min = __MIN(i_min, track);
+ i_max = __MAX(i_max, track);
+ }
+
i_tracks++;
}
+ if( i_max < i_min )
+ *pi_first_track = *pi_last_track = 0;
+ else
+ {
+ *pi_first_track = i_min;
+ *pi_last_track = i_max;
+ }
+
return( i_tracks );
}
#endif /* __APPLE__ */
diff --git a/modules/access/vcd/cdrom.h b/modules/access/vcd/cdrom.h
index 18cb5563ae..fe4dc34f4d 100644
--- a/modules/access/vcd/cdrom.h
+++ b/modules/access/vcd/cdrom.h
@@ -73,6 +73,36 @@ static inline int MSF_TO_LBA2(uint8_t min, uint8_t sec, uint8_t frame)
(uint8_t)((uint8_t)(0xf & (uint8_t)i)+((uint8_t)10*((uint8_t)i >> 4)))
typedef struct vcddev_s vcddev_t;
+typedef struct
+{
+ int i_lba;
+ int i_control;
+} vcddev_sector_t;
+
+typedef struct
+{
+ int i_tracks;
+ vcddev_sector_t *p_sectors;
+ int i_first_track;
+ int i_last_track;
+} vcddev_toc_t;
+
+static inline vcddev_toc_t * vcddev_toc_New( void )
+{
+ return calloc(1, sizeof(vcddev_toc_t));
+}
+
+static inline void vcddev_toc_Reset( vcddev_toc_t *toc )
+{
+ free(toc->p_sectors);
+ memset(toc, 0, sizeof(*toc));
+}
+
+static inline void vcddev_toc_Free( vcddev_toc_t *toc )
+{
+ free(toc->p_sectors);
+ free(toc);
+}
/*****************************************************************************
* structure to store minute/second/frame locations
@@ -110,7 +140,7 @@ typedef struct entries_sect_s
*****************************************************************************/
vcddev_t *ioctl_Open ( vlc_object_t *, const char * );
void ioctl_Close ( vlc_object_t *, vcddev_t * );
-int ioctl_GetTracksMap ( vlc_object_t *, const vcddev_t *, int ** );
+vcddev_toc_t * ioctl_GetTOC ( vlc_object_t *, const vcddev_t *, bool );
int ioctl_ReadSectors ( vlc_object_t *, const vcddev_t *,
int, uint8_t *, int, int );
diff --git a/modules/access/vcd/cdrom_internals.h b/modules/access/vcd/cdrom_internals.h
index 3b8e0a1f9c..6178372496 100644
--- a/modules/access/vcd/cdrom_internals.h
+++ b/modules/access/vcd/cdrom_internals.h
@@ -30,8 +30,7 @@ struct vcddev_s
/* Section used in vcd image mode */
int i_vcdimage_handle; /* vcd image file descriptor */
- int i_tracks; /* number of tracks of the vcd */
- int *p_sectors; /* tracks layout on the vcd */
+ vcddev_toc_t toc; /* tracks layout on the vcd */
/* Section used in vcd device mode */
@@ -180,7 +179,7 @@ static void CloseVCDImage( vlc_object_t *, struct vcddev_s * );
#if defined( __APPLE__ )
static CDTOC *darwin_getTOC( vlc_object_t *, const struct vcddev_s * );
-static int darwin_getNumberOfTracks( CDTOC *, int );
+static int darwin_getNumberOfTracks( CDTOC *, int, int *, int * );
#elif defined( _WIN32 )
static int win32_vcd_open( vlc_object_t *, const char *, struct vcddev_s *);
diff --git a/modules/access/vcd/vcd.c b/modules/access/vcd/vcd.c
index 86fd68004c..40c2000448 100644
--- a/modules/access/vcd/vcd.c
+++ b/modules/access/vcd/vcd.c
@@ -68,7 +68,8 @@ typedef struct
uint64_t offset;
/* Title infos */
- int i_titles;
+ vcddev_toc_t *p_toc;
+
struct
{
uint64_t *seekpoints;
@@ -76,9 +77,7 @@ typedef struct
} titles[99]; /* No more that 99 track in a vcd ? */
int i_current_title;
unsigned i_current_seekpoint;
-
int i_sector; /* Current Sector */
- int *p_sectors; /* Track sectors */
} access_sys_t;
static block_t *Block( stream_t *, bool * );
@@ -151,26 +150,28 @@ static int Open( vlc_object_t *p_this )
p_sys->titles[i].seekpoints = NULL;
/* We read the Table Of Content information */
- p_sys->i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
- p_sys->vcddev, &p_sys->p_sectors );
- if( p_sys->i_titles < 0 )
+ p_sys->p_toc = ioctl_GetTOC( VLC_OBJECT(p_access), p_sys->vcddev, true );
+ if( p_sys->p_toc == NULL )
{
msg_Err( p_access, "unable to count tracks" );
goto error;
}
- else if( p_sys->i_titles <= 1 )
+ else if( p_sys->p_toc->i_tracks <= 1 )
{
+ vcddev_toc_Free( p_sys->p_toc );
+ p_sys->p_toc = NULL;
msg_Err( p_access, "no movie tracks found" );
goto error;
}
/* The first title isn't usable */
- p_sys->i_titles--;
+#define USABLE_TITLES(a) (a - 1)
+ //p_sys->i_titles--;
- for( int i = 0; i < p_sys->i_titles; i++ )
+ for( int i = 0; i < USABLE_TITLES(p_sys->p_toc->i_tracks); 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] start=%d", i, p_sys->p_toc->p_sectors[1+i].i_lba );
+ msg_Dbg( p_access, "title[%d] end=%d", i, p_sys->p_toc->p_sectors[i+2].i_lba );
}
/* Map entry points into chapters */
@@ -180,12 +181,12 @@ static int Open( vlc_object_t *p_this )
}
/* Starting title/chapter and sector */
- if( i_title >= p_sys->i_titles )
+ if( i_title > USABLE_TITLES(p_sys->p_toc->i_tracks) )
i_title = 0;
if( (unsigned)i_chapter >= p_sys->titles[i_title].count )
i_chapter = 0;
- p_sys->i_sector = p_sys->p_sectors[1+i_title];
+ p_sys->i_sector = p_sys->p_toc->p_sectors[1+i_title].i_lba;
if( i_chapter > 0 )
p_sys->i_sector += p_sys->titles[i_title].seekpoints[i_chapter]
/ VCD_DATA_SIZE;
@@ -198,7 +199,7 @@ static int Open( vlc_object_t *p_this )
p_sys->i_current_title = i_title;
p_sys->i_current_seekpoint = i_chapter;
- p_sys->offset = (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_toc->p_sectors[1+i_title].i_lba) *
VCD_DATA_SIZE;
return VLC_SUCCESS;
@@ -220,6 +221,8 @@ static void Close( vlc_object_t *p_this )
for( size_t i = 0; i < ARRAY_SIZE(p_sys->titles); i++ )
free( p_sys->titles[i].seekpoints );
+ vcddev_toc_Free( p_sys->p_toc );
+
ioctl_Close( p_this, p_sys->vcddev );
free( p_sys );
}
@@ -247,8 +250,8 @@ static int Control( stream_t *p_access, int i_query, va_list args )
int i = p_sys->i_current_title;
*va_arg( args, uint64_t * ) =
- (p_sys->p_sectors[i + 2] - p_sys->p_sectors[i + 1])
- * (uint64_t)VCD_DATA_SIZE;
+ (p_sys->p_toc->p_sectors[i + 2].i_lba -
+ p_sys->p_toc->p_sectors[i + 1].i_lba) * (uint64_t)VCD_DATA_SIZE;
break;
}
@@ -265,11 +268,12 @@ static int Control( stream_t *p_access, int i_query, va_list args )
case STREAM_GET_TITLE_INFO:
ppp_title = va_arg( args, input_title_t*** );
/* Duplicate title infos */
- *ppp_title = vlc_alloc( p_sys->i_titles, sizeof(input_title_t *) );
+ *ppp_title = vlc_alloc( USABLE_TITLES(p_sys->p_toc->i_tracks),
+ sizeof(input_title_t *) );
if (!*ppp_title)
return VLC_ENOMEM;
- *va_arg( args, int* ) = p_sys->i_titles;
- for( int i = 0; i < p_sys->i_titles; i++ )
+ *va_arg( args, int* ) = USABLE_TITLES(p_sys->p_toc->i_tracks);
+ for( int i = 0; i < USABLE_TITLES(p_sys->p_toc->i_tracks); i++ )
(*ppp_title)[i] = vlc_input_title_New();
break;
@@ -296,7 +300,7 @@ static int Control( stream_t *p_access, int i_query, va_list args )
p_sys->i_current_seekpoint = 0;
/* Next sector to read */
- p_sys->i_sector = p_sys->p_sectors[1+i];
+ p_sys->i_sector = p_sys->p_toc->p_sectors[1+i].i_lba;
}
break;
}
@@ -310,11 +314,11 @@ static int Control( stream_t *p_access, int i_query, va_list args )
{
p_sys->i_current_seekpoint = i;
- p_sys->i_sector = p_sys->p_sectors[1 + i_title] +
+ p_sys->i_sector = p_sys->p_toc->p_sectors[1 + i_title].i_lba +
p_sys->titles[i_title].seekpoints[i] / VCD_DATA_SIZE;
p_sys->offset = (uint64_t)(p_sys->i_sector -
- p_sys->p_sectors[1 + i_title]) * VCD_DATA_SIZE;
+ p_sys->p_toc->p_sectors[1 + i_title].i_lba) * VCD_DATA_SIZE;
}
break;
}
@@ -331,13 +335,14 @@ static int Control( stream_t *p_access, int i_query, va_list args )
static block_t *Block( stream_t *p_access, bool *restrict eof )
{
access_sys_t *p_sys = p_access->p_sys;
+ const vcddev_toc_t *p_toc = p_sys->p_toc;
int i_blocks = VCD_BLOCKS_ONCE;
block_t *p_block;
/* Check end of title */
- while( p_sys->i_sector >= p_sys->p_sectors[p_sys->i_current_title + 2] )
+ while( p_sys->i_sector >= p_toc->p_sectors[p_sys->i_current_title + 2].i_lba )
{
- if( p_sys->i_current_title + 2 >= p_sys->i_titles )
+ if( p_sys->i_current_title + 2 >= USABLE_TITLES(p_toc->i_tracks) )
{
*eof = true;
return NULL;
@@ -350,9 +355,9 @@ static block_t *Block( stream_t *p_access, bool *restrict eof )
/* Don't read after the end of a title */
if( p_sys->i_sector + i_blocks >=
- p_sys->p_sectors[p_sys->i_current_title + 2] )
+ p_toc->p_sectors[p_sys->i_current_title + 2].i_lba )
{
- i_blocks = p_sys->p_sectors[p_sys->i_current_title + 2 ] - p_sys->i_sector;
+ i_blocks = p_toc->p_sectors[p_sys->i_current_title + 2 ].i_lba - p_sys->i_sector;
}
/* Do the actual reading */
@@ -403,12 +408,13 @@ static block_t *Block( stream_t *p_access, bool *restrict eof )
static int Seek( stream_t *p_access, uint64_t i_pos )
{
access_sys_t *p_sys = p_access->p_sys;
+ const vcddev_toc_t *p_toc = p_sys->p_toc;
int i_title = p_sys->i_current_title;
unsigned i_seekpoint;
/* Next sector to read */
p_sys->offset = i_pos;
- p_sys->i_sector = i_pos / VCD_DATA_SIZE + p_sys->p_sectors[i_title + 1];
+ p_sys->i_sector = i_pos / VCD_DATA_SIZE + p_toc->p_sectors[i_title + 1].i_lba;
/* Update current seekpoint */
for( i_seekpoint = 0; i_seekpoint < p_sys->titles[i_title].count; i_seekpoint++ )
@@ -433,6 +439,7 @@ static int Seek( stream_t *p_access, uint64_t i_pos )
static int EntryPoints( stream_t *p_access )
{
access_sys_t *p_sys = p_access->p_sys;
+ const vcddev_toc_t *p_toc = p_sys->p_toc;
uint8_t sector[VCD_DATA_SIZE];
entries_sect_t entries;
@@ -469,7 +476,7 @@ static int EntryPoints( stream_t *p_access )
BCD_TO_BIN( entries.entry[i].msf.second ),
BCD_TO_BIN( entries.entry[i].msf.frame ) ));
if( i_title < 0 ) continue; /* Should not occur */
- if( i_title >= p_sys->i_titles ) continue;
+ if( i_title >= USABLE_TITLES(p_toc->i_tracks) ) continue;
msg_Dbg( p_access, "Entry[%d] title=%d sector=%d",
i, i_title, i_sector );
@@ -478,7 +485,7 @@ static int EntryPoints( stream_t *p_access )
p_sys->titles[i_title].seekpoints,
sizeof( uint64_t ) * (p_sys->titles[i_title].count + 1) );
p_sys->titles[i_title].seekpoints[p_sys->titles[i_title].count++] =
- (i_sector - p_sys->p_sectors[i_title+1]) * VCD_DATA_SIZE;
+ (i_sector - p_toc->p_sectors[i_title+1].i_lba) * VCD_DATA_SIZE;
}
return VLC_SUCCESS;
More information about the vlc-commits
mailing list