/* * Copyright (c) 2017 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 MODULES_RTP_RTCP_SOURCE_RTCP_TRANSCEIVER_IMPL_H_ #define MODULES_RTP_RTCP_SOURCE_RTCP_TRANSCEIVER_IMPL_H_ #include #include #include #include #include "absl/types/optional.h" #include "api/array_view.h" #include "api/units/timestamp.h" #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h" #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" #include "modules/rtp_rtcp/source/rtcp_packet/remb.h" #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" #include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h" #include "modules/rtp_rtcp/source/rtcp_transceiver_config.h" #include "rtc_base/containers/flat_map.h" #include "rtc_base/task_utils/repeating_task.h" #include "system_wrappers/include/ntp_time.h" namespace webrtc { // // Manage incoming and outgoing rtcp messages for multiple BUNDLED streams. // // This class is not thread-safe. class RtcpTransceiverImpl { public: explicit RtcpTransceiverImpl(const RtcpTransceiverConfig& config); RtcpTransceiverImpl(const RtcpTransceiverImpl&) = delete; RtcpTransceiverImpl& operator=(const RtcpTransceiverImpl&) = delete; ~RtcpTransceiverImpl(); void StopPeriodicTask() { periodic_task_handle_.Stop(); } void AddMediaReceiverRtcpObserver(uint32_t remote_ssrc, MediaReceiverRtcpObserver* observer); void RemoveMediaReceiverRtcpObserver(uint32_t remote_ssrc, MediaReceiverRtcpObserver* observer); // Returns false on failure, e.g. when there is already an handler for the // `local_ssrc`. bool AddMediaSender(uint32_t local_ssrc, RtpStreamRtcpHandler* handler); bool RemoveMediaSender(uint32_t local_ssrc); void SetReadyToSend(bool ready); void ReceivePacket(rtc::ArrayView packet, Timestamp now); void SendCompoundPacket(); void SetRemb(int64_t bitrate_bps, std::vector ssrcs); void UnsetRemb(); void SendNack(uint32_t ssrc, std::vector sequence_numbers); void SendPictureLossIndication(uint32_t ssrc); // If new_request is true then requested sequence no. will increase for each // requested ssrc. void SendFullIntraRequest(rtc::ArrayView ssrcs, bool new_request); // SendCombinedRtcpPacket ignores rtcp mode and does not send a compound // message. https://tools.ietf.org/html/rfc4585#section-3.1 void SendCombinedRtcpPacket( std::vector> rtcp_packets); private: class PacketSender; struct RemoteSenderState; struct LocalSenderState; struct RrtrTimes { // Received remote NTP timestamp in compact representation. uint32_t received_remote_mid_ntp_time; // Local NTP time when the report was received in compact representation. uint32_t local_receive_mid_ntp_time; }; void HandleReceivedPacket(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now, std::vector& report_blocks); // Individual rtcp packet handlers. void HandleBye(const rtcp::CommonHeader& rtcp_packet_header); void HandleSenderReport(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now, std::vector& report_blocks); void HandleReceiverReport(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now, std::vector& report_blocks); void HandleReportBlocks( uint32_t sender_ssrc, Timestamp now, rtc::ArrayView rtcp_report_blocks, std::vector& report_blocks); void HandlePayloadSpecificFeedback( const rtcp::CommonHeader& rtcp_packet_header, Timestamp now); void HandleRtpFeedback(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now); void HandleFir(const rtcp::CommonHeader& rtcp_packet_header); void HandlePli(const rtcp::CommonHeader& rtcp_packet_header); void HandleRemb(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now); void HandleNack(const rtcp::CommonHeader& rtcp_packet_header); void HandleTransportFeedback(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now); void HandleExtendedReports(const rtcp::CommonHeader& rtcp_packet_header, Timestamp now); // Extended Reports blocks handlers. void HandleDlrr(const rtcp::Dlrr& dlrr, Timestamp now); void HandleTargetBitrate(const rtcp::TargetBitrate& target_bitrate, uint32_t remote_ssrc); void ProcessReportBlocks(Timestamp now, rtc::ArrayView report_blocks); void ReschedulePeriodicCompoundPackets(); void SchedulePeriodicCompoundPackets(TimeDelta delay); // Appends RTCP sender and receiver reports to the `sender`. // Both sender and receiver reports may have attached report blocks. // Uses up to `config_.max_packet_size - reserved_bytes.per_packet` // Returns list of sender ssrc in sender reports. struct ReservedBytes { size_t per_packet = 0; size_t per_sender = 0; }; std::vector FillReports(Timestamp now, ReservedBytes reserved_bytes, PacketSender& rtcp_sender); // Creates compound RTCP packet, as defined in // https://tools.ietf.org/html/rfc5506#section-2 void CreateCompoundPacket(Timestamp now, size_t reserved_bytes, PacketSender& rtcp_sender); // Sends RTCP packets. void SendPeriodicCompoundPacket(); void SendImmediateFeedback(const rtcp::RtcpPacket& rtcp_packet); // Generate Report Blocks to be send in Sender or Receiver Reports. std::vector CreateReportBlocks(Timestamp now, size_t num_max_blocks); const RtcpTransceiverConfig config_; std::function)> rtcp_transport_; bool ready_to_send_; absl::optional remb_; // TODO(bugs.webrtc.org/8239): Remove entries from remote_senders_ that are no // longer needed. flat_map remote_senders_; std::list local_senders_; flat_map::iterator> local_senders_by_ssrc_; flat_map received_rrtrs_; RepeatingTaskHandle periodic_task_handle_; }; } // namespace webrtc #endif // MODULES_RTP_RTCP_SOURCE_RTCP_TRANSCEIVER_IMPL_H_