无法获取IAMStreamConfig接口

时间:2018-04-10 05:06:24

标签: c++ video directshow video-capture

我可以使用sampleGrabber从网络摄像头捕获图像并将其保存为位图。而且我知道我可以使用IAMStreamConfig接口将GetFormat和SetFormat视频分辨率。我的问题是,我使用FindInterface()获取IAMStreamConfig *但总是失败。这是因为我将它放在错误的地方或其他我没有注意到的地方。我把它放在RenderStream之前。以下是一些代码,感谢您的耐心和帮助!

INT USBDeviceApp::GetInterfaces()
{
    HRESULT hr;

    hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
        IID_IGraphBuilder, (void **) &pGraphBuilder);
    if (FAILED(hr))
        return hr;

    hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
              IID_ICaptureGraphBuilder2, (void **) &pCaptureGraphBuilder2);
    if (FAILED(hr))
        return hr;

    hr = pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID *)
                                       &pMediaControl);
    if (FAILED(hr))
        return hr;


    hr = pGraphBuilder->QueryInterface(IID_IVideoWindow, (LPVOID *) 
                                       &pVideoWindow);
    if(FAILED(hr))
    {
        return hr;
    }
    hr = pGraphBuilder->QueryInterface(IID_IMediaEvent,(LPVOID *) 
                                      &pMediaEvent);
    if(FAILED(hr))
    {
        return hr;
    }
// ------------------------
// Create the Sample Grabber.
    hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
         IID_IBaseFilter, (void**)&pGrabberF);
    if (FAILED(hr))
    {
        return hr;
    }

      hr = pGrabberF->QueryInterface(IID_ISampleGrabber,
                                (void**)&pSampleGrabber);
      if(FAILED(hr))
      {
        AfxMessageBox(_T("Error SampleGrabber QueryInterface"));
      }


    return 1;
}
INT USBDeviceApp::InitMonikers()
{
    HRESULT hr;
    ULONG cFetched;

    ICreateDevEnum *pCreateDevEnum;     
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, 
         CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
    if (FAILED(hr))
    {
        return hr;
    }

    IEnumMoniker *pEnumMoniker; 

    hr = pCreateDevEnum->
    CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumMoniker, 0);
    if (FAILED(hr) || !pEnumMoniker)
    {
        return -1;
    }

    hr = pEnumMoniker->Next(1, &pMonikerVideo, &cFetched);
    if (S_OK == hr)
    {
        hr = pMonikerVideo->BindToObject(0,0,IID_IBaseFilter, 
                                        (void**)&pVideoCaptureFilter);
        if (FAILED(hr))
        {
            return hr;
        }
    }
    pEnumMoniker->Release();

    return 1;
}
INT USBDeviceApp::CaptureVideo()
{
    HRESULT hr = CoInitialize(NULL);

    hr = GetInterfaces();
    if (FAILED(hr))
    {
        AfxMessageBox(_T("Failed to get video interfaces!"));
        return hr;
    }

    hr = pCaptureGraphBuilder2->SetFiltergraph(pGraphBuilder);
    if (FAILED(hr))
    {
        AfxMessageBox(_T("Failed to attach the filter graph to the capture graph!"));
        return hr;
    }
    //IAMStreamConfig *pConfig
    hr = pCaptureGraphBuilder2->FindInterface(&PIN_CATEGORY_PREVIEW,
                                      &MEDIATYPE_Video,
                                      pVideoCaptureFilter,IID_IAMStreamConfig, (void **)&pConfig);
    if (FAILED(hr))
    {
         AfxMessageBox(_T("Couldn't initialize IAMStreamConfig!"));
    }
    else
    {////
        int iCount = 0,iSize = 0;
        hr = pConfig->GetNumberOfCapabilities(&iCount,&iSize);
        if(iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
        {
            for(int iFormat = 0;iFormat < iCount;iFormat++)
            {
                VIDEO_STREAM_CONFIG_CAPS scc;
                AM_MEDIA_TYPE *pmtConfig;
                hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
                if(hr)
                {
                    if((pmtConfig->majortype == MEDIATYPE_Video) &&
                        (pmtConfig->subtype == MEDIASUBTYPE_RGB24) &&
                        (pmtConfig->formattype == FORMAT_VideoInfo) &&
                        (pmtConfig->cbFormat >= sizeof (VIDEOINFOHEADER)) &&
                        (pmtConfig->pbFormat != NULL))
                    {
                        VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig->pbFormat;
                        pVih->bmiHeader.biWidth = 1280;
                        pVih->bmiHeader.biHeight = 720;
                        pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
                        hr = pConfig->SetFormat(pmtConfi);
                    }

                    DeleteMediaType(pmtConfig);
                }
            }
        }
    }////

    hr = InitMonikers();
    if(FAILED(hr))
    {
    return hr;
    }
    hr = pGraphBuilder->AddFilter(pVideoCaptureFilter, L"Video Capture");
    if (FAILED(hr))
    {
        pVideoCaptureFilter->Release();
        return hr;
    }

    AM_MEDIA_TYPE mt;
    ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
    mt.majortype = MEDIATYPE_Video;
    mt.subtype = MEDIASUBTYPE_RGB24;
    hr = pSampleGrabber->SetMediaType(&mt);

    hr = pSampleGrabber->SetOneShot(FALSE);
    hr = pSampleGrabber->SetBufferSamples(TRUE);

    hr = pGraphBuilder->AddFilter(pGrabberF, L"Sample Grabber");
    if (FAILED(hr))
    {
         return hr;
    }

    hr = pCaptureGraphBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pVideoCaptureFilter, pGrabberF, 0 );
    if (FAILED(hr))
    {
        pVideoCaptureFilter->Release();
        return hr;
    }

    hr = pSampleGrabber->GetConnectedMediaType( &mt );
    if(FAILED( hr ))
    {
        return -1; 
    }
    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;

    pVih = (VIDEOINFOHEADER*) mt.pbFormat;

    CSampleGrabberCB *CB  = new CSampleGrabberCB() ;

    if(!FAILED( hr ))
    {
        CB->Width  = vih->bmiHeader.biWidth;
        CB->Height = vih->bmiHeader.biHeight;
        FreeMediaType( mt );
    }
    hr = pSampleGrabber->SetCallback( CB, 1 );

    pVideoCaptureFilter->Release();

    this->SetUpVideoWindow();
    hr = pMediaControl->Run();
    if (FAILED(hr))
    {
        return hr;
    }

    return hr;
}

hr = pCaptureGraphBuilder2-&gt; FindInterface() 总是无法获得IAMStreamConfig界面,我真的不知道为什么。有人可以帮助我,非常感谢!

1 个答案:

答案 0 :(得分:1)

您的API调用

pCaptureGraphBuilder2->FindInterface(&PIN_CATEGORY_PREVIEW,
   &MEDIATYPE_Video,
   pVideoCaptureFilter,IID_IAMStreamConfig, (void **) &pConfig);

对搜索应用了一些限制,包括引脚类别:您正在寻找预览引脚。例如,下图显示了三个视频捕获设备,但没有一个具有专用的预览引脚:预览引脚是可选的。

enter image description here

您需要考虑到这一点并放宽搜索条件,或者我建议您直接在捕获过滤器上找到您感兴趣的引脚。然后,您将设置它并将其与下游对等过滤器连接。 FindInterface功能强大,但也增加了混淆的机会。