/*
 * Copyright (c) 2016, 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.
 */
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "aom_ports/mem_ops.h"
#include "common/ivfdec.h"
#include "common/obudec.h"
#include "common/tools_common.h"
#include "common/video_reader.h"
#include "common/webmdec.h"

struct AvxVideoReaderStruct {
  AvxVideoInfo info;
  struct AvxInputContext input_ctx;
  struct ObuDecInputContext obu_ctx;
  struct WebmInputContext webm_ctx;
  uint8_t *buffer;
  size_t buffer_size;
  size_t frame_size;
  aom_codec_pts_t pts;
};

AvxVideoReader *aom_video_reader_open(const char *filename) {
  AvxVideoReader *reader = NULL;
  FILE *const file = fopen(filename, "rb");
  if (!file) return NULL;  // Can't open file

  reader = (AvxVideoReader *)calloc(1, sizeof(*reader));
  if (!reader) {
    fclose(file);
    return NULL;  // Can't allocate AvxVideoReader
  }

  reader->input_ctx.filename = filename;
  reader->input_ctx.file = file;
  reader->obu_ctx.avx_ctx = &reader->input_ctx;
  reader->obu_ctx.is_annexb = 1;

  if (file_is_ivf(&reader->input_ctx)) {
    reader->input_ctx.file_type = FILE_TYPE_IVF;
    reader->info.codec_fourcc = reader->input_ctx.fourcc;
    reader->info.frame_width = reader->input_ctx.width;
    reader->info.frame_height = reader->input_ctx.height;
#if CONFIG_WEBM_IO
  } else if (file_is_webm(&reader->webm_ctx, &reader->input_ctx)) {
    reader->input_ctx.file_type = FILE_TYPE_WEBM;
    reader->info.codec_fourcc = reader->input_ctx.fourcc;
    reader->info.frame_width = reader->input_ctx.width;
    reader->info.frame_height = reader->input_ctx.height;
#endif
  } else if (file_is_obu(&reader->obu_ctx)) {
    reader->input_ctx.file_type = FILE_TYPE_OBU;
    // assume AV1
    reader->info.codec_fourcc = AV1_FOURCC;
    reader->info.is_annexb = reader->obu_ctx.is_annexb;
  } else {
    fclose(file);
    free(reader);
    return NULL;  // Unknown file type
  }

  return reader;
}

void aom_video_reader_close(AvxVideoReader *reader) {
  if (reader) {
    fclose(reader->input_ctx.file);
    if (reader->input_ctx.file_type == FILE_TYPE_OBU) {
      obudec_free(&reader->obu_ctx);
    }
    free(reader->buffer);
    free(reader);
  }
}

int aom_video_reader_read_frame(AvxVideoReader *reader) {
  if (reader->input_ctx.file_type == FILE_TYPE_IVF) {
    return !ivf_read_frame(reader->input_ctx.file, &reader->buffer,
                           &reader->frame_size, &reader->buffer_size,
                           &reader->pts);
  } else if (reader->input_ctx.file_type == FILE_TYPE_OBU) {
    return !obudec_read_temporal_unit(&reader->obu_ctx, &reader->buffer,
                                      &reader->frame_size,
                                      &reader->buffer_size);
#if CONFIG_WEBM_IO
  } else if (reader->input_ctx.file_type == FILE_TYPE_WEBM) {
    return !webm_read_frame(&reader->webm_ctx, &reader->buffer,
                            &reader->frame_size, &reader->buffer_size);
#endif
  } else {
    assert(0);
    return 0;
  }
}

const uint8_t *aom_video_reader_get_frame(AvxVideoReader *reader,
                                          size_t *size) {
  if (size) *size = reader->frame_size;

  return reader->buffer;
}

int64_t aom_video_reader_get_frame_pts(AvxVideoReader *reader) {
  return (int64_t)reader->pts;
}

FILE *aom_video_reader_get_file(AvxVideoReader *reader) {
  return reader->input_ctx.file;
}

const AvxVideoInfo *aom_video_reader_get_info(AvxVideoReader *reader) {
  return &reader->info;
}

void aom_video_reader_set_fourcc(AvxVideoReader *reader, uint32_t fourcc) {
  reader->info.codec_fourcc = fourcc;
}
