Modify Lookahead queue API
Modified Lookahead queue context and API, to
facilitate multiple consumers to independently
pop entries pushed into the queue.
Change-Id: I20f5a1894c30bcf169f5d0b621bc4d5daa413015
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 808bb9b..b2238f5 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -416,7 +416,7 @@
*code_arf = 0;
struct lookahead_entry *source =
- av1_lookahead_peek(cpi->lookahead, arf_src_index);
+ av1_lookahead_peek(cpi->lookahead, arf_src_index, ENCODE_STAGE);
if (source != NULL) {
cm->showable_frame = 1;
@@ -454,7 +454,8 @@
static int is_forced_keyframe_pending(struct lookahead_ctx *lookahead,
const int up_to_index) {
for (int i = 0; i <= up_to_index; i++) {
- const struct lookahead_entry *e = av1_lookahead_peek(lookahead, i);
+ const struct lookahead_entry *e =
+ av1_lookahead_peek(lookahead, i, ENCODE_STAGE);
if (e == NULL) {
// We have reached the end of the lookahead buffer and not early-returned
// so there isn't a forced key-frame pending.
@@ -495,10 +496,10 @@
if (!source) {
// Get last frame source.
if (cm->current_frame.frame_number > 0) {
- *last_source = av1_lookahead_peek(cpi->lookahead, -1);
+ *last_source = av1_lookahead_peek(cpi->lookahead, -1, ENCODE_STAGE);
}
// Read in the source frame.
- source = av1_lookahead_pop(cpi->lookahead, *flush);
+ source = av1_lookahead_pop(cpi->lookahead, *flush, ENCODE_STAGE);
if (source == NULL) return NULL;
frame_params->show_frame = 1;
@@ -516,7 +517,7 @@
if (cpi->common.current_frame.frame_number == 0) return 0;
const struct lookahead_entry *lookahead_src =
- av1_lookahead_peek(cpi->lookahead, 0);
+ av1_lookahead_peek(cpi->lookahead, 0, ENCODE_STAGE);
if (lookahead_src == NULL) return 1;
const int is_error_resilient =
@@ -1150,7 +1151,7 @@
struct lookahead_entry *source = NULL;
struct lookahead_entry *last_source = NULL;
if (frame_params.show_existing_frame) {
- source = av1_lookahead_pop(cpi->lookahead, flush);
+ source = av1_lookahead_pop(cpi->lookahead, flush, ENCODE_STAGE);
frame_params.show_frame = 1;
} else {
int show_existing_alt_ref = 0;
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index edf4276..d5df0a7 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -333,7 +333,7 @@
const int alt_offset = 16 - (current_frame->frame_number % 16);
if (alt_offset < 16) {
const struct lookahead_entry *const alt_buf =
- av1_lookahead_peek(cpi->lookahead, alt_offset);
+ av1_lookahead_peek(cpi->lookahead, alt_offset, ENCODE_STAGE);
if (alt_buf != NULL) {
alt_yv12 = &alt_buf->img;
}
diff --git a/av1/encoder/lookahead.c b/av1/encoder/lookahead.c
index 4dd7318..7a42f17 100644
--- a/av1/encoder/lookahead.c
+++ b/av1/encoder/lookahead.c
@@ -60,6 +60,8 @@
const int legacy_byte_alignment = 0;
unsigned int i;
ctx->max_sz = depth;
+ ctx->read_ctxs[ENCODE_STAGE].pop_sz = ctx->max_sz - MAX_PRE_FRAMES;
+ ctx->read_ctxs[ENCODE_STAGE].valid = 1;
ctx->buf = calloc(depth, sizeof(*ctx->buf));
if (!ctx->buf) goto fail;
for (i = 0; i < depth; i++)
@@ -102,8 +104,10 @@
int subsampling_y = src->subsampling_y;
int larger_dimensions, new_dimensions;
- if (ctx->sz + 1 + MAX_PRE_FRAMES > ctx->max_sz) return 1;
- ctx->sz++;
+ assert(ctx->read_ctxs[ENCODE_STAGE].valid == 1);
+ if (ctx->read_ctxs[ENCODE_STAGE].sz + 1 + MAX_PRE_FRAMES > ctx->max_sz)
+ return 1;
+ ctx->read_ctxs[ENCODE_STAGE].sz++;
buf = pop(ctx, &ctx->write_idx);
new_dimensions = width != buf->img.y_crop_width ||
@@ -186,35 +190,41 @@
return 0;
}
-struct lookahead_entry *av1_lookahead_pop(struct lookahead_ctx *ctx,
- int drain) {
+struct lookahead_entry *av1_lookahead_pop(struct lookahead_ctx *ctx, int drain,
+ COMPRESSOR_STAGE stage) {
struct lookahead_entry *buf = NULL;
-
- if (ctx && ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
- buf = pop(ctx, &ctx->read_idx);
- ctx->sz--;
+ if (ctx) {
+ struct read_ctx *read_ctx = &ctx->read_ctxs[stage];
+ assert(read_ctx->valid == 1);
+ if (read_ctx->sz && (drain || read_ctx->sz == read_ctx->pop_sz)) {
+ buf = pop(ctx, &read_ctx->read_idx);
+ read_ctx->sz--;
+ }
}
return buf;
}
-struct lookahead_entry *av1_lookahead_peek(struct lookahead_ctx *ctx,
- int index) {
+struct lookahead_entry *av1_lookahead_peek(struct lookahead_ctx *ctx, int index,
+ COMPRESSOR_STAGE stage) {
struct lookahead_entry *buf = NULL;
-
+ struct read_ctx *read_ctx = NULL;
if (ctx == NULL) {
return buf;
}
+
+ read_ctx = &ctx->read_ctxs[stage];
+ assert(read_ctx->valid == 1);
if (index >= 0) {
// Forward peek
- if (index < ctx->sz) {
- index += ctx->read_idx;
+ if (index < read_ctx->sz) {
+ index += read_ctx->read_idx;
if (index >= ctx->max_sz) index -= ctx->max_sz;
buf = ctx->buf + index;
}
} else if (index < 0) {
// Backward peek
if (-index <= MAX_PRE_FRAMES) {
- index += (int)(ctx->read_idx);
+ index += (int)(read_ctx->read_idx);
if (index < 0) index += (int)(ctx->max_sz);
buf = ctx->buf + index;
}
@@ -223,7 +233,12 @@
return buf;
}
-unsigned int av1_lookahead_depth(struct lookahead_ctx *ctx) {
+unsigned int av1_lookahead_depth(struct lookahead_ctx *ctx,
+ COMPRESSOR_STAGE stage) {
+ struct read_ctx *read_ctx = NULL;
assert(ctx != NULL);
- return ctx->sz;
+
+ read_ctx = &ctx->read_ctxs[stage];
+ assert(read_ctx->valid == 1);
+ return read_ctx->sz;
}
diff --git a/av1/encoder/lookahead.h b/av1/encoder/lookahead.h
index 3b2d94b..7881345 100644
--- a/av1/encoder/lookahead.h
+++ b/av1/encoder/lookahead.h
@@ -31,12 +31,20 @@
// The max of past frames we want to keep in the queue.
#define MAX_PRE_FRAMES 1
+enum { ENCODE_STAGE, MAX_STAGES } UENUM1BYTE(COMPRESSOR_STAGE);
+
+struct read_ctx {
+ int sz; /* Number of buffers currently in the queue */
+ int read_idx; /* Read index */
+ int pop_sz; /* Size to check for pop condition */
+ int valid; /* Is this ctx valid? */
+};
+
struct lookahead_ctx {
- int max_sz; /* Absolute size of the queue */
- int sz; /* Number of buffers currently in the queue */
- int read_idx; /* Read index */
- int write_idx; /* Write index */
- struct lookahead_entry *buf; /* Buffer list */
+ int max_sz; /* Absolute size of the queue */
+ int write_idx; /* Write index */
+ struct read_ctx read_ctxs[MAX_STAGES]; /* Read context */
+ struct lookahead_entry *buf; /* Buffer list */
};
/**\brief Initializes the lookahead stage
@@ -82,7 +90,8 @@
* \retval NULL, if drain set and queue is empty
* \retval NULL, if drain not set and queue not of the configured depth
*/
-struct lookahead_entry *av1_lookahead_pop(struct lookahead_ctx *ctx, int drain);
+struct lookahead_entry *av1_lookahead_pop(struct lookahead_ctx *ctx, int drain,
+ COMPRESSOR_STAGE stage);
/**\brief Get a future source buffer to encode
*
@@ -91,14 +100,15 @@
*
* \retval NULL, if no buffer exists at the specified index
*/
-struct lookahead_entry *av1_lookahead_peek(struct lookahead_ctx *ctx,
- int index);
+struct lookahead_entry *av1_lookahead_peek(struct lookahead_ctx *ctx, int index,
+ COMPRESSOR_STAGE stage);
/**\brief Get the number of frames currently in the lookahead queue
*
* \param[in] ctx Pointer to the lookahead context
*/
-unsigned int av1_lookahead_depth(struct lookahead_ctx *ctx);
+unsigned int av1_lookahead_depth(struct lookahead_ctx *ctx,
+ COMPRESSOR_STAGE stage);
#ifdef __cplusplus
} // extern "C"
diff --git a/av1/encoder/mbgraph.c b/av1/encoder/mbgraph.c
index 0cb6286..d45bb8da 100644
--- a/av1/encoder/mbgraph.c
+++ b/av1/encoder/mbgraph.c
@@ -363,7 +363,7 @@
void av1_update_mbgraph_stats(AV1_COMP *cpi) {
AV1_COMMON *const cm = &cpi->common;
- int i, n_frames = av1_lookahead_depth(cpi->lookahead);
+ int i, n_frames = av1_lookahead_depth(cpi->lookahead, ENCODE_STAGE);
YV12_BUFFER_CONFIG *golden_ref = &get_ref_frame_buf(cm, GOLDEN_FRAME)->buf;
assert(golden_ref != NULL);
@@ -387,7 +387,8 @@
// the ARF MC search backwards, to get optimal results for MV caching
for (i = 0; i < n_frames; i++) {
MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i];
- struct lookahead_entry *q_cur = av1_lookahead_peek(cpi->lookahead, i);
+ struct lookahead_entry *q_cur =
+ av1_lookahead_peek(cpi->lookahead, i, ENCODE_STAGE);
assert(q_cur != NULL);
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index 7b8f8b3..9be19cd 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -1459,7 +1459,8 @@
q = ((int)av1_convert_qindex_to_q(cpi->rc.avg_frame_qindex[KEY_FRAME],
cpi->common.seq_params.bit_depth));
MACROBLOCKD *mbd = &cpi->td.mb.e_mbd;
- struct lookahead_entry *buf = av1_lookahead_peek(cpi->lookahead, distance);
+ struct lookahead_entry *buf =
+ av1_lookahead_peek(cpi->lookahead, distance, ENCODE_STAGE);
int strength;
double noiselevel;
if (is_cur_buf_hbd(mbd)) {
@@ -1516,7 +1517,7 @@
}
const int frames_after_arf =
- av1_lookahead_depth(cpi->lookahead) - distance - 1;
+ av1_lookahead_depth(cpi->lookahead, ENCODE_STAGE) - distance - 1;
int frames_fwd = (frames - 1) >> 1;
int frames_bwd = frames >> 1;
@@ -1600,7 +1601,7 @@
for (frame = 0; frame < frames_to_blur; ++frame) {
const int which_buffer = start_frame - frame;
struct lookahead_entry *buf =
- av1_lookahead_peek(cpi->lookahead, which_buffer);
+ av1_lookahead_peek(cpi->lookahead, which_buffer, ENCODE_STAGE);
if (buf == NULL) {
frames[frames_to_blur - 1 - frame] = NULL;
} else {
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 3d5e909..7c5fabf 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -571,7 +571,8 @@
const GF_GROUP *gf_group = &cpi->gf_group;
const int frame_disp_idx = gf_group->frame_disp_idx[frame_idx];
struct lookahead_entry *buf = av1_lookahead_peek(
- cpi->lookahead, frame_disp_idx - cpi->num_gf_group_show_frames);
+ cpi->lookahead, frame_disp_idx - cpi->num_gf_group_show_frames,
+ ENCODE_STAGE);
return &buf->img;
}
}
@@ -805,8 +806,8 @@
int frame_display_index = gf_index == gf_group->size
? cpi->rc.baseline_gf_interval
: gf_group->frame_disp_idx[gf_index];
- struct lookahead_entry *buf =
- av1_lookahead_peek(cpi->lookahead, frame_display_index - 1);
+ struct lookahead_entry *buf = av1_lookahead_peek(
+ cpi->lookahead, frame_display_index - 1, ENCODE_STAGE);
if (buf == NULL) break;
tpl_frame->gf_picture = &buf->img;
// frame display index = frame offset within the gf group + start frame of
@@ -848,8 +849,8 @@
frame_update_type == INTNL_OVERLAY_UPDATE;
frame_params.frame_type = INTER_FRAME;
- struct lookahead_entry *buf =
- av1_lookahead_peek(cpi->lookahead, frame_display_index - 1);
+ struct lookahead_entry *buf = av1_lookahead_peek(
+ cpi->lookahead, frame_display_index - 1, ENCODE_STAGE);
if (buf == NULL) break;