/*
 * 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_TYPECHECKED(codec, AV1_SET_TILE_MODE, 1);
  AOM_CODEC_CONTROL_TYPECHECKED(codec, AV1D_EXT_TILE_DEBUG, 1);
  AOM_CODEC_CONTROL_TYPECHECKED(codec, AV1_SET_DECODE_TILE_ROW, tr);
  AOM_CODEC_CONTROL_TYPECHECKED(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_TYPECHECKED(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_TYPECHECKED(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;
  aom_codec_ctx_t codec;
  AvxVideoReader *reader = NULL;
  const AvxInterface *decoder = 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);

  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->codec_interface()));

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

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

  // Decode anchor frames.
  AOM_CODEC_CONTROL_TYPECHECKED(&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_TYPECHECKED(&codec, AV1D_GET_IMG_FORMAT, &ref_fmt))
        die_codec(&codec, "Failed to get the image format");

      int frame_res[2];
      if (AOM_CODEC_CONTROL_TYPECHECKED(&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_TYPECHECKED(&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;
}
