dvb: don't preparse
[vlc.git] / modules / access / cdda.c
1 /*****************************************************************************
2  * cdda.c : CD digital audio input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2000, 2003-2006, 2008-2009 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /**
26  * Todo:
27  *   - Improve CDDB support (non-blocking, ...)
28  *   - Fix tracknumber in MRL
29  */
30
31 /*****************************************************************************
32  * Preamble
33  *****************************************************************************/
34
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #endif
38 #include <assert.h>
39
40 #include <vlc_common.h>
41 #include <vlc_plugin.h>
42 #include <vlc_input.h>
43 #include <vlc_access.h>
44 #include <vlc_meta.h>
45 #include <vlc_charset.h> /* ToLocaleDup */
46
47 #include <vlc_codecs.h> /* For WAVEHEADER */
48 #include "vcd/cdrom.h"  /* For CDDA_DATA_SIZE */
49
50 #ifdef HAVE_LIBCDDB
51  #include <cddb/cddb.h>
52  #include <errno.h>
53 #endif
54
55 /*****************************************************************************
56  * Module descriptior
57  *****************************************************************************/
58 static int  Open ( vlc_object_t * );
59 static void Close( vlc_object_t * );
60
61 #define CDAUDIO_DEV_TEXT N_("Audio CD device")
62 #if defined( _WIN32 ) || defined( __OS2__ )
63 # define CDAUDIO_DEV_LONGTEXT N_( \
64     "This is the default Audio CD drive (or file) to use. Don't forget the " \
65     "colon after the drive letter (e.g. D:)")
66 # define CD_DEVICE      "D:"
67 #else
68 # define CDAUDIO_DEV_LONGTEXT N_( \
69     "This is the default Audio CD device to use." )
70 # if defined(__OpenBSD__)
71 #  define CD_DEVICE      "/dev/cd0c"
72 # elif defined(__linux__)
73 #  define CD_DEVICE      "/dev/sr0"
74 # else
75 #  define CD_DEVICE      "/dev/cdrom"
76 # endif
77 #endif
78
79 vlc_module_begin ()
80     set_shortname( N_("Audio CD") )
81     set_description( N_("Audio CD input") )
82     set_capability( "access", 10 )
83     set_category( CAT_INPUT )
84     set_subcategory( SUBCAT_INPUT_ACCESS )
85     set_callbacks( Open, Close )
86
87     add_loadfile( "cd-audio", CD_DEVICE, CDAUDIO_DEV_TEXT,
88                   CDAUDIO_DEV_LONGTEXT, false )
89
90     add_usage_hint( N_("[cdda:][device][@[track]]") )
91     add_integer( "cdda-track", 0 , NULL, NULL, true )
92         change_volatile ()
93     add_integer( "cdda-first-sector", -1, NULL, NULL, true )
94         change_volatile ()
95     add_integer( "cdda-last-sector", -1, NULL, NULL, true )
96         change_volatile ()
97
98 #ifdef HAVE_LIBCDDB
99     add_string( "cddb-server", "freedb.videolan.org", N_( "CDDB Server" ),
100             N_( "Address of the CDDB server to use." ), true )
101     add_integer( "cddb-port", 80, N_( "CDDB port" ),
102             N_( "CDDB Server port to use." ), true )
103         change_integer_range( 1, 65535 )
104 #endif
105
106     add_shortcut( "cdda", "cddasimple" )
107 vlc_module_end ()
108
109
110 /* how many blocks VCDRead will read in each loop */
111 #define CDDA_BLOCKS_ONCE 20
112 #define CDDA_DATA_ONCE   (CDDA_BLOCKS_ONCE * CDDA_DATA_SIZE)
113
114 /*****************************************************************************
115  * Access: local prototypes
116  *****************************************************************************/
117 struct access_sys_t
118 {
119     vcddev_t    *vcddev;                            /* vcd device descriptor */
120     uint64_t    size;
121
122     /* Current position */
123     int         i_sector;                                  /* Current Sector */
124     int        *p_sectors;                                  /* Track sectors */
125
126     /* Wave header for the output data */
127     WAVEHEADER  waveheader;
128     bool        b_header;
129
130     int         i_track;
131     int         i_first_sector;
132     int         i_last_sector;
133 };
134
135 static block_t *Block( access_t * );
136 static int      Seek( access_t *, uint64_t );
137 static int      Control( access_t *, int, va_list );
138
139 static int GetTracks( access_t *p_access, input_item_t *p_current );
140
141 #ifdef HAVE_LIBCDDB
142 static cddb_disc_t *GetCDDBInfo( access_t *p_access, int i_titles, int *p_sectors );
143 #endif
144
145 /*****************************************************************************
146  * Open: open cdda
147  *****************************************************************************/
148 static int Open( vlc_object_t *p_this )
149 {
150     access_t     *p_access = (access_t*)p_this;
151     vcddev_t     *vcddev;
152     char         *psz_name;
153
154     if( !p_access->psz_filepath || !*p_access->psz_filepath )
155     {
156         psz_name = var_InheritString( p_this, "cd-audio" );
157         if( !psz_name )
158             return VLC_EGENERIC;
159     }
160     else psz_name = ToLocaleDup( p_access->psz_filepath );
161
162 #if defined( _WIN32 ) || defined( __OS2__ )
163     if( psz_name[0] && psz_name[1] == ':' &&
164         psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0';
165 #endif
166
167     access_sys_t *p_sys = calloc( 1, sizeof (*p_sys) );
168     if( unlikely(p_sys == NULL) )
169     {
170         free( psz_name );
171         return VLC_ENOMEM;
172     }
173     p_access->p_sys = p_sys;
174
175     /* Open CDDA */
176     vcddev = ioctl_Open( VLC_OBJECT(p_access), psz_name );
177     if( vcddev == NULL )
178         msg_Warn( p_access, "could not open %s", psz_name );
179     free( psz_name );
180     if( vcddev == NULL )
181     {
182         free( p_sys );
183         return VLC_EGENERIC;
184     }
185
186     p_sys->vcddev = vcddev;
187
188     /* Do we play a single track ? */
189     p_sys->i_track = var_InheritInteger( p_access, "cdda-track" ) - 1;
190
191     if( p_sys->i_track < 0 )
192     {
193         /* We only do separate items if the whole disc is requested */
194         input_thread_t *p_input = p_access->p_input;
195
196         int i_ret = -1;
197         if( p_input )
198         {
199             input_item_t *p_current = input_GetItem( p_input );
200             if( p_current )
201                 i_ret = GetTracks( p_access, p_current );
202         }
203         if( i_ret < 0 )
204             goto error;
205     }
206     else
207     {
208         /* Build a WAV header for the output data */
209         memset( &p_sys->waveheader, 0, sizeof(WAVEHEADER) );
210         SetWLE( &p_sys->waveheader.Format, 1 ); /*WAVE_FORMAT_PCM*/
211         SetWLE( &p_sys->waveheader.BitsPerSample, 16);
212         p_sys->waveheader.MainChunkID = VLC_FOURCC('R', 'I', 'F', 'F');
213         p_sys->waveheader.Length = 0;               /* we just don't know */
214         p_sys->waveheader.ChunkTypeID = VLC_FOURCC('W', 'A', 'V', 'E');
215         p_sys->waveheader.SubChunkID = VLC_FOURCC('f', 'm', 't', ' ');
216         SetDWLE( &p_sys->waveheader.SubChunkLength, 16);
217         SetWLE( &p_sys->waveheader.Modus, 2);
218         SetDWLE( &p_sys->waveheader.SampleFreq, 44100);
219         SetWLE( &p_sys->waveheader.BytesPerSample,
220                     2 /*Modus*/ * 16 /*BitsPerSample*/ / 8 );
221         SetDWLE( &p_sys->waveheader.BytesPerSec,
222                     2*16/8 /*BytesPerSample*/ * 44100 /*SampleFreq*/ );
223         p_sys->waveheader.DataChunkID = VLC_FOURCC('d', 'a', 't', 'a');
224         p_sys->waveheader.DataLength = 0;           /* we just don't know */
225
226         p_sys->i_first_sector = var_InheritInteger( p_access,
227                                                     "cdda-first-sector" );
228         p_sys->i_last_sector  = var_InheritInteger( p_access,
229                                                     "cdda-last-sector" );
230         /* Tracknumber in MRL */
231         if( p_sys->i_first_sector < 0 || p_sys->i_last_sector < 0 )
232         {
233             const int i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
234                                                      p_sys->vcddev, &p_sys->p_sectors );
235             if( p_sys->i_track >= i_titles )
236             {
237                 msg_Err( p_access, "invalid track number" );
238                 goto error;
239             }
240             p_sys->i_first_sector = p_sys->p_sectors[p_sys->i_track];
241             p_sys->i_last_sector = p_sys->p_sectors[p_sys->i_track+1];
242         }
243
244         p_sys->i_sector = p_sys->i_first_sector;
245         p_sys->size = (p_sys->i_last_sector - p_sys->i_first_sector)
246                                      * (int64_t)CDDA_DATA_SIZE;
247     }
248
249     /* Set up p_access */
250     access_InitFields( p_access );
251     ACCESS_SET_CALLBACKS( NULL, Block, Control, Seek );
252     return VLC_SUCCESS;
253
254 error:
255     free( p_sys->p_sectors );
256     ioctl_Close( VLC_OBJECT(p_access), p_sys->vcddev );
257     free( p_sys );
258     return VLC_EGENERIC;
259 }
260
261 /*****************************************************************************
262  * Close: closes cdda
263  *****************************************************************************/
264 static void Close( vlc_object_t *p_this )
265 {
266     access_t     *p_access = (access_t *)p_this;
267     access_sys_t *p_sys = p_access->p_sys;
268
269     free( p_sys->p_sectors );
270     ioctl_Close( p_this, p_sys->vcddev );
271     free( p_sys );
272 }
273
274 /*****************************************************************************
275  * Block: read data (CDDA_DATA_ONCE)
276  *****************************************************************************/
277 static block_t *Block( access_t *p_access )
278 {
279     access_sys_t *p_sys = p_access->p_sys;
280     int i_blocks = CDDA_BLOCKS_ONCE;
281     block_t *p_block;
282
283     if( p_sys->i_track < 0 ) p_access->info.b_eof = true;
284
285     /* Check end of file */
286     if( p_access->info.b_eof ) return NULL;
287
288     if( !p_sys->b_header )
289     {
290         /* Return only the header */
291         p_block = block_Alloc( sizeof( WAVEHEADER ) );
292         memcpy( p_block->p_buffer, &p_sys->waveheader, sizeof(WAVEHEADER) );
293         p_sys->b_header = true;
294         return p_block;
295     }
296
297     if( p_sys->i_sector >= p_sys->i_last_sector )
298     {
299         p_access->info.b_eof = true;
300         return NULL;
301     }
302
303     /* Don't read too far */
304     if( p_sys->i_sector + i_blocks >= p_sys->i_last_sector )
305         i_blocks = p_sys->i_last_sector - p_sys->i_sector;
306
307     /* Do the actual reading */
308     if( !( p_block = block_Alloc( i_blocks * CDDA_DATA_SIZE ) ) )
309     {
310         msg_Err( p_access, "cannot get a new block of size: %i",
311                  i_blocks * CDDA_DATA_SIZE );
312         return NULL;
313     }
314
315     if( ioctl_ReadSectors( VLC_OBJECT(p_access), p_sys->vcddev,
316             p_sys->i_sector, p_block->p_buffer, i_blocks, CDDA_TYPE ) < 0 )
317     {
318         msg_Err( p_access, "cannot read sector %i", p_sys->i_sector );
319         block_Release( p_block );
320
321         /* Try to skip one sector (in case of bad sectors) */
322         p_sys->i_sector++;
323         return NULL;
324     }
325
326     /* Update a few values */
327     p_sys->i_sector += i_blocks;
328
329     return p_block;
330 }
331
332 /****************************************************************************
333  * Seek
334  ****************************************************************************/
335 static int Seek( access_t *p_access, uint64_t i_pos )
336 {
337     access_sys_t *p_sys = p_access->p_sys;
338
339     /* Next sector to read */
340     p_sys->i_sector = p_sys->i_first_sector + i_pos / CDDA_DATA_SIZE;
341     assert( p_sys->i_sector >= 0 );
342
343     return VLC_SUCCESS;
344 }
345
346 /*****************************************************************************
347  * Control:
348  *****************************************************************************/
349 static int Control( access_t *p_access, int i_query, va_list args )
350 {
351     switch( i_query )
352     {
353         case ACCESS_CAN_SEEK:
354         case ACCESS_CAN_FASTSEEK:
355         case ACCESS_CAN_PAUSE:
356         case ACCESS_CAN_CONTROL_PACE:
357             *va_arg( args, bool* ) = true;
358             break;
359         case ACCESS_GET_SIZE:
360             *va_arg( args, uint64_t * ) = p_access->p_sys->size;
361             break;
362         case ACCESS_GET_PTS_DELAY:
363             *va_arg( args, int64_t * ) =
364                 INT64_C(1000) * var_InheritInteger( p_access, "disc-caching" );
365             break;
366
367         case ACCESS_SET_PAUSE_STATE:
368             break;
369
370         default:
371             return VLC_EGENERIC;
372     }
373     return VLC_SUCCESS;
374 }
375
376 static int GetTracks( access_t *p_access, input_item_t *p_current )
377 {
378     access_sys_t *p_sys = p_access->p_sys;
379
380     const int i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
381                                              p_sys->vcddev, &p_sys->p_sectors );
382     if( i_titles <= 0 )
383     {
384         if( i_titles < 0 )
385             msg_Err( p_access, "unable to count tracks" );
386         else if( i_titles <= 0 )
387             msg_Err( p_access, "no audio tracks found" );
388         return VLC_EGENERIC;;
389     }
390
391     /* */
392     input_item_SetName( p_current, "Audio CD" );
393
394     const char *psz_album = NULL;
395     const char *psz_year = NULL;
396     const char *psz_genre = NULL;
397     const char *psz_artist = NULL;
398     const char *psz_description = NULL;
399
400 /* Return true if the given string is not NULL and not empty */
401 #define NONEMPTY( psz ) ( (psz) && *(psz) )
402 /* If the given string is NULL or empty, fill it by the return value of 'code' */
403 #define ON_EMPTY( psz, code ) do { if( !NONEMPTY( psz) ) { (psz) = code; } } while(0)
404
405     /* Retreive CDDB information */
406 #ifdef HAVE_LIBCDDB
407     char psz_year_buffer[4+1];
408     msg_Dbg( p_access, "fetching infos with CDDB" );
409     cddb_disc_t *p_disc = GetCDDBInfo( p_access, i_titles, p_sys->p_sectors );
410     if( p_disc )
411     {
412         msg_Dbg( p_access, "Disc ID: %08x", cddb_disc_get_discid( p_disc ) );
413         psz_album = cddb_disc_get_title( p_disc );
414         psz_genre = cddb_disc_get_genre( p_disc );
415
416         /* */
417         const unsigned i_year = cddb_disc_get_year( p_disc );
418         if( i_year > 0 )
419         {
420             psz_year = psz_year_buffer;
421             snprintf( psz_year_buffer, sizeof(psz_year_buffer), "%u", i_year );
422         }
423
424         /* Set artist only if unique */
425         for( int i = 0; i < i_titles; i++ )
426         {
427             cddb_track_t *t = cddb_disc_get_track( p_disc, i );
428             if( !t )
429                 continue;
430             const char *psz_track_artist = cddb_track_get_artist( t );
431             if( psz_artist && psz_track_artist &&
432                 strcmp( psz_artist, psz_track_artist ) )
433             {
434                 psz_artist = NULL;
435                 break;
436             }
437             psz_artist = psz_track_artist;
438         }
439     }
440     else
441         msg_Dbg( p_access, "GetCDDBInfo failed" );
442 #endif
443
444     /* CD-Text */
445     vlc_meta_t **pp_cd_text;
446     int        i_cd_text;
447
448     if( ioctl_GetCdText( VLC_OBJECT(p_access), p_sys->vcddev, &pp_cd_text, &i_cd_text ) )
449     {
450         msg_Dbg( p_access, "CD-TEXT information missing" );
451         i_cd_text = 0;
452         pp_cd_text = NULL;
453     }
454
455     /* Retrieve CD-TEXT information but prefer CDDB */
456     if( i_cd_text > 0 && pp_cd_text[0] )
457     {
458         const vlc_meta_t *p_disc = pp_cd_text[0];
459         ON_EMPTY( psz_album,       vlc_meta_Get( p_disc, vlc_meta_Album ) );
460         ON_EMPTY( psz_genre,       vlc_meta_Get( p_disc, vlc_meta_Genre ) );
461         ON_EMPTY( psz_artist,      vlc_meta_Get( p_disc, vlc_meta_Artist ) );
462         ON_EMPTY( psz_description, vlc_meta_Get( p_disc, vlc_meta_Description ) );
463     }
464
465     if( NONEMPTY( psz_album ) )
466     {
467         input_item_SetName( p_current, psz_album );
468         input_item_SetAlbum( p_current, psz_album );
469     }
470
471     if( NONEMPTY( psz_genre ) )
472         input_item_SetGenre( p_current, psz_genre );
473
474     if( NONEMPTY( psz_artist ) )
475         input_item_SetArtist( p_current, psz_artist );
476
477     if( NONEMPTY( psz_year ) )
478         input_item_SetDate( p_current, psz_year );
479
480     if( NONEMPTY( psz_description ) )
481         input_item_SetDescription( p_current, psz_description );
482
483     const mtime_t i_duration = (int64_t)( p_sys->p_sectors[i_titles] - p_sys->p_sectors[0] ) *
484                                CDDA_DATA_SIZE * 1000000 / 44100 / 2 / 2;
485     input_item_SetDuration( p_current, i_duration );
486
487     input_item_node_t *p_root = input_item_node_Create( p_current );
488
489     /* Build title table */
490     for( int i = 0; i < i_titles; i++ )
491     {
492         char *psz_opt, *psz_name;
493
494         msg_Dbg( p_access, "track[%d] start=%d", i, p_sys->p_sectors[i] );
495
496         /* Define a "default name" */
497         if( asprintf( &psz_name, _("Audio CD - Track %02i"), (i+1) ) == -1 )
498             psz_name = p_access->psz_url;
499
500         /* Create playlist items */
501         const mtime_t i_duration = (int64_t)( p_sys->p_sectors[i+1] - p_sys->p_sectors[i] ) *
502                                    CDDA_DATA_SIZE * 1000000 / 44100 / 2 / 2;
503
504         input_item_t *p_item = input_item_NewDisc( p_access->psz_url,
505                                                    psz_name, i_duration );
506         if( likely(psz_name != p_access->psz_url) )
507             free( psz_name );
508
509         if( unlikely(p_item == NULL) )
510             continue;
511
512         input_item_CopyOptions( p_item, p_current );
513
514         if( likely(asprintf( &psz_opt, "cdda-track=%i", i+1 ) != -1) )
515         {
516             input_item_AddOption( p_item, psz_opt, VLC_INPUT_OPTION_TRUSTED );
517             free( psz_opt );
518         }
519         if( likely(asprintf( &psz_opt, "cdda-first-sector=%i",
520                              p_sys->p_sectors[i] ) != -1) )
521         {
522             input_item_AddOption( p_item, psz_opt, VLC_INPUT_OPTION_TRUSTED );
523             free( psz_opt );
524         }
525         if( likely(asprintf( &psz_opt, "cdda-last-sector=%i",
526                              p_sys->p_sectors[i+1] ) != -1) )
527         {
528             input_item_AddOption( p_item, psz_opt, VLC_INPUT_OPTION_TRUSTED );
529             free( psz_opt );
530         }
531
532         const char *psz_track_title = NULL;
533         const char *psz_track_artist = NULL;
534         const char *psz_track_genre = NULL;
535         const char *psz_track_description = NULL;
536
537 #ifdef HAVE_LIBCDDB
538         /* Retreive CDDB information */
539         if( p_disc )
540         {
541             cddb_track_t *t = cddb_disc_get_track( p_disc, i );
542             if( t != NULL )
543             {
544                 psz_track_title = cddb_track_get_title( t );
545                 psz_track_artist = cddb_track_get_artist( t );
546             }
547         }
548 #endif
549
550         /* Retreive CD-TEXT information but prefer CDDB */
551         if( i+1 < i_cd_text && pp_cd_text[i+1] )
552         {
553             const vlc_meta_t *t = pp_cd_text[i+1];
554
555             ON_EMPTY( psz_track_title,       vlc_meta_Get( t, vlc_meta_Title ) );
556             ON_EMPTY( psz_track_artist,      vlc_meta_Get( t, vlc_meta_Artist ) );
557             ON_EMPTY( psz_track_genre,       vlc_meta_Get( t, vlc_meta_Genre ) );
558             ON_EMPTY( psz_track_description, vlc_meta_Get( t, vlc_meta_Description ) );
559         }
560
561         /* */
562         ON_EMPTY( psz_track_artist,       psz_artist );
563         ON_EMPTY( psz_track_genre,        psz_genre );
564         ON_EMPTY( psz_track_description,  psz_description );
565
566         /* */
567         if( NONEMPTY( psz_track_title ) )
568         {
569             input_item_SetName( p_item, psz_track_title );
570             input_item_SetTitle( p_item, psz_track_title );
571         }
572
573         if( NONEMPTY( psz_track_artist ) )
574             input_item_SetArtist( p_item, psz_track_artist );
575
576         if( NONEMPTY( psz_track_genre ) )
577             input_item_SetGenre( p_item, psz_track_genre );
578
579         if( NONEMPTY( psz_track_description ) )
580             input_item_SetDescription( p_item, psz_track_description );
581
582         if( NONEMPTY( psz_album ) )
583             input_item_SetAlbum( p_item, psz_album );
584
585         if( NONEMPTY( psz_year ) )
586             input_item_SetDate( p_item, psz_year );
587
588         char psz_num[3+1];
589         snprintf( psz_num, sizeof(psz_num), "%d", 1+i );
590         input_item_SetTrackNum( p_item, psz_num );
591
592         input_item_node_AppendItem( p_root, p_item );
593         vlc_gc_decref( p_item );
594     }
595 #undef ON_EMPTY
596 #undef NONEMPTY
597
598     input_item_node_PostAndDelete( p_root );
599
600     /* */
601     for( int i = 0; i < i_cd_text; i++ )
602     {
603         vlc_meta_t *p_meta = pp_cd_text[i];
604         if( !p_meta )
605             continue;
606         vlc_meta_Delete( p_meta );
607     }
608     free( pp_cd_text );
609
610 #ifdef HAVE_LIBCDDB
611     if( p_disc )
612         cddb_disc_destroy( p_disc );
613 #endif
614     return VLC_SUCCESS;
615 }
616
617 #ifdef HAVE_LIBCDDB
618 static cddb_disc_t *GetCDDBInfo( access_t *p_access, int i_titles, int *p_sectors )
619 {
620     if( var_InheritInteger( p_access, "album-art" ) != ALBUM_ART_ALL &&
621         !  var_InheritBool( p_access, "metadata-network-access" ) )
622     {
623         msg_Dbg( p_access, "Album art policy set to manual; no automatic fetching" );
624         return NULL;
625     }
626
627     /* */
628     cddb_conn_t *p_cddb = cddb_new();
629     if( !p_cddb )
630     {
631         msg_Warn( p_access, "unable to use CDDB" );
632         return NULL;
633     }
634
635     /* */
636
637     cddb_http_enable( p_cddb );
638
639     char *psz_tmp = var_InheritString( p_access, "cddb-server" );
640     if( psz_tmp )
641     {
642         cddb_set_server_name( p_cddb, psz_tmp );
643         free( psz_tmp );
644     }
645
646     cddb_set_server_port( p_cddb, var_InheritInteger( p_access, "cddb-port" ) );
647
648     cddb_set_email_address( p_cddb, "vlc@videolan.org" );
649
650     cddb_set_http_path_query( p_cddb, "/~cddb/cddb.cgi" );
651     cddb_set_http_path_submit( p_cddb, "/~cddb/submit.cgi" );
652
653
654     char *psz_cachedir;
655     char *psz_temp = config_GetUserDir( VLC_CACHE_DIR );
656
657     if( asprintf( &psz_cachedir, "%s" DIR_SEP "cddb", psz_temp ) > 0 ) {
658         cddb_cache_enable( p_cddb );
659         cddb_cache_set_dir( p_cddb, psz_cachedir );
660         free( psz_cachedir );
661     }
662     free( psz_temp );
663
664     cddb_set_timeout( p_cddb, 10 );
665
666     /* */
667     cddb_disc_t *p_disc = cddb_disc_new();
668     if( !p_disc )
669     {
670         msg_Err( p_access, "unable to create CDDB disc structure." );
671         goto error;
672     }
673
674     int64_t i_length = 2000000; /* PreGap */
675     for( int i = 0; i < i_titles; i++ )
676     {
677         cddb_track_t *t = cddb_track_new();
678         cddb_track_set_frame_offset( t, p_sectors[i] + 150 );  /* Pregap offset */
679
680         cddb_disc_add_track( p_disc, t );
681         const int64_t i_size = ( p_sectors[i+1] - p_sectors[i] ) *
682                                (int64_t)CDDA_DATA_SIZE;
683         i_length += INT64_C(1000000) * i_size / 44100 / 4  ;
684
685         msg_Dbg( p_access, "Track %i offset: %i", i, p_sectors[i] + 150 );
686     }
687
688     msg_Dbg( p_access, "Total length: %i", (int)(i_length/1000000) );
689     cddb_disc_set_length( p_disc, (int)(i_length/1000000) );
690
691     if( !cddb_disc_calc_discid( p_disc ) )
692     {
693         msg_Err( p_access, "CDDB disc ID calculation failed" );
694         goto error;
695     }
696
697     const int i_matches = cddb_query( p_cddb, p_disc );
698     if( i_matches < 0 )
699     {
700         msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno) );
701         goto error;
702     }
703     else if( i_matches == 0 )
704     {
705         msg_Dbg( p_access, "Couldn't find any matches in CDDB." );
706         goto error;
707     }
708     else if( i_matches > 1 )
709         msg_Warn( p_access, "found %d matches in CDDB. Using first one.", i_matches );
710
711     cddb_read( p_cddb, p_disc );
712
713     cddb_destroy( p_cddb);
714     return p_disc;
715
716 error:
717     if( p_disc )
718         cddb_disc_destroy( p_disc );
719     cddb_destroy( p_cddb );
720     return NULL;
721 }
722 #endif /*HAVE_LIBCDDB*/
723