DirectShow 过滤器未显示为输入捕获设备

Mar*_*ark 3 c++ directshow video-capture input-filter

从此处捕获源过滤器的绝佳示例开始,我编写了自己的输入捕获设备,该设备在 Graph Studio Next 中运行良好,但在 Skype 或类似应用程序中并未显示为捕获设备(即网络摄像头)。

因为我想了解发生了什么,所以我请您帮助我找出那些应用程序需要什么来显示这样的设备。

一些相关代码:

DLL文件

DEFINE_GUID(CLSID_VirtualCam, 0x8e14549a, 0xdb61, 0x4309, 0xaf, 0xa1, 0x35, 0x78, 0xe9, 0x27, 0xe9, 0x33);

const AMOVIESETUP_MEDIATYPE AMSMediaTypesVideo = 
{
    &MEDIATYPE_Video,
    &MEDIASUBTYPE_NULL
};

const AMOVIESETUP_PIN AMSPinVCam[] =
{
    {
        L"Output",             // Pin string name
        FALSE,                 // Is it rendered
        TRUE,                  // Is it an output
        FALSE,                 // Can we have none
        FALSE,                 // Can we have many
        &CLSID_NULL,           // Connects to filter
        NULL,                  // Connects to pin
        1,                     // Number of types
        &AMSMediaTypesVideo      // Pin Media types
    }
};

const AMOVIESETUP_FILTER AMSFilterVCam =
{
    &CLSID_VirtualCam,  // Filter CLSID
    FILTER_NAME,     // String name
    MERIT_PREFERRED,      // Filter merit
    1,                     // Number pins
    AMSPinVCam             // Pin details
};

CFactoryTemplate g_Templates[] = 
{
    {
        FILTER_NAME,
        &CLSID_VirtualCam,
        CVCam::CreateInstance,
        NULL,
        &AMSFilterVCam
    },
};
Run Code Online (Sandbox Code Playgroud)

过滤器.cpp

CVCam::CVCam(LPUNKNOWN lpunk, HRESULT *phr) : CSource(LPCSTR(FILTER_NAME), lpunk, CLSID_VirtualCam)
{
    ASSERT(phr);
    CAutoLock cAutoLock(&m_cStateLock);
    m_paStreams = (CSourceStream **) new CVCamStream*[1];
    m_paStreams[0] = new CVCamStream(phr, this, FILTER_NAME);
}

HRESULT CVCam::QueryInterface(REFIID riid, void **ppv)
{
    if (riid == _uuidof(IAMStreamConfig) || riid == _uuidof(IKsPropertySet))
    {
        HRESULT hr;
        hr = m_paStreams[0]->QueryInterface(riid, ppv);
        if (hr != S_OK) return hr;
    }
    else return CSource::QueryInterface(riid, ppv);

    return S_OK;
}

CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) : CSourceStream(LPCSTR(FILTER_NAME),phr, pParent, pPinName), m_pParent(pParent)
{
    hdc = GetDC(NULL);

    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);

    GetMediaType(8, &m_mt);
}

CVCamStream::~CVCamStream()
{
    Gdiplus::GdiplusShutdown(gdiplusToken);
    DeleteDC(hdc);
} 

HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv)
{   
    if(riid == _uuidof(IAMStreamConfig)) *ppv = (IAMStreamConfig*)this;
    else if(riid == _uuidof(IKsPropertySet)) *ppv = (IKsPropertySet*)this;
    else return CSourceStream::QueryInterface(riid, ppv);

    AddRef();
    return S_OK;
}
Run Code Online (Sandbox Code Playgroud)

我省略了与链接示例非常相似的其他功能,我猜配置是在这些功能中进行的。

您是否发现我的缺陷导致过滤器不被识别为视频捕获设备的任何证据?

当然,过滤器已注册(我在 DirectShow 过滤器管理器中看到它)。

Rom*_* R. 5

不幸的是,您所指的 DirectShow 输入设备项目不是一个 API,它旨在将类似相机的实现带入任何启用视频捕获的应用程序中。

您开发的视频源仅对使用 DirectShow API 进行视频捕获并与您的过滤器具有匹配位数的应用程序可见。尽管相当多的应用程序仍在使用 DirectShow,但它们的使用率往往会随着时间的推移而缓慢下降。例如,新的 Skype 不使用 DirectShow,而 Skype for Business 只是前 Lync 的新名称,这意味着在视频捕获方面与 Skype 几乎没有共享源代码。

我在这篇文章中提供了更多技术细节:虚拟 DirectShow 源的适用性以及该文章中的图片应该给出您的视频源“可见”(绿色框)的应用程序的想法:

也可以看看: