1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2011 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <assert.h> 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h> 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_config.h" 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "lookahead.h" 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp8/common/extend.h" 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MAX_LAG_BUFFERS (CONFIG_REALTIME_ONLY? 1 : 25) 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan 18233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct lookahead_ctx 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int max_sz; /* Absolute size of the queue */ 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sz; /* Number of buffers currently in the queue */ 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int read_idx; /* Read index */ 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int write_idx; /* Write index */ 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct lookahead_entry *buf; /* Buffer list */ 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Return the buffer at the given absolute index and increment the index */ 29233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct lookahead_entry * 30233d2500723e5594f3e7c70896ffeeef32b9c950ywanpop(struct lookahead_ctx *ctx, 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int *idx) 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int index = *idx; 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct lookahead_entry *buf = ctx->buf + index; 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(index < ctx->max_sz); 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(++index >= ctx->max_sz) 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan index -= ctx->max_sz; 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan *idx = index; 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan return buf; 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan 44233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid 45233d2500723e5594f3e7c70896ffeeef32b9c950ywanvp8_lookahead_destroy(struct lookahead_ctx *ctx) 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(ctx) 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(ctx->buf) 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int i; 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan for(i = 0; i < ctx->max_sz; i++) 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8_yv12_de_alloc_frame_buffer(&ctx->buf[i].img); 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(ctx->buf); 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(ctx); 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan 62233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct lookahead_ctx* 63233d2500723e5594f3e7c70896ffeeef32b9c950ywanvp8_lookahead_init(unsigned int width, 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int height, 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int depth) 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct lookahead_ctx *ctx = NULL; 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int i; 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Clamp the lookahead queue depth */ 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(depth < 1) 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan depth = 1; 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if(depth > MAX_LAG_BUFFERS) 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan depth = MAX_LAG_BUFFERS; 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Keep last frame in lookahead buffer by increasing depth by 1.*/ 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan depth += 1; 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Align the buffer dimensions */ 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan width = (width + 15) & ~15; 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan height = (height + 15) & ~15; 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Allocate the lookahead structures */ 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx = calloc(1, sizeof(*ctx)); 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(ctx) 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->max_sz = depth; 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->buf = calloc(depth, sizeof(*ctx->buf)); 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(!ctx->buf) 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan goto bail; 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan for(i=0; i<depth; i++) 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vp8_yv12_alloc_frame_buffer(&ctx->buf[i].img, 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan width, height, VP8BORDERINPIXELS)) 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan goto bail; 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ctx; 97233d2500723e5594f3e7c70896ffeeef32b9c950ywanbail: 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8_lookahead_destroy(ctx); 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan 103233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 104233d2500723e5594f3e7c70896ffeeef32b9c950ywanvp8_lookahead_push(struct lookahead_ctx *ctx, 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG *src, 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t ts_start, 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t ts_end, 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int flags, 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char *active_map) 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct lookahead_entry* buf; 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan int row, col, active_end; 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mb_rows = (src->y_height + 15) >> 4; 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mb_cols = (src->y_width + 15) >> 4; 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(ctx->sz + 2 > ctx->max_sz) 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->sz++; 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan buf = pop(ctx, &ctx->write_idx); 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Only do this partial copy if the following conditions are all met: 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 1. Lookahead queue has has size of 1. 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 2. Active map is provided. 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 3. This is not a key frame, golden nor altref frame. 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->max_sz == 1 && active_map && !flags) 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (row = 0; row < mb_rows; ++row) 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan col = 0; 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (1) 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Find the first active macroblock in this row. */ 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (; col < mb_cols; ++col) 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (active_map[col]) 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* No more active macroblock in this row. */ 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (col == mb_cols) 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Find the end of active region in this row. */ 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan active_end = col; 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (; active_end < mb_cols; ++active_end) 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!active_map[active_end]) 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Only copy this active region. */ 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8_copy_and_extend_frame_with_rect(src, &buf->img, 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan row << 4, 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan col << 4, 16, 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan (active_end - col) << 4); 159233d2500723e5594f3e7c70896ffeeef32b9c950ywan 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Start again from the end of this active region. */ 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan col = active_end; 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan active_map += mb_cols; 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8_copy_and_extend_frame(src, &buf->img); 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan buf->ts_start = ts_start; 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan buf->ts_end = ts_end; 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan buf->flags = flags; 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan 178233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct lookahead_entry* 179233d2500723e5594f3e7c70896ffeeef32b9c950ywanvp8_lookahead_pop(struct lookahead_ctx *ctx, 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan int drain) 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct lookahead_entry* buf = NULL; 183233d2500723e5594f3e7c70896ffeeef32b9c950ywan 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(ctx->sz && (drain || ctx->sz == ctx->max_sz - 1)) 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan buf = pop(ctx, &ctx->read_idx); 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->sz--; 188233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan return buf; 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan 193233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct lookahead_entry* 194233d2500723e5594f3e7c70896ffeeef32b9c950ywanvp8_lookahead_peek(struct lookahead_ctx *ctx, 195233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int index, 196233d2500723e5594f3e7c70896ffeeef32b9c950ywan int direction) 197233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 198233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct lookahead_entry* buf = NULL; 199233d2500723e5594f3e7c70896ffeeef32b9c950ywan 200233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (direction == PEEK_FORWARD) 201233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 202233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(index < ctx->max_sz - 1); 203233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(index < ctx->sz) 204233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 205233d2500723e5594f3e7c70896ffeeef32b9c950ywan index += ctx->read_idx; 206233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(index >= ctx->max_sz) 207233d2500723e5594f3e7c70896ffeeef32b9c950ywan index -= ctx->max_sz; 208233d2500723e5594f3e7c70896ffeeef32b9c950ywan buf = ctx->buf + index; 209233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 210233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 211233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (direction == PEEK_BACKWARD) 212233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 213233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(index == 1); 214233d2500723e5594f3e7c70896ffeeef32b9c950ywan 215233d2500723e5594f3e7c70896ffeeef32b9c950ywan if(ctx->read_idx == 0) 216233d2500723e5594f3e7c70896ffeeef32b9c950ywan index = ctx->max_sz - 1; 217233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 218233d2500723e5594f3e7c70896ffeeef32b9c950ywan index = ctx->read_idx - index; 219233d2500723e5594f3e7c70896ffeeef32b9c950ywan buf = ctx->buf + index; 220233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 221233d2500723e5594f3e7c70896ffeeef32b9c950ywan 222233d2500723e5594f3e7c70896ffeeef32b9c950ywan return buf; 223233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 224233d2500723e5594f3e7c70896ffeeef32b9c950ywan 225233d2500723e5594f3e7c70896ffeeef32b9c950ywan 226233d2500723e5594f3e7c70896ffeeef32b9c950ywanunsigned int 227233d2500723e5594f3e7c70896ffeeef32b9c950ywanvp8_lookahead_depth(struct lookahead_ctx *ctx) 228233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 229233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ctx->sz; 230233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 231