Browse Source

hwcontext_vaapi: implement device creation

tags/n3.1
Anton Khirnov 9 years ago
parent
commit
b8bf9194af
1 changed files with 123 additions and 0 deletions
  1. +123
    -0
      libavutil/hwcontext_vaapi.c

+ 123
- 0
libavutil/hwcontext_vaapi.c View File

@@ -16,6 +16,21 @@
* 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 "buffer.h"
#include "common.h"
@@ -26,6 +41,14 @@
#include "pixdesc.h"
#include "pixfmt.h"

typedef struct VAAPIDevicePriv {
#if HAVE_VAAPI_X11
Display *x11_display;
#endif

int drm_fd;
} VAAPIDevicePriv;

typedef struct VAAPISurfaceFormat {
enum AVPixelFormat pix_fmt;
VAImageFormat image_format;
@@ -823,6 +846,105 @@ fail:
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 = {
.type = AV_HWDEVICE_TYPE_VAAPI,
.name = "VAAPI",
@@ -833,6 +955,7 @@ const HWContextType ff_hwcontext_type_vaapi = {
.frames_hwctx_size = sizeof(AVVAAPIFramesContext),
.frames_priv_size = sizeof(VAAPIFramesContext),

.device_create = &vaapi_device_create,
.device_init = &vaapi_device_init,
.device_uninit = &vaapi_device_uninit,
.frames_get_constraints = &vaapi_frames_get_constraints,


Loading…
Cancel
Save