Commit e8487d71 authored by Hendrik Leppkes's avatar Hendrik Leppkes

Merge commit 'fe498ef5'

* commit 'fe498ef5':
  hwcontext_vaapi: Return all formats for constraints without config
Merged-by: 's avatarHendrik Leppkes <h.leppkes@gmail.com>
parents 5e872d90 fe498ef5
...@@ -155,114 +155,100 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev, ...@@ -155,114 +155,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));
...@@ -276,10 +262,6 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev, ...@@ -276,10 +262,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;
} }
...@@ -287,21 +269,12 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev) ...@@ -287,21 +269,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);
...@@ -327,28 +300,23 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev) ...@@ -327,28 +300,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;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment