From 418564e7d0b4e70611f41b81d9c09f72d2697cfc Mon Sep 17 00:00:00 2001
From: John Koleszar <jkoleszar@google.com>
Date: Wed, 8 May 2013 16:18:44 -0700
Subject: [PATCH] Add vp9_extend_frame_borders

Adds a subsampling aware border extension function. This may be reworked
soon to support more than 3 planes.

Change-Id: I76b81901ad10bb1e678dd4f0d22740ca6c76c43b
---
 vp9/decoder/vp9_onyxd_if.c     |  3 ++-
 vp9/encoder/vp9_firstpass.c    |  2 +-
 vp9/encoder/vp9_onyx_if.c      |  3 ++-
 vpx_scale/generic/yv12extend.c | 31 +++++++++++++++++++++++++++++++
 vpx_scale/vpx_scale_rtcd.sh    |  5 +++++
 5 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/vp9/decoder/vp9_onyxd_if.c b/vp9/decoder/vp9_onyxd_if.c
index c0ce311b1d..6a55e8fb81 100644
--- a/vp9/decoder/vp9_onyxd_if.c
+++ b/vp9/decoder/vp9_onyxd_if.c
@@ -352,7 +352,8 @@ int vp9_receive_compressed_data(VP9D_PTR ptr,
       vp9_loop_filter_frame(cm, &pbi->mb, cm->filter_level, 0,
                             cm->dering_enabled);
     }
-    vp8_yv12_extend_frame_borders(cm->frame_to_show);
+    vp9_extend_frame_borders(cm->frame_to_show,
+                             cm->subsampling_x, cm->subsampling_y);
   }
 
 #if WRITE_RECON_BUFFER == 1
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 0561efef9f..367ebecc32 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -770,7 +770,7 @@ void vp9_first_pass(VP9_COMP *cpi) {
   // swap frame pointers so last frame refers to the frame we just compressed
   swap_yv12(lst_yv12, new_yv12);
 
-  vp8_yv12_extend_frame_borders(lst_yv12);
+  vp9_extend_frame_borders(lst_yv12, cm->subsampling_x, cm->subsampling_y);
 
   // Special case for the first frame. Copy into the GF buffer as a second reference.
   if (cm->current_video_frame == 0)
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 464b649f1d..b6f9eb7f88 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -2439,7 +2439,8 @@ static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) {
                           cm->dering_enabled);
   }
 
-  vp8_yv12_extend_frame_borders(cm->frame_to_show);
+  vp9_extend_frame_borders(cm->frame_to_show,
+                           cm->subsampling_x, cm->subsampling_y);
 
 }
 
diff --git a/vpx_scale/generic/yv12extend.c b/vpx_scale/generic/yv12extend.c
index a322e0a2c3..c38fb807a6 100644
--- a/vpx_scale/generic/yv12extend.c
+++ b/vpx_scale/generic/yv12extend.c
@@ -9,6 +9,7 @@
  */
 
 #include <assert.h>
+#include "./vpx_config.h"
 #include "vpx_scale/yv12config.h"
 #include "vpx_mem/vpx_mem.h"
 #include "vpx_scale/vpx_scale.h"
@@ -94,6 +95,36 @@ vp8_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) {
                (ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2);
 }
 
+#if CONFIG_VP9
+void vp9_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf,
+                                int subsampling_x, int subsampling_y) {
+  const int c_w = (ybf->y_crop_width + subsampling_x) >> subsampling_x;
+  const int c_h = (ybf->y_crop_height + subsampling_y) >> subsampling_y;
+  const int c_et = ybf->border >> subsampling_y;
+  const int c_el = ybf->border >> subsampling_x;
+  const int c_eb = (ybf->border + ybf->y_height - ybf->y_crop_height +
+                    subsampling_y) >> subsampling_y;
+  const int c_er = (ybf->border + ybf->y_width - ybf->y_crop_width +
+                    subsampling_x) >> subsampling_x;
+
+  assert(ybf->y_height - ybf->y_crop_height < 16);
+  assert(ybf->y_width - ybf->y_crop_width < 16);
+  assert(ybf->y_height - ybf->y_crop_height >= 0);
+  assert(ybf->y_width - ybf->y_crop_width >= 0);
+
+  extend_plane(ybf->y_buffer, ybf->y_stride,
+               ybf->y_crop_width, ybf->y_crop_height,
+               ybf->border, ybf->border,
+               ybf->border + ybf->y_height - ybf->y_crop_height,
+               ybf->border + ybf->y_width - ybf->y_crop_width);
+
+  extend_plane(ybf->u_buffer, ybf->uv_stride,
+               c_w, c_h, c_et, c_el, c_eb, c_er);
+
+  extend_plane(ybf->v_buffer, ybf->uv_stride,
+               c_w, c_h, c_et, c_el, c_eb, c_er);
+}
+#endif
 
 /****************************************************************************
  *
diff --git a/vpx_scale/vpx_scale_rtcd.sh b/vpx_scale/vpx_scale_rtcd.sh
index e2bade077c..b4f89077da 100644
--- a/vpx_scale/vpx_scale_rtcd.sh
+++ b/vpx_scale/vpx_scale_rtcd.sh
@@ -24,3 +24,8 @@ specialize vp8_yv12_copy_frame neon
 
 prototype void vp8_yv12_copy_y "struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc"
 specialize vp8_yv12_copy_y neon
+
+if [ "$CONFIG_VP9" = "yes" ]; then
+    prototype void vp9_extend_frame_borders "struct yv12_buffer_config *ybf, int subsampling_x, int subsampling_y"
+    specialize vp9_extend_frame_borders
+fi
-- 
GitLab