[vlc-devel] [PATCH] libvlc: handle the report size callback in the wextern window module

Steve Lhomme robux4 at ycbcr.xyz
Fri Jun 7 10:15:44 CEST 2019


This way it can work for all modules that render externally. And the code is
generic. It also makes more sense to handle the window size in the window
module.
---
 doc/libvlc/d3d11_player.cpp             | 30 +++++------
 doc/libvlc/d3d9_player.c                | 29 ++++++-----
 include/vlc/libvlc_media_player.h       | 27 +++++++---
 lib/media_player.c                      |  3 ++
 modules/video_output/wextern.c          | 66 +++++++++++++++++++++----
 modules/video_output/win32/direct3d11.c |  9 ----
 modules/video_output/win32/direct3d9.c  |  3 --
 7 files changed, 110 insertions(+), 57 deletions(-)

diff --git a/doc/libvlc/d3d11_player.cpp b/doc/libvlc/d3d11_player.cpp
index 9f05080a01..da1ee48daf 100644
--- a/doc/libvlc/d3d11_player.cpp
+++ b/doc/libvlc/d3d11_player.cpp
@@ -190,18 +190,6 @@ static bool Setup_cb( void **opaque, const libvlc_video_direct3d_device_cfg_t *c
 {
     struct render_context *ctx = static_cast<struct render_context *>(*opaque);
     out->device_context = ctx->d3dctx;
-
-    EnterCriticalSection(&ctx->sizeLock);
-    ctx->ReportSize = cfg->report_size_change;
-    ctx->ReportOpaque = cfg->report_opaque;
-
-    if (ctx->ReportSize != nullptr)
-    {
-        /* report our initial size */
-        ctx->ReportSize(ctx->ReportOpaque, ctx->width, ctx->height);
-    }
-    LeaveCriticalSection(&ctx->sizeLock);
-
     return true;
 }
 
@@ -209,8 +197,22 @@ static void Cleanup_cb( void *opaque )
 {
     // here we can release all things Direct3D11 for good (if playing only one file)
     struct render_context *ctx = static_cast<struct render_context *>( opaque );
+}
+
+static void Resize_cb( void *opaque,
+                       void (*report_size_change)(void *report_opaque, unsigned width, unsigned height),
+                       void *report_opaque )
+{
+    struct render_context *ctx = static_cast<struct render_context *>( opaque );
     EnterCriticalSection(&ctx->sizeLock);
-    ctx->ReportSize = nullptr;
+    ctx->ReportSize = report_size_change;
+    ctx->ReportOpaque = report_opaque;
+
+    if (ctx->ReportSize != nullptr)
+    {
+        /* report our initial size */
+        ctx->ReportSize(ctx->ReportOpaque, ctx->width, ctx->height);
+    }
     LeaveCriticalSection(&ctx->sizeLock);
 }
 
@@ -499,7 +501,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
 
     /* Tell VLC to render into our D3D11 environment */
     libvlc_video_direct3d_set_callbacks( p_mp, libvlc_video_direct3d_engine_d3d11,
-                                        Setup_cb, Cleanup_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb, SelectPlane_cb,
+                                        Setup_cb, Cleanup_cb, Resize_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb, SelectPlane_cb,
                                         &Context );
 
     libvlc_media_player_play( p_mp );
diff --git a/doc/libvlc/d3d9_player.c b/doc/libvlc/d3d9_player.c
index faaed4c9b0..43fb3c1d4c 100644
--- a/doc/libvlc/d3d9_player.c
+++ b/doc/libvlc/d3d9_player.c
@@ -243,17 +243,6 @@ static bool Setup_cb( void **opaque, const libvlc_video_direct3d_device_cfg_t *c
 {
     struct render_context *ctx = *opaque;
     out->device_context = ctx->libvlc_d3d;
-
-    EnterCriticalSection(&ctx->sizeLock);
-    ctx->ReportSize = cfg->report_size_change;
-    ctx->ReportOpaque = cfg->report_opaque;
-
-    if (ctx->ReportSize != NULL)
-    {
-        /* report our initial size */
-        ctx->ReportSize(ctx->ReportOpaque, ctx->width, ctx->height);
-    }
-    LeaveCriticalSection(&ctx->sizeLock);
     return true;
 }
 
@@ -261,8 +250,22 @@ static void Cleanup_cb( void *opaque )
 {
     /* here we can release all things Direct3D9 for good  (if playing only one file) */
     struct render_context *ctx = opaque;
+}
+
+static void Resize_cb( void *opaque,
+                       void (*report_size_change)(void *report_opaque, unsigned width, unsigned height),
+                       void *report_opaque )
+{
+    struct render_context *ctx = opaque;
     EnterCriticalSection(&ctx->sizeLock);
-    ctx->ReportSize = NULL;
+    ctx->ReportSize = report_size_change;
+    ctx->ReportOpaque = report_opaque;
+
+    if (ctx->ReportSize != NULL)
+    {
+        /* report our initial size */
+        ctx->ReportSize(ctx->ReportOpaque, ctx->width, ctx->height);
+    }
     LeaveCriticalSection(&ctx->sizeLock);
 }
 
@@ -395,7 +398,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
 
     /* Tell VLC to render into our D3D9 environment */
     libvlc_video_direct3d_set_callbacks( p_mp, libvlc_video_direct3d_engine_d3d9,
-                                        Setup_cb, Cleanup_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb, NULL,
+                                        Setup_cb, Cleanup_cb, Resize_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb, NULL,
                                         &Context );
 
     libvlc_media_player_play( p_mp );
diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index c1529fdecc..2920605ae4 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -611,14 +611,6 @@ typedef enum libvlc_video_direct3d_engine_t {
 typedef struct
 {
     bool hardware_decoding; /** set if D3D11_CREATE_DEVICE_VIDEO_SUPPORT is needed for D3D11 */
-
-    /** Callback to call when the size of the host changes
-     *
-     * \note This may be called from any thread as long as it's not after
-     *    \ref libvlc_video_direct3d_device_cleanup_cb has been called.
-     */
-    void (*report_size_change)(void *report_opaque, unsigned width, unsigned height);
-    void *report_opaque;
 } libvlc_video_direct3d_device_cfg_t;
 
 typedef struct
@@ -655,6 +647,23 @@ typedef bool( *libvlc_video_direct3d_device_setup_cb )( void **opaque,
  */
 typedef void( *libvlc_video_direct3d_device_cleanup_cb )( void *opaque );
 
+/** Set the callback to call when the host app resizes the rendering area.
+ *
+ * This allows text rendering and aspect ratio to be handled properly when the host
+ * rendering size changes.
+ *
+ * It may be called before the \ref libvlc_video_direct3d_device_setup_cb callback.
+ *
+ * \param opaque private pointer set on the opaque parameter of @a libvlc_video_direct3d_device_setup_cb() [IN]
+ * \param report_size_change callback to use when the size changes. [IN]
+ *        The callback is valid until another call to \ref libvlc_video_direct3d_set_resize_cb
+ *        is done. This may be called from any thread.
+ * \param report_opaque private pointer to pass to the \ref report_size_change callback. [IN]
+ */
+typedef void( *libvlc_video_direct3d_set_resize_cb )( void *opaque,
+                                                      void (*report_size_change)(void *report_opaque, unsigned width, unsigned height),
+                                                      void *report_opaque );
+
 typedef struct
 {
     unsigned width;                        /** rendering video width in pixel */
@@ -783,6 +792,7 @@ typedef bool( *libvlc_video_direct3d_select_plane_cb )( void *opaque, size_t pla
  * \param engine the GPU engine to use
  * \param setup_cb callback to setup and return the device to use (cannot be NULL)
  * \param cleanup_cb callback to cleanup the device given by the \ref setup_cb callback
+ * \param resize_cb callback to set the resize callback
  * \param update_output_cb callback to notify of the source format and get the
  *                         rendering format used by the host (cannot be NULL)
  * \param swap_cb callback to tell the host it should display the rendered picture (cannot be NULL)
@@ -799,6 +809,7 @@ bool libvlc_video_direct3d_set_callbacks( libvlc_media_player_t *mp,
                                          libvlc_video_direct3d_engine_t engine,
                                          libvlc_video_direct3d_device_setup_cb setup_cb,
                                          libvlc_video_direct3d_device_cleanup_cb cleanup_cb,
+                                         libvlc_video_direct3d_set_resize_cb resize_cb,
                                          libvlc_video_direct3d_update_output_cb update_output_cb,
                                          libvlc_video_swap_cb swap_cb,
                                          libvlc_video_direct3d_start_end_rendering_cb makeCurrent_cb,
diff --git a/lib/media_player.c b/lib/media_player.c
index 5e6bfdd4cf..4ec277034c 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -593,6 +593,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
     var_Create( mp, "vout-cb-opaque", VLC_VAR_ADDRESS );
     var_Create( mp, "vout-cb-setup", VLC_VAR_ADDRESS );
     var_Create( mp, "vout-cb-cleanup", VLC_VAR_ADDRESS );
+    var_Create( mp, "vout-cb-resize-cb", VLC_VAR_ADDRESS );
     var_Create( mp, "vout-cb-update-output", VLC_VAR_ADDRESS );
     var_Create( mp, "vout-cb-swap", VLC_VAR_ADDRESS );
     var_Create( mp, "vout-cb-get-proc-address", VLC_VAR_ADDRESS );
@@ -1068,6 +1069,7 @@ bool libvlc_video_direct3d_set_callbacks(libvlc_media_player_t *mp,
                                          libvlc_video_direct3d_engine_t engine,
                                          libvlc_video_direct3d_device_setup_cb setup_cb,
                                          libvlc_video_direct3d_device_cleanup_cb cleanup_cb,
+                                         libvlc_video_direct3d_set_resize_cb resize_cb,
                                          libvlc_video_direct3d_update_output_cb update_output_cb,
                                          libvlc_video_swap_cb swap_cb,
                                          libvlc_video_direct3d_start_end_rendering_cb makeCurrent_cb,
@@ -1092,6 +1094,7 @@ bool libvlc_video_direct3d_set_callbacks(libvlc_media_player_t *mp,
     var_SetAddress( mp, "vout-cb-opaque", opaque );
     var_SetAddress( mp, "vout-cb-setup", setup_cb );
     var_SetAddress( mp, "vout-cb-cleanup", cleanup_cb );
+    var_SetAddress( mp, "vout-cb-resize-cb", resize_cb );
     var_SetAddress( mp, "vout-cb-update-output", update_output_cb );
     var_SetAddress( mp, "vout-cb-swap", swap_cb );
     var_SetAddress( mp, "vout-cb-make-current", makeCurrent_cb );
diff --git a/modules/video_output/wextern.c b/modules/video_output/wextern.c
index eab44854cd..5f39918ea4 100644
--- a/modules/video_output/wextern.c
+++ b/modules/video_output/wextern.c
@@ -30,24 +30,70 @@
 #include <vlc_plugin.h>
 #include <vlc_vout_window.h>
 
+#include <vlc/libvlc.h>
+#include <vlc/libvlc_picture.h>
+#include <vlc/libvlc_media.h>
+#include <vlc/libvlc_renderer_discoverer.h>
+#include <vlc/libvlc_media_player.h>
+
+static int Open(vout_window_t *);
+
+vlc_module_begin()
+    set_shortname(N_("Callback window"))
+    set_description(N_("External callback window"))
+    set_category(CAT_VIDEO)
+    set_subcategory(SUBCAT_VIDEO_VOUT)
+    set_capability("vout window", 0)
+    set_callbacks(Open, NULL)
+vlc_module_end()
+
+typedef struct {
+    void                                     *opaque;
+    libvlc_video_direct3d_set_resize_cb      setResizeCb;
+} wextern_t;
+
+static void WindowResize(void *opaque, unsigned width, unsigned height)
+{
+    vout_window_t *window = opaque;
+    vout_window_ReportSize(window, width, height);
+}
+
+static int Enable(struct vout_window_t *wnd, const vout_window_cfg_t *wcfg)
+{
+    wextern_t *sys = wnd->sys;
+
+    if ( sys->setResizeCb != NULL )
+        /* bypass the size handling as the window doesn't handle the size */
+        sys->setResizeCb( sys->opaque, WindowResize, wnd );
+
+    return VLC_SUCCESS;
+}
+
+static void Disable(struct vout_window_t *wnd)
+{
+    wextern_t *sys = wnd->sys;
+
+    if ( sys->setResizeCb != NULL )
+        sys->setResizeCb( sys->opaque, NULL, NULL );
+}
+
 static const struct vout_window_operations ops = {
+    .enable  = Enable,
+    .disable = Disable,
     // .resize: don't let the core resize us on zoom/crop/ar changes
     //          the display module should do the ReportSize for us
 };
 
 static int Open(vout_window_t *wnd)
 {
+    wextern_t *sys = vlc_obj_malloc(VLC_OBJECT(wnd), sizeof(wextern_t));
+    if (unlikely(sys==NULL))
+        return VLC_ENOMEM;
+    sys->opaque          = var_InheritAddress( wnd, "vout-cb-opaque" );
+    sys->setResizeCb     = var_InheritAddress( wnd, "vout-cb-resize-cb" );
+
+    wnd->sys = sys;
     wnd->type = VOUT_WINDOW_TYPE_DUMMY;
     wnd->ops = &ops;
     return VLC_SUCCESS;
 }
-
-vlc_module_begin()
-    set_shortname(N_("Callback window"))
-    set_description(N_("External callback window"))
-    set_category(CAT_VIDEO)
-    set_subcategory(SUBCAT_VIDEO_VOUT)
-    set_capability("vout window", 0)
-    set_callbacks(Open, NULL)
-    add_shortcut("dummy")
-vlc_module_end()
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index 5a123ef951..0606352feb 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -849,12 +849,6 @@ static const d3d_format_t *GetBlendableFormat(vout_display_t *vd, vlc_fourcc_t i
     return FindD3D11Format( vd, &vd->sys->d3d_dev, i_src_chroma, false, 0, 0, 0, false, supportFlags );
 }
 
-static void WindowResize(void *opaque, unsigned width, unsigned height)
-{
-    vout_window_t *window = opaque;
-    vout_window_ReportSize(window, width, height);
-}
-
 static int Direct3D11Open(vout_display_t *vd, video_format_t *fmtp)
 {
     vout_display_sys_t *sys = vd->sys;
@@ -862,9 +856,6 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmtp)
 
     libvlc_video_direct3d_device_cfg_t cfg = {
         .hardware_decoding = is_d3d11_opaque( vd->source.i_chroma ),
-        /* bypass the size handling as the window doesn't handle the size */
-        .report_size_change = vd->cfg->window->ops->resize ? NULL: WindowResize,
-        .report_opaque      = vd->cfg->window->ops->resize ? NULL: vd->cfg->window,
     };
     libvlc_video_direct3d_device_setup_t out;
     ID3D11DeviceContext *d3d11_ctx = NULL;
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index c26aeffba5..2af43c3fcf 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -1715,9 +1715,6 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
 
     libvlc_video_direct3d_device_cfg_t surface_cfg = {
         .hardware_decoding = is_d3d9_opaque( vd->source.i_chroma ),
-        /* bypass the size handling as the window doesn't handle the size */
-        .report_size_change = vd->cfg->window->ops->resize ? NULL: vout_window_ReportSize,
-        .report_opaque     = vd->cfg->window->ops->resize ? NULL: vd->cfg->window,
     };
     libvlc_video_direct3d_device_setup_t device_setup;
     IDirect3DDevice9 *d3d9_device = NULL;
-- 
2.17.1



More information about the vlc-devel mailing list