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

/*
 * This file contains the declaration of the VP8 packetizer class.
 * A packetizer object is created for each encoded video frame. The
 * constructor is called with the payload data and size,
 * together with the fragmentation information and a packetizer mode
 * of choice. Alternatively, if no fragmentation info is available, the
 * second constructor can be used with only payload data and size; in that
 * case the mode kEqualSize is used.
 *
 * After creating the packetizer, the method NextPacket is called
 * repeatedly to get all packets for the frame. The method returns
 * false as long as there are more packets left to fetch.
 */

#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_

#include <queue>
#include <string>
#include <vector>

#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/typedefs.h"

namespace webrtc {

enum VP8PacketizerMode {
  kStrict = 0,  // Split partitions if too large;
                // never aggregate, balance size.
  kAggregate,   // Split partitions if too large; aggregate whole partitions.
  kEqualSize,   // Split entire payload without considering partition limits.
                // This will produce equal size packets for the whole frame.
  kNumModes,
};

// Packetizer for VP8.
class RtpPacketizerVp8 : public RtpPacketizer {
 public:
  // Initialize with payload from encoder and fragmentation info.
  // The payload_data must be exactly one encoded VP8 frame.
  RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info,
                   size_t max_payload_len,
                   size_t last_packet_reduction_len,
                   VP8PacketizerMode mode);

  // Initialize without fragmentation info. Mode kEqualSize will be used.
  // The payload_data must be exactly one encoded VP8 frame.
  RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info,
                   size_t max_payload_len,
                   size_t last_packet_reduction_len);

  virtual ~RtpPacketizerVp8();

  size_t SetPayloadData(const uint8_t* payload_data,
                        size_t payload_size,
                        const RTPFragmentationHeader* fragmentation) override;

  // Get the next payload with VP8 payload header.
  // Write payload and set marker bit of the |packet|.
  // Returns true on success, false otherwise.
  bool NextPacket(RtpPacketToSend* packet) override;

  ProtectionType GetProtectionType() override;

  StorageType GetStorageType(uint32_t retransmission_settings) override;

  std::string ToString() override;

 private:
  typedef struct {
    size_t payload_start_pos;
    size_t size;
    bool first_fragment;
    size_t first_partition_ix;
  } InfoStruct;
  typedef std::queue<InfoStruct> InfoQueue;

  static const int kXBit = 0x80;
  static const int kNBit = 0x20;
  static const int kSBit = 0x10;
  static const int kPartIdField = 0x0F;
  static const int kKeyIdxField = 0x1F;
  static const int kIBit = 0x80;
  static const int kLBit = 0x40;
  static const int kTBit = 0x20;
  static const int kKBit = 0x10;
  static const int kYBit = 0x20;

  // Calculate all packet sizes and load to packet info queue.
  int GeneratePackets();

  // Splits given part of payload (one or more partitions)
  // to packets with a given capacity. If |last_partition| flag is set then the
  // last packet should be reduced by last_packet_reduction_len_.
  void GeneratePacketsSplitPayloadBalanced(size_t payload_offset,
                                           size_t payload_len,
                                           size_t capacity,
                                           bool last_partition,
                                           size_t part_idx);

  // Aggregates partitions starting at |part_idx| to packets of
  // given |capacity|. Last packet, if containing last partition of the frame
  // should be reduced by last_packet_reduction_len_.
  // Returns the first unaggregated partition index.
  size_t GeneratePacketsAggregatePartitions(size_t part_idx, size_t capacity);

  // Insert packet into packet queue.
  void QueuePacket(size_t start_pos,
                   size_t packet_size,
                   size_t first_partition_in_packet,
                   bool start_on_new_fragment);

  // Write the payload header and copy the payload to the buffer.
  // The info in packet_info determines which part of the payload is written
  // and what to write in the header fields.
  int WriteHeaderAndPayload(const InfoStruct& packet_info,
                            uint8_t* buffer,
                            size_t buffer_length) const;

  // Write the X field and the appropriate extension fields to buffer.
  // The function returns the extension length (including X field), or -1
  // on error.
  int WriteExtensionFields(uint8_t* buffer, size_t buffer_length) const;

  // Set the I bit in the x_field, and write PictureID to the appropriate
  // position in buffer. The function returns 0 on success, -1 otherwise.
  int WritePictureIDFields(uint8_t* x_field,
                           uint8_t* buffer,
                           size_t buffer_length,
                           size_t* extension_length) const;

  // Set the L bit in the x_field, and write Tl0PicIdx to the appropriate
  // position in buffer. The function returns 0 on success, -1 otherwise.
  int WriteTl0PicIdxFields(uint8_t* x_field,
                           uint8_t* buffer,
                           size_t buffer_length,
                           size_t* extension_length) const;

  // Set the T and K bits in the x_field, and write TID, Y and KeyIdx to the
  // appropriate position in buffer. The function returns 0 on success,
  // -1 otherwise.
  int WriteTIDAndKeyIdxFields(uint8_t* x_field,
                              uint8_t* buffer,
                              size_t buffer_length,
                              size_t* extension_length) const;

  // Write the PictureID from codec_specific_info_ to buffer. One or two
  // bytes are written, depending on magnitude of PictureID. The function
  // returns the number of bytes written.
  int WritePictureID(uint8_t* buffer, size_t buffer_length) const;

  // Calculate and return length (octets) of the variable header fields in
  // the next header (i.e., header length in addition to vp8_header_bytes_).
  size_t PayloadDescriptorExtraLength() const;

  // Calculate and return length (octets) of PictureID field in the next
  // header. Can be 0, 1, or 2.
  size_t PictureIdLength() const;

  // Check whether each of the optional fields will be included in the header.
  bool XFieldPresent() const;
  bool TIDFieldPresent() const;
  bool KeyIdxFieldPresent() const;
  bool TL0PicIdxFieldPresent() const;
  bool PictureIdPresent() const { return (PictureIdLength() > 0); }

  const uint8_t* payload_data_;
  size_t payload_size_;
  RTPFragmentationHeader part_info_;
  const size_t vp8_fixed_payload_descriptor_bytes_;  // Length of VP8 payload
                                                     // descriptors' fixed part.
  const VP8PacketizerMode mode_;
  const RTPVideoHeaderVP8 hdr_info_;
  size_t num_partitions_;
  const size_t max_payload_len_;
  const size_t last_packet_reduction_len_;
  InfoQueue packets_;

  RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerVp8);
};

// Depacketizer for VP8.
class RtpDepacketizerVp8 : public RtpDepacketizer {
 public:
  virtual ~RtpDepacketizerVp8() {}

  bool Parse(ParsedPayload* parsed_payload,
             const uint8_t* payload_data,
             size_t payload_data_length) override;
};
}  // namespace webrtc
#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_
