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:
parent
3dc886561c
commit
20f4440c73
@ -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)
|
||||||
*/
|
*/
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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() {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user