]> git.sesse.net Git - vlc/blobdiff - modules/demux/gme.c
Splitted dv audio helpers into rawdv.h
[vlc] / modules / demux / gme.c
index 5d6d214a1bac343cf5ee444c58535fcc8777e72c..a389f9e42bbe040db8675ab0ae2bd994d4096df9 100644 (file)
@@ -64,15 +64,15 @@ struct demux_sys_t
 
 static int Demux (demux_t *);
 static int Control (demux_t *, int, va_list);
-static gme_err_t Reader (void *, void *, int);
+static gme_err_t ReaderStream (void *, void *, int);
+static gme_err_t ReaderBlock (void *, void *, int);
 
 static int Open (vlc_object_t *obj)
 {
     demux_t *demux = (demux_t *)obj;
 
     int64_t size = stream_Size (demux->s);
-    if (size < 4 /* GME needs to know the file size */
-     || size > LONG_MAX /* too big for GME */)
+    if (size > LONG_MAX /* too big for GME */)
         return VLC_EGENERIC;
 
     /* Auto detection */
@@ -85,6 +85,14 @@ static int Open (vlc_object_t *obj)
         return VLC_EGENERIC;
     msg_Dbg (obj, "detected file type %s", type);
 
+    block_t *data = NULL;
+    if (size <= 0)
+    {
+        data = stream_BlockRemaining (demux->s, 100000000);
+        if (!data )
+            return VLC_EGENERIC;
+    }
+
     /* Initialization */
     demux_sys_t *sys = malloc (sizeof (*sys));
     if (unlikely(sys == NULL))
@@ -96,7 +104,15 @@ static int Open (vlc_object_t *obj)
         free (sys);
         return VLC_ENOMEM;
     }
-    gme_load_custom (sys->emu, Reader, size, demux->s);
+    if (data)
+    {
+        gme_load_custom (sys->emu, ReaderBlock, data->i_buffer, data);
+        block_Release(data);
+    }
+    else
+    {
+        gme_load_custom (sys->emu, ReaderStream, size, demux->s);
+    }
     gme_start_track (sys->emu, sys->track_id = 0);
 
     es_format_t fmt;
@@ -158,7 +174,7 @@ static void Close (vlc_object_t *obj)
 }
 
 
-static gme_err_t Reader (void *data, void *buf, int length)
+static gme_err_t ReaderStream (void *data, void *buf, int length)
 {
     stream_t *s = data;
 
@@ -166,7 +182,18 @@ static gme_err_t Reader (void *data, void *buf, int length)
         return "short read";
     return NULL;
 }
+static gme_err_t ReaderBlock (void *data, void *buf, int length)
+{
+    block_t *block = data;
 
+    int max = __MIN (length, (int)block->i_buffer);
+    memcpy (buf, block->p_buffer, max);
+    block->i_buffer -= max;
+    block->p_buffer += max;
+    if (max != length)
+        return "short read";
+    return NULL;
+}
 
 #define SAMPLES (RATE / 10)
 
@@ -235,7 +262,7 @@ static int Control (demux_t *demux, int query, va_list args)
                 break;
 
             int seek = (sys->titlev[sys->track_id]->i_length / 1000) * pos;
-            if (seek > INT_MAX || gme_seek (sys->emu, seek))
+            if (gme_seek (sys->emu, seek))
                 break;
             return VLC_SUCCESS;
         }
@@ -275,7 +302,7 @@ static int Control (demux_t *demux, int query, va_list args)
 
             unsigned n = sys->titlec;
             *titlev = malloc (sizeof (**titlev) * n);
-            if (unlikely(titlev == NULL))
+            if (unlikely(*titlev == NULL))
                 n = 0;
             *titlec = n;
             for (unsigned i = 0; i < n; i++)