[vlc-devel] [PATCH 1/7] avcodec: va: pass the software format description to the VA

Steve Lhomme robux4 at ycbcr.xyz
Sat Oct 5 08:56:31 CEST 2019


On 2019-10-04 16:26, Rémi Denis-Courmont wrote:
> Hi,
> 
> Why does the decoder need to care? Isn't that a hassle for the RGB 
> conversion shader rather than the decoding??

Hardware decoders can only decode certain profiles. If you're out of 
that profile it just won't work. In the case of HEVC the 4:2:2, 4:4:4 
and 12 bits support are all in a single "profile" (Range Extension). But 
that information alone doesn't tell much about what kind of output 
you're getting. And some hardware decoders (newer Intel CPUs in my case) 
only support some combination (no 12 bits for example, 4:2:2 only for 10 
bits). The only way to know the kind of output the decoder is going to 
require (and thus if the decoder can actually support the stream) is by 
getting the chroma subsampling from the pixel format.

Side note: in NVDEC we may not be able to support HEVC Rext because we 
need have parsed some of the codec data before we can tell what flavor 
or Rext it is and if the hardware can support it.

Side note: the pixel format will also help detect 10 bits VP9 in lavc 
which we currently only do if the file has CodePrivate data with the 
profile, which is found in almost no 10 bits VP9 files.

> Le 4 octobre 2019 16:15:52 GMT+03:00, Steve Lhomme <robux4 at ycbcr.xyz> a 
> écrit :
> 
>     The codec profile alone doesn't always give information on the bit depth or
>     chroma subsampling (see HEVC Range Extension).
> 
>     The pixel format description is read in the lavc module rather than each VA so
>     they don't have to link with libavutil.
>     ------------------------------------------------------------------------
>       modules/codec/avcodec/d3d11va.c    |  7 ++++---
>       modules/codec/avcodec/directx_va.c | 11 +++++++----
>       modules/codec/avcodec/directx_va.h |  3 ++-
>       modules/codec/avcodec/dxva2.c      |  7 ++++---
>       modules/codec/avcodec/va.c         |  8 +++++---
>       modules/codec/avcodec/va.h         |  6 ++++--
>       modules/codec/avcodec/vaapi.c      |  4 +++-
>       modules/codec/avcodec/video.c      |  4 +++-
>       modules/hw/vdpau/avcodec.c         |  4 +++-
>       9 files changed, 35 insertions(+), 19 deletions(-)
> 
>     diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
>     index d6477cfaca2..c34430bed66 100644
>     --- a/modules/codec/avcodec/d3d11va.c
>     +++ b/modules/codec/avcodec/d3d11va.c
>     @@ -55,7 +55,7 @@ typedef picture_sys_d3d11_t VA_PICSYS;
>       
>       #include "directx_va.h"
>       
>     -static int Open(vlc_va_t *, AVCodecContext *, enum PixelFormat,
>     +static int Open(vlc_va_t *, AVCodecContext *, const AVPixFmtDescriptor *, enum PixelFormat,
>                       const es_format_t *, void *);
>       
>       vlc_module_begin()
>     @@ -302,7 +302,8 @@ static void Close(vlc_va_t *va)
>       
>       static const struct vlc_va_operations ops = { Get, Close, };
>       
>     -static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
>     +static int Open(vlc_va_t *va, AVCodecContext *ctx, const AVPixFmtDescriptor *desc,
>     +                enum PixelFormat pix_fmt,
>                       const es_format_t *fmt, void *picsys)
>       {
>           int err = VLC_EGENERIC;
>     @@ -383,7 +384,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
>       
>           video_format_t fmt_out;
>           static const directx_sys_t dx_sys = { DxGetInputList, DxSetupOutput };
>     -    err = directx_va_Setup(va, &dx_sys, ctx, fmt, isXboxHardware(sys->d3d_dev.d3ddevice), &fmt_out, &sys->hw.surface_count, &sys->decoder_guid);
>     +    err = directx_va_Setup(va, &dx_sys, ctx, desc, fmt, isXboxHardware(sys->d3d_dev.d3ddevice), &fmt_out, &sys->hw.surface_count, &sys->decoder_guid);
>           if (err != VLC_SUCCESS)
>               goto error;
>       
>     diff --git a/modules/codec/avcodec/directx_va.c b/modules/codec/avcodec/directx_va.c
>     index 9f6ce7520cc..51a729630d4 100644
>     --- a/modules/codec/avcodec/directx_va.c
>     +++ b/modules/codec/avcodec/directx_va.c
>     @@ -267,7 +267,8 @@ static const directx_va_mode_t DXVA_MODES[] = {
>           { NULL, NULL, 0, NULL }
>       };
>       
>     -static int FindVideoServiceConversion(vlc_va_t *, const directx_sys_t *, const es_format_t *, video_format_t *fmt_out, const AVCodecContext *, GUID *found_guid);
>     +static int FindVideoServiceConversion(vlc_va_t *, const directx_sys_t *, const es_format_t *, video_format_t *fmt_out,
>     +                                      const AVCodecContext *, const AVPixFmtDescriptor *, GUID *found_guid);
>       
>       char *directx_va_GetDecoderName(const GUID *guid)
>       {
>     @@ -283,7 +284,8 @@ char *directx_va_GetDecoderName(const GUID *guid)
>       }
>       
>       /* */
>     -int directx_va_Setup(vlc_va_t *va, const directx_sys_t *dx_sys, const AVCodecContext *avctx,
>     +int directx_va_Setup(vlc_va_t *va, const directx_sys_t *dx_sys,
>     +                     const AVCodecContext *avctx, const AVPixFmtDescriptor *desc,
>                            const es_format_t *fmt, int flag_xbox,
>                            video_format_t *fmt_out, unsigned *surfaces, GUID *found_guid)
>       {
>     @@ -344,7 +346,7 @@ int directx_va_Setup(vlc_va_t *va, const directx_sys_t *dx_sys, const AVCodecCon
>           fmt_out->i_frame_rate_base = avctx->framerate.den;
>       
>           /* */
>     -    if (FindVideoServiceConversion(va, dx_sys, fmt, fmt_out, avctx, found_guid)) {
>     +    if (FindVideoServiceConversion(va, dx_sys, fmt, fmt_out, avctx, desc, found_guid)) {
>               msg_Err(va, "FindVideoServiceConversion failed");
>               return VLC_EGENERIC;
>           }
>     @@ -390,7 +392,8 @@ static bool profile_supported(const directx_va_mode_t *mode, const es_format_t *
>        * Find the best suited decoder mode GUID and render format.
>        */
>       static int FindVideoServiceConversion(vlc_va_t *va, const directx_sys_t *dx_sys,
>     -                                      const es_format_t *fmt, video_format_t *fmt_out, const AVCodecContext *avctx,
>     +                                      const es_format_t *fmt, video_format_t *fmt_out,
>     +                                      const AVCodecContext *avctx, const AVPixFmtDescriptor *desc,
>                                             GUID *found_guid)
>       {
>           input_list_t p_list = { 0 };
>     diff --git a/modules/codec/avcodec/directx_va.h b/modules/codec/avcodec/directx_va.h
>     index 4e94a95a13a..e3cfea9e37c 100644
>     --- a/modules/codec/avcodec/directx_va.h
>     +++ b/modules/codec/avcodec/directx_va.h
>     @@ -64,7 +64,8 @@ typedef struct
>       
>       } directx_sys_t;
>       
>     -int directx_va_Setup(vlc_va_t *, const directx_sys_t *, const AVCodecContext *avctx, const es_format_t *, int flag_xbox,
>     +int directx_va_Setup(vlc_va_t *, const directx_sys_t *, const AVCodecContext *, const AVPixFmtDescriptor *,
>     +                     const es_format_t *, int flag_xbox,
>                            video_format_t *fmt_out, unsigned *surface_count, GUID *found_guid);
>       char *directx_va_GetDecoderName(const GUID *guid);
>       bool directx_va_canUseDecoder(vlc_va_t *, UINT VendorId, UINT DeviceId, const GUID *pCodec, UINT driverBuild);
>     diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
>     index 24eb59415c3..68e8727e696 100644
>     --- a/modules/codec/avcodec/dxva2.c
>     +++ b/modules/codec/avcodec/dxva2.c
>     @@ -42,7 +42,7 @@ typedef picture_sys_d3d9_t VA_PICSYS;
>       
>       #include "directx_va.h"
>       
>     -static int Open(vlc_va_t *, AVCodecContext *, enum PixelFormat,
>     +static int Open(vlc_va_t *, AVCodecContext *, const AVPixFmtDescriptor *, enum PixelFormat,
>                       const es_format_t *, void *);
>       
>       vlc_module_begin()
>     @@ -243,7 +243,8 @@ static void Close(vlc_va_t *va)
>       
>       static const struct vlc_va_operations ops = { Get, Close, };
>       
>     -static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
>     +static int Open(vlc_va_t *va, AVCodecContext *ctx, const AVPixFmtDescriptor *desc,
>     +                enum PixelFormat pix_fmt,
>                       const es_format_t *fmt, void *picsys)
>       {
>           int err = VLC_EGENERIC;
>     @@ -309,7 +310,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
>       
>           video_format_t fmt_out;
>           static const directx_sys_t dx_sys = { DxGetInputList, DxSetupOutput };
>     -    err = directx_va_Setup(va, &dx_sys, ctx, fmt, 0, &fmt_out, &sys->hw.surface_count, &sys->decoder_guid);
>     +    err = directx_va_Setup(va, &dx_sys, ctx, desc, fmt, 0, &fmt_out, &sys->hw.surface_count, &sys->decoder_guid);
>           if (err != VLC_SUCCESS)
>               goto error;
>       
>     diff --git a/modules/codec/avcodec/va.c b/modules/codec/avcodec/va.c
>     index 7558b2b6874..ac4bd75db88 100644
>     --- a/modules/codec/avcodec/va.c
>     +++ b/modules/codec/avcodec/va.c
>     @@ -92,16 +92,18 @@ static int vlc_va_Start(void *func, bool forced, va_list ap)
>       {
>           vlc_va_t *va = va_arg(ap, vlc_va_t *);
>           AVCodecContext *ctx = va_arg(ap, AVCodecContext *);
>     +    const AVPixFmtDescriptor *src_desc = va_arg(ap, const AVPixFmtDescriptor *);
>           enum PixelFormat pix_fmt = va_arg(ap, enum PixelFormat);
>           const es_format_t *fmt = va_arg(ap, const es_format_t *);
>           void *p_sys = va_arg(ap, void *);
>           vlc_va_open open = func;
>       
>           (void) forced;
>     -    return open(va, ctx, pix_fmt, fmt, p_sys);
>     +    return open(va, ctx, src_desc, pix_fmt, fmt, p_sys);
>       }
>       
>     -vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *avctx,
>     +vlc_va_t *vlc_va_New(vlc_object_t *obj,
>     +                     AVCodecContext *avctx, const AVPixFmtDescriptor *src_desc,
>                            enum PixelFormat pix_fmt, const es_format_t *fmt,
>                            void *sys)
>       {
>     @@ -112,7 +114,7 @@ vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *avctx,
>           char *modlist = var_InheritString(obj, "avcodec-hw");
>       
>           if (vlc_module_load(va, "hw decoder", modlist, true,
>     -                        vlc_va_Start, va, avctx, pix_fmt, fmt, sys) == NULL)
>     +                        vlc_va_Start, va, avctx, src_desc, pix_fmt, fmt, sys) == NULL)
>           {
>               vlc_object_delete(va);
>               va = NULL;
>     diff --git a/modules/codec/avcodec/va.h b/modules/codec/avcodec/va.h
>     index 3e6b827c8f2..7011124baaf 100644
>     --- a/modules/codec/avcodec/va.h
>     +++ b/modules/codec/avcodec/va.h
>     @@ -24,6 +24,7 @@
>       #define VLC_AVCODEC_VA_H 1
>       
>       #include "avcommon_compat.h"
>     +#include <libavutil/pixdesc.h>
>       
>       typedef struct vlc_va_t vlc_va_t;
>       typedef struct vlc_va_sys_t vlc_va_sys_t;
>     @@ -40,7 +41,8 @@ struct vlc_va_t {
>           const struct vlc_va_operations *ops;
>       };
>       
>     -typedef int (*vlc_va_open)(vlc_va_t *, AVCodecContext *, enum PixelFormat,
>     +typedef int (*vlc_va_open)(vlc_va_t *, AVCodecContext *, const AVPixFmtDescriptor *,
>     +                           enum PixelFormat,
>                                  const es_format_t *, void *);
>       
>       #define set_va_callback(activate, priority) \
>     @@ -66,7 +68,7 @@ vlc_fourcc_t vlc_va_GetChroma(enum PixelFormat hwfmt, enum PixelFormat swfmt);
>        * @param fmt VLC format of the content to decode
>        * @return a new VLC object on success, NULL on error.
>        */
>     -vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *,
>     +vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *, const AVPixFmtDescriptor *,
>                            enum PixelFormat, const es_format_t *fmt,
>                            void *p_sys);
>       
>     diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c
>     index 7e8329bf888..be0a321b0e5 100644
>     --- a/modules/codec/avcodec/vaapi.c
>     +++ b/modules/codec/avcodec/vaapi.c
>     @@ -145,9 +145,11 @@ static void Delete(vlc_va_t *va)
>       
>       static const struct vlc_va_operations ops = { Get, Delete, };
>       
>     -static int Create(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
>     +static int Create(vlc_va_t *va, AVCodecContext *ctx, const AVPixFmtDescriptor *desc,
>     +                  enum PixelFormat pix_fmt,
>                         const es_format_t *fmt, void *p_sys)
>       {
>     +    VLC_UNUSED(desc);
>           if (pix_fmt != AV_PIX_FMT_VAAPI_VLD || p_sys == NULL)
>               return VLC_EGENERIC;
>       
>     diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
>     index d69abd7419c..b9fa684290f 100644
>     --- a/modules/codec/avcodec/video.c
>     +++ b/modules/codec/avcodec/video.c
>     @@ -1704,6 +1704,8 @@ no_reuse:
>               AV_PIX_FMT_NONE,
>           };
>       
>     +    const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(swfmt);
>     +
>           for( size_t i = 0; hwfmts[i] != AV_PIX_FMT_NONE; i++ )
>           {
>               enum PixelFormat hwfmt = AV_PIX_FMT_NONE;
>     @@ -1730,7 +1732,7 @@ no_reuse:
>       
>               picture_t *test_pic = decoder_NewPicture(p_dec);
>               assert(!test_pic || test_pic->format.i_chroma == p_dec->fmt_out.video.i_chroma);
>     -        vlc_va_t *va = vlc_va_New(VLC_OBJECT(p_dec), p_context, hwfmt,
>     +        vlc_va_t *va = vlc_va_New(VLC_OBJECT(p_dec), p_context, src_desc, hwfmt,
>                                         &p_dec->fmt_in,
>                                         test_pic ? test_pic->p_sys : NULL);
>               if (test_pic)
>     diff --git a/modules/hw/vdpau/avcodec.c b/modules/hw/vdpau/avcodec.c
>     index 599e86cc06e..e0b94ec55e5 100644
>     --- a/modules/hw/vdpau/avcodec.c
>     +++ b/modules/hw/vdpau/avcodec.c
>     @@ -132,7 +132,8 @@ static void Close(vlc_va_t *va)
>       
>       static const struct vlc_va_operations ops = { Lock, Close, };
>       
>     -static int Open(vlc_va_t *va, AVCodecContext *avctx, enum PixelFormat pix_fmt,
>     +static int Open(vlc_va_t *va, AVCodecContext *avctx, const AVPixFmtDescriptor *desc,
>     +                enum PixelFormat pix_fmt,
>                       const es_format_t *fmt, void *p_sys)
>       {
>           if (pix_fmt != AV_PIX_FMT_VDPAU)
>     @@ -140,6 +141,7 @@ static int Open(vlc_va_t *va, AVCodecContext *avctx, enum PixelFormat pix_fmt,
>       
>           (void) fmt;
>           (void) p_sys;
>     +    (void) desc;
>           void *func;
>           VdpStatus err;
>           VdpChromaType type;
> 
> 
> -- 
> Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser 
> ma brièveté.
> 
> _______________________________________________
> 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