changeset 19298:bbce98bb6d05

renamed cue_read.c to stream_cue.c for consistency
author ben
date Thu, 03 Aug 2006 19:25:16 +0000
parents 4255dce93f82
children e5854db8a39f
files stream/Makefile stream/cue_read.c stream/stream_cue.c
diffstat 3 files changed, 604 insertions(+), 606 deletions(-) [+]
line wrap: on
line diff
--- a/stream/Makefile	Thu Aug 03 19:22:23 2006 +0000
+++ b/stream/Makefile	Thu Aug 03 19:25:16 2006 +0000
@@ -12,9 +12,6 @@
 SRCS += cache2.c
 endif
 
-# Miscellaneous
-SRCS += cue_read.c \
-
 ifeq ($(CDDA),yes)
 SRCS += stream_cdda.c cdinfo.c
   ifeq ($(MPLAYER_NETWORK),yes)
@@ -24,6 +21,7 @@
 
 # Stream readers/writers
 SRCS += stream.c \
+        stream_cue.c \
         stream_file.c \
         stream_null.c \
 
--- a/stream/cue_read.c	Thu Aug 03 19:22:23 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,603 +0,0 @@
-//=================== VideoCD BinCue ==========================
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "config.h"
-#include "mp_msg.h"
-#include "help_mp.h"
-
-#include "stream.h"
-
-#include "help_mp.h"
-#include "m_option.h"
-#include "m_struct.h"
-
-#define byte    unsigned char
-#define SIZERAW 2352
-#define SIZEISO_MODE1 2048
-#define SIZEISO_MODE2_RAW 2352
-#define SIZEISO_MODE2_FORM1 2048
-#define SIZEISO_MODE2_FORM2 2336
-#define AUDIO 0
-#define MODE1 1
-#define MODE2 2
-#define MODE1_2352 10
-#define MODE2_2352 20
-#define MODE1_2048 30
-#define MODE2_2336 40
-#define UNKNOWN -1
-
-static struct stream_priv_s {
-  char* filename;
-} stream_priv_dflts = {
-  NULL
-};
-
-#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
-/// URL definition
-static m_option_t stream_opts_fields[] = {
-  { "string", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL},
-  { NULL, NULL, 0, 0, 0, 0,  NULL }
-};
-static struct m_struct_st stream_opts = {
-  "cue",
-  sizeof(struct stream_priv_s),
-  &stream_priv_dflts,
-  stream_opts_fields
-};
-
-static FILE* fd_cue;
-static int fd_bin = 0;
-
-static char bin_filename[256];
-
-static char cue_filename[256];
-static char bincue_path[256];
-
-
-typedef struct track
-{
-   unsigned short mode;
-   unsigned short minute;
-   unsigned short second;
-   unsigned short frame;
-
-   /* (min*60 + sec) * 75 + fps   */
-
-   unsigned long start_sector;
-
-   /* = the sizes in bytes off all tracks bevor this one */
-   /* its needed if there are mode1 tracks befor the mpeg tracks */
-   unsigned long start_offset;
-
-   /*   unsigned char num[3]; */
-} tTrack;
-
-/* max 99 tracks on a cd */
-static tTrack tracks[100];
-
-static struct cue_track_pos {
-  int track;
-  unsigned short mode;
-  unsigned short minute;
-  unsigned short second;
-  unsigned short frame;
-} cue_current_pos;
-
-/* number of tracks on the cd */
-static int nTracks = 0;
-
-/* presumes Line is preloaded with the "current" line of the file */
-static int cue_getTrackinfo(char *Line, tTrack *track)
-{
-  char inum[3];
-  char min;
-  char sec;
-  char fps;
-  int already_set = 0;
-
-  /* Get the 'mode' */
-  if (strncmp(&Line[2], "TRACK ", 6)==0)
-  {
-/*    strncpy(track->num, &Line[8], 2); track->num[2] = '\0'; */
-
-    track->mode = UNKNOWN;
-    if(strncmp(&Line[11], "AUDIO", 5)==0) track->mode = AUDIO;
-    if(strncmp(&Line[11], "MODE1/2352", 10)==0) track->mode = MODE1_2352;
-    if(strncmp(&Line[11], "MODE1/2048", 10)==0) track->mode = MODE1_2048;
-    if(strncmp(&Line[11], "MODE2/2352", 10)==0) track->mode = MODE2_2352;
-    if(strncmp(&Line[11], "MODE2/2336", 10)==0) track->mode = MODE2_2336;
-  }
-  else return(1);
-
-  /* Get the track indexes */
-  while(1) {
-    if(! fgets( Line, 256, fd_cue ) ) { break;}
-
-    if (strncmp(&Line[2], "TRACK ", 6)==0)
-    {
-      /* next track starting */
-      break;
-    }
-
-    /* Track 0 or 1, take the first an get fill the values*/
-    if (strncmp(&Line[4], "INDEX ", 6)==0)
-    {
-      /* check stuff here so if the answer is false the else stuff below won't be executed */
-      strncpy(inum, &Line[10], 2); inum[2] = '\0';
-      if ((already_set == 0) &&
-          ((strcmp(inum, "00")==0) || (strcmp(inum, "01")==0)))
-      {
-        already_set = 1;
-
-        min = ((Line[13]-'0')<<4) | (Line[14]-'0');
-        sec = ((Line[16]-'0')<<4) | (Line[17]-'0');
-        fps = ((Line[19]-'0')<<4) | (Line[20]-'0');
-
-        track->minute = (((min>>4)*10) + (min&0xf));
-        track->second = (((sec>>4)*10) + (sec&0xf));
-        track->frame  = (((fps>>4)*10) + (fps&0xf));
-      }
-    }
-    else if (strncmp(&Line[4], "PREGAP ", 7)==0) { ; /* ignore */ }
-    else if (strncmp(&Line[4], "FLAGS ", 6)==0)  { ; /* ignore */ }
-    else mp_msg (MSGT_OPEN,MSGL_INFO,
-                 MSGTR_MPDEMUX_CUEREAD_UnexpectedCuefileLine, Line);
-  }
-  return(0);
-}
-
-
-
-/* FIXME: the string operations ( strcpy,strcat ) below depend
- * on the arrays to have the same size, thus we need to make
- * sure the sizes are in sync.
- */
-static int cue_find_bin (char *firstline) {
-  int i,j;
-  char s[256];
-  char t[256];
-
-  /* get the filename out of that */
-  /*                      12345 6  */
-  mp_msg (MSGT_OPEN,MSGL_INFO, "[bincue] cue_find_bin(%s)\n", firstline);
-  if (strncmp(firstline, "FILE \"",6)==0)
-  {
-    i = 0;
-    j = 0;
-    while ( firstline[6 + i] != '"')
-    {
-      bin_filename[j] = firstline[6 + i];
-
-      /* if I found a path info, than delete all bevor it */
-      switch (bin_filename[j])
-      {
-        case '\\':
-          j = 0;
-          break;
-
-        case '/':
-          j = 0;
-          break;
-
-        default:
-          j++;
-      }
-      i++;
-    }
-    bin_filename[j+1] = '\0';
-
-  }
-
-  /* now try to open that file, without path */
-  fd_bin = open (bin_filename, O_RDONLY);
-  if (fd_bin == -1)
-  {
-    mp_msg(MSGT_OPEN,MSGL_STATUS, MSGTR_MPDEMUX_CUEREAD_BinFilenameTested,
-           bin_filename);
-
-    /* now try to find it with the path of the cue file */
-    snprintf(s,sizeof( s ),"%s/%s",bincue_path,bin_filename);
-    fd_bin = open (s, O_RDONLY);
-    if (fd_bin == -1)
-    {
-      mp_msg(MSGT_OPEN,MSGL_STATUS,
-             MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);
-      /* now I would say the whole filename is shit, build our own */
-      strncpy(s, cue_filename, strlen(cue_filename) - 3 );
-      s[strlen(cue_filename) - 3] = '\0';
-      strcat(s, "bin");
-      fd_bin = open (s, O_RDONLY);
-      if (fd_bin == -1)
-      {
-        mp_msg(MSGT_OPEN,MSGL_STATUS,
-               MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);
-
-        /* ok try it with path */
-        snprintf(t, sizeof( t ), "%s/%s", bincue_path, s);
-        fd_bin = open (t, O_RDONLY);
-        if (fd_bin == -1)
-        {
-          mp_msg(MSGT_OPEN,MSGL_STATUS,
-                 MSGTR_MPDEMUX_CUEREAD_BinFilenameTested,t);
-          /* now I would say the whole filename is shit, build our own */
-          strncpy(s, cue_filename, strlen(cue_filename) - 3 );
-          s[strlen(cue_filename) - 3] = '\0';
-          strcat(s, "img");
-          fd_bin = open (s, O_RDONLY);
-          if (fd_bin == -1)
-          {
-            mp_msg(MSGT_OPEN,MSGL_STATUS,
-                   MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);
-            /* ok try it with path */
-            snprintf(t, sizeof( t ), "%s/%s", bincue_path, s);
-            fd_bin = open (t, O_RDONLY);
-            if (fd_bin == -1)
-            {
-              mp_msg(MSGT_OPEN,MSGL_STATUS,
-                     MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);
-
-              /* I'll give up */
-              mp_msg(MSGT_OPEN,MSGL_ERR,
-                     MSGTR_MPDEMUX_CUEREAD_CannotFindBinFile);
-              return -1;
-            }
-          }
-        } else strcpy(bin_filename, t);
-
-      } else strcpy(bin_filename, s);
-
-    } else strcpy(bin_filename, s);
-
-  }
-
-  mp_msg(MSGT_OPEN,MSGL_INFO,
-         MSGTR_MPDEMUX_CUEREAD_UsingBinFile, bin_filename);
-  return 0;
-}
-
-static inline int cue_msf_2_sector(int minute, int second, int frame) {
- return frame + (second + minute * 60 ) * 75;
-}
-
-static inline int cue_get_msf(void) {
-  return cue_msf_2_sector (cue_current_pos.minute,
-                           cue_current_pos.second,
-                           cue_current_pos.frame);
-}
-
-static inline void cue_set_msf(unsigned int sect){
-  cue_current_pos.frame=sect%75;
-  sect=sect/75;
-  cue_current_pos.second=sect%60;
-  sect=sect/60;
-  cue_current_pos.minute=sect;
-}
-
-static inline int cue_mode_2_sector_size(int mode)
-{
-  switch (mode)
-  {
-    case AUDIO:      return AUDIO;
-    case MODE1_2352: return SIZERAW;
-    case MODE1_2048: return SIZEISO_MODE1;
-    case MODE2_2352: return SIZEISO_MODE2_RAW;
-    case MODE2_2336: return SIZEISO_MODE2_FORM2;
-
-    default:
-      mp_msg(MSGT_OPEN,MSGL_FATAL,
-             MSGTR_MPDEMUX_CUEREAD_UnknownModeForBinfile);
-      abort();
-  }
-
-}
-
-
-static int cue_read_cue (char *in_cue_filename)
-{
-  struct stat filestat;
-  char sLine[256];
-  unsigned int sect;
-  char *s,*t;
-  int i;
-
-  /* we have no tracks at the beginning */
-  nTracks = 0;
-
-  fd_bin = 0;
-
-  /* split the filename into a path and filename part */
-  s = strdup(in_cue_filename);
-  t = strrchr(s, '/');
-  if (t == (char *)NULL)
-     t = ".";
-  else {
-     *t = '\0';
-     t = s;
-     if (*t == '\0')
-       strcpy(t, "/");
-  }
-  
-  strlcpy(bincue_path,t,sizeof( bincue_path ));
-  mp_msg(MSGT_OPEN,MSGL_V,"dirname: %s, cuepath: %s\n", t, bincue_path);
-
-  /* no path at all? */
-  if (strcmp(bincue_path, ".") == 0) {
-    mp_msg(MSGT_OPEN,MSGL_V,"bincue_path: %s\n", bincue_path);
-    strlcpy(cue_filename,in_cue_filename,sizeof( cue_filename ));
-  } else {
-    strlcpy(cue_filename,in_cue_filename + strlen(bincue_path) + 1,
-            sizeof( cue_filename ));
-  }
-
-
-
-  /* open the cue file */
-  fd_cue = fopen (in_cue_filename, "r");
-  if (fd_cue == NULL)
-  {
-    mp_msg(MSGT_OPEN,MSGL_ERR,
-           MSGTR_MPDEMUX_CUEREAD_CannotOpenCueFile, in_cue_filename);
-    return -1;
-  }
-
-  /* read the first line and hand it to find_bin, which will
-     test more than one possible name of the file */
-
-  if(! fgets( sLine, 256, fd_cue ) )
-  {
-    mp_msg(MSGT_OPEN,MSGL_ERR,
-           MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);
-    fclose (fd_cue);
-    return -1;
-  }
-
-  if (cue_find_bin(sLine)) {
-    fclose (fd_cue);
-    return -1;
-  }
-
-
-  /* now build the track list */
-  /* red the next line and call our track finder */
-  if(! fgets( sLine, 256, fd_cue ) )
-  {
-    mp_msg(MSGT_OPEN,MSGL_ERR,
-           MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);
-    fclose (fd_cue);
-    return -1;
-  }
-
-  while(!feof(fd_cue))
-  {
-    if (cue_getTrackinfo(sLine, &tracks[nTracks++]) != 0)
-    {
-      mp_msg(MSGT_OPEN,MSGL_ERR,
-             MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);
-      fclose (fd_cue);
-      return -1;
-    }
-  }
-
-  /* make a fake track with stands for the Lead out */
-  if (fstat (fd_bin, &filestat) == -1) {
-    mp_msg(MSGT_OPEN,MSGL_ERR,
-           MSGTR_MPDEMUX_CUEREAD_ErrGettingBinFileSize);
-    fclose (fd_cue);
-    return -1;
-  }
-
-  sect = filestat.st_size / 2352;
-
-  tracks[nTracks].frame = sect%75;
-  sect=sect/75;
-  tracks[nTracks].second = sect%60;
-  sect=sect/60;
-  tracks[nTracks].minute = sect;
-
-
-  /* let's calculate the start sectors and offsets */
-  for(i = 0; i <= nTracks; i++)
-  {
-    tracks[i].start_sector = cue_msf_2_sector(tracks[i].minute,
-                                              tracks[nTracks].second,
-                                              tracks[nTracks].frame);
-
-    /* if we're the first track we don't need to offset of the one befor */
-    if (i == 0)
-    {
-      /* was always 0 on my svcds, but who knows */
-      tracks[0].start_offset = tracks[0].start_sector *
-        cue_mode_2_sector_size(tracks[0].mode);
-    } else
-    {
-      tracks[i].start_offset = tracks[i-1].start_offset +
-        (tracks[i].start_sector - tracks[i-1].start_sector) *
-        cue_mode_2_sector_size(tracks[i-1].mode);
-    }
-  }
-
-  fclose (fd_cue);
-
-  return fd_bin;
-}
-
-
-
-
-static int cue_read_toc_entry(void) {
-
-  int track = cue_current_pos.track - 1;
-
-  /* check if its a valid track, if not return -1 */
-  if (track >= nTracks)
-    return -1;
-
-
-  switch (tracks[track].mode)
-  {
-    case AUDIO:
-      cue_current_pos.mode = AUDIO;
-      break;
-    case MODE1_2352:
-      cue_current_pos.mode = MODE1;
-      break;
-    case MODE1_2048:
-      cue_current_pos.mode = MODE1;
-      break;
-    default: /* MODE2_2352 and MODE2_2336 */
-      cue_current_pos.mode = MODE2;
-  }
-  cue_current_pos.minute = tracks[track].minute;
-  cue_current_pos.second = tracks[track].second;
-  cue_current_pos.frame = tracks[track].frame;
-
-  return 0;
-}
-
-static int cue_vcd_seek_to_track (int track){
-  cue_current_pos.track  = track;
-
-  if (cue_read_toc_entry ())
-    return -1;
-
-  return VCD_SECTOR_DATA * cue_get_msf();
-}
-
-static int cue_vcd_get_track_end (int track){
-  cue_current_pos.frame = tracks[track].frame;
-  cue_current_pos.second = tracks[track].second;
-  cue_current_pos.minute = tracks[track].minute;
-
-  return VCD_SECTOR_DATA * cue_get_msf();
-}
-
-static void cue_vcd_read_toc(void){
-  int i;
-  for (i = 0; i < nTracks; ++i) {
-
-    mp_msg(MSGT_OPEN,MSGL_INFO,
-           MSGTR_MPDEMUX_CUEREAD_InfoTrackFormat,
-           i+1,
-           tracks[i].mode,
-           tracks[i].minute,
-           tracks[i].second,
-           tracks[i].frame
-           );
-  }
-}
-
-static int cue_vcd_read(stream_t *stream, char *mem, int size) {
-  unsigned long position;
-  int track = cue_current_pos.track - 1;
-
-  position = tracks[track].start_offset +
-             (cue_msf_2_sector(cue_current_pos.minute,
-                               cue_current_pos.second,
-                               cue_current_pos.frame) -
-              tracks[track].start_sector)
-             * cue_mode_2_sector_size(tracks[track].mode);
-
-  
-  if(position >= tracks[track+1].start_offset)
-    return 0;
-
-  if(lseek(fd_bin, position+VCD_SECTOR_OFFS, SEEK_SET) == -1) {
-    mp_msg(MSGT_OPEN,MSGL_ERR, MSGTR_MPDEMUX_CUEREAD_UnexpectedBinFileEOF);
-    return 0;
-  }
-
-  if(read(fd_bin, mem, VCD_SECTOR_DATA) != VCD_SECTOR_DATA) {
-    mp_msg(MSGT_OPEN,MSGL_ERR, MSGTR_MPDEMUX_CUEREAD_CannotReadNBytesOfPayload, VCD_SECTOR_DATA);
-    return 0;
-  }
-
-  cue_current_pos.frame++;
-  if (cue_current_pos.frame==75){
-    cue_current_pos.frame=0;
-    cue_current_pos.second++;
-    if (cue_current_pos.second==60){
-      cue_current_pos.second=0;
-      cue_current_pos.minute++;
-    }
-  }
-
-  return VCD_SECTOR_DATA;
-}
-
-static int seek(stream_t *s,off_t newpos) {
-  s->pos=newpos;
-  cue_set_msf(s->pos/VCD_SECTOR_DATA);
-  return 1;
-}
-
-
-static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
-  struct stream_priv_s* p = (struct stream_priv_s*)opts;
-  int ret,ret2,f,track = 0;
-  char *filename = NULL, *colon = NULL;
-
-  if(mode != STREAM_READ || !p->filename) {
-    m_struct_free(&stream_opts,opts);
-    return STREAM_UNSUPORTED;
-  }
-  filename = strdup(p->filename);
-  if(!filename) {
-    m_struct_free(&stream_opts,opts);
-    return STREAM_UNSUPORTED;
-  }
-  colon = strstr(filename, ":");
-  if(colon) {
-    if(strlen(colon)>1)
-      track = atoi(colon+1);
-    *colon = 0;
-  }
-  if(!track)
-    track = 1;
-  
-  f = cue_read_cue(filename);
-  if(f < 0) {
-    m_struct_free(&stream_opts,opts);
-    return STREAM_UNSUPORTED;
-  }
-  cue_vcd_read_toc();
-  ret2=cue_vcd_get_track_end(track);
-  ret=cue_vcd_seek_to_track(track);
-  if(ret<0){ 
-    mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_ErrTrackSelect " (seek)\n");
-    return STREAM_UNSUPORTED;
-  }
-  mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_MPDEMUX_CUEREAD_CueStreamInfo_FilenameTrackTracksavail, filename, track, ret, ret2);
-
-  stream->fd = f;
-  stream->type = STREAMTYPE_VCDBINCUE;
-  stream->sector_size = VCD_SECTOR_DATA;
-  stream->flags = STREAM_READ | STREAM_SEEK_FW;
-  stream->start_pos = ret;
-  stream->end_pos = ret2;
-  stream->fill_buffer = cue_vcd_read;
-  stream->seek = seek;
-
-  free(filename);
-  m_struct_free(&stream_opts,opts);
-  return STREAM_OK;
-}
-
-stream_info_t stream_info_cue = {
-  "CUE track",
-  "cue",
-  "Albeu",
-  "based on the code from ???",
-  open_s,
-  { "cue", NULL },
-  &stream_opts,
-  1 // Urls are an option string
-};
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stream/stream_cue.c	Thu Aug 03 19:25:16 2006 +0000
@@ -0,0 +1,603 @@
+//=================== VideoCD BinCue ==========================
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+
+#include "stream.h"
+
+#include "help_mp.h"
+#include "m_option.h"
+#include "m_struct.h"
+
+#define byte    unsigned char
+#define SIZERAW 2352
+#define SIZEISO_MODE1 2048
+#define SIZEISO_MODE2_RAW 2352
+#define SIZEISO_MODE2_FORM1 2048
+#define SIZEISO_MODE2_FORM2 2336
+#define AUDIO 0
+#define MODE1 1
+#define MODE2 2
+#define MODE1_2352 10
+#define MODE2_2352 20
+#define MODE1_2048 30
+#define MODE2_2336 40
+#define UNKNOWN -1
+
+static struct stream_priv_s {
+  char* filename;
+} stream_priv_dflts = {
+  NULL
+};
+
+#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
+/// URL definition
+static m_option_t stream_opts_fields[] = {
+  { "string", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL},
+  { NULL, NULL, 0, 0, 0, 0,  NULL }
+};
+static struct m_struct_st stream_opts = {
+  "cue",
+  sizeof(struct stream_priv_s),
+  &stream_priv_dflts,
+  stream_opts_fields
+};
+
+static FILE* fd_cue;
+static int fd_bin = 0;
+
+static char bin_filename[256];
+
+static char cue_filename[256];
+static char bincue_path[256];
+
+
+typedef struct track
+{
+   unsigned short mode;
+   unsigned short minute;
+   unsigned short second;
+   unsigned short frame;
+
+   /* (min*60 + sec) * 75 + fps   */
+
+   unsigned long start_sector;
+
+   /* = the sizes in bytes off all tracks bevor this one */
+   /* its needed if there are mode1 tracks befor the mpeg tracks */
+   unsigned long start_offset;
+
+   /*   unsigned char num[3]; */
+} tTrack;
+
+/* max 99 tracks on a cd */
+static tTrack tracks[100];
+
+static struct cue_track_pos {
+  int track;
+  unsigned short mode;
+  unsigned short minute;
+  unsigned short second;
+  unsigned short frame;
+} cue_current_pos;
+
+/* number of tracks on the cd */
+static int nTracks = 0;
+
+/* presumes Line is preloaded with the "current" line of the file */
+static int cue_getTrackinfo(char *Line, tTrack *track)
+{
+  char inum[3];
+  char min;
+  char sec;
+  char fps;
+  int already_set = 0;
+
+  /* Get the 'mode' */
+  if (strncmp(&Line[2], "TRACK ", 6)==0)
+  {
+/*    strncpy(track->num, &Line[8], 2); track->num[2] = '\0'; */
+
+    track->mode = UNKNOWN;
+    if(strncmp(&Line[11], "AUDIO", 5)==0) track->mode = AUDIO;
+    if(strncmp(&Line[11], "MODE1/2352", 10)==0) track->mode = MODE1_2352;
+    if(strncmp(&Line[11], "MODE1/2048", 10)==0) track->mode = MODE1_2048;
+    if(strncmp(&Line[11], "MODE2/2352", 10)==0) track->mode = MODE2_2352;
+    if(strncmp(&Line[11], "MODE2/2336", 10)==0) track->mode = MODE2_2336;
+  }
+  else return(1);
+
+  /* Get the track indexes */
+  while(1) {
+    if(! fgets( Line, 256, fd_cue ) ) { break;}
+
+    if (strncmp(&Line[2], "TRACK ", 6)==0)
+    {
+      /* next track starting */
+      break;
+    }
+
+    /* Track 0 or 1, take the first an get fill the values*/
+    if (strncmp(&Line[4], "INDEX ", 6)==0)
+    {
+      /* check stuff here so if the answer is false the else stuff below won't be executed */
+      strncpy(inum, &Line[10], 2); inum[2] = '\0';
+      if ((already_set == 0) &&
+          ((strcmp(inum, "00")==0) || (strcmp(inum, "01")==0)))
+      {
+        already_set = 1;
+
+        min = ((Line[13]-'0')<<4) | (Line[14]-'0');
+        sec = ((Line[16]-'0')<<4) | (Line[17]-'0');
+        fps = ((Line[19]-'0')<<4) | (Line[20]-'0');
+
+        track->minute = (((min>>4)*10) + (min&0xf));
+        track->second = (((sec>>4)*10) + (sec&0xf));
+        track->frame  = (((fps>>4)*10) + (fps&0xf));
+      }
+    }
+    else if (strncmp(&Line[4], "PREGAP ", 7)==0) { ; /* ignore */ }
+    else if (strncmp(&Line[4], "FLAGS ", 6)==0)  { ; /* ignore */ }
+    else mp_msg (MSGT_OPEN,MSGL_INFO,
+                 MSGTR_MPDEMUX_CUEREAD_UnexpectedCuefileLine, Line);
+  }
+  return(0);
+}
+
+
+
+/* FIXME: the string operations ( strcpy,strcat ) below depend
+ * on the arrays to have the same size, thus we need to make
+ * sure the sizes are in sync.
+ */
+static int cue_find_bin (char *firstline) {
+  int i,j;
+  char s[256];
+  char t[256];
+
+  /* get the filename out of that */
+  /*                      12345 6  */
+  mp_msg (MSGT_OPEN,MSGL_INFO, "[bincue] cue_find_bin(%s)\n", firstline);
+  if (strncmp(firstline, "FILE \"",6)==0)
+  {
+    i = 0;
+    j = 0;
+    while ( firstline[6 + i] != '"')
+    {
+      bin_filename[j] = firstline[6 + i];
+
+      /* if I found a path info, than delete all bevor it */
+      switch (bin_filename[j])
+      {
+        case '\\':
+          j = 0;
+          break;
+
+        case '/':
+          j = 0;
+          break;
+
+        default:
+          j++;
+      }
+      i++;
+    }
+    bin_filename[j+1] = '\0';
+
+  }
+
+  /* now try to open that file, without path */
+  fd_bin = open (bin_filename, O_RDONLY);
+  if (fd_bin == -1)
+  {
+    mp_msg(MSGT_OPEN,MSGL_STATUS, MSGTR_MPDEMUX_CUEREAD_BinFilenameTested,
+           bin_filename);
+
+    /* now try to find it with the path of the cue file */
+    snprintf(s,sizeof( s ),"%s/%s",bincue_path,bin_filename);
+    fd_bin = open (s, O_RDONLY);
+    if (fd_bin == -1)
+    {
+      mp_msg(MSGT_OPEN,MSGL_STATUS,
+             MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);
+      /* now I would say the whole filename is shit, build our own */
+      strncpy(s, cue_filename, strlen(cue_filename) - 3 );
+      s[strlen(cue_filename) - 3] = '\0';
+      strcat(s, "bin");
+      fd_bin = open (s, O_RDONLY);
+      if (fd_bin == -1)
+      {
+        mp_msg(MSGT_OPEN,MSGL_STATUS,
+               MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);
+
+        /* ok try it with path */
+        snprintf(t, sizeof( t ), "%s/%s", bincue_path, s);
+        fd_bin = open (t, O_RDONLY);
+        if (fd_bin == -1)
+        {
+          mp_msg(MSGT_OPEN,MSGL_STATUS,
+                 MSGTR_MPDEMUX_CUEREAD_BinFilenameTested,t);
+          /* now I would say the whole filename is shit, build our own */
+          strncpy(s, cue_filename, strlen(cue_filename) - 3 );
+          s[strlen(cue_filename) - 3] = '\0';
+          strcat(s, "img");
+          fd_bin = open (s, O_RDONLY);
+          if (fd_bin == -1)
+          {
+            mp_msg(MSGT_OPEN,MSGL_STATUS,
+                   MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);
+            /* ok try it with path */
+            snprintf(t, sizeof( t ), "%s/%s", bincue_path, s);
+            fd_bin = open (t, O_RDONLY);
+            if (fd_bin == -1)
+            {
+              mp_msg(MSGT_OPEN,MSGL_STATUS,
+                     MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);
+
+              /* I'll give up */
+              mp_msg(MSGT_OPEN,MSGL_ERR,
+                     MSGTR_MPDEMUX_CUEREAD_CannotFindBinFile);
+              return -1;
+            }
+          }
+        } else strcpy(bin_filename, t);
+
+      } else strcpy(bin_filename, s);
+
+    } else strcpy(bin_filename, s);
+
+  }
+
+  mp_msg(MSGT_OPEN,MSGL_INFO,
+         MSGTR_MPDEMUX_CUEREAD_UsingBinFile, bin_filename);
+  return 0;
+}
+
+static inline int cue_msf_2_sector(int minute, int second, int frame) {
+ return frame + (second + minute * 60 ) * 75;
+}
+
+static inline int cue_get_msf(void) {
+  return cue_msf_2_sector (cue_current_pos.minute,
+                           cue_current_pos.second,
+                           cue_current_pos.frame);
+}
+
+static inline void cue_set_msf(unsigned int sect){
+  cue_current_pos.frame=sect%75;
+  sect=sect/75;
+  cue_current_pos.second=sect%60;
+  sect=sect/60;
+  cue_current_pos.minute=sect;
+}
+
+static inline int cue_mode_2_sector_size(int mode)
+{
+  switch (mode)
+  {
+    case AUDIO:      return AUDIO;
+    case MODE1_2352: return SIZERAW;
+    case MODE1_2048: return SIZEISO_MODE1;
+    case MODE2_2352: return SIZEISO_MODE2_RAW;
+    case MODE2_2336: return SIZEISO_MODE2_FORM2;
+
+    default:
+      mp_msg(MSGT_OPEN,MSGL_FATAL,
+             MSGTR_MPDEMUX_CUEREAD_UnknownModeForBinfile);
+      abort();
+  }
+
+}
+
+
+static int cue_read_cue (char *in_cue_filename)
+{
+  struct stat filestat;
+  char sLine[256];
+  unsigned int sect;
+  char *s,*t;
+  int i;
+
+  /* we have no tracks at the beginning */
+  nTracks = 0;
+
+  fd_bin = 0;
+
+  /* split the filename into a path and filename part */
+  s = strdup(in_cue_filename);
+  t = strrchr(s, '/');
+  if (t == (char *)NULL)
+     t = ".";
+  else {
+     *t = '\0';
+     t = s;
+     if (*t == '\0')
+       strcpy(t, "/");
+  }
+  
+  strlcpy(bincue_path,t,sizeof( bincue_path ));
+  mp_msg(MSGT_OPEN,MSGL_V,"dirname: %s, cuepath: %s\n", t, bincue_path);
+
+  /* no path at all? */
+  if (strcmp(bincue_path, ".") == 0) {
+    mp_msg(MSGT_OPEN,MSGL_V,"bincue_path: %s\n", bincue_path);
+    strlcpy(cue_filename,in_cue_filename,sizeof( cue_filename ));
+  } else {
+    strlcpy(cue_filename,in_cue_filename + strlen(bincue_path) + 1,
+            sizeof( cue_filename ));
+  }
+
+
+
+  /* open the cue file */
+  fd_cue = fopen (in_cue_filename, "r");
+  if (fd_cue == NULL)
+  {
+    mp_msg(MSGT_OPEN,MSGL_ERR,
+           MSGTR_MPDEMUX_CUEREAD_CannotOpenCueFile, in_cue_filename);
+    return -1;
+  }
+
+  /* read the first line and hand it to find_bin, which will
+     test more than one possible name of the file */
+
+  if(! fgets( sLine, 256, fd_cue ) )
+  {
+    mp_msg(MSGT_OPEN,MSGL_ERR,
+           MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);
+    fclose (fd_cue);
+    return -1;
+  }
+
+  if (cue_find_bin(sLine)) {
+    fclose (fd_cue);
+    return -1;
+  }
+
+
+  /* now build the track list */
+  /* red the next line and call our track finder */
+  if(! fgets( sLine, 256, fd_cue ) )
+  {
+    mp_msg(MSGT_OPEN,MSGL_ERR,
+           MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);
+    fclose (fd_cue);
+    return -1;
+  }
+
+  while(!feof(fd_cue))
+  {
+    if (cue_getTrackinfo(sLine, &tracks[nTracks++]) != 0)
+    {
+      mp_msg(MSGT_OPEN,MSGL_ERR,
+             MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);
+      fclose (fd_cue);
+      return -1;
+    }
+  }
+
+  /* make a fake track with stands for the Lead out */
+  if (fstat (fd_bin, &filestat) == -1) {
+    mp_msg(MSGT_OPEN,MSGL_ERR,
+           MSGTR_MPDEMUX_CUEREAD_ErrGettingBinFileSize);
+    fclose (fd_cue);
+    return -1;
+  }
+
+  sect = filestat.st_size / 2352;
+
+  tracks[nTracks].frame = sect%75;
+  sect=sect/75;
+  tracks[nTracks].second = sect%60;
+  sect=sect/60;
+  tracks[nTracks].minute = sect;
+
+
+  /* let's calculate the start sectors and offsets */
+  for(i = 0; i <= nTracks; i++)
+  {
+    tracks[i].start_sector = cue_msf_2_sector(tracks[i].minute,
+                                              tracks[nTracks].second,
+                                              tracks[nTracks].frame);
+
+    /* if we're the first track we don't need to offset of the one befor */
+    if (i == 0)
+    {
+      /* was always 0 on my svcds, but who knows */
+      tracks[0].start_offset = tracks[0].start_sector *
+        cue_mode_2_sector_size(tracks[0].mode);
+    } else
+    {
+      tracks[i].start_offset = tracks[i-1].start_offset +
+        (tracks[i].start_sector - tracks[i-1].start_sector) *
+        cue_mode_2_sector_size(tracks[i-1].mode);
+    }
+  }
+
+  fclose (fd_cue);
+
+  return fd_bin;
+}
+
+
+
+
+static int cue_read_toc_entry(void) {
+
+  int track = cue_current_pos.track - 1;
+
+  /* check if its a valid track, if not return -1 */
+  if (track >= nTracks)
+    return -1;
+
+
+  switch (tracks[track].mode)
+  {
+    case AUDIO:
+      cue_current_pos.mode = AUDIO;
+      break;
+    case MODE1_2352:
+      cue_current_pos.mode = MODE1;
+      break;
+    case MODE1_2048:
+      cue_current_pos.mode = MODE1;
+      break;
+    default: /* MODE2_2352 and MODE2_2336 */
+      cue_current_pos.mode = MODE2;
+  }
+  cue_current_pos.minute = tracks[track].minute;
+  cue_current_pos.second = tracks[track].second;
+  cue_current_pos.frame = tracks[track].frame;
+
+  return 0;
+}
+
+static int cue_vcd_seek_to_track (int track){
+  cue_current_pos.track  = track;
+
+  if (cue_read_toc_entry ())
+    return -1;
+
+  return VCD_SECTOR_DATA * cue_get_msf();
+}
+
+static int cue_vcd_get_track_end (int track){
+  cue_current_pos.frame = tracks[track].frame;
+  cue_current_pos.second = tracks[track].second;
+  cue_current_pos.minute = tracks[track].minute;
+
+  return VCD_SECTOR_DATA * cue_get_msf();
+}
+
+static void cue_vcd_read_toc(void){
+  int i;
+  for (i = 0; i < nTracks; ++i) {
+
+    mp_msg(MSGT_OPEN,MSGL_INFO,
+           MSGTR_MPDEMUX_CUEREAD_InfoTrackFormat,
+           i+1,
+           tracks[i].mode,
+           tracks[i].minute,
+           tracks[i].second,
+           tracks[i].frame
+           );
+  }
+}
+
+static int cue_vcd_read(stream_t *stream, char *mem, int size) {
+  unsigned long position;
+  int track = cue_current_pos.track - 1;
+
+  position = tracks[track].start_offset +
+             (cue_msf_2_sector(cue_current_pos.minute,
+                               cue_current_pos.second,
+                               cue_current_pos.frame) -
+              tracks[track].start_sector)
+             * cue_mode_2_sector_size(tracks[track].mode);
+
+  
+  if(position >= tracks[track+1].start_offset)
+    return 0;
+
+  if(lseek(fd_bin, position+VCD_SECTOR_OFFS, SEEK_SET) == -1) {
+    mp_msg(MSGT_OPEN,MSGL_ERR, MSGTR_MPDEMUX_CUEREAD_UnexpectedBinFileEOF);
+    return 0;
+  }
+
+  if(read(fd_bin, mem, VCD_SECTOR_DATA) != VCD_SECTOR_DATA) {
+    mp_msg(MSGT_OPEN,MSGL_ERR, MSGTR_MPDEMUX_CUEREAD_CannotReadNBytesOfPayload, VCD_SECTOR_DATA);
+    return 0;
+  }
+
+  cue_current_pos.frame++;
+  if (cue_current_pos.frame==75){
+    cue_current_pos.frame=0;
+    cue_current_pos.second++;
+    if (cue_current_pos.second==60){
+      cue_current_pos.second=0;
+      cue_current_pos.minute++;
+    }
+  }
+
+  return VCD_SECTOR_DATA;
+}
+
+static int seek(stream_t *s,off_t newpos) {
+  s->pos=newpos;
+  cue_set_msf(s->pos/VCD_SECTOR_DATA);
+  return 1;
+}
+
+
+static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
+  struct stream_priv_s* p = (struct stream_priv_s*)opts;
+  int ret,ret2,f,track = 0;
+  char *filename = NULL, *colon = NULL;
+
+  if(mode != STREAM_READ || !p->filename) {
+    m_struct_free(&stream_opts,opts);
+    return STREAM_UNSUPORTED;
+  }
+  filename = strdup(p->filename);
+  if(!filename) {
+    m_struct_free(&stream_opts,opts);
+    return STREAM_UNSUPORTED;
+  }
+  colon = strstr(filename, ":");
+  if(colon) {
+    if(strlen(colon)>1)
+      track = atoi(colon+1);
+    *colon = 0;
+  }
+  if(!track)
+    track = 1;
+  
+  f = cue_read_cue(filename);
+  if(f < 0) {
+    m_struct_free(&stream_opts,opts);
+    return STREAM_UNSUPORTED;
+  }
+  cue_vcd_read_toc();
+  ret2=cue_vcd_get_track_end(track);
+  ret=cue_vcd_seek_to_track(track);
+  if(ret<0){ 
+    mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_ErrTrackSelect " (seek)\n");
+    return STREAM_UNSUPORTED;
+  }
+  mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_MPDEMUX_CUEREAD_CueStreamInfo_FilenameTrackTracksavail, filename, track, ret, ret2);
+
+  stream->fd = f;
+  stream->type = STREAMTYPE_VCDBINCUE;
+  stream->sector_size = VCD_SECTOR_DATA;
+  stream->flags = STREAM_READ | STREAM_SEEK_FW;
+  stream->start_pos = ret;
+  stream->end_pos = ret2;
+  stream->fill_buffer = cue_vcd_read;
+  stream->seek = seek;
+
+  free(filename);
+  m_struct_free(&stream_opts,opts);
+  return STREAM_OK;
+}
+
+stream_info_t stream_info_cue = {
+  "CUE track",
+  "cue",
+  "Albeu",
+  "based on the code from ???",
+  open_s,
+  { "cue", NULL },
+  &stream_opts,
+  1 // Urls are an option string
+};
+