static __inline void stuff1st_order_buv ( const BLOCKD *const b, TOKENEXTRA **tp, const int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */ const FRAME_TYPE frametype, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, VP8_COMP *cpi ) { int pt; /* near block/prev token context index */ TOKENEXTRA *t = *tp; /* store tokens starting here */ VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); (void) frametype; (void) type; (void) b; t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt]; t->section = 13; t->skip_eob_node = 0; ++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN]; ++t; *tp = t; pt = 0; /* 0 <-> all coeff data is zero */ *a = *l = pt; }
static void tokenize2nd_order_b ( const BLOCKD *const b, TOKENEXTRA **tp, const int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */ const FRAME_TYPE frametype, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, VP8_COMP *cpi ) { int pt; /* near block/prev token context index */ int c = 0; /* start at DC */ const int eob = b->eob; /* one beyond last nonzero coeff */ TOKENEXTRA *t = *tp; /* store tokens starting here */ int x; const short *qcoeff_ptr = b->qcoeff; VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); do { const int band = vp8_coef_bands[c]; if (c < eob) { int rc = vp8_default_zig_zag1d[c]; const int v = qcoeff_ptr[rc]; assert(-DCT_MAX_VALUE <= v && v < (DCT_MAX_VALUE)); t->Extra = vp8_dct_value_tokens_ptr[v].Extra; x = vp8_dct_value_tokens_ptr[v].Token; } else x = DCT_EOB_TOKEN; t->Token = x; t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt]; t->section = frametype * BLOCK_TYPES * 2 + 2 * type + (c == 0); t->skip_eob_node = pt == 0 && ((band > 0 && type > 0) || (band > 1 && type == 0)); ++cpi->coef_counts [type] [band] [pt] [x]; } while (pt = vp8_prev_token_class[x], ++t, c < eob && ++c < 16); *tp = t; pt = (c != !type); /* 0 <-> all coeff data is zero */ *a = *l = pt; }
static void stuff1st_order_buv ( TOKENEXTRA **tp, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, VP8_COMP *cpi ) { int pt; /* near block/prev token context index */ TOKENEXTRA *t = *tp; /* store tokens starting here */ VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN]; ++t; *tp = t; pt = 0; /* 0 <-> all coeff data is zero */ *a = *l = pt; }
static void tokenize2nd_order_b ( MACROBLOCKD *x, TOKENEXTRA **tp, VP8_COMP *cpi ) { int pt; /* near block/prev token context index */ int c; /* start at DC */ TOKENEXTRA *t = *tp;/* store tokens starting here */ const BLOCKD *b; const short *qcoeff_ptr; ENTROPY_CONTEXT * a; ENTROPY_CONTEXT * l; int band, rc, v, token; int eob; b = x->block + 24; qcoeff_ptr = b->qcoeff; a = (ENTROPY_CONTEXT *)x->above_context + 8; l = (ENTROPY_CONTEXT *)x->left_context + 8; eob = x->eobs[24]; VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); if(!eob) { /* c = band for this case */ t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [1] [0] [pt] [DCT_EOB_TOKEN]; t++; *tp = t; *a = *l = 0; return; } v = qcoeff_ptr[0]; t->Extra = vp8_dct_value_tokens_ptr[v].Extra; token = vp8_dct_value_tokens_ptr[v].Token; t->Token = token; t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [1] [0] [pt] [token]; pt = vp8_prev_token_class[token]; t++; c = 1; for (; c < eob; c++) { rc = vp8_default_zig_zag1d[c]; band = vp8_coef_bands[c]; v = qcoeff_ptr[rc]; t->Extra = vp8_dct_value_tokens_ptr[v].Extra; token = vp8_dct_value_tokens_ptr[v].Token; t->Token = token; t->context_tree = cpi->common.fc.coef_probs [1] [band] [pt]; t->skip_eob_node = ((pt == 0)); ++cpi->coef_counts [1] [band] [pt] [token]; pt = vp8_prev_token_class[token]; t++; } if (c < 16) { band = vp8_coef_bands[c]; t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [1] [band] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [1] [band] [pt] [DCT_EOB_TOKEN]; t++; } *tp = t; *a = *l = 1; }
static void tokenize1st_order_b ( MACROBLOCKD *x, TOKENEXTRA **tp, int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */ VP8_COMP *cpi ) { unsigned int block; const BLOCKD *b; int pt; /* near block/prev token context index */ int c; int token; TOKENEXTRA *t = *tp;/* store tokens starting here */ const short *qcoeff_ptr; ENTROPY_CONTEXT * a; ENTROPY_CONTEXT * l; int band, rc, v; int tmp1, tmp2; b = x->block; /* Luma */ for (block = 0; block < 16; block++, b++) { tmp1 = vp8_block2above[block]; tmp2 = vp8_block2left[block]; qcoeff_ptr = b->qcoeff; a = (ENTROPY_CONTEXT *)x->above_context + tmp1; l = (ENTROPY_CONTEXT *)x->left_context + tmp2; VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); c = type ? 0 : 1; if(c >= *b->eob) { /* c = band for this case */ t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [type] [c] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [type] [c] [pt] [DCT_EOB_TOKEN]; t++; *tp = t; *a = *l = 0; continue; } v = qcoeff_ptr[c]; t->Extra = vp8_dct_value_tokens_ptr[v].Extra; token = vp8_dct_value_tokens_ptr[v].Token; t->Token = token; t->context_tree = cpi->common.fc.coef_probs [type] [c] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [type] [c] [pt] [token]; pt = vp8_prev_token_class[token]; t++; c++; for (; c < *b->eob; c++) { rc = vp8_default_zig_zag1d[c]; band = vp8_coef_bands[c]; v = qcoeff_ptr[rc]; t->Extra = vp8_dct_value_tokens_ptr[v].Extra; token = vp8_dct_value_tokens_ptr[v].Token; t->Token = token; t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt]; t->skip_eob_node = (pt == 0); ++cpi->coef_counts [type] [band] [pt] [token]; pt = vp8_prev_token_class[token]; t++; } if (c < 16) { band = vp8_coef_bands[c]; t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [type] [band] [pt] [DCT_EOB_TOKEN]; t++; } *tp = t; *a = *l = 1; } /* Chroma */ for (block = 16; block < 24; block++, b++) { tmp1 = vp8_block2above[block]; tmp2 = vp8_block2left[block]; qcoeff_ptr = b->qcoeff; a = (ENTROPY_CONTEXT *)x->above_context + tmp1; l = (ENTROPY_CONTEXT *)x->left_context + tmp2; VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); if(!(*b->eob)) { /* c = band for this case */ t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [2] [0] [pt] [DCT_EOB_TOKEN]; t++; *tp = t; *a = *l = 0; continue; } v = qcoeff_ptr[0]; t->Extra = vp8_dct_value_tokens_ptr[v].Extra; token = vp8_dct_value_tokens_ptr[v].Token; t->Token = token; t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [2] [0] [pt] [token]; pt = vp8_prev_token_class[token]; t++; c = 1; for (; c < *b->eob; c++) { rc = vp8_default_zig_zag1d[c]; band = vp8_coef_bands[c]; v = qcoeff_ptr[rc]; t->Extra = vp8_dct_value_tokens_ptr[v].Extra; token = vp8_dct_value_tokens_ptr[v].Token; t->Token = token; t->context_tree = cpi->common.fc.coef_probs [2] [band] [pt]; t->skip_eob_node = (pt == 0); ++cpi->coef_counts [2] [band] [pt] [token]; pt = vp8_prev_token_class[token]; t++; } if (c < 16) { band = vp8_coef_bands[c]; t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [2] [band] [pt]; t->skip_eob_node = 0; ++cpi->coef_counts [2] [band] [pt] [DCT_EOB_TOKEN]; t++; } *tp = t; *a = *l = 1; } }
int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x) { ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)x->above_context; ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)x->left_context; const FRAME_CONTEXT * const fc = &dx->common.fc; BOOL_DECODER *bc = x->current_bc; char *eobs = x->eobs; ENTROPY_CONTEXT *a; ENTROPY_CONTEXT *l; int i; int eobtotal = 0; register int count; const BOOL_DATA *bufptr; const BOOL_DATA *bufend; register unsigned int range; VP8_BD_VALUE value; const int *scan; register unsigned int shift; UINT32 split; VP8_BD_VALUE bigsplit; INT16 *qcoeff_ptr; const vp8_prob *coef_probs; int type; int stop; INT16 val, bits_count; INT16 c; INT16 v; const vp8_prob *Prob; type = 3; i = 0; stop = 16; scan = vp8_default_zig_zag1d; qcoeff_ptr = &x->qcoeff[0]; if (x->mode_info_context->mbmi.mode != B_PRED && x->mode_info_context->mbmi.mode != SPLITMV) { i = 24; stop = 24; type = 1; qcoeff_ptr += 24*16; eobtotal -= 16; } bufend = bc->user_buffer_end; bufptr = bc->user_buffer; value = bc->value; count = bc->count; range = bc->range; coef_probs = fc->coef_probs [type] [ 0 ] [0]; BLOCK_LOOP: a = A + vp8_block2above[i]; l = L + vp8_block2left[i]; c = (INT16)(!type); /*Dest = ((A)!=0) + ((B)!=0);*/ VP8_COMBINEENTROPYCONTEXTS(v, *a, *l); Prob = coef_probs; Prob += v * ENTROPY_NODES; DO_WHILE: Prob += coef_bands_x[c]; DECODE_AND_BRANCH_IF_ZERO(Prob[EOB_CONTEXT_NODE], BLOCK_FINISHED); CHECK_0_: DECODE_AND_LOOP_IF_ZERO(Prob[ZERO_CONTEXT_NODE], CHECK_0_); DECODE_AND_BRANCH_IF_ZERO(Prob[ONE_CONTEXT_NODE], ONE_CONTEXT_NODE_0_); DECODE_AND_BRANCH_IF_ZERO(Prob[LOW_VAL_CONTEXT_NODE], LOW_VAL_CONTEXT_NODE_0_); DECODE_AND_BRANCH_IF_ZERO(Prob[HIGH_LOW_CONTEXT_NODE], HIGH_LOW_CONTEXT_NODE_0_); DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_THREEFOUR_CONTEXT_NODE], CAT_THREEFOUR_CONTEXT_NODE_0_); DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_FIVE_CONTEXT_NODE], CAT_FIVE_CONTEXT_NODE_0_); val = CAT6_MIN_VAL; bits_count = 10; do { DECODE_EXTRABIT_AND_ADJUST_VAL(cat6_prob[bits_count], bits_count); bits_count -- ; } while (bits_count >= 0); DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); CAT_FIVE_CONTEXT_NODE_0_: val = CAT5_MIN_VAL; DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB4, 4); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB3, 3); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB2, 2); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB1, 1); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT5_PROB0, 0); DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); CAT_THREEFOUR_CONTEXT_NODE_0_: DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_THREE_CONTEXT_NODE], CAT_THREE_CONTEXT_NODE_0_); val = CAT4_MIN_VAL; DECODE_EXTRABIT_AND_ADJUST_VAL(CAT4_PROB3, 3); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT4_PROB2, 2); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT4_PROB1, 1); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT4_PROB0, 0); DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); CAT_THREE_CONTEXT_NODE_0_: val = CAT3_MIN_VAL; DECODE_EXTRABIT_AND_ADJUST_VAL(CAT3_PROB2, 2); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT3_PROB1, 1); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT3_PROB0, 0); DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); HIGH_LOW_CONTEXT_NODE_0_: DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_ONE_CONTEXT_NODE], CAT_ONE_CONTEXT_NODE_0_); val = CAT2_MIN_VAL; DECODE_EXTRABIT_AND_ADJUST_VAL(CAT2_PROB1, 1); DECODE_EXTRABIT_AND_ADJUST_VAL(CAT2_PROB0, 0); DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); CAT_ONE_CONTEXT_NODE_0_: val = CAT1_MIN_VAL; DECODE_EXTRABIT_AND_ADJUST_VAL(CAT1_PROB0, 0); DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); LOW_VAL_CONTEXT_NODE_0_: DECODE_AND_BRANCH_IF_ZERO(Prob[TWO_CONTEXT_NODE], TWO_CONTEXT_NODE_0_); DECODE_AND_BRANCH_IF_ZERO(Prob[THREE_CONTEXT_NODE], THREE_CONTEXT_NODE_0_); DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(4); THREE_CONTEXT_NODE_0_: DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(3); TWO_CONTEXT_NODE_0_: DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(2); ONE_CONTEXT_NODE_0_: DECODE_AND_APPLYSIGN(1); Prob = coef_probs + ENTROPY_NODES; if (c < 15) { qcoeff_ptr [ scan[c] ] = (INT16) v; ++c; goto DO_WHILE; } qcoeff_ptr [ 15 ] = (INT16) v; BLOCK_FINISHED: *a = *l = ((eobs[i] = c) != !type); /* any nonzero data? */ eobtotal += c; qcoeff_ptr += 16; i++; if (i < stop) goto BLOCK_LOOP; if (i == 25) { type = 0; i = 0; stop = 16; coef_probs = fc->coef_probs [type] [ 0 ] [0]; qcoeff_ptr -= (24*16 + 16); goto BLOCK_LOOP; } if (i == 16) { type = 2; coef_probs = fc->coef_probs [type] [ 0 ] [0]; stop = 24; goto BLOCK_LOOP; } FILL bc->user_buffer = bufptr; bc->value = value; bc->count = count; bc->range = range; return eobtotal; }