1 /*****************************************************************************
2 * info.c : CD digital audio input information routines
3 *****************************************************************************
4 * Copyright (C) 2004, 2005 the VideoLAN team
7 * Authors: Rocky Bernstein <rocky@panix.com>
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include "callback.h" /* FIXME - reorganize callback.h, cdda.h better */
28 #include "cdda.h" /* private structures. Also #includes vlc things */
30 #include <cdio/cdio.h>
31 #include <cdio/cdtext.h>
32 #include <cdio/logging.h>
33 #include <cdio/cd_types.h>
39 static char *CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
40 const char format_str[], const char *psz_mrl,
43 static char *CDDAFormatMRL( const access_t *p_access, track_t i_track );
47 #define free_and_dup(var, val) \
49 if (val) var = strdup( val );
52 /* Saves CDDB information about CD-DA via libcddb. */
54 GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
57 cddb_conn_t *conn = cddb_new();
58 const CdIo_t *p_cdio = p_cdda->p_cdio;
60 dbg_print( (INPUT_DBG_CALL), "" );
63 cddb_log_set_handler (uninit_log_handler);
68 msg_Warn( p_access, "Unable to initialize libcddb" );
72 char* psz_email = config_GetPsz( p_access, MODULE_STRING "-cddb-email");
73 char* psz_srv_name = config_GetPsz( p_access, MODULE_STRING "-cddb-server");
74 cddb_set_email_address( conn, psz_email );
75 cddb_set_server_name( conn, psz_srv_name );
76 cddb_set_server_port(conn,
77 config_GetInt( p_access,
78 MODULE_STRING "-cddb-port") );
82 /* Set the location of the local CDDB cache directory.
83 The default location of this directory is */
85 if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
86 cddb_cache_disable(conn);
88 char* psz_cache = config_GetPsz( p_access, MODULE_STRING "-cddb-cachedir");
89 cddb_cache_set_dir(conn, psz_cache );
92 cddb_set_timeout(conn,
93 config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
96 if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
98 cddb_http_enable(conn);
102 cddb_http_disable(conn);
105 p_cdda->cddb.disc = cddb_disc_new();
107 if (!p_cdda->cddb.disc)
109 msg_Err( p_access, "Unable to create CDDB disc structure." );
113 for(i = 0; i < p_cdda->i_tracks; i++)
115 track_t i_track = p_cdda->i_first_track + i;
116 cddb_track_t *t = cddb_track_new();
117 cddb_track_set_frame_offset(t,
118 cdio_get_track_lba(p_cdio, i_track));
119 cddb_disc_add_track(p_cdda->cddb.disc, t);
122 cddb_disc_set_length(p_cdda->cddb.disc,
123 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
124 / CDIO_CD_FRAMES_PER_SEC);
126 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
128 msg_Err( p_access, "CDDB disc ID calculation failed" );
132 i_matches = cddb_query(conn, p_cdda->cddb.disc);
137 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
139 cddb_read(conn, p_cdda->cddb.disc);
141 if (p_cdda->i_debug & INPUT_DBG_CDDB)
142 cddb_disc_print(p_cdda->cddb.disc);
147 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
155 #endif /*HAVE_LIBCDDB*/
157 static inline void add_meta_val(access_t *p_access, vlc_meta_type_t meta, const char * val)
159 cdda_data_t *p_cdda = (cdda_data_t *)p_access->p_sys;
160 if (p_cdda->p_meta && val)
161 dbg_print( INPUT_DBG_META, "field %s: %s\n", input_MetaTypeToLocalizedString(meta), val);
164 #define add_cddb_meta(FIELD, VLC_META) \
165 add_meta_val(p_access, VLC_META, cddb_disc_get_##FIELD(p_cdda->cddb.disc));
167 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
170 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
171 cddb_disc_get_##FIELD(p_cdda->cddb.disc)); \
172 psz_buf[sizeof(psz_buf)-1] = '\0'; \
173 add_meta_val(p_access, VLC_META, psz_buf); \
176 /* Adds a string-valued entry to the stream and media information if
177 the string is not null or the null string.
179 #define add_info_str(CATEGORY, TITLE, FIELD) \
180 if (FIELD && strlen(FIELD)) { \
181 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
182 _(TITLE), "%s", FIELD ); \
185 /* Adds a numeric-valued entry to the stream and media information
186 if the number is not zero. */
187 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
189 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
190 _(TITLE), FMT, FIELD ); \
193 /* Adds a CDDB string-valued entry to the stream and media information
194 under category "Disc" if the string is not null or the null string.
196 #define add_cddb_disc_info_str(TITLE, FIELD) \
197 add_info_str("Disc", TITLE, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
199 /* Adds a CDDB numeric-valued entry to the stream and media information
200 under category "Disc" if the string is not null or the null string.
202 #define add_cddb_disc_info_val(TITLE, FMT, FIELD) \
203 add_info_val("Disc", TITLE, FMT, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
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.
208 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
209 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
211 /* Adds a CD-Text string-valued entry to the stream and media information
212 under category "Disc" if the string is not null or the null string.
214 #define add_cdtext_disc_info_str(TITLE, FIELD) \
215 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
219 Saves Meta Information about the CD-DA.
221 Meta information used in "stream and media info" or in playlist
222 info. The intialization of CD-Text or CDDB is done here though.
223 Therefore, this should be called before CDDAMetaInfo is called.
227 CDDAMetaInfoInit( access_t *p_access )
229 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
231 if ( ! p_cdda ) return;
233 dbg_print( (INPUT_DBG_CALL), "p_cdda->i_tracks %d",
236 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
238 p_cdda->p_meta = vlc_meta_New();
242 if ( p_cdda->b_cddb_enabled )
244 GetCDDBInfo(p_access, p_cdda);
247 #endif /*HAVE_LIBCDDB*/
253 for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
255 p_cdda->p_cdtext[i_track] =
256 cdio_get_cdtext(p_cdda->p_cdio, i_track);
262 In the Control routine, we handle Meta Information requests and
263 basically copy what was saved in CDDAMetaInfoInit.
265 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
269 CDDAMetaInfo( access_t *p_access, track_t i_track )
271 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
272 char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
273 char *psz_meta_artist = NULL;
275 if ( ! p_cdda ) return;
277 dbg_print( (INPUT_DBG_CALL), "i_track %d", i_track );
281 /* Set up for Meta and name for CDDB access. */
282 if ( p_cdda->b_cddb_enabled && p_cdda->cddb.disc )
284 if( CDIO_INVALID_TRACK == i_track )
287 psz_meta_title = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
288 psz_meta_artist = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
289 if ( cddb_disc_get_genre(p_cdda->cddb.disc) &&
290 strlen(cddb_disc_get_genre(p_cdda->cddb.disc)) )
291 add_cddb_meta(genre, vlc_meta_Genre);
292 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc))
293 add_cddb_meta_fmt(year, "%d", vlc_meta_Date );
297 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
300 if( cddb_track_get_title(t) != NULL && ! p_cdda->b_nav_mode )
302 add_meta_val( p_access, vlc_meta_Title, cddb_track_get_title(t) );
304 if( cddb_track_get_artist(t) != NULL )
306 add_meta_val( p_access, vlc_meta_Artist, cddb_track_get_artist(t) );
311 #endif /*HAVE_LIBCDDB*/
315 track_t i = p_cdda->i_tracks;
316 const int i_first_track = p_cdda->i_first_track;
317 char psz_buffer[MSTRTIME_MAX_SIZE];
318 unsigned int i_track_frames =
319 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
321 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
323 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
324 (long int) i_duration, p_cdda->i_tracks );
325 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
326 _("Disc"), _("Duration"), "%s",
327 secstotimestr( psz_buffer, i_duration ) );
331 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
332 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
334 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
335 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
339 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
341 add_cddb_disc_info_str("Artist (CDDB)", artist);
342 if ( CDDB_CAT_INVALID != cddb_disc_get_category(p_cdda->cddb.disc) )
343 add_info_str("Disc", "Category (CDDB)",
344 CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
345 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
346 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
347 add_cddb_disc_info_str("Genre (CDDB)", genre);
348 add_cddb_disc_info_str("Title (CDDB)", title);
349 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc) )
350 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
353 #endif /*HAVE_LIBCDDB*/
355 if (p_cdda->p_cdtext[0])
359 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
360 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
361 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
362 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
363 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
364 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
365 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
366 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
368 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
369 if (psz_field && strlen(psz_field))
370 psz_meta_title = psz_field;
372 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
373 if (psz_field && strlen(psz_field))
374 psz_meta_artist = psz_field;
377 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
379 char psz_track[TITLE_MAX];
380 const track_t i_track = i_first_track + i;
381 unsigned int i_track_frames =
382 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
383 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
385 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
386 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
388 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
390 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
392 secstotimestr( psz_buffer, i_duration ) );
394 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
395 _("MRL"), "%s", psz_mrl );
398 if (p_cdda->p_cdtext[i_track])
400 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
401 i_track, CDTEXT_ARRANGER);
402 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
403 i_track, CDTEXT_COMPOSER);
404 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
405 i_track, CDTEXT_DISCID);
406 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
407 i_track, CDTEXT_GENRE);
408 add_cdtext_info_str( psz_track, "Message (CD-Text)",
409 i_track, CDTEXT_MESSAGE);
410 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
411 i_track, CDTEXT_PERFORMER);
412 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
413 i_track, CDTEXT_SONGWRITER);
414 add_cdtext_info_str( psz_track, "Title (CD-Text)",
415 i_track, CDTEXT_TITLE);
419 if (p_cdda->b_cddb_enabled)
421 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
424 add_info_str(psz_track, "Artist (CDDB)",
425 cddb_track_get_artist(t));
426 add_info_str(psz_track, "Title (CDDB)",
427 cddb_track_get_title(t));
428 add_info_str(psz_track, "Extended Data (CDDB)",
429 cddb_track_get_ext_data(t));
432 #endif /*HAVE_LIBCDDB*/
435 /* Above we should have set psz_meta_title and psz_meta_artist
436 to CDDB or CD-Text values or the default value depending on
437 availablity and user preferences.
439 So now add the title and artist to VLC's meta, and the name
440 as shown in the status bar and playlist entry.
442 For playlist mode, the meta title is what's seen at the
443 bottom and in the playlist. For nav-mode playing, it is
444 done by input_control. I don't understand why they do
445 different things. In either case, we may have customized to
446 put in the track name.
448 if ( CDIO_INVALID_TRACK != i_track )
450 char *psz_name = CDDAFormatTitle( p_access, i_track ) ;
451 if ( !p_cdda->b_nav_mode ) {
452 add_meta_val( p_access, vlc_meta_Title, psz_name );
455 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
459 add_meta_val( p_access, vlc_meta_Artist, psz_meta_artist );
464 #define add_format_str_info(val) \
466 const char *str = val; \
471 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
474 saw_control_prefix = false; \
478 #define add_format_num_info(val, fmt) \
482 sprintf(num_str, fmt, val); \
483 len=strlen(num_str); \
485 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
488 saw_control_prefix = false; \
493 cdda_data_t *p_cdda, char *psz_cdtext)
495 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
496 which means CDDB has been enabled and we were able to retrieve the info.*/
498 return !psz_cdtext ||
499 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
507 Take a format string and expand escape sequences, that is sequences that
508 begin with %, with information from the current CD.
509 The expanded string is returned. Here is a list of escape sequences:
511 %a : The album artist **
512 %A : The album information **
514 %e : The extended track data
518 %m : The CD-DA Media Catalog Number (MCN)
519 %n : The number of tracks on the CD
520 %p : The artist/performer/composer in the track **
521 %T : The track number **
522 %s : Number of seconds in this track, or seconds in CD if invalid track
523 %S : Number of seconds on the CD
524 %t : The track name or MRL if no name
525 %Y : The year 19xx or 20xx **
529 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
530 const char format_str[], const char *psz_mrl, track_t i_track)
532 VLC_UNUSED(p_access);
533 #define TEMP_STR_SIZE 256
534 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
535 static char temp_str[TEMP_STR_SIZE];
537 char * tp = temp_str;
538 bool saw_control_prefix = false;
539 size_t format_len = strlen(format_str);
541 memset(temp_str, 0, TEMP_STR_SIZE);
543 for (i=0; i<format_len; i++)
547 if (!saw_control_prefix && format_str[i] != '%')
549 *tp++ = format_str[i];
550 saw_control_prefix = false;
554 switch(format_str[i])
557 if (saw_control_prefix)
561 saw_control_prefix = !saw_control_prefix;
565 if (p_cdda->p_cdtext[0]
566 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
567 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
568 if (want_cddb_info(p_cdda, psz))
569 psz = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
572 if (p_cdda->p_cdtext[0]
573 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
574 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
575 if (want_cddb_info(p_cdda, psz))
576 psz = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
579 if (!p_cdda->b_cddb_enabled) goto not_special;
580 if (p_cdda->cddb.disc)
581 add_format_str_info(CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
584 if (p_cdda->p_cdtext[0]
585 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
586 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
587 if (want_cddb_info(p_cdda, psz))
588 psz = (char *)cddb_disc_get_genre(p_cdda->cddb.disc);
591 if (p_cdda->p_cdtext[0]
592 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
593 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
594 if (want_cddb_info(p_cdda, psz)) {
595 add_format_num_info(cddb_disc_get_discid(p_cdda->cddb.disc), "%x");
597 add_format_str_info(psz);
600 if (!p_cdda->b_cddb_enabled) goto not_special;
601 if (p_cdda->cddb.disc)
602 add_format_num_info(cddb_disc_get_year(p_cdda->cddb.disc),
606 if ( CDIO_INVALID_TRACK == i_track ) break;
607 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
609 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
611 if (t != NULL && cddb_track_get_title(t) != NULL) {
612 add_format_str_info(cddb_track_get_title(t));
614 add_format_str_info(psz_mrl);
619 if (p_cdda->p_cdtext[i_track]
620 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
622 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
625 add_format_str_info(psz_mrl);
629 if ( CDIO_INVALID_TRACK == i_track ) break;
630 if (p_cdda->p_cdtext[i_track]
631 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
632 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
633 if (want_cddb_info(p_cdda, psz))
635 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
637 if (t != NULL && cddb_track_get_artist(t) != NULL)
638 psz = (char *)cddb_track_get_artist(t);
642 if ( CDIO_INVALID_TRACK == i_track ) break;
643 if (p_cdda->p_cdtext[i_track]
644 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
645 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
646 if (want_cddb_info(p_cdda, psz))
648 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
650 if (t != NULL && cddb_track_get_ext_data(t) != NULL)
651 psz = (char *)cddb_track_get_ext_data(t);
657 if (p_cdda->p_cdtext[0]
658 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
659 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
662 if (p_cdda->p_cdtext[0]
663 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
664 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
667 if (p_cdda->p_cdtext[0]
668 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
669 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
672 if (p_cdda->p_cdtext[0]
673 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
674 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
677 if ( CDIO_INVALID_TRACK == i_track ) break;
678 if (p_cdda->p_cdtext[i_track]
679 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
680 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
683 if ( CDIO_INVALID_TRACK == i_track ) break;
684 if (p_cdda->p_cdtext[i_track]
685 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
686 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
691 if ( CDIO_INVALID_TRACK == i_track ) break;
692 if (p_cdda->p_cdtext[i_track]
693 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
694 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
697 #endif /*HAVE_LIBCDDB*/
700 if ( CDIO_INVALID_TRACK != i_track )
702 char psz_buffer[MSTRTIME_MAX_SIZE];
703 unsigned int i_track_frames =
704 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
706 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
707 add_format_str_info( secstotimestr( psz_buffer,
712 /* Fall through to disc duration if CDIO_INVALID_TRACK */
715 char psz_buffer[MSTRTIME_MAX_SIZE];
716 unsigned int i_track_frames =
717 cdio_get_track_lba(p_cdda->p_cdio,
718 CDIO_CDROM_LEADOUT_TRACK);
720 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
721 add_format_str_info( secstotimestr( psz_buffer,
727 add_format_str_info(psz_mrl);
731 add_format_str_info(p_cdda->psz_mcn);
735 add_format_num_info(p_cdda->i_tracks, "%d");
739 add_format_num_info(i_track, "%02d");
743 add_format_str_info(psz);
750 *tp++ = format_str[i];
751 saw_control_prefix = false;
754 return strdup(temp_str);
757 /* Return a MRL for the given track. The caller must free the
760 CDDAFormatMRL( const access_t *p_access, track_t i_track )
762 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
763 const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
764 + strlen(p_cdda->psz_source) +
765 + strlen("@T") + strlen("100") + 1;
766 char *psz_mrl = calloc( 1, psz_mrl_max );
768 if (CDIO_INVALID_TRACK == i_track)
769 snprintf(psz_mrl, psz_mrl_max, "%s%s",
770 CDDA_MRL_PREFIX, p_cdda->psz_source);
772 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
773 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
778 /* Return a title string as specified by the titel format string for the
779 given track. The caller must free the allocated string. */
781 CDDAFormatTitle( const access_t *p_access, track_t i_track )
784 const char *config_varname = MODULE_STRING "-title-format";
785 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
786 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
792 if (p_cdda->b_cddb_enabled)
794 config_varname = MODULE_STRING "-cddb-title-format";
796 #endif /*HAVE_LIBCDDB*/
797 char* psz_config_varname = config_GetPsz( p_access, config_varname );
798 psz_name = CDDAFormatStr( p_access, p_cdda, psz_config_varname,
800 free( psz_config_varname );
811 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
812 bool b_single_track )
815 const track_t i_first_track = p_cdda->i_first_track;
819 p_cdda->b_cddb_enabled =
820 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
821 if( b_single_track && !p_cdda->b_cddb_enabled )
828 if( b_single_track || p_cdda->b_nav_mode ) {
829 i_track = p_cdda->i_track;
833 i_track = CDIO_INVALID_TRACK;
835 CDDAMetaInfoInit( p_access );
836 CDDAMetaInfo( p_access, p_cdda->i_track );
838 if( b_single_track && !p_cdda->b_nav_mode )
840 /*May fill out more information when the playlist user interface becomes
843 track_t i_track = p_cdda->i_track;
844 unsigned int i_track_frames =
845 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
847 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
848 vlc_input_title_New();
850 if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
852 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
853 t->i_length = INT64_C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
855 p_cdda->i_titles = 1;
856 p_access->info.i_update = INPUT_UPDATE_TITLE;
860 input_thread_t *p_input = access_GetParentInput( p_access );
864 input_item_t *p_current = input_GetItem( p_input );
867 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
869 const track_t i_track = i_first_track + i;
870 unsigned int i_track_frames =
871 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
874 t = p_cdda->p_title[i] = vlc_input_title_New();
876 if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
878 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
880 t->i_length = INT64_C(1000000) * t->i_size
881 / CDDA_FREQUENCY_SAMPLE / 4;
883 if( !p_cdda->b_nav_mode )
885 input_item_t *p_child;
886 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
887 char *psz_title = CDDAFormatTitle( p_access, i_track );
888 unsigned int i_track_frames =
889 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
890 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
891 mtime_t i_mduration = i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
893 p_child = input_item_NewWithType( VLC_OBJECT( p_access ),
894 psz_mrl, psz_title, 0, NULL, 0, i_mduration,
898 input_item_CopyOptions( p_current, p_child );
900 input_item_AddSubItem( p_current, p_child );
902 vlc_gc_decref( p_child );
909 p_cdda->i_titles = p_cdda->i_tracks;
910 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
913 input_item_SetDuration( p_current,
914 (mtime_t) p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
915 input_item_SetURI( p_current, CDDAFormatMRL( p_access, p_cdda->i_track ) );
918 vlc_object_release( p_input );