Account sub8x8 block reference filter type for prob context
If a reference block is coded with sub8x8 block size, and if it
has sub-pixel level motion vectors, its prediction filter type
should be used as context information.
The coding performance gains of dual filter type coding scheme are
lowres 0.57%
hdres 0.88%
Change-Id: I68b98f2518d02f11c29d0256aeb45b2580fe5cac
diff --git a/vp10/common/pred_common.c b/vp10/common/pred_common.c
index a4e3bf2..6b10f3b 100644
--- a/vp10/common/pred_common.c
+++ b/vp10/common/pred_common.c
@@ -11,18 +11,20 @@
#include "vp10/common/common.h"
#include "vp10/common/pred_common.h"
+#include "vp10/common/reconinter.h"
#include "vp10/common/seg_common.h"
// Returns a context number for the given MB prediction signal
#if CONFIG_DUAL_FILTER
-static INTERP_FILTER get_ref_filter_type(const MB_MODE_INFO *ref_mbmi,
+static INTERP_FILTER get_ref_filter_type(const MODE_INFO *mi,
+ const MACROBLOCKD *xd,
int dir,
MV_REFERENCE_FRAME ref_frame) {
INTERP_FILTER ref_type = SWITCHABLE_FILTERS;
- const MV tmp_mv[2] = {ref_mbmi->mv[0].as_mv, ref_mbmi->mv[1].as_mv};
- const int use_subpel[2] = {
- ((dir & 0x01) ? tmp_mv[0].col : tmp_mv[0].row) & SUBPEL_MASK,
- ((dir & 0x01) ? tmp_mv[1].col : tmp_mv[1].row) & SUBPEL_MASK,
+ const MB_MODE_INFO *ref_mbmi = &mi->mbmi;
+ int use_subpel[2] = {
+ has_subpel_mv_component(mi, xd, dir),
+ has_subpel_mv_component(mi, xd, dir + 2),
};
if (ref_mbmi->ref_frame[0] == ref_frame && use_subpel[0])
@@ -43,17 +45,16 @@
// The mode info data structure has a one element border above and to the
// left of the entries corresponding to real macroblocks.
// The prediction flags in these dummy entries are initialized to 0.
- const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
- const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
int filter_type_ctx = ctx_offset + (dir & 0x01) * INTER_FILTER_DIR_OFFSET;
int left_type = SWITCHABLE_FILTERS;
int above_type = SWITCHABLE_FILTERS;
if (xd->left_available)
- left_type = get_ref_filter_type(left_mbmi, dir, ref_frame);
+ left_type = get_ref_filter_type(xd->mi[-1], xd, dir, ref_frame);
if (xd->up_available)
- above_type = get_ref_filter_type(above_mbmi, dir, ref_frame);
+ above_type = get_ref_filter_type(xd->mi[-xd->mi_stride], xd,
+ dir, ref_frame);
if (left_type == above_type)
filter_type_ctx += left_type;
diff --git a/vp10/common/reconinter.h b/vp10/common/reconinter.h
index 28a5ae9..c4a0978 100644
--- a/vp10/common/reconinter.h
+++ b/vp10/common/reconinter.h
@@ -434,10 +434,10 @@
#if CONFIG_DUAL_FILTER
// Detect if the block have sub-pixel level motion vectors
// per component.
-static INLINE int has_subpel_mv_component(const MACROBLOCKD *const xd,
+static INLINE int has_subpel_mv_component(const MODE_INFO *const mi,
+ const MACROBLOCKD *const xd,
int dir) {
- MODE_INFO *const mi = xd->mi[0];
- MB_MODE_INFO *const mbmi = &mi->mbmi;
+ const MB_MODE_INFO *const mbmi = &mi->mbmi;
const BLOCK_SIZE bsize = mbmi->sb_type;
int plane;
int ref = (dir >> 1);
diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c
index a92af27..72ab781 100644
--- a/vp10/decoder/decodemv.c
+++ b/vp10/decoder/decodemv.c
@@ -1621,9 +1621,9 @@
mbmi->interp_filter[ref] = (cm->interp_filter == SWITCHABLE) ?
EIGHTTAP_REGULAR : cm->interp_filter;
- if (has_subpel_mv_component(xd, ref) ||
+ if (has_subpel_mv_component(xd->mi[0], xd, ref) ||
(mbmi->ref_frame[1] > INTRA_FRAME &&
- has_subpel_mv_component(xd, ref + 2)))
+ has_subpel_mv_component(xd->mi[0], xd, ref + 2)))
mbmi->interp_filter[ref] = read_interp_filter(cm, xd, ref, r);
}
// The index system worsk as:
diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c
index 9c07051..0cbbc33 100644
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -939,9 +939,9 @@
#endif // CONFIG_EXT_INTERP
#if CONFIG_DUAL_FILTER
for (dir = 0; dir < 2; ++dir) {
- if (has_subpel_mv_component(xd, dir) ||
+ if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
(mbmi->ref_frame[1] > INTRA_FRAME &&
- has_subpel_mv_component(xd, dir + 2))) {
+ has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);
vp10_write_token(w, vp10_switchable_interp_tree,
cm->fc->switchable_interp_prob[ctx],
diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c
index d78d199..e225ece 100644
--- a/vp10/encoder/encodeframe.c
+++ b/vp10/encoder/encodeframe.c
@@ -1024,9 +1024,9 @@
MACROBLOCKD *xd, MB_MODE_INFO *mbmi) {
int dir;
for (dir = 0; dir < 2; ++dir) {
- if (!has_subpel_mv_component(xd, dir) &&
+ if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
(mbmi->ref_frame[1] == NONE ||
- !has_subpel_mv_component(xd, dir + 2)))
+ !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE) ?
EIGHTTAP_REGULAR : cm->interp_filter;
mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
@@ -1038,9 +1038,9 @@
const MB_MODE_INFO *mbmi) {
int dir;
for (dir = 0; dir < 2; ++dir) {
- if (has_subpel_mv_component(xd, dir) ||
+ if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
(mbmi->ref_frame[1] > INTRA_FRAME &&
- has_subpel_mv_component(xd, dir + 2))) {
+ has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);
++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
}
diff --git a/vp10/encoder/rd.c b/vp10/encoder/rd.c
index 0d91fbd..5450647 100644
--- a/vp10/encoder/rd.c
+++ b/vp10/encoder/rd.c
@@ -730,9 +730,9 @@
int dir;
for (dir = 0; dir < 2; ++dir) {
- if (has_subpel_mv_component(xd, dir) ||
+ if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
(mbmi->ref_frame[1] > INTRA_FRAME &&
- has_subpel_mv_component(xd, dir + 2))) {
+ has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);
inter_filter_cost +=
cpi->switchable_interp_costs[ctx][mbmi->interp_filter[dir]];