hwcontext_vaapi: Try to support the VDPAU wrapper

The driver is somewhat bitrotten (not updated for years) but is still
usable for decoding with this change.  To support it, this adds a new
driver quirk to indicate no support at all for surface attributes.

Based on a patch by wm4 <nfxjfg@googlemail.com>.

(cherry picked from commit e791b915c7)
This commit is contained in:
Mark Thompson 2017-01-30 19:11:28 +00:00
parent 204008354f
commit f2e4fb61af
2 changed files with 52 additions and 34 deletions

View File

@ -155,7 +155,8 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
unsigned int fourcc; unsigned int fourcc;
int err, i, j, attr_count, pix_fmt_count; int err, i, j, attr_count, pix_fmt_count;
if (config) { if (config &&
!(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) {
attr_count = 0; attr_count = 0;
vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id,
0, &attr_count); 0, &attr_count);
@ -273,6 +274,11 @@ static const struct {
"ubit", "ubit",
AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE, AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE,
}, },
{
"VDPAU wrapper",
"Splitted-Desktop Systems VDPAU backend for VA-API",
AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES,
},
}; };
static int vaapi_device_init(AVHWDeviceContext *hwdev) static int vaapi_device_init(AVHWDeviceContext *hwdev)
@ -451,43 +457,48 @@ static int vaapi_frames_init(AVHWFramesContext *hwfc)
} }
if (!hwfc->pool) { if (!hwfc->pool) {
int need_memory_type = !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE); if (!(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) {
int need_pixel_format = 1; int need_memory_type = !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE);
for (i = 0; i < avfc->nb_attributes; i++) { int need_pixel_format = 1;
if (ctx->attributes[i].type == VASurfaceAttribMemoryType) for (i = 0; i < avfc->nb_attributes; i++) {
need_memory_type = 0; if (ctx->attributes[i].type == VASurfaceAttribMemoryType)
if (ctx->attributes[i].type == VASurfaceAttribPixelFormat) need_memory_type = 0;
need_pixel_format = 0; if (ctx->attributes[i].type == VASurfaceAttribPixelFormat)
} need_pixel_format = 0;
ctx->nb_attributes = }
avfc->nb_attributes + need_memory_type + need_pixel_format; ctx->nb_attributes =
avfc->nb_attributes + need_memory_type + need_pixel_format;
ctx->attributes = av_malloc(ctx->nb_attributes * ctx->attributes = av_malloc(ctx->nb_attributes *
sizeof(*ctx->attributes)); sizeof(*ctx->attributes));
if (!ctx->attributes) { if (!ctx->attributes) {
err = AVERROR(ENOMEM); err = AVERROR(ENOMEM);
goto fail; goto fail;
} }
for (i = 0; i < avfc->nb_attributes; i++) for (i = 0; i < avfc->nb_attributes; i++)
ctx->attributes[i] = avfc->attributes[i]; ctx->attributes[i] = avfc->attributes[i];
if (need_memory_type) { if (need_memory_type) {
ctx->attributes[i++] = (VASurfaceAttrib) { ctx->attributes[i++] = (VASurfaceAttrib) {
.type = VASurfaceAttribMemoryType, .type = VASurfaceAttribMemoryType,
.flags = VA_SURFACE_ATTRIB_SETTABLE, .flags = VA_SURFACE_ATTRIB_SETTABLE,
.value.type = VAGenericValueTypeInteger, .value.type = VAGenericValueTypeInteger,
.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA, .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA,
}; };
}
if (need_pixel_format) {
ctx->attributes[i++] = (VASurfaceAttrib) {
.type = VASurfaceAttribPixelFormat,
.flags = VA_SURFACE_ATTRIB_SETTABLE,
.value.type = VAGenericValueTypeInteger,
.value.value.i = fourcc,
};
}
av_assert0(i == ctx->nb_attributes);
} else {
ctx->attributes = NULL;
ctx->nb_attributes = 0;
} }
if (need_pixel_format) {
ctx->attributes[i++] = (VASurfaceAttrib) {
.type = VASurfaceAttribPixelFormat,
.flags = VA_SURFACE_ATTRIB_SETTABLE,
.value.type = VAGenericValueTypeInteger,
.value.value.i = fourcc,
};
}
av_assert0(i == ctx->nb_attributes);
ctx->rt_format = rt_format; ctx->rt_format = rt_format;

View File

@ -51,6 +51,13 @@ enum {
* so the surface allocation code will not try to use it. * so the surface allocation code will not try to use it.
*/ */
AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2), AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2),
/**
* The driver does not support surface attributes at all.
* The surface allocation code will never pass them to surface allocation,
* and the results of the vaQuerySurfaceAttributes() call will be faked.
*/
AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES = (1 << 3),
}; };
/** /**