diff --git a/Makefile b/Makefile index c80cbb6de8..c5a127e51d 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,10 @@ ifeq ($(VIDIX),yes) SUBDIRS += libdha vidix DO_MAKE = @ for i in $(SUBDIRS); do $(MAKE) -C $$i $@; done endif +ifeq ($(HAVE_LIBCDIO),yes) +CFLAGS += $(LIBCDIO_INC) +COMMON_LIBS += $(LIBCDIO_LIB) +endif SRCS_COMMON = asxparser.c \ codec-cfg.c \ diff --git a/configure b/configure index f504cfee26..eaf0bfea16 100755 --- a/configure +++ b/configure @@ -226,6 +226,7 @@ Codecs: --enable-gif enable gif support [autodetect] --enable-png enable png input/output support [autodetect] --enable-jpeg enable jpeg input/output support [autodetect] + --enable-libcdio enable external libcdio support [autodetect] --enable-liblzo enable external liblzo support [autodetect] --disable-win32 disable Win32 DLL support [autodetect] --disable-dshow disable Win32/DirectShow support [autodetect] @@ -1480,6 +1481,7 @@ _arts=auto _esd=auto _polyp=auto _jack=auto +_libcdio=auto _liblzo=auto _mad=auto _toolame=auto @@ -1677,6 +1679,8 @@ for ac_option do --disable-mad) _mad=no ;; --disable-toolame) _toolame=no ;; --disable-twolame) _twolame=no ;; + --enable-libcdio) _libcdio=yes ;; + --disable-libcio) _libcdio=no ;; --enable-liblzo) _liblzo=yes ;; --disable-liblzo) _liblzo=no ;; --enable-vorbis) _vorbis=yes ;; @@ -5076,6 +5080,49 @@ fi echores "$_cdparanoia" +echocheck "libcdio" +if test "$_libcdio" = auto && test "$_cdparanoia" = no ; then + if ( pkg-config --modversion libcdio) > /dev/null 2>&1 ; then + cat > $TMPC << EOF +#include +#include +#include +#include +int main() +{ + printf("%s\n", CDIO_VERSION); + return 0; + +} +EOF + _libcdio=no + for _inc_tmp in "$_inc_libcdio" "-I/usr/include/cdio" "-I/usr/local/include/cdio" ; do + cc_check `pkg-config --cflags --libs libcdio` $_inc_tmp $_ld_libcdio -lcdio_cdda -lcdio_paranoia $_ld_lm && _inc_libcdio="$_inc_tmp" && ( $TMPO >> "$TMPLOG" ) && _libcdio=yes && break + done + else + _libcdio=no + fi +fi +if test "$_libcdio" = yes && test "$_cdparanoia" = no ; then + _def_libcdio='#define HAVE_LIBCDIO' + _def_cdparanoia='#define HAVE_CDDA' + _def_havelibcdio='yes' + _inputmodules="cdda $_inputmodules" + _inc_libcdio=`pkg-config --cflags libcdio` + _ld_libcdio=`pkg-config --libs libcdio` + _ld_cdparanoia="$_ld_cdparanoia -lcdio_cdda -lcdio_paranoia -lcdio" +else + if test "$_cdparanoia" = yes ; then + _libcdio="no (using cdparanoia)" + else + _libcdio=no + fi + _def_libcdio='#undef HAVE_LIBCDIO' + _def_havelibcdio='no' +fi +echores "$_libcdio" + + echocheck "freetype >= 2.0.9" # freetype depends on iconv @@ -7116,6 +7163,8 @@ FONTCONFIG_INC = $_inc_fontconfig FONTCONFIG_LIB = $_ld_fontconfig FRIBIDI_INC = $_inc_fribidi FRIBIDI_LIB = $_ld_fribidi +LIBCDIO_INC = $_inc_libcdio +LIBCDIO_LIB = $_ld_libcdio LIBLZO_LIB= $_ld_liblzo MAD_LIB = $_ld_mad VORBIS_LIB = $_ld_vorbis $_ld_libdv @@ -7223,6 +7272,9 @@ $_def_debug /* Toggles colorized output */ //#define MSG_USE_COLORS 1 +/* Indicates that libcdio is available for VCD and CD-DA playback */ +$_def_libcdio + /* Indicates that Ogle's libdvdread is available for DVD playback */ $_def_dvdread diff --git a/libmpdemux/cdd.h b/libmpdemux/cdd.h index a30e21ffeb..ad8a7c150c 100644 --- a/libmpdemux/cdd.h +++ b/libmpdemux/cdd.h @@ -1,8 +1,14 @@ #ifndef __CDD_H__ #define __CDD_H__ +#include "config.h" +#ifndef HAVE_LIBCDIO #include #include +#else +#include +#include +#endif typedef struct { char cddb_hello[1024]; @@ -48,8 +54,13 @@ typedef struct { } cd_info_t; typedef struct { +#ifndef HAVE_LIBCDIO cdrom_drive* cd; cdrom_paranoia* cdp; +#else + cdrom_drive_t* cd; + cdrom_paranoia_t* cdp; +#endif int sector; int start_sector; int end_sector; diff --git a/libmpdemux/cdda.c b/libmpdemux/cdda.c index 7307bbe76d..9f6846aebb 100644 --- a/libmpdemux/cdda.c +++ b/libmpdemux/cdda.c @@ -87,13 +87,17 @@ extern cd_info_t* cddb_parse_xmcd(char *xmcd_file); static int seek(stream_t* s,off_t pos); static int fill_buffer(stream_t* s, char* buffer, int max_len); -static void close(stream_t* s); +static void close_cdda(stream_t* s); static int open_cdda(stream_t *st,int m, void* opts, int* file_format) { struct cdda_params* p = (struct cdda_params*)opts; int mode = p->paranoia_mode; int offset = p->toc_offset; +#ifndef HAVE_LIBCDIO cdrom_drive* cdd = NULL; +#else + cdrom_drive_t* cdd = NULL; +#endif cdda_priv* priv; cd_info_t *cd_info,*cddb_info = NULL; unsigned int audiolen=0; @@ -125,9 +129,11 @@ static int open_cdda(stream_t *st,int m, void* opts, int* file_format) { } #endif +#ifndef HAVE_LIBCDIO if(p->generic_dev) cdd = cdda_identify_scsi(p->generic_dev,p->device,0,NULL); else +#endif #if defined(__NetBSD__) cdd = cdda_identify_scsi(p->device,p->device,0,NULL); #else @@ -144,7 +150,9 @@ static int open_cdda(stream_t *st,int m, void* opts, int* file_format) { if(p->sector_size) { cdd->nsectors = p->sector_size; +#ifndef HAVE_LIBCDIO cdd->bigbuff = p->sector_size * CD_FRAMESIZE_RAW; +#endif } if(cdda_open(cdd) != 0) { @@ -218,10 +226,17 @@ static int open_cdda(stream_t *st,int m, void* opts, int* file_format) { if(p->no_skip) mode |= PARANOIA_MODE_NEVERSKIP; +#ifndef HAVE_LIBCDIO paranoia_modeset(cdd, mode); if(p->search_overlap >= 0) paranoia_overlapset(cdd,p->search_overlap); +#else + paranoia_modeset(priv->cdp, mode); + + if(p->search_overlap >= 0) + paranoia_overlapset(priv->cdp,p->search_overlap); +#endif paranoia_seek(priv->cdp,priv->start_sector,SEEK_SET); priv->sector = priv->start_sector; @@ -235,14 +250,21 @@ static int open_cdda(stream_t *st,int m, void* opts, int* file_format) { #endif st->priv = priv; +#ifndef HAVE_LIBCDIO st->start_pos = priv->start_sector*CD_FRAMESIZE_RAW; st->end_pos = priv->end_sector*CD_FRAMESIZE_RAW; st->type = STREAMTYPE_CDDA; st->sector_size = CD_FRAMESIZE_RAW; +#else + st->start_pos = priv->start_sector*CDIO_CD_FRAMESIZE_RAW; + st->end_pos = priv->end_sector*CDIO_CD_FRAMESIZE_RAW; + st->type = STREAMTYPE_CDDA; + st->sector_size = CDIO_CD_FRAMESIZE_RAW; +#endif st->fill_buffer = fill_buffer; st->seek = seek; - st->close = close; + st->close = close_cdda; *file_format = DEMUXER_TYPE_RAWAUDIO; @@ -251,7 +273,11 @@ static int open_cdda(stream_t *st,int m, void* opts, int* file_format) { return STREAM_OK; } +#ifndef HAVE_LIBCDIO static void cdparanoia_callback(long inpos, int function) { +#else +static void cdparanoia_callback(long int inpos, paranoia_cb_mode_t function) { +#endif } static int fill_buffer(stream_t* s, char* buffer, int max_len) { @@ -263,13 +289,22 @@ static int fill_buffer(stream_t* s, char* buffer, int max_len) { buf = paranoia_read(p->cdp,cdparanoia_callback); #ifdef WORDS_BIGENDIAN +#ifndef HAVE_LIBCDIO for(i=0;isector++; +#ifndef HAVE_LIBCDIO s->pos = p->sector*CD_FRAMESIZE_RAW; memcpy(buffer,buf,CD_FRAMESIZE_RAW); +#else + s->pos = p->sector*CDIO_CD_FRAMESIZE_RAW; + memcpy(buffer,buf,CDIO_CD_FRAMESIZE_RAW); +#endif if((p->sector < p->start_sector) || (p->sector >= p->end_sector)) { s->eof = 1; @@ -290,7 +325,11 @@ static int fill_buffer(stream_t* s, char* buffer, int max_len) { } +#ifndef HAVE_LIBCDIO return CD_FRAMESIZE_RAW; +#else + return CDIO_CD_FRAMESIZE_RAW; +#endif } static int seek(stream_t* s,off_t newpos) { @@ -306,8 +345,13 @@ static int seek(stream_t* s,off_t newpos) { return 0; } +#ifndef HAVE_LIBCDIO sec = s->pos/CD_FRAMESIZE_RAW; //printf("pos: %d, sec: %d ## %d\n", (int)s->pos, (int)sec, CD_FRAMESIZE_RAW); +#else + sec = s->pos/CDIO_CD_FRAMESIZE_RAW; +//printf("pos: %d, sec: %d ## %d\n", (int)s->pos, (int)sec, CDIO_CD_FRAMESIZE_RAW); +#endif //printf("sector: %d new: %d\n", p->sector, sec ); for(i=0;icd->tracks;i++){ @@ -338,14 +382,18 @@ static int seek(stream_t* s,off_t newpos) { #endif p->sector = sec; +#ifndef HAVE_LIBCDIO // s->pos = sec*CD_FRAMESIZE_RAW; +#else +// s->pos = sec*CDIO_CD_FRAMESIZE_RAW; +#endif //printf("seek: %d, sec: %d\n", (int)s->pos, sec); paranoia_seek(p->cdp,sec,SEEK_SET); return 1; } -static void close(stream_t* s) { +static void close_cdda(stream_t* s) { cdda_priv* p = (cdda_priv*)s->priv; paranoia_free(p->cdp); cdda_close(p->cd); diff --git a/libmpdemux/cddb.c b/libmpdemux/cddb.c index 8fe59db0be..04bd83d5fa 100644 --- a/libmpdemux/cddb.c +++ b/libmpdemux/cddb.c @@ -21,10 +21,18 @@ #include #include #include -#include #include #include +#ifdef WIN32 +#ifdef __MINGW32__ +#define mkdir(a,b) mkdir(a) +#endif +#include +#include +#else +#include #include +#endif #include #include @@ -32,6 +40,8 @@ #include #elif defined(__FreeBSD__) || defined(__bsdi__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) #include +#elif defined(WIN32) + #include #endif #include "cdd.h" @@ -83,6 +93,41 @@ read_toc(const char *dev) { return tochdr.cdth_trk1; } +#elif defined(WIN32) +int +read_toc(const char *dev) { + HANDLE drive; + DWORD r; + CDROM_TOC toc; + char device[10]; + int i; + + sprintf(device, "\\\\.\\%s", dev); + drive = CreateFile(device, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + + if(!DeviceIoControl(drive, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(CDROM_TOC), &r, 0)) { + mp_msg(MSGT_OPEN, MSGL_ERR, "Failed to read TOC.\n"); + return 0; + } + + for (i = toc.FirstTrack; i <= toc.LastTrack; i++) { + toc.FirstTrack = i; + cdtoc[i-1].min = toc.TrackData[i - 1].Address[1]; + cdtoc[i-1].sec = toc.TrackData[i - 1].Address[2]; + cdtoc[i-1].frame = toc.TrackData[i - 1].Address[3]; + cdtoc[i-1].frame += cdtoc[i-1].min*60*75; + cdtoc[i-1].frame += cdtoc[i-1].sec*75; + } + toc.FirstTrack = 0xAA; + cdtoc[toc.LastTrack].min = toc.TrackData[toc.LastTrack].Address[1]; + cdtoc[toc.LastTrack].sec = toc.TrackData[toc.LastTrack].Address[2]; + cdtoc[toc.LastTrack].frame = toc.TrackData[toc.LastTrack].Address[3]; + cdtoc[toc.LastTrack].frame += cdtoc[toc.LastTrack].min*60*75; + cdtoc[toc.LastTrack].frame += cdtoc[toc.LastTrack].sec*75; + CloseHandle(drive); + return toc.LastTrack; +} + #elif defined(__FreeBSD__) || defined(__bsdi__) || defined(__DragonFly__) int read_toc(const char *dev) { @@ -281,7 +326,11 @@ cddb_read_cache(cddb_data_t *cddb_data) { sprintf( file_name, "%s%08lx", cddb_data->cache_dir, cddb_data->disc_id); - file_fd = open(file_name, O_RDONLY); + file_fd = open(file_name, O_RDONLY +#ifdef WIN32 + | O_BINARY +#endif + ); if( file_fd<0 ) { printf("No cache found\n"); return -1; @@ -328,7 +377,11 @@ cddb_write_cache(cddb_data_t *cddb_data) { if( ret<0 ) { // Directory not present, create it. ret = mkdir( cddb_data->cache_dir, 0755 ); +#ifdef __MINGW32__ + if( ret<0 && errno != EEXIST ) { +#else if( ret<0 ) { +#endif perror("mkdir"); printf("Failed to create directory %s\n", cddb_data->cache_dir ); return -1; @@ -674,6 +727,12 @@ cddb_resolve(const char *dev, char **xmcd_file) { } home_dir = getenv("HOME"); +#ifdef __MINGW32__ + if( home_dir==NULL ) home_dir = getenv("USERPROFILE"); + if( home_dir==NULL ) home_dir = getenv("HOMEPATH"); + // Last resort, store the cddb cache in the mplayer directory + if( home_dir==NULL ) home_dir = (char *)get_path(""); +#endif if( home_dir==NULL ) { cddb_data.cache_dir = NULL; } else {