[MPlayer-cvslog] r37458 - in trunk/stream: stream_vcd.c vcd_read_libcdio.h

ib subversion at mplayerhq.hu
Tue Aug 25 11:24:45 CEST 2015


Author: ib
Date: Tue Aug 25 11:24:45 2015
New Revision: 37458

Log:
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 Video CD bin/cue images transparently
using the disk scheme vcd:// instead of playing a real disk.

Audio CD images can already be played via cd:// by utilizing libcdio,
but Video CD images can't, although libcdio is capable of doing it.

So 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.

Added:
   trunk/stream/vcd_read_libcdio.h
Modified:
   trunk/stream/stream_vcd.c

Modified: trunk/stream/stream_vcd.c
==============================================================================
--- trunk/stream/stream_vcd.c	Mon Aug 24 22:24:09 2015	(r37457)
+++ trunk/stream/stream_vcd.c	Tue Aug 25 11:24:45 2015	(r37458)
@@ -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 int control(stream_t *stream, int
 }
 
 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 @@ static int open_s(stream_t *stream,int m
   ULONG ulAction;
   ULONG rc;
 #endif
+#if CONFIG_LIBCDIO
+  CdIo *cdio;
+#endif
 
   if(mode != STREAM_READ
 #if defined(__MINGW32__) || defined(__CYGWIN__)
@@ -174,6 +183,9 @@ static int open_s(stream_t *stream,int m
                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 @@ static int open_s(stream_t *stream,int m
   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 @@ static int open_s(stream_t *stream,int m
   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;

Added: trunk/stream/vcd_read_libcdio.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/stream/vcd_read_libcdio.h	Tue Aug 25 11:24:45 2015	(r37458)
@@ -0,0 +1,148 @@
+/*
+ * Based on work by Rocky Bernstein <rocky at panix.com>, 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 */


More information about the MPlayer-cvslog mailing list