// #define MODE_COUNT_TESTING
void vp9_adapt_mode_probs(VP9_COMMON *cm) {
int i;
+ FRAME_CONTEXT *fc = &cm->fc;
#ifdef MODE_COUNT_TESTING
int t;
printf("static const unsigned int\nymode_counts"
"[VP9_YMODES] = {\n");
- for (t = 0; t < VP9_YMODES; ++t) printf("%d, ", cm->fc.ymode_counts[t]);
+ for (t = 0; t < VP9_YMODES; ++t)
+ printf("%d, ", fc->ymode_counts[t]);
printf("};\n");
printf("static const unsigned int\nuv_mode_counts"
"[VP9_YMODES] [VP9_UV_MODES] = {\n");
for (i = 0; i < VP9_YMODES; ++i) {
printf(" {");
- for (t = 0; t < VP9_UV_MODES; ++t) printf("%d, ", cm->fc.uv_mode_counts[i][t]);
+ for (t = 0; t < VP9_UV_MODES; ++t)
+ printf("%d, ", fc->uv_mode_counts[i][t]);
printf("},\n");
}
printf("};\n");
printf("static const unsigned int\nbmode_counts"
"[VP9_NKF_BINTRAMODES] = {\n");
for (t = 0; t < VP9_NKF_BINTRAMODES; ++t)
- printf("%d, ", cm->fc.bmode_counts[t]);
+ printf("%d, ", fc->bmode_counts[t]);
printf("};\n");
printf("static const unsigned int\ni8x8_mode_counts"
"[VP9_I8X8_MODES] = {\n");
- for (t = 0; t < VP9_I8X8_MODES; ++t) printf("%d, ", cm->fc.i8x8_mode_counts[t]);
+ for (t = 0; t < VP9_I8X8_MODES; ++t)
+ printf("%d, ", fc->i8x8_mode_counts[t]);
printf("};\n");
printf("static const unsigned int\nsub_mv_ref_counts"
"[SUBMVREF_COUNT] [VP9_SUBMVREFS] = {\n");
for (i = 0; i < SUBMVREF_COUNT; ++i) {
printf(" {");
- for (t = 0; t < VP9_SUBMVREFS; ++t) printf("%d, ", cm->fc.sub_mv_ref_counts[i][t]);
+ for (t = 0; t < VP9_SUBMVREFS; ++t)
+ printf("%d, ", fc->sub_mv_ref_counts[i][t]);
printf("},\n");
}
printf("};\n");
printf("static const unsigned int\nmbsplit_counts"
"[VP9_NUMMBSPLITS] = {\n");
- for (t = 0; t < VP9_NUMMBSPLITS; ++t) printf("%d, ", cm->fc.mbsplit_counts[t]);
+ for (t = 0; t < VP9_NUMMBSPLITS; ++t)
+ printf("%d, ", fc->mbsplit_counts[t]);
printf("};\n");
#if CONFIG_COMP_INTERINTRA_PRED
printf("static const unsigned int\ninterintra_counts"
"[2] = {\n");
- for (t = 0; t < 2; ++t) printf("%d, ", cm->fc.interintra_counts[t]);
+ for (t = 0; t < 2; ++t)
+ printf("%d, ", fc->interintra_counts[t]);
printf("};\n");
#endif
#endif
update_mode_probs(VP9_YMODES, vp9_ymode_tree,
- cm->fc.ymode_counts, cm->fc.pre_ymode_prob,
- cm->fc.ymode_prob, 0);
+ fc->ymode_counts, fc->pre_ymode_prob,
+ fc->ymode_prob, 0);
update_mode_probs(VP9_I32X32_MODES, vp9_sb_ymode_tree,
- cm->fc.sb_ymode_counts, cm->fc.pre_sb_ymode_prob,
- cm->fc.sb_ymode_prob, 0);
- for (i = 0; i < VP9_YMODES; ++i) {
+ fc->sb_ymode_counts, fc->pre_sb_ymode_prob,
+ fc->sb_ymode_prob, 0);
+
+ for (i = 0; i < VP9_YMODES; ++i)
update_mode_probs(VP9_UV_MODES, vp9_uv_mode_tree,
- cm->fc.uv_mode_counts[i], cm->fc.pre_uv_mode_prob[i],
- cm->fc.uv_mode_prob[i], 0);
- }
+ fc->uv_mode_counts[i], fc->pre_uv_mode_prob[i],
+ fc->uv_mode_prob[i], 0);
+
update_mode_probs(VP9_NKF_BINTRAMODES, vp9_bmode_tree,
- cm->fc.bmode_counts, cm->fc.pre_bmode_prob,
- cm->fc.bmode_prob, 0);
+ fc->bmode_counts, fc->pre_bmode_prob,
+ fc->bmode_prob, 0);
update_mode_probs(VP9_I8X8_MODES,
- vp9_i8x8_mode_tree, cm->fc.i8x8_mode_counts,
- cm->fc.pre_i8x8_mode_prob, cm->fc.i8x8_mode_prob, 0);
- for (i = 0; i < SUBMVREF_COUNT; ++i) {
+ vp9_i8x8_mode_tree, fc->i8x8_mode_counts,
+ fc->pre_i8x8_mode_prob, fc->i8x8_mode_prob, 0);
+
+ for (i = 0; i < SUBMVREF_COUNT; ++i)
update_mode_probs(VP9_SUBMVREFS,
- vp9_sub_mv_ref_tree, cm->fc.sub_mv_ref_counts[i],
- cm->fc.pre_sub_mv_ref_prob[i], cm->fc.sub_mv_ref_prob[i],
+ vp9_sub_mv_ref_tree, fc->sub_mv_ref_counts[i],
+ fc->pre_sub_mv_ref_prob[i], fc->sub_mv_ref_prob[i],
LEFT4X4);
- }
+
update_mode_probs(VP9_NUMMBSPLITS, vp9_mbsplit_tree,
- cm->fc.mbsplit_counts, cm->fc.pre_mbsplit_prob,
- cm->fc.mbsplit_prob, 0);
+ fc->mbsplit_counts, fc->pre_mbsplit_prob,
+ fc->mbsplit_prob, 0);
#if CONFIG_COMP_INTERINTRA_PRED
if (cm->use_interintra) {
int factor, interintra_prob, count;
- interintra_prob = get_binary_prob(cm->fc.interintra_counts[0],
- cm->fc.interintra_counts[1]);
- count = cm->fc.interintra_counts[0] + cm->fc.interintra_counts[1];
+ interintra_prob = get_binary_prob(fc->interintra_counts[0],
+ fc->interintra_counts[1]);
+ count = fc->interintra_counts[0] + fc->interintra_counts[1];
count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
- cm->fc.interintra_prob = weighted_prob(cm->fc.pre_interintra_prob,
- interintra_prob, factor);
+ fc->interintra_prob = weighted_prob(fc->pre_interintra_prob,
+ interintra_prob, factor);
}
#endif
for (i = 0; i < PARTITION_PLANES; i++)
update_mode_probs(PARTITION_TYPES, vp9_partition_tree,
- cm->fc.partition_counts[i], cm->fc.pre_partition_prob[i],
- cm->fc.partition_prob[i], 0);
+ fc->partition_counts[i], fc->pre_partition_prob[i],
+ fc->partition_prob[i], 0);
}
static void set_default_lf_deltas(MACROBLOCKD *xd) {
if (cm->last_frame_seg_map)
vpx_memset(cm->last_frame_seg_map, 0, (cm->mb_rows * cm->mb_cols));
- /* reset the mode ref deltas for loop filter */
+ // Reset the mode ref deltas for loop filter
vpx_memset(xd->last_ref_lf_deltas, 0, sizeof(xd->last_ref_lf_deltas));
vpx_memset(xd->last_mode_lf_deltas, 0, sizeof(xd->last_mode_lf_deltas));
set_default_lf_deltas(xd);
vp9_default_bmode_probs(cm->fc.bmode_prob);
vp9_kf_default_bmode_probs(cm->kf_bmode_prob);
vp9_init_mv_probs(cm);
+
// To force update of the sharpness
cm->last_sharpness_level = -1;
vp9_init_mode_contexts(cm);
- for (i = 0; i < NUM_FRAME_CONTEXTS; i++) {
+ for (i = 0; i < NUM_FRAME_CONTEXTS; i++)
vpx_memcpy(&cm->frame_contexts[i], &cm->fc, sizeof(cm->fc));
- }
vpx_memset(cm->prev_mip, 0,
(cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
#include <assert.h>
#include <stdio.h>
-#define COEFCOUNT_TESTING
-
// #define DEC_DEBUG
#ifdef DEC_DEBUG
int dec_debug = 0;
return start + len > start && start + len <= end;
}
-static TXFM_MODE read_txfm_mode(vp9_reader *r) {
- TXFM_MODE mode = vp9_read_literal(r, 2);
- if (mode == ALLOW_32X32)
- mode += vp9_read_bit(r);
- return mode;
+static void setup_txfm_mode(VP9_COMMON *pc, int lossless, vp9_reader *r) {
+ if (lossless) {
+ pc->txfm_mode = ONLY_4X4;
+ } else {
+ pc->txfm_mode = vp9_read_literal(r, 2);
+ if (pc->txfm_mode == ALLOW_32X32)
+ pc->txfm_mode += vp9_read_bit(r);
+
+ if (pc->txfm_mode == TX_MODE_SELECT) {
+ pc->prob_tx[0] = vp9_read_prob(r);
+ pc->prob_tx[1] = vp9_read_prob(r);
+ pc->prob_tx[2] = vp9_read_prob(r);
+ }
+ }
}
static int get_unsigned_bits(unsigned int num_values) {
VP9_COMMON *const pc = &pbi->common;
for (q = 0; q < QINDEX_RANGE; q++) {
+ // DC value
pc->y_dequant[q][0] = (int16_t)vp9_dc_quant(q, pc->y_dc_delta_q);
pc->uv_dequant[q][0] = (int16_t)vp9_dc_uv_quant(q, pc->uv_dc_delta_q);
- /* all the ac values =; */
+ // AC values
for (i = 1; i < 16; i++) {
const int rc = vp9_default_zig_zag1d_4x4[i];
xd->frame_type = pc->frame_type;
xd->mode_info_context->mbmi.mode = DC_PRED;
xd->mode_info_stride = pc->mode_info_stride;
- xd->corrupted = 0;
}
#if CONFIG_CODE_ZEROGROUP
xd->update_mb_segmentation_data = 0;
xd->segmentation_enabled = vp9_read_bit(r);
- if (xd->segmentation_enabled) {
- // Segmentation map update
- xd->update_mb_segmentation_map = vp9_read_bit(r);
- if (xd->update_mb_segmentation_map) {
- for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
- xd->mb_segment_tree_probs[i] = vp9_read_bit(r) ? vp9_read_prob(r)
- : MAX_PROB;
-
- pc->temporal_update = vp9_read_bit(r);
- if (pc->temporal_update) {
- const vp9_prob *p = xd->mb_segment_tree_probs;
- vp9_prob *mispred_p = xd->mb_segment_mispred_tree_probs;
-
- const int c0 = p[0] * p[1];
- const int c1 = p[0] * (256 - p[1]);
- const int c2 = (256 - p[0]) * p[2];
- const int c3 = (256 - p[0]) * (256 - p[2]);
-
- mispred_p[0] = get_binary_prob(c1, c2 + c3);
- mispred_p[1] = get_binary_prob(c0, c2 + c3);
- mispred_p[2] = get_binary_prob(c0 + c1, c3);
- mispred_p[3] = get_binary_prob(c0 + c1, c2);
-
- for (i = 0; i < PREDICTION_PROBS; i++)
- pc->segment_pred_probs[i] = vp9_read_bit(r) ? vp9_read_prob(r)
- : MAX_PROB;
- } else {
- for (i = 0; i < PREDICTION_PROBS; i++)
- pc->segment_pred_probs[i] = MAX_PROB;
- }
+ if (!xd->segmentation_enabled)
+ return;
+
+ // Segmentation map update
+ xd->update_mb_segmentation_map = vp9_read_bit(r);
+ if (xd->update_mb_segmentation_map) {
+ for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+ xd->mb_segment_tree_probs[i] = vp9_read_bit(r) ? vp9_read_prob(r)
+ : MAX_PROB;
+
+ pc->temporal_update = vp9_read_bit(r);
+ if (pc->temporal_update) {
+ const vp9_prob *p = xd->mb_segment_tree_probs;
+ vp9_prob *mispred_p = xd->mb_segment_mispred_tree_probs;
+
+ const int c0 = p[0] * p[1];
+ const int c1 = p[0] * (256 - p[1]);
+ const int c2 = (256 - p[0]) * p[2];
+ const int c3 = (256 - p[0]) * (256 - p[2]);
+
+ mispred_p[0] = get_binary_prob(c1, c2 + c3);
+ mispred_p[1] = get_binary_prob(c0, c2 + c3);
+ mispred_p[2] = get_binary_prob(c0 + c1, c3);
+ mispred_p[3] = get_binary_prob(c0 + c1, c2);
+
+ for (i = 0; i < PREDICTION_PROBS; i++)
+ pc->segment_pred_probs[i] = vp9_read_bit(r) ? vp9_read_prob(r)
+ : MAX_PROB;
+ } else {
+ for (i = 0; i < PREDICTION_PROBS; i++)
+ pc->segment_pred_probs[i] = MAX_PROB;
}
+ }
- // Segmentation data update
- xd->update_mb_segmentation_data = vp9_read_bit(r);
- if (xd->update_mb_segmentation_data) {
- xd->mb_segment_abs_delta = vp9_read_bit(r);
-
- vp9_clearall_segfeatures(xd);
-
- for (i = 0; i < MAX_MB_SEGMENTS; i++) {
- for (j = 0; j < SEG_LVL_MAX; j++) {
- int data = 0;
- const int feature_enabled = vp9_read_bit(r);
- if (feature_enabled) {
- vp9_enable_segfeature(xd, i, j);
- data = decode_unsigned_max(r, vp9_seg_feature_data_max(j));
- if (vp9_is_segfeature_signed(j))
- data = vp9_read_and_apply_sign(r, data);
- }
- vp9_set_segdata(xd, i, j, data);
+ // Segmentation data update
+ xd->update_mb_segmentation_data = vp9_read_bit(r);
+ if (xd->update_mb_segmentation_data) {
+ xd->mb_segment_abs_delta = vp9_read_bit(r);
+
+ vp9_clearall_segfeatures(xd);
+
+ for (i = 0; i < MAX_MB_SEGMENTS; i++) {
+ for (j = 0; j < SEG_LVL_MAX; j++) {
+ int data = 0;
+ const int feature_enabled = vp9_read_bit(r);
+ if (feature_enabled) {
+ vp9_enable_segfeature(xd, i, j);
+ data = decode_unsigned_max(r, vp9_seg_feature_data_max(j));
+ if (vp9_is_segfeature_signed(j))
+ data = vp9_read_and_apply_sign(r, data);
}
+ vp9_set_segdata(xd, i, j, data);
}
}
}
// Read in loop filter deltas applied at the MB level based on mode or ref
// frame.
xd->mode_ref_lf_delta_update = 0;
- xd->mode_ref_lf_delta_enabled = vp9_read_bit(r);
+ xd->mode_ref_lf_delta_enabled = vp9_read_bit(r);
if (xd->mode_ref_lf_delta_enabled) {
xd->mode_ref_lf_delta_update = vp9_read_bit(r);
if (xd->mode_ref_lf_delta_update) {
mb_init_dequantizer(pbi, &pbi->mb); // MB level dequantizer setup
}
+static INTERPOLATIONFILTERTYPE read_mcomp_filter_type(vp9_reader *r) {
+ return vp9_read_bit(r) ? SWITCHABLE
+ : vp9_read_literal(r, 2);
+}
+
static const uint8_t *read_frame_size(VP9_COMMON *const pc, const uint8_t *data,
const uint8_t *data_end,
int *width, int *height) {
const uint8_t *data = pbi->source;
const uint8_t *data_end = data + pbi->source_sz;
size_t first_partition_size = 0;
+ YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx];
int i;
- // printf("Decoding frame %d\n", pc->current_video_frame);
-
xd->corrupted = 0; // start with no corruption of current frame
- pc->yv12_fb[pc->new_fb_idx].corrupted = 0;
+ new_fb->corrupted = 0;
if (data_end - data < 3) {
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
init_frame(pbi);
// Reset the frame pointers to the current frame size
- vp8_yv12_realloc_frame_buffer(&pc->yv12_fb[pc->new_fb_idx],
- pc->width, pc->height,
+ vp8_yv12_realloc_frame_buffer(new_fb, pc->width, pc->height,
VP9BORDERINPIXELS);
if (vp9_reader_init(&header_bc, data, first_partition_size))
setup_loopfilter(pc, xd, &header_bc);
- // Dummy read for now
- vp9_read_literal(&header_bc, 2);
+ vp9_read_literal(&header_bc, 2); // unused
setup_quantization(pbi, &header_bc);
pc->ref_frame_sign_bias[GOLDEN_FRAME] = vp9_read_bit(&header_bc);
pc->ref_frame_sign_bias[ALTREF_FRAME] = vp9_read_bit(&header_bc);
-
- // Is high precision mv allowed
xd->allow_high_precision_mv = vp9_read_bit(&header_bc);
-
- // Read the type of subpel filter to use
- pc->mcomp_filter_type = vp9_read_bit(&header_bc)
- ? SWITCHABLE
- : vp9_read_literal(&header_bc, 2);
+ pc->mcomp_filter_type = read_mcomp_filter_type(&header_bc);
#if CONFIG_COMP_INTERINTRA_PRED
pc->use_interintra = vp9_read_bit(&header_bc);
pc->refresh_entropy_probs = 0;
pc->frame_parallel_decoding_mode = 1;
}
+
pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2);
vpx_memcpy(&pc->fc, &pc->frame_contexts[pc->frame_context_idx],
sizeof(pc->fc));
setup_pred_probs(pc, &header_bc);
- pc->txfm_mode = xd->lossless ? ONLY_4X4 : read_txfm_mode(&header_bc);
- if (pc->txfm_mode == TX_MODE_SELECT) {
- pc->prob_tx[0] = vp9_read_prob(&header_bc);
- pc->prob_tx[1] = vp9_read_prob(&header_bc);
- pc->prob_tx[2] = vp9_read_prob(&header_bc);
- }
+ setup_txfm_mode(pc, xd->lossless, &header_bc);
// Read inter mode probability context updates
if (pc->frame_type != KEY_FRAME) {
pc->fc.vp9_mode_contexts[i][j] = vp9_read_prob(&header_bc);
}
#if CONFIG_MODELCOEFPROB
- if (pc->frame_type == KEY_FRAME) {
+ if (pc->frame_type == KEY_FRAME)
vp9_default_coef_probs(pc);
- }
#endif
update_frame_context(pbi);
read_coef_probs(pbi, &header_bc);
#if CONFIG_CODE_ZEROGROUP
- read_zpc_probs(&pbi->common, &header_bc);
+ read_zpc_probs(pc, &header_bc);
#endif
// Initialize xd pointers. Any reference should do for xd->pre, so use 0.
setup_pre_planes(xd, &pc->yv12_fb[pc->active_ref_idx[0]], NULL,
0, 0, NULL, NULL);
- setup_dst_planes(xd, &pc->yv12_fb[pc->new_fb_idx], 0, 0);
+ setup_dst_planes(xd, new_fb, 0, 0);
// Create the segmentation map structure and set to 0
if (!pc->last_frame_seg_map)
vpx_calloc((pc->mb_rows * pc->mb_cols), 1));
// set up frame new frame for intra coded blocks
- vp9_setup_intra_recon(&pc->yv12_fb[pc->new_fb_idx]);
+ vp9_setup_intra_recon(new_fb);
vp9_setup_block_dptrs(xd);
vp9_build_block_doffsets(xd);
decode_tiles(pbi, data, first_partition_size, &header_bc, &residual_bc);
- // keep track of the last coded dimensions
pc->last_width = pc->width;
pc->last_height = pc->height;
- // Collect information about decoder corruption.
- // 1. Check first boolean decoder for errors.
- // 2. Check the macroblock information
- pc->yv12_fb[pc->new_fb_idx].corrupted = vp9_reader_has_error(&header_bc) |
- xd->corrupted;
+ new_fb->corrupted = vp9_reader_has_error(&header_bc) | xd->corrupted;
if (!pbi->decoded_key_frame) {
- if (pc->frame_type == KEY_FRAME && !pc->yv12_fb[pc->new_fb_idx].corrupted)
+ if (pc->frame_type == KEY_FRAME && !new_fb->corrupted)
pbi->decoded_key_frame = 1;
else
- vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME,
+ vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"A stream must start with a complete key frame");
}
if (pc->frame_type != KEY_FRAME) {
vp9_adapt_mode_probs(pc);
vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
- vp9_adapt_mode_context(&pbi->common);
+ vp9_adapt_mode_context(pc);
}
}