1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00

Merge commit 'fe498ef5144d3712b887f44a0c5e654add99ead7'

* commit 'fe498ef5144d3712b887f44a0c5e654add99ead7':
  hwcontext_vaapi: Return all formats for constraints without config

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
This commit is contained in:
Hendrik Leppkes 2016-10-07 13:19:53 +02:00
commit e8487d71be

View File

@ -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) { vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id,
av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: " attr_list, &attr_count);
"%d (%s).\n", vas, vaErrorStr(vas)); if (vas != VA_STATUS_SUCCESS) {
err = AVERROR(ENOSYS); av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: "
goto fail; "%d (%s).\n", vas, vaErrorStr(vas));
} err = AVERROR(ENOSYS);
goto fail;
attr_list = av_malloc(attr_count * sizeof(*attr_list)); }
if (!attr_list) {
err = AVERROR(ENOMEM); pix_fmt_count = 0;
goto fail; for (i = 0; i < attr_count; i++) {
} switch (attr_list[i].type) {
case VASurfaceAttribPixelFormat:
vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id, fourcc = attr_list[i].value.value.i;
attr_list, &attr_count); pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc);
if (vas != VA_STATUS_SUCCESS) { if (pix_fmt != AV_PIX_FMT_NONE) {
av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: " ++pix_fmt_count;
"%d (%s).\n", vas, vaErrorStr(vas)); } else {
err = AVERROR(ENOSYS); // Something unsupported - ignore.
goto fail; }
} break;
case VASurfaceAttribMinWidth:
pix_fmt_count = 0; constraints->min_width = attr_list[i].value.value.i;
for (i = 0; i < attr_count; i++) { break;
switch (attr_list[i].type) { case VASurfaceAttribMinHeight:
case VASurfaceAttribPixelFormat: constraints->min_height = attr_list[i].value.value.i;
fourcc = attr_list[i].value.value.i; break;
pix_fmt = vaapi_pix_fmt_from_fourcc(fourcc); case VASurfaceAttribMaxWidth:
if (pix_fmt != AV_PIX_FMT_NONE) { constraints->max_width = attr_list[i].value.value.i;
++pix_fmt_count; break;
} else { case VASurfaceAttribMaxHeight:
// Something unsupported - ignore. constraints->max_height = attr_list[i].value.value.i;
} break;
break; }
case VASurfaceAttribMinWidth: }
constraints->min_width = attr_list[i].value.value.i; if (pix_fmt_count == 0) {
break; // Nothing usable found. Presumably there exists something which
case VASurfaceAttribMinHeight: // works, so leave the set null to indicate unknown.
constraints->min_height = attr_list[i].value.value.i; constraints->valid_sw_formats = NULL;
break; } else {
case VASurfaceAttribMaxWidth: constraints->valid_sw_formats = av_malloc_array(pix_fmt_count + 1,
constraints->max_width = attr_list[i].value.value.i; sizeof(pix_fmt));
break; if (!constraints->valid_sw_formats) {
case VASurfaceAttribMaxHeight: err = AVERROR(ENOMEM);
constraints->max_height = attr_list[i].value.value.i; goto fail;
break; }
for (i = j = 0; i < attr_count; i++) {
if (attr_list[i].type != VASurfaceAttribPixelFormat)
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;
} }
}
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,
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)
{ {
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)
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;
} }