static void count_segs_sb(VP9_COMP *cpi, MODE_INFO *mi, int *no_pred_segcounts, int (*temporal_predictor_count)[2], int *t_unpred_seg_counts, int mi_row, int mi_col, BLOCK_SIZE_TYPE bsize) { VP9_COMMON *const cm = &cpi->common; const int mis = cm->mode_info_stride; int bwl, bhl; const int bsl = mi_width_log2(bsize), bs = 1 << (bsl - 1); if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; bwl = mi_width_log2(mi->mbmi.sb_type); bhl = mi_height_log2(mi->mbmi.sb_type); if (bwl == bsl && bhl == bsl) { count_segs(cpi, mi, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, 1 << bsl, 1 << bsl, mi_row, mi_col); } else if (bwl == bsl && bhl < bsl) { count_segs(cpi, mi, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, 1 << bsl, bs, mi_row, mi_col); count_segs(cpi, mi + bs * mis, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, 1 << bsl, bs, mi_row + bs, mi_col); } else if (bwl < bsl && bhl == bsl) { count_segs(cpi, mi, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, bs, 1 << bsl, mi_row, mi_col); count_segs(cpi, mi + bs, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, bs, 1 << bsl, mi_row, mi_col + bs); } else { BLOCK_SIZE_TYPE subsize; int n; assert(bwl < bsl && bhl < bsl); if (bsize == BLOCK_SIZE_SB64X64) { subsize = BLOCK_SIZE_SB32X32; } else if (bsize == BLOCK_SIZE_SB32X32) { subsize = BLOCK_SIZE_MB16X16; } else { assert(bsize == BLOCK_SIZE_MB16X16); subsize = BLOCK_SIZE_SB8X8; } for (n = 0; n < 4; n++) { const int y_idx = n >> 1, x_idx = n & 0x01; count_segs_sb(cpi, mi + y_idx * bs * mis + x_idx * bs, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, mi_row + y_idx * bs, mi_col + x_idx * bs, subsize); } } }
static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE bsize, int mi_row, int mi_col, int segment_id) { const int mi_offset = mi_row * cm->mi_cols + mi_col; const int bw = 1 << mi_width_log2(bsize); const int bh = 1 << mi_height_log2(bsize); const int xmis = MIN(cm->mi_cols - mi_col, bw); const int ymis = MIN(cm->mi_rows - mi_row, bh); int x, y; assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); for (y = 0; y < ymis; y++) for (x = 0; x < xmis; x++) cm->last_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id; }
void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd, const TileInfo *const tile, int mi_row, int mi_col, vp9_reader *r) { MODE_INFO *const mi = xd->mi_8x8[0]; const BLOCK_SIZE bsize = mi->mbmi.sb_type; const int bw = 1 << mi_width_log2(bsize); const int bh = 1 << mi_height_log2(bsize); const int y_mis = MIN(bh, cm->mi_rows - mi_row); const int x_mis = MIN(bw, cm->mi_cols - mi_col); int x, y, z; if (frame_is_intra_only(cm)) read_intra_frame_mode_info(cm, xd, mi, mi_row, mi_col, r); else read_inter_frame_mode_info(cm, xd, tile, mi, mi_row, mi_col, r); for (y = 0, z = 0; y < y_mis; y++, z += cm->mode_info_stride) { for (x = !y; x < x_mis; x++) { xd->mi_8x8[z + x] = mi; } } }
static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col, vp9_reader *r, BLOCK_SIZE_TYPE bsize) { const int bwl = mi_width_log2(bsize), bhl = mi_height_log2(bsize); const int bw = 1 << bwl, bh = 1 << bhl; int n, eobtotal; VP9_COMMON *const pc = &pbi->common; MODE_INFO *const mi = xd->mode_info_context; MB_MODE_INFO *const mbmi = &mi->mbmi; const int mis = pc->mode_info_stride; assert(mbmi->sb_type == bsize); assert(mbmi->ref_frame[0] != INTRA_FRAME); vp9_setup_interp_filters(xd, mbmi->interp_filter, pc); // generate prediction vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize); if (mbmi->mb_skip_coeff) { vp9_reset_sb_tokens_context(xd, bsize); } else { // re-initialize macroblock dequantizer before detokenization if (xd->segmentation_enabled) mb_init_dequantizer(pc, xd); // dequantization and idct eobtotal = vp9_decode_tokens(pbi, r, bsize); if (eobtotal == 0) { // skip loopfilter for (n = 0; n < bw * bh; n++) { const int x_idx = n & (bw - 1), y_idx = n >> bwl; if (mi_col + x_idx < pc->mi_cols && mi_row + y_idx < pc->mi_rows) mi[y_idx * mis + x_idx].mbmi.mb_skip_coeff = 1; } } else { foreach_transformed_block(xd, bsize, decode_block, xd); } }