/*
 *  Copyright (c) 2014 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.
 */

#include <assert.h>
#include <string.h>

#include "absl/types/optional.h"
#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {

static const size_t kGenericHeaderLength = 1;
static const size_t kExtendedHeaderLength = 2;

RtpPacketizerGeneric::RtpPacketizerGeneric(
    rtc::ArrayView<const uint8_t> payload,
    PayloadSizeLimits limits,
    const RTPVideoHeader& rtp_video_header,
    VideoFrameType frame_type)
    : remaining_payload_(payload) {
  BuildHeader(rtp_video_header, frame_type);

  limits.max_payload_len -= header_size_;
  payload_sizes_ = SplitAboutEqually(payload.size(), limits);
  current_packet_ = payload_sizes_.begin();
}

RtpPacketizerGeneric::RtpPacketizerGeneric(
    rtc::ArrayView<const uint8_t> payload,
    PayloadSizeLimits limits)
    : header_size_(0), remaining_payload_(payload) {
  payload_sizes_ = SplitAboutEqually(payload.size(), limits);
  current_packet_ = payload_sizes_.begin();
}

RtpPacketizerGeneric::~RtpPacketizerGeneric() = default;

size_t RtpPacketizerGeneric::NumPackets() const {
  return payload_sizes_.end() - current_packet_;
}

bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) {
  RTC_DCHECK(packet);
  if (current_packet_ == payload_sizes_.end())
    return false;

  size_t next_packet_payload_len = *current_packet_;

  uint8_t* out_ptr =
      packet->AllocatePayload(header_size_ + next_packet_payload_len);
  RTC_CHECK(out_ptr);

  if (header_size_ > 0) {
    memcpy(out_ptr, header_, header_size_);
    // Remove first-packet bit, following packets are intermediate.
    header_[0] &= ~RtpFormatVideoGeneric::kFirstPacketBit;
  }

  memcpy(out_ptr + header_size_, remaining_payload_.data(),
         next_packet_payload_len);

  remaining_payload_ = remaining_payload_.subview(next_packet_payload_len);

  ++current_packet_;

  // Packets left to produce and data left to split should end at the same time.
  RTC_DCHECK_EQ(current_packet_ == payload_sizes_.end(),
                remaining_payload_.empty());

  packet->SetMarker(remaining_payload_.empty());
  return true;
}

void RtpPacketizerGeneric::BuildHeader(const RTPVideoHeader& rtp_video_header,
                                       VideoFrameType frame_type) {
  header_size_ = kGenericHeaderLength;
  header_[0] = RtpFormatVideoGeneric::kFirstPacketBit;
  if (frame_type == VideoFrameType::kVideoFrameKey) {
    header_[0] |= RtpFormatVideoGeneric::kKeyFrameBit;
  }
  if (rtp_video_header.generic.has_value()) {
    // Store bottom 15 bits of the picture id. Only 15 bits are used for
    // compatibility with other packetizer implemenetations.
    uint16_t picture_id = rtp_video_header.generic->frame_id & 0x7FFF;
    header_[0] |= RtpFormatVideoGeneric::kExtendedHeaderBit;
    header_[1] = (picture_id >> 8) & 0x7F;
    header_[2] = picture_id & 0xFF;
    header_size_ += kExtendedHeaderLength;
  }
}

RtpDepacketizerGeneric::RtpDepacketizerGeneric(bool generic_header_enabled)
    : generic_header_enabled_(generic_header_enabled) {}

RtpDepacketizerGeneric::~RtpDepacketizerGeneric() = default;

bool RtpDepacketizerGeneric::Parse(ParsedPayload* parsed_payload,
                                   const uint8_t* payload_data,
                                   size_t payload_data_length) {
  assert(parsed_payload != NULL);
  if (payload_data_length == 0) {
    RTC_LOG(LS_WARNING) << "Empty payload.";
    return false;
  }

  if (generic_header_enabled_) {
    uint8_t generic_header = *payload_data++;
    --payload_data_length;

    parsed_payload->video_header().frame_type =
        ((generic_header & RtpFormatVideoGeneric::kKeyFrameBit) != 0)
            ? VideoFrameType::kVideoFrameKey
            : VideoFrameType::kVideoFrameDelta;
    parsed_payload->video_header().is_first_packet_in_frame =
        (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0;
    parsed_payload->video_header().codec = kVideoCodecGeneric;
    parsed_payload->video_header().width = 0;
    parsed_payload->video_header().height = 0;

    if (generic_header & RtpFormatVideoGeneric::kExtendedHeaderBit) {
      if (payload_data_length < kExtendedHeaderLength) {
        RTC_LOG(LS_WARNING) << "Too short payload for generic header.";
        return false;
      }
      parsed_payload->video_header().generic.emplace();
      parsed_payload->video_header().generic->frame_id =
          ((payload_data[0] & 0x7F) << 8) | payload_data[1];
      payload_data += kExtendedHeaderLength;
      payload_data_length -= kExtendedHeaderLength;
    }
  }

  parsed_payload->payload = payload_data;
  parsed_payload->payload_length = payload_data_length;
  return true;
}
}  // namespace webrtc
