DirectShow SDK笔记【关于DirectShow(1)】(转载)

转载 2007年10月14日 13:21:00
转自http://blog.csdn.net/laiyiling/archive/2006/11/04/1365732.aspx
About DirectShow
 
    本节描述DirectShow的整体结构。本节包含的内容比较丰富,我们可能不需要知道所有的这些知识。因此,我们首先应该选择浏览全部的内容,然后根据实际应用程序的需要查看Using DirectShow的内容。如果有关于DirectShow结构的特殊问题,可以再回过来参考本节的内容。
 
1. DirectShow System Overview
 
    1.1 The Challenge of Multimedia
    进行多媒体编程主要存在如下几个挑战:
    ·多媒体流包含大量的数据,这些数据又要求进行快速的处理
    ·音频、视频必须同步,以使它们在相同时间开始、停止,以相同的频率播放
    ·数据来源多,包括本地文件,计算机网络,电视广播和视频摄像机
    ·数据源的格式多,比如音频、视频交叉存取的(AVI),高级流格式(ASF),运动图像专家组(MPEG)和数字视频(DV)。
    ·程序员不能预先知道在用户终端系统存在的硬件设备
 
    1.2 The DirectShow Solution
    DirectShow就是被设计来解决这些挑战的。DirectShow通过把应用程序从复杂的数据传输、硬件区别和同步隔离起来。它的主要目标是简化在Windows平台创建数字媒体程序的任务。
    为了达到流递音频、视频所需的流量,DirectShow在可能的任何时候使用DirectDrawDirectSound。这些提交数据的数据有效的利用了用户的声卡和图形卡。DirectShow通过把媒体数据包装为带时间戳的Samples实现回放的同步。为了处理可能不同的数据源、格式和硬件设备,DirectShow使用模块化结构,通过这种结构应用程序可以混合、匹配不同的软件组件,这种组件称为Filters.
    DirectShow提供Filters支持捕捉和基于WDM的调频设备,Filters还支持旧的VFW捕捉卡,为音频压缩管理(ACM)编写的编解码器以及视频压缩管理器(VCM)接口。
    应用程序、DirectShow组件、以及DirectShow所支持的部分硬件、软件组件之间的关系如图。

    如同所示,DirectShow与各种不同的设备进行通信,并控制它们。包括本地文件系统,TV Tuner,视频捕捉卡,VFW编解码器,视频显示(通过DirectDraw或者GDI),以及声卡(通过DirectSound)。因此,DirectShow把应用程序与这些设备的复杂性隔离开来。DirectShow还为某些文件格式提供了本地的压缩、解压Filters.
 
2. The Filter Graph and Its Components
    本条款描述DirectShow的主要组件。主要目的是为应用程序开发人员和编写自定义DirectShow Filter的开发人员做些介绍。应用程序开发人员通常可忽略DirectShow的一些低级细节。但是,阅读此节仍是好主义,可以对DirectShow的结构有一个大概理解。
 
    2.1 About DirectShow Filters
    DirectShow基于模块化结构,每个处理阶段都由称为FilterCOM对象完成。DirectShow提供了一系列标准Filter用于应用程序开发,开发者也可以开发自己的Filter来扩展DirectShow的功能。为了举例说明,这里是一个播放AVI视频文件所需要的步骤,连同完成每步的Filters:
    ·从原始文件读取数据为字节流(File Source Filter
    ·检测AVI头,把字节流分析为单独的视频帧和音频SamplesAVI Splitter Filter
    ·解码视频帧(各种解码Filters, 取决于压缩格式)
    ·画视频帧(Video Renderer Filter
    ·把音频Samples发送到声卡(默认的DirectSound设备Filter
    这些Filters及结构如图所示:
    如图所示,每个Filter都与一个或多个Filter相连接。连接点也是一个COM对象,称为PinsFilters使用PINS把数据从一个Filter移动到下一个。图中的箭头表示数据的流向。在DirectShow,一个Filters的集合称为Filter Graph
    Filter有三种可能的状态,运行,停止,暂停。当一个Filter运行时,它就处理媒体数据流,当停止时,Filter就不处理数据,暂停状态用来在运行前Cue Data, Data Flow in the Filter Graph一节对这些概念有更详细的描述。除非特别的例外,状态改变都是协调贯穿在整个Filter GraphGraph的所有Filter的状态改变都是统一的。因此,Filter Graph也可说是运行,停止,暂停。
    Filter 一般分为下面几种类型。
    (1)、源FilterSource Filter):源Filter引入数据到Filter Graph,数据来源可以是文件、网络、照相机或者是任何地方。每个源Filter处理不同类型的数据源。
    (2)、变换FilterTransform Filter):变换Filter的工作是获取输入流,处理数据,并生成输出流。编码、解码读书变换Filter的例子。
    (3)、提交FilterRenderer Filter):提交FilterFilter图表里处于最后一级,它们接收数据并把数据提交给用户。比如,视频Renderer把视频帧画在显示器,音频Renderer把音频数据发送到声卡,File-Writer Filter把数据写入文件。
    (4)、分割FilterSplitter Filter):分割Filter把输入流分割成多个输出。例如,AVI分割Filter把一个AVI格式的字节流分割成视频流和音频流。
    (5)、混合FilterMux Filter):混合Filter把多个输入组合成一个单独的数据流。例如,AVI混合Filter把视频流和音频流合成一个AVI格式的字节流。它进行AVI分割Filter相反的操作。
    这些Filters种类的区别并非绝对。比如ASF Reader Filter既是Source Filter又是Splitter Filter.
    所有的Filters都暴露了IBaseFilter接口,所有的Pin都暴露了IPin接口。DirectShow也定义了一些其他的接口实现更特殊的功能。
 
    2.2 About the Filter Graph Manager
    Filter Graph Manager也是一个COM对象,用来控制Filter Graph中的所有的Filter,主要有以下的功能:
    ·协调Filters之间的状态改变
    ·建立参考时钟
    ·传递事件到应用程序
    ·提供应用程序建立Filter Graph的方法
    下面就这些功能做一个简单的说明。可以本文档的其他地方找到详细说明。
    状态改变:Filters的状态改变必须以一种特殊顺序发生。因此,应用程序并不将状态改变的命令直接发给Filter,而是发送给Filter Graph Manager一个简单命令,由Manager将命令分发给Graph中每一个FiltersSeeking也是按同样的方式工作,先由应用程序将Seek命令发送到Filter Graph Manager,然后由其分发给每个Filters
    参考时钟:Graph中的Filter都采用的同一个时钟,称为参考时钟(Reference Clock),参考时钟可以确保所有的数据流同步,视频桢或者音频Sample应该被提交的时间称为Presentation Time。它是相对于参考时钟来确定的。Filter Graph Manager应该选择一个参考时钟,可以选择声卡上的时钟,也可以选择系统时钟。
    Graph事件:Filter Graph Manager采用事件队列机制将Graph中发生的事件通知给应用程序,这个机制类似于Windows的消息循环。
    Graph构建的方法:Filter Graph Manager给应用程序提供了将Filter添加进Graph的方法,连接Filter的方法,断开Filter连接的方法。
    Filter Graph Manager没有的一个功能就是把数据从一个Filter移动到另一个Filter。这是由Filters自己通过它们的PIN连接完成的。处理过程总是在不同的线程进行。
    注意:Filters总是与Filter Graph Manager在同一进程,被进程类服务器加载。在Filters之间,FiltersFilter Graph Manager之间的函数调用都不会存在列举(Marshall)。
 
    2.3 About the Media Type
    因为DirectShow是基于模块化的,就需要有一种方式来描述Filter Graph每一个点的数据格式,例如,我们还以播放AVI文件为例,数据以RIFF块的形式进入Graph中,然后被分割成视频和音频流,视频流由一系列视频桢组成,而且还可能是压缩的。解码后,视频流由一系列的非压缩的位图组成,音频流也是同样的处理过程。
 
    2.3.1   Media Types: How DirectShow Represents Format
    媒体类型是一种很普遍的,可以扩展的用来描述数字媒体格式的方法,当两个Filter连接的时候,他们会在某种媒体类型达成一致。媒体类型决定了上一级Filter将要给下游的Filter发送什么类型的数据,以及数据的物理布局。如果两个Filters在媒体类型上没有达成一致,那么他们就没法连接起来。
    对于某些应用程序,我们不需要担心媒体类型。比如在文件回放中,DirectShow处理了所有的细节。其他类型的应用程序可能需要直接在媒体类型上操作。
    媒体类型是通过AM_MEDIA_TYPE结构定义的,此结构包含如下信息:
    ·主类型:它是一个GUID值,定义的全部的数据种类。主类型包括视频、音频、未解析的字节流、MIDI数据等等。
    ·子类型:也是GUID值,进一步定义媒体类型。比如,主类型是视频时,子类型可能是RGB-24RGB-32UYVY等等。对于音频,子类型可能是PCM音频、MPEG-1 Payload等等。主类型提供了比子类型更多的信息,但是它还没有定义格式的所有信息。比如,视频子类型没有定义图像大小和帧率。这些通过下面的格式子块说明。
    ·格式子块:它是描述格式细节的数据块。它是从AM_MEDIA_TYPE结构单独分配。AM_MEDIA_TYPEpbFormat指针指向格式子块。
    pbFormat是一个void*的指针,因为格式块会因为媒体类型的不同而有不同的布局。PCM音频使用WAVEFORMATEX结构。视频块结构包括VIDEOINFOHEADERVIDEOINFOHEADER2AM_MEDIA_TYPEformattype成员是指明在格式块所包含结构类型的GUID。每种结构都有一个GUIDcbForamt成员指定了格式块的大小。总是需要在废弃pbFormat指针前检测它的值。
    如果格式块被填充,主类型和子类型的信息可以忽略。但是,在没有完整的格式块时,主类型和子类型提供了一种方便的方法来识别格式。比如我们可指定一个通用的24RGB格式(MEDIASUBTYPE_RGB24,而不需要知道VIDEOINFOHEADER结构所需要的所有信息,比如图像大小和帧率。
    比如,Filter可能使用下面的代码来检测媒体类型:
HRESULT CheckMediaType(AM_MEDIA_TYPE *pmt)
{
    if (pmt == NULL)         return E_POINTER;
    // Check the major type. We're looking for video.
    if (pmt->majortype != MEDIATYPE_Video)
       return VFW_E_INVALIDMEDIATYPE;
    // Check the subtype. We're looking for 24-bit RGB.
    if (pmt->subtype != MEDIASUBTYPE_RGB24)
    return VFW_E_INVALIDMEDIATYPE;
    // Check the format type and the size of the format block.
    if ((pmt->formattype == FORMAT_VideoInfo) &&
    (pmt->cbFormat >= sizeof(VIDEOINFOHEADER) && (pmt->pbFormat != NULL))
    {
        // Now it's safe to coerce the format block pointer to the
        // correct structure, as defined by the formattype GUID.
        VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
         return S_OK;
    }
    return VFW_E_INVALIDMEDIATYPE;
}
    AM_MEDIA_TYPE结构也包含了一些可选信息。它们可提供一些附加信息。但是Filters并不要求使用它们:
    ·lSampleSize: 如果非0就表示每个Sample的大小。如果是0,表示Sample大小可能随时改变
    ·bFixedSizeSamples: 如果是TRUE,表示lSampleSize值有效,否则应该忽略lSampleSize
    ·bTemporalCompression: 如果是FALSE,表示所有的帧都是关键帧
 
    2.4 About Media Samples and Allocators
    Filters通过Pin的连接来传递数据,数据流是从一个Filter的输出Pin流向相连的Filter的输入Pin。虽然有其他不少的传输机制存在,输出Pin最常用的传递数据的方式是调用输入Pin上的IMemInputPin::Receive方法。
    根据的Filter不同,有多种方式来分配媒体数据的内存块,可以在堆上分配,可以在DirectDraw的表面,也可以采用GDI共享内存,还有其他的一些分配机制。内存分配的响应对象被称为Allocator,也是一个COM对象,暴露了IMemAllocator接口。
    当两个Pin连接的时候,必须有一个Pin提供AllocatorDirectShow定义了一系列函数调用来确定由哪个Pin提供Allocator. PIN之间还会在Buffer的数量和大小上达成一致。
    在数据流开始之前,Allocator会创建一个Buffer池,在数据流动期间,上一级Filter就会将数据填充到Buffers然后传递给下一级Filter。但是,上一级Filter并不是直接将内存Buffer的指针直接传递给下一级的Filter,而是通过一个Media SampleCOM对象,这个COM对象是Allocator创建的用来管理内存BufferMedia Sample暴露了IMediaSample接口,一个Sample包含如下内容:
    ·指向内部Buffer的指针
    ·时间戳
    ·一些标志
    ·可选的媒体类型
    时间戳定义了Presentation TimeRenderer Filter就根据这个时间来安排Render顺序的。标志用来标示数据从前一个Sample后是否中断等等,媒体类型提供了一种中途改变数据格式的方法。通常,一般Sample没有媒体类型,表明它的格式从前一个Sample后没有改变。

    当一个Filter正在使用Buffer,它就会保持一个Sample的引用计数,Allocator通过引用计数用来确定是否可以重新使用一个Buffer。这样就防止了覆盖另一个Filter正在使用的Buffer。当所有的Filter都释放了对Sample的引用,Sample才返回到Allocator的内存池重新使用。 

win10 + VS2013下载directshow相关示例代码及directshow库文件调用

最近需要做虚拟摄像头,网上下载了一个现成的代码调试,用directshow,记录一下环境配置和修改部分,给有需要的朋友 1,环境配置:下载dierectshow vs2013可以自行扩展下载相关代码,...
  • u011668104
  • u011668104
  • 2016年11月14日 19:26
  • 2985

Win7下设置DirectShow编译环境小结(特别的x64位环境)

1. 下载DirectShow 由于现在directShow没有和direcxtx一起发布,而是和windows sdk 打包发布了,Windows SDK 7.1 地址:http://www.mic...
  • dijkstar
  • dijkstar
  • 2016年03月19日 22:32
  • 2735

Directshow学习笔记五-----一个简单的视频播放程序(个人学习总结,仅供参考)

1.       建立一个Filter Graph Manager的实例. 2.       使用Filter Graph Manager 建立一个filter graph. 3.       运...
  • afu1972715000
  • afu1972715000
  • 2015年01月10日 14:24
  • 587

什么是DirectX,DirectShow与DirectX有什么区别?

在介绍同三维万能高清视频采集卡和全能音视频解码编码器软件等多媒体软件时,我们多次提到DirectShow、DirectX,那么什么是DirectShow?什么是DirectX,DirectShow与D...
  • wishfly
  • wishfly
  • 2015年10月17日 23:44
  • 992

关于DirectShow SDK版本变迁说明及解决找不到streams.h文件

1.DirectShow SDK版本变迁说明 做视频聊天和视频播放器程序的时候会涉及到使用DirectShow SDK,原本DirectShow SDK是集成在DirectX中,但自从DirectX ...
  • u011028345
  • u011028345
  • 2017年02月18日 19:34
  • 838

Directshow开发笔记

摘要:本篇文档主要描述关于用Directshow进行视频开发的一些技术 主要包括下面内容 1关于视频捕捉(About Video Capture in Dshow)  2选择一个视频捕捉设备...
  • fin86889003
  • fin86889003
  • 2014年04月01日 17:57
  • 372

配置DirectShow开发环境(VS2010,64位Win8系统)

配置DirectShow开发环境(VS2010,64位Win8系统) 目前,新版的DirectShow并没有包括在DirecxtX中一起发布,而是和Windows SDK一起打包发布,因此首先要下载...
  • iw1210
  • iw1210
  • 2016年03月20日 14:27
  • 1999

一个清华学子写的关于directshow的学习心得【转】

学习DirectShow有一段时间了,把这段学习过程中翻译出来的SDK与大家分享,同时也希望专家们指出我理解上的错误,万分感谢。 1. DirectShow介绍     DirectShow是一个wi...
  • wishfly
  • wishfly
  • 2015年11月18日 10:30
  • 9867

c++ DirectShow播放任意格式的视频

利用opencv只能处理.avi的视频,opencv之前的版本之前试过好像是只能处理.avi未压缩版本的视频,未压缩过的视频相当大,一个文件大概是几十个G。(这个不确定,因为之前用的压缩过的.avi的...
  • KUAILE123
  • KUAILE123
  • 2013年09月08日 16:29
  • 2219

DirectShow 开发环境搭建(整理)

directshow sdk 开发32位程序,用GRMSDK_EN_DVD.iso, 开发64位程序,用GRMSDKX_EN_DVD.iso。 找到Samples\Multimedia\Di...
  • 91program
  • 91program
  • 2014年05月20日 16:16
  • 1779
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DirectShow SDK笔记【关于DirectShow(1)】(转载)
举报原因:
原因补充:

(最多只允许输入30个字)