/*
 *  Copyright (c) 2018 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 "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"

#include <cstdint>

#include "rtc_base/checks.h"

namespace webrtc {

constexpr int RtpGenericFrameDescriptor::kMaxNumFrameDependencies;
constexpr int RtpGenericFrameDescriptor::kMaxTemporalLayers;
constexpr int RtpGenericFrameDescriptor::kMaxSpatialLayers;

RtpGenericFrameDescriptor::RtpGenericFrameDescriptor() = default;
RtpGenericFrameDescriptor::RtpGenericFrameDescriptor(
    const RtpGenericFrameDescriptor&) = default;
RtpGenericFrameDescriptor::~RtpGenericFrameDescriptor() = default;

int RtpGenericFrameDescriptor::TemporalLayer() const {
  RTC_DCHECK(FirstPacketInSubFrame());
  return temporal_layer_;
}

void RtpGenericFrameDescriptor::SetTemporalLayer(int temporal_layer) {
  RTC_DCHECK_GE(temporal_layer, 0);
  RTC_DCHECK_LT(temporal_layer, kMaxTemporalLayers);
  temporal_layer_ = temporal_layer;
}

int RtpGenericFrameDescriptor::SpatialLayer() const {
  RTC_DCHECK(FirstPacketInSubFrame());
  int layer = 0;
  uint8_t spatial_layers = spatial_layers_;
  while (spatial_layers_ != 0 && !(spatial_layers & 1)) {
    spatial_layers >>= 1;
    layer++;
  }
  return layer;
}

uint8_t RtpGenericFrameDescriptor::SpatialLayersBitmask() const {
  RTC_DCHECK(FirstPacketInSubFrame());
  return spatial_layers_;
}

void RtpGenericFrameDescriptor::SetSpatialLayersBitmask(
    uint8_t spatial_layers) {
  RTC_DCHECK(FirstPacketInSubFrame());
  spatial_layers_ = spatial_layers;
}

void RtpGenericFrameDescriptor::SetResolution(int width, int height) {
  RTC_DCHECK(FirstPacketInSubFrame());
  RTC_DCHECK_GE(width, 0);
  RTC_DCHECK_LE(width, 0xFFFF);
  RTC_DCHECK_GE(height, 0);
  RTC_DCHECK_LE(height, 0xFFFF);
  width_ = width;
  height_ = height;
}

uint16_t RtpGenericFrameDescriptor::FrameId() const {
  RTC_DCHECK(FirstPacketInSubFrame());
  return frame_id_;
}

void RtpGenericFrameDescriptor::SetFrameId(uint16_t frame_id) {
  RTC_DCHECK(FirstPacketInSubFrame());
  frame_id_ = frame_id;
}

rtc::ArrayView<const uint16_t>
RtpGenericFrameDescriptor::FrameDependenciesDiffs() const {
  RTC_DCHECK(FirstPacketInSubFrame());
  return rtc::MakeArrayView(frame_deps_id_diffs_, num_frame_deps_);
}

bool RtpGenericFrameDescriptor::AddFrameDependencyDiff(uint16_t fdiff) {
  RTC_DCHECK(FirstPacketInSubFrame());
  if (num_frame_deps_ == kMaxNumFrameDependencies)
    return false;
  if (fdiff == 0)
    return false;
  RTC_DCHECK_LT(fdiff, 1 << 14);
  RTC_DCHECK_GT(fdiff, 0);
  frame_deps_id_diffs_[num_frame_deps_] = fdiff;
  num_frame_deps_++;
  return true;
}

void RtpGenericFrameDescriptor::SetByteRepresentation(
    rtc::ArrayView<const uint8_t> byte_representation) {
  RTC_CHECK(!byte_representation.empty());
  byte_representation_.assign(byte_representation.begin(),
                              byte_representation.end());
  // Clear end_of_subframe bit.
  // Because ByteRepresentation is used for frame authentication, bit describing
  // position of the packet in the frame shouldn't be part of it.
  // This match RtpVideoSender where descriptor is passed for authentication
  // before end_of_subframe bit is decided and set, i.e. it is always 0.
  byte_representation_[0] &= ~0x40;
}

rtc::ArrayView<const uint8_t>
RtpGenericFrameDescriptor::GetByteRepresentation() {
  return byte_representation_;
}

}  // namespace webrtc
