+
+static int GetTracks( access_t *p_access,
+ playlist_t *p_playlist, playlist_item_t *p_parent )
+{
+ access_sys_t *p_sys = p_access->p_sys;
+ int i, i_titles;
+ input_item_t *p_input_item;
+ playlist_item_t *p_item_in_category;
+ char *psz_name;
+ i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
+ p_sys->vcddev, &p_sys->p_sectors );
+ if( i_titles < 0 )
+ {
+ msg_Err( p_access, "unable to count tracks" );
+ return VLC_EGENERIC;;
+ }
+ else if( i_titles <= 0 )
+ {
+ msg_Err( p_access, "no audio tracks found" );
+ return VLC_EGENERIC;
+ }
+
+ p_item_in_category = playlist_ItemToNode( p_playlist, p_parent, pl_Unlocked );
+ playlist_ItemSetName( p_parent, "Audio CD" );
+ var_SetInteger( p_playlist, "item-change", p_parent->p_input->i_id );
+
+#ifdef HAVE_LIBCDDB
+ GetCDDBInfo( p_access, i_titles, p_sys->p_sectors );
+ if( p_sys->p_disc )
+ {
+ if( cddb_disc_get_title( p_sys->p_disc ) )
+ {
+ const char *psz_name = cddb_disc_get_title( p_sys->p_disc );
+ playlist_ItemSetName( p_parent, psz_name );
+ var_SetInteger( p_playlist, "item-change",
+ p_parent->p_input->i_id );
+ }
+ }
+#endif
+
+ /* Build title table */
+ for( i = 0; i < i_titles; i++ )
+ {
+ msg_Dbg( p_access, "track[%d] start=%d", i, p_sys->p_sectors[i] );
+ char *psz_uri, *psz_opt, *psz_first, *psz_last;
+ int i_path_len = p_access->psz_path ? strlen( p_access->psz_path ) : 0;
+
+ psz_name = (char*)malloc( strlen( _("Audio CD - Track ") ) + 5 );
+ psz_opt = (char*)malloc( strlen( "cdda-track=" ) + 3 );
+ psz_first = (char*)malloc( strlen( "cdda-first-sector=" ) + 7 );
+ psz_last = (char*)malloc( strlen( "cdda-last-sector=" ) + 7 );
+ psz_uri = (char*)malloc( i_path_len + 13 );
+
+ snprintf( psz_uri, i_path_len + 13, "cdda://%s",
+ p_access->psz_path ? p_access->psz_path : "" );
+ sprintf( psz_opt, "cdda-track=%i", i+1 );
+ sprintf( psz_first, "cdda-first-sector=%i",p_sys->p_sectors[i] );
+
+// if( i != i_titles -1 )
+ sprintf( psz_last, "cdda-last-sector=%i", p_sys->p_sectors[i+1] );
+// else
+// sprintf( psz_last, "cdda-last-sector=%i", 1242 /* FIXME */);
+
+ /* Define a "default name" */
+ sprintf( psz_name, _("Audio CD - Track %i"), (i+1) );
+
+ /* Create playlist items */
+ p_input_item = input_ItemNewWithType( VLC_OBJECT( p_playlist ),
+ psz_uri, psz_name, 0, NULL, -1,
+ ITEM_TYPE_DISC );
+ input_ItemAddOption( p_input_item, psz_first );
+ input_ItemAddOption( p_input_item, psz_last );
+ input_ItemAddOption( p_input_item, psz_opt );
+
+#ifdef HAVE_LIBCDDB
+ /* If we have CDDB info, change the name */
+ if( p_sys->p_disc )
+ {
+ cddb_track_t *t = cddb_disc_get_track( p_sys->p_disc, i );
+ if( t!= NULL )
+ {
+ if( cddb_track_get_title( t ) != NULL )
+ {
+ free( p_input_item->psz_name );
+ p_input_item->psz_name = strdup( cddb_track_get_title( t ) );
+ input_item_SetTitle( p_input_item, cddb_track_get_title( t ) );
+ }
+ if( cddb_track_get_artist( t ) != NULL )
+ {
+ input_item_SetArtist( p_input_item, cddb_track_get_artist( t ) );
+ }
+ }
+ }
+#endif
+ int i_ret = playlist_BothAddInput( p_playlist, p_input_item,
+ p_item_in_category,
+ PLAYLIST_APPEND, PLAYLIST_END, NULL, NULL,
+ pl_Unlocked );
+ vlc_gc_decref( p_input_item );
+ free( psz_uri ); free( psz_opt ); free( psz_name );
+ free( psz_first ); free( psz_last );
+ if( i_ret != VLC_SUCCESS )
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
+
+#ifdef HAVE_LIBCDDB
+static void GetCDDBInfo( access_t *p_access, int i_titles, int *p_sectors )
+{
+ int i, i_matches;
+ int64_t i_length = 0, i_size = 0;
+ cddb_conn_t *p_cddb = cddb_new();
+
+ if( !p_cddb )
+ {
+ msg_Warn( p_access, "unable to use CDDB" );
+ goto cddb_destroy;
+ }
+
+ char* psz_tmp = config_GetPsz( p_access, "cddb-server" );
+ cddb_set_email_address( p_cddb, "vlc@videolan.org" );
+ cddb_set_server_name( p_cddb, psz_tmp );
+ cddb_set_server_port( p_cddb, config_GetInt( p_access, "cddb-port" ) );
+ free( psz_tmp );
+
+ /// \todo
+ cddb_cache_disable( p_cddb );
+
+// cddb_cache_set_dir( p_cddb,
+// config_GetPsz( p_access,
+// MODULE_STRING "-cddb-cachedir") );
+
+ cddb_set_timeout( p_cddb, 10 );
+
+ /// \todo
+ cddb_http_disable( p_cddb);
+
+ p_access->p_sys->p_disc = cddb_disc_new();
+
+ if(! p_access->p_sys->p_disc )
+ {
+ msg_Err( p_access, "unable to create CDDB disc structure." );
+ goto cddb_end;
+ }
+
+ for(i = 0; i < i_titles ; i++ )
+ {
+ cddb_track_t *t = cddb_track_new();
+ cddb_track_set_frame_offset(t, p_sectors[i] );
+ cddb_disc_add_track( p_access->p_sys->p_disc, t );
+ i_size = ( p_sectors[i+1] - p_sectors[i] ) *
+ (int64_t)CDDA_DATA_SIZE;
+ i_length += INT64_C(1000000) * i_size / 44100 / 4 ;
+ }
+
+ cddb_disc_set_length( p_access->p_sys->p_disc, (int)(i_length/1000000) );
+
+ if (!cddb_disc_calc_discid(p_access->p_sys->p_disc ))
+ {
+ msg_Err( p_access, "CDDB disc ID calculation failed" );
+ goto cddb_destroy;
+ }
+
+ i_matches = cddb_query( p_cddb, p_access->p_sys->p_disc);
+
+ if (i_matches > 0)
+ {
+ if (i_matches > 1)
+ msg_Warn( p_access, "found %d matches in CDDB. Using first one.",
+ i_matches);
+ cddb_read( p_cddb, p_access->p_sys->p_disc );
+ }
+ else
+ msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
+
+cddb_destroy:
+ cddb_destroy( p_cddb);
+
+cddb_end: ;
+}
+#endif /*HAVE_LIBCDDB*/