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:
parent
70ed0a6f91
commit
cac787842c
@ -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)
|
||||
*/
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user