/*
 *  Copyright (c) 2011 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include <assert.h>
#include <stdlib.h>
#include "vpx_config.h"
#include "vp9/encoder/vp9_lookahead.h"
#include "vp9/common/vp9_extend.h"

#define MAX_LAG_BUFFERS 25

struct lookahead_ctx {
  unsigned int max_sz;         /* Absolute size of the queue */
  unsigned int sz;             /* Number of buffers currently in the queue */
  unsigned int read_idx;       /* Read index */
  unsigned int write_idx;      /* Write index */
  struct lookahead_entry *buf; /* Buffer list */
};


/* Return the buffer at the given absolute index and increment the index */
static struct lookahead_entry *
pop(struct lookahead_ctx *ctx,
    unsigned int         *idx) {
  unsigned int            index = *idx;
  struct lookahead_entry *buf = ctx->buf + index;

  assert(index < ctx->max_sz);
  if (++index >= ctx->max_sz)
    index -= ctx->max_sz;
  *idx = index;
  return buf;
}


void
vp9_lookahead_destroy(struct lookahead_ctx *ctx) {
  if (ctx) {
    if (ctx->buf) {
      unsigned int i;

      for (i = 0; i < ctx->max_sz; i++)
        vp8_yv12_de_alloc_frame_buffer(&ctx->buf[i].img);
      free(ctx->buf);
    }
    free(ctx);
  }
}


struct lookahead_ctx *
vp9_lookahead_init(unsigned int width,
                   unsigned int height,
                   unsigned int depth) {
  struct lookahead_ctx *ctx = NULL;

  /* Clamp the lookahead queue depth */
  if (depth < 1)
    depth = 1;
  else if (depth > MAX_LAG_BUFFERS)
    depth = MAX_LAG_BUFFERS;

  /* Align the buffer dimensions */
  width = (width + 15) &~15;
  height = (height + 15) &~15;

  /* Allocate the lookahead structures */
  ctx = calloc(1, sizeof(*ctx));
  if (ctx) {
    unsigned int i;
    ctx->max_sz = depth;
    ctx->buf = calloc(depth, sizeof(*ctx->buf));
    if (!ctx->buf)
      goto bail;
    for (i = 0; i < depth; i++)
      if (vp8_yv12_alloc_frame_buffer(&ctx->buf[i].img,
                                      width, height, VP9BORDERINPIXELS))
        goto bail;
  }
  return ctx;
bail:
  vp9_lookahead_destroy(ctx);
  return NULL;
}


int
vp9_lookahead_push(struct lookahead_ctx *ctx,
                   YV12_BUFFER_CONFIG   *src,
                   int64_t               ts_start,
                   int64_t               ts_end,
                   unsigned int          flags,
                   unsigned char        *active_map) {
  struct lookahead_entry *buf;
  int row, col, active_end;
  int mb_rows = (src->y_height + 15) >> 4;
  int mb_cols = (src->y_width + 15) >> 4;

  if (ctx->sz + 1 > ctx->max_sz)
    return 1;
  ctx->sz++;
  buf = pop(ctx, &ctx->write_idx);

  // Only do this partial copy if the following conditions are all met:
  // 1. Lookahead queue has has size of 1.
  // 2. Active map is provided.
  // 3. This is not a key frame, golden nor altref frame.
  if (ctx->max_sz == 1 && active_map && !flags) {
    for (row = 0; row < mb_rows; ++row) {
      col = 0;

      while (1) {
        // Find the first active macroblock in this row.
        for (; col < mb_cols; ++col) {
          if (active_map[col])
            break;
        }

        // No more active macroblock in this row.
        if (col == mb_cols)
          break;

        // Find the end of active region in this row.
        active_end = col;

        for (; active_end < mb_cols; ++active_end) {
          if (!active_map[active_end])
            break;
        }

        // Only copy this active region.
        vp9_copy_and_extend_frame_with_rect(src, &buf->img,
                                            row << 4,
                                            col << 4, 16,
                                            (active_end - col) << 4);

        // Start again from the end of this active region.
        col = active_end;
      }

      active_map += mb_cols;
    }
  } else {
    vp9_copy_and_extend_frame(src, &buf->img);
  }
  buf->ts_start = ts_start;
  buf->ts_end = ts_end;
  buf->flags = flags;
  return 0;
}


struct lookahead_entry *
vp9_lookahead_pop(struct lookahead_ctx *ctx,
                  int                   drain) {
  struct lookahead_entry *buf = NULL;

  if (ctx->sz && (drain || ctx->sz == ctx->max_sz)) {
    buf = pop(ctx, &ctx->read_idx);
    ctx->sz--;
  }
  return buf;
}


struct lookahead_entry *
vp9_lookahead_peek(struct lookahead_ctx *ctx,
                   int                   index) {
  struct lookahead_entry *buf = NULL;

  assert(index < (int)ctx->max_sz);
  if (index < (int)ctx->sz) {
    index += ctx->read_idx;
    if (index >= (int)ctx->max_sz)
      index -= ctx->max_sz;
    buf = ctx->buf + index;
  }
  return buf;
}


unsigned int
vp9_lookahead_depth(struct lookahead_ctx *ctx) {
  return ctx->sz;
}
