summaryrefslogtreecommitdiff
path: root/vp8/encoder/tokenize.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/encoder/tokenize.c')
-rw-r--r--vp8/encoder/tokenize.c327
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 {