Calculate the available bandwidth before sending a TMMBR
Also changed the way TMMBR was processed since it did not match the new bandwidth estimator. Review URL: http://webrtc-codereview.appspot.com/270003 Patch from pwestin1 <pwestin@webrtc.org>. git-svn-id: http://webrtc.googlecode.com/svn/trunk@925 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -442,6 +442,10 @@ WebRtc_Word32 ModuleRtpRtcpImpl::Process()
|
||||
{
|
||||
WebRtc_UWord16 RTT = 0;
|
||||
_rtcpReceiver.RTT(_rtpReceiver.SSRC(), &RTT, NULL, NULL, NULL);
|
||||
if (TMMBR())
|
||||
{
|
||||
_rtcpSender.CalculateNewTargetBitrate(RTT);
|
||||
}
|
||||
_rtcpSender.SendRTCP(kRtcpReport, 0, 0, RTT);
|
||||
}
|
||||
if(_rtpSender.RTPKeepalive())
|
||||
@ -2489,7 +2493,7 @@ RateControlRegion ModuleRtpRtcpImpl::OnOverUseStateUpdate(
|
||||
bool firstOverUse = false;
|
||||
RateControlRegion region = _rtcpSender.UpdateOverUseState(rateControlInput,
|
||||
firstOverUse);
|
||||
if (firstOverUse && _rtcpSender.Status() == kRtcpNonCompound) {
|
||||
if (firstOverUse) {
|
||||
// Send TMMBR immediately
|
||||
WebRtc_UWord16 RTT = 0;
|
||||
_rtcpReceiver.RTT(_rtpReceiver.SSRC(), &RTT, NULL, NULL, NULL);
|
||||
@ -2625,15 +2629,13 @@ void ModuleRtpRtcpImpl::OnReceivedReferencePictureSelectionIndication(
|
||||
|
||||
void ModuleRtpRtcpImpl::OnReceivedBandwidthEstimateUpdate(
|
||||
const WebRtc_UWord16 bwEstimateKbit) {
|
||||
|
||||
// We received a TMMBR
|
||||
if (_defaultModule) {
|
||||
CriticalSectionScoped lock(_criticalSectionModulePtrs);
|
||||
if (_defaultModule) {
|
||||
// if we use a default module pass this info to the default module
|
||||
_defaultModule->OnReceivedBandwidthEstimateUpdate(bwEstimateKbit);
|
||||
const bool defaultInstance(_childModules.empty() ? false : true);
|
||||
if (defaultInstance) {
|
||||
ProcessDefaultModuleBandwidth();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_audio) {
|
||||
_rtcpReceiver.UpdateBandwidthEstimate(bwEstimateKbit);
|
||||
} else {
|
||||
@ -2644,17 +2646,27 @@ void ModuleRtpRtcpImpl::OnReceivedBandwidthEstimateUpdate(
|
||||
&newBitrate,
|
||||
&fractionLost,
|
||||
&roundTripTime) == 0) {
|
||||
// video callback
|
||||
if (!_defaultModule) {
|
||||
// No default module check if we should trigger OnNetworkChanged
|
||||
// via video callback
|
||||
_rtpReceiver.UpdateBandwidthManagement(newBitrate,
|
||||
fractionLost,
|
||||
roundTripTime);
|
||||
const bool defaultInstance = !_childModules.empty();
|
||||
if ((newBitrate > 0) && !defaultInstance) {
|
||||
}
|
||||
if (newBitrate > 0) {
|
||||
// update bitrate
|
||||
_rtpSender.SetTargetSendBitrate(newBitrate);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_defaultModule) {
|
||||
CriticalSectionScoped lock(_criticalSectionModulePtrs);
|
||||
if (_defaultModule) {
|
||||
// if we use a default module pass this info to the default module
|
||||
_defaultModule->OnReceivedBandwidthEstimateUpdate(bwEstimateKbit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bw estimation
|
||||
@ -2708,39 +2720,7 @@ void ModuleRtpRtcpImpl::OnPacketLossStatisticsUpdate(
|
||||
roundTripTime);
|
||||
} else {
|
||||
if (!_simulcast) {
|
||||
WebRtc_UWord32 minBitrateBps = 0xffffffff;
|
||||
WebRtc_UWord32 maxBitrateBps = 0;
|
||||
{
|
||||
// get min and max for the sending channels
|
||||
CriticalSectionScoped lock(_criticalSectionModulePtrs);
|
||||
|
||||
std::list<ModuleRtpRtcpImpl*>::iterator it =
|
||||
_childModules.begin();
|
||||
while (it != _childModules.end()) {
|
||||
// Get child RTP sender and ask for bitrate estimate
|
||||
ModuleRtpRtcpImpl* childModule = *it;
|
||||
if (childModule->Sending()) {
|
||||
RTPSender& childRtpSender = (*it)->_rtpSender;
|
||||
const WebRtc_UWord32 childEstimateBps =
|
||||
1000 * childRtpSender.TargetSendBitrateKbit();
|
||||
if (childEstimateBps < minBitrateBps) {
|
||||
minBitrateBps = childEstimateBps;
|
||||
}
|
||||
if (childEstimateBps > maxBitrateBps) {
|
||||
maxBitrateBps = childEstimateBps;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
} // end critsect
|
||||
_bandwidthManagement.SetSendBitrate(minBitrateBps, 0, 0);
|
||||
// Update default module bitrate. Don't care about min max.
|
||||
// Check if we should trigger OnNetworkChanged via video callback
|
||||
// TODO(pwestin) for this to work better fractionLost shoudl be the
|
||||
// weighted average loss from all childs
|
||||
_rtpReceiver.UpdateBandwidthManagement(minBitrateBps,
|
||||
fractionLost,
|
||||
roundTripTime);
|
||||
ProcessDefaultModuleBandwidth();
|
||||
} else {
|
||||
// default and simulcast
|
||||
WebRtc_UWord32 newBitrate = 0;
|
||||
@ -2799,6 +2779,63 @@ void ModuleRtpRtcpImpl::OnPacketLossStatisticsUpdate(
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleRtpRtcpImpl::ProcessDefaultModuleBandwidth() {
|
||||
WebRtc_UWord32 minBitrateBps = 0xffffffff;
|
||||
WebRtc_UWord32 maxBitrateBps = 0;
|
||||
WebRtc_UWord32 count = 0;
|
||||
WebRtc_UWord32 fractionLostAcc = 0;
|
||||
WebRtc_UWord16 maxRoundTripTime = 0;
|
||||
{
|
||||
// get min and max for the sending channels
|
||||
CriticalSectionScoped lock(_criticalSectionModulePtrs);
|
||||
|
||||
std::list<ModuleRtpRtcpImpl*>::iterator it =
|
||||
_childModules.begin();
|
||||
while (it != _childModules.end()) {
|
||||
// Get child RTP sender and ask for bitrate estimate
|
||||
ModuleRtpRtcpImpl* childModule = *it;
|
||||
if (childModule->Sending()) {
|
||||
count++;
|
||||
RTPSender& childRtpSender = (*it)->_rtpSender;
|
||||
const WebRtc_UWord32 childEstimateBps =
|
||||
1000 * childRtpSender.TargetSendBitrateKbit();
|
||||
if (childEstimateBps < minBitrateBps) {
|
||||
minBitrateBps = childEstimateBps;
|
||||
}
|
||||
if (childEstimateBps > maxBitrateBps) {
|
||||
maxBitrateBps = childEstimateBps;
|
||||
}
|
||||
WebRtc_UWord16 RTT = 0;
|
||||
WebRtc_UWord8 fractionLost = 0;
|
||||
RTPReceiver& childRtpReceiver = (*it)->_rtpReceiver;
|
||||
RTCPReceiver& childRtcpReceiver = (*it)->_rtcpReceiver;
|
||||
childRtpReceiver.Statistics(&fractionLost,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
false);
|
||||
fractionLostAcc += fractionLost;
|
||||
childRtcpReceiver.RTT(childRtpReceiver.SSRC(),
|
||||
&RTT,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
maxRoundTripTime =
|
||||
(RTT > maxRoundTripTime) ? RTT : maxRoundTripTime;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
} // end critsect
|
||||
_bandwidthManagement.SetSendBitrate(minBitrateBps, 0, 0);
|
||||
// Update default module bitrate. Don't care about min max.
|
||||
// Check if we should trigger OnNetworkChanged via video callback
|
||||
WebRtc_UWord8 fractionLostAvg = WebRtc_UWord8(fractionLostAcc / count);
|
||||
_rtpReceiver.UpdateBandwidthManagement(minBitrateBps,
|
||||
fractionLostAvg ,
|
||||
maxRoundTripTime);
|
||||
}
|
||||
|
||||
void ModuleRtpRtcpImpl::OnRequestSendReport() {
|
||||
_rtcpSender.SendRTCP(kRtcpSr);
|
||||
}
|
||||
@ -2864,56 +2901,13 @@ WebRtc_Word32 ModuleRtpRtcpImpl::UpdateTMMBR() {
|
||||
WebRtc_Word32 newBitrates = 0;
|
||||
WebRtc_UWord32 minBitrateKbit = 0;
|
||||
WebRtc_UWord32 maxBitrateKbit = 0;
|
||||
|
||||
if (_defaultModule) {
|
||||
CriticalSectionScoped lock(_criticalSectionModulePtrs);
|
||||
|
||||
// no callbacks allowed inside here
|
||||
if (_defaultModule) {
|
||||
// let the default module do the update
|
||||
return _defaultModule->UpdateTMMBR();
|
||||
}
|
||||
}
|
||||
|
||||
WebRtc_UWord32 accNumCandidates = 0;
|
||||
|
||||
// Find candidate set
|
||||
if (!_childModules.empty()) {
|
||||
CriticalSectionScoped lock(_criticalSectionModulePtrsFeedback);
|
||||
|
||||
// this module is the default module
|
||||
// loop over all modules using the default codec
|
||||
WebRtc_UWord32 size = 0;
|
||||
std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
|
||||
while (it != _childModules.end()) {
|
||||
ModuleRtpRtcpImpl* module = *it;
|
||||
WebRtc_Word32 tmpSize = module->TMMBRReceived(0, 0, NULL);
|
||||
if (tmpSize > 0) {
|
||||
size += tmpSize;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
|
||||
if (candidateSet == NULL) {
|
||||
// Default module should not handle this
|
||||
return -1;
|
||||
}
|
||||
|
||||
it = _childModules.begin();
|
||||
while (it != _childModules.end()) {
|
||||
ModuleRtpRtcpImpl* module = *it;
|
||||
if (size > accNumCandidates && module) {
|
||||
WebRtc_Word32 accSize = module->TMMBRReceived(size,
|
||||
accNumCandidates,
|
||||
candidateSet);
|
||||
if (accSize > 0) {
|
||||
accNumCandidates = accSize;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
} else {
|
||||
// this module don't use the default module and is not the
|
||||
// default module
|
||||
WebRtc_Word32 size = _rtcpReceiver.TMMBRReceived(0, 0, NULL);
|
||||
if (size > 0) {
|
||||
TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
|
||||
@ -2925,7 +2919,6 @@ WebRtc_Word32 ModuleRtpRtcpImpl::UpdateTMMBR() {
|
||||
// candidate set empty
|
||||
VerifyAndAllocateCandidateSet(0); // resets candidate set
|
||||
}
|
||||
}
|
||||
// Find bounding set
|
||||
TMMBRSet* boundingSet = NULL;
|
||||
numBoundingSet = FindTMMBRBoundingSet(boundingSet);
|
||||
@ -2936,33 +2929,17 @@ WebRtc_Word32 ModuleRtpRtcpImpl::UpdateTMMBR() {
|
||||
"Failed to find TMMBR bounding set.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set bounding set
|
||||
// Inform remote clients about the new bandwidth
|
||||
if (_childModules.empty()) {
|
||||
// inform the remote client
|
||||
_rtcpSender.SetTMMBN(boundingSet,
|
||||
_rtpSender.MaxConfiguredBitrateVideo()/1000);
|
||||
// might trigger a TMMBN
|
||||
} else {
|
||||
// inform child modules using the default codec
|
||||
CriticalSectionScoped lock(_criticalSectionModulePtrsFeedback);
|
||||
std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
|
||||
while (it != _childModules.end()) {
|
||||
ModuleRtpRtcpImpl* module = *it;
|
||||
if (module) {
|
||||
module->SetTMMBN(boundingSet,
|
||||
_rtpSender.MaxConfiguredBitrateVideo()/1000);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
if (numBoundingSet == 0) {
|
||||
// owner of max bitrate request has timed out
|
||||
// empty bounding set has been sent
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get net bitrate from bounding set depending on sent packet rate
|
||||
newBitrates = CalcMinMaxBitRate(_rtpSender.PacketRate(),
|
||||
(WebRtc_UWord32)numBoundingSet,
|
||||
|
||||
@ -532,6 +532,7 @@ protected:
|
||||
RTCPReceiver _rtcpReceiver;
|
||||
private:
|
||||
void SendKeyFrame();
|
||||
void ProcessDefaultModuleBandwidth();
|
||||
|
||||
WebRtc_Word32 _id;
|
||||
const bool _audio;
|
||||
|
||||
Reference in New Issue
Block a user