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

IP攝像機實時監控系統開發全記錄:從FFmpeg解碼到Live555推流

     編輯:關於C語言

項目背景與技術棧

開發一個基於IP攝像機的實時視頻監控系統,核心流程:獲取幀數據 → FFmpeg解碼 → 格式轉換 → x264編碼 → Live555 RTP推流。技術棧涉及FFmpeg、libx264、Live555、Windows SDK,開發周期約半個月,過程坎坷但收穫巨大。

開發過程中的挫折與突破

核心難點與解決方案記錄

1. C/C++混編鏈接錯誤(LNK2019 + extern "C")

現象:引用SDK庫函數報「無法解析的外部符號」,明明已添加庫文件和頭文件。
根因:C++編譯器對函數名進行了Name Mangling,而C語言編譯的SDK導出符號未修飾。
解決:在包含C庫頭文件時包裹extern "C":

#ifdef __cplusplus
extern "C" {
#endif
#include "sdk_header.h"
#ifdef __cplusplus
}
#endif

2. 字符集不匹配導致LoadLibrary失敗

現象:error C2664: LoadLibraryW 不能將 const char[14] 轉換為 LPCWSTR
根因:項目設置為Unicode字符集,但代碼使用窄字符串調用API。
解決:項目屬性 → 配置屬性 → 常規 → 字符集 → 改為「不使用Unicode」或統一使用TEXT()宏/L""寬字符串。

3. FFmpeg解碼後YUV格式困境(YUV422 vs YUV420)

現象:FFmpeg解碼JPEG輸出為YUV422P,但x264編碼器要求YUV420P。直接使用sws_scale轉換程序崩潰。
根因:數據平面指針設置錯誤。參考代碼僅設置data[0](適用RGB24單平面),YUV422/420需設置三個平面data[0]、data[1]、data[2]及對應linesize。
正確代碼:

ctx->pic_src.data[0] = (uint8_t*)pFrame->data[0];
ctx->pic_src.data[1] = (uint8_t*)pFrame->data[1];
ctx->pic_src.data[2] = (uint8_t*)pFrame->data[2];
ctx->pic_src.data[3] = 0;
ctx->pic_src.linesize[0] = pFrame->linesize[0];
ctx->pic_src.linesize[1] = pFrame->linesize[1];
ctx->pic_src.linesize[2] = pFrame->linesize[2];
ctx->pic_src.linesize[3] = 0;

int rs = sws_scale(ctx->sws, ctx->pic_src.data, ctx->pic_src.linesize,
                   0, ctx->rows, ctx->pic_target.data, ctx->pic_target.linesize);

4. x264編碼崩潰與Live555黑屏雙重打擊

x264崩潰:同上,因輸入數據非標準YUV420導致x264_encoder_encode崩潰,修正sws_scale參數後解決。
Live555黑屏:編碼數據寫文件正常,但推流黑屏且運行一段時間崩潰。
關鍵發現:在獲取YUV420數據後過早調用av_free(pFrame)釋放幀內存,導致編碼器讀取到已釋放的內存區域。註釋掉該釋放調用後畫面正常輸出(但引入內存洩漏,每秒約1MB,後續優化)。

最終系統架構總結

IP攝像機 → [獲取幀] → FFmpeg解碼(JPEG→YUV422) 
    → sws_scale格式轉換(YUV422→YUV420) 
    → libx264編碼(H.264) 
    → Live555 RTP/RTCP推流 → 客戶端播放

開發心得與建議

  • 先畫架構圖:明確數據流向、模塊邊界、內存所有權,避免盲目調試。
  • 善用調試手段:中間數據落盤驗證(YUV文件用YUV Player播放、H.264用VLC/FFplay驗證)。
  • 內存管理原則:誰分配誰釋放,跨模塊傳遞數據時明確生命週期,避免過早釋放或重複釋放。
  • 社區力量:技術群、論坛、師兄經驗是解決疑難雜症的關鍵捷徑。
  • 堅持到底:流媒體開發坑多、文檔少、調試難,但攻克後成就感極強。

後續優化方向

  1. 修復內存洩漏:正確管理AVFrame引用計數,使用av_frame_unref替代直接av_free。
  2. 優化編碼參數:調整x264 preset/tune/profile降低延遲。
  3. 添加錯誤恢復:網絡抖動時的重連機制、關鍵幀請求。
  4. 跨平台適配:移植至Linux/嵌入式平台。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved