Commit 4fcaafa3 authored by Rocky Bernstein's avatar Rocky Bernstein

First attempt to reinstate a libcdio cdda.

vlc_meta.h: added CD-Text, ISO 9660, and CDDB fields. Separate email
will be sent about this.

Note: sound may be off by 2 seconds (150 sectors or pregap
amount). The sound for both this and the other cdda plugin don't work
for me. Before the last SVN update though that's what it sounded like.
parent 7adeecde
......@@ -1486,46 +1486,46 @@ then
VLC_ADD_PLUGINS([pvr])
fi
dnl dnl
dnl dnl VCDX and CDDAX modules
dnl dnl
dnl AC_ARG_ENABLE(libcdio,
dnl [ --enable-libcdio CDDA support via libcdio (default enabled)])
dnl
dnl AC_ARG_ENABLE(libcddb,
dnl [ --enable-libcddb CDDB support for CDDAX (default enabled)])
dnl
dnl
dnl VCDX and CDDAX modules
dnl
AC_ARG_ENABLE(libcdio,
[ --enable-libcdio CDDA support via libcdio (default enabled)])
AC_ARG_ENABLE(libcddb,
[ --enable-libcddb CDDB support for CDDAX (default enabled)])
dnl AC_ARG_ENABLE(vcdx,
dnl [ --enable-vcdx VCD support with Navigation (default enabled)])
dnl
dnl AC_ARG_ENABLE(cdda,
dnl [ --enable-cdda CDDA plugin support (default enabled)])
dnl
dnl AC_ARG_ENABLE(cddax,
dnl [ --enable-cddax CDDAX plugin support (default enabled)])
dnl
dnl if test "${enable_cddax}" != "no"
dnl then
dnl PKG_CHECK_MODULES(LIBCDIO, libcdio >= 0.65,
dnl [enable_cddax="no"
dnl AC_DEFINE(HAVE_CDDAX, [], [Define for the CD-DA plugin using libcdio])
dnl VLC_ADD_LDFLAGS([cddax],[$LIBCDIO_LIBS])
dnl VLC_ADD_CFLAGS([cddax],[$LIBCDIO_CFLAGS])
dnl VLC_ADD_PLUGINS([cddax])],
dnl [AC_MSG_WARN(libcdio library not found)
dnl HAVE_CDDAX=no])
dnl
dnl if test "$enable_libcddb" != "no"; then
dnl PKG_CHECK_MODULES(LIBCDDB, libcddb >= 0.9.4, [
dnl HAVE_LIBCDDB=yes
dnl AC_DEFINE(HAVE_LIBCDDB, [], [Define this if you have libcddb installed])
dnl VLC_ADD_LDFLAGS([cddax],[$LIBCDDB_LIBS])
dnl VLC_ADD_CFLAGS([cddax],[$LIBCDDB_CFLAGS])
dnl ],
dnl [AC_MSG_WARN(new enough libcddb not found. CDDB access disabled)
dnl HAVE_LIBCDDB=no])
dnl fi
dnl
AC_ARG_ENABLE(cdda,
[ --enable-cdda CDDA plugin support (default enabled)])
AC_ARG_ENABLE(cddax,
[ --enable-cddax CDDAX plugin support (default enabled)])
if test "${enable_cddax}" != "no"
then
PKG_CHECK_MODULES(LIBCDIO, libcdio >= 0.70,
[enable_cddax="no"
AC_DEFINE(HAVE_CDDAX, [], [Define for the CD-DA plugin using libcdio])
VLC_ADD_LDFLAGS([cddax],[$LIBCDIO_LIBS])
VLC_ADD_CFLAGS([cddax],[$LIBCDIO_CFLAGS])
VLC_ADD_PLUGINS([cddax])],
[AC_MSG_WARN(libcdio library not found)
HAVE_CDDAX=no])
if test "$enable_libcddb" != "no"; then
PKG_CHECK_MODULES(LIBCDDB, libcddb >= 0.9.4, [
HAVE_LIBCDDB=yes
AC_DEFINE(HAVE_LIBCDDB, [], [Define this if you have libcddb installed])
VLC_ADD_LDFLAGS([cddax],[$LIBCDDB_LIBS])
VLC_ADD_CFLAGS([cddax],[$LIBCDDB_CFLAGS])
],
[AC_MSG_WARN(new enough libcddb not found. CDDB access disabled)
HAVE_LIBCDDB=no])
fi
dnl if test "${enable_vcdx}" != "no"
dnl then
dnl PKG_CHECK_MODULES(VCDINFO, libvcdinfo >= 0.7.20,
......@@ -1538,7 +1538,7 @@ dnl VLC_ADD_PLUGINS([vcdx])],
dnl [AC_MSG_WARN(vcdinfo library not found)
dnl HAVE_VCDX=no])
dnl fi
dnl fi
fi
dnl
dnl VCD module
......
......@@ -36,6 +36,30 @@
#define VLC_META_SETTING N_("Setting")
#define VLC_META_URL N_("URL")
#define VLC_META_LANGUAGE N_("Language")
#define VLC_META_CDDB_ARTIST N_("CDDB Artist")
#define VLC_META_CDDB_CATEGORY N_("CDDB Category")
#define VLC_META_CDDB_DISCID N_("CDDB Disc ID")
#define VLC_META_CDDB_EXT_DATA N_("CDDB Extended Data")
#define VLC_META_CDDB_GENRE N_("CDDB Genre")
#define VLC_META_CDDB_YEAR N_("CDDB Year")
#define VLC_META_CDDB_TITLE N_("CDDB Title")
#define VLC_META_CDTEXT_ARRANGER N_("CD-Text Arranger")
#define VLC_META_CDTEXT_COMPOSER N_("CD-Text Composer")
#define VLC_META_CDTEXT_DISCID N_("CD-Text Disc ID")
#define VLC_META_CDTEXT_GENRE N_("CD-Text Genre")
#define VLC_META_CDTEXT_MESSAGE N_("CD-Text Message")
#define VLC_META_CDTEXT_SONGWRITER N_("CD-Text Songwriter")
#define VLC_META_CDTEXT_PERFORMER N_("CD-Text Performer")
#define VLC_META_CDTEXT_TITLE N_("CD-Text Title")
#define VLC_META_ISO_APPLICATION_ID N_("ISO-9660 Application ID")
#define VLC_META_ISO_PREPARER N_("ISO-9660 Preparer")
#define VLC_META_ISO_PUBLISHER N_("ISO-9660 Publisher")
#define VLC_META_ISO_VOLUME N_("ISO-9660 Volume")
#define VLC_META_ISO_VOLUMESET N_("ISO-9660 Volume Set")
#define VLC_META_CODEC_NAME N_("Codec Name")
#define VLC_META_CODEC_DESCRIPTION N_("Codec Description")
......
......@@ -30,7 +30,7 @@
#include <stdlib.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/input.h>
#include <sys/types.h>
#include <cdio/cdio.h>
......@@ -58,26 +58,16 @@
#define CDDA_MRL_PREFIX "cddax://"
/* FIXME: This variable is a hack. Would be nice to eliminate. */
static input_thread_t *p_cdda_input = NULL;
static access_t *p_cdda_input = NULL;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int CDDARead ( input_thread_t *, byte_t *, size_t );
static void CDDASeek ( input_thread_t *, off_t );
static int CDDASetArea ( input_thread_t *, input_area_t * );
static int CDDASetProgram ( input_thread_t *, pgrm_descriptor_t * );
static int CDDAFixupPlayList( input_thread_t *p_input,
cdda_data_t *p_cdda, const char *psz_source,
bool play_single_track);
#if NEED_UPDATE_VAR
static void CDDAUpdateVar( input_thread_t *p_input, int i_entry, int i_action,
const char *p_varname, char *p_label,
const char *p_debug_label );
#endif
static block_t *CDDABlock( 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 );
static void CDDAMetaInfo( access_t *p_access );
/****************************************************************************
* Private functions
......@@ -87,7 +77,7 @@ static void CDDAUpdateVar( input_thread_t *p_input, int i_entry, int i_action,
static void
cdio_log_handler (cdio_log_level_t level, const char message[])
{
cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_access_data;
cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
switch (level) {
case CDIO_LOG_DEBUG:
case CDIO_LOG_INFO:
......@@ -103,7 +93,7 @@ cdio_log_handler (cdio_log_level_t level, const char message[])
break;
default:
msg_Warn( p_cdda_input, message,
_("The above message had unknown vcdimager log level"),
_("The above message had unknown cdio log level"),
level);
}
return;
......@@ -117,7 +107,7 @@ cdio_log_handler (cdio_log_level_t level, const char message[])
static void
cddb_log_handler (cddb_log_level_t level, const char message[])
{
cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_access_data;
cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
switch (level) {
case CDDB_LOG_DEBUG:
case CDDB_LOG_INFO:
......@@ -136,7 +126,7 @@ cddb_log_handler (cddb_log_level_t level, const char message[])
static void
uninit_log_handler (cdio_log_level_t level, const char message[])
{
cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_access_data;
cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_sys;
switch (level) {
case CDIO_LOG_DEBUG:
case CDIO_LOG_INFO:
......@@ -163,283 +153,107 @@ uninit_log_handler (cdio_log_level_t level, const char message[])
}
/*****************************************************************************
* CDDAPlay: Arrange things so we play the specified track.
* VLC_TRUE is returned if there was no error.
* 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.
*****************************************************************************/
vlc_bool_t
CDDAPlay( input_thread_t *p_input, int i_track )
static block_t *
CDDABlock( access_t * p_access )
{
cdda_data_t *p_cdda = (cdda_data_t *) p_input->p_access_data;
block_t *p_block;
cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
int i_blocks = CDDA_BLOCKS_ONCE;
if( i_track > p_cdda->i_nb_tracks || i_track < 1 )
return VLC_FALSE;
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_LSN), "called %d",
p_cdda->i_sector);
CDDASetArea( p_input, p_input->stream.pp_areas[i_track] );
return VLC_TRUE;
}
/* Check end of file */
if( p_access->info.b_eof ) return NULL;
/*****************************************************************************
* CDDARead: reads from the CDDA into PES packets.
*****************************************************************************
* Returns -1 in case of error, 0 in case of EOF, otherwise the number of
* bytes.
*****************************************************************************/
static int CDDARead( input_thread_t * p_input, byte_t * p_buffer,
size_t i_len )
{
cdda_data_t * p_cdda;
int i_blocks;
int i_index;
int i_read;
p_cdda = (cdda_data_t *)p_input->p_access_data;
/* Compute the number of blocks we have to read */
i_blocks = i_len / CDIO_CD_FRAMESIZE_RAW;
i_read = 0;
if( !p_cdda->i_header_pos )
{
p_cdda->i_header_pos = sizeof(WAVEHEADER);
i_blocks = (i_len - sizeof(WAVEHEADER)) / CDIO_CD_FRAMESIZE_RAW;
memcpy( p_buffer, &p_cdda->waveheader, sizeof(WAVEHEADER) );
p_buffer += sizeof(WAVEHEADER);
i_read += sizeof(WAVEHEADER);
if( !p_cdda->b_header )
{
/* Return only the dummy RIFF header we created in Open/Init */
p_block = block_New( p_access, sizeof( WAVEHEADER ) );
memcpy( p_block->p_buffer, &p_cdda->waveheader, sizeof(WAVEHEADER) );
p_cdda->b_header = VLC_TRUE;
return p_block;
}
for( i_index = 0; i_index < i_blocks; i_index++ )
/* Check end of track */
while( p_cdda->i_sector >= p_cdda->p_sectors[p_access->info.i_title + 1] )
{
if( cdio_read_audio_sector( p_cdda->p_cddev->cdio, p_buffer,
p_cdda->i_sector) != 0 )
if( p_access->info.i_title + 1 >= p_cdda->i_tracks )
{
msg_Err( p_input, "could not read sector %lu",
(long unsigned int) p_cdda->i_sector );
return -1;
p_access->info.b_eof = VLC_TRUE;
return NULL;
}
p_cdda->i_sector ++;
if( p_cdda->i_sector == p_cdda->p_sectors[p_cdda->i_track + 1] )
{
input_area_t *p_area;
dbg_print( (INPUT_DBG_LSN|INPUT_DBG_CALL),
"end of track, cur: %lu",
(long unsigned int) p_cdda->i_sector );
/*???? if ( p_cdda->i_track >= p_cdda->i_nb_tracks - 1 )*/
return 0; /* EOF */
vlc_mutex_lock( &p_input->stream.stream_lock );
p_area = p_input->stream.pp_areas[
p_input->stream.p_selected_area->i_id + 1 ];
p_area->i_part = 1;
CDDASetArea( p_input, p_area );
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
i_read += CDIO_CD_FRAMESIZE_RAW;
p_buffer += CDIO_CD_FRAMESIZE_RAW;
p_access->info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SIZE;
p_access->info.i_title++;
p_access->info.i_size =
p_cdda->p_title[p_access->info.i_title]->i_size;
p_access->info.i_pos = 0;
}
if ( i_len % CDIO_CD_FRAMESIZE_RAW ) /* this should not happen */
/* Don't read after the end of a title */
if( p_cdda->i_sector + i_blocks >=
p_cdda->p_sectors[p_access->info.i_title + 1] )
{
msg_Err( p_input, "must read full sectors" );
i_blocks = p_cdda->p_sectors[p_access->info.i_title + 1 ] -
p_cdda->i_sector;
}
return i_read;
}
/*****************************************************************************
* CDDASetProgram: Does nothing since a CDDA is mono_program
*****************************************************************************/
static int CDDASetProgram( input_thread_t * p_input,
pgrm_descriptor_t * p_program)
{
cdda_data_t * p_cdda= (cdda_data_t *) p_input->p_access_data;
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "" );
return 0;
}
/*****************************************************************************
* CDDASetArea: initialize input data for title x.
* It should be called for each user navigation request.
****************************************************************************/
static int CDDASetArea( input_thread_t * p_input, input_area_t * p_area )
{
cdda_data_t *p_cdda = (cdda_data_t*) p_input->p_access_data;
vlc_value_t val;
vlc_value_t text;
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "");
text.psz_string = _("Track");
var_Change( p_input, "title", VLC_VAR_SETTEXT, &text, NULL );
/* we can't use the interface slider until initilization is complete */
p_input->stream.b_seekable = 0;
if( p_area != p_input->stream.p_selected_area )
/* Do the actual reading */
p_block = block_New( p_access, i_blocks * CDIO_CD_FRAMESIZE_RAW );
if( !p_block)
{
/* Change the default area */
p_input->stream.p_selected_area = p_area;
/* Change the current track */
p_cdda->i_track = p_area->i_id - 1;
p_cdda->i_sector = p_cdda->p_sectors[p_cdda->i_track];
/* Update the navigation variables without triggering a callback */
val.i_int = p_area->i_id;
var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL );
msg_Err( p_access, "cannot get a new block of size: %i",
i_blocks * CDIO_CD_FRAMESIZE_RAW );
return NULL;
}
p_cdda->i_sector = p_cdda->p_sectors[p_cdda->i_track];
p_input->stream.p_selected_area->i_tell =
(off_t)p_cdda->i_sector * (off_t)CDIO_CD_FRAMESIZE_RAW
- p_input->stream.p_selected_area->i_start;
if( cdio_read_audio_sectors( p_cdda->p_cddev->cdio, p_block->p_buffer,
p_cdda->i_sector, i_blocks) != 0 )
{
msg_Err( p_access, "could not read sector %lu",
(long unsigned int) p_cdda->i_sector );
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_sector++;
p_access->info.i_pos += CDIO_CD_FRAMESIZE_RAW;
return NULL;
}
/* warn interface that something has changed */
p_input->stream.b_seekable = 1;
p_input->stream.b_changed = 1;
p_cdda->i_sector += i_blocks;
p_access->info.i_pos += p_block->i_buffer;
return 0;
return p_block;
}
/****************************************************************************
* CDDASeek
* CDDASeek - change position for subsequent reads. For example, this
* can happen if the user moves a position slider bar in a GUI.
****************************************************************************/
static void CDDASeek( input_thread_t * p_input, off_t i_off )
static int
CDDASeek( access_t * p_access, int64_t i_pos )
{
cdda_data_t * p_cdda;
p_cdda = (cdda_data_t *) p_input->p_access_data;
p_cdda->i_sector = p_cdda->p_sectors[p_cdda->i_track]
+ i_off / (off_t)CDIO_CD_FRAMESIZE_RAW;
cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell =
(off_t)p_cdda->i_sector * (off_t)CDIO_CD_FRAMESIZE_RAW
- p_input->stream.p_selected_area->i_start;
vlc_mutex_unlock( &p_input->stream.stream_lock );
p_cdda->i_sector = p_cdda->p_sectors[p_access->info.i_title]
+ i_pos / CDIO_CD_FRAMESIZE_RAW;
p_access->info.i_pos = i_pos;
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK),
"sector %lu, offset: %lld, i_tell: %lld",
(long unsigned int) p_cdda->i_sector, i_off,
p_input->stream.p_selected_area->i_tell );
}
#if NEED_UPDATE_VAR
/****************************************************************************
Update the "varname" variable to i_num without triggering a callback.
****************************************************************************/
static void
CDDAUpdateVar( input_thread_t *p_input, int i_num, int i_action,
const char *p_varname, char *p_label,
const char *p_debug_label)
{
vlc_value_t val;
val.i_int = i_num;
if (p_label) {
vlc_value_t text;
text.psz_string = p_label;
var_Change( p_input, p_varname, VLC_VAR_SETTEXT, &text, NULL );
}
var_Change( p_input, p_varname, i_action, &val, NULL );
}
#endif
static void InformationCreate( input_thread_t *p_input )
{
cdda_data_t *p_cdda = (cdda_data_t *) p_input->p_access_data;
#ifdef HAVE_LIBCDDB
if (p_cdda->i_cddb_enabled) {
dbg_print( INPUT_DBG_META, "field %s: %s\n", "Title",
p_cdda->cddb.disc->title );
input_Control( p_input, INPUT_ADD_INFO, _("General"), _("Title"),
"%s", p_cdda->cddb.disc->title );
dbg_print( INPUT_DBG_META, "field %s: %s\n", "Artist",
p_cdda->cddb.disc->artist );
input_Control( p_input, INPUT_ADD_INFO, _("General"), _("Artist"),
"%s", p_cdda->cddb.disc->artist );
dbg_print( INPUT_DBG_META, "field %s: %s\n", "Genre",
p_cdda->cddb.disc->genre );
input_Control( p_input, INPUT_ADD_INFO, _("General"), _("Genre"),
"%s", p_cdda->cddb.disc->genre );
dbg_print( INPUT_DBG_META, "field %s: %s\n", "Extended Data",
p_cdda->cddb.disc->ext_data );
input_Control( p_input, INPUT_ADD_INFO, _("General"), _("Extended Data"),
"%s", p_cdda->cddb.disc->ext_data );
if (p_cdda->cddb.disc->year != 0)
input_Control( p_input, INPUT_ADD_INFO, _("General"),
_("Year"), "%d", p_cdda->cddb.disc->year );
if ( p_cdda->cddb.disc->discid )
input_Control( p_input, INPUT_ADD_INFO, _("General"),
_("CDDB Disc ID"), "%x", p_cdda->cddb.disc->discid );
if ( p_cdda->cddb.disc->category != CDDB_CAT_INVALID )
input_Control( p_input, INPUT_ADD_INFO, _("General"),
_("CDDB Disc Category"), "%s",
CDDB_CATEGORY[p_cdda->cddb.disc->category] );
}
#endif /*HAVE_LIBCDDB*/
#define TITLE_MAX 30
{
track_t i_track = p_cdda->i_nb_tracks;
char psz_buffer[MSTRTIME_MAX_SIZE];
mtime_t i_duration =
(p_cdda->p_sectors[i_track] - p_cdda->p_sectors[0])
/ CDIO_CD_FRAMES_PER_SEC;
dbg_print( INPUT_DBG_META, "Duration %ld", (long int) i_duration );
input_Control( p_input, INPUT_ADD_INFO, _("General"), _("Duration"), "%s",
secstotimestr( psz_buffer, i_duration ) );
for( i_track = 0 ; i_track < p_cdda->i_nb_tracks ; i_track++ ) {
char track_str[TITLE_MAX];
mtime_t i_duration =
(p_cdda->p_sectors[i_track+1] - p_cdda->p_sectors[i_track])
/ CDIO_CD_FRAMES_PER_SEC;
snprintf(track_str, TITLE_MAX, "%s %02d", _("Track"), i_track+1);
input_Control( p_input, INPUT_ADD_INFO, track_str, _("Duration"), "%s",
secstotimestr( psz_buffer, i_duration ) );
#ifdef HAVE_LIBCDDB
if (p_cdda->i_cddb_enabled) {
cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
i_track);
if (t != NULL) {
if ( t->artist != NULL && strlen(t->artist) ) {
input_Control( p_input, INPUT_ADD_INFO, track_str,
_("Artist"), "%s", t->artist );
}
if ( t->title != NULL && strlen(t->title) ) {
input_Control( p_input, INPUT_ADD_INFO, track_str,
_("Title"), "%s", t->title );
}
if ( t->ext_data != NULL && strlen(t->ext_data) ) {
input_Control( p_input, INPUT_ADD_INFO, track_str,
_("Extended Data"), "%s", t->ext_data );
}
}
}
#endif
}
}
"sector %lu, offset: %lld",
(long unsigned int) p_cdda->i_sector, i_pos );
return VLC_SUCCESS;
}
#ifdef HAVE_LIBCDDB
#define free_and_dup(var, val) \
......@@ -448,80 +262,82 @@ static void InformationCreate( input_thread_t *p_input )
static void
GetCDDBInfo( const input_thread_t *p_input, cdda_data_t *p_cdda )
GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
{
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "" );
if (config_GetInt( p_input, MODULE_STRING "-cddb-enabled" )) {
if (config_GetInt( p_access, MODULE_STRING "-cddb-enabled" )) {
int i, i_matches;
cddb_conn_t *conn = cddb_new();
const CdIo *cdio = p_cdda->p_cddev->cdio;
const CdIo *p_cdio = p_cdda->p_cddev->cdio;
cddb_log_set_handler (uninit_log_handler);
if (!conn) {
msg_Warn( p_input, "unable to initialize libcddb" );
msg_Warn( p_access, "unable to initialize libcddb" );
goto cddb_destroy;
}
cddb_set_email_address( conn,
config_GetPsz( p_input,
config_GetPsz( p_access,
MODULE_STRING "-cddb-email") );
cddb_set_server_name( conn,
config_GetPsz( p_input,
config_GetPsz( p_access,
MODULE_STRING "-cddb-server") );
cddb_set_server_port(conn,
config_GetInt( p_input,
config_GetInt( p_access,
MODULE_STRING "-cddb-port") );
/* Set the location of the local CDDB cache directory.
The default location of this directory is */
if (!config_GetInt( p_input, MODULE_STRING "-cddb-enable-cache" ))
if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
cddb_cache_disable(conn);
cddb_cache_set_dir(conn,
config_GetPsz( p_input,
config_GetPsz( p_access,
MODULE_STRING "-cddb-cachedir") );
cddb_set_timeout(conn,
config_GetInt( p_input, MODULE_STRING "-cddb-timeout") );
config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
if (config_GetInt( p_input, MODULE_STRING "-cddb-httpd" )) {
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_input, "Unable to create CDDB disc structure." );
msg_Err( p_access, "Unable to create CDDB disc structure." );
goto cddb_end;
}
for(i = 1; i <= p_cdda->i_nb_tracks; i++) {
p_cdda->psz_mcn = cdio_get_mcn(p_cdio);
for(i = 1; i <= p_cdda->i_tracks; i++) {
cddb_track_t *t = cddb_track_new();
t->frame_offset = cdio_get_track_lba(cdio, i);
t->frame_offset = cdio_get_track_lba(p_cdio, i);
cddb_disc_add_track(p_cdda->cddb.disc, t);
}
p_cdda->cddb.disc->length =
cdio_get_track_lba(cdio, CDIO_CDROM_LEADOUT_TRACK)
cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
/ CDIO_CD_FRAMES_PER_SEC;
if (!cddb_disc_calc_discid(p_cdda->cddb.disc)) {
msg_Err( p_input, "CDDB disc calc failed" );
msg_Err( p_access, "CDDB disc calc failed" );
goto cddb_destroy;
}
i_matches = cddb_query(conn, p_cdda->cddb.disc);
if (i_matches > 0) {
if (i_matches > 1)
msg_Warn( p_input, "Found %d matches in CDDB. Using first one.",
msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
i_matches);
cddb_read(conn, p_cdda->cddb.disc);
......@@ -529,7 +345,7 @@ GetCDDBInfo( const input_thread_t *p_input, cdda_data_t *p_cdda )
cddb_disc_print(p_cdda->cddb.disc);
} else {
msg_Warn( p_input, "CDDB error: %s", cddb_error_str(errno));
msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
}
cddb_destroy:
......@@ -539,6 +355,101 @@ GetCDDBInfo( const input_thread_t *p_input, cdda_data_t *p_cdda )
}
#endif /*HAVE_LIBCDDB*/
#define add_meta_val(FIELD, VLC_META, VAL) \
if ( p_cdda->p_meta ) { \
vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL ); \
dbg_print( INPUT_DBG_META, "field %s: %s\n", VLC_META, VAL ); \
} \
#define add_cddb_meta(FIELD, VLC_META) \
add_meta_val(FIELD, VLC_META, p_cdda->cddb.disc->FIELD);
#define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
{ \
char psz_buf[100]; \
snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
p_cdda->cddb.disc->FIELD ); \
psz_buf[sizeof(psz_buf)-1] = '\0'; \
add_meta_val(FIELD, VLC_META, psz_buf); \
}
/*
Gets and saves CDDA Meta Information. In the Control routine,
we handle Meta Information requests and basically copy what we've
saved here.
*/
static void CDDAMetaInfo( access_t *p_access )
{
cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
#ifdef HAVE_LIBCDDB
if ( p_cdda && p_cdda->i_cddb_enabled ) {
GetCDDBInfo(p_access, p_cdda);
if ( p_cdda->cddb.disc ) {
p_cdda->p_meta = vlc_meta_New();
add_cddb_meta(title, VLC_META_CDDB_TITLE);
add_cddb_meta(artist, VLC_META_CDDB_ARTIST);
add_cddb_meta(genre, VLC_META_CDDB_GENRE);
add_cddb_meta(ext_data, VLC_META_CDDB_EXT_DATA);
add_cddb_meta_fmt(year, "%d", VLC_META_CDDB_YEAR);
add_cddb_meta_fmt(discid, "%x", VLC_META_CDDB_DISCID);
}
}
#endif /*HAVE_LIBCDDB*/
#define TITLE_MAX 30
#if UPDATE_TRACK_INFORMATION_FINISHED
{
track_t i_track = p_cdda->i_tracks;
char psz_buffer[MSTRTIME_MAX_SIZE];
mtime_t i_duration =
(p_cdda->p_sectors[i_track] - p_cdda->p_sectors[0])
/ CDIO_CD_FRAMES_PER_SEC;
dbg_print( INPUT_DBG_META, "Duration %ld", (long int) i_duration );
input_Control( p_access, INPUT_ADD_INFO, _("General"), _("Duration"), "%s",
secstotimestr( psz_buffer, i_duration ) );
for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ ) {
char track_str[TITLE_MAX];
mtime_t i_duration =
(p_cdda->p_sectors[i_track+1] - p_cdda->p_sectors[i_track])