zoukankan      html  css  js  c++  java
  • DirectShow流媒体数据的采集及图片的捕获

    流媒体的处理,以其复杂性和技术性,一向广受工业界的关注。特别伴随着因特网的普及,流媒体在网络上已广泛应用﹐怎样使流媒体的处理变得简单而富有成效逐渐成为了焦点问题。选择一种合适的应用方案,将事半功倍。此时,微软的DirectShow给了我们一个不错的选择。

      DirectShow是微软公司在ActiveMovie和Video for Windows的基础上推出的新一代基于COM的流媒体处理的开发包,与DirectX开发包一起发布。目前,DirectX最新版本为9.0。DirectShow为多媒体流的捕捉和回放提供了强有力的支持。运用DirectShow,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。这样使在多媒体数据库管理系统(MDBMS)中多媒体数据的存取变得更加方便。

      DirectShow 原理及重要的接口

      1、DirectShow工作原理

      1) DirectShow的系统结构

      DirectShow的体系结构如图1所示。


    图1 DirectShow系统

      
      DirectShow位于应用层中。它使用一种叫Filter Graph的模型来管理整个数据流的处理过程;参与数据处理的各个功能模块叫Filter;各个Filter 在Filter Graph中按一定的顺序连接成一条“流水线”协同工作。按照功能来分,Filter大致分为三类:Source Filters、Transform. Filters和Rendering Filters。Source Filters主要负责取得数据,数据源可以是文件、因特网、或者计算机里的采集卡、数字摄像机等,然后将数据往下传输;Transform. Fitlers主要负责数据的格式转换、传输;Rendering Filtes主要负责数据的最终去向,我们可以将数据送给声卡、显卡进行多媒体的演示,也可以输出到文件进行存储。

      在DirectShow系统之上,我们看到的,即是我们的应用程序(Application)。应用程序要按照一定的意图建立起相应的Filter Graph,然后通过Filter Graph Manager来控制整个的数据处理过程。DirectShow能在Filter Graph运行的时候接收到各种事件,并通过消息的方式发送到我们的应用程序。这样,就实现了应用程序与DirectShow系统之间的交互。

      2) Filter概述以及连接

      过滤器(Filter)是DirectShow中最基本的概念。DirectShow是通过Filter Graph来管理Filter的。Filter Graph是Filter的“容器”,而Filter是Filter Graph中的最小功能模块。Filter是一种COM组件,对于每个Filter,都有其自己的Pin,它是由Filter创建的COM对象。Filter通过Pin来进行他们之间的连接。Pin分为两种:输出Pin和输入Pin。输出的Pin把Filter处理后的数据传送到Filter的外部,而输入Pin则是把Filter外部的数据接收到Filter中,以便Filter对这些数据进行处理。对于三种类型的Filter(Source Filter,Transform. Filter,Rendering Filter)的连接图如下:


    图2 Filter的连接


      2、DirectShow对硬件的支持原理

      大家知道,为了提高系统的稳定性,Windows操作系统对硬件操作进行了隔离;应用程序一般不能直接访问硬件。DirectShow Filter工作在用户模式(User mode,操作系统特权级别为Ring 3),而硬件工作在内核模式(Kernel mode,操作系统特权级别为Ring 0),DirectShow解决的方法是,为这些硬件设计包装Filter;这种Filter能够工作在用户模式下,外观、控制方法跟普通Filter一样,而包装Filter内部完成与硬件驱动程序的交互。这样的设计,使得编写DirectShow应用程序的开发人员,从为支持硬件而需做出的特殊处理中解脱出来。DirectShow已经集成的包装Filter,包括Audio Capture Filte(qcap.dll)、VfW Capture Filter(qcap.dll,Filter的Class Id为CLSID_VfwCapture)、TV Tuner Filter(KSTVTune.ax,Filter的Class Id为CLSID_CTVTunerFilter)、Analog Video Crossbar Filter(ksxbar.ax)、TV Audio Filter(Filter的Class Id为CLSID_TVAudioFilter)等;另外,DirectShow为采用WDM驱动程序的硬件设计了KsProxy Filter(Ksproxy.ax,)。下图就是各个包装Filter与硬件交互的结构图:

    应用程序
    DirectShow Filter Graph
    KsTune.ax
    KsXbar.ax
    KsCap.ax
    其他普通的Filter
    Stream Class
    Tuner minidriver Crossbar mindriver Capture minidriver Tuner,Crossbar,Capture minidriver


      3、DirectShow 的重要接口

      DirectShow采用了COM标准,所以很多重要的功能都是通过COM接口来完成。下面就列举一些重要的DirectShow的接口。

      (1) IGraphBuilder接口

      用于构造Filter Graph的接口,建立和管理一系列的Filter,过滤和处理源媒体流。

      (2) IMediaControl接口

      用于控制多媒体流在过滤器图表中的流动,如流的启动和停止。

      (3) IMediaEvent接口

      用于捕获播放过程中发生的事件,并通知应用程序,如EC_COMPLETE等。

      (4) IVideoWindow接口

      用于控制视频窗口的属性。

      (5) IMeadiaSeeking接口

      用于查找媒体的接口,定位流媒体,控制多媒体数据播放提供精确控制。

      (6) IBaseFilter接口

      从ImediaFilter接口继承,用来定义一个具体的过滤器指针,并对多媒体数据进行处理。

      (7) IPin接口

      用于管理两个过滤器之间的Pin,从而连接过滤器。

      (8) IsampleGrabberCB接口

      是Sample Grabber过滤器的一个接口,用于当流媒体数据通过过滤器时进行采样以获得帧图象。


      用DirectShow来使用摄像头,一般要求摄像头的驱动是WDM格式的,当然,一些比较老的驱动格式DirectShow也可支持。在DirectShow中,有一个Sample Grabber过滤器,它是一个可以被插入流的过滤器,它有自己的缓冲,存放采样。我们就可以用它来从一个视频文件中简单的扑获一桢。DirectShow通过图形过滤管理器(Filter Graph Manager)来与上层应用程序和下层的驱动进行联系。DirectShow通过捕获过滤器(Capture Filter)来支持对摄像头的捕获,一个捕获过滤器有多个插口(pin),其中的预览(preview)插口可用来进行显示祯图象。

      1、创建图形过滤管理器Filter Graph

      如上面原理所述,首先要创建Filter Graph:

    CComPtr< IGraphBuilder > m_pGraph;
    hr=m_pGraph.CoCreateInstance( CLSID_FilterGraph );

      2、连接设备

      还要创建系统枚举器组件对象:

    CComPtr<ICreateDevEnum>pCreateDevEnum;pCreateDevEnum.CoCreateInstance( CLSID_SystemDeviceEnum );

      然后使用接口方法CreateClassEnumerator ()为指定的Filter注册类型目录创建一个枚举器,并获得IenumMoniker接口:

    CComPtr< IEnumMoniker > pEm;
    pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0 );

      接着在调用BindToObject()以后,可以将设备标识生成一个DirectShow Filter,将其加到Filter Graph中就可以参与工作了。

    CComPtr< IMoniker > pM;
    CComPtr< IPropertyBag > pBag;
    hr=pM->BindToStorage(0,0,ID_IPropertyBag, (void**) &pBag );

      3、创建Sample Grabber过滤器

    CComPtr< ISampleGrabber > m_pGrabber
    hr=m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );

      当创建好SampleGrabber以后,在Sample Grabber 过滤器连接到别的过滤器之前你必须配置它。然后查询IsampleGrabber接口,还要设置流媒体类型:

    m_pGrabber->SetMediaType();

      可以仅仅指定主媒体类型;或者主类型加子类型;或者主类型,子类型和类型格式。然后就把它加载到FilterGraph中去:

    m_pGraph->AddFilter(pGrabBase,"Grabber" );

      4、查找Filter Graph 的Pin并完成后续连接。

      接下来就可以通过调用IGraphBuilder 的FindPin()接口来查找过滤管理器中的Pin接口,并通过ICaptureGraphBuilder2 中的接口RenderStream()来完成后续的连接。

    hr=pCGB2->FindPin(pCap,PINDIR_OUTPUT,&PIN_CATEGORY_VIDEOPORT, NULL,FALSE,0,&pVPPin);
    hr=pCGB2->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video, pCap,pGrabBase,pRenderer);

      5、获取流媒体类型并运行

      通过GetConnectedMediaType()获取连接流媒体的类型以后,我们可以通过IsampleGrabberCB类的接口BufferCB()来把视频的数据拷贝到自定义的缓冲区中,然后通过在缓冲区的拷贝进行视频到图象数据的拷贝。最后运行﹕

    CComQIPtr<IMediaControl,&IID_IMediaControl > pControl = m_pGraph;
    hr = pControl->Run( );

      结论

      本文讨论了DirectShow的基本原理,创建Filter Graph的基本方法,以及通过DirectShow来捕获视频数据,然后将其保存为自己想要的图象,对于多媒体数据库管理系统是一个非常有利的补充,如对考试报名的软件系统有很强的适应性,可以降低开发成本。提高用户的实用性。

      DirectShow技术是一个开发多媒体的行之有效的方法。在未来几年中,DirectShow技术的发展前景相当广阔,掌握DirectShow的技术将有重要的实用意义。

  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/xyzlmn/p/3168309.html
Copyright © 2011-2022 走看看