/*
 *  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.
 */

// This sub-API supports the following functionalities:
//  - Callbacks for RTP and RTCP events such as modified SSRC or CSRC.
//  - SSRC handling.
//  - Transmission of RTCP reports.
//  - Obtaining RTCP data from incoming RTCP sender reports.
//  - RTP and RTCP statistics (jitter, packet loss, RTT etc.).
//  - Forward Error Correction (FEC).
//  - Writing RTP and RTCP packets to binary files for off‐line analysis of the
//    call quality.
//  - Inserting extra RTP packets into active audio stream.

#ifndef WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_RTP_RTCP_H_
#define WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_RTP_RTCP_H_

#include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"

namespace webrtc {

class VideoEngine;
struct ReceiveBandwidthEstimatorStats;

// This enumerator sets the RTCP mode.
enum ViERTCPMode {
  kRtcpNone = 0,
  kRtcpCompound_RFC4585 = 1,
  kRtcpNonCompound_RFC5506 = 2
};

// This enumerator describes the key frame request mode.
enum ViEKeyFrameRequestMethod {
  kViEKeyFrameRequestNone = 0,
  kViEKeyFrameRequestPliRtcp = 1,
  kViEKeyFrameRequestFirRtp = 2,
  kViEKeyFrameRequestFirRtcp = 3
};

enum StreamType {
  kViEStreamTypeNormal = 0,  // Normal media stream
  kViEStreamTypeRtx = 1  // Retransmission media stream
};

// This class declares an abstract interface for a user defined observer. It is
// up to the VideoEngine user to implement a derived class which implements the
// observer class. The observer is registered using RegisterRTPObserver() and
// deregistered using DeregisterRTPObserver().
class WEBRTC_DLLEXPORT ViERTPObserver {
 public:
  // This method is called if SSRC of the incoming stream is changed.
  virtual void IncomingSSRCChanged(const int video_channel,
                                   const unsigned int SSRC) = 0;

  // This method is called if a field in CSRC changes or if the number of
  // CSRCs changes.
  virtual void IncomingCSRCChanged(const int video_channel,
                                   const unsigned int CSRC,
                                   const bool added) = 0;
 protected:
  virtual ~ViERTPObserver() {}
};

class WEBRTC_DLLEXPORT ViERTP_RTCP {
 public:
  enum { KDefaultDeltaTransmitTimeSeconds = 15 };
  enum { KMaxRTCPCNameLength = 256 };

  // Factory for the ViERTP_RTCP sub‐API and increases an internal reference
  // counter if successful. Returns NULL if the API is not supported or if
  // construction fails.
  static ViERTP_RTCP* GetInterface(VideoEngine* video_engine);

  // Releases the ViERTP_RTCP sub-API and decreases an internal reference
  // counter. Returns the new reference count. This value should be zero
  // for all sub-API:s before the VideoEngine object can be safely deleted.
  virtual int Release() = 0;

  // This function enables you to specify the RTP synchronization source
  // identifier (SSRC) explicitly.
  virtual int SetLocalSSRC(const int video_channel,
                           const unsigned int SSRC,
                           const StreamType usage = kViEStreamTypeNormal,
                           const unsigned char simulcast_idx = 0) = 0;

  // This function gets the SSRC for the outgoing RTP stream for the specified
  // channel.
  virtual int GetLocalSSRC(const int video_channel,
                           unsigned int& SSRC) const = 0;

  // This function map a incoming SSRC to a StreamType so that the engine
  // can know which is the normal stream and which is the RTX
  virtual int SetRemoteSSRCType(const int video_channel,
                                const StreamType usage,
                                const unsigned int SSRC) const = 0;

  // This function gets the SSRC for the incoming RTP stream for the specified
  // channel.
  virtual int GetRemoteSSRC(const int video_channel,
                            unsigned int& SSRC) const = 0;

  // This function returns the CSRCs of the incoming RTP packets.
  virtual int GetRemoteCSRCs(const int video_channel,
                             unsigned int CSRCs[kRtpCsrcSize]) const = 0;

  // This sets a specific payload type for the RTX stream. Note that this
  // doesn't enable RTX, SetLocalSSRC must still be called to enable RTX.
  virtual int SetRtxSendPayloadType(const int video_channel,
                                    const uint8_t payload_type) = 0;

  virtual int SetRtxReceivePayloadType(const int video_channel,
                                       const uint8_t payload_type) = 0;

  // This function enables manual initialization of the sequence number. The
  // start sequence number is normally a random number.
  virtual int SetStartSequenceNumber(const int video_channel,
                                     unsigned short sequence_number) = 0;

  // TODO(pbos): Remove default implementation once this has been implemented
  // in libjingle.
  virtual void SetRtpStateForSsrc(int video_channel,
                                  uint32_t ssrc,
                                  const RtpState& rtp_state) {}
  // TODO(pbos): Remove default implementation once this has been implemented
  // in libjingle.
  virtual RtpState GetRtpStateForSsrc(int video_channel, uint32_t ssrc) {
    return RtpState();
  }

  // This function sets the RTCP status for the specified channel.
  // Default mode is kRtcpCompound_RFC4585.
  virtual int SetRTCPStatus(const int video_channel,
                            const ViERTCPMode rtcp_mode) = 0;

  // This function gets the RTCP status for the specified channel.
  virtual int GetRTCPStatus(const int video_channel,
                            ViERTCPMode& rtcp_mode) const = 0;

  // This function sets the RTCP canonical name (CNAME) for the RTCP reports
  // on a specific channel.
  virtual int SetRTCPCName(const int video_channel,
                           const char rtcp_cname[KMaxRTCPCNameLength]) = 0;

  // TODO(holmer): Remove this API once it has been removed from
  // fakewebrtcvideoengine.h.
  virtual int GetRTCPCName(const int video_channel,
                           char rtcp_cname[KMaxRTCPCNameLength]) const {
    return -1;
  }

  // This function gets the RTCP canonical name (CNAME) for the RTCP reports
  // received on the specified channel.
  virtual int GetRemoteRTCPCName(
      const int video_channel,
      char rtcp_cname[KMaxRTCPCNameLength]) const = 0;

  // This function sends an RTCP APP packet on a specific channel.
  virtual int SendApplicationDefinedRTCPPacket(
      const int video_channel,
      const unsigned char sub_type,
      unsigned int name,
      const char* data,
      unsigned short data_length_in_bytes) = 0;

  // This function enables Negative Acknowledgment (NACK) using RTCP,
  // implemented based on RFC 4585. NACK retransmits RTP packets if lost on
  // the network. This creates a lossless transport at the expense of delay.
  // If using NACK, NACK should be enabled on both endpoints in a call.
  virtual int SetNACKStatus(const int video_channel, const bool enable) = 0;

  // This function enables Forward Error Correction (FEC) using RTCP,
  // implemented based on RFC 5109, to improve packet loss robustness. Extra
  // FEC packets are sent together with the usual media packets, hence
  // part of the bitrate will be used for FEC packets.
  virtual int SetFECStatus(const int video_channel,
                           const bool enable,
                           const unsigned char payload_typeRED,
                           const unsigned char payload_typeFEC) = 0;

  // This function enables hybrid Negative Acknowledgment using RTCP
  // and Forward Error Correction (FEC) implemented based on RFC 5109,
  // to improve packet loss robustness. Extra
  // FEC packets are sent together with the usual media packets, hence will
  // part of the bitrate be used for FEC packets.
  // The hybrid mode will choose between nack only, fec only and both based on
  // network conditions. When both are applied, only packets that were not
  // recovered by the FEC will be nacked.
  virtual int SetHybridNACKFECStatus(const int video_channel,
                                     const bool enable,
                                     const unsigned char payload_typeRED,
                                     const unsigned char payload_typeFEC) = 0;

  // Sets send side support for delayed video buffering (actual delay will
  // be exhibited on the receiver side).
  // Target delay should be set to zero for real-time mode.
  virtual int SetSenderBufferingMode(int video_channel,
                                     int target_delay_ms) = 0;
  // Sets receive side support for delayed video buffering. Target delay should
  // be set to zero for real-time mode.
  virtual int SetReceiverBufferingMode(int video_channel,
                                       int target_delay_ms) = 0;

  // This function enables RTCP key frame requests.
  virtual int SetKeyFrameRequestMethod(
    const int video_channel, const ViEKeyFrameRequestMethod method) = 0;

  // This function enables signaling of temporary bitrate constraints using
  // RTCP, implemented based on RFC4585.
  virtual int SetTMMBRStatus(const int video_channel, const bool enable) = 0;

  // Enables and disables REMB packets for this channel. |sender| indicates
  // this channel is encoding, |receiver| tells the bitrate estimate for
  // this channel should be included in the REMB packet.
  virtual int SetRembStatus(int video_channel,
                            bool sender,
                            bool receiver) = 0;

  // Enables RTP timestamp extension offset described in RFC 5450. This call
  // must be done before ViECodec::SetSendCodec is called.
  virtual int SetSendTimestampOffsetStatus(int video_channel,
                                           bool enable,
                                           int id) = 0;

  virtual int SetReceiveTimestampOffsetStatus(int video_channel,
                                              bool enable,
                                              int id) = 0;

  // Enables RTP absolute send time header extension. This call must be done
  // before ViECodec::SetSendCodec is called.
  virtual int SetSendAbsoluteSendTimeStatus(int video_channel,
                                            bool enable,
                                            int id) = 0;

  // When enabled for a channel, *all* channels on the same transport will be
  // expected to include the absolute send time header extension.
  virtual int SetReceiveAbsoluteSendTimeStatus(int video_channel,
                                               bool enable,
                                               int id) = 0;

  virtual int SetSendVideoRotationStatus(int video_channel,
                                         bool enable,
                                         int id) = 0;

  virtual int SetReceiveVideoRotationStatus(int video_channel,
                                            bool enable,
                                            int id) = 0;

  // Enables/disables RTCP Receiver Reference Time Report Block extension/
  // DLRR Report Block extension (RFC 3611).
  virtual int SetRtcpXrRrtrStatus(int video_channel, bool enable) = 0;

  // Enables transmission smoothening, i.e. packets belonging to the same frame
  // will be sent over a longer period of time instead of sending them
  // back-to-back.
  virtual int SetTransmissionSmoothingStatus(int video_channel,
                                             bool enable) = 0;

  // Sets a minimal bitrate which will be padded to when the encoder doesn't
  // produce enough bitrate.
  // TODO(pbos): Remove default implementation when libjingle's
  // FakeWebRtcVideoEngine is updated.
  virtual int SetMinTransmitBitrate(int video_channel,
                                    int min_transmit_bitrate_kbps) {
    return -1;
  };

  // Set a constant amount to deduct from received bitrate estimates before
  // using it to allocate capacity among outgoing video streams.
  virtual int SetReservedTransmitBitrate(
      int video_channel, unsigned int reserved_transmit_bitrate_bps) {
    return 0;
  }

  // This function returns our locally created statistics of the received RTP
  // stream.
  virtual int GetReceiveChannelRtcpStatistics(const int video_channel,
                                              RtcpStatistics& basic_stats,
                                              int64_t& rtt_ms) const = 0;

  // This function returns statistics reported by the remote client in RTCP
  // report blocks. If several streams are reported, the statistics will be
  // aggregated.
  // If statistics are aggregated, extended_max_sequence_number is not reported,
  // and will always be set to 0.
  virtual int GetSendChannelRtcpStatistics(const int video_channel,
                                           RtcpStatistics& basic_stats,
                                           int64_t& rtt_ms) const = 0;

  // TODO(sprang): Temporary hacks to prevent libjingle build from failing,
  // remove when libjingle has been lifted to support webrtc issue 2589
  virtual int GetReceivedRTCPStatistics(const int video_channel,
                                        unsigned short& fraction_lost,
                                        unsigned int& cumulative_lost,
                                        unsigned int& extended_max,
                                        unsigned int& jitter,
                                        int64_t& rtt_ms) const {
    RtcpStatistics stats;
    int ret_code = GetReceiveChannelRtcpStatistics(video_channel,
                                             stats,
                                             rtt_ms);
    fraction_lost = stats.fraction_lost;
    cumulative_lost = stats.cumulative_lost;
    extended_max = stats.extended_max_sequence_number;
    jitter = stats.jitter;
    return ret_code;
  }
  virtual int GetSentRTCPStatistics(const int video_channel,
                                    unsigned short& fraction_lost,
                                    unsigned int& cumulative_lost,
                                    unsigned int& extended_max,
                                    unsigned int& jitter,
                                    int64_t& rtt_ms) const {
    RtcpStatistics stats;
    int ret_code = GetSendChannelRtcpStatistics(video_channel,
                                                stats,
                                                rtt_ms);
    fraction_lost = stats.fraction_lost;
    cumulative_lost = stats.cumulative_lost;
    extended_max = stats.extended_max_sequence_number;
    jitter = stats.jitter;
    return ret_code;
  }


  virtual int RegisterSendChannelRtcpStatisticsCallback(
      int video_channel, RtcpStatisticsCallback* callback) = 0;

  virtual int DeregisterSendChannelRtcpStatisticsCallback(
      int video_channel, RtcpStatisticsCallback* callback) = 0;

  virtual int RegisterReceiveChannelRtcpStatisticsCallback(
      int video_channel, RtcpStatisticsCallback* callback) = 0;

  virtual int DeregisterReceiveChannelRtcpStatisticsCallback(
      int video_channel, RtcpStatisticsCallback* callback) = 0;

  // The function gets statistics from the sent and received RTP streams.
  virtual int GetRtpStatistics(const int video_channel,
                               StreamDataCounters& sent,
                               StreamDataCounters& received) const = 0;

  // TODO(sprang): Temporary hacks to prevent libjingle build from failing,
  // remove when libjingle has been lifted to support webrtc issue 2589
  virtual int GetRTPStatistics(const int video_channel,
                       size_t& bytes_sent,
                       unsigned int& packets_sent,
                       size_t& bytes_received,
                       unsigned int& packets_received) const {
    StreamDataCounters sent;
    StreamDataCounters received;
    int ret_code = GetRtpStatistics(video_channel, sent, received);
    bytes_sent = sent.transmitted.payload_bytes;
    packets_sent = sent.transmitted.packets;
    bytes_received = received.transmitted.payload_bytes;
    packets_received = received.transmitted.packets;
    return ret_code;
  }

  virtual int RegisterSendChannelRtpStatisticsCallback(
      int video_channel, StreamDataCountersCallback* callback) = 0;

  virtual int DeregisterSendChannelRtpStatisticsCallback(
      int video_channel, StreamDataCountersCallback* callback) = 0;

  virtual int RegisterReceiveChannelRtpStatisticsCallback(
      int video_channel, StreamDataCountersCallback* callback) = 0;

  virtual int DeregisterReceiveChannelRtpStatisticsCallback(
      int video_channel, StreamDataCountersCallback* callback) = 0;


  // Gets sent and received RTCP packet types.
  // TODO(asapersson): Remove default implementation.
  virtual int GetRtcpPacketTypeCounters(
      int video_channel,
      RtcpPacketTypeCounter* packets_sent,
      RtcpPacketTypeCounter* packets_received) const { return -1; }

  // The function gets bandwidth usage statistics from the sent RTP streams in
  // bits/s.
  virtual int GetBandwidthUsage(const int video_channel,
                                unsigned int& total_bitrate_sent,
                                unsigned int& video_bitrate_sent,
                                unsigned int& fec_bitrate_sent,
                                unsigned int& nackBitrateSent) const = 0;

  // (De)Register an observer, called whenever the send bitrate is updated
  virtual int RegisterSendBitrateObserver(
      int video_channel,
      BitrateStatisticsObserver* observer) = 0;

  virtual int DeregisterSendBitrateObserver(
      int video_channel,
      BitrateStatisticsObserver* observer) = 0;

  // This function gets the send-side estimated bandwidth available for video,
  // including overhead, in bits/s.
  virtual int GetEstimatedSendBandwidth(
      const int video_channel,
      unsigned int* estimated_bandwidth) const = 0;

  // This function gets the receive-side estimated bandwidth available for
  // video, including overhead, in bits/s. |estimated_bandwidth| is 0 if there
  // is no valid estimate.
  virtual int GetEstimatedReceiveBandwidth(
      const int video_channel,
      unsigned int* estimated_bandwidth) const = 0;

  // This function gets the PacedSender queuing delay for the last sent frame.
  // TODO(jiayl): remove the default impl when libjingle is updated.
  virtual int GetPacerQueuingDelayMs(
      const int video_channel, int64_t* delay_ms) const {
    return -1;
  }

  // This function enables capturing of RTP packets to a binary file on a
  // specific channel and for a given direction. The file can later be
  // replayed using e.g. RTP Tools rtpplay since the binary file format is
  // compatible with the rtpdump format.
  virtual int StartRTPDump(const int video_channel,
                           const char file_nameUTF8[1024],
                           RTPDirections direction) = 0;

  // This function disables capturing of RTP packets to a binary file on a
  // specific channel and for a given direction.
  virtual int StopRTPDump(const int video_channel,
                          RTPDirections direction) = 0;

  // Registers an instance of a user implementation of the ViERTPObserver.
  virtual int RegisterRTPObserver(const int video_channel,
                                  ViERTPObserver& observer) = 0;

  // Removes a registered instance of ViERTPObserver.
  virtual int DeregisterRTPObserver(const int video_channel) = 0;

  // Registers and instance of a user implementation of ViEFrameCountObserver
  virtual int RegisterSendFrameCountObserver(
      int video_channel, FrameCountObserver* observer) = 0;

  // Removes a registered instance of a ViEFrameCountObserver
  virtual int DeregisterSendFrameCountObserver(
      int video_channel, FrameCountObserver* observer) = 0;

  // Called when RTCP packet type counters might have been changed. User has to
  // filter on SSRCs to determine whether it's status sent or received.
  virtual int RegisterRtcpPacketTypeCounterObserver(
      int video_channel,
      RtcpPacketTypeCounterObserver* observer) = 0;

 protected:
  virtual ~ViERTP_RTCP() {}
};

}  // namespace webrtc

#endif  // WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_RTP_RTCP_H_
