/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
 * Alliance for Open Media Patent License 1.0 was not distributed with this
 * source code in the PATENTS file, you can obtain it at
 * aomedia.org/license/patent-license/.
 */

// Scalable Encoder
// ==============
//
// This is an example of a scalable encoder loop. It takes two input files in
// YV12 format, passes it through the encoder, and writes the compressed
// frames to disk in OBU format.
//
// Getting The Default Configuration
// ---------------------------------
// Encoders have the notion of "usage profiles." For example, an encoder
// may want to publish default configurations for both a video
// conferencing application and a best quality offline encoder. These
// obviously have very different default settings. Consult the
// documentation for your codec to see if it provides any default
// configurations. All codecs provide a default configuration, number 0,
// which is valid for material in the vacinity of QCIF/QVGA.
//
// Updating The Configuration
// ---------------------------------
// Almost all applications will want to update the default configuration
// with settings specific to their usage. Here we set the width and height
// of the video file to that specified on the command line. We also scale
// the default bitrate based on the ratio between the default resolution
// and the resolution specified on the command line.
//
// Encoding A Frame
// ----------------
// The frame is read as a continuous block (size = width * height * 3 / 2)
// from the input file. If a frame was read (the input file has not hit
// EOF) then the frame is passed to the encoder. Otherwise, a NULL
// is passed, indicating the End-Of-Stream condition to the encoder. The
// `frame_cnt` is reused as the presentation time stamp (PTS) and each
// frame is shown for one frame-time in duration. The flags parameter is
// unused in this example.

// Forced Keyframes
// ----------------
// Keyframes can be forced by setting the AOM_EFLAG_FORCE_KF bit of the
// flags passed to `aom_codec_control()`. In this example, we force a
// keyframe every <keyframe-interval> frames. Note, the output stream can
// contain additional keyframes beyond those that have been forced using the
// AOM_EFLAG_FORCE_KF flag because of automatic keyframe placement by the
// encoder.
//
// Processing The Encoded Data
// ---------------------------
// Each packet of type `AOM_CODEC_CX_FRAME_PKT` contains the encoded data
// for this frame. We write a IVF frame header, followed by the raw data.
//
// Cleanup
// -------
// The `aom_codec_destroy` call frees any memory allocated by the codec.
//
// Error Handling
// --------------
// This example does not special case any error return codes. If there was
// an error, a descriptive message is printed and the program exits. With
// few exeptions, aom_codec functions return an enumerated error status,
// with the value `0` indicating success.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "aom/aom_encoder.h"
#include "aom/aomcx.h"
#include "av1/common/enums.h"
#include "common/tools_common.h"
#include "common/video_writer.h"

static const char *exec_name;

void usage_exit(void) {
  fprintf(stderr,
          "Usage: %s <codec> <width> <height> <infile0> <infile1> "
          "<outfile> <frames to encode>\n"
          "See comments in scalable_encoder.c for more information.\n",
          exec_name);
  exit(EXIT_FAILURE);
}

static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
                        int frame_index, int flags, FILE *outfile) {
  int got_pkts = 0;
  aom_codec_iter_t iter = NULL;
  const aom_codec_cx_pkt_t *pkt = NULL;
  const aom_codec_err_t res =
      aom_codec_encode(codec, img, frame_index, 1, flags);
  if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");

  while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
    got_pkts = 1;

    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
      if (fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile) !=
          pkt->data.frame.sz) {
        die_codec(codec, "Failed to write compressed frame");
      }
      printf(keyframe ? "K" : ".");
      printf(" %6d\n", (int)pkt->data.frame.sz);
      fflush(stdout);
    }
  }

  return got_pkts;
}

int main(int argc, char **argv) {
  FILE *infile0 = NULL;
  FILE *infile1 = NULL;
  aom_codec_enc_cfg_t cfg;
  int frame_count = 0;
  aom_image_t raw0, raw1;
  aom_codec_err_t res;
  AvxVideoInfo info;
  const int fps = 30;
  const int bitrate = 200;
  int keyframe_interval = 0;
  int max_frames = 0;
  int frames_encoded = 0;
  const char *codec_arg = NULL;
  const char *width_arg = NULL;
  const char *height_arg = NULL;
  const char *infile0_arg = NULL;
  const char *infile1_arg = NULL;
  const char *outfile_arg = NULL;
  //  const char *keyframe_interval_arg = NULL;
  FILE *outfile = NULL;

  exec_name = argv[0];

  // Clear explicitly, as simply assigning "{ 0 }" generates
  // "missing-field-initializers" warning in some compilers.
  memset(&info, 0, sizeof(info));

  if (argc != 8) die("Invalid number of arguments");

  codec_arg = argv[1];
  width_arg = argv[2];
  height_arg = argv[3];
  infile0_arg = argv[4];
  infile1_arg = argv[5];
  outfile_arg = argv[6];
  max_frames = (int)strtol(argv[7], NULL, 0);

  aom_codec_iface_t *encoder = get_aom_encoder_by_short_name(codec_arg);
  if (!encoder) die("Unsupported codec.");

  info.codec_fourcc = get_fourcc_by_aom_encoder(encoder);
  info.frame_width = (int)strtol(width_arg, NULL, 0);
  info.frame_height = (int)strtol(height_arg, NULL, 0);
  info.time_base.numerator = 1;
  info.time_base.denominator = fps;

  if (info.frame_width <= 0 || info.frame_height <= 0 ||
      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
  }

  if (!aom_img_alloc(&raw0, AOM_IMG_FMT_I420, info.frame_width,
                     info.frame_height, 1)) {
    die("Failed to allocate image for layer 0.");
  }
  if (!aom_img_alloc(&raw1, AOM_IMG_FMT_I420, info.frame_width,
                     info.frame_height, 1)) {
    die("Failed to allocate image for layer 1.");
  }

  //  keyframe_interval = (int)strtol(keyframe_interval_arg, NULL, 0);
  keyframe_interval = 100;
  if (keyframe_interval < 0) die("Invalid keyframe interval value.");

  printf("Using %s\n", aom_codec_iface_name(encoder));

  aom_codec_ctx_t codec;
  res = aom_codec_enc_config_default(encoder, &cfg, 0);
  if (res) die_codec(&codec, "Failed to get default codec config.");

  cfg.g_w = info.frame_width;
  cfg.g_h = info.frame_height;
  cfg.g_timebase.num = info.time_base.numerator;
  cfg.g_timebase.den = info.time_base.denominator;
  cfg.rc_target_bitrate = bitrate;
  cfg.g_error_resilient = 0;
  cfg.g_lag_in_frames = 0;
  cfg.rc_end_usage = AOM_Q;
  cfg.save_as_annexb = 0;

  outfile = fopen(outfile_arg, "wb");
  if (!outfile) die("Failed to open %s for writing.", outfile_arg);

  if (!(infile0 = fopen(infile0_arg, "rb")))
    die("Failed to open %s for reading.", infile0_arg);
  if (!(infile1 = fopen(infile1_arg, "rb")))
    die("Failed to open %s for reading.", infile0_arg);

  if (aom_codec_enc_init(&codec, encoder, &cfg, 0))
    die("Failed to initialize encoder");
  if (aom_codec_control(&codec, AOME_SET_CPUUSED, 8))
    die_codec(&codec, "Failed to set cpu to 8");

  if (aom_codec_control(&codec, AV1E_SET_TILE_COLUMNS, 2))
    die_codec(&codec, "Failed to set tile columns to 2");
  if (aom_codec_control(&codec, AV1E_SET_NUM_TG, 3))
    die_codec(&codec, "Failed to set num of tile groups to 3");

  if (aom_codec_control(&codec, AOME_SET_NUMBER_SPATIAL_LAYERS, 2))
    die_codec(&codec, "Failed to set number of spatial layers to 2");

  // Encode frames.
  while (aom_img_read(&raw0, infile0)) {
    int flags = 0;

    // configure and encode base layer

    if (keyframe_interval > 0 && frames_encoded % keyframe_interval == 0)
      flags |= AOM_EFLAG_FORCE_KF;
    else
      // use previous base layer (LAST) as sole reference
      // save this frame as LAST to be used as reference by enhanmcent layer
      // and next base layer
      flags |= AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
               AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF |
               AOM_EFLAG_NO_REF_BWD | AOM_EFLAG_NO_REF_ARF2 |
#if !CONFIG_NEW_REF_SIGNALING
               AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
#endif  // !CONFIG_NEW_REF_SIGNALING
               AOM_EFLAG_NO_UPD_ENTROPY;
    cfg.g_w = info.frame_width;
    cfg.g_h = info.frame_height;
    if (aom_codec_enc_config_set(&codec, &cfg))
      die_codec(&codec, "Failed to set enc cfg for layer 0");
    if (aom_codec_control(&codec, AOME_SET_SPATIAL_LAYER_ID, 0))
      die_codec(&codec, "Failed to set layer id to 0");
    if (aom_codec_control(&codec, AOME_SET_QP, 62))
      die_codec(&codec, "Failed to set cq level");
    encode_frame(&codec, &raw0, frame_count++, flags, outfile);

    // configure and encode enhancement layer

    //  use LAST (base layer) as sole reference
    flags = AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
            AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF | AOM_EFLAG_NO_REF_BWD |
            AOM_EFLAG_NO_REF_ARF2 |
#if CONFIG_NEW_REF_SIGNALING
            AOM_EFLAG_NO_UPD_ALL |
#else
            AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
#endif  // CONFIG_NEW_REF_SIGNALING
            AOM_EFLAG_NO_UPD_ENTROPY;
    cfg.g_w = info.frame_width;
    cfg.g_h = info.frame_height;
    aom_img_read(&raw1, infile1);
    if (aom_codec_enc_config_set(&codec, &cfg))
      die_codec(&codec, "Failed to set enc cfg for layer 1");
    if (aom_codec_control(&codec, AOME_SET_SPATIAL_LAYER_ID, 1))
      die_codec(&codec, "Failed to set layer id to 1");
    if (aom_codec_control(&codec, AOME_SET_QP, 10))
      die_codec(&codec, "Failed to set cq level");
    encode_frame(&codec, &raw1, frame_count++, flags, outfile);

    frames_encoded++;

    if (max_frames > 0 && frames_encoded >= max_frames) break;
  }

  // Flush encoder.
  while (encode_frame(&codec, NULL, -1, 0, outfile)) continue;

  printf("\n");
  fclose(infile0);
  fclose(infile1);
  printf("Processed %d frames.\n", frame_count / 2);

  aom_img_free(&raw0);
  aom_img_free(&raw1);
  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");

  fclose(outfile);

  return EXIT_SUCCESS;
}
