[vlc-devel] [PATCH] [RFC] always output an opaque D3D9 surface from DXVA

Steve Lhomme robux4 at videolabs.io
Mon Apr 27 11:31:23 CEST 2015


On Thu, Apr 23, 2015 at 10:58 PM, Rémi Denis-Courmont <remi at remlab.net> wrote:
> Le jeudi 23 avril 2015, 17:11:19 Steve Lhomme a écrit :
>> This is a test code to show how DXVA direct rendering could be done.
>>
>> When avcodec asks for an AVFrame, the vout and its decoder pool is already
>> created. So we use the D3D9 device from the picture_t coming from that pool
>> to recreate the DXVA2 decoder surface.
>>
>> This is working fine for normal playback, seeking, opening files of
>> same/different dimensions.
>>
>> The decoder of D3D9 surface is created in the vout wrapper (like all the
>> others) but with a dirty hack for now.
>>
>> This code also works with direct rendering to D3D9, not included in this
>> patch.
>>
>> The changes to the other va->Setup callback are not done and it's a
>> temporary test code. ---
>>  include/vlc_fourcc.h            |   3 +
>>  modules/codec/avcodec/dxva2.c   | 173 ++++++++++++++++++++++------
>>  modules/codec/avcodec/va.h      |   6 +-
>>  modules/codec/avcodec/video.c   |  19 +--
>>  modules/video_chroma/copy.c     |  40 +++++--
>>  src/Makefile.am                 |   2 +
>>  src/misc/fourcc.c               |   3 +
>>  src/video_output/vout_wrapper.c |  17 ++-
>>  src/win32/direct3d9_pool.c      | 248
>> ++++++++++++++++++++++++++++++++++++++++ src/win32/direct3d9_pool.h      |
>> 39 +++++++
>>  10 files changed, 491 insertions(+), 59 deletions(-)
>>  create mode 100644 src/win32/direct3d9_pool.c
>>  create mode 100644 src/win32/direct3d9_pool.h
>>
>> diff --git a/include/vlc_fourcc.h b/include/vlc_fourcc.h
>> index 5d30ece..df82f6f 100644
>> --- a/include/vlc_fourcc.h
>> +++ b/include/vlc_fourcc.h
>> @@ -332,6 +332,9 @@
>>  /* Broadcom MMAL opaque buffer type */
>>  #define VLC_CODEC_MMAL_OPAQUE     VLC_FOURCC('M','M','A','L')
>>
>> +/* DXVA2 opaque video surface for use with D3D9 */
>> +#define VLC_CODEC_D3D9_OPAQUE     VLC_FOURCC('D','X','A','9')
>> +
>>  /* Image codec (video) */
>>  #define VLC_CODEC_PNG             VLC_FOURCC('p','n','g',' ')
>>  #define VLC_CODEC_PPM             VLC_FOURCC('p','p','m',' ')
>> diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
>> index db9820f..4382e24 100644
>> --- a/modules/codec/avcodec/dxva2.c
>> +++ b/modules/codec/avcodec/dxva2.c
>> @@ -42,6 +42,7 @@
>>  #include <vlc_cpu.h>
>>  #include <vlc_plugin.h>
>>  #include <vlc_codecs.h>
>> +#include <vlc_filter.h>
>>
>>  #include <libavcodec/avcodec.h>
>>  #    define DXVA2API_USE_BITFIELDS
>> @@ -55,12 +56,19 @@
>>  static int Open(vlc_va_t *, AVCodecContext *, const es_format_t *);
>>  static void Close(vlc_va_t *, AVCodecContext *);
>>
>> +static int  OpenFilter( vlc_object_t * );
>> +static void CloseFilter( vlc_object_t * );
>> +
>>  vlc_module_begin()
>>      set_description(N_("DirectX Video Acceleration (DXVA) 2.0"))
>>      set_capability("hw decoder", 0)
>>      set_category(CAT_INPUT)
>>      set_subcategory(SUBCAT_INPUT_VCODEC)
>>      set_callbacks(Open, Close)
>> +    add_submodule()
>> +        set_description( N_("DXVA2 surface to planes") )
>> +        set_capability( "video filter2", 10 )
>> +        set_callbacks( OpenFilter, CloseFilter )
>>  vlc_module_end()
>>
>>  #include <windows.h>
>> @@ -348,6 +356,11 @@ struct vlc_va_sys_t
>>      LPDIRECT3DSURFACE9 hw_surface[VA_DXVA2_MAX_SURFACE_COUNT];
>>  };
>>
>> +struct picture_sys_t
>> +{
>> +    LPDIRECT3DSURFACE9 surface;
>> +};
>> +
>>  /* */
>>  static int D3dCreateDevice(vlc_va_t *);
>>  static void D3dDestroyDevice(vlc_va_sys_t *);
>> @@ -369,9 +382,49 @@ static void DxCreateVideoConversion(vlc_va_sys_t *);
>>  static void DxDestroyVideoConversion(vlc_va_sys_t *);
>>
>>  /* */
>> -static int Setup(vlc_va_t *va, AVCodecContext *avctx, vlc_fourcc_t *chroma)
>> +static int Setup(vlc_va_t *va, AVCodecContext *avctx, vlc_fourcc_t
>> *chroma, picture_t *p_test_output) {
>
> I think it is preferable for the hardware context to be made available already
> at Open(). (Also I would pass the picture_sys_t cast to void, rather than the
> whole picture_t. It would be slightly less ugly.)
>
> Besides Setup needs to go away separately. It should be folded into Open()
> (for all plugins). libavcodec has to call get_format() again if the resolution
> changes.

I'll give it a try. Thanks for helping moving this forward.

Also the big remaining question is how to handle the D3D9 picture_t
pool in the core. I did it the quick & dirty way with some if on the
opaque pixel format and surrounded by _WIN32 tests.

I'm not sure it belongs in the core or should be made into a generic
module type or some other forms.

Steve



More information about the vlc-devel mailing list