1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Copyright (c) 2011 The WebM project authors. All Rights Reserved.
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Use of this source code is governed by a BSD-style license
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  that can be found in the LICENSE file in the root of the source
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  tree. An additional intellectual property rights grant can be found
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  in the file PATENTS.  All contributing project authors may
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  be found in the AUTHORS file in the root of the source tree.
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <assert.h>
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <stdlib.h>
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "./vpx_config.h"
14b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_common.h"
16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_extend.h"
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_lookahead.h"
19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_onyx_int.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct lookahead_ctx {
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int max_sz;         /* Absolute size of the queue */
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int sz;             /* Number of buffers currently in the queue */
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int read_idx;       /* Read index */
25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int write_idx;      /* Write index */
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct lookahead_entry *buf; /* Buffer list */
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* Return the buffer at the given absolute index and increment the index */
316ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic struct lookahead_entry *pop(struct lookahead_ctx *ctx,
326ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                   unsigned int *idx) {
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int index = *idx;
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct lookahead_entry *buf = ctx->buf + index;
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(index < ctx->max_sz);
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (++index >= ctx->max_sz)
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    index -= ctx->max_sz;
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *idx = index;
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return buf;
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_lookahead_destroy(struct lookahead_ctx *ctx) {
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (ctx) {
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (ctx->buf) {
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      unsigned int i;
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < ctx->max_sz; i++)
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_free_frame_buffer(&ctx->buf[i].img);
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      free(ctx->buf);
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    free(ctx);
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
586ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstruct lookahead_ctx *vp9_lookahead_init(unsigned int width,
596ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                         unsigned int height,
606ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                         unsigned int subsampling_x,
616ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                         unsigned int subsampling_y,
626ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                         unsigned int depth) {
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct lookahead_ctx *ctx = NULL;
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Clamp the lookahead queue depth
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  depth = clamp(depth, 1, MAX_LAG_BUFFERS);
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
686ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  // Allocate memory to keep previous source frames available.
696ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  depth += MAX_PRE_FRAMES;
706ac915abcdb404a00d927fe6308a47fcf09d9519hkuang
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Allocate the lookahead structures
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx = calloc(1, sizeof(*ctx));
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (ctx) {
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    unsigned int i;
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->max_sz = depth;
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->buf = calloc(depth, sizeof(*ctx->buf));
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!ctx->buf)
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      goto bail;
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < depth; i++)
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (vp9_alloc_frame_buffer(&ctx->buf[i].img,
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 width, height, subsampling_x, subsampling_y,
82b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                 VP9_ENC_BORDER_IN_PIXELS))
83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        goto bail;
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return ctx;
865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang bail:
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_lookahead_destroy(ctx);
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return NULL;
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define USE_PARTIAL_COPY 0
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG   *src,
94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       int64_t ts_start, int64_t ts_end, unsigned int flags) {
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct lookahead_entry *buf;
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if USE_PARTIAL_COPY
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int row, col, active_end;
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mb_rows = (src->y_height + 15) >> 4;
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mb_cols = (src->y_width + 15) >> 4;
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1026ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  if (ctx->sz + 1  + MAX_PRE_FRAMES > ctx->max_sz)
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 1;
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->sz++;
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf = pop(ctx, &ctx->write_idx);
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if USE_PARTIAL_COPY
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // TODO(jkoleszar): This is disabled for now, as
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // vp9_copy_and_extend_frame_with_rect is not subsampling/alpha aware.
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Only do this partial copy if the following conditions are all met:
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // 1. Lookahead queue has has size of 1.
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // 2. Active map is provided.
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // 3. This is not a key frame, golden nor altref frame.
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (ctx->max_sz == 1 && active_map && !flags) {
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (row = 0; row < mb_rows; ++row) {
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      col = 0;
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      while (1) {
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Find the first active macroblock in this row.
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (; col < mb_cols; ++col) {
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (active_map[col])
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            break;
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // No more active macroblock in this row.
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (col == mb_cols)
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          break;
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Find the end of active region in this row.
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        active_end = col;
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (; active_end < mb_cols; ++active_end) {
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (!active_map[active_end])
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            break;
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Only copy this active region.
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_copy_and_extend_frame_with_rect(src, &buf->img,
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            row << 4,
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            col << 4, 16,
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            (active_end - col) << 4);
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Start again from the end of this active region.
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        col = active_end;
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      active_map += mb_cols;
149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_copy_and_extend_frame(src, &buf->img);
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#else
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Partial copy not implemented yet
155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_copy_and_extend_frame(src, &buf->img);
156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf->ts_start = ts_start;
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf->ts_end = ts_end;
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  buf->flags = flags;
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 0;
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1656ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstruct lookahead_entry *vp9_lookahead_pop(struct lookahead_ctx *ctx,
1666ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                          int drain) {
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct lookahead_entry *buf = NULL;
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1696ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    buf = pop(ctx, &ctx->read_idx);
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->sz--;
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return buf;
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1776ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstruct lookahead_entry *vp9_lookahead_peek(struct lookahead_ctx *ctx,
1786ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                           int index) {
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct lookahead_entry *buf = NULL;
180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1816ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  if (index >= 0) {
1826ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    // Forward peek
1836ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    if (index < (int)ctx->sz) {
1846ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      index += ctx->read_idx;
1856ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      if (index >= (int)ctx->max_sz)
1866ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        index -= ctx->max_sz;
1876ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      buf = ctx->buf + index;
1886ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    }
1896ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  } else if (index < 0) {
1906ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    // Backward peek
1916ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    if (-index <= MAX_PRE_FRAMES) {
1926ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      index += ctx->read_idx;
1936ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      if (index < 0)
1946ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        index += ctx->max_sz;
1956ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      buf = ctx->buf + index;
1966ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    }
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1986ac915abcdb404a00d927fe6308a47fcf09d9519hkuang
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return buf;
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangunsigned int vp9_lookahead_depth(struct lookahead_ctx *ctx) {
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return ctx->sz;
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
205