|
|
|
@ -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, |
|
|
|
|