Added support for new RTCP message REMB (remote estimated max bitrate)
Review URL: http://webrtc-codereview.appspot.com/149001 git-svn-id: http://webrtc.googlecode.com/svn/trunk@628 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
679e64d1fc
commit
741da942ec
@ -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
|
||||
*/
|
||||
|
@ -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,
|
||||
|
117
src/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
Normal file
117
src/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
Normal file
@ -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 <gtest/gtest.h>
|
||||
|
||||
#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
|
@ -9,13 +9,14 @@
|
||||
*/
|
||||
|
||||
#include "rtcp_receiver.h"
|
||||
#include "rtcp_utility.h"
|
||||
|
||||
#include <string.h> //memset
|
||||
#include <cassert> //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];
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "rtp_receiver.h"
|
||||
|
||||
#include "rtp_rtcp_defines.h"
|
||||
#include "rtp_rtcp_impl.h"
|
||||
#include "critical_section_wrapper.h"
|
||||
|
||||
#include <cassert>
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -8,16 +8,16 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "rtp_receiver_video.h"
|
||||
|
||||
#include <cassert> //assert
|
||||
#include <cstring> // memcpy()
|
||||
#include <math.h>
|
||||
|
||||
#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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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<ModuleRtpRtcpImpl*>(item->GetItem());
|
||||
if (childModule->Sending())
|
||||
{
|
||||
RTPSender& childRtpSender = static_cast<ModuleRtpRtcpImpl*>(item->GetItem())->_rtpSender;
|
||||
RTPSender& childRtpSender =
|
||||
static_cast<ModuleRtpRtcpImpl*>(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);
|
||||
|
@ -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;
|
||||
|
@ -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_
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user