frame_superres: Post encode/decode upscaling

This patch implements the post-encode and post-decode upscaling for the
frame superresolution experiment to work.

Upscaling happens after cdef and before loop restoration.

For now, this patch forces on random-superres.

The patch also cleans up some broken rate control hooks from VP9
days, to be brought back later when the resize and superres tools
are stable.

Change-Id: If0a8f69224dfaa0f4ae7703bd429ea2af953c7a6
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index d7749dd..5e5db93 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -49,6 +49,9 @@
 #include "av1/common/quant_common.h"
 #include "av1/common/reconinter.h"
 #include "av1/common/reconintra.h"
+#if CONFIG_FRAME_SUPERRES
+#include "av1/common/resize.h"
+#endif  // CONFIG_FRAME_SUPERRES
 #include "av1/common/seg_common.h"
 #include "av1/common/thread_common.h"
 #include "av1/common/tile_common.h"
@@ -2203,6 +2206,7 @@
                     partition,
 #endif
                     bsize);
+
 #if !(CONFIG_MOTION_VAR && CONFIG_NCOBMC)
 #if CONFIG_SUPERTX
   if (!supertx_enabled)
@@ -3020,31 +3024,30 @@
 }
 
 static void setup_render_size(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
+#if CONFIG_FRAME_SUPERRES
+  cm->render_width = cm->superres_upscaled_width;
+  cm->render_height = cm->superres_upscaled_height;
+#else
   cm->render_width = cm->width;
   cm->render_height = cm->height;
+#endif  // CONFIG_FRAME_SUPERRES
   if (aom_rb_read_bit(rb))
     av1_read_frame_size(rb, &cm->render_width, &cm->render_height);
 }
 
 #if CONFIG_FRAME_SUPERRES
 // TODO(afergs): make "struct aom_read_bit_buffer *const rb"?
-static void setup_superres_size(AV1_COMMON *const cm,
-                                struct aom_read_bit_buffer *rb, int *width,
-                                int *height) {
-  // TODO(afergs): Save input resolution - it's the upscaled resolution
+static void setup_superres(AV1_COMMON *const cm, struct aom_read_bit_buffer *rb,
+                           int *width, int *height) {
+  cm->superres_upscaled_width = *width;
+  cm->superres_upscaled_height = *height;
   if (aom_rb_read_bit(rb)) {
     cm->superres_scale_numerator =
         (uint8_t)aom_rb_read_literal(rb, SUPERRES_SCALE_BITS);
     cm->superres_scale_numerator += SUPERRES_SCALE_NUMERATOR_MIN;
     // Don't edit cm->width or cm->height directly, or the buffers won't get
     // resized correctly
-    // TODO(afergs): Should the render resolution not be modified? It's the same
-    // by default (ie. when it isn't sent)...
-    // resize_context_buffers() will change cm->width to equal cm->render_width,
-    // then they'll be the same again
-    *width = *width * cm->superres_scale_numerator / SUPERRES_SCALE_DENOMINATOR;
-    *height =
-        *width * cm->superres_scale_numerator / SUPERRES_SCALE_DENOMINATOR;
+    av1_calculate_superres_size(cm, width, height);
   } else {
     // 1:1 scaling - ie. no scaling, scale not provided
     cm->superres_scale_numerator = SUPERRES_SCALE_DENOMINATOR;
@@ -3097,10 +3100,10 @@
   int width, height;
   BufferPool *const pool = cm->buffer_pool;
   av1_read_frame_size(rb, &width, &height);
-  setup_render_size(cm, rb);
 #if CONFIG_FRAME_SUPERRES
-  setup_superres_size(cm, rb, &width, &height);
+  setup_superres(cm, rb, &width, &height);
 #endif  // CONFIG_FRAME_SUPERRES
+  setup_render_size(cm, rb);
   resize_context_buffers(cm, width, height);
 
   lock_buffer_pool(pool);
@@ -3149,6 +3152,9 @@
       height = buf->y_crop_height;
       cm->render_width = buf->render_width;
       cm->render_height = buf->render_height;
+#if CONFIG_FRAME_SUPERRES
+      setup_superres(cm, rb, &width, &height);
+#endif  // CONFIG_FRAME_SUPERRES
       found = 1;
       break;
     }
@@ -3156,10 +3162,10 @@
 
   if (!found) {
     av1_read_frame_size(rb, &width, &height);
-    setup_render_size(cm, rb);
 #if CONFIG_FRAME_SUPERRES
-    setup_superres_size(cm, rb, &width, &height);
+    setup_superres(cm, rb, &width, &height);
 #endif  // CONFIG_FRAME_SUPERRES
+    setup_render_size(cm, rb);
   }
 
   if (width <= 0 || height <= 0)
@@ -5186,6 +5192,19 @@
 }
 #endif
 
+#if CONFIG_FRAME_SUPERRES
+void superres_post_decode(AV1Decoder *pbi) {
+  AV1_COMMON *const cm = &pbi->common;
+  BufferPool *const pool = cm->buffer_pool;
+
+  if (av1_superres_unscaled(cm)) return;
+
+  lock_buffer_pool(pool);
+  av1_superres_upscale(cm, pool);
+  unlock_buffer_pool(pool);
+}
+#endif  // CONFIG_FRAME_SUPERRES
+
 void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data,
                       const uint8_t *data_end, const uint8_t **p_data_end) {
   AV1_COMMON *const cm = &pbi->common;
@@ -5281,14 +5300,23 @@
 #if CONFIG_TEMPMV_SIGNALING
   if (cm->use_prev_frame_mvs) {
     assert(!cm->error_resilient_mode && cm->prev_frame &&
-           cm->width == last_fb_ref_buf->buf->y_width &&
-           cm->height == last_fb_ref_buf->buf->y_height &&
+#if CONFIG_FRAME_SUPERRES
+           cm->width == cm->last_width && cm->height == cm->last_height &&
+#else
+           cm->width == last_fb_ref_buf->buf->y_crop_width &&
+           cm->height == last_fb_ref_buf->buf->y_crop_height &&
+#endif  // CONFIG_FRAME_SUPERRES
            !cm->prev_frame->intra_only);
   }
 #else
   cm->use_prev_frame_mvs = !cm->error_resilient_mode && cm->prev_frame &&
+#if CONFIG_FRAME_SUPERRES
+                           cm->width == cm->last_width &&
+                           cm->height == cm->last_height &&
+#else
                            cm->width == cm->prev_frame->buf.y_crop_width &&
                            cm->height == cm->prev_frame->buf.y_crop_height &&
+#endif  // CONFIG_FRAME_SUPERRES
                            !cm->last_intra_only && cm->last_show_frame &&
                            (cm->last_frame_type != KEY_FRAME);
 #endif  // CONFIG_TEMPMV_SIGNALING
@@ -5361,6 +5389,10 @@
   }
 #endif  // CONFIG_CDEF
 
+#if CONFIG_FRAME_SUPERRES
+  superres_post_decode(pbi);
+#endif  // CONFIG_FRAME_SUPERRES
+
 #if CONFIG_LOOP_RESTORATION
   if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
       cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index eac280d..15a227c 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -444,7 +444,10 @@
   // border.
   if (pbi->dec_tile_row == -1 && pbi->dec_tile_col == -1)
 #endif  // CONFIG_EXT_TILE
-    aom_extend_frame_inner_borders(cm->frame_to_show);
+    // TODO(debargha): Fix encoder side mv range, so that we can use the
+    // inner border extension. As of now use the larger extension.
+    // aom_extend_frame_inner_borders(cm->frame_to_show);
+    aom_extend_frame_borders(cm->frame_to_show);
 
   aom_clear_system_state();