DirectShow 学习笔记

来源:互联网 发布:bluestack for mac 编辑:程序博客网 时间:2024/05/22 14:47

1、DirectX是什么

DirectX(简称:DX)是微软推出的一套基于Windows系统的多媒体应用程式接口APIs函式。在开发中,DX分为两个部分,一个是运行库,通过DX编译出来的程式必须要有运行库的支持,另外一个是开发库,也就是常说的SDK,这部分是在编译DX程序中是必需的。

DirectX是一种图形应用程序接口(API),简单的说它是一个辅助软件,一个提高系统性能的加速软件,微软创建开发的。他的意思不难理解,Direct是直接的意思,X是很多东西,加在一起就是一组具有共性的东西,这个共性就是直接。微软定义它为“硬件设备无关性”。

DirectX 是微软开发的图形及媒体加速接口,只有安装了它,系统中软件才能比较直接的利用硬件加速资源(高速访问硬件),目前该软件最高版本为9.0c
在Windows操作系统的体系构架中,在内核与硬件之间有一层抽象层,专门对硬件进行屏蔽抽象,所以用户不再被允许对硬件进行直接访问。这样做以后,大大地提高了操作系统的抗破坏性和抗干扰性,但这样以来,使硬件操作的效率大打折扣,许多新硬件的新特性无法直接使用,这对多媒体和游戏的发展显然是一种障碍。DirectX是微软公司提供的一套优秀的应用程序编程接口(APIs),用于联系应用程序和硬件自身,它对发展Windows平台下的多媒体应用程序和电脑游戏起到了关键的作用。

DirectX组件包括:DirectDraw、DirectSound、DirectPlay、Direct3D、DirectInput、DirectSetup、AutoPlay等。

总之,DirectX的主要好处有两个:为软件开发者提供与硬件的无关性;为硬件开发提供策略。
为得到最新的版本,应该从最新的Microsoft Platform SDK中将DirectX安装到系统中。 可以在http://www.microsoft.com/msdn站点或者MSDN光盘中找到platform SDK。缺省情况下,Microsoft Platform SDK被安装到缺省驱动器根目录下的/MSSDK目录中。DirectX 的头文件安装在/MSSDK/INCLUDE目录中,Lib文件安装在/MSSDK/LIB目录中。

Platform SDK包含了一些非常好的DirectX例子和文档。早期发布的DirectX 文档非常粗略而且有些是错误的,现在的版本已经极大地改正了这一问题。最好要熟悉这些文档。

所幸的是,不必一次就处理DirectX的全部功能。DirectX是一套可以分别使用的组件。实际上,在编程概念中,DirectX的不同部分互相没有联系。它们仅仅是具有相同的设计风格和目标:使Windows的游戏编程变得容易。

使用DirectX组件的程序有什么特殊的地方吗?根本没有。使用DirectX组件的程序是基于Win32的程序,它们使用普通Win32 API集,并且可以访问所有可以获得的操作系统工具。实际上,DirectX既可以用于GUI程序,也可以用于控制台程序。可以直接用Petzold-style SDK编程开发程序,也可以用基本类库,如MFC。总的说,唯一的要求是大多数DirectX组件在程序中需要HWND,所以至少要有一个窗口。

2、DirectX 9.0 家族的所有成员

DirectX Graphics:集成了以前的DirectDraw 和Direct3D技术。DirectDraw主要负责2D加速,以实现对显卡内存和系统内存的直接操作;Direct3D主要提供三维绘图硬件接口,它是开发三维DirectX游戏的基础。
DirectInput:主要支持输入服务(包括鼠标、键盘、游戏杆等),同时支持输出设备。
DirectPlay:主要提供多人网络游戏的通信、组织功能。
DirectSetup:主要提供自动安装DirectX组件的API功能。
DirectMusic:主要支持MIDI音乐合成和播放功能。
DirectSound:主要提供音频捕捉、回放、音效处理、硬件加速、直接设备访问等功能。
DirectShow:为Windows平台上处理各种格式的媒体文件的回放、音视频采集等高性能要求的多媒体应用,提供了完整的解决方案。
DirectX Media Objects:DirectShow Filter 的简化模型,提供更方便的流数据处理方案。

3、DirectX的作用

DirectX软件开发包是微软公司提供的一套Windows操作平台上的开发高性能图形、声音、输入、输出和网络游戏的编程接口。它提供了硬件设备无关性。

4、DirectShow的由来及介绍

DirectShow是从DirectX6.0中的DirectX Media 发展而来的,它集成了DirectX家族中其他成员(DirectDraw、DirectSound等)的技术。DirectX Media Objects是从DirectX8.1的DirectShow中分离出来的,成为了另一种高效率的流数据处理解决方案。

  Microsoft DirectShow是一个基于Microsoft Windows平台的媒体流结构。它支持各种格式,包括高级流模式(ASF)、运动图像专家组(MPEG)、音频视频交错(AVI)、音频动态压缩第三层(MP3)和WAV声音文件。它支持Windows驱动模式(WDM)设备的捕捉,以及早期Widows设备的视频。DirectShow结合了其它的DirectX技术。当视频和音频的硬件加速可用时,它能够自动检测并进行使用,同时也支持没有硬件加速的系统。

  DirectShow媒体重放、格式转换和捕捉的任务变得简单。同时,它为需要自定义的解决方案的应用程序提供了对底层流控制结构的访问。您也可以创建自己的DirectShow组件,来支持新的格式或自定义效果。

  使用DirectShow的应用程序类型包括DVD播放器、视频编辑应用程序、AVI到ASF的转换器、MP3播放器和数字视频捕捉应用程序。

   DirectShow是基于组件对象模型(COM)的。要做一个DirectShow的应用程序,您必须了解COM客户端编程。对于大多数应用程序,您不需要实现您自己的COM对象。DirectShow提供了您所需要的组件。(如果您想写自己的组件扩展DirectShow,则必须以COM对象的方式来实现。)

5、程序开发包的选择

请问在Mirosoft DirectX主页上的下载连接有如下:
它们有什么区别:
DirectX 9.0 SDK Update - (April 2005)
DirectX 9.0 SDK Update - (April 2005) Symbol Files
DirectX 9.0c Redistributable for Software Developers - (April 2005)
DirectX 9.0c End-User Runtime

DirectX 9.0 SDK Update - (April 2005) - 就是通常说的DXSDK
DirectX 9.0 SDK Update - (April 2005) Symbol Files - 调试时用的符号文件
DirectX 9.0c Redistributable for Software Developers - (April 2005) - 能够随你的程序一起发行的部分
DirectX 9.0c End-User Runtime - 普通用户安装的DX

6、如何把DirectX关联到VC中?

我们要进行DirectX程序的编译就必须要有DirectX SDK库文件,此文件可以到微软或者本站获取,然后通过VC设置将其关联。下面说明了在VC6和VS.Net下的安装方法。

VC6(英文版):选择菜单Tools->Options,打开Options对话框,选择Directions标签页,选择Include files项,在里面添加DirectX头文件的文件夹路径目录,同样,在Library files项中添加DirectX头文件的文件夹路径目录。

VS.Net(中文版):选择菜单”工具->选项”,打开选项对话框,打开Projects标签页,分别选择”包含文件”和”库文件”进行相应的路径添加即可。

注:VC在进行编译时,会根据排列顺序来进行库文件选取,假设有两个相同名字的库,VC会优先使用排列在前面的库文件。

DirectShow应用程序至少连接库文件Strmiids.lib和Quartz.lib。前者定义了SirectShow标准的CLSID和IID,后者定义了导出函数AMGetErrorText(如果应用程序中没有使用到这个函数,也可以不连接这个库)。

DirectShow应用程序都应该包含Dshow.h文件,但常常用Streams.h文件来代替它。如果包含了Streams.h,则一般库文件还要连接strmbasd.lib、uuid.lib和winmm.lib。

7、DirectShow开发环境的配置

(1)使用VC向导生成一个具体项目,如Win32 Dynamic-Link;

(2)包含头文件streams.h;

(3)在VC的菜单中选择Project|Settings|C/C++,在弹出的对话框中的Category中选择Code generation,然后在Calling convention中选择_stdcall;

(4)使用多线程语言运行时库,即在VC的菜单中选择Project|Settings|C/C++,在弹出的对话框中的Category中选择Code generation,然后在Use run-time library中,Debug版选择Debug Multithreaded,Release版选择Multithreaded。

(5)配置必要的链接库文件,即在VC的菜单中选择Project|Settings|Link,在弹出的对话框中的Category中选择General,然后在Object/library modules中输入如下代码:
  Debug版本 strmbasd.lib, msvcrtd.lib, winmm.lib
  Release版本 strmbase.lib, msvcrt.lib, winmm.lib
并且选中Ignore all default libraries。

  DirectShow SDK建议,DirectShow应用程序应该至少连接库文件strmiids.lib和quartz.lib。前者定义了DirectShow标准的CLSID和IID,后者定义了导出函数AMGetErrorText(如果应用程序中没有使用到这个函数,也可以不连接这个库)。如果程序里包含了头文件streams.h,则一般库文件还要连接strmbasd.lib、uuid.lib、winmm.lib。

(6)将DirectX SDK的Include和Lib目录配置到VC的系统目录中去,并且放在标准的VC目录之前,以保证编译器能够拿到最新版本的源文件。选择Tools|Options|Directories,在弹出的对话框中的Show directories for中选择Include files,配置如下(假设DirectX SDK安装在D:/DXSDK目录下,VC安装在C:/Program Files下):
D:/DXSDK/Include
D:/DXSDK/SAMPLES/C++/DIRECTSHOW/BASECLASSES
D:/DXSDK/SAMPLES/C++/COMMON/INCLUDE
C:/Program Files/Microsoft Visual Studio/VC98/INCLUDE
C:/Program Files/Microsoft Visual Studio/VC98/MFC/INCLUDE
C:/Program Files/Microsoft Visual Studio/VC98/ATL/INCLUDE

再在Show directories for中选择Library files,配置如下:
D:/DXSDK/Lib
D:/DXSDK/SAMPLES/C++/DIRECTSHOW/BASECLASSES/DEBUG
D:/DXSDK/SAMPLES/C++/DIRECTSHOW/BASECLASSES/RELEASE
C:/PROGRAM FILES/MICROSOFT SDK/LIB
C:/Program Files/Microsoft Visual Studio/VC98/LIB
C:/Program Files/Microsoft Visual Studio/VC98/MFC/LIB

(7)因为DirectShow应用程序是一种COM客户程序,因此在调用任何COM函数之前调用CoInitialize()(或CoInitializeEx)函数进行COM库的初始化(一般是在应用程序启动的时候调用一次),在结束COM库使用时调用CoUninitialize()函数进行反初始化(一般是在应用程序退出前调用一次)。

8、VC编译DX程序出现”无法解析的外部符号”是怎么回事?

这个错误经常出现在初学者要进行编译DirectX程序的时候,主要是因为没有将DX的库文件引用到工程中,这里需要注意,我们将DX SDK的路径设置到VC后,并不代表我们已设置好了DX SDK,在我们的DX工程中,我们还需要进行相应的设置操作,把我们所需要的库文件(DirectX SDK Library)加入到我们的工程中,要设置这个库文件有两个方法,一个是在你工程的编译选项中进行添加,另外一种可以通过代码的方法来添加(推荐)。

命令行:#pragma comment( lib,”xxx.lib” )
这个是VC的编译预处理指令,将其加在代码中即可。
例如:#pragma comment( lib,”ddraw.lib” )  这句的意思是将ddraw.lib库加入到工程中进行编译。
注:此命令行不需要加分号(“;”)。

9、DirectShow SDK基类库

在DirectShow SDK基类库中,除了Filter和Pin类外,还有很多工具类。有了这些类的支持,我们开发Filter组件或者DirectShow应用程序会更加轻松。这些类主要包括:CPullPin、COutputQueue、CSourceSeeking、CEnumPins、CEnumMedieTypes、CMemAllocator、CMediaSample、CBaseReferenceClock、CMediaType、CBaseProperyPage等。

10、DirectShow的COM编程基础

  DirectX采用了COM标准,而DirectShow是一套完全基于COM的应用系统。
  
  DirectShow应用程序实际上是一种COM组件的客户程序,只是COM组件的“使用”问题。这些问题包括如何创建COM组件、如何得到组件对象上的解风口以及调用接口方法、如何管理组件对象(即需要熟悉COM的引用计数机制)等。

  COM本身只是一种规范,而不是实现。但是当使用C++来实现时,COM组件就是一个C++类,而接口都是纯虚类。COM规范规定,任何组件或接口都必须从IUnknown接口中继承而来,每个组件都必须实现一个与支相对应的类工厂(Class Factory),类工厂也是一个COM组件,他实现了IClassFactory接口。在IClassFactory的接口函数CreateInstance中,才能使用new操作生成一个与之对应的COM组件类对象实例。

  每个COM组件都使用一个GUID来唯一标识。当创建一个COM组件时,总是首先通过这个GUID调用CoGetClassObject来获得创建这个组件对象的类工厂。然后调用类工厂的接口方法IClassFactory::CreateInstance,就能真正地创建GUID标示的组件对象了。

  一个典型的自注册COM组件DLL所必需的5个函数如下:
DllMain:DLL的入口函数(DirectShow实现的是DllEntryPoint);
DllGetClassObject:用于获得类工厂指针;
DllCanUnloadNow:系统空闲时会调用这个函数,以确定是否可以卸载DLL;
DllRegisterServer:将COM组件注册到注册表中;
DllUnregisterServer:删除注册表中COM组件的注册信息。

11、Filter原理——概述

Filter 是DirectShow中最基本的概念。DirectShow使用Filter Graph来管理Filter(管理者叫做Filter Graph Manager)。Filter Graph是Filter的“容器“,而Filter是Filter Graph中的最小功能模块。

Filter是一种COM组件。为了实现在Filter Graph中的统一操作,每个Filter上都至少实现了IBaseFilter接口。IBaseFilter继承自IMediaFilter。Filter Graph Manager正是通过IMediaFilter的接口方法来控制Filter Graph的状态(运行、暂停、停止)转换。

Filter的类别:
Source Filters主要负责获取数据,数据源可以是文件也可以是设备。只有输出Pin。
Transform Filters主要负责数据的格式转换,例如数据流分离/合成、编码/解码等,然后将数据继续往下传输。既有输入Pin又有输出Pin。
Rendering Filters主要负责数据的最终去向,送达设备或文件。只有输出Pin。

12、Filter原理——注册

实现Filter的文件一般是一个DLL,扩展名可以是.dll,但更多的时候是.ax。一般一个Filter项目都会包含一个.def文件,用于定义4个导出函数。
既然Filter是一种COM组件,使用前就必须先注册。Filter的注册信息一般包括两部分:基本的COM信息和Filter特有信息。在.def文件定义的4个导出函数:DllGetClassObject在创建Filter对象的时候被调用,根据CLSID返回对应的类工厂对象;DllCanUnloadNow用于判断是否可以从内存中卸载Filter DLL,即DLL中实现的所有COM对象是否都已经释放;DllRegisterServer和DllUnregisterServer调用AMovieDllRegisterServer2函数完成COM组件的自注册功能。

13、Filter原理——连接

Filter一般由一个或多个Pin组成,Filter之间通过Pin相互连接,构成一条顺序的链路。

Filter的连接实际上也是Filter上Pin的连接,Pin的连接实际上是连接双方使用的媒体类型的一个“协商”过程。试图连接的两个Filter必须处在同一个Filter Graph中,可以调用接口方法IFilterGraph::AddFilter将指定的Filter加入到Filter Graph。

整个连接过程的步骤大致如下:
A、Filter Graph Manager在输出Pin上调用IPin::Connect;
B、如果输出Pin接受连接,则调用输入Pin上的IPin::ReceiveConnection;
C、如果输入Pin也接受这次连接,则双方连接成功。

14、Filter原理——动态重建技术

由于一些原因,我们需要对已有的Filter Graph进行修改。通常的做法是,先将Filter Graph停止,进行修改之后,在重新启动。另外还能够在保持Filter Graph运行状态的同时实现动态重建。Filter Graph的重建包括如下几种情形:
A、仅仅改变Filter之间连接的媒体类型;
B、增加或删除Filter,重新进行相关Filter之间的连接;
C、对一条Filter链路(Filter Chain)进行操作。

15、Filter原理——数据传送

每个Pin上都实现了IPin接口,这个接口主要用于Pin的连接,而不是数据传送。真正用于数据传送的一般是输入Pin上实现的IMemInputPin接口和输出Pin上实现的IAsyncReader接口。Filter之间的成功连接为数据传送做好了准备。Filter之间是以Sample的形式传送数据的,Sample是一个封装了一定大小数据内存的COM组件。Samplle是由分配器(Allicator,也是一个COM组件)来管理的。连接双方的Pin必须使用同一个分配器,但是这个分配器到底由哪个Pin来创建也需要协商。

数据传送主要有两种模式:推模式(Push Model)和拉模式(Pull Model)。

DirectShow总是使用专门的线程来传送数据。所以,DirectShow应用程序至少包含两条线程,一条应用程序主线程以及至少一条数据传送子线程。

16、Filter原理——状态转换

Filter有3种状态:停止(Stopped)、暂停(Paused)和运行(Running)。其中,暂停可以理解为数据就绪状态,是为了快速切换到运行状态而设计的。作为一种中间状态,暂停也是停止与运行之间切换所必经的一种状态。

17、Filter原理——媒体定位的实现

应用程序可以通过Filter Graph Manager上获得的IMediaSeeking接口,实现对流媒体的随机定位(Seeking)和调整媒体文件的回放速率。实际上,IMediaSeeking接口的真正实现在Filter上。
用于媒体定位的还有另外一个接口IMediaPosition,这是一个支持自动化(Automation)的接口,是为那些弱类型编程语言(如VB)开发DirectShow应用程序而设计的。对于Filter开发人员来说,并不要求实现IMediaPosition。Filter Graph Manager会自动将IMediaPosition的接口方法调用转换为IMediaSeeking的接口方法调用。

18、Filter原理——质量控制的实现

数据线程是通过一种“压迫式”方式往下传送数据的。虽然Video Renderer接收到Sample后,会根据Sample上的时间戳来正确安排显示时机,但仅仅这样是不够的,它并不能改善Filter Graph运行时的性能。因此,DirectShow另外设计了一种“自适应”的反馈机制:质量控制(Quality Control)。质量控制通过IQualityControl接口来实现。具体质量控制策略的实现取决于具体的Filter实现,可能调整发送速度,也可能是丢失部分数据。

19、Filter原理——音视频同步解决方案

在任何系统设计中,最关键的都是系统框架以及控制部分。DirectShow也不例外,这个重要的部分就是Filter Graph Manager,它向下直接控制Filter Graph中的所有Filter,向上对应用程序提供编程接口。可惜的是,微软公司并没有提供这些功能控制的源代码。

DirectShow的音视频同步解决方案就是为Filter Graph选择一个公共的参考时钟(Reference Clock),并且要求传送到Renderer Filter的每个Sample都打上时间戳(Time Stamp);Video Renderer或Audio Renderer根据Sample的时间戳以及参考时钟当前的参考时间,来正确安排Sample的播放时机。

20、Filter原理——对硬件的支持

为了提高系统的稳定性,Windows对硬件操作进行了隔离,应用程序一般不能直接访问硬件。DirectShowFilter工作在用户模式下,而硬件工作在内核模式下,它们之间如何协同工作呢?DirectShow的解决方案是为这些硬件提供包装(Wrapper)Filter,这种Filter能够工作在用户模式下,其外观和控制方法与普通Filter一样,而包装Filter在内部完成与硬件功能的交互。

21、Filter原理——VMR-9的发布

VMR(Video Mixing Renderer)是DirectShow的新一代Video Renderer。VMR有两个版本:VMR-7和VMR-9。前者采用了DirectDraw 7技术,仅仅在Windows XP操作系统下可以获得,并且是XP上默认的用于视频显示的Renderer(代替传统的Video Renderer);后者采用了Direct3D 9的技术,是随DirectX9.0一起发布的,但任何时候都不是默认的Renderer。

安装了DirectX9.0以后,就有4个Video Renderer可供选择使用:传统的Video Renderer、Overlay Mixer、VMR-7和VMR-9。
VMR主要利用了显卡专有的图形处理能力(VMR做视频的合成和显示时并不占用系统的CPU资源),它能够表现的性能对于硬件的依赖性很高。

22、Filter原理——Filter Graph的构建方法

(1)IFilterGraph::AddFilter:该参数提供一个Filter对象,将其加入到Filter Graph中。
(2)IFilterGraph::ConnectDirect:该参数提供输出Pin、输入Pin以及媒体类型,进行直接的连接。
(3)IGraphBuilder::AddSourceFilter:该参数提供源文件名,自动将一个Source Filter加载到Filter Graph中。
(4)IGraphBuilder::Connect:该参数提供输出Pin和输入Pin进行连接,如果连接失败,自动尝试在中间插入必要的格式转换Filter。
(5)IGraphBuilder::Render:该参数提供输出Pin,自动加入必要的Filter完成剩下部分Filter Graph的构建(直到连接到Rendering Filter)。
(6)IGraphBuilder::RnderFile:该参数提供源文件名,自动加入必要的Filter完成这个文件的回放Filter Graph的构建。
Filter通过Pin这样的连接,就能“串联”起来,从而构建完整的Filter Graph。后四种构建方法都有“自动”的功能,这种机制称为智能连接(Intelligent Connect)。

工具推荐
1.软件开发必备翻墙代理,低延迟(50ms),月费10元,详询(宝哥儿QQ1066690060)请自觉遵守国家法律法规

0 0
原创粉丝点击