/* * Copyright (c) 2012 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 "webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h" #include // assert #include // memset #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" namespace webrtc { namespace RTCPHelp { RTCPPacketInformation::RTCPPacketInformation() : rtcpPacketTypeFlags(0), remoteSSRC(0), nackSequenceNumbers(), applicationSubType(0), applicationName(0), applicationData(), applicationLength(0), rtt(0), interArrivalJitter(0), sliPictureId(0), rpsiPictureId(0), receiverEstimatedMaxBitrate(0), ntp_secs(0), ntp_frac(0), rtp_timestamp(0), xr_originator_ssrc(0), xr_dlrr_item(false), VoIPMetric(nullptr) {} RTCPPacketInformation::~RTCPPacketInformation() { delete[] applicationData; } void RTCPPacketInformation::AddVoIPMetric(const RTCPVoIPMetric* metric) { VoIPMetric.reset(new RTCPVoIPMetric()); memcpy(VoIPMetric.get(), metric, sizeof(RTCPVoIPMetric)); } void RTCPPacketInformation::AddApplicationData(const uint8_t* data, const uint16_t size) { uint8_t* oldData = applicationData; uint16_t oldLength = applicationLength; // Don't copy more than kRtcpAppCode_DATA_SIZE bytes. uint16_t copySize = size; if (size > kRtcpAppCode_DATA_SIZE) { copySize = kRtcpAppCode_DATA_SIZE; } applicationLength += copySize; applicationData = new uint8_t[applicationLength]; if (oldData) { memcpy(applicationData, oldData, oldLength); memcpy(applicationData + oldLength, data, copySize); delete[] oldData; } else { memcpy(applicationData, data, copySize); } } void RTCPPacketInformation::ResetNACKPacketIdArray() { nackSequenceNumbers.clear(); } void RTCPPacketInformation::AddNACKPacket(const uint16_t packetID) { if (nackSequenceNumbers.size() >= kSendSideNackListSizeSanity) { return; } nackSequenceNumbers.push_back(packetID); } void RTCPPacketInformation::AddReportInfo( const RTCPReportBlockInformation& report_block_info) { this->rtt = report_block_info.RTT; report_blocks.push_back(report_block_info.remoteReceiveBlock); } RTCPReportBlockInformation::RTCPReportBlockInformation() : remoteReceiveBlock(), remoteMaxJitter(0), RTT(0), minRTT(0), maxRTT(0), avgRTT(0), numAverageCalcs(0) { memset(&remoteReceiveBlock, 0, sizeof(remoteReceiveBlock)); } RTCPReportBlockInformation::~RTCPReportBlockInformation() {} RTCPReceiveInformation::RTCPReceiveInformation() = default; RTCPReceiveInformation::~RTCPReceiveInformation() = default; void RTCPReceiveInformation::InsertTmmbrItem(uint32_t sender_ssrc, const rtcp::TmmbItem& tmmbr_item, int64_t current_time_ms) { TimedTmmbrItem* entry = &tmmbr_[sender_ssrc]; entry->tmmbr_item = rtcp::TmmbItem(sender_ssrc, tmmbr_item.bitrate_bps(), tmmbr_item.packet_overhead()); entry->last_updated_ms = current_time_ms; } void RTCPReceiveInformation::GetTmmbrSet( int64_t current_time_ms, std::vector* candidates) { // Use audio define since we don't know what interval the remote peer use. int64_t timeouted_ms = current_time_ms - 5 * RTCP_INTERVAL_AUDIO_MS; for (auto it = tmmbr_.begin(); it != tmmbr_.end();) { if (it->second.last_updated_ms < timeouted_ms) { // Erase timeout entries. it = tmmbr_.erase(it); } else { candidates->push_back(it->second.tmmbr_item); ++it; } } } void RTCPReceiveInformation::ClearTmmbr() { tmmbr_.clear(); } } // namespace RTCPHelp } // namespace webrtc