网页功能: 加入收藏 设为首页 网站搜索  
点对点视频会议程序VideoNet开发例解
发表日期:2005-08-16作者:[转贴] 出处:CSDN  

  该程序可以用于两个人在LAN/Intranet(或者Internet)上进行视频会议。现在有许多视频会议程序,每个都有各自的性能提升技术。主要的问题是视频会议视频帧的尺寸对于传输来说太大。因此,性能依赖于对帧的编解码。我使用快速h263编码库来达到更好的压缩率提高速度。该程序做些小改动也可以在Internet上使用。

音频的录制与播放

  我在以前的语音会议程序中使用了RecordSound和PlaySound类,这里我将提供摘要说明RecordSound和PlaySound类的使用。

// Create and Start Recorder Thread
   record=new RecordSound(this);
   record->CreateThread();


// Create and Start Player Thread
   play=new PlaySound1(this);
   play->CreateThread();


// Start Recording
   record->PostThreadMessage(WM_RECORDSOUND_STARTRECORDING,0,0);


// Start Playing
   play->PostThreadMessage(WM_PLAYSOUND_STARTPLAYING,0,0);


// During audio recording, data will be available in the OnSoundData
// callback function of the RecordSound class. Here, you can place
// your code to send the data to remote host...


// To play the data received from the remote host
   play->PostThreadMessage(WM_PLAYSOUND_PLAYBLOCK,size,(LPARAM)data);


// Stop Recording
   record->PostThreadMessage(WM_RECORDSOUND_STOPRECORDING,0,0);


// Stop Playing
   play->PostThreadMessage(WM_PLAYSOUND_STOPPLAYING,0,0);


// At last, to Stop the Recording Thread
   record->PostThreadMessage(WM_RECORDSOUND_ENDTHREAD,0,0);


// To stop playing thread...
   play->PostThreadMessage(WM_PLAYSOUND_ENDTHREAD,0,0);

视频捕获

  使用VFW(Video For Windows)API进行视频捕获,它提供了通过webcam进行视频捕获。VideoCapture.h 和VideoCapture.cpp包含了处理视频捕获的代码。

  如下代码说明了如何使用该类:

// Create instance of Class   vidcap=new VideoCapture();
// This is later used to call display function of the main// dialog class when the frame is captured...   vidcap->SetDialog(this);
// This does lot of work, including connecting to the driver// and setting the desired video format. Returns TRUE if// successfully connected to videocapture device.   vidcap->Initialize();
// If successfully connected, you can get the BITMAPINFO// structure associated with the video format. This is later// used to display the captured frame...   this->m_bmpinfo=&vidcap->m_bmpinfo;
// Now you can start the capture....   vidcap->StartCapture();
// Once capture is started, frames will arrive in the "OnCaptureVideo"// callback function of the VideoCapture class. Here you call the// display function to display the frame.
// To stop the capture   vidcap->StopCapture();
// If your job is over....just destroy it..   vidcap->Destroy();
  要使以上代码通过编译,你应该链接适当的库:

#pragma comment(lib,"vfw32")
#pragma comment(lib,"winmm")

显示捕获的视频帧

  有许多方法和API可以显示捕获的视频。你可以使用SetDIBitsToDevice()方法直接显示,但给予GDI的函数非常的慢。更好的方法是使用DrawDib API 显示。DrawDib函数为设备无关位图(DIBs)提供了高性能的图形绘制能力。DrawDib函数直接写入视频内存,因此性能更好。

  以下代码摘要演示了使用DrawDib API显示视频帧。

// Initialize DIB for drawing...   HDRAWDIB hdib=::DrawDibOpen();
// Then call this function with suitable parameters....   ::DrawDibBegin(hdib,...);
// Now, if you are ready with the frame data, just invoke this// function to display the frame   ::DrawDibDraw(hdib,...);
// Finally, termination...   ::DrawDibEnd(hdib);   ::DrawDibClose(hdib);
编解码库

  编码器:

  我使用快速h.263编码库进行编码。该库是使其实时编码更快的 Tmndecoder 修改版。我已经将该库从C转换到C++,这样可以很容易用于任何Windows应用程序。我移除了快速h263编码库中一些不必要的代码与文件,并在.h和.cpp文件中移除了一些定义与申明。
以下是H263编码库的使用方法:

// Initialize the compressor   CParam cparams;   cparams.format = CPARAM_QCIF;   InitH263Encoder(&cparams);
 
//If you need conversion from RGB24 to YUV420, call this   InitLookupTable();
 
// Set up the callback function// OwnWriteFunction is the global function called during// encoding to return the encoded data...   WriteByteFunction = OwnWriteFunction;
 
// For compression, data must be in the YUV420 format...// Hence, before compression, invoke this method   ConvertRGB2YUV(IMAGE_WIDTH,IMAGE_HEIGHT,data,yuv);
// Compress the frame.....   cparams.format  = CPARAM_QCIF;   cparams.inter   = CPARAM_INTRA;   cparams.Q_intra = 8;   cparams.data=yuv;    //  Data in YUV format...   CompressFrame(&cparams, &bits);
// You can get the compressed data from the callback function// that you have registerd at the begining...
// Finally, terminate the encoder// ExitH263Encoder();
解码器:

  这是tmndecoder(H.263解码器)的修改版。使用ANSI C编写,我将它转换到C++使其方便在Windows应用程序中使用。我移除了一些用于显示和文件处理的文件,移除了不必要的代码并增加了一些新文件。

  原始的库中一些文件不适合于实时的解码。我已经做了修改使其适合实时的解码处理。现在,可以使用该库来解码H263帧,该库非常快,性能不错。

  解码的使用方法:
//Initialize the decoder   InitH263Decoder();
// Decompress the frame....// > rgbdata must be large enough to hold the output data...// > decoder produces the image data in YUV420 format. After//   decoding, it is converted into RGB24 format...   DecompressFrame(data,size,rgbdata,buffersize);
// Finaly, terminate the decoder   ExitH263Decoder();
如何运行程序

  拷贝可执行文件到局域网上两台不同的机器中:A和B,运行他们。在机器A(或B)中选择connect菜单条,在弹出的对话框中输入机器B的名字或IP地址然后按connect按钮,在另外一台机器(B)显示出accept/reject对话框,按accept按钮。在机器A将显示一个通知对话框,按OK后开始会议。

That's it....Enjoy......!!!

致谢:

  我感谢 Paul Cheffers 提供了他的音频录制播放类。因为有了开源人士奉献的开源库才有你所看到的videonet程序,我感激Tmndecoder的开发者Karl Lillevold和h.263快速编码库的开发者Roalt Aalmoes 免费提供这些开发库。

  如果你有任何问题或建议,可以发邮件给我 nsry2002@yahoo.co.in

源代码下载 http://www.lihuasoft.net/source/show.php?id=3883

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 点对点视频会议程序VideoNet开发例解
本类热点文章
  P2P之UDP穿透NAT的原理与实现
  Socket传输文件示例
  Socket传输文件示例
  微软ping程序源代码完整版
  Windows Socket API 使用经验
  MSXML 解析 XML
  VC中ftp协议实现多线程断点续传
  一个对Winsock 完成端口模型封装的类
  一个对Winsock 完成端口模型封装的类
  点对点(P2P)多线程断点续传的实现
  编程建立IIS站点和虚拟目录
  Windows网络编程经验小结(1)
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00416