/*
 *  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 <assert.h>
#include <math.h>

#include <map>

#include "webrtc/base/thread_annotations.h"
#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"

#define MAX_INIT_RTP_SEQ_NUMBER 32767  // 2^15 -1.

namespace webrtc {

class BitrateAggregator;
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,
                                 int8_t payload_type,
                                 bool marker_bit,
                                 uint32_t capture_timestamp,
                                 int64_t capture_time_ms,
                                 bool timestamp_provided = true,
                                 bool inc_sequence_number = true) = 0;

  virtual size_t RTPHeaderLength() const = 0;
  virtual uint16_t IncrementSequenceNumber() = 0;
  virtual uint16_t SequenceNumber() const = 0;
  virtual size_t MaxPayloadLength() const = 0;
  virtual size_t MaxDataPayloadLength() const = 0;
  virtual uint16_t PacketOverHead() const = 0;
  virtual uint16_t ActualSendBitrateKbit() const = 0;

  virtual int32_t SendToNetwork(
      uint8_t *data_buffer, size_t payload_length, size_t rtp_header_length,
      int64_t capture_time_ms, StorageType storage,
      PacedSender::Priority priority) = 0;
};

class RTPSender : public RTPSenderInterface {
 public:
  RTPSender(int32_t id,
            bool audio,
            Clock* clock,
            Transport* transport,
            RtpAudioFeedback* audio_feedback,
            PacedSender* paced_sender,
            BitrateStatisticsObserver* bitrate_callback,
            FrameCountObserver* frame_count_observer,
            SendSideDelayObserver* send_side_delay_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();

  // Includes size of RTP and FEC headers.
  virtual size_t MaxDataPayloadLength() const OVERRIDE;

  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);

  void SetSendPayloadType(int8_t payload_type);

  int8_t SendPayloadType() const;

  int SendPayloadFrequency() const;

  void SetSendingStatus(bool enabled);

  void SetSendingMediaStatus(bool enabled);
  bool SendingMedia() const;

  void GetDataCounters(StreamDataCounters* rtp_stats,
                       StreamDataCounters* rtx_stats) const;

  void ResetDataCounters();

  uint32_t StartTimestamp() const;
  void SetStartTimestamp(uint32_t timestamp, bool force);

  uint32_t GenerateNewSSRC();
  void SetSSRC(uint32_t ssrc);

  virtual uint16_t SequenceNumber() const OVERRIDE;
  void SetSequenceNumber(uint16_t seq);

  void SetCsrcs(const std::vector<uint32_t>& csrcs);

  int32_t SetMaxPayloadLength(size_t length, uint16_t packet_over_head);

  int32_t SendOutgoingData(FrameType frame_type,
                           int8_t payload_type,
                           uint32_t timestamp,
                           int64_t capture_time_ms,
                           const uint8_t* payload_data,
                           size_t payload_size,
                           const RTPFragmentationHeader* fragmentation,
                           VideoCodecInformation* codec_info = NULL,
                           const RTPVideoTypeHeader* rtp_type_hdr = NULL);

  // RTP header extension
  int32_t SetTransmissionTimeOffset(int32_t transmission_time_offset);
  int32_t SetAbsoluteSendTime(uint32_t absolute_send_time);

  int32_t RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);

  int32_t DeregisterRtpHeaderExtension(RTPExtensionType type);

  size_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,
                        size_t rtp_packet_length,
                        const RTPHeader& rtp_header,
                        bool is_voiced,
                        uint8_t dBov) const;

  bool TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms,
                        bool retransmission);
  size_t TimeToSendPadding(size_t bytes);

  // NACK.
  int SelectiveRetransmissions() const;
  int SetSelectiveRetransmissions(uint8_t settings);
  void OnReceivedNACK(const std::list<uint16_t>& nack_sequence_numbers,
                      uint16_t avg_rtt);

  void SetStorePacketsStatus(bool enable, uint16_t number_to_store);

  bool StorePackets() const;

  int32_t ReSendPacket(uint16_t packet_id, uint32_t min_resend_time = 0);

  bool ProcessNACKBitRate(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, int associated_payload_type);

  // Functions wrapping RTPSenderInterface.
  virtual int32_t BuildRTPheader(
      uint8_t* data_buffer,
      int8_t payload_type,
      bool marker_bit,
      uint32_t capture_timestamp,
      int64_t capture_time_ms,
      const bool timestamp_provided = true,
      const bool inc_sequence_number = true) OVERRIDE;

  virtual size_t RTPHeaderLength() const OVERRIDE;
  virtual uint16_t IncrementSequenceNumber() OVERRIDE;
  virtual size_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, size_t payload_length, size_t 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(uint8_t key, uint16_t time_ms, 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(uint16_t packet_size_samples);

  // Store the audio level in d_bov for
  // header-extension-for-audio-level-indication.
  int32_t SetAudioLevel(uint8_t level_d_bov);

  // Set payload type for Redundant Audio Data RFC 2198.
  int32_t SetRED(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(bool enable,
                              uint8_t payload_type_red,
                              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);

  size_t SendPadData(uint32_t timestamp,
                     int64_t capture_time_ms,
                     size_t bytes);

  // Called on update of RTP statistics.
  void RegisterRtpStatisticsCallback(StreamDataCountersCallback* callback);
  StreamDataCountersCallback* GetRtpStatisticsCallback() const;

  uint32_t BitrateSent() const;

  void SetRtpState(const RtpState& rtp_state);
  RtpState GetRtpState() const;
  void SetRtxRtpState(const RtpState& rtp_state);
  RtpState GetRtxRtpState() const;

 protected:
  int32_t CheckPayloadType(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<int64_t, int> SendDelayMap;

  size_t CreateRtpHeader(uint8_t* header,
                         int8_t payload_type,
                         uint32_t ssrc,
                         bool marker_bit,
                         uint32_t timestamp,
                         uint16_t sequence_number,
                         const std::vector<uint32_t>& csrcs) const;

  void UpdateNACKBitRate(uint32_t bytes, int64_t now);

  bool PrepareAndSendPacket(uint8_t* buffer,
                            size_t length,
                            int64_t capture_time_ms,
                            bool send_over_rtx,
                            bool is_retransmit);

  // Return the number of bytes sent.  Note that both of these functions may
  // return a larger value that their argument.
  size_t TrySendRedundantPayloads(size_t bytes);
  size_t TrySendPadData(size_t bytes);

  size_t BuildPaddingPacket(uint8_t* packet, size_t header_length);

  void BuildRtxPacket(uint8_t* buffer, size_t* length,
                      uint8_t* buffer_rtx);

  bool SendPacketToNetwork(const uint8_t *packet, size_t size);

  void UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms);

  void UpdateTransmissionTimeOffset(uint8_t* rtp_packet,
                                    size_t rtp_packet_length,
                                    const RTPHeader& rtp_header,
                                    int64_t time_diff_ms) const;
  void UpdateAbsoluteSendTime(uint8_t* rtp_packet,
                              size_t rtp_packet_length,
                              const RTPHeader& rtp_header,
                              int64_t now_ms) const;

  void UpdateRtpStats(const uint8_t* buffer,
                      size_t packet_length,
                      const RTPHeader& header,
                      bool is_rtx,
                      bool is_retransmit);
  bool IsFecPacket(const uint8_t* buffer, const RTPHeader& header) const;

  Clock* clock_;
  int64_t clock_delta_ms_;

  scoped_ptr<BitrateAggregator> bitrates_;
  Bitrate total_bitrate_sent_;

  int32_t id_;
  const bool audio_configured_;
  RTPSenderAudio *audio_;
  RTPSenderVideo *video_;

  PacedSender *paced_sender_;
  int64_t last_capture_time_ms_sent_;
  CriticalSectionWrapper *send_critsect_;

  Transport *transport_;
  bool sending_media_ GUARDED_BY(send_critsect_);

  size_t max_payload_length_;
  uint16_t packet_over_head_;

  int8_t payload_type_ GUARDED_BY(send_critsect_);
  std::map<int8_t, RtpUtility::Payload*> 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];
  size_t nack_byte_count_[NACK_BYTECOUNT_SIZE];
  Bitrate nack_bitrate_;

  RTPPacketHistory packet_history_;

  // Statistics
  scoped_ptr<CriticalSectionWrapper> statistics_crit_;
  SendDelayMap send_delays_ GUARDED_BY(statistics_crit_);
  FrameCounts 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_);
  FrameCountObserver* const frame_count_observer_;
  SendSideDelayObserver* const send_side_delay_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 media_has_been_sent_ GUARDED_BY(send_critsect_);
  bool last_packet_marker_bit_ GUARDED_BY(send_critsect_);
  std::vector<uint32_t> csrcs_ GUARDED_BY(send_critsect_);
  int rtx_ GUARDED_BY(send_critsect_);
  uint32_t ssrc_rtx_ GUARDED_BY(send_critsect_);
  // Mapping apt_rtx_types_[apt] = rtx.
  std::map<int, int> apt_rtx_types_ 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<CriticalSectionWrapper> target_bitrate_critsect_;
  uint32_t target_bitrate_ GUARDED_BY(target_bitrate_critsect_);
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_H_
