首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

點對點視訊會議程式 VideoNet 開發實戰解析

     編輯:VC 教學

VideoNet 是一個基於 LAN/Intranet(亦可擴展至 Internet)的點對點視訊會議程式,採用 H.263 視訊編碼、G.711/G.723 音訊編碼、UDP 即時傳輸。本文詳細解析其核心模組:音訊擷取/播放、視訊擷取 (VFW)、幀顯示 (DrawDib)、H.263 編解碼庫整合與網路傳輸架構。

一、音訊模組:RecordSound / PlaySound 執行緒

// 建立並啟動錄音執行緒
RecordSound* pRecord = new RecordSound(this);
pRecord->CreateThread();

// 建立並啟動播放執行緒
PlaySound1* pPlay = new PlaySound1(this);
pPlay->CreateThread();

// 開始錄音
pRecord->PostThreadMessage(WM_RECORDSOUND_STARTRECORDING, 0, 0);

// 開始播放
pPlay->PostThreadMessage(WM_PLAYSOUND_STARTPLAYING, 0, 0);

// 錄音回呼:取得 PCM 資料 → 封包 → UDP 發送
void OnSoundData(BYTE* pData, int nSize) {
    SendAudioPacket(pData, nSize);
}

// 收到遠端音訊 → 送入播放佇列
void OnAudioPacketReceived(BYTE* pData, int nSize) {
    pPlay->PostThreadMessage(WM_PLAYSOUND_PLAYBLOCK, nSize, (LPARAM)pData);
}

關鍵點:雙執行緒隔離音訊 I/O 與 UI,避免阻塞;使用 waveInOpen/waveOutOpen (MME) 或 IAudioClient (WASAPI) 低延遲路徑。

二、視訊擷取:Video For Windows (VFW)


// VideoCapture 類別封裝 VFW API
VideoCapture* pCap = new VideoCapture();
pCap->SetDialog(this);           // 設定回呼視窗
pCap->Initialize();              // 連接裝置、協商格式 (I420/YUY2/RGB24)
BITMAPINFO* pBmi = &pCap->m_bmpinfo; // 取得格式資訊
pCap->StartCapture();            // 開始預覽,回呼 OnCaptureVideo

// OnCaptureVideo 回呼中:
void OnCaptureVideo(BYTE* pFrame, int nSize) {
    // 1. 本地預覽
    DisplayFrame(pFrame, pBmi);
    // 2. 編碼
    EncodeAndSend(pFrame, pBmi);
}

三、幀顯示:DrawDib 高效繪圖

GDI SetDIBitsToDevice 效能不足,改用 DrawDib 直接寫入顯示記憶體:

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

HDRAWDIB hdd = DrawDibOpen();
DrawDibBegin(hdd, hdc, 0, 0, width, height, pBmi, 0, 0, width, height, 0);
DrawDibDraw(hdd, hdc, 0, 0, width, height, pBmi, pFrame, 0, 0, width, height, 0);
DrawDibEnd(hdd);
DrawDibClose(hdd);

支援 YUV420P → RGB24 硬體加速色彩轉換,CPU 佔用極低。

四、H.263 編解碼庫整合

編碼器 (Fast H.263 / TmN Encoder 移植版)

CParam param;
param.format = CPARAM_QCIF;      // 176x144
param.Q_intra = 8;               // 量化步長
InitH263Encoder(¶m);
InitLookupTable();               // RGB24 -> YUV420 查表

WriteByteFunction = MyWriteCallback; // 設定位元流輸出回呼

// 每幀編碼流程
ConvertRGB2YUV(WIDTH, HEIGHT, rgbFrame, yuvFrame); // 色彩空間轉換
param.data = yuvFrame;
param.inter = CPARAM_INTRA;      // I-frame
CompressFrame(¶m, &bits);    // 輸出透過 MyWriteCallback 回呼

解碼器 (TmN Decoder 移植版)

InitH263Decoder();
// 接收端:收到位元流 → 解碼
DecompressFrame(bitstream, bitstreamSize, rgbOutput, bufferSize);
// 輸出為 RGB24,直接送 DrawDib 顯示
ExitH263Decoder();

優化重點:移除原始庫的檔案 I/O、顯示相關代碼,專注即時串流處理;查表法加速色彩轉換;固定 QCIF 解析度降低運算量。

五、網路傳輸架構

  • 傳輸協定:UDP (低延遲、容忍丟包),應用層自訂封裝:Seq | Timestamp | PayloadType | Size | Data。
  • 穿透 NAT:STUN/TURN/ICE 框架(程式碼預留介面,原版僅 LAN)。
  • 頻寬自適應:根據丟包率/RTT 動態調整 Q_intra、解析度 (QCIF/CIF/4CIF)、幀率。
  • 信令:簡易 TCP 連線交換 IP/Port、能力協商(編碼格式、解析度)。

六、執行與部署

  1. 複製 VideoNet.exe 至兩台機器 A、B。
  2. 啟動雙方,A 選單 Connect → 輸入 B 的 IP/主機名 → Connect。
  3. B 跳出 Accept/Reject 對話框,點 Accept。
  4. 雙向音訊/視訊串流建立,開始會議。

七、開源庫致謝與授權

  • Paul Cheffers:RecordSound/PlaySound 類別。
  • Karl Lillevold:TmN Decoder (H.263 解碼器)。
  • Roalt Aalmoes:Fast H.263 Encoder。

專案採用開源友善授權,歡迎貢獻代碼、回報 Issue、移植至現代平台 (WebRTC, FFmpeg, Qt)。

八、現代化遷移建議

模組現代替代方案效益
VFWMedia Foundation / DirectShow / V4L2 (Linux) / AVFoundation (macOS)硬體加速編碼、多格式支援、跨平台
DrawDibDirect2D / Direct3D 11 / OpenGL / Vulkan / MetalGPU 繪製、零拷貝、高解析度支援
H.263H.264 / H.265 / VP8 / VP9 / AV1 (FFmpeg, libvpx, OpenH264)壓縮效率提升 2-4x、硬體編解碼普及
UDP 自訂WebRTC (SRTP, ICE, DTLS, SCTP) / SRT / RIST端到端加密、NAT 穿透標準化、擁塞控制
音訊 MMEWASAPI (共享/獨佔模式) / AudioWorklet (Web)超低延遲 (<10ms)、格式協商彈性

VideoNet 展示了 2000 年代初期視訊會議核心技術棧,理解其架構有助於掌握現代 WebRTC/媒體伺服器設計精髓。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved