1 /* ****************************************************************************** *\
2
3 Copyright (C) 2012-2020 Intel Corporation. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 - Redistributions of source code must retain the above copyright notice,
8 this list of conditions and the following disclaimer.
9 - Redistributions in binary form must reproduce the above copyright notice,
10 this list of conditions and the following disclaimer in the documentation
11 and/or other materials provided with the distribution.
12 - Neither the name of Intel Corporation nor the names of its contributors
13 may be used to endorse or promote products derived from this software
14 without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 File Name: tracer_windows.cpp
28
29 \* ****************************************************************************** */
30
31 #if defined(_WIN32) || defined(_WIN64)
32
33 #define MFX_DISPATCHER_LOG 1
34
35 #include <windows.h>
36 #include <string.h>
37 #include <iostream>
38 #include "tracer.h"
39 #include "mfx_dispatcher.h"
40 #include "mfx_dispatcher_log.h"
41 #include "../tools/shared_mem_server.h"
42
43
44 //dump messages from dispatcher
45 class DispatcherLogRecorder : public IMsgHandler
46 {
47 static DispatcherLogRecorder m_Instance;
48 public:
get()49 static DispatcherLogRecorder& get(){return m_Instance;}
50 virtual void Write(int level, int opcode, const char * msg, va_list argptr);
51 };
52
53
54 class msdk_analyzer_sink : public IMsgHandler
55 {
56
57 public:
msdk_analyzer_sink()58 msdk_analyzer_sink()
59 {
60 DispatchLog::get().AttachSink(DL_SINK_IMsgHandler, this);
61 DispatchLog::get().DetachSink(DL_SINK_PRINTF, NULL);
62 }
~msdk_analyzer_sink()63 ~msdk_analyzer_sink()
64 {
65 DispatchLog::get().DetachSink(DL_SINK_IMsgHandler, this);
66
67 }
68
Write(int level,int,const char * msg,va_list argptr)69 virtual void Write(int level, int /*opcode*/, const char * msg, va_list argptr)
70 {
71 char message_formated[1024];
72 if ((msg) && (argptr) && (level != DL_LOADED_LIBRARY))
73 {
74 vsprintf_s(message_formated, sizeof(message_formated)/sizeof(message_formated[0]), msg, argptr);
75
76 //todo: eliminate this
77 if (message_formated[strnlen_s(message_formated, 1024)-1] == '\n')
78 {
79 message_formated[strnlen_s(message_formated, 1024)-1] = 0;
80 }
81 Log::WriteLog(message_formated);
82 }
83 }
84
85 };
86
87 static char* g_mfxlib = NULL;
88 bool is_loaded;
89
90
91
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved)92 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
93 {
94 lpReserved;
95 hinstDLL;
96
97 try{
98
99 std::string slib = "";
100 switch( fdwReason ){
101 case DLL_PROCESS_ATTACH:
102 slib = Config::GetParam("core", "lib");
103 g_mfxlib = new char[MAX_PATH];
104 strcpy_s(g_mfxlib, MAX_PATH, slib.c_str());
105 if (!strcmp(g_mfxlib, "none"))
106 {
107 Log::useGUI = true;
108 if (!is_loaded)
109 {
110 run_shared_memory_server();
111 }
112
113 }
114 tracer_init();
115 Log::WriteLog(std::string("function: DLLMain() DLL_PROCESS_ATTACH +"));
116 Log::WriteLog("mfx_tracer: lib=" + std::string(g_mfxlib));
117 Log::WriteLog(std::string("function: DLLMain() DLL_PROCESS_ATTACH - \n\n"));
118 break;
119 case DLL_THREAD_ATTACH:
120
121 break;
122 case DLL_THREAD_DETACH:
123
124 break;
125 case DLL_PROCESS_DETACH:
126 Log::WriteLog(std::string("function: DLLMain() DLL_PROCESS_DETACH +"));
127 //delete [] g_mfxlib;
128 Log::WriteLog(std::string("function: DLLMain() DLL_PROCESS_DETACH - \n\n"));
129 stop_shared_memory_server();
130 break;
131 }
132 }
133 catch (std::exception& e){
134 std::cerr << "Exception: " << e.what() << '\n';
135 }
136 return TRUE;
137 }
138
139 // external define from Dispatcher compiled with/MFX_DISPATCHER_EXPOSED_PREFIX
140 extern "C"
141 {
142 mfxStatus MFX_CDECL disp_MFXInitEx(mfxInitParam par, mfxSession *session);
143 }
144
TracerInit(mfxInitParam par,mfxSession * session)145 mfxStatus TracerInit (mfxInitParam par, mfxSession *session)
146 {
147 DumpContext context;
148 context.context = DUMPCONTEXT_MFX;
149 if (!session) {
150 Log::WriteLog(context.dump("ver", par.Version));
151 Log::WriteLog(context.dump("session", NULL));
152 Log::WriteLog(context.dump_mfxStatus("status", MFX_ERR_NULL_PTR));
153 return MFX_ERR_NULL_PTR;
154 }
155
156 mfxLoader* loader = (mfxLoader*)calloc(1, sizeof(mfxLoader));
157 if (!loader) {
158 Log::WriteLog(context.dump("ver", par.Version));
159 Log::WriteLog(context.dump("session", *session));
160 Log::WriteLog(context.dump_mfxStatus("status", MFX_ERR_MEMORY_ALLOC));
161 return MFX_ERR_MEMORY_ALLOC;
162 }
163
164 Log::WriteLog("LoadLibrary: " + std::string(g_mfxlib));
165 HINSTANCE h_mfxdll = NULL;
166 h_mfxdll = LoadLibrary(g_mfxlib);
167 if (h_mfxdll == NULL){
168 //dispatcher
169 mfxStatus sts;
170 msdk_analyzer_sink sink;
171 is_loaded = true;
172 sts = disp_MFXInitEx(par, session);
173 is_loaded = false;
174 if (sts != MFX_ERR_NONE)
175 {
176 Log::WriteLog(context.dump("ver", par.Version));
177 Log::WriteLog(context.dump("session", *session));
178 Log::WriteLog(context.dump_mfxStatus("status", MFX_ERR_NOT_FOUND));
179 free(loader);
180 return MFX_ERR_NOT_FOUND;
181 }
182 char libModuleName[MAX_PATH];
183
184 GetModuleFileName((HMODULE)(*(MFX_DISP_HANDLE**)(session))->hModule, libModuleName, MAX_PATH);
185 if (GetLastError() != 0)
186 {
187 Log::WriteLog("GetModuleFileName() reported error! \n");
188 free(loader);
189 return MFX_ERR_NOT_FOUND;
190 }
191 h_mfxdll = LoadLibrary(libModuleName);
192 }
193 loader->dlhandle = h_mfxdll;
194
195 //Loading functions table
196 int i;
197 mfxFunctionPointer proc;
198 for (i = 0; i < eFunctionsNum; ++i) {
199 proc = (mfxFunctionPointer)GetProcAddress((HINSTANCE)loader->dlhandle, g_mfxFuncTable[i].name);
200 if (!proc){
201 Sleep(100);
202 proc = (mfxFunctionPointer)GetProcAddress((HINSTANCE)loader->dlhandle, g_mfxFuncTable[i].name);
203 }
204 //if (!proc) break;
205 if(proc) loader->table[i] = proc;
206 }
207 // Initializing loaded library
208 mfxStatus mfx_res = (*(MFXInitPointer)loader->table[eMFXInit])(par.Implementation, &par.Version, &(loader->session));
209 if (MFX_ERR_NONE != mfx_res) {
210 FreeLibrary(h_mfxdll);
211 Log::WriteLog(context.dump("ver", par.Version));
212 Log::WriteLog(context.dump("session", *session));
213 Log::WriteLog(context.dump_mfxStatus("status", mfx_res));
214 free(loader);
215 return mfx_res;
216 }
217 *session = (mfxSession)loader;
218 return MFX_ERR_NONE;
219 }
220
221
MFXInit(mfxIMPL impl,mfxVersion * ver,mfxSession * session)222 mfxStatus MFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session)
223 {
224 if (is_loaded)
225 {
226 return MFX_ERR_ABORTED;
227 }
228 try{
229 DumpContext context;
230 context.context = DUMPCONTEXT_MFX;
231 Log::WriteLog(std::string("function: MFXInit(mfxIMPL impl=" + GetmfxIMPL(impl) + ", mfxVersion *ver=" + ToString(ver) + ", mfxSession *session=" + ToString(session) + ") +"));
232 mfxInitParam par = {};
233
234 par.Implementation = impl;
235 if (ver)
236 {
237 par.Version = *ver;
238 }
239 else
240 {
241 par.Version.Major = DEFAULT_API_VERSION_MAJOR;
242 par.Version.Minor = DEFAULT_API_VERSION_MINOR;
243 }
244 par.ExternalThreads = 0;
245 Timer t;
246 mfxStatus sts = TracerInit(par, session);
247 std::string elapsed = TimeToString(t.GetTime());
248 Log::WriteLog(">> MFXInit called");
249
250 Log::WriteLog(context.dump("impl", impl));
251 if (ver) Log::WriteLog(context.dump("ver", *ver));
252 if (session) Log::WriteLog(context.dump("session", *session));
253 Log::WriteLog(std::string("function: MFXInit(" + elapsed + ", " + context.dump_mfxStatus("status", sts) + ") - \n\n"));
254 return sts;
255 }
256 catch (std::exception& e){
257 std::cerr << "Exception: " << e.what() << '\n';
258 return MFX_ERR_ABORTED;
259 }
260
261 }
262
MFXClose(mfxSession session)263 mfxStatus MFXClose(mfxSession session)
264 {
265 try{
266 DumpContext context;
267 context.context = DUMPCONTEXT_MFX;
268 Log::WriteLog("function: MFXClose(mfxSession session=" + context.toString<mfxSession>(session) + ") +");
269 mfxLoader* loader = (mfxLoader*)session;
270
271 if (!loader){
272 Log::WriteLog(context.dump("session", session));
273 Log::WriteLog(context.dump_mfxStatus("status", MFX_ERR_INVALID_HANDLE));
274 return MFX_ERR_INVALID_HANDLE;
275 }
276 Log::WriteLog(context.dump("session", session));
277 Timer t;
278 mfxStatus mfx_res = (*(MFXClosePointer)loader->table[eMFXClose])(loader->session);
279 std::string elapsed = TimeToString(t.GetTime());
280 Log::WriteLog(">> MFXClose called");
281
282 FreeLibrary((HINSTANCE)loader->dlhandle);
283
284 Log::WriteLog(context.dump("session", session));
285 Log::WriteLog("function: MFXClose(" + elapsed + ", " + context.dump_mfxStatus("status", mfx_res) + ") - \n\n");
286 return mfx_res;
287 }
288 catch (std::exception& e){
289 std::cerr << "Exception: " << e.what() << '\n';
290 return MFX_ERR_ABORTED;
291 }
292 }
293
MFXInitEx(mfxInitParam par,mfxSession * session)294 mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session)
295 {
296 if (is_loaded)
297 {
298 return MFX_ERR_ABORTED;
299 }
300 try{
301 DumpContext context;
302 context.context = DUMPCONTEXT_MFX;
303 Log::WriteLog(std::string("function: MFXInitEx(par.Implementation=" + GetmfxIMPL(par.Implementation) + " par.Versin="+ ToString(&par.Version) +", mfxSession *session=" + ToString(session) + ") +"));
304 Timer t;
305 mfxStatus sts = TracerInit(par, session);
306 std::string elapsed = TimeToString(t.GetTime());
307 Log::WriteLog(">> MFXInitEx called");
308 Log::WriteLog(context.dump("par", par));
309 Log::WriteLog(context.dump("session", *session));
310 Log::WriteLog(std::string("function: MFXInitEx(" + elapsed + ", " + context.dump_mfxStatus("status", sts) + ") - \n\n"));
311 return sts;
312 }
313 catch (std::exception& e){
314 std::cerr << "Exception: " << e.what() << '\n';
315 return MFX_ERR_ABORTED;
316 }
317 }
318
319
320
321 #endif // #if defined(_WIN32) || defined(_WIN64)
322
323
324