summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/common/vp9_alloccommon.c25
-rw-r--r--vp9/common/vp9_alloccommon.h2
-rw-r--r--vp9/common/vp9_blockd.h138
-rw-r--r--vp9/common/vp9_entropymode.c56
-rw-r--r--vp9/common/vp9_entropymode.h10
-rw-r--r--vp9/common/vp9_enums.h3
-rw-r--r--vp9/common/vp9_findnearmv.h51
-rw-r--r--vp9/common/vp9_loopfilter.c24
-rw-r--r--vp9/common/vp9_mvref_common.c12
-rw-r--r--vp9/common/vp9_onyxc_int.h14
-rw-r--r--vp9/common/vp9_quant_common.c47
-rw-r--r--vp9/common/vp9_quant_common.h9
-rw-r--r--vp9/common/vp9_reconinter.c16
-rw-r--r--vp9/common/vp9_reconintra.c275
-rw-r--r--vp9/common/vp9_reconintra4x4.c2
-rw-r--r--vp9/decoder/vp9_decodemv.c73
-rw-r--r--vp9/decoder/vp9_decodframe.c176
-rw-r--r--vp9/decoder/vp9_decodframe.h4
-rw-r--r--vp9/decoder/vp9_detokenize.c3
-rw-r--r--vp9/decoder/vp9_idct_blk.c15
-rw-r--r--vp9/decoder/vp9_onyxd_if.c6
-rw-r--r--vp9/encoder/vp9_bitstream.c166
-rw-r--r--vp9/encoder/vp9_block.h7
-rw-r--r--vp9/encoder/vp9_encodeframe.c357
-rw-r--r--vp9/encoder/vp9_encodeintra.c41
-rw-r--r--vp9/encoder/vp9_encodeintra.h4
-rw-r--r--vp9/encoder/vp9_encodemb.c2
-rw-r--r--vp9/encoder/vp9_encodemb.h4
-rw-r--r--vp9/encoder/vp9_modecosts.c2
-rw-r--r--vp9/encoder/vp9_onyx_if.c42
-rw-r--r--vp9/encoder/vp9_onyx_int.h23
-rw-r--r--vp9/encoder/vp9_quantize.c18
-rw-r--r--vp9/encoder/vp9_ratectrl.c13
-rw-r--r--vp9/encoder/vp9_rdopt.c865
-rw-r--r--vp9/encoder/vp9_rdopt.h4
-rw-r--r--vp9/encoder/vp9_segmentation.c8
-rw-r--r--vp9/encoder/vp9_tokenize.c6
-rw-r--r--vp9/encoder/vp9_variance_c.c8
-rw-r--r--vpx_scale/yv12config.h2
39 files changed, 1977 insertions, 556 deletions
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c
index a80276705..8179a6915 100644
--- a/vp9/common/vp9_alloccommon.c
+++ b/vp9/common/vp9_alloccommon.c
@@ -223,3 +223,28 @@ void vp9_initialize_common() {
vp9_entropy_mode_init();
vp9_entropy_mv_init();
}
+
+
+void vp9_update_frame_size(VP9_COMMON *cm) {
+ const int aligned_width = multiple16(cm->width);
+ const int aligned_height = multiple16(cm->height);
+
+ cm->mb_rows = aligned_height >> 4;
+ cm->mb_cols = aligned_width >> 4;
+
+ cm->mi_rows = aligned_height >> LOG2_MI_SIZE;
+ cm->mi_cols = aligned_width >> LOG2_MI_SIZE;
+
+ cm->MBs = cm->mb_rows * cm->mb_cols;
+ cm->mode_info_stride = cm->mi_cols + 1;
+ cm->mi = cm->mip + cm->mode_info_stride + 1;
+ cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1;
+
+ memset(cm->mip, 0,
+ cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO));
+ vp9_update_mode_info_border(cm, cm->mip);
+ vp9_update_mode_info_in_image(cm, cm->mi);
+
+ vp9_update_mode_info_border(cm, cm->prev_mip);
+ vp9_update_mode_info_in_image(cm, cm->prev_mi);
+}
diff --git a/vp9/common/vp9_alloccommon.h b/vp9/common/vp9_alloccommon.h
index c505717ef..814a7607a 100644
--- a/vp9/common/vp9_alloccommon.h
+++ b/vp9/common/vp9_alloccommon.h
@@ -25,4 +25,6 @@ void vp9_free_frame_buffers(VP9_COMMON *oci);
void vp9_setup_version(VP9_COMMON *oci);
+void vp9_update_frame_size(VP9_COMMON *cm);
+
#endif // VP9_COMMON_VP9_ALLOCCOMMON_H_
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 053159c0a..567098351 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -83,7 +83,9 @@ typedef enum {
D27_PRED, /* Directional 22 deg prediction [anti-clockwise from 0 deg hor] */
D63_PRED, /* Directional 67 deg prediction [anti-clockwise from 0 deg hor] */
TM_PRED, /* Truemotion prediction */
+#if !CONFIG_SB8X8
I8X8_PRED, /* 8x8 based prediction, each 8x8 has its own mode */
+#endif
I4X4_PRED, /* 4x4 based prediction, each 4x4 has its own mode */
NEARESTMV,
NEARMV,
@@ -126,7 +128,9 @@ typedef enum {
#define VP9_YMODES (I4X4_PRED + 1)
#define VP9_UV_MODES (TM_PRED + 1)
+#if !CONFIG_SB8X8
#define VP9_I8X8_MODES (TM_PRED + 1)
+#endif
#define VP9_I32X32_MODES (TM_PRED + 1)
#define VP9_MVREFS (1 + SPLITMV - NEARESTMV)
@@ -169,6 +173,7 @@ typedef enum {
#define VP9_NKF_BINTRAMODES (VP9_BINTRAMODES) /* 10 */
#endif
+#if !CONFIG_SB8X8
typedef enum {
PARTITIONING_16X8 = 0,
PARTITIONING_8X16,
@@ -176,6 +181,7 @@ typedef enum {
PARTITIONING_4X4,
NB_PARTITIONINGS,
} SPLITMV_PARTITIONING_TYPE;
+#endif
/* For keyframes, intra block modes are predicted by the (already decoded)
modes for the Y blocks to the left and above us; for interframes, there
@@ -200,49 +206,62 @@ typedef enum {
MAX_REF_FRAMES = 4
} MV_REFERENCE_FRAME;
-static INLINE int mi_width_log2(BLOCK_SIZE_TYPE sb_type) {
+static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) {
switch (sb_type) {
+ case BLOCK_SIZE_AB4X4: return 0;
#if CONFIG_SB8X8
- case BLOCK_SIZE_SB8X16:
- case BLOCK_SIZE_SB8X8: return 0;
+ case BLOCK_SIZE_SB8X8:
+ case BLOCK_SIZE_SB8X16: return 1;
case BLOCK_SIZE_SB16X8:
#endif
case BLOCK_SIZE_MB16X16:
- case BLOCK_SIZE_SB16X32: return 0 + CONFIG_SB8X8;
+ case BLOCK_SIZE_SB16X32: return 2;
case BLOCK_SIZE_SB32X16:
- case BLOCK_SIZE_SB32X64:
- case BLOCK_SIZE_SB32X32: return 1 + CONFIG_SB8X8;
+ case BLOCK_SIZE_SB32X32:
+ case BLOCK_SIZE_SB32X64: return 3;
case BLOCK_SIZE_SB64X32:
- case BLOCK_SIZE_SB64X64: return 2 + CONFIG_SB8X8;
+ case BLOCK_SIZE_SB64X64: return 4;
default: assert(0);
}
}
-static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) {
+static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) {
switch (sb_type) {
+ case BLOCK_SIZE_AB4X4: return 0;
#if CONFIG_SB8X8
- case BLOCK_SIZE_SB16X8:
- case BLOCK_SIZE_SB8X8: return 0;
+ case BLOCK_SIZE_SB8X8:
+ case BLOCK_SIZE_SB16X8: return 1;
case BLOCK_SIZE_SB8X16:
#endif
case BLOCK_SIZE_MB16X16:
- case BLOCK_SIZE_SB32X16: return 0 + CONFIG_SB8X8;
+ case BLOCK_SIZE_SB32X16: return 2;
case BLOCK_SIZE_SB16X32:
- case BLOCK_SIZE_SB64X32:
- case BLOCK_SIZE_SB32X32: return 1 + CONFIG_SB8X8;
+ case BLOCK_SIZE_SB32X32:
+ case BLOCK_SIZE_SB64X32: return 3;
case BLOCK_SIZE_SB32X64:
- case BLOCK_SIZE_SB64X64: return 2 + CONFIG_SB8X8;
+ case BLOCK_SIZE_SB64X64: return 4;
default: assert(0);
}
}
-// parse block dimension in the unit of 4x4 blocks
-static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) {
- return mi_width_log2(sb_type) + 2 - CONFIG_SB8X8;
+static INLINE int mi_width_log2(BLOCK_SIZE_TYPE sb_type) {
+#if CONFIG_SB8X8
+ int a = b_width_log2(sb_type) - 1;
+#else
+ int a = b_width_log2(sb_type) - 2;
+#endif
+ assert(a >= 0);
+ return a;
}
-static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) {
- return mi_height_log2(sb_type) + 2 - CONFIG_SB8X8;
+static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) {
+#if CONFIG_SB8X8
+ int a = b_height_log2(sb_type) - 1;
+#else
+ int a = b_height_log2(sb_type) - 2;
+#endif
+ assert(a >= 0);
+ return a;
}
typedef struct {
@@ -258,7 +277,9 @@ typedef struct {
int mb_mode_context[MAX_REF_FRAMES];
+#if !CONFIG_SB8X8
SPLITMV_PARTITIONING_TYPE partitioning;
+#endif
unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */
unsigned char need_to_clamp_mvs;
unsigned char need_to_clamp_secondmv;
@@ -280,7 +301,7 @@ typedef struct {
typedef struct {
MB_MODE_INFO mbmi;
- union b_mode_info bmi[16];
+ union b_mode_info bmi[16 >> (CONFIG_SB8X8 * 2)];
} MODE_INFO;
struct scale_factors {
@@ -420,8 +441,11 @@ typedef struct macroblockd {
int corrupted;
- int sb_index;
- int mb_index; // Index of the MB in the SB (0..3)
+ int sb_index; // index of 32x32 block inside the 64x64 block
+ int mb_index; // index of 16x16 block inside the 32x32 block
+#if CONFIG_SB8X8
+ int b_index; // index of 8x8 block inside the 16x16 block
+#endif
int q_index;
} MACROBLOCKD;
@@ -429,10 +453,10 @@ typedef struct macroblockd {
static INLINE void update_partition_context(MACROBLOCKD *xd,
BLOCK_SIZE_TYPE sb_type,
BLOCK_SIZE_TYPE sb_size) {
- int bsl = mi_width_log2(sb_size) - CONFIG_SB8X8, bs = 1 << bsl;
- int bwl = mi_width_log2(sb_type) - CONFIG_SB8X8;
- int bhl = mi_height_log2(sb_type) - CONFIG_SB8X8;
- int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - CONFIG_SB8X8 - bsl;
+ int bsl = mi_width_log2(sb_size), bs = 1 << bsl;
+ int bwl = mi_width_log2(sb_type);
+ int bhl = mi_height_log2(sb_type);
+ int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - bsl;
int i;
// skip macroblock partition
if (bsl == 0)
@@ -468,9 +492,9 @@ static INLINE void update_partition_context(MACROBLOCKD *xd,
static INLINE int partition_plane_context(MACROBLOCKD *xd,
BLOCK_SIZE_TYPE sb_type) {
- int bsl = mi_width_log2(sb_type) - CONFIG_SB8X8, bs = 1 << bsl;
+ int bsl = mi_width_log2(sb_type), bs = 1 << bsl;
int above = 0, left = 0, i;
- int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - bsl - CONFIG_SB8X8;
+ int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - bsl;
assert(mi_width_log2(sb_type) == mi_height_log2(sb_type));
assert(bsl >= 0);
@@ -568,6 +592,7 @@ static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, int ib) {
xd->mode_info_context->bmi[ib].as_mode.context :
#endif
xd->mode_info_context->bmi[ib].as_mode.first);
+#if !CONFIG_SB8X8
} else if (xd->mode_info_context->mbmi.mode == I8X8_PRED &&
xd->q_index < ACTIVE_HT) {
const int ic = (ib & 10);
@@ -602,7 +627,8 @@ static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, int ib) {
// Use 2D DCT
tx_type = DCT_DCT;
#endif
- } else if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
+#endif // !CONFIG_SB8X8
+ } else if (xd->mode_info_context->mbmi.mode <= TM_PRED &&
xd->q_index < ACTIVE_HT) {
#if USE_ADST_FOR_I16X16_4X4
#if USE_ADST_PERIPHERY_ONLY
@@ -646,14 +672,17 @@ static TX_TYPE get_tx_type_8x8(const MACROBLOCKD *xd, int ib) {
#endif
if (ib >= (1 << (wb + hb))) // no chroma adst
return tx_type;
+#if !CONFIG_SB8X8
if (xd->mode_info_context->mbmi.mode == I8X8_PRED &&
xd->q_index < ACTIVE_HT8) {
// TODO(rbultje): MB_PREDICTION_MODE / B_PREDICTION_MODE should be merged
// or the relationship otherwise modified to address this type conversion.
tx_type = txfm_map(pred_mode_conv(
(MB_PREDICTION_MODE)xd->mode_info_context->bmi[ib].as_mode.first));
- } else if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
- xd->q_index < ACTIVE_HT8) {
+ } else
+#endif // CONFIG_SB8X8
+ if (xd->mode_info_context->mbmi.mode <= TM_PRED &&
+ xd->q_index < ACTIVE_HT8) {
#if USE_ADST_FOR_I16X16_8X8
#if USE_ADST_PERIPHERY_ONLY
const int hmax = 1 << wb;
@@ -694,7 +723,7 @@ static TX_TYPE get_tx_type_16x16(const MACROBLOCKD *xd, int ib) {
#endif
if (ib >= (1 << (wb + hb)))
return tx_type;
- if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
+ if (xd->mode_info_context->mbmi.mode <= TM_PRED &&
xd->q_index < ACTIVE_HT16) {
tx_type = txfm_map(pred_mode_conv(xd->mode_info_context->mbmi.mode));
#if USE_ADST_PERIPHERY_ONLY
@@ -725,7 +754,9 @@ void vp9_setup_block_dptrs(MACROBLOCKD *xd);
static TX_SIZE get_uv_tx_size(const MACROBLOCKD *xd) {
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
const TX_SIZE size = mbmi->txfm_size;
+#if !CONFIG_SB8X8
const MB_PREDICTION_MODE mode = mbmi->mode;
+#endif // !CONFIG_SB8X8
switch (mbmi->sb_type) {
case BLOCK_SIZE_SB64X64:
@@ -737,6 +768,17 @@ static TX_SIZE get_uv_tx_size(const MACROBLOCKD *xd) {
return TX_16X16;
else
return size;
+#if CONFIG_SB8X8
+ case BLOCK_SIZE_SB32X16:
+ case BLOCK_SIZE_SB16X32:
+ case BLOCK_SIZE_MB16X16:
+ if (size == TX_16X16)
+ return TX_8X8;
+ else
+ return size;
+ default:
+ return TX_4X4;
+#else // CONFIG_SB8X8
default:
if (size == TX_16X16)
return TX_8X8;
@@ -744,6 +786,7 @@ static TX_SIZE get_uv_tx_size(const MACROBLOCKD *xd) {
return TX_4X4;
else
return size;
+#endif // CONFIG_SB8X8
}
return size;
@@ -799,7 +842,10 @@ typedef void (*foreach_transformed_block_visitor)(int plane, int block,
void *arg);
static INLINE void foreach_transformed_block_in_plane(
const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane,
- int is_split, foreach_transformed_block_visitor visit, void *arg) {
+#if !CONFIG_SB8X8
+ int is_split,
+#endif // !CONFIG_SB8X8
+ foreach_transformed_block_visitor visit, void *arg) {
const int bw = b_width_log2(bsize), bh = b_height_log2(bsize);
// block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
@@ -817,7 +863,10 @@ static INLINE void foreach_transformed_block_in_plane(
// than the size of the subsampled data, or forced externally by the mb mode.
const int ss_max = MAX(xd->plane[plane].subsampling_x,
xd->plane[plane].subsampling_y);
- const int ss_txfrm_size = txfrm_size_b > ss_block_size || is_split
+ const int ss_txfrm_size = txfrm_size_b > ss_block_size
+#if !CONFIG_SB8X8
+ || is_split
+#endif // !CONFIG_SB8X8
? txfrm_size_b - ss_max * 2
: txfrm_size_b;
const int step = 1 << ss_txfrm_size;
@@ -834,17 +883,24 @@ static INLINE void foreach_transformed_block_in_plane(
static INLINE void foreach_transformed_block(
const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize,
foreach_transformed_block_visitor visit, void *arg) {
+#if !CONFIG_SB8X8
const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
const int is_split =
xd->mode_info_context->mbmi.txfm_size == TX_8X8 &&
(mode == I8X8_PRED || mode == SPLITMV);
+#endif // !CONFIG_SB8X8
int plane;
for (plane = 0; plane < MAX_MB_PLANE; plane++) {
+#if !CONFIG_SB8X8
const int is_split_chroma = is_split &&
xd->plane[plane].plane_type == PLANE_TYPE_UV;
+#endif // !CONFIG_SB8X8
- foreach_transformed_block_in_plane(xd, bsize, plane, is_split_chroma,
+ foreach_transformed_block_in_plane(xd, bsize, plane,
+#if !CONFIG_SB8X8
+ is_split_chroma,
+#endif // !CONFIG_SB8X8
visit, arg);
}
}
@@ -852,14 +908,19 @@ static INLINE void foreach_transformed_block(
static INLINE void foreach_transformed_block_uv(
const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize,
foreach_transformed_block_visitor visit, void *arg) {
+#if !CONFIG_SB8X8
const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
const int is_split =
xd->mode_info_context->mbmi.txfm_size == TX_8X8 &&
(mode == I8X8_PRED || mode == SPLITMV);
+#endif // !CONFIG_SB8X8
int plane;
for (plane = 1; plane < MAX_MB_PLANE; plane++) {
- foreach_transformed_block_in_plane(xd, bsize, plane, is_split,
+ foreach_transformed_block_in_plane(xd, bsize, plane,
+#if !CONFIG_SB8X8
+ is_split,
+#endif // !CONFIG_SB8X8
visit, arg);
}
}
@@ -887,11 +948,16 @@ static INLINE void foreach_predicted_block_in_plane(
int pred_w, pred_h;
if (mode == SPLITMV) {
+#if CONFIG_SB8X8
+ pred_w = 0;
+ pred_h = 0;
+#else
// 4x4 or 8x8
const int is_4x4 =
(xd->mode_info_context->mbmi.partitioning == PARTITIONING_4X4);
pred_w = is_4x4 ? 0 : 1 >> xd->plane[plane].subsampling_x;
pred_h = is_4x4 ? 0 : 1 >> xd->plane[plane].subsampling_y;
+#endif
} else {
pred_w = bw;
pred_h = bh;
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c
index 8d5577f24..ed5441cc1 100644
--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -16,6 +16,17 @@
#include "vpx_mem/vpx_mem.h"
static const unsigned int kf_y_mode_cts[8][VP9_YMODES] = {
+#if CONFIG_SB8X8
+ /* DC V H D45 135 117 153 D27 D63 TM i4X4 */
+ {12, 6, 5, 5, 5, 5, 5, 5, 5, 2, 200},
+ {25, 13, 13, 7, 7, 7, 7, 7, 7, 6, 160},
+ {31, 17, 18, 8, 8, 8, 8, 8, 8, 9, 139},
+ {40, 22, 23, 8, 8, 8, 8, 8, 8, 12, 116},
+ {53, 26, 28, 8, 8, 8, 8, 8, 8, 13, 94},
+ {68, 33, 35, 8, 8, 8, 8, 8, 8, 17, 68},
+ {78, 38, 38, 8, 8, 8, 8, 8, 8, 19, 52},
+ {89, 42, 42, 8, 8, 8, 8, 8, 8, 21, 34},
+#else
/* DC V H D45 135 117 153 D27 D63 TM i8x8 i4X4 */
{12, 6, 5, 5, 5, 5, 5, 5, 5, 2, 22, 200},
{25, 13, 13, 7, 7, 7, 7, 7, 7, 6, 27, 160},
@@ -25,11 +36,17 @@ static const unsigned int kf_y_mode_cts[8][VP9_YMODES] = {
{68, 33, 35, 8, 8, 8, 8, 8, 8, 17, 20, 68},
{78, 38, 38, 8, 8, 8, 8, 8, 8, 19, 16, 52},
{89, 42, 42, 8, 8, 8, 8, 8, 8, 21, 12, 34},
+#endif
};
static const unsigned int y_mode_cts [VP9_YMODES] = {
+#if CONFIG_SB8X8
+ /* DC V H D45 135 117 153 D27 D63 TM i4X4 */
+ 98, 19, 15, 14, 14, 14, 14, 12, 12, 13, 70
+#else
/* DC V H D45 135 117 153 D27 D63 TM i8x8 i4X4 */
98, 19, 15, 14, 14, 14, 14, 12, 12, 13, 16, 70
+#endif
};
static const unsigned int uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
@@ -44,14 +61,18 @@ static const unsigned int uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
{ 150, 15, 10, 10, 10, 10, 10, 75, 10, 6}, /* D27 */
{ 150, 15, 10, 10, 10, 10, 10, 10, 75, 6}, /* D63 */
{ 160, 30, 30, 10, 10, 10, 10, 10, 10, 16}, /* TM */
+#if !CONFIG_SB8X8
{ 132, 46, 40, 10, 10, 10, 10, 10, 10, 18}, /* i8x8 - never used */
+#endif
{ 150, 35, 41, 10, 10, 10, 10, 10, 10, 10}, /* i4X4 */
};
+#if !CONFIG_SB8X8
static const unsigned int i8x8_mode_cts [VP9_I8X8_MODES] = {
/* DC V H D45 135 117 153 D27 D63 TM */
73, 49, 61, 30, 30, 30, 30, 30, 30, 13
};
+#endif
static const unsigned int kf_uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
// DC V H D45 135 117 153 D27 D63 TM
@@ -65,7 +86,9 @@ static const unsigned int kf_uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = {
{ 102, 33, 20, 20, 20, 20, 20, 64, 20, 14}, /* D27 */
{ 102, 33, 20, 20, 20, 20, 20, 20, 64, 14}, /* D63 */
{ 132, 36, 30, 20, 20, 20, 20, 20, 20, 18}, /* TM */
+#if !CONFIG_SB8X8
{ 122, 41, 35, 20, 20, 20, 20, 20, 20, 18}, /* i8x8 - never used */
+#endif
{ 122, 41, 35, 20, 20, 20, 20, 20, 20, 18}, /* I4X4 */
};
@@ -123,6 +146,7 @@ const vp9_prob vp9_sub_mv_ref_prob2 [SUBMVREF_COUNT][VP9_SUBMVREFS - 1] = {
{ 208, 1, 1 }
};
+#if !CONFIG_SB8X8
vp9_mbsplit vp9_mbsplits [VP9_NUMMBSPLITS] = {
{
0, 0, 0, 0,
@@ -150,9 +174,17 @@ vp9_mbsplit vp9_mbsplits [VP9_NUMMBSPLITS] = {
const int vp9_mbsplit_count [VP9_NUMMBSPLITS] = { 2, 2, 4, 16};
const vp9_prob vp9_mbsplit_probs [VP9_NUMMBSPLITS - 1] = { 110, 111, 150};
+#endif
const vp9_prob vp9_partition_probs[NUM_PARTITION_CONTEXTS]
[PARTITION_TYPES - 1] = {
+#if CONFIG_SB8X8
+ // FIXME(jingning,rbultje) put real probabilities here
+ {202, 162, 107},
+ {16, 2, 169},
+ {3, 246, 19},
+ {104, 90, 134},
+#endif
{202, 162, 107},
{16, 2, 169},
{3, 246, 19},
@@ -228,8 +260,12 @@ const vp9_tree_index vp9_ymode_tree[VP9_YMODES * 2 - 2] = {
-D27_PRED, -D63_PRED,
16, 18,
-V_PRED, -H_PRED,
+#if CONFIG_SB8X8
+ -TM_PRED, -I4X4_PRED
+#else
-TM_PRED, 20,
-I4X4_PRED, -I8X8_PRED
+#endif
};
const vp9_tree_index vp9_kf_ymode_tree[VP9_YMODES * 2 - 2] = {
@@ -242,10 +278,15 @@ const vp9_tree_index vp9_kf_ymode_tree[VP9_YMODES * 2 - 2] = {
-D27_PRED, -D63_PRED,
16, 18,
-V_PRED, -H_PRED,
+#if CONFIG_SB8X8
+ -TM_PRED, -I4X4_PRED
+#else
-TM_PRED, 20,
-I4X4_PRED, -I8X8_PRED
+#endif
};
+#if !CONFIG_SB8X8
const vp9_tree_index vp9_i8x8_mode_tree[VP9_I8X8_MODES * 2 - 2] = {
2, 14,
-DC_PRED, 4,
@@ -257,6 +298,7 @@ const vp9_tree_index vp9_i8x8_mode_tree[VP9_I8X8_MODES * 2 - 2] = {
-V_PRED, 16,
-H_PRED, -TM_PRED
};
+#endif
const vp9_tree_index vp9_uv_mode_tree[VP9_UV_MODES * 2 - 2] = {
2, 14,
@@ -270,11 +312,13 @@ const vp9_tree_index vp9_uv_mode_tree[VP9_UV_MODES * 2 - 2] = {
-H_PRED, -TM_PRED
};
+#if !CONFIG_SB8X8
const vp9_tree_index vp9_mbsplit_tree[6] = {
-PARTITIONING_4X4, 2,
-PARTITIONING_8X8, 4,
-PARTITIONING_16X8, -PARTITIONING_8X16,
};
+#endif
const vp9_tree_index vp9_mv_ref_tree[8] = {
-ZEROMV, 2,
@@ -308,8 +352,10 @@ struct vp9_token vp9_sb_ymode_encodings[VP9_I32X32_MODES];
struct vp9_token vp9_sb_kf_ymode_encodings[VP9_I32X32_MODES];
struct vp9_token vp9_kf_ymode_encodings[VP9_YMODES];
struct vp9_token vp9_uv_mode_encodings[VP9_UV_MODES];
+#if !CONFIG_SB8X8
struct vp9_token vp9_i8x8_mode_encodings[VP9_I8X8_MODES];
struct vp9_token vp9_mbsplit_encodings[VP9_NUMMBSPLITS];
+#endif
struct vp9_token vp9_mv_ref_encoding_array[VP9_MVREFS];
struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
@@ -340,12 +386,16 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
bct, uv_mode_cts[i], 0);
}
+#if !CONFIG_SB8X8
vp9_tree_probs_from_distribution(vp9_i8x8_mode_tree, x->fc.i8x8_mode_prob,
bct, i8x8_mode_cts, 0);
+#endif
vpx_memcpy(x->fc.sub_mv_ref_prob, vp9_sub_mv_ref_prob2,
sizeof(vp9_sub_mv_ref_prob2));
+#if !CONFIG_SB8X8
vpx_memcpy(x->fc.mbsplit_prob, vp9_mbsplit_probs, sizeof(vp9_mbsplit_probs));
+#endif
vpx_memcpy(x->fc.switchable_interp_prob, vp9_switchable_interp_prob,
sizeof(vp9_switchable_interp_prob));
@@ -449,8 +499,10 @@ void vp9_entropy_mode_init() {
vp9_tokens_from_tree(vp9_sb_ymode_encodings, vp9_sb_ymode_tree);
vp9_tokens_from_tree(vp9_sb_kf_ymode_encodings, vp9_sb_kf_ymode_tree);
vp9_tokens_from_tree(vp9_uv_mode_encodings, vp9_uv_mode_tree);
+#if !CONFIG_SB8X8
vp9_tokens_from_tree(vp9_i8x8_mode_encodings, vp9_i8x8_mode_tree);
vp9_tokens_from_tree(vp9_mbsplit_encodings, vp9_mbsplit_tree);
+#endif
vp9_tokens_from_tree(vp9_switchable_interp_encodings,
vp9_switchable_interp_tree);
vp9_tokens_from_tree(vp9_partition_encodings, vp9_partition_tree);
@@ -629,9 +681,11 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
update_mode_probs(VP9_NKF_BINTRAMODES, vp9_bmode_tree,
fc->bmode_counts, fc->pre_bmode_prob,
fc->bmode_prob, 0);
+#if !CONFIG_SB8X8
update_mode_probs(VP9_I8X8_MODES,
vp9_i8x8_mode_tree, fc->i8x8_mode_counts,
fc->pre_i8x8_mode_prob, fc->i8x8_mode_prob, 0);
+#endif
for (i = 0; i < SUBMVREF_COUNT; ++i)
update_mode_probs(VP9_SUBMVREFS,
@@ -639,9 +693,11 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
fc->pre_sub_mv_ref_prob[i], fc->sub_mv_ref_prob[i],
LEFT4X4);
+#if !CONFIG_SB8X8
update_mode_probs(VP9_NUMMBSPLITS, vp9_mbsplit_tree,
fc->mbsplit_counts, fc->pre_mbsplit_prob,
fc->mbsplit_prob, 0);
+#endif
#if CONFIG_COMP_INTERINTRA_PRED
if (cm->use_interintra) {
int factor, interintra_prob, count;
diff --git a/vp9/common/vp9_entropymode.h b/vp9/common/vp9_entropymode.h
index 665569578..24f988f25 100644
--- a/vp9/common/vp9_entropymode.h
+++ b/vp9/common/vp9_entropymode.h
@@ -15,7 +15,9 @@
#include "vp9/common/vp9_treecoder.h"
#define SUBMVREF_COUNT 5
+#if !CONFIG_SB8X8
#define VP9_NUMMBSPLITS 4
+#endif
#if CONFIG_COMP_INTERINTRA_PRED
#define VP9_DEF_INTERINTRA_PROB 248
@@ -24,6 +26,7 @@
#define SEPARATE_INTERINTRA_UV 0
#endif
+#if !CONFIG_SB8X8
typedef const int vp9_mbsplit[16];
extern vp9_mbsplit vp9_mbsplits[VP9_NUMMBSPLITS];
@@ -31,6 +34,7 @@ extern vp9_mbsplit vp9_mbsplits[VP9_NUMMBSPLITS];
extern const int vp9_mbsplit_count[VP9_NUMMBSPLITS]; /* # of subsets */
extern const vp9_prob vp9_mbsplit_probs[VP9_NUMMBSPLITS - 1];
+#endif
extern int vp9_mv_cont(const int_mv *l, const int_mv *a);
@@ -48,8 +52,10 @@ extern const vp9_tree_index vp9_kf_ymode_tree[];
extern const vp9_tree_index vp9_uv_mode_tree[];
#define vp9_sb_ymode_tree vp9_uv_mode_tree
#define vp9_sb_kf_ymode_tree vp9_uv_mode_tree
+#if !CONFIG_SB8X8
extern const vp9_tree_index vp9_i8x8_mode_tree[];
extern const vp9_tree_index vp9_mbsplit_tree[];
+#endif
extern const vp9_tree_index vp9_mv_ref_tree[];
extern const vp9_tree_index vp9_sb_mv_ref_tree[];
extern const vp9_tree_index vp9_sub_mv_ref_tree[];
@@ -60,9 +66,11 @@ extern struct vp9_token vp9_ymode_encodings[VP9_YMODES];
extern struct vp9_token vp9_sb_ymode_encodings[VP9_I32X32_MODES];
extern struct vp9_token vp9_sb_kf_ymode_encodings[VP9_I32X32_MODES];
extern struct vp9_token vp9_kf_ymode_encodings[VP9_YMODES];
-extern struct vp9_token vp9_i8x8_mode_encodings[VP9_I8X8_MODES];
extern struct vp9_token vp9_uv_mode_encodings[VP9_UV_MODES];
+#if !CONFIG_SB8X8
+extern struct vp9_token vp9_i8x8_mode_encodings[VP9_I8X8_MODES];
extern struct vp9_token vp9_mbsplit_encodings[VP9_NUMMBSPLITS];
+#endif
/* Inter mode values do not start at zero */
diff --git a/vp9/common/vp9_enums.h b/vp9/common/vp9_enums.h
index fddbb557b..3f00ba496 100644
--- a/vp9/common/vp9_enums.h
+++ b/vp9/common/vp9_enums.h
@@ -23,6 +23,7 @@
#define MI_UV_SIZE (1 << (LOG2_MI_SIZE - 1))
typedef enum BLOCK_SIZE_TYPE {
+ BLOCK_SIZE_AB4X4,
#if CONFIG_SB8X8
BLOCK_SIZE_SB8X8,
BLOCK_SIZE_SB8X16,
@@ -46,6 +47,6 @@ typedef enum PARTITION_TYPE {
} PARTITION_TYPE;
#define PARTITION_PLOFFSET 4 // number of probability models per block size
-#define NUM_PARTITION_CONTEXTS (2 * PARTITION_PLOFFSET)
+#define NUM_PARTITION_CONTEXTS ((2 + CONFIG_SB8X8) * PARTITION_PLOFFSET)
#endif // VP9_COMMON_VP9_ENUMS_H_
diff --git a/vp9/common/vp9_findnearmv.h b/vp9/common/vp9_findnearmv.h
index 085454512..df1ab73e8 100644
--- a/vp9/common/vp9_findnearmv.h
+++ b/vp9/common/vp9_findnearmv.h
@@ -74,11 +74,13 @@ vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc,
vp9_prob p[VP9_MVREFS - 1],
const int context);
+#if !CONFIG_SB8X8
extern const uint8_t vp9_mbsplit_offset[4][16];
+#endif
static int left_block_mv(const MACROBLOCKD *xd,
const MODE_INFO *cur_mb, int b) {
- if (!(b & 3)) {
+ if (!(b & (3 >> CONFIG_SB8X8))) {
if (!xd->left_available)
return 0;
@@ -88,7 +90,7 @@ static int left_block_mv(const MACROBLOCKD *xd,
if (cur_mb->mbmi.mode != SPLITMV)
return cur_mb->mbmi.mv[0].as_int;
- b += 4;
+ b += 4 >> CONFIG_SB8X8;
}
return (cur_mb->bmi + b - 1)->as_mv[0].as_int;
@@ -96,7 +98,7 @@ static int left_block_mv(const MACROBLOCKD *xd,
static int left_block_second_mv(const MACROBLOCKD *xd,
const MODE_INFO *cur_mb, int b) {
- if (!(b & 3)) {
+ if (!(b & (3 >> CONFIG_SB8X8))) {
if (!xd->left_available)
return 0;
@@ -106,7 +108,7 @@ static int left_block_second_mv(const MACROBLOCKD *xd,
if (cur_mb->mbmi.mode != SPLITMV)
return cur_mb->mbmi.second_ref_frame > 0 ?
cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
- b += 4;
+ b += 4 >> CONFIG_SB8X8;
}
return cur_mb->mbmi.second_ref_frame > 0 ?
@@ -115,72 +117,85 @@ static int left_block_second_mv(const MACROBLOCKD *xd,
}
static int above_block_mv(const MODE_INFO *cur_mb, int b, int mi_stride) {
- if (!(b >> 2)) {
+ if (!(b >> (2 >> CONFIG_SB8X8))) {
/* On top edge, get from MB above us */
cur_mb -= mi_stride;
if (cur_mb->mbmi.mode != SPLITMV)
return cur_mb->mbmi.mv[0].as_int;
- b += 16;
+ b += 16 >> (2 * CONFIG_SB8X8);
}
- return (cur_mb->bmi + b - 4)->as_mv[0].as_int;
+ return (cur_mb->bmi + b - (4 >> CONFIG_SB8X8))->as_mv[0].as_int;
}
static int above_block_second_mv(const MODE_INFO *cur_mb, int b, int mi_stride) {
- if (!(b >> 2)) {
+ if (!(b >> (2 >> CONFIG_SB8X8))) {
/* On top edge, get from MB above us */
cur_mb -= mi_stride;
if (cur_mb->mbmi.mode != SPLITMV)
return cur_mb->mbmi.second_ref_frame > 0 ?
cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
- b += 16;
+ b += 16 >> (2 * CONFIG_SB8X8);
}
return cur_mb->mbmi.second_ref_frame > 0 ?
- (cur_mb->bmi + b - 4)->as_mv[1].as_int :
- (cur_mb->bmi + b - 4)->as_mv[0].as_int;
+ (cur_mb->bmi + b - (4 >> CONFIG_SB8X8))->as_mv[1].as_int :
+ (cur_mb->bmi + b - (4 >> CONFIG_SB8X8))->as_mv[0].as_int;
}
static B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) {
- if (!(b & 3)) {
+#if CONFIG_SB8X8
+ // FIXME(rbultje, jingning): temporary hack because jenkins doesn't
+ // understand this condition. This will go away soon.
+ if (b == 0 || b == 2) {
+#else
+ if (!(b & (3 >> CONFIG_SB8X8))) {
+#endif
/* On L edge, get from MB to left of us */
--cur_mb;
- if (cur_mb->mbmi.mode < I8X8_PRED) {
+ if (cur_mb->mbmi.mode <= TM_PRED) {
return pred_mode_conv(cur_mb->mbmi.mode);
+#if !CONFIG_SB8X8
} else if (cur_mb->mbmi.mode == I8X8_PRED) {
return pred_mode_conv(
(MB_PREDICTION_MODE)(cur_mb->bmi + 3 + b)->as_mode.first);
+#endif // !CONFIG_SB8X8
} else if (cur_mb->mbmi.mode == I4X4_PRED) {
- return ((cur_mb->bmi + 3 + b)->as_mode.first);
+ return ((cur_mb->bmi + (3 >> CONFIG_SB8X8) + b)->as_mode.first);
} else {
return B_DC_PRED;
}
}
+#if CONFIG_SB8X8
+ assert(b == 1 || b == 3);
+#endif
return (cur_mb->bmi + b - 1)->as_mode.first;
}
static B_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb,
int b, int mi_stride) {
- if (!(b >> 2)) {
+ if (!(b >> (2 >> CONFIG_SB8X8))) {
/* On top edge, get from MB above us */
cur_mb -= mi_stride;
- if (cur_mb->mbmi.mode < I8X8_PRED) {
+ if (cur_mb->mbmi.mode <= TM_PRED) {
return pred_mode_conv(cur_mb->mbmi.mode);
+#if !CONFIG_SB8X8
} else if (cur_mb->mbmi.mode == I8X8_PRED) {
return pred_mode_conv(
(MB_PREDICTION_MODE)(cur_mb->bmi + 12 + b)->as_mode.first);
+#endif
} else if (cur_mb->mbmi.mode == I4X4_PRED) {
- return ((cur_mb->bmi + 12 + b)->as_mode.first);
+ return ((cur_mb->bmi + (CONFIG_SB8X8 ? 2 : 12) + b)->as_mode.first);
} else {
return B_DC_PRED;
}
}
- return (cur_mb->bmi + b - 4)->as_mode.first;
+ return (cur_mb->bmi + b - (4 >> CONFIG_SB8X8))->as_mode.first;
}
#endif // VP9_COMMON_VP9_FINDNEARMV_H_
diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c
index ed0c35463..edb0c540b 100644
--- a/vp9/common/vp9_loopfilter.c
+++ b/vp9/common/vp9_loopfilter.c
@@ -27,7 +27,9 @@ static void lf_init_lut(loop_filter_info_n *lfi) {
lfi->mode_lf_lut[H_PRED] = 1;
lfi->mode_lf_lut[TM_PRED] = 1;
lfi->mode_lf_lut[I4X4_PRED] = 0;
+#if !CONFIG_SB8X8
lfi->mode_lf_lut[I8X8_PRED] = 0;
+#endif
lfi->mode_lf_lut[ZEROMV] = 1;
lfi->mode_lf_lut[NEARESTMV] = 2;
lfi->mode_lf_lut[NEARMV] = 2;
@@ -165,10 +167,14 @@ void vp9_loop_filter_frame_init(VP9_COMMON *cm,
// the MB uses a prediction size of 16x16 and either 16x16 transform
// is used or there is no residue at all.
static int mb_lf_skip(const MB_MODE_INFO *const mbmi) {
- const MB_PREDICTION_MODE mode = mbmi->mode;
const int skip_coef = mbmi->mb_skip_coeff;
const int tx_size = mbmi->txfm_size;
+#if CONFIG_SB8X8
+ return mbmi->sb_type >= BLOCK_SIZE_MB16X16 &&
+#else
+ const MB_PREDICTION_MODE mode = mbmi->mode;
return mode != I4X4_PRED && mode != I8X8_PRED && mode != SPLITMV &&
+#endif
(tx_size >= TX_16X16 || skip_coef);
}
@@ -220,7 +226,13 @@ static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi,
if (!skip_lf) {
if (tx_size >= TX_8X8) {
- if (tx_size == TX_8X8 && (mode == I8X8_PRED || mode == SPLITMV))
+ if (tx_size == TX_8X8 &&
+#if CONFIG_SB8X8
+ (mi->mbmi.sb_type < BLOCK_SIZE_MB16X16)
+#else
+ (mode == I8X8_PRED || mode == SPLITMV)
+#endif
+ )
vp9_loop_filter_bh8x8(y_ptr, u_ptr, v_ptr,
y_stride, uv_stride, &lfi);
else
@@ -244,7 +256,13 @@ static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi,
if (!skip_lf) {
if (tx_size >= TX_8X8) {
- if (tx_size == TX_8X8 && (mode == I8X8_PRED || mode == SPLITMV))
+ if (tx_size == TX_8X8 &&
+#if CONFIG_SB8X8
+ (mi->mbmi.sb_type < BLOCK_SIZE_MB16X16)
+#else
+ (mode == I8X8_PRED || mode == SPLITMV)
+#endif
+ )
vp9_loop_filter_bv8x8(y_ptr, u_ptr, v_ptr,
y_stride, uv_stride, &lfi);
else
diff --git a/vp9/common/vp9_mvref_common.c b/vp9/common/vp9_mvref_common.c
index b6ccb8bd9..7a7ebe64f 100644
--- a/vp9/common/vp9_mvref_common.c
+++ b/vp9/common/vp9_mvref_common.c
@@ -13,6 +13,11 @@
#define MVREF_NEIGHBOURS 8
#if CONFIG_SB8X8
+static int b_mv_ref_search[MVREF_NEIGHBOURS][2] = {
+ {0, -1}, {-1, 0}, {-1, -1}, {0, -2},
+ {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}
+};
+
static int mb_mv_ref_search[MVREF_NEIGHBOURS][2] = {
{0, -1}, {-1, 0}, {-1, -1}, {0, -3},
{-3, 0}, {-1, -3}, {-3, -1}, {-3, -3}
@@ -185,8 +190,15 @@ void vp9_find_mv_refs(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here,
mv_ref_search = sb64_mv_ref_search;
} else if (mbmi->sb_type >= BLOCK_SIZE_SB32X32) {
mv_ref_search = sb_mv_ref_search;
+#if CONFIG_SB8X8
+ } else if (mbmi->sb_type >= BLOCK_SIZE_MB16X16) {
+ mv_ref_search = mb_mv_ref_search;
+ } else {
+ mv_ref_search = b_mv_ref_search;
+#else
} else {
mv_ref_search = mb_mv_ref_search;
+#endif
}
// We first scan for candidate vectors that match the current reference frame
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index 68fed951d..96ceca26a 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -65,9 +65,13 @@ typedef struct frame_contexts {
vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
vp9_prob sb_ymode_prob[VP9_I32X32_MODES - 1];
vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
+#if !CONFIG_SB8X8
vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1];
+#endif
vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+#if !CONFIG_SB8X8
vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1];
+#endif
vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
vp9_coeff_probs coef_probs_4x4[BLOCK_TYPES];
@@ -87,17 +91,25 @@ typedef struct frame_contexts {
vp9_prob pre_ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
vp9_prob pre_sb_ymode_prob[VP9_I32X32_MODES - 1];
vp9_prob pre_uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
+#if !CONFIG_SB8X8
vp9_prob pre_i8x8_mode_prob[VP9_I8X8_MODES - 1];
+#endif
vp9_prob pre_sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+#if !CONFIG_SB8X8
vp9_prob pre_mbsplit_prob[VP9_NUMMBSPLITS - 1];
+#endif
vp9_prob pre_partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
unsigned int bmode_counts[VP9_NKF_BINTRAMODES];
unsigned int ymode_counts[VP9_YMODES]; /* interframe intra mode probs */
unsigned int sb_ymode_counts[VP9_I32X32_MODES];
unsigned int uv_mode_counts[VP9_YMODES][VP9_UV_MODES];
+#if !CONFIG_SB8X8
unsigned int i8x8_mode_counts[VP9_I8X8_MODES]; /* interframe intra probs */
+#endif
unsigned int sub_mv_ref_counts[SUBMVREF_COUNT][VP9_SUBMVREFS];
+#if !CONFIG_SB8X8
unsigned int mbsplit_counts[VP9_NUMMBSPLITS];
+#endif
unsigned int partition_counts[NUM_PARTITION_CONTEXTS][PARTITION_TYPES];
vp9_coeff_probs pre_coef_probs_4x4[BLOCK_TYPES];
@@ -248,7 +260,7 @@ typedef struct VP9Common {
int sharpness_level;
int dering_enabled;
- int refresh_entropy_probs; /* Two state 0 = NO, 1 = YES */
+ int refresh_frame_context; /* Two state 0 = NO, 1 = YES */
int ref_frame_sign_bias[MAX_REF_FRAMES]; /* Two state 0, 1 */
diff --git a/vp9/common/vp9_quant_common.c b/vp9/common/vp9_quant_common.c
index a94c772be..2e9e4cab2 100644
--- a/vp9/common/vp9_quant_common.c
+++ b/vp9/common/vp9_quant_common.c
@@ -11,45 +11,36 @@
#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_quant_common.h"
-static int dc_qlookup[QINDEX_RANGE];
-static int ac_qlookup[QINDEX_RANGE];
+static int16_t dc_qlookup[QINDEX_RANGE];
+static int16_t ac_qlookup[QINDEX_RANGE];
#define ACDC_MIN 4
+// TODO(dkovalev) move to common and reuse
+static double poly3(double a, double b, double c, double d, double x) {
+ return a*x*x*x + b*x*x + c*x + d;
+}
+
void vp9_init_quant_tables() {
- int i;
- int current_val = 4;
- int last_val = 4;
- int ac_val;
+ int i, val = 4;
for (i = 0; i < QINDEX_RANGE; i++) {
- ac_qlookup[i] = current_val;
- current_val = (int)(current_val * 1.02);
- if (current_val == last_val)
- current_val++;
- last_val = current_val;
-
- ac_val = ac_qlookup[i];
- dc_qlookup[i] = (int)((0.000000305 * ac_val * ac_val * ac_val) +
- (-0.00065 * ac_val * ac_val) +
- (0.9 * ac_val) + 0.5);
- if (dc_qlookup[i] < ACDC_MIN)
- dc_qlookup[i] = ACDC_MIN;
- }
-}
+ const int ac_val = val;
-int vp9_dc_quant(int qindex, int delta) {
- return dc_qlookup[clamp(qindex + delta, 0, MAXQ)];
-}
+ val = (int)(val * 1.02);
+ if (val == ac_val)
+ ++val;
-int vp9_dc_uv_quant(int qindex, int delta) {
- return dc_qlookup[clamp(qindex + delta, 0, MAXQ)];
+ ac_qlookup[i] = (int16_t)ac_val;
+ dc_qlookup[i] = (int16_t)MAX(ACDC_MIN, poly3(0.000000305, -0.00065, 0.9,
+ 0.5, ac_val));
+ }
}
-int vp9_ac_yquant(int qindex) {
- return ac_qlookup[clamp(qindex, 0, MAXQ)];
+int16_t vp9_dc_quant(int qindex, int delta) {
+ return dc_qlookup[clamp(qindex + delta, 0, MAXQ)];
}
-int vp9_ac_uv_quant(int qindex, int delta) {
+int16_t vp9_ac_quant(int qindex, int delta) {
return ac_qlookup[clamp(qindex + delta, 0, MAXQ)];
}
diff --git a/vp9/common/vp9_quant_common.h b/vp9/common/vp9_quant_common.h
index 1520c3797..7daf15dc1 100644
--- a/vp9/common/vp9_quant_common.h
+++ b/vp9/common/vp9_quant_common.h
@@ -15,11 +15,8 @@
#include "vp9/common/vp9_onyxc_int.h"
void vp9_init_quant_tables();
-int vp9_ac_yquant(int qindex);
-int vp9_dc_quant(int qindex, int delta);
-int vp9_dc2quant(int qindex, int delta);
-int vp9_ac2quant(int qindex, int delta);
-int vp9_dc_uv_quant(int qindex, int delta);
-int vp9_ac_uv_quant(int qindex, int delta);
+
+int16_t vp9_dc_quant(int qindex, int delta);
+int16_t vp9_ac_quant(int qindex, int delta);
#endif // VP9_COMMON_VP9_QUANT_COMMON_H_
diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c
index 6efe2465e..042006354 100644
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -265,19 +265,27 @@ static INLINE int round_mv_comp_q4(int value) {
return (value < 0 ? value - 2 : value + 2) / 4;
}
+#if CONFIG_SB8X8
+#define IDX1 2
+#define IDX2 3
+#else
+#define IDX1 4
+#define IDX2 5
+#endif
+
static int mi_mv_pred_row_q4(MACROBLOCKD *mb, int off, int idx) {
const int temp = mb->mode_info_context->bmi[off + 0].as_mv[idx].as_mv.row +
mb->mode_info_context->bmi[off + 1].as_mv[idx].as_mv.row +
- mb->mode_info_context->bmi[off + 4].as_mv[idx].as_mv.row +
- mb->mode_info_context->bmi[off + 5].as_mv[idx].as_mv.row;
+ mb->mode_info_context->bmi[off + IDX1].as_mv[idx].as_mv.row +
+ mb->mode_info_context->bmi[off + IDX2].as_mv[idx].as_mv.row;
return round_mv_comp_q4(temp);
}
static int mi_mv_pred_col_q4(MACROBLOCKD *mb, int off, int idx) {
const int temp = mb->mode_info_context->bmi[off + 0].as_mv[idx].as_mv.col +
mb->mode_info_context->bmi[off + 1].as_mv[idx].as_mv.col +
- mb->mode_info_context->bmi[off + 4].as_mv[idx].as_mv.col +
- mb->mode_info_context->bmi[off + 5].as_mv[idx].as_mv.col;
+ mb->mode_info_context->bmi[off + IDX1].as_mv[idx].as_mv.col +
+ mb->mode_info_context->bmi[off + IDX2].as_mv[idx].as_mv.col;
return round_mv_comp_q4(temp);
}
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c
index a603c7eb7..a0155d9a9 100644
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -15,73 +15,37 @@
#include "vp9/common/vp9_reconintra.h"
#include "vpx_mem/vpx_mem.h"
-// Using multiplication and shifting instead of division in diagonal prediction.
-// iscale table is calculated from ((1 << 16) + (i + 2) / 2) / (i+2) and used as
-// ((A + B) * iscale[i] + (1 << 15)) >> 16;
-// where A and B are weighted pixel values.
-static const unsigned int iscale[64] = {
- 32768, 21845, 16384, 13107, 10923, 9362, 8192, 7282,
- 6554, 5958, 5461, 5041, 4681, 4369, 4096, 3855,
- 3641, 3449, 3277, 3121, 2979, 2849, 2731, 2621,
- 2521, 2427, 2341, 2260, 2185, 2114, 2048, 1986,
- 1928, 1872, 1820, 1771, 1725, 1680, 1638, 1598,
- 1560, 1524, 1489, 1456, 1425, 1394, 1365, 1337,
- 1311, 1285, 1260, 1237, 1214, 1192, 1170, 1150,
- 1130, 1111, 1092, 1074, 1057, 1040, 1024, 1008,
-};
-
-static INLINE int iscale_round(int value, int i) {
- return ROUND_POWER_OF_TWO(value * iscale[i], 16);
-}
-
static void d27_predictor(uint8_t *ypred_ptr, int y_stride,
int bw, int bh,
uint8_t *yabove_row, uint8_t *yleft_col) {
int r, c;
-
- r = 0;
- for (c = 0; c < bw - 2; c++) {
- int a = c & 1 ? yleft_col[r + 1]
- : ROUND_POWER_OF_TWO(yleft_col[r] + yleft_col[r + 1], 1);
- int b = yabove_row[c + 2];
- ypred_ptr[c] = iscale_round(2 * a + (c + 1) * b, 1 + c);
- }
-
- for (r = 1; r < bh / 2 - 1; r++) {
- for (c = 0; c < bw - 2 - 2 * r; c++) {
- int a = c & 1 ? yleft_col[r + 1]
- : ROUND_POWER_OF_TWO(yleft_col[r] + yleft_col[r + 1], 1);
- int b = ypred_ptr[(r - 1) * y_stride + c + 2];
- ypred_ptr[r * y_stride + c] = iscale_round(2 * a + (c + 1) * b, 1 + c);
- }
+ // first column
+ for (r = 0; r < bh - 1; ++r) {
+ ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r] +
+ yleft_col[r + 1], 1);
}
-
- for (; r < bh - 1; r++) {
- for (c = 0; c < bw; c++) {
- int v = c & 1 ? yleft_col[r + 1]
- : ROUND_POWER_OF_TWO(yleft_col[r] + yleft_col[r + 1], 1);
- int h = r - c / 2;
- ypred_ptr[h * y_stride + c] = v;
- }
+ ypred_ptr[(bh - 1) * y_stride] = yleft_col[bh-1];
+ ypred_ptr++;
+ // second column
+ for (r = 0; r < bh - 2; ++r) {
+ ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r] +
+ yleft_col[r + 1] * 2 +
+ yleft_col[r + 2], 2);
}
+ ypred_ptr[(bh - 2) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[bh - 2] +
+ yleft_col[bh - 1] * 3,
+ 2);
+ ypred_ptr[(bh - 1) * y_stride] = yleft_col[bh-1];
+ ypred_ptr++;
- c = 0;
- r = bh - 1;
- ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(ypred_ptr[(r - 1) * y_stride] +
- yleft_col[r], 1);
- for (r = bh - 2; r >= bh / 2; --r) {
- const int w = c + (bh - 1 - r) * 2;
- ypred_ptr[r * y_stride + w] =
- ROUND_POWER_OF_TWO(ypred_ptr[(r - 1) * y_stride + w] +
- ypred_ptr[r * y_stride + w - 1], 1);
+ // rest of last row
+ for (c = 0; c < bw - 2; ++c) {
+ ypred_ptr[(bh - 1) * y_stride + c] = yleft_col[bh-1];
}
- for (c = 1; c < bw; c++) {
- for (r = bh - 1; r >= bh / 2 + c / 2; --r) {
- const int w = c + (bh - 1 - r) * 2;
- ypred_ptr[r * y_stride + w] =
- ROUND_POWER_OF_TWO(ypred_ptr[(r - 1) * y_stride + w] +
- ypred_ptr[r * y_stride + w - 1], 1);
+ for (r = bh - 2; r >= 0; --r) {
+ for (c = 0; c < bw - 2; ++c) {
+ ypred_ptr[r * y_stride + c] = ypred_ptr[(r + 1) * y_stride + c - 2];
}
}
}
@@ -90,50 +54,18 @@ static void d63_predictor(uint8_t *ypred_ptr, int y_stride,
int bw, int bh,
uint8_t *yabove_row, uint8_t *yleft_col) {
int r, c;
-
- c = 0;
- for (r = 0; r < bh - 2; r++) {
- int a = r & 1 ? yabove_row[c + 1]
- : ROUND_POWER_OF_TWO(yabove_row[c] + yabove_row[c + 1], 1);
- int b = yleft_col[r + 2];
- ypred_ptr[r * y_stride] = iscale_round(2 * a + (r + 1) * b, 1 + r);
- }
-
- for (c = 1; c < bw / 2 - 1; c++) {
- for (r = 0; r < bh - 2 - 2 * c; r++) {
- int a = r & 1 ? yabove_row[c + 1]
- : ROUND_POWER_OF_TWO(yabove_row[c] + yabove_row[c + 1], 1);
- int b = ypred_ptr[(r + 2) * y_stride + c - 1];
- ypred_ptr[r * y_stride + c] = iscale_round(2 * a + (c + 1) * b, 1 + c);
- }
- }
-
- for (; c < bw - 1; ++c) {
- for (r = 0; r < bh; r++) {
- int v = r & 1 ? yabove_row[c + 1]
- : ROUND_POWER_OF_TWO(yabove_row[c] + yabove_row[c + 1], 1);
- int w = c - r / 2;
- ypred_ptr[r * y_stride + w] = v;
- }
- }
-
- r = 0;
- c = bw - 1;
- ypred_ptr[c] = ROUND_POWER_OF_TWO(ypred_ptr[(c - 1)] + yabove_row[c], 1);
- for (c = bw - 2; c >= bw / 2; --c) {
- const int h = r + (bw - 1 - c) * 2;
- ypred_ptr[h * y_stride + c] =
- ROUND_POWER_OF_TWO(ypred_ptr[h * y_stride + c - 1] +
- ypred_ptr[(h - 1) * y_stride + c], 1);
- }
-
- for (r = 1; r < bh; r++) {
- for (c = bw - 1; c >= bw / 2 + r / 2; --c) {
- const int h = r + (bw - 1 - c) * 2;
- ypred_ptr[h * y_stride + c] =
- ROUND_POWER_OF_TWO(ypred_ptr[h * y_stride + c - 1] +
- ypred_ptr[(h - 1) * y_stride + c], 1);
+ for (r = 0; r < bh; ++r) {
+ for (c = 0; c < bw; ++c) {
+ if (r & 1) {
+ ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[r/2 + c] +
+ yabove_row[r/2 + c + 1] * 2 +
+ yabove_row[r/2 + c + 2], 2);
+ } else {
+ ypred_ptr[c] =ROUND_POWER_OF_TWO(yabove_row[r/2 + c] +
+ yabove_row[r/2+ c + 1], 1);
+ }
}
+ ypred_ptr += y_stride;
}
}
@@ -141,29 +73,16 @@ static void d45_predictor(uint8_t *ypred_ptr, int y_stride,
int bw, int bh,
uint8_t *yabove_row, uint8_t *yleft_col) {
int r, c;
-
- for (r = 0; r < bh - 1; ++r) {
- for (c = 0; c <= r; ++c) {
- ypred_ptr[(r - c) * y_stride + c] = iscale_round(
- yabove_row[r + 1] * (c + 1) + yleft_col[r + 1] * (r - c + 1), r);
- }
- }
-
- for (c = 0; c <= r; ++c) {
- int yabove_ext = yabove_row[r]; // clip_pixel(2 * yabove_row[r] -
- // yabove_row[r - 1]);
- int yleft_ext = yleft_col[r]; // clip_pixel(2 * yleft_col[r] -
- // yleft_col[r-1]);
- ypred_ptr[(r - c) * y_stride + c] =
- iscale_round(yabove_ext * (c + 1) + yleft_ext * (r - c + 1), r);
- }
- for (r = 1; r < bh; ++r) {
- for (c = bw - r; c < bw; ++c) {
- const int yabove_ext = ypred_ptr[(r - 1) * y_stride + c];
- const int yleft_ext = ypred_ptr[r * y_stride + c - 1];
- ypred_ptr[r * y_stride + c] =
- ROUND_POWER_OF_TWO(yabove_ext + yleft_ext, 1);
+ for (r = 0; r < bh; ++r) {
+ for (c = 0; c < bw; ++c) {
+ if (r + c + 2 < bw * 2)
+ ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[r + c] +
+ yabove_row[r + c + 1] * 2 +
+ yabove_row[r + c + 2], 2);
+ else
+ ypred_ptr[c] = yabove_row[bw * 2 - 1];
}
+ ypred_ptr += y_stride;
}
}
@@ -171,29 +90,61 @@ static void d117_predictor(uint8_t *ypred_ptr, int y_stride,
int bw, int bh,
uint8_t *yabove_row, uint8_t *yleft_col) {
int r, c;
+ // first row
for (c = 0; c < bw; c++)
ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[c - 1] + yabove_row[c], 1);
ypred_ptr += y_stride;
- for (c = 0; c < bw; c++)
- ypred_ptr[c] = yabove_row[c - 1];
+
+ // second row
+ ypred_ptr[0] = ROUND_POWER_OF_TWO(yleft_col[0] +
+ yabove_row[-1] * 2 +
+ yabove_row[0], 2);
+ for (c = 1; c < bw; c++)
+ ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[c - 2] +
+ yabove_row[c - 1] * 2 +
+ yabove_row[c], 2);
ypred_ptr += y_stride;
+
+ // the rest of first col
+ ypred_ptr[0] = ROUND_POWER_OF_TWO(yabove_row[-1] +
+ yleft_col[0] * 2 +
+ yleft_col[1], 2);
+ for (r = 3; r < bh; ++r)
+ ypred_ptr[(r-2) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 3] +
+ yleft_col[r - 2] * 2 +
+ yleft_col[r - 1], 2);
+ // the rest of the block
for (r = 2; r < bh; ++r) {
- ypred_ptr[0] = yleft_col[r - 2];
for (c = 1; c < bw; c++)
ypred_ptr[c] = ypred_ptr[-2 * y_stride + c - 1];
ypred_ptr += y_stride;
}
}
+
static void d135_predictor(uint8_t *ypred_ptr, int y_stride,
int bw, int bh,
uint8_t *yabove_row, uint8_t *yleft_col) {
int r, c;
- ypred_ptr[0] = yabove_row[-1];
+ ypred_ptr[0] = ROUND_POWER_OF_TWO(yleft_col[0] +
+ yabove_row[-1] * 2 +
+ yabove_row[0], 2);
for (c = 1; c < bw; c++)
- ypred_ptr[c] = yabove_row[c - 1];
- for (r = 1; r < bh; ++r)
- ypred_ptr[r * y_stride] = yleft_col[r - 1];
+ ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[c - 2] +
+ yabove_row[c - 1] * 2 +
+ yabove_row[c], 2);
+
+ ypred_ptr[y_stride] = ROUND_POWER_OF_TWO(yabove_row[-1] +
+ yleft_col[0] * 2 +
+ yleft_col[1], 2);
+ for (r = 2; r < bh - 1; ++r)
+ ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 2] +
+ yleft_col[r - 1] * 2 +
+ yleft_col[r + 1], 2);
+
+ ypred_ptr[(bh - 1) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[bh - 2] +
+ yleft_col[bh - 1] * 3,
+ 2);
ypred_ptr += y_stride;
for (r = 1; r < bh; ++r) {
@@ -203,22 +154,34 @@ static void d135_predictor(uint8_t *ypred_ptr, int y_stride,
}
}
-static void d153_predictor(uint8_t *ypred_ptr, int y_stride,
+static void d153_predictor(uint8_t *ypred_ptr,
+ int y_stride,
int bw, int bh,
- uint8_t *yabove_row, uint8_t *yleft_col) {
+ uint8_t *yabove_row,
+ uint8_t *yleft_col) {
int r, c;
ypred_ptr[0] = ROUND_POWER_OF_TWO(yabove_row[-1] + yleft_col[0], 1);
for (r = 1; r < bh; r++)
ypred_ptr[r * y_stride] =
ROUND_POWER_OF_TWO(yleft_col[r - 1] + yleft_col[r], 1);
ypred_ptr++;
- ypred_ptr[0] = yabove_row[-1];
- for (r = 1; r < bh; r++)
- ypred_ptr[r * y_stride] = yleft_col[r - 1];
+
+ ypred_ptr[0] = ROUND_POWER_OF_TWO(yleft_col[0] +
+ yabove_row[-1] * 2 +
+ yabove_row[0], 2);
+ ypred_ptr[y_stride] = ROUND_POWER_OF_TWO(yabove_row[-1] +
+ yleft_col[0] * 2 +
+ yleft_col[1], 2);
+ for (r = 2; r < bh; r++)
+ ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 2] +
+ yleft_col[r - 1] * 2 +
+ yleft_col[r], 2);
ypred_ptr++;
for (c = 0; c < bw - 2; c++)
- ypred_ptr[c] = yabove_row[c];
+ ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[c - 1] +
+ yabove_row[c] * 2 +
+ yabove_row[c + 1], 2);
ypred_ptr += y_stride;
for (r = 1; r < bh; ++r) {
for (c = 0; c < bw - 2; c++)
@@ -234,7 +197,7 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
int up_available, int left_available,
int right_available) {
int r, c, i;
- uint8_t yleft_col[64], yabove_data[65], ytop_left;
+ uint8_t yleft_col[64], yabove_data[129], ytop_left;
uint8_t *yabove_row = yabove_data + 1;
// 127 127 127 .. 127 127 127 127 127 127
@@ -254,14 +217,17 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
if (up_available) {
uint8_t *yabove_ptr = src - src_stride;
vpx_memcpy(yabove_row, yabove_ptr, bw);
- ytop_left = left_available ? yabove_ptr[-1] : 127;
+ if (bw == 4 && right_available)
+ vpx_memcpy(yabove_row + bw, yabove_ptr + bw, bw);
+ else
+ vpx_memset(yabove_row + bw, yabove_row[bw -1], bw);
+ ytop_left = left_available ? yabove_ptr[-1] : 129;
} else {
- vpx_memset(yabove_row, 127, bw);
+ vpx_memset(yabove_row, 127, bw * 2);
ytop_left = 127;
}
yabove_row[-1] = ytop_left;
-
switch (mode) {
case DC_PRED: {
int i;
@@ -275,7 +241,6 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
average += yabove_row[i];
count += bw;
}
-
if (left_available) {
for (i = 0; i < bh; i++)
average += yleft_col[i];
@@ -283,7 +248,6 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
}
expected_dc = (average + (count >> 1)) / count;
}
-
for (r = 0; r < bh; r++) {
vpx_memset(ypred_ptr, expected_dc, bw);
ypred_ptr += y_stride;
@@ -292,7 +256,7 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
break;
case V_PRED:
for (r = 0; r < bh; r++) {
- memcpy(ypred_ptr, yabove_row, bw);
+ vpx_memcpy(ypred_ptr, yabove_row, bw);
ypred_ptr += y_stride;
}
break;
@@ -306,7 +270,6 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
for (r = 0; r < bh; r++) {
for (c = 0; c < bw; c++)
ypred_ptr[c] = clip_pixel(yleft_col[r] + yabove_row[c] - ytop_left);
-
ypred_ptr += y_stride;
}
break;
@@ -341,7 +304,7 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
}
} else if (bw > bh) {
uint8_t pred[64*64];
- memset(yleft_col + bh, yleft_col[bh - 1], bw - bh);
+ vpx_memset(yleft_col + bh, yleft_col[bh - 1], bw - bh);
switch (mode) {
case D45_PRED:
d45_predictor(pred, 64, bw, bw, yabove_row, yleft_col);
@@ -365,10 +328,10 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
assert(0);
}
for (i = 0; i < bh; i++)
- memcpy(ypred_ptr + y_stride * i, pred + i * 64, bw);
+ vpx_memcpy(ypred_ptr + y_stride * i, pred + i * 64, bw);
} else {
uint8_t pred[64 * 64];
- memset(yabove_row + bw, yabove_row[bw - 1], bh - bw);
+ vpx_memset(yabove_row + bw * 2, yabove_row[bw * 2 - 1], (bh - bw) * 2);
switch (mode) {
case D45_PRED:
d45_predictor(pred, 64, bh, bh, yabove_row, yleft_col);
@@ -392,7 +355,7 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride,
assert(0);
}
for (i = 0; i < bh; i++)
- memcpy(ypred_ptr + y_stride * i, pred + i * 64, bw);
+ vpx_memcpy(ypred_ptr + y_stride * i, pred + i * 64, bw);
}
break;
default:
@@ -624,7 +587,21 @@ void vp9_intra8x8_predict(MACROBLOCKD *xd,
mode, 8, 8, have_top, have_left,
have_right);
}
+#if !CONFIG_NEWBINTRAMODES
+void vp9_intra4x4_predict(MACROBLOCKD *xd,
+ int block_idx,
+ int mode,
+ uint8_t *predictor, int pre_stride) {
+ const int have_top = (block_idx >> 2) || xd->up_available;
+ const int have_left = (block_idx & 3) || xd->left_available;
+ const int have_right = ((block_idx & 3) != 3);
+ vp9_build_intra_predictors(predictor, pre_stride,
+ predictor, pre_stride,
+ mode, 4, 4, have_top, have_left,
+ have_right);
+}
+#endif
void vp9_intra_uv4x4_predict(MACROBLOCKD *xd,
int block4x4_idx,
int mode,
@@ -632,7 +609,7 @@ void vp9_intra_uv4x4_predict(MACROBLOCKD *xd,
const int block_idx = block4x4_idx & 3;
const int have_top = (block_idx >> 1) || xd->up_available;
const int have_left = (block_idx & 1) || xd->left_available;
- const int have_right = !(block_idx & 1) || xd->right_available;
+ const int have_right = !(block_idx & 1);
vp9_build_intra_predictors(predictor, pre_stride,
predictor, pre_stride,
diff --git a/vp9/common/vp9_reconintra4x4.c b/vp9/common/vp9_reconintra4x4.c
index 08a5fac2b..2a7c7f3fa 100644
--- a/vp9/common/vp9_reconintra4x4.c
+++ b/vp9/common/vp9_reconintra4x4.c
@@ -157,7 +157,6 @@ B_PREDICTION_MODE vp9_find_bpred_context(MACROBLOCKD *xd, int block_idx,
return B_DC_PRED;
return vp9_find_dominant_direction(ptr, stride, 4, tx, ty);
}
-#endif
void vp9_intra4x4_predict(MACROBLOCKD *xd,
int block_idx,
@@ -449,3 +448,4 @@ void vp9_intra4x4_predict(MACROBLOCKD *xd,
#endif
}
}
+#endif
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index c51d0b243..474250cf7 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -65,9 +65,11 @@ static MB_PREDICTION_MODE read_kf_mb_ymode(vp9_reader *r, const vp9_prob *p) {
return (MB_PREDICTION_MODE)treed_read(r, vp9_kf_ymode_tree, p);
}
+#if !CONFIG_SB8X8
static int read_i8x8_mode(vp9_reader *r, const vp9_prob *p) {
return treed_read(r, vp9_i8x8_mode_tree, p);
}
+#endif
static MB_PREDICTION_MODE read_uv_mode(vp9_reader *r, const vp9_prob *p) {
return (MB_PREDICTION_MODE)treed_read(r, vp9_uv_mode_tree, p);
@@ -161,6 +163,7 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
}
}
+#if !CONFIG_SB8X8
if (m->mbmi.mode == I8X8_PRED) {
int i;
for (i = 0; i < 4; ++i) {
@@ -175,14 +178,25 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
}
// chroma mode
- if (m->mbmi.mode != I8X8_PRED) {
+ if (m->mbmi.mode != I8X8_PRED)
+#endif
+ {
m->mbmi.uv_mode = read_uv_mode(r, cm->kf_uv_mode_prob[m->mbmi.mode]);
}
if (cm->txfm_mode == TX_MODE_SELECT &&
!m->mbmi.mb_skip_coeff &&
- m->mbmi.mode <= I8X8_PRED) {
+#if CONFIG_SB8X8
+ m->mbmi.mode != I4X4_PRED
+#else
+ m->mbmi.mode <= I8X8_PRED
+#endif
+ ) {
+#if CONFIG_SB8X8
+ const int allow_16x16 = m->mbmi.sb_type >= BLOCK_SIZE_MB16X16;
+#else
const int allow_16x16 = m->mbmi.mode != I8X8_PRED;
+#endif
const int allow_32x32 = m->mbmi.sb_type >= BLOCK_SIZE_SB32X32;
m->mbmi.txfm_size = select_txfm_size(cm, r, allow_16x16, allow_32x32);
} else if (cm->txfm_mode >= ALLOW_32X32 &&
@@ -767,19 +781,29 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mbmi->uv_mode = DC_PRED;
switch (mbmi->mode) {
case SPLITMV: {
+#if CONFIG_SB8X8
+ const int num_p = 4;
+#else
const int s = treed_read(r, vp9_mbsplit_tree, cm->fc.mbsplit_prob);
const int num_p = vp9_mbsplit_count[s];
+#endif
int j = 0;
+#if !CONFIG_SB8X8
cm->fc.mbsplit_counts[s]++;
- mbmi->need_to_clamp_mvs = 0;
mbmi->partitioning = s;
+#endif
+ mbmi->need_to_clamp_mvs = 0;
do { // for each subset j
int_mv leftmv, abovemv, second_leftmv, second_abovemv;
int_mv blockmv, secondmv;
int mv_contz;
int blockmode;
+#if CONFIG_SB8X8
+ int k = j;
+#else
int k = vp9_mbsplit_offset[s][j]; // first block in subset j
+#endif
leftmv.as_int = left_block_mv(xd, mi, k);
abovemv.as_int = above_block_mv(mi, k, mis);
@@ -851,6 +875,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
}
*/
+#if !CONFIG_SB8X8
{
/* Fill (uniform) modes, mvs of jth subset.
Must do it here because ensuing subsets can
@@ -866,12 +891,12 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
fill_offset++;
} while (--fill_count);
}
-
+#endif
} while (++j < num_p);
}
- mv0->as_int = mi->bmi[15].as_mv[0].as_int;
- mv1->as_int = mi->bmi[15].as_mv[1].as_int;
+ mv0->as_int = mi->bmi[15 >> (2 * CONFIG_SB8X8)].as_mv[0].as_int;
+ mv1->as_int = mi->bmi[15 >> (2 * CONFIG_SB8X8)].as_mv[1].as_int;
break; /* done with SPLITMV */
@@ -957,6 +982,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
} while (++j < 16);
}
+#if !CONFIG_SB8X8
if (mbmi->mode == I8X8_PRED) {
int i;
for (i = 0; i < 4; i++) {
@@ -969,7 +995,9 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mi->bmi[ib + 5].as_mode.first = mode8x8;
cm->fc.i8x8_mode_counts[mode8x8]++;
}
- } else {
+ } else
+#endif
+ {
mbmi->uv_mode = read_uv_mode(r, cm->fc.uv_mode_prob[mbmi->mode]);
cm->fc.uv_mode_counts[mbmi->mode][mbmi->uv_mode]++;
}
@@ -980,23 +1008,44 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
*/
if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
- ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= I8X8_PRED) ||
- (mbmi->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV &&
- mbmi->partitioning == PARTITIONING_4X4)))) {
+ ((mbmi->ref_frame == INTRA_FRAME &&
+#if CONFIG_SB8X8
+ mbmi->mode != I4X4_PRED
+#else
+ mbmi->mode <= I8X8_PRED
+#endif
+ ) ||
+ (mbmi->ref_frame != INTRA_FRAME &&
+#if CONFIG_SB8X8
+ mbmi->mode != SPLITMV
+#else
+ !(mbmi->mode == SPLITMV && mbmi->partitioning == PARTITIONING_4X4)
+#endif
+ ))) {
+#if CONFIG_SB8X8
+ const int allow_16x16 = mbmi->sb_type >= BLOCK_SIZE_MB16X16;
+#else
const int allow_16x16 = mbmi->mode != I8X8_PRED && mbmi->mode != SPLITMV;
+#endif
const int allow_32x32 = mbmi->sb_type >= BLOCK_SIZE_SB32X32;
mbmi->txfm_size = select_txfm_size(cm, r, allow_16x16, allow_32x32);
} else if (mbmi->sb_type >= BLOCK_SIZE_SB32X32 &&
cm->txfm_mode >= ALLOW_32X32) {
mbmi->txfm_size = TX_32X32;
} else if (cm->txfm_mode >= ALLOW_16X16 &&
+#if CONFIG_SB8X8
+ mbmi->sb_type >= BLOCK_SIZE_MB16X16 &&
+#endif
((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= TM_PRED) ||
(mbmi->ref_frame != INTRA_FRAME && mbmi->mode != SPLITMV))) {
mbmi->txfm_size = TX_16X16;
} else if (cm->txfm_mode >= ALLOW_8X8 &&
(!(mbmi->ref_frame == INTRA_FRAME && mbmi->mode == I4X4_PRED) &&
- !(mbmi->ref_frame != INTRA_FRAME && mbmi->mode == SPLITMV &&
- mbmi->partitioning == PARTITIONING_4X4))) {
+ !(mbmi->ref_frame != INTRA_FRAME && mbmi->mode == SPLITMV
+#if !CONFIG_SB8X8
+ && mbmi->partitioning == PARTITIONING_4X4
+#endif
+ ))) {
mbmi->txfm_size = TX_8X8;
} else {
mbmi->txfm_size = TX_4X4;
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 9e5c341af..12f8948d7 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -163,22 +163,20 @@ static vp9_prob read_prob_diff_update(vp9_reader *r, int oldp) {
return (vp9_prob)inv_remap_prob(delp, oldp);
}
-void vp9_init_de_quantizer(VP9D_COMP *pbi) {
- int i;
- int q;
- VP9_COMMON *const pc = &pbi->common;
+void vp9_init_dequantizer(VP9_COMMON *pc) {
+ int q, i;
for (q = 0; q < QINDEX_RANGE; q++) {
// DC value
- pc->y_dequant[q][0] = (int16_t)vp9_dc_quant(q, pc->y_dc_delta_q);
- pc->uv_dequant[q][0] = (int16_t)vp9_dc_uv_quant(q, pc->uv_dc_delta_q);
+ pc->y_dequant[q][0] = vp9_dc_quant(q, pc->y_dc_delta_q);
+ pc->uv_dequant[q][0] = vp9_dc_quant(q, pc->uv_dc_delta_q);
// AC values
for (i = 1; i < 16; i++) {
const int rc = vp9_default_zig_zag1d_4x4[i];
- pc->y_dequant[q][rc] = (int16_t)vp9_ac_yquant(q);
- pc->uv_dequant[q][rc] = (int16_t)vp9_ac_uv_quant(q, pc->uv_ac_delta_q);
+ pc->y_dequant[q][rc] = vp9_ac_quant(q, 0);
+ pc->uv_dequant[q][rc] = vp9_ac_quant(q, pc->uv_ac_delta_q);
}
}
}
@@ -205,6 +203,7 @@ static void mb_init_dequantizer(VP9_COMMON *pc, MACROBLOCKD *xd) {
xd->plane[i].dequant = pc->uv_dequant[xd->q_index];
}
+#if !CONFIG_SB8X8
static void decode_16x16(MACROBLOCKD *xd) {
const TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
@@ -285,6 +284,7 @@ static void decode_8x8(MACROBLOCKD *xd) {
xd->plane[1].dst.stride, xd->plane[2].eobs[0]);
}
}
+#endif
static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx) {
struct macroblockd_plane *const y = &xd->plane[0];
@@ -300,7 +300,7 @@ static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx) {
}
}
-
+#if !CONFIG_SB8X8
static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) {
TX_TYPE tx_type;
int i = 0;
@@ -338,32 +338,6 @@ static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) {
dst, xd->plane[1].dst.stride,
xd->plane[2].eobs[i]);
}
- } else if (mode == I4X4_PRED) {
- for (i = 0; i < 16; i++) {
- int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
- uint8_t* dst;
- dst = raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, i,
- xd->plane[0].dst.buf,
- xd->plane[0].dst.stride);
-#if CONFIG_NEWBINTRAMODES
- xd->mode_info_context->bmi[i].as_mode.context =
- vp9_find_bpred_context(xd, i, dst, xd->plane[0].dst.stride);
- if (!xd->mode_info_context->mbmi.mb_skip_coeff)
- vp9_decode_coefs_4x4(pbi, xd, r, PLANE_TYPE_Y_WITH_DC, i);
-#endif
- vp9_intra4x4_predict(xd, i, b_mode, dst, xd->plane[0].dst.stride);
- tx_type = get_tx_type_4x4(xd, i);
- dequant_add_y(xd, tx_type, i);
- }
-#if CONFIG_NEWBINTRAMODES
- if (!xd->mode_info_context->mbmi.mb_skip_coeff)
- vp9_decode_mb_tokens_4x4_uv(pbi, xd, r);
-#endif
- vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16);
- xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->plane[1].dst.buf,
- xd->plane[1].dst.stride, xd->plane[1].eobs);
- xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->plane[2].dst.buf,
- xd->plane[1].dst.stride, xd->plane[2].eobs);
} else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) {
xd->itxm_add_y_block(xd->plane[0].qcoeff, xd->plane[0].dst.buf,
xd->plane[0].dst.stride, xd);
@@ -382,6 +356,7 @@ static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) {
xd->plane[1].dst.stride, xd->plane[2].eobs);
}
}
+#endif
static int txfrm_block_to_raster_block(MACROBLOCKD *xd,
BLOCK_SIZE_TYPE bsize,
@@ -437,6 +412,73 @@ static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
}
}
+static void decode_atom_intra(VP9D_COMP *pbi, MACROBLOCKD *xd,
+ vp9_reader *r,
+ BLOCK_SIZE_TYPE bsize) {
+ int i = 0;
+ int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
+ int bc = 1 << (bwl + bhl);
+ int tx_type;
+
+ for (i = 0; i < bc; i++) {
+ int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
+ uint8_t* dst;
+ dst = raster_block_offset_uint8(xd, bsize, 0, i,
+ xd->plane[0].dst.buf,
+ xd->plane[0].dst.stride);
+#if CONFIG_NEWBINTRAMODES
+ xd->mode_info_context->bmi[i].as_mode.context =
+ vp9_find_bpred_context(xd, i, dst, xd->plane[0].dst.stride);
+ if (!xd->mode_info_context->mbmi.mb_skip_coeff)
+ vp9_decode_coefs_4x4(pbi, xd, r, PLANE_TYPE_Y_WITH_DC, i);
+#endif
+ vp9_intra4x4_predict(xd, i, b_mode, dst, xd->plane[0].dst.stride);
+ // TODO(jingning): refactor to use foreach_transformed_block_in_plane_
+ tx_type = get_tx_type_4x4(xd, i);
+ dequant_add_y(xd, tx_type, i);
+ }
+#if CONFIG_NEWBINTRAMODES
+ if (!xd->mode_info_context->mbmi.mb_skip_coeff)
+ vp9_decode_mb_tokens_4x4_uv(pbi, xd, r);
+#endif
+ foreach_transformed_block_uv(xd, bsize, decode_block, xd);
+}
+
+static void decode_atom(VP9D_COMP *pbi, MACROBLOCKD *xd,
+ int mi_row, int mi_col,
+ vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
+ MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
+
+ if (pbi->common.frame_type != KEY_FRAME)
+ vp9_setup_interp_filters(xd, mbmi->interp_filter, &pbi->common);
+
+ // prediction
+ if (mbmi->ref_frame == INTRA_FRAME)
+ vp9_build_intra_predictors_sbuv_s(xd, bsize);
+ else
+ vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
+
+ if (mbmi->mb_skip_coeff) {
+ vp9_reset_sb_tokens_context(xd, bsize);
+ } else {
+ // re-initialize macroblock dequantizer before detokenization
+ if (xd->segmentation_enabled)
+ mb_init_dequantizer(&pbi->common, xd);
+
+ if (!vp9_reader_has_error(r)) {
+#if CONFIG_NEWBINTRAMODES
+ if (mbmi->mode != I4X4_PRED)
+#endif
+ vp9_decode_tokens(pbi, xd, r, bsize);
+ }
+ }
+
+ if (mbmi->ref_frame == INTRA_FRAME)
+ decode_atom_intra(pbi, xd, r, bsize);
+ else
+ foreach_transformed_block(xd, bsize, decode_block, xd);
+}
+
static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col,
vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
const int bwl = mi_width_log2(bsize), bhl = mi_height_log2(bsize);
@@ -482,6 +524,7 @@ static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col,
}
}
+#if !CONFIG_SB8X8
// TODO(jingning): Need to merge SB and MB decoding. The MB decoding currently
// couples special handles on I8x8, B_PRED, and splitmv modes.
static void decode_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
@@ -584,6 +627,7 @@ static void decode_mb(VP9D_COMP *pbi, MACROBLOCKD *xd,
}
#endif
}
+#endif
static int get_delta_q(vp9_reader *r, int *dq) {
const int old_value = *dq;
@@ -670,11 +714,26 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col,
vp9_decode_mb_mode_mv(pbi, xd, mi_row, mi_col, r);
set_refs(pbi, mi_row, mi_col);
+#if CONFIG_SB8X8
+ decode_sb(pbi, xd, mi_row, mi_col, r, bsize);
+#else
// TODO(jingning): merge decode_sb_ and decode_mb_
- if (bsize > BLOCK_SIZE_MB16X16)
+ if (bsize > BLOCK_SIZE_MB16X16) {
decode_sb(pbi, xd, mi_row, mi_col, r, bsize);
- else
- decode_mb(pbi, xd, mi_row, mi_col, r);
+ } else {
+ // TODO(jingning): In transition of separating functionalities of decode_mb
+ // into decode_sb and decode_atom. Will remove decode_mb and clean this up
+ // when SB8X8 is on.
+ if (xd->mode_info_context->mbmi.mode == I4X4_PRED ||
+ (xd->mode_info_context->mbmi.mode == SPLITMV &&
+ xd->mode_info_context->mbmi.partitioning == PARTITIONING_4X4))
+ decode_atom(pbi, xd, mi_row, mi_col, r, bsize);
+ else
+ // TODO(jingning): decode_mb still carries deocding process of I8X8_PRED
+ // and SPLITMV of 8x8, 16x8, and 8x16. To be migrated into decode_sb.
+ decode_mb(pbi, xd, mi_row, mi_col, r);
+ }
+#endif
xd->corrupted |= vp9_reader_has_error(r);
}
@@ -887,29 +946,6 @@ static void read_coef_probs(VP9D_COMP *pbi, vp9_reader *r) {
read_coef_probs_common(fc->coef_probs_32x32, TX_32X32, r);
}
-static void update_frame_size(VP9D_COMP *pbi) {
- VP9_COMMON *cm = &pbi->common;
-
- const int width = multiple16(cm->width);
- const int height = multiple16(cm->height);
-
- cm->mb_rows = height / 16;
- cm->mi_rows = height >> LOG2_MI_SIZE;
- cm->mb_cols = width / 16;
- cm->mi_cols = width >> LOG2_MI_SIZE;
- cm->MBs = cm->mb_rows * cm->mb_cols;
- cm->mode_info_stride = cm->mi_cols + 1;
- memset(cm->mip, 0,
- cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO));
- vp9_update_mode_info_border(cm, cm->mip);
- vp9_update_mode_info_border(cm, cm->prev_mip);
-
- cm->mi = cm->mip + cm->mode_info_stride + 1;
- cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1;
- vp9_update_mode_info_in_image(cm, cm->mi);
- vp9_update_mode_info_in_image(cm, cm->prev_mi);
-}
-
static void setup_segmentation(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_reader *r) {
int i, j;
@@ -1030,7 +1066,7 @@ static void setup_quantization(VP9D_COMP *pbi, vp9_reader *r) {
if (get_delta_q(r, &pc->y_dc_delta_q) |
get_delta_q(r, &pc->uv_dc_delta_q) |
get_delta_q(r, &pc->uv_ac_delta_q))
- vp9_init_de_quantizer(pbi);
+ vp9_init_dequantizer(pc);
mb_init_dequantizer(pc, &pbi->mb); // MB level dequantizer setup
}
@@ -1101,7 +1137,7 @@ static const uint8_t *setup_frame_size(VP9D_COMP *pbi, int scaling_active,
pc->display_width = scaling_active ? display_width : width;
pc->display_height = scaling_active ? display_height : height;
- update_frame_size(pbi);
+ vp9_update_frame_size(pc);
}
return data;
@@ -1116,9 +1152,13 @@ static void update_frame_context(FRAME_CONTEXT *fc) {
vp9_copy(fc->pre_sb_ymode_prob, fc->sb_ymode_prob);
vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob);
vp9_copy(fc->pre_bmode_prob, fc->bmode_prob);
+#if !CONFIG_SB8X8
vp9_copy(fc->pre_i8x8_mode_prob, fc->i8x8_mode_prob);
+#endif
vp9_copy(fc->pre_sub_mv_ref_prob, fc->sub_mv_ref_prob);
+#if !CONFIG_SB8X8
vp9_copy(fc->pre_mbsplit_prob, fc->mbsplit_prob);
+#endif
vp9_copy(fc->pre_partition_prob, fc->partition_prob);
fc->pre_nmvc = fc->nmvc;
@@ -1131,9 +1171,13 @@ static void update_frame_context(FRAME_CONTEXT *fc) {
vp9_zero(fc->sb_ymode_counts);
vp9_zero(fc->uv_mode_counts);
vp9_zero(fc->bmode_counts);
+#if !CONFIG_SB8X8
vp9_zero(fc->i8x8_mode_counts);
+#endif
vp9_zero(fc->sub_mv_ref_counts);
+#if !CONFIG_SB8X8
vp9_zero(fc->mbsplit_counts);
+#endif
vp9_zero(fc->NMVcount);
vp9_zero(fc->mv_ref_ct);
vp9_zero(fc->partition_counts);
@@ -1382,10 +1426,10 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
}
if (!pc->error_resilient_mode) {
- pc->refresh_entropy_probs = vp9_read_bit(&header_bc);
+ pc->refresh_frame_context = vp9_read_bit(&header_bc);
pc->frame_parallel_decoding_mode = vp9_read_bit(&header_bc);
} else {
- pc->refresh_entropy_probs = 0;
+ pc->refresh_frame_context = 0;
pc->frame_parallel_decoding_mode = 1;
}
@@ -1477,7 +1521,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
}
#endif
- if (pc->refresh_entropy_probs)
+ if (pc->refresh_frame_context)
pc->frame_contexts[pc->frame_context_idx] = pc->fc;
*p_data_end = vp9_reader_find_end(&residual_bc);
diff --git a/vp9/decoder/vp9_decodframe.h b/vp9/decoder/vp9_decodframe.h
index 391a26519..3aaae65bd 100644
--- a/vp9/decoder/vp9_decodframe.h
+++ b/vp9/decoder/vp9_decodframe.h
@@ -12,8 +12,8 @@
#ifndef VP9_DECODER_VP9_DECODFRAME_H_
#define VP9_DECODER_VP9_DECODFRAME_H_
-struct VP9Decompressor;
+struct VP9Common;
-void vp9_init_de_quantizer(struct VP9Decompressor *pbi);
+void vp9_init_dequantizer(struct VP9Common *pc);
#endif // VP9_DECODER_VP9_DECODFRAME_H_
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index 3ef1e5b32..650defde7 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -85,7 +85,8 @@ DECLARE_ALIGNED(16, extern const uint8_t, vp9_norm[256]);
#define WRITE_COEF_CONTINUE(val, token) \
{ \
- qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(r, val) * dq[c > 0]; \
+ qcoeff_ptr[scan[c]] = vp9_read_and_apply_sign(r, val) * \
+ dq[c > 0] / (1 + (txfm_size == TX_32X32)); \
INCREMENT_COUNT(token); \
c++; \
continue; \
diff --git a/vp9/decoder/vp9_idct_blk.c b/vp9/decoder/vp9_idct_blk.c
index 73c1c4d2c..3480df25e 100644
--- a/vp9/decoder/vp9_idct_blk.c
+++ b/vp9/decoder/vp9_idct_blk.c
@@ -315,23 +315,12 @@ void vp9_idct_add_32x32_c(int16_t *input, uint8_t *dest, int stride, int eob) {
DECLARE_ALIGNED_ARRAY(16, int16_t, output, 1024);
if (eob) {
- input[0] = input[0] / 2;
if (eob == 1) {
vp9_short_idct1_32x32(input, output);
vp9_add_constant_residual_32x32(output[0], dest, stride);
input[0] = 0;
#if !CONFIG_SCATTERSCAN
} else if (eob <= 10) {
- input[1] = input[1] / 2;
- input[2] = input[2] / 2;
- input[3] = input[3] / 2;
- input[32] = input[32] / 2;
- input[33] = input[33] / 2;
- input[34] = input[34] / 2;
- input[64] = input[64] / 2;
- input[65] = input[65] / 2;
- input[96] = input[96] / 2;
-
// the idct halves ( >> 1) the pitch
vp9_short_idct10_32x32(input, output, 64);
@@ -343,10 +332,6 @@ void vp9_idct_add_32x32_c(int16_t *input, uint8_t *dest, int stride, int eob) {
vp9_add_residual_32x32(output, dest, stride);
#endif
} else {
- int i;
- for (i = 1; i < 1024; i++)
- input[i] = input[i] / 2;
-
vp9_short_idct32x32(input, output, 64);
vpx_memset(input, 0, 2048);
vp9_add_residual_32x32(output, dest, stride);
diff --git a/vp9/decoder/vp9_onyxd_if.c b/vp9/decoder/vp9_onyxd_if.c
index a07a8fd45..9582e8f42 100644
--- a/vp9/decoder/vp9_onyxd_if.c
+++ b/vp9/decoder/vp9_onyxd_if.c
@@ -133,10 +133,10 @@ VP9D_PTR vp9_create_decompressor(VP9D_CONFIG *oxcf) {
pbi->common.current_video_frame = 0;
pbi->ready_for_new_data = 1;
- // vp9_init_de_quantizer() is first called here. Add check in
+ // vp9_init_dequantizer() is first called here. Add check in
// frame_init_dequantizer() to avoid unnecessary calling of
- // vp9_init_de_quantizer() for every frame.
- vp9_init_de_quantizer(pbi);
+ // vp9_init_dequantizer() for every frame.
+ vp9_init_dequantizer(&pbi->common);
vp9_loop_filter_init(&pbi->common);
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 38657450e..3c0bab2ce 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -160,28 +160,24 @@ static void update_mbintra_mode_probs(VP9_COMP* const cpi,
vp9_writer* const bc) {
VP9_COMMON *const cm = &cpi->common;
- {
- vp9_prob Pnew [VP9_YMODES - 1];
- unsigned int bct [VP9_YMODES - 1] [2];
-
- update_mode(
- bc, VP9_YMODES, vp9_ymode_encodings, vp9_ymode_tree,
- Pnew, cm->fc.ymode_prob, bct, (unsigned int *)cpi->ymode_count
- );
- update_mode(bc, VP9_I32X32_MODES, vp9_sb_ymode_encodings,
- vp9_sb_ymode_tree, Pnew, cm->fc.sb_ymode_prob, bct,
- (unsigned int *)cpi->sb_ymode_count);
- }
+ vp9_prob pnew[VP9_YMODES - 1];
+ unsigned int bct[VP9_YMODES - 1][2];
+
+ update_mode(bc, VP9_YMODES, vp9_ymode_encodings, vp9_ymode_tree, pnew,
+ cm->fc.ymode_prob, bct, (unsigned int *)cpi->ymode_count);
+
+ update_mode(bc, VP9_I32X32_MODES, vp9_sb_ymode_encodings,
+ vp9_sb_ymode_tree, pnew, cm->fc.sb_ymode_prob, bct,
+ (unsigned int *)cpi->sb_ymode_count);
}
void vp9_update_skip_probs(VP9_COMP *cpi) {
VP9_COMMON *const pc = &cpi->common;
int k;
- for (k = 0; k < MBSKIP_CONTEXTS; ++k) {
+ for (k = 0; k < MBSKIP_CONTEXTS; ++k)
pc->mbskip_pred_probs[k] = get_binary_prob(cpi->skip_false_count[k],
cpi->skip_true_count[k]);
- }
}
static void update_switchable_interp_probs(VP9_COMP *cpi,
@@ -213,18 +209,18 @@ static void update_refpred_stats(VP9_COMP *cpi) {
if (cm->frame_type != KEY_FRAME) {
// From the prediction counts set the probabilities for each context
for (i = 0; i < PREDICTION_PROBS; i++) {
- new_pred_probs[i] = get_binary_prob(cpi->ref_pred_count[i][0],
- cpi->ref_pred_count[i][1]);
+ const int c0 = cpi->ref_pred_count[i][0];
+ const int c1 = cpi->ref_pred_count[i][1];
+
+ new_pred_probs[i] = get_binary_prob(c0, c1);
// Decide whether or not to update the reference frame probs.
// Returned costs are in 1/256 bit units.
- old_cost =
- (cpi->ref_pred_count[i][0] * vp9_cost_zero(cm->ref_pred_probs[i])) +
- (cpi->ref_pred_count[i][1] * vp9_cost_one(cm->ref_pred_probs[i]));
+ old_cost = c0 * vp9_cost_zero(cm->ref_pred_probs[i]) +
+ c1 * vp9_cost_one(cm->ref_pred_probs[i]);
- new_cost =
- (cpi->ref_pred_count[i][0] * vp9_cost_zero(new_pred_probs[i])) +
- (cpi->ref_pred_count[i][1] * vp9_cost_one(new_pred_probs[i]));
+ new_cost = c0 * vp9_cost_zero(new_pred_probs[i]) +
+ c1 * vp9_cost_one(new_pred_probs[i]);
// Cost saving must be >= 8 bits (2048 in these units)
if ((old_cost - new_cost) >= 2048) {
@@ -245,13 +241,11 @@ static void update_refpred_stats(VP9_COMP *cpi) {
static void update_inter_mode_probs(VP9_COMMON *cm,
int mode_context[INTER_MODE_CONTEXTS][4]) {
int i, j;
- unsigned int (*mv_ref_ct)[4][2];
+ unsigned int (*mv_ref_ct)[4][2] = cm->fc.mv_ref_ct;
vpx_memcpy(mode_context, cm->fc.vp9_mode_contexts,
sizeof(cm->fc.vp9_mode_contexts));
- mv_ref_ct = cm->fc.mv_ref_ct;
-
for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
for (j = 0; j < 4; j++) {
int new_prob, old_cost, new_cost;
@@ -287,9 +281,11 @@ static void sb_kfwrite_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
write_token(bc, vp9_uv_mode_tree, p, vp9_sb_kf_ymode_encodings + m);
}
+#if !CONFIG_SB8X8
static void write_i8x8_mode(vp9_writer *bc, int m, const vp9_prob *p) {
write_token(bc, vp9_i8x8_mode_tree, p, vp9_i8x8_mode_encodings + m);
}
+#endif
static void write_uv_mode(vp9_writer *bc, int m, const vp9_prob *p) {
write_token(bc, vp9_uv_mode_tree, p, vp9_uv_mode_encodings + m);
@@ -308,10 +304,11 @@ static void write_kf_bmode(vp9_writer *bc, int m, const vp9_prob *p) {
write_token(bc, vp9_kf_bmode_tree, p, vp9_kf_bmode_encodings + m);
}
+#if !CONFIG_SB8X8
static void write_split(vp9_writer *bc, int x, const vp9_prob *p) {
- write_token(
- bc, vp9_mbsplit_tree, p, vp9_mbsplit_encodings + x);
+ write_token(bc, vp9_mbsplit_tree, p, vp9_mbsplit_encodings + x);
}
+#endif
static int prob_update_savings(const unsigned int *ct,
const vp9_prob oldp, const vp9_prob newp,
@@ -319,17 +316,7 @@ static int prob_update_savings(const unsigned int *ct,
const int old_b = cost_branch256(ct, oldp);
const int new_b = cost_branch256(ct, newp);
const int update_b = 2048 + vp9_cost_upd256;
- return (old_b - new_b - update_b);
-}
-
-static int prob_diff_update_savings(const unsigned int *ct,
- const vp9_prob oldp, const vp9_prob newp,
- const vp9_prob upd) {
- const int old_b = cost_branch256(ct, oldp);
- const int new_b = cost_branch256(ct, newp);
- const int update_b = (newp == oldp ? 0 :
- prob_diff_update_cost(newp, oldp) + vp9_cost_upd256);
- return (old_b - new_b - update_b);
+ return old_b - new_b - update_b;
}
static int prob_diff_update_savings_search(const unsigned int *ct,
@@ -483,10 +470,8 @@ static void pack_mb_tokens(vp9_writer* const bc,
*tp = p;
}
-static void write_mv_ref
-(
- vp9_writer *bc, MB_PREDICTION_MODE m, const vp9_prob *p
-) {
+static void write_mv_ref(vp9_writer *bc, MB_PREDICTION_MODE m,
+ const vp9_prob *p) {
#if CONFIG_DEBUG
assert(NEARESTMV <= m && m <= SPLITMV);
#endif
@@ -503,10 +488,8 @@ static void write_sb_mv_ref(vp9_writer *bc, MB_PREDICTION_MODE m,
vp9_sb_mv_ref_encoding_array - NEARESTMV + m);
}
-static void write_sub_mv_ref
-(
- vp9_writer *bc, B_PREDICTION_MODE m, const vp9_prob *p
-) {
+static void write_sub_mv_ref(vp9_writer *bc, B_PREDICTION_MODE m,
+ const vp9_prob *p) {
#if CONFIG_DEBUG
assert(LEFT4X4 <= m && m <= NEW4X4);
#endif
@@ -749,8 +732,9 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
do {
write_bmode(bc, m->bmi[j].as_mode.first,
pc->fc.bmode_prob);
- } while (++j < 16);
+ } while (++j < (16 >> (CONFIG_SB8X8 * 2)));
}
+#if !CONFIG_SB8X8
if (mode == I8X8_PRED) {
write_i8x8_mode(bc, m->bmi[0].as_mode.first,
pc->fc.i8x8_mode_prob);
@@ -760,7 +744,9 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
pc->fc.i8x8_mode_prob);
write_i8x8_mode(bc, m->bmi[10].as_mode.first,
pc->fc.i8x8_mode_prob);
- } else {
+ } else
+#endif
+ {
write_uv_mode(bc, mi->uv_mode,
pc->fc.uv_mode_prob[mode]);
}
@@ -845,19 +831,26 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
++count_mb_seg[mi->partitioning];
#endif
+#if !CONFIG_SB8X8
write_split(bc, mi->partitioning, cpi->common.fc.mbsplit_prob);
cpi->mbsplit_count[mi->partitioning]++;
+#endif
do {
B_PREDICTION_MODE blockmode;
int_mv blockmv;
+#if !CONFIG_SB8X8
const int *const L = vp9_mbsplits[mi->partitioning];
+#endif
int k = -1; /* first block in subset j */
int mv_contz;
int_mv leftmv, abovemv;
blockmode = cpi->mb.partition_info->bmi[j].mode;
blockmv = cpi->mb.partition_info->bmi[j].mv;
+#if CONFIG_SB8X8
+ k = j;
+#else
#if CONFIG_DEBUG
while (j != L[++k])
if (k >= 16)
@@ -865,6 +858,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
#else
while (j != L[++k]);
#endif
+#endif
leftmv.as_int = left_block_mv(xd, m, k);
abovemv.as_int = above_block_mv(m, k, mis);
mv_contz = vp9_mv_cont(&leftmv, &abovemv);
@@ -896,6 +890,22 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
}
}
+#if CONFIG_SB8X8
+ if (((rf == INTRA_FRAME && mode != I4X4_PRED) ||
+ (rf != INTRA_FRAME && mode != SPLITMV)) &&
+ pc->txfm_mode == TX_MODE_SELECT &&
+ !(skip_coeff || vp9_segfeature_active(xd, segment_id,
+ SEG_LVL_SKIP))) {
+ TX_SIZE sz = mi->txfm_size;
+ // FIXME(rbultje) code ternary symbol once all experiments are merged
+ vp9_write(bc, sz != TX_4X4, pc->prob_tx[0]);
+ if (mi->sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
+ vp9_write(bc, sz != TX_8X8, pc->prob_tx[1]);
+ if (mi->sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
+ vp9_write(bc, sz != TX_16X16, pc->prob_tx[2]);
+ }
+ }
+#else
if (((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
(rf != INTRA_FRAME && !(mode == SPLITMV &&
mi->partitioning == PARTITIONING_4X4))) &&
@@ -911,6 +921,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
vp9_write(bc, sz != TX_16X16, pc->prob_tx[2]);
}
}
+#endif
}
static void write_mb_modes_kf(const VP9_COMP *cpi,
@@ -941,8 +952,8 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
if (ym == I4X4_PRED) {
int i = 0;
do {
- const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
- const B_PREDICTION_MODE L = (xd->left_available || (i & 3)) ?
+ const B_PREDICTION_MODE a = above_block_mode(m, i, mis);
+ const B_PREDICTION_MODE l = (xd->left_available || (i & 3)) ?
left_block_mode(m, i) : B_DC_PRED;
const int bm = m->bmi[i].as_mode.first;
@@ -950,25 +961,36 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
++intra_mode_stats [A] [L] [bm];
#endif
- write_kf_bmode(bc, bm, c->kf_bmode_prob[A][L]);
- } while (++i < 16);
+ write_kf_bmode(bc, bm, c->kf_bmode_prob[a][l]);
+ } while (++i < (16 >> (CONFIG_SB8X8 * 2)));
}
+#if !CONFIG_SB8X8
if (ym == I8X8_PRED) {
- write_i8x8_mode(bc, m->bmi[0].as_mode.first,
- c->fc.i8x8_mode_prob);
+ write_i8x8_mode(bc, m->bmi[0].as_mode.first, c->fc.i8x8_mode_prob);
// printf(" mode: %d\n", m->bmi[0].as_mode.first); fflush(stdout);
- write_i8x8_mode(bc, m->bmi[2].as_mode.first,
- c->fc.i8x8_mode_prob);
+ write_i8x8_mode(bc, m->bmi[2].as_mode.first, c->fc.i8x8_mode_prob);
// printf(" mode: %d\n", m->bmi[2].as_mode.first); fflush(stdout);
- write_i8x8_mode(bc, m->bmi[8].as_mode.first,
- c->fc.i8x8_mode_prob);
+ write_i8x8_mode(bc, m->bmi[8].as_mode.first, c->fc.i8x8_mode_prob);
// printf(" mode: %d\n", m->bmi[8].as_mode.first); fflush(stdout);
- write_i8x8_mode(bc, m->bmi[10].as_mode.first,
- c->fc.i8x8_mode_prob);
+ write_i8x8_mode(bc, m->bmi[10].as_mode.first, c->fc.i8x8_mode_prob);
// printf(" mode: %d\n", m->bmi[10].as_mode.first); fflush(stdout);
} else
+#endif
write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
+#if CONFIG_SB8X8
+ if (ym != I4X4_PRED && c->txfm_mode == TX_MODE_SELECT &&
+ !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
+ TX_SIZE sz = m->mbmi.txfm_size;
+ // FIXME(rbultje) code ternary symbol once all experiments are merged
+ vp9_write(bc, sz != TX_4X4, c->prob_tx[0]);
+ if (m->mbmi.sb_type >= BLOCK_SIZE_MB16X16 && sz != TX_4X4) {
+ vp9_write(bc, sz != TX_8X8, c->prob_tx[1]);
+ if (m->mbmi.sb_type >= BLOCK_SIZE_SB32X32 && sz != TX_8X8)
+ vp9_write(bc, sz != TX_16X16, c->prob_tx[2]);
+ }
+ }
+#else
if (ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
!(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
TX_SIZE sz = m->mbmi.txfm_size;
@@ -980,8 +1002,10 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
vp9_write(bc, sz != TX_16X16, c->prob_tx[2]);
}
}
+#endif
}
+
#if CONFIG_CODE_ZEROGROUP
#ifdef ZPC_STATS
void init_zpcstats() {
@@ -1699,22 +1723,23 @@ static void put_delta_q(vp9_writer *bc, int delta_q) {
static void decide_kf_ymode_entropy(VP9_COMP *cpi) {
int mode_cost[MB_MODE_COUNT];
- int cost;
int bestcost = INT_MAX;
int bestindex = 0;
int i, j;
for (i = 0; i < 8; i++) {
+ int cost = 0;
+
vp9_cost_tokens(mode_cost, cpi->common.kf_ymode_prob[i], vp9_kf_ymode_tree);
- cost = 0;
- for (j = 0; j < VP9_YMODES; j++) {
+
+ for (j = 0; j < VP9_YMODES; j++)
cost += mode_cost[j] * cpi->ymode_count[j];
- }
+
vp9_cost_tokens(mode_cost, cpi->common.sb_kf_ymode_prob[i],
vp9_sb_ymode_tree);
- for (j = 0; j < VP9_I32X32_MODES; j++) {
+ for (j = 0; j < VP9_I32X32_MODES; j++)
cost += mode_cost[j] * cpi->sb_ymode_count[j];
- }
+
if (cost < bestcost) {
bestindex = i;
bestcost = cost;
@@ -2014,9 +2039,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
int i, j, c = 0;
for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) {
count[i] = 0;
- for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j) {
+ for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j)
count[i] += cpi->switchable_interp_count[j][i];
- }
c += (count[i] > 0);
}
if (c == 1) {
@@ -2045,7 +2069,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
}
if (!pc->error_resilient_mode) {
- vp9_write_bit(&header_bc, pc->refresh_entropy_probs);
+ vp9_write_bit(&header_bc, pc->refresh_frame_context);
vp9_write_bit(&header_bc, pc->frame_parallel_decoding_mode);
}
@@ -2172,15 +2196,19 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
vp9_copy(cpi->common.fc.pre_uv_mode_prob, cpi->common.fc.uv_mode_prob);
vp9_copy(cpi->common.fc.pre_bmode_prob, cpi->common.fc.bmode_prob);
vp9_copy(cpi->common.fc.pre_sub_mv_ref_prob, cpi->common.fc.sub_mv_ref_prob);
+#if !CONFIG_SB8X8
vp9_copy(cpi->common.fc.pre_mbsplit_prob, cpi->common.fc.mbsplit_prob);
vp9_copy(cpi->common.fc.pre_i8x8_mode_prob, cpi->common.fc.i8x8_mode_prob);
+#endif
vp9_copy(cpi->common.fc.pre_partition_prob, cpi->common.fc.partition_prob);
cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc;
#if CONFIG_COMP_INTERINTRA_PRED
cpi->common.fc.pre_interintra_prob = cpi->common.fc.interintra_prob;
#endif
vp9_zero(cpi->sub_mv_ref_count);
+#if !CONFIG_SB8X8
vp9_zero(cpi->mbsplit_count);
+#endif
vp9_zero(cpi->common.fc.mv_ref_ct);
update_coef_probs(cpi, &header_bc);
diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h
index 2c06457e7..40ad680b0 100644
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -117,7 +117,9 @@ struct macroblock {
int mbmode_cost[2][MB_MODE_COUNT];
int intra_uv_mode_cost[2][MB_MODE_COUNT];
int bmode_costs[VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES];
+#if !CONFIG_SB8X8
int i8x8_mode_costs[MB_MODE_COUNT];
+#endif
int inter_bmode_costs[B_MODE_COUNT];
int switchable_interp_costs[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS];
@@ -141,6 +143,11 @@ struct macroblock {
// Structure to hold context for each of the 4 MBs within a SB:
// when encoded as 4 independent MBs:
+#if CONFIG_SB8X8
+ PICK_MODE_CONTEXT sb8_context[4][4][4];
+ PICK_MODE_CONTEXT sb8x16_context[4][4][2];
+ PICK_MODE_CONTEXT sb16x8_context[4][4][2];
+#endif
PICK_MODE_CONTEXT mb_context[4][4];
PICK_MODE_CONTEXT sb32x16_context[4][2];
PICK_MODE_CONTEXT sb16x32_context[4][2];
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 06b4d6316..572c6feae 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -47,8 +47,10 @@ int enc_debug = 0;
void vp9_select_interp_filter_type(VP9_COMP *cpi);
+#if !CONFIG_SB8X8
static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
int output_enabled, int mi_row, int mi_col);
+#endif
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
int output_enabled, int mi_row, int mi_col,
@@ -380,6 +382,8 @@ static void update_state(VP9_COMP *cpi,
}
}
if (bsize < BLOCK_SIZE_SB32X32) {
+ if (bsize < BLOCK_SIZE_MB16X16)
+ ctx->txfm_rd_diff[ALLOW_16X16] = ctx->txfm_rd_diff[ALLOW_8X8];
ctx->txfm_rd_diff[ALLOW_32X32] = ctx->txfm_rd_diff[ALLOW_16X16];
}
@@ -387,8 +391,10 @@ static void update_state(VP9_COMP *cpi,
vpx_memcpy(x->partition_info, &ctx->partition_info,
sizeof(PARTITION_INFO));
- mbmi->mv[0].as_int = x->partition_info->bmi[15].mv.as_int;
- mbmi->mv[1].as_int = x->partition_info->bmi[15].second_mv.as_int;
+ mbmi->mv[0].as_int =
+ x->partition_info->bmi[15 >> (CONFIG_SB8X8 * 2)].mv.as_int;
+ mbmi->mv[1].as_int =
+ x->partition_info->bmi[15 >> (CONFIG_SB8X8 * 2)].second_mv.as_int;
#if CONFIG_SB8X8
vpx_memcpy(x->partition_info + mis, &ctx->partition_info,
sizeof(PARTITION_INFO));
@@ -453,7 +459,9 @@ static void update_state(VP9_COMP *cpi,
THR_D27_PRED /*D27_PRED*/,
THR_D63_PRED /*D63_PRED*/,
THR_TM /*TM_PRED*/,
+#if !CONFIG_SB8X8
THR_I8X8_PRED /*I8X8_PRED*/,
+#endif
THR_B_PRED /*I4X4_PRED*/,
};
cpi->mode_chosen_counts[kf_mode_index[mb_mode]]++;
@@ -665,6 +673,7 @@ static void set_offsets(VP9_COMP *cpi,
}
}
+#if !CONFIG_SB8X8
static int pick_mb_mode(VP9_COMP *cpi,
int mi_row,
int mi_col,
@@ -705,6 +714,7 @@ static int pick_mb_mode(VP9_COMP *cpi,
return splitmodes_used;
}
+#endif
static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
TOKENEXTRA **tp, int *totalrate, int *totaldist,
@@ -788,11 +798,15 @@ static void set_block_index(MACROBLOCKD *xd, int idx,
BLOCK_SIZE_TYPE bsize) {
if (bsize >= BLOCK_SIZE_SB32X32) {
xd->sb_index = idx;
- } else {
#if CONFIG_SB8X8
- assert(bsize >= BLOCK_SIZE_MB16X16);
-#endif
+ } else if (bsize >= BLOCK_SIZE_MB16X16) {
xd->mb_index = idx;
+ } else {
+ xd->b_index = idx;
+#else
+ } else {
+ xd->mb_index = idx;
+#endif
}
}
@@ -815,6 +829,14 @@ static PICK_MODE_CONTEXT *get_block_context(MACROBLOCK *x,
return &x->sb16x32_context[xd->sb_index][xd->mb_index];
case BLOCK_SIZE_MB16X16:
return &x->mb_context[xd->sb_index][xd->mb_index];
+#if CONFIG_SB8X8
+ case BLOCK_SIZE_SB16X8:
+ return &x->sb16x8_context[xd->sb_index][xd->mb_index][xd->b_index];
+ case BLOCK_SIZE_SB8X16:
+ return &x->sb8x16_context[xd->sb_index][xd->mb_index][xd->b_index];
+ case BLOCK_SIZE_SB8X8:
+ return &x->sb8_context[xd->sb_index][xd->mb_index][xd->b_index];
+#endif
default:
assert(0);
return NULL;
@@ -835,12 +857,15 @@ static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp,
set_block_index(xd, sub_index, bsize);
set_offsets(cpi, mi_row, mi_col, bsize);
update_state(cpi, get_block_context(x, bsize), bsize, output_enabled);
+#if !CONFIG_SB8X8
if (bsize == BLOCK_SIZE_MB16X16) {
if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
vp9_activity_masking(cpi, x);
encode_macroblock(cpi, tp, output_enabled, mi_row, mi_col);
- } else {
+ } else
+#endif
+ {
encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
}
@@ -855,22 +880,38 @@ static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp,
static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp,
int mi_row, int mi_col, int output_enabled,
BLOCK_SIZE_TYPE level,
- BLOCK_SIZE_TYPE c1, BLOCK_SIZE_TYPE c2[4]) {
+ BLOCK_SIZE_TYPE c1, BLOCK_SIZE_TYPE c2[4]
+#if CONFIG_SB8X8
+ , BLOCK_SIZE_TYPE c3[4][4]
+#endif
+ ) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
const int bsl = mi_width_log2(level), bs = 1 << (bsl - 1);
const int bwl = mi_width_log2(c1), bhl = mi_height_log2(c1);
- int pl;
+ int UNINITIALIZED_IS_SAFE(pl);
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
- set_partition_seg_context(cpi, mi_row, mi_col);
- pl = partition_plane_context(xd, level);
+#if CONFIG_SB8X8
+ if (level > BLOCK_SIZE_SB8X8) {
+#endif
+ set_partition_seg_context(cpi, mi_row, mi_col);
+ pl = partition_plane_context(xd, level);
+#if CONFIG_SB8X8
+ }
+#endif
if (bsl == bwl && bsl == bhl) {
- if (output_enabled && level > BLOCK_SIZE_MB16X16)
+ if (output_enabled &&
+#if CONFIG_SB8X8
+ level > BLOCK_SIZE_SB8X8
+#else
+ level > BLOCK_SIZE_MB16X16
+#endif
+ )
cpi->partition_count[pl][PARTITION_NONE]++;
encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, -1);
} else if (bsl == bhl && bsl > bwl) {
@@ -890,9 +931,17 @@ static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp,
assert(bwl < bsl && bhl < bsl);
if (level == BLOCK_SIZE_SB64X64) {
subsize = BLOCK_SIZE_SB32X32;
+#if CONFIG_SB8X8
+ } else if (level == BLOCK_SIZE_SB32X32) {
+ subsize = BLOCK_SIZE_MB16X16;
+ } else {
+ assert(level == BLOCK_SIZE_MB16X16);
+ subsize = BLOCK_SIZE_SB8X8;
+#else
} else {
assert(level == BLOCK_SIZE_SB32X32);
subsize = BLOCK_SIZE_MB16X16;
+#endif
}
if (output_enabled)
@@ -904,12 +953,22 @@ static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp,
set_block_index(xd, i, subsize);
encode_sb(cpi, tp, mi_row + y_idx * bs, mi_col + x_idx * bs,
output_enabled, subsize,
- subsize == BLOCK_SIZE_MB16X16 ? c1 : c2[i], c2);
+#if CONFIG_SB8X8
+ c2 ? c2[i] : c1, c3 ? c3[i] : NULL, NULL);
+#else
+ c2 ? c2[i] : c1, NULL);
+#endif
}
}
+#if CONFIG_SB8X8
+ if (level > BLOCK_SIZE_SB8X8 &&
+ (level == BLOCK_SIZE_MB16X16 || bsl == bwl || bsl == bhl))
+#else
if (level > BLOCK_SIZE_MB16X16 &&
- (level == BLOCK_SIZE_SB32X32 || bsl == bwl || bsl == bhl)) {
+ (level == BLOCK_SIZE_SB32X32 || bsl == bwl || bsl == bhl))
+#endif
+ {
set_partition_seg_context(cpi, mi_row, mi_col);
update_partition_context(xd, c1, level);
}
@@ -932,7 +991,11 @@ static void encode_sb_row(VP9_COMP *cpi,
for (mi_col = cm->cur_tile_mi_col_start;
mi_col < cm->cur_tile_mi_col_end; mi_col += (4 << CONFIG_SB8X8)) {
int i, p;
+#if CONFIG_SB8X8
+ BLOCK_SIZE_TYPE mb_partitioning[4][4];
+#endif
BLOCK_SIZE_TYPE sb_partitioning[4];
+ BLOCK_SIZE_TYPE sb64_partitioning = BLOCK_SIZE_SB32X32;
int sb64_rate = 0, sb64_dist = 0;
int sb64_skip = 0;
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
@@ -949,6 +1012,9 @@ static void encode_sb_row(VP9_COMP *cpi,
memcpy(&seg_a, cm->above_seg_context + (mi_col >> CONFIG_SB8X8),
sizeof(seg_a));
memcpy(&seg_l, cm->left_seg_context, sizeof(seg_l));
+
+ // FIXME(rbultje): this function should probably be rewritten to be
+ // recursive at some point in the future.
for (i = 0; i < 4; i++) {
const int x_idx = (i & 1) << (1 + CONFIG_SB8X8);
const int y_idx = (i & 2) << CONFIG_SB8X8;
@@ -983,6 +1049,10 @@ static void encode_sb_row(VP9_COMP *cpi,
const int x_idx_m = x_idx + ((j & 1) << CONFIG_SB8X8);
const int y_idx_m = y_idx + ((j >> 1) << CONFIG_SB8X8);
int r, d;
+#if CONFIG_SB8X8
+ int r2, d2, mb16_rate = 0, mb16_dist = 0, k;
+ ENTROPY_CONTEXT l3[4 * MAX_MB_PLANE], a3[4 * MAX_MB_PLANE];
+#endif
if (mi_row + y_idx_m >= cm->mi_rows ||
mi_col + x_idx_m >= cm->mi_cols) {
@@ -993,18 +1063,175 @@ static void encode_sb_row(VP9_COMP *cpi,
// Index of the MB in the SB 0..3
xd->mb_index = j;
+#if CONFIG_SB8X8
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ vpx_memcpy(l3 + 4 * p,
+ cm->left_context[p] +
+ (y_idx_m * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_y)),
+ sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_y);
+ vpx_memcpy(a3 + 4 * p,
+ cm->above_context[p] +
+ ((mi_col + x_idx_m) * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_x)),
+ sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_x);
+ }
+
+ mb_partitioning[i][j] = BLOCK_SIZE_SB8X8;
+ for (k = 0; k < 4; k++) {
+ xd->b_index = k;
+
+ // try 8x8 coding
+ pick_sb_modes(cpi, mi_row + y_idx_m + (k & 1),
+ mi_col + x_idx_m + (k >> 1),
+ tp, &r, &d, BLOCK_SIZE_SB8X8,
+ &x->sb8_context[xd->sb_index][xd->mb_index]
+ [xd->b_index]);
+ mb16_rate += r;
+ mb16_dist += d;
+ update_state(cpi, &x->sb8_context[xd->sb_index][xd->mb_index]
+ [xd->b_index],
+ BLOCK_SIZE_SB8X8, 0);
+ encode_superblock(cpi, tp,
+ 0, mi_row + y_idx_m, mi_col + x_idx_m,
+ BLOCK_SIZE_SB8X8);
+ }
+ set_partition_seg_context(cpi, mi_row + y_idx_m, mi_col + x_idx_m);
+ pl = partition_plane_context(xd, BLOCK_SIZE_MB16X16);
+ mb16_rate += x->partition_cost[pl][PARTITION_SPLIT];
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ vpx_memcpy(cm->left_context[p] +
+ (y_idx_m * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_y)),
+ l3 + 4 * p,
+ sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_y);
+ vpx_memcpy(cm->above_context[p] +
+ ((mi_col + x_idx_m) * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_x)),
+ a3 + 4 * p,
+ sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_x);
+ }
+
+ // try 8x16 coding
+ r2 = 0;
+ d2 = 0;
+ xd->b_index = 0;
+ pick_sb_modes(cpi, mi_row + y_idx_m, mi_col + x_idx_m,
+ tp, &r, &d, BLOCK_SIZE_SB8X16,
+ &x->sb8x16_context[xd->sb_index][xd->mb_index]
+ [xd->b_index]);
+ r2 += r;
+ d2 += d;
+ update_state(cpi, &x->sb8x16_context[xd->sb_index][xd->mb_index]
+ [xd->b_index],
+ BLOCK_SIZE_SB8X16, 0);
+ encode_superblock(cpi, tp,
+ 0, mi_row + y_idx_m, mi_col + x_idx_m,
+ BLOCK_SIZE_SB8X16);
+ xd->b_index = 1;
+ pick_sb_modes(cpi, mi_row + y_idx_m, mi_col + x_idx_m + 1,
+ tp, &r, &d, BLOCK_SIZE_SB8X16,
+ &x->sb8x16_context[xd->sb_index][xd->mb_index]
+ [xd->b_index]);
+ r2 += r;
+ d2 += d;
+ set_partition_seg_context(cpi, mi_row + y_idx_m, mi_col + x_idx_m);
+ pl = partition_plane_context(xd, BLOCK_SIZE_MB16X16);
+ r2 += x->partition_cost[pl][PARTITION_VERT];
+ if (RDCOST(x->rdmult, x->rddiv, r2, d2) <
+ RDCOST(x->rdmult, x->rddiv, mb16_rate, mb16_dist)) {
+ mb16_rate = r;
+ mb16_dist = d;
+ mb_partitioning[i][j] = BLOCK_SIZE_SB8X16;
+ }
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ vpx_memcpy(cm->left_context[p] +
+ (y_idx_m * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_y)),
+ l3 + 4 * p,
+ sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_y);
+ vpx_memcpy(cm->above_context[p] +
+ ((mi_col + x_idx_m) * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_x)),
+ a3 + 4 * p,
+ sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_x);
+ }
+
+ // try 16x8 coding
+ r2 = 0;
+ d2 = 0;
+ xd->b_index = 0;
+ pick_sb_modes(cpi, mi_row + y_idx_m, mi_col + x_idx_m,
+ tp, &r, &d, BLOCK_SIZE_SB16X8,
+ &x->sb16x8_context[xd->sb_index][xd->mb_index]
+ [xd->b_index]);
+ r2 += r;
+ d2 += d;
+ update_state(cpi, &x->sb16x8_context[xd->sb_index][xd->mb_index]
+ [xd->b_index],
+ BLOCK_SIZE_SB16X8, 0);
+ encode_superblock(cpi, tp,
+ 0, mi_row + y_idx_m, mi_col + x_idx_m,
+ BLOCK_SIZE_SB16X8);
+ xd->b_index = 1;
+ pick_sb_modes(cpi, mi_row + y_idx_m + 1, mi_col + x_idx_m,
+ tp, &r, &d, BLOCK_SIZE_SB16X8,
+ &x->sb16x8_context[xd->sb_index][xd->mb_index]
+ [xd->b_index]);
+ r2 += r;
+ d2 += d;
+ set_partition_seg_context(cpi, mi_row + y_idx_m, mi_col + x_idx_m);
+ pl = partition_plane_context(xd, BLOCK_SIZE_MB16X16);
+ r2 += x->partition_cost[pl][PARTITION_HORZ];
+ if (RDCOST(x->rdmult, x->rddiv, r2, d2) <
+ RDCOST(x->rdmult, x->rddiv, mb16_rate, mb16_dist)) {
+ mb16_rate = r;
+ mb16_dist = d;
+ mb_partitioning[i][j] = BLOCK_SIZE_SB16X8;
+ }
+ for (p = 0; p < MAX_MB_PLANE; p++) {
+ vpx_memcpy(cm->left_context[p] +
+ (y_idx_m * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_y)),
+ l3 + 4 * p,
+ sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_y);
+ vpx_memcpy(cm->above_context[p] +
+ ((mi_col + x_idx_m) * 4 >> (CONFIG_SB8X8 +
+ xd->plane[p].subsampling_x)),
+ a3 + 4 * p,
+ sizeof(ENTROPY_CONTEXT) * 4 >> xd->plane[p].subsampling_x);
+ }
+
+ // try as 16x16
+ pick_sb_modes(cpi, mi_row + y_idx_m, mi_col + x_idx_m,
+ tp, &r, &d, BLOCK_SIZE_MB16X16,
+ &x->mb_context[xd->sb_index][xd->mb_index]);
+ set_partition_seg_context(cpi, mi_row + y_idx_m, mi_col + x_idx_m);
+ pl = partition_plane_context(xd, BLOCK_SIZE_MB16X16);
+ r += x->partition_cost[pl][PARTITION_NONE];
+ if (RDCOST(x->rdmult, x->rddiv, r, d) <
+ RDCOST(x->rdmult, x->rddiv, mb16_rate, mb16_dist)) {
+ mb16_rate = r;
+ mb16_dist = d;
+ mb_partitioning[i][j] = BLOCK_SIZE_MB16X16;
+ }
+ sb32_rate += mb16_rate;
+ sb32_dist += mb16_dist;
+#else
splitmodes_used += pick_mb_mode(cpi, mi_row + y_idx_m,
mi_col + x_idx_m, tp, &r, &d);
sb32_rate += r;
sb32_dist += d;
+#endif
// Dummy encode, do not do the tokenization
#if CONFIG_SB8X8
- update_state(cpi, &x->mb_context[xd->sb_index][xd->mb_index],
- BLOCK_SIZE_MB16X16, 0);
-#endif
+ encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0,
+ BLOCK_SIZE_MB16X16, mb_partitioning[i][j], NULL, NULL);
+#else
encode_macroblock(cpi, tp, 0, mi_row + y_idx_m,
mi_col + x_idx_m);
+#endif
}
/* Restore L & A coding context to those in place on entry */
@@ -1168,7 +1395,12 @@ static void encode_sb_row(VP9_COMP *cpi,
// instead of small->big) means we can use as threshold for small, which
// may enable breakouts if RD is not good enough (i.e. faster)
encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0,
- BLOCK_SIZE_SB32X32, sb_partitioning[i], sb_partitioning);
+#if CONFIG_SB8X8
+ BLOCK_SIZE_SB32X32, sb_partitioning[i], mb_partitioning[i],
+ NULL);
+#else
+ BLOCK_SIZE_SB32X32, sb_partitioning[i], NULL);
+#endif
}
for (p = 0; p < MAX_MB_PLANE; p++) {
@@ -1219,7 +1451,7 @@ static void encode_sb_row(VP9_COMP *cpi,
RDCOST(x->rdmult, x->rddiv, sb64_rate, sb64_dist)) {
sb64_rate = r;
sb64_dist = d;
- sb_partitioning[0] = BLOCK_SIZE_SB64X32;
+ sb64_partitioning = BLOCK_SIZE_SB64X32;
}
for (p = 0; p < MAX_MB_PLANE; p++) {
@@ -1264,7 +1496,7 @@ static void encode_sb_row(VP9_COMP *cpi,
RDCOST(x->rdmult, x->rddiv, sb64_rate, sb64_dist)) {
sb64_rate = r;
sb64_dist = d;
- sb_partitioning[0] = BLOCK_SIZE_SB32X64;
+ sb64_partitioning = BLOCK_SIZE_SB32X64;
}
for (p = 0; p < MAX_MB_PLANE; p++) {
@@ -1293,13 +1525,17 @@ static void encode_sb_row(VP9_COMP *cpi,
RDCOST(x->rdmult, x->rddiv, sb64_rate, sb64_dist)) {
sb64_rate = r;
sb64_dist = d;
- sb_partitioning[0] = BLOCK_SIZE_SB64X64;
+ sb64_partitioning = BLOCK_SIZE_SB64X64;
}
}
assert(tp_orig == *tp);
- encode_sb(cpi, tp, mi_row, mi_col, 1,
- BLOCK_SIZE_SB64X64, sb_partitioning[0], sb_partitioning);
+ encode_sb(cpi, tp, mi_row, mi_col, 1, BLOCK_SIZE_SB64X64,
+#if CONFIG_SB8X8
+ sb64_partitioning, sb_partitioning, mb_partitioning);
+#else
+ sb64_partitioning, sb_partitioning);
+#endif
assert(tp_orig < *tp);
}
}
@@ -1344,10 +1580,14 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
vp9_zero(cpi->count_mb_ref_frame_usage)
vp9_zero(cpi->bmode_count)
vp9_zero(cpi->ymode_count)
+#if !CONFIG_SB8X8
vp9_zero(cpi->i8x8_mode_count)
+#endif
vp9_zero(cpi->y_uv_mode_count)
vp9_zero(cpi->sub_mv_ref_count)
+#if !CONFIG_SB8X8
vp9_zero(cpi->mbsplit_count)
+#endif
vp9_zero(cpi->common.fc.mv_ref_ct)
vp9_zero(cpi->sb_ymode_count)
vp9_zero(cpi->partition_count);
@@ -1614,9 +1854,17 @@ static void reset_skip_txfm_size_sb(VP9_COMP *cpi, MODE_INFO *mi,
assert(bwl < bsl && bhl < bsl);
if (bsize == BLOCK_SIZE_SB64X64) {
subsize = BLOCK_SIZE_SB32X32;
+#if CONFIG_SB8X8
+ } else if (bsize == BLOCK_SIZE_SB32X32) {
+ subsize = BLOCK_SIZE_MB16X16;
+ } else {
+ assert(bsize == BLOCK_SIZE_MB16X16);
+ subsize = BLOCK_SIZE_SB8X8;
+#else
} else {
assert(bsize == BLOCK_SIZE_SB32X32);
subsize = BLOCK_SIZE_MB16X16;
+#endif
}
for (n = 0; n < 4; n++) {
@@ -1821,9 +2069,10 @@ static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) {
do {
++ bct[xd->block[b].bmi.as_mode.first];
- } while (++b < 16);
+ } while (++b < (16 >> (CONFIG_SB8X8 * 2)));
}
+#if !CONFIG_SB8X8
if (m == I8X8_PRED) {
i8x8_modes[xd->block[0].bmi.as_mode.first]++;
i8x8_modes[xd->block[2].bmi.as_mode.first]++;
@@ -1831,20 +2080,25 @@ static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) {
i8x8_modes[xd->block[10].bmi.as_mode.first]++;
}
#endif
+#endif
if (xd->mode_info_context->mbmi.sb_type > BLOCK_SIZE_MB16X16) {
++cpi->sb_ymode_count[m];
} else {
++cpi->ymode_count[m];
}
+#if !CONFIG_SB8X8
if (m != I8X8_PRED)
+#endif
++cpi->y_uv_mode_count[m][uvm];
+#if !CONFIG_SB8X8
else {
cpi->i8x8_mode_count[xd->mode_info_context->bmi[0].as_mode.first]++;
cpi->i8x8_mode_count[xd->mode_info_context->bmi[2].as_mode.first]++;
cpi->i8x8_mode_count[xd->mode_info_context->bmi[8].as_mode.first]++;
cpi->i8x8_mode_count[xd->mode_info_context->bmi[10].as_mode.first]++;
}
+#endif
if (m == I4X4_PRED) {
int b = 0;
do {
@@ -1853,7 +2107,7 @@ static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) {
if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS;
#endif
++cpi->bmode_count[m];
- } while (++b < 16);
+ } while (++b < (16 >> (CONFIG_SB8X8 * 2)));
}
}
@@ -1878,6 +2132,7 @@ static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) {
#endif
}
+#if !CONFIG_SB8X8
static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
int output_enabled,
int mi_row, int mi_col) {
@@ -1944,7 +2199,7 @@ static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
#endif
if (mbmi->mode == I4X4_PRED) {
vp9_encode_intra16x16mbuv(cm, x);
- vp9_encode_intra4x4mby(x);
+ vp9_encode_intra4x4mby(x, BLOCK_SIZE_MB16X16);
} else if (mbmi->mode == I8X8_PRED) {
vp9_encode_intra8x8mby(x);
vp9_encode_intra8x8mbuv(x);
@@ -2101,7 +2356,6 @@ static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
#if CONFIG_SB8X8
int y, x;
#endif
-
if (mbmi->mode != I4X4_PRED && mbmi->mode != I8X8_PRED &&
mbmi->mode != SPLITMV && cpi->common.txfm_mode >= ALLOW_16X16) {
mbmi->txfm_size = TX_16X16;
@@ -2126,6 +2380,7 @@ static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
}
}
}
+#endif
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
int output_enabled, int mi_row, int mi_col,
@@ -2176,6 +2431,24 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
vp9_update_zbin_extra(cpi, x);
}
+#if CONFIG_SB8X8
+ if (xd->mode_info_context->mbmi.mode == I4X4_PRED) {
+ assert(bsize == BLOCK_SIZE_SB8X8 &&
+ xd->mode_info_context->mbmi.txfm_size == TX_4X4);
+
+ vp9_encode_intra4x4mby(x, bsize);
+ vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
+ vp9_subtract_sbuv(x, bsize);
+ vp9_transform_sbuv_4x4(x, bsize);
+ vp9_quantize_sbuv_4x4(x, bsize);
+ vp9_optimize_sbuv_4x4(cm, x, bsize);
+ vp9_inverse_transform_sbuv_4x4(xd, bsize);
+ vp9_recon_sbuv(xd, bsize);
+
+ if (output_enabled)
+ sum_intra_stats(cpi, x);
+ } else
+#endif
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
vp9_build_intra_predictors_sby_s(&x->e_mbd, bsize);
vp9_build_intra_predictors_sbuv_s(&x->e_mbd, bsize);
@@ -2211,6 +2484,12 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
}
+#if CONFIG_SB8X8
+ if (xd->mode_info_context->mbmi.mode == I4X4_PRED) {
+ assert(bsize == BLOCK_SIZE_SB8X8);
+ vp9_tokenize_sb(cpi, &x->e_mbd, t, !output_enabled, bsize);
+ } else
+#endif
if (!x->skip) {
vp9_subtract_sb(x, bsize);
@@ -2263,15 +2542,23 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
break;
case TX_8X8:
vp9_transform_sby_8x8(x, bsize);
- vp9_transform_sbuv_8x8(x, bsize);
vp9_quantize_sby_8x8(x, bsize);
- vp9_quantize_sbuv_8x8(x, bsize);
- if (x->optimize) {
+ if (x->optimize)
vp9_optimize_sby_8x8(cm, x, bsize);
- vp9_optimize_sbuv_8x8(cm, x, bsize);
- }
vp9_inverse_transform_sby_8x8(xd, bsize);
- vp9_inverse_transform_sbuv_8x8(xd, bsize);
+ if (bsize >= BLOCK_SIZE_MB16X16) {
+ vp9_transform_sbuv_8x8(x, bsize);
+ vp9_quantize_sbuv_8x8(x, bsize);
+ if (x->optimize)
+ vp9_optimize_sbuv_8x8(cm, x, bsize);
+ vp9_inverse_transform_sbuv_8x8(xd, bsize);
+ } else {
+ vp9_transform_sbuv_4x4(x, bsize);
+ vp9_quantize_sbuv_4x4(x, bsize);
+ if (x->optimize)
+ vp9_optimize_sbuv_4x4(cm, x, bsize);
+ vp9_inverse_transform_sbuv_4x4(xd, bsize);
+ }
break;
case TX_4X4:
vp9_transform_sby_4x4(x, bsize);
@@ -2314,8 +2601,10 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
if (bsize >= BLOCK_SIZE_SB32X32) {
cpi->txfm_count_32x32p[mi->mbmi.txfm_size]++;
- } else {
+ } else if (bsize >= BLOCK_SIZE_MB16X16) {
cpi->txfm_count_16x16p[mi->mbmi.txfm_size]++;
+ } else {
+ cpi->txfm_count_8x8p[mi->mbmi.txfm_size]++;
}
} else {
int x, y;
@@ -2323,6 +2612,8 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32)
sz = TX_16X16;
+ if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16)
+ sz = TX_8X8;
for (y = 0; y < bh; y++) {
for (x = 0; x < bw; x++) {
diff --git a/vp9/encoder/vp9_encodeintra.c b/vp9/encoder/vp9_encodeintra.c
index 54c4f3635..58a6b2a91 100644
--- a/vp9/encoder/vp9_encodeintra.c
+++ b/vp9/encoder/vp9_encodeintra.c
@@ -16,48 +16,53 @@
#include "vp9/common/vp9_invtrans.h"
#include "vp9/encoder/vp9_encodeintra.h"
-static void encode_intra4x4block(MACROBLOCK *x, int ib);
+static void encode_intra4x4block(MACROBLOCK *x, int ib, BLOCK_SIZE_TYPE bs);
int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) {
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
(void) cpi;
+#if !CONFIG_SB8X8
if (use_16x16_pred) {
+#endif
mbmi->mode = DC_PRED;
mbmi->uv_mode = DC_PRED;
mbmi->ref_frame = INTRA_FRAME;
vp9_encode_intra16x16mby(&cpi->common, x);
+#if !CONFIG_SB8X8
} else {
int i;
for (i = 0; i < 16; i++) {
x->e_mbd.mode_info_context->bmi[i].as_mode.first = B_DC_PRED;
- encode_intra4x4block(x, i);
+ encode_intra4x4block(x, i, BLOCK_SIZE_MB16X16);
}
}
+#endif
return vp9_get_mb_ss(x->plane[0].src_diff);
}
-static void encode_intra4x4block(MACROBLOCK *x, int ib) {
+static void encode_intra4x4block(MACROBLOCK *x, int ib,
+ BLOCK_SIZE_TYPE bsize) {
MACROBLOCKD * const xd = &x->e_mbd;
TX_TYPE tx_type;
uint8_t* const src =
- raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib,
+ raster_block_offset_uint8(xd, bsize, 0, ib,
x->plane[0].src.buf, x->plane[0].src.stride);
uint8_t* const dst =
- raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib,
+ raster_block_offset_uint8(xd, bsize, 0, ib,
xd->plane[0].dst.buf, xd->plane[0].dst.stride);
int16_t* const src_diff =
- raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib,
+ raster_block_offset_int16(xd, bsize, 0, ib,
x->plane[0].src_diff);
int16_t* const diff =
- raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib,
+ raster_block_offset_int16(xd, bsize, 0, ib,
xd->plane[0].diff);
int16_t* const coeff = BLOCK_OFFSET(x->plane[0].coeff, ib, 16);
- assert(ib < 16);
+ assert(ib < (16 >> (2 * CONFIG_SB8X8)));
#if CONFIG_NEWBINTRAMODES
xd->mode_info_context->bmi[ib].as_mode.context =
@@ -67,32 +72,34 @@ static void encode_intra4x4block(MACROBLOCK *x, int ib) {
vp9_intra4x4_predict(&x->e_mbd, ib,
xd->mode_info_context->bmi[ib].as_mode.first,
dst, xd->plane[0].dst.stride);
- vp9_subtract_block(4, 4, src_diff, 16,
+ vp9_subtract_block(4, 4, src_diff, 16 >> CONFIG_SB8X8,
src, x->plane[0].src.stride,
dst, xd->plane[0].dst.stride);
tx_type = get_tx_type_4x4(&x->e_mbd, ib);
if (tx_type != DCT_DCT) {
- vp9_short_fht4x4(src_diff, coeff, 16, tx_type);
+ vp9_short_fht4x4(src_diff, coeff, 16 >> CONFIG_SB8X8, tx_type);
x->quantize_b_4x4(x, ib, tx_type, 16);
vp9_short_iht4x4(BLOCK_OFFSET(xd->plane[0].dqcoeff, ib, 16),
- diff, 16, tx_type);
+ diff, 16 >> CONFIG_SB8X8, tx_type);
} else {
- x->fwd_txm4x4(src_diff, coeff, 32);
+ x->fwd_txm4x4(src_diff, coeff, 32 >> CONFIG_SB8X8);
x->quantize_b_4x4(x, ib, tx_type, 16);
vp9_inverse_transform_b_4x4(&x->e_mbd, xd->plane[0].eobs[ib],
BLOCK_OFFSET(xd->plane[0].dqcoeff, ib, 16),
- diff, 32);
+ diff, 32 >> CONFIG_SB8X8);
}
vp9_recon_b(dst, diff, dst, xd->plane[0].dst.stride);
}
-void vp9_encode_intra4x4mby(MACROBLOCK *mb) {
+void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bsize) {
int i;
+ int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
+ int bc = 1 << (bwl + bhl);
- for (i = 0; i < 16; i++)
- encode_intra4x4block(mb, i);
+ for (i = 0; i < bc; i++)
+ encode_intra4x4block(mb, i, bsize);
}
void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x) {
@@ -156,6 +163,7 @@ void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x) {
vp9_recon_sbuv(xd, BLOCK_SIZE_MB16X16);
}
+#if !CONFIG_SB8X8
void vp9_encode_intra8x8(MACROBLOCK *x, int ib) {
MACROBLOCKD *xd = &x->e_mbd;
uint8_t* const src =
@@ -301,3 +309,4 @@ void vp9_encode_intra8x8mbuv(MACROBLOCK *x) {
encode_intra_uv4x4(x, i + 20, mode); // v
}
}
+#endif
diff --git a/vp9/encoder/vp9_encodeintra.h b/vp9/encoder/vp9_encodeintra.h
index 6576c94d2..a4f4c184b 100644
--- a/vp9/encoder/vp9_encodeintra.h
+++ b/vp9/encoder/vp9_encodeintra.h
@@ -16,9 +16,11 @@
int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred);
void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x);
void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x);
-void vp9_encode_intra4x4mby(MACROBLOCK *mb);
+void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bs);
+#if !CONFIG_SB8X8
void vp9_encode_intra8x8mby(MACROBLOCK *x);
void vp9_encode_intra8x8mbuv(MACROBLOCK *x);
void vp9_encode_intra8x8(MACROBLOCK *x, int ib);
+#endif
#endif // VP9_ENCODER_VP9_ENCODEINTRA_H_
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 0cb1ae958..5e7437e6b 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -677,6 +677,7 @@ void vp9_optimize_sbuv_4x4(VP9_COMMON *const cm, MACROBLOCK *x,
}
}
+#if !CONFIG_SB8X8
void vp9_fidct_mb(VP9_COMMON *const cm, MACROBLOCK *x) {
MACROBLOCKD *const xd = &x->e_mbd;
const TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
@@ -735,6 +736,7 @@ void vp9_encode_inter16x16(VP9_COMMON *const cm, MACROBLOCK *x,
vp9_fidct_mb(cm, x);
vp9_recon_sb(xd, BLOCK_SIZE_MB16X16);
}
+#endif
/* this function is used by first pass only */
void vp9_encode_inter16x16y(MACROBLOCK *x, int mi_row, int mi_col) {
diff --git a/vp9/encoder/vp9_encodemb.h b/vp9/encoder/vp9_encodemb.h
index da134a86b..cd206592f 100644
--- a/vp9/encoder/vp9_encodemb.h
+++ b/vp9/encoder/vp9_encodemb.h
@@ -24,8 +24,10 @@ typedef struct {
struct VP9_ENCODER_RTCD;
+#if !CONFIG_SB8X8
void vp9_encode_inter16x16(VP9_COMMON *const cm, MACROBLOCK *x,
int mb_row, int mb_col);
+#endif
void vp9_encode_inter16x16y(MACROBLOCK *x, int mb_row, int mb_col);
@@ -54,7 +56,9 @@ void vp9_transform_sbuv_4x4(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize);
void vp9_optimize_sbuv_4x4(VP9_COMMON *const cm, MACROBLOCK *x,
BLOCK_SIZE_TYPE bsize);
+#if !CONFIG_SB8X8
void vp9_fidct_mb(VP9_COMMON *const cm, MACROBLOCK *x);
+#endif
void vp9_subtract_block(int rows, int cols,
int16_t *diff_ptr, int diff_stride,
diff --git a/vp9/encoder/vp9_modecosts.c b/vp9/encoder/vp9_modecosts.c
index 7d9462f94..88cd1f41b 100644
--- a/vp9/encoder/vp9_modecosts.c
+++ b/vp9/encoder/vp9_modecosts.c
@@ -41,8 +41,10 @@ void vp9_init_mode_costs(VP9_COMP *c) {
x->fc.uv_mode_prob[VP9_YMODES - 1], vp9_uv_mode_tree);
vp9_cost_tokens(c->mb.intra_uv_mode_cost[0],
x->kf_uv_mode_prob[VP9_YMODES - 1], vp9_uv_mode_tree);
+#if !CONFIG_SB8X8
vp9_cost_tokens(c->mb.i8x8_mode_costs,
x->fc.i8x8_mode_prob, vp9_i8x8_mode_tree);
+#endif
for (i = 0; i <= VP9_SWITCHABLE_FILTERS; ++i)
vp9_cost_tokens((int *)c->mb.switchable_interp_costs[i],
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 865cd8a38..ceca60d70 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -626,7 +626,9 @@ static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode, int speed) {
sf->thresh_mult[THR_D63_PRED ] += speed_multiplier * 1500;
sf->thresh_mult[THR_B_PRED ] += speed_multiplier * 2500;
+#if !CONFIG_SB8X8
sf->thresh_mult[THR_I8X8_PRED] += speed_multiplier * 2500;
+#endif
sf->thresh_mult[THR_NEWMV ] += speed_multiplier * 1000;
sf->thresh_mult[THR_NEWG ] += speed_multiplier * 1000;
@@ -980,22 +982,7 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) {
static void update_frame_size(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
- const int aligned_width = multiple16(cm->width);
- const int aligned_height = multiple16(cm->height);
-
- cm->mb_rows = aligned_height >> 4;
- cm->mi_rows = aligned_height >> LOG2_MI_SIZE;
- cm->mb_cols = aligned_width >> 4;
- cm->mi_cols = aligned_width >> LOG2_MI_SIZE;
- cm->MBs = cm->mb_rows * cm->mb_cols;
- cm->mode_info_stride = cm->mi_cols + 1;
- memset(cm->mip, 0,
- cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO));
- vp9_update_mode_info_border(cm, cm->mip);
-
- cm->mi = cm->mip + cm->mode_info_stride + 1;
- cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1;
- vp9_update_mode_info_in_image(cm, cm->mi);
+ vp9_update_frame_size(cm);
// Update size of buffers local to this frame
if (vp8_yv12_realloc_frame_buffer(&cpi->last_frame_uf,
@@ -1205,7 +1192,7 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
// cpi->use_last_frame_only = 0;
cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 1;
- cm->refresh_entropy_probs = 1;
+ cm->refresh_frame_context = 1;
setup_features(cpi);
cpi->mb.e_mbd.allow_high_precision_mv = 0; // Default mv precision adaptation
@@ -2135,10 +2122,7 @@ int vp9_set_reference_enc(VP9_PTR ptr, VP9_REFFRAME ref_frame_flag,
return 0;
}
int vp9_update_entropy(VP9_PTR comp, int update) {
- VP9_COMP *cpi = (VP9_COMP *) comp;
- VP9_COMMON *cm = &cpi->common;
- cm->refresh_entropy_probs = update;
-
+ ((VP9_COMP *)comp)->common.refresh_frame_context = update;
return 0;
}
@@ -2751,7 +2735,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
(cpi->oxcf.frame_parallel_decoding_mode != 0);
if (cm->error_resilient_mode) {
cm->frame_parallel_decoding_mode = 1;
- cm->refresh_entropy_probs = 0;
+ cm->refresh_frame_context = 0;
}
}
@@ -3342,9 +3326,13 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_copy(cpi->common.fc.ymode_counts, cpi->ymode_count);
vp9_copy(cpi->common.fc.uv_mode_counts, cpi->y_uv_mode_count);
vp9_copy(cpi->common.fc.bmode_counts, cpi->bmode_count);
+#if !CONFIG_SB8X8
vp9_copy(cpi->common.fc.i8x8_mode_counts, cpi->i8x8_mode_count);
+#endif
vp9_copy(cpi->common.fc.sub_mv_ref_counts, cpi->sub_mv_ref_count);
+#if !CONFIG_SB8X8
vp9_copy(cpi->common.fc.mbsplit_counts, cpi->mbsplit_count);
+#endif
vp9_copy(cpi->common.fc.partition_counts, cpi->partition_count);
#if CONFIG_COMP_INTERINTRA_PRED
vp9_copy(cpi->common.fc.interintra_counts, cpi->interintra_count);
@@ -3733,7 +3721,7 @@ static int frame_is_reference(const VP9_COMP *cpi) {
cpi->refresh_last_frame ||
cpi->refresh_golden_frame ||
cpi->refresh_alt_ref_frame ||
- cm->refresh_entropy_probs ||
+ cm->refresh_frame_context ||
mb->mode_ref_lf_delta_update ||
mb->update_mb_segmentation_map ||
mb->update_mb_segmentation_data;
@@ -4003,17 +3991,15 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
}
- if (cm->refresh_entropy_probs) {
- vpx_memcpy(&cm->frame_contexts[cm->frame_context_idx], &cm->fc,
- sizeof(cm->fc));
- }
+ if (cm->refresh_frame_context)
+ cm->frame_contexts[cm->frame_context_idx] = cm->fc;
if (*size > 0) {
// if its a dropped frame honor the requests on subsequent frames
cpi->droppable = !frame_is_reference(cpi);
// return to normal state
- cm->refresh_entropy_probs = 1;
+ cm->refresh_frame_context = 1;
cpi->refresh_alt_ref_frame = 0;
cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 1;
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index aeaf1bda3..541127e51 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -48,9 +48,9 @@
#define KEY_FRAME_CONTEXT 5
#if CONFIG_COMP_INTERINTRA_PRED
-#define MAX_MODES 54
+#define MAX_MODES 54 - CONFIG_SB8X8
#else
-#define MAX_MODES 42
+#define MAX_MODES 42 - CONFIG_SB8X8
#endif
#define MIN_THRESHMULT 32
@@ -72,7 +72,9 @@ typedef struct {
// Stats
int y_modes[VP9_YMODES];
int uv_modes[VP9_UV_MODES];
+#if !CONFIG_SB8X8
int i8x8_modes[VP9_I8X8_MODES];
+#endif
int b_modes[B_MODE_COUNT];
int inter_y_modes[MB_MODE_COUNT];
int inter_uv_modes[VP9_UV_MODES];
@@ -100,9 +102,13 @@ typedef struct {
vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1];
+#if !CONFIG_SB8X8
vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1];
+#endif
vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
+#if !CONFIG_SB8X8
vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1];
+#endif
vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
@@ -207,7 +213,9 @@ typedef enum {
THR_SPLITA,
THR_B_PRED,
+#if !CONFIG_SB8X8
THR_I8X8_PRED,
+#endif
THR_COMP_ZEROLG,
THR_COMP_NEARESTLG,
@@ -273,10 +281,17 @@ typedef struct {
} SPEED_FEATURES;
enum BlockSize {
+#if CONFIG_SB8X8
+ BLOCK_4X4,
+ BLOCK_8X8,
+ BLOCK_8X16,
+ BLOCK_16X8,
+#else
BLOCK_16X8 = PARTITIONING_16X8,
BLOCK_8X16 = PARTITIONING_8X16,
BLOCK_8X8 = PARTITIONING_8X8,
BLOCK_4X4 = PARTITIONING_4X4,
+#endif
BLOCK_16X16,
BLOCK_MAX_SEGMENTS,
BLOCK_32X32 = BLOCK_MAX_SEGMENTS,
@@ -451,9 +466,13 @@ typedef struct VP9_COMP {
int sb_ymode_count [VP9_I32X32_MODES];
int ymode_count[VP9_YMODES]; /* intra MB type cts this frame */
int bmode_count[VP9_NKF_BINTRAMODES];
+#if !CONFIG_SB8X8
int i8x8_mode_count[VP9_I8X8_MODES];
+#endif
int sub_mv_ref_count[SUBMVREF_COUNT][VP9_SUBMVREFS];
+#if !CONFIG_SB8X8
int mbsplit_count[VP9_NUMMBSPLITS];
+#endif
int y_uv_mode_count[VP9_YMODES][VP9_UV_MODES];
unsigned int partition_count[NUM_PARTITION_CONTEXTS][PARTITION_TYPES];
#if CONFIG_COMP_INTERINTRA_PRED
diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c
index ece131898..b36a4bc34 100644
--- a/vp9/encoder/vp9_quantize.c
+++ b/vp9/encoder/vp9_quantize.c
@@ -223,9 +223,9 @@ void vp9_quantize_sbuv_16x16(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
}
void vp9_quantize_sbuv_8x8(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
- const int bwl = b_width_log2(bsize) - 2;
- const int bhl = b_height_log2(bsize) - 2;
- const int uoff = 16 << (bhl + bwl);
+ const int bwl = b_width_log2(bsize) - 1;
+ const int bhl = b_height_log2(bsize) - 1;
+ const int uoff = 4 << (bhl + bwl);
int i;
for (i = uoff; i < ((uoff * 3) >> 1); i += 4)
@@ -233,9 +233,9 @@ void vp9_quantize_sbuv_8x8(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
}
void vp9_quantize_sbuv_4x4(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize) {
- const int bwl = b_width_log2(bsize) - 2;
- const int bhl = b_height_log2(bsize) - 2;
- const int uoff = 16 << (bhl + bwl);
+ const int bwl = b_width_log2(bsize);
+ const int bhl = b_height_log2(bsize);
+ const int uoff = 1 << (bhl + bwl);
int i;
for (i = uoff; i < ((uoff * 3) >> 1); i++)
@@ -286,7 +286,7 @@ void vp9_init_quantizer(VP9_COMP *cpi) {
cpi->common.y_dequant[q][0] = quant_val;
cpi->zrun_zbin_boost_y1[q][0] = (quant_val * zbin_boost[0]) >> 7;
- quant_val = vp9_dc_uv_quant(q, cpi->common.uv_dc_delta_q);
+ quant_val = vp9_dc_quant(q, cpi->common.uv_dc_delta_q);
invert_quant(cpi->UVquant[q] + 0, cpi->UVquant_shift[q] + 0, quant_val);
cpi->UVzbin[q][0] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
cpi->UVround[q][0] = (qrounding_factor * quant_val) >> 7;
@@ -297,7 +297,7 @@ void vp9_init_quantizer(VP9_COMP *cpi) {
for (i = 1; i < 16; i++) {
int rc = vp9_default_zig_zag1d_4x4[i];
- quant_val = vp9_ac_yquant(q);
+ quant_val = vp9_ac_quant(q, 0);
invert_quant(cpi->Y1quant[q] + rc, cpi->Y1quant_shift[q] + rc, quant_val);
cpi->Y1zbin[q][rc] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
cpi->Y1round[q][rc] = (qrounding_factor * quant_val) >> 7;
@@ -305,7 +305,7 @@ void vp9_init_quantizer(VP9_COMP *cpi) {
cpi->zrun_zbin_boost_y1[q][i] =
ROUND_POWER_OF_TWO(quant_val * zbin_boost[i], 7);
- quant_val = vp9_ac_uv_quant(q, cpi->common.uv_ac_delta_q);
+ quant_val = vp9_ac_quant(q, cpi->common.uv_ac_delta_q);
invert_quant(cpi->UVquant[q] + rc, cpi->UVquant_shift[q] + rc, quant_val);
cpi->UVzbin[q][rc] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
cpi->UVround[q][rc] = (qrounding_factor * quant_val) >> 7;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index f59385232..42d339dfb 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -89,7 +89,7 @@ static const unsigned int prior_key_frame_weight[KEY_FRAME_CONTEXT] = { 1, 2, 3,
// tables if and when things settle down in the experimental bitstream
double vp9_convert_qindex_to_q(int qindex) {
// Convert the index to a real Q value (scaled down to match old Q values)
- return vp9_ac_yquant(qindex) / 4.0;
+ return vp9_ac_quant(qindex, 0) / 4.0;
}
int vp9_gfboost_qadjust(int qindex) {
@@ -138,9 +138,13 @@ void vp9_save_coding_context(VP9_COMP *cpi) {
vp9_copy(cc->sb_ymode_prob, cm->fc.sb_ymode_prob);
vp9_copy(cc->bmode_prob, cm->fc.bmode_prob);
vp9_copy(cc->uv_mode_prob, cm->fc.uv_mode_prob);
+#if !CONFIG_SB8X8
vp9_copy(cc->i8x8_mode_prob, cm->fc.i8x8_mode_prob);
+#endif
vp9_copy(cc->sub_mv_ref_prob, cm->fc.sub_mv_ref_prob);
+#if !CONFIG_SB8X8
vp9_copy(cc->mbsplit_prob, cm->fc.mbsplit_prob);
+#endif
vp9_copy(cc->partition_prob, cm->fc.partition_prob);
// Stats
@@ -198,10 +202,14 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
vp9_copy(cm->fc.ymode_prob, cc->ymode_prob);
vp9_copy(cm->fc.sb_ymode_prob, cc->sb_ymode_prob);
vp9_copy(cm->fc.bmode_prob, cc->bmode_prob);
+#if !CONFIG_SB8X8
vp9_copy(cm->fc.i8x8_mode_prob, cc->i8x8_mode_prob);
+#endif
vp9_copy(cm->fc.uv_mode_prob, cc->uv_mode_prob);
vp9_copy(cm->fc.sub_mv_ref_prob, cc->sub_mv_ref_prob);
+#if !CONFIG_SB8X8
vp9_copy(cm->fc.mbsplit_prob, cc->mbsplit_prob);
+#endif
vp9_copy(cm->fc.partition_prob, cc->partition_prob);
// Stats
@@ -262,8 +270,7 @@ void vp9_setup_inter_frame(VP9_COMP *cpi) {
vp9_setup_past_independence(cm, xd);
assert(cm->frame_context_idx < NUM_FRAME_CONTEXTS);
- vpx_memcpy(&cm->fc, &cm->frame_contexts[cm->frame_context_idx],
- sizeof(cm->fc));
+ cm->fc = cm->frame_contexts[cm->frame_context_idx];
}
static int estimate_bits_at_q(int frame_kind, int q, int mbs,
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 92b0cf184..da78be14a 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -105,7 +105,9 @@ const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
{SPLITMV, ALTREF_FRAME, NONE},
{I4X4_PRED, INTRA_FRAME, NONE},
+#if !CONFIG_SB8X8
{I8X8_PRED, INTRA_FRAME, NONE},
+#endif
/* compound prediction modes */
{ZEROMV, LAST_FRAME, GOLDEN_FRAME},
@@ -187,7 +189,7 @@ void vp9_init_me_luts() {
}
static int compute_rd_mult(int qindex) {
- int q = vp9_dc_quant(qindex, 0);
+ const int q = vp9_dc_quant(qindex, 0);
return (11 * q * q) >> 2;
}
@@ -563,17 +565,19 @@ static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
rd[TX_32X32][1] < rd[TX_4X4][1]))) {
mbmi->txfm_size = TX_32X32;
- } else if ( cm->txfm_mode == ALLOW_16X16 ||
- (max_txfm_size == TX_16X16 && cm->txfm_mode == ALLOW_32X32) ||
- (cm->txfm_mode == TX_MODE_SELECT &&
- rd[TX_16X16][1] < rd[TX_8X8][1] &&
- rd[TX_16X16][1] < rd[TX_4X4][1])) {
+ } else if (max_txfm_size >= TX_16X16 &&
+ (cm->txfm_mode == ALLOW_16X16 ||
+ cm->txfm_mode == ALLOW_32X32 ||
+ (cm->txfm_mode == TX_MODE_SELECT &&
+ rd[TX_16X16][1] < rd[TX_8X8][1] &&
+ rd[TX_16X16][1] < rd[TX_4X4][1]))) {
mbmi->txfm_size = TX_16X16;
} else if (cm->txfm_mode == ALLOW_8X8 ||
+ cm->txfm_mode == ALLOW_16X16 ||
+ cm->txfm_mode == ALLOW_32X32 ||
(cm->txfm_mode == TX_MODE_SELECT && rd[TX_8X8][1] < rd[TX_4X4][1])) {
mbmi->txfm_size = TX_8X8;
} else {
- assert(cm->txfm_mode == ONLY_4X4 || cm->txfm_mode == TX_MODE_SELECT);
mbmi->txfm_size = TX_4X4;
}
@@ -583,13 +587,14 @@ static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
txfm_cache[ONLY_4X4] = rd[TX_4X4][0];
txfm_cache[ALLOW_8X8] = rd[TX_8X8][0];
- txfm_cache[ALLOW_16X16] = rd[TX_16X16][0];
- txfm_cache[ALLOW_32X32] = rd[max_txfm_size][0];
+ txfm_cache[ALLOW_16X16] = rd[MIN(max_txfm_size, TX_16X16)][0];
+ txfm_cache[ALLOW_32X32] = rd[MIN(max_txfm_size, TX_32X32)][0];
if (max_txfm_size == TX_32X32 &&
rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
rd[TX_32X32][1] < rd[TX_4X4][1])
txfm_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
- else if (rd[TX_16X16][1] < rd[TX_8X8][1] && rd[TX_16X16][1] < rd[TX_4X4][1])
+ else if (max_txfm_size >= TX_16X16 &&
+ rd[TX_16X16][1] < rd[TX_8X8][1] && rd[TX_16X16][1] < rd[TX_4X4][1])
txfm_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
else
txfm_cache[TX_MODE_SELECT] = rd[TX_4X4][1] < rd[TX_8X8][1] ?
@@ -794,12 +799,18 @@ static void super_block_yrd(VP9_COMP *cpi,
if (bs >= BLOCK_SIZE_SB32X32)
super_block_yrd_32x32(cm, x, &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32],
bs);
- super_block_yrd_16x16(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16], bs);
+ if (bs >= BLOCK_SIZE_MB16X16)
+ super_block_yrd_16x16(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16],
+ bs);
super_block_yrd_8x8(cm, x, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8], bs);
super_block_yrd_4x4(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4], bs);
choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s, skip, txfm_cache,
- TX_32X32 - (bs < BLOCK_SIZE_SB32X32));
+ TX_32X32 - (bs < BLOCK_SIZE_SB32X32)
+#if CONFIG_SB8X8
+ - (bs < BLOCK_SIZE_MB16X16)
+#endif
+ );
}
static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
@@ -816,17 +827,41 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
VP9_COMMON *const cm = &cpi->common;
const int src_stride = x->plane[0].src.stride;
uint8_t* const src =
- raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib,
+ raster_block_offset_uint8(xd,
+#if CONFIG_SB8X8
+ BLOCK_SIZE_SB8X8,
+#else
+ BLOCK_SIZE_MB16X16,
+#endif
+ 0, ib,
x->plane[0].src.buf, src_stride);
int16_t* const src_diff =
- raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib,
+ raster_block_offset_int16(xd,
+#if CONFIG_SB8X8
+ BLOCK_SIZE_SB8X8,
+#else
+ BLOCK_SIZE_MB16X16,
+#endif
+ 0, ib,
x->plane[0].src_diff);
int16_t* const diff =
- raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib,
+ raster_block_offset_int16(xd,
+#if CONFIG_SB8X8
+ BLOCK_SIZE_SB8X8,
+#else
+ BLOCK_SIZE_MB16X16,
+#endif
+ 0, ib,
xd->plane[0].diff);
int16_t* const coeff = BLOCK_OFFSET(x->plane[0].coeff, ib, 16);
uint8_t* const dst =
- raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib,
+ raster_block_offset_uint8(xd,
+#if CONFIG_SB8X8
+ BLOCK_SIZE_SB8X8,
+#else
+ BLOCK_SIZE_MB16X16,
+#endif
+ 0, ib,
xd->plane[0].dst.buf, xd->plane[0].dst.stride);
ENTROPY_CONTEXT ta = *a, tempa = *a;
ENTROPY_CONTEXT tl = *l, templ = *l;
@@ -839,7 +874,7 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
* */
DECLARE_ALIGNED_ARRAY(16, int16_t, best_dqcoeff, 16);
- assert(ib < 16);
+ assert(ib < (16 >> (2 * CONFIG_SB8X8)));
#if CONFIG_NEWBINTRAMODES
xd->mode_info_context->bmi[ib].as_mode.context =
vp9_find_bpred_context(xd, ib, dst, xd->plane[0].dst.stride);
@@ -868,17 +903,17 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
#endif
vp9_intra4x4_predict(xd, ib, mode, dst, xd->plane[0].dst.stride);
- vp9_subtract_block(4, 4, src_diff, 16,
+ vp9_subtract_block(4, 4, src_diff, 16 >> CONFIG_SB8X8,
src, src_stride,
dst, xd->plane[0].dst.stride);
xd->mode_info_context->bmi[ib].as_mode.first = mode;
tx_type = get_tx_type_4x4(xd, ib);
if (tx_type != DCT_DCT) {
- vp9_short_fht4x4(src_diff, coeff, 16, tx_type);
+ vp9_short_fht4x4(src_diff, coeff, 16 >> CONFIG_SB8X8, tx_type);
x->quantize_b_4x4(x, ib, tx_type, 16);
} else {
- x->fwd_txm4x4(src_diff, coeff, 32);
+ x->fwd_txm4x4(src_diff, coeff, 32 >> CONFIG_SB8X8);
x->quantize_b_4x4(x, ib, tx_type, 16);
}
@@ -911,9 +946,9 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
// inverse transform
if (best_tx_type != DCT_DCT)
- vp9_short_iht4x4(best_dqcoeff, diff, 16, best_tx_type);
+ vp9_short_iht4x4(best_dqcoeff, diff, 16 >> CONFIG_SB8X8, best_tx_type);
else
- xd->inv_txm4x4(best_dqcoeff, diff, 32);
+ xd->inv_txm4x4(best_dqcoeff, diff, 32 >> CONFIG_SB8X8);
vp9_intra4x4_predict(xd, ib, *best_mode,
dst, xd->plane[0].dst.stride);
@@ -932,7 +967,7 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb,
int distortion = 0;
int tot_rate_y = 0;
int64_t total_rd = 0;
- ENTROPY_CONTEXT t_above[4], t_left[4];
+ ENTROPY_CONTEXT t_above[4 >> CONFIG_SB8X8], t_left[4 >> CONFIG_SB8X8];
int *bmode_costs;
vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
@@ -941,15 +976,21 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb,
xd->mode_info_context->mbmi.mode = I4X4_PRED;
bmode_costs = mb->inter_bmode_costs;
- for (i = 0; i < 16; i++) {
- const int x_idx = i & 3, y_idx = i >> 2;
+ for (i = 0; i < (16 >> (2 * CONFIG_SB8X8)); i++) {
+ const int x_idx = i & (3 >> CONFIG_SB8X8), y_idx = i >> (2 >> CONFIG_SB8X8);
MODE_INFO *const mic = xd->mode_info_context;
const int mis = xd->mode_info_stride;
B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(ry), UNINITIALIZED_IS_SAFE(d);
#if CONFIG_NEWBINTRAMODES
uint8_t* const dst =
- raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, i,
+ raster_block_offset_uint8(xd,
+#if CONFIG_SB8X8
+ BLOCK_SIZE_SB8X8,
+#else
+ BLOCK_SIZE_MB16X16,
+#endif
+ 0, i,
xd->plane[0].dst.buf,
xd->plane[0].dst.stride);
#endif
@@ -1046,6 +1087,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
return best_rd;
}
+#if !CONFIG_SB8X8
static int64_t rd_pick_intra8x8block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
B_PREDICTION_MODE *best_mode,
int *mode_costs,
@@ -1283,6 +1325,7 @@ static int64_t rd_pick_intra8x8mby_modes_and_txsz(VP9_COMP *cpi, MACROBLOCK *x,
return tmp_rd;
}
+#endif // !CONFIG_SB8X8
static int rd_cost_sbuv_4x4(VP9_COMMON *const cm, MACROBLOCK *x,
BLOCK_SIZE_TYPE bsize) {
@@ -1457,10 +1500,9 @@ static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x,
super_block_uvrd_32x32(cm, x, rate, distortion, skippable, bsize);
} else if (mbmi->txfm_size >= TX_16X16 && bsize >= BLOCK_SIZE_SB32X32) {
super_block_uvrd_16x16(cm, x, rate, distortion, skippable, bsize);
- } else if (mbmi->txfm_size >= TX_8X8) {
+ } else if (mbmi->txfm_size >= TX_8X8 && bsize >= BLOCK_SIZE_MB16X16) {
super_block_uvrd_8x8(cm, x, rate, distortion, skippable, bsize);
} else {
- assert(mbmi->txfm_size == TX_4X4);
super_block_uvrd_4x4(cm, x, rate, distortion, skippable, bsize);
}
}
@@ -1524,6 +1566,514 @@ void vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) {
x->e_mbd.mode_info_context->mbmi.mv[0].as_int = mv->as_int;
}
+#if CONFIG_SB8X8
+static int labels2mode(MACROBLOCK *x,
+ int const *labelings, int which_label,
+ B_PREDICTION_MODE this_mode,
+ int_mv *this_mv, int_mv *this_second_mv,
+ int_mv seg_mvs[MAX_REF_FRAMES - 1],
+ int_mv *best_ref_mv,
+ int_mv *second_best_ref_mv,
+ int *mvjcost, int *mvcost[2], VP9_COMP *cpi) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MODE_INFO *const mic = xd->mode_info_context;
+ MB_MODE_INFO * mbmi = &mic->mbmi;
+ const int mis = xd->mode_info_stride;
+ int i, cost = 0, thismvcost = 0;
+
+ /* We have to be careful retrieving previously-encoded motion vectors.
+ Ones from this macroblock have to be pulled from the BLOCKD array
+ as they have not yet made it to the bmi array in our MB_MODE_INFO. */
+ for (i = 0; i < 4; ++i) {
+ const int row = i >> 1, col = i & 1;
+ B_PREDICTION_MODE m;
+
+ if (labelings[i] != which_label)
+ continue;
+
+ if (col && labelings[i] == labelings[i - 1])
+ m = LEFT4X4;
+ else if (row && labelings[i] == labelings[i - 2])
+ m = ABOVE4X4;
+ else {
+ // the only time we should do costing for new motion vector or mode
+ // is when we are on a new label (jbb May 08, 2007)
+ switch (m = this_mode) {
+ case NEW4X4 :
+ if (mbmi->second_ref_frame > 0) {
+ this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int;
+ this_second_mv->as_int =
+ seg_mvs[mbmi->second_ref_frame - 1].as_int;
+ }
+
+ thismvcost = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
+ 102, xd->allow_high_precision_mv);
+ if (mbmi->second_ref_frame > 0) {
+ thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
+ mvjcost, mvcost, 102,
+ xd->allow_high_precision_mv);
+ }
+ break;
+ case LEFT4X4:
+ this_mv->as_int = col ? mic->bmi[i - 1].as_mv[0].as_int :
+ left_block_mv(xd, mic, i);
+ if (mbmi->second_ref_frame > 0)
+ this_second_mv->as_int = col ? mic->bmi[i - 1].as_mv[1].as_int :
+ left_block_second_mv(xd, mic, i);
+ break;
+ case ABOVE4X4:
+ this_mv->as_int = row ? mic->bmi[i - 2].as_mv[0].as_int :
+ above_block_mv(mic, i, mis);
+ if (mbmi->second_ref_frame > 0)
+ this_second_mv->as_int = row ? mic->bmi[i - 2].as_mv[1].as_int :
+ above_block_second_mv(mic, i, mis);
+ break;
+ case ZERO4X4:
+ this_mv->as_int = 0;
+ if (mbmi->second_ref_frame > 0)
+ this_second_mv->as_int = 0;
+ break;
+ default:
+ break;
+ }
+
+ if (m == ABOVE4X4) { // replace above with left if same
+ int_mv left_mv, left_second_mv;
+
+ left_second_mv.as_int = 0;
+ left_mv.as_int = col ? mic->bmi[i - 1].as_mv[0].as_int :
+ left_block_mv(xd, mic, i);
+ if (mbmi->second_ref_frame > 0)
+ left_second_mv.as_int = col ? mic->bmi[i - 1].as_mv[1].as_int :
+ left_block_second_mv(xd, mic, i);
+
+ if (left_mv.as_int == this_mv->as_int &&
+ (mbmi->second_ref_frame <= 0 ||
+ left_second_mv.as_int == this_second_mv->as_int))
+ m = LEFT4X4;
+ }
+
+#if CONFIG_NEWBINTRAMODES
+ cost = x->inter_bmode_costs[m == B_CONTEXT_PRED ?
+ m - CONTEXT_PRED_REPLACEMENTS : m];
+#else
+ cost = x->inter_bmode_costs[m];
+#endif
+ }
+
+ mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
+ if (mbmi->second_ref_frame > 0)
+ mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
+
+ x->partition_info->bmi[i].mode = m;
+ x->partition_info->bmi[i].mv.as_int = this_mv->as_int;
+ if (mbmi->second_ref_frame > 0)
+ x->partition_info->bmi[i].second_mv.as_int = this_second_mv->as_int;
+ }
+
+ cost += thismvcost;
+ return cost;
+}
+
+static int64_t encode_inter_mb_segment(VP9_COMMON *const cm,
+ MACROBLOCK *x,
+ int const *labels,
+ int which_label,
+ int *labelyrate,
+ int *distortion,
+ ENTROPY_CONTEXT *ta,
+ ENTROPY_CONTEXT *tl) {
+ int i;
+ MACROBLOCKD *xd = &x->e_mbd;
+
+ *labelyrate = 0;
+ *distortion = 0;
+ for (i = 0; i < 4; i++) {
+ if (labels[i] == which_label) {
+ const int src_stride = x->plane[0].src.stride;
+ uint8_t* const src =
+ raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+ x->plane[0].src.buf, src_stride);
+ int16_t* const src_diff =
+ raster_block_offset_int16(xd, BLOCK_SIZE_SB8X8, 0, i,
+ x->plane[0].src_diff);
+ int16_t* const coeff = BLOCK_OFFSET(x->plane[0].coeff, 16, i);
+ uint8_t* const pre =
+ raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+ xd->plane[0].pre[0].buf,
+ xd->plane[0].pre[0].stride);
+ uint8_t* const dst =
+ raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+ xd->plane[0].dst.buf,
+ xd->plane[0].dst.stride);
+ int thisdistortion;
+
+ vp9_build_inter_predictor(pre,
+ xd->plane[0].pre[0].stride,
+ dst,
+ xd->plane[0].dst.stride,
+ &xd->mode_info_context->bmi[i].as_mv[0],
+ &xd->scale_factor[0],
+ 4, 4, 0 /* no avg */, &xd->subpix);
+
+ // TODO(debargha): Make this work properly with the
+ // implicit-compoundinter-weight experiment when implicit
+ // weighting for splitmv modes is turned on.
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
+ uint8_t* const second_pre =
+ raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i,
+ xd->plane[0].pre[1].buf,
+ xd->plane[0].pre[1].stride);
+ vp9_build_inter_predictor(second_pre, xd->plane[0].pre[1].stride,
+ dst, xd->plane[0].dst.stride,
+ &xd->mode_info_context->bmi[i].as_mv[1],
+ &xd->scale_factor[1], 4, 4, 1,
+ &xd->subpix);
+ }
+
+ vp9_subtract_block(4, 4, src_diff, 8,
+ src, src_stride,
+ dst, xd->plane[0].dst.stride);
+ x->fwd_txm4x4(src_diff, coeff, 16);
+ x->quantize_b_4x4(x, i, DCT_DCT, 16);
+ thisdistortion = vp9_block_error(coeff,
+ BLOCK_OFFSET(xd->plane[0].dqcoeff,
+ i, 16), 16);
+ *distortion += thisdistortion;
+ *labelyrate += cost_coeffs(cm, x, i, PLANE_TYPE_Y_WITH_DC,
+ ta + (i & 1),
+ tl + (i >> 1), TX_4X4, 16);
+ }
+ }
+ *distortion >>= 2;
+ return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
+}
+
+typedef struct {
+ int_mv *ref_mv, *second_ref_mv;
+ int_mv mvp;
+
+ int64_t segment_rd;
+ int r;
+ int d;
+ int segment_yrate;
+ B_PREDICTION_MODE modes[4];
+ int_mv mvs[4], second_mvs[4];
+ int eobs[4];
+
+ int mvthresh;
+ int *mdcounts;
+} BEST_SEG_INFO;
+#endif // CONFIG_SB8X8
+
+static INLINE int mv_check_bounds(MACROBLOCK *x, int_mv *mv) {
+ int r = 0;
+ r |= (mv->as_mv.row >> 3) < x->mv_row_min;
+ r |= (mv->as_mv.row >> 3) > x->mv_row_max;
+ r |= (mv->as_mv.col >> 3) < x->mv_col_min;
+ r |= (mv->as_mv.col >> 3) > x->mv_col_max;
+ return r;
+}
+
+#if CONFIG_SB8X8
+static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
+ BEST_SEG_INFO *bsi,
+ int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
+ int i, j;
+ static const int labels[4] = { 0, 1, 2, 3 };
+ int br = 0, bd = 0;
+ B_PREDICTION_MODE this_mode;
+ MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
+ const int label_count = 4;
+ int64_t this_segment_rd = 0, other_segment_rd;
+ int label_mv_thresh;
+ int rate = 0;
+ int sbr = 0, sbd = 0;
+ int segmentyrate = 0;
+ int best_eobs[4] = { 0 };
+
+ vp9_variance_fn_ptr_t *v_fn_ptr;
+
+ ENTROPY_CONTEXT t_above[2], t_left[2];
+ ENTROPY_CONTEXT t_above_b[2], t_left_b[2];
+
+ vpx_memcpy(t_above, x->e_mbd.plane[0].above_context, sizeof(t_above));
+ vpx_memcpy(t_left, x->e_mbd.plane[0].left_context, sizeof(t_left));
+
+ v_fn_ptr = &cpi->fn_ptr[BLOCK_4X4];
+
+ // 64 makes this threshold really big effectively
+ // making it so that we very rarely check mvs on
+ // segments. setting this to 1 would make mv thresh
+ // roughly equal to what it is for macroblocks
+ label_mv_thresh = 1 * bsi->mvthresh / label_count;
+
+ // Segmentation method overheads
+ rate += vp9_cost_mv_ref(cpi, SPLITMV,
+ mbmi->mb_mode_context[mbmi->ref_frame]);
+ this_segment_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
+ br += rate;
+ other_segment_rd = this_segment_rd;
+
+ for (i = 0; i < label_count && this_segment_rd < bsi->segment_rd; i++) {
+ int_mv mode_mv[B_MODE_COUNT], second_mode_mv[B_MODE_COUNT];
+ int64_t best_label_rd = INT64_MAX, best_other_rd = INT64_MAX;
+ B_PREDICTION_MODE mode_selected = ZERO4X4;
+ int bestlabelyrate = 0;
+
+ // search for the best motion vector on this segment
+ for (this_mode = LEFT4X4; this_mode <= NEW4X4; this_mode ++) {
+ int64_t this_rd;
+ int distortion;
+ int labelyrate;
+ ENTROPY_CONTEXT t_above_s[2], t_left_s[2];
+
+ vpx_memcpy(t_above_s, t_above, sizeof(t_above_s));
+ vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
+
+ // motion search for newmv (single predictor case only)
+ if (mbmi->second_ref_frame <= 0 && this_mode == NEW4X4) {
+ int sseshift, n;
+ int step_param = 0;
+ int further_steps;
+ int thissme, bestsme = INT_MAX;
+ const struct buf_2d orig_src = x->plane[0].src;
+ const struct buf_2d orig_pre = x->e_mbd.plane[0].pre[0];
+
+ /* Is the best so far sufficiently good that we cant justify doing
+ * and new motion search. */
+ if (best_label_rd < label_mv_thresh)
+ break;
+
+ if (cpi->compressor_speed) {
+ // use previous block's result as next block's MV predictor.
+ if (i > 0) {
+ bsi->mvp.as_int =
+ x->e_mbd.mode_info_context->bmi[i - 1].as_mv[0].as_int;
+ if (i == 2)
+ bsi->mvp.as_int =
+ x->e_mbd.mode_info_context->bmi[i - 2].as_mv[0].as_int;
+ step_param = 2;
+ }
+ }
+
+ further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
+
+ {
+ int sadpb = x->sadperbit4;
+ int_mv mvp_full;
+
+ mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
+ mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
+
+ // find first label
+ n = i;
+
+ // adjust src pointer for this segment
+ x->plane[0].src.buf =
+ raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, n,
+ x->plane[0].src.buf,
+ x->plane[0].src.stride);
+ assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0xf) == 0);
+ x->e_mbd.plane[0].pre[0].buf =
+ raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, n,
+ x->e_mbd.plane[0].pre[0].buf,
+ x->e_mbd.plane[0].pre[0].stride);
+
+ bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
+ sadpb, further_steps, 0, v_fn_ptr,
+ bsi->ref_mv, &mode_mv[NEW4X4]);
+
+ sseshift = 0;
+
+ // Should we do a full search (best quality only)
+ if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000) {
+ /* Check if mvp_full is within the range. */
+ clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
+ x->mv_row_min, x->mv_row_max);
+
+ thissme = cpi->full_search_sad(x, &mvp_full,
+ sadpb, 16, v_fn_ptr,
+ x->nmvjointcost, x->mvcost,
+ bsi->ref_mv,
+ n);
+
+ if (thissme < bestsme) {
+ bestsme = thissme;
+ mode_mv[NEW4X4].as_int =
+ x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int;
+ } else {
+ /* The full search result is actually worse so re-instate the
+ * previous best vector */
+ x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int =
+ mode_mv[NEW4X4].as_int;
+ }
+ }
+ }
+
+ if (bestsme < INT_MAX) {
+ int distortion;
+ unsigned int sse;
+ cpi->find_fractional_mv_step(x, &mode_mv[NEW4X4],
+ bsi->ref_mv, x->errorperbit, v_fn_ptr,
+ x->nmvjointcost, x->mvcost,
+ &distortion, &sse);
+
+ // safe motion search result for use in compound prediction
+ seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEW4X4].as_int;
+ }
+
+ // restore src pointers
+ x->plane[0].src = orig_src;
+ x->e_mbd.plane[0].pre[0] = orig_pre;
+ } else if (mbmi->second_ref_frame > 0 && this_mode == NEW4X4) {
+ /* NEW4X4 */
+ /* motion search not completed? Then skip newmv for this block with
+ * comppred */
+ if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV ||
+ seg_mvs[i][mbmi->ref_frame - 1].as_int == INVALID_MV) {
+ continue;
+ }
+ }
+
+ rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode],
+ &second_mode_mv[this_mode], seg_mvs[i],
+ bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
+ x->mvcost, cpi);
+
+ // Trap vectors that reach beyond the UMV borders
+ 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;
+ }
+ if (mbmi->second_ref_frame > 0 &&
+ mv_check_bounds(x, &second_mode_mv[this_mode]))
+ continue;
+
+ this_rd = encode_inter_mb_segment(&cpi->common,
+ x, labels, i, &labelyrate,
+ &distortion, t_above_s, t_left_s);
+ this_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
+ rate += labelyrate;
+
+ if (this_rd < best_label_rd) {
+ sbr = rate;
+ sbd = distortion;
+ bestlabelyrate = labelyrate;
+ mode_selected = this_mode;
+ best_label_rd = this_rd;
+ for (j = 0; j < 4; j++)
+ if (labels[j] == i)
+ best_eobs[j] = x->e_mbd.plane[0].eobs[j];
+
+ vpx_memcpy(t_above_b, t_above_s, sizeof(t_above_s));
+ vpx_memcpy(t_left_b, t_left_s, sizeof(t_left_s));
+ }
+ } /*for each 4x4 mode*/
+
+ vpx_memcpy(t_above, t_above_b, sizeof(t_above));
+ vpx_memcpy(t_left, t_left_b, sizeof(t_left));
+
+ labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected],
+ &second_mode_mv[mode_selected], seg_mvs[i],
+ bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
+ x->mvcost, cpi);
+
+ br += sbr;
+ bd += sbd;
+ segmentyrate += bestlabelyrate;
+ this_segment_rd += best_label_rd;
+ other_segment_rd += best_other_rd;
+ } /* for each label */
+
+ if (this_segment_rd < bsi->segment_rd) {
+ bsi->r = br;
+ bsi->d = bd;
+ bsi->segment_yrate = segmentyrate;
+ bsi->segment_rd = this_segment_rd;
+
+ // store everything needed to come back to this!!
+ for (i = 0; i < 4; i++) {
+ bsi->mvs[i].as_mv = x->partition_info->bmi[i].mv.as_mv;
+ if (mbmi->second_ref_frame > 0)
+ bsi->second_mvs[i].as_mv = x->partition_info->bmi[i].second_mv.as_mv;
+ bsi->modes[i] = x->partition_info->bmi[i].mode;
+ bsi->eobs[i] = best_eobs[i];
+ }
+ }
+}
+
+static void rd_check_segment(VP9_COMP *cpi, MACROBLOCK *x,
+ BEST_SEG_INFO *bsi,
+ int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
+ rd_check_segment_txsize(cpi, x, bsi, seg_mvs);
+}
+
+static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
+ int_mv *best_ref_mv,
+ int_mv *second_best_ref_mv,
+ int64_t best_rd,
+ int *mdcounts,
+ int *returntotrate,
+ int *returnyrate,
+ int *returndistortion,
+ int *skippable, int mvthresh,
+ int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
+ int i;
+ BEST_SEG_INFO bsi;
+ MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
+
+ vpx_memset(&bsi, 0, sizeof(bsi));
+
+ bsi.segment_rd = best_rd;
+ bsi.ref_mv = best_ref_mv;
+ bsi.second_ref_mv = second_best_ref_mv;
+ bsi.mvp.as_int = best_ref_mv->as_int;
+ bsi.mvthresh = mvthresh;
+ bsi.mdcounts = mdcounts;
+
+ for (i = 0; i < 4; i++)
+ bsi.modes[i] = ZERO4X4;
+
+ rd_check_segment(cpi, x, &bsi, seg_mvs);
+
+ /* set it to the best */
+ for (i = 0; i < 4; i++) {
+ x->e_mbd.mode_info_context->bmi[i].as_mv[0].as_int = bsi.mvs[i].as_int;
+ if (mbmi->second_ref_frame > 0)
+ x->e_mbd.mode_info_context->bmi[i].as_mv[1].as_int =
+ bsi.second_mvs[i].as_int;
+ x->e_mbd.plane[0].eobs[i] = bsi.eobs[i];
+ }
+
+ /* save partitions */
+ x->partition_info->count = 4;
+
+ for (i = 0; i < x->partition_info->count; i++) {
+ x->partition_info->bmi[i].mode = bsi.modes[i];
+ x->partition_info->bmi[i].mv.as_mv = bsi.mvs[i].as_mv;
+ if (mbmi->second_ref_frame > 0)
+ x->partition_info->bmi[i].second_mv.as_mv = bsi.second_mvs[i].as_mv;
+ }
+ /*
+ * used to set mbmi->mv.as_int
+ */
+ x->partition_info->bmi[3].mv.as_int = bsi.mvs[3].as_int;
+ if (mbmi->second_ref_frame > 0)
+ x->partition_info->bmi[3].second_mv.as_int = bsi.second_mvs[3].as_int;
+
+ *returntotrate = bsi.r;
+ *returndistortion = bsi.d;
+ *returnyrate = bsi.segment_yrate;
+ *skippable = vp9_sby_is_skippable(&x->e_mbd, BLOCK_SIZE_SB8X8);
+
+ return (int)(bsi.segment_rd);
+}
+
+#else // !CONFIG_SB8X8
+
static int labels2mode(
MACROBLOCK *x,
int const *labelings, int which_label,
@@ -1887,15 +2437,6 @@ typedef struct {
} BEST_SEG_INFO;
-static INLINE int mv_check_bounds(MACROBLOCK *x, int_mv *mv) {
- int r = 0;
- r |= (mv->as_mv.row >> 3) < x->mv_row_min;
- r |= (mv->as_mv.row >> 3) > x->mv_row_max;
- r |= (mv->as_mv.col >> 3) < x->mv_col_min;
- r |= (mv->as_mv.col >> 3) > x->mv_col_max;
- return r;
-}
-
static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
BEST_SEG_INFO *bsi,
SPLITMV_PARTITIONING_TYPE segmentation,
@@ -2428,6 +2969,7 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
return (int)(bsi.segment_rd);
}
+#endif // !CONFIG_SB8X8
static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
uint8_t *ref_y_buffer, int ref_y_stride,
@@ -2474,6 +3016,7 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
x->mv_best_ref_index[ref_frame] = best_index;
}
+#if !CONFIG_SB8X8
static void set_i8x8_block_modes(MACROBLOCK *x, int modes[4]) {
int i;
MACROBLOCKD *xd = &x->e_mbd;
@@ -2487,6 +3030,7 @@ static void set_i8x8_block_modes(MACROBLOCK *x, int modes[4]) {
// modes[0], modes[1], modes[2], modes[3]);
}
}
+#endif
extern void vp9_calc_ref_probs(int *count, vp9_prob *probs);
static void estimate_curframe_refprobs(VP9_COMP *cpi, vp9_prob mod_refprobs[3], int pred_ref) {
@@ -3193,6 +3737,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
return this_rd; // if 0, this will be re-calculated by caller
}
+#if !CONFIG_SB8X8
static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int mi_row, int mi_col,
int *returnrate, int *returndistortion,
@@ -4053,6 +4598,7 @@ end:
mbmi->second_ref_frame][0],
best_pred_diff, best_txfm_diff);
}
+#endif // !CONFIG_SB8X8
void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int *returnrate, int *returndist,
@@ -4065,14 +4611,30 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int dist_y = 0, dist_uv;
int y_skip = 0, uv_skip;
int64_t txfm_cache[NB_TXFM_MODES], err;
+#if CONFIG_SB8X8
+ MB_PREDICTION_MODE mode;
+ TX_SIZE txfm_size;
+ int rate4x4_y, rate4x4_y_tokenonly, dist4x4_y;
+ int64_t err4x4 = INT64_MAX;
+#endif
int i;
ctx->skip = 0;
xd->mode_info_context->mbmi.mode = DC_PRED;
err = rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
&dist_y, &y_skip, bsize, txfm_cache);
+#if CONFIG_SB8X8
+ mode = xd->mode_info_context->mbmi.mode;
+ txfm_size = xd->mode_info_context->mbmi.txfm_size;
+#endif
rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly,
&dist_uv, &uv_skip, bsize);
+#if CONFIG_SB8X8
+ if (bsize == BLOCK_SIZE_SB8X8)
+ err4x4 = rd_pick_intra4x4mby_modes(cpi, x, &rate4x4_y,
+ &rate4x4_y_tokenonly,
+ &dist4x4_y, err);
+#endif
if (y_skip && uv_skip) {
*returnrate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
@@ -4080,18 +4642,39 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
*returndist = dist_y + (dist_uv >> 2);
memset(ctx->txfm_rd_diff, 0,
sizeof(x->sb32_context[xd->sb_index].txfm_rd_diff));
+#if CONFIG_SB8X8
+ xd->mode_info_context->mbmi.mode = mode;
+ xd->mode_info_context->mbmi.txfm_size = txfm_size;
+ } else if (bsize == BLOCK_SIZE_SB8X8 && err4x4 < err) {
+ *returnrate = rate4x4_y + rate_uv +
+ vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_MBSKIP), 0);
+ *returndist = dist4x4_y + (dist_uv >> 2);
+ for (i = 0; i < NB_TXFM_MODES; i++) {
+ ctx->txfm_rd_diff[i] = MIN(err4x4, err - txfm_cache[i]);
+ }
+ xd->mode_info_context->mbmi.txfm_size = TX_4X4;
+#endif
} else {
*returnrate = rate_y + rate_uv +
vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_MBSKIP), 0);
*returndist = dist_y + (dist_uv >> 2);
for (i = 0; i < NB_TXFM_MODES; i++) {
+#if CONFIG_SB8X8
+ ctx->txfm_rd_diff[i] = MIN(err4x4, err - txfm_cache[i]);
+#else
ctx->txfm_rd_diff[i] = err - txfm_cache[i];
+#endif
}
+#if CONFIG_SB8X8
+ xd->mode_info_context->mbmi.txfm_size = txfm_size;
+ xd->mode_info_context->mbmi.mode = mode;
+#endif
}
vpx_memcpy(&ctx->mic, xd->mode_info_context, sizeof(MODE_INFO));
}
+#if !CONFIG_SB8X8
void vp9_rd_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x,
int *returnrate, int *returndist) {
VP9_COMMON *cm = &cpi->common;
@@ -4218,6 +4801,7 @@ void vp9_rd_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x,
*returnrate = rate;
*returndist = dist;
}
+#endif
int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int mi_row, int mi_col,
@@ -4272,7 +4856,20 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
unsigned int mode_mask = 0;
int64_t mode_distortions[MB_MODE_COUNT] = {-1};
int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
+ int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
+ cpi->common.y_dc_delta_q);
+#if CONFIG_SB8X8
+ int_mv seg_mvs[4][MAX_REF_FRAMES - 1];
+#endif
+
+#if CONFIG_SB8X8
+ for (i = 0; i < 4; i++) {
+ int j;
+ for (j = 0; j < MAX_REF_FRAMES - 1; j++)
+ seg_mvs[i][j].as_int = INVALID_MV;
+ }
+#endif
// Everywhere the flag is set the error is much higher than its neighbors.
ctx->frames_with_high_error = 0;
ctx->modes_with_high_error = 0;
@@ -4400,9 +4997,16 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
// if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
// continue;
- if (this_mode == I8X8_PRED ||
+ if (
+#if CONFIG_SB8X8
+ bsize != BLOCK_SIZE_SB8X8 &&
+ (this_mode == I4X4_PRED || this_mode == SPLITMV)
+#else
this_mode == I4X4_PRED ||
- this_mode == SPLITMV)
+ this_mode == I8X8_PRED ||
+ this_mode == SPLITMV
+#endif
+ )
continue;
// if (vp9_mode_order[mode_index].second_ref_frame == INTRA_FRAME)
// continue;
@@ -4465,6 +5069,27 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
}
+#if CONFIG_SB8X8
+ if (this_mode == I4X4_PRED) {
+ int rate;
+
+ // Note the rate value returned here includes the cost of coding
+ // the I4X4_PRED mode : x->mbmode_cost[xd->frame_type][I4X4_PRED];
+ assert(bsize == BLOCK_SIZE_SB8X8);
+ mbmi->txfm_size = TX_4X4;
+ rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y,
+ &distortion_y, INT64_MAX);
+ rate2 += rate;
+ rate2 += intra_cost_penalty;
+ distortion2 += distortion_y;
+
+ rate2 += rate_uv_intra[TX_4X4];
+ rate_uv = rate_uv_intra[TX_4X4];
+ distortion2 += dist_uv[TX_4X4];
+ distortion_uv = dist_uv[TX_4X4];
+ mbmi->uv_mode = mode_uv[TX_4X4];
+ } else
+#endif
if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
vp9_build_intra_predictors_sby_s(xd, bsize);
@@ -4483,7 +5108,139 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->uv_mode = mode_uv[uv_tx];
rate2 = rate_y + x->mbmode_cost[cm->frame_type][mbmi->mode] + rate_uv;
+ if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
+ rate2 += intra_cost_penalty;
distortion2 = distortion_y + distortion_uv;
+#if CONFIG_SB8X8
+ } else if (this_mode == SPLITMV) {
+ const int is_comp_pred = mbmi->second_ref_frame > 0;
+ int rate, distortion;
+ int64_t this_rd_thresh;
+ int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
+ int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
+ int tmp_best_distortion = INT_MAX, tmp_best_skippable = 0;
+ int switchable_filter_index;
+ int_mv *second_ref = is_comp_pred ?
+ &mbmi->ref_mvs[mbmi->second_ref_frame][0] : NULL;
+ union b_mode_info tmp_best_bmodes[16];
+ MB_MODE_INFO tmp_best_mbmode;
+ PARTITION_INFO tmp_best_partition;
+ int pred_exists = 0;
+ int uv_skippable;
+
+ this_rd_thresh = (mbmi->ref_frame == LAST_FRAME) ?
+ cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
+ this_rd_thresh = (mbmi->ref_frame == GOLDEN_FRAME) ?
+ cpi->rd_threshes[THR_NEWG] : this_rd_thresh;
+ xd->mode_info_context->mbmi.txfm_size = TX_4X4;
+
+ for (switchable_filter_index = 0;
+ switchable_filter_index < VP9_SWITCHABLE_FILTERS;
+ ++switchable_filter_index) {
+ int newbest;
+ mbmi->interp_filter =
+ vp9_switchable_interp[switchable_filter_index];
+ vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
+
+ tmp_rd = rd_pick_best_mbsegmentation(cpi, x,
+ &mbmi->ref_mvs[mbmi->ref_frame][0],
+ second_ref, INT64_MAX, mdcounts,
+ &rate, &rate_y, &distortion,
+ &skippable,
+ (int)this_rd_thresh, seg_mvs);
+ if (cpi->common.mcomp_filter_type == SWITCHABLE) {
+ int rs = SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
+ [vp9_get_pred_context(&cpi->common, xd,
+ PRED_SWITCHABLE_INTERP)]
+ [vp9_switchable_interp_map[mbmi->interp_filter]];
+ tmp_rd += RDCOST(x->rdmult, x->rddiv, rs, 0);
+ }
+ newbest = (tmp_rd < tmp_best_rd);
+ if (newbest) {
+ tmp_best_filter = mbmi->interp_filter;
+ tmp_best_rd = tmp_rd;
+ }
+ if ((newbest && cm->mcomp_filter_type == SWITCHABLE) ||
+ (mbmi->interp_filter == cm->mcomp_filter_type &&
+ cm->mcomp_filter_type != SWITCHABLE)) {
+ tmp_best_rdu = tmp_rd;
+ tmp_best_rate = rate;
+ tmp_best_ratey = rate_y;
+ tmp_best_distortion = distortion;
+ tmp_best_skippable = skippable;
+ vpx_memcpy(&tmp_best_mbmode, mbmi, sizeof(MB_MODE_INFO));
+ vpx_memcpy(&tmp_best_partition, x->partition_info,
+ sizeof(PARTITION_INFO));
+ for (i = 0; i < 4; i++) {
+ tmp_best_bmodes[i] = xd->mode_info_context->bmi[i];
+ }
+ pred_exists = 1;
+ }
+ } // switchable_filter_index loop
+
+ mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE ?
+ tmp_best_filter : cm->mcomp_filter_type);
+ vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
+ if (!pred_exists) {
+ // Handles the special case when a filter that is not in the
+ // switchable list (bilinear, 6-tap) is indicated at the frame level
+ tmp_rd = rd_pick_best_mbsegmentation(cpi, x,
+ &mbmi->ref_mvs[mbmi->ref_frame][0],
+ second_ref, INT64_MAX, mdcounts,
+ &rate, &rate_y, &distortion,
+ &skippable,
+ (int)this_rd_thresh, seg_mvs);
+ } else {
+ if (cpi->common.mcomp_filter_type == SWITCHABLE) {
+ int rs = SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
+ [vp9_get_pred_context(&cpi->common, xd,
+ PRED_SWITCHABLE_INTERP)]
+ [vp9_switchable_interp_map[mbmi->interp_filter]];
+ tmp_best_rdu -= RDCOST(x->rdmult, x->rddiv, rs, 0);
+ }
+ tmp_rd = tmp_best_rdu;
+ rate = tmp_best_rate;
+ rate_y = tmp_best_ratey;
+ distortion = tmp_best_distortion;
+ skippable = tmp_best_skippable;
+ vpx_memcpy(mbmi, &tmp_best_mbmode, sizeof(MB_MODE_INFO));
+ vpx_memcpy(x->partition_info, &tmp_best_partition,
+ sizeof(PARTITION_INFO));
+ for (i = 0; i < 4; i++) {
+ xd->mode_info_context->bmi[i] = tmp_best_bmodes[i];
+ }
+ }
+
+ rate2 += rate;
+ distortion2 += distortion;
+
+ if (cpi->common.mcomp_filter_type == SWITCHABLE)
+ rate2 += SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
+ [vp9_get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
+ [vp9_switchable_interp_map[mbmi->interp_filter]];
+
+ // If even the 'Y' rd value of split is higher than best so far
+ // then dont bother looking at UV
+ vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
+ bsize);
+ vp9_subtract_sbuv(x, bsize);
+ super_block_uvrd_4x4(cm, x, &rate_uv, &distortion_uv,
+ &uv_skippable, bsize);
+ rate2 += rate_uv;
+ distortion2 += distortion_uv;
+ skippable = skippable && uv_skippable;
+
+ if (!mode_excluded) {
+ if (is_comp_pred)
+ mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY;
+ else
+ mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
+ }
+
+ compmode_cost =
+ vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), is_comp_pred);
+ mbmi->mode = this_mode;
+#endif
} else {
YV12_BUFFER_CONFIG *scaled_ref_frame = NULL;
int fb;
@@ -4693,6 +5450,14 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
/* keep record of best txfm size */
+ if (bsize < BLOCK_SIZE_SB32X32) {
+ if (bsize < BLOCK_SIZE_MB16X16) {
+ if (this_mode == SPLITMV || this_mode == I4X4_PRED)
+ txfm_cache[ALLOW_8X8] = txfm_cache[ONLY_4X4];
+ txfm_cache[ALLOW_16X16] = txfm_cache[ALLOW_8X8];
+ }
+ txfm_cache[ALLOW_32X32] = txfm_cache[ALLOW_16X16];
+ }
if (!mode_excluded && this_rd != INT64_MAX) {
for (i = 0; i < NB_TXFM_MODES; i++) {
int64_t adj_rd;
@@ -4769,13 +5534,27 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
(best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME)) {
mbmi->mode = ZEROMV;
mbmi->ref_frame = ALTREF_FRAME;
- mbmi->second_ref_frame = INTRA_FRAME;
+ mbmi->second_ref_frame = NONE;
mbmi->mv[0].as_int = 0;
mbmi->uv_mode = DC_PRED;
mbmi->mb_skip_coeff = 1;
+#if !CONFIG_SB8X8
mbmi->partitioning = 0;
- mbmi->txfm_size = cm->txfm_mode == TX_MODE_SELECT ?
- TX_32X32 : cm->txfm_mode;
+#endif
+ if (cm->txfm_mode == TX_MODE_SELECT) {
+ if (bsize >= BLOCK_SIZE_SB32X32)
+ mbmi->txfm_size = TX_32X32;
+#if CONFIG_SB8X8
+ else if (bsize >= BLOCK_SIZE_MB16X16)
+#else
+ else
+#endif
+ mbmi->txfm_size = TX_16X16;
+#if CONFIG_SB8X8
+ else
+ mbmi->txfm_size = TX_8X8;
+#endif
+ }
vpx_memset(best_txfm_diff, 0, sizeof(best_txfm_diff));
vpx_memset(best_pred_diff, 0, sizeof(best_pred_diff));
@@ -4815,6 +5594,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
return best_rd;
}
+#if !CONFIG_SB8X8
void vp9_pick_mode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
int mi_row, int mi_col,
int *totalrate, int *totaldist) {
@@ -4851,3 +5631,4 @@ void vp9_pick_mode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
*totalrate = rate;
*totaldist = distortion;
}
+#endif
diff --git a/vp9/encoder/vp9_rdopt.h b/vp9/encoder/vp9_rdopt.h
index eef2a4fe9..6533a82e0 100644
--- a/vp9/encoder/vp9_rdopt.h
+++ b/vp9/encoder/vp9_rdopt.h
@@ -19,16 +19,20 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi, int qindex);
void vp9_initialize_me_consts(VP9_COMP *cpi, int qindex);
+#if !CONFIG_SB8X8
void vp9_rd_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x,
int *r, int *d);
+#endif
void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int *r, int *d, BLOCK_SIZE_TYPE bsize,
PICK_MODE_CONTEXT *ctx);
+#if !CONFIG_SB8X8
void vp9_pick_mode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
int mi_row, int mi_col,
int *r, int *d);
+#endif
int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int mi_row, int mi_col,
diff --git a/vp9/encoder/vp9_segmentation.c b/vp9/encoder/vp9_segmentation.c
index 69d3a9617..e04980ce1 100644
--- a/vp9/encoder/vp9_segmentation.c
+++ b/vp9/encoder/vp9_segmentation.c
@@ -196,9 +196,17 @@ static void count_segs_sb(VP9_COMP *cpi, MODE_INFO *mi,
assert(bwl < bsl && bhl < bsl);
if (bsize == BLOCK_SIZE_SB64X64) {
subsize = BLOCK_SIZE_SB32X32;
+#if CONFIG_SB8X8
+ } else if (bsize == BLOCK_SIZE_SB32X32) {
+ subsize = BLOCK_SIZE_MB16X16;
+ } else {
+ assert(bsize == BLOCK_SIZE_MB16X16);
+ subsize = BLOCK_SIZE_SB8X8;
+#else
} else {
assert(bsize == BLOCK_SIZE_SB32X32);
subsize = BLOCK_SIZE_MB16X16;
+#endif
}
for (n = 0; n < 4; n++) {
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index 3c3367071..9756e6e54 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -376,7 +376,11 @@ int vp9_sb_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
int vp9_sby_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) {
int result = 1;
struct is_skippable_args args = {xd, &result};
- foreach_transformed_block_in_plane(xd, bsize, 0, 0, is_skippable, &args);
+ foreach_transformed_block_in_plane(xd, bsize, 0,
+#if !CONFIG_SB8X8
+ 0,
+#endif
+ is_skippable, &args);
return result;
}
diff --git a/vp9/encoder/vp9_variance_c.c b/vp9/encoder/vp9_variance_c.c
index f7916b4f0..c4c70df43 100644
--- a/vp9/encoder/vp9_variance_c.c
+++ b/vp9/encoder/vp9_variance_c.c
@@ -87,9 +87,9 @@ unsigned int vp9_sub_pixel_variance32x64_c(const uint8_t *src_ptr,
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 65, 32, hfilter);
- var_filter_block2d_bil_second_pass(fdata3, temp2, 64, 64, 64, 32, vfilter);
+ var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 64, 32, vfilter);
- return vp9_variance32x64_c(temp2, 64, dst_ptr, dst_pixels_per_line, sse);
+ return vp9_variance32x64_c(temp2, 32, dst_ptr, dst_pixels_per_line, sse);
}
unsigned int vp9_variance32x16_c(const uint8_t *src_ptr,
@@ -155,9 +155,9 @@ unsigned int vp9_sub_pixel_variance16x32_c(const uint8_t *src_ptr,
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 33, 16, hfilter);
- var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 32, 16, vfilter);
+ var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 32, 16, vfilter);
- return vp9_variance16x32_c(temp2, 32, dst_ptr, dst_pixels_per_line, sse);
+ return vp9_variance16x32_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse);
}
unsigned int vp9_variance64x64_c(const uint8_t *src_ptr,
diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h
index 14b6e278b..22df3999e 100644
--- a/vpx_scale/yv12config.h
+++ b/vpx_scale/yv12config.h
@@ -18,7 +18,7 @@ extern "C" {
#include "vpx/vpx_integer.h"
#define VP8BORDERINPIXELS 32
-#define VP9BORDERINPIXELS 64
+#define VP9BORDERINPIXELS 96
#define VP9_INTERP_EXTEND 4
/*************************************