directshow教程(新整理)

Directshow教程0.11
MSDN翻译系列
作者:黄丁杰
说明:如果有任何问题请联系din-je@163。是本人业余翻译的如果有错误请直接发到我邮箱我会立刻改正,directshow的其他文章我会在以后不断翻译出来。如果觉得好请帮我作作宣传。欢迎转载,但是禁止修改。
Directshow起步。
本章主要介绍diirectshow在编写程序时所需的基本概念。在本章你可以总揽下directshow技术。你必须在总体上对本章的编程和媒体有所了解。
本章将介绍
。设置编译环境
。介绍directshow应用程序编程
。如何播放一个文件
设置编译环境:
SSL检测你可以编译工程在命令行模式下或者在vs集成环境中
头文件
所有的directshow应用程序都使用下面的头文件。
Dshow。H
部分directshow接口需要附加的头文件。这些文件会在接口的注意中给出。
所需的库文件
directshow需要如下的库文件
strmiidl。Lib 该库包含CLSIDs和IIDs的接口。所有的directshow都需要该库。
Quartz。Lib 该库包含AMGetErrorText函数。如果你没有调用该函数,该库没有用。
记住在你的编译环境中必须把directx SDK 的头文件库和连接库的目录作为vs优先搜索的路径。这样可以保证编译的时候用的是最新版本的文件。
介绍directshow应用程序编程
本章介绍编写一个directshow程序的基本技术和概念,读完本章你就可以写个你自己的directshow的应用程序了。
滤镜和图像滤镜
directshow是由被称作滤镜的东西构成的。滤镜是一个软件包用来执行对多媒体流的一些操作。比如directshow的滤镜可以
读出一个文件
从视频捕捉设备获取视频流
解码各种各样的多媒体格式,比如MPEG-1S视频。
传输视频和音频到屏幕和声卡。
滤镜几乎完成视频播放所需要的从输入到输出的所有功能。比如一个MPEG-1的滤镜。它可以输入MPEG码流然后输出图像帧用于后续显示
在directshow程序中只要执行把滤镜连接在一起就可以了。就是把一个滤镜的输入和另外一个滤镜的输出连接在一起就可以了。一组连接在一起的滤镜叫做图像滤镜。比如下面的图示就是一个播放AVI文件的图像滤镜的例子
正如上面图示的,文件滤镜把AVI文件从硬盘读入。AVI分离滤镜分离文件流为两个数据流。一个是视频压缩流,一个是硬盘流。AVI解压滤镜用于解压视频流生成视频帧。视频显示滤镜用于把视频帧用directdraw或者GDI显示到屏幕上。音频留输入到默认声音设备滤镜把声音通过directsound播放出来。
因此应用程序就不用管理任何数据流。代替的,滤镜被叫做高端组件叫做图像滤镜的进行控制。程序只要创建一些高级API。就像RUN(用于在图像控件中移动数据)或者STOP(用于停止数据流)。但是如果你要求更多的数据流控制,那你也可以直接存取控制的COM接口。图像滤镜也会反馈一定的事件消息给应用程序。
图像滤镜可以服务另外的目的。提供给应用程序创建图像滤镜的方法,还有把各个滤镜连接在一起的方法。(directshow同时也提供一些帮助的组件可以简单的处理。这些全部都有在文档中描述。
编写一个directshow程序
总的来说,写个directshow程序必须进行这三个步骤。就像下面的图例。
1. 创建个图像滤镜管理的实例
2. 然后用图像理解管理实例建立一个图像滤镜。外部滤镜间依赖于这个图像滤镜。
3. 应用程序应用图像滤镜控制图像滤镜和数字流在滤镜中的流动。通过这些处理。应用程序也应该回应滤镜管理事件。
当处理结束后。应用程序释放图像滤镜管理器和所有的滤镜。因为directshow是基于COM的,因此图像滤镜管理和滤镜都是COM对象。因此你必须对COM客户端编程有所了解。具体的可以在DirectX SDK中的一篇文章叫做《Using COM》中有很好的介绍COM对象的资料。而且是有很多COM编程的书籍可以参考。
如何播放一个文件
本文章是想让你喜欢上Directshwo编程。我们要创建一个简单的命令行下的程序用于播放音频或者视频文件,这个程序实在是太简单了,可是它所完成的功能却是非常强大。这个程序只要短短的几行的代码就可以搞定了。可是它所完成的功能却是以前只有专门公司才能开发出来的软件所能实现的。它可以用来演示播放任何的多媒体文件。用它你可以立刻
喜欢上directshow的编程。
就像上面的文章说描述的那样,一个directshow应用程序总是有三个基本的步骤。
1. 建立个图像滤镜管理器的实例
2. 用图像滤镜管理建立一个图像滤镜
3. 给它运行的消息,让数据流在各个滤镜中移动。
好了,我们开始编写我们直接的多媒体演示程序。天文圆顶
首先我们必须调用CoInitialize来初始化COM库。
(记住directshow在编程的时候全部都没有传统编写COM的影子,因此初学者很容易被它的假象所欺骗,以为directshow根本就不是COM的,或者认为COM就是那么简单。其实directshow就有点象MFC,通过c+++的封装技术和其他大量的技术把COM技术的很多细节都隐藏其来。其实在背后微软已经为我们写了很多很多的代码。我们应该感谢微软为我们作的一切,但是我们也应该佩服微软。居然可以把代码的复用技术发挥到如此的境界。这
些是我们国内软件企业所要学习的地方。废话了)
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
螺杆并联压缩机组{
    // Add error-handling code here. (Omitted for clarity.)
}
为了保持程序的简单,这个例子忽略了返回值。但是你必须在你自己编写的代码中始终检查从任何方法中返回的HERSULT值。这个是很重要的因为他可能是空值。那在后续的调用的时候将产生很多莫名其妙的错误。问题严重哦。
接下来,我们调用CoCreateInstance用来建立滤镜管理器
IGraphBuilder *pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
    CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
如上所示,传入的第一个参数类的标识是CLSID_FilterGraph。按照字面的意思就是用于创建图像滤镜。返回我们就得到了一个HERSULT了,这个是指向滤镜的一个句柄。这个东西就是一个图像滤镜了,它将来要用到所有其他的后续处理之中。还有那个执行描述参数传入的是CLSCTX_INPROC_SERVER。Directshow支持释放线程模型。所以你可以调用CoinitializeEx函数用COINIT_MULTITHREADED参数。
该函数还返回了个IgraphBuilder接口。该接口包含了大多数的用于构建图像滤镜的方法。还用两个方法被用于这个例子。
。ImediaControl接口,该接口用于控制数据流。可以用来停止和启动数据流。
。ImediaEvent接口,该接口用于获取图像滤镜的的事件。在这个例子中我们用来等待播放结束。
抽纸盒
这两个滤镜都是从图像滤镜引出来的。我们可以用刚才返回的IgraphBuilder来得到他们。下面是范例。
IMediaControl *pControl;
IMediaEvent  *pEvent;
directdrawhr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
接下来你就可以建立个图像滤镜。用来播放文件。可是这也是很简单的调用
hr = pGraph->RenderFile(L"C:\\Example.avi", NULL);
IgrapBuilder::RenderFile方法可以用来播放特定的文件。第一次参数就是文件名,不过必须是UNICODE的。第二个参数是用来保留的,现在只要填NULL就可以了。
当然了,如果输入的文件名有错误,或者是根本就不认识的格式,它就会返回错误。这个
时候就应该通过一些错误的代码来报告错误。因为这个例子只是简单的例子,因此没有这些代码,我们始终假设文件是存在的,并且格式是可以被解码的。要是代用成功图像滤镜就会准备播放了。现在我们可以调用ImediaControl::Run函数让他运行。
hr = pControl->Run();
一旦调用成功,数据就开始在滤镜中移动。并且将其播放出来。播放是在另外的线程后台进行的。我们只要等待它播放结束就可以了。我们可以调用ImediaEvent::WaitForCompletion还等待播放结束。
JING液灌溉系统
long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);
该方法会一直等待知道播放解说或者播放出错返回。那个参数INFINITE是告诉该函数,我要等待直到播放结束才返回。不过还有其他的参数,可以方便的使用可以参考Responding to Events这篇文章。
当应用程序结束就可以释放这些接口的指针用于关闭.COM库
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
下面是完整的代码,真的很少。
#include <dshow.h>
void main(void)
{
    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent  *pEvent = NULL;
    // Initialize the COM library.

本文发布于:2024-09-22 15:36:05,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/336470.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:图像   播放   用于
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议