c[-1,1]_winform tabcontrol

c[-1,1]_winform tabcontrol因为Directshow是C++的东西,后来为了方便,才有牛人们在C#把directshow重写,但是相关文档很少,所以为了了解DIrectshow,从C++下的directshow开始是最合理不过的了,但是在C#用不到的知识就基本没有提及了··1基础介绍部分问题摘录:  DirectShow与ActiveMovie的关系?     Active

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

因为Directshow是C++的东西,后来为了方便,才有牛人们在C#把directshow重写,但是相关文档很少,所以为了了解DIrectshow ,从C++下的directshow开始是最合理不过的了,但是在C#用不到的知识就基本没有提及了··

1 基础介绍

部分问题摘录:  

DirectShow与ActiveMovie的关系?
      ActiveMovie是DirectShow原来的名称,现已不再使用,但是一部分API仍保留了”AM”的前缀,比如AM_MEDIA_TYPE和IAMVideoAccelerator。

DMO可以代替DirectShow filter吗?
      在编写编码器、解码器、效果器应用时,鼓励用DMO代替DirectShow filter。在其它的应用中,使用DirectShow filter可能会比较合适。

 

 

基础知识

Directshow使用Filter Graph来管理Filter(管理者叫做FilterGraph Manager).Filter Graph是Graph的“容器”,而Filter是FilterGraph中的最小功能模块。

在directshow中,一个filter链表我们称为Filter Graph

 

Filter是一种COM组件,为了实现在FilterGraph中的统一操作,每个Filter上都至少实现了IBaseFIlter接口。

Filter必须加入到FilterGraph且接入工作链路中才能发挥作用

Filter的链接实际上也是Filter上的Pin链接

试图链接两个Filter必须处于一个FilterGraph中,可以调用接口方法IFilterGraph::ADDFilter将指定Filter加入到FilterGraph中。

 

 

Filter Graph Manager 也是一个com 对象,用来控制Filtergraph 中的所有的filter,主要有以下

的功能:

1 用来协调filter 之间的状态改变,从而使graph中的所有的filter 的状态的改变应该一致。

2 建立一个参考时钟。

3 将filter 的消息返回给应用程序

4 提供方法用来建立 filter graph。

 

 

 1.1 楔子

一个简单的C++例子

在C++中创建DirectShow应用程序的三个步骤

第一步,首先调用CoCreateInstance创建Filter Graph Manager

HRESULT hr =CoCreateInstance(CLSID_FilterGraph, NULL,  CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);

【(CLSID)是CLSID_FilterGraph。Filter GraphManager由进程内DLL(in-process DLL)提供,因此参数3,dwClsContext的值为CLSCTX_INPROC_SERVER。由于DirectShow运行自由线程模式 (free-threading model),所以你同样可以使用COINIT_MULTITHREADED参数来调用CoInitializeEx】

 

  第二步是创建filter graph,调用CoCreateInstance得到的IGraphBuilder接口包含了大部分创建filtergraph的方法。在这个例子中还需要另外两个接口:IMediaControl和IMediaEvent。  IMediaControl控制数据流,它包含开启和停止graph的方法;IMediaEvent包含从Filter Graph Manager获取事件的方法,在这个例子中,这个接口用来得到回放结束事件。所有这些接口由Filter Graph Manager提供,使用得到的IGraphBuiler接口指针来查询得到。

 

IMediaControl *pControl;
    IMediaEvent   *pEvent;
    hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void**)&pEvent);

 

 

现在你可以创建filter graph了,下面是对食品文件的播放

hr = pGraph->RenderFile(L”C://Example.avi”,NULL);

 

 

IGraphBuilder::RenderFile方法创建了一个能够播放指定文件的filter graph,事实上,原本需要做的一些如创建filter实例及将这些filter连接起来的工作,都由这个方法自动完成了,如果是视频文件,这个 filter graph看起来应该是这个样子:

[filesource]->[如果是缩格式,这里是个解码器]->[Video Renderer]

 

要开始回放,调用IMediaControl::Run方法:

  hr = pControl->Run();

 

当filter graph运行时,数据经过各个filter最后回放为视频或音频。回放发生在一个单独的线程中。你可以通过调用IMediaEvent::WaitForCompletion方法来等待回放的结束:

long evCode = 0;
    pEvent->WaitForCompletion(INFINITE, &evCode);

 

 

这个方法在播放期间被阻塞,直至播放结束或超时。 当应用程序结束时,需要释放接口指针并关闭COM库:

pControl->Release();
    pEvent->Release();
    pGraph->Release();
    CoUninitialize();

 

完整代码见:http://blog.csdn.net/eyes4/article/details/133107

 

 2 Directshow详解

2.1关于Filter

DirectShow使用一个模块化的架构,每个处理过程都由一个叫做filter的COM对象来实现。DirectShow为应用程序提供了一系列标准的filter,开发者也可以编写自己的filter来扩展DirectShow的功能。下面是播放一个AVI文件的各个步骤:
    *从文件中读取数据并转成字节流(File Source filter)
    *检查AVI头,分析字节流并将它们分离成视频和音频(AVI Aplitter filter)
    *将视频解码(不同的解码filter,取决于不同的压缩格式)
    *将视频显示出来(Video Renderer filter)
    *将音频送入声卡(Default DirectSound Device filter)

每个filter与一个或多个其它的filter相连,其中的连接点也是一个COM对象,称作Pin,filter使用Pin将数据从一个filter转移到另一个,图中的箭头指示了数据流动的方向。在DirectShow中,这一系列连接在一起的filter称作filter graph
    Filter可能处于有三种不同的状态:运行、停止和暂停状态。filter在运行状态时处理数据,停止状态时停止处理数据,暂停状态则是表示就绪,可以开始进入运行状态。除了极个别的情况,一个filter Graph中的所有filter通常都处理同一个状态下,因此,filter graph也可以称其处于运行、停止、暂停状态。

 

2.2关于媒体类型(Media Type)

    *Major type:主类型,是一个GUID,定义了数据的整体类型,包括了:视频、音频、未分析的字节流、MIDI等。
    *Subtype:子 类型,另一个GUID,进一步定义了数据格式。比如,如果主类型是视频,则子类型可以是RGB-24、RGB-32、UYVY等格式,如果主类型是音频,则可能是PCM或MPEG-1 payload等。子类型提供了比主类型更多的内容,但仍未提供完整的格式定义,比如,子类型没有定义图像尺寸和帧率,这些都将在Format block中被定义。
    *Format block:格式块,定义了具体的格式。格式块是AM_MEDIA_TYPE结构体中一个单独被分配的内存空间,pbFormat成员指向这块内存空间。因为不同的格式会有不同的格式描述,所以 pbFormat成员的类型是void*。比如,PCM音频使用WAVEFORMATEX结构体,视频使用不同的结构体包括:VIDEOINFOHEADER和VIDEOINFOHEADER2。formattype成员是一个GUID,指定了格式块包含了哪种结构体,每一种格式的结构体都被分配了GUID。cbFormat成员定义了格式式块的长度。
    当格式块被定义时,主类型和子类型包含的信息就显得有点多余了。其实,主类型和子类型为识别格式提供了一个便利的方法,比方说,你可以指定一个普通的24 位RGB格式(MEDIASUBTYPE_RGB24),而不需去关心VIDEOINFOHEADER结构体中诸如图像尺寸和帧率这些信息。

关于媒体样本(Media Sample)和分配器(Allocator)

(这部分貌似C#中没有)

 

2.3关于构建Filter Graph

DirectShow提供了一系列用于构建filtergraph的组件,包括:
    *Filter Graph Manager。 这个对象用于控制filter graph,支持IGraphBuilder、IMediaControl和IMediaEventEx等许多接口。所有的directshow应用程序 都需要在某些地方用到这个对象,虽然在有些情况下,是其它的对象为应用程序创建了filter graph manager。
    *Capture Graph Builder。这个对象为构建filtergraph提供附加的方法。它最初是为构建提供视频采集的graph而设计的(这正是它的名字由来),但是对于构建许多另外类型的filter graph也是很有用的。它支持ICaptureGraphBuilder2接口。

下面两个名称须分清楚:

IGraphBuilderFilter Graph Manager

ICaptureGraphBuilder2CaptureGraph Builder

  2.4 智能连接(Intelligent Connect

智能连接这个术语覆盖了一系列FilterGraph Manager用于构建所有或部份filter graph的算法。任何时候,当Filter Graph Manager需要添加filter来完成graph时,它大致做以下几件事情:
    1.如果有一个filter存在于graph中,而且这个filter有至少一个没有连接的input pin,Filter Graph Manager试着去试用这个filter。

Grap构建概述

创建一个filter graph,从创建一个FilterGraph Manager实例开始:

IGraphBuilder* pIGB;  HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,(void **)&pIGB);

 

 

     Filter GraphManager支持下列Graph构建方法:
    *IFilterGraph::ConnectDirect
,在两个pin之间进行直接连接,如果连接失败,则返回失败
    *IFilterGraph::Connect,连接两个Pin,如果可能的话,直接连接它们,否则,在中间加入其它的filter来完成连接。
    *IGraphBuilder::Render,从某个输出Pin处开始完成余下的graph构建。该方法会自动在输出pin后面添加必须的filter,直到rendererfilter为止。
    *IGraphBuilder::RenderFile,构建一个完整的文件回放graph。
    *IGraphBuilder::AddFilter, 将一个filter添加到graph中。它不连接filter,并且在调用此方法前,filter必须已经被创建。创建filter可以是用CoCreateInstance方法或使用Filter Mapper或系统设备枚举器(System Device Enumerator)。
    这些方法提供了三种构建graph的途径:
    1.filter graph manager构建整个graph
    2.filter graph manager构建部分graph
    3.应用程序构建整个graph

 

【1】Filter Graph Manager构建整个graph
    如果你仅仅是想回放一个已知格式的文件,如AVI、MPEG、WAV或MP3,使用RenderFile方法。
    RenderFile方法首先寻找注册在系统中能分析源文件的filter,它使用协议名(如http://),文件扩展名或文件的头几个字节来决定选择哪一个源filter。
    Filter Graph Manager使用一个迭代过程来完成余下的graph构建。在这个迭代过程中,它逐个列出filter的输出pin上支持的媒体类型,并搜索哪个已注册的filter的输入Pin接受该媒体类型。它使用一系列的规则来缩小filter的范围并排定优先顺序:
    *filter类别(category)标识的filter的一般功能
    *媒体类型描述filter能在接受或能输出哪种数据类型
    *merit值决定filter被尝试的次序。如果两个filter具有相同的filter类别并且同时支持相同的输入类型,Filter Graph Manager选择merit值大的那一个。一些filter故意给出一个小merit值是因为它是为特殊用途设计的,仅能由应用程序来将其添加到graph。
    Filter Graph Manager使用Filter Mapper对象来搜索已注册的filter。
    每个filter被添加时,filter graph manager试着将其与前一个filter的输出pin连接。它们协商决定他们是否能连接,如果能,哪一种媒体类型被用来连接。如果新filter不能连接,filter graph manager丢弃它并尝试别一个,这个过程一直继续到每个流都被render为止。

   【2】 Filter GraphManager构建部分graph
    如果不仅仅是播放一个文件,那么你的应用程序就必须做一些graph的构建工作。比如,一个视频采集应用程序必须先选择一个source filter并将其添加到graph中去。如果你需要将数据写入到一个AVI文件中,你必须添加一个AVI Mux和File Write filter。不过,也经常有可能让filter graph manager来完成整个graph,比如,你可以通过Render方法来render一个pin进行预览。
   
    【3】应用程序构建整个graph
    在某些场合,你的应用程序需要添加和连接每个filter来构建graph。在这种情况下,你很可能明确地知道哪些filter需要加到graph中去。使用这种方式,应用程序通过调用AddFilter方法添加每个filter,然后枚举filter上的pin,调用Connect或 ConnectDirect来连接它们。

 

智能连接
    智能连接是filter graph manager用以构建filter graph的机制。它包含了一系列相关的用以选择filter和将它们添加到graph中去的算法。作为应用程序开发者,你并不需要很具体地了解智能连接的细节。如果你在构建某个filter graph时遇到问题并希望能解决它,或者你正在编写你自己的filter并希望它能自动地被graph构建,请阅读这一节。
    智能连接涉及以下IGraphBuilder方法:
    *IGraphBuilder::Render
    *IGraphBuilder::AddSourceFilter
    *IGraphBuilder::RenderFile
    *IGraphBuilder::Connect
    Render方法构建一部分graph,它从一个尚未连接的输出pin开始顺着数据流的方向往下,添加必要的filter,起始的那个filter必须已被添加到了graph中。Render方法每一步都搜索一个能够连接到前一个filter的filter,如果新连接上的filter有多个输出pin,数据流能自动分流,搜索直到每个流都被renderer为止。如果Render方法搜索到的filter无法使用,它会返回去尝试另一个filter。

详细内容见:http://blog.csdn.net/eyes4/article/details/133119

 

 内容主要摘于:http://blog.csdn.net/eyes4
                             DirectShow SDK 学习笔记

      

开源C# directshow类库

http://directshownet.sourceforge.net/                      

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/182930.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • plot函数的用法_ezplot函数

    plot函数的用法_ezplot函数matlab的图形绘制是非常重要的一种功能,所有关于数据分析挖掘方面一定会用到此项功能。在我们开始第三章数据可视化之前,必须先把plot函数必须弄得清清楚楚才行,下面让我们看看关于它的一切吧!一.plot首先,plot有几种形式(1)plot(X,Y):创建数据Y相对于中相应值X的二维折线图其中,若X,Y是向量,长度必须相等,图是Y对X的若X,Y是矩阵…

    2022年10月11日
  • ASP.NET验证控件之RangeValidator「建议收藏」

    ASP.NET验证控件之RangeValidator「建议收藏」RangeValidator控件用于检测用户输入的值是否介于两个值之间。可以对不同类型的值进行比较,比如数字、日期以及字符。我们一般会用来验证输入的年龄或者考试的分数等。下面我们一块看看RangeValidator的属性:属性描述 BackColor 背景颜色 ControlToValidate

  • 8000401a 因为配置标志不正确 错误及解决办法

    8000401a 因为配置标志不正确 错误及解决办法解决办法:如果是64位的office运行dcomcnfg打开组件服务如果是32位的office,则运行comexp.msc-32打开组件服务依次展开”组件服务”->“计算机”->“我的电脑”->“DCOM配置”找到”MicrosoftExcel应用程序”或”MicrosoftWord应用程序”,点击”安全”选项卡,依次把”启动和激活权限”,”访问权限”都选择为自定义,然后依次点击它们的编辑,把NetworkService和IIS_IUSRS添加进去,并加入所有的权限…

  • js 判断数组中是否包含某个元素_前端数组包含某个元素

    js 判断数组中是否包含某个元素_前端数组包含某个元素Array.prototype.S=String.fromCharCode(2); Array.prototype.in_array=function(e){ varr=newRegExp(this.S+e+this.S); return(r.test(this.S+this.join(this.S)+this.S)); }; vararr=

    2022年10月19日
  • ODI性能问题

    ODI性能问题

  • 密码学笔记

    密码学笔记

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号