我是COM编程的新手,但精通C#.Net,尝试运行此代码,但是由于某些原因,当我通过将鼠标悬停在“”上来检查值时,IMFMediaSource对象未在调试模式下初始化为Visual Studio。 pSource”指针显示“信息不可用,没有为mfcore.dll加载符号”,但是hr返回“ S_Ok”,但是当Next语句执行“ QueryInterface”时,hr返回“ E_NOINTERFACE”。
请详细解释我做错了什么,因为我的主要动机是制作一个用于视频捕获的DLL,并将其与Unity Engine C#一起使用。
#pragma comment(lib,"mfplat.lib")
#pragma message("linking with Microsoft's Media Foundation mfplat library ...")
#pragma comment(lib,"mf.lib")
#pragma comment(lib,"mfcore.lib")
#pragma message("linking with Microsoft's Media Foundation mf library ...")
#pragma comment(lib,"mfreadwrite.lib")
#pragma message("linking with Microsoft's Media Foundation mfreadwrite library ...")
#pragma comment(lib,"mfuuid.lib")
#pragma message("linking with Microsoft's Media Foundation mfuuid library ...")
#pragma comment(lib,"d3d9.lib")
#pragma message("linking with Microsoft's DirectX 3D 9 library ...")
#pragma comment(lib,"shlwapi.lib")
#pragma message("linking with Microsoft's shlwapi library ...")
#pragma comment(lib,"Advapi32.lib")
#pragma message("linking with Microsoft's Advapi32 library ...")
int main(int argc, char** argv)
{
HRESULT hr;
hr = ::CoInitialize(NULL);
if (FAILED(hr))
abort();
hr = ::MFStartup(MF_VERSION, MFSTARTUP_NOSOCKET);
if (FAILED(hr))
abort();
IMFMediaSource* media_source = 0;
IMFSourceReader* source_reader = 0;
IMFAttributes* pAttributes = 0;
hr = MFCreateAttributes(&pAttributes, 1);
if (FAILED(hr))
abort();
// Set the device type to video.
hr = pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
if (FAILED(hr))
abort();
UINT32 count;
IMFActivate **ppDevices = NULL;
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
if (FAILED(hr))
abort();
if (count == 0)
abort();
// Create the media source object.
IMFMediaSource *pSource = NULL;
hr = ppDevices[0]->ActivateObject(IID_IMFMediaSource, (void**)&pSource);
if (FAILED(hr))
abort();
pSource->AddRef();//on hovering over the "pSource" in VS2017 shows "Information Not available, no symbol loaded for mfcore.dll"
IMFAttributes* pSourceAttributes = NULL;
hr = pSource->QueryInterface(IID_IMFAttributes, (void**)&pSourceAttributes);
if (FAILED(hr))
abort(); //hr is assigned -> "E_NOINTERFACE" and program quits
const size_t nDeviceNameSize = 1024;
LPWSTR pDeviceName = new WCHAR[nDeviceNameSize];
UINT32 nActualBufferSize;
hr = pSourceAttributes->GetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, pDeviceName, nDeviceNameSize, &nActualBufferSize);
if (FAILED(hr))
abort();
// Set the symbolic link.
hr = pAttributes->SetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, pDeviceName);
if (FAILED(hr))
abort();
// Create device source interface
hr = MFCreateDeviceSource(pAttributes, &media_source);
if (FAILED(hr))
abort();
}
答案 0 :(得分:1)
flask run
界面在激活对象上可用,而不在媒体源上[必需]提供。如果您按照如下所示更新代码,则可以查询IMFAttributes
值。这是因为像媒体源这样的原语不需要保留,公开甚至不需要知道注册信息-媒体源本身就是纯实现。
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK
请注意,此记录的行为可在此处找到更多详细信息:Audio/Video Capture in Media Foundation:
您可以查询激活对象的各种属性,包括以下属性:[…] 下面的示例采用
IMFAttributes* pSourceAttributes = NULL; hr = //pSource ppDevices[0] // <<-------- ->QueryInterface(IID_IMFAttributes, (void**)&pSourceAttributes); if (FAILED(hr)) abort(); //hr is assigned -> "E_NOINTERFACE" and program quits
指针数组,并将每个设备的显示名称打印到调试窗口:[…]
答案 1 :(得分:0)
代码
hr = pSource-> QueryInterface(IID_IMFAttributes, (void **)&pSourceAttributes);
返回E_NOINTERFACE
是因为MediaSource
并非从IMFAttributes
继承而来。
为了您的目的-获得设备的友好名称和符号链接,代码必须从IMFAttributes
(IMFActivate
)中获取ppDevices[0]
:
// Read friendlyName of device
ResultCode::Result MediaFoundation::readFriendlyName(IMFActivate *pDevice, std::wstring &friendlyName)
{
ResultCode::Result result = ResultCode::MEDIA_FOUNDATION_READFRIENDLYNAME_ERROR;
wchar_t *pFriendlyName = NULL;
HRESULT hr = S_OK;
hr = pDevice->GetAllocatedString(
MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
&pFriendlyName,
NULL
);
if (FAILED(hr))
{
DebugPrintOut::getInstance().printOut(L"MEDIA FOUNDATION: readFriendlyName cannot be executed!!!\n");
goto finish;
}
friendlyName = std::wstring(pFriendlyName);
result = ResultCode::OK;
finish:
if (pFriendlyName)
CoTaskMemFree(pFriendlyName);
return result;
}
和:
// Read symbolicLink of device
ResultCode::Result MediaFoundation::readSymbolicLink(IMFActivate *pDevice,
std::wstring &symbolicLink)
{
ResultCode::Result result = ResultCode::MEDIA_FOUNDATION_READSYMBOLICLINK_ERROR;
wchar_t *pSymbolicLink = NULL;
HRESULT hr = S_OK;
hr = pDevice->GetAllocatedString(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
&pSymbolicLink,
NULL
);
if (FAILED(hr))
{
DebugPrintOut::getInstance().printOut(L"MEDIA FOUNDATION: readSymbolicLink cannot be executed!!!\n");
goto finish;
}
symbolicLink = std::wstring(pSymbolicLink);
result = ResultCode::OK;
finish:
if (pSymbolicLink)
CoTaskMemFree(pSymbolicLink);
return result;
}
我建议阅读代码为Capturing Live-video from Web-camera on Windows 7 and Windows 8
的文章。P.S。对于Unity Engine,我可以推荐另一个项目:UnityWebCamViewer