簡體   English   中英

使用 GStreamer OpenCV Videocapture 時的灰色視頻幀 C++

[英]Grey Video frames when using OpenCV Videocapture with GStreamer C++

收到的幀

嘿,我是 Gstreamer 的新手,想通過 a.network 將從攝像機捕獲並使用 OpenCV 處理的視頻發送到接收部分。 然后接收部分讀取它並顯示它。 這應實時完成。 它基本上適用於下面的代碼/gstreamer 設置,但是一旦幀丟失(至少我認為這是原因),視頻就會以灰色部分的形式損壞(附圖)。

OpenCV 發送部分:

cv::VideoWriter videoTransmitter("appsrc ! videoconvert ! videoscale ! x264enc ! rtph264pay config-interval=1 pt=96 ! udpsink host=192.168.168.99 port=5000", cv::VideoWriter::fourcc('H', '2', '6', '4'), 10, videoTransmitter_imageSize, true);

OpenCV 接收部分:

cv::VideoCapture videoReceiver("udpsrc port=5000 ! application/x-rtp ! rtpjitterbuffer ! rtph264depay ! avdec_h264 ! videoconvert ! appsink", cv::CAP_GSTREAMER);

它基本上可以工作,但我經常在視頻中看到灰色部分,然后停留一段時間直到視頻正確顯示。 我猜它總是在由於傳輸而丟失幀時發生。 但是,我怎樣才能擺脫這些灰色/損壞的框架? 任何提示? 我需要設置任何 Gstreamer 參數來調整結果嗎? 有沒有更好的方法來 stream 與 opencv over.network 的視頻?

任何幫助表示贊賞!

不,Gstreamer 中沒有任何機制來檢測損壞的幀,因為這沒有意義。

在大多數現代視頻編解碼器中,幀不再完整發送,而是分成幾片(意味着只有幀的一小部分)。 它可以采用多個內部數據包(每個數據包包含多個切片)來構建一個完整的幀,這是一件好事,因為它使您的 stream 對錯誤更具彈性,並允許對切片進行多線程解碼(例如)。

為了實現你想要的,你有多種解決方案:

  1. 僅在 UDP 上使用 RTP/RTCP 而不是 RTP 至少 RTP 包含一個序列號和“幀結束”標記,因此可以檢測到一些數據包丟失。 默認情況下,Gstreamer 不關心這些,除非您啟動了 RTP/RTCP session。如果您使用 RTCP 設置 session,您可以在某些數據包丟失時收到報告。 我不確定是否有一種管道方式可以在丟棄數據包時得到通知,因此您可能仍需要在 gstreamer 管道中編寫一個 appsink 來添加一些代碼來檢測此事件。 但是,這會告訴您出了什么問題,但不會告訴您什么時候可以恢復或錯誤有多大。 在 Gstreamer 中,它稱為 RTPSession,您對stats::XXX_nack_count 屬性感興趣,
  2. 添加一些附加協議來計算編碼器的 output 幀/NAL/數據包的校驗和並進行帶外傳輸。 確保解碼器還計算傳入幀/NAL/數據包的校驗和,如果不匹配,您就會知道解碼失敗。 當心可能會干擾您的算法的數據包/幀重新排序(通常 B 幀將在它們的依賴關系之后重新排序)。 同樣,您無法知道何時在出現錯誤時恢復。 如果您只有部分數據包丟失,使用 TCP 而不是 UDP 可能足以修復它,但如果它是帶寬問題,它將無法恢復(如果視頻帶寬>.網絡帶寬,它會崩潰,因為 TCP不能' t丟棄數據包以適應)
  3. 僅使用內部視頻編解碼器(如 APNG 或 JPEG) JPEG 也可以部分解碼,但 gstreamer 的默認軟件 jpeg 解碼器不會 output 部分 JPEG 幀。
  4. 在編碼器中設置一個封閉且更短的 GOP 許多編碼器都有一個偽“gop = 圖片組”參數,並在錯誤后解碼時計算解碼器中的幀數。 GOP 確保無論編碼的 state 是什么,在 GOP 幀之后,編碼器將發出一組非依賴幀(可能有足夠的內部幀/切片來重建完整的幀)。 這將允許在錯誤后通過丟棄GOP - 1幀來恢復(你必須解碼它們,但你不能使用它們,它們可能已損壞),你需要一種檢測錯誤的方法,請參見上面的第 1 點或第 2 點. 對於x264enc ,該參數稱為key-int-max 您可能還想嘗試intra-refresh=true ,這樣錯誤時的破幀效果會更短。 缺點是相同視頻質量的帶寬增加。
  5. 使用具有可縮放視頻編碼的視頻編解碼器(例如,SVC 而不是 AVC)。 在這種情況下,如果出現解碼錯誤,您將獲得質量較低的幀而不是損壞的幀。 據我所知,Gstreamer 中沒有任何免費的 SVC 編碼器。
  6. 處理它 用 OpenCV 計算圖片的飽和度 map 並計算其偏差和均值。 如果它與之前的圖片有很大不同,則停止計算,直到 GOP 過去並且飽和度回到預期水平。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM