info.c 34.5 KB
Newer Older
1
2
3
/*****************************************************************************
 * info.c : CD digital audio input information routines
 *****************************************************************************
4
 * Copyright (C) 2004, 2005 the VideoLAN team
zorglub's avatar
zorglub committed
5
 * $Id$
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 *
 * Authors: Rocky Bernstein <rocky@panix.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
dionoea's avatar
dionoea committed
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
23
24
25
26
27
28
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include "callback.h"      /* FIXME - reorganize callback.h, cdda.h better */
#include "cdda.h"          /* private structures. Also #includes vlc things */
29
30

#warning playlist code must not be used here.
31
32
33
34
35
36
37
38
39
40
41
42
#include <vlc_playlist.h>  /* Has to come *after* cdda.h */

#include <cdio/cdio.h>
#include <cdio/cdtext.h>
#include <cdio/logging.h>
#include <cdio/cd_types.h>
#include "info.h"

#ifdef HAVE_ERRNO_H
#   include <errno.h>
#endif

43
static char *CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
44
45
                const char format_str[], const char *psz_mrl,
                track_t i_track);
46

47
48
static char *CDDAFormatMRL( const access_t *p_access, track_t i_track );

49
50
51
52
53
54
55
#ifdef HAVE_LIBCDDB

#define free_and_dup(var, val) \
  if (var) free(var);          \
  if (val) var=strdup(val);


56
/* Saves CDDB information about CD-DA via libcddb. */
57
static void
58
GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
59
{
zorglub's avatar
zorglub committed
60
61
    int i, i_matches;
    cddb_conn_t  *conn = cddb_new();
62
    const CdIo_t *p_cdio = p_cdda->p_cdio;
63

zorglub's avatar
zorglub committed
64
    dbg_print( (INPUT_DBG_CALL), "" );
65
66

#ifdef FIXME_NOW
zorglub's avatar
zorglub committed
67
    cddb_log_set_handler (uninit_log_handler);
68
#endif
zorglub's avatar
zorglub committed
69
70
71
72
73
74
75

    if (!conn)
    {
        msg_Warn( p_access, "Unable to initialize libcddb" );
        goto cddb_destroy;
    }

ivoire's avatar
ivoire committed
76
77
78
79
    char* psz_email = config_GetPsz( p_access, MODULE_STRING "-cddb-email");
    char* psz_srv_name = config_GetPsz( p_access, MODULE_STRING "-cddb-server");
    cddb_set_email_address( conn, psz_email );
    cddb_set_server_name( conn, psz_srv_name );
zorglub's avatar
zorglub committed
80
81
82
    cddb_set_server_port(conn,
                         config_GetInt( p_access,
                                        MODULE_STRING "-cddb-port") );
ivoire's avatar
ivoire committed
83
84
    free( psz_email );
    free( psz_srv_name );
zorglub's avatar
zorglub committed
85

86
87
88
  /* Set the location of the local CDDB cache directory.
     The default location of this directory is */

zorglub's avatar
zorglub committed
89
90
91
    if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
        cddb_cache_disable(conn);

ivoire's avatar
ivoire committed
92
93
94
    char* psz_cache = config_GetPsz( p_access, MODULE_STRING "-cddb-cachedir");
    cddb_cache_set_dir(conn, psz_cache );
    free( psz_cache );
zorglub's avatar
zorglub committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

    cddb_set_timeout(conn,
                   config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );


    if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
    {
        cddb_http_enable(conn);
    }
    else
    {
        cddb_http_disable(conn);
    }

    p_cdda->cddb.disc = cddb_disc_new();

    if (!p_cdda->cddb.disc)
    {
        msg_Err( p_access, "Unable to create CDDB disc structure." );
        goto cddb_end;
    }

    for(i = 0; i < p_cdda->i_tracks; i++)
    {
        track_t i_track =  p_cdda->i_first_track + i;
        cddb_track_t *t = cddb_track_new();
121
122
    cddb_track_set_frame_offset(t,
                    cdio_get_track_lba(p_cdio, i_track));
zorglub's avatar
zorglub committed
123
124
125
        cddb_disc_add_track(p_cdda->cddb.disc, t);
    }

126
    cddb_disc_set_length(p_cdda->cddb.disc,
127
128
             cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
             / CDIO_CD_FRAMES_PER_SEC);
zorglub's avatar
zorglub committed
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

    if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
    {
        msg_Err( p_access, "CDDB disc ID calculation failed" );
        goto cddb_destroy;
    }

    i_matches = cddb_query(conn, p_cdda->cddb.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(conn, p_cdda->cddb.disc);

        if (p_cdda->i_debug & INPUT_DBG_CDDB)
            cddb_disc_print(p_cdda->cddb.disc);

    }
    else
    {
        msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
    }
153

zorglub's avatar
zorglub committed
154
155
156
157
cddb_destroy:
    cddb_destroy(conn);

cddb_end: ;
158
159
160
}
#endif /*HAVE_LIBCDDB*/

161
162
163
164
165
166
#define add_meta_val(VLC_META, VAL)                           \
  if ( p_cdda->p_meta && VAL) {                               \
    /*vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL );*/        \
    dbg_print( INPUT_DBG_META, "field %s: %s\n",              \
            input_MetaTypeToLocalizedString(VLC_META), VAL ); \
  }                                                           \
zorglub's avatar
zorglub committed
167

168
#define add_cddb_meta(FIELD, VLC_META)                            \
169
  add_meta_val(VLC_META, cddb_disc_get_##FIELD(p_cdda->cddb.disc));
zorglub's avatar
zorglub committed
170
171
172
173
174

#define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META)                 \
  {                                                                     \
    char psz_buf[100];                                                  \
    snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC,                  \
175
              cddb_disc_get_##FIELD(p_cdda->cddb.disc));                               \
zorglub's avatar
zorglub committed
176
    psz_buf[sizeof(psz_buf)-1] = '\0';                                  \
177
    add_meta_val(VLC_META, psz_buf);                    \
zorglub's avatar
zorglub committed
178
  }
179
180
181
182

/* Adds a string-valued entry to the stream and media information if
   the string is not null or the null string.
 */
zorglub's avatar
zorglub committed
183
184
185
186
187
188
189
#define add_info_str(CATEGORY, TITLE, FIELD)                      \
  if (FIELD && strlen(FIELD)) {                                   \
    input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY,     \
                   _(TITLE), "%s", FIELD );                       \
  }

/* Adds a numeric-valued entry to the stream and media information
190
   if the number is not zero. */
zorglub's avatar
zorglub committed
191
192
193
194
195
#define add_info_val(CATEGORY, TITLE, FMT, FIELD)                 \
  if (FIELD) {                                                    \
    input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY,     \
                   _(TITLE), FMT, FIELD );                        \
  }
196
197
198
199

/* Adds a CDDB string-valued entry to the stream and media information
   under category "Disc" if the string is not null or the null string.
 */
zorglub's avatar
zorglub committed
200
#define add_cddb_disc_info_str(TITLE, FIELD)                    \
201
  add_info_str("Disc", TITLE, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
202
203
204
205

/* Adds a CDDB numeric-valued entry to the stream and media information
   under category "Disc" if the string is not null or the null string.
 */
zorglub's avatar
zorglub committed
206
#define add_cddb_disc_info_val(TITLE, FMT, FIELD)               \
207
  add_info_val("Disc", TITLE, FMT, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
208
209
210
211

/* Adds a CD-Text string-valued entry to the stream and media information
   under category "Disc" if the string is not null or the null string.
 */
zorglub's avatar
zorglub committed
212
#define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD)              \
213
214
215
216
217
    add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])

/* Adds a CD-Text string-valued entry to the stream and media information
   under category "Disc" if the string is not null or the null string.
 */
zorglub's avatar
zorglub committed
218
#define add_cdtext_disc_info_str(TITLE, FIELD) \
219
220
221
  add_cdtext_info_str("Disc", TITLE, 0, FIELD)


222
/*
223
224
225
226
227
  Saves Meta Information about the CD-DA.

  Meta information used in "stream and media info" or in playlist
  info. The intialization of CD-Text or CDDB is done here though.
  Therefore, this should be called before CDDAMetaInfo is called.
228
229

 */
230
void
231
CDDAMetaInfoInit( access_t *p_access )
232
233
{
    cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;
Jean-Paul Saman's avatar
Jean-Paul Saman committed
234

235
236
    if ( ! p_cdda ) return;

237
238
    dbg_print( (INPUT_DBG_CALL), "p_cdda->i_tracks %d",
           p_cdda->i_tracks );
239

240
    p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
241
#if 0
242
    p_cdda->p_meta = vlc_meta_New();
243
#endif
244
245
246
247
248
249
250
251

#ifdef HAVE_LIBCDDB
    if ( p_cdda->b_cddb_enabled )
    {
        GetCDDBInfo(p_access, p_cdda);
    }

#endif /*HAVE_LIBCDDB*/
252
 
253
254
#define TITLE_MAX 30
    {
255
        track_t i_track;
256

Jean-Paul Saman's avatar
Jean-Paul Saman committed
257
258
259
260
261
        for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
        {
            p_cdda->p_cdtext[i_track] =
            cdio_get_cdtext(p_cdda->p_cdio, i_track);
        }
262
263
264
    }
}

265
266
/*
 In the Control routine, we handle Meta Information requests and
267
 basically copy what was saved in CDDAMetaInfoInit.
268

269
270
 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
 CD.
zorglub's avatar
zorglub committed
271
 */
272
void
273
CDDAMetaInfo( access_t *p_access, track_t i_track )
274
{
zorglub's avatar
zorglub committed
275
    cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
276
    char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
277
    char *psz_meta_artist = NULL;
Jean-Paul Saman's avatar
Jean-Paul Saman committed
278

zorglub's avatar
zorglub committed
279
280
    if ( ! p_cdda ) return;

281
282
    dbg_print( (INPUT_DBG_CALL), "i_track %d", i_track );

283
#ifdef HAVE_LIBCDDB
284
285

    /* Set up for Meta and name for CDDB access. */
286
    if ( p_cdda->b_cddb_enabled &&  p_cdda->cddb.disc )
zorglub's avatar
zorglub committed
287
    {
288
        if( CDIO_INVALID_TRACK == i_track )
Jean-Paul Saman's avatar
Jean-Paul Saman committed
289
        {
290

Jean-Paul Saman's avatar
Jean-Paul Saman committed
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
            psz_meta_title  = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
            psz_meta_artist = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
            if ( cddb_disc_get_genre(p_cdda->cddb.disc) &&
                strlen(cddb_disc_get_genre(p_cdda->cddb.disc)) )
                add_cddb_meta(genre, vlc_meta_Genre);
            if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc))
                add_cddb_meta_fmt(year, "%d", vlc_meta_Date );
        }
        else
        {
            cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
            if (t != NULL )
            {
                if( cddb_track_get_title(t) != NULL && ! p_cdda->b_nav_mode )
                {
                    add_meta_val( vlc_meta_Title, cddb_track_get_title(t) );
                }
                if( cddb_track_get_artist(t) != NULL )
                {
                    add_meta_val( vlc_meta_Artist, cddb_track_get_artist(t) );
                }
            }
        }
314
315
    }
#endif /*HAVE_LIBCDDB*/
Jean-Paul Saman's avatar
Jean-Paul Saman committed
316

317
#define TITLE_MAX 30
zorglub's avatar
zorglub committed
318
319
320
321
    {
        track_t i = p_cdda->i_tracks;
        const int i_first_track = p_cdda->i_first_track;
        char psz_buffer[MSTRTIME_MAX_SIZE];
Jean-Paul Saman's avatar
Jean-Paul Saman committed
322
323
324
        unsigned int i_track_frames =
        cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);

325
        mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
zorglub's avatar
zorglub committed
326

327
328
        dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
           (long int) i_duration, p_cdda->i_tracks );
zorglub's avatar
zorglub committed
329
330
331
332
        input_Control( p_cdda->p_input, INPUT_ADD_INFO,
                       _("Disc"), _("Duration"), "%s",
                       secstotimestr( psz_buffer, i_duration ) );

Jean-Paul Saman's avatar
Jean-Paul Saman committed
333
334
335
336
337
338
339
340
        if (p_cdda->psz_mcn)
        {
            input_Control( p_cdda->p_input, INPUT_ADD_INFO,
                _("Disc"), _("Media Catalog Number (MCN)"), "%s",
                p_cdda->psz_mcn );
            input_Control( p_cdda->p_input, INPUT_ADD_INFO,
                _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
        }
341

342
#ifdef HAVE_LIBCDDB
zorglub's avatar
zorglub committed
343
344
        if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
        {
Jean-Paul Saman's avatar
Jean-Paul Saman committed
345
346
347
348
349
350
351
352
353
354
            add_cddb_disc_info_str("Artist (CDDB)", artist);
            if ( CDDB_CAT_INVALID != cddb_disc_get_category(p_cdda->cddb.disc) )
                add_info_str("Disc", "Category (CDDB)",
                        CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
            add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
            add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
            add_cddb_disc_info_str("Genre (CDDB)",  genre);
            add_cddb_disc_info_str("Title (CDDB)",  title);
            if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc) )
                add_cddb_disc_info_val("Year (CDDB)", "%d", year);
zorglub's avatar
zorglub committed
355
356

        }
357
358
#endif /*HAVE_LIBCDDB*/

zorglub's avatar
zorglub committed
359
360
        if (p_cdda->p_cdtext[0])
        {
Jean-Paul Saman's avatar
Jean-Paul Saman committed
361
362
            char *psz_field;

zorglub's avatar
zorglub committed
363
364
365
366
367
368
369
370
            add_cdtext_disc_info_str("Arranger (CD-Text)",    CDTEXT_ARRANGER);
            add_cdtext_disc_info_str("Composer (CD-Text)",    CDTEXT_COMPOSER);
            add_cdtext_disc_info_str("Disc ID (CD-Text)",     CDTEXT_DISCID);
            add_cdtext_disc_info_str("Genre (CD-Text)",       CDTEXT_GENRE);
            add_cdtext_disc_info_str("Message (CD-Text)",     CDTEXT_MESSAGE);
            add_cdtext_disc_info_str("Performer (CD-Text)",   CDTEXT_PERFORMER);
            add_cdtext_disc_info_str("Songwriter (CD-Text)",  CDTEXT_SONGWRITER);
            add_cdtext_disc_info_str("Title (CD-Text)",       CDTEXT_TITLE);
371

Jean-Paul Saman's avatar
Jean-Paul Saman committed
372
373
374
375
376
377
378
            psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
            if (psz_field && strlen(psz_field))
                psz_meta_title = psz_field;

            psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
            if (psz_field && strlen(psz_field))
                psz_meta_artist = psz_field;
379
380
        }

Jean-Paul Saman's avatar
Jean-Paul Saman committed
381
        for( i = 0 ; i < p_cdda->i_tracks ; i++ )
382
        {
Jean-Paul Saman's avatar
Jean-Paul Saman committed
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
            char psz_track[TITLE_MAX];
            const track_t i_track = i_first_track + i;
            unsigned int i_track_frames =
            cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
            cdio_get_track_lsn(p_cdda->p_cdio, i_track);

            mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
            char *psz_mrl = CDDAFormatMRL( p_access, i_track );

            snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);

            input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
                _("Duration"), "%s",
                secstotimestr( psz_buffer, i_duration ) );

            input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
                _("MRL"), "%s", psz_mrl );
            free(psz_mrl);

            if (p_cdda->p_cdtext[i_track])
            {
                add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
                        i_track, CDTEXT_ARRANGER);
                add_cdtext_info_str( psz_track, "Composer (CD-Text)",
                        i_track, CDTEXT_COMPOSER);
                add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
                        i_track, CDTEXT_DISCID);
                add_cdtext_info_str( psz_track, "Genre (CD-Text)",
                        i_track, CDTEXT_GENRE);
                add_cdtext_info_str( psz_track, "Message (CD-Text)",
                        i_track, CDTEXT_MESSAGE);
                add_cdtext_info_str( psz_track, "Performer (CD-Text)",
                        i_track, CDTEXT_PERFORMER);
                add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
                        i_track, CDTEXT_SONGWRITER);
                add_cdtext_info_str( psz_track, "Title (CD-Text)",
                        i_track, CDTEXT_TITLE);
            }

422
#ifdef HAVE_LIBCDDB
Jean-Paul Saman's avatar
Jean-Paul Saman committed
423
424
425
426
427
428
429
430
431
432
433
434
435
            if (p_cdda->b_cddb_enabled)
            {
                cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
                if (t != NULL)
                {
                    add_info_str(psz_track, "Artist (CDDB)",
                            cddb_track_get_artist(t));
                    add_info_str(psz_track, "Title (CDDB)",
                            cddb_track_get_title(t));
                    add_info_str(psz_track, "Extended Data (CDDB)",
                            cddb_track_get_ext_data(t));
                }
            }
436
#endif /*HAVE_LIBCDDB*/
Jean-Paul Saman's avatar
Jean-Paul Saman committed
437
        }
438
439
440
441
442
443
444
445
446
447
448
449
450
451

    /* Above we should have set psz_meta_title and psz_meta_artist
       to CDDB or CD-Text values or the default value depending on
       availablity and user preferences.

       So now add the title and artist to VLC's meta, and the name
       as shown in the status bar and playlist entry.

       For playlist mode, the meta title is what's seen at the
       bottom and in the playlist. For nav-mode playing, it is
       done by input_control. I don't understand why they do
       different things. In either case, we may have customized to
       put in the track name.
     */
Jean-Paul Saman's avatar
Jean-Paul Saman committed
452
        if ( CDIO_INVALID_TRACK != i_track )
453
        {
Jean-Paul Saman's avatar
Jean-Paul Saman committed
454
455
456
457
458
459
460
461
462
463
            char *psz_name = CDDAFormatTitle( p_access, i_track ) ;
            if ( !p_cdda->b_nav_mode ) {
                add_meta_val( vlc_meta_Title, psz_name );
            } else
            {
                input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
                free(psz_name);
            }
            if (psz_meta_artist)
            add_meta_val( vlc_meta_Artist, psz_meta_artist );
464
        }
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    }
}

#define add_format_str_info(val)                         \
  {                                                      \
    const char *str = val;                               \
    unsigned int len;                                    \
    if (val != NULL) {                                   \
      len=strlen(str);                                   \
      if (len != 0) {                                    \
        strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));    \
        tp += len;                                       \
      }                                                  \
      saw_control_prefix = false;                        \
    }                                                    \
  }

#define add_format_num_info(val, fmt)                    \
  {                                                      \
    char num_str[10];                                    \
    unsigned int len;                                    \
    sprintf(num_str, fmt, val);                          \
    len=strlen(num_str);                                 \
    if (len != 0) {                                      \
      strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));  \
      tp += len;                                         \
    }                                                    \
    saw_control_prefix = false;                          \
  }

495
496
static inline bool
want_cddb_info(
497
cdda_data_t *p_cdda, char *psz_cdtext)
498
499
500
{
  /* We either don't have CD-Text info, or we do but we prefer to get CDDB
     which means CDDB has been enabled and we were able to retrieve the info.*/
501
#ifdef HAVE_LIBCDDB
Jean-Paul Saman's avatar
Jean-Paul Saman committed
502
503
    return !psz_cdtext ||
        (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
504
#else
Jean-Paul Saman's avatar
Jean-Paul Saman committed
505
    return false;
506
#endif
507
508
509
}


510
511
512
513
514
515
516
517
/*!
   Take a format string and expand escape sequences, that is sequences that
   begin with %, with information from the current CD.
   The expanded string is returned. Here is a list of escape sequences:

   %a : The album artist **
   %A : The album information **
   %C : Category **
Rocky Bernstein's avatar
Rocky Bernstein committed
518
   %e : The extended track data
519
520
521
522
523
524
525
   %I : CDDB disk ID **
   %G : Genre **
   %M : The current MRL
   %m : The CD-DA Media Catalog Number (MCN)
   %n : The number of tracks on the CD
   %p : The artist/performer/composer in the track **
   %T : The track number **
526
527
   %s : Number of seconds in this track, or seconds in CD if invalid track
   %S : Number of seconds on the CD
528
   %t : The track name or MRL if no name
529
530
531
   %Y : The year 19xx or 20xx **
   %% : a %
*/
532
char *
533
CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
Rocky Bernstein's avatar
Rocky Bernstein committed
534
               const char format_str[], const char *psz_mrl, track_t i_track)
535
536
537
{
#define TEMP_STR_SIZE 256
#define TEMP_STR_LEN (TEMP_STR_SIZE-1)
538
    static char temp_str[TEMP_STR_SIZE];
zorglub's avatar
zorglub committed
539
540
    size_t i;
    char * tp = temp_str;
541
    bool saw_control_prefix = false;
zorglub's avatar
zorglub committed
542
    size_t format_len = strlen(format_str);
543

zorglub's avatar
zorglub committed
544
    memset(temp_str, 0, TEMP_STR_SIZE);
545

zorglub's avatar
zorglub committed
546
547
    for (i=0; i<format_len; i++)
    {
548
        char *psz = NULL;
549

zorglub's avatar
zorglub committed
550
551
552
553
554
555
        if (!saw_control_prefix && format_str[i] != '%')
        {
            *tp++ = format_str[i];
            saw_control_prefix = false;
            continue;
        }
556

zorglub's avatar
zorglub committed
557
558
559
560
561
562
563
564
565
        switch(format_str[i])
        {
            case '%':
              if (saw_control_prefix)
              {
                  *tp++ = '%';
              }
              saw_control_prefix = !saw_control_prefix;
              break;
566
#ifdef HAVE_LIBCDDB
zorglub's avatar
zorglub committed
567
            case 'a':
zorglub's avatar
zorglub committed
568
569
                if (p_cdda->p_cdtext[0]
                    && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
Jean-Paul Saman's avatar
Jean-Paul Saman committed
570
                    psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
zorglub's avatar
zorglub committed
571
                if (want_cddb_info(p_cdda, psz))
Jean-Paul Saman's avatar
Jean-Paul Saman committed
572
                    psz = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
573
                goto format_str;
zorglub's avatar
zorglub committed
574
            case 'A':
zorglub's avatar
zorglub committed
575
576
                if (p_cdda->p_cdtext[0]
                    && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
Jean-Paul Saman's avatar
Jean-Paul Saman committed
577
578
579
                    psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
                if (want_cddb_info(p_cdda, psz))
                    psz =  (char *)cddb_disc_get_title(p_cdda->cddb.disc);
580
                goto format_str;
zorglub's avatar
zorglub committed
581
582
583
            case 'C':
                if (!p_cdda->b_cddb_enabled) goto not_special;
                if (p_cdda->cddb.disc)
584
                    add_format_str_info(CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
zorglub's avatar
zorglub committed
585
586
                break;
            case 'G':
zorglub's avatar
zorglub committed
587
588
                if (p_cdda->p_cdtext[0]
                    && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
Jean-Paul Saman's avatar
Jean-Paul Saman committed
589
                    psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
zorglub's avatar
zorglub committed
590
                if (want_cddb_info(p_cdda, psz))
Jean-Paul Saman's avatar
Jean-Paul Saman committed
591
                    psz = (char *)cddb_disc_get_genre(p_cdda->cddb.disc);
zorglub's avatar
zorglub committed
592
                goto format_str;
zorglub's avatar
zorglub committed
593
            case 'I':
zorglub's avatar
zorglub committed
594
595
                if (p_cdda->p_cdtext[0]
                    && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
Jean-Paul Saman's avatar
Jean-Paul Saman committed
596
                    psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
zorglub's avatar
zorglub committed
597
                if (want_cddb_info(p_cdda, psz)) {
Jean-Paul Saman's avatar
Jean-Paul Saman committed
598
                    add_format_num_info(cddb_disc_get_discid(p_cdda->cddb.disc), "%x");
zorglub's avatar
zorglub committed
599
                } else if (psz)
Jean-Paul Saman's avatar
Jean-Paul Saman committed
600
                    add_format_str_info(psz);
zorglub's avatar
zorglub committed
601
602
603
604
                break;
            case 'Y':
                if (!p_cdda->b_cddb_enabled) goto not_special;
                if (p_cdda->cddb.disc)
605
606
                    add_format_num_info(cddb_disc_get_year(p_cdda->cddb.disc),
                    "%5d");
zorglub's avatar
zorglub committed
607
608
                break;
            case 't':
zorglub's avatar
zorglub committed
609
                if ( CDIO_INVALID_TRACK == i_track ) break;
zorglub's avatar
zorglub committed
610
611
612
613
                if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
                {
                    cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
                                                        i_track-1);
614
615
                    if (t != NULL && cddb_track_get_title(t) != NULL) {
                      add_format_str_info(cddb_track_get_title(t));
zorglub's avatar
zorglub committed
616
                    } else {
Rocky Bernstein's avatar
Rocky Bernstein committed
617
                      add_format_str_info(psz_mrl);
zorglub's avatar
zorglub committed
618
                    }
Jean-Paul Saman's avatar
Jean-Paul Saman committed
619
620
621
622
623
624
625
626
627
628
629
                }
                else
                {
                    if (p_cdda->p_cdtext[i_track]
                        && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
                    {
                        add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
                    }
                    else
                        add_format_str_info(psz_mrl);
                }
zorglub's avatar
zorglub committed
630
                break;
Jean-Paul Saman's avatar
Jean-Paul Saman committed
631
632
633
634
635
636
            case 'p':
                if ( CDIO_INVALID_TRACK == i_track ) break;
                if (p_cdda->p_cdtext[i_track]
                    && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
                    psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
                if (want_cddb_info(p_cdda, psz))
zorglub's avatar
zorglub committed
637
638
                {
                    cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
Jean-Paul Saman's avatar
Jean-Paul Saman committed
639
640
641
                                i_track-1);
                    if (t != NULL && cddb_track_get_artist(t) != NULL)
                    psz = (char *)cddb_track_get_artist(t);
642
                }
Jean-Paul Saman's avatar
Jean-Paul Saman committed
643
644
645
646
647
648
649
650
651
652
653
654
655
656
                goto format_str;
            case 'e':
                    if ( CDIO_INVALID_TRACK == i_track ) break;
                    if (p_cdda->p_cdtext[i_track]
                        && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
                    psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
                    if (want_cddb_info(p_cdda, psz))
                    {
                        cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
                                                            i_track-1);
                        if (t != NULL && cddb_track_get_ext_data(t) != NULL)
                            psz = (char *)cddb_track_get_ext_data(t);
                    }
                    goto format_str;
zorglub's avatar
zorglub committed
657
                break;
658
659
#else
            case 'a':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
660
661
662
663
                if (p_cdda->p_cdtext[0]
                && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
                psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
                    goto format_str;
664
            case 'A':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
665
666
667
                if (p_cdda->p_cdtext[0]
                    && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
                psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
668
669
                goto format_str;
            case 'G':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
670
671
672
673
                if (p_cdda->p_cdtext[0]
                && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
                    psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
                goto format_str;
674
            case 'I':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
675
676
677
                if (p_cdda->p_cdtext[0]
                    && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
                    add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
678
                break;
Jean-Paul Saman's avatar
Jean-Paul Saman committed
679
680
681
682
683
684
            case 'p':
                if ( CDIO_INVALID_TRACK == i_track ) break;
                if (p_cdda->p_cdtext[i_track]
                    && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
                psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
                goto format_str;
Rocky Bernstein's avatar
Rocky Bernstein committed
685
            case 't':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
686
687
688
689
690
691
                if ( CDIO_INVALID_TRACK == i_track ) break;
                if (p_cdda->p_cdtext[i_track]
                    && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
                    psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
                else
                    psz = psz_mrl;
Rocky Bernstein's avatar
Rocky Bernstein committed
692
                goto format_str;
693
            case 'e':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
694
695
696
697
698
                if ( CDIO_INVALID_TRACK == i_track ) break;
                if (p_cdda->p_cdtext[i_track]
                    && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
                psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
                goto format_str;
699
                break;
700
#endif /*HAVE_LIBCDDB*/
701

702
            case 's':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
703
                if ( CDIO_INVALID_TRACK != i_track )
704
705
                {
                    char psz_buffer[MSTRTIME_MAX_SIZE];
Jean-Paul Saman's avatar
Jean-Paul Saman committed
706
707
                    unsigned int i_track_frames =
                    cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
708
                    mtime_t i_duration =
Jean-Paul Saman's avatar
Jean-Paul Saman committed
709
                        i_track_frames / CDIO_CD_FRAMES_PER_SEC;
710
711
                    add_format_str_info( secstotimestr( psz_buffer,
                            i_duration ) );
Jean-Paul Saman's avatar
Jean-Paul Saman committed
712
                    break;
713
714
                }

Jean-Paul Saman's avatar
Jean-Paul Saman committed
715
            /* Fall through to disc duration if CDIO_INVALID_TRACK  */
716
717
718
            case 'S':
                {
                    char psz_buffer[MSTRTIME_MAX_SIZE];
Jean-Paul Saman's avatar
Jean-Paul Saman committed
719
720
721
                    unsigned int i_track_frames =
                    cdio_get_track_lba(p_cdda->p_cdio,
                        CDIO_CDROM_LEADOUT_TRACK);
722
                    mtime_t i_duration =
Jean-Paul Saman's avatar
Jean-Paul Saman committed
723
                    i_track_frames / CDIO_CD_FRAMES_PER_SEC;
724
725
                    add_format_str_info( secstotimestr( psz_buffer,
                            i_duration ) );
Jean-Paul Saman's avatar
Jean-Paul Saman committed
726
                    break;
727
728
                }

zorglub's avatar
zorglub committed
729
            case 'M':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
730
731
                add_format_str_info(psz_mrl);
                break;
732

zorglub's avatar
zorglub committed
733
            case 'm':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
734
735
                add_format_str_info(p_cdda->psz_mcn);
                break;
736

zorglub's avatar
zorglub committed
737
            case 'n':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
738
739
                add_format_num_info(p_cdda->i_tracks, "%d");
                break;
740

zorglub's avatar
zorglub committed
741
            case 'T':
Jean-Paul Saman's avatar
Jean-Paul Saman committed
742
743
744
745
746
747
                add_format_num_info(i_track, "%02d");
                break;
            format_str:
                if (psz)
                    add_format_str_info(psz);
                break;
748
#ifdef HAVE_LIBCDDB
zorglub's avatar
zorglub committed
749
            not_special:
750
#endif
zorglub's avatar
zorglub committed
751
752
753
754
755
            default:
                *tp++ = '%';
                *tp++ = format_str[i];
                saw_control_prefix = false;
        }
756
    }
zorglub's avatar
zorglub committed
757
    return strdup(temp_str);
758
759
}

760
/* Return a MRL for the given track. The caller must free the
761
762
763
764
765
   allocated string. */
static char *
CDDAFormatMRL( const access_t *p_access, track_t i_track )
{
    cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
766
    const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
767
768
      + strlen(p_cdda->psz_source) +
      + strlen("@T") + strlen("100") + 1;
769
    char *psz_mrl = calloc( 1, psz_mrl_max );
Jean-Paul Saman's avatar
Jean-Paul Saman committed
770

771
772
    if (CDIO_INVALID_TRACK == i_track)
      snprintf(psz_mrl, psz_mrl_max, "%s%s",
773
774
           CDDA_MRL_PREFIX, p_cdda->psz_source);
    else
775
      snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
776
           CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
777
778
779
780
    return psz_mrl;
}


781
/* Return a title string as specified by the titel format string for the
782
783
784
   given track. The caller must free the allocated string. */
char *
CDDAFormatTitle( const access_t *p_access, track_t i_track )
785
{
786

787
    const char *config_varname = MODULE_STRING "-title-format";
788
789
790
    cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
    char *psz_mrl = CDDAFormatMRL( p_access, i_track );

791
    if( psz_mrl )
792
793
794
    {
        char *psz_name;
#ifdef HAVE_LIBCDDB
Jean-Paul Saman's avatar
Jean-Paul Saman committed
795
796
797
798
        if (p_cdda->b_cddb_enabled)
        {
            config_varname = MODULE_STRING "-cddb-title-format";
        }
799
#endif /*HAVE_LIBCDDB*/
ivoire's avatar
ivoire committed
800
801
802
803
804
        char* psz_config_varname = config_GetPsz( p_access, config_varname );
        psz_name = CDDAFormatStr( p_access, p_cdda, psz_config_varname,
                                  psz_mrl, i_track );
        free( psz_config_varname );
        free( psz_mrl );
Jean-Paul Saman's avatar
Jean-Paul Saman committed
805
        return psz_name;
806
    }
ivoire's avatar
ivoire committed
807
    return NULL;
808
809
810
}

static playlist_item_t *
zorglub's avatar
zorglub committed
811
CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
812
                        playlist_t *p_playlist, playlist_item_t *p_item,
813
                        track_t i_track )
814
{
815
    unsigned int i_track_frames =
Jean-Paul Saman's avatar
Jean-Paul Saman committed
816
817
    cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
    cdio_get_track_lsn(p_cdda->p_cdio, i_track);
818
    mtime_t i_mduration = i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
819
820
    char *psz_title = NULL;
    char *psz_mrl   = NULL;
zorglub's avatar
zorglub committed
821
822
823

    playlist_item_t *p_child = NULL;

824
    if( !p_item ) return NULL;
825

826
827
    psz_title = CDDAFormatTitle( p_access, i_track ) ;
    psz_mrl = CDDAFormatMRL( p_access, i_track  ) ;
828

zorglub's avatar
zorglub committed
829
    dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
830
               psz_mrl, psz_title, (long int) i_mduration / 1000000 );
zorglub's avatar
zorglub committed
831
832

    p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
833
    input_item_SetDuration( p_child->p_input,
834
            (mtime_t) i_mduration );
835
836
    free(psz_mrl);
    free(psz_title);
zorglub's avatar
zorglub committed
837
838
839
840
841

    if( !p_child ) return NULL;
    return p_child;
}

842
843
/*
   Fixes up playlist.
844
*/
845
int
846
CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
847
                   bool b_single_track )
848
{
zorglub's avatar
zorglub committed
849
    int i;
850
    playlist_t * p_playlist = NULL;
zorglub's avatar
zorglub committed
851
    const track_t i_first_track = p_cdda->i_first_track;
852
    playlist_item_t *p_item = NULL;
853
    bool b_play = false;
854
    track_t    i_track;
855
856

#ifdef HAVE_LIBCDDB
zorglub's avatar
zorglub committed
857
858
859
860
    p_cdda->b_cddb_enabled =
        config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
    if( b_single_track && !p_cdda->b_cddb_enabled )
        return VLC_SUCCESS;
861
#else
zorglub's avatar
zorglub committed
862
863
    if( b_single_track )
        return VLC_SUCCESS;
864
865
#endif

866
    if (! p_cdda->b_nav_mode ) {
zorglub's avatar
zorglub committed
867
        p_playlist = pl_Yield( p_access );
868
869
    }

870
871
    if( b_single_track || p_cdda->b_nav_mode ) {
        i_track = p_cdda->i_track;
zorglub's avatar
zorglub committed
872
873
874
    }
    else
    {
875
        i_track = CDIO_INVALID_TRACK;
zorglub's avatar
zorglub committed
876
    }
877
878
    CDDAMetaInfoInit( p_access );
    CDDAMetaInfo( p_access, p_cdda->i_track );
zorglub's avatar
zorglub committed
879

880
881
882
883
884
    if( p_playlist )
    {
        input_thread_t *p_input = (input_thread_t*)vlc_object_find( p_access, VLC_OBJECT_INPUT, FIND_PARENT );
        if( p_input )
        {
ivoire's avatar
ivoire committed
885
            p_item = playlist_ItemGetByInput( p_playlist, input_GetItem(p_input), pl_Unlocked );
886

887
            if( p_item == p_playlist->status.p_item && !b_single_track )
888
                b_play = true;
889
            else
890
                b_play = false;
891
892
            vlc_object_release( p_input );
        }
zorglub's avatar
zorglub committed
893
894
    }

895
    if( b_single_track && !p_cdda->b_nav_mode )
zorglub's avatar
zorglub committed
896
897
898
899
900
    {
        /*May fill out more information when the playlist user interface becomes
           more mature.
         */
        track_t i_track = p_cdda->i_track;
Jean-Paul Saman's avatar
Jean-Paul Saman committed
901
902
903
        unsigned int i_track_frames =
        cdio_get_track_sec_count(p_cdda->p_cdio, i_track);

zorglub's avatar
zorglub committed
904
905
906
907
        input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
        vlc_input_title_New();

        asprintf( &t->psz_name, _("Track %i"), i_track );
908
        t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
909
        t->i_length = INT64_C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
zorglub's avatar
zorglub committed
910

Jean-Paul Saman's avatar
Jean-Paul Saman committed
911
912
913
914
915
916
917
918
        if( p_item )
        {
            input_item_SetDuration( p_item->p_input, (mtime_t) i_track_frames
            * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
                input_item_SetURI( p_item->p_input,
                        CDDAFormatMRL( p_access, i_track ) );
        }

zorglub's avatar
zorglub committed
919
        p_cdda->i_titles = 1;
Jean-Paul Saman's avatar
Jean-Paul Saman committed
920
        p_access->info.i_update = INPUT_UPDATE_TITLE;
zorglub's avatar
zorglub committed
921
922
923
    }
    else
    {
Jean-Paul Saman's avatar
Jean-Paul Saman committed
924
        input_title_t *t;
925

Jean-Paul Saman's avatar
Jean-Paul Saman committed
926
        if( !p_cdda->b_nav_mode )
ivoire's avatar
ivoire committed
927
            playlist_ItemToNode( p_playlist, p_item, pl_Unlocked );
928

zorglub's avatar
zorglub committed
929
930
931
932
        for( i = 0 ; i < p_cdda->i_tracks ; i++ )
        {
            playlist_item_t *p_child;
            const track_t i_track = i_first_track + i;
Jean-Paul Saman's avatar
Jean-Paul Saman committed
933
934
            unsigned int i_track_frames =
                cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
935

936
            t = p_cdda->p_title[i] = vlc_input_title_New();
zorglub's avatar
zorglub committed
937
938

            asprintf( &t->psz_name, _("Track %i"), i_track );
939
            t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
zorglub's avatar
zorglub committed
940

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
941
            t->i_length = INT64_C(1000000) * t->i_size
Jean-Paul Saman's avatar
Jean-Paul Saman committed
942
                / CDDA_FREQUENCY_SAMPLE / 4;
zorglub's avatar
zorglub committed
943

Jean-Paul Saman's avatar
Jean-Paul Saman committed
944
945
946
947
948
            if ( ! p_cdda->b_nav_mode )
            {
                p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
                                                  p_item, i_track );
            }
zorglub's avatar
zorglub committed
949
        }
950
951

        p_cdda->i_titles = p_cdda->i_tracks;
Jean-Paul Saman's avatar
Jean-Paul Saman committed
952
953
        p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
        if( p_item )
954
        {
Jean-Paul Saman's avatar
Jean-Paul Saman committed
955
            input_item_SetDuration( p_item->p_input, (mtime_t) p_access->info.i_size
956
957
958
                    * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
            input_item_SetURI( p_item->p_input,
                    CDDAFormatMRL( p_access, p_cdda->i_track ) );
Jean-Paul Saman's avatar
Jean-Paul Saman committed
959
        }
zorglub's avatar
zorglub committed
960
961
962
963
    }

    if( b_play )
    {
ivoire's avatar
ivoire committed
964
        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Unlocked,
zorglub's avatar
zorglub committed
965
966
967
                          p_playlist->status.p_item, NULL );
    }

ivoire's avatar
ivoire committed
968
    if (p_playlist) pl_Release( p_access );
zorglub's avatar
zorglub committed
969
    return VLC_SUCCESS;
970
971
}

Rocky Bernstein's avatar
Rocky Bernstein committed
972

973
/*
Rocky Bernstein's avatar
Rocky Bernstein committed
974
975
976
977
978
 * Local variables:
 *  mode: C
 *  style: gnu
 * End:
 */