mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 21:51:09 +00:00
2b3f690355
See release note https://github.com/oneapi-src/oneVPL/releases/tag/v2022.2.0 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2738>
1173 lines
42 KiB
C++
1173 lines
42 KiB
C++
/*############################################################################
|
|
# Copyright (C) Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
############################################################################*/
|
|
|
|
#include <windows.h>
|
|
|
|
#include <stringapiset.h>
|
|
|
|
#include <memory>
|
|
#include <new>
|
|
|
|
#include "windows/mfx_critical_section.h"
|
|
#include "windows/mfx_dispatcher.h"
|
|
#include "windows/mfx_dispatcher_log.h"
|
|
#include "windows/mfx_library_iterator.h"
|
|
#include "windows/mfx_load_dll.h"
|
|
|
|
#include "windows/mfx_vector.h"
|
|
|
|
#if defined(MEDIASDK_UWP_DISPATCHER)
|
|
#include "windows/mfx_driver_store_loader.h"
|
|
#endif
|
|
|
|
#include <string.h> /* for memset on Linux */
|
|
|
|
#include <stdlib.h> /* for qsort on Linux */
|
|
|
|
// module-local definitions
|
|
namespace {
|
|
|
|
const struct {
|
|
// instance implementation type
|
|
eMfxImplType implType;
|
|
// real implementation
|
|
mfxIMPL impl;
|
|
// adapter numbers
|
|
mfxU32 adapterID;
|
|
|
|
} implTypes[] = {
|
|
// MFX_IMPL_AUTO case
|
|
{ MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE, 0 },
|
|
{ MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0 },
|
|
|
|
// MFX_IMPL_ANY case
|
|
{ MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE, 0 },
|
|
{ MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE2, 1 },
|
|
{ MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE3, 2 },
|
|
{ MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE4, 3 },
|
|
{ MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0 },
|
|
{ MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0 }, // unused - was MFX_IMPL_AUDIO
|
|
};
|
|
|
|
const struct {
|
|
// start index in implTypes table for specified implementation
|
|
mfxU32 minIndex;
|
|
// last index in implTypes table for specified implementation
|
|
mfxU32 maxIndex;
|
|
|
|
} implTypesRange[] = {
|
|
{ 0, 1 }, // MFX_IMPL_AUTO
|
|
{ 1, 1 }, // MFX_IMPL_SOFTWARE
|
|
{ 0, 0 }, // MFX_IMPL_HARDWARE
|
|
{ 2, 6 }, // MFX_IMPL_AUTO_ANY
|
|
{ 2, 5 }, // MFX_IMPL_HARDWARE_ANY
|
|
{ 3, 3 }, // MFX_IMPL_HARDWARE2
|
|
{ 4, 4 }, // MFX_IMPL_HARDWARE3
|
|
{ 5, 5 }, // MFX_IMPL_HARDWARE4
|
|
{ 2, 6 }, // MFX_IMPL_RUNTIME, same as MFX_IMPL_HARDWARE_ANY
|
|
};
|
|
|
|
MFX::mfxCriticalSection dispGuard = 0;
|
|
|
|
} // namespace
|
|
|
|
using namespace MFX;
|
|
|
|
#if !defined(MEDIASDK_UWP_DISPATCHER)
|
|
|
|
//
|
|
// Implement DLL exposed functions. MFXInit and MFXClose have to do
|
|
// slightly more than other. They require to be implemented explicitly.
|
|
// All other functions are implemented implicitly.
|
|
//
|
|
|
|
typedef MFXVector<MFX_DISP_HANDLE_EX *> HandleVector;
|
|
typedef MFXVector<mfxStatus> StatusVector;
|
|
|
|
struct VectorHandleGuard {
|
|
explicit VectorHandleGuard(HandleVector &aVector) : m_vector(aVector) {}
|
|
~VectorHandleGuard() {
|
|
HandleVector::iterator it = m_vector.begin(), et = m_vector.end();
|
|
for (; it != et; ++it) {
|
|
delete *it;
|
|
}
|
|
}
|
|
|
|
HandleVector &m_vector;
|
|
|
|
private:
|
|
void operator=(const VectorHandleGuard &);
|
|
};
|
|
|
|
static int HandleSort(const void *plhs, const void *prhs) {
|
|
const MFX_DISP_HANDLE_EX *lhs = *(const MFX_DISP_HANDLE_EX **)plhs;
|
|
const MFX_DISP_HANDLE_EX *rhs = *(const MFX_DISP_HANDLE_EX **)prhs;
|
|
const mfxVersion vplInitVersion = { 255, 1 };
|
|
|
|
// prefer oneVPL runtime (API = 1.255)
|
|
if ((lhs->actualApiVersion.Version == vplInitVersion.Version) &&
|
|
(rhs->actualApiVersion < lhs->actualApiVersion)) {
|
|
return -1;
|
|
}
|
|
if ((rhs->actualApiVersion.Version == vplInitVersion.Version) &&
|
|
(lhs->actualApiVersion < rhs->actualApiVersion)) {
|
|
return 1;
|
|
}
|
|
|
|
// prefer HW implementation
|
|
if (lhs->implType != MFX_LIB_HARDWARE && rhs->implType == MFX_LIB_HARDWARE) {
|
|
return 1;
|
|
}
|
|
if (lhs->implType == MFX_LIB_HARDWARE && rhs->implType != MFX_LIB_HARDWARE) {
|
|
return -1;
|
|
}
|
|
|
|
// prefer integrated GPU
|
|
if (lhs->mediaAdapterType != MFX_MEDIA_INTEGRATED &&
|
|
rhs->mediaAdapterType == MFX_MEDIA_INTEGRATED) {
|
|
return 1;
|
|
}
|
|
if (lhs->mediaAdapterType == MFX_MEDIA_INTEGRATED &&
|
|
rhs->mediaAdapterType != MFX_MEDIA_INTEGRATED) {
|
|
return -1;
|
|
}
|
|
|
|
// prefer dll with lower API version
|
|
if (lhs->actualApiVersion < rhs->actualApiVersion) {
|
|
return -1;
|
|
}
|
|
if (rhs->actualApiVersion < lhs->actualApiVersion) {
|
|
return 1;
|
|
}
|
|
|
|
// if versions are equal prefer library with HW
|
|
if (lhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION && rhs->loadStatus == MFX_ERR_NONE) {
|
|
return 1;
|
|
}
|
|
if (lhs->loadStatus == MFX_ERR_NONE && rhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session) {
|
|
MFX::MFXAutomaticCriticalSection guard(&dispGuard);
|
|
|
|
DISPATCHER_LOG_BLOCK(("MFXInitEx (impl=%s, pVer=%d.%d, ExternalThreads=%d session=0x%p\n",
|
|
DispatcherLog_GetMFXImplString(par.Implementation).c_str(),
|
|
par.Version.Major,
|
|
par.Version.Minor,
|
|
par.ExternalThreads,
|
|
session));
|
|
|
|
mfxStatus mfxRes = MFX_ERR_UNSUPPORTED;
|
|
HandleVector allocatedHandle;
|
|
VectorHandleGuard handleGuard(allocatedHandle);
|
|
|
|
MFX_DISP_HANDLE_EX *pHandle;
|
|
wchar_t dllName[MFX_MAX_DLL_PATH] = { 0 };
|
|
MFX::MFXLibraryIterator libIterator;
|
|
|
|
// there iterators are used only if the caller specified implicit type like AUTO
|
|
mfxU32 curImplIdx, maxImplIdx;
|
|
// implementation method masked from the input parameter
|
|
// special case for audio library
|
|
const mfxIMPL implMethod = par.Implementation & (MFX_IMPL_VIA_ANY - 1);
|
|
|
|
// implementation interface masked from the input parameter
|
|
mfxIMPL implInterface = par.Implementation & -MFX_IMPL_VIA_ANY;
|
|
mfxIMPL implInterfaceOrig = implInterface;
|
|
mfxVersion requiredVersion = { { MFX_VERSION_MINOR, MFX_VERSION_MAJOR } };
|
|
|
|
mfxInitializationParam vplParam = {};
|
|
if (implMethod == MFX_IMPL_SOFTWARE) {
|
|
vplParam.AccelerationMode = MFX_ACCEL_MODE_NA;
|
|
}
|
|
else {
|
|
// hardware - D3D11 by default
|
|
if (implInterface == MFX_IMPL_VIA_D3D9)
|
|
vplParam.AccelerationMode = MFX_ACCEL_MODE_VIA_D3D9;
|
|
else
|
|
vplParam.AccelerationMode = MFX_ACCEL_MODE_VIA_D3D11;
|
|
}
|
|
|
|
// check error(s)
|
|
if (NULL == session) {
|
|
return MFX_ERR_NULL_PTR;
|
|
}
|
|
|
|
if (((MFX_IMPL_AUTO > implMethod) || (MFX_IMPL_RUNTIME < implMethod))) {
|
|
return MFX_ERR_UNSUPPORTED;
|
|
}
|
|
|
|
// set the minimal required version
|
|
requiredVersion = par.Version;
|
|
|
|
try {
|
|
// reset the session value
|
|
*session = 0;
|
|
|
|
// allocate the dispatching handle and call-table
|
|
pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
|
|
}
|
|
catch (...) {
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
}
|
|
|
|
DISPATCHER_LOG_INFO(
|
|
(("Required API version is %u.%u\n"), requiredVersion.Major, requiredVersion.Minor));
|
|
// particular implementation value
|
|
mfxIMPL curImpl;
|
|
|
|
// Load HW library or RT from system location
|
|
curImplIdx = implTypesRange[implMethod].minIndex;
|
|
maxImplIdx = implTypesRange[implMethod].maxIndex;
|
|
do {
|
|
int currentStorage = MFX::MFX_STORAGE_ID_FIRST;
|
|
implInterface = implInterfaceOrig;
|
|
do {
|
|
// this storage will be checked below
|
|
if (currentStorage == MFX::MFX_APP_FOLDER) {
|
|
currentStorage += 1;
|
|
continue;
|
|
}
|
|
|
|
// initialize the library iterator
|
|
mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
|
|
implInterface,
|
|
implTypes[curImplIdx].adapterID,
|
|
currentStorage);
|
|
|
|
// look through the list of installed SDK version,
|
|
// looking for a suitable library with higher merit value.
|
|
if (MFX_ERR_NONE == mfxRes) {
|
|
if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType &&
|
|
(!implInterface || MFX_IMPL_VIA_ANY == implInterface)) {
|
|
implInterface = libIterator.GetImplementationType();
|
|
}
|
|
|
|
do {
|
|
eMfxImplType implType = implTypes[curImplIdx].implType;
|
|
|
|
// select a desired DLL
|
|
mfxRes = libIterator.SelectDLLVersion(dllName,
|
|
sizeof(dllName) / sizeof(dllName[0]),
|
|
&implType,
|
|
pHandle->apiVersion);
|
|
if (MFX_ERR_NONE != mfxRes) {
|
|
break;
|
|
}
|
|
DISPATCHER_LOG_INFO((("loading library %S\n"), dllName));
|
|
// try to load the selected DLL
|
|
curImpl = implTypes[curImplIdx].impl;
|
|
mfxRes = pHandle->LoadSelectedDLL(dllName,
|
|
implType,
|
|
curImpl,
|
|
implInterface,
|
|
par,
|
|
vplParam);
|
|
// unload the failed DLL
|
|
if (MFX_ERR_NONE != mfxRes) {
|
|
pHandle->Close();
|
|
continue;
|
|
}
|
|
|
|
mfxPlatform platform = { MFX_PLATFORM_UNKNOWN, 0, MFX_MEDIA_UNKNOWN };
|
|
if (pHandle->callTable[eMFXVideoCORE_QueryPlatform]) {
|
|
mfxRes = MFXVideoCORE_QueryPlatform((mfxSession)pHandle, &platform);
|
|
if (MFX_ERR_NONE != mfxRes) {
|
|
DISPATCHER_LOG_WRN(
|
|
("MFXVideoCORE_QueryPlatform failed, rejecting loaded library\n"));
|
|
pHandle->Close();
|
|
continue;
|
|
}
|
|
}
|
|
pHandle->mediaAdapterType = platform.MediaAdapterType;
|
|
DISPATCHER_LOG_INFO(
|
|
(("media adapter type is %d\n"), pHandle->mediaAdapterType));
|
|
|
|
libIterator.GetSubKeyName(
|
|
pHandle->subkeyName,
|
|
sizeof(pHandle->subkeyName) / sizeof(pHandle->subkeyName[0]));
|
|
pHandle->storageID = libIterator.GetStorageID();
|
|
allocatedHandle.push_back(pHandle);
|
|
pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
|
|
} while (MFX_ERR_NONE != mfxRes);
|
|
}
|
|
|
|
// select another place for loading engine
|
|
currentStorage += 1;
|
|
|
|
} while ((MFX_ERR_NONE != mfxRes) && (MFX::MFX_STORAGE_ID_LAST >= currentStorage));
|
|
|
|
} while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx));
|
|
|
|
curImplIdx = implTypesRange[implMethod].minIndex;
|
|
maxImplIdx = implTypesRange[implMethod].maxIndex;
|
|
|
|
// Load RT from app folder (libmfxsw64 with API >= 1.10)
|
|
do {
|
|
implInterface = implInterfaceOrig;
|
|
// initialize the library iterator
|
|
mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
|
|
implInterface,
|
|
implTypes[curImplIdx].adapterID,
|
|
MFX::MFX_APP_FOLDER);
|
|
|
|
if (MFX_ERR_NONE == mfxRes) {
|
|
if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType &&
|
|
(!implInterface || MFX_IMPL_VIA_ANY == implInterface)) {
|
|
implInterface = libIterator.GetImplementationType();
|
|
}
|
|
|
|
do {
|
|
eMfxImplType implType;
|
|
|
|
// select a desired DLL
|
|
mfxRes = libIterator.SelectDLLVersion(dllName,
|
|
sizeof(dllName) / sizeof(dllName[0]),
|
|
&implType,
|
|
pHandle->apiVersion);
|
|
if (MFX_ERR_NONE != mfxRes) {
|
|
break;
|
|
}
|
|
DISPATCHER_LOG_INFO((("loading library %S\n"), dllName));
|
|
|
|
// try to load the selected DLL
|
|
curImpl = implTypes[curImplIdx].impl;
|
|
mfxRes = pHandle->LoadSelectedDLL(dllName,
|
|
implType,
|
|
curImpl,
|
|
implInterface,
|
|
par,
|
|
vplParam);
|
|
// unload the failed DLL
|
|
if (MFX_ERR_NONE != mfxRes) {
|
|
pHandle->Close();
|
|
}
|
|
else {
|
|
if (pHandle->actualApiVersion.Major == 1 &&
|
|
pHandle->actualApiVersion.Minor <= 9) {
|
|
// this is not RT, skip it
|
|
mfxRes = MFX_ERR_ABORTED;
|
|
break;
|
|
}
|
|
pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
|
|
allocatedHandle.push_back(pHandle);
|
|
pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
|
|
}
|
|
|
|
} while (MFX_ERR_NONE != mfxRes);
|
|
}
|
|
} while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx));
|
|
|
|
// Load HW and SW libraries using legacy default DLL search mechanism
|
|
// set current library index again
|
|
curImplIdx = implTypesRange[implMethod].minIndex;
|
|
do {
|
|
implInterface = implInterfaceOrig;
|
|
|
|
mfxRes = MFX::mfx_get_default_dll_name(dllName,
|
|
sizeof(dllName) / sizeof(dllName[0]),
|
|
implTypes[curImplIdx].implType);
|
|
|
|
if (MFX_ERR_NONE == mfxRes) {
|
|
DISPATCHER_LOG_INFO((("loading default library %S\n"), dllName))
|
|
|
|
// try to load the selected DLL using default DLL search mechanism
|
|
if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType) {
|
|
if (!implInterface) {
|
|
implInterface = MFX_IMPL_VIA_ANY;
|
|
}
|
|
mfxU32 curVendorID = 0, curDeviceID = 0;
|
|
mfxRes = MFX::SelectImplementationType(implTypes[curImplIdx].adapterID,
|
|
&implInterface,
|
|
&curVendorID,
|
|
&curDeviceID);
|
|
if (curVendorID != INTEL_VENDOR_ID)
|
|
mfxRes = MFX_ERR_UNKNOWN;
|
|
}
|
|
if (MFX_ERR_NONE == mfxRes) {
|
|
// try to load the selected DLL using default DLL search mechanism
|
|
mfxRes = pHandle->LoadSelectedDLL(dllName,
|
|
implTypes[curImplIdx].implType,
|
|
implTypes[curImplIdx].impl,
|
|
implInterface,
|
|
par,
|
|
vplParam);
|
|
}
|
|
// unload the failed DLL
|
|
if ((MFX_ERR_NONE != mfxRes) && (MFX_WRN_PARTIAL_ACCELERATION != mfxRes)) {
|
|
pHandle->Close();
|
|
}
|
|
else {
|
|
pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
|
|
allocatedHandle.push_back(pHandle);
|
|
pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
|
|
}
|
|
}
|
|
} while ((MFX_ERR_NONE > mfxRes) && (++curImplIdx <= maxImplIdx));
|
|
delete pHandle;
|
|
|
|
if (allocatedHandle.size() == 0)
|
|
return MFX_ERR_UNSUPPORTED;
|
|
|
|
{ // sort candidate list
|
|
bool NeedSort = false;
|
|
HandleVector::iterator first = allocatedHandle.begin(), it = allocatedHandle.begin(),
|
|
et = allocatedHandle.end();
|
|
for (it++; it != et; ++it)
|
|
if (HandleSort(&(*first), &(*it)) != 0)
|
|
NeedSort = true;
|
|
|
|
// sort allocatedHandle so that the most preferred dll is at the beginning
|
|
if (NeedSort)
|
|
qsort(&(*allocatedHandle.begin()),
|
|
allocatedHandle.size(),
|
|
sizeof(MFX_DISP_HANDLE_EX *),
|
|
&HandleSort);
|
|
}
|
|
HandleVector::iterator candidate = allocatedHandle.begin();
|
|
// check the final result of loading
|
|
try {
|
|
pHandle = *candidate;
|
|
//pulling up current mediasdk version, that required to match plugin version
|
|
//block for now to avoid KW scanning failure (UNUSED)
|
|
//mfxVersion apiVerActual = { { 0, 0 } };
|
|
//mfxStatus stsQueryVersion =
|
|
// MFXQueryVersion((mfxSession)pHandle, &apiVerActual);
|
|
}
|
|
catch (...) {
|
|
DISPATCHER_LOG_ERROR((("unknown exception while loading plugins\n")))
|
|
}
|
|
|
|
// everything is OK. Save pointers to the output variable
|
|
*candidate = 0; // keep this one safe from guard destructor
|
|
|
|
//===================================
|
|
|
|
// MFXVideoCORE_QueryPlatform call creates d3d device handle, so we have handle right after MFXInit and can't accept external handle
|
|
// This is a workaround which calls close-init to remove that handle
|
|
|
|
mfxFunctionPointer *actualTable = pHandle->callTable;
|
|
mfxFunctionPointer pFunc;
|
|
|
|
pFunc = actualTable[eMFXClose];
|
|
mfxRes = (*(mfxStatus(MFX_CDECL *)(mfxSession))pFunc)(pHandle->session);
|
|
if (mfxRes != MFX_ERR_NONE)
|
|
return mfxRes;
|
|
|
|
pHandle->session = 0;
|
|
bool callOldInit = !actualTable[eMFXInitEx];
|
|
pFunc = actualTable[(callOldInit) ? eMFXInit : eMFXInitEx];
|
|
|
|
mfxVersion version(pHandle->apiVersion);
|
|
if (callOldInit) {
|
|
pHandle->loadStatus = (*(mfxStatus(MFX_CDECL *)(mfxIMPL, mfxVersion *, mfxSession *))pFunc)(
|
|
pHandle->impl | pHandle->implInterface,
|
|
&version,
|
|
&pHandle->session);
|
|
}
|
|
else {
|
|
mfxInitParam initPar = par;
|
|
initPar.Implementation = pHandle->impl | pHandle->implInterface;
|
|
initPar.Version = version;
|
|
pHandle->loadStatus =
|
|
(*(mfxStatus(MFX_CDECL *)(mfxInitParam, mfxSession *))pFunc)(initPar,
|
|
&pHandle->session);
|
|
}
|
|
|
|
//===================================
|
|
|
|
*((MFX_DISP_HANDLE_EX **)session) = pHandle;
|
|
|
|
return pHandle->loadStatus;
|
|
|
|
} // mfxStatus MFXInitEx(mfxIMPL impl, mfxVersion *ver, mfxSession *session)
|
|
|
|
// internal function - load a specific DLL, return unsupported if it fails
|
|
// vplParam is required for API >= 2.0 (load via MFXInitialize)
|
|
mfxStatus MFXInitEx2(mfxVersion version,
|
|
mfxInitializationParam vplParam,
|
|
mfxIMPL hwImpl,
|
|
mfxSession *session,
|
|
mfxU16 *deviceID,
|
|
wchar_t *dllName) {
|
|
MFX::MFXAutomaticCriticalSection guard(&dispGuard);
|
|
|
|
mfxStatus mfxRes = MFX_ERR_NONE;
|
|
HandleVector allocatedHandle;
|
|
VectorHandleGuard handleGuard(allocatedHandle);
|
|
|
|
MFX_DISP_HANDLE *pHandle;
|
|
|
|
*deviceID = 0;
|
|
|
|
// fill minimal 1.x parameters for LoadSelectedDLL to choose correct initialization path
|
|
mfxInitParam par = {};
|
|
par.Version = version;
|
|
|
|
// select first adapter if not specified
|
|
// only relevant for MSDK-via-MFXLoad path
|
|
if (!hwImpl)
|
|
hwImpl = MFX_IMPL_HARDWARE;
|
|
|
|
switch (vplParam.AccelerationMode) {
|
|
case MFX_ACCEL_MODE_NA:
|
|
par.Implementation = MFX_IMPL_SOFTWARE;
|
|
break;
|
|
case MFX_ACCEL_MODE_VIA_D3D9:
|
|
par.Implementation = hwImpl | MFX_IMPL_VIA_D3D9;
|
|
break;
|
|
case MFX_ACCEL_MODE_VIA_D3D11:
|
|
par.Implementation = hwImpl | MFX_IMPL_VIA_D3D11;
|
|
break;
|
|
case MFX_ACCEL_MODE_VIA_VAAPI:
|
|
par.Implementation = hwImpl | MFX_IMPL_VIA_VAAPI;
|
|
break;
|
|
default:
|
|
par.Implementation = hwImpl;
|
|
break;
|
|
}
|
|
|
|
#ifdef ONEVPL_EXPERIMENTAL
|
|
// if GPUCopy is enabled via MFXSetConfigProperty(DeviceCopy), set corresponding
|
|
// flag in mfxInitParam for legacy RTs
|
|
par.GPUCopy = vplParam.DeviceCopy;
|
|
#endif
|
|
|
|
// also pass extBuf array (if any) to MFXInitEx for 1.x API
|
|
par.NumExtParam = vplParam.NumExtParam;
|
|
par.ExtParam = (vplParam.NumExtParam ? vplParam.ExtParam : nullptr);
|
|
|
|
eMfxImplType implType =
|
|
(par.Implementation == MFX_IMPL_SOFTWARE ? MFX_LIB_SOFTWARE : MFX_LIB_HARDWARE);
|
|
mfxIMPL implInterface = par.Implementation & -MFX_IMPL_VIA_ANY;
|
|
const mfxIMPL implMethod = par.Implementation & (MFX_IMPL_VIA_ANY - 1);
|
|
|
|
// check error(s)
|
|
if (NULL == session || NULL == dllName) {
|
|
return MFX_ERR_NULL_PTR;
|
|
}
|
|
|
|
try {
|
|
// reset the session value
|
|
*session = 0;
|
|
|
|
// allocate the dispatching handle and call-table
|
|
pHandle = new MFX_DISP_HANDLE(par.Version);
|
|
}
|
|
catch (...) {
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
}
|
|
|
|
if (MFX_ERR_NONE == mfxRes) {
|
|
DISPATCHER_LOG_INFO((("loading default library %S\n"), dllName))
|
|
|
|
if (MFX_ERR_NONE == mfxRes) {
|
|
// try to load the selected DLL using given DLL name
|
|
mfxRes = pHandle->LoadSelectedDLL(dllName,
|
|
implType,
|
|
implMethod,
|
|
implInterface,
|
|
par,
|
|
vplParam);
|
|
}
|
|
// unload the failed DLL
|
|
if (MFX_ERR_NONE != mfxRes) {
|
|
pHandle->Close();
|
|
delete pHandle;
|
|
return MFX_ERR_UNSUPPORTED;
|
|
}
|
|
else {
|
|
pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
|
|
}
|
|
}
|
|
|
|
// everything is OK. Save pointers to the output variable
|
|
*((MFX_DISP_HANDLE **)session) = pHandle;
|
|
|
|
return pHandle->loadStatus;
|
|
}
|
|
|
|
mfxStatus MFXClose(mfxSession session) {
|
|
MFX::MFXAutomaticCriticalSection guard(&dispGuard);
|
|
|
|
mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
|
|
MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *)session;
|
|
|
|
// check error(s)
|
|
if (pHandle) {
|
|
try {
|
|
// unload the DLL library
|
|
mfxRes = pHandle->Close();
|
|
|
|
// it is possible, that there is an active child session.
|
|
// can't unload library in that case.
|
|
if (MFX_ERR_UNDEFINED_BEHAVIOR != mfxRes) {
|
|
// release the handle
|
|
delete pHandle;
|
|
}
|
|
}
|
|
catch (...) {
|
|
mfxRes = MFX_ERR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
|
|
return mfxRes;
|
|
|
|
} // mfxStatus MFXClose(mfxSession session)
|
|
|
|
#else // relates to !defined (MEDIASDK_UWP_DISPATCHER), i.e. #else part as if MEDIASDK_UWP_DISPATCHER defined
|
|
|
|
static mfxModuleHandle hModule;
|
|
|
|
// for the UWP_DISPATCHER purposes implementation of MFXinitEx is calling
|
|
// InitialiseMediaSession() implemented in intel_gfx_api.dll
|
|
mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session) {
|
|
#if defined(MEDIASDK_ARM_LOADER)
|
|
|
|
return MFX_ERR_UNSUPPORTED;
|
|
|
|
#else
|
|
|
|
wchar_t IntelGFXAPIdllName[MFX_MAX_DLL_PATH] = { 0 };
|
|
mfxI32 adapterNum = -1;
|
|
|
|
switch (par.Implementation & 0xf) {
|
|
case MFX_IMPL_SOFTWARE:
|
|
#if (MFX_VERSION >= MFX_VERSION_NEXT)
|
|
case MFX_IMPL_SINGLE_THREAD:
|
|
#endif
|
|
return MFX_ERR_UNSUPPORTED;
|
|
case MFX_IMPL_AUTO:
|
|
case MFX_IMPL_HARDWARE:
|
|
adapterNum = 0;
|
|
break;
|
|
case MFX_IMPL_HARDWARE2:
|
|
adapterNum = 1;
|
|
break;
|
|
case MFX_IMPL_HARDWARE3:
|
|
adapterNum = 2;
|
|
break;
|
|
case MFX_IMPL_HARDWARE4:
|
|
adapterNum = 3;
|
|
break;
|
|
default:
|
|
return GfxApiInitPriorityIntegrated(par, session, hModule);
|
|
}
|
|
|
|
return GfxApiInitByAdapterNum(par, adapterNum, session, hModule);
|
|
|
|
#endif
|
|
}
|
|
|
|
// for the UWP_DISPATCHER purposes implementation of MFXClose is calling
|
|
// DisposeMediaSession() implemented in intel_gfx_api.dll
|
|
mfxStatus MFXClose(mfxSession session) {
|
|
if (NULL == session) {
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
}
|
|
|
|
mfxStatus sts = MFX_ERR_NONE;
|
|
|
|
#if defined(MEDIASDK_ARM_LOADER)
|
|
|
|
sts = MFX_ERR_UNSUPPORTED;
|
|
|
|
#else
|
|
|
|
sts = GfxApiClose(session, hModule);
|
|
|
|
#endif
|
|
|
|
session = (mfxSession)NULL;
|
|
return sts;
|
|
}
|
|
|
|
#undef FUNCTION
|
|
#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
|
|
return_value func_name formal_param_list { \
|
|
mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
|
|
\
|
|
_mfxSession *pHandle = (_mfxSession *)session; \
|
|
\
|
|
/* get the function's address and make a call */ \
|
|
if (pHandle) { \
|
|
mfxFunctionPointer pFunc = pHandle->callPlugInsTable[e##func_name]; \
|
|
if (pFunc) { \
|
|
/* pass down the call */ \
|
|
mfxRes = (*(mfxStatus(MFX_CDECL *) formal_param_list)pFunc)actual_param_list; \
|
|
} \
|
|
} \
|
|
return mfxRes; \
|
|
}
|
|
|
|
FUNCTION(mfxStatus,
|
|
MFXVideoUSER_Load,
|
|
(mfxSession session, const mfxPluginUID *uid, mfxU32 version),
|
|
(session, uid, version))
|
|
FUNCTION(
|
|
mfxStatus,
|
|
MFXVideoUSER_LoadByPath,
|
|
(mfxSession session, const mfxPluginUID *uid, mfxU32 version, const mfxChar *path, mfxU32 len),
|
|
(session, uid, version, path, len))
|
|
FUNCTION(mfxStatus,
|
|
MFXVideoUSER_UnLoad,
|
|
(mfxSession session, const mfxPluginUID *uid),
|
|
(session, uid))
|
|
FUNCTION(mfxStatus,
|
|
MFXAudioUSER_Load,
|
|
(mfxSession session, const mfxPluginUID *uid, mfxU32 version),
|
|
(session, uid, version))
|
|
FUNCTION(mfxStatus,
|
|
MFXAudioUSER_UnLoad,
|
|
(mfxSession session, const mfxPluginUID *uid),
|
|
(session, uid))
|
|
|
|
#endif //!defined(MEDIASDK_UWP_DISPATCHER)
|
|
|
|
mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session) {
|
|
mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
|
|
MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *)session;
|
|
MFX_DISP_HANDLE *pChildHandle = (MFX_DISP_HANDLE *)child_session;
|
|
|
|
// get the function's address and make a call
|
|
if ((pHandle) && (pChildHandle) &&
|
|
(pHandle->actualApiVersion == pChildHandle->actualApiVersion)) {
|
|
/* check whether it is audio session or video */
|
|
int tableIndex = eMFXJoinSession;
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callTable[tableIndex];
|
|
|
|
if (pFunc) {
|
|
// pass down the call
|
|
mfxRes =
|
|
(*(mfxStatus(MFX_CDECL *)(mfxSession, mfxSession))pFunc)(pHandle->session,
|
|
pChildHandle->session);
|
|
}
|
|
}
|
|
|
|
return mfxRes;
|
|
|
|
} // mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session)
|
|
|
|
static mfxStatus AllocateCloneHandle(MFX_DISP_HANDLE *parentHandle, MFX_DISP_HANDLE **cloneHandle) {
|
|
MFX_DISP_HANDLE *ph = parentHandle;
|
|
MFX_DISP_HANDLE *ch = nullptr;
|
|
|
|
if (!ph || !ph->hModule)
|
|
return MFX_ERR_NULL_PTR;
|
|
|
|
// get full path to the DLL of the parent session
|
|
wchar_t dllName[MFX::msdk_disp_path_len];
|
|
DWORD nSize = GetModuleFileNameW((HMODULE)(ph->hModule), dllName, msdk_disp_path_len);
|
|
if (nSize == 0 || nSize == msdk_disp_path_len)
|
|
return MFX_ERR_UNSUPPORTED;
|
|
|
|
try {
|
|
// requested version matches original session
|
|
ch = new MFX_DISP_HANDLE(ph->apiVersion);
|
|
}
|
|
catch (...) {
|
|
return MFX_ERR_MEMORY_ALLOC;
|
|
}
|
|
|
|
// initialization param structs are not used when bCloneSession == true
|
|
mfxInitParam par = {};
|
|
mfxInitializationParam vplParam = {};
|
|
|
|
// initialization extBufs are not saved at this level
|
|
// the RT should save these when the parent session is created and may use
|
|
// them when creating the cloned session
|
|
par.NumExtParam = 0;
|
|
|
|
// load the selected DLL, fill out function pointer tables and other state
|
|
mfxStatus sts = ch->LoadSelectedDLL(dllName,
|
|
ph->implType,
|
|
ph->impl,
|
|
ph->implInterface,
|
|
par,
|
|
vplParam,
|
|
true);
|
|
|
|
// unload the failed DLL
|
|
if (sts) {
|
|
ch->Close();
|
|
delete ch;
|
|
return MFX_ERR_UNSUPPORTED;
|
|
}
|
|
else {
|
|
ch->storageID = MFX::MFX_UNKNOWN_KEY;
|
|
}
|
|
|
|
*cloneHandle = ch;
|
|
|
|
return MFX_ERR_NONE;
|
|
}
|
|
|
|
mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone) {
|
|
mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;
|
|
MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *)session;
|
|
mfxVersion apiVersion;
|
|
mfxIMPL impl;
|
|
|
|
if (!clone)
|
|
return MFX_ERR_NULL_PTR;
|
|
*clone = NULL;
|
|
|
|
// check error(s)
|
|
if (pHandle) {
|
|
// initialize the clone session
|
|
// for runtimes with 1.x API, call MFXInit followed by MFXJoinSession
|
|
// for runtimes with 2.x API, use RT implementation of MFXCloneSession (passthrough)
|
|
apiVersion = pHandle->actualApiVersion;
|
|
|
|
if (apiVersion.Major == 1) {
|
|
impl = pHandle->impl | pHandle->implInterface;
|
|
mfxRes = MFXInit(impl, &apiVersion, clone);
|
|
if (MFX_ERR_NONE != mfxRes) {
|
|
return mfxRes;
|
|
}
|
|
|
|
// join the sessions
|
|
mfxRes = MFXJoinSession(session, *clone);
|
|
if (MFX_ERR_NONE != mfxRes) {
|
|
MFXClose(*clone);
|
|
*clone = NULL;
|
|
return mfxRes;
|
|
}
|
|
}
|
|
else if (apiVersion.Major == 2) {
|
|
int tableIndex = eMFXCloneSession;
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callTable[tableIndex];
|
|
if (!pFunc)
|
|
return MFX_ERR_UNSUPPORTED;
|
|
|
|
// allocate new dispatcher-level session object and initialize state
|
|
// (function pointer tables, impl type, etc.)
|
|
MFX_DISP_HANDLE *cloneHandle;
|
|
mfxRes = AllocateCloneHandle(pHandle, &cloneHandle);
|
|
if (mfxRes != MFX_ERR_NONE)
|
|
return mfxRes;
|
|
|
|
// call RT implementation of MFXCloneSession
|
|
mfxSession cloneRT;
|
|
mfxRes = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxSession *))pFunc)(pHandle->session,
|
|
&cloneRT);
|
|
|
|
if (mfxRes != MFX_ERR_NONE || cloneRT == NULL) {
|
|
// RT call failed, delete cloned session
|
|
delete cloneHandle;
|
|
return MFX_ERR_UNSUPPORTED;
|
|
}
|
|
cloneHandle->session = cloneRT;
|
|
|
|
// get version of cloned session
|
|
mfxVersion cloneVersion = {};
|
|
mfxRes = MFXQueryVersion((mfxSession)cloneHandle, &cloneVersion);
|
|
if (mfxRes != MFX_ERR_NONE) {
|
|
MFXClose(cloneHandle);
|
|
return MFX_ERR_UNSUPPORTED;
|
|
}
|
|
|
|
cloneHandle->actualApiVersion = cloneVersion;
|
|
*clone = (mfxSession)cloneHandle;
|
|
}
|
|
else {
|
|
return MFX_ERR_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
return mfxRes;
|
|
|
|
} // mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone)
|
|
|
|
mfxStatus MFXInit(mfxIMPL impl, mfxVersion *pVer, mfxSession *session) {
|
|
mfxInitParam par = {};
|
|
|
|
par.Implementation = impl;
|
|
if (pVer) {
|
|
par.Version = *pVer;
|
|
}
|
|
else {
|
|
par.Version.Major = DEFAULT_API_VERSION_MAJOR;
|
|
par.Version.Minor = DEFAULT_API_VERSION_MINOR;
|
|
}
|
|
par.ExternalThreads = 0;
|
|
|
|
return MFXInitEx(par, session);
|
|
}
|
|
|
|
// passthrough functions to implementation
|
|
mfxStatus MFXMemory_GetSurfaceForVPP(mfxSession session, mfxFrameSurface1 **surface) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXMemory_GetSurfaceForVPP];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 **))pFunc)(session, surface);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXMemory_GetSurfaceForVPPOut(mfxSession session, mfxFrameSurface1 **surface) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXMemory_GetSurfaceForVPPOut];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 **))pFunc)(session, surface);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXMemory_GetSurfaceForEncode(mfxSession session, mfxFrameSurface1 **surface) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXMemory_GetSurfaceForEncode];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 **))pFunc)(session, surface);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXMemory_GetSurfaceForDecode(mfxSession session, mfxFrameSurface1 **surface) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXMemory_GetSurfaceForDecode];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 **))pFunc)(session, surface);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXVideoDECODE_VPP_Init(mfxSession session,
|
|
mfxVideoParam *decode_par,
|
|
mfxVideoChannelParam **vpp_par_array,
|
|
mfxU32 num_vpp_par) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_Init];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts =
|
|
(*(mfxStatus(MFX_CDECL *)(mfxSession, mfxVideoParam *, mfxVideoChannelParam **, mfxU32))
|
|
pFunc)(session, decode_par, vpp_par_array, num_vpp_par);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXVideoDECODE_VPP_DecodeFrameAsync(mfxSession session,
|
|
mfxBitstream *bs,
|
|
mfxU32 *skip_channels,
|
|
mfxU32 num_skip_channels,
|
|
mfxSurfaceArray **surf_array_out) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_DecodeFrameAsync];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts = (*(mfxStatus(
|
|
MFX_CDECL *)(mfxSession, mfxBitstream *, mfxU32 *, mfxU32, mfxSurfaceArray **))
|
|
pFunc)(session, bs, skip_channels, num_skip_channels, surf_array_out);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXVideoDECODE_VPP_Reset(mfxSession session,
|
|
mfxVideoParam *decode_par,
|
|
mfxVideoChannelParam **vpp_par_array,
|
|
mfxU32 num_vpp_par) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_Reset];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts =
|
|
(*(mfxStatus(MFX_CDECL *)(mfxSession, mfxVideoParam *, mfxVideoChannelParam **, mfxU32))
|
|
pFunc)(session, decode_par, vpp_par_array, num_vpp_par);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXVideoDECODE_VPP_GetChannelParam(mfxSession session,
|
|
mfxVideoChannelParam *par,
|
|
mfxU32 channel_id) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_GetChannelParam];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxVideoChannelParam *, mfxU32))pFunc)(
|
|
session,
|
|
par,
|
|
channel_id);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXVideoDECODE_VPP_Close(mfxSession session) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_Close];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts = (*(mfxStatus(MFX_CDECL *)(mfxSession))pFunc)(session);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
mfxStatus MFXVideoVPP_ProcessFrameAsync(mfxSession session,
|
|
mfxFrameSurface1 *in,
|
|
mfxFrameSurface1 **out) {
|
|
mfxStatus sts = MFX_ERR_INVALID_HANDLE;
|
|
|
|
if (!session)
|
|
return MFX_ERR_INVALID_HANDLE;
|
|
|
|
struct _mfxSession *pHandle = (struct _mfxSession *)session;
|
|
|
|
mfxFunctionPointer pFunc;
|
|
pFunc = pHandle->callVideoTable2[eMFXVideoVPP_ProcessFrameAsync];
|
|
if (pFunc) {
|
|
session = pHandle->session;
|
|
sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 *, mfxFrameSurface1 **))pFunc)(
|
|
session,
|
|
in,
|
|
out);
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
|
|
//
|
|
//
|
|
// implement all other calling functions.
|
|
// They just call a procedure of DLL library from the table.
|
|
//
|
|
|
|
// define for common functions (from mfxsession.h)
|
|
#undef FUNCTION
|
|
#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
|
|
return_value func_name formal_param_list { \
|
|
mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
|
|
_mfxSession *pHandle = (_mfxSession *)session; \
|
|
/* get the function's address and make a call */ \
|
|
if (pHandle) { \
|
|
/* check whether it is audio session or video */ \
|
|
int tableIndex = e##func_name; \
|
|
mfxFunctionPointer pFunc; \
|
|
pFunc = pHandle->callTable[tableIndex]; \
|
|
if (pFunc) { \
|
|
/* get the real session pointer */ \
|
|
session = pHandle->session; \
|
|
/* pass down the call */ \
|
|
mfxRes = (*(mfxStatus(MFX_CDECL *) formal_param_list)pFunc)actual_param_list; \
|
|
} \
|
|
} \
|
|
return mfxRes; \
|
|
}
|
|
|
|
FUNCTION(mfxStatus, MFXQueryIMPL, (mfxSession session, mfxIMPL *impl), (session, impl))
|
|
FUNCTION(mfxStatus, MFXQueryVersion, (mfxSession session, mfxVersion *version), (session, version))
|
|
|
|
// these functions are not necessary in LOADER part of dispatcher and
|
|
// need to be included only in in SOLID dispatcher or PROCTABLE part of dispatcher
|
|
|
|
FUNCTION(mfxStatus, MFXDisjoinSession, (mfxSession session), (session))
|
|
FUNCTION(mfxStatus, MFXSetPriority, (mfxSession session, mfxPriority priority), (session, priority))
|
|
FUNCTION(mfxStatus,
|
|
MFXGetPriority,
|
|
(mfxSession session, mfxPriority *priority),
|
|
(session, priority))
|
|
|
|
#undef FUNCTION
|
|
#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
|
|
return_value func_name formal_param_list { \
|
|
mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE; \
|
|
_mfxSession *pHandle = (_mfxSession *)session; \
|
|
/* get the function's address and make a call */ \
|
|
if (pHandle) { \
|
|
mfxFunctionPointer pFunc = pHandle->callTable[e##func_name]; \
|
|
if (pFunc) { \
|
|
/* get the real session pointer */ \
|
|
session = pHandle->session; \
|
|
/* pass down the call */ \
|
|
mfxRes = (*(mfxStatus(MFX_CDECL *) formal_param_list)pFunc)actual_param_list; \
|
|
} \
|
|
} \
|
|
return mfxRes; \
|
|
}
|
|
|
|
#include "windows/mfx_exposed_functions_list.h"
|