XP下采用DirectShow采集摄像头

来源:互联网 发布:mac os 10.7的升级包 编辑:程序博客网 时间:2024/05/27 16:43

 

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

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

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

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

 

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

一、初始化工作

1、DirctShow环境初始化
booluEye_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会返回失败

booluEye_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
booluEye_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
booluEye_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();

四、  开始播放

booluEye_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里有自己的查看特征接口, 那么就直接调用接口

booluEye_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信息

booluEye_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;}


 

原创粉丝点击