/*
 *  Copyright (c) 2011 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_FORWARD_ERROR_CORRECTION_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_

#include <list>
#include <vector>

#include "typedefs.h"
#include "rtp_rtcp_defines.h"

namespace webrtc {

// Forward declaration.
struct FecPacket;

/**
 * Performs codec-independent forward error correction (FEC), based on RFC 5109.
 * Option exists to enable unequal protection (UEP) across packets.
 * This is not to be confused with protection within packets
 * (referred to as uneven level protection (ULP) in RFC 5109).
 */
class ForwardErrorCorrection {
 public:
  // Maximum number of media packets we can protect
  static const int kMaxMediaPackets = 48;

  struct Packet {
    uint16_t length;               /**> Length of packet in bytes. */
    uint8_t data[IP_PACKET_SIZE];  /**> Packet data. */
  };

  /**
   * The received list parameter of #DecodeFEC() must reference structs of this
   * type. The lastMediaPktInFrame is not required to be used for correct
   * recovery, but will reduce delay by allowing #DecodeFEC() to pre-emptively
   * determine frame completion. If set, we assume a FEC stream, and the
   * following assumptions must hold:\n
   *
   * 1. The media packets in a frame have contiguous sequence numbers, i.e. the
   *    frame's FEC packets have sequence numbers either lower than the first
   *    media packet or higher than the last media packet.\n
   * 2. All FEC packets have a sequence number base equal to the first media
   *    packet in the corresponding frame.\n
   *
   * The ssrc member is needed to ensure we can restore the SSRC field of
   * recovered packets. In most situations this could be retrieved from other
   * media packets, but in the case of an FEC packet protecting a single
   * missing media packet, we have no other means of obtaining it.
   */
  struct ReceivedPacket {
    uint16_t seqNum;    /**> Sequence number of packet. */
    uint32_t ssrc;      /**> SSRC of the current frame. Must be set for FEC
                             packets, but not required for media packets. */
    bool isFec;          /**> Set to true if this is an FEC packet and false
                              otherwise. */
    bool lastMediaPktInFrame; /**> Set to true to mark the last media packet in
                                   the frame and false otherwise. */
    Packet* pkt;              /**> Pointer to the packet storage. */
  };

  /**
   * The recovered list parameter of #DecodeFEC() will reference structs of
   * this type.
   */
  struct RecoveredPacket {
    bool wasRecovered;  /**> Will be true if this packet was recovered by
                             the FEC. Otherwise it was a media packet passed in
                             through the received packet list. */
    uint16_t seqNum;    /**> Sequence number of the packet. This is mostly for
                             implementation convenience but could be utilized
                             by the user if so desired. */
    Packet* pkt;        /**> Pointer to the packet storage. */
  };

  /**
   * \param[in] id Module ID
   */
  ForwardErrorCorrection(int32_t id);

  virtual ~ForwardErrorCorrection();

  /**
   * Generates a list of FEC packets from supplied media packets.
   *
   * \param[in]  mediaPacketList     List of media packets to protect, of type
   *                                 #Packet. All packets must belong to the
   *                                 same frame and the list must not be empty.
   * \param[in]  protectionFactor    FEC protection overhead in the [0, 255]
   *                                 domain. To obtain 100% overhead, or an
   *                                 equal number of FEC packets as media
   *                                 packets, use 255.
   * \param[in] numImportantPackets  The number of "important" packets in the
   *                                 frame. These packets may receive greater
   *                                 protection than the remaining packets. The
   *                                 important packets must be located at the
   *                                 start of the media packet list. For codecs
   *                                 with data partitioning, the important
   *                                 packets may correspond to first partition
   *                                 packets.
   * \param[in] useUnequalProtection Parameter to enable/disable unequal
   *                                 protection  (UEP) across packets. Enabling
   *                                 UEP will allocate more protection to the
   *                                 numImportantPackets from the start of the
   *                                 mediaPacketList.
   * \param[out] fecPacketList       List of FEC packets, of type #Packet. Must
   *                                 be empty on entry. The memory available
   *                                 through the list will be valid until the
   *                                 next call to GenerateFEC().
   *
   * \return 0 on success, -1 on failure.
   */
  int32_t GenerateFEC(const std::list<Packet*>& mediaPacketList,
                      uint8_t protectionFactor,
                      int numImportantPackets,
                      bool useUnequalProtection,
                      std::list<Packet*>* fecPacketList);

  /**
   *  Decodes a list of media and FEC packets. It will parse the input received
   *  packet list, storing FEC packets internally and inserting media packets to
   *  the output recovered packet list. The recovered list will be sorted by
   *  as cending sequence number and have duplicates removed. The function
   *  should be called as new packets arrive, with the recovered list being
   *  progressively assembled with each call. The received packet list will be
   *  empty at output.\n
   *
   *  The user will allocate packets submitted through the received list. The
   *  function will handle allocation of recovered packets and optionally
   *  deleting of all packet memory. The user may delete the recovered list
   *  packets, in which case they must remove deleted packets from the
   *  recovered list.\n
   *
   *  Before deleting an instance of the class, call the function with an empty
   *  received packet list and the completion parameter set to true. This will
   *  free any outstanding memory.
   *
   * \param[in]  receivedPacketList  List of new received packets, of type
   *                                 #ReceivedPacket, beloning to a single
   *                                 frame. At output the list will be empty,
   *                                 with packets  either stored internally,
   *                                 or accessible through the recovered list.
   * \param[out] recoveredPacketList List of recovered media packets, of type
   *                                 #RecoveredPacket, belonging to a single
   *                                 frame. The memory available through the
   *                                 list will be valid until the next call to
   *                                 DecodeFEC() in which the completion
   *                                 parameter is set to true.
   * \param[in] lastFECSeqNum        Estimated last seqNumber before this frame.
   * \param[in,out] frameComplete    Set to true on input to indicate the start
   *                                 of a new frame. On output, this will be
   *                                 set to true if all media packets in the
   *                                 frame have been recovered. Note that the
   *                                 frame may be complete without this
   *                                 parameter having been set, as it may not
   *                                 always be possible to determine frame
   *                                 completion.
   *
   * \return 0 on success, -1 on failure.
   */
  int32_t DecodeFEC(std::list<ReceivedPacket*>* receivedPacketList,
                    std::list<RecoveredPacket*>* recoveredPacketList,
                    uint16_t lastFECSeqNum,
                    bool& frameComplete);
  /**
   * Gets the size in bytes of the FEC/ULP headers, which must be accounted for
   * as packet overhead.
   * \return Packet overhead in bytes.
   */
  static uint16_t PacketOverhead();

 private:
  // True if first is <= than second.
  static bool CompareRecoveredPackets(RecoveredPacket* first,
                                      RecoveredPacket* second);

  void GenerateFecUlpHeaders(const std::list<Packet*>& mediaPacketList,
                             uint8_t* packetMask,
                             uint32_t numFecPackets);

  void GenerateFecBitStrings(const std::list<Packet*>& mediaPacketList,
                             uint8_t* packetMask,
                             uint32_t numFecPackets);

  // Reset internal states from last frame and clear the recoveredPacketList.
  void ResetState(std::list<RecoveredPacket*>* recoveredPacketList);

  // Insert received packets into FEC or recovered list.
  void InsertPackets(std::list<ReceivedPacket*>* receivedPacketList,
                     std::list<RecoveredPacket*>* recoveredPacketList);

  // Insert media packet into recovered packet list. We delete duplicates.
  void InsertMediaPacket(ReceivedPacket* rxPacket,
                         std::list<RecoveredPacket*>* recoveredPacketList);

  // Insert packet into FEC list. We delete duplicates.
  void InsertFECPacket(ReceivedPacket* rxPacket);

  // Insert into recovered list in correct position.
  void InsertRecoveredPacket(
      RecoveredPacket* recPacketToInsert,
      std::list<RecoveredPacket*>* recoveredPacketList);

  // Attempt to recover missing packets.
  void AttemptRecover(std::list<RecoveredPacket*>* recoveredPacketList);

  // Recover a missing packet.
  void RecoverPacket(const FecPacket& fecPacket,
                     RecoveredPacket* recPacketToInsert);

  // Get number of protected packet in the fecPacket.
  uint32_t NumberOfProtectedPackets(
      const FecPacket& fecPacket,
      std::list<RecoveredPacket*>* recoveredPacketList);

  int32_t _id;
  std::vector<Packet> _generatedFecPackets;
  std::list<FecPacket*> _fecPacketList;
  uint16_t _seqNumBase;
  bool _lastMediaPacketReceived;
  bool _fecPacketReceived;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_
