diff options
Diffstat (limited to 'modules/rtp_rtcp/source')
-rw-r--r-- | modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc | 1 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtcp_sender.cc | 83 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtcp_sender.h | 182 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtcp_sender_unittest.cc | 1 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_format_vp8.cc | 2 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 28 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_rtcp_impl.h | 7 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender.cc | 100 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender.h | 19 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender_unittest.cc | 52 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender_video.cc | 11 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/tmmbr_help.cc | 279 |
12 files changed, 378 insertions, 387 deletions
diff --git a/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc index 88463e47..0514277f 100644 --- a/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc +++ b/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc @@ -97,7 +97,6 @@ void RtcpFormatRembTest::SetUp() { rtcp_receiver_ = new RTCPReceiver(0, system_clock_, dummy_rtp_rtcp_impl_); test_transport_ = new TestTransport(rtcp_receiver_); - EXPECT_EQ(0, rtcp_sender_->Init()); EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_)); } diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc index b9ab0c1e..2cf7e1cb 100644 --- a/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/modules/rtp_rtcp/source/rtcp_sender.cc @@ -188,61 +188,6 @@ RTCPSender::~RTCPSender() { } int32_t -RTCPSender::Init() -{ - CriticalSectionScoped lock(_criticalSectionRTCPSender); - - _method = kRtcpOff; - _cbTransport = NULL; - _usingNack = false; - _sending = false; - _sendTMMBN = false; - _TMMBR = false; - _IJ = false; - _REMB = false; - _sendREMB = false; - last_rtp_timestamp_ = 0; - last_frame_capture_time_ms_ = -1; - start_timestamp_ = -1; - _SSRC = 0; - _remoteSSRC = 0; - _cameraDelayMS = 0; - _sequenceNumberFIR = 0; - _tmmbr_Send = 0; - _packetOH_Send = 0; - _nextTimeToSendRTCP = 0; - _CSRCs = 0; - _appSend = false; - _appSubType = 0; - - if(_appData) - { - delete [] _appData; - _appData = NULL; - } - _appLength = 0; - - xrSendReceiverReferenceTimeEnabled_ = false; - - _xrSendVoIPMetric = false; - - memset(&_xrVoIPMetric, 0, sizeof(_xrVoIPMetric)); - memset(_CNAME, 0, sizeof(_CNAME)); - memset(_lastSendReport, 0, sizeof(_lastSendReport)); - memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); - last_xr_rr_.clear(); - - memset(&packet_type_counter_, 0, sizeof(packet_type_counter_)); - return 0; -} - -void -RTCPSender::ChangeUniqueId(const int32_t id) -{ - _id = id; -} - -int32_t RTCPSender::RegisterSendTransport(Transport* outgoingTransport) { CriticalSectionScoped lock(_criticalSectionTransport); @@ -330,17 +275,17 @@ RTCPSender::SetREMBData(const uint32_t bitrate, { CriticalSectionScoped lock(_criticalSectionRTCPSender); _rembBitrate = bitrate; - + if(_sizeRembSSRC < numberOfSSRC) { delete [] _rembSSRC; _rembSSRC = new uint32_t[numberOfSSRC]; _sizeRembSSRC = numberOfSSRC; - } + } _lengthRembSSRC = numberOfSSRC; for (int i = 0; i < numberOfSSRC; i++) - { + { _rembSSRC[i] = SSRC[i]; } _sendREMB = true; @@ -381,6 +326,7 @@ RTCPSender::SetIJStatus(const bool enable) } void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) { + CriticalSectionScoped lock(_criticalSectionRTCPSender); start_timestamp_ = start_timestamp; } @@ -431,14 +377,6 @@ RTCPSender::SetCameraDelay(const int32_t delayMS) return 0; } -int32_t RTCPSender::CNAME(char cName[RTCP_CNAME_SIZE]) { - assert(cName); - CriticalSectionScoped lock(_criticalSectionRTCPSender); - cName[RTCP_CNAME_SIZE - 1] = 0; - strncpy(cName, _CNAME, RTCP_CNAME_SIZE - 1); - return 0; -} - int32_t RTCPSender::SetCNAME(const char cName[RTCP_CNAME_SIZE]) { if (!cName) return -1; @@ -694,13 +632,9 @@ int32_t RTCPSender::BuildSR(const FeedbackState& feedback_state, // the frame being captured at this moment. We are calculating that // timestamp as the last frame's timestamp + the time since the last frame // was captured. - { - // Needs protection since this method is called on the process thread. - CriticalSectionScoped lock(_criticalSectionRTCPSender); - RTPtime = start_timestamp_ + last_rtp_timestamp_ + ( - _clock->TimeInMilliseconds() - last_frame_capture_time_ms_) * - (feedback_state.frequency_hz / 1000); - } + RTPtime = start_timestamp_ + last_rtp_timestamp_ + + (_clock->TimeInMilliseconds() - last_frame_capture_time_ms_) * + (feedback_state.frequency_hz / 1000); // Add sender data // Save for our length field @@ -1175,7 +1109,7 @@ RTCPSender::BuildREMB(uint8_t* rtcpbuffer, int& pos) rtcpbuffer[pos++]=(uint8_t)(brMantissa >> 8); rtcpbuffer[pos++]=(uint8_t)(brMantissa); - for (int i = 0; i < _lengthRembSSRC; i++) + for (int i = 0; i < _lengthRembSSRC; i++) { RtpUtility::AssignUWord32ToBuffer(rtcpbuffer + pos, _rembSSRC[i]); pos += 4; @@ -2110,6 +2044,7 @@ RTCPSender::SendToNetwork(const uint8_t* dataBuffer, int32_t RTCPSender::SetCSRCStatus(const bool include) { + CriticalSectionScoped lock(_criticalSectionRTCPSender); _includeCSRCs = include; return 0; } diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h index cbbc32aa..fad3b5e3 100644 --- a/modules/rtp_rtcp/source/rtcp_sender.h +++ b/modules/rtp_rtcp/source/rtcp_sender.h @@ -23,6 +23,7 @@ #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" #include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/system_wrappers/interface/thread_annotations.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -74,10 +75,6 @@ public: ReceiveStatistics* receive_statistics); virtual ~RTCPSender(); - void ChangeUniqueId(const int32_t id); - - int32_t Init(); - int32_t RegisterSendTransport(Transport* outgoingTransport); RTCPMethod Status() const; @@ -100,7 +97,6 @@ public: int32_t SetCameraDelay(const int32_t delayMS); - int32_t CNAME(char cName[RTCP_CNAME_SIZE]); int32_t SetCNAME(const char cName[RTCP_CNAME_SIZE]); int32_t AddMixedCNAME(const uint32_t SSRC, @@ -185,13 +181,12 @@ public: private: int32_t SendToNetwork(const uint8_t* dataBuffer, const uint16_t length); - void UpdatePacketRate(); - int32_t WriteAllReportBlocksToBuffer(uint8_t* rtcpbuffer, int pos, uint8_t& numberOfReportBlocks, const uint32_t NTPsec, - const uint32_t NTPfrac); + const uint32_t NTPfrac) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); int32_t WriteReportBlocksToBuffer( uint8_t* rtcpbuffer, @@ -212,12 +207,14 @@ private: uint8_t* rtcpbuffer, int& pos, uint32_t NTPsec, - uint32_t NTPfrac); + uint32_t NTPfrac) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); int32_t BuildRR(uint8_t* rtcpbuffer, int& pos, const uint32_t NTPsec, - const uint32_t NTPfrac); + const uint32_t NTPfrac) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); int PrepareRTCP( const FeedbackState& feedback_state, @@ -234,117 +231,136 @@ private: int32_t BuildExtendedJitterReport( uint8_t* rtcpbuffer, int& pos, - const uint32_t jitterTransmissionTimeOffset); - - int32_t BuildSDEC(uint8_t* rtcpbuffer, int& pos); - int32_t BuildPLI(uint8_t* rtcpbuffer, int& pos); - int32_t BuildREMB(uint8_t* rtcpbuffer, int& pos); - int32_t BuildTMMBR(ModuleRtpRtcpImpl* module, - uint8_t* rtcpbuffer, - int& pos); - int32_t BuildTMMBN(uint8_t* rtcpbuffer, int& pos); - int32_t BuildAPP(uint8_t* rtcpbuffer, int& pos); - int32_t BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos); - int32_t BuildBYE(uint8_t* rtcpbuffer, int& pos); - int32_t BuildFIR(uint8_t* rtcpbuffer, int& pos, bool repeat); - int32_t BuildSLI(uint8_t* rtcpbuffer, - int& pos, - const uint8_t pictureID); + const uint32_t jitterTransmissionTimeOffset) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + + int32_t BuildSDEC(uint8_t* rtcpbuffer, int& pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildPLI(uint8_t* rtcpbuffer, int& pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildREMB(uint8_t* rtcpbuffer, int& pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildTMMBR(ModuleRtpRtcpImpl* module, uint8_t* rtcpbuffer, int& pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildTMMBN(uint8_t* rtcpbuffer, int& pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildAPP(uint8_t* rtcpbuffer, int& pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildBYE(uint8_t* rtcpbuffer, int& pos) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildFIR(uint8_t* rtcpbuffer, int& pos, bool repeat) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); + int32_t BuildSLI(uint8_t* rtcpbuffer, int& pos, const uint8_t pictureID) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); int32_t BuildRPSI(uint8_t* rtcpbuffer, int& pos, const uint64_t pictureID, - const uint8_t payloadType); + const uint8_t payloadType) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); int32_t BuildNACK(uint8_t* rtcpbuffer, int& pos, const int32_t nackSize, const uint16_t* nackList, - std::string* nackString); - + std::string* nackString) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); int32_t BuildReceiverReferenceTime(uint8_t* buffer, int& pos, uint32_t ntp_sec, - uint32_t ntp_frac); + uint32_t ntp_frac) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); int32_t BuildDlrr(uint8_t* buffer, int& pos, - const RtcpReceiveTimeInfo& info); + const RtcpReceiveTimeInfo& info) + EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPSender); private: - int32_t _id; + const int32_t _id; const bool _audio; - Clock* _clock; - RTCPMethod _method; + Clock* const _clock; + RTCPMethod _method GUARDED_BY(_criticalSectionRTCPSender); CriticalSectionWrapper* _criticalSectionTransport; - Transport* _cbTransport; + Transport* _cbTransport GUARDED_BY(_criticalSectionTransport); CriticalSectionWrapper* _criticalSectionRTCPSender; - bool _usingNack; - bool _sending; - bool _sendTMMBN; - bool _REMB; - bool _sendREMB; - bool _TMMBR; - bool _IJ; - - int64_t _nextTimeToSendRTCP; - - uint32_t start_timestamp_; - uint32_t last_rtp_timestamp_; - int64_t last_frame_capture_time_ms_; - uint32_t _SSRC; - uint32_t _remoteSSRC; // SSRC that we receive on our RTP channel - char _CNAME[RTCP_CNAME_SIZE]; - - - ReceiveStatistics* receive_statistics_; - std::map<uint32_t, RTCPReportBlock*> internal_report_blocks_; - std::map<uint32_t, RTCPReportBlock*> external_report_blocks_; - std::map<uint32_t, RTCPUtility::RTCPCnameInformation*> _csrcCNAMEs; - - int32_t _cameraDelayMS; + bool _usingNack GUARDED_BY(_criticalSectionRTCPSender); + bool _sending GUARDED_BY(_criticalSectionRTCPSender); + bool _sendTMMBN GUARDED_BY(_criticalSectionRTCPSender); + bool _REMB GUARDED_BY(_criticalSectionRTCPSender); + bool _sendREMB GUARDED_BY(_criticalSectionRTCPSender); + bool _TMMBR GUARDED_BY(_criticalSectionRTCPSender); + bool _IJ GUARDED_BY(_criticalSectionRTCPSender); + + int64_t _nextTimeToSendRTCP GUARDED_BY(_criticalSectionRTCPSender); + + uint32_t start_timestamp_ GUARDED_BY(_criticalSectionRTCPSender); + uint32_t last_rtp_timestamp_ GUARDED_BY(_criticalSectionRTCPSender); + int64_t last_frame_capture_time_ms_ GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _SSRC GUARDED_BY(_criticalSectionRTCPSender); + // SSRC that we receive on our RTP channel + uint32_t _remoteSSRC GUARDED_BY(_criticalSectionRTCPSender); + char _CNAME[RTCP_CNAME_SIZE] GUARDED_BY(_criticalSectionRTCPSender); + + ReceiveStatistics* receive_statistics_ + GUARDED_BY(_criticalSectionRTCPSender); + std::map<uint32_t, RTCPReportBlock*> internal_report_blocks_ + GUARDED_BY(_criticalSectionRTCPSender); + std::map<uint32_t, RTCPReportBlock*> external_report_blocks_ + GUARDED_BY(_criticalSectionRTCPSender); + std::map<uint32_t, RTCPUtility::RTCPCnameInformation*> _csrcCNAMEs + GUARDED_BY(_criticalSectionRTCPSender); + + int32_t _cameraDelayMS GUARDED_BY(_criticalSectionRTCPSender); // Sent - uint32_t _lastSendReport[RTCP_NUMBER_OF_SR]; // allow packet loss and RTT above 1 sec - uint32_t _lastRTCPTime[RTCP_NUMBER_OF_SR]; + uint32_t _lastSendReport[RTCP_NUMBER_OF_SR] GUARDED_BY( + _criticalSectionRTCPSender); // allow packet loss and RTT above 1 sec + uint32_t _lastRTCPTime[RTCP_NUMBER_OF_SR] GUARDED_BY( + _criticalSectionRTCPSender); // Sent XR receiver reference time report. // <mid ntp (mid 32 bits of the 64 bits NTP timestamp), send time in ms>. - std::map<uint32_t, int64_t> last_xr_rr_; + std::map<uint32_t, int64_t> last_xr_rr_ + GUARDED_BY(_criticalSectionRTCPSender); // send CSRCs - uint8_t _CSRCs; - uint32_t _CSRC[kRtpCsrcSize]; - bool _includeCSRCs; + uint8_t _CSRCs GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _CSRC[kRtpCsrcSize] GUARDED_BY(_criticalSectionRTCPSender); + bool _includeCSRCs GUARDED_BY(_criticalSectionRTCPSender); // Full intra request - uint8_t _sequenceNumberFIR; + uint8_t _sequenceNumberFIR GUARDED_BY(_criticalSectionRTCPSender); - // REMB - uint8_t _lengthRembSSRC; - uint8_t _sizeRembSSRC; - uint32_t* _rembSSRC; - uint32_t _rembBitrate; + // REMB + uint8_t _lengthRembSSRC GUARDED_BY(_criticalSectionRTCPSender); + uint8_t _sizeRembSSRC GUARDED_BY(_criticalSectionRTCPSender); + uint32_t* _rembSSRC GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _rembBitrate GUARDED_BY(_criticalSectionRTCPSender); - TMMBRHelp _tmmbrHelp; - uint32_t _tmmbr_Send; - uint32_t _packetOH_Send; + TMMBRHelp _tmmbrHelp GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _tmmbr_Send GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _packetOH_Send GUARDED_BY(_criticalSectionRTCPSender); // APP - bool _appSend; - uint8_t _appSubType; - uint32_t _appName; - uint8_t* _appData; - uint16_t _appLength; + bool _appSend GUARDED_BY(_criticalSectionRTCPSender); + uint8_t _appSubType GUARDED_BY(_criticalSectionRTCPSender); + uint32_t _appName GUARDED_BY(_criticalSectionRTCPSender); + uint8_t* _appData GUARDED_BY(_criticalSectionRTCPSender); + uint16_t _appLength GUARDED_BY(_criticalSectionRTCPSender); // True if sending of XR Receiver reference time report is enabled. - bool xrSendReceiverReferenceTimeEnabled_; + bool xrSendReceiverReferenceTimeEnabled_ + GUARDED_BY(_criticalSectionRTCPSender); // XR VoIP metric - bool _xrSendVoIPMetric; - RTCPVoIPMetric _xrVoIPMetric; + bool _xrSendVoIPMetric GUARDED_BY(_criticalSectionRTCPSender); + RTCPVoIPMetric _xrVoIPMetric GUARDED_BY(_criticalSectionRTCPSender); - RtcpPacketTypeCounter packet_type_counter_; + RtcpPacketTypeCounter packet_type_counter_ + GUARDED_BY(_criticalSectionRTCPSender); }; } // namespace webrtc diff --git a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc index dfb655c5..cba1c346 100644 --- a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc +++ b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc @@ -304,7 +304,6 @@ class RtcpSenderTest : public ::testing::Test { rtcp_receiver_ = new RTCPReceiver(0, &clock_, rtp_rtcp_impl_); test_transport_->SetRTCPReceiver(rtcp_receiver_); // Initialize - EXPECT_EQ(0, rtcp_sender_->Init()); EXPECT_EQ(0, rtcp_sender_->RegisterSendTransport(test_transport_)); } ~RtcpSenderTest() { diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.cc b/modules/rtp_rtcp/source/rtp_format_vp8.cc index 360176b3..9c04c25a 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp8.cc +++ b/modules/rtp_rtcp/source/rtp_format_vp8.cc @@ -420,7 +420,7 @@ int RtpFormatVp8::WriteTIDAndKeyIdxFields(uint8_t* x_field, *data_field = 0; if (TIDFieldPresent()) { *x_field |= kTBit; - assert(hdr_info_.temporalIdx >= 0 && hdr_info_.temporalIdx <= 3); + assert(hdr_info_.temporalIdx <= 3); *data_field |= hdr_info_.temporalIdx << 6; *data_field |= hdr_info_.layerSync ? kYBit : 0; } diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 855d51b7..349340f5 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -38,20 +38,21 @@ RtpRtcp::Configuration::Configuration() audio_messages(NullObjectRtpAudioFeedback()), remote_bitrate_estimator(NULL), paced_sender(NULL), - send_bitrate_observer(NULL) { + send_bitrate_observer(NULL), + send_frame_count_observer(NULL), + send_side_delay_observer(NULL) { } RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) { if (configuration.clock) { return new ModuleRtpRtcpImpl(configuration); } else { + // No clock implementation provided, use default clock. RtpRtcp::Configuration configuration_copy; memcpy(&configuration_copy, &configuration, sizeof(RtpRtcp::Configuration)); configuration_copy.clock = Clock::GetRealTimeClock(); - ModuleRtpRtcpImpl* rtp_rtcp_instance = - new ModuleRtpRtcpImpl(configuration_copy); - return rtp_rtcp_instance; + return new ModuleRtpRtcpImpl(configuration_copy); } } @@ -62,7 +63,9 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration) configuration.outgoing_transport, configuration.audio_messages, configuration.paced_sender, - configuration.send_bitrate_observer), + configuration.send_bitrate_observer, + configuration.send_frame_count_observer, + configuration.send_side_delay_observer), rtcp_sender_(configuration.id, configuration.audio, configuration.clock, @@ -82,7 +85,7 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration) CriticalSectionWrapper::CreateCriticalSection()), default_module_( static_cast<ModuleRtpRtcpImpl*>(configuration.default_module)), - padding_index_(-1), // Start padding at the first child module. + padding_index_(static_cast<size_t>(-1)), // Start padding at first child. nack_method_(kNackOff), nack_last_time_sent_full_(0), nack_last_seq_number_sent_(0), @@ -722,10 +725,6 @@ int32_t ModuleRtpRtcpImpl::SetCNAME(const char c_name[RTCP_CNAME_SIZE]) { return rtcp_sender_.SetCNAME(c_name); } -int32_t ModuleRtpRtcpImpl::CNAME(char c_name[RTCP_CNAME_SIZE]) { - return rtcp_sender_.CNAME(c_name); -} - int32_t ModuleRtpRtcpImpl::AddMixedCNAME( const uint32_t ssrc, const char c_name[RTCP_CNAME_SIZE]) { @@ -1350,15 +1349,6 @@ StreamDataCountersCallback* return rtp_sender_.GetRtpStatisticsCallback(); } -void ModuleRtpRtcpImpl::RegisterSendFrameCountObserver( - FrameCountObserver* observer) { - rtp_sender_.RegisterFrameCountObserver(observer); -} - -FrameCountObserver* ModuleRtpRtcpImpl::GetSendFrameCountObserver() const { - return rtp_sender_.GetFrameCountObserver(); -} - bool ModuleRtpRtcpImpl::IsDefaultModule() const { CriticalSectionScoped cs(critical_section_module_ptrs_.get()); return !child_modules_.empty(); diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h index b65131fb..7e7ea027 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -148,9 +148,6 @@ class ModuleRtpRtcpImpl : public RtpRtcp { // Set RTCP CName. virtual int32_t SetCNAME(const char c_name[RTCP_CNAME_SIZE]) OVERRIDE; - // Get RTCP CName. - virtual int32_t CNAME(char c_name[RTCP_CNAME_SIZE]) OVERRIDE; - // Get remote CName. virtual int32_t RemoteCNAME(const uint32_t remote_ssrc, char c_name[RTCP_CNAME_SIZE]) const OVERRIDE; @@ -373,10 +370,6 @@ class ModuleRtpRtcpImpl : public RtpRtcp { void OnRequestSendReport(); - virtual void RegisterSendFrameCountObserver( - FrameCountObserver* observer) OVERRIDE; - virtual FrameCountObserver* GetSendFrameCountObserver() const OVERRIDE; - protected: void RegisterChildModule(RtpRtcp* module); diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc index 858fc42a..c24b15a3 100644 --- a/modules/rtp_rtcp/source/rtp_sender.cc +++ b/modules/rtp_rtcp/source/rtp_sender.cc @@ -46,7 +46,9 @@ RTPSender::RTPSender(const int32_t id, Transport* transport, RtpAudioFeedback* audio_feedback, PacedSender* paced_sender, - BitrateStatisticsObserver* bitrate_callback) + BitrateStatisticsObserver* bitrate_callback, + FrameCountObserver* frame_count_observer, + SendSideDelayObserver* send_side_delay_observer) : clock_(clock), bitrate_sent_(clock, this), id_(id), @@ -71,9 +73,10 @@ RTPSender::RTPSender(const int32_t id, packet_history_(clock), // Statistics statistics_crit_(CriticalSectionWrapper::CreateCriticalSection()), - frame_count_observer_(NULL), rtp_stats_callback_(NULL), bitrate_callback_(bitrate_callback), + frame_count_observer_(frame_count_observer), + send_side_delay_observer_(send_side_delay_observer), // RTP variables start_timestamp_forced_(false), start_timestamp_(0), @@ -163,9 +166,7 @@ uint32_t RTPSender::NackOverheadRate() const { bool RTPSender::GetSendSideDelay(int* avg_send_delay_ms, int* max_send_delay_ms) const { - if (!SendingMedia()) - return false; - CriticalSectionScoped cs(statistics_crit_.get()); + CriticalSectionScoped lock(statistics_crit_.get()); SendDelayMap::const_iterator it = send_delays_.upper_bound( clock_->TimeInMilliseconds() - kSendSideDelayWindowMs); if (it == send_delays_.end()) @@ -508,7 +509,7 @@ bool RTPSender::SendPaddingAccordingToBitrate( last_timestamp_time_ms_ = clock_->TimeInMilliseconds(); } int bytes_sent = SendPadData(payload_type, timestamp, capture_time_ms, - bytes, kDontRetransmit, false, false); + bytes, false, false); // We did not manage to send all bytes. Comparing with 31 due to modulus 32. return bytes - bytes_sent < 31; } @@ -532,10 +533,12 @@ int RTPSender::BuildPaddingPacket(uint8_t* packet, int header_length, return padding_bytes_in_packet; } -int RTPSender::SendPadData(int payload_type, uint32_t timestamp, - int64_t capture_time_ms, int32_t bytes, - StorageType store, bool force_full_size_packets, - bool only_pad_after_markerbit) { +int RTPSender::SendPadData(int payload_type, + uint32_t timestamp, + int64_t capture_time_ms, + int32_t bytes, + bool force_full_size_packets, + bool over_rtx) { // Drop this packet if we're not sending media packets. if (!SendingMedia()) { return bytes; @@ -564,7 +567,7 @@ int RTPSender::SendPadData(int payload_type, uint32_t timestamp, CriticalSectionScoped cs(send_critsect_); // Only send padding packets following the last packet of a frame, // indicated by the marker bit. - if (only_pad_after_markerbit && !last_packet_marker_bit_) + if (!over_rtx && !last_packet_marker_bit_) return bytes_sent; if (rtx_ == kRtxOff) { ssrc = ssrc_; @@ -578,19 +581,35 @@ int RTPSender::SendPadData(int payload_type, uint32_t timestamp, } uint8_t padding_packet[IP_PACKET_SIZE]; - int header_length = CreateRTPHeader(padding_packet, payload_type, ssrc, - false, timestamp, sequence_number, NULL, + int header_length = CreateRTPHeader(padding_packet, + payload_type, + ssrc, + false, + timestamp, + sequence_number, + NULL, 0); - padding_bytes_in_packet = BuildPaddingPacket(padding_packet, header_length, - bytes); - if (0 > SendToNetwork(padding_packet, padding_bytes_in_packet, - header_length, capture_time_ms, store, - PacedSender::kLowPriority)) { - // Error sending the packet. - break; + padding_bytes_in_packet = + BuildPaddingPacket(padding_packet, header_length, bytes); + int length = padding_bytes_in_packet + header_length; + int64_t now_ms = clock_->TimeInMilliseconds(); + + RtpUtility::RtpHeaderParser rtp_parser(padding_packet, length); + RTPHeader rtp_header; + rtp_parser.Parse(rtp_header); + + if (capture_time_ms > 0) { + UpdateTransmissionTimeOffset( + padding_packet, length, rtp_header, now_ms - capture_time_ms); } + + UpdateAbsoluteSendTime(padding_packet, length, rtp_header, now_ms); + if (!SendPacketToNetwork(padding_packet, length)) + break; bytes_sent += padding_bytes_in_packet; + UpdateRtpStats(padding_packet, length, rtp_header, over_rtx, false); } + return bytes_sent; } @@ -918,9 +937,8 @@ int RTPSender::TimeToSendPadding(int bytes) { timestamp, capture_time_ms, bytes, - kDontStore, true, - rtx == kRtxOff); + rtx != kRtxOff); bytes_sent += padding_sent; } return bytes_sent; @@ -979,10 +997,26 @@ int32_t RTPSender::SendToNetwork( } void RTPSender::UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms) { - CriticalSectionScoped cs(statistics_crit_.get()); - send_delays_[now_ms] = now_ms - capture_time_ms; - send_delays_.erase(send_delays_.begin(), - send_delays_.lower_bound(now_ms - kSendSideDelayWindowMs)); + uint32_t ssrc; + int avg_delay_ms = 0; + int max_delay_ms = 0; + { + CriticalSectionScoped lock(send_critsect_); + ssrc = ssrc_; + } + { + CriticalSectionScoped cs(statistics_crit_.get()); + // TODO(holmer): Compute this iteratively instead. + send_delays_[now_ms] = now_ms - capture_time_ms; + send_delays_.erase(send_delays_.begin(), + send_delays_.lower_bound(now_ms - + kSendSideDelayWindowMs)); + } + if (send_side_delay_observer_ && + GetSendSideDelay(&avg_delay_ms, &max_delay_ms)) { + send_side_delay_observer_->SendSideDelayUpdated(avg_delay_ms, + max_delay_ms, ssrc); + } } void RTPSender::ProcessBitrate() { @@ -1035,7 +1069,9 @@ uint32_t RTPSender::Packets() const { // Number of sent RTP bytes. uint32_t RTPSender::Bytes() const { CriticalSectionScoped lock(statistics_crit_.get()); - return rtp_stats_.bytes + rtx_rtp_stats_.bytes; + return rtp_stats_.bytes + rtp_stats_.header_bytes + rtp_stats_.padding_bytes + + rtx_rtp_stats_.bytes + rtx_rtp_stats_.header_bytes + + rtx_rtp_stats_.padding_bytes; } int RTPSender::CreateRTPHeader( @@ -1664,16 +1700,6 @@ void RTPSender::BuildRtxPacket(uint8_t* buffer, uint16_t* length, *length += 2; } -void RTPSender::RegisterFrameCountObserver(FrameCountObserver* observer) { - CriticalSectionScoped cs(statistics_crit_.get()); - frame_count_observer_ = observer; -} - -FrameCountObserver* RTPSender::GetFrameCountObserver() const { - CriticalSectionScoped cs(statistics_crit_.get()); - return frame_count_observer_; -} - void RTPSender::RegisterRtpStatisticsCallback( StreamDataCountersCallback* callback) { CriticalSectionScoped cs(statistics_crit_.get()); diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h index 0cc35cf4..4a9e10ed 100644 --- a/modules/rtp_rtcp/source/rtp_sender.h +++ b/modules/rtp_rtcp/source/rtp_sender.h @@ -70,7 +70,9 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer { RTPSender(const int32_t id, const bool audio, Clock *clock, Transport *transport, RtpAudioFeedback *audio_feedback, PacedSender *paced_sender, - BitrateStatisticsObserver* bitrate_callback); + BitrateStatisticsObserver* bitrate_callback, + FrameCountObserver* frame_count_observer, + SendSideDelayObserver* send_side_delay_observer); virtual ~RTPSender(); void ProcessBitrate(); @@ -265,12 +267,12 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer { int32_t SetFecParameters(const FecProtectionParams *delta_params, const FecProtectionParams *key_params); - virtual void RegisterFrameCountObserver(FrameCountObserver* observer); - virtual FrameCountObserver* GetFrameCountObserver() const; - - int SendPadData(int payload_type, uint32_t timestamp, int64_t capture_time_ms, - int32_t bytes, StorageType store, - bool force_full_size_packets, bool only_pad_after_markerbit); + int SendPadData(int payload_type, + uint32_t timestamp, + int64_t capture_time_ms, + int32_t bytes, + bool force_full_size_packets, + bool only_pad_after_markerbit); // Called on update of RTP statistics. void RegisterRtpStatisticsCallback(StreamDataCountersCallback* callback); @@ -373,11 +375,12 @@ class RTPSender : public RTPSenderInterface, public Bitrate::Observer { scoped_ptr<CriticalSectionWrapper> statistics_crit_; SendDelayMap send_delays_ GUARDED_BY(statistics_crit_); std::map<FrameType, uint32_t> frame_counts_ GUARDED_BY(statistics_crit_); - FrameCountObserver* frame_count_observer_ GUARDED_BY(statistics_crit_); StreamDataCounters rtp_stats_ GUARDED_BY(statistics_crit_); StreamDataCounters rtx_rtp_stats_ GUARDED_BY(statistics_crit_); StreamDataCountersCallback* rtp_stats_callback_ GUARDED_BY(statistics_crit_); BitrateStatisticsObserver* const bitrate_callback_; + FrameCountObserver* const frame_count_observer_; + SendSideDelayObserver* const send_side_delay_observer_; // RTP variables bool start_timestamp_forced_ GUARDED_BY(send_critsect_); diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc index e08aa202..40b10548 100644 --- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -62,13 +62,12 @@ uint64_t ConvertMsToAbsSendTime(int64_t time_ms) { class LoopbackTransportTest : public webrtc::Transport { public: LoopbackTransportTest() - : packets_sent_(0), - last_sent_packet_len_(0) { - } + : packets_sent_(0), last_sent_packet_len_(0), total_bytes_sent_(0) {} virtual int SendPacket(int channel, const void *data, int len) { packets_sent_++; memcpy(last_sent_packet_, data, len); last_sent_packet_len_ = len; + total_bytes_sent_ += static_cast<size_t>(len); return len; } virtual int SendRTCPPacket(int channel, const void *data, int len) { @@ -76,6 +75,7 @@ class LoopbackTransportTest : public webrtc::Transport { } int packets_sent_; int last_sent_packet_len_; + size_t total_bytes_sent_; uint8_t last_sent_packet_[kMaxPacketLength]; }; @@ -94,7 +94,7 @@ class RtpSenderTest : public ::testing::Test { virtual void SetUp() { rtp_sender_.reset(new RTPSender(0, false, &fake_clock_, &transport_, NULL, - &mock_paced_sender_, NULL)); + &mock_paced_sender_, NULL, NULL, NULL)); rtp_sender_->SetSequenceNumber(kSeqNum); } @@ -672,7 +672,7 @@ TEST_F(RtpSenderTest, SendPadding) { TEST_F(RtpSenderTest, SendRedundantPayloads) { MockTransport transport; rtp_sender_.reset(new RTPSender(0, false, &fake_clock_, &transport, NULL, - &mock_paced_sender_, NULL)); + &mock_paced_sender_, NULL, NULL, NULL)); rtp_sender_->SetSequenceNumber(kSeqNum); // Make all packets go through the pacer. EXPECT_CALL(mock_paced_sender_, @@ -817,6 +817,9 @@ TEST_F(RtpSenderTest, FrameCountCallbacks) { uint32_t delta_frames_; } callback; + rtp_sender_.reset(new RTPSender(0, false, &fake_clock_, &transport_, NULL, + &mock_paced_sender_, NULL, &callback, NULL)); + char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC"; const uint8_t payload_type = 127; ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000, @@ -825,8 +828,6 @@ TEST_F(RtpSenderTest, FrameCountCallbacks) { rtp_sender_->SetStorePacketsStatus(true, 1); uint32_t ssrc = rtp_sender_->SSRC(); - rtp_sender_->RegisterFrameCountObserver(&callback); - ASSERT_EQ(0, rtp_sender_->SendOutgoingData(kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload), NULL)); @@ -845,7 +846,7 @@ TEST_F(RtpSenderTest, FrameCountCallbacks) { EXPECT_EQ(1U, callback.key_frames_); EXPECT_EQ(1U, callback.delta_frames_); - rtp_sender_->RegisterFrameCountObserver(NULL); + rtp_sender_.reset(); } TEST_F(RtpSenderTest, BitrateCallbacks) { @@ -866,7 +867,7 @@ TEST_F(RtpSenderTest, BitrateCallbacks) { BitrateStatistics bitrate_; } callback; rtp_sender_.reset(new RTPSender(0, false, &fake_clock_, &transport_, NULL, - &mock_paced_sender_, &callback)); + &mock_paced_sender_, &callback, NULL, NULL)); // Simulate kNumPackets sent with kPacketInterval ms intervals. const uint32_t kNumPackets = 15; @@ -922,7 +923,7 @@ class RtpSenderAudioTest : public RtpSenderTest { virtual void SetUp() { payload_ = kAudioPayload; rtp_sender_.reset(new RTPSender(0, true, &fake_clock_, &transport_, NULL, - &mock_paced_sender_, NULL)); + &mock_paced_sender_, NULL, NULL, NULL)); rtp_sender_->SetSequenceNumber(kSeqNum); } }; @@ -1070,4 +1071,35 @@ TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) { sizeof(extension))); } +TEST_F(RtpSenderTest, BytesReportedCorrectly) { + const char* kPayloadName = "GENERIC"; + const uint8_t kPayloadType = 127; + rtp_sender_->SetSSRC(1234); + rtp_sender_->SetRtxSsrc(4321); + rtp_sender_->SetRtxPayloadType(kPayloadType - 1); + rtp_sender_->SetRTXStatus(kRtxRetransmitted | kRtxRedundantPayloads); + + ASSERT_EQ( + 0, + rtp_sender_->RegisterPayload(kPayloadName, kPayloadType, 90000, 0, 1500)); + uint8_t payload[] = {47, 11, 32, 93, 89}; + + ASSERT_EQ(0, + rtp_sender_->SendOutgoingData(kVideoFrameKey, + kPayloadType, + 1234, + 4321, + payload, + sizeof(payload), + 0)); + + EXPECT_GT(transport_.total_bytes_sent_, 0u); + EXPECT_EQ(transport_.total_bytes_sent_, rtp_sender_->Bytes()); + size_t last_bytes_sent = transport_.total_bytes_sent_; + + rtp_sender_->TimeToSendPadding(42); + + EXPECT_GT(transport_.total_bytes_sent_, last_bytes_sent); + EXPECT_EQ(transport_.total_bytes_sent_, rtp_sender_->Bytes()); +} } // namespace webrtc diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc index ea5f7a7e..c53dd21d 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -434,17 +434,18 @@ RTPSenderVideo::SendVP8(const FrameType frameType, if (rtpTypeHdr->VP8.temporalIdx == 0 && !(_retransmissionSettings & kRetransmitBaseLayer)) { storage = kDontRetransmit; - } - if (rtpTypeHdr->VP8.temporalIdx > 0 && + } else if (rtpTypeHdr->VP8.temporalIdx != kNoTemporalIdx && !(_retransmissionSettings & kRetransmitHigherLayers)) { storage = kDontRetransmit; } bool last = false; _numberFirstPartition = 0; - // |rtpTypeHdr->VP8.temporalIdx| is zero for base layers, or -1 if the field - // isn't used. We currently only protect base layers. - bool protect = (rtpTypeHdr->VP8.temporalIdx < 1); + // |rtpTypeHdr->VP8.temporalIdx| is zero for base layers, or kNoTemporalIdx + // if the field isn't used (so all layers are the base layer). We currently + // only protect base layers, so look for these two cases. + bool protect = rtpTypeHdr->VP8.temporalIdx == 0 || + rtpTypeHdr->VP8.temporalIdx == kNoTemporalIdx; while (!last) { // Write VP8 Payload Descriptor and VP8 payload. diff --git a/modules/rtp_rtcp/source/tmmbr_help.cc b/modules/rtp_rtcp/source/tmmbr_help.cc index ecdf6b87..fb1ed625 100644 --- a/modules/rtp_rtcp/source/tmmbr_help.cc +++ b/modules/rtp_rtcp/source/tmmbr_help.cc @@ -266,180 +266,177 @@ TMMBRHelp::FindTMMBRBoundingSet(int32_t numCandidates, TMMBRSet& candidateSet) numBoundingSet++; } } - if (numBoundingSet != 1) - { - numBoundingSet = -1; - } - } else + return (numBoundingSet == 1) ? 1 : -1; + } + + // 1. Sort by increasing packetOH + for (int i = candidateSet.sizeOfSet() - 1; i >= 0; i--) { - // 1. Sort by increasing packetOH - for (int i = candidateSet.sizeOfSet() - 1; i >= 0; i--) + for (int j = 1; j <= i; j++) { - for (int j = 1; j <= i; j++) + if (candidateSet.PacketOH(j-1) > candidateSet.PacketOH(j)) { - if (candidateSet.PacketOH(j-1) > candidateSet.PacketOH(j)) - { - candidateSet.SwapEntries(j-1, j); - } + candidateSet.SwapEntries(j-1, j); } } - // 2. For tuples with same OH, keep the one w/ the lowest bitrate - for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + } + // 2. For tuples with same OH, keep the one w/ the lowest bitrate + for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + { + if (candidateSet.Tmmbr(i) > 0) { - if (candidateSet.Tmmbr(i) > 0) + // get min bitrate for packets w/ same OH + uint32_t currentPacketOH = candidateSet.PacketOH(i); + uint32_t currentMinTMMBR = candidateSet.Tmmbr(i); + uint32_t currentMinIndexTMMBR = i; + for (uint32_t j = i+1; j < candidateSet.sizeOfSet(); j++) { - // get min bitrate for packets w/ same OH - uint32_t currentPacketOH = candidateSet.PacketOH(i); - uint32_t currentMinTMMBR = candidateSet.Tmmbr(i); - uint32_t currentMinIndexTMMBR = i; - for (uint32_t j = i+1; j < candidateSet.sizeOfSet(); j++) + if(candidateSet.PacketOH(j) == currentPacketOH) { - if(candidateSet.PacketOH(j) == currentPacketOH) + if(candidateSet.Tmmbr(j) < currentMinTMMBR) { - if(candidateSet.Tmmbr(j) < currentMinTMMBR) - { - currentMinTMMBR = candidateSet.Tmmbr(j); - currentMinIndexTMMBR = j; - } + currentMinTMMBR = candidateSet.Tmmbr(j); + currentMinIndexTMMBR = j; } } - // keep lowest bitrate - for (uint32_t j = 0; j < candidateSet.sizeOfSet(); j++) + } + // keep lowest bitrate + for (uint32_t j = 0; j < candidateSet.sizeOfSet(); j++) + { + if(candidateSet.PacketOH(j) == currentPacketOH + && j != currentMinIndexTMMBR) { - if(candidateSet.PacketOH(j) == currentPacketOH - && j != currentMinIndexTMMBR) - { - candidateSet.ClearEntry(j); - } + candidateSet.ClearEntry(j); } } } - // 3. Select and remove tuple w/ lowest tmmbr. - // (If more than 1, choose the one w/ highest OH). - uint32_t minTMMBR = 0; - uint32_t minIndexTMMBR = 0; - for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + } + // 3. Select and remove tuple w/ lowest tmmbr. + // (If more than 1, choose the one w/ highest OH). + uint32_t minTMMBR = 0; + uint32_t minIndexTMMBR = 0; + for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + { + if (candidateSet.Tmmbr(i) > 0) { - if (candidateSet.Tmmbr(i) > 0) - { - minTMMBR = candidateSet.Tmmbr(i); - minIndexTMMBR = i; - break; - } + minTMMBR = candidateSet.Tmmbr(i); + minIndexTMMBR = i; + break; } + } - for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + { + if (candidateSet.Tmmbr(i) > 0 && candidateSet.Tmmbr(i) <= minTMMBR) { - if (candidateSet.Tmmbr(i) > 0 && candidateSet.Tmmbr(i) <= minTMMBR) - { - // get min bitrate - minTMMBR = candidateSet.Tmmbr(i); - minIndexTMMBR = i; - } + // get min bitrate + minTMMBR = candidateSet.Tmmbr(i); + minIndexTMMBR = i; } - // first member of selected list - _boundingSet.SetEntry(numBoundingSet, - candidateSet.Tmmbr(minIndexTMMBR), - candidateSet.PacketOH(minIndexTMMBR), - candidateSet.Ssrc(minIndexTMMBR)); - - // set intersection value - _ptrIntersectionBoundingSet[numBoundingSet] = 0; - // calculate its maximum packet rate (where its line crosses x-axis) - _ptrMaxPRBoundingSet[numBoundingSet] - = _boundingSet.Tmmbr(numBoundingSet) * 1000 - / float(8 * _boundingSet.PacketOH(numBoundingSet)); - numBoundingSet++; - // remove from candidate list - candidateSet.ClearEntry(minIndexTMMBR); - numCandidates--; - - // 4. Discard from candidate list all tuple w/ lower OH - // (next tuple must be steeper) - for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + } + // first member of selected list + _boundingSet.SetEntry(numBoundingSet, + candidateSet.Tmmbr(minIndexTMMBR), + candidateSet.PacketOH(minIndexTMMBR), + candidateSet.Ssrc(minIndexTMMBR)); + + // set intersection value + _ptrIntersectionBoundingSet[numBoundingSet] = 0; + // calculate its maximum packet rate (where its line crosses x-axis) + _ptrMaxPRBoundingSet[numBoundingSet] + = _boundingSet.Tmmbr(numBoundingSet) * 1000 + / float(8 * _boundingSet.PacketOH(numBoundingSet)); + numBoundingSet++; + // remove from candidate list + candidateSet.ClearEntry(minIndexTMMBR); + numCandidates--; + + // 4. Discard from candidate list all tuple w/ lower OH + // (next tuple must be steeper) + for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + { + if(candidateSet.Tmmbr(i) > 0 + && candidateSet.PacketOH(i) < _boundingSet.PacketOH(0)) { - if(candidateSet.Tmmbr(i) > 0 - && candidateSet.PacketOH(i) < _boundingSet.PacketOH(0)) - { - candidateSet.ClearEntry(i); - numCandidates--; - } + candidateSet.ClearEntry(i); + numCandidates--; } + } - if (numCandidates == 0) - { - // Should be true already:_boundingSet.lengthOfSet = numBoundingSet; - assert(_boundingSet.lengthOfSet() == numBoundingSet); - return numBoundingSet; - } + if (numCandidates == 0) + { + // Should be true already:_boundingSet.lengthOfSet = numBoundingSet; + assert(_boundingSet.lengthOfSet() == numBoundingSet); + return numBoundingSet; + } - bool getNewCandidate = true; - int curCandidateTMMBR = 0; - int curCandidateIndex = 0; - int curCandidatePacketOH = 0; - int curCandidateSSRC = 0; - do + bool getNewCandidate = true; + int curCandidateTMMBR = 0; + int curCandidateIndex = 0; + int curCandidatePacketOH = 0; + int curCandidateSSRC = 0; + do + { + if (getNewCandidate) { - if (getNewCandidate) + // 5. Remove first remaining tuple from candidate list + for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) { - // 5. Remove first remaining tuple from candidate list - for (uint32_t i = 0; i < candidateSet.sizeOfSet(); i++) + if (candidateSet.Tmmbr(i) > 0) { - if (candidateSet.Tmmbr(i) > 0) - { - curCandidateTMMBR = candidateSet.Tmmbr(i); - curCandidatePacketOH = candidateSet.PacketOH(i); - curCandidateSSRC = candidateSet.Ssrc(i); - curCandidateIndex = i; - candidateSet.ClearEntry(curCandidateIndex); - break; - } + curCandidateTMMBR = candidateSet.Tmmbr(i); + curCandidatePacketOH = candidateSet.PacketOH(i); + curCandidateSSRC = candidateSet.Ssrc(i); + curCandidateIndex = i; + candidateSet.ClearEntry(curCandidateIndex); + break; } } + } - // 6. Calculate packet rate and intersection of the current - // line with line of last tuple in selected list - float packetRate - = float(curCandidateTMMBR - - _boundingSet.Tmmbr(numBoundingSet-1))*1000 - / (8*(curCandidatePacketOH - - _boundingSet.PacketOH(numBoundingSet-1))); - - // 7. If the packet rate is equal or lower than intersection of - // last tuple in selected list, - // remove last tuple in selected list & go back to step 6 - if(packetRate <= _ptrIntersectionBoundingSet[numBoundingSet-1]) - { - // remove last tuple and goto step 6 - numBoundingSet--; - _boundingSet.ClearEntry(numBoundingSet); - _ptrIntersectionBoundingSet[numBoundingSet] = 0; - _ptrMaxPRBoundingSet[numBoundingSet] = 0; - getNewCandidate = false; - } else + // 6. Calculate packet rate and intersection of the current + // line with line of last tuple in selected list + float packetRate + = float(curCandidateTMMBR + - _boundingSet.Tmmbr(numBoundingSet-1))*1000 + / (8*(curCandidatePacketOH + - _boundingSet.PacketOH(numBoundingSet-1))); + + // 7. If the packet rate is equal or lower than intersection of + // last tuple in selected list, + // remove last tuple in selected list & go back to step 6 + if(packetRate <= _ptrIntersectionBoundingSet[numBoundingSet-1]) + { + // remove last tuple and goto step 6 + numBoundingSet--; + _boundingSet.ClearEntry(numBoundingSet); + _ptrIntersectionBoundingSet[numBoundingSet] = 0; + _ptrMaxPRBoundingSet[numBoundingSet] = 0; + getNewCandidate = false; + } else + { + // 8. If packet rate is lower than maximum packet rate of + // last tuple in selected list, add current tuple to selected + // list + if (packetRate < _ptrMaxPRBoundingSet[numBoundingSet-1]) { - // 8. If packet rate is lower than maximum packet rate of - // last tuple in selected list, add current tuple to selected - // list - if (packetRate < _ptrMaxPRBoundingSet[numBoundingSet-1]) - { - _boundingSet.SetEntry(numBoundingSet, - curCandidateTMMBR, - curCandidatePacketOH, - curCandidateSSRC); - _ptrIntersectionBoundingSet[numBoundingSet] = packetRate; - _ptrMaxPRBoundingSet[numBoundingSet] - = _boundingSet.Tmmbr(numBoundingSet)*1000 - / float(8*_boundingSet.PacketOH(numBoundingSet)); - numBoundingSet++; - } - numCandidates--; - getNewCandidate = true; + _boundingSet.SetEntry(numBoundingSet, + curCandidateTMMBR, + curCandidatePacketOH, + curCandidateSSRC); + _ptrIntersectionBoundingSet[numBoundingSet] = packetRate; + _ptrMaxPRBoundingSet[numBoundingSet] + = _boundingSet.Tmmbr(numBoundingSet)*1000 + / float(8*_boundingSet.PacketOH(numBoundingSet)); + numBoundingSet++; } + numCandidates--; + getNewCandidate = true; + } + + // 9. Go back to step 5 if any tuple remains in candidate list + } while (numCandidates > 0); - // 9. Go back to step 5 if any tuple remains in candidate list - } while (numCandidates > 0); - } return numBoundingSet; } |