[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