TAG:
zhengyong 发表于 2003-12-12 9:42:12 -------------------------------------------------------------------------------- 点击浏览该文件 由于很多朋友找我要mpeg4网络视频传输的代码,我应付不过来了,只好在此撰写此文。。 声明:这个文章由菜鸟中的菜鸟所写,高手请不要取笑,欢迎多多指教!希望此文能为广大菜鸟们有所助益。 前言: 写这篇文章的目的是想跟某些象我一样半路出家来搞视频传输的人分享一些学习的经验 我本人学的专业跟视频处理八辈子搭不上关系,连vc编程也不会 却在导师逼迫下弄起了视频传输和图像处理,郁闷二字已经远远不能表达我的感受了。。 对于我这种不会编程的菜鸟,要做视频传输只能东拼西凑了。。原理不甚明了 废话不多说了。。 我目前搭建的mpeg4网络视频传输系统很简单: 只有视频没有音频 网络打包发送和接受的sender和receiver filter由directx9.0里面的dsnetwork例子修改而来 因此只有网络组播功能,没有rtp功能(这个功能大家可以尝试用jrtplib.lib解决) 我没有深入探讨dsnetwork的机理,只是简单把原例子的mpeg-2改成了自己所需的编码格式,实际上我是改成了DIVX格式。。实际运行中,使用不同的coder和decoder会有不同的效果,有些效果不错,有些甚至不能解码!!!我不准备探讨其中原因了,我只知道用divx代替原例中的mpeg-2效果不错(divx的版本也有影响,我用的是5.02,大家可以尝试),而用xvid则无法解码! 我的filter graph如下: 发送端:10moons sdk2000 video capture--->divx coder---->multicast sender 接受端:multicast receiver---->divx decoder----->video renderer 除了sender和receiver这两个filter,其他filter都可以从directshow直接获取 刚才说了,sender和receiver是从dsnetwork修改而来的 就是把其中的dssend.cpp和dsrecv.cpp中的getmediatype和checkmediatype函数修改了一下 将原来的mpeg2改成你所要的压缩格式 修改方法如下: 1.dssend.cpp中作如下修改,并把checkmediatype函数去掉(这是我用的简易方法,你也可以修改checkmediatype函数使之适用于你的压缩格式) ------------------------------------------------------------------------------- CInputPin::GetMediaType ( IN int iPos, OUT CMediaType * pmt ) { ASSERT (pmt) ; if (iPos == 0) { pmt -> InitMediaType () ; ////////修改了DSnetwork原有的MPEG2的MEDIATYPE和MEDIASUBTYPE pmt -> SetType (& MEDIATYPE_Video) ; pmt -> SetSubtype (& TIME_FORMAT_NONE) ;//适应任何形式 return S_OK ; } return VFW_S_NO_MORE_ITEMS ; } ------------------------------------------------------------------- 2.在dsrecv.cpp中作如下修改,并把checkmediatype函数去掉 ---------------------------------------------------------------------- CNetOutputPin::GetMediaType ( IN int iPosition, OUT CMediaType * pmt ) { HRESULT hr ; if (iPosition == 0) { ASSERT (pmt) ; pmt -> InitMediaType () ; ////////修改了DSnetwork原有的MPEG2的MEDIATYPE和MEDIASUBTYPE, 注意DIVX是在dsrecv.h定义的GUID pmt -> SetType (& MEDIATYPE_Video) ; pmt -> SetSubtype (& DIVX) ; ////////设置outputpin的Format VIDEOINFO *pvi = (VIDEOINFO *) pmt->AllocFormatBuffer(sizeof(VIDEOINFO)); ZeroMemory(pvi, sizeof(VIDEOINFO)); DWORD fccXvid = ''3VID''; pvi->bmiHeader.biCompression = fccXvid; pvi->bmiHeader.biBitCount = 24; pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pvi->bmiHeader.biWidth = 320; pvi->bmiHeader.biHeight = 240; //pvi->bmiHeader.biPlanes = 1; pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); SetRectEmpty(&(pvi->rcSource)); SetRectEmpty(&(pvi->rcTarget)); pmt->SetFormatType(&FORMAT_VideoInfo); //pmt->SetTemporalCompression(FALSE); pmt->SetSampleSize(pvi->bmiHeader.biSizeImage); /////////////////////////// hr = S_OK ; } else { hr = VFW_S_NO_MORE_ITEMS ; } return hr ; } ------------------------------------------------------------------ 3.在dsrecv.h中加入以下句子,注意这段guid是根据你所要的压缩格式修改的,这里用的是我使用的divx5.02版本的guid ------------------------------------------------------------------------- DEFINE_GUID(DIVX, 0x33564944, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); --------------------------------------------------------------------------- ok,就改这么多东西就可以把dsnetwork变成你所需要的东西拉。。 顺便把我所修改的几个程序文件都放到附件里,大家可以尝试把这几个文件替换原来dsnetwork中的相应文件,然后编译就可以知道效果了。。 附上我的graph 最后一点建议: 如果菜鸟们跟我一样,对directshow编程中如果使用和连接filter不甚明了的话 建议使用**提高的DSdemo.dll(请作者原谅,俺忘了您大号了,好像是红*工作组) 这样可以大大简化你编程的难度。。 dll及其使用方法在附件中 点击浏览该文件 (zhengyong) |