*/
#include <mfx/mfxvideo.h>
+#include <mfx/mfxplugin.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libavutil/avstring.h"
#include "libavutil/error.h"
#include "avcodec.h"
switch (codec_id) {
case AV_CODEC_ID_H264:
return MFX_CODEC_AVC;
+#if QSV_VERSION_ATLEAST(1, 8)
+ case AV_CODEC_ID_HEVC:
+ return MFX_CODEC_HEVC;
+#endif
case AV_CODEC_ID_MPEG1VIDEO:
case AV_CODEC_ID_MPEG2VIDEO:
return MFX_CODEC_MPEG2;
return AVERROR_UNKNOWN;
}
}
+static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
+{
+ // 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
+ int ret = 0;
+ 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;
+ }
-int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session)
+ 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);
+ ret = MFXVideoCORE_SetHandle(session,
+ (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)va_dpy);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error %d during set display handle\n", ret);
+ return ff_qsv_error(ret);
+ }
+ break;
+ }
+ }
+#endif //AVCODEC_QSV_LINUX_SESSION_HANDLE
+ return 0;
+}
+/**
+ * @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,
+ const char *load_plugins)
{
mfxIMPL impl = MFX_IMPL_AUTO_ANY;
mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
return ff_qsv_error(ret);
}
+ ret = ff_qsv_set_display_handle(avctx, *session);
+ if (ret < 0)
+ return ret;
+
MFXQueryIMPL(*session, &impl);
switch (MFX_IMPL_BASETYPE(impl)) {
desc = "unknown";
}
+ if (load_plugins && *load_plugins) {
+ while (*load_plugins) {
+ mfxPluginUID uid;
+ int i, err = 0;
+
+ char *plugin = av_get_token(&load_plugins, ":");
+ if (!plugin)
+ return AVERROR(ENOMEM);
+ if (strlen(plugin) != 2 * sizeof(uid.Data)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID length\n");
+ err = AVERROR(EINVAL);
+ goto load_plugin_fail;
+ }
+
+ for (i = 0; i < sizeof(uid.Data); i++) {
+ err = sscanf(plugin + 2 * i, "%2hhx", uid.Data + i);
+ if (err != 1) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID\n");
+ err = AVERROR(EINVAL);
+ goto load_plugin_fail;
+ }
+
+ }
+
+ ret = MFXVideoUSER_Load(*session, &uid, 1);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n",
+ plugin);
+ err = ff_qsv_error(ret);
+ goto load_plugin_fail;
+ }
+
+load_plugin_fail:
+ av_freep(&plugin);
+ if (err < 0)
+ return err;
+ }
+ }
+
av_log(avctx, AV_LOG_VERBOSE,
"Initialized an internal MFX session using %s implementation\n",
desc);