Move RTCPHelp::RTCPReceiveInformation inside RTCPReceiver

move all logic from that class into RTCPReceiver too,
Simplify and fix style on the way.

BUG=webrtc:5565

Review-Url: https://codereview.webrtc.org/2373053002
Cr-Commit-Position: refs/heads/master@{#14442}
This commit is contained in:
danilchap
2016-09-29 15:28:07 -07:00
committed by Commit bot
parent c8d21712dd
commit 7851bda9bc
4 changed files with 115 additions and 207 deletions

View File

@ -14,8 +14,10 @@
#include <string.h>
#include <limits>
#include <map>
#include <memory>
#include <utility>
#include <vector>
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
@ -47,7 +49,6 @@ namespace {
using rtcp::CommonHeader;
using rtcp::ReportBlock;
using RTCPHelp::RTCPReceiveInformation;
using RTCPHelp::RTCPReportBlockInformation;
// The number of RTCP time intervals needed to trigger a timeout.
@ -70,6 +71,23 @@ struct RTCPReceiver::PacketInformation {
std::unique_ptr<rtcp::TransportFeedback> transport_feedback;
};
struct RTCPReceiver::ReceiveInformation {
struct TimedTmmbrItem {
rtcp::TmmbItem tmmbr_item;
int64_t last_updated_ms;
};
int64_t last_time_received_ms = 0;
int64_t last_fir_request_ms = 0;
int32_t last_fir_sequence_number = -1;
bool ready_for_delete = false;
std::vector<rtcp::TmmbItem> tmmbn;
std::map<uint32_t, TimedTmmbrItem> tmmbr;
};
RTCPReceiver::RTCPReceiver(
Clock* clock,
bool receiver_only,
@ -93,7 +111,6 @@ RTCPReceiver::RTCPReceiver(
_lastReceivedXRNTPfrac(0),
xr_rrtr_status_(false),
xr_rr_rtt_ms_(0),
_receivedInfoMap(),
_lastReceivedRrMs(0),
_lastIncreasedSequenceNumberMs(0),
stats_callback_(NULL),
@ -113,12 +130,6 @@ RTCPReceiver::~RTCPReceiver() {
info_map->erase(it_info);
}
}
while (!_receivedInfoMap.empty()) {
std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
_receivedInfoMap.begin();
delete first->second;
_receivedInfoMap.erase(first);
}
}
bool RTCPReceiver::IncomingPacket(const uint8_t* packet, size_t packet_size) {
@ -137,12 +148,9 @@ bool RTCPReceiver::IncomingPacket(const uint8_t* packet, size_t packet_size) {
int64_t RTCPReceiver::LastReceivedReceiverReport() const {
rtc::CritScope lock(&_criticalSectionRTCPReceiver);
int64_t last_received_rr = -1;
for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
it != _receivedInfoMap.end(); ++it) {
if (it->second->last_time_received_ms > last_received_rr) {
last_received_rr = it->second->last_time_received_ms;
}
}
for (const auto& kv : received_infos_)
if (kv.second.last_time_received_ms > last_received_rr)
last_received_rr = kv.second.last_time_received_ms;
return last_received_rr;
}
@ -420,9 +428,7 @@ void RTCPReceiver::HandleSenderReport(const CommonHeader& rtcp_block,
packet_information->remote_ssrc = remoteSSRC;
RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
if (!ptrReceiveInfo)
return;
CreateReceiveInformation(remoteSSRC);
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
"remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
@ -445,8 +451,6 @@ void RTCPReceiver::HandleSenderReport(const CommonHeader& rtcp_block,
// we will store all the receive blocks.
packet_information->packet_type_flags |= kRtcpRr;
}
// Update that this remote is alive.
ptrReceiveInfo->last_time_received_ms = _clock->TimeInMilliseconds();
for (const rtcp::ReportBlock report_block : sender_report.report_blocks())
HandleReportBlock(report_block, packet_information, remoteSSRC);
@ -464,18 +468,13 @@ void RTCPReceiver::HandleReceiverReport(const CommonHeader& rtcp_block,
packet_information->remote_ssrc = remoteSSRC;
RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
if (!ptrReceiveInfo)
return;
CreateReceiveInformation(remoteSSRC);
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
"remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
packet_information->packet_type_flags |= kRtcpRr;
// Update that this remote is alive.
ptrReceiveInfo->last_time_received_ms = _clock->TimeInMilliseconds();
for (const ReportBlock& report_block : receiver_report.report_blocks())
HandleReportBlock(report_block, packet_information, remoteSSRC);
}
@ -602,31 +601,19 @@ RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
return it_info->second;
}
RTCPReceiveInformation* RTCPReceiver::CreateReceiveInformation(
uint32_t remoteSSRC) {
rtc::CritScope lock(&_criticalSectionRTCPReceiver);
std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
_receivedInfoMap.find(remoteSSRC);
if (it != _receivedInfoMap.end()) {
return it->second;
}
RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
_receivedInfoMap[remoteSSRC] = receiveInfo;
return receiveInfo;
void RTCPReceiver::CreateReceiveInformation(uint32_t remote_ssrc) {
// Create or find receive information.
ReceiveInformation* receive_info = &received_infos_[remote_ssrc];
// Update that this remote is alive.
receive_info->last_time_received_ms = _clock->TimeInMilliseconds();
}
RTCPReceiveInformation* RTCPReceiver::GetReceiveInformation(
uint32_t remoteSSRC) {
rtc::CritScope lock(&_criticalSectionRTCPReceiver);
std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
_receivedInfoMap.find(remoteSSRC);
if (it == _receivedInfoMap.end()) {
return NULL;
}
return it->second;
RTCPReceiver::ReceiveInformation* RTCPReceiver::GetReceiveInformation(
uint32_t remote_ssrc) {
auto it = received_infos_.find(remote_ssrc);
if (it == received_infos_.end())
return nullptr;
return &it->second;
}
bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
@ -661,61 +648,43 @@ bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
rtc::CritScope lock(&_criticalSectionRTCPReceiver);
bool updateBoundingSet = false;
int64_t timeNow = _clock->TimeInMilliseconds();
bool update_bounding_set = false;
int64_t now_ms = _clock->TimeInMilliseconds();
// Use audio define since we don't know what interval the remote peer use.
int64_t timeouted_ms = now_ms - 5 * RTCP_INTERVAL_AUDIO_MS;
std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
_receivedInfoMap.begin();
while (receiveInfoIt != _receivedInfoMap.end()) {
RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
if (receiveInfo == NULL) {
return updateBoundingSet;
}
// time since last received rtcp packet
// when we dont have a lastTimeReceived and the object is marked
// readyForDelete it's removed from the map
if (receiveInfo->last_time_received_ms > 0) {
/// use audio define since we don't know what interval the remote peer is
// using
if ((timeNow - receiveInfo->last_time_received_ms) >
5 * RTCP_INTERVAL_AUDIO_MS) {
// no rtcp packet for the last five regular intervals, reset limitations
receiveInfo->ClearTmmbr();
// prevent that we call this over and over again
receiveInfo->last_time_received_ms = 0;
// send new TMMBN to all channels using the default codec
updateBoundingSet = true;
for (auto receive_info_it = received_infos_.begin();
receive_info_it != received_infos_.end();) {
ReceiveInformation* receive_info = &receive_info_it->second;
if (receive_info->last_time_received_ms > 0) {
if (receive_info->last_time_received_ms < timeouted_ms) {
// No rtcp packet for the last 5 regular intervals, reset limitations.
receive_info->tmmbr.clear();
// Prevent that we call this over and over again.
receive_info->last_time_received_ms = 0;
// Send new TMMBN to all channels using the default codec.
update_bounding_set = true;
}
receiveInfoIt++;
} else if (receiveInfo->ready_for_delete) {
// store our current receiveInfoItem
std::map<uint32_t, RTCPReceiveInformation*>::iterator
receiveInfoItemToBeErased = receiveInfoIt;
receiveInfoIt++;
delete receiveInfoItemToBeErased->second;
_receivedInfoMap.erase(receiveInfoItemToBeErased);
++receive_info_it;
} else if (receive_info->ready_for_delete) {
// When we dont have a last_time_received_ms and the object is marked
// ready_for_delete it's removed from the map.
receive_info_it = received_infos_.erase(receive_info_it);
} else {
receiveInfoIt++;
++receive_info_it;
}
}
return updateBoundingSet;
return update_bounding_set;
}
std::vector<rtcp::TmmbItem> RTCPReceiver::BoundingSet(bool* tmmbr_owner) {
rtc::CritScope lock(&_criticalSectionRTCPReceiver);
std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
_receivedInfoMap.find(_remoteSSRC);
if (receiveInfoIt == _receivedInfoMap.end()) {
ReceiveInformation* receive_info = GetReceiveInformation(_remoteSSRC);
if (!receive_info)
return std::vector<rtcp::TmmbItem>();
}
RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
RTC_DCHECK(receiveInfo);
*tmmbr_owner = TMMBRHelp::IsOwner(receiveInfo->tmmbn, main_ssrc_);
return receiveInfo->tmmbn;
*tmmbr_owner = TMMBRHelp::IsOwner(receive_info->tmmbn, main_ssrc_);
return receive_info->tmmbn;
}
void RTCPReceiver::HandleSDES(const CommonHeader& rtcp_block,
@ -778,12 +747,10 @@ void RTCPReceiver::HandleBYE(const CommonHeader& rtcp_block) {
}
}
// we can't delete it due to TMMBR
std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
_receivedInfoMap.find(bye.sender_ssrc());
if (receiveInfoIt != _receivedInfoMap.end())
receiveInfoIt->second->ready_for_delete = true;
// We can't delete it due to TMMBR.
ReceiveInformation* receive_info = GetReceiveInformation(bye.sender_ssrc());
if (receive_info)
receive_info->ready_for_delete = true;
received_cnames_.erase(bye.sender_ssrc());
xr_rr_rtt_ms_ = 0;
@ -861,21 +828,25 @@ void RTCPReceiver::HandleTMMBR(const CommonHeader& rtcp_block,
return;
}
uint32_t senderSSRC = tmmbr.sender_ssrc();
RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
if (!ptrReceiveInfo) // This remote SSRC must be saved before.
uint32_t sender_ssrc = tmmbr.sender_ssrc();
ReceiveInformation* receive_info = GetReceiveInformation(sender_ssrc);
if (!receive_info) // This remote SSRC must be saved before.
return;
if (tmmbr.media_ssrc()) {
// media_ssrc() SHOULD be 0 if same as SenderSSRC.
// In relay mode this is a valid number.
senderSSRC = tmmbr.media_ssrc();
sender_ssrc = tmmbr.media_ssrc();
}
for (const rtcp::TmmbItem& request : tmmbr.requests()) {
if (main_ssrc_ == request.ssrc() && request.bitrate_bps()) {
ptrReceiveInfo->InsertTmmbrItem(senderSSRC, request,
_clock->TimeInMilliseconds());
auto* entry = &receive_info->tmmbr[sender_ssrc];
entry->tmmbr_item = rtcp::TmmbItem(sender_ssrc,
request.bitrate_bps(),
request.packet_overhead());
entry->last_updated_ms = _clock->TimeInMilliseconds();
packet_information->packet_type_flags |= kRtcpTmmbr;
}
}
@ -889,15 +860,14 @@ void RTCPReceiver::HandleTMMBN(const CommonHeader& rtcp_block,
return;
}
RTCPReceiveInformation* ptrReceiveInfo =
GetReceiveInformation(tmmbn.sender_ssrc());
if (!ptrReceiveInfo) // This remote SSRC must be saved before.
ReceiveInformation* receive_info = GetReceiveInformation(tmmbn.sender_ssrc());
if (!receive_info) // This remote SSRC must be saved before.
return;
packet_information->packet_type_flags |= kRtcpTmmbn;
for (const auto& item : tmmbn.items())
ptrReceiveInfo->tmmbn.push_back(item);
receive_info->tmmbn.push_back(item);
}
void RTCPReceiver::HandleSR_REQ(const CommonHeader& rtcp_block,
@ -960,8 +930,7 @@ void RTCPReceiver::HandleFIR(const CommonHeader& rtcp_block,
return;
}
RTCPReceiveInformation* ptrReceiveInfo =
GetReceiveInformation(fir.sender_ssrc());
ReceiveInformation* receive_info = GetReceiveInformation(fir.sender_ssrc());
for (const rtcp::Fir::Request& fir_request : fir.requests()) {
// Is it our sender that is requested to generate a new keyframe
@ -970,25 +939,21 @@ void RTCPReceiver::HandleFIR(const CommonHeader& rtcp_block,
++packet_type_counter_.fir_packets;
// rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
// we don't know who this originate from
if (ptrReceiveInfo) {
// check if we have reported this FIRSequenceNumber before
if (fir_request.seq_nr != ptrReceiveInfo->last_fir_sequence_number) {
int64_t now = _clock->TimeInMilliseconds();
// sanity; don't go crazy with the callbacks
if ((now - ptrReceiveInfo->last_fir_request_ms) >
RTCP_MIN_FRAME_LENGTH_MS) {
ptrReceiveInfo->last_fir_request_ms = now;
ptrReceiveInfo->last_fir_sequence_number = fir_request.seq_nr;
// received signal that we need to send a new key frame
packet_information->packet_type_flags |= kRtcpFir;
}
}
} else {
// received signal that we need to send a new key frame
packet_information->packet_type_flags |= kRtcpFir;
if (receive_info) {
// Check if we have reported this FIRSequenceNumber before.
if (fir_request.seq_nr == receive_info->last_fir_sequence_number)
continue;
int64_t now_ms = _clock->TimeInMilliseconds();
// Sanity: don't go crazy with the callbacks.
if (now_ms - receive_info->last_fir_request_ms < RTCP_MIN_FRAME_LENGTH_MS)
continue;
receive_info->last_fir_request_ms = now_ms;
receive_info->last_fir_sequence_number = fir_request.seq_nr;
}
// Received signal that we need to send a new key frame.
packet_information->packet_type_flags |= kRtcpFir;
}
}
@ -1150,16 +1115,24 @@ int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
return 0;
}
std::vector<rtcp::TmmbItem> RTCPReceiver::TmmbrReceived() const {
std::vector<rtcp::TmmbItem> RTCPReceiver::TmmbrReceived() {
rtc::CritScope lock(&_criticalSectionRTCPReceiver);
std::vector<rtcp::TmmbItem> candidates;
int64_t now_ms = _clock->TimeInMilliseconds();
// Use audio define since we don't know what interval the remote peer use.
int64_t timeouted_ms = now_ms - 5 * RTCP_INTERVAL_AUDIO_MS;
for (const auto& kv : _receivedInfoMap) {
RTCPReceiveInformation* receive_info = kv.second;
RTC_DCHECK(receive_info);
receive_info->GetTmmbrSet(now_ms, &candidates);
for (auto& kv : received_infos_) {
for (auto it = kv.second.tmmbr.begin(); it != kv.second.tmmbr.end();) {
if (it->second.last_updated_ms < timeouted_ms) {
// Erase timeout entries.
it = kv.second.tmmbr.erase(it);
} else {
candidates.push_back(it->second.tmmbr_item);
++it;
}
}
}
return candidates;
}