• John Koleszar's avatar
    Refactor lookahead ring buffer · 88841f10
    John Koleszar authored
    This patch cleans up the source buffer storage and copy mechanism to
    allow access through a standard push/pop/peek interface. This approach
    also avoids an extra copy in the case where the source is not a
    multiple of 16, fixing issue #102.
    
    Change-Id: I05808c39f5743625cb4c7af54cc841b9b10fdbd9
    88841f10
lookahead.c 3.71 KiB
/*
 *  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 "lookahead.h"
#include "vp8/common/extend.h"
#define MAX_LAG_BUFFERS (CONFIG_REALTIME_ONLY? 1 : 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
vp8_lookahead_destroy(struct lookahead_ctx *ctx)
    if(ctx)
        if(ctx->buf)
            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*
vp8_lookahead_init(unsigned int width,
                   unsigned int height,
                   unsigned int depth)
    struct lookahead_ctx *ctx = NULL;
    int i;
    /* Clamp the lookahead queue depth */
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
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) { 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, 16)) goto bail; } return ctx; bail: vp8_lookahead_destroy(ctx); return NULL; } int vp8_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, int64_t ts_start, int64_t ts_end, unsigned int flags) { struct lookahead_entry* buf; if(ctx->sz + 1 > ctx->max_sz) return 1; ctx->sz++; buf = pop(ctx, &ctx->write_idx); vp8_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* vp8_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* vp8_lookahead_peek(struct lookahead_ctx *ctx, int index) { struct lookahead_entry* buf = NULL;
141142143144145146147148149150151152153154155156157158
assert(index < ctx->max_sz); if(index < ctx->sz) { index += ctx->read_idx; if(index >= ctx->max_sz) index -= ctx->max_sz; buf = ctx->buf + index; } return buf; } unsigned int vp8_lookahead_depth(struct lookahead_ctx *ctx) { return ctx->sz; }