return tx_type;
}
+#define USE_ADST_FOR_I16X16_8X8 0
+#define USE_ADST_FOR_I16X16_4X4 0
+#define USE_ADST_FOR_I8X8_4X4 1
+#define USE_ADST_PERIPHERY_ONLY 1
+
static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, const BLOCKD *b) {
+ // TODO(debargha): explore different patterns for ADST usage when blocksize
+ // is smaller than the prediction size
TX_TYPE tx_type = DCT_DCT;
+ int ib = (int)(b - xd->block);
+ if (ib >= 16)
+ return tx_type;
+#if CONFIG_SUPERBLOCKS
+ // TODO(rbultje, debargha): Explore ADST usage for superblocks
+ if (xd->mode_info_context->mbmi.encoded_as_sb)
+ return tx_type;
+#endif
if (xd->mode_info_context->mbmi.mode == B_PRED &&
xd->q_index < ACTIVE_HT) {
tx_type = txfm_map(
b->bmi.as_mode.first == B_CONTEXT_PRED ? b->bmi.as_mode.context :
#endif
b->bmi.as_mode.first);
+ } else if (xd->mode_info_context->mbmi.mode == I8X8_PRED &&
+ xd->q_index < ACTIVE_HT) {
+#if USE_ADST_FOR_I8X8_4X4
+#if USE_ADST_PERIPHERY_ONLY
+ // Use ADST for periphery blocks only
+ int ic = (ib & 10);
+ b += ic - ib;
+ tx_type = (ic != 10) ?
+ txfm_map(pred_mode_conv((MB_PREDICTION_MODE)b->bmi.as_mode.first)) :
+ DCT_DCT;
+#else
+ // Use ADST
+ tx_type = txfm_map(pred_mode_conv(
+ (MB_PREDICTION_MODE)b->bmi.as_mode.first));
+#endif
+#else
+ // Use 2D DCT
+ tx_type = DCT_DCT;
+#endif
+ } else if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
+ xd->q_index < ACTIVE_HT) {
+#if USE_ADST_FOR_I16X16_4X4
+#if USE_ADST_PERIPHERY_ONLY
+ // Use ADST for periphery blocks only
+ tx_type = (ib < 4 || ((ib & 3) == 0)) ?
+ txfm_map(pred_mode_conv(xd->mode_info_context->mbmi.mode)) : DCT_DCT;
+#else
+ // Use ADST
+ tx_type = txfm_map(pred_mode_conv(xd->mode_info_context->mbmi.mode));
+#endif
+#else
+ // Use 2D DCT
+ tx_type = DCT_DCT;
+#endif
}
return tx_type;
}
static TX_TYPE get_tx_type_8x8(const MACROBLOCKD *xd, const BLOCKD *b) {
+ // TODO(debargha): explore different patterns for ADST usage when blocksize
+ // is smaller than the prediction size
TX_TYPE tx_type = DCT_DCT;
+ int ib = (int)(b - xd->block);
+ if (ib >= 16)
+ return tx_type;
+#if CONFIG_SUPERBLOCKS
+ // TODO(rbultje, debargha): Explore ADST usage for superblocks
+ if (xd->mode_info_context->mbmi.encoded_as_sb)
+ return tx_type;
+#endif
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)b->bmi.as_mode.first));
+ (MB_PREDICTION_MODE)b->bmi.as_mode.first));
+ } else if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
+ xd->q_index < ACTIVE_HT8) {
+#if USE_ADST_FOR_I8X8_4X4
+#if USE_ADST_PERIPHERY_ONLY
+ // Use ADST for periphery blocks only
+ tx_type = (ib != 10) ?
+ txfm_map(pred_mode_conv(xd->mode_info_context->mbmi.mode)) : DCT_DCT;
+#else
+ // Use ADST
+ tx_type = txfm_map(pred_mode_conv(xd->mode_info_context->mbmi.mode));
+#endif
+#else
+ // Use 2D DCT
+ tx_type = DCT_DCT;
+#endif
}
return tx_type;
}
static TX_TYPE get_tx_type_16x16(const MACROBLOCKD *xd, const BLOCKD *b) {
TX_TYPE tx_type = DCT_DCT;
- if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
+ int ib = (int)(b - xd->block);
+ if (ib >= 16)
+ return tx_type;
#if CONFIG_SUPERBLOCKS
- !xd->mode_info_context->mbmi.encoded_as_sb &&
+ // TODO(rbultje, debargha): Explore ADST usage for superblocks
+ if (xd->mode_info_context->mbmi.encoded_as_sb)
+ return tx_type;
#endif
+ if (xd->mode_info_context->mbmi.mode < I8X8_PRED &&
xd->q_index < ACTIVE_HT16) {
tx_type = txfm_map(pred_mode_conv(xd->mode_info_context->mbmi.mode));
}
return tx_type;
}
+static int get_2nd_order_usage(const MACROBLOCKD *xd) {
+ int has_2nd_order = (xd->mode_info_context->mbmi.mode != SPLITMV &&
+ xd->mode_info_context->mbmi.mode != I8X8_PRED &&
+ xd->mode_info_context->mbmi.mode != B_PRED &&
+ xd->mode_info_context->mbmi.txfm_size != TX_16X16);
+ if (has_2nd_order)
+ has_2nd_order = (get_tx_type(xd, xd->block) == DCT_DCT);
+ return has_2nd_order;
+}
+
extern void vp9_build_block_doffsets(MACROBLOCKD *xd);
extern void vp9_setup_block_dptrs(MACROBLOCKD *xd);
void vp9_inverse_transform_mby_4x4(MACROBLOCKD *xd) {
int i;
BLOCKD *blockd = xd->block;
+ int has_2nd_order = get_2nd_order_usage(xd);
- if (xd->mode_info_context->mbmi.mode != SPLITMV) {
+ if (has_2nd_order) {
/* do 2nd order transform on the dc block */
vp9_short_inv_walsh4x4(blockd[24].dqcoeff, blockd[24].diff);
recon_dcblock(xd);
}
for (i = 0; i < 16; i++) {
- vp9_inverse_transform_b_4x4(xd, i, 32);
+ TX_TYPE tx_type = get_tx_type_4x4(xd, &xd->block[i]);
+ if (tx_type != DCT_DCT) {
+ vp9_ihtllm_c(xd->block[i].dqcoeff, xd->block[i].diff, 32,
+ tx_type, 4);
+ } else {
+ vp9_inverse_transform_b_4x4(xd, i, 32);
+ }
}
}
void vp9_inverse_transform_mbuv_4x4(MACROBLOCKD *xd) {
int i;
+
for (i = 16; i < 24; i++) {
vp9_inverse_transform_b_4x4(xd, i, 16);
}
void vp9_inverse_transform_mby_8x8(MACROBLOCKD *xd) {
int i;
BLOCKD *blockd = xd->block;
+ int has_2nd_order = get_2nd_order_usage(xd);
- if (xd->mode_info_context->mbmi.mode != SPLITMV) {
+ if (has_2nd_order) {
// do 2nd order transform on the dc block
vp9_short_ihaar2x2(blockd[24].dqcoeff, blockd[24].diff, 8);
recon_dcblock_8x8(xd); // need to change for 8x8
}
for (i = 0; i < 9; i += 8) {
- vp9_inverse_transform_b_8x8(&blockd[i].dqcoeff[0],
- &blockd[i].diff[0], 32);
+ TX_TYPE tx_type = get_tx_type_8x8(xd, &xd->block[i]);
+ if (tx_type != DCT_DCT) {
+ vp9_ihtllm_c(xd->block[i].dqcoeff, xd->block[i].diff, 32, tx_type, 8);
+ } else {
+ vp9_inverse_transform_b_8x8(&blockd[i].dqcoeff[0],
+ &blockd[i].diff[0], 32);
+ }
}
for (i = 2; i < 11; i += 8) {
- vp9_inverse_transform_b_8x8(&blockd[i + 2].dqcoeff[0],
- &blockd[i].diff[0], 32);
+ TX_TYPE tx_type = get_tx_type_8x8(xd, &xd->block[i]);
+ if (tx_type != DCT_DCT) {
+ vp9_ihtllm_c(xd->block[i + 2].dqcoeff, xd->block[i].diff, 32, tx_type, 8);
+ } else {
+ vp9_inverse_transform_b_8x8(&blockd[i + 2].dqcoeff[0],
+ &blockd[i].diff[0], 32);
+ }
}
}
}
void vp9_inverse_transform_mby_16x16(MACROBLOCKD *xd) {
- vp9_inverse_transform_b_16x16(&xd->block[0].dqcoeff[0],
- &xd->block[0].diff[0], 32);
+ BLOCKD *bd = &xd->block[0];
+ TX_TYPE tx_type = get_tx_type_16x16(xd, bd);
+ if (tx_type != DCT_DCT) {
+ vp9_ihtllm_c(bd->dqcoeff, bd->diff, 32, tx_type, 16);
+ } else {
+ vp9_inverse_transform_b_16x16(&xd->block[0].dqcoeff[0],
+ &xd->block[0].diff[0], 32);
+ }
}
void vp9_inverse_transform_mb_16x16(MACROBLOCKD *xd) {
&index, c_refmv, ref_weight);
// If there is a second valid mv then add it as well.
- if (c2_ref_frame != INTRA_FRAME) {
+ if (c2_ref_frame > INTRA_FRAME) {
scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias );
ref_weight = ref_distance_weight[i] +
((c2_ref_frame == ref_frame) << 4);
&index, c_refmv, ref_weight);
// If there is a second valid mv then add it as well.
- if (c2_ref_frame != INTRA_FRAME) {
+ if (c2_ref_frame > INTRA_FRAME) {
scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias );
ref_weight = ref_distance_weight[i] +
((c2_ref_frame == ref_frame) << 4);
&index, c_refmv, ref_weight);
// If there is a second valid mv then add it as well.
- if (c2_ref_frame != INTRA_FRAME) {
+ if (c2_ref_frame > INTRA_FRAME) {
scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias );
ref_weight = ref_distance_weight[i] +
((c2_ref_frame == ref_frame) << 4);
// TODO(debargha): Explore different ways of combining predictors
// or designing the tables below
static const int scale_bits = 8;
- static const int scale_max = 1 << scale_bits;
- static const int scale_round = (1 << scale_bits) - 1;
+ static const int scale_max = 256; // 1 << scale_bits;
+ static const int scale_round = 127; // (1 << (scale_bits - 1));
// This table is a function A + B*exp(-kx), where x is hor. index
static const int weights1d[32] = {
128, 122, 116, 111, 107, 103, 99, 96,
#ifdef DEBUG_DEC_MV
int dec_mvcount = 0;
#endif
+// #define DEC_DEBUG
+#ifdef DEC_DEBUG
+extern int dec_debug;
+#endif
static int read_bmode(vp9_reader *bc, const vp9_prob *p) {
B_PREDICTION_MODE m = treed_read(bc, vp9_bmode_tree, p);
xd->pre.u_buffer = cm->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
xd->pre.v_buffer = cm->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
+#ifdef DEC_DEBUG
+ if (dec_debug)
+ printf("%d %d\n", xd->mode_info_context->mbmi.mv[0].as_mv.row,
+ xd->mode_info_context->mbmi.mv[0].as_mv.col);
+#endif
vp9_find_mv_refs(xd, mi, prev_mi,
ref_frame, mbmi->ref_mvs[ref_frame],
cm->ref_frame_sign_bias);
vp9_mv_ref_probs(&pbi->common, mv_ref_p,
mbmi->mb_mode_context[ref_frame]);
+#ifdef DEC_DEBUG
+ if (dec_debug)
+ printf("[D %d %d] %d %d %d %d\n", ref_frame,
+ mbmi->mb_mode_context[ref_frame],
+ mv_ref_p[0], mv_ref_p[1], mv_ref_p[2], mv_ref_p[3]);
+#endif
}
// Is the segment level mode feature enabled for this segment
#include <assert.h>
#include <stdio.h>
-
#define COEFCOUNT_TESTING
+// #define DEC_DEBUG
+#ifdef DEC_DEBUG
+int dec_debug = 0;
+#endif
+
static int merge_index(int v, int n, int modulus) {
int max1 = (n - 1 - modulus / 2) / modulus + 1;
if (v < max1) v = v * modulus + modulus / 2;
}
}
+static void decode_16x16(VP9D_COMP *pbi, MACROBLOCKD *xd,
+ BOOL_DECODER* const bc) {
+ BLOCKD *bd = &xd->block[0];
+ TX_TYPE tx_type = get_tx_type_16x16(xd, bd);
+ assert(get_2nd_order_usage(xd) == 0);
+#ifdef DEC_DEBUG
+ if (dec_debug) {
+ int i;
+ printf("\n");
+ printf("qcoeff 16x16\n");
+ for (i = 0; i < 400; i++) {
+ printf("%3d ", xd->qcoeff[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ printf("\n");
+ printf("predictor\n");
+ for (i = 0; i < 400; i++) {
+ printf("%3d ", xd->predictor[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ }
+#endif
+ if (tx_type != DCT_DCT) {
+ vp9_ht_dequant_idct_add_16x16_c(tx_type, xd->qcoeff,
+ xd->block[0].dequant, xd->predictor,
+ xd->dst.y_buffer, 16, xd->dst.y_stride);
+ } else {
+ vp9_dequant_idct_add_16x16(xd->qcoeff, xd->block[0].dequant,
+ xd->predictor, xd->dst.y_buffer,
+ 16, xd->dst.y_stride, xd->eobs[0]);
+ }
+ vp9_dequant_idct_add_uv_block_8x8(
+ xd->qcoeff + 16 * 16, xd->block[16].dequant,
+ xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
+ xd->dst.uv_stride, xd->eobs + 16, xd);
+}
+
+static void decode_8x8(VP9D_COMP *pbi, MACROBLOCKD *xd,
+ BOOL_DECODER* const bc) {
+ // First do Y
+ // if the first one is DCT_DCT assume all the rest are as well
+ TX_TYPE tx_type = get_tx_type_8x8(xd, &xd->block[0]);
+#ifdef DEC_DEBUG
+ if (dec_debug) {
+ int i;
+ printf("\n");
+ printf("qcoeff 8x8\n");
+ for (i = 0; i < 400; i++) {
+ printf("%3d ", xd->qcoeff[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ }
+#endif
+ if (tx_type != DCT_DCT || xd->mode_info_context->mbmi.mode == I8X8_PRED) {
+ int i;
+ assert(get_2nd_order_usage(xd) == 0);
+ for (i = 0; i < 4; i++) {
+ int ib = vp9_i8x8_block[i];
+ const int iblock[4] = {0, 1, 4, 5};
+ int idx = (ib & 0x02) ? (ib + 2) : ib;
+ short *q = xd->block[idx].qcoeff;
+ short *dq = xd->block[0].dequant;
+ unsigned char *pre = xd->block[ib].predictor;
+ unsigned char *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
+ int stride = xd->dst.y_stride;
+ BLOCKD *b = &xd->block[ib];
+ if (xd->mode_info_context->mbmi.mode == I8X8_PRED) {
+ int i8x8mode = b->bmi.as_mode.first;
+ vp9_intra8x8_predict(b, i8x8mode, b->predictor);
+ }
+ tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
+ if (tx_type != DCT_DCT) {
+ vp9_ht_dequant_idct_add_8x8_c(tx_type, q, dq, pre, dst, 16, stride);
+ } else {
+ vp9_dequant_idct_add_8x8_c(q, dq, pre, dst, 16, stride,
+ 0, xd->eobs[idx]);
+ }
+ }
+ } else if (xd->mode_info_context->mbmi.mode == SPLITMV) {
+ assert(get_2nd_order_usage(xd) == 0);
+ vp9_dequant_idct_add_y_block_8x8(xd->qcoeff,
+ xd->block[0].dequant,
+ xd->predictor,
+ xd->dst.y_buffer,
+ xd->dst.y_stride,
+ xd->eobs, xd);
+ } else {
+ assert(get_2nd_order_usage(xd) == 1);
+ BLOCKD *b = &xd->block[24];
+ vp9_dequantize_b_2x2(b);
+ vp9_short_ihaar2x2(&b->dqcoeff[0], b->diff, 8);
+ ((int *)b->qcoeff)[0] = 0; // 2nd order block are set to 0 after idct
+ ((int *)b->qcoeff)[1] = 0;
+ ((int *)b->qcoeff)[2] = 0;
+ ((int *)b->qcoeff)[3] = 0;
+ ((int *)b->qcoeff)[4] = 0;
+ ((int *)b->qcoeff)[5] = 0;
+ ((int *)b->qcoeff)[6] = 0;
+ ((int *)b->qcoeff)[7] = 0;
+ vp9_dequant_dc_idct_add_y_block_8x8(xd->qcoeff,
+ xd->block[0].dequant,
+ xd->predictor,
+ xd->dst.y_buffer,
+ xd->dst.y_stride,
+ xd->eobs,
+ xd->block[24].diff,
+ xd);
+ }
+
+ // Now do UV
+ if (xd->mode_info_context->mbmi.mode == I8X8_PRED) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ int ib = vp9_i8x8_block[i];
+ BLOCKD *b = &xd->block[ib];
+ int i8x8mode = b->bmi.as_mode.first;
+ b = &xd->block[16 + i];
+ vp9_intra_uv4x4_predict(&xd->block[16 + i], i8x8mode, b->predictor);
+ pbi->idct_add(b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 8, b->dst_stride);
+ b = &xd->block[20 + i];
+ vp9_intra_uv4x4_predict(&xd->block[20 + i], i8x8mode, b->predictor);
+ pbi->idct_add(b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 8, b->dst_stride);
+ }
+ } else if (xd->mode_info_context->mbmi.mode == SPLITMV) {
+ pbi->idct_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant,
+ xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
+ xd->dst.uv_stride, xd->eobs + 16);
+ } else {
+ vp9_dequant_idct_add_uv_block_8x8
+ (xd->qcoeff + 16 * 16, xd->block[16].dequant,
+ xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
+ xd->dst.uv_stride, xd->eobs + 16, xd);
+ }
+#ifdef DEC_DEBUG
+ if (dec_debug) {
+ int i;
+ printf("\n");
+ printf("predictor\n");
+ for (i = 0; i < 384; i++) {
+ printf("%3d ", xd->predictor[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ }
+#endif
+}
+
+static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd,
+ BOOL_DECODER* const bc) {
+ TX_TYPE tx_type;
+ int i, eobtotal = 0;
+ MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode;
+ if (mode == I8X8_PRED) {
+ assert(get_2nd_order_usage(xd) == 0);
+ for (i = 0; i < 4; i++) {
+ int ib = vp9_i8x8_block[i];
+ const int iblock[4] = {0, 1, 4, 5};
+ int j;
+ int i8x8mode;
+ BLOCKD *b;
+ int idx = (ib & 0x02) ? (ib + 2) : ib;
+ short *q = xd->block[idx].qcoeff;
+ short *dq = xd->block[0].dequant;
+ unsigned char *pre = xd->block[ib].predictor;
+ unsigned char *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
+ int stride = xd->dst.y_stride;
+ b = &xd->block[ib];
+ i8x8mode = b->bmi.as_mode.first;
+ vp9_intra8x8_predict(b, i8x8mode, b->predictor);
+ for (j = 0; j < 4; j++) {
+ b = &xd->block[ib + iblock[j]];
+ tx_type = get_tx_type_4x4(xd, b);
+ if (tx_type != DCT_DCT) {
+ vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
+ b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 16,
+ b->dst_stride);
+ } else {
+ vp9_dequant_idct_add(b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 16, b->dst_stride);
+ }
+ }
+ b = &xd->block[16 + i];
+ vp9_intra_uv4x4_predict(b, i8x8mode, b->predictor);
+ pbi->idct_add(b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 8, b->dst_stride);
+ b = &xd->block[20 + i];
+ vp9_intra_uv4x4_predict(b, i8x8mode, b->predictor);
+ pbi->idct_add(b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 8, b->dst_stride);
+ }
+ } else if (mode == B_PRED) {
+ assert(get_2nd_order_usage(xd) == 0);
+ for (i = 0; i < 16; i++) {
+ int b_mode;
+#if CONFIG_COMP_INTRA_PRED
+ int b_mode2;
+#endif
+ BLOCKD *b = &xd->block[i];
+ b_mode = xd->mode_info_context->bmi[i].as_mode.first;
+#if CONFIG_NEWBINTRAMODES
+ xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context =
+ vp9_find_bpred_context(b);
+#endif
+ if (!xd->mode_info_context->mbmi.mb_skip_coeff)
+ eobtotal += vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i);
+#if CONFIG_COMP_INTRA_PRED
+ b_mode2 = xd->mode_info_context->bmi[i].as_mode.second;
+
+ if (b_mode2 == (B_PREDICTION_MODE)(B_DC_PRED - 1)) {
+#endif
+ vp9_intra4x4_predict(b, b_mode, b->predictor);
+#if CONFIG_COMP_INTRA_PRED
+ } else {
+ vp9_comp_intra4x4_predict(b, b_mode, b_mode2, b->predictor);
+ }
+#endif
+ tx_type = get_tx_type_4x4(xd, b);
+ if (tx_type != DCT_DCT) {
+ vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
+ b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 16, b->dst_stride);
+ } else {
+ vp9_dequant_idct_add(b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 16, b->dst_stride);
+ }
+ xd->above_context->y2 = 1;
+ xd->left_context->y2 = 1;
+ }
+ if (!xd->mode_info_context->mbmi.mb_skip_coeff) {
+ vp9_decode_mb_tokens_4x4_uv(pbi, xd, bc);
+ }
+ vp9_build_intra_predictors_mbuv(xd);
+ pbi->idct_add_uv_block(xd->qcoeff + 16 * 16,
+ xd->block[16].dequant,
+ xd->predictor + 16 * 16,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.uv_stride,
+ xd->eobs + 16);
+ } else if (mode == SPLITMV) {
+ assert(get_2nd_order_usage(xd) == 0);
+ pbi->idct_add_y_block(xd->qcoeff,
+ xd->block[0].dequant,
+ xd->predictor,
+ xd->dst.y_buffer,
+ xd->dst.y_stride,
+ xd->eobs);
+ pbi->idct_add_uv_block(xd->qcoeff + 16 * 16,
+ xd->block[16].dequant,
+ xd->predictor + 16 * 16,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.uv_stride,
+ xd->eobs + 16);
+ } else {
+#ifdef DEC_DEBUG
+ if (dec_debug) {
+ int i;
+ printf("\n");
+ printf("qcoeff 4x4\n");
+ for (i = 0; i < 400; i++) {
+ printf("%3d ", xd->qcoeff[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ printf("\n");
+ printf("predictor\n");
+ for (i = 0; i < 400; i++) {
+ printf("%3d ", xd->predictor[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ }
+#endif
+ tx_type = get_tx_type_4x4(xd, &xd->block[0]);
+ if (tx_type != DCT_DCT) {
+ assert(get_2nd_order_usage(xd) == 0);
+ for (i = 0; i < 16; i++) {
+ BLOCKD *b = &xd->block[i];
+ tx_type = get_tx_type_4x4(xd, b);
+ if (tx_type != DCT_DCT) {
+ vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
+ b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 16,
+ b->dst_stride);
+ } else {
+ vp9_dequant_idct_add(b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 16, b->dst_stride);
+ }
+ }
+ } else {
+ assert(get_2nd_order_usage(xd) == 1);
+ BLOCKD *b = &xd->block[24];
+ vp9_dequantize_b(b);
+ if (xd->eobs[24] > 1) {
+ vp9_short_inv_walsh4x4(&b->dqcoeff[0], b->diff);
+ ((int *)b->qcoeff)[0] = 0;
+ ((int *)b->qcoeff)[1] = 0;
+ ((int *)b->qcoeff)[2] = 0;
+ ((int *)b->qcoeff)[3] = 0;
+ ((int *)b->qcoeff)[4] = 0;
+ ((int *)b->qcoeff)[5] = 0;
+ ((int *)b->qcoeff)[6] = 0;
+ ((int *)b->qcoeff)[7] = 0;
+ } else {
+ xd->inv_walsh4x4_1(&b->dqcoeff[0], b->diff);
+ ((int *)b->qcoeff)[0] = 0;
+ }
+ vp9_dequantize_b(b);
+ pbi->dc_idct_add_y_block(xd->qcoeff,
+ xd->block[0].dequant,
+ xd->predictor,
+ xd->dst.y_buffer,
+ xd->dst.y_stride,
+ xd->eobs,
+ xd->block[24].diff);
+ }
+ pbi->idct_add_uv_block(xd->qcoeff + 16 * 16,
+ xd->block[16].dequant,
+ xd->predictor + 16 * 16,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.uv_stride,
+ xd->eobs + 16);
+ }
+}
+
#if CONFIG_SUPERBLOCKS
static void decode_superblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
int mb_row, unsigned int mb_col,
}
if (tx_size == TX_16X16) {
- vp9_dequant_idct_add_16x16(xd->qcoeff, xd->block[0].dequant,
- xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
- xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
- xd->dst.y_stride, xd->dst.y_stride, xd->eobs[0]);
+ TX_TYPE tx_type = get_tx_type_16x16(xd, &xd->block[0]);
+ if (tx_type != DCT_DCT) {
+ vp9_ht_dequant_idct_add_16x16_c(
+ tx_type, xd->qcoeff, xd->block[0].dequant,
+ xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+ xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+ xd->dst.y_stride, xd->dst.y_stride);
+ } else {
+ vp9_dequant_idct_add_16x16(
+ xd->qcoeff, xd->block[0].dequant,
+ xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+ xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+ xd->dst.y_stride, xd->dst.y_stride, xd->eobs[0]);
+ }
vp9_dequant_idct_add_uv_block_8x8_inplace_c(xd->qcoeff + 16 * 16,
xd->block[16].dequant,
xd->dst.u_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.v_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.uv_stride, xd->eobs + 16, xd);
} else if (tx_size == TX_8X8) {
- vp9_dequantize_b_2x2(b);
- vp9_short_ihaar2x2(&b->dqcoeff[0], b->diff, 8);
- ((int *)b->qcoeff)[0] = 0; // 2nd order block are set to 0 after idct
- ((int *)b->qcoeff)[1] = 0;
- ((int *)b->qcoeff)[2] = 0;
- ((int *)b->qcoeff)[3] = 0;
- ((int *)b->qcoeff)[4] = 0;
- ((int *)b->qcoeff)[5] = 0;
- ((int *)b->qcoeff)[6] = 0;
- ((int *)b->qcoeff)[7] = 0;
- vp9_dequant_dc_idct_add_y_block_8x8_inplace_c(xd->qcoeff,
- xd->block[0].dequant,
- xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
- xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
- vp9_dequant_idct_add_uv_block_8x8_inplace_c(xd->qcoeff + 16 * 16,
- xd->block[16].dequant,
- xd->dst.u_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
- xd->dst.v_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
- xd->dst.uv_stride, xd->eobs + 16, xd);
- } else {
- vp9_dequantize_b(b);
- if (xd->eobs[24] > 1) {
- vp9_short_inv_walsh4x4(&b->dqcoeff[0], b->diff);
- ((int *)b->qcoeff)[0] = 0;
+ TX_TYPE tx_type = get_tx_type_8x8(xd, &xd->block[0]);
+ if (tx_type != DCT_DCT) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ int ib = vp9_i8x8_block[i];
+ const int iblock[4] = {0, 1, 4, 5};
+ const int ioffset[4] = {0, 1, 0, 1};
+ int idx = (ib & 0x02) ? (ib + 2) : ib;
+ int i8x8mode = -1;
+ short *q = xd->block[idx].qcoeff;
+ short *dq = xd->block[0].dequant;
+ unsigned char *pre = xd->block[ib].predictor;
+ unsigned char *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
+ int stride = xd->dst.y_stride;
+ BLOCKD *b = &xd->block[ib];
+ tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
+ if (tx_type != DCT_DCT) {
+ vp9_ht_dequant_idct_add_8x8_c(
+ tx_type, q, dq,
+ xd->dst.y_buffer + (y_idx * 16 + (i / 2) * 8) * xd->dst.y_stride
+ + x_idx * 16 + (i & 1) * 8,
+ xd->dst.y_buffer + (y_idx * 16 + (i / 2) * 8) * xd->dst.y_stride
+ + x_idx * 16 + (i & 1) * 8,
+ stride, stride);
+ } else {
+ vp9_dequant_idct_add_8x8_c(
+ q, dq,
+ xd->dst.y_buffer + (y_idx * 16 + (i / 2) * 8) * xd->dst.y_stride
+ + x_idx * 16 + (i & 1) * 8,
+ xd->dst.y_buffer + (y_idx * 16 + (i / 2) * 8) * xd->dst.y_stride
+ + x_idx * 16 + (i & 1) * 8,
+ stride, stride, 0, b->eob);
+ }
+ vp9_dequant_idct_add_uv_block_8x8_inplace_c(
+ xd->qcoeff + 16 * 16, xd->block[16].dequant,
+ xd->dst.u_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
+ xd->dst.v_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
+ xd->dst.uv_stride, xd->eobs + 16, xd);
+ }
+ } else {
+ vp9_dequantize_b_2x2(b);
+ vp9_short_ihaar2x2(&b->dqcoeff[0], b->diff, 8);
+ ((int *)b->qcoeff)[0] = 0; // 2nd order block are set to 0 after idct
((int *)b->qcoeff)[1] = 0;
((int *)b->qcoeff)[2] = 0;
((int *)b->qcoeff)[3] = 0;
((int *)b->qcoeff)[5] = 0;
((int *)b->qcoeff)[6] = 0;
((int *)b->qcoeff)[7] = 0;
+ vp9_dequant_dc_idct_add_y_block_8x8_inplace_c(
+ xd->qcoeff, xd->block[0].dequant,
+ xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+ xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
+ vp9_dequant_idct_add_uv_block_8x8_inplace_c(
+ xd->qcoeff + 16 * 16, xd->block[16].dequant,
+ xd->dst.u_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
+ xd->dst.v_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
+ xd->dst.uv_stride, xd->eobs + 16, xd);
+ }
+ } else {
+ TX_TYPE tx_type = get_tx_type_4x4(xd, &xd->block[0]);
+ if (tx_type != DCT_DCT) {
+ for (i = 0; i < 16; i++) {
+ BLOCKD *b = &xd->block[i];
+ tx_type = get_tx_type_4x4(xd, b);
+ if (tx_type != DCT_DCT) {
+ vp9_ht_dequant_idct_add_c(
+ tx_type, b->qcoeff, b->dequant,
+ xd->dst.y_buffer + (y_idx * 16 + (i / 4) * 4) * xd->dst.y_stride
+ + x_idx * 16 + (i & 3) * 4,
+ xd->dst.y_buffer + (y_idx * 16 + (i / 4) * 4) * xd->dst.y_stride
+ + x_idx * 16 + (i & 3) * 4,
+ xd->dst.y_stride, xd->dst.y_stride);
+ } else {
+ vp9_dequant_idct_add_c(
+ b->qcoeff, b->dequant,
+ xd->dst.y_buffer + (y_idx * 16 + (i / 4) * 4) * xd->dst.y_stride
+ + x_idx * 16 + (i & 3) * 4,
+ xd->dst.y_buffer + (y_idx * 16 + (i / 4) * 4) * xd->dst.y_stride
+ + x_idx * 16 + (i & 3) * 4,
+ xd->dst.y_stride, xd->dst.y_stride);
+ }
+ }
} else {
- xd->inv_walsh4x4_1(&b->dqcoeff[0], b->diff);
- ((int *)b->qcoeff)[0] = 0;
+ vp9_dequantize_b(b);
+ if (xd->eobs[24] > 1) {
+ vp9_short_inv_walsh4x4(&b->dqcoeff[0], b->diff);
+ ((int *)b->qcoeff)[0] = 0;
+ ((int *)b->qcoeff)[1] = 0;
+ ((int *)b->qcoeff)[2] = 0;
+ ((int *)b->qcoeff)[3] = 0;
+ ((int *)b->qcoeff)[4] = 0;
+ ((int *)b->qcoeff)[5] = 0;
+ ((int *)b->qcoeff)[6] = 0;
+ ((int *)b->qcoeff)[7] = 0;
+ } else {
+ xd->inv_walsh4x4_1(&b->dqcoeff[0], b->diff);
+ ((int *)b->qcoeff)[0] = 0;
+ }
+ vp9_dequant_dc_idct_add_y_block_4x4_inplace_c(
+ xd->qcoeff, xd->block[0].dequant,
+ xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
+ xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
}
-
- vp9_dequant_dc_idct_add_y_block_4x4_inplace_c(xd->qcoeff,
- xd->block[0].dequant,
- xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
- xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
- vp9_dequant_idct_add_uv_block_4x4_inplace_c(xd->qcoeff + 16 * 16,
- xd->block[16].dequant,
+ vp9_dequant_idct_add_uv_block_4x4_inplace_c(
+ xd->qcoeff + 16 * 16, xd->block[16].dequant,
xd->dst.u_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.v_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.uv_stride, xd->eobs + 16, xd);
skip_recon_mb(pbi, xd);
return;
}
+#ifdef DEC_DEBUG
+ if (dec_debug)
+ printf("Decoding mb: %d %d\n", xd->mode_info_context->mbmi.mode, tx_size);
+#endif
// moved to be performed before detokenization
// if (xd->segmentation_enabled)
vp9_build_inter_predictors_mb(xd);
}
- /* dequantization and idct */
- if (mode == I8X8_PRED) {
- for (i = 0; i < 4; i++) {
- int ib = vp9_i8x8_block[i];
- const int iblock[4] = {0, 1, 4, 5};
- int j;
- int i8x8mode;
- BLOCKD *b;
-
- int idx = (ib & 0x02) ? (ib + 2) : ib;
-
- short *q = xd->block[idx].qcoeff;
- short *dq = xd->block[0].dequant;
- unsigned char *pre = xd->block[ib].predictor;
- unsigned char *dst = *(xd->block[ib].base_dst) + xd->block[ib].dst;
- int stride = xd->dst.y_stride;
-
- b = &xd->block[ib];
- i8x8mode = b->bmi.as_mode.first;
- vp9_intra8x8_predict(b, i8x8mode, b->predictor);
-
- if (xd->mode_info_context->mbmi.txfm_size == TX_8X8) {
- tx_type = get_tx_type(xd, &xd->block[idx]);
- if (tx_type != DCT_DCT) {
- vp9_ht_dequant_idct_add_8x8_c(tx_type,
- q, dq, pre, dst, 16, stride);
- } else {
- vp9_dequant_idct_add_8x8_c(q, dq, pre, dst, 16, stride, 0,
- xd->eobs[idx]);
- }
- q += 64;
- } else {
- for (j = 0; j < 4; j++) {
- b = &xd->block[ib + iblock[j]];
- vp9_dequant_idct_add(b->qcoeff, b->dequant, b->predictor,
- *(b->base_dst) + b->dst, 16, b->dst_stride);
- }
- }
- b = &xd->block[16 + i];
- vp9_intra_uv4x4_predict(b, i8x8mode, b->predictor);
- pbi->idct_add(b->qcoeff, b->dequant, b->predictor,
- *(b->base_dst) + b->dst, 8, b->dst_stride);
- b = &xd->block[20 + i];
- vp9_intra_uv4x4_predict(b, i8x8mode, b->predictor);
- pbi->idct_add(b->qcoeff, b->dequant, b->predictor,
- *(b->base_dst) + b->dst, 8, b->dst_stride);
- }
- } else if (mode == B_PRED) {
+ if (tx_size == TX_16X16) {
+ decode_16x16(pbi, xd, bc);
+ } else if (tx_size == TX_8X8) {
+ decode_8x8(pbi, xd, bc);
+ } else {
+ decode_4x4(pbi, xd, bc);
+ }
+#ifdef DEC_DEBUG
+ if (dec_debug) {
+ int i, j;
+ printf("\n");
+ printf("final y\n");
for (i = 0; i < 16; i++) {
- int b_mode;
-#if CONFIG_COMP_INTRA_PRED
- int b_mode2;
-#endif
- BLOCKD *b = &xd->block[i];
- b_mode = xd->mode_info_context->bmi[i].as_mode.first;
-#if CONFIG_NEWBINTRAMODES
- xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context =
- vp9_find_bpred_context(b);
-#endif
- if (!xd->mode_info_context->mbmi.mb_skip_coeff)
- eobtotal += vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i);
-#if CONFIG_COMP_INTRA_PRED
- b_mode2 = xd->mode_info_context->bmi[i].as_mode.second;
-
- if (b_mode2 == (B_PREDICTION_MODE)(B_DC_PRED - 1)) {
-#endif
- vp9_intra4x4_predict(b, b_mode, b->predictor);
-#if CONFIG_COMP_INTRA_PRED
- } else {
- vp9_comp_intra4x4_predict(b, b_mode, b_mode2, b->predictor);
- }
-#endif
-
- tx_type = get_tx_type(xd, b);
- if (tx_type != DCT_DCT) {
- vp9_ht_dequant_idct_add_c(tx_type, b->qcoeff,
- b->dequant, b->predictor,
- *(b->base_dst) + b->dst, 16, b->dst_stride);
- } else {
- vp9_dequant_idct_add(b->qcoeff, b->dequant, b->predictor,
- *(b->base_dst) + b->dst, 16, b->dst_stride);
- }
- xd->above_context->y2 = 1;
- xd->left_context->y2 = 1;
+ for (j = 0; j < 16; j++)
+ printf("%3d ", xd->dst.y_buffer[i * xd->dst.y_stride + j]);
+ printf("\n");
}
- if (!xd->mode_info_context->mbmi.mb_skip_coeff)
- vp9_decode_mb_tokens_4x4_uv(pbi, xd, bc);
- } else if (mode == SPLITMV) {
- if (tx_size == TX_8X8) {
- vp9_dequant_idct_add_y_block_8x8(xd->qcoeff, xd->block[0].dequant,
- xd->predictor, xd->dst.y_buffer,
- xd->dst.y_stride, xd->eobs, xd);
- } else {
- pbi->idct_add_y_block(xd->qcoeff, xd->block[0].dequant,
- xd->predictor, xd->dst.y_buffer,
- xd->dst.y_stride, xd->eobs);
+ printf("\n");
+ printf("final u\n");
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++)
+ printf("%3d ", xd->dst.u_buffer[i * xd->dst.uv_stride + j]);
+ printf("\n");
}
} else {
- BLOCKD *b = &xd->block[24];
-
- if (tx_size == TX_16X16) {
- BLOCKD *bd = &xd->block[0];
- tx_type = get_tx_type(xd, bd);
- if (tx_type != DCT_DCT) {
- vp9_ht_dequant_idct_add_16x16_c(tx_type, xd->qcoeff,
- xd->block[0].dequant, xd->predictor,
- xd->dst.y_buffer, 16, xd->dst.y_stride);
- } else {
- vp9_dequant_idct_add_16x16(xd->qcoeff, xd->block[0].dequant,
- xd->predictor, xd->dst.y_buffer,
- 16, xd->dst.y_stride, xd->eobs[0]);
- }
- } else if (tx_size == TX_8X8) {
- vp9_dequantize_b_2x2(b);
- vp9_short_ihaar2x2(&b->dqcoeff[0], b->diff, 8);
- ((int *)b->qcoeff)[0] = 0; // 2nd order block are set to 0 after idct
- ((int *)b->qcoeff)[1] = 0;
- ((int *)b->qcoeff)[2] = 0;
- ((int *)b->qcoeff)[3] = 0;
- ((int *)b->qcoeff)[4] = 0;
- ((int *)b->qcoeff)[5] = 0;
- ((int *)b->qcoeff)[6] = 0;
- ((int *)b->qcoeff)[7] = 0;
- vp9_dequant_dc_idct_add_y_block_8x8(xd->qcoeff,
- xd->block[0].dequant, xd->predictor, xd->dst.y_buffer,
- xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
- } else {
- vp9_dequantize_b(b);
- if (xd->eobs[24] > 1) {
- vp9_short_inv_walsh4x4(&b->dqcoeff[0], b->diff);
- ((int *)b->qcoeff)[0] = 0;
- ((int *)b->qcoeff)[1] = 0;
- ((int *)b->qcoeff)[2] = 0;
- ((int *)b->qcoeff)[3] = 0;
- ((int *)b->qcoeff)[4] = 0;
- ((int *)b->qcoeff)[5] = 0;
- ((int *)b->qcoeff)[6] = 0;
- ((int *)b->qcoeff)[7] = 0;
- } else {
- xd->inv_walsh4x4_1(&b->dqcoeff[0], b->diff);
- ((int *)b->qcoeff)[0] = 0;
- }
-
- pbi->dc_idct_add_y_block(xd->qcoeff, xd->block[0].dequant, xd->predictor,
- xd->dst.y_buffer, xd->dst.y_stride, xd->eobs,
- xd->block[24].diff);
+ printf("\n");
+ printf("final v\n");
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++)
+ printf("%3d ", xd->dst.v_buffer[i * xd->dst.uv_stride + j]);
+ printf("\n");
}
+ fflush(stdout);
}
-
- if ((tx_size == TX_8X8 &&
- xd->mode_info_context->mbmi.mode != I8X8_PRED &&
- xd->mode_info_context->mbmi.mode != SPLITMV)
- || tx_size == TX_16X16
- )
- vp9_dequant_idct_add_uv_block_8x8
- (xd->qcoeff + 16 * 16, xd->block[16].dequant,
- xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
- xd->dst.uv_stride, xd->eobs + 16, xd);
- else if (xd->mode_info_context->mbmi.mode != I8X8_PRED)
- pbi->idct_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant,
- xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
- xd->dst.uv_stride, xd->eobs + 16);
+#endif
}
#if CONFIG_SUPERBLOCKS
}
#endif
-
+#ifdef DEC_DEBUG
+ dec_debug = (pbi->common.current_video_frame == 73 &&
+ mb_row == 4 && mb_col == 13);
+ 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);
}
-#if 0
-static void read_coef_probs2(VP9D_COMP *pbi) {
- const vp9_prob grpupd = 192;
- int i, j, k, l;
- vp9_reader *const bc = &pbi->bc;
- VP9_COMMON *const pc = &pbi->common;
- for (l = 0; l < ENTROPY_NODES; l++) {
- if (vp9_read(bc, grpupd)) {
- // printf("Decoding %d\n", l);
- for (i = 0; i < BLOCK_TYPES; i++)
- for (j = !i; j < COEF_BANDS; j++)
- for (k = 0; k < PREV_COEF_CONTEXTS; k++) {
- if (k >= 3 && ((i == 0 && j == 1) ||
- (i > 0 && j == 0)))
- continue;
- {
- vp9_prob *const p = pc->fc.coef_probs [i][j][k] + l;
- int u = vp9_read(bc, COEF_UPDATE_PROB);
- if (u) *p = read_prob_diff_update(bc, *p);
- }
- }
- }
- }
- if (pbi->common.txfm_mode == ALLOW_8X8) {
- for (l = 0; l < ENTROPY_NODES; l++) {
- if (vp9_read(bc, grpupd)) {
- for (i = 0; i < BLOCK_TYPES_8X8; i++)
- for (j = !i; j < COEF_BANDS; j++)
- for (k = 0; k < PREV_COEF_CONTEXTS; k++) {
- if (k >= 3 && ((i == 0 && j == 1) ||
- (i > 0 && j == 0)))
- continue;
- {
- vp9_prob *const p = pc->fc.coef_probs_8x8 [i][j][k] + l;
-
- int u = vp9_read(bc, COEF_UPDATE_PROB_8X8);
- if (u) *p = read_prob_diff_update(bc, *p);
- }
- }
- }
- }
- }
-}
-#endif
-
static void read_coef_probs_common(
BOOL_DECODER* const bc,
vp9_prob coef_probs[BLOCK_TYPES][COEF_BANDS]
}
}
}
+#ifdef DEC_DEBUG
+ printf("Decode frame %d\n", pc->current_video_frame);
+#endif
if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME) ||
pc->Width == 0 || pc->Height == 0) {
#include "vpx_mem/vpx_mem.h"
#include "vp9/decoder/vp9_onyxd_int.h"
-#ifdef DEC_DEBUG
-extern int dec_debug;
-#endif
-
static void add_residual(const int16_t *diff, const uint8_t *pred, int pitch,
uint8_t *dest, int stride, int width, int height) {
int r, c;
for (i = 0; i < 16; i++) {
DQ[i] = (int16_t)((Q[i] * DQC[i]));
}
-#ifdef DEC_DEBUG
- if (dec_debug) {
- int j;
- printf("Dequantize 2x2\n");
- for (j = 0; j < 16; j++) printf("%d ", Q[j]);
- printf("\n");
- for (j = 0; j < 16; j++) printf("%d ", DQ[j]);
- printf("\n");
- }
-#endif
}
void vp9_dequant_idct_add_8x8_c(int16_t *input, const int16_t *dq,
int16_t *diff_ptr = output;
int i;
-#ifdef DEC_DEBUG
- if (dec_debug) {
- int j;
- printf("Input 8x8\n");
- for (j = 0; j < 64; j++) {
- printf("%d ", input[j]);
- if (j % 8 == 7) printf("\n");
- }
- }
-#endif
-
/* If dc is 1, then input[0] is the reconstructed value, do not need
* dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1.
*/
for (i = 1; i < 64; i++) {
input[i] = input[i] * dq[1];
}
-#ifdef DEC_DEBUG
- if (dec_debug) {
- int j;
- printf("Input DQ 8x8\n");
- for (j = 0; j < 64; j++) {
- printf("%d ", input[j]);
- if (j % 8 == 7) printf("\n");
- }
- }
-#endif
-
// the idct halves ( >> 1) the pitch
vp9_short_idct8x8_c(input, output, 16);
-#ifdef DEC_DEBUG
- if (dec_debug) {
- int j;
- printf("Output 8x8\n");
- for (j = 0; j < 64; j++) {
- printf("%d ", output[j]);
- if (j % 8 == 7) printf("\n");
- }
- }
-#endif
vpx_memset(input, 0, 128);
add_residual(diff_ptr, pred, pitch, dest, stride, 8, 8);
-#ifdef DEC_DEBUG
- if (dec_debug) {
- int k, j;
- printf("Final 8x8\n");
- for (j = 0; j < 8; j++) {
- for (k = 0; k < 8; k++) {
- printf("%d ", origdest[k]);
- }
- printf("\n");
- origdest += stride;
- }
- }
-#endif
}
}
{ 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 };
void vp9_reset_mb_tokens_context(MACROBLOCKD* const xd) {
- /* Clear entropy contexts for Y2 blocks */
+ /* Clear entropy contexts */
if ((xd->mode_info_context->mbmi.mode != B_PRED &&
- xd->mode_info_context->mbmi.mode != I8X8_PRED &&
- xd->mode_info_context->mbmi.mode != SPLITMV)
- || xd->mode_info_context->mbmi.txfm_size == TX_16X16
- ) {
+ xd->mode_info_context->mbmi.mode != I8X8_PRED &&
+ xd->mode_info_context->mbmi.mode != SPLITMV)
+ || xd->mode_info_context->mbmi.txfm_size == TX_16X16) {
vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
} else {
int c, i, eobtotal = 0, seg_eob;
const int segment_id = xd->mode_info_context->mbmi.segment_id;
+ int has_2nd_order = get_2nd_order_usage(xd);
// 2nd order DC block
- if (xd->mode_info_context->mbmi.mode != B_PRED &&
- xd->mode_info_context->mbmi.mode != SPLITMV &&
- xd->mode_info_context->mbmi.mode != I8X8_PRED) {
+ if (has_2nd_order) {
ENTROPY_CONTEXT *const a = A + vp9_block2above_8x8[24];
ENTROPY_CONTEXT *const l = L + vp9_block2left_8x8[24];
} else {
xd->above_context->y2 = 1;
xd->left_context->y2 = 1;
+ eobs[24] = 0;
type = PLANE_TYPE_Y_WITH_DC;
}
eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, type,
type == PLANE_TYPE_Y_WITH_DC ?
- get_tx_type(xd, xd->block + i) : DCT_DCT,
+ get_tx_type(xd, xd->block + i) : DCT_DCT,
seg_eob, xd->block[i].qcoeff,
vp9_default_zig_zag1d_8x8,
TX_8X8, vp9_coef_bands_8x8);
TX_TYPE tx_type = DCT_DCT;
if (type == PLANE_TYPE_Y_WITH_DC)
- tx_type = get_tx_type(xd, &xd->block[i]);
+ tx_type = get_tx_type_4x4(xd, &xd->block[i]);
switch (tx_type) {
case ADST_DCT :
scan = vp9_row_scan;
int i, eobtotal = 0;
PLANE_TYPE type;
- if (xd->mode_info_context->mbmi.mode != B_PRED &&
- xd->mode_info_context->mbmi.mode != I8X8_PRED &&
- xd->mode_info_context->mbmi.mode != SPLITMV) {
+ int has_2nd_order = get_2nd_order_usage(xd);
+
+ if (has_2nd_order) {
eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_Y2, 24) - 16;
type = PLANE_TYPE_Y_NO_DC;
} else {
xd->above_context->y2 = 1;
xd->left_context->y2 = 1;
+ xd->eobs[24] = 0;
type = PLANE_TYPE_Y_WITH_DC;
}
* the regular quantize_b function pointer */
void vp8_quantize_mby_neon(MACROBLOCK *x) {
int i;
- int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
- && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
+ int has_2nd_order = get_2nd_order_usage(xd);
for (i = 0; i < 16; i += 2)
x->quantize_b_pair(&x->block[i], &x->block[i + 1],
void vp8_quantize_mb_neon(MACROBLOCK *x) {
int i;
- int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
- && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
+ int has_2nd_order = get_2nd_order_usage(xd);
for (i = 0; i < 24; i += 2)
x->quantize_b_pair(&x->block[i], &x->block[i + 1],
#endif
write_ymode(bc, mode, pc->fc.ymode_prob);
}
-
if (mode == B_PRED) {
int j = 0;
#if CONFIG_COMP_INTRA_PRED
#define IF_RTCD(x) NULL
#endif
+// #define ENC_DEBUG
#ifdef ENC_DEBUG
int enc_debug = 0;
-int mb_row_debug, mb_col_debug;
#endif
static void encode_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->ref_mvs[rf], &best_mv);
mbmi->best_index = best_index;
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
unsigned int best_index;
best_index =
pick_best_mv_ref(x, sec_ref_frame, mbmi->mv[1],
cpi->seg0_progress = (((mb_col & ~1) * 2 + (mb_row & ~1) * cm->mb_cols + i) << 16) / cm->MBs;
}
+#ifdef ENC_DEBUG
+ enc_debug = (cpi->common.current_video_frame == 73 &&
+ mb_row == 4 && mb_col == 13);
+ if (enc_debug)
+ printf("pick_mb_modes %d %d\n", mb_row, mb_col);
+#endif
vp9_pick_mode_inter_macroblock(cpi, x, recon_yoffset,
recon_uvoffset, &r, &d);
*totalrate += r;
xd->mb_index = i;
-#ifdef ENC_DEBUG
- enc_debug = (cpi->common.current_video_frame == 0 &&
- mb_row == 0 && mb_col == 0);
- mb_col_debug = mb_col;
- mb_row_debug = mb_row;
-#endif
-
// Restore MB state to that when it was picked
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
TOKENEXTRA *tp = cpi->tok;
int totalrate;
- //printf("encode_frame_internal\n");
+ // printf("encode_frame_internal frame %d (%d)\n",
+ // cpi->common.current_video_frame, cpi->common.show_frame);
// Compute a modified set of reference frame probabilities to use when
// prediction fails. These are based on the current general estimates for
assert(!xd->mode_info_context->mbmi.encoded_as_sb);
#endif
+#ifdef ENC_DEBUG
+ enc_debug = (cpi->common.current_video_frame == 73 &&
+ mb_row == 4 && mb_col == 13);
+ if (enc_debug)
+ printf("Encode MB %d %d output %d\n", mb_row, mb_col, output_enabled);
+#endif
if (cm->frame_type == KEY_FRAME) {
if (cpi->oxcf.tuning == VP8_TUNE_SSIM && output_enabled) {
// Adjust the zbin based on this MB rate.
}
if (mbmi->ref_frame == INTRA_FRAME) {
+#ifdef ENC_DEBUG
+ if (enc_debug) {
+ printf("Mode %d skip %d tx_size %d\n", mbmi->mode, x->skip,
+ mbmi->txfm_size);
+ }
+#endif
if (mbmi->mode == B_PRED) {
vp9_encode_intra16x16mbuv(x);
vp9_encode_intra4x4mby(x);
sum_intra_stats(cpi, x);
} else {
int ref_fb_idx;
+#ifdef ENC_DEBUG
+ if (enc_debug)
+ printf("Mode %d skip %d tx_size %d ref %d ref2 %d mv %d %d\n",
+ mbmi->mode, x->skip, mbmi->txfm_size,
+ mbmi->ref_frame, mbmi->second_ref_frame,
+ mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col);
+#endif
assert(cm->frame_type != KEY_FRAME);
mbmi->mb_skip_coeff = 0;
} else {
- vp9_build_1st_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
- xd->dst.u_buffer, xd->dst.v_buffer,
+ 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,
+ 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 (!x->skip) {
#ifdef ENC_DEBUG
if (enc_debug) {
- int i;
- printf("Segment=%d [%d, %d]: %d %d:\n", mbmi->segment_id, mb_col_debug,
- mb_row_debug, xd->mb_to_left_edge, xd->mb_to_top_edge);
+ int i, j;
+ printf("\n");
+ printf("qcoeff\n");
for (i = 0; i < 400; i++) {
printf("%3d ", xd->qcoeff[i]);
if (i % 16 == 15) printf("\n");
}
printf("\n");
- printf("eobs = ");
- for (i = 0; i < 25; i++)
- printf("%d:%d ", i, xd->block[i].eob);
+ printf("predictor\n");
+ for (i = 0; i < 384; i++) {
+ printf("%3d ", xd->predictor[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ printf("\n");
+ printf("src_diff\n");
+ for (i = 0; i < 384; i++) {
+ printf("%3d ", x->src_diff[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ printf("\n");
+ printf("diff\n");
+ for (i = 0; i < 384; i++) {
+ printf("%3d ", xd->block[0].diff[i]);
+ if (i % 16 == 15) printf("\n");
+ }
+ printf("\n");
+ printf("final y\n");
+ for (i = 0; i < 16; i++) {
+ for (j = 0; j < 16; j++)
+ printf("%3d ", xd->dst.y_buffer[i * xd->dst.y_stride + j]);
+ printf("\n");
+ }
+ printf("\n");
+ printf("final u\n");
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++)
+ printf("%3d ", xd->dst.u_buffer[i * xd->dst.uv_stride + j]);
+ printf("\n");
+ }
printf("\n");
+ printf("final v\n");
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++)
+ printf("%3d ", xd->dst.v_buffer[i * xd->dst.uv_stride + j]);
+ printf("\n");
+ }
fflush(stdout);
}
#endif
vp9_tokenize_mb(cpi, xd, t, !output_enabled);
-#ifdef ENC_DEBUG
- if (enc_debug) {
- printf("Tokenized\n");
- fflush(stdout);
- }
-#endif
} else {
int mb_skip_context =
cpi->common.mb_no_coeff_skip ?
vp9_subtract_b(be, b, 16);
- tx_type = get_tx_type(&x->e_mbd, b);
+ tx_type = get_tx_type_4x4(&x->e_mbd, b);
if (tx_type != DCT_DCT) {
vp9_fht(be->src_diff, 32, be->coeff, tx_type, 4);
vp9_ht_quantize_b_4x4(be, b, tx_type);
vp9_subtract_mby(x->src_diff, *(b->base_src), xd->predictor, b->src_stride);
if (tx_size == TX_16X16) {
- BLOCKD *bd = &xd->block[0];
- tx_type = get_tx_type(xd, bd);
- if (tx_type != DCT_DCT) {
- vp9_fht(b->src_diff, 32, b->coeff, tx_type, 16);
- vp9_quantize_mby_16x16(x);
- if (x->optimize)
- vp9_optimize_mby_16x16(x);
- vp9_ihtllm_c(bd->dqcoeff, bd->diff, 32, tx_type, 16);
- } else {
- vp9_transform_mby_16x16(x);
- vp9_quantize_mby_16x16(x);
- if (x->optimize)
- vp9_optimize_mby_16x16(x);
- vp9_inverse_transform_mby_16x16(xd);
- }
+ vp9_transform_mby_16x16(x);
+ vp9_quantize_mby_16x16(x);
+ if (x->optimize)
+ vp9_optimize_mby_16x16(x);
+ vp9_inverse_transform_mby_16x16(xd);
} else if (tx_size == TX_8X8) {
vp9_transform_mby_8x8(x);
vp9_quantize_mby_8x8(x);
b->predictor);
}
#endif
+ // generate residual blocks
+ vp9_subtract_4b_c(be, b, 16);
if (xd->mode_info_context->mbmi.txfm_size == TX_8X8) {
int idx = (ib & 0x02) ? (ib + 2) : ib;
- // generate residual blocks
- vp9_subtract_4b_c(be, b, 16);
-
- tx_type = get_tx_type(xd, xd->block + idx);
+ tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
if (tx_type != DCT_DCT) {
vp9_fht(be->src_diff, 32, (x->block + idx)->coeff,
tx_type, 8);
for (i = 0; i < 4; i++) {
b = &xd->block[ib + iblock[i]];
be = &x->block[ib + iblock[i]];
- vp9_subtract_b(be, b, 16);
- x->vp9_short_fdct4x4(be->src_diff, be->coeff, 32);
- x->quantize_b_4x4(be, b);
- vp9_inverse_transform_b_4x4(xd, ib + iblock[i], 32);
+ tx_type = get_tx_type_4x4(xd, b);
+ if (tx_type != DCT_DCT) {
+ vp9_fht_c(be->src_diff, 32, be->coeff, tx_type, 4);
+ vp9_ht_quantize_b_4x4(be, b, tx_type);
+ vp9_ihtllm_c(b->dqcoeff, b->diff, 32, tx_type, 4);
+ } else {
+ x->vp9_short_fdct4x4(be->src_diff, be->coeff, 32);
+ x->quantize_b_4x4(be, b);
+ vp9_inverse_transform_b_4x4(xd, ib + iblock[i], 32);
+ }
}
}
for (i = 0; i < 16; i++) {
src_diff_ptr[i] = x->coeff[i * 16];
+ x->coeff[i * 16] = 0;
}
}
void vp9_transform_mby_4x4(MACROBLOCK *x) {
int i;
+ MACROBLOCKD *xd = &x->e_mbd;
+ int has_2nd_order = get_2nd_order_usage(xd);
- for (i = 0; i < 16; i += 2) {
- x->vp9_short_fdct8x4(&x->block[i].src_diff[0],
- &x->block[i].coeff[0], 32);
+ for (i = 0; i < 16; i++) {
+ BLOCK *b = &x->block[i];
+ TX_TYPE tx_type = get_tx_type_4x4(xd, &xd->block[i]);
+ if (tx_type != DCT_DCT) {
+ assert(has_2nd_order == 0);
+ vp9_fht_c(b->src_diff, 32, b->coeff, tx_type, 4);
+ } else {
+ x->vp9_short_fdct4x4(&x->block[i].src_diff[0],
+ &x->block[i].coeff[0], 32);
+ }
}
- if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
+ if (has_2nd_order) {
// build dc block from 16 y dc values
build_dcblock_4x4(x);
// do 2nd order transform on the dc block
x->short_walsh4x4(&x->block[24].src_diff[0],
&x->block[24].coeff[0], 8);
+ } else {
+ vpx_memset(x->block[24].coeff, 0, 16 * sizeof(x->block[24].coeff[0]));
}
}
src_diff_ptr[1] = x->coeff[4 * 16];
src_diff_ptr[4] = x->coeff[8 * 16];
src_diff_ptr[8] = x->coeff[12 * 16];
+ x->coeff[0 * 16] = 0;
+ x->coeff[4 * 16] = 0;
+ x->coeff[8 * 16] = 0;
+ x->coeff[12 * 16] = 0;
}
void vp9_transform_mby_8x8(MACROBLOCK *x) {
int i;
+ MACROBLOCKD *xd = &x->e_mbd;
+ TX_TYPE tx_type;
+ int has_2nd_order = get_2nd_order_usage(xd);
for (i = 0; i < 9; i += 8) {
- x->vp9_short_fdct8x8(&x->block[i].src_diff[0],
- &x->block[i].coeff[0], 32);
+ BLOCK *b = &x->block[i];
+ tx_type = get_tx_type_8x8(xd, &xd->block[i]);
+ if (tx_type != DCT_DCT) {
+ assert(has_2nd_order == 0);
+ vp9_fht_c(b->src_diff, 32, b->coeff, tx_type, 8);
+ } else {
+ x->vp9_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i].coeff[0], 32);
+ }
}
for (i = 2; i < 11; i += 8) {
- x->vp9_short_fdct8x8(&x->block[i].src_diff[0],
- &x->block[i + 2].coeff[0], 32);
+ BLOCK *b = &x->block[i];
+ tx_type = get_tx_type_8x8(xd, &xd->block[i]);
+ if (tx_type != DCT_DCT) {
+ assert(has_2nd_order == 0);
+ vp9_fht_c(b->src_diff, 32, (b + 2)->coeff, tx_type, 8);
+ } else {
+ x->vp9_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i + 2].coeff[0], 32);
+ }
}
- if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
+ if (has_2nd_order) {
// build dc block from 2x2 y dc values
build_dcblock_8x8(x);
// do 2nd order transform on the dc block
x->short_fhaar2x2(&x->block[24].src_diff[0],
&x->block[24].coeff[0], 8);
+ } else {
+ vpx_memset(x->block[24].coeff, 0, 16 * sizeof(x->block[24].coeff[0]));
}
}
}
void vp9_transform_mby_16x16(MACROBLOCK *x) {
+ MACROBLOCKD *xd = &x->e_mbd;
+ BLOCK *b = &x->block[0];
+ TX_TYPE tx_type = get_tx_type_16x16(xd, &xd->block[0]);
vp9_clear_system_state();
- x->vp9_short_fdct16x16(&x->block[0].src_diff[0],
- &x->block[0].coeff[0], 32);
+ if (tx_type != DCT_DCT) {
+ vp9_fht_c(b->src_diff, 32, b->coeff, tx_type, 16);
+ } else {
+ x->vp9_short_fdct16x16(&x->block[0].src_diff[0],
+ &x->block[0].coeff[0], 32);
+ }
}
void vp9_transform_mb_16x16(MACROBLOCK *x) {
// TODO: this isn't called (for intra4x4 modes), but will be left in
// since it could be used later
{
- TX_TYPE tx_type = get_tx_type(&mb->e_mbd, d);
+ TX_TYPE tx_type = get_tx_type_4x4(&mb->e_mbd, d);
if (tx_type != DCT_DCT) {
switch (tx_type) {
case ADST_DCT:
ta = (ENTROPY_CONTEXT *)&t_above;
tl = (ENTROPY_CONTEXT *)&t_left;
- has_2nd_order = (mode != B_PRED && mode != I8X8_PRED && mode != SPLITMV);
+ has_2nd_order = get_2nd_order_usage(&x->e_mbd);
+
type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
for (b = 0; b < 16; b++) {
ENTROPY_CONTEXT_PLANES t_above, t_left;
ENTROPY_CONTEXT *ta;
ENTROPY_CONTEXT *tl;
- int has_2nd_order = x->e_mbd.mode_info_context->mbmi.mode != SPLITMV;
+ int has_2nd_order = get_2nd_order_usage(&x->e_mbd);
if (!x->e_mbd.above_context || !x->e_mbd.left_context)
return;
void vp9_quantize_mby_4x4_c(MACROBLOCK *x) {
int i;
- int has_2nd_order = x->e_mbd.mode_info_context->mbmi.mode != SPLITMV;
+ int has_2nd_order = get_2nd_order_usage(&x->e_mbd);
- for (i = 0; i < 16; i++)
- x->quantize_b_4x4(&x->block[i], &x->e_mbd.block[i]);
-
- if (has_2nd_order)
+ for (i = 0; i < 16; i++) {
+ TX_TYPE tx_type = get_tx_type_4x4(&x->e_mbd, &x->e_mbd.block[i]);
+ if (tx_type != DCT_DCT) {
+ assert(has_2nd_order == 0);
+ vp9_ht_quantize_b_4x4(&x->block[i], &x->e_mbd.block[i], tx_type);
+ } else {
+ x->quantize_b_4x4(&x->block[i], &x->e_mbd.block[i]);
+ }
+ }
+ if (has_2nd_order) {
x->quantize_b_4x4(&x->block[24], &x->e_mbd.block[24]);
+ } else {
+ vpx_memset(x->e_mbd.block[24].qcoeff, 0,
+ 16 * sizeof(x->e_mbd.block[24].qcoeff[0]));
+ vpx_memset(x->e_mbd.block[24].dqcoeff, 0,
+ 16 * sizeof(x->e_mbd.block[24].dqcoeff[0]));
+ x->e_mbd.block[24].eob = 0;
+ }
}
void vp9_quantize_mbuv_4x4_c(MACROBLOCK *x) {
void vp9_quantize_mby_8x8(MACROBLOCK *x) {
int i;
- int has_2nd_order = x->e_mbd.mode_info_context->mbmi.mode != SPLITMV;
+ int has_2nd_order = get_2nd_order_usage(&x->e_mbd);
for (i = 0; i < 16; i ++) {
x->e_mbd.block[i].eob = 0;
}
x->e_mbd.block[24].eob = 0;
- for (i = 0; i < 16; i += 4)
+ for (i = 0; i < 16; i += 4) {
+ int ib = (i & 8) + ((i & 4) >> 1);
+ TX_TYPE tx_type = get_tx_type_8x8(&x->e_mbd, &x->e_mbd.block[ib]);
+ if (tx_type != DCT_DCT)
+ assert(has_2nd_order == 0);
x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]);
+ }
- if (has_2nd_order)
+ if (has_2nd_order) {
x->quantize_b_2x2(&x->block[24], &x->e_mbd.block[24]);
+ } else {
+ vpx_memset(x->e_mbd.block[24].qcoeff, 0,
+ 16 * sizeof(x->e_mbd.block[24].qcoeff[0]));
+ vpx_memset(x->e_mbd.block[24].dqcoeff, 0,
+ 16 * sizeof(x->e_mbd.block[24].dqcoeff[0]));
+ x->e_mbd.block[24].eob = 0;
+ }
}
void vp9_quantize_mbuv_8x8(MACROBLOCK *x) {
return error;
}
+int vp9_mbblock_error_8x8_c(MACROBLOCK *mb, int dc) {
+ BLOCK *be;
+ BLOCKD *bd;
+ int i, j;
+ int berror, error = 0;
+
+ for (i = 0; i < 16; i+=4) {
+ be = &mb->block[i];
+ bd = &mb->e_mbd.block[i];
+ berror = 0;
+ for (j = dc; j < 64; j++) {
+ int this_diff = be->coeff[j] - bd->dqcoeff[j];
+ berror += this_diff * this_diff;
+ }
+ error += berror;
+ }
+ return error;
+}
+
int vp9_mbblock_error_c(MACROBLOCK *mb, int dc) {
BLOCK *be;
BLOCKD *bd;
for (i = 0; i < 16; i++) {
be = &mb->block[i];
bd = &mb->e_mbd.block[i];
-
berror = 0;
-
for (j = dc; j < 16; j++) {
int this_diff = be->coeff[j] - bd->dqcoeff[j];
berror += this_diff * this_diff;
}
-
error += berror;
}
-
return error;
}
return cost;
}
-static int rdcost_mby_4x4(MACROBLOCK *mb, int backup) {
+static int rdcost_mby_4x4(MACROBLOCK *mb, int has_2nd_order, int backup) {
int cost = 0;
int b;
MACROBLOCKD *xd = &mb->e_mbd;
}
for (b = 0; b < 16; b++)
- cost += cost_coeffs(mb, xd->block + b, PLANE_TYPE_Y_NO_DC,
+ cost += cost_coeffs(mb, xd->block + b,
+ (has_2nd_order ?
+ PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC),
ta + vp9_block2above[b], tl + vp9_block2left[b],
TX_4X4);
- cost += cost_coeffs(mb, xd->block + 24, PLANE_TYPE_Y2,
- ta + vp9_block2above[24], tl + vp9_block2left[24],
- TX_4X4);
+ if (has_2nd_order)
+ cost += cost_coeffs(mb, xd->block + 24, PLANE_TYPE_Y2,
+ ta + vp9_block2above[24], tl + vp9_block2left[24],
+ TX_4X4);
return cost;
}
BLOCKD *const x_y2 = xd->block + 24;
short *Y2DCPtr = mb_y2->src_diff;
BLOCK *beptr;
- int d;
+ int d, i, has_2nd_order;
+ xd->mode_info_context->mbmi.txfm_size = TX_4X4;
+ has_2nd_order = get_2nd_order_usage(xd);
// Fdct and building the 2nd order block
- for (beptr = mb->block; beptr < mb->block + 16; beptr += 2) {
- mb->vp9_short_fdct8x4(beptr->src_diff, beptr->coeff, 32);
- *Y2DCPtr++ = beptr->coeff[0];
- *Y2DCPtr++ = beptr->coeff[16];
- }
-
- // 2nd order fdct
- mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8);
-
- // Quantization
- for (b = 0; b < 16; b++) {
- mb->quantize_b_4x4(&mb->block[b], &xd->block[b]);
- }
-
- // DC predication and Quantization of 2nd Order block
- mb->quantize_b_4x4(mb_y2, x_y2);
-
- // Distortion
- d = vp9_mbblock_error(mb, 1);
-
- d += vp9_block_error(mb_y2->coeff, x_y2->dqcoeff, 16);
+ vp9_transform_mby_4x4(mb);
+ vp9_quantize_mby_4x4(mb);
+ d = vp9_mbblock_error(mb, has_2nd_order);
+ if (has_2nd_order)
+ d += vp9_block_error(mb_y2->coeff, x_y2->dqcoeff, 16);
*Distortion = (d >> 2);
// rate
- *Rate = rdcost_mby_4x4(mb, backup);
- *skippable = vp9_mby_is_skippable_4x4(&mb->e_mbd, 1);
+ *Rate = rdcost_mby_4x4(mb, has_2nd_order, backup);
+ *skippable = vp9_mby_is_skippable_4x4(&mb->e_mbd, has_2nd_order);
}
-static int rdcost_mby_8x8(MACROBLOCK *mb, int backup) {
+static int rdcost_mby_8x8(MACROBLOCK *mb, int has_2nd_order, int backup) {
int cost = 0;
int b;
MACROBLOCKD *xd = &mb->e_mbd;
}
for (b = 0; b < 16; b += 4)
- cost += cost_coeffs(mb, xd->block + b, PLANE_TYPE_Y_NO_DC,
+ cost += cost_coeffs(mb, xd->block + b,
+ (has_2nd_order ?
+ PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC),
ta + vp9_block2above_8x8[b], tl + vp9_block2left_8x8[b],
TX_8X8);
- cost += cost_coeffs_2x2(mb, xd->block + 24, PLANE_TYPE_Y2,
- ta + vp9_block2above[24], tl + vp9_block2left[24]);
+ if (has_2nd_order)
+ cost += cost_coeffs_2x2(mb, xd->block + 24, PLANE_TYPE_Y2,
+ ta + vp9_block2above[24], tl + vp9_block2left[24]);
return cost;
}
MACROBLOCKD *const xd = &mb->e_mbd;
BLOCK *const mb_y2 = mb->block + 24;
BLOCKD *const x_y2 = xd->block + 24;
- int d;
+ int d, has_2nd_order;
+
+ xd->mode_info_context->mbmi.txfm_size = TX_8X8;
vp9_transform_mby_8x8(mb);
vp9_quantize_mby_8x8(mb);
-
- /* remove 1st order dc to properly combine 1st/2nd order distortion */
- mb->coeff[0] = 0;
- mb->coeff[64] = 0;
- mb->coeff[128] = 0;
- mb->coeff[192] = 0;
- xd->dqcoeff[0] = 0;
- xd->dqcoeff[64] = 0;
- xd->dqcoeff[128] = 0;
- xd->dqcoeff[192] = 0;
-
- d = vp9_mbblock_error(mb, 0);
- d += vp9_block_error(mb_y2->coeff, x_y2->dqcoeff, 16);
+ has_2nd_order = get_2nd_order_usage(xd);
+ d = vp9_mbblock_error_8x8_c(mb, has_2nd_order);
+ if (has_2nd_order)
+ d += vp9_block_error(mb_y2->coeff, x_y2->dqcoeff, 16);
*Distortion = (d >> 2);
// rate
- *Rate = rdcost_mby_8x8(mb, backup);
- *skippable = vp9_mby_is_skippable_8x8(&mb->e_mbd, 1);
+ *Rate = rdcost_mby_8x8(mb, has_2nd_order, backup);
+ *skippable = vp9_mby_is_skippable_8x8(&mb->e_mbd, has_2nd_order);
}
static int rdcost_mby_16x16(MACROBLOCK *mb, int backup) {
BLOCK *be = &mb->block[0];
TX_TYPE tx_type;
- tx_type = get_tx_type_16x16(xd, b);
- if (tx_type != DCT_DCT) {
- vp9_fht(be->src_diff, 32, be->coeff, tx_type, 16);
- } else
- vp9_transform_mby_16x16(mb);
-
+ xd->mode_info_context->mbmi.txfm_size = TX_16X16;
+ vp9_transform_mby_16x16(mb);
vp9_quantize_mby_16x16(mb);
// TODO(jingning) is it possible to quickly determine whether to force
// trailing coefficients to be zero, instead of running trellis
#endif
MACROBLOCKD *xd = &x->e_mbd;
int64_t best_rd = INT64_MAX;
- int distortion, rate = 0;
+ int distortion = 0, rate = 0;
BLOCK *be = x->block + ib;
BLOCKD *b = xd->block + ib;
ENTROPY_CONTEXT ta0, ta1, besta0 = 0, besta1 = 0;
for (mode2 = DC_PRED - 1; mode2 != TM_PRED + 1; mode2++) {
#endif
int64_t this_rd;
- int rate_t;
+ int rate_t = 0;
// FIXME rate for compound mode and second intrapred mode
rate = mode_costs[mode];
vp9_subtract_4b_c(be, b, 16);
+ assert(get_2nd_order_usage(xd) == 0);
if (xd->mode_info_context->mbmi.txfm_size == TX_8X8) {
TX_TYPE tx_type = get_tx_type_8x8(xd, b);
if (tx_type != DCT_DCT)
ta1 = ta0;
tl1 = tl0;
} else {
- x->vp9_short_fdct8x4(be->src_diff, be->coeff, 32);
- x->vp9_short_fdct8x4((be + 4)->src_diff, (be + 4)->coeff, 32);
-
- x->quantize_b_4x4_pair(x->block + ib, x->block + ib + 1,
- xd->block + ib, xd->block + ib + 1);
- x->quantize_b_4x4_pair(x->block + ib + 4, x->block + ib + 5,
- xd->block + ib + 4, xd->block + ib + 5);
-
- distortion = vp9_block_error_c((x->block + ib)->coeff,
- (xd->block + ib)->dqcoeff, 16);
- distortion += vp9_block_error_c((x->block + ib + 1)->coeff,
- (xd->block + ib + 1)->dqcoeff, 16);
- distortion += vp9_block_error_c((x->block + ib + 4)->coeff,
- (xd->block + ib + 4)->dqcoeff, 16);
- distortion += vp9_block_error_c((x->block + ib + 5)->coeff,
- (xd->block + ib + 5)->dqcoeff, 16);
-
+ static const int iblock[4] = {0, 1, 4, 5};
+ TX_TYPE tx_type;
+ int i;
ta0 = a[vp9_block2above[ib]];
ta1 = a[vp9_block2above[ib + 1]];
tl0 = l[vp9_block2left[ib]];
tl1 = l[vp9_block2left[ib + 4]];
- rate_t = cost_coeffs(x, xd->block + ib, PLANE_TYPE_Y_WITH_DC,
- &ta0, &tl0, TX_4X4);
- rate_t += cost_coeffs(x, xd->block + ib + 1, PLANE_TYPE_Y_WITH_DC,
- &ta1, &tl0, TX_4X4);
- rate_t += cost_coeffs(x, xd->block + ib + 4, PLANE_TYPE_Y_WITH_DC,
- &ta0, &tl1, TX_4X4);
- rate_t += cost_coeffs(x, xd->block + ib + 5, PLANE_TYPE_Y_WITH_DC,
- &ta1, &tl1, TX_4X4);
+ distortion = 0;
+ rate_t = 0;
+ for (i = 0; i < 4; ++i) {
+ b = &xd->block[ib + iblock[i]];
+ be = &x->block[ib + iblock[i]];
+ tx_type = get_tx_type_4x4(xd, b);
+ if (tx_type != DCT_DCT) {
+ vp9_fht_c(be->src_diff, 32, be->coeff, tx_type, 4);
+ vp9_ht_quantize_b_4x4(be, b, tx_type);
+ } else {
+ x->vp9_short_fdct4x4(be->src_diff, be->coeff, 32);
+ x->quantize_b_4x4(be, b);
+ }
+ distortion += vp9_block_error_c(be->coeff, b->dqcoeff, 16);
+ rate_t += cost_coeffs(x, b, PLANE_TYPE_Y_WITH_DC,
+ // i&1 ? &ta1 : &ta0, i&2 ? &tl1 : &tl0,
+ &ta0, &tl0,
+ TX_4X4);
+ }
rate += rate_t;
}
} else /* 8x8 */ {
if (otherrd) {
for (j = 0; j < 4; j += 2) {
- BLOCKD *bd3 = &xd->block[ib + iblock[j]];
- BLOCK *be3 = &x->block[ib + iblock[j]];
- x->vp9_short_fdct8x4(be3->src_diff, be3->coeff, 32);
- x->quantize_b_4x4_pair(be3, be3 + 1, bd3, bd3 + 1);
- thisdistortion = vp9_block_error_c(be3->coeff, bd3->dqcoeff, 32);
+ BLOCKD *bd = &xd->block[ib + iblock[j]];
+ BLOCK *be = &x->block[ib + iblock[j]];
+ x->vp9_short_fdct8x4(be->src_diff, be->coeff, 32);
+ x->quantize_b_4x4_pair(be, be + 1, bd, bd + 1);
+ thisdistortion = vp9_block_error_c(be->coeff, bd->dqcoeff, 32);
otherdist += thisdistortion;
- othercost += cost_coeffs(x, bd3, PLANE_TYPE_Y_WITH_DC,
+ othercost += cost_coeffs(x, bd, PLANE_TYPE_Y_WITH_DC,
tacp + vp9_block2above[ib + iblock[j]],
tlcp + vp9_block2left[ib + iblock[j]],
TX_4X4);
- othercost += cost_coeffs(x, bd3 + 1, PLANE_TYPE_Y_WITH_DC,
+ othercost += cost_coeffs(x, bd + 1, PLANE_TYPE_Y_WITH_DC,
tacp + vp9_block2above[ib + iblock[j] + 1],
tlcp + vp9_block2left[ib + iblock[j]],
TX_4X4);
this_mode = vp9_mode_order[mode_index].mode;
ref_frame = vp9_mode_order[mode_index].ref_frame;
- assert(ref_frame == INTRA_FRAME ||
- (cpi->ref_frame_flags & flag_list[ref_frame]));
+ if (!(ref_frame == INTRA_FRAME ||
+ (cpi->ref_frame_flags & flag_list[ref_frame]))) {
+ continue;
+ }
mbmi->ref_frame = ref_frame;
comp_pred = vp9_mode_order[mode_index].second_ref_frame > INTRA_FRAME;
mbmi->mode = this_mode;
*a = *l = (c != !type); /* 0 <-> all coeff data is zero */
}
-int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_y2_block) {
+int vp9_mby_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
int skip = 1;
int i = 0;
- if (has_y2_block) {
+ if (has_2nd_order) {
for (i = 0; i < 16; i++)
skip &= (xd->block[i].eob < 2);
skip &= (!xd->block[24].eob);
return skip;
}
-static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_y2_block) {
- return (vp9_mby_is_skippable_4x4(xd, has_y2_block) &
+static int mb_is_skippable_4x4(MACROBLOCKD *xd, int has_2nd_order) {
+ return (vp9_mby_is_skippable_4x4(xd, has_2nd_order) &
vp9_mbuv_is_skippable_4x4(xd));
}
-int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_y2_block) {
+int vp9_mby_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
int skip = 1;
int i = 0;
- if (has_y2_block) {
+ if (has_2nd_order) {
for (i = 0; i < 16; i += 4)
skip &= (xd->block[i].eob < 2);
skip &= (!xd->block[24].eob);
return (!xd->block[16].eob) & (!xd->block[20].eob);
}
-static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_y2_block) {
- return (vp9_mby_is_skippable_8x8(xd, has_y2_block) &
+static int mb_is_skippable_8x8(MACROBLOCKD *xd, int has_2nd_order) {
+ return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
vp9_mbuv_is_skippable_8x8(xd));
}
-static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_y2_block) {
- return (vp9_mby_is_skippable_8x8(xd, has_y2_block) &
+static int mb_is_skippable_8x8_4x4uv(MACROBLOCKD *xd, int has_2nd_order) {
+ return (vp9_mby_is_skippable_8x8(xd, has_2nd_order) &
vp9_mbuv_is_skippable_4x4(xd));
}
TOKENEXTRA **t,
int dry_run) {
PLANE_TYPE plane_type;
- int has_y2_block;
+ int has_2nd_order;
int b;
int tx_size = xd->mode_info_context->mbmi.txfm_size;
int mb_skip_context = vp9_get_pred_context(&cpi->common, xd, PRED_MBSKIP);
} else
skip_inc = 0;
- has_y2_block = (tx_size != TX_16X16
- && xd->mode_info_context->mbmi.mode != B_PRED
- && xd->mode_info_context->mbmi.mode != I8X8_PRED
- && xd->mode_info_context->mbmi.mode != SPLITMV);
+ has_2nd_order = get_2nd_order_usage(xd);
switch (tx_size) {
case TX_16X16:
case TX_8X8:
if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
xd->mode_info_context->mbmi.mode == SPLITMV)
- xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_8x8_4x4uv(xd, 0);
+ xd->mode_info_context->mbmi.mb_skip_coeff =
+ mb_is_skippable_8x8_4x4uv(xd, 0);
else
- xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_8x8(xd, has_y2_block);
+ xd->mode_info_context->mbmi.mb_skip_coeff =
+ mb_is_skippable_8x8(xd, has_2nd_order);
break;
default:
- xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_4x4(xd, has_y2_block);
+ xd->mode_info_context->mbmi.mb_skip_coeff =
+ mb_is_skippable_4x4(xd, has_2nd_order);
break;
}
if (!dry_run)
cpi->skip_false_count[mb_skip_context] += skip_inc;
- if (has_y2_block) {
+ if (has_2nd_order) {
if (tx_size == TX_8X8) {
tokenize_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2,
A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24],
ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
PLANE_TYPE plane_type;
int b;
- const int has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED &&
- xd->mode_info_context->mbmi.mode != I8X8_PRED &&
- xd->mode_info_context->mbmi.mode != SPLITMV);
+ int has_2nd_order = get_2nd_order_usage(xd);
- if (has_y2_block) {
+ if (has_2nd_order) {
stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2,
A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24],
TX_8X8, dry_run);
ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
int b;
PLANE_TYPE plane_type;
- const int has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED &&
- xd->mode_info_context->mbmi.mode != I8X8_PRED &&
- xd->mode_info_context->mbmi.mode != SPLITMV);
+ int has_2nd_order = (xd->mode_info_context->mbmi.mode != B_PRED &&
+ xd->mode_info_context->mbmi.mode != I8X8_PRED &&
+ xd->mode_info_context->mbmi.mode != SPLITMV);
+ if (has_2nd_order && get_tx_type(xd, &xd->block[0]) != DCT_DCT)
+ has_2nd_order = 0;
- if (has_y2_block) {
+ if (has_2nd_order) {
stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2, A + vp9_block2above[24],
L + vp9_block2left[24], TX_4X4, dry_run);
plane_type = PLANE_TYPE_Y_NO_DC;
TOKENEXTRA **t, int dry_run) {
ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context;
ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context;
+ PLANE_TYPE plane_type;
int b;
+ int has_2nd_order = get_2nd_order_usage(xd);
+ if (has_2nd_order) {
+ stuff_b(cpi, xd, xd->block + 24, t, PLANE_TYPE_Y2,
+ A + vp9_block2above_8x8[24], L + vp9_block2left_8x8[24],
+ TX_8X8, dry_run);
+ plane_type = PLANE_TYPE_Y_NO_DC;
+ } else {
+ plane_type = PLANE_TYPE_Y_WITH_DC;
+ }
+
for (b = 0; b < 16; b += 4) {
- stuff_b(cpi, xd, xd->block + b, t, PLANE_TYPE_Y_WITH_DC,
+ stuff_b(cpi, xd, xd->block + b, t, plane_type,
A + vp9_block2above_8x8[b], L + vp9_block2left_8x8[b],
TX_8X8, dry_run);
A[vp9_block2above_8x8[b] + 1] = A[vp9_block2above_8x8[b]];
}
void vp9_fix_contexts(MACROBLOCKD *xd) {
- /* Clear entropy contexts for Y2 blocks */
+ /* Clear entropy contexts for blocks */
if ((xd->mode_info_context->mbmi.mode != B_PRED
- && xd->mode_info_context->mbmi.mode != I8X8_PRED
- && xd->mode_info_context->mbmi.mode != SPLITMV)
+ && xd->mode_info_context->mbmi.mode != I8X8_PRED
+ && xd->mode_info_context->mbmi.mode != SPLITMV)
|| xd->mode_info_context->mbmi.txfm_size == TX_16X16
) {
vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
show_histogram(hist->bucket, buckets, hist->total, scale);
}
+#define mmin(a, b) ((a) < (b) ? (a) : (b))
+static void find_mismatch(vpx_image_t *img1, vpx_image_t *img2,
+ int yloc[2], int uloc[2], int vloc[2]) {
+ int match = 1;
+ int i, j;
+ yloc[0] = yloc[1] = -1;
+ for (i = 0, match = 1; match && i < img1->d_h; i+=32) {
+ for (j = 0; match && j < img1->d_w; j+=32) {
+ int k, l;
+ int si = mmin(i + 32, img1->d_h) - i;
+ int sj = mmin(j + 32, img1->d_w) - j;
+ for (k = 0; match && k < si; k++)
+ for (l = 0; match && l < sj; l++) {
+ if (*(img1->planes[VPX_PLANE_Y] +
+ (i + k) * img1->stride[VPX_PLANE_Y] + j + l) !=
+ *(img2->planes[VPX_PLANE_Y] +
+ (i + k) * img2->stride[VPX_PLANE_Y] + j + l)) {
+ yloc[0] = i + k;
+ yloc[1] = j + l;
+ match = 0;
+ break;
+ }
+ }
+ }
+ }
+ uloc[0] = uloc[1] = -1;
+ for (i = 0, match = 1; match && i < (img1->d_h + 1) / 2; i+=16) {
+ for (j = 0; j < match && (img1->d_w + 1) / 2; j+=16) {
+ int k, l;
+ int si = mmin(i + 16, (img1->d_h + 1) / 2) - i;
+ int sj = mmin(j + 16, (img1->d_w + 1) / 2) - j;
+ for (k = 0; match && k < si; k++)
+ for (l = 0; match && l < sj; l++) {
+ if (*(img1->planes[VPX_PLANE_U] +
+ (i + k) * img1->stride[VPX_PLANE_U] + j + l) !=
+ *(img2->planes[VPX_PLANE_U] +
+ (i + k) * img2->stride[VPX_PLANE_U] + j + l)) {
+ uloc[0] = i + k;
+ uloc[1] = j + l;
+ match = 0;
+ break;
+ }
+ }
+ }
+ }
+ vloc[0] = vloc[1] = -1;
+ for (i = 0, match = 1; match && i < (img1->d_h + 1) / 2; i+=16) {
+ for (j = 0; j < match && (img1->d_w + 1) / 2; j+=16) {
+ int k, l;
+ int si = mmin(i + 16, (img1->d_h + 1) / 2) - i;
+ int sj = mmin(j + 16, (img1->d_w + 1) / 2) - j;
+ for (k = 0; match && k < si; k++)
+ for (l = 0; match && l < sj; l++) {
+ if (*(img1->planes[VPX_PLANE_V] +
+ (i + k) * img1->stride[VPX_PLANE_V] + j + l) !=
+ *(img2->planes[VPX_PLANE_V] +
+ (i + k) * img2->stride[VPX_PLANE_V] + j + l)) {
+ vloc[0] = i + k;
+ vloc[1] = j + l;
+ match = 0;
+ break;
+ }
+ }
+ }
+ }
+}
static int compare_img(vpx_image_t *img1, vpx_image_t *img2)
{
if (!stream->mismatch_seen
&& !compare_img(&stream->ref_enc.img, &stream->ref_dec.img)) {
/* TODO(jkoleszar): make fatal. */
- warn("Stream %d: Encode/decode mismatch on frame %d",
- stream->index, stream->frames_out);
+ int y[2], u[2], v[2];
+ find_mismatch(&stream->ref_enc.img, &stream->ref_dec.img,
+ y, u, v);
+ warn("Stream %d: Encode/decode mismatch on frame %d"
+ " at Y[%d, %d], U[%d, %d], V[%d, %d]",
+ stream->index, stream->frames_out,
+ y[0], y[1], u[0], u[1], v[0], v[1]);
stream->mismatch_seen = stream->frames_out;
}
}