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;