vlc | branch: master | Francois Cartegnie <[email protected]> | 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; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
