mirror of https://git.ffmpeg.org/ffmpeg.git
hwcontext_vaapi: Only accept a render node when deriving from DRM device
If we are given a non-render node, try to find the matching render node and fail if that isn't possible. libva will not accept a non-render device which is not DRM master, because it requires legacy DRM authentication to succeed in that case: <https://github.com/intel/libva/blob/master/va/drm/va_drm.c#L68-L75>. This is annoying for kmsgrab because in most recording situations DRM master is already held by something else (such as a windowing system), leading to device derivation not working and forcing the user to create the target VAAPI device separately.
This commit is contained in:
parent
a7b92cb559
commit
bc9b6358fb
|
@ -1631,6 +1631,7 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx,
|
||||||
AVDRMDeviceContext *src_hwctx = src_ctx->hwctx;
|
AVDRMDeviceContext *src_hwctx = src_ctx->hwctx;
|
||||||
VADisplay *display;
|
VADisplay *display;
|
||||||
VAAPIDevicePriv *priv;
|
VAAPIDevicePriv *priv;
|
||||||
|
int fd;
|
||||||
|
|
||||||
if (src_hwctx->fd < 0) {
|
if (src_hwctx->fd < 0) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated "
|
av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated "
|
||||||
|
@ -1638,17 +1639,56 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx,
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_LIBDRM
|
||||||
|
{
|
||||||
|
int node_type = drmGetNodeTypeFromFd(src_hwctx->fd);
|
||||||
|
char *render_node;
|
||||||
|
if (node_type < 0) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "DRM instance fd does not appear "
|
||||||
|
"to refer to a DRM device.\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
if (node_type == DRM_NODE_RENDER) {
|
||||||
|
fd = src_hwctx->fd;
|
||||||
|
} else {
|
||||||
|
render_node = drmGetRenderDeviceNameFromFd(src_hwctx->fd);
|
||||||
|
if (!render_node) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Failed to find a render node "
|
||||||
|
"matching the DRM device.\n");
|
||||||
|
return AVERROR(ENODEV);
|
||||||
|
}
|
||||||
|
fd = open(render_node, O_RDWR);
|
||||||
|
if (fd < 0) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Failed to open render node %s"
|
||||||
|
"matching the DRM device.\n", render_node);
|
||||||
|
free(render_node);
|
||||||
|
return AVERROR(errno);
|
||||||
|
}
|
||||||
|
av_log(ctx, AV_LOG_VERBOSE, "Using render node %s in place "
|
||||||
|
"of non-render DRM device.\n", render_node);
|
||||||
|
free(render_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fd = src_hwctx->fd;
|
||||||
|
#endif
|
||||||
|
|
||||||
priv = av_mallocz(sizeof(*priv));
|
priv = av_mallocz(sizeof(*priv));
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
// Inherits the fd from the source context, which will close it.
|
if (fd == src_hwctx->fd) {
|
||||||
|
// The fd is inherited from the source context and we are holding
|
||||||
|
// a reference to that, we don't want to close it from here.
|
||||||
priv->drm_fd = -1;
|
priv->drm_fd = -1;
|
||||||
|
} else {
|
||||||
|
priv->drm_fd = fd;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->user_opaque = priv;
|
ctx->user_opaque = priv;
|
||||||
ctx->free = &vaapi_device_free;
|
ctx->free = &vaapi_device_free;
|
||||||
|
|
||||||
display = vaGetDisplayDRM(src_hwctx->fd);
|
display = vaGetDisplayDRM(fd);
|
||||||
if (!display) {
|
if (!display) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from "
|
av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from "
|
||||||
"DRM device.\n");
|
"DRM device.\n");
|
||||||
|
|
Loading…
Reference in New Issue