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

Steve Lhomme robux4 at ycbcr.xyz
Fri Jun 7 10:19:37 CEST 2019


That means the libvlc changes a bit by separating the resize callback 
from the device setup. It just shows it's better that way whatever 
design we may have internally in the future, otherwise we're tied to a 
particular way of working.

On 2019-06-07 10:15, Steve Lhomme wrote:
> 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
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
> 


More information about the vlc-devel mailing list