mirror of https://git.ffmpeg.org/ffmpeg.git
Merge commit 'b8bf9194af602cf3a4bcd19a5e278e3d6d69f8fa'
* commit 'b8bf9194af602cf3a4bcd19a5e278e3d6d69f8fa': hwcontext_vaapi: implement device creation Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
This commit is contained in:
commit
ed5d03ff6f
|
@ -16,6 +16,21 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if HAVE_VAAPI_X11
|
||||||
|
# include <va/va_x11.h>
|
||||||
|
#endif
|
||||||
|
#if HAVE_VAAPI_DRM
|
||||||
|
# include <va/va_drm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#if HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "avassert.h"
|
#include "avassert.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -26,6 +41,14 @@
|
||||||
#include "pixdesc.h"
|
#include "pixdesc.h"
|
||||||
#include "pixfmt.h"
|
#include "pixfmt.h"
|
||||||
|
|
||||||
|
typedef struct VAAPIDevicePriv {
|
||||||
|
#if HAVE_VAAPI_X11
|
||||||
|
Display *x11_display;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int drm_fd;
|
||||||
|
} VAAPIDevicePriv;
|
||||||
|
|
||||||
typedef struct VAAPISurfaceFormat {
|
typedef struct VAAPISurfaceFormat {
|
||||||
enum AVPixelFormat pix_fmt;
|
enum AVPixelFormat pix_fmt;
|
||||||
VAImageFormat image_format;
|
VAImageFormat image_format;
|
||||||
|
@ -823,6 +846,105 @@ fail:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vaapi_device_free(AVHWDeviceContext *ctx)
|
||||||
|
{
|
||||||
|
AVVAAPIDeviceContext *hwctx = ctx->hwctx;
|
||||||
|
VAAPIDevicePriv *priv = ctx->user_opaque;
|
||||||
|
|
||||||
|
if (hwctx->display)
|
||||||
|
vaTerminate(hwctx->display);
|
||||||
|
|
||||||
|
#if HAVE_VAAPI_X11
|
||||||
|
if (priv->x11_display)
|
||||||
|
XCloseDisplay(priv->x11_display);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (priv->drm_fd >= 0)
|
||||||
|
close(priv->drm_fd);
|
||||||
|
|
||||||
|
av_freep(&priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device,
|
||||||
|
AVDictionary *opts, int flags)
|
||||||
|
{
|
||||||
|
AVVAAPIDeviceContext *hwctx = ctx->hwctx;
|
||||||
|
VAAPIDevicePriv *priv;
|
||||||
|
VADisplay display = 0;
|
||||||
|
VAStatus vas;
|
||||||
|
int major, minor;
|
||||||
|
|
||||||
|
priv = av_mallocz(sizeof(*priv));
|
||||||
|
if (!priv)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
priv->drm_fd = -1;
|
||||||
|
|
||||||
|
ctx->user_opaque = priv;
|
||||||
|
ctx->free = vaapi_device_free;
|
||||||
|
|
||||||
|
#if HAVE_VAAPI_X11
|
||||||
|
if (!display && !(device && device[0] == '/')) {
|
||||||
|
// Try to open the device as an X11 display.
|
||||||
|
priv->x11_display = XOpenDisplay(device);
|
||||||
|
if (!priv->x11_display) {
|
||||||
|
av_log(ctx, AV_LOG_VERBOSE, "Cannot open X11 display "
|
||||||
|
"%s.\n", XDisplayName(device));
|
||||||
|
} else {
|
||||||
|
display = vaGetDisplay(priv->x11_display);
|
||||||
|
if (!display) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display "
|
||||||
|
"from X11 display %s.\n", XDisplayName(device));
|
||||||
|
return AVERROR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via "
|
||||||
|
"X11 display %s.\n", XDisplayName(device));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_VAAPI_DRM
|
||||||
|
if (!display && device) {
|
||||||
|
// Try to open the device as a DRM path.
|
||||||
|
priv->drm_fd = open(device, O_RDWR);
|
||||||
|
if (priv->drm_fd < 0) {
|
||||||
|
av_log(ctx, AV_LOG_VERBOSE, "Cannot open DRM device %s.\n",
|
||||||
|
device);
|
||||||
|
} else {
|
||||||
|
display = vaGetDisplayDRM(priv->drm_fd);
|
||||||
|
if (!display) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display "
|
||||||
|
"from DRM device %s.\n", device);
|
||||||
|
return AVERROR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via "
|
||||||
|
"DRM device %s.\n", device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!display) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "No VA display found for "
|
||||||
|
"device: %s.\n", device ? device : "");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
hwctx->display = display;
|
||||||
|
|
||||||
|
vas = vaInitialize(display, &major, &minor);
|
||||||
|
if (vas != VA_STATUS_SUCCESS) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI "
|
||||||
|
"connection: %d (%s).\n", vas, vaErrorStr(vas));
|
||||||
|
return AVERROR(EIO);
|
||||||
|
}
|
||||||
|
av_log(ctx, AV_LOG_VERBOSE, "Initialised VAAPI connection: "
|
||||||
|
"version %d.%d\n", major, minor);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const HWContextType ff_hwcontext_type_vaapi = {
|
const HWContextType ff_hwcontext_type_vaapi = {
|
||||||
.type = AV_HWDEVICE_TYPE_VAAPI,
|
.type = AV_HWDEVICE_TYPE_VAAPI,
|
||||||
.name = "VAAPI",
|
.name = "VAAPI",
|
||||||
|
@ -833,6 +955,7 @@ const HWContextType ff_hwcontext_type_vaapi = {
|
||||||
.frames_hwctx_size = sizeof(AVVAAPIFramesContext),
|
.frames_hwctx_size = sizeof(AVVAAPIFramesContext),
|
||||||
.frames_priv_size = sizeof(VAAPIFramesContext),
|
.frames_priv_size = sizeof(VAAPIFramesContext),
|
||||||
|
|
||||||
|
.device_create = &vaapi_device_create,
|
||||||
.device_init = &vaapi_device_init,
|
.device_init = &vaapi_device_init,
|
||||||
.device_uninit = &vaapi_device_uninit,
|
.device_uninit = &vaapi_device_uninit,
|
||||||
.frames_get_constraints = &vaapi_frames_get_constraints,
|
.frames_get_constraints = &vaapi_frames_get_constraints,
|
||||||
|
|
Loading…
Reference in New Issue