/* * 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.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/dlrr.h" #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h" #include "rtc_base/constructor_magic.h" #include "rtc_base/critical_section.h" #include "rtc_base/random.h" #include "rtc_base/thread_annotations.h" namespace webrtc { class ModuleRtpRtcpImpl; class RtcEventLog; class RTCPSender { 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. ModuleRtpRtcpImpl* module; }; explicit RTCPSender(const RtpRtcp::Configuration& config); virtual ~RTCPSender(); RtcpMode Status() const; void SetRTCPStatus(RtcpMode method); bool Sending() const; int32_t SetSendingStatus(const FeedbackState& feedback_state, bool enabled); // combine the functions int32_t SetNackStatus(bool enable); void SetTimestampOffset(uint32_t timestamp_offset); // 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); void SetRtpClockRate(int8_t payload_type, int rtp_clock_rate_hz); uint32_t SSRC() const; void SetSSRC(uint32_t ssrc); void SetRemoteSSRC(uint32_t ssrc); int32_t SetCNAME(const char* cName); int32_t AddMixedCNAME(uint32_t SSRC, const char* c_name); int32_t RemoveMixedCNAME(uint32_t SSRC); bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const; int32_t SendRTCP(const FeedbackState& feedback_state, RTCPPacketType packetType, int32_t nackSize = 0, const uint16_t* nackList = 0); int32_t SendCompoundRTCP(const FeedbackState& feedback_state, const std::set& packetTypes, int32_t nackSize = 0, const uint16_t* nackList = 0); 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); void SetRemb(int64_t bitrate_bps, std::vector ssrcs); void UnsetRemb(); bool TMMBR() const; void SetTMMBRStatus(bool enable); void SetMaxRtpPacketSize(size_t max_packet_size); void SetTmmbn(std::vector bounding_set); int32_t SetApplicationSpecificData(uint8_t subType, uint32_t name, const uint8_t* data, uint16_t length); void SendRtcpXrReceiverReferenceTime(bool enable); bool RtcpXrReceiverReferenceTime() const; void SetCsrcs(const std::vector& csrcs); void SetTargetBitrate(unsigned int target_bitrate); void SetVideoBitrateAllocation(const VideoBitrateAllocation& bitrate); bool SendFeedbackPacket(const rtcp::TransportFeedback& packet); bool SendNetworkStateEstimatePacket(const rtcp::RemoteEstimate& packet); private: class RtcpContext; // Determine which RTCP messages should be sent and setup flags. void PrepareReport(const FeedbackState& feedback_state) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::vector CreateReportBlocks( const FeedbackState& feedback_state) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildSR(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildRR(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildSDES(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildPLI(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildREMB(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildTMMBR(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildTMMBN(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildAPP(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildLossNotification( const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildExtendedReports( const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildBYE(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildFIR(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); std::unique_ptr BuildNACK(const RtcpContext& context) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); private: const bool audio_; Clock* const clock_; Random random_ RTC_GUARDED_BY(critical_section_rtcp_sender_); RtcpMode method_ RTC_GUARDED_BY(critical_section_rtcp_sender_); RtcEventLog* const event_log_; Transport* const transport_; const int report_interval_ms_; rtc::CriticalSection critical_section_rtcp_sender_; bool sending_ RTC_GUARDED_BY(critical_section_rtcp_sender_); int64_t next_time_to_send_rtcp_ RTC_GUARDED_BY(critical_section_rtcp_sender_); uint32_t timestamp_offset_ RTC_GUARDED_BY(critical_section_rtcp_sender_); uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(critical_section_rtcp_sender_); int64_t last_frame_capture_time_ms_ RTC_GUARDED_BY(critical_section_rtcp_sender_); uint32_t ssrc_ RTC_GUARDED_BY(critical_section_rtcp_sender_); // SSRC that we receive on our RTP channel uint32_t remote_ssrc_ RTC_GUARDED_BY(critical_section_rtcp_sender_); std::string cname_ RTC_GUARDED_BY(critical_section_rtcp_sender_); ReceiveStatisticsProvider* receive_statistics_ RTC_GUARDED_BY(critical_section_rtcp_sender_); std::map csrc_cnames_ RTC_GUARDED_BY(critical_section_rtcp_sender_); // send CSRCs std::vector csrcs_ RTC_GUARDED_BY(critical_section_rtcp_sender_); // Full intra request uint8_t sequence_number_fir_ RTC_GUARDED_BY(critical_section_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(critical_section_rtcp_sender_); // REMB int64_t remb_bitrate_ RTC_GUARDED_BY(critical_section_rtcp_sender_); std::vector remb_ssrcs_ RTC_GUARDED_BY(critical_section_rtcp_sender_); std::vector tmmbn_to_send_ RTC_GUARDED_BY(critical_section_rtcp_sender_); uint32_t tmmbr_send_bps_ RTC_GUARDED_BY(critical_section_rtcp_sender_); uint32_t packet_oh_send_ RTC_GUARDED_BY(critical_section_rtcp_sender_); size_t max_packet_size_ RTC_GUARDED_BY(critical_section_rtcp_sender_); // APP uint8_t app_sub_type_ RTC_GUARDED_BY(critical_section_rtcp_sender_); uint32_t app_name_ RTC_GUARDED_BY(critical_section_rtcp_sender_); std::unique_ptr app_data_ RTC_GUARDED_BY(critical_section_rtcp_sender_); uint16_t app_length_ RTC_GUARDED_BY(critical_section_rtcp_sender_); // True if sending of XR Receiver reference time report is enabled. bool xr_send_receiver_reference_time_enabled_ RTC_GUARDED_BY(critical_section_rtcp_sender_); RtcpPacketTypeCounterObserver* const packet_type_counter_observer_; RtcpPacketTypeCounter packet_type_counter_ RTC_GUARDED_BY(critical_section_rtcp_sender_); RtcpNackStats nack_stats_ RTC_GUARDED_BY(critical_section_rtcp_sender_); VideoBitrateAllocation video_bitrate_allocation_ RTC_GUARDED_BY(critical_section_rtcp_sender_); bool send_video_bitrate_allocation_ RTC_GUARDED_BY(critical_section_rtcp_sender_); std::map rtp_clock_rates_khz_ RTC_GUARDED_BY(critical_section_rtcp_sender_); int8_t last_payload_type_ RTC_GUARDED_BY(critical_section_rtcp_sender_); absl::optional CheckAndUpdateLayerStructure( const VideoBitrateAllocation& bitrate) const RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); void SetFlag(uint32_t type, bool is_volatile) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); void SetFlags(const std::set& types, bool is_volatile) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); bool IsFlagPresent(uint32_t type) const RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); bool ConsumeFlag(uint32_t type, bool forced = false) RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_); bool AllVolatileFlagsConsumed() const RTC_EXCLUSIVE_LOCKS_REQUIRED(critical_section_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(critical_section_rtcp_sender_); typedef std::unique_ptr (RTCPSender::*BuilderFunc)( const RtcpContext&); // Map from RTCPPacketType to builder. std::map builders_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RTCPSender); }; } // namespace webrtc #endif // MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_