summaryrefslogtreecommitdiff
path: root/vp9/decoder
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@google.com>2013-01-05 18:20:25 -0800
committerRonald S. Bultje <rbultje@google.com>2013-01-05 18:20:25 -0800
commitc3941665e995f12f9aa9b47a32c06d20978993fc (patch)
tree1d2c8c57a6196e07eb3df5e8d7fc29cfd083687a /vp9/decoder
parent81d1171fd4614c3b60439b97007a3ec7ea5e3d0c (diff)
downloadlibvpx-c3941665e995f12f9aa9b47a32c06d20978993fc.tar
libvpx-c3941665e995f12f9aa9b47a32c06d20978993fc.tar.gz
libvpx-c3941665e995f12f9aa9b47a32c06d20978993fc.tar.bz2
libvpx-c3941665e995f12f9aa9b47a32c06d20978993fc.zip
64x64 blocksize support.
3.2% gains on std/hd, 1.0% gains on hd. Change-Id: I481d5df23d8a4fc650a5bcba956554490b2bd200
Diffstat (limited to 'vp9/decoder')
-rw-r--r--vp9/decoder/vp9_decodemv.c98
-rw-r--r--vp9/decoder/vp9_decodframe.c561
2 files changed, 411 insertions, 248 deletions
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index cbd3fb984..bbe2e953c 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -14,7 +14,7 @@
#include "vp9/common/vp9_entropymode.h"
#include "vp9/decoder/vp9_onyxd_int.h"
#include "vp9/common/vp9_findnearmv.h"
-
+#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_entropy.h"
@@ -122,7 +122,24 @@ static void kfread_modes(VP9D_COMP *pbi,
m->mbmi.segment_id = 0;
if (pbi->mb.update_mb_segmentation_map) {
read_mb_segid(bc, &m->mbmi, &pbi->mb);
- pbi->common.last_frame_seg_map[map_index] = m->mbmi.segment_id;
+#if CONFIG_SUPERBLOCKS
+ if (m->mbmi.sb_type) {
+ const int nmbs = 1 << m->mbmi.sb_type;
+ const int ymbs = MIN(cm->mb_rows - mb_row, nmbs);
+ const int xmbs = MIN(cm->mb_cols - mb_col, nmbs);
+ int x, y;
+
+ for (y = 0; y < ymbs; y++) {
+ for (x = 0; x < xmbs; x++) {
+ cm->last_frame_seg_map[map_index + x + y * cm->mb_cols] =
+ m->mbmi.segment_id;
+ }
+ }
+ } else
+#endif
+ {
+ cm->last_frame_seg_map[map_index] = m->mbmi.segment_id;
+ }
}
m->mbmi.mb_skip_coeff = 0;
@@ -145,7 +162,7 @@ static void kfread_modes(VP9D_COMP *pbi,
}
#if CONFIG_SUPERBLOCKS
- if (m->mbmi.encoded_as_sb) {
+ if (m->mbmi.sb_type) {
y_mode = (MB_PREDICTION_MODE) read_kf_sb_ymode(bc,
pbi->common.sb_kf_ymode_prob[pbi->common.kf_ymode_probs_index]);
} else
@@ -212,12 +229,12 @@ static void kfread_modes(VP9D_COMP *pbi,
if (m->mbmi.txfm_size != TX_4X4 && m->mbmi.mode != I8X8_PRED) {
m->mbmi.txfm_size += vp9_read(bc, cm->prob_tx[1]);
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
- if (m->mbmi.txfm_size != TX_8X8 && m->mbmi.encoded_as_sb)
+ if (m->mbmi.txfm_size != TX_8X8 && m->mbmi.sb_type)
m->mbmi.txfm_size += vp9_read(bc, cm->prob_tx[2]);
#endif
}
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
- } else if (cm->txfm_mode >= ALLOW_32X32 && m->mbmi.encoded_as_sb) {
+ } else if (cm->txfm_mode >= ALLOW_32X32 && m->mbmi.sb_type) {
m->mbmi.txfm_size = TX_32X32;
#endif
} else if (cm->txfm_mode >= ALLOW_16X16 && m->mbmi.mode <= TM_PRED) {
@@ -638,14 +655,17 @@ static void read_mb_segment_id(VP9D_COMP *pbi,
read_mb_segid(bc, mbmi, xd);
}
#if CONFIG_SUPERBLOCKS
- if (mbmi->encoded_as_sb) {
- cm->last_frame_seg_map[index] = mbmi->segment_id;
- if (mb_col + 1 < cm->mb_cols)
- cm->last_frame_seg_map[index + 1] = mbmi->segment_id;
- if (mb_row + 1 < cm->mb_rows) {
- cm->last_frame_seg_map[index + cm->mb_cols] = mbmi->segment_id;
- if (mb_col + 1 < cm->mb_cols)
- cm->last_frame_seg_map[index + cm->mb_cols + 1] = mbmi->segment_id;
+ if (mbmi->sb_type) {
+ const int nmbs = 1 << mbmi->sb_type;
+ const int ymbs = MIN(cm->mb_rows - mb_row, nmbs);
+ const int xmbs = MIN(cm->mb_cols - mb_col, nmbs);
+ int x, y;
+
+ for (y = 0; y < ymbs; y++) {
+ for (x = 0; x < xmbs; x++) {
+ cm->last_frame_seg_map[index + x + y * cm->mb_cols] =
+ mbmi->segment_id;
+ }
}
} else
#endif
@@ -654,18 +674,21 @@ static void read_mb_segment_id(VP9D_COMP *pbi,
}
} else {
#if CONFIG_SUPERBLOCKS
- if (mbmi->encoded_as_sb) {
- mbmi->segment_id = cm->last_frame_seg_map[index];
- if (mb_col < cm->mb_cols - 1)
- mbmi->segment_id = mbmi->segment_id &&
- cm->last_frame_seg_map[index + 1];
- if (mb_row < cm->mb_rows - 1) {
- mbmi->segment_id = mbmi->segment_id &&
- cm->last_frame_seg_map[index + cm->mb_cols];
- if (mb_col < cm->mb_cols - 1)
- mbmi->segment_id = mbmi->segment_id &&
- cm->last_frame_seg_map[index + cm->mb_cols + 1];
+ if (mbmi->sb_type) {
+ const int nmbs = 1 << mbmi->sb_type;
+ const int ymbs = MIN(cm->mb_rows - mb_row, nmbs);
+ const int xmbs = MIN(cm->mb_cols - mb_col, nmbs);
+ unsigned segment_id = -1;
+ int x, y;
+
+ for (y = 0; y < ymbs; y++) {
+ for (x = 0; x < xmbs; x++) {
+ segment_id = MIN(segment_id,
+ cm->last_frame_seg_map[index + x +
+ y * cm->mb_cols]);
+ }
}
+ mbmi->segment_id = segment_id;
} else
#endif
{
@@ -693,6 +716,11 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
int mb_to_right_edge;
int mb_to_top_edge;
int mb_to_bottom_edge;
+#if CONFIG_SUPERBLOCKS
+ const int mb_size = 1 << mi->mbmi.sb_type;
+#else
+ const int mb_size = 1;
+#endif
mb_to_top_edge = xd->mb_to_top_edge;
mb_to_bottom_edge = xd->mb_to_bottom_edge;
@@ -707,18 +735,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
xd->mb_to_left_edge =
mb_to_left_edge = -((mb_col * 16) << 3);
mb_to_left_edge -= LEFT_TOP_MARGIN;
-
-#if CONFIG_SUPERBLOCKS
- if (mi->mbmi.encoded_as_sb) {
- xd->mb_to_right_edge =
- mb_to_right_edge = ((pbi->common.mb_cols - 2 - mb_col) * 16) << 3;
- } else {
-#endif
- xd->mb_to_right_edge =
- mb_to_right_edge = ((pbi->common.mb_cols - 1 - mb_col) * 16) << 3;
-#if CONFIG_SUPERBLOCKS
- }
-#endif
+ xd->mb_to_right_edge =
+ mb_to_right_edge = ((pbi->common.mb_cols - mb_size - mb_col) * 16) << 3;
mb_to_right_edge += RIGHT_BOTTOM_MARGIN;
// Make sure the MACROBLOCKD mode info pointer is pointed at the
@@ -801,7 +819,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
vp9_get_segdata(xd, mbmi->segment_id, SEG_LVL_MODE);
} else {
#if CONFIG_SUPERBLOCKS
- if (mbmi->encoded_as_sb)
+ if (mbmi->sb_type)
mbmi->mode = read_sb_mv_ref(bc, mv_ref_p);
else
#endif
@@ -1155,7 +1173,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mbmi->mode = (MB_PREDICTION_MODE)
vp9_get_segdata(xd, mbmi->segment_id, SEG_LVL_MODE);
#if CONFIG_SUPERBLOCKS
- } else if (mbmi->encoded_as_sb) {
+ } else if (mbmi->sb_type) {
mbmi->mode = (MB_PREDICTION_MODE)
read_sb_ymode(bc, pbi->common.fc.sb_ymode_prob);
pbi->common.fc.sb_ymode_counts[mbmi->mode]++;
@@ -1232,12 +1250,12 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mbmi->mode != SPLITMV) {
mbmi->txfm_size += vp9_read(bc, cm->prob_tx[1]);
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
- if (mbmi->encoded_as_sb && mbmi->txfm_size != TX_8X8)
+ if (mbmi->sb_type && mbmi->txfm_size != TX_8X8)
mbmi->txfm_size += vp9_read(bc, cm->prob_tx[2]);
#endif
}
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
- } else if (mbmi->encoded_as_sb && cm->txfm_mode >= ALLOW_32X32) {
+ } else if (mbmi->sb_type && cm->txfm_mode >= ALLOW_32X32) {
mbmi->txfm_size = TX_32X32;
#endif
} else if (cm->txfm_mode >= ALLOW_16X16 &&
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index af345824e..d524ade66 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -10,6 +10,7 @@
#include "vp9/decoder/vp9_onyxd_int.h"
+#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_header.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_reconintra4x4.h"
@@ -172,55 +173,69 @@ static void mb_init_dequantizer(VP9D_COMP *pbi, MACROBLOCKD *xd) {
static void skip_recon_mb(VP9D_COMP *pbi, MACROBLOCKD *xd) {
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
#if CONFIG_SUPERBLOCKS
- if (xd->mode_info_context->mbmi.encoded_as_sb) {
+#if CONFIG_SUPERBLOCKS64
+ if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
+ vp9_build_intra_predictors_sb64uv_s(xd);
+ vp9_build_intra_predictors_sb64y_s(xd);
+ } else
+#endif // CONFIG_SUPERBLOCKS64
+ if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB32X32) {
vp9_build_intra_predictors_sbuv_s(xd);
vp9_build_intra_predictors_sby_s(xd);
- } else {
-#endif
- vp9_build_intra_predictors_mbuv_s(xd);
- vp9_build_intra_predictors_mby_s(xd);
-#if CONFIG_SUPERBLOCKS
+ } else
+#endif // CONFIG_SUPERBLOCKS
+ {
+ vp9_build_intra_predictors_mbuv_s(xd);
+ vp9_build_intra_predictors_mby_s(xd);
}
-#endif
} else {
#if CONFIG_SUPERBLOCKS
- if (xd->mode_info_context->mbmi.encoded_as_sb) {
+#if CONFIG_SUPERBLOCKS64
+ if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
+ vp9_build_inter64x64_predictors_sb(xd,
+ xd->dst.y_buffer,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.y_stride,
+ xd->dst.uv_stride);
+ } else
+#endif // CONFIG_SUPERBLOCKS64
+ if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB32X32) {
vp9_build_inter32x32_predictors_sb(xd,
xd->dst.y_buffer,
xd->dst.u_buffer,
xd->dst.v_buffer,
xd->dst.y_stride,
xd->dst.uv_stride);
- } else {
-#endif
- vp9_build_1st_inter16x16_predictors_mb(xd,
- xd->dst.y_buffer,
- xd->dst.u_buffer,
- xd->dst.v_buffer,
- xd->dst.y_stride,
- xd->dst.uv_stride);
-
- if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
- vp9_build_2nd_inter16x16_predictors_mb(xd,
+ } else
+#endif // CONFIG_SUPERBLOCKS
+ {
+ vp9_build_1st_inter16x16_predictors_mb(xd,
xd->dst.y_buffer,
xd->dst.u_buffer,
xd->dst.v_buffer,
xd->dst.y_stride,
xd->dst.uv_stride);
- }
-#if CONFIG_COMP_INTERINTRA_PRED
- else if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) {
- vp9_build_interintra_16x16_predictors_mb(xd,
+
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
+ vp9_build_2nd_inter16x16_predictors_mb(xd,
xd->dst.y_buffer,
xd->dst.u_buffer,
xd->dst.v_buffer,
xd->dst.y_stride,
xd->dst.uv_stride);
- }
+ }
+#if CONFIG_COMP_INTERINTRA_PRED
+ else if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) {
+ vp9_build_interintra_16x16_predictors_mb(xd,
+ xd->dst.y_buffer,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.y_stride,
+ xd->dst.uv_stride);
+ }
#endif
-#if CONFIG_SUPERBLOCKS
}
-#endif
}
}
@@ -546,8 +561,9 @@ static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd,
#if CONFIG_SUPERBLOCKS
static void decode_16x16_sb(VP9D_COMP *pbi, MACROBLOCKD *xd,
- BOOL_DECODER* const bc, int n) {
- int x_idx = n & 1, y_idx = n >> 1;
+ BOOL_DECODER* const bc, int n,
+ int maska, int shiftb) {
+ int x_idx = n & maska, y_idx = n >> shiftb;
TX_TYPE tx_type = get_tx_type_16x16(xd, &xd->block[0]);
if (tx_type != DCT_DCT) {
vp9_ht_dequant_idct_add_16x16_c(
@@ -571,9 +587,10 @@ static void decode_16x16_sb(VP9D_COMP *pbi, MACROBLOCKD *xd,
};
static void decode_8x8_sb(VP9D_COMP *pbi, MACROBLOCKD *xd,
- BOOL_DECODER* const bc, int n) {
+ BOOL_DECODER* const bc, int n,
+ int maska, int shiftb) {
+ int x_idx = n & maska, y_idx = n >> shiftb;
BLOCKD *b = &xd->block[24];
- int x_idx = n & 1, y_idx = n >> 1;
TX_TYPE tx_type = get_tx_type_8x8(xd, &xd->block[0]);
if (tx_type != DCT_DCT) {
int i;
@@ -632,9 +649,10 @@ static void decode_8x8_sb(VP9D_COMP *pbi, MACROBLOCKD *xd,
};
static void decode_4x4_sb(VP9D_COMP *pbi, MACROBLOCKD *xd,
- BOOL_DECODER* const bc, int n) {
+ BOOL_DECODER* const bc, int n,
+ int maska, int shiftb) {
+ int x_idx = n & maska, y_idx = n >> shiftb;
BLOCKD *b = &xd->block[24];
- int x_idx = n & 1, y_idx = n >> 1;
TX_TYPE tx_type = get_tx_type_4x4(xd, &xd->block[0]);
if (tx_type != DCT_DCT) {
int i;
@@ -687,16 +705,148 @@ static void decode_4x4_sb(VP9D_COMP *pbi, MACROBLOCKD *xd,
xd->dst.uv_stride, xd->eobs + 16, xd);
};
-static void decode_superblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
- int mb_row, unsigned int mb_col,
- BOOL_DECODER* const bc) {
+#if CONFIG_SUPERBLOCKS64
+static void decode_superblock64(VP9D_COMP *pbi, MACROBLOCKD *xd,
+ int mb_row, unsigned int mb_col,
+ BOOL_DECODER* const bc) {
int i, n, eobtotal;
TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
VP9_COMMON *const pc = &pbi->common;
MODE_INFO *orig_mi = xd->mode_info_context;
const int mis = pc->mode_info_stride;
- assert(xd->mode_info_context->mbmi.encoded_as_sb);
+ assert(xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB64X64);
+
+ if (pbi->common.frame_type != KEY_FRAME)
+ vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter, pc);
+
+ // re-initialize macroblock dequantizer before detokenization
+ if (xd->segmentation_enabled)
+ mb_init_dequantizer(pbi, xd);
+
+ if (xd->mode_info_context->mbmi.mb_skip_coeff) {
+ int n;
+
+ vp9_reset_mb_tokens_context(xd);
+ for (n = 1; n <= 3; n++) {
+ if (mb_col < pc->mb_cols - n)
+ xd->above_context += n;
+ if (mb_row < pc->mb_rows - n)
+ xd->left_context += n;
+ vp9_reset_mb_tokens_context(xd);
+ if (mb_col < pc->mb_cols - n)
+ xd->above_context -= n;
+ if (mb_row < pc->mb_rows - n)
+ xd->left_context -= n;
+ }
+
+ /* Special case: Force the loopfilter to skip when eobtotal and
+ * mb_skip_coeff are zero.
+ */
+ skip_recon_mb(pbi, xd);
+ return;
+ }
+
+ /* do prediction */
+ if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
+ vp9_build_intra_predictors_sb64y_s(xd);
+ vp9_build_intra_predictors_sb64uv_s(xd);
+ } else {
+ vp9_build_inter64x64_predictors_sb(xd, xd->dst.y_buffer,
+ xd->dst.u_buffer, xd->dst.v_buffer,
+ xd->dst.y_stride, xd->dst.uv_stride);
+ }
+
+ /* dequantization and idct */
+#if CONFIG_TX32X32
+ if (xd->mode_info_context->mbmi.txfm_size == TX_32X32) {
+ for (n = 0; n < 4; n++) {
+ const int x_idx = n & 1, y_idx = n >> 1;
+
+ if (mb_col + x_idx * 2 >= pc->mb_cols ||
+ mb_row + y_idx * 2 >= pc->mb_rows)
+ continue;
+
+ xd->left_context = pc->left_context + (y_idx << 1);
+ xd->above_context = pc->above_context + mb_col + (x_idx << 1);
+ xd->mode_info_context = orig_mi + x_idx * 2 + y_idx * 2 * mis;
+ eobtotal = vp9_decode_sb_tokens(pbi, xd, bc);
+ if (eobtotal == 0) { // skip loopfilter
+ xd->mode_info_context->mbmi.mb_skip_coeff = 1;
+ if (mb_col + 1 < pc->mb_cols)
+ xd->mode_info_context[1].mbmi.mb_skip_coeff = 1;
+ if (mb_row + 1 < pc->mb_rows) {
+ xd->mode_info_context[mis].mbmi.mb_skip_coeff = 1;
+ if (mb_col + 1 < pc->mb_cols)
+ xd->mode_info_context[mis + 1].mbmi.mb_skip_coeff = 1;
+ }
+ } else {
+ vp9_dequant_idct_add_32x32(xd->sb_coeff_data.qcoeff, xd->block[0].dequant,
+ xd->dst.y_buffer + x_idx * 32 +
+ xd->dst.y_stride * y_idx * 32,
+ xd->dst.y_buffer + x_idx * 32 +
+ xd->dst.y_stride * y_idx * 32,
+ xd->dst.y_stride, xd->dst.y_stride,
+ xd->eobs[0]);
+ vp9_dequant_idct_add_uv_block_16x16_c(xd->sb_coeff_data.qcoeff + 1024,
+ xd->block[16].dequant,
+ xd->dst.u_buffer + x_idx * 16 +
+ xd->dst.uv_stride * y_idx * 16,
+ xd->dst.v_buffer + x_idx * 16 +
+ xd->dst.uv_stride * y_idx * 16,
+ xd->dst.uv_stride, xd->eobs + 16);
+ }
+ }
+ } else {
+#endif
+ for (n = 0; n < 16; n++) {
+ int x_idx = n & 3, y_idx = n >> 2;
+
+ if (mb_col + x_idx >= pc->mb_cols || mb_row + y_idx >= pc->mb_rows)
+ continue;
+
+ xd->above_context = pc->above_context + mb_col + x_idx;
+ xd->left_context = pc->left_context + y_idx;
+ xd->mode_info_context = orig_mi + x_idx + y_idx * mis;
+ for (i = 0; i < 25; i++) {
+ xd->block[i].eob = 0;
+ xd->eobs[i] = 0;
+ }
+
+ eobtotal = vp9_decode_mb_tokens(pbi, xd, bc);
+ if (eobtotal == 0) { // skip loopfilter
+ xd->mode_info_context->mbmi.mb_skip_coeff = 1;
+ continue;
+ }
+
+ if (tx_size == TX_16X16) {
+ decode_16x16_sb(pbi, xd, bc, n, 3, 2);
+ } else if (tx_size == TX_8X8) {
+ decode_8x8_sb(pbi, xd, bc, n, 3, 2);
+ } else {
+ decode_4x4_sb(pbi, xd, bc, n, 3, 2);
+ }
+ }
+#if CONFIG_TX32X32
+ }
+#endif
+
+ xd->above_context = pc->above_context + mb_col;
+ xd->left_context = pc->left_context;
+ xd->mode_info_context = orig_mi;
+}
+#endif // CONFIG_SUPERBLOCKS64
+
+static void decode_superblock32(VP9D_COMP *pbi, MACROBLOCKD *xd,
+ int mb_row, unsigned int mb_col,
+ BOOL_DECODER* const bc) {
+ int i, n, eobtotal;
+ TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
+ VP9_COMMON *const pc = &pbi->common;
+ MODE_INFO *orig_mi = xd->mode_info_context;
+ const int mis = pc->mode_info_stride;
+
+ assert(xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB32X32);
if (pbi->common.frame_type != KEY_FRAME)
vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter, pc);
@@ -767,7 +917,7 @@ static void decode_superblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
xd->above_context = pc->above_context + mb_col + x_idx;
- xd->left_context = pc->left_context + y_idx;
+ xd->left_context = pc->left_context + y_idx + (mb_row & 2);
xd->mode_info_context = orig_mi + x_idx + y_idx * mis;
for (i = 0; i < 25; i++) {
xd->block[i].eob = 0;
@@ -781,16 +931,16 @@ static void decode_superblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
}
if (tx_size == TX_16X16) {
- decode_16x16_sb(pbi, xd, bc, n);
+ decode_16x16_sb(pbi, xd, bc, n, 1, 1);
} else if (tx_size == TX_8X8) {
- decode_8x8_sb(pbi, xd, bc, n);
+ decode_8x8_sb(pbi, xd, bc, n, 1, 1);
} else {
- decode_4x4_sb(pbi, xd, bc, n);
+ decode_4x4_sb(pbi, xd, bc, n, 1, 1);
}
}
xd->above_context = pc->above_context + mb_col;
- xd->left_context = pc->left_context;
+ xd->left_context = pc->left_context + (mb_row & 2);
xd->mode_info_context = orig_mi;
#if CONFIG_TX32X32
}
@@ -807,7 +957,7 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
int tx_size;
#if CONFIG_SUPERBLOCKS
- assert(!xd->mode_info_context->mbmi.encoded_as_sb);
+ assert(!xd->mode_info_context->mbmi.sb_type);
#endif
// re-initialize macroblock dequantizer before detokenization
@@ -930,190 +1080,186 @@ static int get_delta_q(vp9_reader *bc, int prev, int *q_update) {
FILE *vpxlog = 0;
#endif
-/* Decode a row of Superblocks (2x2 region of MBs) */
-static void
-decode_sb_row(VP9D_COMP *pbi, VP9_COMMON *pc, int mbrow, MACROBLOCKD *xd,
- BOOL_DECODER* const bc) {
- int i;
- int sb_col;
- int mb_row, mb_col;
- int recon_yoffset, recon_uvoffset;
- int ref_fb_idx = pc->lst_fb_idx;
- int dst_fb_idx = pc->new_fb_idx;
- int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
- int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
- int row_delta[4] = { 0, +1, 0, -1};
- int col_delta[4] = { +1, -1, +1, +1};
- int sb_cols = (pc->mb_cols + 1) >> 1;
+static void set_offsets(VP9D_COMP *pbi, int block_size,
+ int mb_row, int mb_col) {
+ VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
+ const int mis = cm->mode_info_stride;
+ const int idx = mis * mb_row + mb_col;
+ const int dst_fb_idx = cm->new_fb_idx;
+ const int recon_y_stride = cm->yv12_fb[dst_fb_idx].y_stride;
+ const int recon_uv_stride = cm->yv12_fb[dst_fb_idx].uv_stride;
+ const int recon_yoffset = mb_row * 16 * recon_y_stride + 16 * mb_col;
+ const int recon_uvoffset = mb_row * 8 * recon_uv_stride + 8 * mb_col;
+
+ xd->mode_info_context = cm->mi + idx;
+#if CONFIG_SUPERBLOCKS
+ xd->mode_info_context->mbmi.sb_type = block_size >> 5;
+#endif
+ xd->prev_mode_info_context = cm->prev_mi + idx;
+ xd->above_context = cm->above_context + mb_col;
+ xd->left_context = cm->left_context + (mb_row & 3);
- // For a SB there are 2 left contexts, each pertaining to a MB row within
- vpx_memset(pc->left_context, 0, sizeof(pc->left_context));
+ /* Distance of Mb to the various image edges.
+ * These are specified to 8th pel as they are always compared to
+ * values that are in 1/8th pel units
+ */
+ block_size >>= 4; // in mb units
+ xd->mb_to_top_edge = -((mb_row * 16)) << 3;
+ xd->mb_to_left_edge = -((mb_col * 16) << 3);
+ xd->mb_to_bottom_edge = ((cm->mb_rows - block_size - mb_row) * 16) << 3;
+ xd->mb_to_right_edge = ((cm->mb_cols - block_size - mb_col) * 16) << 3;
+
+ xd->up_available = (mb_row != 0);
+ xd->left_available = (mb_col != 0);
+
+ xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
+ xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
+ xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
+}
- mb_row = mbrow;
- mb_col = 0;
+static void set_refs(VP9D_COMP *pbi, int block_size,
+ int mb_row, int mb_col) {
+ VP9_COMMON *const cm = &pbi->common;
+ MACROBLOCKD *const xd = &pbi->mb;
+ MODE_INFO *mi = xd->mode_info_context;
+ MB_MODE_INFO *const mbmi = &mi->mbmi;
+
+ if (mbmi->ref_frame > INTRA_FRAME) {
+ int ref_fb_idx, ref_yoffset, ref_uvoffset, ref_y_stride, ref_uv_stride;
+
+ /* Select the appropriate reference frame for this MB */
+ if (mbmi->ref_frame == LAST_FRAME)
+ ref_fb_idx = cm->lst_fb_idx;
+ else if (mbmi->ref_frame == GOLDEN_FRAME)
+ ref_fb_idx = cm->gld_fb_idx;
+ else
+ ref_fb_idx = cm->alt_fb_idx;
- for (sb_col = 0; sb_col < sb_cols; sb_col++) {
- MODE_INFO *mi = xd->mode_info_context;
+ ref_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
+ ref_yoffset = mb_row * 16 * ref_y_stride + 16 * mb_col;
+ xd->pre.y_buffer = cm->yv12_fb[ref_fb_idx].y_buffer + ref_yoffset;
+ ref_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
+ ref_uvoffset = mb_row * 8 * ref_uv_stride + 8 * mb_col;
+ xd->pre.u_buffer = cm->yv12_fb[ref_fb_idx].u_buffer + ref_uvoffset;
+ xd->pre.v_buffer = cm->yv12_fb[ref_fb_idx].v_buffer + ref_uvoffset;
-#if CONFIG_SUPERBLOCKS
- mi->mbmi.encoded_as_sb = vp9_read(bc, pc->sb_coded);
-#endif
+ /* propagate errors from reference frames */
+ xd->corrupted |= cm->yv12_fb[ref_fb_idx].corrupted;
- // Process the 4 MBs within the SB in the order:
- // top-left, top-right, bottom-left, bottom-right
- for (i = 0; i < 4; i++) {
- int dy = row_delta[i];
- int dx = col_delta[i];
- int offset_extended = dy * xd->mode_info_stride + dx;
-
- xd->mb_index = i;
-
- mi = xd->mode_info_context;
- if ((mb_row >= pc->mb_rows) || (mb_col >= pc->mb_cols)) {
- // MB lies outside frame, skip on to next
- mb_row += dy;
- mb_col += dx;
- xd->mode_info_context += offset_extended;
- xd->prev_mode_info_context += offset_extended;
- continue;
- }
-#if CONFIG_SUPERBLOCKS
- if (i)
- mi->mbmi.encoded_as_sb = 0;
-#endif
+ if (mbmi->second_ref_frame > INTRA_FRAME) {
+ int second_ref_fb_idx;
- // Set above context pointer
- xd->above_context = pc->above_context + mb_col;
- xd->left_context = pc->left_context + (i >> 1);
+ /* Select the appropriate reference frame for this MB */
+ if (mbmi->second_ref_frame == LAST_FRAME)
+ second_ref_fb_idx = cm->lst_fb_idx;
+ else if (mbmi->second_ref_frame == GOLDEN_FRAME)
+ second_ref_fb_idx = cm->gld_fb_idx;
+ else
+ second_ref_fb_idx = cm->alt_fb_idx;
+
+ xd->second_pre.y_buffer =
+ cm->yv12_fb[second_ref_fb_idx].y_buffer + ref_yoffset;
+ xd->second_pre.u_buffer =
+ cm->yv12_fb[second_ref_fb_idx].u_buffer + ref_uvoffset;
+ xd->second_pre.v_buffer =
+ cm->yv12_fb[second_ref_fb_idx].v_buffer + ref_uvoffset;
+
+ /* propagate errors from reference frames */
+ xd->corrupted |= cm->yv12_fb[second_ref_fb_idx].corrupted;
+ }
+ }
- /* Distance of Mb to the various image edges.
- * These are specified to 8th pel as they are always compared to
- * values that are in 1/8th pel units
- */
- xd->mb_to_top_edge = -((mb_row * 16)) << 3;
- xd->mb_to_left_edge = -((mb_col * 16) << 3);
-#if CONFIG_SUPERBLOCKS
- if (mi->mbmi.encoded_as_sb) {
- xd->mb_to_bottom_edge = ((pc->mb_rows - 2 - mb_row) * 16) << 3;
- xd->mb_to_right_edge = ((pc->mb_cols - 2 - mb_col) * 16) << 3;
- } else {
-#endif
- xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
- xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
#if CONFIG_SUPERBLOCKS
+ if (mbmi->sb_type) {
+ const int n_mbs = 1 << mbmi->sb_type;
+ const int y_mbs = MIN(n_mbs, cm->mb_rows - mb_row);
+ const int x_mbs = MIN(n_mbs, cm->mb_cols - mb_col);
+ const int mis = cm->mode_info_stride;
+ int x, y;
+
+ for (y = 0; y < y_mbs; y++) {
+ for (x = !y; x < x_mbs; x++) {
+ mi[y * mis + x] = *mi;
}
+ }
+ }
#endif
-#ifdef DEC_DEBUG
- dec_debug = (pbi->common.current_video_frame == 46 &&
- mb_row == 5 && mb_col == 2);
- if (dec_debug)
-#if CONFIG_SUPERBLOCKS
- printf("Enter Debug %d %d sb %d\n", mb_row, mb_col,
- mi->mbmi.encoded_as_sb);
-#else
- printf("Enter Debug %d %d\n", mb_row, mb_col);
-#endif
-#endif
- xd->up_available = (mb_row != 0);
- xd->left_available = (mb_col != 0);
-
+}
- recon_yoffset = (mb_row * recon_y_stride * 16) + (mb_col * 16);
- recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col * 8);
+/* Decode a row of Superblocks (2x2 region of MBs) */
+static void decode_sb_row(VP9D_COMP *pbi, VP9_COMMON *pc,
+ int mb_row, MACROBLOCKD *xd,
+ BOOL_DECODER* const bc) {
+ int mb_col;
- xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
- xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
- xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
+ // For a SB there are 2 left contexts, each pertaining to a MB row within
+ vpx_memset(pc->left_context, 0, sizeof(pc->left_context));
+ for (mb_col = 0; mb_col < pc->mb_cols; mb_col += 4) {
+#if CONFIG_SUPERBLOCKS64 && CONFIG_SUPERBLOCKS
+ if (vp9_read(bc, pc->sb64_coded)) {
+ set_offsets(pbi, 64, mb_row, mb_col);
vp9_decode_mb_mode_mv(pbi, xd, mb_row, mb_col, bc);
+ set_refs(pbi, 64, mb_row, mb_col);
+ decode_superblock64(pbi, xd, mb_row, mb_col, bc);
+ xd->corrupted |= bool_error(bc);
+ } else
+#endif // CONFIG_SUPERBLOCKS64
+ {
+ int j;
- update_blockd_bmi(xd);
-#ifdef DEC_DEBUG
- if (dec_debug)
- printf("Hello\n");
-#endif
-
- /* Select the appropriate reference frame for this MB */
- if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
- ref_fb_idx = pc->lst_fb_idx;
- else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
- ref_fb_idx = pc->gld_fb_idx;
- else
- ref_fb_idx = pc->alt_fb_idx;
-
- xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
- xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
- xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
+ for (j = 0; j < 4; j++) {
+ const int x_idx_sb = (j & 1) << 1, y_idx_sb = j & 2;
- if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
- int second_ref_fb_idx;
-
- /* Select the appropriate reference frame for this MB */
- if (xd->mode_info_context->mbmi.second_ref_frame == LAST_FRAME)
- second_ref_fb_idx = pc->lst_fb_idx;
- else if (xd->mode_info_context->mbmi.second_ref_frame ==
- GOLDEN_FRAME)
- second_ref_fb_idx = pc->gld_fb_idx;
- else
- second_ref_fb_idx = pc->alt_fb_idx;
-
- xd->second_pre.y_buffer =
- pc->yv12_fb[second_ref_fb_idx].y_buffer + recon_yoffset;
- xd->second_pre.u_buffer =
- pc->yv12_fb[second_ref_fb_idx].u_buffer + recon_uvoffset;
- xd->second_pre.v_buffer =
- pc->yv12_fb[second_ref_fb_idx].v_buffer + recon_uvoffset;
- }
+ if (mb_row + y_idx_sb >= pc->mb_rows ||
+ mb_col + x_idx_sb >= pc->mb_cols) {
+ // MB lies outside frame, skip on to next
+ continue;
+ }
- if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME) {
- /* propagate errors from reference frames */
- xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
- }
+ xd->sb_index = j;
#if CONFIG_SUPERBLOCKS
- if (xd->mode_info_context->mbmi.encoded_as_sb) {
- if (mb_col < pc->mb_cols - 1)
- mi[1] = mi[0];
- if (mb_row < pc->mb_rows - 1) {
- mi[pc->mode_info_stride] = mi[0];
- if (mb_col < pc->mb_cols - 1)
- mi[pc->mode_info_stride + 1] = mi[0];
- }
- }
- if (xd->mode_info_context->mbmi.encoded_as_sb) {
- decode_superblock(pbi, xd, mb_row, mb_col, bc);
- } else {
-#endif
- vp9_intra_prediction_down_copy(xd);
- decode_macroblock(pbi, xd, mb_row, mb_col, bc);
-#if CONFIG_SUPERBLOCKS
- }
-#endif
+ if (vp9_read(bc, pc->sb32_coded)) {
+ set_offsets(pbi, 32, mb_row + y_idx_sb, mb_col + x_idx_sb);
+ vp9_decode_mb_mode_mv(pbi,
+ xd, mb_row + y_idx_sb, mb_col + x_idx_sb, bc);
+ set_refs(pbi, 32, mb_row + y_idx_sb, mb_col + x_idx_sb);
+ decode_superblock32(pbi,
+ xd, mb_row + y_idx_sb, mb_col + x_idx_sb, bc);
+ xd->corrupted |= bool_error(bc);
+ } else
+#endif // CONFIG_SUPERBLOCKS
+ {
+ int i;
+
+ // Process the 4 MBs within the SB in the order:
+ // top-left, top-right, bottom-left, bottom-right
+ for (i = 0; i < 4; i++) {
+ const int x_idx = x_idx_sb + (i & 1), y_idx = y_idx_sb + (i >> 1);
+
+ if (mb_row + y_idx >= pc->mb_rows ||
+ mb_col + x_idx >= pc->mb_cols) {
+ // MB lies outside frame, skip on to next
+ continue;
+ }
- /* check if the boolean decoder has suffered an error */
- xd->corrupted |= bool_error(bc);
+ set_offsets(pbi, 16, mb_row + y_idx, mb_col + x_idx);
+ xd->mb_index = i;
+ vp9_decode_mb_mode_mv(pbi, xd, mb_row + y_idx, mb_col + x_idx, bc);
+ update_blockd_bmi(xd);
+ set_refs(pbi, 16, mb_row + y_idx, mb_col + x_idx);
+ vp9_intra_prediction_down_copy(xd);
+ decode_macroblock(pbi, xd, mb_row, mb_col, bc);
-#if CONFIG_SUPERBLOCKS
- if (mi->mbmi.encoded_as_sb) {
- assert(!i);
- mb_col += 2;
- xd->mode_info_context += 2;
- xd->prev_mode_info_context += 2;
- break;
+ /* check if the boolean decoder has suffered an error */
+ xd->corrupted |= bool_error(bc);
+ }
+ }
}
-#endif
-
- // skip to next MB
- xd->mode_info_context += offset_extended;
- xd->prev_mode_info_context += offset_extended;
- mb_row += dy;
- mb_col += dx;
}
}
-
- /* skip prediction column */
- xd->mode_info_context += 1 - (pc->mb_cols & 0x1) + xd->mode_info_stride;
- xd->prev_mode_info_context += 1 - (pc->mb_cols & 0x1) + xd->mode_info_stride;
}
static unsigned int read_partition_size(const unsigned char *cx_size) {
@@ -1462,7 +1608,10 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
}
#if CONFIG_SUPERBLOCKS
- pc->sb_coded = vp9_read_literal(&header_bc, 8);
+#if CONFIG_SUPERBLOCKS64
+ pc->sb64_coded = vp9_read_literal(&header_bc, 8);
+#endif
+ pc->sb32_coded = vp9_read_literal(&header_bc, 8);
#endif
/* Read the loop filter level and type */
@@ -1727,12 +1876,8 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
vpx_memset(pc->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols);
- // Resset the macroblock mode info context to the start of the list
- xd->mode_info_context = pc->mi;
- xd->prev_mode_info_context = pc->prev_mi;
-
/* Decode a row of superblocks */
- for (mb_row = 0; mb_row < pc->mb_rows; mb_row += 2) {
+ for (mb_row = 0; mb_row < pc->mb_rows; mb_row += 4) {
decode_sb_row(pbi, pc, mb_row, xd, &residual_bc);
}
corrupt_tokens |= xd->corrupted;