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

Steve Lhomme robux4 at ycbcr.xyz
Tue Apr 30 12:31:11 CEST 2019


On 4/30/2019 12:09 PM, Thomas Guillem wrote:
>
> 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.

Yes, but in the end I think the openGL API could be merged into this. It 
depends how the conversation goes. OpenGL has MakeCurrent and 
GetProcAddress but otherwise it's pretty much the same things. Adding a 
feature to one (HDR for example) should also mean support for the other.

>
> 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
> _______________________________________________
> 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