[vlc-devel] [RFC 1/6] libvlc: add rendering callbacks for D3D11 and D3D9

Thomas Guillem thomas at gllm.fr
Tue Apr 30 12:09:25 CEST 2019



On Tue, Apr 30, 2019, at 11:35, Steve Lhomme wrote:
> ---
>  include/vlc/libvlc_media_player.h | 143 ++++++++++++++++++++++++++++++
>  lib/libvlc.sym                    |   1 +
>  lib/media_player.c                |  39 ++++++++
>  3 files changed, 183 insertions(+)
> 
> diff --git a/include/vlc/libvlc_media_player.h 
> b/include/vlc/libvlc_media_player.h
> index ca72a550d3..51dd964600 100644
> --- a/include/vlc/libvlc_media_player.h
> +++ b/include/vlc/libvlc_media_player.h
> @@ -557,6 +557,149 @@ int libvlc_video_set_output_callbacks( 
> libvlc_media_player_t *mp,
>                                          libvlc_video_getProcAddress_cb 
> getProcAddress_cb,
>                                          void* opaque );
>  
> +
> +/**
> + * Enumeration of the Video engine to be used on output.
> + * can be passed to @a libvlc_video_set_rendering_callbacks
> + */
> +typedef enum libvlc_video_rendering_t {
> +    /** Direct3D11 rendering engine */
> +    libvlc_video_rendering_direct3d11,
> +    /** Direct3D9 rendering engine */
> +    libvlc_video_rendering_direct3d9,
> +} libvlc_video_rendering_t;
> +
> +typedef struct
> +{
> +    unsigned width;     /** rendering video width in pixel */
> +    unsigned height;    /** rendering video height in pixel */
> +} libvlc_video_callback_setup_t;
> +
> +/**
> + * List of control passed to the @a libvlc_video_control_cb callback
> + */
> +typedef enum libvlc_video_callback_control_t {
> +    /** Setup the rendering environment.
> +     *
> +     * \ref input ignored
> +     * \ref output pointer depending on the type of the engine
> +     *
> +     * For \ref libvlc_video_rendering_direct3d9 the output must be a 
> IDirect3DDevice9*.
> +     * A reference to this object is held until the \ref 
> LIBVLC_VIDEO_DEVICE_CLEANUP is called.
> +     * the device must be created with 
> D3DPRESENT_PARAMETERS.hDeviceWindow set to 0.
> +     *
> +     * For \ref libvlc_video_rendering_direct3d11 the output must be a 
> ID3D11DeviceContext*.
> +     * A reference to this object is held until the \ref 
> LIBVLC_VIDEO_DEVICE_CLEANUP is called.
> +     * The ID3D11Device used to create ID3D11DeviceContext must have 
> multithreading enabled.
> +     */
> +    LIBVLC_VIDEO_DEVICE_SETUP,
> +
> +    /** Cleanup the rendering environment initialized during \ref 
> LIBVLC_VIDEO_DEVICE_SETUP.
> +     *
> +     * \ref input ignored
> +     * \ref output ignored
> +     */
> +    LIBVLC_VIDEO_DEVICE_CLEANUP,
> +
> +    /** Update the rendering output setup.
> +     *
> +     * \ref input const libvlc_video_callback_setup_t* with the new 
> setup
> +     * \ref output ignored
> +     */
> +    LIBVLC_VIDEO_UPDATE_OUTPUT,
> +
> +    /** Callback prototype called after performing drawing calls.
> +     *
> +     * \ref input ignored
> +     * \ref output ignored
> +     */
> +    LIBVLC_VIDEO_SWAP,
> +
> +    /** Tell the host the rendering is about to start.
> +     *
> +     * \ref input ignored
> +     * \ref output ignored
> +     *
> +     * Between \ref LIBVLC_VIDEO_START_RENDERING and \ref 
> LIBVLC_VIDEO_FINISHED_RENDERING
> +     * of Direct3D9 the following may change on the provided 
> IDirect3DDevice9*:
> +     * - D3DSAMP_ADDRESSU
> +     * - D3DSAMP_ADDRESSV
> +     * - D3DSAMP_MINFILTER
> +     * - D3DSAMP_MAGFILTER
> +     * - D3DRS_AMBIENT
> +     * - D3DRS_CULLMODE
> +     * - D3DRS_ZENABLE
> +     * - D3DRS_LIGHTING
> +     * - D3DRS_DITHERENABLE
> +     * - D3DRS_STENCILENABLE
> +     * - D3DRS_ALPHABLENDENABLE
> +     * - D3DRS_SRCBLEND,D3DBLEND_SRCALPHA
> +     * - D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA
> +     * - D3DPCMPCAPS_GREATER
> +     * - D3DRS_ALPHATESTENABLE
> +     * - D3DRS_ALPHAREF
> +     * - D3DRS_ALPHAFUNC
> +     * - D3DTSS_COLOROP
> +     * - D3DTSS_COLORARG1
> +     * - D3DTSS_ALPHAOP
> +     * - D3DTSS_ALPHAARG1
> +     * - D3DTSS_ALPHAARG2
> +     *
> +     * Between \ref LIBVLC_VIDEO_START_RENDERING and \ref 
> LIBVLC_VIDEO_FINISHED_RENDERING
> +     * of Direct3D11 the following may change on the provided 
> ID3D11DeviceContext*:
> +     * - IASetPrimitiveTopology()
> +     * - IASetInputLayout()
> +     * - IASetVertexBuffers()
> +     * - IASetIndexBuffer()
> +     * - VSSetConstantBuffers()
> +     * - VSSetShader()
> +     * - PSSetSamplers()
> +     * - PSSetConstantBuffers()
> +     * - PSSetShaderResources()
> +     * - PSSetShader()
> +     * - RSSetViewports()
> +     * - DrawIndexed()
> +     */
> +    LIBVLC_VIDEO_START_RENDERING,
> +
> +    /** Tell the host the rendering has ended.
> +     *
> +     * \ref input ignored
> +     * \ref output ignored
> +     */
> +    LIBVLC_VIDEO_FINISHED_RENDERING,
> +} libvlc_video_callback_control_t;
> +
> +/**
> + * Callback prototype for the @a libvlc_video_set_surface_callbacks 
> callback.
> + *
> + * \param opaque private pointer passed to the @a 
> libvlc_video_set_surface_callbacks() [IN]
> + * \version LibVLC 4.0.0 or later
> + */
> +typedef int (*libvlc_video_control_cb)(void* opaque,
> +                                       libvlc_video_callback_control_t 
> control,
> +                                       const void *input,
> +                                       void **output);
> +
> +/**
> + * Set callbacks and data to render decoded video to a custom Direct3D 
> output
> + *
> + * \warning VLC will perform video rendering in its own thread and at 
> its own rate,
> + * You need to provide your own synchronisation mechanism.
> + *
> + * \param mp the media player
> + * \param engine the GPU engine to use
> + * \param control_cb callback that receives all the \ref 
> libvlc_video_callback_control_t
> + * \param opaque private pointer passed to the control callback
> + * \libvlc_return_bool
> + * \version LibVLC 4.0.0 or later
> + */
> +LIBVLC_API
> +int libvlc_video_set_rendering_callbacks( libvlc_media_player_t *mp,
> +                                          libvlc_video_rendering_t 
> engine,
> +                                          libvlc_video_control_cb 
> control_cb,
> +                                          void* opaque );
> +

This function can be used only with d3d9 and d3d11, right ? I think it should be explicit in the function name.

libvlc_video_set_d3dx_callbacks ?

>  /**
>   * Set the NSView handler where the media player should render its 
> video output.
>   *
> diff --git a/lib/libvlc.sym b/lib/libvlc.sym
> index ef132c37e4..f212088b30 100644
> --- a/lib/libvlc.sym
> +++ b/lib/libvlc.sym
> @@ -244,6 +244,7 @@ libvlc_video_set_deinterlace
>  libvlc_video_set_format
>  libvlc_video_set_format_callbacks
>  libvlc_video_set_output_callbacks
> +libvlc_video_set_rendering_callbacks
>  libvlc_video_set_key_input
>  libvlc_video_set_logo_int
>  libvlc_video_set_logo_string
> diff --git a/lib/media_player.c b/lib/media_player.c
> index 106e7d26b0..e04f1dab19 100644
> --- a/lib/media_player.c
> +++ b/lib/media_player.c
> @@ -646,6 +646,7 @@ libvlc_media_player_new( libvlc_instance_t 
> *instance )
>      var_Create( mp, "vout-cb-swap", VLC_VAR_ADDRESS );
>      var_Create( mp, "vout-cb-get-proc-address", VLC_VAR_ADDRESS );
>      var_Create( mp, "vout-cb-make-current", VLC_VAR_ADDRESS );
> +    var_Create( mp, "vout-cb-control", VLC_VAR_ADDRESS );
>  
>      var_Create (mp, "avcodec-hw", VLC_VAR_STRING);
>      var_Create (mp, "drawable-xid", VLC_VAR_INTEGER);
> @@ -1202,6 +1203,31 @@ int libvlc_video_set_output_callbacks( 
> libvlc_media_player_t *mp,
>  }
>  
>  
> +int libvlc_video_set_rendering_callbacks( libvlc_media_player_t *mp,
> +                                        libvlc_video_rendering_t 
> engine,
> +                                        libvlc_video_control_cb 
> control_cb,
> +                                        void* opaque )
> +{
> +    var_SetString( mp, "window", "wdummy");
> +
> +    if ( engine == libvlc_video_rendering_direct3d11 )
> +    {
> +        var_SetString ( mp, "vout", "direct3d11" );
> +        var_SetString ( mp, "avcodec-hw", "d3d11va");
> +    }
> +    else if ( engine == libvlc_video_rendering_direct3d9 )
> +    {
> +        var_SetString ( mp, "vout", "direct3d9" );
> +        var_SetString ( mp, "avcodec-hw", "dxva2");
> +    }
> +    else
> +        return 0;
> +
> +    var_SetAddress( mp, "vout-cb-opaque", opaque );
> +    var_SetAddress( mp, "vout-cb-control", control_cb );
> +    return 1;
> +}
> +
>  
> /**************************************************************************
>   * set_nsobject
>   
> **************************************************************************/
> @@ -2049,3 +2075,16 @@ int 
> libvlc_media_player_get_role(libvlc_media_player_t *mp)
>      free(str);
>      return ret;
>  }
> +
> +#include <vlc_vout_display.h>
> +
> +static_assert(VLC_VIDEO_SURFACE_DEVICE_SETUP       == 
> LIBVLC_VIDEO_DEVICE_SETUP &&
> +              VLC_VIDEO_SURFACE_DEVICE_CLEANUP     == 
> LIBVLC_VIDEO_DEVICE_CLEANUP &&
> +              VLC_VIDEO_SURFACE_UPDATE_OUTPUT      == 
> LIBVLC_VIDEO_UPDATE_OUTPUT &&
> +              VLC_VIDEO_SURFACE_SWAP               == 
> LIBVLC_VIDEO_SWAP &&
> +              VLC_VIDEO_SURFACE_START_RENDERING    == 
> LIBVLC_VIDEO_START_RENDERING &&
> +              VLC_VIDEO_SURFACE_FINISHED_RENDERING == 
> LIBVLC_VIDEO_FINISHED_RENDERING &&
> +              sizeof(vlc_video_surface_cfg_t)           == 
> sizeof(libvlc_video_callback_setup_t) &&
> +              offsetof(vlc_video_surface_cfg_t, width)  == 
> offsetof(libvlc_video_callback_setup_t, width) &&
> +              offsetof(vlc_video_surface_cfg_t, height) == 
> offsetof(libvlc_video_callback_setup_t, height)
> +              , "video surface mismatch");
> -- 
> 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