zoukankan      html  css  js  c++  java
  • 使用DirectShow驱动摄像头

         对于小摄像头的驱动有几种方法,通过使用DirectShow来驱动摄像头灵活性比较好,有简单的方法也有比较复杂但更有效的方法,本文只介绍简单方法,希望与大家交流! 用DirectShow来使用摄像头,一般要求摄像头的驱动是WDM格式的,当然,一些比较老的驱动格式DirectShow也可支持。DirectShow通过图形过滤管理器(Filter Graph Manager)来与上层应用程序和下层的驱动进行联系。DirectShow通过一种叫作捕获过滤器(Capture Filter)的东东来支持对摄像头的捕获,一个捕获过滤器有多个插口(pin),其中的预览(preview)插口可用来进行显示祯图象。

         DirectShow通过几个COM接口来对视频捕获的全过程进行控制,其中IGraphBuilder 用于建立过滤器,ICaptureGraphBuilder2用于与下层的驱动程序建立联系,IVideoWindow,IMediaControl,IMediaEventEx分别对整个过程的视频窗口,播放过程和事件响应进行控制



    下面是例程:

     CComQIPtr<IVideoWindow> m_pVW;
    CComQIPtr<IMediaControl> m_pMC;
    CComQIPtr<IMediaEventEx> m_pME;
    CComPtr<IGraphBuilder> m_pGraph;
    CComPtr<ICaptureGraphBuilder2> m_pCapture;
    DWORD m_dwGraphRegister;
    bool bInit(HWND hWnd)
    {
    HRESULT hr;
    //获得接口
    hr=CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
    IID_IGraphBuilder, (void **) &m_pGraph);
    if (FAILED(hr))
    return false;
    hr=CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
    IID_ICaptureGraphBuilder2, (void **) &m_pCapture);
    if (FAILED(hr))
    return false;
    m_pMC=m_pGraph;
    m_pVW=m_pGraph;
    m_pME=m_pGraph;
    //取得消息
    m_pME->SetNotifyWindow((OAHWND)(m_hWnd=hWnd), WM_GRAPHNOTIFY, 0);
    //将过滤和捕获进行连接
    m_pCapture->SetFiltergraph(m_pGraph);
    //设备联接
    //枚举设备
    CComPtr <ICreateDevEnum> pCde=NULL;
    CComPtr <IEnumMoniker> pEm=NULL;
    hr=CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
    IID_ICreateDevEnum, (void **) &pCde);
    if (FAILED(hr))
    return false;
    pCde->CreateClassEnumerator(CLSID_VideoInputDeviceCategory
    , &pEm, 0);
    if(pEm==NULL)
    return false;
    CComPtr <IMoniker> pM=NULL;
    ULONG cFetched;
    CComPtr<IBaseFilter> pBf=NULL;
    if(pEm->Next(1,&pM,&cFetched)==S_OK)
    {
    pM->BindToObject(0,0,IID_IBaseFilter, (void**)&pBf);
    pM.Release();
    }
    else
    {
    return false;
    }
    //将设备添加到graph
    hr = m_pGraph->AddFilter(pBf, L"Video Capture");
    if (FAILED(hr))
    return false;
    //连接一个源插口
    hr=m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video
    ,pBf,NULL,NULL);
    if (FAILED(hr))
    return false;
    pBf.Release();
    //设定视频窗口
    //设定视频窗口为主窗口的一个子窗口
    hr=m_pVW->put_Owner((OAHWND)hWnd);
    if (FAILED(hr))
    return false;
    //设定窗口样式
    m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
    if (FAILED(hr))
    return false;
    //设定窗口大小
    CRect rectClient;
    GetClientRect(hWnd,rectClient);
    m_pVW->SetWindowPosition(0, 0, 320, 240);
    //设定可视
    hr=m_pVW->put_Visible(OATRUE);
    if (FAILED(hr))
    return false;
    //将对象加入到运行对象列表中
    CComPtr<IRunningObjectTable> pROT;
    GetRunningObjectTable(0,&pROT);
    WCHAR c[128];
    wsprintfW(c, L"FilterGraph %08x pid %08x\0", (DWORD_PTR)m_pGraph.p,
    GetCurrentProcessId());
    hr = CreateItemMoniker(L"!",c,&pM);
    if (FAILED(hr))
    return false;
    hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE,m_pGraph,
    pM,&m_dwGraphRegister);
    pM.Release();
    return false;
    }
  • 相关阅读:
    @RequestParam注解使用:Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
    cglib动态代理导致注解丢失问题及如何修改注解允许被继承
    springboot Autowired BeanNotOfRequiredTypeException
    git根据用户过滤提交记录
    不同包下,相同数据结构的两个类进行转换
    How to use Jackson to deserialise an array of objects
    jooq实践
    java如何寻找main函数对应的类
    Python--matplotlib
    Python 和 Scikit-Learn
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/1304694.html
Copyright © 2011-2022 走看看