New attempt to cleanup TMMBR.

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1990 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pwestin@webrtc.org 2012-04-05 08:30:10 +00:00
parent 70ed0a6f91
commit cac787842c
12 changed files with 167 additions and 385 deletions

View File

@ -807,14 +807,6 @@ public:
*/
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)
*/

View File

@ -31,8 +31,6 @@ BandwidthManagement::BandwidthManagement(const WebRtc_Word32 id) :
_last_fraction_loss(0),
_last_round_trip_time(0),
_bwEstimateIncoming(0),
_smoothedFractionLostQ4(-1), // indicate uninitialized
_sFLFactorQ4(14), // 0.875 in Q4
_timeLastIncrease(0)
{
}
@ -269,20 +267,7 @@ WebRtc_UWord32 BandwidthManagement::ShapeSimple(WebRtc_Word32 packetLoss,
newBitRate += 1000;
}
// Calculate smoothed loss number
if (_smoothedFractionLostQ4 < 0)
{
// startup
_smoothedFractionLostQ4 = static_cast<WebRtc_UWord16>(packetLoss);
}
else
{
_smoothedFractionLostQ4 = ((_sFLFactorQ4 * _smoothedFractionLostQ4 + 8) >> 4) // Q4*Q4 = Q8; down to Q4 again with proper rounding
+ (16 - _sFLFactorQ4) * static_cast<WebRtc_UWord16>(packetLoss); // Q4 * Q0 = Q4
}
// Calculate what rate TFRC would apply in this situation
//WebRtc_Word32 tfrcRate = CalcTFRCbps(1000, rtt, _smoothedFractionLostQ4 >> 4); // scale loss to Q0 (back to [0, 255])
WebRtc_Word32 tfrcRate = CalcTFRCbps(1000, rtt, packetLoss); // scale loss to Q0 (back to [0, 255])
if (reducing &&
@ -290,7 +275,7 @@ WebRtc_UWord32 BandwidthManagement::ShapeSimple(WebRtc_Word32 packetLoss,
static_cast<WebRtc_UWord32>(tfrcRate) > newBitRate)
{
// do not reduce further if rate is below TFRC rate
newBitRate = _bitRate;
newBitRate = tfrcRate;
}
if (_bwEstimateIncoming > 0 && newBitRate > _bwEstimateIncoming)

View File

@ -85,8 +85,6 @@ private:
// bandwidth estimate
WebRtc_UWord32 _bwEstimateIncoming;
WebRtc_Word16 _smoothedFractionLostQ4;
WebRtc_Word16 _sFLFactorQ4; // forgetting factor for _smoothedFractionLostQ4
WebRtc_Word64 _timeLastIncrease;
};
} // namespace webrtc

View File

@ -27,28 +27,28 @@ namespace webrtc {
using namespace RTCPUtility;
using namespace RTCPHelp;
RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id,
RtpRtcpClock* clock,
ModuleRtpRtcpImpl* owner) :
_id(id),
_clock(*clock),
_method(kRtcpOff),
_lastReceived(0),
_rtpRtcp(*owner),
_criticalSectionFeedbacks(CriticalSectionWrapper::CreateCriticalSection()),
_cbRtcpFeedback(NULL),
_cbVideoFeedback(NULL),
_criticalSectionRTCPReceiver(
CriticalSectionWrapper::CreateCriticalSection()),
_SSRC(0),
_remoteSSRC(0),
_remoteSenderInfo(),
_lastReceivedSRNTPsecs(0),
_lastReceivedSRNTPfrac(0),
_receivedInfoMap(),
_packetTimeOutMS(0),
_rtt(0)
{
RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock,
ModuleRtpRtcpImpl* owner)
: TMMBRHelp(),
_id(id),
_clock(*clock),
_method(kRtcpOff),
_lastReceived(0),
_rtpRtcp(*owner),
_criticalSectionFeedbacks(
CriticalSectionWrapper::CreateCriticalSection()),
_cbRtcpFeedback(NULL),
_cbVideoFeedback(NULL),
_criticalSectionRTCPReceiver(
CriticalSectionWrapper::CreateCriticalSection()),
_SSRC(0),
_remoteSSRC(0),
_remoteSenderInfo(),
_lastReceivedSRNTPsecs(0),
_lastReceivedSRNTPfrac(0),
_receivedInfoMap(),
_packetTimeOutMS(0),
_rtt(0) {
memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
}
@ -1224,15 +1224,58 @@ RTCPReceiver::OnReceivedSliceLossIndication(const WebRtc_UWord8 pitureID) const
}
}
void
RTCPReceiver::OnReceivedReferencePictureSelectionIndication(const WebRtc_UWord64 pitureID) const
{
CriticalSectionScoped lock(_criticalSectionFeedbacks);
void RTCPReceiver::OnReceivedReferencePictureSelectionIndication(
const WebRtc_UWord64 pitureID) const {
CriticalSectionScoped lock(_criticalSectionFeedbacks);
if(_cbRtcpFeedback)
{
_cbRtcpFeedback->OnRPSIReceived(_id, pitureID);
}
if (_cbRtcpFeedback) {
_cbRtcpFeedback->OnRPSIReceived(_id, pitureID);
}
}
WebRtc_Word32 RTCPReceiver::UpdateTMMBR() {
WebRtc_Word32 numBoundingSet = 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
if (CalcMinBitRate(&minBitrateKbit)) {
// 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
@ -1247,7 +1290,7 @@ void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
"SIG [RTCP] Incoming TMMBR to id:%d", _id);
// Might trigger a OnReceivedBandwidthEstimateUpdate.
_rtpRtcp.OnReceivedTMMBR();
UpdateTMMBR();
}
if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb)
{
@ -1387,18 +1430,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,
char cName[RTCP_CNAME_SIZE]) const {
if (cName == NULL) {

View File

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

View File

@ -68,7 +68,7 @@ RTCPSender::RTCPSender(const WebRtc_Word32 id,
_rembBitrate(0),
_bitrate_observer(NULL),
_tmmbrHelp(audio),
_tmmbrHelp(),
_tmmbr_Send(0),
_packetOH_Send(0),
_remoteRateControl(),
@ -2165,20 +2165,6 @@ RTCPSender::SetTMMBN(const TMMBRSet* boundingSet,
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
RTCPSender::UpdateOverUseState(const RateControlInput& rateControlInput, bool& firstOverUse)
{

View File

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

View File

@ -82,7 +82,6 @@ void RtpRtcp::DestroyRtpRtcp(RtpRtcp* module) {
ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const WebRtc_Word32 id,
const bool audio,
RtpRtcpClock* clock):
TMMBRHelp(audio),
_rtpSender(id, audio, clock),
_rtpReceiver(id, audio, clock, this),
_rtcpSender(id, audio, clock, this),
@ -266,7 +265,7 @@ void ModuleRtpRtcpImpl::RegisterChildModule(RtpRtcp* module) {
CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback);
// we use two locks for protecting _childModules one
// (_criticalSectionModulePtrsFeedback) for incoming
// messages (BitrateSent and UpdateTMMBR) and _criticalSectionModulePtrs
// messages (BitrateSent) and _criticalSectionModulePtrs
// for all outgoing messages sending packets etc
_childModules.push_back((ModuleRtpRtcpImpl*)module);
}
@ -415,19 +414,21 @@ WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
// default module or no RTCP received yet.
max_rtt = kDefaultRtt;
}
if (REMB() && _rtcpSender.ValidBitrateEstimate()) {
unsigned int target_bitrate =
if (_rtcpSender.ValidBitrateEstimate()) {
if (REMB()) {
uint32_t target_bitrate =
_rtcpSender.CalculateNewTargetBitrate(max_rtt);
_rtcpSender.UpdateRemoteBitrateEstimate(target_bitrate);
} else if (TMMBR()) {
_rtcpSender.CalculateNewTargetBitrate(max_rtt);
_rtcpSender.UpdateRemoteBitrateEstimate(target_bitrate);
} else if (TMMBR()) {
_rtcpSender.CalculateNewTargetBitrate(max_rtt);
}
}
_rtcpSender.SendRTCP(kRtcpReport);
}
if (UpdateRTCPReceiveInformationTimers()) {
// a receiver has timed out
UpdateTMMBR();
_rtcpReceiver.UpdateTMMBR();
}
return 0;
}
@ -1670,29 +1671,13 @@ WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBRStatus(const bool enable) {
return _rtcpSender.SetTMMBRStatus(enable);
}
WebRtc_Word32 ModuleRtpRtcpImpl::TMMBRReceived(
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_Word32 ModuleRtpRtcpImpl::SetTMMBN(const TMMBRSet* boundingSet) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetTMMBN()");
WebRtc_UWord32 maxBitrateKbit = _rtpSender.MaxConfiguredBitrateVideo() / 1000;
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
*/
@ -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(
const RateControlInput& rateControlInput) {
@ -2506,34 +2449,32 @@ void ModuleRtpRtcpImpl::OnReceivedReferencePictureSelectionIndication(
void ModuleRtpRtcpImpl::OnReceivedBandwidthEstimateUpdate(
const WebRtc_UWord16 bwEstimateKbit) {
// We received a TMMBR
if (_audio) {
return;
}
const bool defaultInstance(_childModules.empty() ? false : true);
if (defaultInstance) {
ProcessDefaultModuleBandwidth();
return;
}
if (_audio) {
_rtcpReceiver.UpdateBandwidthEstimate(bwEstimateKbit);
} else {
WebRtc_UWord32 newBitrate = 0;
WebRtc_UWord8 fractionLost = 0;
WebRtc_UWord16 roundTripTime = 0;
if (_bandwidthManagement.UpdateBandwidthEstimate(bwEstimateKbit,
&newBitrate,
&fractionLost,
&roundTripTime) == 0) {
if (!_defaultModule) {
// No default module check if we should trigger OnNetworkChanged
// via video callback
_rtpReceiver.UpdateBandwidthManagement(newBitrate,
fractionLost,
roundTripTime);
}
if (newBitrate > 0) {
// update bitrate
_rtpSender.SetTargetSendBitrate(newBitrate);
}
WebRtc_UWord32 newBitrate = 0;
WebRtc_UWord8 fractionLost = 0;
WebRtc_UWord16 roundTripTime = 0;
if (_bandwidthManagement.UpdateBandwidthEstimate(bwEstimateKbit,
&newBitrate,
&fractionLost,
&roundTripTime) == 0) {
if (!_defaultModule) {
// No default module check if we should trigger OnNetworkChanged
// via video callback
_rtpReceiver.UpdateBandwidthManagement(newBitrate,
fractionLost,
roundTripTime);
}
if (newBitrate > 0) {
// update bitrate
_rtpSender.SetTargetSendBitrate(newBitrate);
}
}
if (_defaultModule) {
@ -2768,88 +2709,16 @@ WebRtc_Word32 ModuleRtpRtcpImpl::LastReceivedNTP(
return 0;
}
void ModuleRtpRtcpImpl::OnReceivedTMMBR() {
// we received a TMMBR in a RTCP packet
// answer with a TMMBN
UpdateTMMBR();
}
bool ModuleRtpRtcpImpl::UpdateRTCPReceiveInformationTimers() {
// if this returns true this channel has timed out
// periodically check if this is true and if so call UpdateTMMBR
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
WebRtc_Word32 ModuleRtpRtcpImpl::BoundingSet(bool& tmmbrOwner,
TMMBRSet*& boundingSet) {
return _rtcpReceiver.BoundingSet(tmmbrOwner,
boundingSet);
return _rtcpReceiver.BoundingSet(tmmbrOwner, boundingSet);
}
void ModuleRtpRtcpImpl::SendKeyFrame() {

View File

@ -26,7 +26,7 @@ class MatlabPlot;
namespace webrtc {
class ModuleRtpRtcpImpl : public RtpRtcp, private TMMBRHelp
class ModuleRtpRtcpImpl : public RtpRtcp
{
public:
ModuleRtpRtcpImpl(const WebRtc_Word32 id,
@ -341,15 +341,7 @@ public:
virtual WebRtc_Word32 SetTMMBRStatus(const bool enable);
virtual WebRtc_Word32 TMMBRReceived(const WebRtc_UWord32 size,
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);
WebRtc_Word32 SetTMMBN(const TMMBRSet* boundingSet);
virtual WebRtc_UWord16 MaxPayloadLength() const;
@ -496,8 +488,6 @@ public:
// good state of RTP receiver inform sender
virtual WebRtc_Word32 SendRTCPReferencePictureSelection(const WebRtc_UWord64 pictureID);
virtual void OnBandwidthEstimateUpdate(WebRtc_UWord16 bandWidthKbit);
void OnReceivedNTP() ;
// bw estimation
@ -547,8 +537,6 @@ protected:
// Get remote SequenceNumber
WebRtc_UWord16 RemoteSequenceNumber() const;
WebRtc_Word32 UpdateTMMBR();
// only for internal testing
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
* that can be found in the LICENSE file in the root of the source
@ -10,6 +10,7 @@
#include "tmmbr_help.h"
#include <limits>
#include "rtp_rtcp_config.h"
namespace webrtc {
@ -61,24 +62,21 @@ TMMBRSet::VerifyAndAllocateSet(WebRtc_UWord32 minimumSize)
lengthOfSet = 0;
}
TMMBRHelp::TMMBRHelp(const bool audio) :
_criticalSection(CriticalSectionWrapper::CreateCriticalSection()),
_audio(audio),
_candidateSet(),
_boundingSet(),
_boundingSetToSend(),
_ptrIntersectionBoundingSet(NULL),
_ptrMaxPRBoundingSet(NULL)
{
TMMBRHelp::TMMBRHelp()
: _criticalSection(CriticalSectionWrapper::CreateCriticalSection()),
_candidateSet(),
_boundingSet(),
_boundingSetToSend(),
_ptrIntersectionBoundingSet(NULL),
_ptrMaxPRBoundingSet(NULL) {
}
TMMBRHelp::~TMMBRHelp()
{
delete [] _ptrIntersectionBoundingSet;
delete [] _ptrMaxPRBoundingSet;
_ptrIntersectionBoundingSet = 0;
_ptrMaxPRBoundingSet = 0;
delete _criticalSection;
TMMBRHelp::~TMMBRHelp() {
delete [] _ptrIntersectionBoundingSet;
delete [] _ptrMaxPRBoundingSet;
_ptrIntersectionBoundingSet = 0;
_ptrMaxPRBoundingSet = 0;
delete _criticalSection;
}
TMMBRSet*
@ -101,10 +99,8 @@ TMMBRHelp::VerifyAndAllocateBoundingSet(WebRtc_UWord32 minimumSize)
return &_boundingSet;
}
TMMBRSet*
TMMBRHelp::BoundingSet()
{
return &_boundingSet;
TMMBRSet* TMMBRHelp::BoundingSet() {
return &_boundingSet;
}
WebRtc_Word32
@ -413,95 +409,39 @@ TMMBRHelp::FindTMMBRBoundingSet(WebRtc_Word32 numCandidates, TMMBRSet& candidate
return numBoundingSet;
}
bool
TMMBRHelp::IsOwner(const WebRtc_UWord32 ssrc,
const WebRtc_UWord32 length) const
{
CriticalSectionScoped lock(_criticalSection);
bool TMMBRHelp::IsOwner(const WebRtc_UWord32 ssrc,
const WebRtc_UWord32 length) const {
CriticalSectionScoped lock(_criticalSection);
if (length == 0)
{
// empty bounding set
return false;
}
for(WebRtc_UWord32 i = 0; (i < length) && (i < _boundingSet.sizeOfSet); ++i)
{
if(_boundingSet.ptrSsrcSet[i] == ssrc)
{
return true;
}
}
if (length == 0) {
// 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;
}
WebRtc_Word32
TMMBRHelp::CalcMinMaxBitRate(const WebRtc_UWord32 totalPacketRate,
const WebRtc_UWord32 lengthOfBoundingSet,
WebRtc_UWord32& minBitrateKbit,
WebRtc_UWord32& maxBitrateKbit) const
{
CriticalSectionScoped lock(_criticalSection);
bool TMMBRHelp::CalcMinBitRate( WebRtc_UWord32* minBitrateKbit) const {
CriticalSectionScoped lock(_criticalSection);
if (lengthOfBoundingSet <= 0 || _candidateSet.sizeOfSet == 0)
{
// empty bounding set
return -1;
if (_candidateSet.sizeOfSet == 0) {
// Empty bounding set.
return false;
}
*minBitrateKbit = std::numeric_limits<uint32_t>::max();
for (WebRtc_UWord32 i = 0; i < _candidateSet.sizeOfSet; ++i) {
WebRtc_UWord32 curNetBitRateKbit = _candidateSet.ptrTmmbrSet[i];
if (curNetBitRateKbit < MIN_VIDEO_BW_MANAGEMENT_BITRATE) {
curNetBitRateKbit = MIN_VIDEO_BW_MANAGEMENT_BITRATE;
}
minBitrateKbit = 0xFFFFFFFF;
maxBitrateKbit = 0;
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
- (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;
*minBitrateKbit = curNetBitRateKbit < *minBitrateKbit ?
curNetBitRateKbit : *minBitrateKbit;
}
return true;
}
} // 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
* that can be found in the LICENSE file in the root of the source
@ -38,7 +38,7 @@ public:
class TMMBRHelp
{
public:
TMMBRHelp(const bool audio);
TMMBRHelp();
virtual ~TMMBRHelp();
TMMBRSet* BoundingSet(); // used for debuging
@ -47,16 +47,13 @@ public:
TMMBRSet* VerifyAndAllocateCandidateSet(const WebRtc_UWord32 minimumSize);
WebRtc_Word32 FindTMMBRBoundingSet(TMMBRSet*& boundingSet);
WebRtc_Word32 SetTMMBRBoundingSetToSend(const TMMBRSet* boundingSetToSend,
const WebRtc_UWord32 maxBitrateKbit);
WebRtc_Word32 SetTMMBRBoundingSetToSend(
const TMMBRSet* boundingSetToSend,
const WebRtc_UWord32 maxBitrateKbit);
bool IsOwner(const WebRtc_UWord32 ssrc,
const WebRtc_UWord32 length) const;
bool IsOwner(const WebRtc_UWord32 ssrc, const WebRtc_UWord32 length) const;
WebRtc_Word32 CalcMinMaxBitRate(const WebRtc_UWord32 totalPacketRate,
const WebRtc_UWord32 lengthOfBoundingSet,
WebRtc_UWord32& minBitrateKbit,
WebRtc_UWord32& maxBitrateKbit) const;
bool CalcMinBitRate(WebRtc_UWord32* minBitrateKbit) const;
protected:
TMMBRSet* VerifyAndAllocateBoundingSet(WebRtc_UWord32 minimumSize);
@ -66,7 +63,6 @@ protected:
private:
CriticalSectionWrapper* _criticalSection;
const bool _audio;
TMMBRSet _candidateSet;
TMMBRSet _boundingSet;
TMMBRSet _boundingSetToSend;

View File

@ -194,7 +194,7 @@ TEST_F(ViEVideoVerificationTest, RunsFullStackWithoutErrors) {
// Set a low bit rate so the encoder budget will be tight, causing it to drop
// frames every now and then.
const int kBitRateKbps = 50;
const int kPacketLossPercent = 10;
const int kPacketLossPercent = 5;
const int kNetworkDelayMs = 100;
ViETest::Log("Bit rate : %5d kbps", kBitRateKbps);
ViETest::Log("Packet loss : %5d %%", kPacketLossPercent);