qsv: Update SDK version to v2022.2.4
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / qsv / gstqsvutils.cpp
1 /* GStreamer
2  * Copyright (C) 2021 Seungha Yang <seungha@centricular.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "gstqsvutils.h"
25
26 #ifdef G_OS_WIN32
27 #include <gst/d3d11/gstd3d11.h>
28 #include <wrl.h>
29
30 /* *INDENT-OFF* */
31 using namespace Microsoft::WRL;
32 /* *INDENT-ON* */
33 #else
34 #include <gst/va/gstva.h>
35 #endif
36
37 static mfxLoader _loader = nullptr;
38
39 mfxLoader
40 gst_qsv_get_loader (void)
41 {
42   static gsize load_once = 0;
43
44   if (g_once_init_enter (&load_once)) {
45     _loader = MFXLoad ();
46     g_once_init_leave (&load_once, 1);
47   }
48
49   return _loader;
50 }
51
52 void
53 gst_qsv_deinit (void)
54 {
55   g_clear_pointer (&_loader, MFXUnload);
56 }
57
58 #ifdef G_OS_WIN32
59 static GList *
60 gst_qsv_get_d3d11_devices (void)
61 {
62   GList *rst = nullptr;
63   HRESULT hr;
64   ComPtr < IDXGIFactory1 > factory;
65
66   hr = CreateDXGIFactory1 (IID_PPV_ARGS (&factory));
67   if (FAILED (hr))
68     return nullptr;
69
70   for (guint idx = 0;; idx++) {
71     ComPtr < IDXGIAdapter1 > adapter;
72     DXGI_ADAPTER_DESC desc;
73     gint64 luid;
74     GstD3D11Device *device;
75     ComPtr < ID3D10Multithread > multi_thread;
76     ID3D11Device *device_handle;
77
78     hr = factory->EnumAdapters1 (idx, &adapter);
79     if (FAILED (hr))
80       return rst;
81
82     hr = adapter->GetDesc (&desc);
83     if (FAILED (hr))
84       continue;
85
86     if (desc.VendorId != 0x8086)
87       continue;
88
89     luid = gst_d3d11_luid_to_int64 (&desc.AdapterLuid);
90     device = gst_d3d11_device_new_for_adapter_luid (luid,
91         D3D11_CREATE_DEVICE_BGRA_SUPPORT);
92
93     if (!device)
94       continue;
95
96     device_handle = gst_d3d11_device_get_device_handle (device);
97     hr = device_handle->QueryInterface (IID_PPV_ARGS (&multi_thread));
98     if (FAILED (hr)) {
99       gst_object_unref (device);
100       continue;
101     }
102
103     /* Should enable mutithread protection layer, otherwise QSV will return
104      * error code when this handle is passed to QSV via
105      * MFXVideoCORE_SetHandle() */
106     multi_thread->SetMultithreadProtected (TRUE);
107
108     rst = g_list_append (rst, device);
109   }
110
111   return rst;
112 }
113 #else /* G_OS_WIN32 */
114 static GList *
115 gst_qsv_get_va_displays (void)
116 {
117   gchar path[64];
118   GList *rst = nullptr;
119
120   for (guint i = 0; i < 8; i++) {
121     GstVaDisplay *display;
122     GstVaImplementation impl;
123
124     g_snprintf (path, sizeof (path), "/dev/dri/renderD%d", 128 + i);
125     if (!g_file_test (path, G_FILE_TEST_EXISTS))
126       continue;
127
128     display = gst_va_display_drm_new_from_path (path);
129     if (!display)
130       continue;
131
132     impl = gst_va_display_get_implementation (display);
133     if (impl != GST_VA_IMPLEMENTATION_INTEL_I965 &&
134         impl != GST_VA_IMPLEMENTATION_INTEL_IHD) {
135       gst_object_unref (display);
136       continue;
137     }
138
139     rst = g_list_append (rst, display);
140   }
141
142   return rst;
143 }
144 #endif
145
146 GList *
147 gst_qsv_get_platform_devices (void)
148 {
149 #ifdef G_OS_WIN32
150   return gst_qsv_get_d3d11_devices ();
151 #else
152   return gst_qsv_get_va_displays ();
153 #endif
154 }
155
156 const gchar *
157 gst_qsv_status_to_string (mfxStatus status)
158 {
159 #define CASE(err) \
160     case err: \
161     return G_STRINGIFY (err);
162
163   switch (status) {
164       CASE (MFX_ERR_NONE);
165       CASE (MFX_ERR_UNKNOWN);
166       CASE (MFX_ERR_NULL_PTR);
167       CASE (MFX_ERR_UNSUPPORTED);
168       CASE (MFX_ERR_MEMORY_ALLOC);
169       CASE (MFX_ERR_NOT_ENOUGH_BUFFER);
170       CASE (MFX_ERR_INVALID_HANDLE);
171       CASE (MFX_ERR_LOCK_MEMORY);
172       CASE (MFX_ERR_NOT_INITIALIZED);
173       CASE (MFX_ERR_NOT_FOUND);
174       CASE (MFX_ERR_MORE_DATA);
175       CASE (MFX_ERR_MORE_SURFACE);
176       CASE (MFX_ERR_ABORTED);
177       CASE (MFX_ERR_DEVICE_LOST);
178       CASE (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
179       CASE (MFX_ERR_INVALID_VIDEO_PARAM);
180       CASE (MFX_ERR_UNDEFINED_BEHAVIOR);
181       CASE (MFX_ERR_DEVICE_FAILED);
182       CASE (MFX_ERR_MORE_BITSTREAM);
183       CASE (MFX_ERR_GPU_HANG);
184       CASE (MFX_ERR_REALLOC_SURFACE);
185       CASE (MFX_ERR_RESOURCE_MAPPED);
186       CASE (MFX_ERR_NOT_IMPLEMENTED);
187       CASE (MFX_WRN_IN_EXECUTION);
188       CASE (MFX_WRN_DEVICE_BUSY);
189       CASE (MFX_WRN_VIDEO_PARAM_CHANGED);
190       CASE (MFX_WRN_PARTIAL_ACCELERATION);
191       CASE (MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
192       CASE (MFX_WRN_VALUE_NOT_CHANGED);
193       CASE (MFX_WRN_OUT_OF_RANGE);
194       CASE (MFX_WRN_FILTER_SKIPPED);
195       CASE (MFX_ERR_NONE_PARTIAL_OUTPUT);
196       CASE (MFX_WRN_ALLOC_TIMEOUT_EXPIRED);
197     default:
198       break;
199   }
200 #undef CASE
201
202   return "Unknown";
203 }