static int get_delta_q(vp8_reader *bc, int prev, int *q_update) { int ret_val = 0; if (vp8_read_bit(bc)) { ret_val = vp8_read_literal(bc, 4); if (vp8_read_bit(bc)) ret_val = -ret_val; } /* Trigger a quantizer update if the delta-q value has changed */ if (ret_val != prev) *q_update = 1; return ret_val; }
void vp8_kfread_modes(VP8D_COMP *pbi) { VP8_COMMON *const cp = & pbi->common; vp8_reader *const bc = & pbi->bc; MODE_INFO *m = cp->mi; const int ms = cp->mode_info_stride; int mb_row = -1; vp8_prob prob_skip_false = 0; if (cp->mb_no_coeff_skip) prob_skip_false = (vp8_prob)(vp8_read_literal(bc, 8)); while (++mb_row < cp->mb_rows) { int mb_col = -1; while (++mb_col < cp->mb_cols) { MB_PREDICTION_MODE y_mode; // Read the Macroblock segmentation map if it is being updated explicitly this frame (reset to 0 above by default) // By default on a key frame reset all MBs to segment 0 m->mbmi.segment_id = 0; if (pbi->mb.update_mb_segmentation_map) vp8_read_mb_features(bc, &m->mbmi, &pbi->mb); // Read the macroblock coeff skip flag if this feature is in use, else default to 0 if (cp->mb_no_coeff_skip) m->mbmi.mb_skip_coeff = vp8_read(bc, prob_skip_false); else m->mbmi.mb_skip_coeff = 0; y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc, cp->kf_ymode_prob); m->mbmi.ref_frame = INTRA_FRAME; if ((m->mbmi.mode = y_mode) == B_PRED) { int i = 0; do { const B_PREDICTION_MODE A = vp8_above_bmi(m, i, ms)->mode; const B_PREDICTION_MODE L = vp8_left_bmi(m, i)->mode; m->bmi[i].mode = (B_PREDICTION_MODE) vp8_read_bmode(bc, cp->kf_bmode_prob [A] [L]); } while (++i < 16); } else { int BMode; int i = 0; switch (y_mode) { case DC_PRED: BMode = B_DC_PRED; break; case V_PRED: BMode = B_VE_PRED; break; case H_PRED: BMode = B_HE_PRED; break; case TM_PRED: BMode = B_TM_PRED; break; default: BMode = B_DC_PRED; break; } do { m->bmi[i].mode = (B_PREDICTION_MODE)BMode; } while (++i < 16); } (m++)->mbmi.uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, cp->kf_uv_mode_prob); } m++; // skip the border } }
static void setup_token_decoder(VP8D_COMP *pbi, const unsigned char* token_part_sizes) { vp8_reader *bool_decoder = &pbi->mbc[0]; unsigned int partition_idx; unsigned int fragment_idx; unsigned int num_token_partitions; const unsigned char *first_fragment_end = pbi->fragments.ptrs[0] + pbi->fragments.sizes[0]; TOKEN_PARTITION multi_token_partition = (TOKEN_PARTITION)vp8_read_literal(&pbi->mbc[8], 2); if (!vp8dx_bool_error(&pbi->mbc[8])) pbi->common.multi_token_partition = multi_token_partition; num_token_partitions = 1 << pbi->common.multi_token_partition; /* Check for partitions within the fragments and unpack the fragments * so that each fragment pointer points to its corresponding partition. */ for (fragment_idx = 0; fragment_idx < pbi->fragments.count; ++fragment_idx) { unsigned int fragment_size = pbi->fragments.sizes[fragment_idx]; const unsigned char *fragment_end = pbi->fragments.ptrs[fragment_idx] + fragment_size; /* Special case for handling the first partition since we have already * read its size. */ if (fragment_idx == 0) { /* Size of first partition + token partition sizes element */ ptrdiff_t ext_first_part_size = token_part_sizes - pbi->fragments.ptrs[0] + 3 * (num_token_partitions - 1); fragment_size -= (unsigned int)ext_first_part_size; if (fragment_size > 0) { pbi->fragments.sizes[0] = (unsigned int)ext_first_part_size; /* The fragment contains an additional partition. Move to * next. */ fragment_idx++; pbi->fragments.ptrs[fragment_idx] = pbi->fragments.ptrs[0] + pbi->fragments.sizes[0]; } } /* Split the chunk into partitions read from the bitstream */ while (fragment_size > 0) { ptrdiff_t partition_size = read_available_partition_size( pbi, token_part_sizes, pbi->fragments.ptrs[fragment_idx], first_fragment_end, fragment_end, fragment_idx - 1, num_token_partitions); pbi->fragments.sizes[fragment_idx] = (unsigned int)partition_size; fragment_size -= (unsigned int)partition_size; assert(fragment_idx <= num_token_partitions); if (fragment_size > 0) { /* The fragment contains an additional partition. * Move to next. */ fragment_idx++; pbi->fragments.ptrs[fragment_idx] = pbi->fragments.ptrs[fragment_idx - 1] + partition_size; } } } pbi->fragments.count = num_token_partitions + 1; for (partition_idx = 1; partition_idx < pbi->fragments.count; ++partition_idx) { if (vp8dx_start_decode(bool_decoder, pbi->fragments.ptrs[partition_idx], pbi->fragments.sizes[partition_idx], pbi->decrypt_cb, pbi->decrypt_state)) vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate bool decoder %d", partition_idx); bool_decoder++; } #if CONFIG_MULTITHREAD /* Clamp number of decoder threads */ if (pbi->decoding_thread_count > num_token_partitions - 1) pbi->decoding_thread_count = num_token_partitions - 1; #endif }