1、視頻編碼格式初始配置
media\engine\internaldecoderfactory.cc
2、FEC
Branch65版本 src\modules\rtp_rtcp\source\forward_error_correction.cc
對抗網絡丟包:前向糾錯(FEC)
FEC頭部為10字節,包含內容如下:
E flag:擴展位,供將來使用,當前設置為0。
L flag:指示長偏移掩碼是否使用,0表示偏移掩碼為16位,1表示為48位。
P/X/CC/M/PT recovery field:由本FEC包所保護的所有媒體數據包的RTP頭部的P/X/CC/M/PT flag位經XOR操作后得到。
SN base:本FEC包所保護的媒體數據包的RTP報文的序列號最小值。
TS recovery field: 由本FEC包所保護的所有媒體數據包的RTP頭部中的Timestamp字段經XOR操作后得到。
Length recovery field: 由本FEC包所保護的所有媒體數據包的負載長度(包括CSRC、RTP頭部擴展、負載和padding的長度之和,以16位無符號網絡序表示)經XOR操作后得到。
原理:
3、視頻分辨率初始配置
pc\videocapturertracksource.cc、
選取的原則是,在kVideoFormats里面找參數與kDefaultFormat默認值最接近的一組參數,作為本端的編碼能力。
4、視頻碼率
media\engine\webrtcmediaengine.cc
調用 EncoderStreamFactory::CreateEncoderStreams
BPP指數:每像素位數(BPP)是應用於視頻文件中每個像素的平均數據量。通過將數據速率(kbps)除以視頻的每秒像素數(像素寬度乘以高度像素乘以每秒幀數)來計算:
BPP = 數據速率/(分辨率*每秒幀數)
BPP通常在0.05到0.150之間,具體取決於場景中的運動量。運動越多,BPP應該越高。
BPP也與分辨率成反比:分辨率越低,在不產生巨大比特率的情況下BPP越高。這是因為與高分辨率視頻相比,低分辨率視頻中要復制或參考的總像素更少。
要基於BPP計算比特率的大小,
比特率 =(分辨率*每秒幀* BPP)/ 1000
一般bpp=0.11適合大部分編碼器和編碼標准,可達到比較好的視頻效果
5、幀率最大值
理論上編碼器的輸入幀率小於等於視頻采集的幀率。編碼器編碼的性能+視頻采集幀率決定編碼器的輸入幀率。
若攝像頭的640*480的采集幀率是30fps,若編碼器的640*480的編碼性能是60fps,那么編碼器的輸入幀率為640*480 30fps。
若編碼器性能比較差,640*480的編碼性能是25fps,那么編碼器的輸入幀率為640*480 25fps。
實現這個最低幀率選擇的算法是FrameDropper漏斗算法。算法大概原理是,漏斗進口定時將視頻采集的幀率送到漏斗隊列里面,當編碼器性能調度過來,找算法要數據的時候,將漏斗的最新一幀視頻送給編碼器。
詳細實現參見:VideoStreamEncoder::EncodeTask->Run->OnIncomingFrame
代碼:
Branch 65:
webrtc\media\engine\webrtcvideoengine.h
6、SRTP
webrtc\src\webrtc\api\peerconnectioninterface.h
disable_encryption = true 取消SRTP
disable_encryption = false 開啟SRTP
配置秘鑰 就是 控制dtls的接口
7、上述幀率碼率流程
在webrtc里面函數實現如下:
->VideoStreamEncoder::EncodeVideoFrame
->VideoSender::AddVideoFrame----在這個函數中讀取全局變量encoder_params_,判斷是否需要調整視頻參數。
->VideoSender::SetEncoderParameters
->VCMGenericEncoder::SetEncoderParameters
8、mtu最大包長
用RTP/RTCP實現是實時視頻數據的傳輸,要控制數據包的大小,使之不被路由器分片,webrtc默認設置
Branch65 代碼位置 \src\media\engine\constants.cc
9、BWE降碼率
BWE模塊決定視頻通訊中可以發送多大碼率視頻不會使網絡擁塞,防止視頻通訊質量下降。
最新版本webrtc使用trendline算法實現網絡擁塞預估,早期版本使用KalmanFilter算法。兩種算法都是基於接收端的網絡延遲進行碼率估計。早期的KalmanFilter算法是在接收端根據網絡延時,計算出合適的帶寬,通過REMB RTCP報文反饋給發送端,讓發送端按照該碼率發送視頻數據。trendline算法對此進行了優化,在發送端根據網絡延時,計算合適的帶寬。
基本思想是:丟包率反映網絡擁塞狀況。如果丟包率很小或者為0,說明網絡狀況良好,在不超過預設最大碼率的情況下,可以增大發送端碼率;反之如果丟包率變大,說明網絡狀況變差,此時應減少發送端碼率。在其它情況下,發送端碼率保持不變。
基於延遲的擁塞控制是通過每組包的到達時間的延遲差(delta delay)的增長趨勢來判斷網絡是否過載,如果過載進行碼率下調,如果處於平衡范圍維持當前碼率,如果是網絡承載不飽滿進行碼率上調。這里有幾個關鍵技術:包組延遲評估(InterArrival)、濾波器趨勢判斷(TrendlineEstimator)、過載檢測(OveruseDetector)和碼率調節(AimdRateControl)。
webrtc具體實現:
丟包擁塞控制(trendline)
BaseChannel::ProcessPacket
->WebRtcVideoChannel::OnRtcpReceived
->Call::DeliverPacket
->Call::DeliverRtcp
->VideoSendStream::DeliverRtcp
->VideoSendStreamImpl::DeliverRtcp
->ModuleRtpRtcpImpl::IncomingRtcpPacket
->RTCPReceiver::IncomingPacket
->RTCPReceiver::TriggerCallbacksFromRtcpPacket
->SendSideCongestionController::OnTransportFeedback
基於延時擁塞控制
BaseChannel::ProcessPacket
->WebRtcVideoChannel::OnRtcpReceived
->Call::DeliverPacket
->Call::DeliverRtcp
->VideoSendStream::DeliverRtcp
->VideoSendStreamImpl::DeliverRtcp
->ModuleRtpRtcpImpl::IncomingRtcpPacket
->RTCPReceiver::IncomingPacket
->RTCPReceiver::TriggerCallbacksFromRtcpPacket
->BitrateControllerImpl::RtcpBandwidthObserverImpl::OnReceivedRtcpReceiverReport
->BitrateControllerImpl::OnReceivedRtcpReceiverReport
->SendSideBandwidthEstimation::UpdateReceiverBlock
->SendSideBandwidthEstimation::UpdateEstimate
10、nack
webrtc支持RTPFB和PLI FB兩種重傳方式。
\src\media\engine\webrtcvideoengine.cc
視頻重傳:VideoSendStreamImpl::ConfigureProtection
音頻重傳:VCMLossProtectionLogic::SetMethod
11、視頻PT
也就是RTP包頭的PT值 有效荷載類型,占7位,用於說明RTP報文中有效載荷的類型,如GSM音頻、JPEM圖像等,在流媒體中大部分是用來區分音頻流和視頻流的,這樣便於客戶端進行解析
src\media\engine\webrtcvideoengine.cc
12、音頻PT
\src\media\engine\webrtcvoiceengine.cc
13、ICE的參數配置
全局搜索RTCConfiguration類的實現
Branch65 在api\peerconnectioninterface.h
something from :
https://blog.csdn.net/CrystalShaw/article/details/83413772
https://blog.csdn.net/CrystalShaw/article/details/80372015
https://blog.csdn.net/qq_37051858/article/details/111353756
丟包檢測算法:https://blog.csdn.net/tanningzhong/article/details/87278810