Introduce encode_strategy.c & av1_encode interface

* Add new files av1/encoder/encode_strategy.{c,h} containing
  av1_encode_strategy().  High-level encoding strategy will be moved
  to av1_encode_strategy from av1_get_compressed_data(),
  Pass{0,2}Encode(), etc.
* Add new interface av1_encode() in encoder.{c,h} to form the boundary
  between high-level encoding strategy and low-level frame encoding.

In this patch av1_encode_strategy() directly calls av1_encode().
High-level encoding strategy will be gradually moved into
av1_encode_strategy() and low-level housekeeping will be moved below
av1_encode().  The new boundary will make the parameters for
frame-encoding explicit and grouped together.

(Also, I remove the unused skip_adapt flag for convenience).

This forms part of wider restructuring and refactoring in order to
achieve a clean API separation at the entry to the low-level encoder.

BUG=aomedia:2244

Change-Id: Ia5e0e9ba56a26134fddf0fb82b5104bce60f2888
diff --git a/av1/av1.cmake b/av1/av1.cmake
index 19f639d..fadded7 100644
--- a/av1/av1.cmake
+++ b/av1/av1.cmake
@@ -137,6 +137,8 @@
             "${AOM_ROOT}/av1/encoder/encodemb.h"
             "${AOM_ROOT}/av1/encoder/encodemv.c"
             "${AOM_ROOT}/av1/encoder/encodemv.h"
+            "${AOM_ROOT}/av1/encoder/encode_strategy.c"
+            "${AOM_ROOT}/av1/encoder/encode_strategy.h"
             "${AOM_ROOT}/av1/encoder/encoder.c"
             "${AOM_ROOT}/av1/encoder/encoder.h"
             "${AOM_ROOT}/av1/encoder/encodetxb.c"
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
new file mode 100644
index 0000000..ca00a6e
--- /dev/null
+++ b/av1/encoder/encode_strategy.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#include <stdint.h>
+
+#include "aom/aom_codec.h"
+
+#include "av1/encoder/encoder.h"
+#include "av1/encoder/encode_strategy.h"
+
+int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
+                        uint8_t *const dest, unsigned int *frame_flags) {
+  EncodeFrameParams frame_params = { 0 };
+  EncodeFrameResults frame_results = { 0 };
+
+  // TODO(david.turner@argondesign.com): Move all the encode strategy
+  // (largely near av1_get_compressed_data) in here
+
+  // TODO(david.turner@argondesign.com): Change all the encode strategy to
+  // modify frame_params instead of cm or cpi.
+
+  frame_params.frame_flags = frame_flags;
+
+  if (av1_encode(cpi, dest, &frame_params, &frame_results) != AOM_CODEC_OK) {
+    return AOM_CODEC_ERROR;
+  }
+
+  *size = frame_results.size;
+
+  return AOM_CODEC_OK;
+}
diff --git a/av1/encoder/encode_strategy.h b/av1/encoder/encode_strategy.h
new file mode 100644
index 0000000..89f2d34
--- /dev/null
+++ b/av1/encoder/encode_strategy.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#ifndef AOM_AV1_ENCODE_STRATEGY_H_
+#define AOM_AV1_ENCODE_STRATEGY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// This function will implement high-level encode strategy, choosing frame type,
+// frame placement, etc.  It populates an EncodeFrameParams struct with the
+// results of these decisions and then calls av1_encode()
+int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
+                        uint8_t *const dest, unsigned int *frame_flags);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // AOM_AV1_ENCODE_STRATEGY_H_
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 4c0e13e..2352b15 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -54,6 +54,7 @@
 #include "av1/encoder/context_tree.h"
 #include "av1/encoder/encodeframe.h"
 #include "av1/encoder/encodemv.h"
+#include "av1/encoder/encode_strategy.h"
 #include "av1/encoder/encoder.h"
 #include "av1/encoder/encodetxb.h"
 #include "av1/encoder/ethread.h"
@@ -5173,7 +5174,6 @@
 }
 
 static int encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size, uint8_t *dest,
-                                     int skip_adapt,
                                      unsigned int *frame_flags) {
   AV1_COMMON *const cm = &cpi->common;
   SequenceHeader *const seq_params = &cm->seq_params;
@@ -5450,8 +5450,6 @@
 
   cpi->seq_params_locked = 1;
 
-  if (skip_adapt) return AOM_CODEC_OK;
-
   // Update reference frame ids for reference frames this frame will overwrite
   if (seq_params->frame_id_numbers_present_flag) {
     for (int i = 0; i < REF_FRAMES; i++) {
@@ -5539,6 +5537,20 @@
   return AOM_CODEC_OK;
 }
 
+int av1_encode(AV1_COMP *const cpi, uint8_t *const dest,
+               const EncodeFrameParams *const frame_params,
+               EncodeFrameResults *const frame_results) {
+  // TODO(david.turner@argondesign.com): Copy data from frame_params to cpi and
+  // cm as appropriate
+
+  if (encode_frame_to_data_rate(cpi, &frame_results->size, dest,
+                                frame_params->frame_flags) != AOM_CODEC_OK) {
+    return AOM_CODEC_ERROR;
+  }
+
+  return AOM_CODEC_OK;
+}
+
 static INLINE void update_keyframe_counters(AV1_COMP *cpi) {
   // TODO(zoeliu): To investigate whether we should treat BWDREF_FRAME
   //               differently here for rc->avg_frame_bandwidth.
@@ -5591,14 +5603,13 @@
 }
 
 static int Pass0Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
-                       int skip_adapt, unsigned int *frame_flags) {
+                       unsigned int *frame_flags) {
   if (cpi->oxcf.rc_mode == AOM_CBR) {
     av1_rc_get_one_pass_cbr_params(cpi);
   } else {
     av1_rc_get_one_pass_vbr_params(cpi);
   }
-  if (encode_frame_to_data_rate(cpi, size, dest, skip_adapt, frame_flags) !=
-      AOM_CODEC_OK) {
+  if (av1_encode_strategy(cpi, size, dest, frame_flags) != AOM_CODEC_OK) {
     return AOM_CODEC_ERROR;
   }
   set_additional_frame_flags(&cpi->common, frame_flags);
@@ -5619,8 +5630,7 @@
   cm->txcoeff_cost_count = 0;
 #endif
 
-  if (encode_frame_to_data_rate(cpi, size, dest, 0, frame_flags) !=
-      AOM_CODEC_OK) {
+  if (av1_encode_strategy(cpi, size, dest, frame_flags) != AOM_CODEC_OK) {
     return AOM_CODEC_ERROR;
   }
   set_additional_frame_flags(&cpi->common, frame_flags);
@@ -7017,7 +7027,7 @@
       return AOM_CODEC_ERROR;
   } else {
     // One pass encode
-    if (Pass0Encode(cpi, size, dest, 0, frame_flags) != AOM_CODEC_OK)
+    if (Pass0Encode(cpi, size, dest, frame_flags) != AOM_CODEC_OK)
       return AOM_CODEC_ERROR;
   }
   if (oxcf->pass != 1 && cpi->common.allow_screen_content_tools) {
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index af02e07..2c1c4db 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -867,6 +867,18 @@
   int is_screen_content_type;
 } AV1_COMP;
 
+// EncodeFrameParams contains per-frame encoding parameters decided upon by
+// av1_encode_strategy() and passed down to av1_encode()
+typedef struct {
+  unsigned int *frame_flags;
+} EncodeFrameParams;
+
+// EncodeFrameResults contains information about the result of encoding a
+// single frame
+typedef struct {
+  size_t size;  // Size of resulting bitstream
+} EncodeFrameResults;
+
 // Must not be called more than once.
 void av1_initialize_enc(void);
 
@@ -887,6 +899,10 @@
                             int64_t *time_end, int flush,
                             const aom_rational_t *timebase);
 
+int av1_encode(AV1_COMP *const cpi, uint8_t *const dest,
+               const EncodeFrameParams *const frame_params,
+               EncodeFrameResults *const frame_results);
+
 int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest);
 
 int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame);