Let firstpass_info support past stats

We need past stats for keyframe detection.
In this CL cur_index is added to indicate current frame's index.
start_index is indicating the first available stats.
When cur_index != start_index, it means there are past stats
available.

We use FIRSTPASS_INFO_STATS_PAST_MIN to control the past stats size.

BUG=aomedia:3069
BUG=aomedia:3070

Change-Id: I5f359c5081ffeced21c50662f716ee958186eb79
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index 1367cdb..8e3518e 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -162,7 +162,17 @@
   double cor_coeff;
 } FIRSTPASS_STATS;
 
-/*!\cond */
+// We want to keep one past stats for key frame detection
+// in test_candidate_kf()
+#define FIRSTPASS_INFO_STATS_PAST_MIN 1
+
+// The size of static buffer used in FIRSTPASS_INFO.
+#define FIRSTPASS_INFO_STATIC_BUF_SIZE \
+  (MAX_LAP_BUFFERS + FIRSTPASS_INFO_STATS_PAST_MIN)
+
+/*!
+ * \brief  Data structure used for managing first pass stats
+ */
 typedef struct {
   /*!
    * An static buffer that will be used when no ext_stats_buf is assigned.
@@ -173,7 +183,7 @@
    * encode the video in the same pass. In this scenario, the stats will
    * be pushed and popped from static_stats_buf.
    */
-  FIRSTPASS_STATS static_stats_buf[MAX_LAP_BUFFERS];
+  FIRSTPASS_STATS static_stats_buf[FIRSTPASS_INFO_STATIC_BUF_SIZE];
   /*!
    * A pointer point to first pass stats.
    * Note that this buffer will be used as ring buffer.
@@ -184,15 +194,37 @@
    */
   int stats_buf_size;
   /*!
-   * start_index of the current frame's stats
+   * start index of the available frame stats
+   * Note that start_index doesn't always point to
+   * current frame's stats because we need to
+   * keep past stats as well. To access current
+   * frame's stats, please use cur_index.
    */
   int start_index;
+
   /*!
    * count available stats stored in stats_buf
+   * the following condition should stay true
+   * stats_count = future_stats_count + past_stats_count
    */
   int stats_count;
 
   /*!
+   *  index of the current frame's stats
+   */
+  int cur_index;
+
+  /*!
+   * count available future stats including current stats
+   */
+  int future_stats_count;
+
+  /*!
+   * count available past stats EXCLUDING current stats
+   */
+  int past_stats_count;
+
+  /*!
    * Accumulation of the stats being pushed into firstpass_info
    */
   FIRSTPASS_STATS total_stats;
@@ -214,15 +246,31 @@
                                         FIRSTPASS_STATS *ext_stats_buf,
                                         int ext_stats_buf_size);
 
+/*!\brief Move cur_index by 1
+ *
+ * \ingroup rate_control
+ * \param[out]   firstpass_info      struct of firstpass_info.
+ * \return status
+ */
+aom_codec_err_t av1_firstpass_info_move_cur_index(
+    FIRSTPASS_INFO *firstpass_info);
+
 /*!\brief Pop a stats from firstpass_info
  *
  * \ingroup rate_control
  * \param[out]   firstpass_info      struct of firstpass_info.
- * \param[out]   output_stats        output stats
  * \return status
  */
-aom_codec_err_t av1_firstpass_info_pop(FIRSTPASS_INFO *firstpass_info,
-                                       FIRSTPASS_STATS *output_stats);
+aom_codec_err_t av1_firstpass_info_pop(FIRSTPASS_INFO *firstpass_info);
+
+/*!\brief Move cur_index by 1 and pop a stats from firstpass_info
+ *
+ * \ingroup rate_control
+ * \param[out]   firstpass_info      struct of firstpass_info.
+ * \return status
+ */
+aom_codec_err_t av1_firstpass_info_move_cur_index_and_pop(
+    FIRSTPASS_INFO *firstpass_info);
 
 /*!\brief Push a stats into firstpass_info
  *
@@ -237,23 +285,57 @@
 
 /*!\brief Peek at a stats from firstpass_info
  *
+ * The target index is as follows.
+ * (cur_index + offset_from_cur) % firstpass_info->stats_buf_size
+ *
  * \ingroup rate_control
  * \param[in]  firstpass_info      struct of firstpass_info.
- * \param[in]  stats_index_offset  index offset.
+ * \param[in]  offset_from_cur  index offset from cur_index.
  * \return pointer to the stats. The pointer will be NULL if
  *         stats_index_offset is invalid.
  */
 const FIRSTPASS_STATS *av1_firstpass_info_peek(
-    const FIRSTPASS_INFO *firstpass_info, int stats_index_offset);
+    const FIRSTPASS_INFO *firstpass_info, int offset_from_cur);
 
+/*!\brief Count the future stats from the target in firstpass_info
+ * Note that the target stats will be counted as well.
+ * The target index is as follows.
+ * (cur_index + offset_from_curr) % firstpass_info->stats_buf_size
+ *
+ * \ingroup rate_control
+ * \param[in]  firstpass_info    struct of firstpass_info.
+ * \param[in]  offset_from_cur  target stats's inffset
+ *                               from cur_index.
+ * \return Number of stats in the future after the target stats
+ *         including itself.
+ */
+int av1_firstpass_info_future_count(const FIRSTPASS_INFO *firstpass_info,
+                                    int offset_from_cur);
+
+/*!\brief Count the past stats before the target in firstpass_info
+ * Note that the target stats will NOT be counted.
+ * The target index is as follows.
+ * (cur_index + offset_from_cur) % firstpass_info->stats_buf_size
+ *
+ * \ingroup rate_control
+ * \param[in]  firstpass_info    struct of firstpass_info.
+ * \param[in]  offset_from_cur  target stats's index offset
+ *                               from cur_index.
+ * \return Number of stats in the past before the target stats
+ *         excluding itself.
+ */
+int av1_firstpass_info_past_count(const FIRSTPASS_INFO *firstpass_info,
+                                  int offset_from_cur);
+
+/*!\cond */
 #define FC_ANIMATION_THRESH 0.15
 enum {
   FC_NORMAL = 0,
   FC_GRAPHICS_ANIMATION = 1,
   FRAME_CONTENT_TYPES = 2
 } UENUM1BYTE(FRAME_CONTENT_TYPE);
-
 /*!\endcond */
+
 /*!
  * \brief  Data related to the current GF/ARF group and the
  * individual frames within the group