access.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:36k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * access.c : CD digital audio input module for vlc using libcdio
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2003, 2004, 2005 the VideoLAN team
  5.  * $Id: db3ed3efcc74e8ab33484334e940213da2ef7f29 $
  6.  *
  7.  * Authors: Rocky Bernstein <rocky@panix.com>
  8.  *          Laurent Aimar <fenrir@via.ecp.fr>
  9.  *          Gildas Bazin <gbazin@netcourrier.com>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  24.  *****************************************************************************/
  25. /*****************************************************************************
  26.  * Preamble
  27.  *****************************************************************************/
  28. #include "callback.h"      /* FIXME - reorganize callback.h, cdda.h better */
  29. #include "cdda.h"          /* private structures. Also #includes vlc things */
  30. #include "info.h"          /* headers for meta info retrieval */
  31. #include "access.h"
  32. #include <vlc_keys.h>
  33. #include <vlc_dialog.h>
  34. #include <cdio/cdio.h>
  35. #include <cdio/logging.h>
  36. #include <cdio/cd_types.h>
  37. /* #ifdef variables below are defined via config.h via #include vlc above. */
  38. #ifdef HAVE_SYS_TYPES_H
  39. #include <sys/types.h>
  40. #endif
  41. #ifdef HAVE_UNISTD_H
  42. #   include <unistd.h>
  43. #endif
  44. /* FIXME: This variable is a hack. Would be nice to eliminate. */
  45. access_t *p_cdda_input = NULL;
  46. /*****************************************************************************
  47.  * Local prototypes
  48.  *****************************************************************************/
  49. static ssize_t  CDDARead( access_t *, uint8_t *, size_t );
  50. static block_t *CDDAReadBlocks( access_t * p_access );
  51. static int      CDDASeek( access_t * p_access, int64_t i_pos );
  52. static int      CDDAControl( access_t *p_access, int i_query,
  53.                              va_list args );
  54. static int      CDDAInit( access_t *p_access, cdda_data_t *p_cdda ) ;
  55. /****************************************************************************
  56.  * Private functions
  57.  ****************************************************************************/
  58. /* process messages that originate from libcdio.
  59.    called by CDDAOpen
  60. */
  61. static void
  62. cdio_log_handler( cdio_log_level_t level, const char message[] )
  63. {
  64.     cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
  65.     if( p_cdda == NULL )
  66.         return;
  67.     switch( level )
  68.     {
  69.         case CDIO_LOG_DEBUG:
  70.         case CDIO_LOG_INFO:
  71.             if (p_cdda->i_debug & INPUT_DBG_CDIO)
  72.             msg_Dbg( p_cdda_input, "%s", message);
  73.             break;
  74.         case CDIO_LOG_WARN:
  75.             msg_Warn( p_cdda_input, "%s", message);
  76.             break;
  77.         case CDIO_LOG_ERROR:
  78.         case CDIO_LOG_ASSERT:
  79.             msg_Err( p_cdda_input, "%s", message);
  80.             break;
  81.         default:
  82.             msg_Warn( p_cdda_input, "%sn%s %d", message,
  83.                     "the above message had unknown cdio log level",
  84.                     level);
  85.             break;
  86.     }
  87. }
  88. #ifdef HAVE_LIBCDDB
  89. /*! This routine is called by libcddb routines on error.
  90.    called by CDDAOpen
  91. */
  92. static void
  93. cddb_log_handler( cddb_log_level_t level, const char message[] )
  94. {
  95.     cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
  96.     switch( level )
  97.     {
  98.         case CDDB_LOG_DEBUG:
  99.         case CDDB_LOG_INFO:
  100.             if( !(p_cdda->i_debug & INPUT_DBG_CDDB) )
  101.                 return;
  102.         /* Fall through if to warn case */
  103.         default:
  104.             cdio_log_handler( level, message );
  105.             break;
  106.     }
  107. }
  108. #endif /*HAVE_LIBCDDB*/
  109. /*! This routine is when vlc is not fully set up (before full initialization)
  110.   or is not around (before finalization).
  111. */
  112. static void
  113. uninit_log_handler( cdio_log_level_t level, const char message[] )
  114. {
  115.     cdda_data_t *p_cdda = NULL;
  116.     if( p_cdda_input )
  117.         p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
  118.      switch( level )
  119.      {
  120.         case CDIO_LOG_DEBUG:
  121.         case CDIO_LOG_INFO:
  122.             if( !p_cdda || !(p_cdda->i_debug & (INPUT_DBG_CDIO|INPUT_DBG_CDDB)) )
  123.                 return;
  124.         /* Fall through if to warn case */
  125.         case CDIO_LOG_WARN:
  126.             fprintf( stderr, "WARN: %sn", message );
  127.             break;
  128.         case CDIO_LOG_ERROR:
  129.             fprintf( stderr, "ERROR: %sn", message );
  130.             break;
  131.         case CDIO_LOG_ASSERT:
  132.             fprintf( stderr, "ASSERT ERROR: %sn", message );
  133.             break;
  134.         default:
  135.             fprintf( stderr, "UNKNOWN ERROR: %sn%s %dn", message,
  136.                             "The above message had unknown cdio log level",
  137.                             level );
  138.         break;
  139.     }
  140.     /* gl_default_cdio_log_handler (level, message); */
  141. }
  142. /* Only used in audio control mode. Gets the current LSN from the
  143.    CD-ROM drive. */
  144. static int64_t get_audio_position ( access_t *p_access )
  145. {
  146.     cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;
  147.     lsn_t i_offset;
  148. #if LIBCDIO_VERSION_NUM >= 73
  149.     if( p_cdda->b_audio_ctl )
  150.     {
  151.         cdio_subchannel_t sub;
  152.         CdIo_t *p_cdio = p_cdda->p_cdio;
  153.         if( DRIVER_OP_SUCCESS == cdio_audio_read_subchannel(p_cdio, &sub) )
  154.         {
  155.             if( (sub.audio_status != CDIO_MMC_READ_SUB_ST_PAUSED) &&
  156.                 (sub.audio_status != CDIO_MMC_READ_SUB_ST_PLAY) )
  157.                 return CDIO_INVALID_LSN;
  158.             if( ! p_cdda->b_nav_mode )
  159.             {
  160.                 i_offset = cdio_msf_to_lba( (&sub.abs_addr) );
  161.             }
  162.             else
  163.             {
  164.                 i_offset = cdio_msf_to_lba( (&sub.rel_addr) );
  165.             }
  166.         }
  167.         else
  168.         {
  169.             i_offset = p_cdda->i_lsn;
  170.         }
  171.     }
  172.     else
  173.     {
  174.         i_offset = p_cdda->i_lsn;
  175.     }
  176. #else
  177.         i_offset = p_cdda->i_lsn;
  178. #endif
  179.     return i_offset;
  180. }
  181. /*****************************************************************************
  182.  * CDDAReadBlocks: reads a group of blocks from the CD-DA and returns
  183.  * an allocated pointer to the data. NULL is returned if no data
  184.  * read. It is also possible if we haven't read a RIFF header in which
  185.  * case one that we creaded during Open/Initialization is returned.
  186.  *****************************************************************************/
  187. static block_t * CDDAReadBlocks( access_t * p_access )
  188. {
  189.     block_t     *p_block;
  190.     cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;
  191.     int          i_blocks = p_cdda->i_blocks_per_read;
  192.     dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_LSN),
  193.                 "called i_lsn: %d i_pos: %lld, size: %lld",
  194.                 p_cdda->i_lsn, p_access->info.i_pos, p_access->info.i_size );
  195.     /* Check end of file */
  196.     if( p_access->info.b_eof )
  197.         return NULL;
  198.     if( !p_cdda->b_header )
  199.       {
  200.         /* Return only the dummy RIFF header we created in Open/Init */
  201.         p_block = block_New( p_access, sizeof( WAVEHEADER ) );
  202.         memcpy( p_block->p_buffer, &p_cdda->waveheader, sizeof(WAVEHEADER) );
  203.         p_cdda->b_header = true;
  204.         return p_block;
  205.     }
  206.     /* Check end of track */
  207.     while( p_cdda->i_lsn > cdio_get_track_last_lsn(p_cdda->p_cdio,
  208.            p_cdda->i_track) )
  209.     {
  210.         bool go_on;
  211.         if( p_cdda->b_nav_mode )
  212.             go_on = p_cdda->i_lsn > p_cdda->last_disc_frame;
  213.         else
  214.             go_on = p_cdda->i_track >= p_cdda->i_first_track+p_cdda->i_titles-1 ;
  215.         if( go_on )
  216.         {
  217.             dbg_print( (INPUT_DBG_LSN), "EOF");
  218.                         p_access->info.b_eof = true;
  219.             return NULL;
  220.         }
  221.         p_access->info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_META;
  222.         p_access->info.i_title++;
  223.         p_cdda->i_track++;
  224.         if( p_cdda-> b_nav_mode )
  225.         {
  226.             char *psz_title = CDDAFormatTitle( p_access, p_cdda->i_track );
  227.             input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_title );
  228.             free(psz_title);
  229.         }
  230.         else
  231.         {
  232.             p_access->info.i_size =
  233.                     p_cdda->p_title[p_access->info.i_title]->i_size;
  234.             p_access->info.i_pos = 0;
  235.             p_access->info.i_update |= INPUT_UPDATE_SIZE;
  236.         }
  237.     }
  238.     /* Possibly adjust i_blocks so we don't read past the end of a track. */
  239.     if( p_cdda->i_lsn + i_blocks >=
  240.         cdio_get_track_lsn(p_cdda->p_cdio, p_cdda->i_track+1) )
  241.     {
  242.         i_blocks = cdio_get_track_lsn( p_cdda->p_cdio, p_cdda->i_track+1 )
  243.                     - p_cdda->i_lsn;
  244.     }
  245.     /* Do the actual reading */
  246.     p_block = block_New( p_access, i_blocks * CDIO_CD_FRAMESIZE_RAW );
  247.     if( !p_block)
  248.     {
  249.         msg_Err( p_access, "cannot get a new block of size: %i",
  250.                 i_blocks * CDIO_CD_FRAMESIZE_RAW );
  251.         dialog_Fatal( p_access, _("CD reading failed"),
  252.                         _("VLC could not get a new block of size: %i."),
  253.                         i_blocks * CDIO_CD_FRAMESIZE_RAW );
  254.         return NULL;
  255.     }
  256.     {
  257. #if LIBCDIO_VERSION_NUM >= 72
  258.         driver_return_code_t rc = DRIVER_OP_SUCCESS;
  259.         if( p_cdda->e_paranoia && p_cdda->paranoia )
  260.         {
  261.             int i;
  262.             for( i = 0; i < i_blocks; i++ )
  263.             {
  264.                 int16_t *p_readbuf = cdio_paranoia_read( p_cdda->paranoia, NULL );
  265.                 char *psz_err = cdio_cddap_errors( p_cdda->paranoia_cd );
  266.                 char *psz_mes = cdio_cddap_messages( p_cdda->paranoia_cd );
  267.                 if( psz_mes || psz_err )
  268.                     msg_Err( p_access, "%s%s", psz_mes ? psz_mes: "",
  269.                              psz_err ? psz_err: "" );
  270.                 free( psz_err );
  271.                 free( psz_mes );
  272.                 if( !p_readbuf )
  273.                 {
  274.                     msg_Err( p_access, "paranoia read error on frame %i",
  275.                     p_cdda->i_lsn+i );
  276.                 }
  277.                 else
  278.                     memcpy( p_block->p_buffer + i * CDIO_CD_FRAMESIZE_RAW,
  279.                             p_readbuf, CDIO_CD_FRAMESIZE_RAW );
  280.             }
  281.         }
  282.         else
  283.             rc = cdio_read_audio_sectors( p_cdda->p_cdio, p_block->p_buffer,
  284.                                           p_cdda->i_lsn, i_blocks );
  285. #else
  286. #define DRIVER_OP_SUCCESS 0
  287.         int rc = cdio_read_audio_sectors( p_cdda->p_cdio, p_block->p_buffer,
  288.                                           p_cdda->i_lsn, i_blocks);
  289. #endif
  290.         if( rc != DRIVER_OP_SUCCESS )
  291.         {
  292.             msg_Err( p_access, "could not read %d sectors starting from %lu",
  293.                      i_blocks, (long unsigned int) p_cdda->i_lsn );
  294.             block_Release( p_block );
  295.             /* If we had problems above, assume the problem is with
  296.                 the first sector of the read and set to skip it.  In
  297.                 the future libcdio may have cdparanoia support.
  298.             */
  299.             p_cdda->i_lsn++;
  300.             p_access->info.i_pos += CDIO_CD_FRAMESIZE_RAW;
  301.             return NULL;
  302.         }
  303.     }
  304.     p_cdda->i_lsn        += i_blocks;
  305.     p_access->info.i_pos += i_blocks * CDIO_CD_FRAMESIZE_RAW;
  306.     return p_block;
  307. }
  308. /*****************************************************************************
  309.  * CDDARead: Handler for audio control reads the CD-DA.
  310.  *****************************************************************************/
  311. static ssize_t
  312. CDDARead( access_t * p_access, uint8_t *p_buffer, size_t i_len )
  313. {
  314.     cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;
  315.     dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_LSN),
  316.                "called lsn: %d pos: %lld, size: %lld",
  317.                 p_cdda->i_lsn, p_access->info.i_pos, p_access->info.i_size);
  318.     /* Check end of file */
  319.     if( p_access->info.b_eof )
  320.         return 0;
  321.     {
  322.         lsn_t i_lsn = get_audio_position(p_access);
  323.         if( CDIO_INVALID_LSN == i_lsn )
  324.         {
  325.             dbg_print( (INPUT_DBG_LSN), "invalid lsn" );
  326.             memset( p_buffer, 0, i_len );
  327.             return i_len;
  328.         }
  329.         p_cdda->i_lsn = i_lsn;
  330.         p_access->info.i_pos = p_cdda->i_lsn * CDIO_CD_FRAMESIZE_RAW;
  331.     }
  332.     dbg_print( (INPUT_DBG_LSN), "updated lsn: %d", p_cdda->i_lsn );
  333.     /* Check end of track */
  334.     while( p_cdda->i_lsn > cdio_get_track_last_lsn( p_cdda->p_cdio,
  335.                                                     p_cdda->i_track) )
  336.     {
  337.         if( p_cdda->i_track >= p_cdda->i_first_track + p_cdda->i_titles - 1 )
  338.         {
  339.             dbg_print( (INPUT_DBG_LSN), "EOF");
  340.             p_access->info.b_eof = true;
  341.             return 0;
  342.         }
  343.         p_access->info.i_update |= INPUT_UPDATE_TITLE;
  344.         p_access->info.i_title++;
  345.         p_cdda->i_track++;
  346.         if( p_cdda-> b_nav_mode )
  347.         {
  348.             char *psz_title = CDDAFormatTitle( p_access, p_cdda->i_track );
  349.             input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_title );
  350.             free( psz_title );
  351.         }
  352.         else
  353.         {
  354.             p_access->info.i_size =
  355.                 p_cdda->p_title[p_access->info.i_title]->i_size;
  356.             p_access->info.i_pos = 0;
  357.             p_access->info.i_update |= INPUT_UPDATE_SIZE;
  358.         }
  359.     }
  360.     memset( p_buffer, 0, i_len );
  361.     return i_len;
  362. }
  363. /*! Pause CD playing via audio control */
  364. static bool cdda_audio_pause( CdIo_t *p_cdio )
  365. {
  366.     bool b_ok = true;
  367. #if LIBCDIO_VERSION_NUM >= 73
  368.     cdio_subchannel_t sub;
  369.     if( DRIVER_OP_SUCCESS == cdio_audio_read_subchannel( p_cdio, &sub ) )
  370.     {
  371.         if( sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY )
  372.         {
  373.             b_ok = DRIVER_OP_SUCCESS == cdio_audio_pause(p_cdio);
  374.         }
  375.     }
  376.     else
  377.         b_ok = false;
  378. #endif
  379.     return b_ok;
  380. }
  381. #if LIBCDIO_VERSION_NUM >= 73
  382. /*! play CD using audio controls */
  383. static driver_return_code_t
  384. cdda_audio_play( CdIo_t *p_cdio, lsn_t start_lsn, lsn_t end_lsn )
  385. {
  386.     msf_t start_msf;
  387.     msf_t last_msf;
  388.     cdio_lsn_to_msf( start_lsn, &start_msf );
  389.     cdio_lsn_to_msf( end_lsn, &last_msf );
  390.     cdda_audio_pause( p_cdio );
  391.     return cdio_audio_play_msf( p_cdio, &start_msf, &last_msf );
  392. }
  393. #endif
  394. /****************************************************************************
  395.  * CDDASeek - change position for subsequent reads. For example, this
  396.  * can happen if the user moves a position slider bar in a GUI.
  397.  ****************************************************************************/
  398. static int CDDASeek( access_t * p_access, int64_t i_pos )
  399. {
  400.     cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
  401.     dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK),
  402.                "lsn %lu, offset: %lld",
  403.                (long unsigned int) p_cdda->i_lsn, i_pos );
  404.     p_cdda->i_lsn = (i_pos / CDIO_CD_FRAMESIZE_RAW);
  405. #if LIBCDIO_VERSION_NUM >= 72
  406.     if( p_cdda->e_paranoia && p_cdda->paranoia )
  407.          cdio_paranoia_seek( p_cdda->paranoia, p_cdda->i_lsn, SEEK_SET );
  408. #endif
  409. #if LIBCDIO_VERSION_NUM >= 73
  410.     if( p_cdda->b_audio_ctl )
  411.     {
  412.         track_t i_track = cdio_get_track( p_cdda->p_cdio, p_cdda->i_lsn );
  413.         lsn_t i_last_lsn;
  414.         if( p_cdda->b_nav_mode )
  415.             i_last_lsn = p_cdda->last_disc_frame;
  416.         else
  417.             i_last_lsn = cdio_get_track_last_lsn( p_cdda->p_cdio, i_track );
  418.         cdda_audio_play( p_cdda->p_cdio, p_cdda->i_lsn, i_last_lsn );
  419.     }
  420. #endif
  421.     if( ! p_cdda->b_nav_mode )
  422.         p_cdda->i_lsn += cdio_get_track_lsn( p_cdda->p_cdio, p_cdda->i_track );
  423.     /* Seeked backwards and we are doing disc mode. */
  424.     if( p_cdda->b_nav_mode && p_access->info.i_pos > i_pos )
  425.     {
  426.         track_t i_track;
  427.         char *psz_title;
  428.         for( i_track = p_cdda->i_track; i_track > 1 &&
  429.              p_cdda->i_lsn < cdio_get_track_lsn( p_cdda->p_cdio, i_track );
  430.              i_track--, p_access->info.i_title-- )
  431.             ;
  432.         p_cdda->i_track = i_track;
  433.         p_access->info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_META ;
  434.         psz_title  = CDDAFormatTitle( p_access, p_cdda->i_track );
  435.         input_Control( p_cdda->p_input, INPUT_SET_NAME,
  436.                         psz_title );
  437.         free( psz_title );
  438.     }
  439.     p_access->info.i_pos = i_pos;
  440.     p_access->info.b_eof = false;
  441.     return VLC_SUCCESS;
  442. }
  443. /*
  444.   Set up internal state so that we play a given track.
  445.   If we are using audio-ctl mode we also activate CD-ROM
  446.   to play.
  447.  */
  448. static bool cdda_play_track( access_t *p_access, track_t i_track )
  449. {
  450.     cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
  451.     dbg_print( (INPUT_DBG_CALL), "called track: %dn", i_track );
  452.     if( i_track > p_cdda->i_tracks )
  453.     {
  454.         msg_Err( p_access, "CD has %d tracks, and you requested track %d",
  455.                  p_cdda->i_tracks, i_track );
  456.         return false;
  457.     }
  458.     p_cdda->i_track = i_track;
  459.     /* set up the frame boundaries for this particular track */
  460.     p_cdda->first_frame = p_cdda->i_lsn =
  461.     cdio_get_track_lsn( p_cdda->p_cdio, i_track );
  462.     p_cdda->last_frame  = cdio_get_track_lsn( p_cdda->p_cdio, i_track+1 ) - 1;
  463. #if LIBCDIO_VERSION_NUM >= 73
  464.     if( p_cdda->b_audio_ctl )
  465.     {
  466.         lsn_t i_last_lsn;
  467.         if( p_cdda->b_nav_mode )
  468.             i_last_lsn = p_cdda->last_disc_frame;
  469.         else
  470.             i_last_lsn = cdio_get_track_last_lsn( p_cdda->p_cdio, i_track );
  471.         cdda_audio_play( p_cdda->p_cdio, p_cdda->i_lsn, i_last_lsn );
  472.     }
  473. #endif
  474.     return true;
  475. }
  476. /****************************************************************************
  477.  * Public functions
  478.  ****************************************************************************/
  479. /*****************************************************************************
  480.  * Open: open cdda device or image file and initialize structures
  481.  *       for subsequent operations.
  482.  *****************************************************************************/
  483. int CDDAOpen( vlc_object_t *p_this )
  484. {
  485.     access_t    *p_access = (access_t*)p_this;
  486.     char *      psz_source = NULL;
  487.     cdda_data_t *p_cdda    = NULL;
  488.     CdIo_t      *p_cdio;
  489.     track_t     i_track = 1;
  490.     bool  b_single_track = false;
  491.     int         i_rc = VLC_EGENERIC;
  492.     p_access->p_sys = NULL;
  493.     /* Set where to log errors messages from libcdio. */
  494.     p_cdda_input = p_access;
  495.     /* parse the options passed in command line : */
  496.     if( p_access->psz_path && *p_access->psz_path )
  497.     {
  498.         char *psz_parser = psz_source = strdup( p_access->psz_path );
  499.         while( *psz_parser && *psz_parser != '@' )
  500.         {
  501.             psz_parser++;
  502.         }
  503.         if( *psz_parser == '@' )
  504.         {
  505.             /* Found options */
  506.             *psz_parser = '';
  507.             ++psz_parser;
  508.             if ('T' == *psz_parser || 't' == *psz_parser )
  509.             ++psz_parser;
  510.             i_track = (int)strtol( psz_parser, NULL, 10 );
  511.             i_track = i_track ? i_track : 1;
  512.             b_single_track = true;
  513.         }
  514.     }
  515.     if( !psz_source || !*psz_source )
  516.     {
  517.         free( psz_source );
  518.         /* No device/track given. Continue only when this plugin was
  519.            selected */
  520.         if( !p_this->b_force )
  521.             return VLC_EGENERIC;
  522.         psz_source = var_CreateGetString( p_this, "cd-audio" );
  523.         if( !psz_source || !*psz_source )
  524.         {
  525.             free( psz_source );
  526.             /* Scan for a CD-ROM drive with a CD-DA in it. */
  527.             char **ppsz_drives =
  528.                     cdio_get_devices_with_cap( NULL,  CDIO_FS_AUDIO, false );
  529.             if( (NULL == ppsz_drives) || (NULL == ppsz_drives[0]) )
  530.             {
  531.                 msg_Err( p_access,
  532.                          "libcdio couldn't find something with a CD-DA in it" );
  533.                 if( ppsz_drives )
  534.                     cdio_free_device_list( ppsz_drives );
  535.                 return VLC_EGENERIC;
  536.             }
  537.             psz_source = strdup( ppsz_drives[0] );
  538.             cdio_free_device_list( ppsz_drives );
  539.         }
  540.     }
  541.     cdio_log_set_handler( cdio_log_handler );
  542.     /* Open CDDA */
  543.     if( !(p_cdio = cdio_open( psz_source, DRIVER_UNKNOWN )) )
  544.     {
  545.         msg_Warn( p_access, "could not open %s", psz_source );
  546.         free( psz_source );
  547.         return VLC_EGENERIC;
  548.     }
  549.     p_cdda = calloc( 1, sizeof(cdda_data_t) );
  550.     if( p_cdda == NULL )
  551.     {
  552.         free( psz_source );
  553.         return VLC_ENOMEM;
  554.     }
  555. #ifdef HAVE_LIBCDDB
  556.     cddb_log_set_handler ( cddb_log_handler );
  557.     p_cdda->cddb.disc = NULL;
  558.     p_cdda->b_cddb_enabled =
  559.         var_CreateGetInteger( p_access, "album-art" ) != ALBUM_ART_WHEN_ASKED &&
  560.         config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
  561. #endif
  562.     p_cdda->b_cdtext =
  563.         config_GetInt( p_access, MODULE_STRING "-cdtext-enabled" );
  564.     p_cdda->b_cdtext_prefer =
  565.         config_GetInt( p_access, MODULE_STRING "-cdtext-prefer" );
  566. #if LIBCDIO_VERSION_NUM >= 73
  567.     p_cdda->b_audio_ctl =
  568.         config_GetInt( p_access, MODULE_STRING "-analog-output" );
  569. #endif
  570.     p_cdda->psz_source = strdup( psz_source );
  571.     p_cdda->b_header   = false;
  572.     p_cdda->p_cdio     = p_cdio;
  573.     p_cdda->i_tracks   = 0;
  574.     p_cdda->i_titles   = 0;
  575.     p_cdda->i_debug    = config_GetInt( p_this, MODULE_STRING "-debug" );
  576.     p_cdda->b_nav_mode = config_GetInt(p_this, MODULE_STRING "-navigation-mode" );
  577.     p_cdda->i_blocks_per_read =
  578.             config_GetInt( p_this, MODULE_STRING "-blocks-per-read" );
  579.     p_cdda->last_disc_frame =
  580.             cdio_get_track_lsn( p_cdio, CDIO_CDROM_LEADOUT_TRACK );
  581.     p_cdda->p_input = vlc_object_find( p_access, VLC_OBJECT_INPUT,
  582.                                        FIND_PARENT );
  583.     if( 0 == p_cdda->i_blocks_per_read )
  584.         p_cdda->i_blocks_per_read = DEFAULT_BLOCKS_PER_READ;
  585.     if( (p_cdda->i_blocks_per_read < MIN_BLOCKS_PER_READ)
  586.          || (p_cdda->i_blocks_per_read > MAX_BLOCKS_PER_READ) )
  587.     {
  588.         msg_Warn( p_cdda_input,
  589.                   "number of blocks (%d) has to be between %d and %d. "
  590.                   "Using %d.",
  591.                   p_cdda->i_blocks_per_read,
  592.                   MIN_BLOCKS_PER_READ, MAX_BLOCKS_PER_READ,
  593.                   DEFAULT_BLOCKS_PER_READ );
  594.         p_cdda->i_blocks_per_read = DEFAULT_BLOCKS_PER_READ;
  595.     }
  596.     dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "%s", psz_source );
  597.     /* Set up p_access */
  598.     if( p_cdda->b_audio_ctl )
  599.     {
  600.         p_access->pf_read  = CDDARead;
  601.         p_access->pf_block = NULL;
  602.     }
  603.     else
  604.     {
  605.         p_access->pf_read  = NULL;
  606.         p_access->pf_block = CDDAReadBlocks;
  607.     }
  608.     p_access->pf_control = CDDAControl;
  609.     p_access->pf_seek    = CDDASeek;
  610.     {
  611.         lsn_t i_last_lsn;
  612.         if( p_cdda->b_nav_mode )
  613.             i_last_lsn = p_cdda->last_disc_frame;
  614.         else
  615.             i_last_lsn = cdio_get_track_last_lsn( p_cdio, i_track );
  616.         if( CDIO_INVALID_LSN != i_last_lsn )
  617.             p_access->info.i_size = i_last_lsn * (uint64_t) CDIO_CD_FRAMESIZE_RAW;
  618.         else
  619.             p_access->info.i_size = 0;
  620.     }
  621.     p_access->info.i_update    = 0;
  622.     p_access->info.b_eof       = false;
  623.     p_access->info.i_title     = 0;
  624.     p_access->info.i_seekpoint = 0;
  625.     p_access->p_sys     = (access_sys_t *) p_cdda;
  626.     /* We read the Table Of Content information */
  627.     i_rc = CDDAInit( p_access, p_cdda );
  628.     if( VLC_SUCCESS != i_rc )
  629.         goto error;
  630.     cdda_play_track( p_access, i_track );
  631.     CDDAFixupPlaylist( p_access, p_cdda, b_single_track );
  632. #if LIBCDIO_VERSION_NUM >= 72
  633.     {
  634.         char *psz_paranoia = config_GetPsz( p_access,
  635.                                 MODULE_STRING "-paranoia" );
  636.         p_cdda->e_paranoia = PARANOIA_MODE_DISABLE;
  637.         if( psz_paranoia && *psz_paranoia )
  638.         {
  639.             if( !strncmp( psz_paranoia, "full", strlen("full") ) )
  640.                 p_cdda->e_paranoia = PARANOIA_MODE_FULL;
  641.             else if( !strncmp(psz_paranoia, "overlap", strlen("overlap")) )
  642.                 p_cdda->e_paranoia = PARANOIA_MODE_OVERLAP;
  643.             /* Use CD Paranoia? */
  644.             if( p_cdda->e_paranoia )
  645.             {
  646.                 p_cdda->paranoia_cd =
  647.                             cdio_cddap_identify_cdio( p_cdio, 1, NULL );
  648.                 /* We'll set for verbose paranoia messages. */
  649.                 cdio_cddap_verbose_set( p_cdda->paranoia_cd,
  650.                                         CDDA_MESSAGE_PRINTIT,
  651.                                         CDDA_MESSAGE_PRINTIT );
  652.                 if ( 0 != cdio_cddap_open(p_cdda->paranoia_cd) )
  653.                 {
  654.                     msg_Warn( p_cdda_input, "unable to get paranoia support - "
  655.                                 "continuing without it." );
  656.                     p_cdda->e_paranoia = PARANOIA_MODE_DISABLE;
  657.                 }
  658.                 else
  659.                 {
  660.                     p_cdda->paranoia = cdio_paranoia_init(p_cdda->paranoia_cd);
  661.                     cdio_paranoia_seek( p_cdda->paranoia, p_cdda->i_lsn,
  662.                                         SEEK_SET);
  663.                     /* Set reading mode for full or overlap paranoia,
  664.                      * but allow skipping sectors. */
  665.                     cdio_paranoia_modeset( p_cdda->paranoia,
  666.                             PARANOIA_MODE_FULL == p_cdda->e_paranoia ?
  667.                             PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP :
  668.                             PARANOIA_MODE_OVERLAP^PARANOIA_MODE_NEVERSKIP );
  669.                 }
  670.             }
  671.         }
  672.         free( psz_paranoia );
  673.     }
  674. #endif
  675.     /* Build a WAV header to put in front of the output data.
  676.        This gets sent back in the Block (read) routine.
  677.      */
  678.     memset( &p_cdda->waveheader, 0, sizeof(WAVEHEADER) );
  679.     SetWLE( &p_cdda->waveheader.Format, 1 ); /*WAVE_FORMAT_PCM*/
  680.     SetWLE( &p_cdda->waveheader.BitsPerSample, 16);
  681.     p_cdda->waveheader.MainChunkID = VLC_FOURCC('R', 'I', 'F', 'F');
  682.     p_cdda->waveheader.Length = 0;                     /* we just don't know */
  683.     p_cdda->waveheader.ChunkTypeID = VLC_FOURCC('W', 'A', 'V', 'E');
  684.     p_cdda->waveheader.SubChunkID  = VLC_FOURCC('f', 'm', 't', ' ');
  685.     SetDWLE( &p_cdda->waveheader.SubChunkLength, 16);
  686.     SetWLE( &p_cdda->waveheader.Modus, 2);
  687.     SetDWLE( &p_cdda->waveheader.SampleFreq, CDDA_FREQUENCY_SAMPLE);
  688.     SetWLE( &p_cdda->waveheader.BytesPerSample,
  689.             2 /*Modus*/ * 16 /*BitsPerSample*/ / 8 );
  690.     SetDWLE( &p_cdda->waveheader.BytesPerSec,
  691.              2*16/8 /*BytesPerSample*/ * CDDA_FREQUENCY_SAMPLE );
  692.     p_cdda->waveheader.DataChunkID = VLC_FOURCC('d', 'a', 't', 'a');
  693.     p_cdda->waveheader.DataLength  = 0;    /* we just don't know */
  694.     /* PTS delay */
  695.     var_Create( p_access, MODULE_STRING "-caching",
  696.                 VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
  697.     vlc_object_release( p_cdda->p_input );
  698.     free( psz_source );
  699.     return VLC_SUCCESS;
  700.  error:
  701.     cdio_destroy( p_cdda->p_cdio );
  702.     free( psz_source );
  703.     if( p_cdda )
  704.     {
  705.         if ( p_cdda->p_input )
  706.             vlc_object_release( p_cdda->p_input );
  707.         free(p_cdda);
  708.     }
  709.     return i_rc;
  710. }
  711. /*****************************************************************************
  712.  * CDDAClose: closes cdda and frees any resources associded with it.
  713.  *****************************************************************************/
  714. void CDDAClose (vlc_object_t *p_this )
  715. {
  716.     access_t    *p_access = (access_t *) p_this;
  717.     cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;
  718.     track_t      i;
  719. #if LIBCDIO_VERSION_NUM >= 73
  720.     if( p_cdda->b_audio_ctl )
  721.         cdio_audio_stop(p_cdda->p_cdio);
  722. #endif
  723.     dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "" );
  724.     /* Remove playlist titles */
  725.     for( i = 0; i < p_cdda->i_titles; i++ )
  726.     {
  727.         vlc_input_title_Delete( p_cdda->p_title[i] );
  728.     }
  729. #ifdef HAVE_LIBCDDB
  730.     cddb_log_set_handler( (cddb_log_handler_t) uninit_log_handler );
  731.     if( p_cdda->b_cddb_enabled )
  732.         cddb_disc_destroy( p_cdda->cddb.disc );
  733. #endif
  734.     cdio_destroy( p_cdda->p_cdio );
  735.     cdio_log_set_handler( uninit_log_handler );
  736. #if LIBCDIO_VERSION_NUM >= 72
  737.     if( p_cdda->paranoia )
  738.         cdio_paranoia_free(p_cdda->paranoia);
  739.     if( p_cdda->paranoia_cd )
  740.         cdio_cddap_close_no_free_cdio( p_cdda->paranoia_cd );
  741. #endif
  742.     free( p_cdda->psz_mcn );
  743.     free( p_cdda->psz_source );
  744. #if LIBCDDB_VERSION_NUM >= 1
  745.     libcddb_shutdown();
  746. #endif
  747.     free( p_cdda );
  748.     p_cdda = NULL;
  749.     p_cdda_input = NULL;
  750. }
  751. /*****************************************************************************
  752.  * Control: The front-end or vlc engine calls here to ether get
  753.  * information such as meta information or plugin capabilities or to
  754.  * issue miscellaneous "set" requests.
  755.  *****************************************************************************/
  756. static int CDDAControl( access_t *p_access, int i_query, va_list args )
  757. {
  758.     cdda_data_t  *p_cdda = (cdda_data_t *) p_access->p_sys;
  759.     int          *pi_int;
  760.     int i;
  761.     dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_EVENT),
  762.                "query %d", i_query );
  763.     switch( i_query )
  764.     {
  765.         /* Pass back a copy of meta information that was gathered when we
  766.            during the Open/Initialize call.
  767.          */
  768.         case ACCESS_GET_META:
  769.         {
  770. #if 0
  771.             vlc_meta_t **pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
  772.             if( p_cdda->p_meta )
  773.             {
  774.                 *pp_meta = vlc_meta_Duplicate( p_cdda->p_meta );
  775.                 dbg_print( INPUT_DBG_META, "%s", "Meta copied" );
  776.                 return VLC_SUCCESS;
  777.             }
  778.             else
  779. #endif
  780.             {
  781.                 msg_Warn( p_access, "tried to copy NULL meta info" );
  782.                 return VLC_EGENERIC;
  783.             }
  784.         }
  785.         case ACCESS_CAN_CONTROL_PACE:
  786.         {
  787.             bool *pb_bool = (bool*)va_arg( args, bool* );
  788.             *pb_bool = p_cdda->b_audio_ctl ? false : true;
  789.             dbg_print( INPUT_DBG_META, "can control pace? %d", *pb_bool);
  790.             return VLC_SUCCESS;
  791.         }
  792.         case ACCESS_CAN_FASTSEEK:
  793.             dbg_print( INPUT_DBG_META, "can fast seek?");
  794.             goto common;
  795.         case ACCESS_CAN_SEEK:
  796.             dbg_print( INPUT_DBG_META, "can seek?");
  797.             goto common;
  798.         case ACCESS_CAN_PAUSE:
  799.             dbg_print( INPUT_DBG_META, "can pause?");
  800.  common:
  801.             {
  802.                 bool *pb_bool = (bool*)va_arg( args, bool* );
  803.                 *pb_bool = true;
  804.                 return VLC_SUCCESS;
  805.             }
  806.         case ACCESS_GET_PTS_DELAY:
  807.         {
  808.             int64_t *pi_64 = (int64_t*)va_arg( args, int64_t * );
  809.             *pi_64 = var_GetInteger( p_access, MODULE_STRING "-caching" )
  810.               * MILLISECONDS_PER_SEC;
  811.             break;
  812.         }
  813.         case ACCESS_GET_TITLE_INFO:
  814.         {
  815.             input_title_t ***ppp_title =
  816.              (input_title_t***)va_arg( args, input_title_t*** );
  817.             pi_int    = (int*)va_arg( args, int* );
  818.             *((int*)va_arg( args, int* )) = 1; /* Title offset */
  819.             dbg_print ( INPUT_DBG_EVENT,
  820.                         "GET TITLE: i_tracks %d, i_tracks %d",
  821.                         p_cdda->i_tracks, p_cdda->i_tracks );
  822.             CDDAMetaInfo( p_access, CDIO_INVALID_TRACK );
  823.             if( p_cdda->b_nav_mode)
  824.             {
  825.                 char *psz_title = CDDAFormatTitle( p_access, p_cdda->i_track );
  826.                 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_title );
  827.                 free(psz_title);
  828.             }
  829.             /* Duplicate title info */
  830.             if( p_cdda->i_titles == 0 )
  831.             {
  832.                 *pi_int = 0; ppp_title = NULL;
  833.                 return VLC_SUCCESS;
  834.             }
  835.             *pi_int = p_cdda->i_titles;
  836.             *ppp_title = calloc(1, sizeof( input_title_t **)
  837.                                            * p_cdda->i_titles );
  838.             if (!*ppp_title)
  839.                 return VLC_ENOMEM;
  840.             for( i = 0; i < p_cdda->i_titles; i++ )
  841.             {
  842.                 if ( p_cdda->p_title[i] )
  843.                 {
  844.                     (*ppp_title)[i] =
  845.                         vlc_input_title_Duplicate( p_cdda->p_title[i] );
  846.                 }
  847.             }
  848.             break;
  849.         }
  850.         case ACCESS_SET_TITLE:
  851.         {
  852.             i = (int)va_arg( args, int );
  853.             dbg_print( INPUT_DBG_EVENT, "set title %d", i );
  854.             if( i != p_access->info.i_title )
  855.             {
  856.                 const track_t i_track = p_cdda->i_first_track + i;
  857.                 /* Update info */
  858.                 p_access->info.i_title = i;
  859.                 if( p_cdda->b_nav_mode)
  860.                 {
  861.                     lsn_t i_last_lsn;
  862.                     char *psz_title = CDDAFormatTitle( p_access, i_track );
  863.                     input_Control( p_cdda->p_input, INPUT_SET_NAME,
  864.                                    psz_title );
  865.                     free( psz_title );
  866.                     p_cdda->i_track = i_track;
  867.                     i_last_lsn = cdio_get_track_lsn( p_cdda->p_cdio,
  868.                                                 CDIO_CDROM_LEADOUT_TRACK );
  869.                     if( CDIO_INVALID_LSN != i_last_lsn )
  870.                         p_access->info.i_size = (int64_t) CDIO_CD_FRAMESIZE_RAW
  871.                                                             * i_last_lsn ;
  872.                     p_access->info.i_pos = (int64_t)
  873.                                     cdio_get_track_lsn( p_cdda->p_cdio, i_track )
  874.                                                         * CDIO_CD_FRAMESIZE_RAW;
  875.                 }
  876.                 else
  877.                 {
  878.                     p_access->info.i_size = p_cdda->p_title[i]->i_size;
  879.                     p_access->info.i_pos  = 0;
  880.                 }
  881.                 p_access->info.i_update = INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
  882.                 /* Next sector to read */
  883.                 p_cdda->i_lsn = cdio_get_track_lsn( p_cdda->p_cdio, i_track );
  884.             }
  885.             break;
  886.         }
  887.         case ACCESS_SET_PAUSE_STATE:
  888.             dbg_print( INPUT_DBG_META, "Pause");
  889.             if( p_cdda->b_audio_ctl )
  890.                 cdda_audio_pause( p_cdda->p_cdio );
  891.             break;
  892.         case ACCESS_SET_SEEKPOINT:
  893.             dbg_print( INPUT_DBG_META, "set seekpoint");
  894.             return VLC_EGENERIC;
  895.         case ACCESS_SET_PRIVATE_ID_STATE:
  896.             dbg_print( INPUT_DBG_META, "set private id state");
  897.             return VLC_EGENERIC;
  898.         default:
  899.             msg_Warn( p_access, "unimplemented query in control" );
  900.             return VLC_EGENERIC;
  901.     }
  902.     return VLC_SUCCESS;
  903. }
  904. /*****************************************************************************
  905.   CDDAInit:
  906.  Initialize information pertaining to the CD: the number of tracks,
  907.  first track number, LSNs for each track and the leadout. The leadout
  908.  information is stored after the last track. The LSN array is
  909.  0-origin, same as p_access->info.  Add first_track to get what track
  910.  number this is on the CD. Note: libcdio uses the real track number.
  911.  On input we assume p_cdda->p_cdio and p_cdda->i_track have been set.
  912.  We return the VLC-type status, e.g. VLC_SUCCESS, VLC_ENOMEM, etc.
  913.  *****************************************************************************/
  914. static int CDDAInit( access_t *p_access, cdda_data_t *p_cdda )
  915. {
  916.     discmode_t  discmode = CDIO_DISC_MODE_NO_INFO;
  917.     p_cdda->i_tracks       = cdio_get_num_tracks( p_cdda->p_cdio );
  918.     p_cdda->i_first_track  = cdio_get_first_track_num( p_cdda->p_cdio );
  919.     discmode = cdio_get_discmode( p_cdda->p_cdio );
  920.     switch( discmode )
  921.     {
  922.         case CDIO_DISC_MODE_CD_DA:
  923.         case CDIO_DISC_MODE_CD_MIXED:
  924.             /* These are possible for CD-DA */
  925.             break;
  926.         default:
  927.             /* These are not possible for CD-DA */
  928.             msg_Err( p_access,
  929.                 "Disc seems not to be CD-DA. libcdio reports it is %s",
  930.                 discmode2str[discmode]
  931.                 );
  932.             return VLC_EGENERIC;
  933.     }
  934.     /* Set reading start LSN. */
  935.     p_cdda->i_lsn = cdio_get_track_lsn(p_cdda->p_cdio, p_cdda->i_track);
  936.     return VLC_SUCCESS;
  937. }
  938. /*
  939.  * Local variables:
  940.  *  mode: C
  941.  *  style: gnu
  942.  * End:
  943.  */