/*
 * 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/.
 */
#ifndef AOM_AV1_AV1_IFACE_COMMON_H_
#define AOM_AV1_AV1_IFACE_COMMON_H_

#include <assert.h>

#include "aom_ports/mem.h"
#include "aom_scale/yv12config.h"
#include "av1/common/enums.h"

/* Constant value specifying size of subgop*/
#define MAX_SUBGOP_SIZE 32
typedef struct {
  int disp_frame_idx;
  int is_filtered;
  int show_frame;
  int show_existing_frame;
  int pyramid_level;
  int qindex;

  int refresh_frame_flags;
  int num_references;
  int ref_frame_pyr_level[INTER_REFS_PER_FRAME];
  int ref_frame_disp_order[INTER_REFS_PER_FRAME];
  int is_valid_ref_frame[INTER_REFS_PER_FRAME];
  unsigned int ref_frame_map[REF_FRAMES];
} SubGOPStepData;

typedef struct {
  int num_steps;
  int step_idx_enc;
  int step_idx_dec;
  SubGOPStepData step[MAX_SUBGOP_SIZE];
} SubGOPData;

static void yuvconfig2image(aom_image_t *img, const YV12_BUFFER_CONFIG *yv12,
                            void *user_priv) {
  /* aom_img_wrap() doesn't allow specifying independent strides for
   * the Y, U, and V planes, nor other alignment adjustments that
   * might be representable by a YV12_BUFFER_CONFIG, so we just
   * initialize all the fields.
   */
  int bps;
  if (!yv12->subsampling_y) {
    if (!yv12->subsampling_x) {
      img->fmt = AOM_IMG_FMT_I444;
      bps = 24;
    } else {
      img->fmt = AOM_IMG_FMT_I422;
      bps = 16;
    }
  } else {
    img->fmt = AOM_IMG_FMT_I420;
    bps = 12;
  }
  img->cp = yv12->color_primaries;
  img->tc = yv12->transfer_characteristics;
  img->mc = yv12->matrix_coefficients;
  img->monochrome = yv12->monochrome;
  img->csp = yv12->chroma_sample_position;
  img->range = yv12->color_range;
  img->bit_depth = 8;
  img->w = yv12->y_width;
  img->h = yv12->y_height;
  img->d_w = yv12->y_crop_width;
  img->d_h = yv12->y_crop_height;
  img->r_w = yv12->render_width;
  img->r_h = yv12->render_height;
  img->x_chroma_shift = yv12->subsampling_x;
  img->y_chroma_shift = yv12->subsampling_y;
  bps *= 2;
  // aom_image_t uses byte strides and a pointer to the first byte
  // of the image.
  img->fmt = (aom_img_fmt_t)(img->fmt | AOM_IMG_FMT_HIGHBITDEPTH);
  img->bit_depth = yv12->bit_depth;
  img->planes[AOM_PLANE_Y] = (uint8_t *)yv12->y_buffer;
  img->planes[AOM_PLANE_U] = (uint8_t *)yv12->u_buffer;
  img->planes[AOM_PLANE_V] = (uint8_t *)yv12->v_buffer;
  img->stride[AOM_PLANE_Y] = 2 * yv12->y_stride;
  img->stride[AOM_PLANE_U] = 2 * yv12->uv_stride;
  img->stride[AOM_PLANE_V] = 2 * yv12->uv_stride;
  img->bps = bps;
  img->user_priv = user_priv;
  img->img_data = yv12->buffer_alloc;
  img->img_data_owner = 0;
  img->self_allocd = 0;
  img->sz = yv12->frame_size;
  assert(!yv12->metadata);
  img->metadata = NULL;
}

static aom_codec_err_t image2yuvconfig(const aom_image_t *img,
                                       YV12_BUFFER_CONFIG *yv12) {
  yv12->y_buffer = (uint16_t *)img->planes[AOM_PLANE_Y];
  yv12->u_buffer = (uint16_t *)img->planes[AOM_PLANE_U];
  yv12->v_buffer = (uint16_t *)img->planes[AOM_PLANE_V];

  yv12->y_crop_width = img->d_w;
  yv12->y_crop_height = img->d_h;
  yv12->render_width = img->r_w;
  yv12->render_height = img->r_h;
  yv12->y_width = img->w;
  yv12->y_height = img->h;

  yv12->uv_width =
      img->x_chroma_shift == 1 ? (1 + yv12->y_width) / 2 : yv12->y_width;
  yv12->uv_height =
      img->y_chroma_shift == 1 ? (1 + yv12->y_height) / 2 : yv12->y_height;
  yv12->uv_crop_width = yv12->uv_width;
  yv12->uv_crop_height = yv12->uv_height;

  yv12->y_stride = img->stride[AOM_PLANE_Y];
  yv12->uv_stride = img->stride[AOM_PLANE_U];
  yv12->color_primaries = img->cp;
  yv12->transfer_characteristics = img->tc;
  yv12->matrix_coefficients = img->mc;
  yv12->monochrome = img->monochrome;
  yv12->chroma_sample_position = img->csp;
  yv12->color_range = img->range;

  // In aom_image_t
  //     planes point to uint8 address of start of data
  //     stride counts uint8s to reach next row
  // In YV12_BUFFER_CONFIG
  //     y_buffer, u_buffer, v_buffer point to uint16 address of data
  //     stride and border counts in uint16s
  // This means that all the address calculations in the main body of code
  // should work correctly.
  // However, before we do any pixel operations we need to cast the address
  // to a uint16 ponter and double its value.
  yv12->y_stride >>= 1;
  yv12->uv_stride >>= 1;

  // Note(yunqing): if img is allocated the same as the frame buffer, y_stride
  // is 32-byte aligned. Also, handle the cases while allocating img without a
  // border or stride_align is less than 32.
  int border = (yv12->y_stride - (int)((img->w + 31) & ~31)) / 2;
  yv12->border = (border < 0) ? 0 : border;
  yv12->subsampling_x = img->x_chroma_shift;
  yv12->subsampling_y = img->y_chroma_shift;
  yv12->metadata = img->metadata;
  return AOM_CODEC_OK;
}

static void image2yuvconfig_upshift(aom_image_t *hbd_img,
                                    const aom_image_t *img,
                                    YV12_BUFFER_CONFIG *yv12) {
  aom_img_upshift(hbd_img, img, 0);
  // Copy some properties aom_img_upshift() ignores
  hbd_img->cp = img->cp;
  hbd_img->tc = img->tc;
  hbd_img->mc = img->mc;
  hbd_img->monochrome = img->monochrome;
  hbd_img->csp = img->csp;
  hbd_img->range = img->range;
  image2yuvconfig(hbd_img, yv12);
  yv12->metadata = img->metadata;
}
#endif  // AOM_AV1_AV1_IFACE_COMMON_H_
