[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