vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Mon Mar 30 22:39:47 2015 +0300| [b67f295520b479d0ead21d11fb8c9aea74902f77] | committer: Rémi Denis-Courmont
libvlc: add libvlc_media_new_callbacks() for custom input media (fixes #8562) > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b67f295520b479d0ead21d11fb8c9aea74902f77 --- include/vlc/libvlc_media.h | 91 ++++++++++++++++++++++++++++++++++++++++++++ lib/libvlc.sym | 1 + lib/media.c | 20 ++++++++++ 3 files changed, 112 insertions(+) diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h index 18cb500..9b16526 100644 --- a/include/vlc/libvlc_media.h +++ b/include/vlc/libvlc_media.h @@ -270,6 +270,64 @@ typedef enum libvlc_media_parse_flag_t } libvlc_media_parse_flag_t; /** + * Callback prototype to open a custom bitstream input media. + * + * The same media item can be opened multiple times. Each time, this callback + * is invoked. It should allocate and initialize any instance-specific + * resources, then store them in *datap. The instance resources can be freed + * in the @ref libvlc_close_cb callback. + * + * \param opaque private pointer as passed to libvlc_media_new_callbacks() + * \param datap storage space for a private data pointer [OUT] + * \param sizep byte length of the bitstream or 0 if unknown [OUT] + * + * \note For convenience, *datap is initially NULL and *sizep is initially 0. + * + * \return 0 on success, non-zero on error. In case of failure, the other + * callbacks will not be invoked and any value stored in *datap and *sizep is + * discarded. + */ +typedef int (*libvlc_media_open_cb)(void *opaque, void **datap, + uint64_t *sizep); + +/** + * Callback prototype to read data from a custom bitstream input media. + * + * \param opaque private pointer as set by the @ref libvlc_media_open_cb + * callback + * \param buf start address of the buffer to read data into + * \param len bytes length of the buffer + * + * \return strictly positive number of bytes read, 0 on end-of-stream, + * or -1 on non-recoverable error + * + * \note If no data is immediately available, then the callback should sleep. + * \warning The application is responsible for avoiding deadlock situations. + * In particular, the callback should return an error if playback is stopped; + * if it does not return, then libvlc_media_player_stop() will never return. + */ +typedef ssize_t (*libvlc_media_read_cb)(void *opaque, unsigned char *buf, + size_t len); + +/** + * Callback prototype to seek a custom bitstream input media. + * + * \param opaque private pointer as set by the @ref libvlc_media_open_cb + * callback + * \param offset absolute byte offset to seek to + * \return 0 on success, -1 on error. + */ +typedef int (*libvlc_media_seek_cb)(void *opaque, uint64_t offset); + +/** + * Callback prototype to close a custom bitstream input media. + * + * \param opaque private pointer as set by the @ref libvlc_media_open_cb + * callback + */ +typedef void (*libvlc_media_close_cb)(void *opaque); + +/** * Create a media with a certain given media resource location, * for instance a valid URL. * @@ -329,6 +387,39 @@ LIBVLC_API libvlc_media_t *libvlc_media_new_fd( libvlc_instance_t *p_instance, int fd ); +/** + * Create a media with custom callbacks to read the data from. + * + * \param instance LibVLC instance + * \param open_cb callback to open the custom bitstream input media + * \param read_cb callback to read data (must not be NULL) + * \param seek_cb callback to seek, or NULL if seeking is not supported + * \param close_cb callback to close the media, or NULL if unnecessary + * \param opaque data pointer for the open callback + * + * \return the newly created media or NULL on error + * + * \note If open_cb is NULL, the opaque pointer will be passed to read_cb, + * seek_cb and close_cb, and the stream size will be treated as unknown. + * + * \note The callbacks may be called asynchronously (from another thread). + * A single stream instance need not be reentrant. However the open_cb needs to + * be reentrant if the media is used by multiple player instances. + * + * \warning The callbacks may be used until all or any player instances + * that were supplied the media item are stopped. + * + * \see libvlc_media_release + * + * \version LibVLC 3.0.0 and later. + */ +LIBVLC_API libvlc_media_t *libvlc_media_new_callbacks( + libvlc_instance_t *instance, + libvlc_media_open_cb open_cb, + libvlc_media_read_cb read_cb, + libvlc_media_seek_cb seek_cb, + libvlc_media_close_cb close_cb, + void *opaque ); /** * Create a media as an empty node with a given name. diff --git a/lib/libvlc.sym b/lib/libvlc.sym index 1e241e7..c0c206f 100644 --- a/lib/libvlc.sym +++ b/lib/libvlc.sym @@ -131,6 +131,7 @@ libvlc_media_list_remove_index libvlc_media_list_retain libvlc_media_list_set_media libvlc_media_list_unlock +libvlc_media_new_callbacks libvlc_media_new_fd libvlc_media_new_location libvlc_media_new_path diff --git a/lib/media.c b/lib/media.c index 1d01c11..f5886ad 100644 --- a/lib/media.c +++ b/lib/media.c @@ -426,6 +426,26 @@ libvlc_media_t *libvlc_media_new_fd( libvlc_instance_t *p_instance, int fd ) return libvlc_media_new_location( p_instance, mrl ); } +libvlc_media_t *libvlc_media_new_callbacks(libvlc_instance_t *p_instance, + libvlc_media_open_cb open_cb, + libvlc_media_read_cb read_cb, + libvlc_media_seek_cb seek_cb, + libvlc_media_close_cb close_cb, + void *opaque) +{ + libvlc_media_t *m = libvlc_media_new_location(p_instance, "imem://"); + if (unlikely(m == NULL)) + return NULL; + + assert(read_cb != NULL); + input_item_AddOpaque(m->p_input_item, "imem-data", opaque); + input_item_AddOpaque(m->p_input_item, "imem-open", open_cb); + input_item_AddOpaque(m->p_input_item, "imem-read", read_cb); + input_item_AddOpaque(m->p_input_item, "imem-seek", seek_cb); + input_item_AddOpaque(m->p_input_item, "imem-close", close_cb); + return m; +} + /************************************************************************** * Create a new media descriptor object **************************************************************************/ _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
