/* * 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. */ #ifndef MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_ #define MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_ #include #include #include #include #include #include "absl/types/optional.h" #include "api/call/transport.h" #include "api/video/video_bitrate_allocation.h" #include "modules/remote_bitrate_estimator/include/bwe_defines.h" #include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "modules/rtp_rtcp/include/receive_statistics.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtcp_nack_stats.h" #include "modules/rtp_rtcp/source/rtcp_packet.h" #include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h" #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" #include "rtc_base/random.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" namespace webrtc { class RTCPReceiver; class RtcEventLog; class RTCPSender final { public: struct FeedbackState { FeedbackState(); FeedbackState(const FeedbackState&); FeedbackState(FeedbackState&&); ~FeedbackState(); uint32_t packets_sent; size_t media_bytes_sent; uint32_t send_bitrate; uint32_t last_rr_ntp_secs; uint32_t last_rr_ntp_frac; uint32_t remote_sr; std::vector last_xr_rtis; // Used when generating TMMBR. RTCPReceiver* receiver; }; explicit RTCPSender(const RtpRtcpInterface::Configuration& config); RTCPSender() = delete; RTCPSender(const RTCPSender&) = delete; RTCPSender& operator=(const RTCPSender&) = delete; virtual ~RTCPSender(); RtcpMode Status() const RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetRTCPStatus(RtcpMode method) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); bool Sending() const RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); int32_t SetSendingStatus(const FeedbackState& feedback_state, bool enabled) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); // combine the functions int32_t SetNackStatus(bool enable) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetTimestampOffset(uint32_t timestamp_offset) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); // TODO(bugs.webrtc.org/6458): Remove default parameter value when all the // depending projects are updated to correctly set payload type. void SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms, int8_t payload_type = -1) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetRtpClockRate(int8_t payload_type, int rtp_clock_rate_hz) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); uint32_t SSRC() const { return ssrc_; } void SetRemoteSSRC(uint32_t ssrc) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); int32_t SetCNAME(const char* cName) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); int32_t AddMixedCNAME(uint32_t SSRC, const char* c_name) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); int32_t RemoveMixedCNAME(uint32_t SSRC) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); int32_t SendRTCP(const FeedbackState& feedback_state, RTCPPacketType packetType, int32_t nackSize = 0, const uint16_t* nackList = 0) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); int32_t SendCompoundRTCP(const FeedbackState& feedback_state, const std::set& packetTypes, int32_t nackSize = 0, const uint16_t* nackList = nullptr) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); int32_t SendLossNotification(const FeedbackState& feedback_state, uint16_t last_decoded_seq_num, uint16_t last_received_seq_num, bool decodability_flag, bool buffering_allowed) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetRemb(int64_t bitrate_bps, std::vector ssrcs) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void UnsetRemb() RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); bool TMMBR() const RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetTMMBRStatus(bool enable) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetMaxRtpPacketSize(size_t max_packet_size) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetTmmbn(std::vector bounding_set) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SendRtcpXrReceiverReferenceTime(bool enable) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); bool RtcpXrReceiverReferenceTime() const RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetCsrcs(const std::vector& csrcs) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetTargetBitrate(unsigned int target_bitrate) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SetVideoBitrateAllocation(const VideoBitrateAllocation& bitrate) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); void SendCombinedRtcpPacket( std::vector> rtcp_packets) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); private: class RtcpContext; int32_t SendCompoundRTCPLocked(const FeedbackState& feedback_state, const std::set& packet_types, int32_t nack_size, const uint16_t* nack_list) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); absl::optional ComputeCompoundRTCPPacket( const FeedbackState& feedback_state, const std::set& packet_types, int32_t nack_size, const uint16_t* nack_list, rtcp::CompoundPacket* out_packet) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); // Determine which RTCP messages should be sent and setup flags. void PrepareReport(const FeedbackState& feedback_state) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::vector CreateReportBlocks( const FeedbackState& feedback_state) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildSR(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildRR(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildSDES(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildPLI(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildREMB(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildTMMBR(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildTMMBN(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildAPP(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildLossNotification( const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildExtendedReports( const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildBYE(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildFIR(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); std::unique_ptr BuildNACK(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); private: const bool audio_; const uint32_t ssrc_; Clock* const clock_; Random random_ RTC_GUARDED_BY(mutex_rtcp_sender_); RtcpMode method_ RTC_GUARDED_BY(mutex_rtcp_sender_); RtcEventLog* const event_log_; Transport* const transport_; const int report_interval_ms_; mutable Mutex mutex_rtcp_sender_; bool sending_ RTC_GUARDED_BY(mutex_rtcp_sender_); int64_t next_time_to_send_rtcp_ RTC_GUARDED_BY(mutex_rtcp_sender_); uint32_t timestamp_offset_ RTC_GUARDED_BY(mutex_rtcp_sender_); uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(mutex_rtcp_sender_); int64_t last_frame_capture_time_ms_ RTC_GUARDED_BY(mutex_rtcp_sender_); // SSRC that we receive on our RTP channel uint32_t remote_ssrc_ RTC_GUARDED_BY(mutex_rtcp_sender_); std::string cname_ RTC_GUARDED_BY(mutex_rtcp_sender_); ReceiveStatisticsProvider* receive_statistics_ RTC_GUARDED_BY(mutex_rtcp_sender_); std::map csrc_cnames_ RTC_GUARDED_BY(mutex_rtcp_sender_); // send CSRCs std::vector csrcs_ RTC_GUARDED_BY(mutex_rtcp_sender_); // Full intra request uint8_t sequence_number_fir_ RTC_GUARDED_BY(mutex_rtcp_sender_); // Loss Notification struct LossNotificationState { uint16_t last_decoded_seq_num; uint16_t last_received_seq_num; bool decodability_flag; }; LossNotificationState loss_notification_state_ RTC_GUARDED_BY(mutex_rtcp_sender_); // REMB int64_t remb_bitrate_ RTC_GUARDED_BY(mutex_rtcp_sender_); std::vector remb_ssrcs_ RTC_GUARDED_BY(mutex_rtcp_sender_); std::vector tmmbn_to_send_ RTC_GUARDED_BY(mutex_rtcp_sender_); uint32_t tmmbr_send_bps_ RTC_GUARDED_BY(mutex_rtcp_sender_); uint32_t packet_oh_send_ RTC_GUARDED_BY(mutex_rtcp_sender_); size_t max_packet_size_ RTC_GUARDED_BY(mutex_rtcp_sender_); // True if sending of XR Receiver reference time report is enabled. bool xr_send_receiver_reference_time_enabled_ RTC_GUARDED_BY(mutex_rtcp_sender_); RtcpPacketTypeCounterObserver* const packet_type_counter_observer_; RtcpPacketTypeCounter packet_type_counter_ RTC_GUARDED_BY(mutex_rtcp_sender_); RtcpNackStats nack_stats_ RTC_GUARDED_BY(mutex_rtcp_sender_); VideoBitrateAllocation video_bitrate_allocation_ RTC_GUARDED_BY(mutex_rtcp_sender_); bool send_video_bitrate_allocation_ RTC_GUARDED_BY(mutex_rtcp_sender_); std::map rtp_clock_rates_khz_ RTC_GUARDED_BY(mutex_rtcp_sender_); int8_t last_payload_type_ RTC_GUARDED_BY(mutex_rtcp_sender_); absl::optional CheckAndUpdateLayerStructure( const VideoBitrateAllocation& bitrate) const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); void SetFlag(uint32_t type, bool is_volatile) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); void SetFlags(const std::set& types, bool is_volatile) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); bool IsFlagPresent(uint32_t type) const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); bool ConsumeFlag(uint32_t type, bool forced = false) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); bool AllVolatileFlagsConsumed() const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_rtcp_sender_); struct ReportFlag { ReportFlag(uint32_t type, bool is_volatile) : type(type), is_volatile(is_volatile) {} bool operator<(const ReportFlag& flag) const { return type < flag.type; } bool operator==(const ReportFlag& flag) const { return type == flag.type; } const uint32_t type; const bool is_volatile; }; std::set report_flags_ RTC_GUARDED_BY(mutex_rtcp_sender_); typedef std::unique_ptr (RTCPSender::*BuilderFunc)( const RtcpContext&); // Map from RTCPPacketType to builder. std::map builders_; }; } // namespace webrtc #endif // MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_