diff options
Diffstat (limited to 'vp8/encoder/tokenize.c')
-rw-r--r-- | vp8/encoder/tokenize.c | 327 |
1 files changed, 261 insertions, 66 deletions
diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c index 81ba6f2be..dac18c6db 100644 --- a/vp8/encoder/tokenize.c +++ b/vp8/encoder/tokenize.c @@ -26,17 +26,23 @@ #ifdef ENTROPY_STATS INT64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; INT64 context_counters_8x8[BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; -extern unsigned int tree_update_hist [BLOCK_TYPES] -[COEF_BANDS] -[PREV_COEF_CONTEXTS] -[ENTROPY_NODES][2]; -extern unsigned int tree_update_hist_8x8 [BLOCK_TYPES_8X8] -[COEF_BANDS] -[PREV_COEF_CONTEXTS] -[ENTROPY_NODES] [2]; +#if CONFIG_TX16X16 +INT64 context_counters_16x16[BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; +#endif +extern unsigned int tree_update_hist[BLOCK_TYPES][COEF_BANDS] + [PREV_COEF_CONTEXTS][ENTROPY_NODES][2]; +extern unsigned int tree_update_hist_8x8[BLOCK_TYPES_8X8][COEF_BANDS] + [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2]; +#if CONFIG_TX16X16 +extern unsigned int tree_update_hist_16x16[BLOCK_TYPES_16X16][COEF_BANDS] + [PREV_COEF_CONTEXTS][ENTROPY_NODES] [2]; +#endif #endif void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t); void vp8_stuff_mb_8x8(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t); +#if CONFIG_TX16X16 +void vp8_stuff_mb_16x16(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t); +#endif void vp8_fix_contexts(MACROBLOCKD *x); static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2]; @@ -103,6 +109,54 @@ static void fill_value_tokens() { vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; } +#if CONFIG_TX16X16 +static void tokenize1st_order_b_16x16(MACROBLOCKD *xd, const BLOCKD *const b, TOKENEXTRA **tp, + const int type, 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 unless type 0 */ + 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; + + int seg_eob = 256; + int segment_id = xd->mode_info_context->mbmi.segment_id; + + if (segfeature_active(xd, segment_id, SEG_LVL_EOB)) + seg_eob = get_segdata(xd, segment_id, SEG_LVL_EOB); + + VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); + + do { + const int band = vp8_coef_bands_16x16[c]; + int v; + + x = DCT_EOB_TOKEN; + if (c < eob) { + int rc = vp8_default_zig_zag1d_16x16[c]; + 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; + } + + t->Token = x; + t->context_tree = cpi->common.fc.coef_probs_16x16[type][band][pt]; + + t->skip_eob_node = pt == 0 && ((band > 0 && type > 0) || (band > 1 && type == 0)); + + ++cpi->coef_counts_16x16[type][band][pt][x]; + } while (pt = vp8_prev_token_class[x], ++t, c < eob && ++c < seg_eob); + + *tp = t; + pt = (c != !type); /* 0 <-> all coeff data is zero */ + *a = *l = pt; +} +#endif + static void tokenize2nd_order_b_8x8 ( MACROBLOCKD *xd, @@ -170,12 +224,8 @@ static void tokenize2nd_order_b_8x8 } -static void tokenize2nd_order_b -( - MACROBLOCKD *xd, - TOKENEXTRA **tp, - VP8_COMP *cpi -) { +static void tokenize2nd_order_b(MACROBLOCKD *xd, 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 */ @@ -188,9 +238,8 @@ static void tokenize2nd_order_b int seg_eob = 16; int segment_id = xd->mode_info_context->mbmi.segment_id; - if (segfeature_active(xd, segment_id, SEG_LVL_EOB)) { + if (segfeature_active(xd, segment_id, SEG_LVL_EOB)) seg_eob = get_segdata(xd, segment_id, SEG_LVL_EOB); - } b = xd->block + 24; qcoeff_ptr = b->qcoeff; @@ -542,14 +591,10 @@ static void tokenize1st_order_b unsigned int block; const BLOCKD *b; int pt; /* near block/prev token context index */ - int c; - int token; + int band, rc, v, c, 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; + ENTROPY_CONTEXT *a, *l; int seg_eob = 16; int segment_id = xd->mode_info_context->mbmi.segment_id; @@ -561,11 +606,9 @@ static void tokenize1st_order_b b = xd->block; /* Luma */ for (block = 0; block < 16; block++, b++) { - tmp1 = vp8_block2above[block]; - tmp2 = vp8_block2left[block]; qcoeff_ptr = b->qcoeff; - a = (ENTROPY_CONTEXT *)xd->above_context + tmp1; - l = (ENTROPY_CONTEXT *)xd->left_context + tmp2; + a = (ENTROPY_CONTEXT *)xd->above_context + vp8_block2above[block]; + l = (ENTROPY_CONTEXT *)xd->left_context + vp8_block2left[block]; VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); c = type ? 0 : 1; @@ -609,11 +652,9 @@ static void tokenize1st_order_b } /* Chroma */ for (block = 16; block < 24; block++, b++) { - tmp1 = vp8_block2above[block]; - tmp2 = vp8_block2left[block]; qcoeff_ptr = b->qcoeff; - a = (ENTROPY_CONTEXT *)xd->above_context + tmp1; - l = (ENTROPY_CONTEXT *)xd->left_context + tmp2; + a = (ENTROPY_CONTEXT *)xd->above_context + vp8_block2above[block]; + l = (ENTROPY_CONTEXT *)xd->left_context + vp8_block2left[block]; VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); @@ -701,6 +742,20 @@ int mb_is_skippable_8x8(MACROBLOCKD *x) { return (mby_is_skippable_8x8(x) & mbuv_is_skippable_8x8(x)); } +#if CONFIG_TX16X16 +int mby_is_skippable_16x16(MACROBLOCKD *x) { + int skip = 1; + //skip &= (x->block[0].eob < 2); // I think this should be commented? No second order == DC must be coded + //skip &= (x->block[0].eob < 1); + //skip &= (!x->block[24].eob); + skip &= !x->block[0].eob; + return skip; +} + +int mb_is_skippable_16x16(MACROBLOCKD *x) { + return (mby_is_skippable_16x16(x) & mbuv_is_skippable_8x8(x)); +} +#endif void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) { int plane_type; @@ -730,16 +785,32 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) { has_y2_block = (x->mode_info_context->mbmi.mode != B_PRED && x->mode_info_context->mbmi.mode != I8X8_PRED && x->mode_info_context->mbmi.mode != SPLITMV); +#if CONFIG_TX16X16 + if (tx_type == TX_16X16) has_y2_block = 0; // Because of inter frames +#endif - x->mode_info_context->mbmi.mb_skip_coeff = - ((tx_type == TX_8X8) ? - mb_is_skippable_8x8(x) : - mb_is_skippable(x, has_y2_block)); + switch (tx_type) { +#if CONFIG_TX16X16 + case TX_16X16: + x->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(x); + break; +#endif + case TX_8X8: + x->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_8x8(x); + break; + default: + x->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable(x, has_y2_block); + break; + } if (x->mode_info_context->mbmi.mb_skip_coeff) { cpi->skip_true_count[mb_skip_context] += skip_inc; - if (!cpi->common.mb_no_coeff_skip) { +#if CONFIG_TX16X16 + if (tx_type == TX_16X16) + vp8_stuff_mb_16x16(cpi, x, t); + else +#endif if (tx_type == TX_8X8) vp8_stuff_mb_8x8(cpi, x, t); else @@ -766,9 +837,28 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) { tokenize2nd_order_b(x, t, cpi); plane_type = 0; - } +#if CONFIG_TX16X16 + if (tx_type == TX_16X16) { + ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context; + ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context; + tokenize1st_order_b_16x16(x, x->block, t, 3, x->frame_type, A, L, cpi); + for (b = 1; b < 16; b++) { + *(A + vp8_block2above[b]) = *(A); + *(L + vp8_block2left[b] ) = *(L); + } + for (b = 16; b < 24; b += 4) { + tokenize1st_order_b_8x8(x, x->block + b, t, 2, x->frame_type, + A + vp8_block2above_8x8[b], L + vp8_block2left_8x8[b], cpi); + *(A + vp8_block2above_8x8[b]+1) = *(A + vp8_block2above_8x8[b]); + *(L + vp8_block2left_8x8[b]+1 ) = *(L + vp8_block2left_8x8[b]); + } + vpx_memset(&A[8], 0, sizeof(A[8])); + vpx_memset(&L[8], 0, sizeof(L[8])); + } + else +#endif if (tx_type == TX_8X8) { ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)x->above_context; ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)x->left_context; @@ -827,15 +917,20 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) { #ifdef ENTROPY_STATS - void init_context_counters(void) { FILE *f = fopen("context.bin", "rb"); if (!f) { vpx_memset(context_counters, 0, sizeof(context_counters)); vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8)); +#if CONFIG_TX16X16 + vpx_memset(context_counters_16x16, 0, sizeof(context_counters_16x16)); +#endif } else { fread(context_counters, sizeof(context_counters), 1, f); fread(context_counters_8x8, sizeof(context_counters_8x8), 1, f); +#if CONFIG_TX16X16 + fread(context_counters_16x16, sizeof(context_counters_16x16), 1, f); +#endif fclose(f); } @@ -843,15 +938,20 @@ void init_context_counters(void) { if (!f) { vpx_memset(tree_update_hist, 0, sizeof(tree_update_hist)); vpx_memset(tree_update_hist_8x8, 0, sizeof(tree_update_hist_8x8)); +#if CONFIG_TX16X16 + vpx_memset(tree_update_hist_16x16, 0, sizeof(tree_update_hist_16x16)); +#endif } else { fread(tree_update_hist, sizeof(tree_update_hist), 1, f); fread(tree_update_hist_8x8, sizeof(tree_update_hist_8x8), 1, f); +#if CONFIG_TX16X16 + fread(tree_update_hist_16x16, sizeof(tree_update_hist_16x16), 1, f); +#endif fclose(f); } } void print_context_counters() { - int type, band, pt, t; FILE *f = fopen("context.c", "w"); @@ -892,7 +992,6 @@ void print_context_counters() { fprintf(f, "static const unsigned int\nvp8_default_coef_counts_8x8" "[BLOCK_TYPES_8X8] [COEF_BANDS]" "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {"); - type = 0; do { fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); @@ -921,26 +1020,54 @@ void print_context_counters() { fprintf(f, "\n }"); } while (++type < BLOCK_TYPES_8X8); + fprintf(f, "\n};\n"); +#if CONFIG_TX16X16 + fprintf(f, "static const unsigned int\nvp8_default_coef_counts_16x16" + "[BLOCK_TYPES_16X16] [COEF_BANDS]" + "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {"); + type = 0; + do { + fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); + band = 0; + do { + fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); + pt = 0; + do { + fprintf(f, "%s\n {", Comma(pt)); + t = 0; + do { + const INT64 x = context_counters_16x16 [type] [band] [pt] [t]; + const int y = (int) x; + + assert(x == (INT64) y); /* no overflow handling yet */ + fprintf(f, "%s %d", Comma(t), y); + + } while (++t < MAX_ENTROPY_TOKENS); + + fprintf(f, "}"); + } while (++pt < PREV_COEF_CONTEXTS); + + fprintf(f, "\n }"); + + } while (++band < COEF_BANDS); + + fprintf(f, "\n }"); + } while (++type < BLOCK_TYPES_16X16); fprintf(f, "\n};\n"); +#endif fprintf(f, "static const vp8_prob\n" "vp8_default_coef_probs[BLOCK_TYPES] [COEF_BANDS] \n" "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {"); type = 0; - do { fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); - band = 0; - do { fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); - pt = 0; - do { - unsigned int branch_ct [ENTROPY_NODES] [2]; unsigned int coef_counts[MAX_ENTROPY_TOKENS]; vp8_prob coef_probs[ENTROPY_NODES]; @@ -952,7 +1079,6 @@ void print_context_counters() { fprintf(f, "%s\n {", Comma(pt)); t = 0; - do { fprintf(f, "%s %d", Comma(t), coef_probs[t]); @@ -960,11 +1086,8 @@ void print_context_counters() { fprintf(f, "}"); } while (++pt < PREV_COEF_CONTEXTS); - fprintf(f, "\n }"); - } while (++band < COEF_BANDS); - fprintf(f, "\n }"); } while (++type < BLOCK_TYPES); fprintf(f, "\n};\n"); @@ -973,19 +1096,13 @@ void print_context_counters() { "vp8_default_coef_probs_8x8[BLOCK_TYPES_8X8] [COEF_BANDS]\n" "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {"); type = 0; - do { fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); - band = 0; - do { fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); - pt = 0; - do { - unsigned int branch_ct [ENTROPY_NODES] [2]; unsigned int coef_counts[MAX_ENTROPY_TOKENS]; vp8_prob coef_probs[ENTROPY_NODES]; @@ -994,34 +1111,65 @@ void print_context_counters() { vp8_tree_probs_from_distribution( MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree, coef_probs, branch_ct, coef_counts, 256, 1); - fprintf(f, "%s\n {", Comma(pt)); - t = 0; + t = 0; do { fprintf(f, "%s %d", Comma(t), coef_probs[t]); - } while (++t < ENTROPY_NODES); - fprintf(f, "}"); } while (++pt < PREV_COEF_CONTEXTS); - fprintf(f, "\n }"); - } while (++band < COEF_BANDS); - fprintf(f, "\n }"); } while (++type < BLOCK_TYPES_8X8); fprintf(f, "\n};\n"); +#if CONFIG_TX16X16 + fprintf(f, "static const vp8_prob\n" + "vp8_default_coef_probs_16x16[BLOCK_TYPES_16X16] [COEF_BANDS]\n" + "[PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {"); + type = 0; + do { + fprintf(f, "%s\n { /* block Type %d */", Comma(type), type); + band = 0; + do { + fprintf(f, "%s\n { /* Coeff Band %d */", Comma(band), band); + pt = 0; + do { + unsigned int branch_ct [ENTROPY_NODES] [2]; + unsigned int coef_counts[MAX_ENTROPY_TOKENS]; + vp8_prob coef_probs[ENTROPY_NODES]; + for (t = 0; t < MAX_ENTROPY_TOKENS; ++t) + coef_counts[t] = context_counters_16x16[type] [band] [pt] [t]; + vp8_tree_probs_from_distribution( + MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree, + coef_probs, branch_ct, coef_counts, 256, 1); + fprintf(f, "%s\n {", Comma(pt)); + + t = 0; + do { + fprintf(f, "%s %d", Comma(t), coef_probs[t]); + } while (++t < ENTROPY_NODES); + fprintf(f, "}"); + } while (++pt < PREV_COEF_CONTEXTS); + fprintf(f, "\n }"); + } while (++band < COEF_BANDS); + fprintf(f, "\n }"); + } while (++type < BLOCK_TYPES_16X16); + fprintf(f, "\n};\n"); +#endif + fclose(f); f = fopen("context.bin", "wb"); fwrite(context_counters, sizeof(context_counters), 1, f); fwrite(context_counters_8x8, sizeof(context_counters_8x8), 1, f); +#if CONFIG_TX16X16 + fwrite(context_counters_16x16, sizeof(context_counters_16x16), 1, f); +#endif fclose(f); } - #endif @@ -1151,6 +1299,50 @@ void vp8_stuff_mb_8x8(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) { } +#if CONFIG_TX16X16 +static __inline +void stuff1st_order_b_16x16(const BLOCKD *const b, TOKENEXTRA **tp, 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) b; + + t->Token = DCT_EOB_TOKEN; + t->context_tree = cpi->common.fc.coef_probs_16x16[3][1][pt]; + t->skip_eob_node = 0; + ++t; + *tp = t; + ++cpi->coef_counts_16x16[3][1][pt][DCT_EOB_TOKEN]; + pt = 0; /* 0 <-> all coeff data is zero */ + *a = *l = pt; +} + +void vp8_stuff_mb_16x16(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) { + ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context; + ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context; + int b, i; + + stuff1st_order_b_16x16(x->block, t, x->frame_type, A, L, cpi); + for (i = 1; i < 16; i++) { + *(A + vp8_block2above[i]) = *(A); + *(L + vp8_block2left[i]) = *(L); + } + for (b = 16; b < 24; b += 4) { + stuff1st_order_buv_8x8(x->block + b, t, 2, x->frame_type, + A + vp8_block2above[b], + L + vp8_block2left[b], + cpi); + *(A + vp8_block2above_8x8[b]+1) = *(A + vp8_block2above_8x8[b]); + *(L + vp8_block2left_8x8[b]+1 ) = *(L + vp8_block2left_8x8[b]); + } + vpx_memset(&A[8], 0, sizeof(A[8])); + vpx_memset(&L[8], 0, sizeof(L[8])); +} +#endif + static __inline void stuff2nd_order_b ( TOKENEXTRA **tp, @@ -1215,7 +1407,6 @@ void stuff1st_order_buv ++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN]; pt = 0; /* 0 <-> all coeff data is zero */ *a = *l = pt; - } void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) { @@ -1241,9 +1432,13 @@ void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) { } void vp8_fix_contexts(MACROBLOCKD *x) { /* Clear entropy contexts for Y2 blocks */ - if (x->mode_info_context->mbmi.mode != B_PRED + if ((x->mode_info_context->mbmi.mode != B_PRED && x->mode_info_context->mbmi.mode != I8X8_PRED - && x->mode_info_context->mbmi.mode != SPLITMV) { + && x->mode_info_context->mbmi.mode != SPLITMV) +#if CONFIG_TX16X16 + || x->mode_info_context->mbmi.txfm_size == TX_16X16 +#endif + ) { vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); } else { |