欢迎来到论文网! 识人者智,自知者明,通过生日认识自己! 生日公历:
网站地图 | Tags标签 | RSS
论文网 论文网8200余万篇毕业论文、各种论文格式和论文范文以及9千多种期刊杂志的论文征稿及论文投稿信息,是论文写作、论文投稿和论文发表的论文参考网站,也是科研人员论文检测和发表论文的理想平台。lunwenf@yeah.net。
您当前的位置:首页 > 科技论文 > 计算机论文

基于DirectShow技术的流媒体软件服务器和客户端的设计与实现(图文)

时间:2011-04-24  作者:秩名

论文导读:如图3.1所示,标识“0001”的SourceFilter用于接收网络上发来的MPEG1数据,且工作在拉模式下。本文介绍了流媒体的服务器与客户端实现。可以看出,DirectShow对媒体开发提供了强大的支持性。
关键词:DirectShow,Filter,流媒体,客户端/服务器
 

1 引言

 

 
 

多媒体的流式传输实际上牵扯到两方面的技术。其一就是服务器与客户端的通信技术;其二就是客户端对接收到的多媒体流进行实时解码后的播放技术。显然,网络通信可以用Windows Socket技术,多媒体流的解码播放可以使用DirectShow[2]技术。本文重点讨论服务器与客户端的实现。

2 服务器的简单实现原理

服务器端负责MPEG数据的发送,供演示用。这里主要的工作是,在对话框初始化函数(OnInitDialog)中建立一个监听Socket。当客户端有连接请求时,CListenSocket中就发出一个自定义消息WM_NEW_SOCKET给主对话框;主对话框响应该消息,用CMediaSocketServer与客户端建立连接。

CMediaSocketServer有两个独立的工作者线程,用户可以自定义它们的线程循环体。CMediaSocketServer::ReceivingLoop为接收线程处理,服务器根据命令的类型执行相应的操作,比如数据发送、停滞、断开等。当接收到DATA_REQUEST命令后就开始数据发送;数据发送处理在CMediaSocketServer::SendingLoop中。免费论文网

3 基于DirectShow技术的本地解码播放

客户端的多媒体解码,使用DirectShow[2]技术是最方便的了。也就是说,需要写一个能够接受服务器发来的数据、并提供给Filter Graph中其他的Filter解码的Source Filter。这种Filter Graph可以如图3.1所示构建。

图3.1 接收并播放MPEG1流的Filter Graph

如图3.1所示,标识“0001”的Source Filter用于接收网络上发来的MPEG1数据,且工作在拉模式下。可以看出Source filter将获取的多媒体数据通过Outpin送到MPEG分解转换过滤器,MPEG分解转换过滤器有一个输入针脚,两个输出针角分别将视频和音频解释码器进行解码,最后两路数据分别通过视频表示过滤器、音频表示过滤器送到显卡和声卡进行回放。

4 客户端播放器的实现

先看FilterGraph的构建过程(参见CFilterGraph::BuildGraph),BuildGraph函数首先创建了一个Filter Graph组件,然后获得一系列的控制接口,接下来创建Source Filter。因为这是一个程序内实现的Filter,不能通过CoCreateInstance函数去创建它,而要直接生成。

// Media type

if (m_bInit){

CMediaTypemt;

mt.majortype =MEDIATYPE_Stream;

mt.subtype= MEDIASUBTYPE_MPEG1System;

m_pSourceStream =new CMemStream(m_pDataList);

m_pSourceReader=newCMemReader(m_pSourceStream, &mt, &hr);

m_pSourceReader->AddRef();

// Add ourfilter

hr =m_pGB->AddFilter(m_pSourceReader, NULL);

if (FAILED(hr)){

m_bInit= false;

}

}

BuildGraph函数最后没有将Source Filter的输出Pin连出去,因为Source Filter在没有缓存一定数量前,与Splitter连接不会成功。此时启动一个等待线程;当Source Filter接收到足够的数据后,在构建完整的Filter Graph。

启动等待线程实现:

bool CFilterGraph::BuildGraph()

{

m_bInit = false;

//… …

if (m_bInit){

// Waiting forevent to start filter graph

::AfxBeginThread((AFX_THREADPROC)

CFilterGraph::WaitingThrd,this);

}

return m_bInit ;

}

等待线程实现:

CFilterGraph::WaitingThrd(void * pParam)

{

CFilterGraph *pGraph = (CFilterGraph *) pParam;

if (pGraph !=NULL && pGraph->m_pDataList !=

NULL){

::WaitForSingleObject(pGraph->m_pDataList->

m_hBufEnough,INFINITE);

if(!pGraph->IsRunning()){

pGraph->StartGraph();

}

}

return 1;

}

在StartGraph()中,构建完整的Filter Graph,并运行它,实现如下:

CFilterGraph::StartGraph(void)

{

if (m_bInit){

m_bRun = true;

HRESULT hr = NULL;

hr=m_pGB->Render(m_pSourceReader->GetPin(0));

if (FAILED(hr)){

m_bRun= false;

returnfalse;

}

hr =m_pVW->put_Visible(OAFALSE);

hr =m_pVW->put_Owner((OAHWND)m_hOwner);

hr =m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);

hr =m_pVW->SetWindowPosition(m_nLeft,

m_nTop, m_nWidth, m_nHeight);

// Enable the parent window to get the mouse and keyboard event inthe video window

hr=m_pVW->put_MessageDrain((OAHWND)m_hOw

ner);

hr =m_pVW->put_Visible(OATRUE);

// run thefilter graph

hr =m_pMC->Run();

return true;

}

return false;

}

当服务器处于就绪状态等待客户端连接时,客户端就可以在本地生成一个Socket与其进行连接。免费论文网。然后客户端就启动一个线程(AFX_THREADPROC) CWorkerSocket::ReceivingThrd()处于接受数据状态。

当发送命令请求服务器发送数据后,CWorkerSocket 子类CMediaSocketClient中的ReceivingLoop(void)不断的根据服务器发来的Socket包进行解包。免费论文网。如果是数据包(包头信息为DATA_MEDIA)则写入双缓冲队列中PoolList头部缓冲区,并把其加入到DataList的尾部等待SourceFilter的读取。当缓存到一定数量时(程序中设置为包数达到PACK_INIT_COUNT = 100),启动CFilterGraph中的StartGraph()从而建立起FilterGraph,并且运行它。这样,我们就在我们的应用程序中看到媒体的播放了。

5 结论

本文介绍了流媒体的服务器与客户端实现。可以看出,DirectShow对媒体开发提供了强大的支持性。有了DirectShow,开发媒体变得多么轻松与简便。


参考文献
[1] 陆其明,DirectShow开发指南,清华大学出版社,2003.12,第一版
[2] 陆其明,DirectShow实务精选,科学出版社北京电子出版社,2004.7,第一版
 

 

查看相关论文专题
加入收藏  打印本文
上一篇论文:基于CAN总线的音频报警模块的设计
下一篇论文:基于FA506细纱机的嵌入式PLC系统的研究
科技论文分类
科技小论文 数学建模论文
数学论文 节能减排论文
数学小论文 低碳生活论文
物理论文 建筑工程论文
网站设计论文 农业论文
图书情报 环境保护论文
计算机论文 化学论文
机电一体化论文 生物论文
网络安全论文 机械论文
水利论文 地质论文
交通论文
相关计算机论文
最新计算机论文
读者推荐的计算机论文