/*
 *  Copyright (c) 2023 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 "rtc_tools/video_encoder/encoded_image_file_writer.h"

#include "modules/video_coding/svc/scalability_mode_util.h"
#include "rtc_base/logging.h"

namespace webrtc {
namespace test {

EncodedImageFileWriter::EncodedImageFileWriter(
    const VideoCodec& video_codec_setting)
    : video_codec_setting_(video_codec_setting) {
  const char* codec_string =
      CodecTypeToPayloadString(video_codec_setting.codecType);

  // Retrieve scalability mode information.
  absl::optional<ScalabilityMode> scalability_mode =
      video_codec_setting.GetScalabilityMode();
  RTC_CHECK(scalability_mode);
  spatial_layers_ = ScalabilityModeToNumSpatialLayers(*scalability_mode);
  temporal_layers_ = ScalabilityModeToNumTemporalLayers(*scalability_mode);
  inter_layer_pred_mode_ =
      ScalabilityModeToInterLayerPredMode(*scalability_mode);

  RTC_CHECK_GT(spatial_layers_, 0);
  RTC_CHECK_GT(temporal_layers_, 0);
  // Create writer for every decode target.
  for (int i = 0; i < spatial_layers_; ++i) {
    for (int j = 0; j < temporal_layers_; ++j) {
      char buffer[256];
      rtc::SimpleStringBuilder name(buffer);
      name << "output-" << codec_string << "-"
           << ScalabilityModeToString(*scalability_mode) << "-L" << i << "T"
           << j << ".ivf";

      decode_target_writers_.emplace_back(std::make_pair(
          IvfFileWriter::Wrap(FileWrapper::OpenWriteOnly(name.str()), 0),
          name.str()));
    }
  }
}

EncodedImageFileWriter::~EncodedImageFileWriter() {
  for (size_t i = 0; i < decode_target_writers_.size(); ++i) {
    decode_target_writers_[i].first->Close();
    RTC_LOG(LS_INFO) << "Written: " << decode_target_writers_[i].second;
  }
}

int EncodedImageFileWriter::Write(const EncodedImage& encoded_image) {
  // L1T1 does not set `SpatialIndex` and `TemporalIndex` in `EncodedImage`.
  const int spatial_index = encoded_image.SpatialIndex().value_or(0);
  const int temporal_index = encoded_image.TemporalIndex().value_or(0);
  RTC_CHECK_LT(spatial_index, spatial_layers_);
  RTC_CHECK_LT(temporal_index, temporal_layers_);

  if (spatial_index == 0) {
    is_base_layer_key_frame =
        (encoded_image._frameType == VideoFrameType::kVideoFrameKey);
  }

  switch (inter_layer_pred_mode_) {
    case InterLayerPredMode::kOff: {
      // Write to this spatial layer.
      for (int j = temporal_index; j < temporal_layers_; ++j) {
        const int index = spatial_index * temporal_layers_ + j;
        RTC_CHECK_LT(index, decode_target_writers_.size());

        decode_target_writers_[index].first->WriteFrame(
            encoded_image, video_codec_setting_.codecType);
      }
      break;
    }

    case InterLayerPredMode::kOn: {
      // Write to this and higher spatial layers.
      for (int i = spatial_index; i < spatial_layers_; ++i) {
        for (int j = temporal_index; j < temporal_layers_; ++j) {
          const int index = i * temporal_layers_ + j;
          RTC_CHECK_LT(index, decode_target_writers_.size());

          decode_target_writers_[index].first->WriteFrame(
              encoded_image, video_codec_setting_.codecType);
        }
      }
      break;
    }

    case InterLayerPredMode::kOnKeyPic: {
      for (int i = spatial_index; i < spatial_layers_; ++i) {
        for (int j = temporal_index; j < temporal_layers_; ++j) {
          const int index = i * temporal_layers_ + j;
          RTC_CHECK_LT(index, decode_target_writers_.size());

          decode_target_writers_[index].first->WriteFrame(
              encoded_image, video_codec_setting_.codecType);
        }

        // Write to higher spatial layers only if key frame.
        if (!is_base_layer_key_frame) {
          break;
        }
      }
      break;
    }
  }

  return 0;
}

}  // namespace test
}  // namespace webrtc
