diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index b19ce3880a..3977ee4f20 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -55,6 +55,7 @@ using rtcp::ReportBlock; const int kRrTimeoutIntervals = 3; const int64_t kMaxWarningLogIntervalMs = 10000; +const int64_t kRtcpMinFrameLengthMs = 17; } // namespace @@ -80,9 +81,6 @@ struct RTCPReceiver::ReceiveInformation { 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 tmmbn; @@ -99,6 +97,13 @@ struct RTCPReceiver::ReportBlockWithRtt { size_t num_rtts = 0; }; +struct RTCPReceiver::LastFirStatus { + LastFirStatus(int64_t now_ms, uint8_t sequence_number) + : request_ms(now_ms), sequence_number(sequence_number) {} + int64_t request_ms; + uint8_t sequence_number; +}; + RTCPReceiver::RTCPReceiver( Clock* clock, bool receiver_only, @@ -683,6 +688,7 @@ void RTCPReceiver::HandleBye(const CommonHeader& rtcp_block) { if (receive_info) receive_info->ready_for_delete = true; + last_fir_.erase(bye.sender_ssrc()); received_cnames_.erase(bye.sender_ssrc()); xr_rr_rtt_ms_ = 0; } @@ -880,8 +886,6 @@ void RTCPReceiver::HandleFir(const CommonHeader& rtcp_block, return; } - 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. if (main_ssrc_ != fir_request.ssrc) @@ -889,18 +893,22 @@ void RTCPReceiver::HandleFir(const CommonHeader& rtcp_block, ++packet_type_counter_.fir_packets; - if (receive_info) { + int64_t now_ms = clock_->TimeInMilliseconds(); + auto inserted = last_fir_.insert(std::make_pair( + fir.sender_ssrc(), LastFirStatus(now_ms, fir_request.seq_nr))); + if (!inserted.second) { // There was already an entry. + LastFirStatus* last_fir = &inserted.first->second; + // Check if we have reported this FIRSequenceNumber before. - if (fir_request.seq_nr == receive_info->last_fir_sequence_number) + if (fir_request.seq_nr == 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) + if (now_ms - last_fir->request_ms < kRtcpMinFrameLengthMs) continue; - receive_info->last_fir_request_ms = now_ms; - receive_info->last_fir_sequence_number = fir_request.seq_nr; + last_fir->request_ms = now_ms; + 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; diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h index b86b03060c..26defae680 100644 --- a/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h +++ b/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h @@ -119,6 +119,7 @@ class RTCPReceiver { struct PacketInformation; struct ReceiveInformation; struct ReportBlockWithRtt; + struct LastFirStatus; // Mapped by remote ssrc. using ReceivedInfoMap = std::map; // RTCP report blocks mapped by remote SSRC. @@ -245,6 +246,7 @@ class RTCPReceiver { ReportBlockMap received_report_blocks_ GUARDED_BY(rtcp_receiver_lock_); ReceivedInfoMap received_infos_ GUARDED_BY(rtcp_receiver_lock_); int64_t oldest_received_info_ms_ GUARDED_BY(rtcp_receiver_lock_); + std::map last_fir_ GUARDED_BY(rtcp_receiver_lock_); std::map received_cnames_ GUARDED_BY(rtcp_receiver_lock_); diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h index f09bf55617..5d0505816e 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h @@ -23,7 +23,6 @@ enum { RTCP_INTERVAL_VIDEO_MS = 1000 }; enum { RTCP_INTERVAL_AUDIO_MS = 5000 }; enum { RTCP_SEND_BEFORE_KEY_FRAME_MS = 100 }; enum { RTCP_MAX_REPORT_BLOCKS = 31 }; // RFC 3550 page 37 -enum { RTCP_MIN_FRAME_LENGTH_MS = 17 }; enum { kRtcpAppCode_DATA_SIZE = 32 * 4 }; // multiple of 4, this is not a limitation of the size