/*
 *  Copyright (c) 2020 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 MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_
#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_

#include <vector>

#include "absl/container/inlined_vector.h"
#include "absl/types/optional.h"
#include "api/transport/rtp/dependency_descriptor.h"
#include "api/video/video_bitrate_allocation.h"
#include "common_video/generic_frame_descriptor/generic_frame_info.h"

namespace webrtc {

// Controls how video should be encoded to be scalable. Outputs results as
// buffer usage configuration for encoder and enough details to communicate the
// scalability structure via dependency descriptor rtp header extension.
class ScalableVideoController {
 public:
  struct StreamLayersConfig {
    int num_spatial_layers = 1;
    int num_temporal_layers = 1;
    // Spatial layers scaling. Frames with spatial_id = i expected to be encoded
    // with original_resolution * scaling_factor_num[i] / scaling_factor_den[i].
    int scaling_factor_num[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1};
    int scaling_factor_den[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1};
  };
  class LayerFrameConfig {
   public:
    // Builders/setters.
    LayerFrameConfig& Id(int value);
    LayerFrameConfig& Keyframe();
    LayerFrameConfig& S(int value);
    LayerFrameConfig& T(int value);
    LayerFrameConfig& Reference(int buffer_id);
    LayerFrameConfig& Update(int buffer_id);
    LayerFrameConfig& ReferenceAndUpdate(int buffer_id);

    // Getters.
    int Id() const { return id_; }
    bool IsKeyframe() const { return is_keyframe_; }
    int SpatialId() const { return spatial_id_; }
    int TemporalId() const { return temporal_id_; }
    const absl::InlinedVector<CodecBufferUsage, kMaxEncoderBuffers>& Buffers()
        const {
      return buffers_;
    }

   private:
    // Id to match configuration returned by NextFrameConfig with
    // (possibly modified) configuration passed back via OnEncoderDone.
    // The meaning of the id is an implementation detail of
    // the ScalableVideoController.
    int id_ = 0;

    // Indication frame should be encoded as a key frame. In particular when
    // `is_keyframe=true` property `CodecBufferUsage::referenced` should be
    // ignored and treated as false.
    bool is_keyframe_ = false;

    int spatial_id_ = 0;
    int temporal_id_ = 0;
    // Describes how encoder which buffers encoder allowed to reference and
    // which buffers encoder should update.
    absl::InlinedVector<CodecBufferUsage, kMaxEncoderBuffers> buffers_;
  };

  virtual ~ScalableVideoController() = default;

  // Returns video structure description for encoder to configure itself.
  virtual StreamLayersConfig StreamConfig() const = 0;

  // Returns video structure description in format compatible with
  // dependency descriptor rtp header extension.
  virtual FrameDependencyStructure DependencyStructure() const = 0;

  // Notifies Controller with updated bitrates per layer. In particular notifies
  // when certain layers should be disabled.
  // Controller shouldn't produce LayerFrameConfig for disabled layers.
  // TODO(bugs.webrtc.org/11404): Make pure virtual when implemented by all
  // structures.
  virtual void OnRatesUpdated(const VideoBitrateAllocation& bitrates) {}

  // When `restart` is true, first `LayerFrameConfig` should have `is_keyframe`
  // set to true.
  // Returned vector shouldn't be empty.
  virtual std::vector<LayerFrameConfig> NextFrameConfig(bool restart) = 0;

  // Returns configuration to pass to EncoderCallback.
  virtual absl::optional<GenericFrameInfo> OnEncodeDone(
      LayerFrameConfig config) = 0;
};

// Below are implementation details.
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::Id(int value) {
  id_ = value;
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::Keyframe() {
  is_keyframe_ = true;
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::S(int value) {
  spatial_id_ = value;
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::T(int value) {
  temporal_id_ = value;
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::Reference(int buffer_id) {
  buffers_.emplace_back(buffer_id, /*referenced=*/true, /*updated=*/false);
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::Update(int buffer_id) {
  buffers_.emplace_back(buffer_id, /*referenced=*/false, /*updated=*/true);
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::ReferenceAndUpdate(int buffer_id) {
  buffers_.emplace_back(buffer_id, /*referenced=*/true, /*updated=*/true);
  return *this;
}

}  // namespace webrtc

#endif  // MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_
