So here is a patch that I'm using for my build of libVLC. Now, if you leave the unlock callback as NULL it takes this as meaning you're not going to be supplying a buffer and the internal buffer should be passed directly to the display callback.
Essentially, before:
- i allocate a buffer in setup callback
- between lock and unlock i don't touch it, because libVLC is copying from its buffer into it
- in display i copy it to the texture and render
- in cleanup i free the buffer
After:
- in display i copy the internal buffer to the texture and render
- no need for a lock, unlock or cleanup function. Setup just makes any changes to chroma, size etc that i require.
From your comments above you probably don't agree with this change to the API and that's totally fine, but I'm sharing it just in case. Or maybe someone else would find it useful. One thing I couldn't figure out was what to change to enable "npapi" to build on Windows when you run make package-win32-zip. At the moment with this patch it fails due to the change in the display callback signature.
Code: Select all
From bd649e5ba8040b9da8eb9f3ac445a52d994aabac Mon Sep 17 00:00:00 2001
From: Oliver Collyer <ovcollyer@mac.com>
Date: Wed, 26 Oct 2016 07:39:38 +0300
Subject: [PATCH 1/1] Optionally pass decode buffer to display cb
callback instead of copying
---
include/vlc/libvlc_media_player.h | 3 ++-
lib/media_player.c | 2 +-
modules/video_output/vmem.c | 29 ++++++++++++++++++++++-------
3 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index 9a73b4f..f469e98 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -323,7 +323,8 @@ typedef void (*libvlc_video_unlock_cb)(void *opaque, void *picture,
* \param picture private pointer returned from the @ref libvlc_video_lock_cb
* callback [IN]
*/
-typedef void (*libvlc_video_display_cb)(void *opaque, void *picture);
+typedef void (*libvlc_video_display_cb)(void *opaque, void *picture,
+ void *const *planes);
/**
* Callback prototype to configure picture buffers format.
diff --git a/lib/media_player.c b/lib/media_player.c
index db08274..29fa43c 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -1073,7 +1073,7 @@ int libvlc_media_player_set_renderer( libvlc_media_player_t *p_mi,
void libvlc_video_set_callbacks( libvlc_media_player_t *mp,
void *(*lock_cb) (void *, void **),
void (*unlock_cb) (void *, void *, void *const *),
- void (*display_cb) (void *, void *),
+ void (*display_cb) (void *, void *, void *const *),
void *opaque )
{
var_SetAddress( mp, "vmem-lock", lock_cb );
diff --git a/modules/video_output/vmem.c b/modules/video_output/vmem.c
index 25d8a86..1c82ec8 100644
--- a/modules/video_output/vmem.c
+++ b/modules/video_output/vmem.c
@@ -93,7 +93,7 @@ struct vout_display_sys_t {
void *pic_opaque;
void *(*lock)(void *sys, void **plane);
void (*unlock)(void *sys, void *id, void *const *plane);
- void (*display)(void *sys, void *id);
+ void (*display)(void *sys, void *id, void *const *plane);
void (*cleanup)(void *sys);
unsigned pitches[PICTURE_PLANE_MAX];
@@ -124,11 +124,6 @@ static int Open(vlc_object_t *object)
vlc_format_cb setup = var_InheritAddress(vd, "vmem-setup");
sys->lock = var_InheritAddress(vd, "vmem-lock");
- if (sys->lock == NULL) {
- msg_Err(vd, "missing lock callback");
- free(sys);
- return VLC_EGENERIC;
- }
sys->unlock = var_InheritAddress(vd, "vmem-unlock");
sys->display = var_InheritAddress(vd, "vmem-display");
sys->cleanup = var_InheritAddress(vd, "vmem-cleanup");
@@ -255,6 +250,11 @@ static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic)
picture_resource_t rsc = { .p_sys = NULL };
void *planes[PICTURE_PLANE_MAX];
+ if (sys->lock == NULL) {
+ sys->pic_opaque = NULL;
+ return;
+ }
+
sys->pic_opaque = sys->lock(sys->opaque, planes);
for (unsigned i = 0; i < PICTURE_PLANE_MAX; i++) {
@@ -279,8 +279,23 @@ static void Display(vout_display_t *vd, picture_t *pic, subpicture_t *subpic)
{
vout_display_sys_t *sys = vd->sys;
+ void *planes[PICTURE_PLANE_MAX];
+ if (sys->lock == NULL) {
+ for (unsigned i = 0; i < PICTURE_PLANE_MAX; i++) {
+ if (i < (unsigned)pic->i_planes) {
+ plane_t *p_src = pic->p+i;
+ planes[i] = p_src->p_pixels;
+ } else
+ planes[i] = NULL;
+ }
+ } else {
+ for (unsigned i = 0; i < PICTURE_PLANE_MAX; i++) {
+ planes[i] = NULL;
+ }
+ }
+
if (sys->display != NULL)
- sys->display(sys->opaque, sys->pic_opaque);
+ sys->display(sys->opaque, sys->pic_opaque, planes);
picture_Release(pic);
VLC_UNUSED(subpic);
--
2.7.4