]> git.sesse.net Git - vlc/blob - modules/access/cdda/info.c
Some compilation fixes when HAVE_LIBCDDB is not defined.
[vlc] / modules / access / cdda / info.c
1 /*****************************************************************************
2  * info.c : CD digital audio input information routines
3  *****************************************************************************
4  * Copyright (C) 2004 VideoLAN
5  * $Id: info.c 8845 2004-09-29 09:00:41Z rocky $
6  *
7  * Authors: Rocky Bernstein <rocky@panix.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include "callback.h"      /* FIXME - reorganize callback.h, cdda.h better */
28 #include "cdda.h"          /* private structures. Also #includes vlc things */
29 #include <vlc_playlist.h>  /* Has to come *after* cdda.h */
30
31 #include <cdio/cdio.h>
32 #include <cdio/cdtext.h>
33 #include <cdio/logging.h>
34 #include <cdio/cd_types.h>
35 #include "info.h"
36
37 #ifdef HAVE_ERRNO_H
38 #   include <errno.h>
39 #endif
40
41 #define CDDA_MRL_PREFIX "cddax://"
42
43 #ifdef HAVE_LIBCDDB
44
45 #define free_and_dup(var, val) \
46   if (var) free(var);          \
47   if (val) var=strdup(val);
48
49
50 static void GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
51 {
52     int i, i_matches;
53     cddb_conn_t  *conn = cddb_new();
54     const CdIo *p_cdio = p_cdda->p_cdio;
55
56     dbg_print( (INPUT_DBG_CALL), "" );
57
58 #ifdef FIXME_NOW
59     cddb_log_set_handler (uninit_log_handler);
60 #endif
61
62     if (!conn)
63     {
64         msg_Warn( p_access, "Unable to initialize libcddb" );
65         goto cddb_destroy;
66     }
67
68     cddb_set_email_address( conn,
69                             config_GetPsz( p_access,
70                                            MODULE_STRING "-cddb-email") );
71     cddb_set_server_name( conn,
72                           config_GetPsz( p_access,
73                                          MODULE_STRING "-cddb-server") );
74     cddb_set_server_port(conn,
75                          config_GetInt( p_access,
76                                         MODULE_STRING "-cddb-port") );
77
78   /* Set the location of the local CDDB cache directory.
79      The default location of this directory is */
80
81     if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
82         cddb_cache_disable(conn);
83
84     cddb_cache_set_dir(conn,
85                      config_GetPsz( p_access,
86                                     MODULE_STRING "-cddb-cachedir") );
87
88     cddb_set_timeout(conn,
89                    config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
90
91
92     if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
93     {
94         cddb_http_enable(conn);
95     }
96     else
97     {
98         cddb_http_disable(conn);
99     }
100
101     p_cdda->cddb.disc = cddb_disc_new();
102
103     if (!p_cdda->cddb.disc)
104     {
105         msg_Err( p_access, "Unable to create CDDB disc structure." );
106         goto cddb_end;
107     }
108
109     for(i = 0; i < p_cdda->i_tracks; i++)
110     {
111         track_t i_track =  p_cdda->i_first_track + i;
112         cddb_track_t *t = cddb_track_new();
113         t->frame_offset = cdio_get_track_lba(p_cdio, i_track);
114         cddb_disc_add_track(p_cdda->cddb.disc, t);
115     }
116
117     p_cdda->cddb.disc->length =
118         cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
119         / CDIO_CD_FRAMES_PER_SEC;
120
121     if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
122     {
123         msg_Err( p_access, "CDDB disc ID calculation failed" );
124         goto cddb_destroy;
125     }
126
127     i_matches = cddb_query(conn, p_cdda->cddb.disc);
128
129     if (i_matches > 0)
130     {
131         if (i_matches > 1)
132              msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
133                                  i_matches);
134         cddb_read(conn, p_cdda->cddb.disc);
135
136         if (p_cdda->i_debug & INPUT_DBG_CDDB)
137             cddb_disc_print(p_cdda->cddb.disc);
138
139     }
140     else
141     {
142         msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
143     }
144
145 cddb_destroy:
146     cddb_destroy(conn);
147
148 cddb_end: ;
149 }
150 #endif /*HAVE_LIBCDDB*/
151
152 #define add_meta_val(FIELD, VLC_META, VAL)                              \
153   if ( p_cdda->p_meta && VAL) {                                         \
154     vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL );                      \
155     dbg_print( INPUT_DBG_META, "field %s: %s\n", VLC_META, VAL );       \
156   }                                                                     \
157
158 #define add_cddb_meta(FIELD, VLC_META)                                  \
159   add_meta_val(FIELD, VLC_META, p_cdda->cddb.disc->FIELD);
160
161 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META)                 \
162   {                                                                     \
163     char psz_buf[100];                                                  \
164     snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC,                  \
165               p_cdda->cddb.disc->FIELD );                               \
166     psz_buf[sizeof(psz_buf)-1] = '\0';                                  \
167     add_meta_val(FIELD, VLC_META, psz_buf);                             \
168   }
169
170 /* Adds a string-valued entry to the stream and media information if
171    the string is not null or the null string.
172  */
173 #define add_info_str(CATEGORY, TITLE, FIELD)                      \
174   if (FIELD && strlen(FIELD)) {                                   \
175     input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY,     \
176                    _(TITLE), "%s", FIELD );                       \
177   }
178
179 /* Adds a numeric-valued entry to the stream and media information
180    if the number is not zero. */
181 #define add_info_val(CATEGORY, TITLE, FMT, FIELD)                 \
182   if (FIELD) {                                                    \
183     input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY,     \
184                    _(TITLE), FMT, FIELD );                        \
185   }
186
187 /* Adds a CDDB string-valued entry to the stream and media information
188    under category "Disc" if the string is not null or the null string.
189  */
190 #define add_cddb_disc_info_str(TITLE, FIELD)                    \
191   add_info_str("Disc", TITLE, p_cdda->cddb.disc->FIELD)
192
193 /* Adds a CDDB numeric-valued entry to the stream and media information
194    under category "Disc" if the string is not null or the null string.
195  */
196 #define add_cddb_disc_info_val(TITLE, FMT, FIELD)               \
197   add_info_val("Disc", TITLE, FMT, p_cdda->cddb.disc->FIELD)
198
199 /* Adds a CD-Text string-valued entry to the stream and media information
200    under category "Disc" if the string is not null or the null string.
201  */
202 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD)              \
203     add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
204
205 /* Adds a CD-Text string-valued entry to the stream and media information
206    under category "Disc" if the string is not null or the null string.
207  */
208 #define add_cdtext_disc_info_str(TITLE, FIELD) \
209   add_cdtext_info_str("Disc", TITLE, 0, FIELD)
210
211
212 /*
213  Gets and saves Meta Information about the CD-DA.
214
215  In the Control routine, we handle Meta Information requests and
216  basically copy what we've saved here.
217
218  Meta information is also used elsewhere such as in "stream and
219  media info" or in playlist info. The intialization of CD-Text or CDDB
220  is done here though.
221  */
222 void CDDAMetaInfo( access_t *p_access, int i_track )
223 {
224     cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
225
226     if ( ! p_cdda ) return;
227
228     p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
229
230 #ifdef HAVE_LIBCDDB
231     if ( p_cdda->b_cddb_enabled )
232     {
233         GetCDDBInfo(p_access, p_cdda);
234         if ( p_cdda->cddb.disc )
235         {
236             p_cdda->p_meta = vlc_meta_New();
237             if( i_track == -1 )
238             {
239                 add_cddb_meta(title,    VLC_META_TITLE);
240                 add_cddb_meta(artist,   VLC_META_ARTIST);
241                 input_Control( p_cdda->p_input, INPUT_SET_NAME,
242                                p_cdda->cddb.disc->artist );
243             }
244             else
245             {
246                 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
247                                                     i_track-1);
248                 if (t != NULL )
249                 {
250                     if( t->title != NULL )
251                     {
252                         add_meta_val( NULL, VLC_META_TITLE, t->title );
253                     }
254                     if( t->artist != NULL )
255                     {
256                         add_meta_val( NULL, VLC_META_ARTIST, t->artist );
257                     }
258                 }
259             }
260             add_cddb_meta(genre,    VLC_META_GENRE);
261             add_cddb_meta_fmt(year,   "%d", VLC_META_DATE );
262         }
263     }
264
265 #endif /*HAVE_LIBCDDB*/
266 #define TITLE_MAX 30
267     {
268         track_t i = p_cdda->i_tracks;
269         const int i_first_track = p_cdda->i_first_track;
270         char psz_buffer[MSTRTIME_MAX_SIZE];
271         mtime_t i_duration =
272               (p_cdda->lsn[i_first_track+i] - p_cdda->lsn[i_first_track])
273               / CDIO_CD_FRAMES_PER_SEC;
274
275         dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d", 
276                    (long int) i_duration, p_cdda->i_tracks );
277         input_Control( p_cdda->p_input, INPUT_ADD_INFO,
278                        _("Disc"), _("Duration"), "%s",
279                        secstotimestr( psz_buffer, i_duration ) );
280
281         input_Control( p_cdda->p_input, INPUT_ADD_INFO,
282                        _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
283
284 #ifdef HAVE_LIBCDDB
285         if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
286         {
287           add_cddb_disc_info_str("Artist (CDDB)", artist);
288           add_cddb_disc_info_str("Genre (CDDB)",  genre);
289           add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
290           add_cddb_disc_info_val("Year (CDDB)", "%d", year);
291           add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
292           add_cddb_disc_info_str("Title (CDDB)",  title);
293           add_info_str("Disc", "Category (CDDB)",
294                         CDDB_CATEGORY[p_cdda->cddb.disc->category]);
295
296         }
297 #endif /*HAVE_LIBCDDB*/
298
299         p_cdda->p_cdtext[0] = cdio_get_cdtext(p_cdda->p_cdio, 0);
300         if (p_cdda->p_cdtext[0])
301         {
302             add_cdtext_disc_info_str("Arranger (CD-Text)",    CDTEXT_ARRANGER);
303             add_cdtext_disc_info_str("Composer (CD-Text)",    CDTEXT_COMPOSER);
304             add_cdtext_disc_info_str("Disc ID (CD-Text)",     CDTEXT_DISCID);
305             add_cdtext_disc_info_str("Genre (CD-Text)",       CDTEXT_GENRE);
306             add_cdtext_disc_info_str("Message (CD-Text)",     CDTEXT_MESSAGE);
307             add_cdtext_disc_info_str("Performer (CD-Text)",   CDTEXT_PERFORMER);
308             add_cdtext_disc_info_str("Songwriter (CD-Text)",  CDTEXT_SONGWRITER);
309             add_cdtext_disc_info_str("Title (CD-Text)",       CDTEXT_TITLE);
310         }
311
312         for( i = 0 ; i < p_cdda->i_tracks ; i++ )
313         {
314           char psz_track[TITLE_MAX];
315           const track_t i_track = i_first_track + i;
316           mtime_t i_duration = (p_cdda->lsn[i_track+1] -
317                                 p_cdda->lsn[i_track])
318             / CDIO_CD_FRAMES_PER_SEC;
319           snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
320
321           input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
322                          _("Duration"), "%s",
323                          secstotimestr( psz_buffer, i_duration ) );
324           
325           p_cdda->p_cdtext[i_track] =
326             cdio_get_cdtext(p_cdda->p_cdio, i_track);
327           
328           if (p_cdda->p_cdtext[i_track])
329             {
330               add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
331                                    i_track, CDTEXT_ARRANGER);
332               add_cdtext_info_str( psz_track, "Composer (CD-Text)",
333                                    i_track, CDTEXT_COMPOSER);
334               add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
335                                    i_track, CDTEXT_DISCID);
336               add_cdtext_info_str( psz_track, "Genre (CD-Text)",
337                                    i_track, CDTEXT_GENRE);
338               add_cdtext_info_str( psz_track, "Message (CD-Text)",
339                                    i_track, CDTEXT_MESSAGE);
340               add_cdtext_info_str( psz_track, "Performer (CD-Text)",
341                                    i_track, CDTEXT_PERFORMER);
342               add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
343                                    i_track, CDTEXT_SONGWRITER);
344               add_cdtext_info_str( psz_track, "Title (CD-Text)",
345                                    i_track, CDTEXT_TITLE);
346             }
347           
348 #ifdef HAVE_LIBCDDB
349           if (p_cdda->b_cddb_enabled)
350             {
351               cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
352               if (t != NULL)
353                 {
354                   add_info_str(psz_track, "Artist (CDDB)", t->artist);
355                   add_info_str(psz_track, "Title (CDDB)",  t->title);
356                   add_info_str(psz_track, "Extended Data (CDDB)",
357                                t->ext_data);
358                 }
359             }
360 #endif /*HAVE_LIBCDDB*/
361         }
362     }
363 }
364
365 #define add_format_str_info(val)                         \
366   {                                                      \
367     const char *str = val;                               \
368     unsigned int len;                                    \
369     if (val != NULL) {                                   \
370       len=strlen(str);                                   \
371       if (len != 0) {                                    \
372         strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));    \
373         tp += len;                                       \
374       }                                                  \
375       saw_control_prefix = false;                        \
376     }                                                    \
377   }
378
379 #define add_format_num_info(val, fmt)                    \
380   {                                                      \
381     char num_str[10];                                    \
382     unsigned int len;                                    \
383     sprintf(num_str, fmt, val);                          \
384     len=strlen(num_str);                                 \
385     if (len != 0) {                                      \
386       strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));  \
387       tp += len;                                         \
388     }                                                    \
389     saw_control_prefix = false;                          \
390   }
391
392 static inline bool
393 want_cddb_info(
394 cdda_data_t *p_cdda, char *psz_cdtext) 
395 {
396   /* We either don't have CD-Text info, or we do but we prefer to get CDDB
397      which means CDDB has been enabled and we were able to retrieve the info.*/
398 #ifdef HAVE_LIBCDDB
399   return !psz_cdtext || 
400     (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
401 #else
402   return false;
403 #endif
404 }
405
406
407 /*!
408    Take a format string and expand escape sequences, that is sequences that
409    begin with %, with information from the current CD.
410    The expanded string is returned. Here is a list of escape sequences:
411
412    %a : The album artist **
413    %A : The album information **
414    %C : Category **
415    %I : CDDB disk ID **
416    %G : Genre **
417    %M : The current MRL
418    %m : The CD-DA Media Catalog Number (MCN)
419    %n : The number of tracks on the CD
420    %p : The artist/performer/composer in the track **
421    %T : The track number **
422    %s : Number of seconds in this track
423    %t : The name **
424    %Y : The year 19xx or 20xx **
425    %% : a %
426 */
427 static char *
428 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
429                const char format_str[], const char *mrl, track_t i_track)
430 {
431 #define TEMP_STR_SIZE 256
432 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
433     static char    temp_str[TEMP_STR_SIZE];
434     size_t i;
435     char * tp = temp_str;
436     vlc_bool_t saw_control_prefix = false;
437     size_t format_len = strlen(format_str);
438
439     memset(temp_str, 0, TEMP_STR_SIZE);
440
441     for (i=0; i<format_len; i++)
442     {
443         char *psz = NULL;
444
445         if (!saw_control_prefix && format_str[i] != '%')
446         {
447             *tp++ = format_str[i];
448             saw_control_prefix = false;
449             continue;
450         }
451
452         switch(format_str[i])
453         {
454             case '%':
455               if (saw_control_prefix)
456               {
457                   *tp++ = '%';
458               }
459               saw_control_prefix = !saw_control_prefix;
460               break;
461 #ifdef HAVE_LIBCDDB
462             case 'a':
463                 if (p_cdda->p_cdtext[0] 
464                     && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
465                   psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
466                 if (want_cddb_info(p_cdda, psz))
467                   psz = p_cdda->cddb.disc->artist;
468                 goto format_str;
469             case 'A':
470                 if (p_cdda->p_cdtext[0] 
471                     && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
472                   psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
473                 if (want_cddb_info(p_cdda, psz))
474                   psz =  p_cdda->cddb.disc->title;
475                 goto format_str;
476             case 'C':
477                 if (!p_cdda->b_cddb_enabled) goto not_special;
478                 if (p_cdda->cddb.disc)
479                     add_format_str_info(
480                                   CDDB_CATEGORY[p_cdda->cddb.disc->category]);
481                 break;
482             case 'G':
483                 if (p_cdda->p_cdtext[0] 
484                     && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
485                   psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
486                 if (want_cddb_info(p_cdda, psz))
487                   psz = p_cdda->cddb.disc->genre;
488                 goto format_str;
489             case 'I':
490                 if (p_cdda->p_cdtext[0] 
491                     && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
492                   psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
493                 if (want_cddb_info(p_cdda, psz)) {
494                      add_format_num_info(p_cdda->cddb.disc->discid, "%x");
495                 } else if (psz)
496                      add_format_str_info(psz);
497                 break;
498             case 'Y':
499                 if (!p_cdda->b_cddb_enabled) goto not_special;
500                 if (p_cdda->cddb.disc)
501                     add_format_num_info(p_cdda->cddb.disc->year, "%5d");
502                 break;
503             case 't':
504                 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
505                 {
506                     cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
507                                                         i_track-1);
508                     if (t != NULL && t->title != NULL)
509                       add_format_str_info(t->title);
510                 }
511                 else goto not_special;
512                 break;
513             case 'p':
514                 if (p_cdda->p_cdtext[i_track] 
515                     && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
516                   psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
517                 if (want_cddb_info(p_cdda, psz))
518                   {
519                     cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
520                                                         i_track-1);
521                     if (t != NULL && t->artist != NULL)
522                       psz = t->artist;
523                   }
524                 goto format_str;
525             case 'e':
526                 if (p_cdda->p_cdtext[i_track] 
527                     && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
528                   psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
529                 if (want_cddb_info(p_cdda, psz))
530                 {
531                     cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
532                                                         i_track-1);
533                     if (t != NULL && t->ext_data != NULL)
534                         psz = t->ext_data;
535                 } 
536                 goto format_str;
537                 break;
538             case 's':
539                 if (p_cdda->b_cddb_enabled)
540                 {
541                     char psz_buffer[MSTRTIME_MAX_SIZE];
542                     mtime_t i_duration = (p_cdda->lsn[i_track+1] -
543                                           p_cdda->lsn[i_track])
544                                           / CDIO_CD_FRAMES_PER_SEC;
545                     add_format_str_info(secstotimestr( psz_buffer,
546                                        i_duration ) );
547                 } else goto not_special;
548                 break;
549 #else
550             case 'a':
551                 if (p_cdda->p_cdtext[0] 
552                     && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
553                     psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
554                 goto format_str;
555             case 'A':
556                 if (p_cdda->p_cdtext[0] 
557                     && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
558                     psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
559                 goto format_str;
560             case 'G':
561                 if (p_cdda->p_cdtext[0] 
562                     && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
563                   psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
564                 goto format_str;
565             case 'I':
566                 if (p_cdda->p_cdtext[0] 
567                     && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
568                   add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
569                 break;
570             case 'p':
571                 if (p_cdda->p_cdtext[i_track] 
572                     && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
573                   psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
574                 goto format_str;
575             case 'e':
576                 if (p_cdda->p_cdtext[i_track] 
577                     && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
578                   psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
579                 goto format_str;
580                 break;
581 #endif /*HAVE_LIBCDDB*/
582
583             case 'M':
584               add_format_str_info(mrl);
585               break;
586
587             case 'm':
588               add_format_str_info(p_cdda->psz_mcn);
589               break;
590
591             case 'n':
592               add_format_num_info(p_cdda->i_tracks, "%d");
593               break;
594
595             case 'T':
596               add_format_num_info(i_track, "%02d");
597               break;
598             format_str:
599               if (psz)
600                 add_format_str_info(psz);
601               break;
602 #ifdef HAVE_LIBCDDB
603             not_special:
604 #endif
605             default:
606                 *tp++ = '%';
607                 *tp++ = format_str[i];
608                 saw_control_prefix = false;
609         }
610     }
611     return strdup(temp_str);
612 }
613
614 /* Adds a string-valued entry to the playlist information under "Track"
615    if the string is not null or the null string.
616  */
617 #define add_playlist_track_info_str(TITLE, FIELD)                        \
618     if (FIELD && strlen(FIELD))                                          \
619     {                                                                    \
620         playlist_ItemAddInfo( p_item, _("Track"), _(TITLE),              \
621                               "%s", FIELD);                              \
622     }
623
624 playlist_item_t *
625 CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
626                         playlist_t *p_playlist, playlist_item_t *p_item, 
627                         track_t i_track, char *psz_mrl, int psz_mrl_max,
628                         const char *psz_source )
629 {
630     mtime_t i_duration = (p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track])
631                          * (1000000 / CDIO_CD_FRAMES_PER_SEC) ;
632     char *psz_title;
633     char *config_varname = MODULE_STRING "-title-format";
634
635     playlist_item_t *p_child = NULL;
636
637     if( !p_item )
638     {
639         return NULL;
640     }
641
642 #ifdef HAVE_LIBCDDB
643     if (p_cdda->b_cddb_enabled)
644     {
645         config_varname = MODULE_STRING "-cddb-title-format";
646     }
647 #endif /*HAVE_LIBCDDB*/
648
649
650     psz_title = CDDAFormatStr( p_access, p_cdda,
651                                config_GetPsz( p_access, config_varname ),
652                                psz_mrl, i_track);
653
654     snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
655              CDDA_MRL_PREFIX, psz_source, i_track);
656
657     dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
658                psz_mrl, psz_title, (long int) i_duration / 1000000 );
659
660     p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
661     p_child->input.b_fixed_name = VLC_TRUE;
662
663     if( !p_child ) return NULL;
664
665     playlist_NodeAddItem( p_playlist, p_child,
666                           p_item->pp_parents[0]->i_view,
667                           p_item, PLAYLIST_APPEND, PLAYLIST_END );
668     playlist_CopyParents( p_item, p_child );
669
670     return p_child;
671 }
672
673 int CDDAAddMetaToItem( access_t *p_access, cdda_data_t *p_cdda,
674                        playlist_item_t *p_item, const char *psz_source,
675                        int i_track, vlc_bool_t b_single )
676 {
677     vlc_mutex_lock( &p_item->input.lock );
678
679     add_playlist_track_info_str("Source",  psz_source);
680     playlist_ItemAddInfo( p_item, _("Track"), _("Track Number"),
681                           "%d", i_track );
682
683     if (p_cdda->p_cdtext[0])
684     {
685         const cdtext_t *p = p_cdda->p_cdtext[0];
686         add_playlist_track_info_str("Disc Arranger (CD-Text)",
687                                      p->field[CDTEXT_ARRANGER]);
688         add_playlist_track_info_str("Disc Composer (CD-Text)",
689                                     p->field[CDTEXT_COMPOSER]);
690         add_playlist_track_info_str("Disc ID (CD-Text)",
691                                     p->field[CDTEXT_DISCID]);
692         add_playlist_track_info_str("Disc Genre (CD-Text)",
693                                     p->field[CDTEXT_GENRE]);
694         add_playlist_track_info_str("Disc Message (CD-Text)",
695                                     p->field[CDTEXT_MESSAGE]);
696         add_playlist_track_info_str("Disc Performer (CD-Text)",
697                                     p->field[CDTEXT_PERFORMER]);
698         add_playlist_track_info_str("Disc Songwriter (CD-Text)",
699                                     p->field[CDTEXT_SONGWRITER]);
700         add_playlist_track_info_str("Disc Title (CD-Text)",
701                                     p->field[CDTEXT_TITLE]);
702     }
703
704     if (p_cdda->p_cdtext[i_track])
705     {
706         const cdtext_t *p = p_cdda->p_cdtext[i_track];
707         add_playlist_track_info_str("Arranger (CD-Text)",
708                                     p->field[CDTEXT_ARRANGER]);
709         add_playlist_track_info_str("Composer (CD-Text)",
710                                     p->field[CDTEXT_COMPOSER]);
711         add_playlist_track_info_str("Genre (CD-Text)",
712                                     p->field[CDTEXT_GENRE]);
713         add_playlist_track_info_str("Message (CD-Text)",
714                                     p->field[CDTEXT_MESSAGE]);
715         add_playlist_track_info_str("Performer (CD-Text)",
716                                     p->field[CDTEXT_PERFORMER]);
717         add_playlist_track_info_str("Songwriter (CD-Text)",
718                                     p->field[CDTEXT_SONGWRITER]);
719         add_playlist_track_info_str("Title (CD-Text)",
720                                     p->field[CDTEXT_TITLE]);
721     }
722
723 #ifdef HAVE_LIBCDDB
724     if (p_cdda->b_cddb_enabled)
725     {
726         cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
727                                             i_track-p_cdda->i_first_track);
728
729         add_playlist_track_info_str("Disc Album (CDDB)",
730                                     p_cdda->cddb.disc->title);
731         add_playlist_track_info_str("Disc Artist(s) (CDDB)",
732                                     p_cdda->cddb.disc->artist);
733         add_playlist_track_info_str("Disc Category (CDDB)",
734                                     CDDB_CATEGORY[p_cdda->cddb.disc->category]);
735         add_playlist_track_info_str("Disc Genre (CDDB)",
736                                     p_cdda->cddb.disc->genre);
737
738         if ( p_cdda->cddb.disc->discid )
739         {
740             playlist_ItemAddInfo( p_item, _("Track"), _("Disc ID (CDDB)"),
741                                   "%x", p_cdda->cddb.disc->discid );
742         }
743         if (p_cdda->cddb.disc->year != 0)
744         {
745             playlist_ItemAddInfo( p_item, _("Track"), _("Year (CDDB)"),
746                                  "%5d", p_cdda->cddb.disc->year );
747         }
748
749         if (t)
750         {
751             if (t->artist)
752                 add_playlist_track_info_str("Track Artist (CDDB)",
753                                              t->artist);
754            if (t->title)
755                 add_playlist_track_info_str("Track Title (CDDB)",
756                                             t->title);
757         }
758     }
759 #endif /*HAVE_LIBCDDB*/
760
761     vlc_mutex_unlock( &p_item->input.lock );
762
763     return VLC_SUCCESS;
764 }
765
766 int
767 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
768                    const char *psz_source, vlc_bool_t b_single_track )
769 {
770     int i;
771     playlist_t * p_playlist;
772     char       * psz_mrl;
773     unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX) + strlen(psz_source) +
774       strlen("@T") + strlen("100") + 1;
775     const track_t i_first_track = p_cdda->i_first_track;
776     playlist_item_t *p_item;
777     vlc_bool_t b_play = VLC_FALSE;
778
779 #ifdef HAVE_LIBCDDB
780     p_cdda->b_cddb_enabled =
781         config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
782     if( b_single_track && !p_cdda->b_cddb_enabled )
783         return VLC_SUCCESS;
784 #else
785     if( b_single_track )
786         return VLC_SUCCESS;
787 #endif
788
789     psz_mrl = malloc( psz_mrl_max );
790
791     if( psz_mrl == NULL )
792     {
793         msg_Warn( p_access, "out of memory" );
794         return VLC_ENOMEM;
795     }
796
797     p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST,
798                                                FIND_ANYWHERE );
799     if( !p_playlist )
800     {
801         msg_Warn( p_access, "can't find playlist" );
802         free(psz_mrl);
803         return VLC_EGENERIC;
804     }
805
806     if( b_single_track )
807     {
808         CDDAMetaInfo( p_access, p_cdda->i_track );
809     }
810     else
811     {
812         CDDAMetaInfo( p_access, -1 );
813     }
814
815     p_item = playlist_ItemGetByInput( p_playlist,
816                         ((input_thread_t *)p_access->p_parent)->input.p_item );
817
818     if( p_item == p_playlist->status.p_item && !b_single_track )
819     {
820         b_play = VLC_TRUE;
821     }
822     else
823     {
824         b_play = VLC_FALSE;
825     }
826
827     if( b_single_track )
828     {
829         /*May fill out more information when the playlist user interface becomes
830            more mature.
831          */
832         track_t i_track = p_cdda->i_track;
833
834         input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
835         vlc_input_title_New();
836
837         asprintf( &t->psz_name, _("Track %i"), i_track );
838         t->i_size = p_access->info.i_size =
839                   ( p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track] ) *
840                              (int64_t) CDIO_CD_FRAMESIZE_RAW;
841
842         t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
843
844
845         CDDAAddMetaToItem( p_access, p_cdda, p_item, psz_source, i_track,
846                            VLC_FALSE );
847
848         p_cdda->i_titles = 1;
849     }
850     else
851     {
852         playlist_ItemToNode( p_playlist, p_item );
853         for( i = 0 ; i < p_cdda->i_tracks ; i++ )
854         {
855             playlist_item_t *p_child;
856             const track_t i_track = i_first_track + i;
857             input_title_t *t = p_cdda->p_title[i] = vlc_input_title_New();
858
859             asprintf( &t->psz_name, _("Track %i"), i_track );
860             t->i_size = ( p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track] ) *
861                           (int64_t) CDIO_CD_FRAMESIZE_RAW;
862
863             t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
864
865             p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
866                                               p_item,
867                                               i_track, psz_mrl,
868                                               psz_mrl_max, psz_source );
869             CDDAAddMetaToItem( p_access, p_cdda, p_child, psz_source,
870                                i_track, VLC_TRUE );
871         }
872         p_cdda->i_titles = p_cdda->i_tracks; /* should be +1 */
873         p_access->info.i_size =
874                (p_cdda->lsn[i_first_track + p_cdda->i_tracks]
875                - p_cdda->lsn[i_first_track]) * (int64_t) CDIO_CD_FRAMESIZE_RAW;
876     }
877
878     if( b_play )
879     {
880         playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
881                           p_playlist->status.i_view,
882                           p_playlist->status.p_item, NULL );
883     }
884
885     vlc_object_release( p_playlist );
886
887     return VLC_SUCCESS;
888 }
889