2 * Copyright (c) 2011 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
13 #include "./vpx_config.h"
15 #include "vp9/common/vp9_common.h"
17 #include "vp9/encoder/vp9_encoder.h"
18 #include "vp9/encoder/vp9_extend.h"
19 #include "vp9/encoder/vp9_lookahead.h"
21 // The max of past frames we want to keep in the queue.
22 #define MAX_PRE_FRAMES 1
24 struct lookahead_ctx {
25 unsigned int max_sz; /* Absolute size of the queue */
26 unsigned int sz; /* Number of buffers currently in the queue */
27 unsigned int read_idx; /* Read index */
28 unsigned int write_idx; /* Write index */
29 struct lookahead_entry *buf; /* Buffer list */
33 /* Return the buffer at the given absolute index and increment the index */
34 static struct lookahead_entry *pop(struct lookahead_ctx *ctx,
36 unsigned int index = *idx;
37 struct lookahead_entry *buf = ctx->buf + index;
39 assert(index < ctx->max_sz);
40 if (++index >= ctx->max_sz)
47 void vp9_lookahead_destroy(struct lookahead_ctx *ctx) {
52 for (i = 0; i < ctx->max_sz; i++)
53 vp9_free_frame_buffer(&ctx->buf[i].img);
61 struct lookahead_ctx *vp9_lookahead_init(unsigned int width,
63 unsigned int subsampling_x,
64 unsigned int subsampling_y,
66 struct lookahead_ctx *ctx = NULL;
68 // Clamp the lookahead queue depth
69 depth = clamp(depth, 1, MAX_LAG_BUFFERS);
71 // Allocate memory to keep previous source frames available.
72 depth += MAX_PRE_FRAMES;
74 // Allocate the lookahead structures
75 ctx = calloc(1, sizeof(*ctx));
79 ctx->buf = calloc(depth, sizeof(*ctx->buf));
82 for (i = 0; i < depth; i++)
83 if (vp9_alloc_frame_buffer(&ctx->buf[i].img,
84 width, height, subsampling_x, subsampling_y,
85 VP9_ENC_BORDER_IN_PIXELS))
90 vp9_lookahead_destroy(ctx);
94 #define USE_PARTIAL_COPY 0
96 int vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
97 int64_t ts_start, int64_t ts_end, unsigned int flags) {
98 struct lookahead_entry *buf;
100 int row, col, active_end;
101 int mb_rows = (src->y_height + 15) >> 4;
102 int mb_cols = (src->y_width + 15) >> 4;
105 if (ctx->sz + 1 + MAX_PRE_FRAMES > ctx->max_sz)
108 buf = pop(ctx, &ctx->write_idx);
111 // TODO(jkoleszar): This is disabled for now, as
112 // vp9_copy_and_extend_frame_with_rect is not subsampling/alpha aware.
114 // Only do this partial copy if the following conditions are all met:
115 // 1. Lookahead queue has has size of 1.
116 // 2. Active map is provided.
117 // 3. This is not a key frame, golden nor altref frame.
118 if (ctx->max_sz == 1 && active_map && !flags) {
119 for (row = 0; row < mb_rows; ++row) {
123 // Find the first active macroblock in this row.
124 for (; col < mb_cols; ++col) {
129 // No more active macroblock in this row.
133 // Find the end of active region in this row.
136 for (; active_end < mb_cols; ++active_end) {
137 if (!active_map[active_end])
141 // Only copy this active region.
142 vp9_copy_and_extend_frame_with_rect(src, &buf->img,
145 (active_end - col) << 4);
147 // Start again from the end of this active region.
151 active_map += mb_cols;
154 vp9_copy_and_extend_frame(src, &buf->img);
157 // Partial copy not implemented yet
158 vp9_copy_and_extend_frame(src, &buf->img);
161 buf->ts_start = ts_start;
162 buf->ts_end = ts_end;
168 struct lookahead_entry *vp9_lookahead_pop(struct lookahead_ctx *ctx,
170 struct lookahead_entry *buf = NULL;
172 if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
173 buf = pop(ctx, &ctx->read_idx);
180 struct lookahead_entry *vp9_lookahead_peek(struct lookahead_ctx *ctx,
182 struct lookahead_entry *buf = NULL;
186 if (index < (int)ctx->sz) {
187 index += ctx->read_idx;
188 if (index >= (int)ctx->max_sz)
189 index -= ctx->max_sz;
190 buf = ctx->buf + index;
192 } else if (index < 0) {
194 if (-index <= MAX_PRE_FRAMES) {
195 index += ctx->read_idx;
197 index += ctx->max_sz;
198 buf = ctx->buf + index;
205 unsigned int vp9_lookahead_depth(struct lookahead_ctx *ctx) {