Clean up TMMBR handling.

Review URL: https://webrtc-codereview.appspot.com/465001

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1961 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pwestin@webrtc.org 2012-03-30 11:40:15 +00:00
parent 3dc886561c
commit 20f4440c73
9 changed files with 180 additions and 366 deletions

View File

@ -807,14 +807,6 @@ public:
*/ */
virtual WebRtc_Word32 SetTMMBRStatus(const bool enable) = 0; virtual WebRtc_Word32 SetTMMBRStatus(const bool enable) = 0;
/*
* local bw estimation changed
*
* for video called by internal estimator
* for audio (iSAC) called by engine, geting the data from the decoder
*/
virtual void OnBandwidthEstimateUpdate(WebRtc_UWord16 bandWidthKbit) = 0;
/* /*
* (NACK) * (NACK)
*/ */

View File

@ -27,28 +27,28 @@ namespace webrtc {
using namespace RTCPUtility; using namespace RTCPUtility;
using namespace RTCPHelp; using namespace RTCPHelp;
RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock,
RtpRtcpClock* clock, ModuleRtpRtcpImpl* owner)
ModuleRtpRtcpImpl* owner) : : TMMBRHelp(),
_id(id), _id(id),
_clock(*clock), _clock(*clock),
_method(kRtcpOff), _method(kRtcpOff),
_lastReceived(0), _lastReceived(0),
_rtpRtcp(*owner), _rtpRtcp(*owner),
_criticalSectionFeedbacks(CriticalSectionWrapper::CreateCriticalSection()), _criticalSectionFeedbacks(
_cbRtcpFeedback(NULL), CriticalSectionWrapper::CreateCriticalSection()),
_cbVideoFeedback(NULL), _cbRtcpFeedback(NULL),
_criticalSectionRTCPReceiver( _cbVideoFeedback(NULL),
CriticalSectionWrapper::CreateCriticalSection()), _criticalSectionRTCPReceiver(
_SSRC(0), CriticalSectionWrapper::CreateCriticalSection()),
_remoteSSRC(0), _SSRC(0),
_remoteSenderInfo(), _remoteSSRC(0),
_lastReceivedSRNTPsecs(0), _remoteSenderInfo(),
_lastReceivedSRNTPfrac(0), _lastReceivedSRNTPsecs(0),
_receivedInfoMap(), _lastReceivedSRNTPfrac(0),
_packetTimeOutMS(0), _receivedInfoMap(),
_rtt(0) _packetTimeOutMS(0),
{ _rtt(0) {
memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo)); memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__); WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
} }
@ -1224,15 +1224,63 @@ RTCPReceiver::OnReceivedSliceLossIndication(const WebRtc_UWord8 pitureID) const
} }
} }
void void RTCPReceiver::OnReceivedReferencePictureSelectionIndication(
RTCPReceiver::OnReceivedReferencePictureSelectionIndication(const WebRtc_UWord64 pitureID) const const WebRtc_UWord64 pitureID) const {
{ CriticalSectionScoped lock(_criticalSectionFeedbacks);
CriticalSectionScoped lock(_criticalSectionFeedbacks);
if(_cbRtcpFeedback) if (_cbRtcpFeedback) {
{ _cbRtcpFeedback->OnRPSIReceived(_id, pitureID);
_cbRtcpFeedback->OnRPSIReceived(_id, pitureID); }
} }
WebRtc_Word32 RTCPReceiver::UpdateTMMBR() {
WebRtc_Word32 numBoundingSet = 0;
WebRtc_Word32 newBitrates = 0;
WebRtc_UWord32 minBitrateKbit = 0;
WebRtc_UWord32 maxBitrateKbit = 0;
WebRtc_UWord32 accNumCandidates = 0;
WebRtc_Word32 size = TMMBRReceived(0, 0, NULL);
if (size > 0) {
TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
// get candidate set from receiver
accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
} else {
// candidate set empty
VerifyAndAllocateCandidateSet(0); // resets candidate set
}
// Find bounding set
TMMBRSet* boundingSet = NULL;
numBoundingSet = FindTMMBRBoundingSet(boundingSet);
if (numBoundingSet == -1) {
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
"Failed to find TMMBR bounding set.");
return -1;
}
// Set bounding set
// Inform remote clients about the new bandwidth
// inform the remote client
_rtpRtcp.SetTMMBN(boundingSet);
// might trigger a TMMBN
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 = CalcMinBitRate(static_cast<WebRtc_UWord32>(numBoundingSet),
&minBitrateKbit);
// no critsect when calling out to "unknown" code
if (newBitrates == 0) {
// we have a new bandwidth estimate on this channel
_rtpRtcp.OnReceivedBandwidthEstimateUpdate((WebRtc_UWord16)minBitrateKbit);
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
"Set TMMBR request min:%d kbps max:%d kbps, channel: %d",
minBitrateKbit, maxBitrateKbit, _id);
}
return 0;
} }
// Holding no Critical section // Holding no Critical section
@ -1247,7 +1295,7 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
"SIG [RTCP] Incoming TMMBR to id:%d", _id); "SIG [RTCP] Incoming TMMBR to id:%d", _id);
// Might trigger a OnReceivedBandwidthEstimateUpdate. // Might trigger a OnReceivedBandwidthEstimateUpdate.
_rtpRtcp.OnReceivedTMMBR(); UpdateTMMBR();
} }
if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb)
{ {
@ -1387,18 +1435,6 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
} }
} }
void
RTCPReceiver::UpdateBandwidthEstimate(const WebRtc_UWord16 bwEstimateKbit)
{
CriticalSectionScoped lock(_criticalSectionFeedbacks);
if(_cbRtcpFeedback)
{
_cbRtcpFeedback->OnTMMBRReceived(_id, bwEstimateKbit);
}
}
WebRtc_Word32 RTCPReceiver::CNAME(const WebRtc_UWord32 remoteSSRC, WebRtc_Word32 RTCPReceiver::CNAME(const WebRtc_UWord32 remoteSSRC,
char cName[RTCP_CNAME_SIZE]) const { char cName[RTCP_CNAME_SIZE]) const {
if (cName == NULL) { if (cName == NULL) {

View File

@ -19,11 +19,12 @@
#include "rtcp_utility.h" #include "rtcp_utility.h"
#include "rtp_rtcp_defines.h" #include "rtp_rtcp_defines.h"
#include "rtcp_receiver_help.h" #include "rtcp_receiver_help.h"
#include "tmmbr_help.h"
namespace webrtc { namespace webrtc {
class ModuleRtpRtcpImpl; class ModuleRtpRtcpImpl;
class RTCPReceiver class RTCPReceiver : public TMMBRHelp
{ {
public: public:
RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock, RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock,
@ -97,10 +98,9 @@ public:
bool UpdateRTCPReceiveInformationTimers(); bool UpdateRTCPReceiveInformationTimers();
void UpdateBandwidthEstimate(const WebRtc_UWord16 bwEstimateKbit); WebRtc_Word32 BoundingSet(bool &tmmbrOwner, TMMBRSet*& boundingSetRec);
WebRtc_Word32 BoundingSet(bool &tmmbrOwner, WebRtc_Word32 UpdateTMMBR();
TMMBRSet*& boundingSetRec);
WebRtc_Word32 SetPacketTimeout(const WebRtc_UWord32 timeoutMS); WebRtc_Word32 SetPacketTimeout(const WebRtc_UWord32 timeoutMS);
void PacketTimeout(); void PacketTimeout();

View File

@ -68,7 +68,7 @@ RTCPSender::RTCPSender(const WebRtc_Word32 id,
_rembBitrate(0), _rembBitrate(0),
_bitrate_observer(NULL), _bitrate_observer(NULL),
_tmmbrHelp(audio), _tmmbrHelp(),
_tmmbr_Send(0), _tmmbr_Send(0),
_packetOH_Send(0), _packetOH_Send(0),
_remoteRateControl(), _remoteRateControl(),
@ -2165,20 +2165,6 @@ RTCPSender::SetTMMBN(const TMMBRSet* boundingSet,
return -1; return -1;
} }
WebRtc_Word32
RTCPSender::RequestTMMBR(WebRtc_UWord32 estimatedBW, WebRtc_UWord32 packetOH)
{
CriticalSectionScoped lock(_criticalSectionRTCPSender);
if(_TMMBR)
{
_tmmbr_Send = estimatedBW;
_packetOH_Send = packetOH;
return 0;
}
return -1;
}
RateControlRegion RateControlRegion
RTCPSender::UpdateOverUseState(const RateControlInput& rateControlInput, bool& firstOverUse) RTCPSender::UpdateOverUseState(const RateControlInput& rateControlInput, bool& firstOverUse)
{ {

View File

@ -103,9 +103,6 @@ public:
WebRtc_Word32 SetTMMBN(const TMMBRSet* boundingSet, WebRtc_Word32 SetTMMBN(const TMMBRSet* boundingSet,
const WebRtc_UWord32 maxBitrateKbit); const WebRtc_UWord32 maxBitrateKbit);
WebRtc_Word32 RequestTMMBR(const WebRtc_UWord32 estimatedBW,
const WebRtc_UWord32 packetOH);
/* /*
* Extended jitter report * Extended jitter report
*/ */

View File

@ -82,7 +82,6 @@ void RtpRtcp::DestroyRtpRtcp(RtpRtcp* module) {
ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const WebRtc_Word32 id, ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const WebRtc_Word32 id,
const bool audio, const bool audio,
RtpRtcpClock* clock): RtpRtcpClock* clock):
TMMBRHelp(audio),
_rtpSender(id, audio, clock), _rtpSender(id, audio, clock),
_rtpReceiver(id, audio, clock, this), _rtpReceiver(id, audio, clock, this),
_rtcpSender(id, audio, clock, this), _rtcpSender(id, audio, clock, this),
@ -266,7 +265,7 @@ void ModuleRtpRtcpImpl::RegisterChildModule(RtpRtcp* module) {
CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback); CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback);
// we use two locks for protecting _childModules one // we use two locks for protecting _childModules one
// (_criticalSectionModulePtrsFeedback) for incoming // (_criticalSectionModulePtrsFeedback) for incoming
// messages (BitrateSent and UpdateTMMBR) and _criticalSectionModulePtrs // messages (BitrateSent) and _criticalSectionModulePtrs
// for all outgoing messages sending packets etc // for all outgoing messages sending packets etc
_childModules.push_back((ModuleRtpRtcpImpl*)module); _childModules.push_back((ModuleRtpRtcpImpl*)module);
} }
@ -415,19 +414,21 @@ WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
// default module or no RTCP received yet. // default module or no RTCP received yet.
max_rtt = kDefaultRtt; max_rtt = kDefaultRtt;
} }
if (REMB() && _rtcpSender.ValidBitrateEstimate()) { if (_rtcpSender.ValidBitrateEstimate()) {
unsigned int target_bitrate = if (REMB()) {
uint32_t target_bitrate =
_rtcpSender.CalculateNewTargetBitrate(max_rtt);
_rtcpSender.UpdateRemoteBitrateEstimate(target_bitrate);
} else if (TMMBR()) {
_rtcpSender.CalculateNewTargetBitrate(max_rtt); _rtcpSender.CalculateNewTargetBitrate(max_rtt);
_rtcpSender.UpdateRemoteBitrateEstimate(target_bitrate); }
} else if (TMMBR()) {
_rtcpSender.CalculateNewTargetBitrate(max_rtt);
} }
_rtcpSender.SendRTCP(kRtcpReport); _rtcpSender.SendRTCP(kRtcpReport);
} }
if (UpdateRTCPReceiveInformationTimers()) { if (UpdateRTCPReceiveInformationTimers()) {
// a receiver has timed out // a receiver has timed out
UpdateTMMBR(); _rtcpReceiver.UpdateTMMBR();
} }
return 0; return 0;
} }
@ -1670,29 +1671,13 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBRStatus(const bool enable) {
return _rtcpSender.SetTMMBRStatus(enable); return _rtcpSender.SetTMMBRStatus(enable);
} }
WebRtc_Word32 ModuleRtpRtcpImpl::TMMBRReceived( WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBN(const TMMBRSet* boundingSet) {
const WebRtc_UWord32 size,
const WebRtc_UWord32 accNumCandidates,
TMMBRSet* candidateSet) const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "TMMBRReceived()");
return _rtcpReceiver.TMMBRReceived(size, accNumCandidates, candidateSet);
}
WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBN(const TMMBRSet* boundingSet,
const WebRtc_UWord32 maxBitrateKbit) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetTMMBN()"); WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetTMMBN()");
WebRtc_UWord32 maxBitrateKbit = _rtpSender.MaxConfiguredBitrateVideo() / 1000;
return _rtcpSender.SetTMMBN(boundingSet, maxBitrateKbit); return _rtcpSender.SetTMMBN(boundingSet, maxBitrateKbit);
} }
WebRtc_Word32 ModuleRtpRtcpImpl::RequestTMMBR(const WebRtc_UWord32 estimatedBW,
const WebRtc_UWord32 packetOH) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RequestTMMBR()");
return _rtcpSender.RequestTMMBR(estimatedBW, packetOH);
}
/* /*
* (NACK) Negative acknowledgement * (NACK) Negative acknowledgement
*/ */
@ -2299,48 +2284,6 @@ void ModuleRtpRtcpImpl::OnReceivedNTP() {
} }
} }
// our local BW estimate is updated
void ModuleRtpRtcpImpl::OnBandwidthEstimateUpdate(
WebRtc_UWord16 bandWidthKbit) {
WebRtc_UWord32 maxBitrateKbit = _rtpReceiver.MaxConfiguredBitrate() / 1000;
if (maxBitrateKbit) {
// the app has set a max bitrate
if (maxBitrateKbit < bandWidthKbit) {
// cap TMMBR at max configured bitrate
bandWidthKbit = (WebRtc_UWord16)maxBitrateKbit;
}
}
if (_rtcpSender.TMMBR()) {
/* Maximum total media bit rate:
The upper limit on total media bit rate for a given media
stream at a particular receiver and for its selected protocol
layer. Note that this value cannot be measured on the
received media stream. Instead, it needs to be calculated or
determined through other means, such as quality of service
(QoS) negotiations or local resource limitations. Also note
that this value is an average (on a timescale that is
reasonable for the application) and that it may be different
from the instantaneous bit rate seen by packets in the media
stream.
*/
/* Overhead:
All protocol header information required to convey a packet
with media data from sender to receiver, from the application
layer down to a pre-defined protocol level (for example, down
to, and including, the IP header). Overhead may include, for
example, IP, UDP, and RTP headers, any layer 2 headers, any
Contributing Sources (CSRCs), RTP padding, and RTP header
extensions. Overhead excludes any RTP payload headers and the
payload itself.
*/
_rtpReceiver.PacketOHReceived();
// call RequestTMMBR when our localy created estimate changes
_rtcpSender.RequestTMMBR(bandWidthKbit, 0);
}
}
RateControlRegion ModuleRtpRtcpImpl::OnOverUseStateUpdate( RateControlRegion ModuleRtpRtcpImpl::OnOverUseStateUpdate(
const RateControlInput& rateControlInput) { const RateControlInput& rateControlInput) {
@ -2506,34 +2449,32 @@ void ModuleRtpRtcpImpl::OnReceivedReferencePictureSelectionIndication(
void ModuleRtpRtcpImpl::OnReceivedBandwidthEstimateUpdate( void ModuleRtpRtcpImpl::OnReceivedBandwidthEstimateUpdate(
const WebRtc_UWord16 bwEstimateKbit) { const WebRtc_UWord16 bwEstimateKbit) {
// We received a TMMBR // We received a TMMBR
if (_audio) {
return;
}
const bool defaultInstance(_childModules.empty() ? false : true); const bool defaultInstance(_childModules.empty() ? false : true);
if (defaultInstance) { if (defaultInstance) {
ProcessDefaultModuleBandwidth(); ProcessDefaultModuleBandwidth();
return; return;
} }
if (_audio) { WebRtc_UWord32 newBitrate = 0;
_rtcpReceiver.UpdateBandwidthEstimate(bwEstimateKbit); WebRtc_UWord8 fractionLost = 0;
} else { WebRtc_UWord16 roundTripTime = 0;
WebRtc_UWord32 newBitrate = 0; if (_bandwidthManagement.UpdateBandwidthEstimate(bwEstimateKbit,
WebRtc_UWord8 fractionLost = 0; &newBitrate,
WebRtc_UWord16 roundTripTime = 0; &fractionLost,
if (_bandwidthManagement.UpdateBandwidthEstimate(bwEstimateKbit, &roundTripTime) == 0) {
&newBitrate, if (!_defaultModule) {
&fractionLost, // No default module check if we should trigger OnNetworkChanged
&roundTripTime) == 0) { // via video callback
if (!_defaultModule) { _rtpReceiver.UpdateBandwidthManagement(newBitrate,
// No default module check if we should trigger OnNetworkChanged fractionLost,
// via video callback roundTripTime);
_rtpReceiver.UpdateBandwidthManagement(newBitrate, }
fractionLost, if (newBitrate > 0) {
roundTripTime); // update bitrate
} _rtpSender.SetTargetSendBitrate(newBitrate);
if (newBitrate > 0) {
// update bitrate
_rtpSender.SetTargetSendBitrate(newBitrate);
}
} }
} }
if (_defaultModule) { if (_defaultModule) {
@ -2768,88 +2709,16 @@ WebRtc_Word32 ModuleRtpRtcpImpl::LastReceivedNTP(
return 0; return 0;
} }
void ModuleRtpRtcpImpl::OnReceivedTMMBR() {
// we received a TMMBR in a RTCP packet
// answer with a TMMBN
UpdateTMMBR();
}
bool ModuleRtpRtcpImpl::UpdateRTCPReceiveInformationTimers() { bool ModuleRtpRtcpImpl::UpdateRTCPReceiveInformationTimers() {
// if this returns true this channel has timed out // if this returns true this channel has timed out
// periodically check if this is true and if so call UpdateTMMBR // periodically check if this is true and if so call UpdateTMMBR
return _rtcpReceiver.UpdateRTCPReceiveInformationTimers(); return _rtcpReceiver.UpdateRTCPReceiveInformationTimers();
} }
WebRtc_Word32 ModuleRtpRtcpImpl::UpdateTMMBR() {
WebRtc_Word32 numBoundingSet = 0;
WebRtc_Word32 newBitrates = 0;
WebRtc_UWord32 minBitrateKbit = 0;
WebRtc_UWord32 maxBitrateKbit = 0;
WebRtc_UWord32 accNumCandidates = 0;
if (!_childModules.empty()) {
// Default module should not handle this
return -1;
}
WebRtc_Word32 size = _rtcpReceiver.TMMBRReceived(0, 0, NULL);
if (size > 0) {
TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
// get candidate set from receiver
accNumCandidates = _rtcpReceiver.TMMBRReceived(size,
accNumCandidates,
candidateSet);
} else {
// candidate set empty
VerifyAndAllocateCandidateSet(0); // resets candidate set
}
// Find bounding set
TMMBRSet* boundingSet = NULL;
numBoundingSet = FindTMMBRBoundingSet(boundingSet);
if (numBoundingSet == -1) {
WEBRTC_TRACE(kTraceWarning,
kTraceRtpRtcp,
_id,
"Failed to find TMMBR bounding set.");
return -1;
}
// Set bounding set
// Inform remote clients about the new bandwidth
// inform the remote client
_rtcpSender.SetTMMBN(boundingSet,
_rtpSender.MaxConfiguredBitrateVideo() / 1000);
// might trigger a TMMBN
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,
minBitrateKbit,
maxBitrateKbit);
// no critsect when calling out to "unknown" code
if (newBitrates == 0) {
// we have new bitrate
// Set new max bitrate
// we have a new bandwidth estimate on this channel
OnReceivedBandwidthEstimateUpdate((WebRtc_UWord16)minBitrateKbit);
WEBRTC_TRACE(kTraceStream,
kTraceRtpRtcp,
_id,
"Set TMMBR request min:%d kbps max:%d kbps, channel: %d",
minBitrateKbit, maxBitrateKbit, _id);
}
return 0;
}
// called from RTCPsender // called from RTCPsender
WebRtc_Word32 ModuleRtpRtcpImpl::BoundingSet(bool& tmmbrOwner, WebRtc_Word32 ModuleRtpRtcpImpl::BoundingSet(bool& tmmbrOwner,
TMMBRSet*& boundingSet) { TMMBRSet*& boundingSet) {
return _rtcpReceiver.BoundingSet(tmmbrOwner, return _rtcpReceiver.BoundingSet(tmmbrOwner, boundingSet);
boundingSet);
} }
void ModuleRtpRtcpImpl::SendKeyFrame() { void ModuleRtpRtcpImpl::SendKeyFrame() {

View File

@ -26,7 +26,7 @@ class MatlabPlot;
namespace webrtc { namespace webrtc {
class ModuleRtpRtcpImpl : public RtpRtcp, private TMMBRHelp class ModuleRtpRtcpImpl : public RtpRtcp
{ {
public: public:
ModuleRtpRtcpImpl(const WebRtc_Word32 id, ModuleRtpRtcpImpl(const WebRtc_Word32 id,
@ -341,15 +341,7 @@ public:
virtual WebRtc_Word32 SetTMMBRStatus(const bool enable); virtual WebRtc_Word32 SetTMMBRStatus(const bool enable);
virtual WebRtc_Word32 TMMBRReceived(const WebRtc_UWord32 size, WebRtc_Word32 SetTMMBN(const TMMBRSet* boundingSet);
const WebRtc_UWord32 accNumCandidates,
TMMBRSet* candidateSet) const;
virtual WebRtc_Word32 SetTMMBN(const TMMBRSet* boundingSet,
const WebRtc_UWord32 maxBitrateKbit);
virtual WebRtc_Word32 RequestTMMBR(const WebRtc_UWord32 estimatedBW,
const WebRtc_UWord32 packetOH);
virtual WebRtc_UWord16 MaxPayloadLength() const; virtual WebRtc_UWord16 MaxPayloadLength() const;
@ -496,8 +488,6 @@ public:
// good state of RTP receiver inform sender // good state of RTP receiver inform sender
virtual WebRtc_Word32 SendRTCPReferencePictureSelection(const WebRtc_UWord64 pictureID); virtual WebRtc_Word32 SendRTCPReferencePictureSelection(const WebRtc_UWord64 pictureID);
virtual void OnBandwidthEstimateUpdate(WebRtc_UWord16 bandWidthKbit);
void OnReceivedNTP() ; void OnReceivedNTP() ;
// bw estimation // bw estimation
@ -547,8 +537,6 @@ protected:
// Get remote SequenceNumber // Get remote SequenceNumber
WebRtc_UWord16 RemoteSequenceNumber() const; WebRtc_UWord16 RemoteSequenceNumber() const;
WebRtc_Word32 UpdateTMMBR();
// only for internal testing // only for internal testing
WebRtc_UWord32 LastSendReport(WebRtc_UWord32& lastRTCPTime); WebRtc_UWord32 LastSendReport(WebRtc_UWord32& lastRTCPTime);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source * that can be found in the LICENSE file in the root of the source
@ -61,24 +61,21 @@ TMMBRSet::VerifyAndAllocateSet(WebRtc_UWord32 minimumSize)
lengthOfSet = 0; lengthOfSet = 0;
} }
TMMBRHelp::TMMBRHelp(const bool audio) : TMMBRHelp::TMMBRHelp()
_criticalSection(CriticalSectionWrapper::CreateCriticalSection()), : _criticalSection(CriticalSectionWrapper::CreateCriticalSection()),
_audio(audio), _candidateSet(),
_candidateSet(), _boundingSet(),
_boundingSet(), _boundingSetToSend(),
_boundingSetToSend(), _ptrIntersectionBoundingSet(NULL),
_ptrIntersectionBoundingSet(NULL), _ptrMaxPRBoundingSet(NULL) {
_ptrMaxPRBoundingSet(NULL)
{
} }
TMMBRHelp::~TMMBRHelp() TMMBRHelp::~TMMBRHelp() {
{ delete [] _ptrIntersectionBoundingSet;
delete [] _ptrIntersectionBoundingSet; delete [] _ptrMaxPRBoundingSet;
delete [] _ptrMaxPRBoundingSet; _ptrIntersectionBoundingSet = 0;
_ptrIntersectionBoundingSet = 0; _ptrMaxPRBoundingSet = 0;
_ptrMaxPRBoundingSet = 0; delete _criticalSection;
delete _criticalSection;
} }
TMMBRSet* TMMBRSet*
@ -101,10 +98,8 @@ TMMBRHelp::VerifyAndAllocateBoundingSet(WebRtc_UWord32 minimumSize)
return &_boundingSet; return &_boundingSet;
} }
TMMBRSet* TMMBRSet* TMMBRHelp::BoundingSet() {
TMMBRHelp::BoundingSet() return &_boundingSet;
{
return &_boundingSet;
} }
WebRtc_Word32 WebRtc_Word32
@ -413,95 +408,49 @@ TMMBRHelp::FindTMMBRBoundingSet(WebRtc_Word32 numCandidates, TMMBRSet& candidate
return numBoundingSet; return numBoundingSet;
} }
bool bool TMMBRHelp::IsOwner(const WebRtc_UWord32 ssrc,
TMMBRHelp::IsOwner(const WebRtc_UWord32 ssrc, const WebRtc_UWord32 length) const {
const WebRtc_UWord32 length) const CriticalSectionScoped lock(_criticalSection);
{
CriticalSectionScoped lock(_criticalSection);
if (length == 0) if (length == 0) {
{ // empty bounding set
// empty bounding set
return false;
}
for(WebRtc_UWord32 i = 0; (i < length) && (i < _boundingSet.sizeOfSet); ++i)
{
if(_boundingSet.ptrSsrcSet[i] == ssrc)
{
return true;
}
}
return false; return false;
}
for(WebRtc_UWord32 i = 0; (i < length) && (i < _boundingSet.sizeOfSet); ++i) {
if(_boundingSet.ptrSsrcSet[i] == ssrc) {
return true;
}
}
return false;
} }
WebRtc_Word32 WebRtc_Word32 TMMBRHelp::CalcMinBitRate(
TMMBRHelp::CalcMinMaxBitRate(const WebRtc_UWord32 totalPacketRate, const WebRtc_UWord32 lengthOfBoundingSet,
const WebRtc_UWord32 lengthOfBoundingSet, WebRtc_UWord32* minBitrateKbit) const {
WebRtc_UWord32& minBitrateKbit, CriticalSectionScoped lock(_criticalSection);
WebRtc_UWord32& maxBitrateKbit) const
{
CriticalSectionScoped lock(_criticalSection);
if (lengthOfBoundingSet <= 0 || _candidateSet.sizeOfSet == 0) if (lengthOfBoundingSet <= 0 || _candidateSet.sizeOfSet == 0) {
{ // empty bounding set
// empty bounding set return -1;
return -1; }
*minBitrateKbit = 0xFFFFFFFF;
for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet; ++i) {
if (_candidateSet.ptrTmmbrSet[i]) {
WebRtc_Word32 curNetBitRate =
static_cast<WebRtc_Word32>(_candidateSet.ptrTmmbrSet[i] * 1000.0);
if (curNetBitRate < 0) {
// could be negative for a large packet rate
curNetBitRate = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
}
*minBitrateKbit = (WebRtc_UWord32(curNetBitRate) < *minBitrateKbit) ?
curNetBitRate : *minBitrateKbit;
} }
}
minBitrateKbit = 0xFFFFFFFF; if (*minBitrateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE) {
maxBitrateKbit = 0; *minBitrateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
}
for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet; ++i) return 0;
{
if (_candidateSet.ptrTmmbrSet[i])
{
WebRtc_Word32 curNetBitRate = static_cast<WebRtc_Word32>((_candidateSet.ptrTmmbrSet[i]*1000.0
- (totalPacketRate * (_candidateSet.ptrPacketOHSet[i] << 3)))/1000 + 0.5);
if (curNetBitRate < 0)
{
// could be negative for a large packet rate
if(_audio)
{
curNetBitRate = MIN_AUDIO_BW_MANAGEMENT_BITRATE;
}else
{
curNetBitRate = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
}
}
minBitrateKbit = (WebRtc_UWord32(curNetBitRate) < minBitrateKbit) ? curNetBitRate : minBitrateKbit;
}
}
maxBitrateKbit = minBitrateKbit;
if (maxBitrateKbit == 0 || maxBitrateKbit < minBitrateKbit)
{
return -1;
}
if(_audio)
{
if (minBitrateKbit < MIN_AUDIO_BW_MANAGEMENT_BITRATE)
{
minBitrateKbit = MIN_AUDIO_BW_MANAGEMENT_BITRATE;
}
if (maxBitrateKbit < MIN_AUDIO_BW_MANAGEMENT_BITRATE)
{
maxBitrateKbit = MIN_AUDIO_BW_MANAGEMENT_BITRATE;
}
}else
{
if (minBitrateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE)
{
minBitrateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
}
if (maxBitrateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE)
{
maxBitrateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
}
}
return 0;
} }
} // namespace webrtc } // namespace webrtc

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source * that can be found in the LICENSE file in the root of the source
@ -38,7 +38,7 @@ public:
class TMMBRHelp class TMMBRHelp
{ {
public: public:
TMMBRHelp(const bool audio); TMMBRHelp();
virtual ~TMMBRHelp(); virtual ~TMMBRHelp();
TMMBRSet* BoundingSet(); // used for debuging TMMBRSet* BoundingSet(); // used for debuging
@ -47,16 +47,14 @@ public:
TMMBRSet* VerifyAndAllocateCandidateSet(const WebRtc_UWord32 minimumSize); TMMBRSet* VerifyAndAllocateCandidateSet(const WebRtc_UWord32 minimumSize);
WebRtc_Word32 FindTMMBRBoundingSet(TMMBRSet*& boundingSet); WebRtc_Word32 FindTMMBRBoundingSet(TMMBRSet*& boundingSet);
WebRtc_Word32 SetTMMBRBoundingSetToSend(const TMMBRSet* boundingSetToSend, WebRtc_Word32 SetTMMBRBoundingSetToSend(
const WebRtc_UWord32 maxBitrateKbit); const TMMBRSet* boundingSetToSend,
const WebRtc_UWord32 maxBitrateKbit);
bool IsOwner(const WebRtc_UWord32 ssrc, bool IsOwner(const WebRtc_UWord32 ssrc, const WebRtc_UWord32 length) const;
const WebRtc_UWord32 length) const;
WebRtc_Word32 CalcMinMaxBitRate(const WebRtc_UWord32 totalPacketRate, WebRtc_Word32 CalcMinBitRate(const WebRtc_UWord32 lengthOfBoundingSet,
const WebRtc_UWord32 lengthOfBoundingSet, WebRtc_UWord32* minBitrateKbit) const;
WebRtc_UWord32& minBitrateKbit,
WebRtc_UWord32& maxBitrateKbit) const;
protected: protected:
TMMBRSet* VerifyAndAllocateBoundingSet(WebRtc_UWord32 minimumSize); TMMBRSet* VerifyAndAllocateBoundingSet(WebRtc_UWord32 minimumSize);
@ -66,7 +64,6 @@ protected:
private: private:
CriticalSectionWrapper* _criticalSection; CriticalSectionWrapper* _criticalSection;
const bool _audio;
TMMBRSet _candidateSet; TMMBRSet _candidateSet;
TMMBRSet _boundingSet; TMMBRSet _boundingSet;
TMMBRSet _boundingSetToSend; TMMBRSet _boundingSetToSend;