[vlc-devel] [PATCH] lib: New API to use imem for access.

Mark Lee mark.lee at capricasoftware.co.uk
Wed Jan 15 16:53:55 CET 2014


---
 include/vlc/libvlc_media_player.h | 68 +++++++++++++++++++++++++++++++
 lib/libvlc.sym                    |  1 +
 lib/media_player.c                | 38 ++++++++++++++++++
 modules/access/imem.c             | 84 +++++++++++++++++++++++++++++----------
 4 files changed, 171 insertions(+), 20 deletions(-)

diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index 27f7b97..37b3c2b 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -635,6 +635,74 @@ LIBVLC_API
 void libvlc_audio_set_format( libvlc_media_player_t *mp, const char *format,
                               unsigned rate, unsigned channels );
 
+/**
+ * Callback prototype to open media for memory access (imem).
+ *
+ * \param data opaque pointer
+ * \param cookie text identifier
+ * \param location optional location for the media (from the parsed imem MRL)
+ * \return zero on success, non-zero on error
+ */
+typedef int (*libvlc_memory_open_cb)(void *data, const char *cookie, const char *location);
+
+/**
+ * Callback prototype to close media for memory access (imem).
+ *
+ * \param data opaque pointer
+ * \param cookie text identifier
+ */
+typedef void (*libvlc_memory_close_cb)(void *data, const char *cookie);
+
+/**
+ * Callback prototype to read media data for memory access (imem).
+ *
+ * \param data opaque pointer
+ * \param cookie text identifier
+ * \param buffer_size size of the filled data buffer
+ * \param buffer pointer to the filled data buffer
+ * \return zero on success, non-zero on error (or EOF)
+ */
+typedef int (*libvlc_memory_read_cb)(void *data, const char *cookie, size_t *buffer_size, void **buffer);
+
+/**
+ * Callback prototype to seek within media for memory access (imem).
+ *
+ * FIXME seeking is not currently supported by imem.
+ *
+ * \param data opaque pointer
+ * \param cookie text identifier
+ * \param offset offset within the buffer to seek to
+ * \return zero on success, non-zero on error
+ */
+typedef int (*libvlc_memory_seek_cb)(void *data, const char *cookie, uint64_t offset);
+
+/**
+ * Setup memory access callbacks (imem).
+ *
+ * This is used to provide 'raw' media data from an in-memory buffer (e.g.
+ * reading a stream into a buffer).
+ *
+ * The 'data' and 'cookie' parameters can contain optional application-specific
+ * values.
+ *
+ * \param mp the media player
+ * \param open callback function to open the media, or NULL
+ * \param close callback function to close the media, or NULL
+ * \param read callback function to read data (must not be NULL)
+ * \param seek callback function to seek within the data, or NULL
+ * \param data opaque pointer
+ * \param cookie text identifier
+ * \return zero on success, non-zero on error
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API
+int libvlc_memory_set_access_callbacks( libvlc_media_player_t *mp,
+                                        libvlc_memory_open_cb open,
+                                        libvlc_memory_close_cb close,
+                                        libvlc_memory_read_cb read,
+                                        libvlc_memory_seek_cb seek,
+                                        void *data, const char *cookie );
+
 /** \bug This might go away ... to be replaced by a broader system */
 
 /**
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 7c99668..edf560c 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -186,6 +186,7 @@ libvlc_media_set_user_data
 libvlc_media_subitems
 libvlc_media_tracks_get
 libvlc_media_tracks_release
+libvlc_memory_set_access_callbacks
 libvlc_new
 libvlc_playlist_play
 libvlc_release
diff --git a/lib/media_player.c b/lib/media_player.c
index c23dd42..5b975e5 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -458,6 +458,15 @@ libvlc_media_player_new( libvlc_instance_t *instance )
     var_Create (mp, "amem-rate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
     var_Create (mp, "amem-channels", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
 
+    /* Memory */
+    var_Create (mp, "imem-open", VLC_VAR_ADDRESS);
+    var_Create (mp, "imem-close", VLC_VAR_ADDRESS);
+    var_Create (mp, "imem-read", VLC_VAR_ADDRESS);
+    var_Create (mp, "imem-seek", VLC_VAR_ADDRESS);
+    var_Create (mp, "imem-data", VLC_VAR_STRING);
+    var_Create (mp, "imem-cookie", VLC_VAR_STRING);
+    var_Create (mp, "imem-cat", VLC_VAR_INTEGER);
+
     /* Video Title */
     var_Create (mp, "video-title-show", VLC_VAR_BOOL);
     var_Create (mp, "video-title-position", VLC_VAR_INTEGER);
@@ -981,6 +990,35 @@ void libvlc_audio_set_format( libvlc_media_player_t *mp, const char *format,
     var_SetInteger( mp, "amem-channels", channels );
 }
 
+int libvlc_memory_set_access_callbacks( libvlc_media_player_t *mp,
+                                        libvlc_memory_open_cb open,
+                                        libvlc_memory_close_cb close,
+                                        libvlc_memory_read_cb read,
+                                        libvlc_memory_seek_cb seek,
+                                        void *data, const char *cookie)
+{
+    if (!read)
+        return -1;
+
+    var_SetAddress( mp, "imem-open", open );
+    var_SetAddress( mp, "imem-close", close );
+    var_SetAddress( mp, "imem-read", read );
+    var_SetAddress( mp, "imem-seek", seek );
+
+    char *buf;
+    if ( asprintf( &buf, "%p", data ) == -1 )
+        return -1;
+
+    var_SetString( mp, "imem-data", buf );
+    free( buf );
+
+    var_SetString( mp, "imem-cookie", cookie );
+
+    // Category 4 means "access"
+    var_SetInteger( mp, "imem-cat", 4 );
+
+    return 0;
+}
 
 /**************************************************************************
  * Getters for stream information
diff --git a/modules/access/imem.c b/modules/access/imem.c
index 5b4b056..2a50521 100644
--- a/modules/access/imem.c
+++ b/modules/access/imem.c
@@ -195,6 +195,11 @@ typedef int  (*imem_get_t)(void *data, const char *cookie,
                            size_t *, void **);
 typedef void (*imem_release_t)(void *data, const char *cookie, size_t, void *);
 
+typedef int (*imem_open_t)(void *data, const char *cookie, const char *location);
+typedef void (*imem_close_t)(void *data, const char *cookie);
+typedef int (*imem_read_t)(void *data, const char *cookie, size_t *buffer_size, void **buffer);
+typedef int (*imem_seek_t)(void *data, const char *cookie, uint64_t offset);
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -211,6 +216,10 @@ typedef struct {
     struct {
         imem_get_t      get;
         imem_release_t  release;
+        imem_open_t     open;
+        imem_close_t    close;
+        imem_read_t     read;
+        imem_seek_t     seek;
         void           *data;
         char           *cookie;
     } source;
@@ -246,20 +255,28 @@ static int OpenCommon(vlc_object_t *object, imem_sys_t **sys_ptr, const char *ps
         return VLC_ENOMEM;
 
     /* Read the user functions */
-    tmp = var_InheritString(object, "imem-get");
-    if (tmp)
-        sys->source.get = (imem_get_t)(intptr_t)strtoll(tmp, NULL, 0);
-    free(tmp);
+    sys->source.open = var_InheritAddress(object, "imem-open");
+    sys->source.close = var_InheritAddress(object, "imem-close");
+    sys->source.read = var_InheritAddress(object, "imem-read");
+    sys->source.seek = var_InheritAddress(object, "imem-seek");
 
-    tmp = var_InheritString(object, "imem-release");
-    if (tmp)
-        sys->source.release = (imem_release_t)(intptr_t)strtoll(tmp, NULL, 0);
-    free(tmp);
-
-    if (!sys->source.get || !sys->source.release) {
-        msg_Err(object, "Invalid get/release function pointers");
-        free(sys);
-        return VLC_EGENERIC;
+    if (!sys->source.read)
+    {
+        tmp = var_InheritString(object, "imem-get");
+        if (tmp)
+            sys->source.get = (imem_get_t)(intptr_t)strtoll(tmp, NULL, 0);
+        free(tmp);
+
+        tmp = var_InheritString(object, "imem-release");
+        if (tmp)
+            sys->source.release = (imem_release_t)(intptr_t)strtoll(tmp, NULL, 0);
+        free(tmp);
+
+        if (!sys->source.get || !sys->source.release) {
+            msg_Err(object, "Invalid get/release function pointers");
+            free(sys);
+            return VLC_EGENERIC;
+        }
     }
 
     tmp = var_InheritString(object, "imem-data");
@@ -274,9 +291,15 @@ static int OpenCommon(vlc_object_t *object, imem_sys_t **sys_ptr, const char *ps
 
     sys->source.cookie = var_InheritString(object, "imem-cookie");
 
-    msg_Dbg(object, "Using get(%p), release(%p), data(%p), cookie(%s)",
-            sys->source.get, sys->source.release, sys->source.data,
-            sys->source.cookie ? sys->source.cookie : "(null)");
+    if (!sys->source.read)
+        msg_Dbg(object, "Using get(%p), release(%p), data(%p), cookie(%s)",
+                sys->source.get, sys->source.release, sys->source.data,
+                sys->source.cookie ? sys->source.cookie : "(null)");
+    else
+        msg_Dbg(object, "Using open(%p), close(%p), read(%p), seek(%p), data(%p), cookie(%s)",
+                sys->source.open, sys->source.close, sys->source.read,
+                sys->source.seek, sys->source.data,
+                sys->source.cookie ? sys->source.cookie : "(null)");
 
     /* */
     sys->dts       = 0;
@@ -310,6 +333,13 @@ static int OpenAccess(vlc_object_t *object)
     access->pf_seek    = NULL;
     access->p_sys      = (access_sys_t*)sys;
 
+    if (sys->source.open)
+        if (sys->source.open(sys->source.data, sys->source.cookie, access->psz_location))
+        {
+            CloseCommon(sys);
+            return VLC_EGENERIC;
+        }
+
     return VLC_SUCCESS;
 }
 
@@ -320,6 +350,10 @@ static void CloseAccess(vlc_object_t *object)
 {
     access_t *access = (access_t *)object;
 
+    imem_sys_t* sys = access->p_sys;
+    if (sys->source.close)
+        sys->source.close(sys->source.data, sys->source.cookie);
+
     CloseCommon((imem_sys_t*)access->p_sys);
 }
 
@@ -373,8 +407,17 @@ static block_t *Block(access_t *access)
     size_t buffer_size;
     void   *buffer;
 
-    if (sys->source.get(sys->source.data, sys->source.cookie,
-                        NULL, NULL, &flags, &buffer_size, &buffer)) {
+    imem_read_t read = sys->source.read;
+    if (read)
+    {
+        if (read(sys->source.data, sys->source.cookie, &buffer_size, &buffer))
+        {
+            access->info.b_eof = true;
+            return NULL;
+        }
+    }
+    else if (sys->source.get(sys->source.data, sys->source.cookie,
+                             NULL, NULL, &flags, &buffer_size, &buffer)) {
         access->info.b_eof = true;
         return NULL;
     }
@@ -386,8 +429,9 @@ static block_t *Block(access_t *access)
             memcpy(block->p_buffer, buffer, buffer_size);
     }
 
-    sys->source.release(sys->source.data, sys->source.cookie,
-                        buffer_size, buffer);
+    if (!read)
+        sys->source.release(sys->source.data, sys->source.cookie,
+                            buffer_size, buffer);
     return block;
 }
 
-- 
1.8.1.2




More information about the vlc-devel mailing list