From 8e4445c6bb161457cadaa39af79b6de40a216715 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 16:33:15 +0200 Subject: hwcontext_vdpau: implement device creation --- configure | 3 +- libavutil/hwcontext_vdpau.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 43c563f16c..261200d511 100755 --- a/configure +++ b/configure @@ -4766,8 +4766,7 @@ enabled vdpau && disable vdpau enabled vdpau && enabled xlib && - check_func_headers "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau && - prepend avconv_libs $($ldflags_filter "-lvdpau") && + check_lib2 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau && enable vdpau_x11 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" diff --git a/libavutil/hwcontext_vdpau.c b/libavutil/hwcontext_vdpau.c index faae5f8641..9722c10b87 100644 --- a/libavutil/hwcontext_vdpau.c +++ b/libavutil/hwcontext_vdpau.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #include #include @@ -388,6 +390,82 @@ static int vdpau_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, return 0; } +#if HAVE_VDPAU_X11 +#include +#include + +typedef struct VDPAUDevicePriv { + VdpDeviceDestroy *device_destroy; + Display *dpy; +} VDPAUDevicePriv; + +static void vdpau_device_free(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDevicePriv *priv = ctx->user_opaque; + + if (priv->device_destroy) + priv->device_destroy(hwctx->device); + if (priv->dpy) + XCloseDisplay(priv->dpy); + av_freep(&priv); +} + +static int vdpau_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + + VDPAUDevicePriv *priv; + VdpStatus err; + VdpGetInformationString *get_information_string; + const char *display, *vendor; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = vdpau_device_free; + + priv->dpy = XOpenDisplay(device); + if (!priv->dpy) { + av_log(ctx, AV_LOG_ERROR, "Cannot open the X11 display %s.\n", + XDisplayName(device)); + return AVERROR_UNKNOWN; + } + display = XDisplayString(priv->dpy); + + err = vdp_device_create_x11(priv->dpy, XDefaultScreen(priv->dpy), + &hwctx->device, &hwctx->get_proc_address); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "VDPAU device creation on X11 display %s failed.\n", + display); + return AVERROR_UNKNOWN; + } + +#define GET_CALLBACK(id, result) \ +do { \ + void *tmp; \ + err = hwctx->get_proc_address(hwctx->device, id, &tmp); \ + if (err != VDP_STATUS_OK) { \ + av_log(ctx, AV_LOG_ERROR, "Error getting the " #id " callback.\n"); \ + return AVERROR_UNKNOWN; \ + } \ + result = tmp; \ +} while (0) + + GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string); + GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, priv->device_destroy); + + get_information_string(&vendor); + av_log(ctx, AV_LOG_VERBOSE, "Successfully created a VDPAU device (%s) on " + "X11 display %s\n", vendor, display); + + return 0; +} +#endif + const HWContextType ff_hwcontext_type_vdpau = { .type = AV_HWDEVICE_TYPE_VDPAU, .name = "VDPAU", @@ -396,6 +474,9 @@ const HWContextType ff_hwcontext_type_vdpau = { .device_priv_size = sizeof(VDPAUDeviceContext), .frames_priv_size = sizeof(VDPAUFramesContext), +#if HAVE_VDPAU_X11 + .device_create = vdpau_device_create, +#endif .device_init = vdpau_device_init, .device_uninit = vdpau_device_uninit, .frames_init = vdpau_frames_init, -- cgit v1.2.3