Split out callback routines.
Some cleanup. Still largely broken though.
SOURCES_cddax = \
access.c \
+ access.h \
+ callback.c \
+ callback.h \
cdda.c \
cdda.h \
$(NULL)
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <vlc/vlc.h>
-#include <vlc/input.h>
-#include <vlc_playlist.h>
+#include "callback.h" /* FIXME - reorganize callback.h, cdda.h better */
+#include "cdda.h" /* private structures. Also #includes vlc things */
+#include <vlc_playlist.h> /* Has to come *after* cdda.h */
+#include "vlc_keys.h"
-#include <sys/types.h>
#include <cdio/cdio.h>
#include <cdio/logging.h>
#include <cdio/cd_types.h>
-#include "codecs.h"
-#include "vlc_keys.h"
+#include <stdio.h>
+
+/* #ifdef variables below are defined via config.h via #include vlc above. */
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
# include <errno.h>
#endif
-#include <string.h>
-
-#include "cdda.h"
-
#define CDDA_MRL_PREFIX "cddax://"
-/* how many blocks Open will read in each loop. Note libcdio and
- SCSI MMC devices can read at most 25 blocks.
-*/
-#define CDDA_BLOCKS_ONCE 20
-#define CDDA_DATA_ONCE (CDDA_BLOCKS_ONCE * CDIO_CD_FRAMESIZE_RAW)
-
/* Frequency of sample in bits per second. */
#define CDDA_FREQUENCY_SAMPLE 44100
/* FIXME: This variable is a hack. Would be nice to eliminate. */
-static access_t *p_cdda_input = NULL;
+access_t *p_cdda_input = NULL;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static block_t *CDDABlock( access_t * p_access );
+static block_t *CDDAReadBlocks( access_t * p_access );
static int CDDASeek( access_t * p_access, int64_t i_pos );
static int CDDAControl( access_t *p_access, int i_query,
va_list args );
}
/*****************************************************************************
- * CDDARead: reads CDDA_BLOCKS_ONCE from the CD-DA and returns an
- * allocated pointer to the data. NULL is returned if no data read. It
- * is also possible if we haven't read a RIFF header in which case one
- * that we creaded during Open/Initialization is returned.
+ * CDDAReadBlocks: reads a group of blocks from the CD-DA and returns
+ * an allocated pointer to the data. NULL is returned if no data
+ * read. It is also possible if we haven't read a RIFF header in which
+ * case one that we creaded during Open/Initialization is returned.
*****************************************************************************/
static block_t *
-CDDABlock( access_t * p_access )
+CDDAReadBlocks( access_t * p_access )
{
block_t *p_block;
cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
- int i_blocks = CDDA_BLOCKS_ONCE;
+ int i_blocks = p_cdda->i_blocks_per_read;
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_LSN), "called %d",
p_cdda->i_lsn);
p_cdda->i_track++;
}
- /* Don't read after the end of a title */
+ /* Possibly adjust i_blocks so we don't read past the end of a track. */
if( p_cdda->i_lsn + i_blocks >=
p_cdda->p_lsns[p_access->info.i_title + 1] )
{
p_block = block_New( p_access, i_blocks * CDIO_CD_FRAMESIZE_RAW );
if( !p_block)
{
- msg_Err( p_access, "cannot get a new block of size: %i",
- i_blocks * CDIO_CD_FRAMESIZE_RAW );
- return NULL;
+ msg_Err( p_access, _("Cannot get a new block of size: %i"),
+ i_blocks * CDIO_CD_FRAMESIZE_RAW );
+ return NULL;
}
if( cdio_read_audio_sectors( p_cdda->p_cdio, p_block->p_buffer,
p_cdda->i_lsn, i_blocks) != 0 )
{
- msg_Err( p_access, "could not read sector %lu",
- (long unsigned int) p_cdda->i_lsn );
- block_Release( p_block );
-
- /* If we had problems above, assume the problem is with
- the first sector of the read and set to skip it. In
- the future libcdio may have cdparanoia support.
- */
- p_cdda->i_lsn++;
- p_access->info.i_pos += CDIO_CD_FRAMESIZE_RAW;
- return NULL;
+ msg_Err( p_access, _("could not read sector %lu"),
+ (long unsigned int) p_cdda->i_lsn );
+ block_Release( p_block );
+
+ /* If we had problems above, assume the problem is with
+ the first sector of the read and set to skip it. In
+ the future libcdio may have cdparanoia support.
+ */
+ p_cdda->i_lsn++;
+ p_access->info.i_pos += CDIO_CD_FRAMESIZE_RAW;
+ return NULL;
}
-
+
p_cdda->i_lsn += i_blocks;
p_access->info.i_pos += p_block->i_buffer;
cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
p_cdda->i_lsn = p_cdda->p_lsns[p_access->info.i_title]
- + i_pos / CDIO_CD_FRAMESIZE_RAW;
+ + (i_pos / CDIO_CD_FRAMESIZE_RAW);
p_access->info.i_pos = i_pos;
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK),
/****************************************************************************
* Public functions
****************************************************************************/
-int
-E_(CDDADebugCB) ( vlc_object_t *p_this, const char *psz_name,
- vlc_value_t oldval, vlc_value_t val, void *p_data )
-{
- cdda_data_t *p_cdda;
-
- if (NULL == p_cdda_input) return VLC_EGENERIC;
-
- p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
-
- if (p_cdda->i_debug & (INPUT_DBG_CALL|INPUT_DBG_EXT)) {
- msg_Dbg( p_cdda_input, "Old debug (x%0x) %d, new debug (x%0x) %d",
- p_cdda->i_debug, p_cdda->i_debug, val.i_int, val.i_int);
- }
- p_cdda->i_debug = val.i_int;
- return VLC_SUCCESS;
-}
-
-int
-E_(CDDBEnabledCB) ( vlc_object_t *p_this, const char *psz_name,
- vlc_value_t oldval, vlc_value_t val, void *p_data )
-{
- cdda_data_t *p_cdda;
-
- if (NULL == p_cdda_input) return VLC_EGENERIC;
-
- p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
-
-#ifdef HAVE_LIBCDDB
- if (p_cdda->i_debug & (INPUT_DBG_CALL|INPUT_DBG_EXT)) {
- msg_Dbg( p_cdda_input, "Old CDDB Enabled (x%0x) %d, new (x%0x) %d",
- p_cdda->i_cddb_enabled, p_cdda->i_cddb_enabled,
- val.i_int, val.i_int);
- }
- p_cdda->i_cddb_enabled = val.i_int;
-#endif
- return VLC_SUCCESS;
-}
/*****************************************************************************
* Open: open cdda device or image file and initialize structures
i_track = i_track ? i_track : 1;
b_single_track = true;
}
- } else {
+ }
+ if (!psz_source || !*psz_source)
+ {
/* No device/track given. Continue only when this plugin was
selected */
if( !p_this->b_force ) return VLC_EGENERIC;
p_cdda->b_header = VLC_FALSE;
p_cdda->p_cdio = p_cdio;
p_cdda->i_track = i_track;
- p_cdda->i_debug = config_GetInt( p_this, MODULE_STRING "-debug" );
+ p_cdda->i_debug = config_GetInt(p_this, MODULE_STRING "-debug");
+ p_cdda->i_blocks_per_read
+ = config_GetInt(p_this, MODULE_STRING "-blocks-per-read");
+
+ if (0 == p_cdda->i_blocks_per_read)
+ p_cdda->i_blocks_per_read = DEFAULT_BLOCKS_PER_READ;
+
+ if ( p_cdda->i_blocks_per_read < MIN_BLOCKS_PER_READ
+ || p_cdda->i_blocks_per_read > MAX_BLOCKS_PER_READ ) {
+ msg_Warn( p_cdda_input,
+ "Number of blocks (%d) has to be between %d and %d. "
+ "Using %d.",
+ p_cdda->i_blocks_per_read,
+ MIN_BLOCKS_PER_READ, MAX_BLOCKS_PER_READ,
+ DEFAULT_BLOCKS_PER_READ );
+ p_cdda->i_blocks_per_read = DEFAULT_BLOCKS_PER_READ;
+ }
+
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "%s", psz_source );
/* Set up p_access */
p_access->pf_read = NULL;
- p_access->pf_block = CDDABlock;
+ p_access->pf_block = CDDAReadBlocks;
p_access->pf_control = CDDAControl;
p_access->pf_seek = CDDASeek;
/* */
case ACCESS_GET_MTU:
pi_int = (int*)va_arg( args, int * );
- *pi_int = CDDA_DATA_ONCE;
+ *pi_int = p_cdda-> i_blocks_per_read * CDIO_CD_FRAMESIZE_RAW;
break;
case ACCESS_GET_PTS_DELAY:
0-origin, same as p_access->info. Add first_track to get what track
number this is on the CD. Note: libcdio uses the real track number.
+ On input we assume p_cdda->p_cdio and p_cdda->i_track have been set.
+
We return the VLC-type status, e.g. VLC_SUCCESS, VLC_ENOMEM, etc.
*****************************************************************************/
static int
return VLC_ENOMEM;
}
-
/* Fill the p_lsns structure with the track/sector matches.
Note cdio_get_track_lsn when given num_tracks + 1 will return
(p_cdda->p_lsns)[ i ] =
cdio_get_track_lsn(p_cdda->p_cdio, p_cdda->i_first_track+i);
}
-
+
+ /* Set reading start LSN. */
+ p_cdda->i_lsn = p_cdda->p_lsns[p_cdda->i_track - p_cdda->i_first_track];
+
return VLC_SUCCESS;
}
--- /dev/null
+/*****************************************************************************
+ * access.h : access headers for CD digital audio input module
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id: access.h 8606 2004-08-31 18:32:54Z rocky $
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Open: open cdda device or image file and initialize structures
+ * for subsequent operations.
+ *****************************************************************************/
+int E_(CDDAOpen) ( vlc_object_t * );
+
+/*****************************************************************************
+ * CDDAClose: closes cdda and frees any resources associded with it.
+ *****************************************************************************/
+void E_(CDDAClose) ( vlc_object_t * );
--- /dev/null
+/*****************************************************************************
+ * callback.c : Callbacks for CD digital audio input module
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id: callback.c 8606 2004-08-31 18:32:54Z rocky $
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#include "callback.h"
+#include "cdda.h"
+
+int
+E_(CDDADebugCB) ( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t oldval, vlc_value_t val, void *p_data )
+{
+ cdda_data_t *p_cdda;
+
+ if (NULL == p_cdda_input) return VLC_EGENERIC;
+
+ p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
+
+ if (p_cdda->i_debug & (INPUT_DBG_CALL|INPUT_DBG_EXT)) {
+ msg_Dbg( p_cdda_input, "Old debug (x%0x) %d, new debug (x%0x) %d",
+ p_cdda->i_debug, p_cdda->i_debug, val.i_int, val.i_int);
+ }
+ p_cdda->i_debug = val.i_int;
+ return VLC_SUCCESS;
+}
+
+int
+E_(CDDBEnabledCB) ( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t oldval, vlc_value_t val, void *p_data )
+{
+ cdda_data_t *p_cdda;
+
+ if (NULL == p_cdda_input) return VLC_EGENERIC;
+
+ p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
+
+#ifdef HAVE_LIBCDDB
+ if (p_cdda->i_debug & (INPUT_DBG_CALL|INPUT_DBG_EXT)) {
+ msg_Dbg( p_cdda_input, "Old CDDB Enabled (x%0x) %d, new (x%0x) %d",
+ p_cdda->i_cddb_enabled, p_cdda->i_cddb_enabled,
+ val.i_int, val.i_int);
+ }
+ p_cdda->i_cddb_enabled = val.i_int;
+#endif
+ return VLC_SUCCESS;
+}
+
+int
+E_(CDDABlocksPerReadCB) ( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t oldval, vlc_value_t val, void *p_data )
+{
+ cdda_data_t *p_cdda;
+
+ if (NULL == p_cdda_input) return VLC_EGENERIC;
+
+ p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
+
+ if (p_cdda->i_debug & (INPUT_DBG_CALL|INPUT_DBG_EXT)) {
+ msg_Dbg( p_cdda_input, "Old blocks per read: %d, new %d",
+ p_cdda->i_blocks_per_read, val.i_int);
+ }
+
+ if (0 == val.i_int) val.i_int = DEFAULT_BLOCKS_PER_READ;
+ if ( val.i_int >= MIN_BLOCKS_PER_READ && val.i_int <= MAX_BLOCKS_PER_READ )
+ p_cdda->i_blocks_per_read = val.i_int;
+ else {
+ msg_Warn( p_cdda_input,
+ "Number of blocks (%d) has to be between %d and %d. No change.",
+ val.i_int, MIN_BLOCKS_PER_READ, MAX_BLOCKS_PER_READ );
+ }
+
+ return VLC_SUCCESS;
+}
--- /dev/null
+/*****************************************************************************
+ * callback.h : Callbacks for CD digital audio input module
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id: callback.h 8606 2004-08-31 18:32:54Z rocky $
+ *
+ * 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
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#include <vlc/vlc.h>
+
+/*
+ Minimum, maximum and default number of blocks we allow on read.
+*/
+#define MIN_BLOCKS_PER_READ 1
+#define MAX_BLOCKS_PER_READ 25
+#define DEFAULT_BLOCKS_PER_READ 20
+
+int E_(CDDADebugCB) ( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t oldval, vlc_value_t val,
+ void *p_data );
+
+int E_(CDDBEnabledCB)( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t oldval, vlc_value_t val,
+ void *p_data );
+
+
+int E_(CDDABlocksPerReadCB) ( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t oldval, vlc_value_t val,
+ void *p_data );
+
/*****************************************************************************
* cddax.c : CD digital audio input module for vlc using libcdio
*****************************************************************************
- * Copyright (C) 2000,2003 VideoLAN
+ * Copyright (C) 2000, 2003, 2004 VideoLAN
* $Id$
*
* Authors: Rocky Bernstein <rocky@panix.com>
* Preamble
*****************************************************************************/
-#include <vlc/vlc.h>
-
-/*****************************************************************************
- * prototypes
- *****************************************************************************/
-int E_(CDDAOpen) ( vlc_object_t * );
-void E_(CDDAClose) ( vlc_object_t * );
-
-int E_(CDDADebugCB) ( vlc_object_t *p_this, const char *psz_name,
- vlc_value_t oldval, vlc_value_t val,
- void *p_data );
-
-int E_(CDDBEnabledCB)( vlc_object_t *p_this, const char *psz_name,
- vlc_value_t oldval, vlc_value_t val,
- void *p_data );
+#include "callback.h"
+#include "access.h"
/*****************************************************************************
* Module descriptor
"Allows you to modify the default caching value for CDDA streams. This " \
"value should be set in millisecond units." )
+#define BLOCKS_PER_READ_LONGTEXT N_( \
+ "Allows you to specify how many CD blocks to get on a single CD read. " \
+ "Generally on newer/faster CD's, this increases throughput at the " \
+ "expense of a little more memory usage and initial delay. SCSI-MMC " \
+ "limitations generally don't allow for more than 25 blocks per access.")
+
#define CDDB_TITLE_FMT_LONGTEXT N_( \
"Format used in the GUI Playlist Title. Similar to the Unix date \n" \
"Format specifiers that start with a percent sign. Specifiers are: \n" \
vlc_module_begin();
add_usage_hint( N_("cddax://[device-or-file][@[T]track]") );
set_description( _("Compact Disc Digital Audio (CD-DA) input") );
- set_capability( "access2", 10 /* slightly higher than cdda */ );
+ set_capability( "access2", 10 /* compare with priority of cdda */ );
set_callbacks( E_(CDDAOpen), E_(CDDAClose) );
add_shortcut( "cddax" );
add_shortcut( "cd" );
DEBUG_LONGTEXT, VLC_TRUE );
add_integer( MODULE_STRING "-caching",
- DEFAULT_PTS_DELAY / 1000, NULL,
+ DEFAULT_PTS_DELAY / MILLISECONDS_PER_SEC, NULL,
N_("Caching value in microseconds"),
CACHING_LONGTEXT, VLC_TRUE );
+ add_integer( MODULE_STRING "-blocks-per-read",
+ DEFAULT_BLOCKS_PER_READ, E_(CDDABlocksPerReadCB),
+ N_("Number of blocks per CD read"),
+ BLOCKS_PER_READ_LONGTEXT, VLC_TRUE );
+
add_string( MODULE_STRING "-author-format",
"%A - %a %C %I", NULL,
N_("Format to use in playlist \"author\" field"),
add_string( MODULE_STRING "-cddb-server", "freedb.freedb.org", NULL,
N_("CDDB server"),
N_( "Contact this CDDB server look up CD-DA information"),
- VLC_TRUE );
+ VLC_TRUE );
add_integer( MODULE_STRING "-cddb-port", 8880, NULL,
N_("CDDB server port"),
add_string( MODULE_STRING "-cddb-email", "me@home", NULL,
N_("email address reported to CDDB server"),
N_("email address reported to CDDB server"),
- VLC_TRUE );
+ VLC_TRUE );
add_bool( MODULE_STRING "-cddb-enable-cache", 1, NULL,
N_("Cache CDDB lookups?"),
add_string( MODULE_STRING "-cddb-cachedir", "~/.cddbslave", NULL,
N_("Directory to cache CDDB requests"),
N_("Directory to cache CDDB requests"),
- VLC_TRUE );
+ VLC_TRUE );
#endif
/*****************************************************************************
- * cdda.h : CD-DA input module header for vlc
- * using libcdio, libvcd and libvcdinfo
+ * cdda.h : CD-DA input module header for vlc using libcdio.
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id$
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
+#include <vlc/input.h>
#include <cdio/cdio.h>
+#include <cdio/cdtext.h>
#include "vlc_meta.h"
+#include "codecs.h"
#ifdef HAVE_LIBCDDB
#include <cddb/cddb.h>
*****************************************************************************/
typedef struct cdda_data_s
{
- CdIo *p_cdio; /* libcdio CD device */
- int i_tracks; /* # of tracks (titles) */
- int i_first_track; /* # of first track */
-
- /* Current position */
- int i_track; /* Current track */
- lsn_t i_lsn; /* Current Logical Sector Number */
- lsn_t * p_lsns; /* Track LSNs */
-
- int i_debug; /* Debugging mask */
- char * psz_mcn; /* Media Catalog Number */
- vlc_meta_t *p_meta;
-
- input_title_t *p_title[CDIO_CD_MAX_TRACKS];
-
+ CdIo *p_cdio; /* libcdio CD device */
+ track_t i_tracks; /* # of tracks (titles) */
+ track_t i_first_track; /* # of first track */
+
+ /* Current position */
+ track_t i_track; /* Current track */
+ lsn_t i_lsn; /* Current Logical Sector Number */
+ lsn_t * p_lsns; /* Track LSNs */
+
+ int i_blocks_per_read; /* # blocks to get in a read */
+ int i_debug; /* Debugging mask */
+ /* Information about CD */
+ vlc_meta_t *p_meta;
+ char * psz_mcn; /* Media Catalog Number */
+ cdtext_t *cdtext; /* CD-Text info */
+ input_title_t *p_title[CDIO_CD_MAX_TRACKS];
+
+
#ifdef HAVE_LIBCDDB
- int i_cddb_enabled;
+ int i_cddb_enabled;
struct {
- bool have_info; /* True if we have any info */
- cddb_disc_t *disc; /* libcdio uses this to get disc info */
- int disc_length; /* Length in frames of cd. Used in
- CDDB lookups */
+ vlc_bool_t have_info; /* True if we have any info */
+ cddb_disc_t *disc; /* libcdio uses this to get disc
+ info */
+ int disc_length; /* Length in frames of cd. Used
+ in CDDB lookups */
} cddb;
#endif
- WAVEHEADER waveheader; /* Wave header for the output data */
- vlc_bool_t b_header;
+ WAVEHEADER waveheader; /* Wave header for the output data */
+ vlc_bool_t b_header;
} cdda_data_t;
-/*****************************************************************************
- * CDDAPlay: Arrange things so we play the specified track.
- * VLC_TRUE is returned if there was no error.
- *****************************************************************************/
-vlc_bool_t CDDAPlay ( input_thread_t *, int );
+/* FIXME: This variable is a hack. Would be nice to eliminate. */
+extern access_t *p_cdda_input;