/* * 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 WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_H_ #include #include #include #include "webrtc/common_types.h" #include "webrtc/modules/pacing/include/paced_sender.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" #include "webrtc/modules/rtp_rtcp/source/bitrate.h" #include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h" #include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h" #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h" #include "webrtc/modules/rtp_rtcp/source/ssrc_database.h" #include "webrtc/modules/rtp_rtcp/source/video_codec_information.h" #include "webrtc/system_wrappers/interface/thread_annotations.h" #define MAX_INIT_RTP_SEQ_NUMBER 32767 // 2^15 -1. namespace webrtc { class CriticalSectionWrapper; class RTPSenderAudio; class RTPSenderVideo; class RTPSenderInterface { public: RTPSenderInterface() {} virtual ~RTPSenderInterface() {} virtual uint32_t SSRC() const = 0; virtual uint32_t Timestamp() const = 0; virtual int32_t BuildRTPheader(uint8_t* data_buffer, const int8_t payload_type, const bool marker_bit, const uint32_t capture_timestamp, int64_t capture_time_ms, const bool timestamp_provided = true, const bool inc_sequence_number = true) = 0; virtual uint16_t RTPHeaderLength() const = 0; virtual uint16_t IncrementSequenceNumber() = 0; virtual uint16_t SequenceNumber() const = 0; virtual uint16_t MaxPayloadLength() const = 0; virtual uint16_t MaxDataPayloadLength() const = 0; virtual uint16_t PacketOverHead() const = 0; virtual uint16_t ActualSendBitrateKbit() const = 0; virtual int32_t SendToNetwork( uint8_t *data_buffer, int payload_length, int rtp_header_length, int64_t capture_time_ms, StorageType storage, PacedSender::Priority priority) = 0; }; class RTPSender : public RTPSenderInterface, public Bitrate::Observer { public: RTPSender(const int32_t id, const bool audio, Clock *clock, Transport *transport, RtpAudioFeedback *audio_feedback, PacedSender *paced_sender, BitrateStatisticsObserver* bitrate_callback, FrameCountObserver* frame_count_observer); virtual ~RTPSender(); void ProcessBitrate(); virtual uint16_t ActualSendBitrateKbit() const OVERRIDE; uint32_t VideoBitrateSent() const; uint32_t FecOverheadRate() const; uint32_t NackOverheadRate() const; // Returns true if the statistics have been calculated, and false if no frame // was sent within the statistics window. bool GetSendSideDelay(int* avg_send_delay_ms, int* max_send_delay_ms) const; void SetTargetBitrate(uint32_t bitrate); uint32_t GetTargetBitrate(); virtual uint16_t MaxDataPayloadLength() const OVERRIDE; // with RTP and FEC headers. int32_t RegisterPayload( const char payload_name[RTP_PAYLOAD_NAME_SIZE], const int8_t payload_type, const uint32_t frequency, const uint8_t channels, const uint32_t rate); int32_t DeRegisterSendPayload(const int8_t payload_type); int8_t SendPayloadType() const; int SendPayloadFrequency() const; void SetSendingStatus(bool enabled); void SetSendingMediaStatus(const bool enabled); bool SendingMedia() const; // Number of sent RTP packets. uint32_t Packets() const; // Number of sent RTP bytes. uint32_t Bytes() const; void ResetDataCounters(); uint32_t StartTimestamp() const; void SetStartTimestamp(uint32_t timestamp, bool force); uint32_t GenerateNewSSRC(); void SetSSRC(const uint32_t ssrc); virtual uint16_t SequenceNumber() const OVERRIDE; void SetSequenceNumber(uint16_t seq); int32_t CSRCs(uint32_t arr_of_csrc[kRtpCsrcSize]) const; void SetCSRCStatus(const bool include); void SetCSRCs(const uint32_t arr_of_csrc[kRtpCsrcSize], const uint8_t arr_length); int32_t SetMaxPayloadLength(const uint16_t length, const uint16_t packet_over_head); int32_t SendOutgoingData(const FrameType frame_type, const int8_t payload_type, const uint32_t timestamp, int64_t capture_time_ms, const uint8_t* payload_data, const uint32_t payload_size, const RTPFragmentationHeader* fragmentation, VideoCodecInformation* codec_info = NULL, const RTPVideoTypeHeader* rtp_type_hdr = NULL); // RTP header extension int32_t SetTransmissionTimeOffset( const int32_t transmission_time_offset); int32_t SetAbsoluteSendTime( const uint32_t absolute_send_time); int32_t RegisterRtpHeaderExtension(const RTPExtensionType type, const uint8_t id); int32_t DeregisterRtpHeaderExtension(const RTPExtensionType type); uint16_t RtpHeaderExtensionTotalLength() const; uint16_t BuildRTPHeaderExtension(uint8_t* data_buffer) const; uint8_t BuildTransmissionTimeOffsetExtension(uint8_t *data_buffer) const; uint8_t BuildAudioLevelExtension(uint8_t* data_buffer) const; uint8_t BuildAbsoluteSendTimeExtension(uint8_t* data_buffer) const; bool UpdateAudioLevel(uint8_t *rtp_packet, const uint16_t rtp_packet_length, const RTPHeader &rtp_header, const bool is_voiced, const uint8_t dBov) const; bool TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms, bool retransmission); int TimeToSendPadding(int bytes); // NACK. int SelectiveRetransmissions() const; int SetSelectiveRetransmissions(uint8_t settings); void OnReceivedNACK(const std::list& nack_sequence_numbers, const uint16_t avg_rtt); void SetStorePacketsStatus(const bool enable, const uint16_t number_to_store); bool StorePackets() const; int32_t ReSendPacket(uint16_t packet_id, uint32_t min_resend_time = 0); bool ProcessNACKBitRate(const uint32_t now); // RTX. void SetRTXStatus(int mode); void RTXStatus(int* mode, uint32_t* ssrc, int* payload_type) const; uint32_t RtxSsrc() const; void SetRtxSsrc(uint32_t ssrc); void SetRtxPayloadType(int payloadType); // Functions wrapping RTPSenderInterface. virtual int32_t BuildRTPheader( uint8_t* data_buffer, const int8_t payload_type, const bool marker_bit, const uint32_t capture_timestamp, int64_t capture_time_ms, const bool timestamp_provided = true, const bool inc_sequence_number = true) OVERRIDE; virtual uint16_t RTPHeaderLength() const OVERRIDE; virtual uint16_t IncrementSequenceNumber() OVERRIDE; virtual uint16_t MaxPayloadLength() const OVERRIDE; virtual uint16_t PacketOverHead() const OVERRIDE; // Current timestamp. virtual uint32_t Timestamp() const OVERRIDE; virtual uint32_t SSRC() const OVERRIDE; virtual int32_t SendToNetwork( uint8_t *data_buffer, int payload_length, int rtp_header_length, int64_t capture_time_ms, StorageType storage, PacedSender::Priority priority) OVERRIDE; // Audio. // Send a DTMF tone using RFC 2833 (4733). int32_t SendTelephoneEvent(const uint8_t key, const uint16_t time_ms, const uint8_t level); bool SendTelephoneEventActive(int8_t *telephone_event) const; // Set audio packet size, used to determine when it's time to send a DTMF // packet in silence (CNG). int32_t SetAudioPacketSize(const uint16_t packet_size_samples); // Store the audio level in d_bov for // header-extension-for-audio-level-indication. int32_t SetAudioLevel(const uint8_t level_d_bov); // Set payload type for Redundant Audio Data RFC 2198. int32_t SetRED(const int8_t payload_type); // Get payload type for Redundant Audio Data RFC 2198. int32_t RED(int8_t *payload_type) const; // Video. VideoCodecInformation *CodecInformationVideo(); RtpVideoCodecTypes VideoCodecType() const; uint32_t MaxConfiguredBitrateVideo() const; int32_t SendRTPIntraRequest(); // FEC. int32_t SetGenericFECStatus(const bool enable, const uint8_t payload_type_red, const uint8_t payload_type_fec); int32_t GenericFECStatus(bool *enable, uint8_t *payload_type_red, uint8_t *payload_type_fec) const; int32_t SetFecParameters(const FecProtectionParams *delta_params, const FecProtectionParams *key_params); int SendPadData(int payload_type, uint32_t timestamp, int64_t capture_time_ms, int32_t bytes, StorageType store, bool force_full_size_packets, bool only_pad_after_markerbit); // Called on update of RTP statistics. void RegisterRtpStatisticsCallback(StreamDataCountersCallback* callback); StreamDataCountersCallback* GetRtpStatisticsCallback() const; uint32_t BitrateSent() const; virtual void BitrateUpdated(const BitrateStatistics& stats) OVERRIDE; void SetRtpState(const RtpState& rtp_state); RtpState GetRtpState() const; void SetRtxRtpState(const RtpState& rtp_state); RtpState GetRtxRtpState() const; protected: int32_t CheckPayloadType(const int8_t payload_type, RtpVideoCodecTypes *video_type); private: // Maps capture time in milliseconds to send-side delay in milliseconds. // Send-side delay is the difference between transmission time and capture // time. typedef std::map SendDelayMap; int CreateRTPHeader(uint8_t* header, int8_t payload_type, uint32_t ssrc, bool marker_bit, uint32_t timestamp, uint16_t sequence_number, const uint32_t* csrcs, uint8_t csrcs_length) const; void UpdateNACKBitRate(const uint32_t bytes, const uint32_t now); bool PrepareAndSendPacket(uint8_t* buffer, uint16_t length, int64_t capture_time_ms, bool send_over_rtx, bool is_retransmit); int SendRedundantPayloads(int payload_type, int bytes); bool SendPaddingAccordingToBitrate(int8_t payload_type, uint32_t capture_timestamp, int64_t capture_time_ms); int BuildPaddingPacket(uint8_t* packet, int header_length, int32_t bytes); void BuildRtxPacket(uint8_t* buffer, uint16_t* length, uint8_t* buffer_rtx); bool SendPacketToNetwork(const uint8_t *packet, uint32_t size); void UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms); void UpdateTransmissionTimeOffset(uint8_t *rtp_packet, const uint16_t rtp_packet_length, const RTPHeader &rtp_header, const int64_t time_diff_ms) const; void UpdateAbsoluteSendTime(uint8_t *rtp_packet, const uint16_t rtp_packet_length, const RTPHeader &rtp_header, const int64_t now_ms) const; void UpdateRtpStats(const uint8_t* buffer, uint32_t size, const RTPHeader& header, bool is_rtx, bool is_retransmit); bool IsFecPacket(const uint8_t* buffer, const RTPHeader& header) const; Clock* clock_; Bitrate bitrate_sent_; int32_t id_; const bool audio_configured_; RTPSenderAudio *audio_; RTPSenderVideo *video_; PacedSender *paced_sender_; CriticalSectionWrapper *send_critsect_; Transport *transport_; bool sending_media_ GUARDED_BY(send_critsect_); uint16_t max_payload_length_; uint16_t packet_over_head_; int8_t payload_type_ GUARDED_BY(send_critsect_); std::map payload_type_map_; RtpHeaderExtensionMap rtp_header_extension_map_; int32_t transmission_time_offset_; uint32_t absolute_send_time_; // NACK uint32_t nack_byte_count_times_[NACK_BYTECOUNT_SIZE]; int32_t nack_byte_count_[NACK_BYTECOUNT_SIZE]; Bitrate nack_bitrate_; RTPPacketHistory packet_history_; // Statistics scoped_ptr statistics_crit_; SendDelayMap send_delays_ GUARDED_BY(statistics_crit_); std::map frame_counts_ GUARDED_BY(statistics_crit_); StreamDataCounters rtp_stats_ GUARDED_BY(statistics_crit_); StreamDataCounters rtx_rtp_stats_ GUARDED_BY(statistics_crit_); StreamDataCountersCallback* rtp_stats_callback_ GUARDED_BY(statistics_crit_); BitrateStatisticsObserver* const bitrate_callback_; FrameCountObserver* const frame_count_observer_; // RTP variables bool start_timestamp_forced_ GUARDED_BY(send_critsect_); uint32_t start_timestamp_ GUARDED_BY(send_critsect_); SSRCDatabase& ssrc_db_ GUARDED_BY(send_critsect_); uint32_t remote_ssrc_ GUARDED_BY(send_critsect_); bool sequence_number_forced_ GUARDED_BY(send_critsect_); uint16_t sequence_number_ GUARDED_BY(send_critsect_); uint16_t sequence_number_rtx_ GUARDED_BY(send_critsect_); bool ssrc_forced_ GUARDED_BY(send_critsect_); uint32_t ssrc_ GUARDED_BY(send_critsect_); uint32_t timestamp_ GUARDED_BY(send_critsect_); int64_t capture_time_ms_ GUARDED_BY(send_critsect_); int64_t last_timestamp_time_ms_ GUARDED_BY(send_critsect_); bool last_packet_marker_bit_ GUARDED_BY(send_critsect_); uint8_t num_csrcs_ GUARDED_BY(send_critsect_); uint32_t csrcs_[kRtpCsrcSize] GUARDED_BY(send_critsect_); bool include_csrcs_ GUARDED_BY(send_critsect_); int rtx_ GUARDED_BY(send_critsect_); uint32_t ssrc_rtx_ GUARDED_BY(send_critsect_); int payload_type_rtx_ GUARDED_BY(send_critsect_); // Note: Don't access this variable directly, always go through // SetTargetBitrateKbps or GetTargetBitrateKbps. Also remember // that by the time the function returns there is no guarantee // that the target bitrate is still valid. scoped_ptr target_bitrate_critsect_; uint32_t target_bitrate_ GUARDED_BY(target_bitrate_critsect_); }; } // namespace webrtc #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_H_