diff --git a/src/modules/rtp_rtcp/interface/rtp_rtcp.h b/src/modules/rtp_rtcp/interface/rtp_rtcp.h index 181706db2..3f4bf4210 100644 --- a/src/modules/rtp_rtcp/interface/rtp_rtcp.h +++ b/src/modules/rtp_rtcp/interface/rtp_rtcp.h @@ -749,6 +749,16 @@ public: */ virtual WebRtc_Word32 SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) = 0; + /* + * (REMB) Receiver Estimated Max Bitrate + */ + virtual bool REMB() const = 0;; + + virtual WebRtc_Word32 SetREMBStatus(const bool enable) = 0; + + virtual WebRtc_Word32 SetREMBData(const WebRtc_UWord32 bitrate, + const WebRtc_UWord8 numberOfSSRC, + const WebRtc_UWord32* SSRC) = 0; /* * (TMMBR) Temporary Max Media Bit Rate */ diff --git a/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h index 28178fca8..c2f4cb33c 100644 --- a/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h +++ b/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h @@ -55,12 +55,12 @@ enum RTCPPacketType kRtcpFir = 0x0040, kRtcpTmmbr = 0x0080, kRtcpTmmbn = 0x0100, - kRtcpSrReq = 0x0200, - kRtcpXrVoipMetric = 0x0400, + kRtcpSrReq = 0x0200, + kRtcpXrVoipMetric = 0x0400, kRtcpApp = 0x0800, - kRtcpAppBwe = 0x0801, kRtcpSli = 0x4000, - kRtcpRpsi = 0x8000 + kRtcpRpsi = 0x8000, + kRtcpRemb = 0x10000 }; enum KeyFrameRequestMethod @@ -104,9 +104,10 @@ struct RTCPReportBlock class RtpData { public: - virtual WebRtc_Word32 OnReceivedPayloadData(const WebRtc_UWord8* payloadData, - const WebRtc_UWord16 payloadSize, - const WebRtcRTPHeader* rtpHeader) = 0; + virtual WebRtc_Word32 OnReceivedPayloadData( + const WebRtc_UWord8* payloadData, + const WebRtc_UWord16 payloadSize, + const WebRtcRTPHeader* rtpHeader) = 0; protected: virtual ~RtpData() {} }; @@ -124,9 +125,10 @@ public: const WebRtc_UWord16 /*length*/, const WebRtc_UWord8* /*data*/) {}; - virtual void OnXRVoIPMetricReceived(const WebRtc_Word32 /*id*/, - const RTCPVoIPMetric* /*metric*/, - const WebRtc_Word8 /*VoIPmetricBuffer*/[28]) {}; + virtual void OnXRVoIPMetricReceived( + const WebRtc_Word32 /*id*/, + const RTCPVoIPMetric* /*metric*/, + const WebRtc_Word8 /*VoIPmetricBuffer*/[28]) {}; virtual void OnRTCPPacketTimeout(const WebRtc_Word32 /*id*/) {}; @@ -139,6 +141,10 @@ public: virtual void OnRPSIReceived(const WebRtc_Word32 /*id*/, const WebRtc_UWord64 /*pictureId*/) {}; + virtual void OnReceiverEstimatedMaxBitrateReceived( + const WebRtc_Word32 /*id*/, + const WebRtc_UWord32 /*bitRate*/) {}; + virtual void OnSendReportReceived(const WebRtc_Word32 id, const WebRtc_UWord32 senderSSRC) {}; @@ -156,12 +162,13 @@ public: /* * channels - number of channels in codec (1 = mono, 2 = stereo) */ - virtual WebRtc_Word32 OnInitializeDecoder(const WebRtc_Word32 id, - const WebRtc_Word8 payloadType, - const WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], - const int frequency, - const WebRtc_UWord8 channels, - const WebRtc_UWord32 rate) = 0; + virtual WebRtc_Word32 OnInitializeDecoder( + const WebRtc_Word32 id, + const WebRtc_Word8 payloadType, + const WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], + const int frequency, + const WebRtc_UWord8 channels, + const WebRtc_UWord32 rate) = 0; virtual void OnPacketTimeout(const WebRtc_Word32 id) = 0; @@ -203,8 +210,9 @@ class RtpVideoFeedback { public: // this function should call codec module to inform it about the request - virtual void OnReceivedIntraFrameRequest(const WebRtc_Word32 id, - const WebRtc_UWord8 message = 0) = 0; + virtual void OnReceivedIntraFrameRequest( + const WebRtc_Word32 id, + const WebRtc_UWord8 message = 0) = 0; virtual void OnNetworkChanged(const WebRtc_Word32 id, const WebRtc_UWord32 minBitrateBps, diff --git a/src/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/src/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc new file mode 100644 index 000000000..727604c93 --- /dev/null +++ b/src/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 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 + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include + +#include "typedefs.h" +#include "common_types.h" +#include "rtp_utility.h" +#include "rtcp_sender.h" +#include "rtcp_receiver.h" +#include "rtp_rtcp_impl.h" +#include "bwe_defines.h" + +namespace { + +using namespace webrtc; + + +class TestTransport : public Transport { + public: + TestTransport(RTCPReceiver* rtcp_receiver) : + rtcp_receiver_(rtcp_receiver) { + } + + virtual int SendPacket(int /*channel*/, const void* /*data*/, int /*len*/) { + return -1; + } + virtual int SendRTCPPacket(int /*channel*/, + const void *packet, + int packetLength) { + RTCPUtility::RTCPParserV2 rtcpParser((WebRtc_UWord8*)packet, + (WebRtc_Word32)packetLength, + true); // Allow non-compound RTCP + + EXPECT_EQ(true, rtcpParser.IsValid()); + RTCPHelp::RTCPPacketInformation rtcpPacketInformation; + EXPECT_EQ(0, rtcp_receiver_->IncomingRTCPPacket(rtcpPacketInformation, + &rtcpParser)); + + EXPECT_EQ((WebRtc_UWord32)kRtcpRemb, + rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb); + EXPECT_EQ((WebRtc_UWord32)1234, + rtcpPacketInformation.receiverEstimatedMaxBitrate); + return packetLength; + } + private: + RTCPReceiver* rtcp_receiver_; +}; + + +class RtcpFormatRembTest : public ::testing::Test { + protected: + RtcpFormatRembTest() {}; + virtual void SetUp(); + virtual void TearDown(); + + ModuleRtpRtcpImpl* dummy_rtp_rtcp_impl_; + RTCPSender* rtcp_sender_; + RTCPReceiver* rtcp_receiver_; + TestTransport* test_transport_; +}; + +void RtcpFormatRembTest::SetUp() { + dummy_rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(0, false); + rtcp_sender_ = new RTCPSender(0, false, dummy_rtp_rtcp_impl_); + rtcp_receiver_ = new RTCPReceiver(0, dummy_rtp_rtcp_impl_); + test_transport_ = new TestTransport(rtcp_receiver_); + + EXPECT_EQ(0, rtcp_sender_->Init()); + EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_)); +} + +void RtcpFormatRembTest::TearDown() { + delete rtcp_sender_; + delete rtcp_receiver_; + delete dummy_rtp_rtcp_impl_; + delete test_transport_; +} + +TEST_F(RtcpFormatRembTest, TestBasicAPI) { + EXPECT_EQ(false, rtcp_sender_->REMB()); + EXPECT_EQ(0, rtcp_sender_->SetREMBStatus(true)); + EXPECT_EQ(true, rtcp_sender_->REMB()); + EXPECT_EQ(0, rtcp_sender_->SetREMBStatus(false)); + EXPECT_EQ(false, rtcp_sender_->REMB()); + + EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 0, NULL)); +} + +TEST_F(RtcpFormatRembTest, TestNonCompund) { + WebRtc_UWord32 SSRC = 456789; + EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpNonCompound)); + EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 1, &SSRC)); + EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb)); +} + +TEST_F(RtcpFormatRembTest, TestCompund) { + WebRtc_UWord32 SSRCs[2] = {456789, 98765}; + EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); + EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 2, SSRCs)); + EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb)); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} + +} // namespace diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver.cc b/src/modules/rtp_rtcp/source/rtcp_receiver.cc index 6bad528b6..d5caf5726 100644 --- a/src/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/src/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -9,13 +9,14 @@ */ #include "rtcp_receiver.h" -#include "rtcp_utility.h" #include //memset #include //assert #include "trace.h" #include "critical_section_wrapper.h" +#include "rtcp_utility.h" +#include "rtp_rtcp_impl.h" namespace { @@ -26,11 +27,11 @@ namespace webrtc { using namespace RTCPUtility; using namespace RTCPHelp; -RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, ModuleRtpRtcpPrivate& callback) : +RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, ModuleRtpRtcpImpl* owner) : _id(id), _method(kRtcpOff), _lastReceived(0), - _cbRtcpPrivate(callback), + _rtpRtcp(*owner), _criticalSectionFeedbacks(*CriticalSectionWrapper::CreateCriticalSection()), _cbRtcpFeedback(NULL), _cbVideoFeedback(NULL), @@ -354,6 +355,9 @@ RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation, case RTCPUtility::kRtcpPsfbFirCode: HandleFIR(*rtcpParser, rtcpPacketInformation); break; + case RTCPUtility::kRtcpPsfbAppCode: + HandlePsfbApp(*rtcpParser, rtcpPacketInformation); + break; case RTCPUtility::kRtcpAppCode: // generic application messages HandleAPP(*rtcpParser, rtcpPacketInformation); @@ -477,7 +481,8 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket, _criticalSectionRTCPReceiver.Leave(); // to avoid problem with accuireing _criticalSectionRTCPSender while holding _criticalSectionRTCPReceiver - WebRtc_UWord32 sendTimeMS = _cbRtcpPrivate.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR); + WebRtc_UWord32 sendTimeMS = + _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR); _criticalSectionRTCPReceiver.Enter(); @@ -1129,6 +1134,30 @@ RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser, } } +// no need for critsect we have _criticalSectionRTCPReceiver +void +RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser, + RTCPPacketInformation& rtcpPacketInformation) +{ + RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate(); + if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) + { + HandleREMBItem(rtcpParser, rtcpPacketInformation); + } +} + +void +RTCPReceiver::HandleREMBItem(RTCPUtility::RTCPParserV2& rtcpParser, + RTCPPacketInformation& rtcpPacketInformation) +{ + rtcpParser.Iterate(); + const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet(); + + rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb; + rtcpPacketInformation.receiverEstimatedMaxBitrate = rtcpPacket.REMB.BitRate; + // TODO send up SSRCs and do a sanity check +} + // no need for critsect we have _criticalSectionRTCPReceiver void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser, @@ -1248,26 +1277,27 @@ RTCPReceiver::TriggerCallbacksFromRTCPPacket(RTCPPacketInformation& rtcpPacketIn { if(rtcpPacketInformation.reportBlock) { - _cbRtcpPrivate.OnPacketLossStatisticsUpdate(rtcpPacketInformation.fractionLost, - rtcpPacketInformation.roundTripTime, - rtcpPacketInformation.lastReceivedExtendedHighSeqNum, - rtcpPacketInformation.jitter); + _rtpRtcp.OnPacketLossStatisticsUpdate( + rtcpPacketInformation.fractionLost, + rtcpPacketInformation.roundTripTime, + rtcpPacketInformation.lastReceivedExtendedHighSeqNum, + rtcpPacketInformation.jitter); } } if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) { - _cbRtcpPrivate.OnReceivedNTP(); + _rtpRtcp.OnReceivedNTP(); } if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) { - _cbRtcpPrivate.OnRequestSendReport(); + _rtpRtcp.OnRequestSendReport(); } if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) { if (rtcpPacketInformation.nackSequenceNumbersLength > 0) { WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id, "SIG [RTCP] Incoming NACK to id:%d", _id); - _cbRtcpPrivate.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbersLength, + _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbersLength, rtcpPacketInformation.nackSequenceNumbers); } } @@ -1276,7 +1306,7 @@ RTCPReceiver::TriggerCallbacksFromRTCPPacket(RTCPPacketInformation& rtcpPacketIn WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id, "SIG [RTCP] Incoming TMMBR to id:%d", _id); // might trigger a OnReceivedBandwidthEstimateUpdate - _cbRtcpPrivate.OnReceivedTMMBR(); + _rtpRtcp.OnReceivedTMMBR(); } if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) || (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) @@ -1289,17 +1319,18 @@ RTCPReceiver::TriggerCallbacksFromRTCPPacket(RTCPPacketInformation& rtcpPacketIn WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id, "SIG [RTCP] Incoming FIR to id:%d", _id); } // we need use a bounce it up to handle default channel - _cbRtcpPrivate.OnReceivedIntraFrameRequest(0); + _rtpRtcp.OnReceivedIntraFrameRequest(0); } if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) { // we need use a bounce it up to handle default channel - _cbRtcpPrivate.OnReceivedSliceLossIndication(rtcpPacketInformation.sliPictureId); + _rtpRtcp.OnReceivedSliceLossIndication(rtcpPacketInformation.sliPictureId); } if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) { // we need use a bounce it up to handle default channel - _cbRtcpPrivate.OnReceivedReferencePictureSelectionIndication(rtcpPacketInformation.rpsiPictureId); + _rtpRtcp.OnReceivedReferencePictureSelectionIndication( + rtcpPacketInformation.rpsiPictureId); } { CriticalSectionScoped lock(_criticalSectionFeedbacks); @@ -1317,6 +1348,11 @@ RTCPReceiver::TriggerCallbacksFromRTCPPacket(RTCPPacketInformation& rtcpPacketIn { _cbRtcpFeedback->OnReceiveReportReceived(_id, rtcpPacketInformation.remoteSSRC); } + if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) + { + _cbRtcpFeedback->OnReceiverEstimatedMaxBitrateReceived(_id, + rtcpPacketInformation.receiverEstimatedMaxBitrate); + } if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) { WebRtc_Word8 VoIPmetricBuffer[7*4]; diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver.h b/src/modules/rtp_rtcp/source/rtcp_receiver.h index 2486f8594..47640e823 100644 --- a/src/modules/rtp_rtcp/source/rtcp_receiver.h +++ b/src/modules/rtp_rtcp/source/rtcp_receiver.h @@ -16,14 +16,15 @@ #include "rtp_utility.h" #include "rtcp_utility.h" #include "rtp_rtcp_defines.h" -#include "rtp_rtcp_private.h" #include "rtcp_receiver_help.h" namespace webrtc { +class ModuleRtpRtcpImpl; + class RTCPReceiver { public: - RTCPReceiver(const WebRtc_Word32 id, ModuleRtpRtcpPrivate& callback); + RTCPReceiver(const WebRtc_Word32 id, ModuleRtpRtcpImpl* owner); virtual ~RTCPReceiver(); void ChangeUniqueId(const WebRtc_Word32 id); @@ -50,20 +51,20 @@ public: // get received cname WebRtc_Word32 CNAME(const WebRtc_UWord32 remoteSSRC, - WebRtc_Word8 cName[RTCP_CNAME_SIZE]) const; + WebRtc_Word8 cName[RTCP_CNAME_SIZE]) const; // get received NTP WebRtc_Word32 NTP(WebRtc_UWord32 *ReceivedNTPsecs, - WebRtc_UWord32 *ReceivedNTPfrac, - WebRtc_UWord32 *RTCPArrivalTimeSecs, - WebRtc_UWord32 *RTCPArrivalTimeFrac) const; + WebRtc_UWord32 *ReceivedNTPfrac, + WebRtc_UWord32 *RTCPArrivalTimeSecs, + WebRtc_UWord32 *RTCPArrivalTimeFrac) const; // get rtt WebRtc_Word32 RTT(const WebRtc_UWord32 remoteSSRC, - WebRtc_UWord16* RTT, - WebRtc_UWord16* avgRTT, - WebRtc_UWord16* minRTT, - WebRtc_UWord16* maxRTT) const; + WebRtc_UWord16* RTT, + WebRtc_UWord16* avgRTT, + WebRtc_UWord16* minRTT, + WebRtc_UWord16* maxRTT) const; WebRtc_Word32 ResetRTT(const WebRtc_UWord32 remoteSSRC); @@ -140,6 +141,12 @@ protected: void HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser, RTCPHelp::RTCPPacketInformation& rtcpPacketInformation); + void HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser, + RTCPHelp::RTCPPacketInformation& rtcpPacketInformation); + + void HandleREMBItem(RTCPUtility::RTCPParserV2& rtcpParser, + RTCPHelp::RTCPPacketInformation& rtcpPacketInformation); + void HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser, RTCPHelp::RTCPPacketInformation& rtcpPacketInformation); @@ -170,18 +177,18 @@ protected: RTCPHelp::RTCPPacketInformation& rtcpPacketInformation); private: - WebRtc_Word32 _id; - RTCPMethod _method; - WebRtc_UWord32 _lastReceived; - ModuleRtpRtcpPrivate& _cbRtcpPrivate; + WebRtc_Word32 _id; + RTCPMethod _method; + WebRtc_UWord32 _lastReceived; + ModuleRtpRtcpImpl& _rtpRtcp; - CriticalSectionWrapper& _criticalSectionFeedbacks; - RtcpFeedback* _cbRtcpFeedback; - RtpVideoFeedback* _cbVideoFeedback; + CriticalSectionWrapper& _criticalSectionFeedbacks; + RtcpFeedback* _cbRtcpFeedback; + RtpVideoFeedback* _cbVideoFeedback; - CriticalSectionWrapper& _criticalSectionRTCPReceiver; - WebRtc_UWord32 _SSRC; - WebRtc_UWord32 _remoteSSRC; + CriticalSectionWrapper& _criticalSectionRTCPReceiver; + WebRtc_UWord32 _SSRC; + WebRtc_UWord32 _remoteSSRC; // Received send report RTCPSenderInfo _remoteSenderInfo; diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver_help.h b/src/modules/rtp_rtcp/source/rtcp_receiver_help.h index 26caaa92f..acd755bae 100644 --- a/src/modules/rtp_rtcp/source/rtcp_receiver_help.h +++ b/src/modules/rtp_rtcp/source/rtcp_receiver_help.h @@ -51,7 +51,7 @@ public: WebRtc_UWord8* applicationData; WebRtc_UWord16 applicationLength; - bool reportBlock; + bool reportBlock; WebRtc_UWord8 fractionLost; WebRtc_UWord16 roundTripTime; WebRtc_UWord32 lastReceivedExtendedHighSeqNum; @@ -59,6 +59,7 @@ public: WebRtc_UWord8 sliPictureId; WebRtc_UWord64 rpsiPictureId; + WebRtc_UWord32 receiverEstimatedMaxBitrate; RTCPVoIPMetric* VoIPMetric; }; diff --git a/src/modules/rtp_rtcp/source/rtcp_sender.cc b/src/modules/rtp_rtcp/source/rtcp_sender.cc index 89af2879b..5d2dc6779 100644 --- a/src/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/src/modules/rtp_rtcp/source/rtcp_sender.cc @@ -20,14 +20,16 @@ #include "common_types.h" #include "critical_section_wrapper.h" +#include "rtp_rtcp_impl.h" + namespace webrtc { RTCPSender::RTCPSender(const WebRtc_Word32 id, const bool audio, - ModuleRtpRtcpPrivate& callback) : + ModuleRtpRtcpImpl* owner) : _id(id), _audio(audio), _method(kRtcpOff), - _cbRtcpPrivate(callback), + _rtpRtcp(*owner), _criticalSectionTransport(*CriticalSectionWrapper::CreateCriticalSection()), _cbTransport(NULL), @@ -35,6 +37,8 @@ RTCPSender::RTCPSender(const WebRtc_Word32 id, _usingNack(false), _sending(false), _sendTMMBN(false), + _REMB(false), + _sendREMB(false), _TMMBR(false), _nextTimeToSendRTCP(0), _SSRC(0), @@ -55,6 +59,11 @@ RTCPSender::RTCPSender(const WebRtc_Word32 id, _sequenceNumberFIR(0), _lastTimeFIR(0), + _lengthRembSSRC(0), + _sizeRembSSRC(0), + _rembSSRC(NULL), + _rembBitrate(0), + _tmmbrHelp(audio), _tmmbr_Send(0), _packetOH_Send(0), @@ -77,10 +86,8 @@ RTCPSender::RTCPSender(const WebRtc_Word32 id, RTCPSender::~RTCPSender() { - if(_appData) - { - delete [] _appData; - } + delete [] _rembSSRC; + delete [] _appData; MapItem* item = _reportBlocks.First(); while(item) @@ -121,6 +128,8 @@ RTCPSender::Init() _sending = false; _sendTMMBN = false; _TMMBR = false; + _REMB = false; + _sendREMB = false; _SSRC = 0; _remoteSSRC = 0; _cameraDelayMS = 0; @@ -219,6 +228,44 @@ RTCPSender::SetSendingStatus(const bool sending) return 0; } +bool +RTCPSender::REMB() const +{ + CriticalSectionScoped lock(_criticalSectionRTCPSender); + return _REMB; +} + +WebRtc_Word32 +RTCPSender::SetREMBStatus(const bool enable) +{ + CriticalSectionScoped lock(_criticalSectionRTCPSender); + _REMB = enable; + return 0; +} + +WebRtc_Word32 +RTCPSender::SetREMBData(const WebRtc_UWord32 bitrate, + const WebRtc_UWord8 numberOfSSRC, + const WebRtc_UWord32* SSRC) +{ + CriticalSectionScoped lock(_criticalSectionRTCPSender); + _rembBitrate = bitrate; + + if(_sizeRembSSRC < numberOfSSRC) + { + delete [] _rembSSRC; + _rembSSRC = new WebRtc_UWord32[numberOfSSRC]; + _sizeRembSSRC = numberOfSSRC; + } + + _lengthRembSSRC = numberOfSSRC; + for (int i = 0; i < numberOfSSRC; i++) + { + _rembSSRC[i] = SSRC[i]; + } + return 0; +} + bool RTCPSender::TMMBR() const { @@ -585,7 +632,7 @@ RTCPSender::BuildSR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32 freqHz = 90000; // For video if(_audio) { - freqHz = _cbRtcpPrivate.CurrentSendFrequencyHz(); + freqHz = _rtpRtcp.CurrentSendFrequencyHz(); RTPtime = ModuleRTPUtility::CurrentRTP(freqHz); } else // video @@ -615,11 +662,11 @@ RTCPSender::BuildSR(WebRtc_UWord8* rtcpbuffer, pos += 4; //sender's packet count - ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _cbRtcpPrivate.PacketCountSent()); + ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _rtpRtcp.PacketCountSent()); pos += 4; //sender's octet count - ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _cbRtcpPrivate.ByteCountSent()); + ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _rtpRtcp.ByteCountSent()); pos += 4; WebRtc_UWord8 numberOfReportBlocks = 0; @@ -1000,23 +1047,81 @@ RTCPSender::BuildRPSI(WebRtc_UWord8* rtcpbuffer, } WebRtc_Word32 -RTCPSender::BuildTMMBR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos, WebRtc_UWord32 RTT) +RTCPSender::BuildREMB(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) +{ + // sanity + if(pos + 20 + 4 * _lengthRembSSRC >= IP_PACKET_SIZE) + { + return -2; + } + // add application layer feedback + WebRtc_UWord8 FMT = 15; + rtcpbuffer[pos++]=(WebRtc_UWord8)0x80 + FMT; + rtcpbuffer[pos++]=(WebRtc_UWord8)206; + + rtcpbuffer[pos++]=(WebRtc_UWord8)0; + rtcpbuffer[pos++]=_lengthRembSSRC + 4; + + // Add our own SSRC + ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _SSRC); + pos += 4; + + // Remote SSRC must be 0 + ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, 0); + pos += 4; + + rtcpbuffer[pos++]='R'; + rtcpbuffer[pos++]='E'; + rtcpbuffer[pos++]='M'; + rtcpbuffer[pos++]='B'; + + rtcpbuffer[pos++] = _lengthRembSSRC; + // 6 bit Exp + // 18 bit mantissa + WebRtc_UWord8 brExp = 0; + for(WebRtc_UWord32 i=0; i<64; i++) + { + if(_rembBitrate <= ((WebRtc_UWord32)262143 << i)) + { + brExp = i; + break; + } + } + const WebRtc_UWord32 brMantissa = (_rembBitrate >> brExp); + rtcpbuffer[pos++]=(WebRtc_UWord8)((brExp << 2) + ((brMantissa >> 16) & 0x03)); + rtcpbuffer[pos++]=(WebRtc_UWord8)(brMantissa >> 8); + rtcpbuffer[pos++]=(WebRtc_UWord8)(brMantissa); + + for (int i = 0; i < _lengthRembSSRC; i++) + { + ModuleRTPUtility::AssignUWord32ToBuffer(rtcpbuffer+pos, _rembSSRC[i]); + pos += 4; + } + return 0; +} + +WebRtc_UWord32 +RTCPSender::CalculateNewTargetBitrate(WebRtc_UWord32 RTT) +{ + WebRtc_UWord32 target_bitrate = _remoteRateControl.TargetBitRate(RTT); + _tmmbr_Send = target_bitrate / 1000; + return target_bitrate; +} + +WebRtc_Word32 +RTCPSender::BuildTMMBR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos) { // Before sending the TMMBR check the received TMMBN, only an owner is allowed to raise the bitrate // If the sender is an owner of the TMMBN -> send TMMBR // If not an owner but the TMMBR would enter the TMMBN -> send TMMBR - // About to send TMMBR, first run remote rate control - // to get a target bit rate. - _tmmbr_Send = _remoteRateControl.TargetBitRate(RTT) / 1000; - // get current bounding set from RTCP receiver bool tmmbrOwner = false; TMMBRSet* candidateSet = _tmmbrHelp.CandidateSet(); // store in candidateSet, allocates one extra slot // holding _criticalSectionRTCPSender while calling RTCPreceiver which will accuire _criticalSectionRTCPReceiver // is a potental deadlock but since RTCPreceiver is not doing the revese we should be fine - WebRtc_Word32 lengthOfBoundingSet = _cbRtcpPrivate.BoundingSet(tmmbrOwner, candidateSet); + WebRtc_Word32 lengthOfBoundingSet = _rtpRtcp.BoundingSet(tmmbrOwner, candidateSet); if(lengthOfBoundingSet > 0) { @@ -1479,10 +1584,10 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags, rtcpPacketTypeFlags & kRtcpRr) { // get statistics from our RTPreceiver outside critsect - if(_cbRtcpPrivate.ReportBlockStatistics(&received.fractionLost, - &received.cumulativeLost, - &received.extendedHighSeqNum, - &received.jitter) == 0) + if(_rtpRtcp.ReportBlockStatistics(&received.fractionLost, + &received.cumulativeLost, + &received.extendedHighSeqNum, + &received.jitter) == 0) { hasReceived = true; @@ -1491,7 +1596,9 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags, WebRtc_UWord32 remoteSR = 0; // ok even if we have not received a SR, we will send 0 in that case - _cbRtcpPrivate.LastReceivedNTP(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac, remoteSR); + _rtpRtcp.LastReceivedNTP(lastReceivedRRNTPsecs, + lastReceivedRRNTPfrac, + remoteSR); // get our NTP as late as possible to avoid a race ModuleRTPUtility::CurrentNTP(NTPsec, NTPfrac); @@ -1531,6 +1638,11 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags, rtcpPacketTypeFlags |= kRtcpApp; _appSend = false; } + if(_REMB && _sendREMB) + { + rtcpPacketTypeFlags |= kRtcpRemb; + _sendREMB = false; + } if(_xrSendVoIPMetric) { rtcpPacketTypeFlags |= kRtcpXrVoipMetric; @@ -1581,7 +1693,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags, if(_sending) { // calc bw for video 360/sendBW in kbit/s - WebRtc_Word32 sendBitrateKbit = _cbRtcpPrivate.BitrateSent()/1000; + WebRtc_Word32 sendBitrateKbit = _rtpRtcp.BitrateSent()/1000; if(sendBitrateKbit != 0) { minIntervalMs = 360000/sendBitrateKbit; @@ -1691,7 +1803,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags, } if(rtcpPacketTypeFlags & kRtcpRpsi) { - const WebRtc_Word8 payloadType = _cbRtcpPrivate.SendPayloadType(); + const WebRtc_Word8 payloadType = _rtpRtcp.SendPayloadType(); if(payloadType == -1) { return -1; @@ -1706,6 +1818,18 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags, break; // out of buffer } } + if(rtcpPacketTypeFlags & kRtcpRemb) + { + buildVal = BuildREMB(rtcpbuffer, pos); + if(buildVal == -1) + { + return -1; // error + + }else if(buildVal == -2) + { + break; // out of buffer + } + } if(rtcpPacketTypeFlags & kRtcpBye) { buildVal = BuildBYE(rtcpbuffer, pos); @@ -1732,7 +1856,7 @@ RTCPSender::SendRTCP(const WebRtc_UWord32 packetTypeFlags, } if(rtcpPacketTypeFlags & kRtcpTmmbr) { - buildVal = BuildTMMBR(rtcpbuffer, pos, RTT); + buildVal = BuildTMMBR(rtcpbuffer, pos); if(buildVal == -1) { return -1; // error diff --git a/src/modules/rtp_rtcp/source/rtcp_sender.h b/src/modules/rtp_rtcp/source/rtcp_sender.h index c920a1137..69ca816cf 100644 --- a/src/modules/rtp_rtcp/source/rtcp_sender.h +++ b/src/modules/rtp_rtcp/source/rtcp_sender.h @@ -15,14 +15,17 @@ #include "rtp_utility.h" #include "map_wrapper.h" #include "rtp_rtcp_defines.h" -#include "rtp_rtcp_private.h" #include "remote_rate_control.h" +#include "tmmbr_help.h" namespace webrtc { + +class ModuleRtpRtcpImpl; + class RTCPSender { public: - RTCPSender(const WebRtc_Word32 id, const bool audio, ModuleRtpRtcpPrivate& callback); + RTCPSender(const WebRtc_Word32 id, const bool audio, ModuleRtpRtcpImpl* owner); virtual ~RTCPSender(); void ChangeUniqueId(const WebRtc_Word32 id); @@ -60,16 +63,26 @@ public: WebRtc_UWord32 LastSendReport(WebRtc_UWord32& lastRTCPTime); WebRtc_Word32 SendRTCP(const WebRtc_UWord32 rtcpPacketTypeFlags, - const WebRtc_Word32 nackSize = 0, - const WebRtc_UWord16* nackList = 0, - const WebRtc_UWord32 RTT = 0, - const WebRtc_UWord64 pictureID = 0); + const WebRtc_Word32 nackSize = 0, + const WebRtc_UWord16* nackList = 0, + const WebRtc_UWord32 RTT = 0, + const WebRtc_UWord64 pictureID = 0); WebRtc_Word32 AddReportBlock(const WebRtc_UWord32 SSRC, const RTCPReportBlock* receiveBlock); WebRtc_Word32 RemoveReportBlock(const WebRtc_UWord32 SSRC); + /* + * REMB + */ + bool REMB() const; + + WebRtc_Word32 SetREMBStatus(const bool enable); + + WebRtc_Word32 SetREMBData(const WebRtc_UWord32 bitrate, + const WebRtc_UWord8 numberOfSSRC, + const WebRtc_UWord32* SSRC); /* * TMMBR */ @@ -78,24 +91,24 @@ public: WebRtc_Word32 SetTMMBRStatus(const bool enable); 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); + const WebRtc_UWord32 packetOH); /* * */ WebRtc_Word32 SetApplicationSpecificData(const WebRtc_UWord8 subType, - const WebRtc_UWord32 name, - const WebRtc_UWord8* data, - const WebRtc_UWord16 length); + const WebRtc_UWord32 name, + const WebRtc_UWord8* data, + const WebRtc_UWord16 length); WebRtc_Word32 SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric); WebRtc_Word32 SetCSRCs(const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize], - const WebRtc_UWord8 arrLength); + const WebRtc_UWord8 arrLength); WebRtc_Word32 SetCSRCStatus(const bool include); @@ -105,6 +118,8 @@ public: RateControlRegion UpdateOverUseState(const RateControlInput& rateControlInput, bool& firstOverUse); + WebRtc_UWord32 CalculateNewTargetBitrate(WebRtc_UWord32 RTT); + private: WebRtc_Word32 SendToNetwork(const WebRtc_UWord8* dataBuffer, const WebRtc_UWord16 length); @@ -132,7 +147,8 @@ private: WebRtc_Word32 BuildSDEC(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos); WebRtc_Word32 BuildPLI(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos); - WebRtc_Word32 BuildTMMBR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos, WebRtc_UWord32 RTT); + WebRtc_Word32 BuildREMB(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos); + WebRtc_Word32 BuildTMMBR(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos); WebRtc_Word32 BuildTMMBN(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos); WebRtc_Word32 BuildAPP(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos); WebRtc_Word32 BuildVoIPMetric(WebRtc_UWord8* rtcpbuffer, WebRtc_UWord32& pos); @@ -154,19 +170,21 @@ private: const WebRtc_UWord16* nackList); private: - WebRtc_Word32 _id; - const bool _audio; - RTCPMethod _method; + WebRtc_Word32 _id; + const bool _audio; + RTCPMethod _method; - ModuleRtpRtcpPrivate& _cbRtcpPrivate; + ModuleRtpRtcpImpl& _rtpRtcp; - CriticalSectionWrapper& _criticalSectionTransport; - Transport* _cbTransport; + CriticalSectionWrapper& _criticalSectionTransport; + Transport* _cbTransport; - CriticalSectionWrapper& _criticalSectionRTCPSender; + CriticalSectionWrapper& _criticalSectionRTCPSender; bool _usingNack; bool _sending; bool _sendTMMBN; + bool _REMB; + bool _sendREMB; bool _TMMBR; WebRtc_UWord32 _nextTimeToSendRTCP; @@ -193,7 +211,12 @@ private: WebRtc_UWord8 _sequenceNumberFIR; WebRtc_UWord32 _lastTimeFIR; - // TMMBR + // REMB + WebRtc_UWord8 _lengthRembSSRC; + WebRtc_UWord8 _sizeRembSSRC; + WebRtc_UWord32* _rembSSRC; + WebRtc_UWord32 _rembBitrate; + TMMBRHelp _tmmbrHelp; WebRtc_UWord32 _tmmbr_Send; WebRtc_UWord32 _packetOH_Send; diff --git a/src/modules/rtp_rtcp/source/rtcp_utility.cc b/src/modules/rtp_rtcp/source/rtcp_utility.cc index f1e7b8530..b153981f7 100644 --- a/src/modules/rtp_rtcp/source/rtcp_utility.cc +++ b/src/modules/rtp_rtcp/source/rtcp_utility.cc @@ -118,6 +118,12 @@ RTCPUtility::RTCPParserV2::Iterate() case State_PSFB_FIRItem: IterateFIRItem(); break; + case State_PSFB_AppItem: + IteratePsfbAppItem(); + break; + case State_PSFB_REMBItem: + IteratePsfbREMBItem(); + break; case State_AppItem: IterateAppItem(); break; @@ -320,6 +326,26 @@ RTCPUtility::RTCPParserV2::IterateFIRItem() } } +void +RTCPUtility::RTCPParserV2::IteratePsfbAppItem() +{ + const bool success = ParsePsfbAppItem(); + if (!success) + { + Iterate(); + } +} + +void +RTCPUtility::RTCPParserV2::IteratePsfbREMBItem() +{ + const bool success = ParsePsfbREMBItem(); + if (!success) + { + Iterate(); + } +} + void RTCPUtility::RTCPParserV2::IterateAppItem() { @@ -340,8 +366,8 @@ RTCPUtility::RTCPParserV2::Validate() RTCPCommonHeader header; const bool success = RTCPParseCommonHeader(_ptrRTCPDataBegin, - _ptrRTCPDataEnd, - header); + _ptrRTCPDataEnd, + header); if (!success) { @@ -1010,6 +1036,11 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header) _state = State_PSFB_FIRItem; return true; + case 15: + _packetType = kRtcpPsfbAppCode; + + _state = State_PSFB_AppItem; + return true; default: break; } @@ -1094,6 +1125,78 @@ RTCPUtility::RTCPParserV2::ParseNACKItem() return true; } +bool +RTCPUtility::RTCPParserV2::ParsePsfbAppItem() +{ + const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; + + if (length < 4) + { + _state = State_TopLevel; + + EndCurrentBlock(); + return false; + } + if(*_ptrRTCPData++ != 'R') + { + _state = State_TopLevel; + + EndCurrentBlock(); + return false; + } + if(*_ptrRTCPData++ != 'E') + { + _state = State_TopLevel; + + EndCurrentBlock(); + return false; + } + if(*_ptrRTCPData++ != 'M') + { + _state = State_TopLevel; + + EndCurrentBlock(); + return false; + } + if(*_ptrRTCPData++ != 'B') + { + _state = State_TopLevel; + + EndCurrentBlock(); + return false; + } + _packetType = kRtcpPsfbRembItemCode; + _state = State_PSFB_REMBItem; + return true; +} + +bool +RTCPUtility::RTCPParserV2::ParsePsfbREMBItem() +{ + const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData; + + if (length < 4) + { + _state = State_TopLevel; + + EndCurrentBlock(); + return false; + } + + const WebRtc_UWord8 numSSRC = *_ptrRTCPData++; + const WebRtc_UWord8 brExp = (_ptrRTCPData[0] >> 2) & 0x3F; + + WebRtc_UWord32 brMantissa = (_ptrRTCPData[0] & 0x03) << 16; + brMantissa += (_ptrRTCPData[1] << 8); + brMantissa += (_ptrRTCPData[2]); + + _ptrRTCPData += 3; // Fwd read data + _packet.REMB.BitRate = (brMantissa << brExp); + + _ptrRTCPData += 4 * numSSRC; // Ignore the SSRCs for now + return true; +} + bool RTCPUtility::RTCPParserV2::ParseTMMBRItem() { diff --git a/src/modules/rtp_rtcp/source/rtcp_utility.h b/src/modules/rtp_rtcp/source/rtcp_utility.h index decb606ee..4bdf1359e 100644 --- a/src/modules/rtp_rtcp/source/rtcp_utility.h +++ b/src/modules/rtp_rtcp/source/rtcp_utility.h @@ -177,11 +177,14 @@ namespace RTCPUtility { // RFC4585 WebRtc_UWord32 SenderSSRC; WebRtc_UWord32 MediaSSRC; - WebRtc_UWord8 PayloadType; - WebRtc_UWord16 NumberOfValidBits; + WebRtc_UWord8 PayloadType; + WebRtc_UWord16 NumberOfValidBits; WebRtc_UWord8 NativeBitString[RTCP_RPSI_DATA_SIZE]; }; - + struct RTCPPacketPSFBREMB + { + WebRtc_UWord32 BitRate; + }; // generic name APP struct RTCPPacketAPP { @@ -207,6 +210,7 @@ namespace RTCPUtility { RTCPPacketPSFBSLI SLI; RTCPPacketPSFBSLIItem SLIItem; RTCPPacketPSFBRPSI RPSI; + RTCPPacketPSFBREMB REMB; RTCPPacketRTPFBTMMBR TMMBR; RTCPPacketRTPFBTMMBRItem TMMBRItem; @@ -242,6 +246,8 @@ namespace RTCPUtility { kRtcpPsfbRpsiCode, kRtcpPsfbSliCode, kRtcpPsfbSliItemCode, + kRtcpPsfbAppCode, + kRtcpPsfbRembItemCode, // RFC5104 kRtcpRtpfbTmmbrCode, @@ -329,6 +335,8 @@ namespace RTCPUtility { State_PSFB_SLIItem, // SLI FCI item State_PSFB_RPSIItem, // RPSI FCI item State_PSFB_FIRItem, // FIR FCI item + State_PSFB_AppItem, // Application specific FCI item + State_PSFB_REMBItem, // Application specific REMB item State_XRItem, State_AppItem }; @@ -344,6 +352,8 @@ namespace RTCPUtility { void IterateSLIItem(); void IterateRPSIItem(); void IterateFIRItem(); + void IteratePsfbAppItem(); + void IteratePsfbREMBItem(); void IterateAppItem(); void Validate(); @@ -371,6 +381,8 @@ namespace RTCPUtility { bool ParseSLIItem(); bool ParseRPSIItem(); bool ParseFIRItem(); + bool ParsePsfbAppItem(); + bool ParsePsfbREMBItem(); bool ParseAPP(const RTCPCommonHeader& header); bool ParseAPPItem(); diff --git a/src/modules/rtp_rtcp/source/rtp_receiver.cc b/src/modules/rtp_rtcp/source/rtp_receiver.cc index 172a91ae2..d5d3102c2 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver.cc +++ b/src/modules/rtp_rtcp/source/rtp_receiver.cc @@ -12,6 +12,7 @@ #include "rtp_receiver.h" #include "rtp_rtcp_defines.h" +#include "rtp_rtcp_impl.h" #include "critical_section_wrapper.h" #include @@ -22,13 +23,13 @@ namespace webrtc { RTPReceiver::RTPReceiver(const WebRtc_Word32 id, const bool audio, - ModuleRtpRtcpPrivate& callback) : + ModuleRtpRtcpImpl* owner) : RTPReceiverAudio(id), - RTPReceiverVideo(id, callback), + RTPReceiverVideo(id, owner), _id(id), _audio(audio), + _rtpRtcp(*owner), _criticalSectionCbs(*CriticalSectionWrapper::CreateCriticalSection()), - _cbPrivateFeedback(callback), _cbRtpFeedback(NULL), _cbRtpData(NULL), @@ -956,7 +957,7 @@ RTPReceiver::RetransmitOfOldPacket(const WebRtc_UWord16 sequenceNumber, WebRtc_Word32 rtpTimeStampDiffMS = ((WebRtc_Word32)(rtpTimeStamp - _lastReceivedTimestamp))/90; // diff in time stamp since last received in order WebRtc_UWord16 minRTT = 0; - _cbPrivateFeedback.RTT(_SSRC,NULL,NULL,&minRTT, NULL); + _rtpRtcp.RTT(_SSRC,NULL,NULL,&minRTT, NULL); if(minRTT == 0) { // no update @@ -1154,7 +1155,7 @@ RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader) { // we need to get this to our RTCP sender and receiver // need to do this outside critical section - _cbPrivateFeedback.SetRemoteSSRC(rtpHeader->header.ssrc); + _rtpRtcp.SetRemoteSSRC(rtpHeader->header.ssrc); } CriticalSectionScoped lock(_criticalSectionCbs); diff --git a/src/modules/rtp_rtcp/source/rtp_receiver.h b/src/modules/rtp_rtcp/source/rtp_receiver.h index 3c87aa977..899468b35 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver.h +++ b/src/modules/rtp_rtcp/source/rtp_receiver.h @@ -22,6 +22,7 @@ namespace webrtc { class RtpRtcpFeedback; +class ModuleRtpRtcpImpl; class Trace; class RTPReceiver : public RTPReceiverAudio, public RTPReceiverVideo, public Bitrate @@ -29,7 +30,7 @@ class RTPReceiver : public RTPReceiverAudio, public RTPReceiverVideo, public Bit public: RTPReceiver(const WebRtc_Word32 id, const bool audio, - ModuleRtpRtcpPrivate& callback); + ModuleRtpRtcpImpl* owner); virtual ~RTPReceiver(); @@ -104,22 +105,22 @@ public: WebRtc_Word32 SetSSRCFilter(const bool enable, const WebRtc_UWord32 allowedSSRC); WebRtc_Word32 Statistics(WebRtc_UWord8 *fraction_lost, - WebRtc_UWord32 *cum_lost, - WebRtc_UWord32 *ext_max, - WebRtc_UWord32 *jitter, // will be moved from JB - WebRtc_UWord32 *max_jitter, - bool reset = false) const; + WebRtc_UWord32 *cum_lost, + WebRtc_UWord32 *ext_max, + WebRtc_UWord32 *jitter, // will be moved from JB + WebRtc_UWord32 *max_jitter, + bool reset = false) const; WebRtc_Word32 Statistics(WebRtc_UWord8 *fraction_lost, - WebRtc_UWord32 *cum_lost, - WebRtc_UWord32 *ext_max, - WebRtc_UWord32 *jitter, // will be moved from JB - WebRtc_UWord32 *max_jitter, - WebRtc_Word32 *missing, - bool reset = false) const; + WebRtc_UWord32 *cum_lost, + WebRtc_UWord32 *ext_max, + WebRtc_UWord32 *jitter, // will be moved from JB + WebRtc_UWord32 *max_jitter, + WebRtc_Word32 *missing, + bool reset = false) const; WebRtc_Word32 DataCounters(WebRtc_UWord32 *bytesReceived, - WebRtc_UWord32 *packetsReceived) const; + WebRtc_UWord32 *packetsReceived) const; WebRtc_Word32 ResetStatistics(); @@ -132,12 +133,12 @@ public: WebRtc_UWord32 ByteCountReceived() const; virtual WebRtc_UWord32 PayloadTypeToPayload(const WebRtc_UWord8 payloadType, - ModuleRTPUtility::Payload*& payload) const; + ModuleRTPUtility::Payload*& payload) const; protected: virtual WebRtc_Word32 CallbackOfReceivedPayloadData(const WebRtc_UWord8* payloadData, - const WebRtc_UWord16 payloadSize, - const WebRtcRTPHeader* rtpHeader); + const WebRtc_UWord16 payloadSize, + const WebRtcRTPHeader* rtpHeader); virtual bool RetransmitOfOldPacket(const WebRtc_UWord16 sequenceNumber, const WebRtc_UWord32 rtpTimeStamp) const; @@ -158,20 +159,20 @@ private: void CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader); void CheckCSRC(const WebRtcRTPHeader* rtpHeader); WebRtc_Word32 CheckPayloadChanged(const WebRtcRTPHeader* rtpHeader, - const WebRtc_Word8 firstPayloadByte, - bool& isRED, - ModuleRTPUtility::AudioPayload& audioSpecific, - ModuleRTPUtility::VideoPayload& videoSpecific); + const WebRtc_Word8 firstPayloadByte, + bool& isRED, + ModuleRTPUtility::AudioPayload& audioSpecific, + ModuleRTPUtility::VideoPayload& videoSpecific); void UpdateNACKBitRate(WebRtc_Word32 bytes, WebRtc_UWord32 now); bool ProcessNACKBitRate(WebRtc_UWord32 now); private: - WebRtc_Word32 _id; + WebRtc_Word32 _id; const bool _audio; + ModuleRtpRtcpImpl& _rtpRtcp; CriticalSectionWrapper& _criticalSectionCbs; - ModuleRtpRtcpPrivate& _cbPrivateFeedback; RtpFeedback* _cbRtpFeedback; RtpData* _cbRtpData; diff --git a/src/modules/rtp_rtcp/source/rtp_receiver_video.cc b/src/modules/rtp_rtcp/source/rtp_receiver_video.cc index 535cf0e42..279047daa 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver_video.cc +++ b/src/modules/rtp_rtcp/source/rtp_receiver_video.cc @@ -8,16 +8,16 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include "rtp_receiver_video.h" + #include //assert #include // memcpy() #include -#include "rtp_receiver_video.h" - #include "critical_section_wrapper.h" #include "tick_util.h" - #include "receiver_fec.h" +#include "rtp_rtcp_impl.h" namespace webrtc { WebRtc_UWord32 BitRateBPS(WebRtc_UWord16 x ) @@ -26,11 +26,11 @@ WebRtc_UWord32 BitRateBPS(WebRtc_UWord16 x ) } RTPReceiverVideo::RTPReceiverVideo(const WebRtc_Word32 id, - ModuleRtpRtcpPrivate& callback): + ModuleRtpRtcpImpl* owner): _id(id), + _rtpRtcp(*owner), _criticalSectionFeedback(*CriticalSectionWrapper::CreateCriticalSection()), _cbVideoFeedback(NULL), - _cbPrivateFeedback(callback), _criticalSectionReceiverVideo(*CriticalSectionWrapper::CreateCriticalSection()), _completeFrame(false), @@ -304,7 +304,7 @@ RTPReceiverVideo::ParseVideoCodecSpecific(WebRtcRTPHeader* rtpHeader, _criticalSectionReceiverVideo.Leave(); // Call the callback outside critical section - const RateControlRegion region = _cbPrivateFeedback.OnOverUseStateUpdate(input); + const RateControlRegion region = _rtpRtcp.OnOverUseStateUpdate(input); _criticalSectionReceiverVideo.Enter(); _overUseDetector.SetRateControlRegion(region); diff --git a/src/modules/rtp_rtcp/source/rtp_receiver_video.h b/src/modules/rtp_rtcp/source/rtp_receiver_video.h index 8d36490fe..f71cd9bd3 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver_video.h +++ b/src/modules/rtp_rtcp/source/rtp_receiver_video.h @@ -12,7 +12,6 @@ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_VIDEO_H_ #include "rtp_rtcp_defines.h" -#include "rtp_rtcp_private.h" #include "rtp_utility.h" #include "typedefs.h" @@ -25,12 +24,13 @@ namespace webrtc { class ReceiverFEC; +class ModuleRtpRtcpImpl; class RTPReceiverVideo { public: RTPReceiverVideo(const WebRtc_Word32 id, - ModuleRtpRtcpPrivate& callback); + ModuleRtpRtcpImpl* owner); virtual ~RTPReceiverVideo(); @@ -123,11 +123,10 @@ protected: private: WebRtc_Word32 _id; + ModuleRtpRtcpImpl& _rtpRtcp; - CriticalSectionWrapper& _criticalSectionFeedback; - RtpVideoFeedback* _cbVideoFeedback; - - ModuleRtpRtcpPrivate& _cbPrivateFeedback; + CriticalSectionWrapper& _criticalSectionFeedback; + RtpVideoFeedback* _cbVideoFeedback; CriticalSectionWrapper& _criticalSectionReceiverVideo; diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp.gypi b/src/modules/rtp_rtcp/source/rtp_rtcp.gypi index 1a235cdc9..b397598a2 100644 --- a/src/modules/rtp_rtcp/source/rtp_rtcp.gypi +++ b/src/modules/rtp_rtcp/source/rtp_rtcp.gypi @@ -33,7 +33,6 @@ 'rtp_rtcp_config.h', 'rtp_rtcp_impl.cc', 'rtp_rtcp_impl.h', - 'rtp_rtcp_private.h', 'rtcp_receiver.cc', 'rtcp_receiver.h', 'rtcp_receiver_help.cc', diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 97e699a76..dd8fb15f3 100644 --- a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -61,7 +61,9 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const WebRtc_Word32 id, const bool audio): TMMBRHelp(audio), _rtpSender(id, audio), - _rtpReceiver(id, audio, *this), + _rtpReceiver(id, audio, this), + _rtcpSender(id, audio, this), + _rtcpReceiver(id, this), _id(id), _audio(audio), _collisionDetected(false), @@ -77,13 +79,11 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const WebRtc_Word32 id, _deadOrAliveActive(false), _deadOrAliveTimeoutMS(0), _deadOrAliveLastTimer(0), - _rtcpReceiver(id,*this), _bandwidthManagement(id), _receivedNTPsecsAudio(0), _receivedNTPfracAudio(0), _RTCPArrivalTimeSecsAudio(0), _RTCPArrivalTimeFracAudio(0), - _rtcpSender(id, audio, *this), _nackMethod(kNackOff), _nackLastTimeSent(0), _nackLastSeqNumberSent(0), @@ -212,7 +212,7 @@ ModuleRtpRtcpImpl::RegisterDefaultModule(RtpRtcp* module) { _defaultModule->DeRegisterChildModule(this); } - _defaultModule = (ModuleRtpRtcpPrivate*)module; + _defaultModule = (ModuleRtpRtcpImpl*)module; _defaultModule->RegisterChildModule(this); return 0; } @@ -310,7 +310,7 @@ ModuleRtpRtcpImpl::RegisterSyncModule(RtpRtcp* audioModule) return -1; } CriticalSectionScoped lock(_criticalSectionModulePtrs); - _audioModule = (ModuleRtpRtcpPrivate*)audioModule; + _audioModule = (ModuleRtpRtcpImpl*)audioModule; return _audioModule->RegisterVideoModule(this); } @@ -322,7 +322,7 @@ ModuleRtpRtcpImpl::DeRegisterSyncModule() CriticalSectionScoped lock(_criticalSectionModulePtrs); if(_audioModule) { - ModuleRtpRtcpPrivate* audioModule=_audioModule; + ModuleRtpRtcpImpl* audioModule=_audioModule; _audioModule = NULL; _receivedNTPsecsAudio = 0; _receivedNTPfracAudio = 0; @@ -347,7 +347,7 @@ ModuleRtpRtcpImpl::RegisterVideoModule(RtpRtcp* videoModule) return -1; } CriticalSectionScoped lock(_criticalSectionModulePtrs); - _videoModule = (ModuleRtpRtcpPrivate*)videoModule; + _videoModule = (ModuleRtpRtcpImpl*)videoModule; return 0; } @@ -359,7 +359,7 @@ ModuleRtpRtcpImpl::DeRegisterVideoModule() CriticalSectionScoped lock(_criticalSectionModulePtrs); if(_videoModule) { - ModuleRtpRtcpPrivate* videoModule=_videoModule; + ModuleRtpRtcpImpl* videoModule=_videoModule; _videoModule=NULL; videoModule->DeRegisterSyncModule(); } @@ -1517,6 +1517,39 @@ ModuleRtpRtcpImpl::RemoveRTCPReportBlock(const WebRtc_UWord32 SSRC) return _rtcpSender.RemoveReportBlock(SSRC); } + /* + * (REMB) Receiver Estimated Max Bitrate + */ +bool +ModuleRtpRtcpImpl::REMB() const +{ + WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "REMB()"); + + return _rtcpSender.REMB(); +} + +WebRtc_Word32 +ModuleRtpRtcpImpl::SetREMBStatus(const bool enable) +{ + if(enable) + { + WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetREMBStatus(enable)"); + }else + { + WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetREMBStatus(disable)"); + } + return _rtcpSender.SetREMBStatus(enable); +} + +WebRtc_Word32 +ModuleRtpRtcpImpl::SetREMBData(const WebRtc_UWord32 bitrate, + const WebRtc_UWord8 numberOfSSRC, + const WebRtc_UWord32* SSRC) +{ + WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetREMBData(bitrate:%d,?,?)", bitrate); + return _rtcpSender.SetREMBData(bitrate, numberOfSSRC, SSRC); +} + /* * (TMMBR) Temporary Max Media Bit Rate */ @@ -1538,7 +1571,6 @@ ModuleRtpRtcpImpl::SetTMMBRStatus(const bool enable) { WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetTMMBRStatus(disable)"); } - return _rtcpSender.SetTMMBRStatus(enable); } @@ -1642,7 +1674,7 @@ ModuleRtpRtcpImpl::SendNACK(const WebRtc_UWord16* nackList, { waitTime = 100; //During startup we don't have an RTT } - const WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS(); + const WebRtc_UWord32 now = ModuleRTPUtility::GetTimeInMS(); const WebRtc_UWord32 timeLimit = now - waitTime; if(_nackLastTimeSent < timeLimit) @@ -2023,9 +2055,6 @@ ModuleRtpRtcpImpl::SetFECUepProtection(const bool keyUseUepProtection, } } - /* - * Implementation of ModuleRtpRtcpPrivate - */ void ModuleRtpRtcpImpl::SetRemoteSSRC(const WebRtc_UWord32 SSRC) { @@ -2204,7 +2233,10 @@ ModuleRtpRtcpImpl::OnOverUseStateUpdate(const RateControlInput& rateControlInput // Send TMMBR immediately WebRtc_UWord16 RTT = 0; _rtcpReceiver.RTT(_rtpReceiver.SSRC(), &RTT, NULL,NULL,NULL); - _rtcpSender.SendRTCP(kRtcpTmmbr, 0, 0, RTT); + // About to send TMMBR, first run remote rate control + // to get a target bit rate. + _rtcpSender.CalculateNewTargetBitrate(RTT); + _rtcpSender.SendRTCP(kRtcpTmmbr); } return region; } @@ -2370,10 +2402,12 @@ ModuleRtpRtcpImpl::OnPacketLossStatisticsUpdate(const WebRtc_UWord8 fractionLost while(item) { // Get child RTP sender and ask for bitrate estimate - ModuleRtpRtcpPrivate* childModule = (ModuleRtpRtcpPrivate*)item->GetItem(); + ModuleRtpRtcpImpl* childModule = + static_cast(item->GetItem()); if (childModule->Sending()) { - RTPSender& childRtpSender = static_cast(item->GetItem())->_rtpSender; + RTPSender& childRtpSender = + static_cast(item->GetItem())->_rtpSender; WebRtc_UWord32 childEstimateBps = 1000*childRtpSender.TargetSendBitrateKbit(); if (childEstimateBps < minBitrateBps) { @@ -2504,7 +2538,7 @@ ModuleRtpRtcpImpl::UpdateTMMBR() ListItem* item = _childModules.First(); while(item) { - ModuleRtpRtcpPrivate* module = (ModuleRtpRtcpPrivate*)item->GetItem(); + ModuleRtpRtcpImpl* module = (ModuleRtpRtcpImpl*)item->GetItem(); WebRtc_Word32 tmpSize = module->TMMBRReceived(0,0, NULL); if(tmpSize > 0) { @@ -2521,7 +2555,7 @@ ModuleRtpRtcpImpl::UpdateTMMBR() item = _childModules.First(); while(item) { - ModuleRtpRtcpPrivate* module = (ModuleRtpRtcpPrivate*)item->GetItem(); + ModuleRtpRtcpImpl* module = (ModuleRtpRtcpImpl*)item->GetItem(); if(size > accNumCandidates && module) { WebRtc_Word32 accSize = module->TMMBRReceived(size, accNumCandidates, candidateSet); @@ -2571,7 +2605,7 @@ ModuleRtpRtcpImpl::UpdateTMMBR() ListItem* item = _childModules.First(); while(item) { - ModuleRtpRtcpPrivate* module = (ModuleRtpRtcpPrivate*)item->GetItem(); + ModuleRtpRtcpImpl* module = (ModuleRtpRtcpImpl*)item->GetItem(); if( module) { module->SetTMMBN(boundingSet, _rtpSender.MaxConfiguredBitrateVideo()/1000); diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h index b0be027c0..09fb3f44b 100644 --- a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -12,7 +12,6 @@ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_IMPL_H_ #include "rtp_rtcp.h" -#include "rtp_rtcp_private.h" #include "rtp_sender.h" #include "rtp_receiver.h" @@ -28,7 +27,7 @@ class MatlabPlot; namespace webrtc { -class ModuleRtpRtcpImpl : public ModuleRtpRtcpPrivate, private TMMBRHelp +class ModuleRtpRtcpImpl : public RtpRtcp, private TMMBRHelp { public: ModuleRtpRtcpImpl(const WebRtc_Word32 id, @@ -317,6 +316,16 @@ public: virtual WebRtc_Word32 RemoveRTCPReportBlock(const WebRtc_UWord32 SSRC); + /* + * (REMB) Receiver Estimated Max Bitrate + */ + virtual bool REMB() const; + + virtual WebRtc_Word32 SetREMBStatus(const bool enable); + + virtual WebRtc_Word32 SetREMBData(const WebRtc_UWord32 bitrate, + const WebRtc_UWord8 numberOfSSRC, + const WebRtc_UWord32* SSRC); /* * (TMMBR) Temporary Max Media Bit Rate */ @@ -453,22 +462,20 @@ public: virtual WebRtc_Word32 SetH263InverseLogic(const bool enable); - // only for internal testing - WebRtc_UWord32 LastSendReport(WebRtc_UWord32& lastRTCPTime); + virtual WebRtc_Word32 LastReceivedNTP(WebRtc_UWord32& NTPsecs, + WebRtc_UWord32& NTPfrac, + WebRtc_UWord32& remoteSR); -protected: - virtual void RegisterChildModule(RtpRtcp* module); + virtual WebRtc_Word32 BoundingSet(bool &tmmbrOwner, + TMMBRSet*& boundingSetRec); - virtual void DeRegisterChildModule(RtpRtcp* module); + virtual WebRtc_UWord32 BitrateSent() const; - bool UpdateRTCPReceiveInformationTimers(); - - void ProcessDeadOrAliveTimer(); - - /* - * Implementation of ModuleRtpRtcpPrivate - */ virtual void SetRemoteSSRC(const WebRtc_UWord32 SSRC); + + virtual WebRtc_UWord32 SendTimeOfSendReport(const WebRtc_UWord32 sendReport); + + virtual RateControlRegion OnOverUseStateUpdate(const RateControlInput& rateControlInput); virtual void OnReceivedNTP() ; @@ -478,7 +485,6 @@ protected: const WebRtc_UWord32 lastReceivedExtendedHighSeqNum, const WebRtc_UWord32 jitter); - // bw estimation virtual void OnReceivedTMMBR(); virtual void OnBandwidthEstimateUpdate(WebRtc_UWord16 bandWidthKbit); @@ -486,8 +492,6 @@ protected: virtual void OnReceivedBandwidthEstimateUpdate(const WebRtc_UWord16 bwEstimateMinKbit, const WebRtc_UWord16 bwEstimateMaxKbit); - virtual RateControlRegion OnOverUseStateUpdate(const RateControlInput& rateControlInput); - // bad state of RTP receiver request a keyframe virtual void OnRequestIntraFrame(const FrameType frameType); @@ -506,14 +510,17 @@ protected: const WebRtc_UWord16* nackSequenceNumbers); virtual void OnRequestSendReport(); + // only for internal testing + WebRtc_UWord32 LastSendReport(WebRtc_UWord32& lastRTCPTime); - virtual WebRtc_UWord32 SendTimeOfSendReport(const WebRtc_UWord32 sendReport); +protected: + virtual void RegisterChildModule(RtpRtcp* module); - virtual WebRtc_Word32 LastReceivedNTP(WebRtc_UWord32& NTPsecs, // when we received the last report - WebRtc_UWord32& NTPfrac, - WebRtc_UWord32& remoteSR); // NTP inside the last received (mid 16 bits from sec and frac) + virtual void DeRegisterChildModule(RtpRtcp* module); - virtual WebRtc_UWord32 BitrateSent() const; + bool UpdateRTCPReceiveInformationTimers(); + + void ProcessDeadOrAliveTimer(); virtual WebRtc_UWord32 BitrateReceivedNow() const; @@ -522,35 +529,33 @@ protected: virtual WebRtc_Word32 UpdateTMMBR(); - virtual WebRtc_Word32 BoundingSet(bool &tmmbrOwner, - TMMBRSet*& boundingSetRec); - RTPSender _rtpSender; RTPReceiver _rtpReceiver; + RTCPSender _rtcpSender; + RTCPReceiver _rtcpReceiver; private: void SendKeyFrame(); - WebRtc_Word32 _id; + WebRtc_Word32 _id; const bool _audio; bool _collisionDetected; - WebRtc_UWord32 _lastProcessTime; - WebRtc_UWord16 _packetOverHead; + WebRtc_UWord32 _lastProcessTime; + WebRtc_UWord16 _packetOverHead; - CriticalSectionWrapper& _criticalSectionModulePtrs; - CriticalSectionWrapper& _criticalSectionModulePtrsFeedback; - ModuleRtpRtcpPrivate* _defaultModule; - ModuleRtpRtcpPrivate* _audioModule; - ModuleRtpRtcpPrivate* _videoModule; - ListWrapper _childModules; + CriticalSectionWrapper& _criticalSectionModulePtrs; + CriticalSectionWrapper& _criticalSectionModulePtrsFeedback; + ModuleRtpRtcpImpl* _defaultModule; + ModuleRtpRtcpImpl* _audioModule; + ModuleRtpRtcpImpl* _videoModule; + ListWrapper _childModules; // Dead or alive bool _deadOrAliveActive; - WebRtc_UWord32 _deadOrAliveTimeoutMS; - WebRtc_UWord32 _deadOrAliveLastTimer; + WebRtc_UWord32 _deadOrAliveTimeoutMS; + WebRtc_UWord32 _deadOrAliveLastTimer; // receive side - RTCPReceiver _rtcpReceiver; BandwidthManagement _bandwidthManagement; WebRtc_UWord32 _receivedNTPsecsAudio; @@ -559,7 +564,6 @@ private: WebRtc_UWord32 _RTCPArrivalTimeFracAudio; // send side - RTCPSender _rtcpSender; NACKMethod _nackMethod; WebRtc_UWord32 _nackLastTimeSent; WebRtc_UWord16 _nackLastSeqNumberSent; diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_private.h b/src/modules/rtp_rtcp/source/rtp_rtcp_private.h deleted file mode 100644 index b09bcb834..000000000 --- a/src/modules/rtp_rtcp/source/rtp_rtcp_private.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2011 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 - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_PRIVATE_H_ -#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_PRIVATE_H_ - -#include "bwe_defines.h" -#include "rtp_rtcp.h" -#include "tmmbr_help.h" -#include "rtp_utility.h" - -namespace webrtc { -class ModuleRtpRtcpPrivate : public RtpRtcp -{ -public: - virtual void RegisterChildModule(RtpRtcp* module) = 0; - virtual void DeRegisterChildModule(RtpRtcp* module) = 0; - - virtual WebRtc_Word32 RegisterVideoModule(RtpRtcp* videoModule) = 0; - virtual void DeRegisterVideoModule() = 0; - - virtual void SetRemoteSSRC(const WebRtc_UWord32 SSRC) = 0; - - virtual WebRtc_Word8 SendPayloadType() const = 0; - - virtual RtpVideoCodecTypes ReceivedVideoCodec() const = 0; - - virtual RtpVideoCodecTypes SendVideoCodec() const = 0; - - // lipsync - virtual void OnReceivedNTP() = 0; - - // bw estimation - virtual void OnPacketLossStatisticsUpdate(const WebRtc_UWord8 fractionLost, - const WebRtc_UWord16 roundTripTime, - const WebRtc_UWord32 lastReceivedExtendedHighSeqNum, - const WebRtc_UWord32 jitter) = 0; - - // bw estimation - virtual void OnReceivedTMMBR() = 0; - - // bw estimation - virtual void OnReceivedBandwidthEstimateUpdate( const WebRtc_UWord16 bwEstimateMinKbit, - const WebRtc_UWord16 bwEstimateMaxKbit ) = 0; - - // - virtual RateControlRegion OnOverUseStateUpdate(const RateControlInput& rateControlInput) = 0; - - // received a request for a new key frame - virtual void OnReceivedIntraFrameRequest(const WebRtc_UWord8 message) = 0; - - // received a request for a new SLI - virtual void OnReceivedSliceLossIndication(const WebRtc_UWord8 pictureID) = 0; - - // received a new refereence frame - virtual void OnReceivedReferencePictureSelectionIndication(const WebRtc_UWord64 pitureID) = 0; - - // request for a RTCP send report - virtual void OnRequestSendReport() = 0; - - // Get remote SequenceNumber - virtual WebRtc_UWord16 RemoteSequenceNumber() const = 0; - - virtual WebRtc_UWord32 PacketCountSent() const = 0; - - virtual int CurrentSendFrequencyHz() const = 0; - - virtual WebRtc_UWord32 ByteCountSent() const = 0; - - virtual WebRtc_UWord32 BitrateReceivedNow() const = 0; - - virtual WebRtc_UWord32 SendTimeOfSendReport(const WebRtc_UWord32 sendReport) = 0; - - virtual WebRtc_Word32 LastReceivedNTP(WebRtc_UWord32& NTPsecs, // when we received the last report - WebRtc_UWord32& NTPfrac, - WebRtc_UWord32& remoteSR) = 0; // NTP inside the last received (mid 16 bits from sec and frac) - - virtual WebRtc_Word32 ReportBlockStatistics(WebRtc_UWord8 *fraction_lost, - WebRtc_UWord32 *cum_lost, - WebRtc_UWord32 *ext_max, - WebRtc_UWord32 *jitter) = 0; - - // bad state of RTP receiver request a keyframe - virtual void OnRequestIntraFrame( const FrameType frameType) = 0; - - /* - * NACK - */ - virtual void OnReceivedNACK(const WebRtc_UWord16 nackSequenceNumbersLength, - const WebRtc_UWord16* nackSequenceNumbers) = 0; - - /* - * TMMBR - */ - virtual WebRtc_Word32 UpdateTMMBR() = 0; - - virtual WebRtc_Word32 SetTMMBN(const TMMBRSet* boundingSet, - const WebRtc_UWord32 maxBitrateKbit) = 0; - - virtual WebRtc_Word32 BoundingSet(bool &tmmbrOwner, - TMMBRSet*& boundingSetRec)= 0; - - virtual WebRtc_Word32 TMMBRReceived(const WebRtc_UWord32 size, - const WebRtc_UWord32 accNumCandidates, - TMMBRSet* candidateSet) const = 0; -}; -} // namespace webrtc -#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_PRIVATE_H_ diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi b/src/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi index 6eed8d05b..b096d4d4d 100644 --- a/src/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi +++ b/src/modules/rtp_rtcp/source/rtp_rtcp_tests.gypi @@ -23,6 +23,23 @@ 'rtp_format_vp8_unittest.cc', ], }, + { + 'target_name': 'rtcp_format_remb_unittest', + 'type': 'executable', + 'dependencies': [ + 'rtp_rtcp', + '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', + '../../testing/gtest.gyp:gtest', + '../../testing/gtest.gyp:gtest_main', + ], + 'include_dirs': [ + '.', + '../../../', + ], + 'sources': [ + 'rtcp_format_remb_unittest.cc', + ], + }, { 'target_name': 'rtp_utility_test', 'type': 'executable',