/*
 *  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,
                                    const uint8_t associated_payload_type) = 0;

  virtual int SetRtxReceivePayloadType(
      const int video_channel,
      const uint8_t payload_type,
      const uint8_t associated_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 RTCP packet type statistics from a sent/received stream.
  virtual int GetSendRtcpPacketTypeCounter(
      int video_channel,
      RtcpPacketTypeCounter* packet_counter) const = 0;

  virtual int GetReceiveRtcpPacketTypeCounter(
      int video_channel,
      RtcpPacketTypeCounter* packet_counter) const = 0;

  // 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_
