/*
 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. 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 www.aomedia.org/license/patent.
 */

// Lightfield Decoder
// ==================
//
// This is an example of a simple lightfield decoder. It builds upon the
// simple_decoder.c example.  It takes an input file containing the compressed
// data (in ivf format), treating it as a lightfield instead of a video; and a
// text file with a list of tiles to decode. There is an optional parameter
// allowing to choose the output format, and the supported formats are
// YUV1D(default), YUV, and NV12.
// After running the lightfield encoder, run lightfield decoder to decode a
// batch of tiles:
// examples/lightfield_decoder vase10x10.ivf vase_reference.yuv 4 tile_list.txt
// 0(optional)
// The tile_list.txt is expected to be of the form:
// Frame <frame_index0>
// <image_index0> <anchor_index0> <tile_col0> <tile_row0>
// <image_index1> <anchor_index1> <tile_col1> <tile_row1>
// ...
// Frame <frame_index1)
// ...
//
// The "Frame" markers indicate a new render frame and thus a new tile list
// will be started and the old one flushed.  The image_indexN, anchor_indexN,
// tile_colN, and tile_rowN identify an individual tile to be decoded and
// to use anchor_indexN anchor image for MCP.

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

#include "aom/aom_decoder.h"
#include "aom/aomdx.h"
#include "aom_scale/yv12config.h"
#include "av1/common/enums.h"
#include "common/tools_common.h"
#include "common/video_reader.h"

static const char *exec_name;

void usage_exit(void) {
  fprintf(stderr,
          "Usage: %s <infile> <outfile> <num_references> <tile_list> <output "
          "format(optional)>\n",
          exec_name);
  exit(EXIT_FAILURE);
}

// Output frame size
const int output_frame_width = 512;
const int output_frame_height = 512;

static void aom_img_copy_tile(const aom_image_t *src, const aom_image_t *dst,
                              int dst_row_offset, int dst_col_offset) {
  const int shift = (src->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 1 : 0;
  int plane;

  for (plane = 0; plane < 3; ++plane) {
    const unsigned char *src_buf = src->planes[plane];
    const int src_stride = src->stride[plane];
    unsigned char *dst_buf = dst->planes[plane];
    const int dst_stride = dst->stride[plane];
    const int roffset =
        (plane > 0) ? dst_row_offset >> dst->y_chroma_shift : dst_row_offset;
    const int coffset =
        (plane > 0) ? dst_col_offset >> dst->x_chroma_shift : dst_col_offset;

    // col offset needs to be adjusted for HBD.
    dst_buf += roffset * dst_stride + (coffset << shift);

    const int w = (aom_img_plane_width(src, plane) << shift);
    const int h = aom_img_plane_height(src, plane);
    int y;

    for (y = 0; y < h; ++y) {
      memcpy(dst_buf, src_buf, w);
      src_buf += src_stride;
      dst_buf += dst_stride;
    }
  }
}

void decode_tile(aom_codec_ctx_t *codec, const unsigned char *frame,
                 size_t frame_size, int tr, int tc, int ref_idx,
                 aom_image_t *reference_images, aom_image_t *output,
                 int *tile_idx, unsigned int *output_bit_depth,
                 aom_image_t **img_ptr, int output_format) {
  aom_codec_control_(codec, AV1_SET_TILE_MODE, 1);
  aom_codec_control_(codec, AV1D_EXT_TILE_DEBUG, 1);
  aom_codec_control_(codec, AV1_SET_DECODE_TILE_ROW, tr);
  aom_codec_control_(codec, AV1_SET_DECODE_TILE_COL, tc);

  av1_ref_frame_t ref;
  ref.idx = 0;
  ref.use_external_ref = 1;
  ref.img = reference_images[ref_idx];
  if (aom_codec_control(codec, AV1_SET_REFERENCE, &ref)) {
    die_codec(codec, "Failed to set reference frame.");
  }

  aom_codec_err_t aom_status = aom_codec_decode(codec, frame, frame_size, NULL);
  if (aom_status) die_codec(codec, "Failed to decode tile.");

  aom_codec_iter_t iter = NULL;
  aom_image_t *img = aom_codec_get_frame(codec, &iter);
  if (!img) die_codec(codec, "Failed to get frame.");
  *img_ptr = img;

  // aom_img_alloc() sets bit_depth as follows:
  // output->bit_depth = (fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 16 : 8;
  // Use img->bit_depth(read from bitstream), so that aom_shift_img()
  // works as expected.
  output->bit_depth = img->bit_depth;
  *output_bit_depth = img->bit_depth;

  if (output_format != YUV1D) {
    // read out the tile size.
    unsigned int tile_size = 0;
    if (aom_codec_control(codec, AV1D_GET_TILE_SIZE, &tile_size))
      die_codec(codec, "Failed to get the tile size");
    const unsigned int tile_width = tile_size >> 16;
    const unsigned int tile_height = tile_size & 65535;
    const uint32_t output_frame_width_in_tiles =
        output_frame_width / tile_width;

    // Copy the tile to the output frame.
    const int row_offset =
        (*tile_idx / output_frame_width_in_tiles) * tile_height;
    const int col_offset =
        (*tile_idx % output_frame_width_in_tiles) * tile_width;

    aom_img_copy_tile(img, output, row_offset, col_offset);
    (*tile_idx)++;
  }
}

static void img_write_to_file(const aom_image_t *img, FILE *file,
                              int output_format) {
  if (output_format == YUV)
    aom_img_write(img, file);
  else if (output_format == NV12)
    aom_img_write_nv12(img, file);
  else
    die("Invalid output format");
}

int main(int argc, char **argv) {
  FILE *outfile = NULL;
  AvxVideoReader *reader = NULL;
  const AvxVideoInfo *info = NULL;
  int num_references;
  aom_img_fmt_t ref_fmt = 0;
  aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
  aom_image_t output;
  aom_image_t *output_shifted = NULL;
  size_t frame_size = 0;
  const unsigned char *frame = NULL;
  int i, j;
  const char *tile_list_file = NULL;
  int output_format = YUV1D;
  exec_name = argv[0];

  if (argc < 5) die("Invalid number of arguments.");

  reader = aom_video_reader_open(argv[1]);
  if (!reader) die("Failed to open %s for reading.", argv[1]);

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

  num_references = (int)strtol(argv[3], NULL, 0);
  tile_list_file = argv[4];

  if (argc > 5) output_format = (int)strtol(argv[5], NULL, 0);
  if (output_format < YUV1D || output_format > NV12)
    die("Output format out of range [0, 2]");

  info = aom_video_reader_get_info(reader);

  aom_codec_iface_t *decoder;
  if (info->codec_fourcc == LST_FOURCC)
    decoder = get_aom_decoder_by_fourcc(AV1_FOURCC);
  else
    die("Unknown input codec.");
  printf("Using %s\n", aom_codec_iface_name(decoder));

  aom_codec_ctx_t codec;
  if (aom_codec_dec_init(&codec, decoder, NULL, 0))
    die_codec(&codec, "Failed to initialize decoder.");

  if (aom_codec_control(&codec, AV1D_SET_IS_ANNEXB, info->is_annexb)) {
    die("Failed to set annex b status");
  }

  // Decode anchor frames.
  aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
  for (i = 0; i < num_references; ++i) {
    aom_video_reader_read_frame(reader);
    frame = aom_video_reader_get_frame(reader, &frame_size);
    if (aom_codec_decode(&codec, frame, frame_size, NULL))
      die_codec(&codec, "Failed to decode frame.");

    if (i == 0) {
      if (aom_codec_control(&codec, AV1D_GET_IMG_FORMAT, &ref_fmt))
        die_codec(&codec, "Failed to get the image format");

      int frame_res[2];
      if (aom_codec_control(&codec, AV1D_GET_FRAME_SIZE, frame_res))
        die_codec(&codec, "Failed to get the image frame size");

      // Allocate memory to store decoded references. Allocate memory with the
      // border so that it can be used as a reference.
      for (j = 0; j < num_references; j++) {
        unsigned int border = AOM_DEC_BORDER_IN_PIXELS;
        if (!aom_img_alloc_with_border(&reference_images[j], ref_fmt,
                                       frame_res[0], frame_res[1], 32, 8,
                                       border)) {
          die("Failed to allocate references.");
        }
      }
    }

    if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
                          &reference_images[i]))
      die_codec(&codec, "Failed to copy decoded reference frame");

    aom_codec_iter_t iter = NULL;
    aom_image_t *img = NULL;
    while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
      char name[1024];
      snprintf(name, sizeof(name), "ref_%d.yuv", i);
      printf("writing ref image to %s, %d, %d\n", name, img->d_w, img->d_h);
      FILE *ref_file = fopen(name, "wb");
      aom_img_write(img, ref_file);
      fclose(ref_file);
    }
  }

  FILE *infile = aom_video_reader_get_file(reader);
  // Record the offset of the first camera image.
  const FileOffset camera_frame_pos = ftello(infile);

  printf("Loading compressed frames into memory.\n");

  // Count the frames in the lightfield.
  int num_frames = 0;
  while (aom_video_reader_read_frame(reader)) {
    ++num_frames;
  }
  if (num_frames < 1) die("Input light field has no frames.");

  // Read all of the lightfield frames into memory.
  unsigned char **frames =
      (unsigned char **)malloc(num_frames * sizeof(unsigned char *));
  size_t *frame_sizes = (size_t *)malloc(num_frames * sizeof(size_t));
  // Seek to the first camera image.
  fseeko(infile, camera_frame_pos, SEEK_SET);
  for (int f = 0; f < num_frames; ++f) {
    aom_video_reader_read_frame(reader);
    frame = aom_video_reader_get_frame(reader, &frame_size);
    frames[f] = (unsigned char *)malloc(frame_size * sizeof(unsigned char));
    memcpy(frames[f], frame, frame_size);
    frame_sizes[f] = frame_size;
  }
  printf("Read %d frames.\n", num_frames);

  if (output_format != YUV1D) {
    // Allocate the output frame.
    aom_img_fmt_t out_fmt = ref_fmt;
    if (FORCE_HIGHBITDEPTH_DECODING) out_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
    if (!aom_img_alloc(&output, out_fmt, output_frame_width,
                       output_frame_height, 32))
      die("Failed to allocate output image.");
  }

  printf("Decoding tile list from file.\n");
  char line[1024];
  FILE *tile_list_fptr = fopen(tile_list_file, "r");
  if (!tile_list_fptr) die_codec(&codec, "Failed to open tile list file.");
  int tile_list_cnt = 0;
  int tile_list_writes = 0;
  int tile_idx = 0;
  aom_image_t *out = NULL;
  unsigned int output_bit_depth = 0;

  while ((fgets(line, 1024, tile_list_fptr)) != NULL) {
    if (line[0] == 'F') {
      if (output_format != YUV1D) {
        // Write out the tile list.
        if (tile_list_cnt) {
          out = &output;
          if (output_bit_depth != 0)
            aom_shift_img(output_bit_depth, &out, &output_shifted);
          img_write_to_file(out, outfile, output_format);
          tile_list_writes++;
        }

        tile_list_cnt++;
        tile_idx = 0;
        // Then memset the frame.
        memset(output.img_data, 0, output.sz);
      }
      continue;
    }

    int image_idx, ref_idx, tc, tr;
    sscanf(line, "%d %d %d %d", &image_idx, &ref_idx, &tc, &tr);
    if (image_idx >= num_frames) {
      die("Tile list image_idx out of bounds: %d >= %d.", image_idx,
          num_frames);
    }
    if (ref_idx >= num_references) {
      die("Tile list ref_idx out of bounds: %d >= %d.", ref_idx,
          num_references);
    }
    frame = frames[image_idx];
    frame_size = frame_sizes[image_idx];

    aom_image_t *img = NULL;
    decode_tile(&codec, frame, frame_size, tr, tc, ref_idx, reference_images,
                &output, &tile_idx, &output_bit_depth, &img, output_format);
    if (output_format == YUV1D) {
      out = img;
      if (output_bit_depth != 0)
        aom_shift_img(output_bit_depth, &out, &output_shifted);
      aom_img_write(out, outfile);
    }
  }

  if (output_format != YUV1D) {
    // Write out the last tile list.
    if (tile_list_writes < tile_list_cnt) {
      out = &output;
      if (output_bit_depth != 0)
        aom_shift_img(output_bit_depth, &out, &output_shifted);
      img_write_to_file(out, outfile, output_format);
    }
  }

  if (output_shifted) aom_img_free(output_shifted);
  if (output_format != YUV1D) aom_img_free(&output);
  for (i = 0; i < num_references; i++) aom_img_free(&reference_images[i]);
  for (int f = 0; f < num_frames; ++f) {
    free(frames[f]);
  }
  free(frame_sizes);
  free(frames);
  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
  aom_video_reader_close(reader);
  fclose(outfile);

  return EXIT_SUCCESS;
}
