Web lists-archives.com

[MPlayer-dev-eng] [PATCH] Enable playing Video CDs with libcdio




In times in which CDROM drives are becoming less and less common, it might be
useful to be able to play bin/cue images instead of real disks (although one
might doubt whether playing Video CDs is useful at all).

For Audio CDs, it is already possible to play images utilizing libcdio, but
it isn't for Video CDs, although libcdio is capable of doing it.

Make the general VCD stream driver aware of libcdio and add the necessary
libcdio specific routines.

This is based on work from Rocky Bernstein, rocky panix com, posted 2004 on
the development mailing list.

Ingo
Index: stream/stream_vcd.c
===================================================================
--- stream/stream_vcd.c	(revision 37444)
+++ stream/stream_vcd.c	(working copy)
@@ -46,6 +46,8 @@
 #include "vcd_read_win32.h"
 #elif defined(__OS2__)
 #include "vcd_read_os2.h"
+#elif CONFIG_LIBCDIO
+#include "vcd_read_libcdio.h"
 #else
 #include "vcd_read.h"
 #endif
@@ -124,6 +126,10 @@
 }
 
 static void close_s(stream_t *stream) {
+#if CONFIG_LIBCDIO
+  mp_vcd_priv_t *vcd = stream->priv;
+  cdio_destroy(vcd->cdio);
+#endif
   free(stream->priv);
 }
 
@@ -144,6 +150,9 @@
   ULONG ulAction;
   ULONG rc;
 #endif
+#if CONFIG_LIBCDIO
+  CdIo *cdio;
+#endif
 
   if(mode != STREAM_READ
 #if defined(__MINGW32__) || defined(__CYGWIN__)
@@ -174,6 +183,9 @@
                OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE | OPEN_FLAGS_DASD,
                NULL);
   f = rc ? -1 : hcd;
+#elif CONFIG_LIBCDIO
+  cdio = cdio_open(p->device, DRIVER_UNKNOWN);
+  f = cdio ? 0 : -1;
 #else
   f=open(p->device,O_RDONLY);
 #endif
@@ -186,14 +198,26 @@
   vcd = vcd_read_toc(f);
   if(!vcd) {
     mp_msg(MSGT_OPEN,MSGL_ERR,"Failed to get cd toc\n");
+#if CONFIG_LIBCDIO
+    cdio_destroy(cdio);
+#else
     close(f);
+#endif
     m_struct_free(&stream_opts,opts);
     return STREAM_ERROR;
   }
+#if CONFIG_LIBCDIO
+  else
+    vcd->cdio = cdio;
+#endif
   ret2=vcd_get_track_end(vcd,p->track);
   if(ret2<0){
     mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_ErrTrackSelect " (get)\n");
+#if CONFIG_LIBCDIO
+    cdio_destroy(cdio);
+#else
     close(f);
+#endif
     free(vcd);
     m_struct_free(&stream_opts,opts);
     return STREAM_ERROR;
@@ -201,7 +225,11 @@
   ret=vcd_seek_to_track(vcd,p->track);
   if(ret<0){
     mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_ErrTrackSelect " (seek)\n");
+#if CONFIG_LIBCDIO
+    cdio_destroy(cdio);
+#else
     close(f);
+#endif
     free(vcd);
     m_struct_free(&stream_opts,opts);
     return STREAM_ERROR;
Index: stream/vcd_read_libcdio.h
===================================================================
--- stream/vcd_read_libcdio.h	(revision 0)
+++ stream/vcd_read_libcdio.h	(working copy)
@@ -0,0 +1,148 @@
+/*
+ * Based on work by Rocky Bernstein <rocky@xxxxxxxxx>, 2004,
+ * adapted by Ingo Brückl.
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer 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.
+ *
+ * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPLAYER_VCD_READ_LIBCDIO_H
+#define MPLAYER_VCD_READ_LIBCDIO_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_CDIO_PARANOIA_H
+#include <cdio/cdda.h>
+#include <cdio/paranoia.h>
+#elif HAVE_CDIO_PARANOIA_PARANOIA_H
+#include <cdio/paranoia/cdda.h>
+#include <cdio/paranoia/paranoia.h>
+#endif
+
+/** Private vcd data. */
+typedef struct {
+    track_t track;     /**< Current track being played. */
+    lsn_t lsn;         /**< Current logical sector number. */
+    CdIo *cdio;        /**< Pointer to internal libcdio data. */
+} mp_vcd_priv_t;
+
+/**
+ * @brief Prepare reading of the Video CD.
+ *
+ * @param fd (unused)
+ *
+ * @return pointer to the newly allocated private vcd data
+ */
+static inline mp_vcd_priv_t *vcd_read_toc(int fd)
+{
+    mp_vcd_priv_t *vcd = malloc(sizeof(mp_vcd_priv_t));
+
+    return vcd;
+}
+
+/**
+ * @brief Set the track of the Video CD to be read next.
+ *
+ * @param vcd pointer to the private vcd data
+ * @param track track to be read next
+ *
+ * @return sector offset in bytes or -1 (error)
+ */
+static int vcd_seek_to_track(mp_vcd_priv_t *vcd, int track)
+{
+    vcd->lsn = cdio_get_track_lsn(vcd->cdio, track);
+
+    if (vcd->lsn == CDIO_INVALID_LSN)
+        return -1;
+
+    return M2F2_SECTOR_SIZE * vcd->lsn;
+}
+
+/**
+ * @brief Determine the number of sectors of a Video CD track.
+ *
+ * @param vcd pointer to the private vcd data
+ * @param track track to examine
+ *
+ * @return sector offset in bytes or -1 (error)
+ */
+static int vcd_get_track_end(mp_vcd_priv_t *vcd, int track)
+{
+    lsn_t end_lsn;
+
+    if (vcd_seek_to_track(vcd, track) == -1)
+        return -1;
+
+    end_lsn = vcd->lsn + cdio_get_track_sec_count(vcd->cdio, track) - 1;
+
+    if (end_lsn == CDIO_INVALID_LSN)
+        return -1;
+
+    return M2F2_SECTOR_SIZE * end_lsn;
+}
+
+/**
+ * @brief Get last track number of the Video CD.
+ *
+ * @param vcd pointer to the private vcd data
+ *
+ * @return last track number
+ */
+static inline int vcd_end_track(mp_vcd_priv_t *vcd)
+{
+    return cdio_get_last_track_num(vcd->cdio);
+}
+
+/**
+ * @brief Set the sector of the Video CD to be read next.
+ *
+ * @param vcd pointer to the private vcd data
+ * @param sect sector to be read next
+ */
+static inline void vcd_set_msf(mp_vcd_priv_t *vcd, unsigned int sect)
+{
+    vcd->lsn = sect;
+}
+
+/**
+ * @brief Read a sector of the Video CD.
+ *
+ * @note As a side effect, the sector pointer will be incremented.
+ *
+ * @param vcd pointer to the private vcd data
+ * @param buffer pointer to a buffer suitable to store the data
+ *
+ * @return number of bytes read or 0 (error)
+ */
+static int vcd_read(mp_vcd_priv_t *vcd, char *buffer)
+{
+    struct {
+        uint8_t subheader[CDIO_CD_SUBHEADER_SIZE];
+        uint8_t data[M2F2_SECTOR_SIZE];
+        uint8_t spare[4];
+    } vcd_sector;
+
+    if (cdio_read_mode2_sector(vcd->cdio, &vcd_sector, vcd->lsn, true) != 0)
+        return 0;
+
+    memcpy(buffer, vcd_sector.data, M2F2_SECTOR_SIZE);
+    vcd->lsn++;
+
+    return M2F2_SECTOR_SIZE;
+}
+
+#endif /* MPLAYER_VCD_READ_LIBCDIO_H */
_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng@xxxxxxxxxxxx
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng