summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure1
-rw-r--r--vp8/common/blockd.h23
-rw-r--r--vp8/common/entropy.h4
-rw-r--r--vp8/common/entropymode.c50
-rw-r--r--vp8/common/entropymode.h27
-rw-r--r--vp8/common/entropymv.c1
-rw-r--r--vp8/common/entropymv.h5
-rw-r--r--vp8/common/filter.c143
-rw-r--r--vp8/common/onyxc_int.h15
-rw-r--r--vp8/common/pred_common.c79
-rw-r--r--vp8/common/pred_common.h7
-rw-r--r--vp8/common/reconinter.c75
-rw-r--r--vp8/common/reconinter.h5
-rw-r--r--vp8/decoder/decodemv.c37
-rw-r--r--vp8/decoder/decodframe.c90
-rw-r--r--vp8/encoder/bitstream.c117
-rw-r--r--vp8/encoder/block.h6
-rw-r--r--vp8/encoder/encodeframe.c74
-rw-r--r--vp8/encoder/modecosts.c10
-rw-r--r--vp8/encoder/onyx_if.c79
-rw-r--r--vp8/encoder/onyx_int.h9
-rw-r--r--vp8/encoder/ratectrl.c6
-rw-r--r--vp8/encoder/rdopt.c139
23 files changed, 699 insertions, 303 deletions
diff --git a/configure b/configure
index 3cecfcd57..525ccd168 100755
--- a/configure
+++ b/configure
@@ -225,6 +225,7 @@ EXPERIMENT_LIST="
pred_filter
lossless
hybridtransform
+ switchable_interp
"
CONFIG_LIST="
external_build
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index dc0639f83..1bbaa6422 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -76,7 +76,25 @@ typedef enum {
INTER_FRAME = 1
} FRAME_TYPE;
-typedef enum {
+typedef enum
+{
+ SIXTAP = 0,
+ BILINEAR = 1,
+#if CONFIG_ENHANCED_INTERP
+ EIGHTTAP = 2,
+ EIGHTTAP_SHARP = 3,
+#if CONFIG_SWITCHABLE_INTERP
+ SWITCHABLE /* should be the last one */
+#endif
+#endif
+} INTERPOLATIONFILTERTYPE;
+
+#if 0//CONFIG_SWITCHABLE_INTERP
+#define VP8_SWITCHABLE_FILTERS 2 /* number of switchable filters */
+#endif
+
+typedef enum
+{
DC_PRED, /* average of above and left pixels */
V_PRED, /* vertical prediction */
H_PRED, /* horizontal prediction */
@@ -226,6 +244,9 @@ typedef struct {
// Flag to turn prediction signal filter on(1)/off(0 ) at the MB level
unsigned int pred_filter_enabled;
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ INTERPOLATIONFILTERTYPE interp_filter;
+#endif
} MB_MODE_INFO;
diff --git a/vp8/common/entropy.h b/vp8/common/entropy.h
index 8bb718a06..9993741c8 100644
--- a/vp8/common/entropy.h
+++ b/vp8/common/entropy.h
@@ -18,8 +18,8 @@
#include "coefupdateprobs.h"
-#define SUBMVREF_COUNT 5
-#define VP8_NUMMBSPLITS 4
+//#define SUBMVREF_COUNT 5
+//#define VP8_NUMMBSPLITS 4
/* Coefficient token alphabet */
diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c
index e48df3b36..4500e9c11 100644
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -9,10 +9,8 @@
*/
+#include "onyxc_int.h"
#include "modecont.h"
-#include "entropymode.h"
-#include "entropymv.h"
-#include "entropy.h"
#include "vpx_mem/vpx_mem.h"
@@ -286,6 +284,10 @@ void vp8_init_mbmode_probs(VP8_COMMON *x) {
vpx_memcpy(x->fc.sub_mv_ref_prob, vp8_sub_mv_ref_prob2, sizeof(vp8_sub_mv_ref_prob2));
vpx_memcpy(x->fc.mbsplit_prob, vp8_mbsplit_probs, sizeof(vp8_mbsplit_probs));
+#if CONFIG_SWITCHABLE_INTERP
+ vpx_memcpy(x->fc.switchable_interp_prob, vp8_switchable_interp_prob,
+ sizeof(vp8_switchable_interp_prob));
+#endif
}
@@ -323,6 +325,44 @@ void vp8_kf_default_bmode_probs(vp8_prob p [VP8_BINTRAMODES] [VP8_BINTRAMODES] [
} while (++i < VP8_BINTRAMODES);
}
+#if CONFIG_SWITCHABLE_INTERP
+#if VP8_SWITCHABLE_FILTERS == 3
+const vp8_tree_index vp8_switchable_interp_tree[VP8_SWITCHABLE_FILTERS*2-2] = {
+ -0, 2,
+ -1, -2
+};
+struct vp8_token_struct vp8_switchable_interp_encodings[VP8_SWITCHABLE_FILTERS];
+const INTERPOLATIONFILTERTYPE vp8_switchable_interp[VP8_SWITCHABLE_FILTERS] = {
+ EIGHTTAP, SIXTAP, EIGHTTAP_SHARP};
+const int vp8_switchable_interp_map[SWITCHABLE+1] = {1, -1, 0, 2, -1};
+const vp8_prob vp8_switchable_interp_prob [VP8_SWITCHABLE_FILTERS+1]
+ [VP8_SWITCHABLE_FILTERS-1] = {
+ {248, 192}, { 32, 248}, { 32, 32}, {192, 160}
+};
+#elif VP8_SWITCHABLE_FILTERS == 2
+const vp8_tree_index vp8_switchable_interp_tree[VP8_SWITCHABLE_FILTERS*2-2] = {
+ -0, -1,
+};
+struct vp8_token_struct vp8_switchable_interp_encodings[VP8_SWITCHABLE_FILTERS];
+const vp8_prob vp8_switchable_interp_prob [VP8_SWITCHABLE_FILTERS+1]
+ [VP8_SWITCHABLE_FILTERS-1] = {
+ {248},
+ { 64},
+ {192},
+};
+//#define SWITCHABLE_86
+#ifdef SWITCHABLE_86
+const INTERPOLATIONFILTERTYPE vp8_switchable_interp[VP8_SWITCHABLE_FILTERS] = {
+ EIGHTTAP, SIXTAP};
+const int vp8_switchable_interp_map[SWITCHABLE+1] = {1, -1, 0, -1, -1}; //8, 6
+#else
+const INTERPOLATIONFILTERTYPE vp8_switchable_interp[VP8_SWITCHABLE_FILTERS] = {
+ EIGHTTAP, EIGHTTAP_SHARP};
+const int vp8_switchable_interp_map[SWITCHABLE+1] = {-1, -1, 0, 1, -1}; //8, 8s
+#endif
+#endif
+#endif
+
void vp8_entropy_mode_init() {
vp8_tokens_from_tree(vp8_bmode_encodings, vp8_bmode_tree);
@@ -331,6 +371,10 @@ void vp8_entropy_mode_init() {
vp8_tokens_from_tree(vp8_uv_mode_encodings, vp8_uv_mode_tree);
vp8_tokens_from_tree(vp8_i8x8_mode_encodings, vp8_i8x8_mode_tree);
vp8_tokens_from_tree(vp8_mbsplit_encodings, vp8_mbsplit_tree);
+#if CONFIG_SWITCHABLE_INTERP
+ vp8_tokens_from_tree(vp8_switchable_interp_encodings,
+ vp8_switchable_interp_tree);
+#endif
vp8_tokens_from_tree_offset(vp8_mv_ref_encoding_array,
vp8_mv_ref_tree, NEARESTMV);
diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h
index f66c1c859..f9cc263b9 100644
--- a/vp8/common/entropymode.h
+++ b/vp8/common/entropymode.h
@@ -12,9 +12,12 @@
#ifndef __INC_ENTROPYMODE_H
#define __INC_ENTROPYMODE_H
-#include "onyxc_int.h"
+#include "blockd.h"
#include "treecoder.h"
+#define SUBMVREF_COUNT 5
+#define VP8_NUMMBSPLITS 4
+
typedef const int vp8_mbsplit[16];
extern vp8_mbsplit vp8_mbsplits [VP8_NUMMBSPLITS];
@@ -56,10 +59,11 @@ extern struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS];
void vp8_entropy_mode_init(void);
-void vp8_init_mbmode_probs(VP8_COMMON *x);
-extern void vp8_init_mode_contexts(VP8_COMMON *pc);
-extern void vp8_update_mode_context(VP8_COMMON *pc);;
-extern void vp8_accum_mv_refs(VP8_COMMON *pc,
+struct VP8Common;
+void vp8_init_mbmode_probs(struct VP8Common *x);
+extern void vp8_init_mode_contexts(struct VP8Common *pc);
+extern void vp8_update_mode_context(struct VP8Common *pc);;
+extern void vp8_accum_mv_refs(struct VP8Common *pc,
MB_PREDICTION_MODE m,
const int ct[4]);
@@ -67,4 +71,17 @@ void vp8_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES - 1]);
void vp8_kf_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES - 1]);
void vp8_adapt_mode_probs(struct VP8Common *);
+
+#if CONFIG_SWITCHABLE_INTERP
+#define VP8_SWITCHABLE_FILTERS 2 /* number of switchable filters */
+extern const INTERPOLATIONFILTERTYPE vp8_switchable_interp
+ [VP8_SWITCHABLE_FILTERS];
+extern const int vp8_switchable_interp_map[SWITCHABLE+1];
+extern const vp8_tree_index vp8_switchable_interp_tree
+ [2*(VP8_SWITCHABLE_FILTERS-1)];
+extern struct vp8_token_struct vp8_switchable_interp_encodings
+ [VP8_SWITCHABLE_FILTERS];
+extern const vp8_prob vp8_switchable_interp_prob
+ [VP8_SWITCHABLE_FILTERS+1][VP8_SWITCHABLE_FILTERS-1];
+#endif
#endif
diff --git a/vp8/common/entropymv.c b/vp8/common/entropymv.c
index 3dd72cc76..c1ea62d27 100644
--- a/vp8/common/entropymv.c
+++ b/vp8/common/entropymv.c
@@ -116,7 +116,6 @@ const vp8_tree_index vp8_small_mvtree [14] = {
};
struct vp8_token_struct vp8_small_mvencodings [8];
-
__inline static void calc_prob(vp8_prob *p, const unsigned int ct[2], int pbits) {
const unsigned int tot = ct[0] + ct[1];
if (tot) {
diff --git a/vp8/common/entropymv.h b/vp8/common/entropymv.h
index 96ea7ffae..c0726ecea 100644
--- a/vp8/common/entropymv.h
+++ b/vp8/common/entropymv.h
@@ -14,6 +14,7 @@
#include "treecoder.h"
#include "vpx_config.h"
+#include "blockd.h"
enum {
mv_max = 1023, /* max absolute value of a MV component */
@@ -78,5 +79,9 @@ extern struct vp8_token_struct vp8_small_mvencodings_hp [16];
#endif
void vp8_entropy_mv_init();
+#if CONFIG_ADAPTIVE_ENTROPY
+struct VP8Common;
+void vp8_adapt_mv_probs(struct VP8Common *cm);
+#endif
#endif
diff --git a/vp8/common/filter.c b/vp8/common/filter.c
index 856bad5a6..78c239080 100644
--- a/vp8/common/filter.c
+++ b/vp8/common/filter.c
@@ -46,7 +46,7 @@ DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[SUBPEL_SHIFTS][2]) = {
#if CONFIG_ENHANCED_INTERP
#define FILTER_ALPHA 0
-#define FILTER_ALPHA_SHARP 60
+#define FILTER_ALPHA_SHARP 1
DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_8[SUBPEL_SHIFTS][2 * INTERP_EXTEND]) = {
#if SUBPEL_SHIFTS==16
#if FILTER_ALPHA == 0
@@ -91,24 +91,6 @@ DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_8[SUBPEL_SHIFTS][2 * INTERP
{ 0, 3, -9, 27, 118, -13, 3, -1},
{ 0, 2, -6, 18, 122, -10, 2, 0},
{ 0, 1, -3, 8, 126, -5, 1, 0}
-#elif FILTER_ALPHA == 45
- /* alpha = 0.45 */
- { 0, 0, 0, 128, 0, 0, 0, 0},
- { 0, 1, -5, 126, 8, -3, 1, 0},
- { 0, 2, -9, 122, 17, -6, 2, 0},
- { 0, 3, -13, 117, 27, -8, 2, 0},
- { -1, 4, -15, 111, 37, -11, 3, 0},
- { -1, 4, -17, 104, 47, -13, 4, 0},
- { -1, 5, -18, 96, 58, -15, 4, -1},
- { -1, 5, -18, 87, 68, -17, 5, -1},
- { -1, 5, -18, 78, 78, -18, 5, -1},
- { -1, 5, -17, 68, 87, -18, 5, -1},
- { -1, 4, -15, 58, 96, -18, 5, -1},
- { 0, 4, -13, 47, 104, -17, 4, -1},
- { 0, 3, -11, 37, 111, -15, 4, -1},
- { 0, 2, -8, 27, 117, -13, 3, 0},
- { 0, 2, -6, 17, 122, -9, 2, 0},
- { 0, 1, -3, 8, 126, -5, 1, 0}
#endif /* FILTER_ALPHA */
#else /* SUBPEL_SHIFTS==16 */
#if FILTER_ALPHA == 0
@@ -130,23 +112,48 @@ DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_8[SUBPEL_SHIFTS][2 * INTERP
{ -1, 5, -16, 58, 96, -18, 5, -1},
{ 0, 3, -11, 37, 112, -16, 4, -1},
{ 0, 2, -6, 18, 122, -10, 2, 0}
-#elif FILTER_ALPHA == 45
- /* alpha = 0.45 */
- { 0, 0, 0, 128, 0, 0, 0, 0},
- { 0, 2, -9, 122, 17, -6, 2, 0},
- { -1, 4, -15, 111, 37, -11, 3, 0},
- { -1, 5, -18, 96, 58, -15, 4, -1},
- { -1, 5, -18, 78, 78, -18, 5, -1},
- { -1, 4, -15, 58, 96, -18, 5, -1},
- { 0, 3, -11, 37, 111, -15, 4, -1},
- { 0, 2, -6, 17, 122, -9, 2, 0},
#endif /* FILTER_ALPHA */
#endif /* SUBPEL_SHIFTS==16 */
};
DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_8s[SUBPEL_SHIFTS][2 * INTERP_EXTEND]) = {
#if SUBPEL_SHIFTS==16
-#if FILTER_ALPHA_SHARP == 65
+#if FILTER_ALPHA_SHARP == 1
+ /* dct based filter */
+ {0, 0, 0, 128, 0, 0, 0, 0},
+ {-1, 3, -7, 127, 8, -3, 1, 0},
+ {-2, 5, -13, 125, 17, -6, 3, -1},
+ {-3, 7, -17, 121, 27, -10, 5, -2},
+ {-4, 9, -20, 115, 37, -13, 6, -2},
+ {-4, 10, -23, 108, 48, -16, 8, -3},
+ {-4, 10, -24, 100, 59, -19, 9, -3},
+ {-4, 11, -24, 90, 70, -21, 10, -4},
+ {-4, 11, -23, 80, 80, -23, 11, -4},
+ {-4, 10, -21, 70, 90, -24, 11, -4},
+ {-3, 9, -19, 59, 100, -24, 10, -4},
+ {-3, 8, -16, 48, 108, -23, 10, -4},
+ {-2, 6, -13, 37, 115, -20, 9, -4},
+ {-2, 5, -10, 27, 121, -17, 7, -3},
+ {-1, 3, -6, 17, 125, -13, 5, -2},
+ {0, 1, -3, 8, 127, -7, 3, -1}
+#elif FILTER_ALPHA_SHARP == 75
+ {0, 0, 0, 128, 0, 0, 0, 0},
+ {-1, 2, -6, 126, 9, -3, 2, -1},
+ {-1, 4, -11, 123, 18, -7, 3, -1},
+ {-2, 6, -16, 119, 28, -10, 5, -2},
+ {-2, 7, -19, 113, 38, -13, 6, -2},
+ {-3, 8, -21, 106, 49, -16, 7, -2},
+ {-3, 9, -22, 99, 59, -19, 8, -3},
+ {-3, 9, -23, 90, 70, -21, 9, -3},
+ {-3, 9, -22, 80, 80, -22, 9, -3},
+ {-3, 9, -21, 70, 90, -23, 9, -3},
+ {-3, 8, -19, 59, 99, -22, 9, -3},
+ {-2, 7, -16, 49, 106, -21, 8, -3},
+ {-2, 6, -13, 38, 113, -19, 7, -2},
+ {-2, 5, -10, 28, 119, -16, 6, -2},
+ {-1, 3, -7, 18, 123, -11, 4, -1},
+ {-1, 2, -3, 9, 126, -6, 2, -1}
+#elif FILTER_ALPHA_SHARP == 65
/* alpha = 0.65 */
{ 0, 0, 0, 128, 0, 0, 0, 0},
{ 0, 2, -6, 126, 8, -3, 1, 0},
@@ -164,45 +171,27 @@ DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_8s[SUBPEL_SHIFTS][2 * INTER
{ -1, 4, -10, 27, 118, -14, 5, -1},
{ -1, 2, -6, 18, 123, -10, 3, -1},
{ 0, 1, -3, 8, 126, -6, 2, 0}
-#elif FILTER_ALPHA_SHARP == 60
- /* alpha = 0.60 */
- { 0, 0, 0, 128, 0, 0, 0, 0},
- { 0, 2, -6, 126, 8, -3, 1, 0},
- { -1, 3, -10, 123, 18, -6, 2, -1},
- { -1, 4, -14, 118, 28, -9, 3, -1},
- { -1, 5, -17, 112, 38, -12, 4, -1},
- { -1, 6, -19, 105, 48, -15, 5, -1},
- { -1, 6, -20, 97, 58, -17, 6, -1},
- { -1, 6, -20, 88, 69, -19, 6, -1},
- { -1, 6, -20, 79, 79, -20, 6, -1},
- { -1, 6, -19, 69, 88, -20, 6, -1},
- { -1, 6, -17, 58, 97, -20, 6, -1},
- { -1, 5, -15, 48, 105, -19, 6, -1},
- { -1, 4, -12, 38, 112, -17, 5, -1},
- { -1, 3, -9, 28, 118, -14, 4, -1},
- { -1, 2, -6, 18, 123, -10, 3, -1},
- { 0, 1, -3, 8, 126, -6, 2, 0}
-#elif FILTER_ALPHA_SHARP == 55
- /* alpha = 0.55 */
- { 0, 0, 0, 128, 0, 0, 0, 0},
- { 0, 1, -5, 126, 8, -3, 1, 0},
- { -1, 2, -10, 123, 18, -6, 2, 0},
- { -1, 4, -13, 118, 27, -9, 3, -1},
- { -1, 5, -16, 112, 37, -12, 4, -1},
- { -1, 5, -18, 105, 48, -14, 4, -1},
- { -1, 5, -19, 97, 58, -16, 5, -1},
- { -1, 6, -19, 88, 68, -18, 5, -1},
- { -1, 6, -19, 78, 78, -19, 6, -1},
- { -1, 5, -18, 68, 88, -19, 6, -1},
- { -1, 5, -16, 58, 97, -19, 5, -1},
- { -1, 4, -14, 48, 105, -18, 5, -1},
- { -1, 4, -12, 37, 112, -16, 5, -1},
- { -1, 3, -9, 27, 118, -13, 4, -1},
- { 0, 2, -6, 18, 123, -10, 2, -1},
- { 0, 1, -3, 8, 126, -5, 1, 0}
#endif /* FILTER_ALPHA_SHARP */
#else /* SUBPEL_SHIFTS==16 */
-#if FILTER_ALPHA_SHARP == 65
+#if FILTER_ALPHA_SHARP == 1
+ {0, 0, 0, 128, 0, 0, 0, 0},
+ {-2, 5, -13, 125, 17, -6, 3, -1},
+ {-4, 9, -20, 115, 37, -13, 6, -2},
+ {-4, 10, -24, 100, 59, -19, 9, -3},
+ {-4, 10, -23, 81, 81, -23, 10, -4},
+ {-3, 9, -19, 59, 100, -24, 10, -4},
+ {-2, 6, -13, 37, 115, -20, 9, -4},
+ {-1, 3, -6, 17, 125, -13, 5, -2}
+#elif FILTER_ALPHA_SHARP == 75
+ {0, 0, 0, 128, 0, 0, 0, 0},
+ {-1, 4, -11, 123, 18, -7, 3, -1},
+ {-2, 7, -19, 113, 38, -13, 6, -2},
+ {-3, 9, -22, 99, 59, -19, 8, -3},
+ {-3, 9, -22, 80, 80, -22, 9, -3},
+ {-3, 8, -19, 59, 99, -22, 9, -3},
+ {-2, 6, -13, 38, 113, -19, 7, -2},
+ {-1, 3, -7, 18, 123, -11, 4, -1}
+#elif FILTER_ALPHA_SHARP == 65
/* alpha = 0.65 */
{ 0, 0, 0, 128, 0, 0, 0, 0},
{ -1, 3, -10, 123, 18, -6, 2, -1},
@@ -212,26 +201,6 @@ DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_8s[SUBPEL_SHIFTS][2 * INTER
{ -2, 6, -17, 59, 98, -21, 7, -2},
{ -1, 5, -13, 38, 112, -17, 5, -1},
{ -1, 2, -6, 18, 123, -10, 3, -1}
-#elif FILTER_ALPHA_SHARP == 60
- /* alpha = 0.60 */
- { 0, 0, 0, 128, 0, 0, 0, 0},
- { -1, 3, -10, 123, 18, -6, 2, -1},
- { -1, 5, -17, 112, 38, -12, 4, -1},
- { -1, 6, -20, 97, 58, -17, 6, -1},
- { -1, 6, -20, 79, 79, -20, 6, -1},
- { -1, 6, -17, 58, 97, -20, 6, -1},
- { -1, 4, -12, 38, 112, -17, 5, -1},
- { -1, 2, -6, 18, 123, -10, 3, -1}
-#elif FILTER_ALPHA_SHARP == 55
- /* alpha = 0.55 */
- { 0, 0, 0, 128, 0, 0, 0, 0},
- { -1, 2, -10, 123, 18, -6, 2, 0},
- { -1, 5, -16, 112, 37, -12, 4, -1},
- { -1, 5, -19, 97, 58, -16, 5, -1},
- { -1, 6, -19, 78, 78, -19, 6, -1},
- { -1, 5, -16, 58, 97, -19, 5, -1},
- { -1, 4, -12, 37, 112, -16, 5, -1},
- { 0, 2, -6, 18, 123, -10, 2, -1}
#endif /* FILTER_ALPHA_SHARP */
#endif /* SUBPEL_SHIFTS==16 */
};
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index 8f2417f66..ccecc4963 100644
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -17,6 +17,7 @@
#include "loopfilter.h"
#include "entropymv.h"
#include "entropy.h"
+#include "entropymode.h"
#include "idct.h"
#include "recon.h"
#if CONFIG_POSTPROC
@@ -82,6 +83,11 @@ typedef struct frame_contexts {
#if CONFIG_HIGH_PRECISION_MV
unsigned int MVcount_hp [2] [MVvals_hp];
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ vp8_prob switchable_interp_prob[VP8_SWITCHABLE_FILTERS+1]
+ [VP8_SWITCHABLE_FILTERS-1];
+#endif
+
int mode_context[6][4];
int mode_context_a[6][4];
int vp8_mode_contexts[6][4];
@@ -95,15 +101,6 @@ typedef enum {
} CLAMP_TYPE;
typedef enum {
- SIXTAP = 0,
- BILINEAR = 1,
-#if CONFIG_ENHANCED_INTERP
- EIGHTTAP = 2,
- EIGHTTAP_SHARP = 3,
-#endif
-} INTERPOLATIONFILTERTYPE;
-
-typedef enum {
SINGLE_PREDICTION_ONLY = 0,
COMP_PREDICTION_ONLY = 1,
HYBRID_PREDICTION = 2,
diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c
index 2d46496f1..b7d52a54f 100644
--- a/vp8/common/pred_common.c
+++ b/vp8/common/pred_common.c
@@ -62,6 +62,38 @@ unsigned char get_pred_context(VP8_COMMON *const cm,
(m - cm->mode_info_stride)->mbmi.mb_skip_coeff;
break;
+#if CONFIG_SWITCHABLE_INTERP
+ case PRED_SWITCHABLE_INTERP:
+ {
+ int left_in_image = (m - 1)->mbmi.mb_in_image;
+ int above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image;
+ int left_mode = (m - 1)->mbmi.mode;
+ int above_mode = (m - cm->mode_info_stride)->mbmi.mode;
+ int left_interp, above_interp;
+ if (left_in_image && left_mode >= NEARESTMV && left_mode <= SPLITMV)
+ left_interp = vp8_switchable_interp_map[(m - 1)->mbmi.interp_filter];
+ else
+ left_interp = VP8_SWITCHABLE_FILTERS;
+ if (above_in_image && above_mode >= NEARESTMV && above_mode <= SPLITMV)
+ above_interp = vp8_switchable_interp_map[
+ (m - cm->mode_info_stride)->mbmi.interp_filter];
+ else
+ above_interp = VP8_SWITCHABLE_FILTERS;
+
+ if (left_interp == above_interp)
+ pred_context = left_interp;
+ else if (left_interp == VP8_SWITCHABLE_FILTERS &&
+ above_interp != VP8_SWITCHABLE_FILTERS)
+ pred_context = above_interp;
+ else if (left_interp != VP8_SWITCHABLE_FILTERS &&
+ above_interp == VP8_SWITCHABLE_FILTERS)
+ pred_context = left_interp;
+ else
+ pred_context = VP8_SWITCHABLE_FILTERS;
+ }
+ break;
+#endif
+
default:
// TODO *** add error trap code.
pred_context = 0;
@@ -111,6 +143,53 @@ vp8_prob get_pred_prob(VP8_COMMON *const cm,
return pred_probability;
}
+// This function returns a context probability ptr for coding a given
+// prediction signal
+vp8_prob *get_pred_probs(VP8_COMMON *const cm,
+ MACROBLOCKD *const xd,
+ PRED_ID pred_id) {
+ vp8_prob *pred_probability;
+ int pred_context;
+
+ // Get the appropriate prediction context
+ pred_context = get_pred_context(cm, xd, pred_id);
+
+ switch (pred_id) {
+ case PRED_SEG_ID:
+ pred_probability = &cm->segment_pred_probs[pred_context];
+ break;
+
+ case PRED_REF:
+ pred_probability = &cm->ref_pred_probs[pred_context];
+ break;
+
+ case PRED_COMP:
+ // In keeping with convention elsewhre the probability returned is
+ // the probability of a "0" outcome which in this case means the
+ // probability of comp pred off.
+ pred_probability = &cm->prob_comppred[pred_context];
+ break;
+
+#if CONFIG_NEWENTROPY
+ case PRED_MBSKIP:
+ pred_probability = &cm->mbskip_pred_probs[pred_context];
+ break;
+#endif
+
+#if CONFIG_SWITCHABLE_INTERP
+ case PRED_SWITCHABLE_INTERP:
+ pred_probability = &cm->fc.switchable_interp_prob[pred_context][0];
+ break;
+#endif
+ default:
+ // TODO *** add error trap code.
+ pred_probability = NULL;
+ break;
+ }
+
+ return pred_probability;
+}
+
// This function returns the status of the given prediction signal.
// I.e. is the predicted value for the given signal correct.
unsigned char get_pred_flag(MACROBLOCKD *const xd,
diff --git a/vp8/common/pred_common.h b/vp8/common/pred_common.h
index a1b019fc6..f4992f555 100644
--- a/vp8/common/pred_common.h
+++ b/vp8/common/pred_common.h
@@ -22,6 +22,9 @@ typedef enum {
PRED_REF = 1,
PRED_COMP = 2,
PRED_MBSKIP = 3,
+#if CONFIG_SWITCHABLE_INTERP
+ PRED_SWITCHABLE_INTERP = 4,
+#endif
} PRED_ID;
@@ -33,6 +36,10 @@ extern vp8_prob get_pred_prob(VP8_COMMON *const cm,
MACROBLOCKD *const xd,
PRED_ID pred_id);
+extern vp8_prob *get_pred_probs(VP8_COMMON *const cm,
+ MACROBLOCKD *const xd,
+ PRED_ID pred_id);
+
extern unsigned char get_pred_flag(MACROBLOCKD *const xd,
PRED_ID pred_id);
diff --git a/vp8/common/reconinter.c b/vp8/common/reconinter.c
index d94ab4449..6f7d963c6 100644
--- a/vp8/common/reconinter.c
+++ b/vp8/common/reconinter.c
@@ -19,6 +19,81 @@
#include "onyxc_int.h"
#endif
+void vp8_setup_interp_filters(MACROBLOCKD *xd,
+ INTERPOLATIONFILTERTYPE mcomp_filter_type,
+ VP8_COMMON *cm) {
+ if (mcomp_filter_type == SIXTAP) {
+ xd->subpixel_predict = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, sixtap4x4);
+ xd->subpixel_predict8x4 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, sixtap8x4);
+ xd->subpixel_predict8x8 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, sixtap8x8);
+ xd->subpixel_predict16x16 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, sixtap16x16);
+ xd->subpixel_predict_avg = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, sixtap_avg4x4);
+ xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, sixtap_avg8x8);
+ xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, sixtap_avg16x16);
+ }
+#if CONFIG_ENHANCED_INTERP
+ else if (mcomp_filter_type == EIGHTTAP
+#if CONFIG_SWITCHABLE_INTERP
+ ||
+ mcomp_filter_type == SWITCHABLE
+#endif
+ ) {
+ xd->subpixel_predict = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap4x4);
+ xd->subpixel_predict8x4 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap8x4);
+ xd->subpixel_predict8x8 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap8x8);
+ xd->subpixel_predict16x16 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap16x16);
+ xd->subpixel_predict_avg = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap_avg4x4);
+ xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap_avg8x8);
+ xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap_avg16x16);
+ } else if (mcomp_filter_type == EIGHTTAP_SHARP) {
+ xd->subpixel_predict = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap4x4_sharp);
+ xd->subpixel_predict8x4 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap8x4_sharp);
+ xd->subpixel_predict8x8 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap8x8_sharp);
+ xd->subpixel_predict16x16 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap16x16_sharp);
+ xd->subpixel_predict_avg = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap_avg4x4_sharp);
+ xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap_avg8x8_sharp);
+ xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, eighttap_avg16x16_sharp);
+ }
+#endif
+ else {
+ xd->subpixel_predict = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, bilinear4x4);
+ xd->subpixel_predict8x4 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, bilinear8x4);
+ xd->subpixel_predict8x8 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, bilinear8x8);
+ xd->subpixel_predict16x16 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, bilinear16x16);
+ xd->subpixel_predict_avg = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, bilinear_avg4x4);
+ xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, bilinear_avg8x8);
+ xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
+ &cm->rtcd.subpix, bilinear_avg16x16);
+ }
+}
+
void vp8_copy_mem16x16_c(
unsigned char *src,
int src_stride,
diff --git a/vp8/common/reconinter.h b/vp8/common/reconinter.h
index 0f8b44f22..7755c526e 100644
--- a/vp8/common/reconinter.h
+++ b/vp8/common/reconinter.h
@@ -12,6 +12,10 @@
#ifndef __INC_RECONINTER_H
#define __INC_RECONINTER_H
+#if CONFIG_RUNTIME_CPU_DETECT
+#include "onyxc_int.h"
+#endif
+
extern void vp8_build_inter_predictors_mb(MACROBLOCKD *x);
extern void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x,
unsigned char *dst_y,
@@ -33,5 +37,6 @@ extern void vp8_build_2nd_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn
extern void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x);
extern void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD *x);
+extern void vp8_setup_interp_filters(MACROBLOCKD *x, INTERPOLATIONFILTERTYPE filter, VP8_COMMON *cm);
#endif
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 4b4ad919e..3cfdbac0b 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -427,7 +427,21 @@ static const unsigned char mbsplit_fill_offset[4][16] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
};
-
+#if CONFIG_SWITCHABLE_INTERP
+static void read_switchable_interp_probs(VP8D_COMP *pbi) {
+ VP8_COMMON *const cm = & pbi->common;
+ vp8_reader *const bc = & pbi->bc;
+ int i, j;
+ for (j = 0; j <= VP8_SWITCHABLE_FILTERS; ++j) {
+ //for (j = 0; j <= 0; ++j) {
+ for (i = 0; i < VP8_SWITCHABLE_FILTERS - 1; ++i) {
+ cm->fc.switchable_interp_prob[j][i] = vp8_read_literal(bc, 8);
+ }
+ }
+ //printf("DECODER: %d %d\n", cm->fc.switchable_interp_prob[0],
+ //cm->fc.switchable_interp_prob[1]);
+}
+#endif
static void mb_mode_mv_init(VP8D_COMP *pbi) {
VP8_COMMON *const cm = & pbi->common;
@@ -452,6 +466,10 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) {
if (cm->pred_filter_mode == 2)
cm->prob_pred_filter_off = (vp8_prob)vp8_read_literal(bc, 8);
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ if (cm->mcomp_filter_type == SWITCHABLE)
+ read_switchable_interp_probs(pbi);
+#endif
// Decode the baseline probabilities for decoding reference frame
cm->prob_intra_coded = (vp8_prob)vp8_read_literal(bc, 8);
cm->prob_last_coded = (vp8_prob)vp8_read_literal(bc, 8);
@@ -634,6 +652,19 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mbmi->pred_filter_enabled = cm->pred_filter_mode;
}
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ if (mbmi->mode >= NEARESTMV && mbmi->mode <= SPLITMV)
+ {
+ if (cm->mcomp_filter_type == SWITCHABLE) {
+ mbmi->interp_filter = vp8_switchable_interp[
+ vp8_treed_read(bc, vp8_switchable_interp_tree,
+ get_pred_probs(cm, xd, PRED_SWITCHABLE_INTERP))];
+ //printf("Reading: %d\n", mbmi->interp_filter);
+ } else {
+ mbmi->interp_filter = cm->mcomp_filter_type;
+ }
+ }
+#endif
if (cm->comp_pred_mode == COMP_PREDICTION_ONLY ||
(cm->comp_pred_mode == HYBRID_PREDICTION &&
@@ -928,8 +959,8 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
#endif
}
} else {
- mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc,
- pbi->common.fc.uv_mode_prob[mbmi->mode]);
+ mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(
+ bc, pbi->common.fc.uv_mode_prob[mbmi->mode]);
pbi->common.fc.uv_mode_counts[mbmi->mode][mbmi->uv_mode]++;
}
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index 8cd35143a..c31595d59 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -261,6 +261,11 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
}
mode = xd->mode_info_context->mbmi.mode;
+#if CONFIG_SWITCHABLE_INTERP
+ if (pbi->common.frame_type != KEY_FRAME)
+ vp8_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter,
+ &pbi->common);
+#endif
if (eobtotal == 0 && mode != B_PRED && mode != SPLITMV
&& mode != I8X8_PRED
@@ -750,47 +755,7 @@ static void init_frame(VP8D_COMP *pbi) {
pc->mcomp_filter_type = BILINEAR;
/* To enable choice of different interploation filters */
- if (pc->mcomp_filter_type == SIXTAP) {
- xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg4x4);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg16x16);
- }
-#if CONFIG_ENHANCED_INTERP
- else if (pc->mcomp_filter_type == EIGHTTAP) {
- xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap16x16);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
- RTCD_VTABLE(subpix), eighttap_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
- RTCD_VTABLE(subpix), eighttap_avg16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg4x4);
- } else if (pc->mcomp_filter_type == EIGHTTAP_SHARP) {
- xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap4x4_sharp);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x4_sharp);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x8_sharp);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap16x16_sharp);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg4x4_sharp);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
- RTCD_VTABLE(subpix), eighttap_avg8x8_sharp);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
- RTCD_VTABLE(subpix), eighttap_avg16x16_sharp);
- }
-#endif
- else {
- xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg4x4);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg16x16);
- }
+ vp8_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
}
xd->left_context = &pc->left_context;
@@ -1263,41 +1228,16 @@ int vp8_decode_frame(VP8D_COMP *pbi) {
#endif
#if CONFIG_ENHANCED_INTERP
// Read the type of subpel filter to use
- pc->mcomp_filter_type = vp8_read_literal(bc, 2);
- /* To enable choice of different interploation filters */
- if (pc->mcomp_filter_type == SIXTAP) {
- xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg4x4);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg16x16);
- } else if (pc->mcomp_filter_type == EIGHTTAP) {
- xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg4x4);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg16x16);
- } else if (pc->mcomp_filter_type == EIGHTTAP_SHARP) {
- xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap4x4_sharp);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x4_sharp);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x8_sharp);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap16x16_sharp);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg4x4_sharp);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg8x8_sharp);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg16x16_sharp);
- } else {
- xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg4x4);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg16x16);
+#if CONFIG_SWITCHABLE_INTERP
+ if (vp8_read_bit(bc)) {
+ pc->mcomp_filter_type = SWITCHABLE;
+ } else
+#endif
+ {
+ pc->mcomp_filter_type = vp8_read_literal(bc, 2);
}
+ /* To enable choice of different interploation filters */
+ vp8_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
#endif
}
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index db3e30982..97e791bc6 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -33,17 +33,15 @@ unsigned __int64 Sectionbits[500];
#endif
#ifdef ENTROPY_STATS
-int intra_mode_stats[VP8_BINTRAMODES]
-[VP8_BINTRAMODES]
-[VP8_BINTRAMODES];
+int intra_mode_stats [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES];
unsigned int tree_update_hist [BLOCK_TYPES]
-[COEF_BANDS]
-[PREV_COEF_CONTEXTS]
-[ENTROPY_NODES][2];
+ [COEF_BANDS]
+ [PREV_COEF_CONTEXTS]
+ [ENTROPY_NODES][2];
unsigned int tree_update_hist_8x8 [BLOCK_TYPES_8X8]
-[COEF_BANDS]
-[PREV_COEF_CONTEXTS]
-[ENTROPY_NODES] [2];
+ [COEF_BANDS]
+ [PREV_COEF_CONTEXTS]
+ [ENTROPY_NODES] [2];
extern unsigned int active_section;
#endif
@@ -173,6 +171,59 @@ void update_skip_probs(VP8_COMP *cpi) {
}
}
+#if CONFIG_SWITCHABLE_INTERP
+void update_switchable_interp_probs(VP8_COMP *cpi) {
+ VP8_COMMON *const pc = & cpi->common;
+ vp8_writer *const w = & cpi->bc;
+ unsigned int branch_ct[32][2];
+ int i, j;
+ for (j = 0; j <= VP8_SWITCHABLE_FILTERS; ++j) {
+ //for (j = 0; j <= 0; ++j) {
+/*
+ if (!cpi->dummy_packing)
+#if VP8_SWITCHABLE_FILTERS == 3
+ printf("HELLO %d %d %d\n", cpi->switchable_interp_count[j][0],
+ cpi->switchable_interp_count[j][1], cpi->switchable_interp_count[j][2]);
+#else
+ printf("HELLO %d %d\n", cpi->switchable_interp_count[j][0],
+ cpi->switchable_interp_count[j][1]);
+#endif
+*/
+ vp8_tree_probs_from_distribution(
+ VP8_SWITCHABLE_FILTERS,
+ vp8_switchable_interp_encodings, vp8_switchable_interp_tree,
+ pc->fc.switchable_interp_prob[j], branch_ct, cpi->switchable_interp_count[j],
+ 256, 1
+ );
+ for (i = 0; i < VP8_SWITCHABLE_FILTERS - 1; ++i) {
+ if (pc->fc.switchable_interp_prob[j][i] < 1)
+ pc->fc.switchable_interp_prob[j][i] = 1;
+ vp8_write_literal(w, pc->fc.switchable_interp_prob[j][i], 8);
+/*
+ if (!cpi->dummy_packing)
+#if VP8_SWITCHABLE_FILTERS == 3
+ printf("Probs %d %d [%d]\n",
+ pc->fc.switchable_interp_prob[j][0],
+ pc->fc.switchable_interp_prob[j][1], pc->frame_type);
+#else
+ printf("Probs %d [%d]\n", pc->fc.switchable_interp_prob[j][0],
+ pc->frame_type);
+#endif
+*/
+ }
+ }
+ /*
+ if (!cpi->dummy_packing)
+#if VP8_SWITCHABLE_FILTERS == 3
+ printf("Probs %d %d [%d]\n",
+ pc->fc.switchable_interp_prob[0], pc->fc.switchable_interp_prob[1], pc->frame_type);
+#else
+ printf("Probs %d [%d]\n", pc->fc.switchable_interp_prob[0], pc->frame_type);
+#endif
+ */
+}
+#endif
+
// This function updates the reference frame prediction stats
static void update_refpred_stats(VP8_COMP *cpi) {
VP8_COMMON *const cm = & cpi->common;
@@ -710,6 +761,10 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) {
// printf("pred_filter_mode:%d prob_pred_filter_off:%d\n",
// pc->pred_filter_mode, pc->prob_pred_filter_off);
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ if (pc->mcomp_filter_type == SWITCHABLE)
+ update_switchable_interp_probs(cpi);
+#endif
vp8_write_literal(w, pc->prob_intra_coded, 8);
vp8_write_literal(w, pc->prob_last_coded, 8);
@@ -907,6 +962,21 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) {
cpi->common.pred_filter_mode);
}
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ if (mode >= NEARESTMV && mode <= SPLITMV)
+ {
+ if (cpi->common.mcomp_filter_type == SWITCHABLE) {
+ vp8_write_token(w, vp8_switchable_interp_tree,
+ get_pred_probs(&cpi->common, xd, PRED_SWITCHABLE_INTERP),
+ vp8_switchable_interp_encodings +
+ vp8_switchable_interp_map[mi->interp_filter]);
+ //if (!cpi->dummy_packing) printf("Reading: %d\n", mi->interp_filter);
+ } else {
+ assert (mi->interp_filter ==
+ cpi->common.mcomp_filter_type);
+ }
+ }
+#endif
if (mi->second_ref_frame &&
(mode == NEWMV || mode == SPLITMV)) {
int_mv n1, n2;
@@ -2204,9 +2274,34 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
vp8_write_bit(bc, (xd->allow_high_precision_mv) ? 1 : 0);
#endif
#if CONFIG_ENHANCED_INTERP
+#if CONFIG_SWITCHABLE_INTERP
+ if (pc->mcomp_filter_type == SWITCHABLE) {
+ /* Check to see if only one of the filters is actually used */
+ int count[VP8_SWITCHABLE_FILTERS];
+ int i, j, c = 0;
+ for (i = 0; i < VP8_SWITCHABLE_FILTERS; ++i) {
+ count[i] = 0;
+ for (j = 0; j <= VP8_SWITCHABLE_FILTERS; ++j) {
+ count[i] += cpi->switchable_interp_count[j][i];
+ }
+ c += (count[i] > 0);
+ }
+ if (c == 1) {
+ /* Only one filter is used. So set the filter at frame level */
+ for (i = 0; i < VP8_SWITCHABLE_FILTERS; ++i) {
+ if (count[i]) {
+ pc->mcomp_filter_type = vp8_switchable_interp[i];
+ break;
+ }
+ }
+ }
+ }
// Signal the type of subpel filter to use
- vp8_write_literal(bc, (pc->mcomp_filter_type), 2);
-#endif
+ vp8_write_bit(bc, (pc->mcomp_filter_type == SWITCHABLE));
+ if (pc->mcomp_filter_type != SWITCHABLE)
+#endif /* CONFIG_SWITCHABLE_INTERP */
+ vp8_write_literal(bc, (pc->mcomp_filter_type), 2);
+#endif /* CONFIG_ENHANCED_INTERP */
}
vp8_write_bit(bc, pc->refresh_entropy_probs);
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
index 766e80776..b69ffa94e 100644
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -13,10 +13,10 @@
#define __INC_BLOCK_H
#include "vp8/common/onyx.h"
-#include "vp8/common/blockd.h"
#include "vp8/common/entropymv.h"
#include "vp8/common/entropy.h"
#include "vpx_ports/mem.h"
+#include "vp8/common/onyxc_int.h"
// motion search site
typedef struct {
@@ -122,6 +122,10 @@ typedef struct {
int bmode_costs[VP8_BINTRAMODES][VP8_BINTRAMODES][VP8_BINTRAMODES];
int i8x8_mode_costs[MB_MODE_COUNT];
int inter_bmode_costs[B_MODE_COUNT];
+#if CONFIG_SWITCHABLE_INTERP
+ int switchable_interp_costs[VP8_SWITCHABLE_FILTERS+1]
+ [VP8_SWITCHABLE_FILTERS];
+#endif
// These define limits to motion vector components to prevent them from extending outside the UMV borders
int mv_col_min;
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 737348ace..909d56961 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -69,7 +69,6 @@ void vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x,
static void adjust_act_zbin(VP8_COMP *cpi, MACROBLOCK *x);
-
#ifdef MODE_STATS
unsigned int inter_y_modes[MB_MODE_COUNT];
unsigned int inter_uv_modes[VP8_UV_MODES];
@@ -1094,71 +1093,7 @@ static void encode_frame_internal(VP8_COMP *cpi) {
totalrate = 0;
// Functions setup for all frame types so we can use MC in AltRef
- if (cm->mcomp_filter_type == SIXTAP) {
- xd->subpixel_predict = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, sixtap4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, sixtap8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, sixtap8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, sixtap16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, sixtap_avg4x4);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, sixtap_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, sixtap_avg16x16);
- }
-#if CONFIG_ENHANCED_INTERP
- else if (cm->mcomp_filter_type == EIGHTTAP) {
- xd->subpixel_predict = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap_avg4x4);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap_avg16x16);
- } else if (cm->mcomp_filter_type == EIGHTTAP_SHARP) {
- xd->subpixel_predict = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap4x4_sharp);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap8x4_sharp);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap8x8_sharp);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap16x16_sharp);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap_avg4x4_sharp);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap_avg8x8_sharp);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, eighttap_avg16x16_sharp);
- }
-#endif
- else {
- xd->subpixel_predict = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, bilinear4x4);
- xd->subpixel_predict8x4 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, bilinear8x4);
- xd->subpixel_predict8x8 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, bilinear8x8);
- xd->subpixel_predict16x16 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, bilinear16x16);
- xd->subpixel_predict_avg = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, bilinear_avg4x4);
- xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, bilinear_avg8x8);
- xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
- &cpi->common.rtcd.subpix, bilinear_avg16x16);
- }
+ vp8_setup_interp_filters(xd, cm->mcomp_filter_type, cm);
// Reset frame count of inter 0,0 motion vector usage.
cpi->inter_zz_count = 0;
@@ -1177,7 +1112,9 @@ static void encode_frame_internal(VP8_COMP *cpi) {
}
cpi->pred_filter_on_count = 0;
cpi->pred_filter_off_count = 0;
-
+#endif
+#if CONFIG_SWITCHABLE_INTERP
+ vp8_zero(cpi->switchable_interp_count);
#endif
#if 0
@@ -1547,6 +1484,9 @@ void vp8cx_encode_inter_macroblock
x->skip = 0;
+#if CONFIG_SWITCHABLE_INTERP
+ vp8_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter, cm);
+#endif
if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
// Adjust the zbin based on this MB rate.
adjust_act_zbin(cpi, x);
diff --git a/vp8/encoder/modecosts.c b/vp8/encoder/modecosts.c
index 8752eead7..b1abd1e2a 100644
--- a/vp8/encoder/modecosts.c
+++ b/vp8/encoder/modecosts.c
@@ -46,4 +46,14 @@ void vp8_init_mode_costs(VP8_COMP *c) {
vp8_cost_tokens(c->mb.i8x8_mode_costs,
x->fc.i8x8_mode_prob, vp8_i8x8_mode_tree);
+#if CONFIG_SWITCHABLE_INTERP
+ {
+ int i;
+ for (i = 0; i <= VP8_SWITCHABLE_FILTERS; ++i)
+ //for (i = 0; i <= 0; ++i)
+ vp8_cost_tokens((int *)c->mb.switchable_interp_costs[i],
+ x->fc.switchable_interp_prob[i],
+ vp8_switchable_interp_tree);
+ }
+#endif
}
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 05fe0ff75..5b6684ac8 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -82,16 +82,16 @@ static void set_default_lf_deltas(VP8_COMP *cpi);
extern const int vp8_gf_interval_table[101];
#if CONFIG_ENHANCED_INTERP
-#define SEARCH_BEST_FILTER 0 /* to search exhaustively for best filter */
+#define SEARCH_BEST_FILTER 0 /* to search for best filter */
#define RESET_FOREACH_FILTER 0 /* whether to reset the encoder state
-before trying each new filter */
+ * before trying each new filter */
+#define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */
#endif
#if CONFIG_HIGH_PRECISION_MV
#define ALTREF_HIGH_PRECISION_MV 1 /* whether to use high precision mv for altref computation */
-#define HIGH_PRECISION_MV_QTHRESH 200 /* Q threshold for use of high precision mv */
-/* Choose a very high value for now so
- * that HIGH_PRECISION is always chosen
- */
+#define HIGH_PRECISION_MV_QTHRESH 200 /* Q threshold for use of high precision mv
+ * Choose a very high value for now so
+ * that HIGH_PRECISION is always chosen */
#endif
#if CONFIG_INTERNAL_STATS
@@ -207,6 +207,7 @@ int calculate_minq_index(double maxq,
}
return QINDEX_RANGE - 1;
}
+
void init_minq_luts() {
int i;
double maxq;
@@ -706,6 +707,14 @@ void vp8_set_speed_features(VP8_COMP *cpi) {
sf->thresh_mult[THR_V_PRED ] = 1000;
sf->thresh_mult[THR_H_PRED ] = 1000;
+#if CONFIG_NEWINTRAMODES
+ sf->thresh_mult[THR_D45_PRED ] = 1000;
+ sf->thresh_mult[THR_D135_PRED] = 1000;
+ sf->thresh_mult[THR_D117_PRED] = 1000;
+ sf->thresh_mult[THR_D153_PRED] = 1000;
+ sf->thresh_mult[THR_D27_PRED ] = 1000;
+ sf->thresh_mult[THR_D63_PRED ] = 1000;
+#endif
sf->thresh_mult[THR_B_PRED ] = 2000;
sf->thresh_mult[THR_I8X8_PRED] = 2000;
sf->thresh_mult[THR_TM ] = 1000;
@@ -2902,7 +2911,13 @@ static void encode_frame_to_data_rate
#endif
/* list of filters to search over */
- int mcomp_filters_to_search[] = {EIGHTTAP, EIGHTTAP_SHARP, SIXTAP};
+ int mcomp_filters_to_search[] = {
+#if CONFIG_SWITCHABLE_INTERP
+ EIGHTTAP, EIGHTTAP_SHARP, SIXTAP, SWITCHABLE
+#else
+ EIGHTTAP, EIGHTTAP_SHARP, SIXTAP,
+#endif
+ };
int mcomp_filters = sizeof(mcomp_filters_to_search) / sizeof(*mcomp_filters_to_search);
int mcomp_filter_index = 0;
INT64 mcomp_filter_cost[4];
@@ -3129,8 +3144,14 @@ static void encode_frame_to_data_rate
if (sf->search_best_filter) {
cm->mcomp_filter_type = mcomp_filters_to_search[0];
mcomp_filter_index = 0;
- } else
- cm->mcomp_filter_type = EIGHTTAP;
+ } else {
+#if CONFIG_SWITCHABLE_INTERP
+ cm->mcomp_filter_type = SWITCHABLE;
+#else
+ cm->mcomp_filter_type =
+ (Q < SHARP_FILTER_QTHRESH ? EIGHTTAP_SHARP : EIGHTTAP);
+#endif
+ }
#endif
#if CONFIG_HIGH_PRECISION_MV
/* TODO: Decide this more intelligently */
@@ -3434,7 +3455,9 @@ static void encode_frame_to_data_rate
Q = q_low;
// Clamp cpi->zbin_over_quant
- cpi->zbin_over_quant = (cpi->zbin_over_quant < zbin_oq_low) ? zbin_oq_low : (cpi->zbin_over_quant > zbin_oq_high) ? zbin_oq_high : cpi->zbin_over_quant;
+ cpi->zbin_over_quant = (cpi->zbin_over_quant < zbin_oq_low) ?
+ zbin_oq_low : (cpi->zbin_over_quant > zbin_oq_high) ?
+ zbin_oq_high : cpi->zbin_over_quant;
// Loop = ((Q != last_q) || (last_zbin_oq != cpi->zbin_over_quant)) ? TRUE : FALSE;
Loop = ((Q != last_q)) ? TRUE : FALSE;
@@ -3445,6 +3468,40 @@ static void encode_frame_to_data_rate
if (cpi->is_src_frame_alt_ref)
Loop = FALSE;
+#if CONFIG_ENHANCED_INTERP && CONFIG_SWITCHABLE_INTERP
+ if (cm->frame_type != KEY_FRAME &&
+ !sf->search_best_filter &&
+ cm->mcomp_filter_type == SWITCHABLE) {
+ int interp_factor = Q / 3; /* denominator is 256 */
+ int count[VP8_SWITCHABLE_FILTERS];
+ int tot_count = 0, c = 0, thr;
+ int i, j;
+ for (i = 0; i < VP8_SWITCHABLE_FILTERS; ++i) {
+ count[i] = 0;
+ for (j = 0; j <= VP8_SWITCHABLE_FILTERS; ++j) {
+ count[i] += cpi->switchable_interp_count[j][i];
+ }
+ tot_count += count[i];
+ }
+
+ thr = ((tot_count * interp_factor + 128) >> 8);
+ for (i = 0; i < VP8_SWITCHABLE_FILTERS; ++i) {
+ c += (count[i] >= thr);
+ }
+ if (c == 1) {
+ /* Mostly one filter is used. So set the filter at frame level */
+ for (i = 0; i < VP8_SWITCHABLE_FILTERS; ++i) {
+ if (count[i]) {
+ cm->mcomp_filter_type = vp8_switchable_interp[i];
+ Loop = TRUE; /* Make sure to loop since the filter changed */
+ //loop_count = -1;
+ break;
+ }
+ }
+ }
+ }
+#endif
+
#if CONFIG_ENHANCED_INTERP
if (Loop == FALSE && cm->frame_type != KEY_FRAME && sf->search_best_filter) {
if (mcomp_filter_index < mcomp_filters) {
@@ -3498,7 +3555,7 @@ static void encode_frame_to_data_rate
#endif
}
}
-#endif
+#endif /* CONFIG_ENHANCED_INTERP */
if (Loop == TRUE) {
loop_count++;
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index cf7193324..2821aadd0 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -102,6 +102,11 @@ typedef struct {
vp8_prob sub_mv_ref_prob [SUBMVREF_COUNT][VP8_SUBMVREFS - 1];
vp8_prob mbsplit_prob [VP8_NUMMBSPLITS - 1];
+#if CONFIG_SWITCHABLE_INTERP
+ vp8_prob switchable_interp_prob[VP8_SWITCHABLE_FILTERS + 1]
+ [VP8_SWITCHABLE_FILTERS - 1];
+#endif
+
int mv_ref_ct[6][4][2];
int mode_context[6][4];
int mv_ref_ct_a[6][4][2];
@@ -724,6 +729,10 @@ typedef struct VP8_COMP {
int pred_filter_on_count;
int pred_filter_off_count;
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ unsigned int switchable_interp_count[VP8_SWITCHABLE_FILTERS+1]
+ [VP8_SWITCHABLE_FILTERS];
+#endif
} VP8_COMP;
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index 9885f8742..43f38568a 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -174,6 +174,9 @@ void vp8_save_coding_context(VP8_COMP *cpi) {
vp8_copy(cc->coef_probs, cm->fc.coef_probs);
vp8_copy(cc->coef_probs_8x8, cm->fc.coef_probs_8x8);
+#if CONFIG_SWITCHABLE_INTERP
+ vp8_copy(cc->switchable_interp_prob, cm->fc.switchable_interp_prob);
+#endif
}
void vp8_restore_coding_context(VP8_COMP *cpi) {
@@ -227,6 +230,9 @@ void vp8_restore_coding_context(VP8_COMP *cpi) {
vp8_copy(cm->fc.coef_probs, cc->coef_probs);
vp8_copy(cm->fc.coef_probs_8x8, cc->coef_probs_8x8);
+#if CONFIG_SWITCHABLE_INTERP
+ vp8_copy(cm->fc.switchable_interp_prob, cc->switchable_interp_prob);
+#endif
}
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index cd45074b7..5fd92a5fa 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -64,6 +64,11 @@ extern void vp8_ht_quantize_b(BLOCK *b, BLOCKD *d);
#define INVALID_MV 0x80008000
+#if CONFIG_SWITCHABLE_INTERP
+/* Factor to weigh the rate for switchable interp filters */
+#define SWITCHABLE_INTERP_RATE_FACTOR 1
+#endif
+
static const int auto_speed_thresh[17] = {
1000,
200,
@@ -2682,6 +2687,9 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// int all_rates[MAX_MODES];
// int all_dist[MAX_MODES];
// int intermodecost[MAX_MODES];
+#if CONFIG_SWITCHABLE_INTERP
+ int switchable_filter_index = 0;
+#endif
MB_PREDICTION_MODE uv_intra_mode;
MB_PREDICTION_MODE uv_intra_mode_8x8 = 0;
@@ -2792,18 +2800,18 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// that depend on the current prediction etc.
vp8_estimate_ref_frame_costs(cpi, segment_id, ref_costs);
- for (mode_index = 0; mode_index < MAX_MODES; mode_index++) {
+#if CONFIG_SWITCHABLE_INTERP
+ for (mode_index = 0; mode_index < MAX_MODES;
+ mode_index += (!switchable_filter_index)) {
+#else
+ for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
+#endif
int this_rd = INT_MAX;
int disable_skip = 0;
int other_cost = 0;
int compmode_cost = 0;
int mode_excluded = 0;
- // Test best rd so far against threshold for trying this mode.
- if (best_rd <= cpi->rd_threshes[mode_index]) {
- continue;
- }
-
// These variables hold are rolling total cost and distortion for this mode
rate2 = 0;
distortion2 = 0;
@@ -2820,6 +2828,25 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
#if CONFIG_PRED_FILTER
xd->mode_info_context->mbmi.pred_filter_enabled = 0;
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ if (cpi->common.mcomp_filter_type == SWITCHABLE &&
+ this_mode >= NEARESTMV && this_mode <= SPLITMV) {
+ xd->mode_info_context->mbmi.interp_filter =
+ vp8_switchable_interp[switchable_filter_index++];
+ if (switchable_filter_index == VP8_SWITCHABLE_FILTERS)
+ switchable_filter_index = 0;
+ //printf("Searching %d (%d)\n", this_mode, switchable_filter_index);
+ } else {
+ xd->mode_info_context->mbmi.interp_filter = cpi->common.mcomp_filter_type;
+ }
+ vp8_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter,
+ &cpi->common);
+#endif
+
+ // Test best rd so far against threshold for trying this mode.
+ if (best_rd <= cpi->rd_threshes[mode_index]) {
+ continue;
+ }
// current coding mode under rate-distortion optimization test loop
#if CONFIG_HYBRIDTRANSFORM
@@ -2906,7 +2933,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
}
- if (!x->e_mbd.mode_info_context->mbmi.second_ref_frame)
+ if (!x->e_mbd.mode_info_context->mbmi.second_ref_frame) {
switch (this_mode) {
case B_PRED: {
int tmp_rd;
@@ -2934,7 +2961,8 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
case I8X8_PRED: {
int tmp_rd;
tmp_rd = rd_pick_intra8x8mby_modes(cpi,
- x, &rate, &rate_y, &distortion, best_yrd);
+ x, &rate, &rate_y, &distortion,
+ best_yrd);
rate2 += rate;
distortion2 += distortion;
@@ -2967,17 +2995,30 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
int tmp_rd;
int this_rd_thresh;
- this_rd_thresh = (x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME) ? cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
- this_rd_thresh = (x->e_mbd.mode_info_context->mbmi.ref_frame == GOLDEN_FRAME) ? cpi->rd_threshes[THR_NEWG] : this_rd_thresh;
+ this_rd_thresh =
+ (x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME) ?
+ cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
+ this_rd_thresh =
+ (x->e_mbd.mode_info_context->mbmi.ref_frame == GOLDEN_FRAME) ?
+ cpi->rd_threshes[THR_NEWG] : this_rd_thresh;
tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, NULL,
best_yrd, mdcounts,
- &rate, &rate_y, &distortion, this_rd_thresh, seg_mvs);
+ &rate, &rate_y, &distortion,
+ this_rd_thresh, seg_mvs);
rate2 += rate;
distortion2 += distortion;
- // If even the 'Y' rd value of split is higher than best so far then dont bother looking at UV
+#if CONFIG_SWITCHABLE_INTERP
+ if (cpi->common.mcomp_filter_type == SWITCHABLE)
+ rate2 += SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
+ [get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
+ [vp8_switchable_interp_map[
+ x->e_mbd.mode_info_context->mbmi.interp_filter]];
+#endif
+ // If even the 'Y' rd value of split is higher than best so far
+ // then dont bother looking at UV
if (tmp_rd < best_yrd) {
// Now work out UV cost and add it in
rd_inter4x4_uv(cpi, x, &rate_uv, &distortion_uv, cpi->common.full_pixel);
@@ -3174,7 +3215,8 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
vp8_clamp_mv2(&mode_mv[this_mode], xd);
// Do not bother proceeding if the vector (from newmv,nearest or near) is 0,0 as this should then be coded using the zeromv mode.
- if (((this_mode == NEARMV) || (this_mode == NEARESTMV)) && (mode_mv[this_mode].as_int == 0)) {
+ if (((this_mode == NEARMV) || (this_mode == NEARESTMV)) &&
+ (mode_mv[this_mode].as_int == 0)) {
continue;
}
@@ -3183,8 +3225,10 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// Trap vectors that reach beyond the UMV borders
// Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
// because of the lack of break statements in the previous two cases.
- if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
- ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
+ if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) ||
+ ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
+ ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) ||
+ ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
continue;
}
@@ -3197,6 +3241,13 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
rate2 += vp8_cost_bit(cpi->common.prob_pred_filter_off,
xd->mode_info_context->mbmi.pred_filter_enabled);
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ if (cpi->common.mcomp_filter_type == SWITCHABLE)
+ rate2 += SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
+ [get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
+ [vp8_switchable_interp_map[
+ x->e_mbd.mode_info_context->mbmi.interp_filter]];
+#endif
vp8_build_inter16x16_predictors_mby(&x->e_mbd);
@@ -3278,7 +3329,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
default:
break;
}
- else { /* x->e_mbd.mode_info_context->mbmi.second_ref_frame != 0 */
+ } else { /* x->e_mbd.mode_info_context->mbmi.second_ref_frame != 0 */
int ref1 = x->e_mbd.mode_info_context->mbmi.ref_frame;
int ref2 = x->e_mbd.mode_info_context->mbmi.second_ref_frame;
@@ -3330,12 +3381,18 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
int tmp_rd;
int this_rd_thresh;
- this_rd_thresh = (x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME) ? cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
- this_rd_thresh = (x->e_mbd.mode_info_context->mbmi.ref_frame == GOLDEN_FRAME) ? cpi->rd_threshes[THR_NEWG] : this_rd_thresh;
+ this_rd_thresh =
+ (x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME) ?
+ cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
+ this_rd_thresh =
+ (x->e_mbd.mode_info_context->mbmi.ref_frame == GOLDEN_FRAME) ?
+ cpi->rd_threshes[THR_NEWG] : this_rd_thresh;
- tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, &second_best_ref_mv,
+ tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv,
+ &second_best_ref_mv,
best_yrd, mdcounts,
- &rate, &rate_y, &distortion, this_rd_thresh, seg_mvs);
+ &rate, &rate_y, &distortion,
+ this_rd_thresh, seg_mvs);
rate2 += rate;
distortion2 += distortion;
@@ -3488,6 +3545,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
}
+#if 0//CONFIG_SWITCHABLE_INTERP
+ if (this_mode >= NEARESTMV && this_mode <= SPLITMV &&
+ cm->mcomp_filter_type == SWITCHABLE)
+ printf("mode %d (%d): %d\n", this_mode, switchable_filter_index, this_rd);
+#endif
+
// Experimental debug code.
// all_rds[mode_index] = this_rd;
// all_rates[mode_index] = rate2;
@@ -3560,11 +3623,17 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
}
}
- // Testing this mode gave rise to an improvement in best error score. Lower threshold a bit for next time
- cpi->rd_thresh_mult[mode_index] = (cpi->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2)) ? cpi->rd_thresh_mult[mode_index] - 2 : MIN_THRESHMULT;
- cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
+ // Testing this mode gave rise to an improvement in best error score.
+ // Lower threshold a bit for next time
+ cpi->rd_thresh_mult[mode_index] =
+ (cpi->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2)) ?
+ cpi->rd_thresh_mult[mode_index] - 2 : MIN_THRESHMULT;
+ cpi->rd_threshes[mode_index] =
+ (cpi->rd_baseline_thresh[mode_index] >> 7) *
+ cpi->rd_thresh_mult[mode_index];
}
- // If the mode did not help improve the best error case then raise the threshold for testing that mode next time around.
+ // If the mode did not help improve the best error case then raise the
+ // threshold for testing that mode next time around.
else {
cpi->rd_thresh_mult[mode_index] += 4;
@@ -3617,13 +3686,29 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
else
++cpi->pred_filter_off_count;
#endif
+#if CONFIG_SWITCHABLE_INTERP
+ //printf("Bestmode %d (%d): %d\n", best_mbmode.mode, best_mbmode.interp_filter, best_rd);
+ if (cpi->common.mcomp_filter_type == SWITCHABLE &&
+ best_mbmode.mode >= NEARESTMV &&
+ best_mbmode.mode <= SPLITMV) {
+ ++cpi->switchable_interp_count
+ [get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
+ [vp8_switchable_interp_map[best_mbmode.interp_filter]];
+ }
+#endif
// Reduce the activation RD thresholds for the best choice mode
- if ((cpi->rd_baseline_thresh[best_mode_index] > 0) && (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2))) {
+ if ((cpi->rd_baseline_thresh[best_mode_index] > 0) &&
+ (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2))) {
int best_adjustment = (cpi->rd_thresh_mult[best_mode_index] >> 2);
- cpi->rd_thresh_mult[best_mode_index] = (cpi->rd_thresh_mult[best_mode_index] >= (MIN_THRESHMULT + best_adjustment)) ? cpi->rd_thresh_mult[best_mode_index] - best_adjustment : MIN_THRESHMULT;
- cpi->rd_threshes[best_mode_index] = (cpi->rd_baseline_thresh[best_mode_index] >> 7) * cpi->rd_thresh_mult[best_mode_index];
+ cpi->rd_thresh_mult[best_mode_index] =
+ (cpi->rd_thresh_mult[best_mode_index] >=
+ (MIN_THRESHMULT + best_adjustment)) ?
+ cpi->rd_thresh_mult[best_mode_index] - best_adjustment : MIN_THRESHMULT;
+ cpi->rd_threshes[best_mode_index] =
+ (cpi->rd_baseline_thresh[best_mode_index] >> 7) *
+ cpi->rd_thresh_mult[best_mode_index];
// If we chose a split mode then reset the new MV thresholds as well
/*if ( vp8_mode_order[best_mode_index].mode == SPLITMV )