IMFMediaSource“没有为mfcore.dll加载任何符号”,而QueryInterface给出了“ E_NOINTERFACE”

时间:2018-10-27 04:31:02

标签: c++ unity3d ms-media-foundation

我是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();

}

2 个答案:

答案 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继承而来。 为了您的目的-获得设备的友好名称和符号链接,代码必须从IMFAttributesIMFActivate)中获取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