/*
 * 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 Decoder
// ==============
//
// This is an example of a scalable decoder loop. It takes a 2-spatial-layer
// input file
// containing the compressed data (in OBU format), passes it through the
// decoder, and writes the decompressed frames to disk. The base layer and
// enhancement layers are stored as separate files, out_lyr0.yuv and
// out_lyr1.yuv, respectively.
//
// Standard Includes
// -----------------
// For decoders, you only have to include `avm_decoder.h` and then any
// header files for the specific codecs you use. In this case, we're using
// av2.
//
// Initializing The Codec
// ----------------------
// The libavm decoder is initialized by the call to avm_codec_dec_init().
// Determining the codec interface to use is handled by AvxVideoReader and the
// functions prefixed with avm_video_reader_. Discussion of those functions is
// beyond the scope of this example, but the main gist is to open the input file
// and parse just enough of it to determine if it's a AVx file and which AVx
// codec is contained within the file.
// Note the NULL pointer passed to avm_codec_dec_init(). We do that in this
// example because we want the algorithm to determine the stream configuration
// (width/height) and allocate memory automatically.
//
// Decoding A Frame
// ----------------
// Once the frame has been read into memory, it is decoded using the
// `avm_codec_decode` function. The call takes a pointer to the data
// (`frame`) and the length of the data (`frame_size`). No application data
// is associated with the frame in this example, so the `user_priv`
// parameter is NULL. The `deadline` parameter is left at zero for this
// example. This parameter is generally only used when doing adaptive post
// processing.
//
// Codecs may produce a variable number of output frames for every call to
// `avm_codec_decode`. These frames are retrieved by the
// `avm_codec_get_frame` iterator function. The iterator variable `iter` is
// initialized to NULL each time `avm_codec_decode` is called.
// `avm_codec_get_frame` is called in a loop, returning a pointer to a
// decoded image or NULL to indicate the end of list.
//
// Processing The Decoded Data
// ---------------------------
// In this example, we simply write the encoded data to disk. It is
// important to honor the image's `stride` values.
//
// Cleanup
// -------
// The `avm_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 exceptions, avm_codec functions return an enumerated error status,
// with the value `0` indicating success.

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

#include "avm/avm_decoder.h"
#include "avm/avmdx.h"
#include "common/obudec.h"
#include "common/tools_common.h"
#include "common/video_reader.h"

static const char *exec_name;

#define MAX_LAYERS 5

void usage_exit(void) {
  fprintf(stderr, "Usage: %s <infile>\n", exec_name);
  exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
  int frame_cnt = 0;
  FILE *outfile[MAX_LAYERS];
  char filename[80];
  FILE *inputfile = NULL;
  uint8_t *buf = NULL;
  size_t bytes_in_buffer = 0;
  size_t buffer_size = 0;
  struct AvxInputContext avm_input_ctx;
#if CONFIG_F436_OBUORDER
  struct ObuDecInputContext obu_ctx = { &avm_input_ctx, NULL, 0, 0 };
#else
  struct ObuDecInputContext obu_ctx = { &avm_input_ctx, NULL, 0, 0, 0 };
#endif
  avm_codec_stream_info_t si;
  uint8_t tmpbuf[32];
  unsigned int i;

  exec_name = argv[0];

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

  if (!(inputfile = fopen(argv[1], "rb")))
    die("Failed to open %s for read.", argv[1]);
  obu_ctx.avx_ctx->file = inputfile;
  obu_ctx.avx_ctx->filename = argv[1];

  avm_codec_iface_t *decoder = get_avm_decoder_by_index(0);
  printf("Using %s\n", avm_codec_iface_name(decoder));

  avm_codec_ctx_t codec;
  if (avm_codec_dec_init(&codec, decoder, NULL, 0))
    die("Failed to initialize decoder.");

  if (avm_codec_control(&codec, AV2D_SET_OUTPUT_ALL_LAYERS, 1)) {
    die_codec(&codec, "Failed to set output_all_layers control.");
  }

  // peak sequence header OBU to get number of spatial layers
  const size_t ret = fread(tmpbuf, 1, 32, inputfile);
  if (ret != 32) die_codec(&codec, "Input is not a valid obu file");
  if (avm_codec_peek_stream_info(decoder, tmpbuf, 32, &si)) {
    die_codec(&codec, "Input is not a valid obu file");
  }
  fseek(inputfile, -32, SEEK_CUR);

  if (!file_is_obu(&obu_ctx))
    die_codec(&codec, "Input is not a valid obu file");

  // open base layer output yuv file
  snprintf(filename, sizeof(filename), "out_lyr%d.yuv", 0);
  if (!(outfile[0] = fopen(filename, "wb")))
    die("Failed top open output for writing.");

  // open any enhancement layer output yuv files
  for (i = 1; i < si.number_mlayers; i++) {
    snprintf(filename, sizeof(filename), "out_lyr%u.yuv", i);
    if (!(outfile[i] = fopen(filename, "wb")))
      die("Failed to open output for writing.");
  }

#if CONFIG_F436_OBUORDER
  while (
      !obudec_read_frame_unit(&obu_ctx, &buf, &bytes_in_buffer, &buffer_size))
#else
  while (!obudec_read_temporal_unit(&obu_ctx, &buf, &bytes_in_buffer,
                                    &buffer_size))
#endif
  {
    avm_codec_iter_t iter = NULL;
    avm_image_t *img = NULL;
    if (avm_codec_decode(&codec, buf, bytes_in_buffer, NULL))
      die_codec(&codec, "Failed to decode frame.");

    while ((img = avm_codec_get_frame(&codec, &iter)) != NULL) {
      avm_image_t *img_shifted =
          avm_img_alloc(NULL, AVM_IMG_FMT_I420, img->d_w, img->d_h, 16);
      img_shifted->bit_depth = 8;
      avm_img_downshift(img_shifted, img,
                        img->bit_depth - img_shifted->bit_depth,
                        img_shifted->bit_depth);
      if (img->mlayer_id == 0) {
        printf("Writing        base layer 0 %d\n", frame_cnt);
        avm_img_write(img_shifted, outfile[0]);
      } else if (img->mlayer_id <= (int)(si.number_mlayers - 1)) {
        printf("Writing enhancement layer %d %d\n", img->mlayer_id, frame_cnt);
        avm_img_write(img_shifted, outfile[img->mlayer_id]);
      } else {
        die_codec(&codec, "Invalid bitstream. Layer id exceeds layer count");
      }
      if (img->mlayer_id == (int)(si.number_mlayers - 1)) ++frame_cnt;
    }
  }

  printf("Processed %d frames.\n", frame_cnt);
  if (avm_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");

  for (i = 0; i < si.number_mlayers; i++) fclose(outfile[i]);

  fclose(inputfile);

  return EXIT_SUCCESS;
}
