avcodec: va: pass the software format description to the VA

The codec profile alone doesn't always give information on the bit depth or
chroma subsampling (see HEVC Range Extension).

(cherry picked from commit c8a1298cec) (edited)

edited:
* on 3.0 the picture_sys_t is passed to the VA
* on 3.0 the directx_sys_t is not const
* on 4.0 FindVideoServiceConversion returns the matching decoder GUID

Signed-off-by: Steve Lhomme <robux4@ycbcr.xyz>
This commit is contained in:
Steve Lhomme 2019-10-04 10:04:28 +02:00
parent fb75641be0
commit 529391522a
9 changed files with 34 additions and 19 deletions

View File

@ -55,7 +55,7 @@
#define D3D_DecoderSurface ID3D11VideoDecoderOutputView
#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 *, picture_sys_t *p_sys);
static void Close(vlc_va_t *, void **);
@ -307,7 +307,8 @@ static void Close(vlc_va_t *va, void **ctx)
free(sys);
}
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, picture_sys_t *p_sys)
{
int err = VLC_EGENERIC;
@ -398,7 +399,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
if (err!=VLC_SUCCESS)
goto error;
err = directx_va_Setup(va, &sys->dx_sys, ctx, fmt, isXboxHardware(&sys->d3d_dev));
err = directx_va_Setup(va, &sys->dx_sys, ctx, desc, fmt, isXboxHardware(&sys->d3d_dev));
if (err != VLC_SUCCESS)
goto error;

View File

@ -274,7 +274,8 @@ static const directx_va_mode_t DXVA_MODES[] = {
{ NULL, NULL, 0, NULL }
};
static int FindVideoServiceConversion(vlc_va_t *, directx_sys_t *, const es_format_t *, const AVCodecContext *);
static int FindVideoServiceConversion(vlc_va_t *, directx_sys_t *, const es_format_t *,
const AVCodecContext *, const AVPixFmtDescriptor *);
char *directx_va_GetDecoderName(const GUID *guid)
{
@ -290,11 +291,12 @@ char *directx_va_GetDecoderName(const GUID *guid)
}
/* */
int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, const AVCodecContext *avctx,
int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys,
const AVCodecContext *avctx, const AVPixFmtDescriptor *desc,
const es_format_t *fmt, int flag_xbox)
{
/* */
if (FindVideoServiceConversion(va, dx_sys, fmt, avctx)) {
if (FindVideoServiceConversion(va, dx_sys, fmt, avctx, desc)) {
msg_Err(va, "FindVideoServiceConversion failed");
return VLC_EGENERIC;
}
@ -396,7 +398,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, directx_sys_t *dx_sys,
const es_format_t *fmt, const AVCodecContext *avctx)
const es_format_t *fmt,
const AVCodecContext *avctx, const AVPixFmtDescriptor *desc)
{
input_list_t p_list = { 0 };
int err = dx_sys->pf_get_input_list(va, &p_list);

View File

@ -80,7 +80,8 @@ typedef struct
int directx_va_Open(vlc_va_t *, directx_sys_t *);
void directx_va_Close(vlc_va_t *, directx_sys_t *);
int directx_va_Setup(vlc_va_t *, directx_sys_t *, const AVCodecContext *avctx, const es_format_t *, int flag_xbox);
int directx_va_Setup(vlc_va_t *, directx_sys_t *, const AVCodecContext *, const AVPixFmtDescriptor *,
const es_format_t *, int flag_xbox);
char *directx_va_GetDecoderName(const GUID *guid);
bool directx_va_canUseDecoder(vlc_va_t *, UINT VendorId, UINT DeviceId, const GUID *pCodec, UINT driverBuild);

View File

@ -43,7 +43,7 @@
#define D3D_DecoderSurface IDirect3DSurface9
#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 *, picture_sys_t *p_sys);
static void Close(vlc_va_t *, void **);
@ -254,7 +254,8 @@ static void Close(vlc_va_t *va, void **ctx)
free(sys);
}
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, picture_sys_t *p_sys)
{
int err = VLC_EGENERIC;
@ -315,7 +316,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
if (err!=VLC_SUCCESS)
goto error;
err = directx_va_Setup(va, &sys->dx_sys, ctx, fmt, 0);
err = directx_va_Setup(va, &sys->dx_sys, ctx, desc, fmt, 0);
if (err != VLC_SUCCESS)
goto error;

View File

@ -96,13 +96,14 @@ static int vlc_va_Start(void *func, 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 *);
picture_sys_t *p_sys = va_arg(ap, picture_sys_t *);
int (*open)(vlc_va_t *, AVCodecContext *, enum PixelFormat,
int (*open)(vlc_va_t *, AVCodecContext *, const AVPixFmtDescriptor *, enum PixelFormat,
const es_format_t *, picture_sys_t *) = func;
return open(va, ctx, pix_fmt, fmt, p_sys);
return open(va, ctx, src_desc, pix_fmt, fmt, p_sys);
}
static void vlc_va_Stop(void *func, va_list ap)
@ -114,7 +115,8 @@ static void vlc_va_Stop(void *func, va_list ap)
close(va, hwctx);
}
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,
picture_sys_t *p_sys)
{
@ -125,7 +127,7 @@ vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *avctx,
char *modlist = var_InheritString(obj, "avcodec-hw");
va->module = vlc_module_load(va, "hw decoder", modlist, true,
vlc_va_Start, va, avctx, pix_fmt, fmt, p_sys);
vlc_va_Start, va, avctx, src_desc, pix_fmt, fmt, p_sys);
free(modlist);
if (va->module == NULL)
{

View File

@ -25,6 +25,7 @@
#ifndef VLC_AVCODEC_VA_H
#define VLC_AVCODEC_VA_H 1
#include <libavutil/pixdesc.h>
typedef struct vlc_va_t vlc_va_t;
typedef struct vlc_va_sys_t vlc_va_sys_t;
@ -54,7 +55,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,
picture_sys_t *p_sys);

View File

@ -151,9 +151,11 @@ static void Delete(vlc_va_t *va, void **hwctx)
free(sys);
}
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, picture_sys_t *p_sys)
{
VLC_UNUSED(desc);
if (pix_fmt != AV_PIX_FMT_VAAPI || p_sys == NULL)
return VLC_EGENERIC;

View File

@ -1631,6 +1631,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;
@ -1657,7 +1659,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)

View File

@ -108,7 +108,8 @@ static int Lock(vlc_va_t *va, picture_t *pic, uint8_t **data)
return VLC_SUCCESS;
}
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, picture_sys_t *p_sys)
{
if (pix_fmt != AV_PIX_FMT_VDPAU)
@ -116,6 +117,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;