/*
 * 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"

struct AvxVideoReaderStruct {
  AvxVideoInfo info;
  struct AvxInputContext input_ctx;
  struct ObuDecInputContext obu_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;
  } 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);
  } 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;
}
