]> granicus.if.org Git - libvpx/commitdiff
Rework sub8x8 chroma component inter predictor
authorJingning Han <jingning@google.com>
Tue, 17 May 2016 01:27:20 +0000 (18:27 -0700)
committerJingning Han <jingning@google.com>
Thu, 19 May 2016 16:03:57 +0000 (09:03 -0700)
This commit makes the sub8x8 chroma component inter predictor
operate at 2x2 block level. This allows one to use the actual motion
vector associated with each individal pixel block. It improves the
compression performance

lowres  0.40%
midres  0.25%
hdres   0.15%

Change-Id: Ia40e07cc7fde463dbf660018850e024932136c4f

vp10/common/reconinter.c
vp10/common/reconinter.h

index d6ac4bb8da290ec003b24d76ccf9c0538a8df622..ca2537bec843d193d9f0da4b8cc277c107b4d890 100644 (file)
@@ -759,6 +759,74 @@ void build_inter_predictors(MACROBLOCKD *xd, int plane,
   const int is_compound = has_second_ref(&mi->mbmi);
   int ref;
 
+#if CONFIG_DUAL_FILTER
+  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
+    int blk_num = 1 << (pd->subsampling_x + pd->subsampling_y);
+    int chr_idx;
+    int x_base = x;
+    int y_base = y;
+    int x_step = w >> pd->subsampling_x;
+    int y_step = h >> pd->subsampling_y;
+
+    for (chr_idx = 0; chr_idx < blk_num; ++chr_idx) {
+      for (ref = 0; ref < 1 + is_compound; ++ref) {
+        const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
+        struct buf_2d *const pre_buf = &pd->pre[ref];
+        struct buf_2d *const dst_buf = &pd->dst;
+        uint8_t *dst = dst_buf->buf;
+        const MV mv = mi->bmi[chr_idx].as_mv[ref].as_mv;
+        const MV mv_q4 = clamp_mv_to_umv_border_sb(xd, &mv, bw, bh,
+                                                   pd->subsampling_x,
+                                                   pd->subsampling_y);
+        uint8_t *pre;
+        MV32 scaled_mv;
+        int xs, ys, subpel_x, subpel_y;
+        const int is_scaled = vp10_is_scaled(sf);
+
+        x = x_base + (chr_idx & 0x01) * x_step;
+        y = y_base + (chr_idx >> 1) * y_step;
+
+        dst += dst_buf->stride * y + x;
+
+        if (is_scaled) {
+          pre = pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
+          scaled_mv = vp10_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
+          xs = sf->x_step_q4;
+          ys = sf->y_step_q4;
+        } else {
+          pre = pre_buf->buf + y * pre_buf->stride + x;
+          scaled_mv.row = mv_q4.row;
+          scaled_mv.col = mv_q4.col;
+          xs = ys = 16;
+        }
+
+        subpel_x = scaled_mv.col & SUBPEL_MASK;
+        subpel_y = scaled_mv.row & SUBPEL_MASK;
+        pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride
+               + (scaled_mv.col >> SUBPEL_BITS);
+
+    #if CONFIG_EXT_INTER
+        if (ref && is_interinter_wedge_used(mi->mbmi.sb_type) &&
+            mi->mbmi.use_wedge_interinter)
+          vp10_make_masked_inter_predictor(
+              pre, pre_buf->stride, dst, dst_buf->stride,
+              subpel_x, subpel_y, sf, w, h,
+              mi->mbmi.interp_filter, xs, ys,
+    #if CONFIG_SUPERTX
+              wedge_offset_x, wedge_offset_y,
+    #endif  // CONFIG_SUPERTX
+              xd);
+        else
+    #endif  // CONFIG_EXT_INTER
+          vp10_make_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
+                                    subpel_x, subpel_y, sf, x_step, y_step, ref,
+                                    mi->mbmi.interp_filter, xs, ys, xd);
+      }
+    }
+    return;
+  }
+#endif
+
   for (ref = 0; ref < 1 + is_compound; ++ref) {
     const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
     struct buf_2d *const pre_buf = &pd->pre[ref];
index c4a09783e9ef7cd3cf8fa6317fdb4a78f03f5ce7..65b97f8bbf56a73db9c78cd3d8682074bd928de4 100644 (file)
@@ -44,7 +44,8 @@ static INLINE void inter_predictor(const uint8_t *src, int src_stride,
 
 #if CONFIG_DUAL_FILTER
   if (interp_filter_params_x.taps == SUBPEL_TAPS &&
-      interp_filter_params_y.taps == SUBPEL_TAPS) {
+      interp_filter_params_y.taps == SUBPEL_TAPS &&
+      w > 2 && h > 2) {
     const int16_t *kernel_x =
         vp10_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
     const int16_t *kernel_y =