summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Uskov <ivan.uskov@nablet.com>2015-06-30 20:13:09 +0300
committerMichael Niedermayer <michaelni@gmx.at>2015-07-02 15:05:56 +0200
commitdb89f45535aa3e99bceb5f6bf957c90e7ca39841 (patch)
tree2d4ce508ade131ba4dca4fb6cef7d55ade28209c
parent8cbce1001db365bab58304609692003f29407541 (diff)
avcodec/qsv: Extending QSV/MFX session initialization for the linux platform where a display handle is required.
Now ff_qsv_init_internal_session() is able to find appropriate display handle under linux using VAAPI. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/qsv.c70
-rw-r--r--libavcodec/qsv_internal.h17
2 files changed, 86 insertions, 1 deletions
diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 31be9d1fa3..714c7948cb 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -77,6 +77,21 @@ int ff_qsv_error(int mfx_err)
}
}
+/**
+ * @brief Initialize a MSDK session
+ *
+ * Media SDK is based on sessions, so this is the prerequisite
+ * initialization for HW acceleration. For Windows the session is
+ * complete and ready to use, for Linux a display handle is
+ * required. For releases of Media Server Studio >= 2015 R4 the
+ * render nodes interface is preferred (/dev/dri/renderD).
+ * Using Media Server Studio 2015 R4 or newer is recommended
+ * but the older /dev/dri/card interface is also searched
+ * for broader compatibility.
+ *
+ * @param avctx ffmpeg metadata for this codec context
+ * @param session the MSDK session used
+ */
int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session)
{
mfxIMPL impl = MFX_IMPL_AUTO_ANY;
@@ -91,6 +106,61 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session)
return ff_qsv_error(ret);
}
+
+ // this code is only required for Linux. It searches for a valid
+ // display handle. First in /dev/dri/renderD then in /dev/dri/card
+#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
+ // VAAPI display handle
+ VADisplay va_dpy = NULL;
+ VAStatus va_res = VA_STATUS_SUCCESS;
+ int major_version = 0, minor_version = 0;
+ int fd = -1;
+ char adapterpath[256];
+ int adapter_num;
+
+ //search for valid graphics device
+ for (adapter_num = 0;adapter_num < 6;adapter_num++) {
+
+ if (adapter_num<3) {
+ snprintf(adapterpath,sizeof(adapterpath),
+ "/dev/dri/renderD%d", adapter_num+128);
+ } else {
+ snprintf(adapterpath,sizeof(adapterpath),
+ "/dev/dri/card%d", adapter_num-3);
+ }
+
+ fd = open(adapterpath, O_RDWR);
+ if (fd < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "mfx init: %s fd open failed\n", adapterpath);
+ continue;
+ }
+
+ va_dpy = vaGetDisplayDRM(fd);
+ if (!va_dpy) {
+ av_log(avctx, AV_LOG_ERROR,
+ "mfx init: %s vaGetDisplayDRM failed\n", adapterpath);
+ close(fd);
+ continue;
+ }
+
+ va_res = vaInitialize(va_dpy, &major_version, &minor_version);
+ if (VA_STATUS_SUCCESS != va_res) {
+ av_log(avctx, AV_LOG_ERROR,
+ "mfx init: %s vaInitialize failed\n", adapterpath);
+ close(fd);
+ fd = -1;
+ continue;
+ } else {
+ av_log(avctx, AV_LOG_VERBOSE,
+ "mfx initialization: %s vaInitialize successful\n",adapterpath);
+ break;
+ }
+ }
+ MFXVideoCORE_SetHandle((*session), (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)va_dpy);
+
+#endif //AVCODEC_QSV_LINUX_SESSION_HANDLE
+
MFXQueryIMPL(*session, &impl);
switch (MFX_IMPL_BASETYPE(impl)) {
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 86fca5fd8c..ae03bf3ae8 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -21,12 +21,27 @@
#ifndef AVCODEC_QSV_INTERNAL_H
#define AVCODEC_QSV_INTERNAL_H
+#if CONFIG_VAAPI
+#define AVCODEC_QSV_LINUX_SESSION_HANDLE
+#endif //CONFIG_VAAPI
+
+#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <va/va.h>
+#include <va/va_drm.h>
+#endif
+
#include <mfx/mfxvideo.h>
#include "libavutil/frame.h"
#define QSV_VERSION_MAJOR 1
-#define QSV_VERSION_MINOR 1
+#define QSV_VERSION_MINOR 9
#define ASYNC_DEPTH_DEFAULT 4 // internal parallelism