程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> VC++ >> 點對點視頻會議程序VideoNet開發例解

點對點視頻會議程序VideoNet開發例解

編輯:VC++

  下載源代碼。

  該程序可以用於兩個人在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 免費提供這些開發庫。

  如果你有任何問題或建議,可以發郵件給我 [email protected]

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved