hwcontext_vaapi: Return all formats for constraints without config

No longer make a dummy device configuration to query.  Instead, just
return everything we recognise from the whole format list.  Also
change the device setup code to query that list only, rather than
intersecting it with the constraint output.

This makes hwupload more usable on mesa/gallium where the video
processor only declares support for RGB formats, making it unable to
deal with YUV formats before this patch.  It might introduce some
different trickier failures in the internal upload/download code
because the set of allowed formats there has changed, though I didn't
find any obvious regressions with i965.
pull/237/merge
Mark Thompson 9 years ago
parent 11b8030309
commit fe498ef514
  1. 190
      libavutil/hwcontext_vaapi.c

@ -153,114 +153,100 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
{ {
AVVAAPIDeviceContext *hwctx = hwdev->hwctx; AVVAAPIDeviceContext *hwctx = hwdev->hwctx;
const AVVAAPIHWConfig *config = hwconfig; const AVVAAPIHWConfig *config = hwconfig;
AVVAAPIHWConfig *tmp_config; VAAPIDeviceContext *ctx = hwdev->internal->priv;
VASurfaceAttrib *attr_list = NULL; VASurfaceAttrib *attr_list = NULL;
VAStatus vas; VAStatus vas;
enum AVPixelFormat pix_fmt; enum AVPixelFormat pix_fmt;
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 (!hwconfig) { if (config) {
// No configuration was provided, so we create a temporary pipeline attr_count = 0;
// configuration in order to query all supported image formats. vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id,
0, &attr_count);
tmp_config = av_mallocz(sizeof(*config));
if (!tmp_config)
return AVERROR(ENOMEM);
vas = vaCreateConfig(hwctx->display,
VAProfileNone, VAEntrypointVideoProc,
NULL, 0, &tmp_config->config_id);
if (vas != VA_STATUS_SUCCESS) { if (vas != VA_STATUS_SUCCESS) {
// No vpp. We might still be able to do something useful if av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: "
// codecs are supported, so try to make the most-commonly "%d (%s).\n", vas, vaErrorStr(vas));
// supported decoder configuration we can to query instead. err = AVERROR(ENOSYS);
vas = vaCreateConfig(hwctx->display, goto fail;
VAProfileH264ConstrainedBaseline,
VAEntrypointVLD, NULL, 0,
&tmp_config->config_id);
if (vas != VA_STATUS_SUCCESS) {
av_freep(&tmp_config);
return AVERROR(ENOSYS);
}
} }
config = tmp_config; attr_list = av_malloc(attr_count * sizeof(*attr_list));
} if (!attr_list) {
err = AVERROR(ENOMEM);
attr_count = 0; goto fail;
vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, }
0, &attr_count);
if (vas != VA_STATUS_SUCCESS) {
av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: "
"%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(ENOSYS);
goto fail;
}
attr_list = av_malloc(attr_count * sizeof(*attr_list)); vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id,
if (!attr_list) { attr_list, &attr_count);
err = AVERROR(ENOMEM); if (vas != VA_STATUS_SUCCESS) {
goto fail; av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: "
} "%d (%s).\n", vas, vaErrorStr(vas));
err = AVERROR(ENOSYS);
goto fail;
}
vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, pix_fmt_count = 0;
attr_list, &attr_count); for (i = 0; i < attr_count; i++) {
if (vas != VA_STATUS_SUCCESS) { switch (attr_list[i].type) {
av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: " case VASurfaceAttribPixelFormat:
"%d (%s).\n", vas, vaErrorStr(vas)); fourcc = attr_list[i].value.value.i;
err = AVERROR(ENOSYS); pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc);
goto fail; if (pix_fmt != AV_PIX_FMT_NONE) {
} ++pix_fmt_count;
} else {
// Something unsupported - ignore.
}
break;
case VASurfaceAttribMinWidth:
constraints->min_width = attr_list[i].value.value.i;
break;
case VASurfaceAttribMinHeight:
constraints->min_height = attr_list[i].value.value.i;
break;
case VASurfaceAttribMaxWidth:
constraints->max_width = attr_list[i].value.value.i;
break;
case VASurfaceAttribMaxHeight:
constraints->max_height = attr_list[i].value.value.i;
break;
}
}
if (pix_fmt_count == 0) {
// Nothing usable found. Presumably there exists something which
// works, so leave the set null to indicate unknown.
constraints->valid_sw_formats = NULL;
} else {
constraints->valid_sw_formats = av_malloc_array(pix_fmt_count + 1,
sizeof(pix_fmt));
if (!constraints->valid_sw_formats) {
err = AVERROR(ENOMEM);
goto fail;
}
pix_fmt_count = 0; for (i = j = 0; i < attr_count; i++) {
for (i = 0; i < attr_count; i++) { if (attr_list[i].type != VASurfaceAttribPixelFormat)
switch (attr_list[i].type) { continue;
case VASurfaceAttribPixelFormat: fourcc = attr_list[i].value.value.i;
fourcc = attr_list[i].value.value.i; pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc);
pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); if (pix_fmt != AV_PIX_FMT_NONE)
if (pix_fmt != AV_PIX_FMT_NONE) { constraints->valid_sw_formats[j++] = pix_fmt;
++pix_fmt_count;
} else {
// Something unsupported - ignore.
} }
break; av_assert0(j == pix_fmt_count);
case VASurfaceAttribMinWidth: constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE;
constraints->min_width = attr_list[i].value.value.i;
break;
case VASurfaceAttribMinHeight:
constraints->min_height = attr_list[i].value.value.i;
break;
case VASurfaceAttribMaxWidth:
constraints->max_width = attr_list[i].value.value.i;
break;
case VASurfaceAttribMaxHeight:
constraints->max_height = attr_list[i].value.value.i;
break;
} }
}
if (pix_fmt_count == 0) {
// Nothing usable found. Presumably there exists something which
// works, so leave the set null to indicate unknown.
constraints->valid_sw_formats = NULL;
} else { } else {
constraints->valid_sw_formats = av_malloc_array(pix_fmt_count + 1, // No configuration supplied.
// Return the full set of image formats known by the implementation.
constraints->valid_sw_formats = av_malloc_array(ctx->nb_formats + 1,
sizeof(pix_fmt)); sizeof(pix_fmt));
if (!constraints->valid_sw_formats) { if (!constraints->valid_sw_formats) {
err = AVERROR(ENOMEM); err = AVERROR(ENOMEM);
goto fail; goto fail;
} }
for (i = 0; i < ctx->nb_formats; i++)
for (i = j = 0; i < attr_count; i++) { constraints->valid_sw_formats[i] = ctx->formats[i].pix_fmt;
if (attr_list[i].type != VASurfaceAttribPixelFormat) constraints->valid_sw_formats[i] = AV_PIX_FMT_NONE;
continue;
fourcc = attr_list[i].value.value.i;
pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc);
if (pix_fmt != AV_PIX_FMT_NONE)
constraints->valid_sw_formats[j++] = pix_fmt;
}
av_assert0(j == pix_fmt_count);
constraints->valid_sw_formats[j] = AV_PIX_FMT_NONE;
} }
constraints->valid_hw_formats = av_malloc_array(2, sizeof(pix_fmt)); constraints->valid_hw_formats = av_malloc_array(2, sizeof(pix_fmt));
@ -274,10 +260,6 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
err = 0; err = 0;
fail: fail:
av_freep(&attr_list); av_freep(&attr_list);
if (!hwconfig) {
vaDestroyConfig(hwctx->display, tmp_config->config_id);
av_freep(&tmp_config);
}
return err; return err;
} }
@ -285,21 +267,12 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
{ {
VAAPIDeviceContext *ctx = hwdev->internal->priv; VAAPIDeviceContext *ctx = hwdev->internal->priv;
AVVAAPIDeviceContext *hwctx = hwdev->hwctx; AVVAAPIDeviceContext *hwctx = hwdev->hwctx;
AVHWFramesConstraints *constraints = NULL;
VAImageFormat *image_list = NULL; VAImageFormat *image_list = NULL;
VAStatus vas; VAStatus vas;
int err, i, j, image_count; int err, i, image_count;
enum AVPixelFormat pix_fmt; enum AVPixelFormat pix_fmt;
unsigned int fourcc; unsigned int fourcc;
constraints = av_mallocz(sizeof(*constraints));
if (!constraints)
goto fail;
err = vaapi_frames_get_constraints(hwdev, NULL, constraints);
if (err < 0)
goto fail;
image_count = vaMaxNumImageFormats(hwctx->display); image_count = vaMaxNumImageFormats(hwctx->display);
if (image_count <= 0) { if (image_count <= 0) {
err = AVERROR(EIO); err = AVERROR(EIO);
@ -325,28 +298,23 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
for (i = 0; i < image_count; i++) { for (i = 0; i < image_count; i++) {
fourcc = image_list[i].fourcc; fourcc = image_list[i].fourcc;
pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc);
for (j = 0; constraints->valid_sw_formats[j] != AV_PIX_FMT_NONE; j++) { if (pix_fmt == AV_PIX_FMT_NONE) {
if (pix_fmt == constraints->valid_sw_formats[j]) av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> unknown.\n",
break; fourcc);
} } else {
if (constraints->valid_sw_formats[j] != AV_PIX_FMT_NONE) {
av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n", av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n",
fourcc, av_get_pix_fmt_name(pix_fmt)); fourcc, av_get_pix_fmt_name(pix_fmt));
ctx->formats[ctx->nb_formats].pix_fmt = pix_fmt; ctx->formats[ctx->nb_formats].pix_fmt = pix_fmt;
ctx->formats[ctx->nb_formats].image_format = image_list[i]; ctx->formats[ctx->nb_formats].image_format = image_list[i];
++ctx->nb_formats; ++ctx->nb_formats;
} else {
av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> unknown.\n", fourcc);
} }
} }
av_free(image_list); av_free(image_list);
av_hwframe_constraints_free(&constraints);
return 0; return 0;
fail: fail:
av_freep(&ctx->formats); av_freep(&ctx->formats);
av_free(image_list); av_free(image_list);
av_hwframe_constraints_free(&constraints);
return err; return err;
} }

Loading…
Cancel
Save