main.cpp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166
  1. // Copyright (c) 2012-2020 Intel Corporation
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in all
  11. // copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. // SOFTWARE.
  20. #include <windows.h>
  21. #include <stringapiset.h>
  22. #include <new>
  23. #include <memory>
  24. #include "mfx_dispatcher.h"
  25. #include "mfx_load_dll.h"
  26. #include "mfx_dispatcher_log.h"
  27. #include "mfx_library_iterator.h"
  28. #include "mfx_critical_section.h"
  29. #if defined(MEDIASDK_UWP_DISPATCHER)
  30. #include "mfx_dispatcher_uwp.h"
  31. #endif
  32. #include <string.h> /* for memset on Linux */
  33. #include <stdlib.h> /* for qsort on Linux */
  34. #include "mfx_load_plugin.h"
  35. #include "mfx_plugin_hive.h"
  36. // module-local definitions
  37. namespace
  38. {
  39. const
  40. struct
  41. {
  42. // instance implementation type
  43. eMfxImplType implType;
  44. // real implementation
  45. mfxIMPL impl;
  46. // adapter numbers
  47. mfxU32 adapterID;
  48. } implTypes[] =
  49. {
  50. // MFX_IMPL_AUTO case
  51. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE, 0},
  52. {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0},
  53. // MFX_IMPL_ANY case
  54. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE, 0},
  55. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE2, 1},
  56. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE3, 2},
  57. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE4, 3},
  58. {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0},
  59. {MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE | MFX_IMPL_AUDIO, 0},
  60. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  61. //MFX_SINGLE_THREAD case
  62. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE | MFX_IMPL_EXTERNAL_THREADING, 0},
  63. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE2 | MFX_IMPL_EXTERNAL_THREADING, 1},
  64. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE3 | MFX_IMPL_EXTERNAL_THREADING, 2},
  65. {MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE4 | MFX_IMPL_EXTERNAL_THREADING, 3},
  66. #endif
  67. };
  68. const
  69. struct
  70. {
  71. // start index in implTypes table for specified implementation
  72. mfxU32 minIndex;
  73. // last index in implTypes table for specified implementation
  74. mfxU32 maxIndex;
  75. } implTypesRange[] =
  76. {
  77. {0, 1}, // MFX_IMPL_AUTO
  78. {1, 1}, // MFX_IMPL_SOFTWARE
  79. {0, 0}, // MFX_IMPL_HARDWARE
  80. {2, 6}, // MFX_IMPL_AUTO_ANY
  81. {2, 5}, // MFX_IMPL_HARDWARE_ANY
  82. {3, 3}, // MFX_IMPL_HARDWARE2
  83. {4, 4}, // MFX_IMPL_HARDWARE3
  84. {5, 5}, // MFX_IMPL_HARDWARE4
  85. {2, 6}, // MFX_IMPL_RUNTIME, same as MFX_IMPL_HARDWARE_ANY
  86. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  87. {8, 11}, // MFX_SINGLE_THREAD,
  88. #endif
  89. {7, 7} // MFX_IMPL_AUDIO
  90. };
  91. MFX::mfxCriticalSection dispGuard = 0;
  92. } // namespace
  93. using namespace MFX;
  94. #if !defined(MEDIASDK_UWP_DISPATCHER)
  95. //
  96. // Implement DLL exposed functions. MFXInit and MFXClose have to do
  97. // slightly more than other. They require to be implemented explicitly.
  98. // All other functions are implemented implicitly.
  99. //
  100. typedef MFXVector<MFX_DISP_HANDLE_EX*> HandleVector;
  101. typedef MFXVector<mfxStatus> StatusVector;
  102. struct VectorHandleGuard
  103. {
  104. VectorHandleGuard(HandleVector& aVector): m_vector(aVector) {}
  105. ~VectorHandleGuard()
  106. {
  107. HandleVector::iterator it = m_vector.begin(),
  108. et = m_vector.end();
  109. for ( ; it != et; ++it)
  110. {
  111. delete *it;
  112. }
  113. }
  114. HandleVector& m_vector;
  115. private:
  116. void operator=(const VectorHandleGuard&);
  117. };
  118. static int HandleSort (const void * plhs, const void * prhs)
  119. {
  120. const MFX_DISP_HANDLE_EX * lhs = *(const MFX_DISP_HANDLE_EX **)plhs;
  121. const MFX_DISP_HANDLE_EX * rhs = *(const MFX_DISP_HANDLE_EX **)prhs;
  122. // prefer HW implementation
  123. if (lhs->implType != MFX_LIB_HARDWARE && rhs->implType == MFX_LIB_HARDWARE)
  124. {
  125. return 1;
  126. }
  127. if (lhs->implType == MFX_LIB_HARDWARE && rhs->implType != MFX_LIB_HARDWARE)
  128. {
  129. return -1;
  130. }
  131. // prefer integrated GPU
  132. if (lhs->mediaAdapterType != MFX_MEDIA_INTEGRATED && rhs->mediaAdapterType == MFX_MEDIA_INTEGRATED)
  133. {
  134. return 1;
  135. }
  136. if (lhs->mediaAdapterType == MFX_MEDIA_INTEGRATED && rhs->mediaAdapterType != MFX_MEDIA_INTEGRATED)
  137. {
  138. return -1;
  139. }
  140. // prefer dll with lower API version
  141. if (lhs->actualApiVersion < rhs->actualApiVersion)
  142. {
  143. return -1;
  144. }
  145. if (rhs->actualApiVersion < lhs->actualApiVersion)
  146. {
  147. return 1;
  148. }
  149. // if versions are equal prefer library with HW
  150. if (lhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION && rhs->loadStatus == MFX_ERR_NONE)
  151. {
  152. return 1;
  153. }
  154. if (lhs->loadStatus == MFX_ERR_NONE && rhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION)
  155. {
  156. return -1;
  157. }
  158. return 0;
  159. }
  160. mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session)
  161. {
  162. MFX::MFXAutomaticCriticalSection guard(&dispGuard);
  163. DISPATCHER_LOG_BLOCK( ("MFXInitEx (impl=%s, pVer=%d.%d, ExternalThreads=%d session=0x%p\n"
  164. , DispatcherLog_GetMFXImplString(par.Implementation).c_str()
  165. , par.Version.Major
  166. , par.Version.Minor
  167. , par.ExternalThreads
  168. , session));
  169. mfxStatus mfxRes = MFX_ERR_UNSUPPORTED;
  170. HandleVector allocatedHandle;
  171. VectorHandleGuard handleGuard(allocatedHandle);
  172. MFX_DISP_HANDLE_EX *pHandle;
  173. wchar_t dllName[MFX_MAX_DLL_PATH] = { 0 };
  174. MFX::MFXLibraryIterator libIterator;
  175. // there iterators are used only if the caller specified implicit type like AUTO
  176. mfxU32 curImplIdx, maxImplIdx;
  177. // implementation method masked from the input parameter
  178. // special case for audio library
  179. const mfxIMPL implMethod = (par.Implementation & MFX_IMPL_AUDIO) ? (sizeof(implTypesRange) / sizeof(implTypesRange[0]) - 1) : (par.Implementation & (MFX_IMPL_VIA_ANY - 1));
  180. // implementation interface masked from the input parameter
  181. mfxIMPL implInterface = par.Implementation & -MFX_IMPL_VIA_ANY;
  182. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  183. bool isSingleThread = (implInterface & MFX_IMPL_EXTERNAL_THREADING) > 0;
  184. implInterface &= ~MFX_IMPL_EXTERNAL_THREADING;
  185. #endif
  186. mfxIMPL implInterfaceOrig = implInterface;
  187. mfxVersion requiredVersion = {{MFX_VERSION_MINOR, MFX_VERSION_MAJOR}};
  188. // check error(s)
  189. if (NULL == session)
  190. {
  191. return MFX_ERR_NULL_PTR;
  192. }
  193. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  194. if (((MFX_IMPL_AUTO > implMethod) || (MFX_IMPL_SINGLE_THREAD < implMethod)) && !(par.Implementation & MFX_IMPL_AUDIO))
  195. #else
  196. if (((MFX_IMPL_AUTO > implMethod) || (MFX_IMPL_RUNTIME < implMethod)) && !(par.Implementation & MFX_IMPL_AUDIO))
  197. #endif
  198. {
  199. return MFX_ERR_UNSUPPORTED;
  200. }
  201. // set the minimal required version
  202. requiredVersion = par.Version;
  203. try
  204. {
  205. // reset the session value
  206. *session = 0;
  207. // allocate the dispatching handle and call-table
  208. pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
  209. }
  210. catch(...)
  211. {
  212. return MFX_ERR_MEMORY_ALLOC;
  213. }
  214. DISPATCHER_LOG_INFO((("Required API version is %u.%u\n"), requiredVersion.Major, requiredVersion.Minor));
  215. // particular implementation value
  216. mfxIMPL curImpl;
  217. // Load HW library or RT from system location
  218. curImplIdx = implTypesRange[implMethod].minIndex;
  219. maxImplIdx = implTypesRange[implMethod].maxIndex;
  220. do
  221. {
  222. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  223. if (isSingleThread && implTypes[curImplIdx].implType != MFX_LIB_HARDWARE)
  224. continue;
  225. #endif
  226. int currentStorage = MFX::MFX_STORAGE_ID_FIRST;
  227. implInterface = implInterfaceOrig;
  228. do
  229. {
  230. // this storage will be checked below
  231. if (currentStorage == MFX::MFX_APP_FOLDER)
  232. {
  233. currentStorage += 1;
  234. continue;
  235. }
  236. // initialize the library iterator
  237. mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
  238. implInterface,
  239. implTypes[curImplIdx].adapterID,
  240. currentStorage);
  241. // look through the list of installed SDK version,
  242. // looking for a suitable library with higher merit value.
  243. if (MFX_ERR_NONE == mfxRes)
  244. {
  245. if (
  246. MFX_LIB_HARDWARE == implTypes[curImplIdx].implType
  247. && (!implInterface
  248. || MFX_IMPL_VIA_ANY == implInterface))
  249. {
  250. implInterface = libIterator.GetImplementationType();
  251. }
  252. do
  253. {
  254. eMfxImplType implType = implTypes[curImplIdx].implType;
  255. // select a desired DLL
  256. mfxRes = libIterator.SelectDLLVersion(dllName,
  257. sizeof(dllName) / sizeof(dllName[0]),
  258. &implType,
  259. pHandle->apiVersion);
  260. if (MFX_ERR_NONE != mfxRes)
  261. {
  262. break;
  263. }
  264. DISPATCHER_LOG_INFO((("loading library %S\n"), dllName));
  265. // try to load the selected DLL
  266. curImpl = implTypes[curImplIdx].impl;
  267. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  268. if (isSingleThread)
  269. curImpl |= MFX_IMPL_EXTERNAL_THREADING;
  270. #endif
  271. mfxRes = pHandle->LoadSelectedDLL(dllName, implType, curImpl, implInterface, par);
  272. // unload the failed DLL
  273. if (MFX_ERR_NONE != mfxRes)
  274. {
  275. pHandle->Close();
  276. continue;
  277. }
  278. mfxPlatform platform = { MFX_PLATFORM_UNKNOWN, 0, MFX_MEDIA_UNKNOWN };
  279. if (pHandle->callTable[eMFXVideoCORE_QueryPlatform])
  280. {
  281. mfxRes = MFXVideoCORE_QueryPlatform((mfxSession)pHandle, &platform);
  282. if (MFX_ERR_NONE != mfxRes)
  283. {
  284. DISPATCHER_LOG_WRN(("MFXVideoCORE_QueryPlatform failed, rejecting loaded library\n"));
  285. pHandle->Close();
  286. continue;
  287. }
  288. }
  289. pHandle->mediaAdapterType = platform.MediaAdapterType;
  290. DISPATCHER_LOG_INFO((("media adapter type is %d\n"), pHandle->mediaAdapterType));
  291. libIterator.GetSubKeyName(pHandle->subkeyName, sizeof(pHandle->subkeyName) / sizeof(pHandle->subkeyName[0]));
  292. pHandle->storageID = libIterator.GetStorageID();
  293. allocatedHandle.push_back(pHandle);
  294. pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
  295. } while (MFX_ERR_NONE != mfxRes);
  296. }
  297. // select another place for loading engine
  298. currentStorage += 1;
  299. } while ((MFX_ERR_NONE != mfxRes) && (MFX::MFX_STORAGE_ID_LAST >= currentStorage));
  300. } while (++curImplIdx <= maxImplIdx);
  301. curImplIdx = implTypesRange[implMethod].minIndex;
  302. maxImplIdx = implTypesRange[implMethod].maxIndex;
  303. // Load RT from app folder (libmfxsw64 with API >= 1.10)
  304. do
  305. {
  306. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  307. if (isSingleThread && implTypes[curImplIdx].implType != MFX_LIB_HARDWARE)
  308. continue;
  309. #endif
  310. implInterface = implInterfaceOrig;
  311. // initialize the library iterator
  312. mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
  313. implInterface,
  314. implTypes[curImplIdx].adapterID,
  315. MFX::MFX_APP_FOLDER);
  316. if (MFX_ERR_NONE == mfxRes)
  317. {
  318. if (
  319. MFX_LIB_HARDWARE == implTypes[curImplIdx].implType
  320. && (!implInterface
  321. || MFX_IMPL_VIA_ANY == implInterface))
  322. {
  323. implInterface = libIterator.GetImplementationType();
  324. }
  325. do
  326. {
  327. eMfxImplType implType;
  328. // select a desired DLL
  329. mfxRes = libIterator.SelectDLLVersion(dllName,
  330. sizeof(dllName) / sizeof(dllName[0]),
  331. &implType,
  332. pHandle->apiVersion);
  333. if (MFX_ERR_NONE != mfxRes)
  334. {
  335. break;
  336. }
  337. DISPATCHER_LOG_INFO((("loading library %S\n"), dllName));
  338. // try to load the selected DLL
  339. curImpl = implTypes[curImplIdx].impl;
  340. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  341. if (isSingleThread)
  342. curImpl |= MFX_IMPL_EXTERNAL_THREADING;
  343. #endif
  344. mfxRes = pHandle->LoadSelectedDLL(dllName, implType, curImpl, implInterface, par);
  345. // unload the failed DLL
  346. if (MFX_ERR_NONE != mfxRes)
  347. {
  348. pHandle->Close();
  349. }
  350. else
  351. {
  352. if (pHandle->actualApiVersion.Major == 1 && pHandle->actualApiVersion.Minor <= 9)
  353. {
  354. // this is not RT, skip it
  355. mfxRes = MFX_ERR_ABORTED;
  356. break;
  357. }
  358. pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
  359. allocatedHandle.push_back(pHandle);
  360. pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
  361. }
  362. } while (MFX_ERR_NONE != mfxRes);
  363. }
  364. } while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx));
  365. // Load HW and SW libraries using legacy default DLL search mechanism
  366. // set current library index again
  367. curImplIdx = implTypesRange[implMethod].minIndex;
  368. do
  369. {
  370. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  371. if (isSingleThread && implTypes[curImplIdx].implType != MFX_LIB_HARDWARE)
  372. continue;
  373. #endif
  374. implInterface = implInterfaceOrig;
  375. if (par.Implementation & MFX_IMPL_AUDIO)
  376. {
  377. mfxRes = MFX::mfx_get_default_audio_dll_name(dllName,
  378. sizeof(dllName) / sizeof(dllName[0]),
  379. implTypes[curImplIdx].implType);
  380. }
  381. else
  382. {
  383. mfxRes = MFX::mfx_get_default_dll_name(dllName,
  384. sizeof(dllName) / sizeof(dllName[0]),
  385. implTypes[curImplIdx].implType);
  386. }
  387. if (MFX_ERR_NONE == mfxRes)
  388. {
  389. DISPATCHER_LOG_INFO((("loading default library %S\n"), dllName))
  390. // try to load the selected DLL using default DLL search mechanism
  391. if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType)
  392. {
  393. if (!implInterface)
  394. {
  395. implInterface = MFX_IMPL_VIA_ANY;
  396. }
  397. mfxU32 curVendorID = 0, curDeviceID = 0;
  398. mfxRes = MFX::SelectImplementationType(implTypes[curImplIdx].adapterID, &implInterface, &curVendorID, &curDeviceID);
  399. if (curVendorID != INTEL_VENDOR_ID)
  400. mfxRes = MFX_ERR_UNKNOWN;
  401. }
  402. if (MFX_ERR_NONE == mfxRes)
  403. {
  404. curImpl = implTypes[curImplIdx].impl;
  405. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  406. if (isSingleThread)
  407. curImpl |= MFX_IMPL_EXTERNAL_THREADING;
  408. #endif
  409. // try to load the selected DLL using default DLL search mechanism
  410. mfxRes = pHandle->LoadSelectedDLL(dllName,
  411. implTypes[curImplIdx].implType,
  412. curImpl,
  413. implInterface,
  414. par);
  415. }
  416. // unload the failed DLL
  417. if ((MFX_ERR_NONE != mfxRes) &&
  418. (MFX_WRN_PARTIAL_ACCELERATION != mfxRes))
  419. {
  420. pHandle->Close();
  421. }
  422. else
  423. {
  424. pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
  425. allocatedHandle.push_back(pHandle);
  426. pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
  427. }
  428. }
  429. }
  430. while ((MFX_ERR_NONE > mfxRes) && (++curImplIdx <= maxImplIdx));
  431. delete pHandle;
  432. if (allocatedHandle.size() == 0)
  433. return MFX_ERR_UNSUPPORTED;
  434. { // sort candidate list
  435. bool NeedSort = false;
  436. HandleVector::iterator first = allocatedHandle.begin(),
  437. it = allocatedHandle.begin(),
  438. et = allocatedHandle.end();
  439. for (it++; it != et; ++it)
  440. if (HandleSort(&(*first), &(*it)) != 0)
  441. NeedSort = true;
  442. // sort allocatedHandle so that the most preferred dll is at the beginning
  443. if (NeedSort)
  444. qsort(&(*allocatedHandle.begin()), allocatedHandle.size(), sizeof(MFX_DISP_HANDLE_EX*), &HandleSort);
  445. }
  446. HandleVector::iterator candidate = allocatedHandle.begin();
  447. // check the final result of loading
  448. try
  449. {
  450. pHandle = *candidate;
  451. //pulling up current mediasdk version, that required to match plugin version
  452. mfxVersion apiVerActual = { { 0, 0 } };
  453. mfxStatus stsQueryVersion = MFXQueryVersion((mfxSession)pHandle, &apiVerActual);
  454. if (MFX_ERR_NONE != stsQueryVersion)
  455. {
  456. DISPATCHER_LOG_ERROR((("MFXQueryVersion returned: %d, cannot load plugins\n"), mfxRes))
  457. }
  458. else
  459. {
  460. MFX::MFXPluginStorage & hive = pHandle->pluginHive;
  461. HandleVector::iterator it = allocatedHandle.begin(),
  462. et = allocatedHandle.end();
  463. for (; it != et; ++it)
  464. {
  465. // Registering default plugins set
  466. MFX::MFXDefaultPlugins defaultPugins(apiVerActual, *it, (*it)->implType);
  467. hive.insert(hive.end(), defaultPugins.begin(), defaultPugins.end());
  468. if ((*it)->storageID != MFX::MFX_UNKNOWN_KEY)
  469. {
  470. // Scan HW plugins in subkeys of registry library
  471. MFX::MFXPluginsInHive plgsInHive((*it)->storageID, (*it)->subkeyName, apiVerActual);
  472. hive.insert(hive.end(), plgsInHive.begin(), plgsInHive.end());
  473. }
  474. }
  475. //setting up plugins records
  476. for(int i = MFX::MFX_STORAGE_ID_FIRST; i <= MFX::MFX_STORAGE_ID_LAST; i++)
  477. {
  478. MFX::MFXPluginsInHive plgsInHive(i, NULL, apiVerActual);
  479. hive.insert(hive.end(), plgsInHive.begin(), plgsInHive.end());
  480. }
  481. // SOLID dispatcher also loads plug-ins from file system
  482. MFX::MFXPluginsInFS plgsInFS(apiVerActual);
  483. hive.insert(hive.end(), plgsInFS.begin(), plgsInFS.end());
  484. }
  485. pHandle->callPlugInsTable[eMFXVideoUSER_Load] = (mfxFunctionPointer)MFXVideoUSER_Load;
  486. pHandle->callPlugInsTable[eMFXVideoUSER_LoadByPath] = (mfxFunctionPointer)MFXVideoUSER_LoadByPath;
  487. pHandle->callPlugInsTable[eMFXVideoUSER_UnLoad] = (mfxFunctionPointer)MFXVideoUSER_UnLoad;
  488. pHandle->callPlugInsTable[eMFXAudioUSER_Load] = (mfxFunctionPointer)MFXAudioUSER_Load;
  489. pHandle->callPlugInsTable[eMFXAudioUSER_UnLoad] = (mfxFunctionPointer)MFXAudioUSER_UnLoad;
  490. }
  491. catch(...)
  492. {
  493. DISPATCHER_LOG_ERROR((("unknown exception while loading plugins\n")))
  494. }
  495. // everything is OK. Save pointers to the output variable
  496. *candidate = 0; // keep this one safe from guard destructor
  497. //===================================
  498. // MFXVideoCORE_QueryPlatform call creates d3d device handle, so we have handle right after MFXInit and can't accept external handle
  499. // This is a workaround which calls close-init to remove that handle
  500. mfxFunctionPointer *actualTable = (pHandle->impl & MFX_IMPL_AUDIO) ? pHandle->callAudioTable : pHandle->callTable;
  501. mfxFunctionPointer pFunc;
  502. pFunc = actualTable[eMFXClose];
  503. mfxRes = (*(mfxStatus(MFX_CDECL *) (mfxSession)) pFunc) (pHandle->session);
  504. if (mfxRes != MFX_ERR_NONE)
  505. return mfxRes;
  506. pHandle->session = 0;
  507. bool callOldInit = (pHandle->impl & MFX_IMPL_AUDIO) || !actualTable[eMFXInitEx];
  508. pFunc = actualTable[(callOldInit) ? eMFXInit : eMFXInitEx];
  509. mfxVersion version(pHandle->apiVersion);
  510. if (callOldInit)
  511. {
  512. pHandle->loadStatus = (*(mfxStatus(MFX_CDECL *) (mfxIMPL, mfxVersion *, mfxSession *)) pFunc) (pHandle->impl | pHandle->implInterface, &version, &pHandle->session);
  513. }
  514. else
  515. {
  516. mfxInitParam initPar = par;
  517. initPar.Implementation = pHandle->impl | pHandle->implInterface;
  518. initPar.Version = version;
  519. pHandle->loadStatus = (*(mfxStatus(MFX_CDECL *) (mfxInitParam, mfxSession *)) pFunc) (initPar, &pHandle->session);
  520. }
  521. //===================================
  522. *((MFX_DISP_HANDLE_EX **) session) = pHandle;
  523. return pHandle->loadStatus;
  524. } // mfxStatus MFXInitEx(mfxIMPL impl, mfxVersion *ver, mfxSession *session)
  525. mfxStatus MFXClose(mfxSession session)
  526. {
  527. MFX::MFXAutomaticCriticalSection guard(&dispGuard);
  528. mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
  529. MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *) session;
  530. // check error(s)
  531. if (pHandle)
  532. {
  533. try
  534. {
  535. // unload the DLL library
  536. mfxRes = pHandle->Close();
  537. // it is possible, that there is an active child session.
  538. // can't unload library in that case.
  539. if (MFX_ERR_UNDEFINED_BEHAVIOR != mfxRes)
  540. {
  541. // release the handle
  542. delete pHandle;
  543. }
  544. }
  545. catch(...)
  546. {
  547. mfxRes = MFX_ERR_INVALID_HANDLE;
  548. }
  549. }
  550. return mfxRes;
  551. } // mfxStatus MFXClose(mfxSession session)
  552. mfxStatus MFXVideoUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version)
  553. {
  554. mfxStatus sts = MFX_ERR_NONE;
  555. bool ErrFlag = false;
  556. if (!session)
  557. {
  558. DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: session=NULL\n")));
  559. return MFX_ERR_NULL_PTR;
  560. }
  561. MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session;
  562. if (!uid)
  563. {
  564. DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: uid=NULL\n")));
  565. return MFX_ERR_NULL_PTR;
  566. }
  567. DISPATCHER_LOG_INFO((("MFXVideoUSER_Load: uid=" MFXGUIDTYPE()" version=%d\n")
  568. , MFXGUIDTOHEX(uid)
  569. , version))
  570. size_t pluginsChecked = 0;
  571. for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++)
  572. {
  573. if (i->PluginUID != *uid)
  574. {
  575. continue;
  576. }
  577. //check rest in records
  578. if (i->PluginVersion < version)
  579. {
  580. DISPATCHER_LOG_INFO((("MFXVideoUSER_Load: registered \"Plugin Version\" for GUID=" MFXGUIDTYPE()" is %d, that is smaller that requested\n")
  581. , MFXGUIDTOHEX(uid)
  582. , i->PluginVersion))
  583. continue;
  584. }
  585. try
  586. {
  587. sts = pHandle.pluginFactory.Create(*i);
  588. if( MFX_ERR_NONE != sts)
  589. {
  590. ErrFlag = (ErrFlag || (sts == MFX_ERR_UNDEFINED_BEHAVIOR));
  591. continue;
  592. }
  593. return MFX_ERR_NONE;
  594. }
  595. catch(...)
  596. {
  597. continue;
  598. }
  599. }
  600. // Specified UID was not found among individually registed plugins, now try load it from default sets if any
  601. for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++)
  602. {
  603. if (!i->Default)
  604. continue;
  605. i->PluginUID = *uid;
  606. i->PluginVersion = (mfxU16)version;
  607. try
  608. {
  609. sts = pHandle.pluginFactory.Create(*i);
  610. if( MFX_ERR_NONE != sts)
  611. {
  612. ErrFlag = (ErrFlag || (sts == MFX_ERR_UNDEFINED_BEHAVIOR));
  613. continue;
  614. }
  615. return MFX_ERR_NONE;
  616. }
  617. catch(...)
  618. {
  619. continue;
  620. }
  621. }
  622. DISPATCHER_LOG_ERROR((("MFXVideoUSER_Load: cannot find registered plugin with requested UID, total plugins available=%d\n"), pHandle.pluginHive.size()));
  623. if (ErrFlag)
  624. return MFX_ERR_UNDEFINED_BEHAVIOR;
  625. else
  626. return MFX_ERR_NOT_FOUND;
  627. }
  628. mfxStatus MFXVideoUSER_LoadByPath(mfxSession session, const mfxPluginUID *uid, mfxU32 version, const mfxChar *path, mfxU32 len)
  629. {
  630. if (!session)
  631. {
  632. DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: session=NULL\n")));
  633. return MFX_ERR_NULL_PTR;
  634. }
  635. MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session;
  636. if (!uid)
  637. {
  638. DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: uid=NULL\n")));
  639. return MFX_ERR_NULL_PTR;
  640. }
  641. DISPATCHER_LOG_INFO((("MFXVideoUSER_LoadByPath: %S uid=" MFXGUIDTYPE()" version=%d\n")
  642. , path
  643. , MFXGUIDTOHEX(uid)
  644. , version))
  645. PluginDescriptionRecord record;
  646. record.sName[0] = 0;
  647. wchar_t wPath[MAX_PLUGIN_PATH];
  648. int res = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, len, wPath, MAX_PLUGIN_PATH-1);
  649. if (!res)
  650. {
  651. DISPATCHER_LOG_ERROR((("MFXVideoUSER_LoadByPath: can't convert UTF-8 path to UTF-16\n")));
  652. return MFX_ERR_NOT_FOUND;
  653. }
  654. wPath[res]=0;
  655. wcscpy_s(record.sPath, MAX_PLUGIN_PATH, wPath);
  656. record.PluginUID = *uid;
  657. record.PluginVersion = (mfxU16)version;
  658. record.Default = true;
  659. try
  660. {
  661. return pHandle.pluginFactory.Create(record);
  662. }
  663. catch(...)
  664. {
  665. return MFX_ERR_NOT_FOUND;
  666. }
  667. }
  668. mfxStatus MFXVideoUSER_UnLoad(mfxSession session, const mfxPluginUID *uid)
  669. {
  670. if (!session)
  671. {
  672. DISPATCHER_LOG_ERROR((("MFXVideoUSER_UnLoad: session=NULL\n")));
  673. return MFX_ERR_NULL_PTR;
  674. }
  675. MFX_DISP_HANDLE &rHandle = *(MFX_DISP_HANDLE *) session;
  676. if (!uid)
  677. {
  678. DISPATCHER_LOG_ERROR((("MFXVideoUSER_UnLoad: uid=NULL\n")));
  679. return MFX_ERR_NULL_PTR;
  680. }
  681. bool bDestroyed = rHandle.pluginFactory.Destroy(*uid);
  682. if (bDestroyed)
  683. {
  684. DISPATCHER_LOG_INFO((("MFXVideoUSER_UnLoad : plugin with GUID=" MFXGUIDTYPE()" unloaded\n"), MFXGUIDTOHEX(uid)));
  685. } else
  686. {
  687. DISPATCHER_LOG_ERROR((("MFXVideoUSER_UnLoad : plugin with GUID=" MFXGUIDTYPE()" not found\n"), MFXGUIDTOHEX(uid)));
  688. }
  689. return bDestroyed ? MFX_ERR_NONE : MFX_ERR_NOT_FOUND;
  690. }
  691. mfxStatus MFXAudioUSER_Load(mfxSession session, const mfxPluginUID *uid, mfxU32 version)
  692. {
  693. if (!session)
  694. {
  695. DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: session=NULL\n")));
  696. return MFX_ERR_NULL_PTR;
  697. }
  698. MFX_DISP_HANDLE &pHandle = *(MFX_DISP_HANDLE *) session;
  699. if (!uid)
  700. {
  701. DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: uid=NULL\n")));
  702. return MFX_ERR_NULL_PTR;
  703. }
  704. DISPATCHER_LOG_INFO((("MFXAudioUSER_Load: uid=" MFXGUIDTYPE()" version=%d\n")
  705. , MFXGUIDTOHEX(uid)
  706. , version))
  707. size_t pluginsChecked = 0;
  708. PluginDescriptionRecord defaultPluginRecord;
  709. for (MFX::MFXPluginStorage::iterator i = pHandle.pluginHive.begin();i != pHandle.pluginHive.end(); i++, pluginsChecked++)
  710. {
  711. if (i->PluginUID != *uid)
  712. {
  713. if (i->Default) // PluginUID == 0 for default set
  714. {
  715. defaultPluginRecord = *i;
  716. }
  717. continue;
  718. }
  719. //check rest in records
  720. if (i->PluginVersion < version)
  721. {
  722. DISPATCHER_LOG_INFO((("MFXAudioUSER_Load: registered \"Plugin Version\" for GUID=" MFXGUIDTYPE()" is %d, that is smaller that requested\n")
  723. , MFXGUIDTOHEX(uid)
  724. , i->PluginVersion))
  725. continue;
  726. }
  727. try {
  728. return pHandle.pluginFactory.Create(*i);
  729. }
  730. catch(...) {
  731. return MFX_ERR_UNKNOWN;
  732. }
  733. }
  734. // Specified UID was not found among individually registed plugins, now try load it from default set if any
  735. if (defaultPluginRecord.Default)
  736. {
  737. defaultPluginRecord.PluginUID = *uid;
  738. defaultPluginRecord.onlyVersionRegistered = true;
  739. defaultPluginRecord.PluginVersion = (mfxU16)version;
  740. try {
  741. return pHandle.pluginFactory.Create(defaultPluginRecord);
  742. }
  743. catch(...) {
  744. return MFX_ERR_UNKNOWN;
  745. }
  746. }
  747. DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: cannot find registered plugin with requested UID, total plugins available=%d\n"), pHandle.pluginHive.size()));
  748. return MFX_ERR_NOT_FOUND;
  749. }
  750. mfxStatus MFXAudioUSER_UnLoad(mfxSession session, const mfxPluginUID *uid)
  751. {
  752. if (!session)
  753. {
  754. DISPATCHER_LOG_ERROR((("MFXAudioUSER_UnLoad: session=NULL\n")));
  755. return MFX_ERR_NULL_PTR;
  756. }
  757. MFX_DISP_HANDLE &rHandle = *(MFX_DISP_HANDLE *) session;
  758. if (!uid)
  759. {
  760. DISPATCHER_LOG_ERROR((("MFXAudioUSER_Load: uid=NULL\n")));
  761. return MFX_ERR_NULL_PTR;
  762. }
  763. bool bDestroyed = rHandle.pluginFactory.Destroy(*uid);
  764. if (bDestroyed)
  765. {
  766. DISPATCHER_LOG_INFO((("MFXAudioUSER_UnLoad : plugin with GUID=" MFXGUIDTYPE()" unloaded\n"), MFXGUIDTOHEX(uid)));
  767. } else
  768. {
  769. DISPATCHER_LOG_ERROR((("MFXAudioUSER_UnLoad : plugin with GUID=" MFXGUIDTYPE()" not found\n"), MFXGUIDTOHEX(uid)));
  770. }
  771. return bDestroyed ? MFX_ERR_NONE : MFX_ERR_NOT_FOUND;
  772. }
  773. #else // relates to !defined (MEDIASDK_UWP_DISPATCHER), i.e. #else part as if MEDIASDK_UWP_DISPATCHER defined
  774. static mfxModuleHandle hModule;
  775. // for the UWP_DISPATCHER purposes implementation of MFXinitEx is calling
  776. // InitialiseMediaSession() implemented in intel_gfx_api.dll
  777. mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session)
  778. {
  779. #if defined(MEDIASDK_ARM_LOADER)
  780. return MFX_ERR_UNSUPPORTED;
  781. #else
  782. wchar_t IntelGFXAPIdllName[MFX_MAX_DLL_PATH] = { 0 };
  783. mfxI32 adapterNum = -1;
  784. switch (par.Implementation & 0xf)
  785. {
  786. case MFX_IMPL_SOFTWARE:
  787. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  788. case MFX_IMPL_SINGLE_THREAD:
  789. #endif
  790. return MFX_ERR_UNSUPPORTED;
  791. case MFX_IMPL_AUTO:
  792. case MFX_IMPL_HARDWARE:
  793. adapterNum = 0;
  794. break;
  795. case MFX_IMPL_HARDWARE2:
  796. adapterNum = 1;
  797. break;
  798. case MFX_IMPL_HARDWARE3:
  799. adapterNum = 2;
  800. break;
  801. case MFX_IMPL_HARDWARE4:
  802. adapterNum = 3;
  803. break;
  804. default:
  805. return GfxApiInitPriorityIntegrated(par, session, hModule);
  806. }
  807. return GfxApiInitByAdapterNum(par, adapterNum, session, hModule);
  808. #endif
  809. }
  810. // for the UWP_DISPATCHER purposes implementation of MFXClose is calling
  811. // DisposeMediaSession() implemented in intel_gfx_api.dll
  812. mfxStatus MFXClose(mfxSession session)
  813. {
  814. if (NULL == session) {
  815. return MFX_ERR_INVALID_HANDLE;
  816. }
  817. mfxStatus sts = MFX_ERR_NONE;
  818. #if defined(MEDIASDK_ARM_LOADER)
  819. sts = MFX_ERR_UNSUPPORTED;
  820. #else
  821. sts = GfxApiClose(session, hModule);
  822. #endif
  823. session = (mfxSession)NULL;
  824. return sts;
  825. }
  826. #undef FUNCTION
  827. #define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
  828. return_value func_name formal_param_list \
  829. { \
  830. mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
  831. \
  832. _mfxSession *pHandle = (_mfxSession *) session; \
  833. \
  834. /* get the function's address and make a call */ \
  835. if (pHandle) \
  836. { \
  837. mfxFunctionPointer pFunc = pHandle->callPlugInsTable[e##func_name]; \
  838. if (pFunc) \
  839. { \
  840. /* pass down the call */ \
  841. mfxRes = (*(mfxStatus (MFX_CDECL *) formal_param_list) pFunc) actual_param_list; \
  842. } \
  843. } \
  844. return mfxRes; \
  845. }
  846. FUNCTION(mfxStatus, MFXVideoUSER_Load, (mfxSession session, const mfxPluginUID *uid, mfxU32 version), (session, uid, version))
  847. FUNCTION(mfxStatus, MFXVideoUSER_LoadByPath, (mfxSession session, const mfxPluginUID *uid, mfxU32 version, const mfxChar *path, mfxU32 len), (session, uid, version, path, len))
  848. FUNCTION(mfxStatus, MFXVideoUSER_UnLoad, (mfxSession session, const mfxPluginUID *uid), (session, uid))
  849. FUNCTION(mfxStatus, MFXAudioUSER_Load, (mfxSession session, const mfxPluginUID *uid, mfxU32 version), (session, uid, version))
  850. FUNCTION(mfxStatus, MFXAudioUSER_UnLoad, (mfxSession session, const mfxPluginUID *uid), (session, uid))
  851. #endif //!defined(MEDIASDK_UWP_DISPATCHER)
  852. mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session)
  853. {
  854. mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
  855. MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *)session;
  856. MFX_DISP_HANDLE *pChildHandle = (MFX_DISP_HANDLE *)child_session;
  857. // get the function's address and make a call
  858. if ((pHandle) && (pChildHandle) && (pHandle->actualApiVersion == pChildHandle->actualApiVersion))
  859. {
  860. /* check whether it is audio session or video */
  861. int tableIndex = eMFXJoinSession;
  862. mfxFunctionPointer pFunc;
  863. if (pHandle->impl & MFX_IMPL_AUDIO)
  864. {
  865. pFunc = pHandle->callAudioTable[tableIndex];
  866. }
  867. else
  868. {
  869. pFunc = pHandle->callTable[tableIndex];
  870. }
  871. if (pFunc)
  872. {
  873. // pass down the call
  874. mfxRes = (*(mfxStatus(MFX_CDECL *) (mfxSession, mfxSession)) pFunc) (pHandle->session,
  875. pChildHandle->session);
  876. }
  877. }
  878. return mfxRes;
  879. } // mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session)
  880. mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone)
  881. {
  882. mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
  883. MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *)session;
  884. mfxVersion apiVersion;
  885. mfxIMPL impl;
  886. // check error(s)
  887. if (pHandle)
  888. {
  889. // initialize the clone session
  890. apiVersion = pHandle->apiVersion;
  891. impl = pHandle->impl | pHandle->implInterface;
  892. mfxRes = MFXInit(impl, &apiVersion, clone);
  893. if (MFX_ERR_NONE != mfxRes)
  894. {
  895. return mfxRes;
  896. }
  897. // join the sessions
  898. mfxRes = MFXJoinSession(session, *clone);
  899. if (MFX_ERR_NONE != mfxRes)
  900. {
  901. MFXClose(*clone);
  902. *clone = NULL;
  903. return mfxRes;
  904. }
  905. }
  906. return mfxRes;
  907. } // mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone)
  908. mfxStatus MFXInit(mfxIMPL impl, mfxVersion *pVer, mfxSession *session)
  909. {
  910. mfxInitParam par = {};
  911. par.Implementation = impl;
  912. if (pVer)
  913. {
  914. par.Version = *pVer;
  915. }
  916. else
  917. {
  918. par.Version.Major = DEFAULT_API_VERSION_MAJOR;
  919. par.Version.Minor = DEFAULT_API_VERSION_MINOR;
  920. }
  921. par.ExternalThreads = 0;
  922. return MFXInitEx(par, session);
  923. }
  924. //
  925. //
  926. // implement all other calling functions.
  927. // They just call a procedure of DLL library from the table.
  928. //
  929. // define for common functions (from mfxsession.h)
  930. #undef FUNCTION
  931. #define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
  932. return_value func_name formal_param_list \
  933. { \
  934. mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
  935. _mfxSession *pHandle = (_mfxSession *) session; \
  936. /* get the function's address and make a call */ \
  937. if (pHandle) \
  938. { \
  939. /* check whether it is audio session or video */ \
  940. int tableIndex = e##func_name; \
  941. mfxFunctionPointer pFunc; \
  942. if (pHandle->impl & MFX_IMPL_AUDIO) \
  943. { \
  944. pFunc = pHandle->callAudioTable[tableIndex]; \
  945. } \
  946. else \
  947. { \
  948. pFunc = pHandle->callTable[tableIndex]; \
  949. } \
  950. if (pFunc) \
  951. { \
  952. /* get the real session pointer */ \
  953. session = pHandle->session; \
  954. /* pass down the call */ \
  955. mfxRes = (*(mfxStatus (MFX_CDECL *) formal_param_list) pFunc) actual_param_list; \
  956. } \
  957. } \
  958. return mfxRes; \
  959. }
  960. FUNCTION(mfxStatus, MFXQueryIMPL, (mfxSession session, mfxIMPL *impl), (session, impl))
  961. FUNCTION(mfxStatus, MFXQueryVersion, (mfxSession session, mfxVersion *version), (session, version))
  962. // these functions are not necessary in LOADER part of dispatcher and
  963. // need to be included only in in SOLID dispatcher or PROCTABLE part of dispatcher
  964. FUNCTION(mfxStatus, MFXDisjoinSession, (mfxSession session), (session))
  965. FUNCTION(mfxStatus, MFXSetPriority, (mfxSession session, mfxPriority priority), (session, priority))
  966. FUNCTION(mfxStatus, MFXGetPriority, (mfxSession session, mfxPriority *priority), (session, priority))
  967. #undef FUNCTION
  968. #define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
  969. return_value func_name formal_param_list \
  970. { \
  971. mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
  972. _mfxSession *pHandle = (_mfxSession *) session;\
  973. /* get the function's address and make a call */ \
  974. if (pHandle) \
  975. { \
  976. mfxFunctionPointer pFunc = pHandle->callTable[e##func_name]; \
  977. if (pFunc) \
  978. { \
  979. /* get the real session pointer */ \
  980. session = pHandle->session; \
  981. /* pass down the call */ \
  982. mfxRes = (*(mfxStatus (MFX_CDECL *) formal_param_list) pFunc) actual_param_list; \
  983. } \
  984. } \
  985. return mfxRes; \
  986. }
  987. #include "mfx_exposed_functions_list.h"
  988. #undef FUNCTION
  989. #define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
  990. return_value func_name formal_param_list \
  991. { \
  992. mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
  993. _mfxSession *pHandle = (_mfxSession *) session; \
  994. /* get the function's address and make a call */ \
  995. if (pHandle) \
  996. { \
  997. mfxFunctionPointer pFunc = pHandle->callAudioTable[e##func_name]; \
  998. if (pFunc) \
  999. { \
  1000. /* get the real session pointer */ \
  1001. session = pHandle->session; \
  1002. /* pass down the call */ \
  1003. mfxRes = (*(mfxStatus (MFX_CDECL *) formal_param_list) pFunc) actual_param_list; \
  1004. } \
  1005. } \
  1006. return mfxRes; \
  1007. }
  1008. #include "mfxaudio_exposed_functions_list.h"