2 * Intel MediaSDK QSV encoder/decoder shared code
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <mfx/mfxvideo.h>
23 #include "libavutil/error.h"
26 #include "qsv_internal.h"
28 int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
31 case AV_CODEC_ID_H264:
33 case AV_CODEC_ID_MPEG1VIDEO:
34 case AV_CODEC_ID_MPEG2VIDEO:
35 return MFX_CODEC_MPEG2;
42 return AVERROR(ENOSYS);
45 int ff_qsv_error(int mfx_err)
50 case MFX_ERR_MEMORY_ALLOC:
51 case MFX_ERR_NOT_ENOUGH_BUFFER:
52 return AVERROR(ENOMEM);
53 case MFX_ERR_INVALID_HANDLE:
54 return AVERROR(EINVAL);
55 case MFX_ERR_DEVICE_FAILED:
56 case MFX_ERR_DEVICE_LOST:
57 case MFX_ERR_LOCK_MEMORY:
59 case MFX_ERR_NULL_PTR:
60 case MFX_ERR_UNDEFINED_BEHAVIOR:
61 case MFX_ERR_NOT_INITIALIZED:
63 case MFX_ERR_UNSUPPORTED:
64 case MFX_ERR_NOT_FOUND:
65 return AVERROR(ENOSYS);
66 case MFX_ERR_MORE_DATA:
67 case MFX_ERR_MORE_SURFACE:
68 case MFX_ERR_MORE_BITSTREAM:
69 return AVERROR(EAGAIN);
70 case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM:
71 case MFX_ERR_INVALID_VIDEO_PARAM:
72 return AVERROR(EINVAL);
76 return AVERROR_UNKNOWN;
79 static int ff_qsv_set_display_handle(AVCodecContext *avctx, mfxSession session)
81 // this code is only required for Linux. It searches for a valid
82 // display handle. First in /dev/dri/renderD then in /dev/dri/card
83 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
84 // VAAPI display handle
86 VADisplay va_dpy = NULL;
87 VAStatus va_res = VA_STATUS_SUCCESS;
88 int major_version = 0, minor_version = 0;
90 char adapterpath[256];
93 //search for valid graphics device
94 for (adapter_num = 0;adapter_num < 6;adapter_num++) {
97 snprintf(adapterpath,sizeof(adapterpath),
98 "/dev/dri/renderD%d", adapter_num+128);
100 snprintf(adapterpath,sizeof(adapterpath),
101 "/dev/dri/card%d", adapter_num-3);
104 fd = open(adapterpath, O_RDWR);
106 av_log(avctx, AV_LOG_ERROR,
107 "mfx init: %s fd open failed\n", adapterpath);
111 va_dpy = vaGetDisplayDRM(fd);
113 av_log(avctx, AV_LOG_ERROR,
114 "mfx init: %s vaGetDisplayDRM failed\n", adapterpath);
119 va_res = vaInitialize(va_dpy, &major_version, &minor_version);
120 if (VA_STATUS_SUCCESS != va_res) {
121 av_log(avctx, AV_LOG_ERROR,
122 "mfx init: %s vaInitialize failed\n", adapterpath);
127 av_log(avctx, AV_LOG_VERBOSE,
128 "mfx initialization: %s vaInitialize successful\n",adapterpath);
129 ret = MFXVideoCORE_SetHandle(session,
130 (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)va_dpy);
132 av_log(avctx, AV_LOG_ERROR,
133 "Error %d during set display handle\n", ret);
134 return ff_qsv_error(ret);
139 #endif //AVCODEC_QSV_LINUX_SESSION_HANDLE
143 * @brief Initialize a MSDK session
145 * Media SDK is based on sessions, so this is the prerequisite
146 * initialization for HW acceleration. For Windows the session is
147 * complete and ready to use, for Linux a display handle is
148 * required. For releases of Media Server Studio >= 2015 R4 the
149 * render nodes interface is preferred (/dev/dri/renderD).
150 * Using Media Server Studio 2015 R4 or newer is recommended
151 * but the older /dev/dri/card interface is also searched
152 * for broader compatibility.
154 * @param avctx ffmpeg metadata for this codec context
155 * @param session the MSDK session used
157 int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session)
159 mfxIMPL impl = MFX_IMPL_AUTO_ANY;
160 mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
165 ret = MFXInit(impl, &ver, session);
167 av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n");
168 return ff_qsv_error(ret);
171 ret = ff_qsv_set_display_handle(avctx, *session);
175 MFXQueryIMPL(*session, &impl);
177 switch (MFX_IMPL_BASETYPE(impl)) {
178 case MFX_IMPL_SOFTWARE:
181 case MFX_IMPL_HARDWARE:
182 case MFX_IMPL_HARDWARE2:
183 case MFX_IMPL_HARDWARE3:
184 case MFX_IMPL_HARDWARE4:
185 desc = "hardware accelerated";
191 av_log(avctx, AV_LOG_VERBOSE,
192 "Initialized an internal MFX session using %s implementation\n",