/*
 *  Copyright (c) 2016 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 "webrtc/modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h"

#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"

namespace webrtc {
namespace rtcp {
constexpr size_t kTargetBitrateHeaderSizeBytes = 4;
constexpr uint8_t TargetBitrate::kBlockType;
const size_t TargetBitrate::kBitrateItemSizeBytes = 4;

TargetBitrate::BitrateItem::BitrateItem()
    : spatial_layer(0), temporal_layer(0), target_bitrate_kbps(0) {}

TargetBitrate::BitrateItem::BitrateItem(uint8_t spatial_layer,
                                        uint8_t temporal_layer,
                                        uint32_t target_bitrate_kbps)
    : spatial_layer(spatial_layer),
      temporal_layer(temporal_layer),
      target_bitrate_kbps(target_bitrate_kbps) {}

//  RFC 4585: Feedback format.
//
//  Common packet format:
//
//   0                   1                   2                   3
//   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |     BT=42     |   reserved    |         block length          |
//  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
//  Target bitrate item (repeat as many times as necessary).
//
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  |   S   |   T   |                Target Bitrate                 |
//  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//  :  ...                                                          :
//
//  Spatial Layer (S): 4 bits
//    Indicates which temporal layer this bitrate concerns.
//
//  Temporal Layer (T): 4 bits
//    Indicates which temporal layer this bitrate concerns.
//
//  Target Bitrate: 24 bits
//    The encoder target bitrate for this layer, in kbps.
//
//  As an example of how S and T are intended to be used, VP8 simulcast will
//  use a separate TargetBitrate message per stream, since they are transmitted
//  on separate SSRCs, with temporal layers grouped by stream.
//  If VP9 SVC is used, there will be only one SSRC, so each spatial and
//  temporal layer combo used shall be specified in the TargetBitrate packet.

TargetBitrate::TargetBitrate() {}
TargetBitrate::~TargetBitrate() {}

void TargetBitrate::Create(uint8_t* buffer) const {
  buffer[0] = kBlockType;
  buffer[1] = 0;  // Reserved.
  const size_t block_length_words = (BlockLength() / 4) - 1;
  ByteWriter<uint16_t>::WriteBigEndian(&buffer[2], block_length_words);

  size_t index = kTargetBitrateHeaderSizeBytes;
  for (const BitrateItem& item : bitrates_) {
    buffer[index] = (item.spatial_layer << 4) | item.temporal_layer;
    ByteWriter<uint32_t, 3>::WriteBigEndian(&buffer[index + 1],
                                            item.target_bitrate_kbps);
    index += kBitrateItemSizeBytes;
  }
}

bool TargetBitrate::Parse(const uint8_t* block, uint16_t block_length) {
  if (block_length < 1) {
    LOG(LS_WARNING)
        << "Cannot parse TargetBitrate RTCP packet: Too little payload data ("
        << kTargetBitrateHeaderSizeBytes << " bytes needed, got "
        << block_length * 4 << ").";
    return false;
  }

  // Validate block header (should already have been parsed and checked).
  RTC_DCHECK_EQ(block[0], kBlockType);
  RTC_DCHECK_EQ(block_length, ByteReader<uint16_t>::ReadBigEndian(&block[2]));

  // Header specifies block length - 1, but since we ignore the header, which
  // occupies exactly on block, we can just treat this as payload length.
  const size_t payload_bytes = block_length * 4;
  const size_t num_items = payload_bytes / kBitrateItemSizeBytes;
  size_t index = kTargetBitrateHeaderSizeBytes;
  bitrates_.clear();
  for (size_t i = 0; i < num_items; ++i) {
    uint8_t layers = block[index];
    uint32_t bitrate_kbps =
        ByteReader<uint32_t, 3>::ReadBigEndian(&block[index + 1]);
    index += kBitrateItemSizeBytes;
    AddTargetBitrate((layers >> 4) & 0x0F, layers & 0x0F, bitrate_kbps);
  }

  return true;
}

void TargetBitrate::AddTargetBitrate(uint8_t spatial_layer,
                                     uint8_t temporal_layer,
                                     uint32_t target_bitrate_kbps) {
  RTC_DCHECK_LE(spatial_layer, 0x0F);
  RTC_DCHECK_LE(temporal_layer, 0x0F);
  RTC_DCHECK_LE(target_bitrate_kbps, 0x00FFFFFFU);
  bitrates_.push_back(
      BitrateItem(spatial_layer, temporal_layer, target_bitrate_kbps));
}

const std::vector<TargetBitrate::BitrateItem>&
TargetBitrate::GetTargetBitrates() const {
  return bitrates_;
}

size_t TargetBitrate::BlockLength() const {
  return kTargetBitrateHeaderSizeBytes +
         bitrates_.size() * kBitrateItemSizeBytes;
}

}  // namespace rtcp
}  // namespace webrtc
