??xml version="1.0" encoding="utf-8" standalone="yes"?>香蕉久久夜色精品国产小说,久久精品aⅴ无码中文字字幕不卡,国产成人精品久久一区二区三区http://www.shnenglu.com/niewenlong/category/5216.htmlzh-cnMon, 19 May 2008 13:11:37 GMTMon, 19 May 2008 13:11:37 GMT60几种开源SIP协议栈对?http://www.shnenglu.com/niewenlong/archive/2007/09/24/32792.html聂文?/dc:creator>聂文?/author>Mon, 24 Sep 2007 09:08:00 GMThttp://www.shnenglu.com/niewenlong/archive/2007/09/24/32792.htmlhttp://www.shnenglu.com/niewenlong/comments/32792.htmlhttp://www.shnenglu.com/niewenlong/archive/2007/09/24/32792.html#Feedback0http://www.shnenglu.com/niewenlong/comments/commentRss/32792.htmlhttp://www.shnenglu.com/niewenlong/services/trackbacks/32792.html 

    OPAL是Open Phone Abstraction LibraryQ是Openh323的下一个版本,它仍然用了Openh323的体pȝ构,q在其基上进行扩展,同时实现了SIP,H.323Q但在音频和视频的编码和传输部分有较大改动。OPAL初衷设计是包含Q何电话通信协议Q所以其底层q行了高度的抽象化,所以也能够很容易的支持MGCP,PSTN和将来会出现的协议。不q由于Openh323的最后一个版本还在开发中Q所以原?月发布的OPAL也被推迟Q现有的OPALq非怸完善QBUG也非常多Q不q相信以Openh323的开发班底,一定能让OPAL十分优秀?

CVS : :pserver:anonymous@cvs.sourceforge.net:/cvsroot/openh323/opal
Language : C++
VxWorks port : Yes 
Win32 port : Yes 
Linux port : Yes 
Supports RFC 3261 : Yes 
Supports RFC 2327 : Yes 
Supports RFC 3264 : Yes 
Supports RFC 3263 : No 
Supports RFC 3515 : Yes 
Supports RFC 3262 : No 
Supports RFC 3311 : No 
TCP : Yes 
UDP : Yes 
SIZE :  8MB
License : MPL
Document : None
Samples : UA,GK

    VOCAL是vovida.org开发的SIPpȝQVOCAL应该是目前功能最完善Q用者最多的开源SIP协议栈了.它不只包括了协议栈,q包括了h323与sip转换|关Q对SIP的各UServer的功能支持也非常完善.不过很可惜,不支持windowsq_Q而且自从vovida被CISCO收购以后停止了开发,最后的版本?003q?月的1.5.0?
CVS : :pserver:anonymous@cvs.vovida.org:/cvsroot/vocal
Language : C++
VxWorks port : No 
Win32 port : Partial 
Linux port : Yes 
Supports RFC 3261 : Partial 
Supports RFC 2327 : Yes 
Supports RFC 3264 : 
Supports RFC 3263 : 
Supports RFC 3515 : Yes 
Supports RFC 3262 : 
Supports RFC 3311 : 
TCP : Yes 
UDP : Yes 
SIZE : 6MB
License: Vovida software licencse
Document : Few
Samples : UA,GK,GW

    sipX是一个SIPpȝQ由SIPFoundry开发。sipX是从reSIProcate分离出来的,sipX除了包括SIP stack外,q包括了sipXphone,sipXproxy,sipXregistry{等...,由它们构成了完整的SIPpȝQ而且sipxq支持嵌入式pȝQ各个模块可以按需取舍。不q可惜是几乎没有M开发文?
SVN : http://scm.sipfoundry.org/viewsvn/
Language : C++
VxWorks port : Yes 
Win32 port : Yes 
Linux port : Yes 
Supports RFC 3261 : Yes 
Supports RFC 2327 : Yes 
Supports RFC 3264 : Yes 
Supports RFC 3263 : Yes 
Supports RFC 3515 : Yes 
Supports RFC 3262 : No 
Supports RFC 3311 : No 
TCP : Yes 
UDP : Yes 
SIZE : <4 Mb 
License : LGPL 
Document : None
Samples : UA,GK,GW

    ReSIProcate同样也是由SIPFoundry开发,ReSIProcate最开始v源于Vocal,׃Vocal开始只支持rfc3254Qؓ了支持最新的rfc3261,ReSIProcate诞生了,但现在,ReSIProcate已经成ؓ一个独立SIP协议栈了Q它十分E_Qƈ且很多商业程序都在用?
SVN : http://scm.sipfoundry.org/viewsvn/resiprocate/main/sip/
Language : C++
VxWorks port : No 
Win32 port : Yes 
Linux port : Yes 
Supports RFC 3261 : Yes 
Supports RFC 2327 : Yes 
Supports RFC 3264 : Yes 
Supports RFC 3263 : Partial 
Supports RFC 3515 : Yes 
Supports RFC 3262 : No 
Supports RFC 3311 : No 
TCP : Yes 
UDP : Yes 
SIZE : < 2.5 Mb 
License : Vovida 
Document : Few
Samples : None

    oSIP的开发开始于2000q?月,W一个版本在2001q?月发布,到现在已l发展到2.0.9了。它采用ANSI C~写Q而且l构单小巧,所以速度特别快,它ƈ不提供高层的SIP会话控制API,它主要提供一些解析SIP/SDP消息的API和事务处理的状态机QoSIP的作者还开发了ZoSIP的UA lib:exosip和proxy server lib:partysip.
CVS : :ext:anoncvs@savannah.gnu.org:/cvsroot/osip
Language : C
VxWorks port : Yes 
Win32 port : Yes 
Linux port : Yes 
Supports RFC 3261 : Yes 
Supports RFC 2327 : Yes 
Supports RFC 3264 : Yes 
Supports RFC 3263 : Yes
Supports RFC 3515 : No 
Supports RFC 3262 : No 
Supports RFC 3311 : Yes 
TCP : Yes
UDP : Yes
SIZE : 400kb 
License : LGPL
Samples : UA,GK

    l合上述评测Q可以看?USIP协议栈各有千U,OPAL有发展潜力,VOCAL比较完善QsipX兼容性好QReSIProcate教稳定,oSIPy而快速。所以要Ҏ应用的不同选择恰当的协议栈q行研究开发?/p>

]]>
ZDirectShow的MPEG-4视频传输pȝ的研I与实现http://www.shnenglu.com/niewenlong/archive/2007/09/24/32782.html聂文?/dc:creator>聂文?/author>Mon, 24 Sep 2007 06:47:00 GMThttp://www.shnenglu.com/niewenlong/archive/2007/09/24/32782.htmlhttp://www.shnenglu.com/niewenlong/comments/32782.htmlhttp://www.shnenglu.com/niewenlong/archive/2007/09/24/32782.html#Feedback0http://www.shnenglu.com/niewenlong/comments/commentRss/32782.htmlhttp://www.shnenglu.com/niewenlong/services/trackbacks/32782.html关键?视频; 采集; 压羃; DirectShow; MPEG-4,RTP

1 引言
    q年来,随着国民l济的发展,C会各个部门对于视频监视pȝ的需求越来越多。但目前的很多监视系l都跟具体的g相关Q必要具体的采集卡的支持才能实现。所以有必要开发一U具有通用性的视频监视pȝQ用普通的摄像头就能实现视频的采集?br>    ZDirectShow的开发能很灵zd控制韌频的效果Q所以选择DirectShowq种可扩展性好的技术做开发对以后的应用升U很有帮助。此外, Z实现媒体传输控制的{略Q流媒体的传输和回放也是应解决的问题之一。由Microsoft提供的DirectShow技术基于组件对象模型技术,?持宽杄格式变化Q提供高品质的多媒体回放。利用它可以在普通微Z实现媒体的客户端处理,q可以提高系l的通用性和可扩展性?br>    对于视频数据的传输,压羃率是一个必考虑到的因素。MPEG-4是由ISO和IEC的MPEGl制定的一个关于活动图像和声音的编码国际标准。它在基?内容的交互性、压~率、通用讉K能力{方面提供了一pd新的或改q的功能。MPEG-4视频在提供较好的囑փ质量的同时拥有较高的压羃率,适合于作Z?的图像压~标准?

2  相关技?br>
2.1 DirectShow技术简?br>
     DirectShow是Microsoft为开发高性能多媒体应用而开发的底层应用E序接口QAPIQ?它是DirectX家族的核心成员之一?DirectShow自n是通过一U系l内|的或程序员开发的qo器(FilterQ来控制和处理多媒体数据的体pȝ构。该体系l构定义了如何处理和控制 qo器内部及怺之间的多媒体数据。每个过滤器都有输入或输出针QPinQ? 或两者都有?br>    qo器(FilterQ是DirectShow的基本组成部分,是Filter Graph(qo器图)中最的功能模块QDirectShow多媒体数据的处理分L不同的步骤,q些不同的步骤由相应的Filterd理。这h 们可以把不同的过滤器搭配在一赯到我们要求的来处理多媒体数据。过滤器Ҏ实现功能的不同大致可分ؓ3c:
Q?Q?nbsp;源过滤器QSource FiltersQ。源qo器负责得到原始媒体数据。这些媒体数据的来源包括本地盘或网l上的媒体文件、各U采集卡{?br>Q?Q?nbsp;转换qo器(Transform FiltersQ。{换过滤器的Q务是处理从其他过滤器中接收的数据Q经q一定的处理后再传递给下一个过滤器。编解码器就是典型的转换qo器?br>Q?Q?nbsp;表现qo器(Rendering FiltersQ。表现过滤器Ҏ收到的数据进行最后的处理。它做的工作有:把媒体数据保存ؓ文g、将数据发送到|络、显C频、回N频等[1]?br>    在DirectShow pȝ之上是应用程?Application) 。应用程序要按照E序所要实现的功能建立L应的Filter Graph ,然后借助于Filter Graph Manager 来控制整个数据的处理q程。DirectShow 能在Filter Graph q行的时候接收到各种事g,q过消息的方式发送到应用E序。这样就实现了应用程序与DirectShow pȝ之间的交互?br>2.2 RTP/RTCP协议介绍
    实时传输协议RTP(Realtime Transport Protocol)是针对Internet 上多媒体数据的一个传输协议,1996 q由IETF( Internet 工程dl? 的AVT组作ؓRFC1889 发布AVT组后来对该文q行了不断改q,?003q?月提Z代替RFC1889的RFC3550。RTP充分体现了应用层分q一C通信协议?设计思想Q允许其用户了解、调整甚臛_定连l媒体的打包ҎQ该协议被广泛用于VoIP、视频等实时媒体的传送。RTP 协议包括RTP 和RTCP(RTP 控制协议) 两个关系十分密切的子协议Q?br>    (1)  RTP协议Q传输具有实时特性的数据Q?br>    Q?QRTCP协议-监测QoS 和传送参与传输者的信息?br>    RTP(实时传输协议) 通常工作在UDP的上层,从上层接收多媒体信息码流(如MPEG-4视频) Q组装成RTP 数据?然后发送给下层UDP Q相当于OSI 的会话层Q提供同步和排序服务。故RTP 协议适用于传送连l性强的数据,如视频、音频等Qƈ对网l引L时g差错有一定的自适应能力。RTCP 为实时控制协议,用于理控制信息Q如监视|络的g时和带宽Q一旦所传输的多媒体信息的带宽发生变化,接收端则通知发送端Q广播符号化识别码和~码参数Q?辑ֈ控制传输质量的目的。此?如果底层|络支持多点传播的话QRTP q支持用多点传播向多个目的端点发送数据?br>    RTP协议h如下特点[5]Q?br>Q?Q灵zL?br>    RTP协议的数据报文和控制报文使用不同的端口,数据和控制分,q样大大地提高了协议的灵zL,处理也简单?br>Q?Q支持多?br>    如果下层|\支持Q可以支持多播?br>Q?Q可扩展?br>    RTP协议通常Z个具体的应用提供服务Q通过一个具体的应用q程实现Q而不作ؓOSI体系l构中单独的一层来实现QRTP只提供协议框Ӟ开发者可以根据应用的具体要求对协议进行充分的扩展?br>
3 关键技术的实现

    该系l的发送端实现思\如下Q用USB摄像头采集数据,用Divx 5.1.1 Codec 寚w集到的数据进行MPEG-4的编码,然后q到一个发送Filter把编码后的数据发送出厅R其Filter Graph如图1所C?Q?

                      ?   发送端的Filter Graph
   接收端的实现思\如下:通过一个接收Filter接收发送端发送的数据Q然后再用Divx Decoder FilterҎ收到的数据进行解码。最后用Video Renderer把解码后的数据播攑և来。其Filter Graph如图2所C:

                      ?   接收端的Filter Graph
3.1  数据采集及编码的实现
3.1.1 采集Filter Graph的实?/strong>
    采集应用的Filter Graph一般比较复杂,而直接用Filter Graph Manager上的IGraphBuilder接口构徏q种Filter Graph,有时候难度又很大。ؓ此,DirectShow特别提供了一个辅助组件Capture Graph Builder,来简化这UFilter Graph的创建?br>    首先是创建Filter Graph Manager lgQ核心代码如下:
 

3.1.2 加入采集Filter

3.1.3加入MPEG-4~码器Filter
    q里我们采用Divx 提供的开源编码Filter。安装DivX.Pro.v5.1.1后会自动安装Divx的编码器Filter和解码器FilterQ注Q解码器 Filter在接收端要用刎ͼ。在E序中加入Divx的编码器FilterQ实现思想是在Video Compressors目录下枚丑ֈ名称?DivX Pro(tm) 5.1.1 Codec"的Filter后Q把它加入到Filter Graph中即可?br>3.2 数据的发送和接收
3.2.1 数据的发送Filter的实?/strong>  
    数据的发送要开发一个发送FilterQؓ了编E上的方便,q里采用E序内Filter的Ş式来实现。即用类的Ş式而不是编写一个成一个后~为ax的组?注册后再使用。这里我们定义一个承自CBaseFilter的类CFilterMpeg4Sender。这个类必须实现以下功能[3]Q?br>   (1) 在类中定义CFilterMpeg4Sender上的Pin的实例mInputPin?br>   (2) 实现l承自CBaseFilter::GetPin,用于q回Filter上各个Pin的对象指针?br>   (3) 实现l承自CBaseFilter::GetPin,用于q回Filter上各个Pin的数量?br>    定义一个承自CRenderedInputPin的类CMpeg4InputPinQ用于实现CFilterMpeg4Sender上的输入pinQ发送Filter通过该输入pin接收~码Filter输出的数据,然后按一定的规则发送?br>    q个cddC下功能[2]Q?br>   (1) 重写ҎEndOfStream?br>   (2) 实现IPin::BeginFlush和IPin::EndFlush两个函数?br>   (3) 重写ҎCBasePin::CheckMediaTypeq行q接时媒体类型的查?br>   (4) 重写ҎCBasePin:: Receive(),接收Sampleq发?br>3.2.2 数据的接收Filter的实?
?据的接收其实是要~写一个Source Filter, q个Source Filter名称为CFilterMpeg4ReceiverQ也l承自CBaseFilter。这跟发送Filter的实现有些类|有一炚w要注意的 是该Filter输出的MediaType的设|?br>     Char  MediaType[]=//媒体数据cd,通过在发送端把媒体类型写C个文件中而得到然后通过语句QCFilterMpeg4Receiver:: SetupMediaType((char *)MediaType,88)讄输出数据的MediaType?br>    CFilterMpeg4Receiver::SetupMediaType再调用CMpeg4OutPin::SetupMediaTypeQ)讄、接收到的媒体数据的格式Q?br>3.2.3 数据的网l传输的实现
 
 
     数据的发送我们采用开源代码JRTPLIB?】提供的RTP协议栈。最新的JRTPLIB对RFC3550的实现进行了装Q开发h员只要初步了?RTP协议可以开发出高质量的韌频传输程序。用JRTPLIBӞ只需要通过l承RTPSessionc,再重C下几个函数就可以实现视频数据?接收?/p>


     在网l带宽比较低的情况下Q如十几KBpsQ,数据丢现象比较严重Q这对于囑փ质量有很大的影响。我们采用拆帧(拆成1400个字节)以后再发送的ҎQ来降低丢率。接收端收到数据后,再把属于同一视频帧的数据再组h?br>    |络发送接收程序流E图如图3所C:

?  |络发送接收程序流E图


    对程序流E图的说明如下:
Q?Q发送端拆的算法如下:

   然后把属于同一视频帧的数据l好Q发送到解码Filter?br>   l过试Q在CDMA1.X|络下)Q采用拆帧方法传输视频数据比直接发送丢包率更低Q传输质量有了很大的提高?br>3.3 数据解码及回攄实现
    解码Filter使用的是Divx提供的开源解码器Q在接收Filter的后面接上该解码Filter卛_Q最后接上Renderer Filter可以把接收到的数据回放出来?br>3.4 实现帧率控制功能
    通过在采集设备和~码FilterQDivX Pro(tm) 5.1.1 CodecQ之间加入一个率控制Filter来实现率的控制Q该Filter相当于一个视频数计数器Q每接收C帧,q不立即把该帧发l下游的~码 FilterQ而是把计数器的值加1Q当计数器的D到最大值时才把当前收到的发出厅R在接收端发控制帧率命ol采集端可以很方便的实现帧率的远端控 制?br>    E序片断如下Q?br>
    加了帧率控制Filter的发送端 Filter Graph 如图4所C:


?   实现了率控制的Filter Graph 

4 ȝ

    该系l采用了DirectShow技术实CMPEG-4视频数据的传输,视频数据的传输采用了RTP协议。而且q实Cq端帧率的控Ӟ该系l可以很?便的UL到未?G|络的图像传输系l中。对~解码器q行研究Q采用H.264技术实现编解码Filter是下一步要完成的工作,当然在传输质?QQoSQ方面也要深入进行研I?/p>

参考文?/strong>

1  邉|,Ҏ?ZDiectShow的视频广播系l设计与实现[J].微型Z应用,2004, 4 :58-60
2  Microsoft DirectX C++ SDK Document [EB/OL],2003
3  陆其?DiectShow开发指南[M].北京.清华大学出版C?2004
4  陆其?DiectShow实务_N[M].北京:U学出版C?2004
5  张明?《基于RTP的视频传输控制方法的研究》[D].郑州市:郑州大学, 2004.3
6  Jori Liesenborgs   JRTPLIB 3.1.0 [EB/OL] 

]]>
用DirectShow实现QQ的音视频聊天功能http://www.shnenglu.com/niewenlong/archive/2007/09/24/32781.html聂文?/dc:creator>聂文?/author>Mon, 24 Sep 2007 06:45:00 GMThttp://www.shnenglu.com/niewenlong/archive/2007/09/24/32781.htmlhttp://www.shnenglu.com/niewenlong/comments/32781.htmlhttp://www.shnenglu.com/niewenlong/archive/2007/09/24/32781.html#Feedback0http://www.shnenglu.com/niewenlong/comments/commentRss/32781.htmlhttp://www.shnenglu.com/niewenlong/services/trackbacks/32781.html   |络视音频系l主要功能就在于视音频的采集Q网l传输两个方面,通过Video CapturepdAPI函数Q你可以轻杄搞定视频捕捉Q但是对于视频的|络传输Q则要费一番功夫了?对于视音频数据的传输Q只单地使用数据报套接字传输韌频数据是不可行的Q还必须在UDP层上采用RTPQ实时传输协议)和RTCPQ实时传输控制协议)来改善服务质量。实时传输协议提供具有实时特征的、端到端的数据传输服务。我们在韌频数据前插入包含有蝲h识、序受时间戳和同步源标识W的RTP包头Q然后利用数据报套接字在IP|络上传输RTP包,以此改善q箋重放效果和音视频同步。实时传输控制协议RTCP用于RTP的控Ӟ它最基本的功能是利用发送者报告和接收者报告来推断|络的服务质量,若拥塞状况严重,则改用低速率~码标准或降低数据传输比特率Q以减少|络负荷Q提供较好的Q.S保证?br>
  Directshow对于韌频的采集提供了很好的接口Q利用ICaptureGraphBuilder2接口可以很轻杄建立赯频捕捉的graph图,通过枚D音频讑֤FilterQ也可以很轻杄实现音频的捕捉,有点ȝ的是韌频数据的传输Q我们可以自己封装RTP和RTCP的协议,来自己实C个filterQ用来发送和接收韌频数据,当然了Directshow也提供了一l支持用RTP协议的网l传输多媒体的Filters。你也完全可以用Directshow提供的RTPpd的filter实现数据的传输?br>
  下面分析一下这些RTP Filters?br>
  新定义的Filter包括 RTP Source Filter QRTP Render FilterQRTP Demux FilterQRTP Receive Playload Handler (RPH) filterQRTP Send Payload (SPH) filterQ用这5个filter构徏一个通过RTP协议传输韌频数据的Graph是没有问题的?br>
  RTP Source filter被用来从一个单独的RTP会话中接收RTP和RTCP包。这个filter提供一个指定发送给其它LRTCP接收器报告和指定|络地址和端口接口来接收RTP会话的接口?br>
  RTP Rend filter是用来将数据发到|络上的一个filterQ这个filter也提供了和RTP source Filter cM的接口?br>
  RTP Demux filter用来多\分离来自 RTP Source filter的RTP 包,q个filter有一个或者多个输出的pin。这个Filter提供了如何控制多路分d如何分配到特定输出pin的接口?br>
  RTP RPH Filter 是用来网l过来的RTP包还原成原来的数据格式,主要支持H.261QH.263QIndeoQG.711QG.723和G.729和常见的多种韌频负载类型?br>
  RTP SPH filter则和RPH filter的功能相对,它的d是将韌?压羃filter输出?数据分解为RTP包,它提供的接口有指定最大生成包大小和pt倹{?br>
  下面我们看看如何?/font>q些filter来搭建我们采集和传输的graph图?br>



  ?和图2展示了DirectShow RTP中定义的filters如何q用。图1是一个采集本地多媒体数据q用RTP协议通过|络发送的filter graph。它包含一个输出原始视频的视频采集filterQ紧跟一个压~的编码filter。一旦压~,q些帧就会被发送到RTP SPH filterQ分片打包,生成RTP包,对应的发送到 RTP Render filterQ通过|络传输q些包。图2展现了一个filter graphQ用来接收包含视频流RTP包,播放视频。这个graph׃个用来接收包的RTP Source filterQ一个根据源和负载类型进行分cȝRTP Demux filterQ一个把RTP包{为压~视频的RTP RPH filterl成。这些filter随后的是用来解压帧的解码filterQ一个显C未压羃帧的渲染filter?br>
  有了RTP filter的帮助我们就可以完成cMqq的功能了Q可以实现在|络上进行视频和音频的交互了Q下面我l出在网l上两个客户端A和Bq行音频和视频交互的Graph图。这里我对图1和图2中的RTP filterq行了自己封装,编解码filter直接装CRTP Source filter 和RTP Render filter中,q样Graph囑ְ昑־很简z,RTP Source filter只是用来接收|络q来的音视频数据Q然后将数据传递给客户E序QRTP Render filter则是采集到的音视频数据发送到|络上的另一个客LQ编解码则的工作则封装到q两个filter之中?br>

? |络视频和音频交互的Graph?/div>

  如果你也惌己封装自qSource 和Render filterQ首先你要选择自己的编解码Q视频编解码是选择H261QH263Q还?MEPG4Q音频是选择G729q是G711Q要首先定好。选好~解码,装的工作就单了?br>
  不多说了Q下面看看我l出的代码吧?br>
  首先要定义一下用到的四个RTP filter的CLSID?br>
static const GUID CLSID_FG729Render = { 0x3556f7d8, 0x5b5, 0x4015, { 0xb9, 0x40, 0x65, 0xb8, 0x8, 0x94, 0xc8, 0xf9 } }; //音频发?
static const GUID CLSID_FG729Source = { 0x290bf11a, 0x93b4, 0x4662, { 0xb1, 0xa3, 0xa, 0x53, 0x51, 0xeb, 0xe5, 0x8e } };//音频接收
static const GUID CLSID_FH263Source = { 0xa0431ccf, 0x75db, 0x463e, { 0xb1, 0xcd, 0xe, 0x9d, 0xb6, 0x67, 0xba, 0x72 } };//视频接收
static const GUID CLSID_FH263Render = { 0x787969cf, 0xc1b6, 0x41c5, { 0xba, 0xa8, 0x4e, 0xff, 0xa3, 0xdb, 0xe4, 0x1f } };//视频发?br>//发送和接收韌频数据的filter
CComPtr< IBaseFilter > m_pAudioRtpRender ;
CComPtr< IBaseFilter > m_pAudioRtpSource ;
CComPtr< IBaseFilter > m_pVideoRtpRender ;
CComPtr< IBaseFilter > m_pVideoRtpSource ;

char szClientA[100];
int iVideoPort = 9937;
int iAudioPort = 9938;

//构徏视频的graph?q发送数?br>CComPtr< IGraphBuilder > m_pVideoGraphBuilder; //视频囑Ş理?
CComPtr< ICaptureGraphBuilder2 > m_pVideoCapGraphBuilder;
CComPtr< IBaseFilter > m_pFilterVideoCap;
CComPtr< IVideoWindow > m_pVideoWindow;
CComPtr< IMediaControl > m_pVideoMediaCtrl ;
CComPtr< IBaseFilter > m_pVideoRenderFilter;

HRESULT CMyDialog::VideoGraphInitAndSend()
{
 HRESULT hr;
 hr =m_pVideoGraphBuilder.CoCreateInstance( CLSID_FilterGraph );
 if(FAILED(hr))
  return hr;
 hr =m_pVideoCapGraphBuilder.CoCreateInstance( CLSID_CaptureGraphBuilder2);
 if(FAILED (hr))
  return hr;
 m_pVideoCapGraphBuilder->SetFiltergraph(m_pVideoGraphBuilder);
 m_pVideoGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&m_pVideoMediaCtrl);
 m_pVideoGraphBuilder->QueryInterface(IID_IVideoWindow,(void**)&m_pVideoWindow)

 FindDeviceFilter(&m_pFilterVideoCap,CLSID_VideoInputDeviceCategory);
 if(m_pFilterVideoCap)
  m_pVideoGraphBuilder->AddFilter( m_pFilterVideoCap,T2W("VideoCap") ) ;
  //创徏预览的filter
 hr = m_pRenderFilterVideo.CoCreateInstance(CLSID_VideoRenderer);
 if(FAILED(hr))
  return hr;
 m_pVideoGraphBuilder->AddFilter( m_pRenderFilterVideo, L"VideoRenderFilter" );
 Connect(m_pFilterVideoCap ,m_pRenderFilterVideo) ;
 //讄预览的窗?br>
 CRect rc ;
 GetClientRect(m_hOwnerWnd, &rc );
 int iWidth = rc.right - rc.left ;
 int iHeight = rc.bottom - rc.top ;
 int iLeft, iTop;
 if((iHeight*1.0)/(iWidth*1.0) >= 0.75)
 {
  //按宽度算
  int tmpiHeight = iWidth*3/4;
  iTop = (iHeight - tmpiHeight)/2;
  iHeight = tmpiHeight;
  iLeft = 0;
 }
 else
 {
  //按高度算
  int tmpiWidth = iHeight*4/3;
  iLeft = (iWidth - tmpiWidth)/2;
  iWidth = tmpiWidth;
  iTop = 0;
 }
 m_pVideoWindow->put_Owner( (OAHWND) m_hPreviewWnd ) ;
 m_pVideoWindow->put_Visible( OATRUE );
 m_pVideoWindow->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS ) ;

 //q接到网lƈ发?br> CComPtr< IRtpOption > pRenderOption;
 CComPtr< IVideoOption > pVideoOption;

 tagVideoInfo vif(160,120,24);
 int t=((int)(m_iFrameRate/5)*5)+5;
 vif.nBitCount=24;
 vif.nWidth=160;
 vif.nHeight=120;

 hr = ::CoCreateInstance(CLSID_FH263Render, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&m_pVideoRtpRender);
 if(FAILED(hr))
  return hr;
 m_pVideoRtpRender->QueryInterface(IID_IJRTPOption, (void**)&pRenderOption);
 m_pVideoRtpRender->QueryInterface(IID_IVideoOption,(void**)&pVideoOption);
 pVideoOption->SetProperty(&vif);
 pVideoOption->SetSendFrameRate(m_iFrameRate,1);//1 不发送数据,0 实际发送数?br> Connect(m_pFilterVideoCap ,m_pVideoRtpRender) ;
 //q接Ҏ
 hr= pRenderOption->Connect(szClientA,iVideoPort,1024);
 if(FAILED(hr))
  return hr;
 m_pVideoMediaCtrl->Run();
}
//视频的接?br>CComPtr< IGraphBuilder > m_pVideoGraphBuilder; //视频囑Ş理?
CComPtr< IBaseFilter > m_pFilterVideoCap;
CComPtr< IVideoWindow > m_pVideoWindow;
CComPtr< IMediaControl > m_pVideoMediaCtrl ;
CComPtr< IBaseFilter > m_pVideoRenderFilter;
HWND m_hRenderWnd ;
HRESULT VideoRecive()
{
 HRESULT hr;
 hr=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,
 IID_IFilterGraph,(void**)&m_pVideoGraphBuilder);

 m_pVideoGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&m_pVideoMediaCtrl);
 m_pVideoGraphBuilder->QueryInterface(IID_IVideoWindow,(void**)&m_pVideoWindow)
 
 hr = ::CoCreateInstance(CLSID_FH263Source, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&m_pVideoRtpSource);
 if(FAILED(hr))
  return hr;
 m_pVideoGraphBuilder->AddFilter(m_pVideoRtpSource, L"My Custom Source");

 CComPtr< IRtpOption > m_pRtpOption;
 CComPtr< IVideoOption > m_pVideoOption;
 m_pVideoRtpSource->QueryInterface(IID_IJRTPOption, (void **)&m_pRtpOption);
 m_pVideoRtpSource->QueryInterface(IID_IVideoOption, (void **)&m_pVideoOption);

 tagVideoInfo vif(160, 120 ,24);
 m_pVideoOption->SetProperty(&vif);
 hr= pRenderOption->Connect(szClientA,iVideoPort +1,1024);
 if(FAILED(hr))
  return hr;

 //创徏预览的filter
 hr = m_pRenderFilterVideo.CoCreateInstance(CLSID_VideoRenderer);
 if(FAILED(hr))
  return hr;
 m_pVideoGraphBuilder->AddFilter( m_pRenderFilterVideo, L"VideoRenderFilter" );
 Connect(m_pVideoRtpSource ,m_pRenderFilterVideo) ;

 CRect rc ;
 GetClientRect(m_hOwnerWnd, &rc );
 int iWidth = rc.right - rc.left ;
 int iHeight = rc.bottom - rc.top ;
 int iLeft, iTop;
 if((iHeight*1.0)/(iWidth*1.0) >= 0.75)
 {
  //按宽度算
  int tmpiHeight = iWidth*3/4;
  iTop = (iHeight - tmpiHeight)/2;
  iHeight = tmpiHeight;
  iLeft = 0;
 }
 else
 {
  //按高度算
  int tmpiWidth = iHeight*4/3;
  iLeft = (iWidth - tmpiWidth)/2;
  iWidth = tmpiWidth;
  iTop = 0;
 }
 m_pVideoWindow->put_Owner( (OAHWND) m_hRenderWnd ) ;
 m_pVideoWindow->put_Visible( OATRUE );
 m_pVideoWindow->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS ) ;
 m_pVideoMediaCtrl->Run();

 return S_OK;
}
//
HRESULT FindDeviceFilter(IBaseFilter ** ppSrcFilter,GUID deviceGUID)
{
 HRESULT hr;
 IBaseFilter * pSrc = NULL;
 CComPtr <IMoniker> pMoniker =NULL;
 ULONG cFetched;

 if (!ppSrcFilter)
  return E_POINTER;

 // Create the system device enumerator
 CComPtr <ICreateDevEnum> pDevEnum =NULL;

 hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
 IID_ICreateDevEnum, (void **) &pDevEnum);
 if (FAILED(hr))
  return hr;

 // Create an enumerator for the video capture devices
 CComPtr <IEnumMoniker> pClassEnum = NULL;

 hr = pDevEnum->CreateClassEnumerator (deviceGUID, &pClassEnum, 0);
 if (FAILED(hr))
  return hr;

 if (pClassEnum == NULL)
  return E_FAIL;

 if (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
 {
  hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
  if (FAILED(hr))
   return hr;
 }
 else
  return E_FAIL;

 *ppSrcFilter = pSrc;

 return S_OK;
}

//构徏音频Graph图,q发?br>CComPtr< IGraphBuilder > m_pAudioGraphBuilder; //音频囑Ş理?
CComPtr< ICaptureGraphBuilder2 > m_pCapAudioGraphBuilder;
CComPtr< IBaseFilter > m_pFilterAudioCap;
CComPtr< IMediaControl > m_pAudioMediaCtrl ;

HRESULT AudioGraphInit()
{
 HRESULT hr;
 hr =m_pAudioGraphBuilder.CoCreateInstance( CLSID_FilterGraph );
 if(FAILED(hr))
  return hr;
 hr =m_pCapAudioGraphBuilder.CoCreateInstance( CLSID_CaptureGraphBuilder2);
 if(FAILED (hr))
  return hr;
 m_pAudioGraphBuilder->SetFiltergraph(m_pCapAudioGraphBuilder);
 m_pAudioGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&m_pAudioMediaCtrl);

 FindDeviceFilter(&m_pFilterVideoCap,CLSID_AudioInputDeviceCategory);
 if(m_pFilterAudioCap)
  m_pAudioGraphBuilder->AddFilter( m_pFilterAudioCap,T2W("AudioCap") ) ;

 //发送到|络
 hr =::CoCreateInstance(CLSID_FG729Render,NULL,CLSCTX_INPROC,
 IID_IBaseFilter,(void**)&m_pFilterRtpSendAudio)
 if(FAILED(hr))
  return hr;
 m_pAudioGraphBuilder->AddFilter(m_pAudioRtpRender, L"FilterRtpSendAudio");
 Connect(m_pFilterAudioCap,m_pAudioRtpRender);

 CComPtr< IRtpOption > pOption ;
 m_pAudioRtpRender->QueryInterface(IID_IJRTPOption,(void**)&pOption)
 hr =pOption->Connect(szClientA,iAudioPort,1024);
 if(FAILED(hr))
  return hr;

 m_pAudioMediaCtrl->Run();
 return S_OK;
}
//音频的接?
CComPtr< IGraphBuilder > m_pAudioGraphBuilder; //音频囑Ş理?
CComPtr< ICaptureGraphBuilder2 > m_pCapAudioGraphBuilder;
CComPtr< IBaseFilter > m_pFilterAudioCap;
CComPtr< IMediaControl > m_pAudioMediaCtrl ;
CComPtr<IBaseFilter> m_pAudioRender;
HRESULT AudioRecive()
{
 HRESULT hr;
 hr =m_pAudioGraphBuilder.CoCreateInstance( CLSID_FilterGraph );
 if(FAILED(hr))
  return hr;
 m_pAudioGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&m_pAudioMediaCtrl);

 hr = m_pAudioRtpSource->CoCreateInstance(CLSID_FG729Source) ;
 if(FAILED(hr))
  return hr;
 m_pAudioGraphBuilder->AddFilter(m_pAudioRtpSource,L"AudioRtp");
 //创徏声卡Renderfilter
 FindDeviceFilter(&m_pAudioRender,CLSID_AudioRendererCategory);
 m_pAudioGraphBuilder->AddFilter(m_pAudioRender,L"AudioRender");
 CComPtr< IRtpOption > pRtpOption ;
 m_pAudioRtpSource->QueryInterface(IID_IJRTPOption,(void**)&pRtpOption)
 hr= pRtpOption->Connect(szClientA,iAudioPort+2,1024);
 if(FAILED (hr))
  return hr;

 Connect(m_pAudioRtpSource,m_pAudioRender);
 
 m_pAudioMediaCtrl->Run();
 return S_OK;
}


]]>
ٸþþþþñŪ߳| ȾþùŷһƷ| þþƷ2020| ˾þˬ| ھƷþþþù| þþþAVȥ| þþƷ| þˬˬƬAV鶹 | þù޾Ʒ| ձƷþþþĻ| ŷѹۿþ| ŷպþþƷһ| Ʒһþò| ޾þþþþAV| 99REþþƷﶼǾƷ| ҰĻþ | ޾ƷŮþþ| þþþþݴۺϾƷ| Ůþþùһ| þþƷѴƬƬ | þþþƷҰ| þþƷAV뽿ɫ| ŷ޾Ʒ˾þ| ˾Ʒþۺ| þþþavר| þþþþþþƷŮ99| Ļ޹˾þþƷ| þԭƷ| þþƷѹۿ97| 99þwww˳ɾƷ| ɫۺɫþû | þۺϳDž| þ˿ྫƷĻ| þ99Ʒþþþþ벥| ޹˾þþƷӰ| ݺɫþۺ| þþƷһ| ŷþۺŷ| Ʒþþþþ| 99ȶǾƷþþþþ| þƬѹۿ|