该程序可以用于两个人在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 免费提供这些开发库。
分享到:
相关推荐
实现点对点的视频会议功能的所有相关技术。 点对点视频会议程序:VideoNet
点对点视频会议程序VideoNet源代码
点对点视频会议程序VideoNet开发的源代码,用c编写,其编码和解码过程采用H263标准
该程序可以用于两个人在LAN/Intranet(或者Internet)上进行视频会议。现在有许多视频会议程序,每个都有各自的性能提升技术。主要的问题是视频会议视频帧的尺寸对于传输来说太大。因此,性能依赖于对帧的编解码。我...
商业编程-源码-点对点视频会议程序VideoNet源代码.zip
编译通过,但出现内存错误,很不解,如有兴趣的,可以交流一下!!!!这个程序是网上下载的!!可是为什么都是有这样的一个错误呢/
VideoNet_src视频聊天程序VideoNet_src视频聊天程序VideoNet_src视频聊天程序
点对点视频会议程序VideoNetVC源代码,实现了点对点的视频会议功能。
在进行VideoNet的程序(在http://www.codeproject.com/Articles/7573/VideoNetb下载的)学习中,...后来反复查网上帖子解决该问题: 本资源为:修改了ConvertRGB2YUV出错问题的基于H263协议压缩的VideoNet 视频聊天程序
VideoNet源程序,实现视屏采集传输(局域网)播放,使用h263编码。有人说运行有问题,那是因为它的摄像头采集是RGB格式,现在的摄像头一般都是YUY2格式了,参考代码就行~
视频捕获、压缩、传输VideoNet 源代码
VideoNet_src.rar UDP tran...
P2P视频 不错哦
使用VC6.0的VFW获取摄像头图像预览,截图,录像,其中录像时,程序不能被打断,会死掉,还有别的解决办法,没有尝试。 其中预览功能使用的是VFW自己的 BOOL capPreview(hwnd,f),这个使用Graphics Device Interface ...
视频场景识别是机器学习和计算机视觉一个...本文在中国多媒体大会(CCF ChinaMM 2019)最新推出的VideoNet数据集上进行了实验,实验结果表明基于多粒度的视频特征的注意力机制的模型与传统方法相比具有明显的优越性.
在MSN World中,用户不会彼此直接通信。我们研究了P2P开源视频/音频会议系统。 经过研究,我发现VideoNet应用程序适合并修改了VideoNet,并适应了MSNPSharp。 我使用了模拟编解码器。
wavexxxx抓音频、播放音频(参照VideoNet_src,修正SoundRec线程类注销时未释放内存的bug, SoundPlay动态申请内存,将数据拉过来,省去罗嗦的CCriticalSection Lock/Unlock) 如果要使用MPEG4,建议使用MS 的mpg4...
使用VFW读取摄像头,然后H263压缩,存成文件,参考http://www.codeproject.com/KB/IP/videonet.aspx
VFW 读取摄像头,显示,然后H263编码压缩,存成文件 参考http://www.codeproject.com/KB/IP/videonet.aspx