mpeg4网络视频传输

来源:互联网 发布:淘宝客服非法个人信息 编辑:程序博客网 时间:2024/05/16 11:19
我目前搭建的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变成你所需要的东西拉。。