Media Foundation - 如何 select 从 crossbar 输入?

Media Foundation - How to select input from crossbar?

晚上好

我正在尝试使用 Media Foundation 将一个小的视频捕获 DLL 放在一起,该 DLL 主要改编自 SimpleCapture 和 CaptureEngine SDK 示例。当我的捕获源是我的内置网络摄像头时,整个事情都很好。

问题是当我尝试使用具有多个输入(s 视频、复合和立体声音频)的外部 USB 图像采集卡时,没有预览流。我有一个使用 DShow 界面的函数,它似乎成功地更改了横杆上的选定输入(通过在 运行 函数之后查看 AMCAP 中的选项进行验证)但是我无法让设备完全预览。

是否有一种媒体基础方法可以从交叉栏中选择输入?或者,如果不是,您能否建议以下交叉开关输入选择代码可能有什么问题:

HRESULT CaptureManager::doSelectInputUsingCrossbar(std::wstring deviceName, long input) 
{


IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
IBaseFilter* pSrc = NULL;

ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pClassEnum = NULL;
IMoniker *pMoniker = NULL;
bool bCameraFound = false;
IPropertyBag *pPropBag = NULL;


bool crossbarSet = false;

HRESULT hr = S_OK;

if (!(input == PhysConn_Video_Composite || input == PhysConn_Video_SVideo))
{
    return S_FALSE;
}



// Create the Filter Graph Manager.
 hr = CoCreateInstance(CLSID_FilterGraph, NULL,
    CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

if (SUCCEEDED(hr))
{
    // Create the Capture Graph Builder.
    hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
        CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
        (void **)&pBuilder);
    if (SUCCEEDED(hr))
    {
        pBuilder->SetFiltergraph(pGraph);
    }
    else return hr;
}
else return hr;

//////////////////////////


// chooses the default camera filter

hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
    IID_ICreateDevEnum, (void **)&pDevEnum);
if (FAILED(hr))
{

    return E_FAIL;
}

// Create an enumerator for video capture devices.

if (FAILED(pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0)))
{

    return E_FAIL;
}

if (pClassEnum == NULL)
{
    CheckHR(hr, "Class enumerator is null - no input devices detected?");
    pDevEnum->Release();
    return E_FAIL;
}



while (!bCameraFound && (pClassEnum->Next(1, &pMoniker, NULL) == S_OK))
{

    HRESULT hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
    if (FAILED(hr))
    {
        pMoniker->Release();
        continue;  // Skip this one, maybe the next one will work.
    }

    // Find the description or friendly name.
    VARIANT varName;
    VariantInit(&varName);
    hr = pPropBag->Read(L"Description", &varName, 0);
    if (FAILED(hr))
    {
        hr = pPropBag->Read(L"FriendlyName", &varName, 0);
    }
    if (SUCCEEDED(hr))
    {
        if (0 == wcscmp(varName.bstrVal, deviceName.c_str()))
        {
            pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc);
            bCameraFound = true;
            break;
        }//if
        VariantClear(&varName);
    }

    pPropBag->Release();
    pMoniker->Release();
}//while

pClassEnum->Release();
pDevEnum->Release();

if (!bCameraFound)//else
{
    CheckHR(hr, "Error: Get device Moniker, No device found");
    goto done;
}



hr = pGraph->AddFilter(pSrc, L"video capture adapter");
if (FAILED(hr))
{
    CheckHR(hr, "Can't add capture device to graph");
    goto done;
}


///////////////


IAMCrossbar *pxBar = NULL;
hr = pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, pSrc, IID_IAMCrossbar, (void **)&pxBar);
if (FAILED(hr))
{
    hr = pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSrc, IID_IAMCrossbar, (void **)&pxBar);

    if (FAILED(hr))
    {
        CheckHR(hr, "Failed to get crossbar filter");
        goto done;
    }
}//if
else
{
    CheckHR(hr, "Failed to get crossbar (capture)");
    goto done;
}

LONG lInpin, lOutpin;
hr = pxBar->get_PinCounts(&lOutpin, &lInpin);

BOOL IPin = TRUE; LONG pIndex = 0, pRIndex = 0, pType = 0;

while (pIndex < lInpin)
{
    hr = pxBar->get_CrossbarPinInfo(IPin, pIndex, &pRIndex, &pType);

    if (pType == input)
    {
        break;
    }

    pIndex++;
}

BOOL OPin = FALSE; LONG pOIndex = 0, pORIndex = 0, pOType = 0;

while (pOIndex < lOutpin)
{
    hr = pxBar->get_CrossbarPinInfo(OPin, pOIndex, &pORIndex, &pOType);

    if (pOType == PhysConn_Video_VideoDecoder)
    {
        break;
    }

    pIndex++;
}

hr = pxBar->Route(pOIndex, pIndex);




done:
SafeRelease(&pPropBag);
SafeRelease(&pMoniker);
SafeRelease(&pxBar);


SafeRelease(&pGraph);
SafeRelease(&pBuilder);
SafeRelease(&pSrc);

return hr;

}

Microsoft Media Foundation 不支持 USB 图像采集卡。 Microsoft Media Foundation 通过 USB 视频 Class 设备驱动程序支持实时源。现代网络摄像头支持此类驱动程序,但 USB 图像采集卡不支持。 USB 帧抓取器支持基于 PUSH 模型处理管道的 DirectShow 过滤器 - 源将媒体样本发送到媒体图中,而 Microsoft Media Foundation 使用 PULL 模型处理管道 - 接收器发送对新媒体样本和源的请求 "listen"这样的要求。

最好的。