diff mbox

[FFmpeg-devel] hwcontext_d3d11va: implement av_hwdevice_get_hwframe_constraints()

Message ID 20180116130837.22233-1-nfxjfg@googlemail.com
State Accepted
Commit 27b9f82e2c5dca3ad642ed13c2360032a17687ec
Headers show

Commit Message

wm4 Jan. 16, 2018, 1:08 p.m. UTC
D3D11 has rather fine grained per texture format capabilities for
different uses that can be queried at runtime. Since we don't know at
the time av_hwdevice_get_hwframe_constraints() is called what the user
wants to do with this, we simply return all formats that have the most
basic support.
---
 libavutil/hwcontext_d3d11va.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Comments

wm4 Jan. 16, 2018, 4:42 p.m. UTC | #1
On Tue, 16 Jan 2018 14:08:37 +0100
wm4 <nfxjfg@googlemail.com> wrote:

> D3D11 has rather fine grained per texture format capabilities for
> different uses that can be queried at runtime. Since we don't know at
> the time av_hwdevice_get_hwframe_constraints() is called what the user
> wants to do with this, we simply return all formats that have the most
> basic support.
> ---
>  libavutil/hwcontext_d3d11va.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
> index 2f97156a54..960883c9d8 100644
> --- a/libavutil/hwcontext_d3d11va.c
> +++ b/libavutil/hwcontext_d3d11va.c
> @@ -120,6 +120,38 @@ static void d3d11va_frames_uninit(AVHWFramesContext *ctx)
>      s->staging_texture = NULL;
>  }
>  
> +static int d3d11va_frames_get_constraints(AVHWDeviceContext *ctx,
> +                                          const void *hwconfig,
> +                                          AVHWFramesConstraints *constraints)
> +{
> +    AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
> +    int nb_sw_formats = 0;
> +    HRESULT hr;
> +    int i;
> +
> +    constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1,
> +                                                    sizeof(*constraints->valid_sw_formats));
> +    if (!constraints->valid_sw_formats)
> +        return AVERROR(ENOMEM);
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
> +        UINT format_support = 0;
> +        hr = ID3D11Device_CheckFormatSupport(device_hwctx->device, supported_formats[i].d3d_format, &format_support);
> +        if (SUCCEEDED(hr) && (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D))
> +            constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt;
> +    }
> +    constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE;
> +
> +    constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
> +    if (!constraints->valid_hw_formats)
> +        return AVERROR(ENOMEM);
> +
> +    constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D11;
> +    constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
> +
> +    return 0;
> +}
> +
>  static void free_texture(void *opaque, uint8_t *data)
>  {
>      ID3D11Texture2D_Release((ID3D11Texture2D *)opaque);
> @@ -576,6 +608,7 @@ const HWContextType ff_hwcontext_type_d3d11va = {
>      .device_create        = d3d11va_device_create,
>      .device_init          = d3d11va_device_init,
>      .device_uninit        = d3d11va_device_uninit,
> +    .frames_get_constraints = d3d11va_frames_get_constraints,
>      .frames_init          = d3d11va_frames_init,
>      .frames_uninit        = d3d11va_frames_uninit,
>      .frames_get_buffer    = d3d11va_get_buffer,

Received a casual OK from atomnuker on IRC - pushed.
Steve Lhomme Jan. 16, 2018, 4:47 p.m. UTC | #2
Le 16/01/2018 à 17:42, wm4 a écrit :
> On Tue, 16 Jan 2018 14:08:37 +0100
> wm4 <nfxjfg@googlemail.com> wrote:
>
>> D3D11 has rather fine grained per texture format capabilities for
>> different uses that can be queried at runtime. Since we don't know at
>> the time av_hwdevice_get_hwframe_constraints() is called what the user
>> wants to do with this, we simply return all formats that have the most
>> basic support.
>> ---
>>   libavutil/hwcontext_d3d11va.c | 33 +++++++++++++++++++++++++++++++++
>>   1 file changed, 33 insertions(+)
>>
>> diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
>> index 2f97156a54..960883c9d8 100644
>> --- a/libavutil/hwcontext_d3d11va.c
>> +++ b/libavutil/hwcontext_d3d11va.c
>> @@ -120,6 +120,38 @@ static void d3d11va_frames_uninit(AVHWFramesContext *ctx)
>>       s->staging_texture = NULL;
>>   }
>>   
>> +static int d3d11va_frames_get_constraints(AVHWDeviceContext *ctx,
>> +                                          const void *hwconfig,
>> +                                          AVHWFramesConstraints *constraints)
>> +{
>> +    AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
>> +    int nb_sw_formats = 0;
>> +    HRESULT hr;
>> +    int i;
>> +
>> +    constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1,
>> +                                                    sizeof(*constraints->valid_sw_formats));
>> +    if (!constraints->valid_sw_formats)
>> +        return AVERROR(ENOMEM);
>> +
>> +    for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
>> +        UINT format_support = 0;
>> +        hr = ID3D11Device_CheckFormatSupport(device_hwctx->device, supported_formats[i].d3d_format, &format_support);
>> +        if (SUCCEEDED(hr) && (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D))

If you want to check the format can be used by the decoder, you should 
at least check for
D3D11_FORMAT_SUPPORT_DECODER_OUTPUT

>> +            constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt;
>> +    }
>> +    constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE;
>> +
>> +    constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
>> +    if (!constraints->valid_hw_formats)
>> +        return AVERROR(ENOMEM);
>> +
>> +    constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D11;
>> +    constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
>> +
>> +    return 0;
>> +}
>> +
>>   static void free_texture(void *opaque, uint8_t *data)
>>   {
>>       ID3D11Texture2D_Release((ID3D11Texture2D *)opaque);
>> @@ -576,6 +608,7 @@ const HWContextType ff_hwcontext_type_d3d11va = {
>>       .device_create        = d3d11va_device_create,
>>       .device_init          = d3d11va_device_init,
>>       .device_uninit        = d3d11va_device_uninit,
>> +    .frames_get_constraints = d3d11va_frames_get_constraints,
>>       .frames_init          = d3d11va_frames_init,
>>       .frames_uninit        = d3d11va_frames_uninit,
>>       .frames_get_buffer    = d3d11va_get_buffer,
> Received a casual OK from atomnuker on IRC - pushed.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
wm4 Jan. 16, 2018, 5:05 p.m. UTC | #3
On Tue, 16 Jan 2018 17:47:14 +0100
Steve Lhomme <robux4@ycbcr.xyz> wrote:

> Le 16/01/2018 à 17:42, wm4 a écrit :
> > On Tue, 16 Jan 2018 14:08:37 +0100
> > wm4 <nfxjfg@googlemail.com> wrote:
> >  
> >> D3D11 has rather fine grained per texture format capabilities for
> >> different uses that can be queried at runtime. Since we don't know at
> >> the time av_hwdevice_get_hwframe_constraints() is called what the user
> >> wants to do with this, we simply return all formats that have the most
> >> basic support.
> >> ---
> >>   libavutil/hwcontext_d3d11va.c | 33 +++++++++++++++++++++++++++++++++
> >>   1 file changed, 33 insertions(+)
> >>
> >> diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
> >> index 2f97156a54..960883c9d8 100644
> >> --- a/libavutil/hwcontext_d3d11va.c
> >> +++ b/libavutil/hwcontext_d3d11va.c
> >> @@ -120,6 +120,38 @@ static void d3d11va_frames_uninit(AVHWFramesContext *ctx)
> >>       s->staging_texture = NULL;
> >>   }
> >>   
> >> +static int d3d11va_frames_get_constraints(AVHWDeviceContext *ctx,
> >> +                                          const void *hwconfig,
> >> +                                          AVHWFramesConstraints *constraints)
> >> +{
> >> +    AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
> >> +    int nb_sw_formats = 0;
> >> +    HRESULT hr;
> >> +    int i;
> >> +
> >> +    constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1,
> >> +                                                    sizeof(*constraints->valid_sw_formats));
> >> +    if (!constraints->valid_sw_formats)
> >> +        return AVERROR(ENOMEM);
> >> +
> >> +    for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
> >> +        UINT format_support = 0;
> >> +        hr = ID3D11Device_CheckFormatSupport(device_hwctx->device, supported_formats[i].d3d_format, &format_support);
> >> +        if (SUCCEEDED(hr) && (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D))  
> 
> If you want to check the format can be used by the decoder, you should 
> at least check for
> D3D11_FORMAT_SUPPORT_DECODER_OUTPUT

Yeah, but it's not necessarily used for decoding. There are other valid
uses of D3D surfaces, e.g. video processor input (and it's realistic
that someone would add support for that to libavfilter).

Mark Thompson suggested on IRC that hwconfig could be used to pass
special requirements (such as whether the surface is to be used for
decoding), so if we ever need this later, it's extensible.
diff mbox

Patch

diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
index 2f97156a54..960883c9d8 100644
--- a/libavutil/hwcontext_d3d11va.c
+++ b/libavutil/hwcontext_d3d11va.c
@@ -120,6 +120,38 @@  static void d3d11va_frames_uninit(AVHWFramesContext *ctx)
     s->staging_texture = NULL;
 }
 
+static int d3d11va_frames_get_constraints(AVHWDeviceContext *ctx,
+                                          const void *hwconfig,
+                                          AVHWFramesConstraints *constraints)
+{
+    AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
+    int nb_sw_formats = 0;
+    HRESULT hr;
+    int i;
+
+    constraints->valid_sw_formats = av_malloc_array(FF_ARRAY_ELEMS(supported_formats) + 1,
+                                                    sizeof(*constraints->valid_sw_formats));
+    if (!constraints->valid_sw_formats)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
+        UINT format_support = 0;
+        hr = ID3D11Device_CheckFormatSupport(device_hwctx->device, supported_formats[i].d3d_format, &format_support);
+        if (SUCCEEDED(hr) && (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D))
+            constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt;
+    }
+    constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE;
+
+    constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
+    if (!constraints->valid_hw_formats)
+        return AVERROR(ENOMEM);
+
+    constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D11;
+    constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
+
+    return 0;
+}
+
 static void free_texture(void *opaque, uint8_t *data)
 {
     ID3D11Texture2D_Release((ID3D11Texture2D *)opaque);
@@ -576,6 +608,7 @@  const HWContextType ff_hwcontext_type_d3d11va = {
     .device_create        = d3d11va_device_create,
     .device_init          = d3d11va_device_init,
     .device_uninit        = d3d11va_device_uninit,
+    .frames_get_constraints = d3d11va_frames_get_constraints,
     .frames_init          = d3d11va_frames_init,
     .frames_uninit        = d3d11va_frames_uninit,
     .frames_get_buffer    = d3d11va_get_buffer,