用directshow实现qq的音视频聊天功能

上传人:j****9 文档编号:45357444 上传时间:2018-06-16 格式:DOC 页数:11 大小:115.50KB
返回 下载 相关 举报
用directshow实现qq的音视频聊天功能_第1页
第1页 / 共11页
用directshow实现qq的音视频聊天功能_第2页
第2页 / 共11页
用directshow实现qq的音视频聊天功能_第3页
第3页 / 共11页
用directshow实现qq的音视频聊天功能_第4页
第4页 / 共11页
用directshow实现qq的音视频聊天功能_第5页
第5页 / 共11页
点击查看更多>>
资源描述

《用directshow实现qq的音视频聊天功能》由会员分享,可在线阅读,更多相关《用directshow实现qq的音视频聊天功能(11页珍藏版)》请在金锄头文库上搜索。

1、用用 DirectShow 实现实现 QQ 的音视频聊天功能的音视频聊天功能 当下比较流行的即时通信工具,比如 MSN,QQ 等都实现了视音频的功能,通过视频,音频,我们可以更好的和朋友通过网络进行沟通,本文通过 DirectShow 技术模拟 QQ 实现了视频和音频的采集,传输,基本实现了 QQ 的视音频聊天的功能。网络视音频系统主要功能就在于视音频的采集,网络传输两个方面,通过 Video Capture 系列 API 函数,你就可以轻松的搞定视频捕捉,但是对于视频的网络传输,则要费一番功夫了。 对于视音频数据的传输,只简单地使用数据报套接字传输音视频数据是不可行的,还必须在 UDP 层上

2、采用 RTP(实时传输协议)和 RTCP(实时传输控制协议)来改善服务质量。实时传输协议提供具有实时特征的、端到端的数据传输服务。我们在音视频数据前插入包含有载荷标识、序号、时间戳和同步源标识符的 RTP 包头,然后利用数据报套接字在 IP 网络上传输 RTP 包,以此改善连续重放效果和音视频同步。实时传输控制协议 RTCP 用于 RTP 的控制,它最基本的功能是利用发送者报告和接收者报告来推断网络的服务质量,若拥塞状况严重,则改用低速率编码标准或降低数据传输比特率,以减少网络负荷,提供较好的 Q.S 保证。Directshow 对于音视频的采集提供了很好的接口,利用 ICaptureGrap

3、hBuilder2 接口可以很轻松的建立起视频捕捉的 graph 图,通过枚举音频设备 Filter,也可以很轻松的实现音频的捕捉,有点麻烦的是音视频数据的传输,我们可以自己封装 RTP 和 RTCP 的协议,来自己实现一个 filter,用来发送和接收音视频数据,当然了 Directshow 也提供了一组支持使用RTP 协议的网络传输多媒体流的 Filters。你也完全可以用 Directshow 提供的 RTP 系列的filter 实现数据的传输。下面分析一下这些 RTP Filters。新定义的 Filter 包括 RTP Source Filter ,RTP Render Filter

4、,RTP Demux Filter,RTP Receive Playload Handler (RPH) filter,RTP Send Payload (SPH) filter,使用这 5 个 filter 构建一个通过 RTP 协议传输音视频数据的 Graph 是没有问题的。RTP Source filter 被用来从一个单独的 RTP 会话中接收 RTP 和 RTCP 包。这个 filter 提供一个指定发送给其它主机 RTCP 接收器报告和指定网络地址和端口接口来接收 RTP 会话的接口。RTP Rend filter 是用来将数据发到网络上的一个 filter,这个 filter 也

5、提供了和 RTP source Filter 类似的接口。RTP Demux filter 用来多路分离来自 RTP Source filter 的 RTP 包,这个 filter 有一个或者多个输出的 pin。这个 Filter 提供了如何控制多路分离和如何分配到特定输出 pin 的接口。RTP RPH Filter 是用来网络过来的 RTP 包还原成原来的数据格式,主要支持H.261,H.263,Indeo,G.711,G.723 和 G.729 和常见的多种音视频负载类型。RTP SPH filter 则和 RPH filter 的功能相对,它的任务是将音视频 压缩 filter 输出的

6、 数据分解为 RTP 包,它提供的接口有指定最大生成包大小和 pt 值。下面我们看看如何用这些 filter 来搭建我们采集和传输的 graph 图。图 1 和图 2 展示了 DirectShow RTP 中定义的 filters 如何运用。图 1 是一个采集本地多媒体数据并使用 RTP 协议通过网络发送的 filter graph。它包含一个输出原始视频帧的视频采集 filter,紧跟一个压缩帧的编码 filter。一旦压缩,这些帧就会被发送到 RTP SPH filter,分片打包,生成 RTP 包,对应的发送到 RTP Render filter,通过网络传输这些包。图 2 展现了一个

7、filter graph,用来接收包含视频流 RTP 包,播放视频。这个 graph 由一个用来接收包的 RTP Source filter,一个根据源和负载类型进行分类的 RTP Demux filter,一个把RTP 包转为压缩视频帧的 RTP RPH filter 组成。这些 filter 随后的是用来解压帧的解码filter,一个显示未压缩帧的渲染 filter。有了 RTP filter 的帮助我们就可以完成类似 qq 的功能了,可以实现在网络上进行视频和音频的交互了,下面我给出在网络上两个客户端 A 和 B 进行音频和视频交互的 Graph 图。这里我对图 1 和图 2 中的 RT

8、P filter 进行了自己封装,将编解码 filter 直接封装到了 RTP Source filter 和 RTP Render filter 中,这样 Graph 图就显得很简洁,RTP Source filter只是用来接收网络过来的音视频数据,然后将数据传递给客户程序,RTP Render filter 则是将采集到的音视频数据发送到网络上的另一个客户端,编解码则的工作则封装到这两个 filter之中。图 3 网络视频和音频交互的 Graph 图如果你也想自己封装自己的 Source 和 Render filter,首先你要选择自己的编解码,视频编解码是选择 H261,H263,还是

9、 MEPG4,音频是选择 G729 还是 G711,要首先确定好。选好编解码,封装的工作就简单了。不多说了,下面看看我给出的代码吧。首先要定义一下用到的四个 RTP filter 的 CLSID。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,

10、 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 ;/视 频发送 /发送和接收音视频数据的 filter C

11、ComPtr m_pAudioRtpRender ; CComPtr m_pAudioRtpSource ; CComPtr m_pVideoRtpRender ; CComPtr m_pVideoRtpSource ;char szClientA100; int iVideoPort = 9937;int iAudioPort = 9938;/构建视频的 graph 图,并发送数据 CComPtr m_pVideoGraphBuilder; /视频图形管理 器 CComPtr m_pVideoCapGraphBuilder; CComPtr m_pFilterVideoCap; CComPt

12、r m_pVideoWindow; CComPtr m_pVideoMediaCtrl ; CComPtr 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 (h

13、r)return hr;m_pVideoCapGraphBuilder- SetFiltergraph(m_pVideoGraphBuilder);m_pVideoGraphBuilder-QueryInterface(IID_IMediaControl, (void *)m_pVideoGraphBuilder- QueryInterface(IID_IVideoWindow,(void*)if(m_pFilterVideoCap)m_pVideoGraphBuilder-AddFilter( m_pFilterVideoCap,T2W(“VideoCap“) ) ;/创建预览的 filte

14、rhr = m_pRenderFilterVideo.CoCreateInstance(CLSID_VideoRenderer);if(FAILED(hr)return hr;m_pVideoGraphBuilder-AddFilter( m_pRenderFilterVideo, L“VideoRenderFilter“ );Connect(m_pFilterVideoCap ,m_pRenderFilterVideo) ;/设置预览的窗口CRect rc ; GetClientRect(m_hOwnerWnd, int iWidth = rc.right - rc.left ;int iH

15、eight = 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( (

16、OAHWND) m_hPreviewWnd ) ;m_pVideoWindow-put_Visible( OATRUE );m_pVideoWindow-put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS ) ;/连接到网络并发送CComPtr pRenderOption; CComPtr 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 *)if(FAILED(hr)return hr;m_pVideoRtpRender-Q

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号