当前位置: 代码迷 >> 多媒体/流媒体开发 >> 流媒体开发的一些经验,希望对菜鸟有所帮助
  详细解决方案

流媒体开发的一些经验,希望对菜鸟有所帮助

热度:5947   发布时间:2013-02-26 00:00:00.0
流媒体开发的一些经验,希望对初学者有所帮助
见到网络上好多朋友从事流媒体开发,而不得法,到处求助而又有很少人回复,本人也是深有感触,现在断断续续的从事了一年多

的directshow的开发,对directshow有了一点点了解,在此写出来给那些初学者一些帮助,当然,本人水平也很差,如果在说明的

过程中有错误或者不对的地方,请大家多提意见和指正。。
1、首先说下媒体格式
audio:我所了解的wav、mp3、wma三中格式,基本上我都是先把它们解码成pcm的基本音频格式进行处理的。至于如何转换成wav

(PCM)格式的我就不多说了,通过一些decode解码器,在用wavedest的filter写到文件就成wav文件了,在这里我说一下两个wav文

件的合成。基本的音频文件的合成可以使用每个数据的叠加,数据的/2叠加等方法来合成两个音频数据。至于声音文件的放大,可

以对每个数据按照比例放大,当然要注意越界的问题。这里所说的合成是采样率、位数都相同的情况下。还有就是pcm数据的组成

格式,比如,8位的wav歌曲,双声道,它数据的存放格式是左、右、左、右这种格式,对于声道的拆分也可以采用这种格式。
video:常见的压缩格式有h263   h263++,mpeg1(avi,vcd)等基本是参照mpeg1的和h263是不同的两中标准。mpeg2居于dvd品质的

压缩格式,和dvd有一小点区别,mpeg4是现在最流行的基于网络的流媒体压缩格式,用的开源的有xvid,vidx等编解码器。最后就

是h264,是mpeg和定义h263的两个组织共同定义的,同等品质下的压缩率是mpeg4的一半。本人水平有限,对编解码没有研究,基

本上都是用别人的,编解码我就不多说了。对音频的处理,我只限于对基本的bmp图的处理。下面说说如何将音频数据和无压缩的

原始bmp图合成为avi。通过capture拿到sample,然后扩充dump的fi个合成sample戳,然后用wmwriter把这两个sample写到文件里

面。

2、下面说说简单的流媒体传输
基于directshow的架构的流,基本上是以sample为核心的,就是说我们只要拿到一个sample,把它通过网络发送出去,接收端接收

到以后把它复原(可以自己实现Allocater来开发smaple   pool,也可以直接从编解码的input   pin来获得sample来填充),然后通

过output   pin   把它deliver到后面的filter就可以了
先说一个不处理的音频、视频流的传输
audio   capture-> audio   sender   #####   net   #####   audio   receiver   ->   audio   render
vidio   caputre->   video   sender   ####   new   #####   video   receiver   ->   video   render

先说sender:重载CBaseInputPin,然后在媒体格式设置的时候,如下
HRESULT GetMediaType   (IN     int     iPos,OUT   CMediaType   *         pmt)  
{
if(iPos==0)
{
pmt-> InitMediaType();
pmt-> SetType(&MEDIATYPE_Video);
pmt-> SetType(&MEDIASUBTYPE_RGB24);
return   S_OK;
}
return   VFW_S_NO_MORE_ITEMS   ;
}

HRESULT CheckMediaType   (IN     const   CMediaType   *     pmt)
{
ASSERT(pmt);
//if(pmt-> majortype   !=   MEDIATYPE_Video   &&   pmt-> subtype   !=   MEDIASUBTYPE_XVID_TRANSPORT) return  

S_FALSE;
if(pmt-> majortype   ==   MEDIATYPE_Video   &&   pmt-> subtype   ==   MEDIASUBTYPE_RGB24)
{
VIDEOINFO   *pInfo   =   (VIDEOINFO   *)   pmt-> Format();
if(pInfo-> bmiHeader.biWidth   ==   160   &&  
pInfo-> bmiHeader.biHeight==120 ) return   S_OK;
}
return   E_INVALIDARG;
}
然后在input   的receive事件里面   发送sample的数据就可以了。
至于receive端:有两种模式,一种是自己实现IMemAllocator,这时候就要破坏pin协商的时候的(DecideAllocator)的input端

的开辟的请求,可以参考dsnetwork的receiver,一种就是默认的从output   pin,GetDeliveryBuffer得到sample接口,然后把接收

到的值的buf填充就可以了,然后调用output   pin   的deliver   下发下去就可以了。


------解决方案--------------------------------------------------------
Hi:
At it happens I have a problem how to let WMP load our source streaming filter. You known WMP can play remote files on the Internet; I guess it must load the File Source (URL) that can parse the protocol of http; then it can download the media content and play them.

So I want to do like the File Source (URL) to load our source streaming filter and parse the protocol RTSP. And I do followings:

[HKEY_CLASSES_ROOT\rtsp]

@= "RTSP "

"Source Filter "= "{11D7C001-211E-4492-BEDA-B0AF7348B12D} "



[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shell\URLProtocols\rtsp]
  相关解决方案