XP下采用DirectShow采集摄像头

 

转载请标明是引用于 http://blog.csdn.net/chenyujing1234 

欢迎大家提出意见,一起讨论!

需要示例源码的请独自联系我.

前提: 摄像头能正常工作、摄像头有创建directshow filter

 

大家可以对比我的另一篇文章学习:    wince系统下DirectShow采集摄像头

一、初始化工作

1、DirctShow环境初始化
bool
uEye_DirectShow_Demo_Dlg::DirectShow_Init()
{
    // initialize the COM library on the current thread
    HRESULT err= CoInitialize(NULL);

    if( FAILED(err))
    {
        MessageBoxEx( NULL, "Initializing COM library failed!", __FUNCTION__, MB_ICONERROR, 0);
    }

    return err == S_OK;
}

2、搜索Video源

如果没有设备接入,那么CreateClassEnumerator会返回失败

bool
uEye_DirectShow_Demo_Dlg::VideoSourcesList_Fill()
{
    HRESULT status= S_OK;

    // create System Device Enumerator
    ICreateDevEnum *pSystemDeviceEnumerator= NULL;
    status= CoCreateInstance(  CLSID_SystemDeviceEnum,
                                NULL,
                                CLSCTX_INPROC,
                                IID_ICreateDevEnum,
                                (void**)&pSystemDeviceEnumerator);
    if( FAILED(status))
    {
        MessageBoxEx( NULL, "Creating System Device Enumerator failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    // create Class Enumerator that lists alls video input devices among the system devices
    IEnumMoniker *pVideoInputDeviceEnumerator= NULL;
    status= pSystemDeviceEnumerator->CreateClassEnumerator( CLSID_VideoInputDeviceCategory,
                                                            &pVideoInputDeviceEnumerator,
                                                            0);

    // release the System Device Enumerator which is not needed anymore
    pSystemDeviceEnumerator->Release();
    pSystemDeviceEnumerator= NULL;

    if( status != S_OK)
    {
        MessageBoxEx( NULL, "Creating Class Enumerator failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    // add entry '[no device selected]' to list
    m_comboVideoSources.AddString( "[no device selected]");
    m_comboVideoSources.SetItemDataPtr( 0, NULL);

    // for each enumerated video input device: add it to the list
    IMoniker *pMoniker= NULL;
    while( pVideoInputDeviceEnumerator->Next( 1, &pMoniker, NULL) == S_OK )
    {
        VARIANT var;
        VariantInit(&var);

        // make filters properties accessible
        IPropertyBag *pPropBag= NULL;
        status= pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**)&pPropBag);
        if( FAILED(status))
        {
            pPropBag= NULL;
            MessageBoxEx( NULL, "Accessing filter properties failed!", __FUNCTION__, MB_ICONERROR, 0);
            // continue with the next filter
        }
        else
        {
            // add a reference to the storage object
            pPropBag->AddRef();

            // get the name of this filter
            status= pPropBag->Read( L"FriendlyName", &var, 0);
            if( FAILED(status))
            {
                MessageBoxEx( NULL, "Reading filter name failed!", __FUNCTION__, MB_ICONERROR, 0);
                // continue with the next filter
            }
            else
            {
                // if uEye Capture Device:
                // add filtername to the list and link the moniker pointer to the list entry
                CString sTemp(var.bstrVal);
#if (0) /* jma [04/08/2010] add devices named UI... too */
                if( sTemp.Find( "uEye Capture Device", 0) != -1)
#endif
                if ((sTemp.Find( "uEye Capture Device", 0) != -1) || (sTemp.Find( "UI", 0) != -1))
                {
                    int index = m_comboVideoSources.AddString( sTemp);
                    // dont forget to release the moniker later!
                    m_comboVideoSources.SetItemDataPtr( index, pMoniker);
                }
                else
                {
                    pMoniker->Release();
                    pMoniker= NULL;
                }
            }

            // release the reference to the storage object
            pPropBag->Release();
            pPropBag= NULL;
        }

        VariantClear(&var);
    }

    // release the class enumerator
    pVideoInputDeviceEnumerator->Release();
    pVideoInputDeviceEnumerator= NULL;

    // select first list entry
    m_comboVideoSources.SetCurSel( 0);

    return false;
}


二、选择某个摄像设备

1、先停止原有的Media
bool
uEye_DirectShow_Demo_Dlg::FilterGraph_Stop()
{
    Invalidate();

    // proceed only if filter graph manager object present
    if( m_pActiveFilterGraphManager == NULL)
    {
        return true;
    }

    HRESULT status= S_OK;

    // get the MediaControl interface of the graph
    IMediaControl* pMediaControl= NULL;
    status= m_pActiveFilterGraphManager->QueryInterface( IID_IMediaControl, (void**)&pMediaControl);
    if( FAILED(status) || pMediaControl == NULL)
    {
        MessageBoxEx( NULL, "Querying MediaControl interface of the filter graph manager failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    //// check for graph to be executing before allowing to stop

    //OAFilterState filterState= 0;   // OAFilterState is actually a long
    //status= pMediaControl->GetState( 100, &filterState);
    //if( FAILED(status))
    //{
    //    // cleanup

    //    // release the MediaControl interface object
    //    pMediaControl->Release();
    //    pMediaControl= NULL;

    //    MessageBoxEx( NULL, "Querying graph state failed!", __FUNCTION__, MB_ICONERROR, 0);
    //    return false;
    //}

    //if( filterState != State_Stopped)
    {
        // stop the execution of the graph
        status= pMediaControl->Stop();
        if( FAILED(status))
        {
            // cleanup

            // release the MediaControl interface object
            pMediaControl->Release();
            pMediaControl= NULL;

            MessageBoxEx( NULL, "Stopping the graph failed!", __FUNCTION__, MB_ICONERROR, 0);
            return false;
        }

        // update the graph state view
        UpdateGraphState( State_Stopped);
    }

    // release the MediaControl interface object
    pMediaControl->Release();
    pMediaControl= NULL;

    return true;
}


2、删除Graph
bool
uEye_DirectShow_Demo_Dlg::FilterGraph_Destroy()
{
    // proceed only if filter graph manager object present
    if( m_pActiveFilterGraphManager == NULL)
    {
        return true;
    }

    if( !FilterGraph_Stop())
    {
        return false;
    }

    // disable 'dump graph' button as long as no graph present
    m_bnDumpGraph.EnableWindow( FALSE);

    // delete the capture filter
    m_pActiveVideoSource->Release();
    m_pActiveVideoSource= NULL;

    // delete the graph
    m_pActiveFilterGraphManager->Release();
    m_pActiveFilterGraphManager= NULL;

    // update the graph state view
    UpdateGraphState( -1);

    return true;
}


 

3、根据选择的设备的moniker来创建Graph

分为:

(1)为选择的设备创建capture filter

 status= pMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**)&m_pActiveVideoSource);

(2) 创建一个capture Graph Builder对象

ICaptureGraphBuilder2* pCaptureGraphBuilder= NULL;
    status= CoCreateInstance(   CLSID_CaptureGraphBuilder2,
                                NULL,
                                CLSCTX_INPROC,
                                IID_ICaptureGraphBuilder2,
                                (void**)&pCaptureGraphBuilder);

(3) 创建 Filter Graph Manager

  // create the Filter Graph Manager
    status= CoCreateInstance(   CLSID_FilterGraph,
                                NULL,
                                CLSCTX_INPROC,
                                IID_IGraphBuilder,
                                (void **)&m_pActiveFilterGraphManager);

(4) 初始化Capture Graph Builder 对象,把graph和builder 连接起来

   status= pCaptureGraphBuilder->SetFiltergraph( m_pActiveFilterGraphManager);

(5) 增加Capture到graph中

  status= m_pActiveFilterGraphManager->AddFilter( m_pActiveVideoSource, L"Video Capture");

(6) render 视频的capture pin, 把caputre filter和render连接起来

  status= pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,
                                                &MEDIATYPE_Video,
                                                m_pActiveVideoSource,
                                                NULL,
                                                NULL);

(7) 查询filter graph manager的VideoWindow接口

 IVideoWindow* pVideoWindow= NULL;
    status= m_pActiveFilterGraphManager->QueryInterface( IID_IVideoWindow, (void**)&pVideoWindow);

(8) 把video view连接到graph

 // connect the dialogs video view to the graph
    CWnd* pwnd= GetDlgItem( IDC_STATIC_VIDEOVIEW);
    pVideoWindow->put_Owner( (OAHWND)pwnd->m_hWnd);  // put_Owner always returns NOERROR

// we dont want a title bar on our video view
    long pWindowStyle = 0;
    pVideoWindow->get_WindowStyle(&pWindowStyle);
    pWindowStyle &= ~WS_CAPTION;
    pVideoWindow->put_WindowStyle(pWindowStyle);

    // adjust graphs video geometry
    CRect rc( 0, 0, 0, 0);
    pwnd->GetClientRect( &rc);
    pVideoWindow->SetWindowPosition( rc.left, rc.top, rc.Width(), rc.Height());

    // release the VideoWindow interface object, we do not need it anymore
    pVideoWindow->Release();

四、  开始播放

bool
uEye_DirectShow_Demo_Dlg::FilterGraph_Start()
{
    // proceed only if filter graph manager object present
    if( m_pActiveFilterGraphManager == NULL)
    {
        return true;
    }

    HRESULT status= S_OK;

    // get the MediaControl interface of the graph
    IMediaControl* pMediaControl= NULL;
    status= m_pActiveFilterGraphManager->QueryInterface( IID_IMediaControl, (void**)&pMediaControl);
    if( FAILED(status) || pMediaControl == NULL)
    {
        MessageBoxEx( NULL, "Querying MediaControl interface of the filter graph manager failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    //// check for graph to be stopped before allowing to start

    //OAFilterState filterState= 0;   // OAFilterState is actually a long
    //status= pMediaControl->GetState( 100, &filterState);
    //if( FAILED(status))
    //{
    //    // cleanup

    //    // release the MediaControl interface object
    //    pMediaControl->Release();
    //    pMediaControl= NULL;

    //    MessageBoxEx( NULL, "Querying graph state failed!", __FUNCTION__, MB_ICONERROR, 0);
    //    return false;
    //}

    //if( filterState == State_Stopped)
    {
        // start the execution of the graph
        status= pMediaControl->Run();
        if( FAILED(status))
        {
            // cleanup

            // release the MediaControl interface object
            pMediaControl->Release();
            pMediaControl= NULL;

            MessageBoxEx( NULL, "Starting the graph failed!", __FUNCTION__, MB_ICONERROR, 0);
            return false;
        }

        // update the graph state view
        UpdateGraphState( State_Running);
    }

    // release the MediaControl interface object
    pMediaControl->Release();
    pMediaControl= NULL;

    return true;
}


五、 pin 特征的查看

如果pin里有自己的查看特征接口, 那么就直接调用接口

bool
uEye_DirectShow_Demo_Dlg::ShowPinProperties()
{
    // proceed only if video source object present
    if( m_pActiveVideoSource == NULL)
    {
        return true;
    }

    HRESULT status= S_OK;

    IPin* pPin= GetPin( m_pActiveVideoSource, PINDIR_OUTPUT, &MEDIATYPE_Video, &PIN_CATEGORY_CAPTURE);
    if( pPin == NULL)
    {
        MessageBoxEx( NULL, "Pin not available!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    IUnknown* pFilterUnk= NULL;
    status= pPin->QueryInterface( IID_IUnknown, (void**)&pFilterUnk);
    if( FAILED(status))
    {
        // cleanup

        pPin->Release();
        pPin= NULL;

        MessageBoxEx( NULL, "Querying pin's IAMStreamConfig interface failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    ISpecifyPropertyPages* pSpecifyPropertyPages= NULL;
    status= pFilterUnk->QueryInterface( IID_ISpecifyPropertyPages, (void**)&pSpecifyPropertyPages);
    if( FAILED(status))
    {
        // cleanup

        pFilterUnk->Release();
        pFilterUnk= NULL;

        pPin->Release();
        pPin= NULL;

        MessageBoxEx( NULL, "Querying pin's ISpecifyPropertyPages interface failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    CAUUID cauuid= { 0, NULL};
    status= pSpecifyPropertyPages->GetPages( &cauuid);
    if( FAILED(status))
    {
        // cleanup

        pSpecifyPropertyPages->Release();
        pSpecifyPropertyPages->Release();
        pSpecifyPropertyPages= NULL;

        pFilterUnk->Release();
        pFilterUnk= NULL;

        pPin->Release();
        pPin= NULL;

        MessageBoxEx( NULL, "Querying pin's ISpecifyPropertyPages interface failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }
    pSpecifyPropertyPages->Release();
    pSpecifyPropertyPages->Release();
    pSpecifyPropertyPages= NULL;

    status= OleCreatePropertyFrame( GetSafeHwnd(),//*this,
                                    0,
                                    0,
                                    OLESTR("uEye Capture Device Pin"),
                                    1,
                                    (IUnknown**)&pFilterUnk,
                                    cauuid.cElems,
                                    (GUID*)cauuid.pElems,
                                    0,
                                    0,
                                    NULL);

    if( FAILED(status))
    {
        // cleanup

        CoTaskMemFree( cauuid.pElems);
        cauuid.pElems= NULL;
        cauuid.cElems= 0;

        pFilterUnk->Release();
        pFilterUnk= NULL;

        pPin->Release();
        pPin= NULL;

        MessageBoxEx( NULL, "OleCreatePropertyFrame failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    // cleanup

    CoTaskMemFree( cauuid.pElems);
    cauuid.pElems= NULL;
    cauuid.cElems= 0;

    pFilterUnk->Release();
    pFilterUnk= NULL;

    pPin->Release();
    pPin= NULL;

    return true;
}


六、 查询包含的 filter信息

bool
uEye_DirectShow_Demo_Dlg::EnumerateFilters() 
{
    // proceed only if filter graph builder object present
    if( m_pActiveFilterGraphManager == NULL)
    {
        return false;
    }

    IEnumFilters *pEnum = NULL;
    IBaseFilter *pFilter;
    ULONG cFetched;

    HRESULT hr = m_pActiveFilterGraphManager->EnumFilters(&pEnum);
    if (FAILED(hr))
    {
        MessageBoxEx( NULL, "Enumerating filters failed!", __FUNCTION__, MB_ICONERROR, 0);
        return false;
    }

    CString sInfo( "Filters in the Graph:\n\n");
    int i= 0;

    while(pEnum->Next(1, &pFilter, &cFetched) == S_OK)
    {
        i++;

        FILTER_INFO FilterInfo;
        hr = pFilter->QueryFilterInfo(&FilterInfo);
        if (FAILED(hr))
        {
            MessageBoxEx( NULL, "Could not get the filter info", __FUNCTION__, MB_ICONERROR, 0);
            continue;  // Maybe the next one will work.
        }

        LPWSTR pVendorInfo= NULL;
        hr= pFilter->QueryVendorInfo( &pVendorInfo);
        if( FAILED(hr))
        {
            pVendorInfo= NULL;
        }


        if( pVendorInfo != NULL)
        {
            sInfo.AppendFormat( "%d: %S (by %S)\n", i, FilterInfo.achName, pVendorInfo);
            CoTaskMemFree( pVendorInfo);
            pVendorInfo= NULL;
        }
        else
        {
            sInfo.AppendFormat( "%d: %S\n", i, FilterInfo.achName);
        }

        // The FILTER_INFO structure holds a pointer to the Filter Graph
        // Manager, with a reference count that must be released.
        if (FilterInfo.pGraph != NULL)
        {
            FilterInfo.pGraph->Release();
        }
        pFilter->Release();
    }

    pEnum->Release();

    MessageBoxEx( NULL, sInfo.GetBuffer(), __FUNCTION__, MB_OK, 0);

    return true;
}


 

你可能感兴趣的:(XP下采用DirectShow采集摄像头)