当前位置: 首页 > news >正文

杭州做网站的好公司哪家好做乒乓球网站的图片

杭州做网站的好公司哪家好,做乒乓球网站的图片,代账公司如何拉客户,资源机流媒体的处理#xff0c;以其复杂性和技术性#xff0c;一向广受工业界的关注。特别伴随着因特网的普及#xff0c;流媒体在网络上的广泛应用#xff0c;怎样使流媒体的处理变得简单而富有成效逐渐成为了焦点问题。选择一种合适的应用方案#xff0c;事半功倍。此时#…流媒体的处理以其复杂性和技术性一向广受工业界的关注。特别伴随着因特网的普及流媒体在网络上的广泛应用怎样使流媒体的处理变得简单而富有成效逐渐成为了焦点问题。选择一种合适的应用方案事半功倍。此时微软的DirectShow给了我们一个不错的选择。  DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包与DirectX开发包一起发布。目前DirectX最新版本为8.1。  那么DirectShow能够做些什么呢且看DirectShow为多媒体流的捕捉和回放提供了强有力的支持。运用DirectShow我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据并且进行相应的后期处理乃至存储到文件中。它广泛地支持各种媒体格式包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等使得多媒体数据的回放变得轻而易举。另外DirectShow还集成了DirectX其它部分比如DirectDraw、DirectSound的技术直接支持DVD的播放视频的非线性编辑以及与数字摄像机的数据交换。更值得一提的是DirectShow提供的是一种开放式的开发环境我们可以根据自己的需要定制自己的组件。 DirectShow使用一种叫Filter Graph的模型来管理整个数据流的处理过程参与数据处理的各个功能模块叫做Filter各个Filter在Filter Graph中按一定的顺序连接成一条“流水线”协同工作。大家可以看到按照功能来分Filter大致分为三类Source Filters、Transform Filters和Rendering Filters。Source Filters主要负责取得数据数据源可以是文件、因特网、或者计算机里的采集卡、数字摄像机等然后将数据往下传输Transform Fitlers主要负责数据的格式转换、传输Rendering Filtes主要负责数据的最终去向我们可以将数据送给声卡、显卡进行多媒体的演示也可以输出到文件进行存储。值得注意的是三个部分并不是都只有一个Filter去完成功能。恰恰相反每个部分往往是有几个Fitler协同工作的。比如Transform Filters可能包含了一个Mpeg的解码Filter、以及视频色彩空间的转换Filter、音频采样频率转换Filter等等。除了系统提供的大量Filter外我们可以定制自己的Filter以完成我们需要的功能。下图是一条典型的Avi文件回放Filter Graph链路 在DirectShow系统之上我们看到的即是我们的应用程序Application。应用程序要按照一定的意图建立起相应的Filter Graph然后通过Filter Graph Manager来控制整个的数据处理过程。DirectShow能在Filter Graph运行的时候接收到各种事件并通过消息的方式发送到我们的应用程序。这样就实现了应用程序与DirectShow系统之间的交互。下图给出了DirectShow应用程序开发的一般过程 以上简单介绍了DirectShow的系统结构希望大家对这个强劲的应用框架已经有了大概的认识。如果你有兴趣可以详细研究DirectX的帮助文档。DirectShow是一个强大的开发包另外它是基于COM的因此要求程序员具有COM编程的一些基本知识。关于如何深入学习DirectShow应用结构以及开发自己的Filter请参阅笔者的后续文章。笔者将从编程的角度详细讲述来源于实际工作中的经验之谈。  从下面开始我们要从程序员的角度进一步深入探讨一下DirectShow的应用以及Filter的开发。  在这之前笔者首先要特别提一下微软提供的一个Filter测试工具——GraphEdit它的路径在DXSDK/bin/DXUtils/GraphEdit.exe。如果您还没有安装DirectX SDK请到微软的网站上去下载。通过这个工具我们可以很直观地看到Filter Graph的运行及处理流程方便我们进行程序调试。如果您手边就有电脑还等什么马上体验一下吧运行GraphEdit执行File-Render Media File…选择一个媒体文件当Filter Graph构建成功后按下工具栏的运行按钮您就能看到刚才选择的媒体文件被回放出来了看到了吧写一个媒体播放器也就这么回事   接下去我们开讲Filter的开发。  学习DirectShow Filter的开发不外乎以下几种方法看帮助文档、看示例代码和看SDK基类源代码。看帮助文档应着重于总体概念上的理解看示例代码应与基类源代码的研究同步进行因为自己写Filter关键的第一步是选择一个合适的Filter基类和Pin的基类。对于Filter的把握一般认为要掌握以下三方面的内容Filter之间Pin的连接、Filter之间的数据传输以及流媒体的随机访问或者说流的定位。下面就开始分别进行阐述。  所谓的Filter Pin之间的连接实际上是Pin之间Media Type媒体类型的一个协商过程。连接总是从输出Pin指向输入Pin的。要想深入了解具体的连接过程就必须认真研读SDK的基类源代码位于DXSDK/samples/Multimedia/DirectShow/BaseClasses/amfilter.cpp类CBasePin的Connect方法。连接的大致过程为枚举欲连接的输入Pin上所有的媒体类型逐一用这些媒体类型与输出Pin进行连接如果输出Pin也接受这种媒体类型则Pin之间的连接宣告成功如果所有输入Pin上枚举的媒体类型输出Pin都不支持则枚举输出Pin上的所有媒体类型并逐一用这些媒体类型与输入Pin进行连接。如果输入Pin接受其中的一种媒体类型则Pin之间的连接到此也宣告成功如果输出Pin上的所有媒体类型输入Pin都不支持则这两个Pin之间的连接过程宣告失败。  有一点需要注意的是上述的输入Pin与输出Pin一般不属于同一个Filter典型的是上一级Filter也叫Upstream Filter的输出Pin连向下一级Filter也叫Downstream Filter的输入Pin。 当Filter的Pin之间连接完成也就是说连接双方通过协商取得了一种大家都支持的媒体类型之后即开始为数据传输做准备。这些准备工作中最重要的是Pin上的内存分配器的协商一般也是由输出Pin发起。在DirectShow Filter之间数据是通过一个一个数据包传送的这个数据包叫做Sample。Sample本身是一个COM对象拥有一段内存用以装载数据Sample就由内存分配器Allocator来统一管理。已成功连接的一对输出、输入Pin使用同一个内存分配器所以数据从输出Pin传送到输入Pin上是无需内存拷贝的。而典型的数据拷贝一般发生在Filter内部从Filter的输入Pin上读取数据后进行一定意图的处理然后在Filter的输出Pin上填充数据然后继续往下传输。下面我们就具体阐述一下Filter之间的数据传送。首先大家要区分一下Filter的两种主要的数据传输模式推模式Push Model和拉模式Pull Model。  所谓推模式即源FilterSource Filter自己能够产生数据并且一般在它的输出Pin上有独立的子线程负责将数据发送出去常见的情况如代表WDM模型的采集卡的Live Source Filter而所谓拉模式即源Filter不具有把自己的数据送出去的能力这种情况下一般源Filter后紧跟着接一个Parser Filter或Splitter Filter这种Filter一般在输入Pin上有个独立的子线程负责不断地从源Filter索取数据然后经过处理后将数据传送下去常见的情况如文件源。推模式下源Filter是主动的拉模式下源Filter是被动的。而事实上如果将上图拉模式中的源Filter和Splitter Filter看成另一个虚拟的源Filter则后面的Filter之间的数据传输也与推模式完全相同。  那么数据到底是怎么通过连接着的Pin传输的呢首先来看推模式。在源Filter后面的Filter输入Pin上一定实现了一个IMemInputPin接口数据正是通过上一级Filter调用这个接口的Receive方法进行传输的。值得注意的是上面已经提到过数据从输出Pin通过Receive方法调用传输到输入Pin上并没有进行内存拷贝它只是一个相当于数据到达的“通知”。再看一下拉模式。拉模式下的源Filter的输出Pin上一定实现了一个IAsyncReader接口其后面的Splitter Filter就是通过调用这个接口的Request方法或者SyncRead方法来获得数据。Splitter Filter然后像推模式一样调用下一级Filter输入Pin上的IMemInputPin接口Receive方法实现数据的往下传送。深入了解这部分内容请认真研读SDK的基类源代码位于DXSDK/samples/Multimedia/DirectShow/BaseClasses/source.cpp和pullpin.cpp。  下面我们来讲一下流的定位Media Seeking。在GraphEdit中当我们成功构建了一个Filter Graph之后我们就可以播放它。在播放中我们可以看到进度条也在相应地前进。当然我们也可以通过拖动进度条实现随机访问。要做到这一点在应用程序级别应该可以知道Filter Graph总共要播放多长时间当前播放到什么位置等等。那么在Filter级别这一点是怎么实现的呢  我们知道若干个Filter通过Pin的相互连接组成了Filter Graph。而这个Filter Graph是由另一个COM对象Filter Graph Manager来管理的。通过Filter Graph Manager我们就可以得到一个IMediaSeeking的接口来实现对流媒体的定位。在Filter级别我们可以看到Filter Graph Manager首先从最后一个FilterRenderer Filter开始询问上一级Filter的输出Pin是否支持IMediaSeeking接口。如果支持则返回这个接口如果不支持则继续往上一级Filter询问直到源Filter。一般在源Filter的输出Pin上实现IMediaSeeking接口它告诉调用者总共有多长时间的媒体内容当前播放位置等信息。如果是文件源一般在Parser Filter或Splitter Filter实现这个接口。对于Filter开发者来说如果我们写的是源Filter我们就要在Filter的输出Pin上实现IMediaSeeking这个接口如果写的是中间的传输Filter只需要在输出Pin上将用户的获得接口请求往上传递给上一级Filter的输出Pin如果写的是Renderer Filter需要在Filter上将用户的获得接口请求往上传递给上一级Filter的输出Pin。进一步的了解请认真研读SDK的基类源代码位于DXSDK/samples/Multimedia/DirectShow/BaseClasses/transfrm.cpp的类方法CTransformOutputPin::NonDelegatingQueryInterface实现和ctlutil.cpp中类CPosPassThru的实现。以上我们介绍了一下如何学习DirectShow Filter开发以及一些开始写自己的Filter之前的预备知识。下一讲笔者将根据自己开发Filter的经验手把手教你如何写自己的Filter。如何写自己的Filter  首先从VC的项目开始请确认你已经给VC配置好了DirectX的开发环境。写自己的Filter第一步是使用VC建立一个Filter的项目。由于DirectX SDK提供了很多Filter的例子项目位于DXSDK/samples/Multimedia/DirectShow/ Filters目录下最简单的方法就是拷贝一个然后再在此基础上修改。但如果你是Filter开发的初学者笔者并不赞成这么做。  自己新建一个Filter项目也很简单。使用VC的向导建立一个空的”Win32 Dynamic-link Library”项目。注意几个文件是必须有的.def文件定义四个导出函数定义Filter类的.cpp文件和.h文件并在.cpp文件中定义Filter的注册信息以及两个Filter的注册函数DllRegisterServer和DllUnregisterServer。注Filter的注册信息是Filter在注册时写到注册表里的内容格式可以参考SDK的示例代码Filter相关的GUID务必使用GuidGen.exe产生。接下去进行项目的设置Project-Settings…。此时你可以打开一个SDK的例子项目进行对比有些宏定义完全可以照抄最后注意将输出文件的扩展名改为.ax。  上一讲曾经提到过在写Filter之前选择一个合适的Filter基类是至关重要的。为此你必须对几个Filter的基类有相当的了解。在实际应用中Filter的基类并不总是选择CBaseFilter的。相反因为我们绝大部分写的都是中间的传输FilterTransform Filter所以基类选择CTransformFilter和CTransInPlaceFilter的居多。如果我们写的是源Filter我们可以选择CSource作为基类如果是Renderer Filter可以选择CBaseRenderer或CBaseVideoRenderer等。  总之选择好Filter的基类是很重要的。当然选择Filter的基类也是很灵活的没有绝对的标准。能够通过CTransformFilter实现的Filter当然也能从CBaseFilter一步一步实现。下面笔者就从本人的实际经验出发对Filter基类的选择提出几点建议供大家参考。  首先你必须明确这个Filter要完成什么样的功能即要对Filter项目进行需求分析。请尽量保持Filter实现的功能的单一性。如果必要的话你可以将需求分解由两个或者更多的功能单一的Filter去实现总的功能需求。  其次你应该明确这个Filter大致在整个Filter Graph的位置这个Filter的输入是什么数据输出是什么数据有几个输入Pin、几个输出Pin等等。你可以画出这个Filter的草图。弄清这一点十分重要这将直接决定你使用哪种“模型”的Filter。比如如果Filter仅有一个输入Pin和一个输出Pin而且一进一处的媒体类型相同则一般采用CTransInPlaceFilter作为Filter的基类如果媒体类型不一样则一般选择CTransformFilter作为基类。  再者考虑一些数据传输、处理的特殊性要求。比如Filter的输入和输出的Sample并不是一一对应的这就一般要在输入Pin上进行数据的缓存而在输出Pin上使用专门的线程进行数据处理。这种情况下Filter的基类选择CSource为宜虽然这个Filter并不是源Filter。  当Filter的基类选定了之后Pin的基类也就相应选定了。接下去就是Filter和Pin上的代码实现了。有一点需要注意的是从软件设计的角度上来说应该将你的逻辑类代码同Filter的代码分开。下面我们一起来看一下输入Pin的实现。你需要实现基类所有的纯虚函数比如CheckMediaType等。在CheckMediaType内你可以对媒体类型进行检验看是否是你期望的那种。因为大部分Filter采用的是推模式传输数据所以在输入Pin上一般都实现了Receive方法。有的基类里面已经实现了Receive而在Filter类上留一个纯虚函数供用户重载进行数据处理。这种情况下一般是无需重载Receive方法的除非基类的实现不符合你的实际要求。而如果你重载了Receive方法一般会同时重载以下三个函数EndOfStream、BeginFlush和EndFlush。我们再来看一下输出Pin的实现。一般情况下你要实现基类所有的纯虚函数除了CheckMediaType进行媒体类型检查外一般还有DecideBufferSize以决定Sample使用内存的大小GetMediaType提供支持的媒体类型。最后我们看一下Filter类的实现。首先当然也要实现基类的所有纯虚函数。除此之外Filter还要实现CreateInstance以提供COM的入口实现NonDelegatingQueryInterface以暴露支持的接口。如果我们创建了自定义的输入、输出Pin一般我们还要重载GetPinCount和GetPin两个函数。  Filter框架的实现大致就是这样。你或许还想知道怎样在Filter上实现一个自定义的接口以及怎么实现Filter的属性页等等。限于篇幅笔者就不展开阐述了。其实这些问题都能在SDK的示例项目中找到答案。其他的关于在实际编程中应该注意的一些问题笔者整理了一下供大家参考。  1. 锁Lock问题  DirectShow应用程序至少包含有两条线程一条主线程和一条数据传输线程。既然是多线程肯定会碰到线程同步的问题。Filter有两种锁Filter对象锁和数据流锁。Filter对象锁用于Filter级别的如Filter状态转换、BeginFlush、EndFlush等数据流锁用于数据处理线程内比如Receive、EndOfStream等。如果这两种锁没有搞清楚很容易产生程序的死锁这一点特别需要提醒。  2. EndOfStream问题  当Filter接收到这个“消息”意味着上一级Filter的数据都已经发送完毕。在这之后如果Receive再有数据接收也不应该去理睬它。如果Filter对输入Pin上的数据进行了缓存在接收到EndOfStream后应确保所有缓存的数据都已经处理过了才能返回。  3. Media Seeking问题  一般情况下你只需要在Filter的输出Pin上实现NonDelegatingQueryInterface方法当用户申请得到IID_ImediaPosition接口或IID_IMediaSeeking接口时将请求往上一级Filter的输出Pin上传递。当Filter Graph进行Mediaseeking的时候一般会调用Filter上的BeginFlush、EndFlush和NewSegment。如果你的Filter对数据进行了缓存你就要重载它们并做出相应的处理。如果你的Filter负责给发送出去的Sample打时间戳那么在Mediaseeking之后应该重新从零开始打起。  4. 关于使用专门的线程  如果你使用了专门的线程进行数据的处理和发送你需要特别小心不要让线程进行死循环并且要让线程处理函数能够去时时检查线程命令。应该确保在Filter结束工作的时候线程也能正常地结束。有时候你把GraphEdit程序关掉但GraphEdit进程仍在内存中往往就是因为数据线程没有安全关闭这个原因。   5. 如何从媒体类型中获取信息  比如你想在输入Pin连接的媒体类型中获取视频图像的宽、高等信息你应该在输入Pin的CompleteConnect方法中实现而不要在SetMediaType中。  DirectX媒体对象DirectX Media Objects简称DMOs是微软提供的另一种流数据处理COM组件。与DirectShow filter相比DMO有很多相似之处。对filter原理的熟悉将会大大帮助你对DMO的学习。另外DMO也因其结构简单、易于创建和使用而倍受微软推崇。DMO与filter的对比  1. DMO比filter实现的功能要少很多这使得DMO“体积”很小  2. DMO使用起来比filter更有灵活性。DMO的使用不需要filter graph应用程序可以直接与DMO交互。而DMO也可以通过一个DMO wrapper filter工作于DirectShow环境  3. DMO总是同步处理数据不像filter有独立的数据传送线程需要考虑多线程编程问题  4. 与传统的编解码管理器ACM、VCM相比用DMO开发的编解码器是基于COM的更易于扩展。并且DMO支持多个输入和多个输出  5. DMO不需要像filter一样分配数据传送的内存而有DMO的使用者负责  6. DMO是一个独立功能模块不需要像filter一样连接成一条链路  7. DMO不需要像filter一样将数据“推”下去数据的输入输出都是由DMO的使用者完成的  所有这些优点使得DMO成为微软对于Encoder和Decoder开发的重点推荐模式。DirectX 9.0 SDK中微软更是把DMO从DirectShow中分离出来而对于一些transform filter微软也推荐用DMO的方式来替换。  关于DMO的使用方式目前大概有两种一种是应用程序直接使用DMO另一种就是在DirectShow filter中的应用。后者比较简单只是使用了一个DMO wrapper filter。在DirectShow应用程序中DMO是对用户透明的所有使用DMO的工作均由DMO wrapper filter来完成。参见下面的代码。 // Create the DMO Wrapper filter.IBaseFilter *pFilter;HRESULT hr CoCreateInstanceCLSID_DMOWrapperFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_castvoid**pFilter; if SUCCEEDEDhr {// Query for IDMOWrapperFilter.IDMOWrapperFilter *pDmoWrapper;hr pFilter-QueryInterfaceIID_IDMOWrapperFilter, reinterpret_castvoid**pDmoWrapper; if SUCCEEDEDhr { // Initialize the filter.hr pDmoWrapper-InitCLSID_MyDMO, DMOCATEGORY_VIDEO_EFFECT; pDmoWrapper-Release; if SUCCEEDEDhr {// Add the filter to the graph.hr pGraph-AddFilterpFilter, LMy DMO;}}pFilter-Release;} 而对于DMO的直接使用以下几点是要特别注意的。  1. 在处理数据之前必须为每条输入输出stream设置media typeOptional stream除外  2. 从DMO从获取的media type未必包含format块但是在给DMO设置media type时务必带上这部分信息MIDI除外  3. 应用程序必须自己负责分配数据缓存。缓存的大小可以通过调用DMO的IMediaObject::GetInputSizeInfo或IMediaObject::GetOutputSizeInfo得到。DMO使用的数据缓存也是一个COM对象支持ImediaBuffer接口与DirectShow filter的Media Sample类似。  4. 一般的DMO依次调用IMediaObject::ProcessInput和IMediaObject::ProcessOutput处理数据In-Place的DMO调用IMediaObjectInPlace::Process处理数据。两套方法不能混用。  5. 在调用ProcessOutput时如果返回的标记是DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE说明数据的数据还没有完全取出需要再次调用ProcessOutput。  6. 所有输入数据都已输入完成应该调用DMO的IMediaObject::Discontinuity方法。  7. 如果你想中断数据处理流程调用DMO的IMediaObject::Flush。  8. 区别两种不同的可丢弃stream标记分别为DMO_OUTPUT_STREAMF_OPTIONAL和DMO_OUTPUT_STREAMF_DISCARDABLE。注意后者是要设置media type的。
http://www.zqtcl.cn/news/91596/

相关文章:

  • 做网站需要多少职务阿克苏交通建设局网站
  • 柳市建设网站python 网站开发 环境
  • 重庆建设网站的公司网站建设公司国内技术最强
  • 建设一个网站花多少钱江苏省水利工程建设局网站
  • 美橙建站之星怎么样嘉兴网站系统总部
  • 织梦企业门户网站网站只收录无权重
  • 枣庄市 网站建设南宁制作网站
  • 动漫网站建设的目的it外包公司怎么找
  • 怎样打开网站制作千图app的优势
  • 网站建设销售经理职责大桥石化集团网站谁做的
  • 黄金网站软件免费靖江seo快速排名
  • 网站建设经验做法和取得的成效wordpress 浏览器兼容
  • 代理记账注册公司图片商丘网站seo
  • 北京网站建设推荐安徽秒搜科技河南建设工程信息网招标公告
  • 网站开发项目实训总结微网站设计
  • 山东济南建网站公司东莞排名seo网站关键词优化
  • 找网站建设企业培训机构哪家最好
  • 建什么类型个人网站比较好开发高端网站建设价格
  • 网站开发 卡片网站建设合同需要印花税
  • 手机端网站图片上传如何做新公司取名字大全免费
  • vue.js网站建设智慧团建官方网站登录入口
  • 江宁区建设局网站网站建设 美食站点
  • 哈尔滨松北区建设局网站唐山企业网站模板建站
  • 服装公司网站策划书外网设计灵感网站
  • 学做婴儿衣服网站windows 建网站
  • 银饰品网站建设规划策划书wordpress近义词搜索
  • 淘宝联盟网站推广位怎么做网站开发合同支付
  • 有没有一些有试卷做的网站ios开发教程
  • 网站备案服务类型红酒公司网站源码
  • 南宁网站优化推广方案4000套微信小游戏源码