summaryrefslogtreecommitdiff
path: root/vp8/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/encoder')
-rw-r--r--vp8/encoder/bitstream.c303
-rw-r--r--vp8/encoder/block.h8
-rw-r--r--vp8/encoder/dct.c142
-rw-r--r--vp8/encoder/dct.h18
-rw-r--r--vp8/encoder/defaultcoefcounts.h179
-rw-r--r--vp8/encoder/encodeframe.c458
-rw-r--r--vp8/encoder/encodeintra.c122
-rw-r--r--vp8/encoder/encodemb.c678
-rw-r--r--vp8/encoder/encodemb.h12
-rw-r--r--vp8/encoder/ethreading.c18
-rw-r--r--vp8/encoder/firstpass.c2
-rw-r--r--vp8/encoder/generic/csystemdependent.c18
-rw-r--r--vp8/encoder/onyx_if.c214
-rw-r--r--vp8/encoder/onyx_int.h13
-rw-r--r--vp8/encoder/psnr.c2
-rw-r--r--vp8/encoder/quantize.c597
-rw-r--r--vp8/encoder/quantize.h32
-rw-r--r--vp8/encoder/ratectrl.c49
-rw-r--r--vp8/encoder/rdopt.c79
-rw-r--r--vp8/encoder/rdopt.h1
-rw-r--r--vp8/encoder/tokenize.c489
-rw-r--r--vp8/encoder/tokenize.h4
22 files changed, 3328 insertions, 110 deletions
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index cea8e1232..e65a7f9d4 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -24,7 +24,9 @@
#include "bitstream.h"
#include "defaultcoefcounts.h"
-
+#if CONFIG_SEGMENTATION
+static int segment_cost = 0;
+#endif
const int vp8cx_base_skip_false_prob[128] =
{
255, 255, 255, 255, 255, 255, 255, 255,
@@ -52,11 +54,19 @@ unsigned __int64 Sectionbits[500];
#ifdef ENTROPY_STATS
int intra_mode_stats[10][10][10];
static unsigned int tree_update_hist [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] [2];
+#if CONFIG_T8X8
+static unsigned int tree_update_hist_8x8 [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] [2];
+#endif
+
extern unsigned int active_section;
#endif
#ifdef MODE_STATS
int count_mb_seg[4] = { 0, 0, 0, 0 };
+#if CONFIG_SEGMENTATION
+int segment_modes_intra[MAX_MB_SEGMENTS] = { 0, 0, 0, 0 };
+int segment_modes_inter[MAX_MB_SEGMENTS] = { 0, 0, 0, 0 };
+#endif
#endif
@@ -813,24 +823,39 @@ static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi, const MACRO
case 0:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[1]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]);
+#endif
break;
case 1:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 1, x->mb_segment_tree_probs[1]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[1]);
+#endif
break;
case 2:
vp8_write(w, 1, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[2]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[2]);
+#endif
break;
case 3:
vp8_write(w, 1, x->mb_segment_tree_probs[0]);
vp8_write(w, 1, x->mb_segment_tree_probs[2]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[2]);
+#endif
break;
// TRAP.. This should not happen
default:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[1]);
+#if CONFIG_SEGMENTATION
+ segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]);
+#endif
break;
}
}
@@ -842,7 +867,13 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
VP8_COMMON *const pc = & cpi->common;
vp8_writer *const w = & cpi->bc;
const MV_CONTEXT *mvc = pc->fc.mvc;
-
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
+#if CONFIG_SEGMENTATION
+ int left_id, above_id;
+ int i;
+ int sum;
+ int index = 0;
+#endif
const int *const rfct = cpi->count_mb_ref_frame_usage;
const int rf_intra = rfct[INTRA_FRAME];
const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
@@ -899,7 +930,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
update_mbintra_mode_probs(cpi);
vp8_write_mvprobs(cpi);
-
+#if CONFIG_SEGMENTATION
+ vp8_write_bit(w, (xd->temporal_update) ? 1:0);
+#endif
while (++mb_row < pc->mb_rows)
{
int mb_col = -1;
@@ -910,7 +943,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
const MV_REFERENCE_FRAME rf = mi->ref_frame;
const MB_PREDICTION_MODE mode = mi->mode;
- MACROBLOCKD *xd = &cpi->mb.e_mbd;
+ //MACROBLOCKD *xd = &cpi->mb.e_mbd;
// Distance of Mb to the various image edges.
// These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units
@@ -918,13 +951,53 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
xd->mb_to_top_edge = -((mb_row * 16)) << 3;
xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
-
+#if CONFIG_SEGMENTATION
+ xd->up_available = (mb_row != 0);
+ xd->left_available = (mb_col != 0);
+#endif
#ifdef ENTROPY_STATS
active_section = 9;
#endif
+#ifdef MODE_STATS
+#if CONFIG_SEGMENTATION
+ segment_modes_inter[mi->segment_id]++;
+#endif
+#endif
if (cpi->mb.e_mbd.update_mb_segmentation_map)
+ {
+#if CONFIG_SEGMENTATION
+ if (xd->temporal_update)
+ {
+ sum = 0;
+ if (mb_col != 0)
+ sum += (m-1)->mbmi.segment_flag;
+ if (mb_row != 0)
+ sum += (m-pc->mb_cols)->mbmi.segment_flag;
+
+ if (m->mbmi.segment_flag == 0)
+ {
+ vp8_write(w,0,xd->mb_segment_tree_probs[3+sum]);
+ segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[3+sum]);
+ }
+ else
+ {
+ vp8_write(w,1,xd->mb_segment_tree_probs[3+sum]);
+ segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[3+sum]);
+ write_mb_features(w, mi, &cpi->mb.e_mbd);
+ cpi->segmentation_map[index] = mi->segment_id;
+ }
+ }
+ else
+ {
+ write_mb_features(w, mi, &cpi->mb.e_mbd);
+ cpi->segmentation_map[index] = mi->segment_id;
+ }
+ index++;
+#else
write_mb_features(w, mi, &cpi->mb.e_mbd);
+#endif
+ }
if (pc->mb_no_coeff_skip)
vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false);
@@ -1059,7 +1132,11 @@ static void write_kfmodes(VP8_COMP *cpi)
const VP8_COMMON *const c = & cpi->common;
/* const */
MODE_INFO *m = c->mi;
-
+#if CONFIG_SEGMENTATION
+ int left_id, above_id;
+ int i;
+ int index = 0;
+#endif
int mb_row = -1;
int prob_skip_false = 0;
@@ -1084,9 +1161,28 @@ static void write_kfmodes(VP8_COMP *cpi)
while (++mb_col < c->mb_cols)
{
const int ym = m->mbmi.mode;
+#if CONFIG_SEGMENTATION
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
+ xd->up_available = (mb_row != 0);
+ xd->left_available = (mb_col != 0);
+#endif
+#ifdef MODE_STATS
+#if CONFIG_SEGMENTATION
+ segment_modes_intra[m->mbmi.segment_id]++;
+#endif
+#endif
if (cpi->mb.e_mbd.update_mb_segmentation_map)
+ {
+#if CONFIG_SEGMENTATION
+
write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+ cpi->segmentation_map[index] = m->mbmi.segment_id;
+ index++;
+#else
+ write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+#endif
+ }
if (c->mb_no_coeff_skip)
vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
@@ -1315,6 +1411,7 @@ static int default_coef_context_savings(VP8_COMP *cpi)
int vp8_estimate_entropy_savings(VP8_COMP *cpi)
{
int savings = 0;
+ int i=0;
const int *const rfct = cpi->count_mb_ref_frame_usage;
const int rf_intra = rfct[INTRA_FRAME];
@@ -1379,6 +1476,65 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
savings += default_coef_context_savings(cpi);
+#if CONFIG_T8X8
+ i = 0;
+ do
+ {
+ int j = 0;
+
+ do
+ {
+ int k = 0;
+
+ do
+ {
+ /* at every context */
+
+ /* calc probs and branch cts for this frame only */
+ //vp8_prob new_p [ENTROPY_NODES];
+ //unsigned int branch_ct [ENTROPY_NODES] [2];
+
+ int t = 0; /* token/prob index */
+
+ vp8_tree_probs_from_distribution(
+ MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+ cpi->frame_coef_probs_8x8 [i][j][k], cpi->frame_branch_ct_8x8 [i][j][k], cpi->coef_counts_8x8 [i][j][k],
+ 256, 1
+ );
+
+ do
+ {
+ const unsigned int *ct = cpi->frame_branch_ct_8x8 [i][j][k][t];
+ const vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
+
+ const vp8_prob old = cpi->common.fc.coef_probs_8x8 [i][j][k][t];
+ const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
+
+ const int old_b = vp8_cost_branch(ct, old);
+ const int new_b = vp8_cost_branch(ct, newp);
+
+ const int update_b = 8 +
+ ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
+
+ const int s = old_b - new_b - update_b;
+
+ if (s > 0)
+ savings += s;
+
+
+ }
+ while (++t < MAX_ENTROPY_TOKENS - 1);
+
+
+ }
+ while (++k < PREV_COEF_CONTEXTS);
+ }
+ while (++j < COEF_BANDS);
+ }
+ while (++i < BLOCK_TYPES);
+#endif
+
+
return savings;
}
@@ -1505,6 +1661,92 @@ static void update_coef_probs(VP8_COMP *cpi)
}
while (++i < BLOCK_TYPES);
+#if CONFIG_T8X8
+ i = 0;
+ do
+ {
+ int j = 0;
+
+ do
+ {
+ int k = 0;
+
+ do
+ {
+ //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
+ /* at every context */
+
+ /* calc probs and branch cts for this frame only */
+ //vp8_prob new_p [ENTROPY_NODES];
+ //unsigned int branch_ct [ENTROPY_NODES] [2];
+
+ int t = 0; /* token/prob index */
+
+ //vp8_tree_probs_from_distribution(
+ // MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+ // new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
+ // 256, 1
+ // );
+
+ do
+ {
+ const unsigned int *ct = cpi->frame_branch_ct_8x8 [i][j][k][t];
+ const vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
+
+ vp8_prob *Pold = cpi->common.fc.coef_probs_8x8 [i][j][k] + t;
+ const vp8_prob old = *Pold;
+ const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
+
+ const int old_b = vp8_cost_branch(ct, old);
+ const int new_b = vp8_cost_branch(ct, newp);
+
+ const int update_b = 8 +
+ ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
+
+ const int s = old_b - new_b - update_b;
+ const int u = s > 0 ? 1 : 0;
+
+ vp8_write(w, u, upd);
+
+
+#ifdef ENTROPY_STATS
+ ++ tree_update_hist_8x8 [i][j][k][t] [u];
+#endif
+
+ if (u)
+ {
+ /* send/use new probability */
+
+ *Pold = newp;
+ vp8_write_literal(w, newp, 8);
+
+ savings += s;
+
+ }
+
+ }
+ while (++t < MAX_ENTROPY_TOKENS - 1);
+
+ /* Accum token counts for generation of default statistics */
+#ifdef ENTROPY_STATS
+ t = 0;
+
+ do
+ {
+ context_counters_8x8 [i][j][k][t] += cpi->coef_counts_8x8 [i][j][k][t];
+ }
+ while (++t < MAX_ENTROPY_TOKENS);
+
+#endif
+
+ }
+ while (++k < PREV_COEF_CONTEXTS);
+ }
+ while (++j < COEF_BANDS);
+ }
+ while (++i < BLOCK_TYPES);
+#endif
+
}
#ifdef PACKET_TESTING
FILE *vpxlogc = 0;
@@ -1585,8 +1827,9 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
}
else
vp8_start_encode(bc, cx_data);
-
-
+#if CONFIG_SEGMENTATION
+ xd->update_mb_segmentation_map = 1;
+#endif
// Signal whether or not Segmentation is enabled
vp8_write_bit(bc, (xd->segmentation_enabled) ? 1 : 0);
@@ -1636,8 +1879,12 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
if (xd->update_mb_segmentation_map)
{
+ #if CONFIG_SEGMENTATION
// Write the probs used to decode the segment id for each macro block.
+ for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+#else
for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+#endif
{
int Data = xd->mb_segment_tree_probs[i];
@@ -1909,6 +2156,46 @@ void print_tree_update_probs()
}
fprintf(f, "};\n");
+
+#if CONFIG_T8X8
+ fprintf(f, "const vp8_prob tree_update_probs_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {\n");
+
+ for (i = 0; i < BLOCK_TYPES; i++)
+ {
+ fprintf(f, " { \n");
+
+ for (j = 0; j < COEF_BANDS; j++)
+ {
+ fprintf(f, " {\n");
+
+ for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+ {
+ fprintf(f, " {");
+
+ for (l = 0; l < MAX_ENTROPY_TOKENS - 1; l++)
+ {
+ Sum = tree_update_hist_8x8[i][j][k][l][0] + tree_update_hist_8x8[i][j][k][l][1];
+
+ if (Sum > 0)
+ {
+ if (((tree_update_hist_8x8[i][j][k][l][0] * 255) / Sum) > 0)
+ fprintf(f, "%3ld, ", (tree_update_hist_8x8[i][j][k][l][0] * 255) / Sum);
+ else
+ fprintf(f, "%3ld, ", 1);
+ }
+ else
+ fprintf(f, "%3ld, ", 128);
+ }
+
+ fprintf(f, "},\n");
+ }
+
+ fprintf(f, " },\n");
+ }
+
+ fprintf(f, " },\n");
+ }
+#endif
fclose(f);
}
#endif
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
index 0d14b545c..8a95db798 100644
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -46,7 +46,7 @@ typedef struct
int src;
int src_stride;
-// MV enc_mv;
+ // MV enc_mv;
int force_empty;
} BLOCK;
@@ -126,6 +126,12 @@ typedef struct
void (*short_walsh4x4)(short *input, short *output, int pitch);
void (*quantize_b)(BLOCK *b, BLOCKD *d);
void (*quantize_b_pair)(BLOCK *b1, BLOCK *b2, BLOCKD *d0, BLOCKD *d1);
+ #if CONFIG_T8X8
+ void (*vp8_short_fdct8x8)(short *input, short *output, int pitch);
+ void (*short_fhaar2x2)(short *input, short *output, int pitch);
+ void (*quantize_b_8x8)(BLOCK *b, BLOCKD *d);
+ void (*quantize_b_2x2)(BLOCK *b, BLOCKD *d);
+#endif
} MACROBLOCK;
diff --git a/vp8/encoder/dct.c b/vp8/encoder/dct.c
index b5a11ae34..fd4c62cd4 100644
--- a/vp8/encoder/dct.c
+++ b/vp8/encoder/dct.c
@@ -10,7 +10,123 @@
#include <math.h>
+#include "vpx_ports/config.h"
+
+
+
+
+#if CONFIG_T8X8
+void vp8_short_fdct8x8_c(short *block, short *coefs, int pitch)
+{
+ int j1, i, j, k;
+ float b[8];
+ float b1[8];
+ float d[8][8];
+ float f0 = (float) .7071068;
+ float f1 = (float) .4903926;
+ float f2 = (float) .4619398;
+ float f3 = (float) .4157348;
+ float f4 = (float) .3535534;
+ float f5 = (float) .2777851;
+ float f6 = (float) .1913417;
+ float f7 = (float) .0975452;
+ pitch = pitch / 2;
+ for (i = 0, k = 0; i < 8; i++, k += pitch)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ b[j] = (float)( block[k + j]<<1);
+ }
+ /* Horizontal transform */
+ for (j = 0; j < 4; j++)
+ {
+ j1 = 7 - j;
+ b1[j] = b[j] + b[j1];
+ b1[j1] = b[j] - b[j1];
+ }
+ b[0] = b1[0] + b1[3];
+ b[1] = b1[1] + b1[2];
+ b[2] = b1[1] - b1[2];
+ b[3] = b1[0] - b1[3];
+ b[4] = b1[4];
+ b[5] = (b1[6] - b1[5]) * f0;
+ b[6] = (b1[6] + b1[5]) * f0;
+ b[7] = b1[7];
+ d[i][0] = (b[0] + b[1]) * f4;
+ d[i][4] = (b[0] - b[1]) * f4;
+ d[i][2] = b[2] * f6 + b[3] * f2;
+ d[i][6] = b[3] * f6 - b[2] * f2;
+ b1[4] = b[4] + b[5];
+ b1[7] = b[7] + b[6];
+ b1[5] = b[4] - b[5];
+ b1[6] = b[7] - b[6];
+ d[i][1] = b1[4] * f7 + b1[7] * f1;
+ d[i][5] = b1[5] * f3 + b1[6] * f5;
+ d[i][7] = b1[7] * f7 - b1[4] * f1;
+ d[i][3] = b1[6] * f3 - b1[5] * f5;
+ }
+ /* Vertical transform */
+ for (i = 0; i < 8; i++)
+ {
+ for (j = 0; j < 4; j++)
+ {
+ j1 = 7 - j;
+ b1[j] = d[j][i] + d[j1][i];
+ b1[j1] = d[j][i] - d[j1][i];
+ }
+ b[0] = b1[0] + b1[3];
+ b[1] = b1[1] + b1[2];
+ b[2] = b1[1] - b1[2];
+ b[3] = b1[0] - b1[3];
+ b[4] = b1[4];
+ b[5] = (b1[6] - b1[5]) * f0;
+ b[6] = (b1[6] + b1[5]) * f0;
+ b[7] = b1[7];
+ d[0][i] = (b[0] + b[1]) * f4;
+ d[4][i] = (b[0] - b[1]) * f4;
+ d[2][i] = b[2] * f6 + b[3] * f2;
+ d[6][i] = b[3] * f6 - b[2] * f2;
+ b1[4] = b[4] + b[5];
+ b1[7] = b[7] + b[6];
+ b1[5] = b[4] - b[5];
+ b1[6] = b[7] - b[6];
+ d[1][i] = b1[4] * f7 + b1[7] * f1;
+ d[5][i] = b1[5] * f3 + b1[6] * f5;
+ d[7][i] = b1[7] * f7 - b1[4] * f1;
+ d[3][i] = b1[6] * f3 - b1[5] * f5;
+ }
+ for (i = 0; i < 8; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ *(coefs + j + i * 8) = (short) floor(d[i][j] +0.5);
+ }
+ }
+ return;
+}
+
+
+
+void vp8_short_fhaar2x2_c(short *input, short *output, int pitch) //pitch = 8
+{
+ /* [1 1 ; 1 -1] orthogonal transform */
+ /* use position: 0,1, 4, 8 */
+ int i;
+ short *ip1 = input;
+ short *op1 = output;
+ for (i = 0; i < 16; i++)
+ {
+ op1[i] = 0;
+ }
+
+ op1[0]=ip1[0] + ip1[1] + ip1[4] + ip1[8];
+ op1[1]=ip1[0] - ip1[1] + ip1[4] - ip1[8];
+ op1[4]=ip1[0] + ip1[1] - ip1[4] - ip1[8];
+ op1[8]=ip1[0] - ip1[1] - ip1[4] + ip1[8];
+
+}
+#endif
void vp8_short_fdct4x4_c(short *input, short *output, int pitch)
{
int i;
@@ -20,11 +136,17 @@ void vp8_short_fdct4x4_c(short *input, short *output, int pitch)
for (i = 0; i < 4; i++)
{
+#if CONFIG_EXTEND_QRANGE
+ a1 = ((ip[0] + ip[3])<<5);
+ b1 = ((ip[1] + ip[2])<<5);
+ c1 = ((ip[1] - ip[2])<<5);
+ d1 = ((ip[0] - ip[3])<<5);
+#else
a1 = ((ip[0] + ip[3])<<3);
b1 = ((ip[1] + ip[2])<<3);
c1 = ((ip[1] - ip[2])<<3);
d1 = ((ip[0] - ip[3])<<3);
-
+#endif
op[0] = a1 + b1;
op[2] = a1 - b1;
@@ -72,12 +194,22 @@ void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
for (i = 0; i < 4; i++)
{
+#if !CONFIG_EXTEND_QRANGE
a1 = ((ip[0] + ip[2])<<2);
d1 = ((ip[1] + ip[3])<<2);
c1 = ((ip[1] - ip[3])<<2);
b1 = ((ip[0] - ip[2])<<2);
op[0] = a1 + d1 + (a1!=0);
+#else
+ a1 = ((ip[0] + ip[2]));
+ d1 = ((ip[1] + ip[3]));
+ c1 = ((ip[1] - ip[3]));
+ b1 = ((ip[0] - ip[2]));
+
+
+ op[0] = a1 + d1;
+#endif
op[1] = b1 + c1;
op[2] = b1 - c1;
op[3] = a1 - d1;
@@ -105,11 +237,17 @@ void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
c2 += c2<0;
d2 += d2<0;
+#if !CONFIG_EXTEND_QRANGE
op[0] = (a2+3) >> 3;
op[4] = (b2+3) >> 3;
op[8] = (c2+3) >> 3;
op[12]= (d2+3) >> 3;
-
+#else
+ op[0] = (a2+1) >> 2;
+ op[4] = (b2+1) >> 2;
+ op[8] = (c2+1) >> 2;
+ op[12]= (d2+1) >> 2;
+#endif
ip++;
op++;
}
diff --git a/vp8/encoder/dct.h b/vp8/encoder/dct.h
index fec3b4c37..c37d47aca 100644
--- a/vp8/encoder/dct.h
+++ b/vp8/encoder/dct.h
@@ -22,6 +22,20 @@
#include "arm/dct_arm.h"
#endif
+#if CONFIG_T8X8
+
+#ifndef vp8_fdct_short8x8
+#define vp8_fdct_short8x8 vp8_short_fdct8x8_c
+#endif
+extern prototype_fdct(vp8_fdct_short8x8);
+
+#ifndef vp8_fhaar_short2x2
+#define vp8_fhaar_short2x2 vp8_short_fhaar2x2_c
+#endif
+extern prototype_fdct(vp8_fhaar_short2x2);
+
+#endif
+
#ifndef vp8_fdct_short4x4
#define vp8_fdct_short4x4 vp8_short_fdct4x4_c
#endif
@@ -49,6 +63,10 @@ extern prototype_fdct(vp8_fdct_walsh_short4x4);
typedef prototype_fdct(*vp8_fdct_fn_t);
typedef struct
{
+#if CONFIG_T8X8
+ vp8_fdct_fn_t short8x8;
+ vp8_fdct_fn_t haar_short2x2;
+#endif
vp8_fdct_fn_t short4x4;
vp8_fdct_fn_t short8x4;
vp8_fdct_fn_t fast4x4;
diff --git a/vp8/encoder/defaultcoefcounts.h b/vp8/encoder/defaultcoefcounts.h
index 2c0f3ddf3..3b54c823c 100644
--- a/vp8/encoder/defaultcoefcounts.h
+++ b/vp8/encoder/defaultcoefcounts.h
@@ -221,3 +221,182 @@ static const unsigned int default_coef_counts[BLOCK_TYPES]
},
},
};
+
+
+#if CONFIG_T8X8
+const unsigned int vp8_default_coef_counts_8x8[BLOCK_TYPES]
+ [COEF_BANDS]
+ [PREV_COEF_CONTEXTS]
+ [MAX_ENTROPY_TOKENS] =
+{
+
+ { /* block Type 0 */
+ { /* Coeff Band 0 */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 1 */
+ { 21041, 13314, 3420, 592, 117, 0, 0, 0, 0, 0, 0, 11783},
+ { 48236, 6918, 586, 153, 0, 0, 0, 0, 0, 0, 0, 23137},
+ { 676112, 106685, 24701, 6003, 1426, 429, 165, 0, 0, 0, 0, 28910}
+ },
+ { /* Coeff Band 2 */
+ { 660107, 75227, 8451, 1345, 259, 0, 0, 0, 0, 0, 0, 0},
+ { 79164, 36835, 6865, 1185, 246, 47, 0, 0, 0, 0, 0, 2575},
+ { 19469, 14330, 3070, 579, 94, 6, 0, 0, 0, 0, 0, 44}
+ },
+ { /* Coeff Band 3 */
+ { 1978004, 235343, 28485, 3242, 271, 0, 0, 0, 0, 0, 0, 0},
+ { 228684, 106736, 21431, 2842, 272, 46, 0, 0, 0, 0, 0, 9266},
+ { 32470, 27496, 6852, 1386, 45, 93, 0, 0, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 4 */
+ { 1911212, 224613, 49653, 13748, 2541, 568, 48, 0, 0, 0, 0, 0},
+ { 196670, 103472, 44473, 11490, 2432, 977, 72, 0, 0, 0, 0, 9447},
+ { 37876, 40417, 19142, 6069, 1799, 727, 51, 0, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 5 */
+ { 3813399, 437714, 64387, 11312, 695, 219, 0, 0, 0, 0, 0, 0},
+ { 438288, 215917, 61905, 10194, 674, 107, 0, 0, 0, 0, 0, 17808},
+ { 99139, 93643, 30054, 5758, 802, 171, 0, 0, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 6 */
+ { 12259383, 1625505, 234927, 46306, 8417, 1456, 151, 0, 0, 0, 0, 0},
+ { 1518161, 734287, 204240, 44228, 9462, 2240, 65, 0, 0, 0, 0, 107630},
+ { 292470, 258894, 94925, 25864, 6662, 2055, 170, 0, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 7 */
+ { 9791308, 2118949, 169439, 16735, 1122, 0, 0, 0, 0, 0, 0, 0},
+ { 1500281, 752410, 123259, 13065, 1168, 47, 0, 0, 0, 0, 0, 707182},
+ { 193067, 142638, 31018, 4719, 516, 138, 0, 0, 0, 0, 0, 12439}
+ }
+ },
+ { /* block Type 1 */
+ { /* Coeff Band 0 */
+ { 16925, 10553, 852, 16, 63, 87, 47, 0, 0, 0, 0, 31232},
+ { 39777, 26839, 6822, 1908, 678, 456, 227, 168, 35, 0, 0, 46825},
+ { 17300, 16666, 4168, 1209, 492, 154, 118, 207, 0, 0, 0, 19608}
+ },
+ { /* Coeff Band 1 */
+ { 35882, 31722, 4625, 1270, 266, 237, 0, 0, 0, 0, 0, 0},
+ { 15426, 13894, 4482, 1305, 281, 43, 0, 0, 0, 0, 0, 18627},
+ { 3900, 6552, 3472, 1723, 746, 366, 115, 35, 0, 0, 0, 798}
+ },
+ { /* Coeff Band 2 */
+ { 21998, 29132, 3353, 679, 46, 0, 0, 0, 0, 0, 0, 0},
+ { 9098, 15767, 3794, 792, 268, 47, 0, 0, 0, 0, 0, 22402},
+ { 4007, 8472, 2844, 687, 217, 0, 0, 0, 0, 0, 0, 2739}
+ },
+ { /* Coeff Band 3 */
+ { 0, 31414, 2911, 682, 96, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 16515, 4425, 938, 124, 0, 0, 0, 0, 0, 0, 31369},
+ { 0, 4833, 2787, 1213, 150, 0, 0, 0, 0, 0, 0, 3744}
+ },
+ { /* Coeff Band 4 */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 5 */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 6 */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52762},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13326}
+ },
+ { /* Coeff Band 7 */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ }
+ },
+ { /* block Type 2 */
+ { /* Coeff Band 0 */
+ { 4444, 1614, 120, 48, 0, 48, 0, 0, 0, 0, 0, 278},
+ { 192436, 103730, 24494, 9845, 4122, 1193, 102, 0, 0, 0, 0, 2577},
+ { 3473446, 2308716, 815510, 370374, 167797, 92152, 12073, 86, 0, 0, 0, 6801}
+ },
+ { /* Coeff Band 1 */
+ { 2150616, 1136388, 250011, 86888, 31434, 13746, 1243, 0, 0, 0, 0, 0},
+ { 1179945, 799802, 266012, 106787, 40809, 16486, 1546, 0, 0, 0, 0, 2673},
+ { 465128, 504130, 286989, 146259, 62380, 30192, 2866, 20, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 2 */
+ { 2157762, 1177519, 282665, 108499, 43389, 23224, 2597, 34, 0, 0, 0, 0},
+ { 1135685, 813705, 278079, 123255, 53935, 29492, 3152, 39, 0, 0, 0, 2978},
+ { 391894, 428037, 264216, 144306, 69326, 40281, 5541, 29, 0, 0, 0, 38}
+ },
+ { /* Coeff Band 3 */
+ { 6669109, 3468471, 782161, 288484, 115500, 51083, 4943, 41, 0, 0, 0, 0},
+ { 3454493, 2361636, 809524, 337663, 141343, 65036, 6361, 0, 0, 0, 0, 8730},
+ { 1231825, 1359522, 824686, 420784, 185517, 98731, 10973, 72, 0, 0, 0, 20}
+ },
+ { /* Coeff Band 4 */
+ { 7606203, 3452846, 659856, 191703, 49335, 14336, 450, 0, 0, 0, 0, 0},
+ { 3806506, 2379332, 691697, 224938, 61966, 18324, 766, 0, 0, 0, 0, 8193},
+ { 1270110, 1283728, 628775, 243378, 72617, 24897, 1087, 0, 0, 0, 0, 0}
+ },
+ { /* Coeff Band 5 */
+ { 15314169, 7436809, 1579928, 515790, 167453, 58305, 3502, 19, 0, 0, 0, 0},
+ { 7021286, 4667922, 1545706, 574463, 191793, 68748, 4048, 1, 0, 0, 0, 17222},
+ { 2011989, 2145878, 1185336, 534879, 195719, 79103, 5343, 4, 0, 0, 0, 37}
+ },
+ { /* Coeff Band 6 */
+ { 63458382, 25384462, 4208045, 1091050, 299011, 95242, 5238, 33, 0, 0, 0, 0},
+ { 25638401, 14694085, 3945978, 1195420, 344813, 117355, 6703, 0, 0, 0, 0, 216811},
+ { 5988177, 5824044, 2754413, 1077350, 370739, 139710, 9693, 38, 0, 0, 0, 1835}
+ },
+ { /* Coeff Band 7 */
+ { 74998348, 29342158, 2955001, 452912, 69631, 9516, 37, 0, 0, 0, 0, 0},
+ { 24762356, 13281085, 2409883, 436787, 68948, 10658, 36, 0, 0, 0, 0, 6614989},
+ { 3882867, 3224489, 1052289, 252890, 46967, 8548, 154, 0, 0, 0, 0, 194354}
+ }
+ },
+ { /* block Type 3 */
+ { /* Coeff Band 0 */
+ { 10583, 12059, 3155, 1041, 248, 175, 24, 2, 0, 0, 0, 5717},
+ { 42461, 41782, 13553, 4966, 1352, 855, 89, 0, 0, 0, 0, 15000},
+ { 4691125, 5045589, 2673566, 1089317, 378161, 160268, 18252, 813, 69, 13, 0, 49}
+ },
+ { /* Coeff Band 1 */
+ { 1535203, 1685686, 924565, 390329, 141709, 60523, 5983, 171, 0, 0, 0, 0},
+ { 1594021, 1793276, 1016078, 441332, 164159, 70843, 8098, 311, 0, 0, 0, 11312},
+ { 1225223, 1430184, 888492, 460713, 203286, 115149, 22061, 804, 7, 0, 0, 0}
+ },
+ { /* Coeff Band 2 */
+ { 1522386, 1590366, 799910, 303691, 96625, 37608, 3637, 180, 33, 11, 0, 0},
+ { 1682184, 1793869, 913649, 353520, 113674, 46309, 4736, 221, 18, 3, 0, 963},
+ { 1574580, 1740474, 954392, 417994, 151400, 67091, 8000, 536, 73, 10, 0, 63}
+ },
+ { /* Coeff Band 3 */
+ { 4963672, 5197790, 2585383, 982161, 313333, 118498, 16014, 536, 62, 0, 0, 0},
+ { 5223913, 5569803, 2845858, 1107384, 364949, 147841, 18296, 658, 11, 11, 0, 1866},
+ { 4042207, 4548894, 2608767, 1154993, 446290, 221295, 41054, 2438, 124, 20, 0, 0}
+ },
+ { /* Coeff Band 4 */
+ { 3857216, 4431325, 2670447, 1330169, 553301, 286825, 46763, 1917, 0, 0, 0, 0},
+ { 4226215, 4963701, 3046198, 1523923, 644670, 355519, 58792, 2525, 0, 0, 0, 1298},
+ { 3831873, 4580350, 3018580, 1660048, 797298, 502983, 123906, 7172, 16, 0, 0, 0}
+ },
+ { /* Coeff Band 5 */
+ { 8524543, 9285149, 4979435, 2039330, 683458, 266032, 22628, 270, 0, 0, 0, 0},
+ { 9432163, 10428088, 5715661, 2385738, 838389, 326264, 29981, 361, 0, 0, 0, 884},
+ { 9039066, 10368964, 6136765, 2862030, 1098269, 511668, 63105, 945, 14, 0, 0, 0}
+ },
+ { /* Coeff Band 6 */
+ { 33222872, 34748297, 17701695, 7214933, 2602336, 1191859, 187873, 12667, 390, 3, 0, 0},
+ { 34765051, 37140719, 19525578, 8268934, 3085012, 1473864, 246743, 15258, 736, 3, 0, 8403},
+ { 28591289, 32252393, 19037068, 9213729, 4020653, 2372354, 586420, 67428, 3920, 92, 7, 3}
+ },
+ { /* Coeff Band 7 */
+ { 68604786, 60777665, 19712887, 5656955, 1520443, 507166, 51829, 2466, 10, 0, 0, 0},
+ { 55447403, 51682540, 19008774, 5928582, 1706884, 595531, 65998, 3661, 101, 0, 0, 8468343},
+ { 28321970, 29149398, 13565882, 5258675, 1868588, 898041, 192023, 21497, 672, 17, 0, 1884921}
+ }
+ }
+ };
+#endif
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 5d4e7e71e..1c4a93636 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -26,10 +26,12 @@
#include "vp8/common/findnearmv.h"
#include "vp8/common/reconintra.h"
#include <stdio.h>
+#include <math.h>
#include <limits.h>
#include "vp8/common/subpixel.h"
#include "vpx_ports/vpx_timer.h"
+
#if CONFIG_RUNTIME_CPU_DETECT
#define RTCD(x) &cpi->common.rtcd.x
#define IF_RTCD(x) (x)
@@ -37,6 +39,18 @@
#define RTCD(x) NULL
#define IF_RTCD(x) NULL
#endif
+
+#if CONFIG_SEGMENTATION
+#define SEEK_SEGID 12
+#define SEEK_SAMEID 4
+#define SEEK_DIFFID 7
+#endif
+
+#ifdef ENC_DEBUG
+int enc_debug=0;
+int mb_row_debug, mb_col_debug;
+#endif
+
extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex);
@@ -52,6 +66,8 @@ int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
static void adjust_act_zbin( VP8_COMP *cpi, MACROBLOCK *x );
+
+
#ifdef MODE_STATS
unsigned int inter_y_modes[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned int inter_uv_modes[4] = {0, 0, 0, 0};
@@ -80,6 +96,186 @@ static const unsigned char VP8_VAR_OFFS[16]=
};
+
+#if CONFIG_T8X8
+
+//INTRA mode transform size
+//When all three criteria are off the default is 4x4
+//#define INTRA_VARIANCE_ENTROPY_CRITERIA
+#define INTRA_WTD_SSE_ENTROPY_CRITERIA
+//#define INTRA_TEST_8X8_ONLY
+//
+//INTER mode transform size
+//When all three criteria are off the default is 4x4
+//#define INTER_VARIANCE_ENTROPY_CRITERIA
+#define INTER_WTD_SSE_ENTROPY_CRITERIA
+//#define INTER_TEST_8X8_ONLY
+
+double variance_Block(short *b1, int pitch, int dimension)
+{
+ short ip[8][8]={{0}};
+ short *b = b1;
+ int i, j = 0;
+ double mean = 0.0, variance = 0.0;
+ for (i = 0; i < dimension; i++)
+ {
+ for (j = 0; j < dimension; j++)
+ {
+ ip[i][j] = b[j];
+ mean += ip[i][j];
+ }
+ b += pitch;
+ }
+ mean /= (dimension*dimension);
+
+ for (i = 0; i < dimension; i++)
+ {
+ for (j = 0; j < dimension; j++)
+ {
+ variance += (ip[i][j]-mean)*(ip[i][j]-mean);
+ }
+ }
+ variance /= (dimension*dimension);
+ return variance;
+}
+
+double mean_Block(short *b, int pitch, int dimension)
+{
+ short ip[8][8]={{0}};
+ int i, j = 0;
+ double mean = 0;
+ for (i = 0; i < dimension; i++)
+ {
+ for (j = 0; j < dimension; j++)
+ {
+ ip[i][j] = b[j];
+ mean += ip[i][j];
+ }
+ b += pitch;
+ }
+ mean /= (dimension*dimension);
+
+ return mean;
+}
+
+int SSE_Block(short *b, int pitch, int dimension)
+{
+ int i, j, sse_block = 0;
+ for (i = 0; i < dimension; i++)
+ {
+ for (j = 0; j < dimension; j++)
+ {
+ sse_block += b[j]*b[j];
+ }
+ b += pitch;
+ }
+ return sse_block;
+}
+
+double Compute_Variance_Entropy(MACROBLOCK *x)
+{
+ double variance_8[4] = {0.0, 0.0, 0.0, 0.0}, sum_var = 0.0, all_entropy = 0.0;
+ variance_8[0] = variance_Block(x->block[0].src_diff, 16, 8);
+ variance_8[1] = variance_Block(x->block[2].src_diff, 16, 8);
+ variance_8[2] = variance_Block(x->block[8].src_diff, 16, 8);
+ variance_8[3] = variance_Block(x->block[10].src_diff, 16, 8);
+ sum_var = variance_8[0] + variance_8[1] + variance_8[2] + variance_8[3];
+ if(sum_var)
+ {
+ int i;
+ for(i = 0; i <4; i++)
+ {
+ if(variance_8[i])
+ {
+ variance_8[i] /= sum_var;
+ all_entropy -= variance_8[i]*log(variance_8[i]);
+ }
+ }
+ }
+ return (all_entropy /log(2));
+}
+
+double Compute_Wtd_SSE_SubEntropy(MACROBLOCK *x)
+{
+ double variance_8[4] = {0.0, 0.0, 0.0, 0.0};
+ double entropy_8[4] = {0.0, 0.0, 0.0, 0.0};
+ double sse_1, sse_2, sse_3, sse_4, sse_0;
+ int i;
+ for (i=0;i<3;i+=2)
+ {
+ sse_0 = SSE_Block(x->block[i].src_diff, 16, 8);
+ if(sse_0)
+ {
+ sse_1 = SSE_Block(x->block[i].src_diff, 16, 4)/sse_0;
+ sse_2 = SSE_Block(x->block[i+1].src_diff, 16, 4)/sse_0;
+ sse_3 = SSE_Block(x->block[i+4].src_diff, 16, 4)/sse_0;
+ sse_4 = SSE_Block(x->block[i+5].src_diff, 16, 4)/sse_0;
+ variance_8[i]= variance_Block(x->block[i].src_diff, 16, 8);
+ if(sse_1 && sse_2 && sse_3 && sse_4)
+ entropy_8[i]= (-sse_1*log(sse_1)
+ -sse_2*log(sse_2)
+ -sse_3*log(sse_3)
+ -sse_4*log(sse_4))/log(2);
+ }
+ }
+ for (i=8;i<11;i+=2)
+ {
+ if(sse_0)
+ {
+ sse_0 = SSE_Block(x->block[i].src_diff, 16, 8);
+ sse_1 = SSE_Block(x->block[i].src_diff, 16, 4)/sse_0;
+ sse_2 = SSE_Block(x->block[i+1].src_diff, 16, 4)/sse_0;
+ sse_3 = SSE_Block(x->block[i+4].src_diff, 16, 4)/sse_0;
+ sse_4 = SSE_Block(x->block[i+5].src_diff, 16, 4)/sse_0;
+ variance_8[i-7]= variance_Block(x->block[i].src_diff, 16, 8);
+ if(sse_1 && sse_2 && sse_3 && sse_4)
+ entropy_8[i-7]= (-sse_1*log(sse_1)
+ -sse_2*log(sse_2)
+ -sse_3*log(sse_3)
+ -sse_4*log(sse_4))/log(2);
+ }
+ }
+ if(variance_8[0]+variance_8[1]+variance_8[2]+variance_8[3])
+ return (entropy_8[0]*variance_8[0]+
+ entropy_8[1]*variance_8[1]+
+ entropy_8[2]*variance_8[2]+
+ entropy_8[3]*variance_8[3])/
+ (variance_8[0]+
+ variance_8[1]+
+ variance_8[2]+
+ variance_8[3]);
+ else
+ return 0;
+}
+
+int vp8_8x8_selection_intra(MACROBLOCK *x)
+{
+#ifdef INTRA_VARIANCE_ENTROPY_CRITERIA
+ return (Compute_Variance_Entropy(x) > 1.2);
+#elif defined(INTRA_WTD_SSE_ENTROPY_CRITERIA)
+ return (Compute_Wtd_SSE_SubEntropy(x) > 1.2);
+#elif defined(INTRA_TEST_8X8_ONLY)
+ return 1;
+#else
+ return 0; //when all criteria are off use the default 4x4 only
+#endif
+}
+
+int vp8_8x8_selection_inter(MACROBLOCK *x)
+{
+#ifdef INTER_VARIANCE_ENTROPY_CRITERIA
+ return (Compute_Variance_Entropy(x) > 1.5);
+#elif defined(INTER_WTD_SSE_ENTROPY_CRITERIA)
+ return (Compute_Wtd_SSE_SubEntropy(x) > 1.5);
+#elif defined(INTER_TEST_8X8_ONLY)
+ return 1;
+#else
+ return 0; //when all criteria are off use the default 4x4 only
+#endif
+}
+
+#endif
+
// Original activity measure from Tim T's code.
static unsigned int tt_activity_measure( VP8_COMP *cpi, MACROBLOCK *x )
{
@@ -376,7 +572,10 @@ void encode_mb_row(VP8_COMP *cpi,
int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
int map_index = (mb_row * cpi->common.mb_cols);
-
+#if CONFIG_SEGMENTATION
+ int left_id, above_id;
+ int sum;
+#endif
#if CONFIG_MULTITHREAD
const int nsync = cpi->mt_sync_range;
const int rightmost_col = cm->mb_cols - 1;
@@ -415,6 +614,12 @@ void encode_mb_row(VP8_COMP *cpi,
// for each macroblock col in image
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
{
+#ifdef ENC_DEBUG
+ //enc_debug = (cpi->count==29 && mb_row==5 && mb_col==0);
+ enc_debug = (cpi->count==4 && mb_row==17 && mb_col==13);
+ mb_col_debug=mb_col;
+ mb_row_debug=mb_row;
+#endif
// Distance of Mb to the left & right edges, specified in
// 1/8th pel units as they are always compared to values
// that are in 1/8th pel units
@@ -461,8 +666,14 @@ void encode_mb_row(VP8_COMP *cpi,
if (xd->segmentation_enabled)
{
// Code to set segment id in xd->mbmi.segment_id for current MB (with range checking)
+#if CONFIG_T8X8
+ // Reset segment_id to 0 or 1 so that the default transform mode is 4x4
+ if (cpi->segmentation_map[map_index+mb_col] <= 3)
+ xd->mode_info_context->mbmi.segment_id = cpi->segmentation_map[map_index+mb_col]&1;
+#else
if (cpi->segmentation_map[map_index+mb_col] <= 3)
xd->mode_info_context->mbmi.segment_id = cpi->segmentation_map[map_index+mb_col];
+#endif
else
xd->mode_info_context->mbmi.segment_id = 0;
@@ -476,24 +687,27 @@ void encode_mb_row(VP8_COMP *cpi,
if (cm->frame_type == KEY_FRAME)
{
*totalrate += vp8cx_encode_intra_macro_block(cpi, x, tp);
+ //Note the encoder may have changed the segment_id
+
#ifdef MODE_STATS
- y_modes[xd->mbmi.mode] ++;
+ y_modes[xd->mode_info_context->mbmi.mode] ++;
#endif
}
else
{
*totalrate += vp8cx_encode_inter_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset);
+ //Note the encoder may have changed the segment_id
#ifdef MODE_STATS
- inter_y_modes[xd->mbmi.mode] ++;
+ inter_y_modes[xd->mode_info_context->mbmi.mode] ++;
- if (xd->mbmi.mode == SPLITMV)
+ if (xd->mode_info_context->mbmi.mode == SPLITMV)
{
int b;
- for (b = 0; b < xd->mbmi.partition_count; b++)
+ for (b = 0; b < x->partition_info->count; b++)
{
- inter_b_modes[x->partition->bmi[b].mode] ++;
+ inter_b_modes[x->partition_info->bmi[b].mode] ++;
}
}
@@ -534,6 +748,12 @@ void encode_mb_row(VP8_COMP *cpi,
// Increment the activity mask pointers.
x->mb_activity_ptr++;
+#if CONFIG_SEGMENTATION
+ if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME))
+ xd->mode_info_context->mbmi.segment_id = 0;
+ else
+ xd->mode_info_context->mbmi.segment_id = 1;
+#endif
/* save the block info */
for (i = 0; i < 16; i++)
xd->mode_info_context->bmi[i] = xd->block[i].bmi;
@@ -546,9 +766,42 @@ void encode_mb_row(VP8_COMP *cpi,
recon_yoffset += 16;
recon_uvoffset += 8;
- // Keep track of segment useage
- segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
+#if CONFIG_SEGMENTATION
+ //cpi->segmentation_map[mb_row * cm->mb_cols + mb_col] = xd->mbmi.segment_id;
+ if (cm->frame_type == KEY_FRAME)
+ {
+ segment_counts[xd->mode_info_context->mbmi.segment_id]++;
+ }
+ else
+ {
+ sum = 0;
+ if (mb_col != 0)
+ sum += (xd->mode_info_context-1)->mbmi.segment_flag;
+ if (mb_row != 0)
+ sum += (xd->mode_info_context-cm->mb_cols)->mbmi.segment_flag;
+
+ if (xd->mode_info_context->mbmi.segment_id == cpi->segmentation_map[(mb_row*cm->mb_cols) + mb_col])
+ xd->mode_info_context->mbmi.segment_flag = 0;
+ else
+ xd->mode_info_context->mbmi.segment_flag = 1;
+ if (xd->mode_info_context->mbmi.segment_flag == 0)
+ {
+ segment_counts[SEEK_SAMEID + sum]++;
+ segment_counts[10]++;
+ }
+ else
+ {
+ segment_counts[SEEK_DIFFID + sum]++;
+ segment_counts[11]++;
+ //calculate individual segment ids
+ segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
+ }
+ }
+ segment_counts[SEEK_SEGID + xd->mode_info_context->mbmi.segment_id] ++;
+#else
+ segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
+#endif
// skip to next mb
xd->mode_info_context++;
x->partition_info++;
@@ -675,7 +928,13 @@ void vp8_encode_frame(VP8_COMP *cpi)
MACROBLOCKD *const xd = & x->e_mbd;
TOKENEXTRA *tp = cpi->tok;
+#if CONFIG_SEGMENTATION
+ int segment_counts[MAX_MB_SEGMENTS + SEEK_SEGID];
+ int prob[3];
+ int new_cost, original_cost;
+#else
int segment_counts[MAX_MB_SEGMENTS];
+#endif
int totalrate;
vpx_memset(segment_counts, 0, sizeof(segment_counts));
@@ -736,9 +995,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
vp8cx_frame_init_quantizer(cpi);
- vp8_initialize_rd_consts(cpi,
- vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
-
+ vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q);
vp8cx_initialize_me_consts(cpi, cm->base_qindex);
if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
@@ -847,41 +1104,126 @@ void vp8_encode_frame(VP8_COMP *cpi)
}
-
// Work out the segment probabilites if segmentation is enabled
if (xd->segmentation_enabled)
{
int tot_count;
int i;
+ int count1,count2,count3,count4;
// Set to defaults
vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));
+#if CONFIG_SEGMENTATION
+
+ tot_count = segment_counts[12] + segment_counts[13] + segment_counts[14] + segment_counts[15];
+ count1 = segment_counts[12] + segment_counts[13];
+ count2 = segment_counts[14] + segment_counts[15];
+
+ if (tot_count)
+ prob[0] = (count1 * 255) / tot_count;
+
+ if (count1 > 0)
+ prob[1] = (segment_counts[12] * 255) /count1;
+
+ if (count2 > 0)
+ prob[2] = (segment_counts[14] * 255) /count2;
+
+ if (cm->frame_type != KEY_FRAME)
+ {
+ tot_count = segment_counts[4] + segment_counts[7];
+ if (tot_count)
+ xd->mb_segment_tree_probs[3] = (segment_counts[4] * 255)/tot_count;
+
+ tot_count = segment_counts[5] + segment_counts[8];
+ if (tot_count)
+ xd->mb_segment_tree_probs[4] = (segment_counts[5] * 255)/tot_count;
+
+ tot_count = segment_counts[6] + segment_counts[9];
+ if (tot_count)
+ xd->mb_segment_tree_probs[5] = (segment_counts[6] * 255)/tot_count;
+ }
tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
+ count3 = segment_counts[0] + segment_counts[1];
+ count4 = segment_counts[2] + segment_counts[3];
if (tot_count)
+ xd->mb_segment_tree_probs[0] = (count3 * 255) / tot_count;
+
+ if (count3 > 0)
+ xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count3;
+
+ if (count4 > 0)
+ xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count4;
+
+ for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
{
- xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count;
+ if (xd->mb_segment_tree_probs[i] == 0)
+ xd->mb_segment_tree_probs[i] = 1;
+ }
- tot_count = segment_counts[0] + segment_counts[1];
+ original_cost = count1 * vp8_cost_zero(prob[0]) + count2 * vp8_cost_one(prob[0]);
- if (tot_count > 0)
- {
- xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count;
- }
+ if (count1 > 0)
+ original_cost += segment_counts[12] * vp8_cost_zero(prob[1]) + segment_counts[13] * vp8_cost_one(prob[1]);
+
+ if (count2 > 0)
+ original_cost += segment_counts[14] * vp8_cost_zero(prob[2]) + segment_counts[15] * vp8_cost_one(prob[2]) ;
+
+ new_cost = 0;
+
+ if (cm->frame_type != KEY_FRAME)
+ {
+ new_cost = segment_counts[4] * vp8_cost_zero(xd->mb_segment_tree_probs[3]) + segment_counts[7] * vp8_cost_one(xd->mb_segment_tree_probs[3]);
- tot_count = segment_counts[2] + segment_counts[3];
+ new_cost += segment_counts[5] * vp8_cost_zero(xd->mb_segment_tree_probs[4]) + segment_counts[8] * vp8_cost_one(xd->mb_segment_tree_probs[4]);
- if (tot_count > 0)
- xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count;
+ new_cost += segment_counts[6] * vp8_cost_zero(xd->mb_segment_tree_probs[5]) + segment_counts[9] * vp8_cost_one (xd->mb_segment_tree_probs[5]);
+ }
+
+ if (tot_count > 0)
+ new_cost += count3 * vp8_cost_zero(xd->mb_segment_tree_probs[0]) + count4 * vp8_cost_one(xd->mb_segment_tree_probs[0]);
+
+ if (count3 > 0)
+ new_cost += segment_counts[0] * vp8_cost_zero(xd->mb_segment_tree_probs[1]) + segment_counts[1] * vp8_cost_one(xd->mb_segment_tree_probs[1]);
- // Zero probabilities not allowed
- for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++)
+ if (count4 > 0)
+ new_cost += segment_counts[2] * vp8_cost_zero(xd->mb_segment_tree_probs[2]) + segment_counts[3] * vp8_cost_one(xd->mb_segment_tree_probs[2]) ;
+
+ if (new_cost < original_cost)
+ xd->temporal_update = 1;
+ else
+ {
+ xd->temporal_update = 0;
+ xd->mb_segment_tree_probs[0] = prob[0];
+ xd->mb_segment_tree_probs[1] = prob[1];
+ xd->mb_segment_tree_probs[2] = prob[2];
+ }
+#else
+ tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
+ count1 = segment_counts[0] + segment_counts[1];
+ count2 = segment_counts[2] + segment_counts[3];
+
+ if (tot_count)
+ xd->mb_segment_tree_probs[0] = (count1 * 255) / tot_count;
+
+ if (count1 > 0)
+ xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count1;
+
+ if (count2 > 0)
+ xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count2;
+
+#endif
+ // Zero probabilities not allowed
+#if CONFIG_SEGMENTATION
+ for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+#else
+ for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+#endif
{
if (xd->mb_segment_tree_probs[i] == 0)
xd->mb_segment_tree_probs[i] = 1;
}
- }
}
// 256 rate units to the bit
@@ -1083,7 +1425,7 @@ static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x)
do
{
- ++ bct[xd->block[b].bmi.mode];
+ ++ bct[xd->block[b].bmi.as_mode];
}
while (++b < 16);
}
@@ -1121,6 +1463,10 @@ int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
{
int rate;
+#if CONFIG_T8X8
+ if (x->e_mbd.segmentation_enabled)
+ x->e_mbd.update_mb_segmentation_map = 1;
+#endif
if (cpi->sf.RD && cpi->compressor_speed != 2)
vp8_rd_pick_intra_mode(cpi, x, &rate);
else
@@ -1135,12 +1481,22 @@ int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
if (x->e_mbd.mode_info_context->mbmi.mode == B_PRED)
vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
else
+ {
+#if CONFIG_T8X8
+ if (x->e_mbd.segmentation_enabled)
+ x->e_mbd.mode_info_context->mbmi.segment_id |= (vp8_8x8_selection_intra(x) << 1);
+#endif
vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
-
+ }
vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
sum_intra_stats(cpi, x);
vp8_tokenize_mb(cpi, &x->e_mbd, t);
-
+#if CONFIG_T8X8
+ if( x->e_mbd.mode_info_context->mbmi.segment_id >=2)
+ cpi->t8x8_count++;
+ else
+ cpi->t4x4_count++;
+#endif
return rate;
}
#ifdef SPEEDSTATS
@@ -1262,16 +1618,25 @@ int vp8cx_encode_inter_macroblock
cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame] ++;
+#if CONFIG_T8X8
+ if (xd->segmentation_enabled)
+ x->e_mbd.update_mb_segmentation_map = 1;
+#endif
+
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
{
- vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
-
if (xd->mode_info_context->mbmi.mode == B_PRED)
{
+ vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
}
else
{
+#if CONFIG_T8X8
+ if (xd->segmentation_enabled)
+ xd->mode_info_context->mbmi.segment_id |= (vp8_8x8_selection_intra(x) << 1);
+#endif
+ vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
}
@@ -1280,6 +1645,10 @@ int vp8cx_encode_inter_macroblock
else
{
int ref_fb_idx;
+#if CONFIG_T8X8
+ if (xd->segmentation_enabled)
+ xd->mode_info_context->mbmi.segment_id |= (vp8_8x8_selection_inter(x) << 1);
+#endif
vp8_build_uvmvs(xd, cpi->common.full_pixel);
@@ -1309,9 +1678,40 @@ int vp8cx_encode_inter_macroblock
xd->dst.y_stride, xd->dst.uv_stride);
}
+#if CONFIG_T8X8
+ if (x->e_mbd.mode_info_context->mbmi.segment_id >=2)
+ cpi->t8x8_count++;
+ else
+ cpi->t4x4_count++;
+#endif
if (!x->skip)
+ {
+#ifdef ENC_DEBUG
+ if (enc_debug)
+ {
+ int i;
+ printf("Segment=%d [%d, %d]: %d %d:\n", x->e_mbd.mode_info_context->mbmi.segment_id, mb_col_debug, mb_row_debug, xd->mb_to_left_edge, xd->mb_to_top_edge);
+ for (i =0; i<400; i++) {
+ printf("%3d ", xd->qcoeff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("\n");
+ printf("eobs = ");
+ for (i=0;i<25;i++)
+ printf("%d:%d ", i, xd->block[i].eob);
+ printf("\n");
+ fflush(stdout);
+ }
+#endif
vp8_tokenize_mb(cpi, xd, t);
+#ifdef ENC_DEBUG
+ if (enc_debug) {
+ printf("Tokenized\n");
+ fflush(stdout);
+ }
+#endif
+ }
else
{
if (cpi->common.mb_no_coeff_skip)
diff --git a/vp8/encoder/encodeintra.c b/vp8/encoder/encodeintra.c
index 59db0253b..10afed3ec 100644
--- a/vp8/encoder/encodeintra.c
+++ b/vp8/encoder/encodeintra.c
@@ -22,6 +22,10 @@
#include "encodeintra.h"
+#ifdef ENC_DEBUG
+extern int enc_debug;
+#endif
+
#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
@@ -96,15 +100,67 @@ void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mby)(&x->e_mbd);
ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride);
-
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_transform_intra_mby_8x8(x);
+ else
+#endif
vp8_transform_intra_mby(x);
- vp8_quantize_mby(x);
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_quantize_mby_8x8(x);
+ else
+#endif
+ vp8_quantize_mby(x);
if (x->optimize)
+ {
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_optimize_mby_8x8(x, rtcd);
+ else
+#endif
vp8_optimize_mby(x, rtcd);
+ }
- vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+ else
+#endif
+ vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+
+#ifdef ENC_DEBUG
+ if (enc_debug) {
+ int i;
+ printf("Intra qcoeff:\n");
+ printf("%d %d:\n", x->e_mbd.mb_to_left_edge, x->e_mbd.mb_to_top_edge);
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.qcoeff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("Intra dqcoeff:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.dqcoeff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("Intra diff:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.diff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("Intra predictor:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.predictor[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("eobs:\n");
+ for (i=0;i<25;i++)
+ printf("%d ", x->e_mbd.block[i].eob);
+ printf("\n");
+ }
+#endif
RECON_INVOKE(&rtcd->common->recon, recon_mby)
(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
@@ -116,14 +172,66 @@ void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mbuv)(&x->e_mbd);
ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_transform_mbuv_8x8(x);
+ else
+#endif
+ vp8_transform_mbuv(x);
- vp8_transform_mbuv(x);
-
- vp8_quantize_mbuv(x);
-
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_quantize_mbuv_8x8(x);
+ else
+#endif
+ vp8_quantize_mbuv(x);
+
+#ifdef ENC_DEBUG
+ if (enc_debug) {
+ int i;
+ printf("vp8_encode_intra16x16mbuv\n");
+ printf("%d %d:\n", x->e_mbd.mb_to_left_edge, x->e_mbd.mb_to_top_edge);
+ printf("qcoeff:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.qcoeff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("dqcoeff:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.dqcoeff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("diff:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.diff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("predictor:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.predictor[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("eobs:\n");
+ for (i=0;i<25;i++)
+ printf("%d ", x->e_mbd.block[i].eob);
+ printf("\n");
+ }
+#endif
if (x->optimize)
+ {
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_optimize_mbuv_8x8(x, rtcd);
+ else
+#endif
vp8_optimize_mbuv(x, rtcd);
+ }
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_inverse_transform_mbuv_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+ else
+#endif
vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c
index 3ed16b681..408a5956e 100644
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -26,6 +26,11 @@
#else
#define IF_RTCD(x) NULL
#endif
+
+#ifdef ENC_DEBUG
+extern int enc_debug;
+#endif
+
void vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch)
{
unsigned char *src_ptr = (*(be->base_src) + be->src);
@@ -117,7 +122,21 @@ static void build_dcblock(MACROBLOCK *x)
src_diff_ptr[i] = x->coeff[i * 16];
}
}
-
+#if CONFIG_T8X8
+void vp8_build_dcblock_8x8(MACROBLOCK *x)
+{
+ short *src_diff_ptr = &x->src_diff[384];
+ int i;
+ for (i = 0; i < 16; i++)
+ {
+ src_diff_ptr[i] = 0;
+ }
+ src_diff_ptr[0] = x->coeff[0 * 16];
+ src_diff_ptr[1] = x->coeff[4 * 16];
+ src_diff_ptr[4] = x->coeff[8 * 16];
+ src_diff_ptr[8] = x->coeff[12 * 16];
+}
+#endif
void vp8_transform_mbuv(MACROBLOCK *x)
{
int i;
@@ -197,10 +216,104 @@ static void transform_mby(MACROBLOCK *x)
}
}
+#if CONFIG_T8X8
+void vp8_transform_mbuv_8x8(MACROBLOCK *x)
+{
+ int i;
-#define RDTRUNC(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
+ for (i = 16; i < 24; i += 4)
+ {
+ x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i].coeff[0], 16);
+ }
+}
+
+
+void vp8_transform_intra_mby_8x8(MACROBLOCK *x)//changed
+{
+ int i;
+
+ for (i = 0; i < 9; i += 8)
+ {
+ x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i].coeff[0], 32);
+ }
+ for (i = 2; i < 11; i += 8)
+ {
+ x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i+2].coeff[0], 32);
+ }
+ // build dc block from 16 y dc values
+ vp8_build_dcblock_8x8(x);
+ //vp8_build_dcblock(x);
+
+ // do 2nd order transform on the dc block
+ x->short_fhaar2x2(&x->block[24].src_diff[0],
+ &x->block[24].coeff[0], 8);
+
+}
+
+
+void vp8_transform_mb_8x8(MACROBLOCK *x)
+{
+ int i;
+
+ for (i = 0; i < 9; i += 8)
+ {
+ x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i].coeff[0], 32);
+ }
+ for (i = 2; i < 11; i += 8)
+ {
+ x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i+2].coeff[0], 32);
+ }
+ // build dc block from 16 y dc values
+ if (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
+ vp8_build_dcblock_8x8(x);
+ //vp8_build_dcblock(x);
+
+ for (i = 16; i < 24; i += 4)
+ {
+ x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i].coeff[0], 16);
+ }
+
+ // do 2nd order transform on the dc block
+ if (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
+ x->short_fhaar2x2(&x->block[24].src_diff[0],
+ &x->block[24].coeff[0], 8);
+}
+
+void vp8_transform_mby_8x8(MACROBLOCK *x)
+{
+ int i;
+ for (i = 0; i < 9; i += 8)
+ {
+ x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i].coeff[0], 32);
+ }
+ for (i = 2; i < 11; i += 8)
+ {
+ x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
+ &x->block[i+2].coeff[0], 32);
+ }
+ // build dc block from 16 y dc values
+ if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
+ {
+ //vp8_build_dcblock(x);
+ vp8_build_dcblock_8x8(x);
+ x->short_fhaar2x2(&x->block[24].src_diff[0],
+ &x->block[24].coeff[0], 8);
+ }
+}
+
+#endif
+
+#define RDTRUNC(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
+#define RDTRUNC_8x8(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
typedef struct vp8_token_state vp8_token_state;
struct vp8_token_state{
@@ -214,7 +327,11 @@ struct vp8_token_state{
// TODO: experiments to find optimal multiple numbers
#define Y1_RD_MULT 4
#define UV_RD_MULT 2
+#if !CONFIG_EXTEND_QRANGE
#define Y2_RD_MULT 16
+#else
+#define Y2_RD_MULT 4
+#endif
static const int plane_rd_mult[4]=
{
@@ -577,27 +694,554 @@ void vp8_optimize_mbuv(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
}
}
+#if CONFIG_T8X8
+void optimize_b_8x8(MACROBLOCK *mb, int i, int type,
+ ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
+ ENTROPY_CONTEXT *a1, ENTROPY_CONTEXT *l1,
+ const VP8_ENCODER_RTCD *rtcd)
+{
+ BLOCK *b;
+ BLOCKD *d;
+ vp8_token_state tokens[65][2];
+ unsigned best_mask[2];
+ const short *dequant_ptr;
+ const short *coeff_ptr;
+ short *qcoeff_ptr;
+ short *dqcoeff_ptr;
+ int eob;
+ int i0;
+ int rc;
+ int x;
+ int sz = 0;
+ int next;
+ int rdmult;
+ int rddiv;
+ int final_eob;
+ int rd_cost0;
+ int rd_cost1;
+ int rate0;
+ int rate1;
+ int error0;
+ int error1;
+ int t0;
+ int t1;
+ int best;
+ int band;
+ int pt;
+
+ b = &mb->block[i];
+ d = &mb->e_mbd.block[i];
+
+ /* Enable this to test the effect of RDO as a replacement for the dynamic
+ * zero bin instead of an augmentation of it.
+ */
+#if 0
+ vp8_strict_quantize_b(b, d);
+#endif
+
+ dequant_ptr = d->dequant;
+ coeff_ptr = b->coeff;
+ qcoeff_ptr = d->qcoeff;
+ dqcoeff_ptr = d->dqcoeff;
+ i0 = !type;
+ eob = d->eob;
+
+ /* Now set up a Viterbi trellis to evaluate alternative roundings. */
+ /* TODO: These should vary with the block type, since the quantizer does. */
+ rdmult = mb->rdmult << 2;
+ rddiv = mb->rddiv;
+ best_mask[0] = best_mask[1] = 0;
+ /* Initialize the sentinel node of the trellis. */
+ tokens[eob][0].rate = 0;
+ tokens[eob][0].error = 0;
+ tokens[eob][0].next = 64;
+ tokens[eob][0].token = DCT_EOB_TOKEN;
+ tokens[eob][0].qc = 0;
+ *(tokens[eob] + 1) = *(tokens[eob] + 0);
+ next = eob;
+ for (i = eob; i-- > i0;)
+ {
+ int base_bits;
+ int d2;
+ int dx;
+
+ rc = vp8_default_zig_zag1d_8x8[i];
+ x = qcoeff_ptr[rc];
+ /* Only add a trellis state for non-zero coefficients. */
+ if (x)
+ {
+ int shortcut=0;
+ error0 = tokens[next][0].error;
+ error1 = tokens[next][1].error;
+ /* Evaluate the first possibility for this state. */
+ rate0 = tokens[next][0].rate;
+ rate1 = tokens[next][1].rate;
+ t0 = (vp8_dct_value_tokens_ptr + x)->Token;
+ /* Consider both possible successor states. */
+ if (next < 64)
+ {
+ band = vp8_coef_bands_8x8[i + 1];
+ pt = vp8_prev_token_class[t0];
+ rate0 +=
+ mb->token_costs[type][band][pt][tokens[next][0].token];
+ rate1 +=
+ mb->token_costs[type][band][pt][tokens[next][1].token];
+ }
+ rd_cost0 = RDCOST_8x8(rdmult, rddiv, rate0, error0);
+ rd_cost1 = RDCOST_8x8(rdmult, rddiv, rate1, error1);
+ if (rd_cost0 == rd_cost1)
+ {
+ rd_cost0 = RDTRUNC_8x8(rdmult, rddiv, rate0, error0);
+ rd_cost1 = RDTRUNC_8x8(rdmult, rddiv, rate1, error1);
+ }
+ /* And pick the best. */
+ best = rd_cost1 < rd_cost0;
+ base_bits = *(vp8_dct_value_cost_ptr + x);
+ dx = dqcoeff_ptr[rc] - coeff_ptr[rc];
+ d2 = dx*dx;
+ tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
+ tokens[i][0].error = d2 + (best ? error1 : error0);
+ tokens[i][0].next = next;
+ tokens[i][0].token = t0;
+ tokens[i][0].qc = x;
+ best_mask[0] |= best << i;
+ /* Evaluate the second possibility for this state. */
+ rate0 = tokens[next][0].rate;
+ rate1 = tokens[next][1].rate;
+
+ if((abs(x)*dequant_ptr[rc!=0]>abs(coeff_ptr[rc])) &&
+ (abs(x)*dequant_ptr[rc!=0]<abs(coeff_ptr[rc])+dequant_ptr[rc!=0]))
+ shortcut = 1;
+ else
+ shortcut = 0;
+
+ if(shortcut)
+ {
+ sz = -(x < 0);
+ x -= 2*sz + 1;
+ }
+
+ /* Consider both possible successor states. */
+ if (!x)
+ {
+ /* If we reduced this coefficient to zero, check to see if
+ * we need to move the EOB back here.
+ */
+ t0 = tokens[next][0].token == DCT_EOB_TOKEN ?
+ DCT_EOB_TOKEN : ZERO_TOKEN;
+ t1 = tokens[next][1].token == DCT_EOB_TOKEN ?
+ DCT_EOB_TOKEN : ZERO_TOKEN;
+ }
+ else
+ {
+ t0=t1 = (vp8_dct_value_tokens_ptr + x)->Token;
+ }
+ if (next < 64)
+ {
+ band = vp8_coef_bands_8x8[i + 1];
+ if(t0!=DCT_EOB_TOKEN)
+ {
+ pt = vp8_prev_token_class[t0];
+ rate0 += mb->token_costs[type][band][pt][
+ tokens[next][0].token];
+ }
+ if(t1!=DCT_EOB_TOKEN)
+ {
+ pt = vp8_prev_token_class[t1];
+ rate1 += mb->token_costs[type][band][pt][
+ tokens[next][1].token];
+ }
+ }
+
+ rd_cost0 = RDCOST_8x8(rdmult, rddiv, rate0, error0);
+ rd_cost1 = RDCOST_8x8(rdmult, rddiv, rate1, error1);
+ if (rd_cost0 == rd_cost1)
+ {
+ rd_cost0 = RDTRUNC_8x8(rdmult, rddiv, rate0, error0);
+ rd_cost1 = RDTRUNC_8x8(rdmult, rddiv, rate1, error1);
+ }
+ /* And pick the best. */
+ best = rd_cost1 < rd_cost0;
+ base_bits = *(vp8_dct_value_cost_ptr + x);
+
+ if(shortcut)
+ {
+ dx -= (dequant_ptr[rc!=0] + sz) ^ sz;
+ d2 = dx*dx;
+ }
+ tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
+ tokens[i][1].error = d2 + (best ? error1 : error0);
+ tokens[i][1].next = next;
+ tokens[i][1].token =best?t1:t0;
+ tokens[i][1].qc = x;
+ best_mask[1] |= best << i;
+ /* Finally, make this the new head of the trellis. */
+ next = i;
+ }
+ /* There's no choice to make for a zero coefficient, so we don't
+ * add a new trellis node, but we do need to update the costs.
+ */
+ else
+ {
+ band = vp8_coef_bands_8x8[i + 1];
+ t0 = tokens[next][0].token;
+ t1 = tokens[next][1].token;
+ /* Update the cost of each path if we're past the EOB token. */
+ if (t0 != DCT_EOB_TOKEN)
+ {
+ tokens[next][0].rate += mb->token_costs[type][band][0][t0];
+ tokens[next][0].token = ZERO_TOKEN;
+ }
+ if (t1 != DCT_EOB_TOKEN)
+ {
+ tokens[next][1].rate += mb->token_costs[type][band][0][t1];
+ tokens[next][1].token = ZERO_TOKEN;
+ }
+ /* Don't update next, because we didn't add a new node. */
+ }
+ }
+
+ /* Now pick the best path through the whole trellis. */
+ band = vp8_coef_bands_8x8[i + 1];
+ VP8_COMBINEENTROPYCONTEXTS_8x8(pt, *a, *l, *a1, *l1);
+ rate0 = tokens[next][0].rate;
+ rate1 = tokens[next][1].rate;
+ error0 = tokens[next][0].error;
+ error1 = tokens[next][1].error;
+ t0 = tokens[next][0].token;
+ t1 = tokens[next][1].token;
+ rate0 += mb->token_costs[type][band][pt][t0];
+ rate1 += mb->token_costs[type][band][pt][t1];
+ rd_cost0 = RDCOST_8x8(rdmult, rddiv, rate0, error0);
+ rd_cost1 = RDCOST_8x8(rdmult, rddiv, rate1, error1);
+ if (rd_cost0 == rd_cost1)
+ {
+ rd_cost0 = RDTRUNC_8x8(rdmult, rddiv, rate0, error0);
+ rd_cost1 = RDTRUNC_8x8(rdmult, rddiv, rate1, error1);
+ }
+ best = rd_cost1 < rd_cost0;
+ final_eob = i0 - 1;
+ for (i = next; i < eob; i = next)
+ {
+ x = tokens[i][best].qc;
+ if (x)
+ final_eob = i;
+ rc = vp8_default_zig_zag1d_8x8[i];
+ qcoeff_ptr[rc] = x;
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0];
+ next = tokens[i][best].next;
+ best = (best_mask[best] >> i) & 1;
+ }
+ final_eob++;
+
+ d->eob = final_eob;
+ *a = *l = (d->eob != !type);
+
+}
+
+void optimize_mb_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
+{
+ int b;
+ int type;
+ int has_2nd_order;
+ ENTROPY_CONTEXT_PLANES t_above, t_left;
+ ENTROPY_CONTEXT *ta;
+ ENTROPY_CONTEXT *tl;
+
+ vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
+ vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
+
+ ta = (ENTROPY_CONTEXT *)&t_above;
+ tl = (ENTROPY_CONTEXT *)&t_left;
+
+ has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
+ && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
+ type = has_2nd_order ? 0 : 3;
+
+ for (b = 0; b < 16; b+=4)
+ {
+ optimize_b_8x8(x, b, type,
+ ta + vp8_block2above[b], tl + vp8_block2left[b],
+ ta + vp8_block2above[b+1], tl + vp8_block2left[b+4],
+ rtcd);
+
+ if(b==0)
+ {
+ *(ta + vp8_block2above[1]) = *(ta + vp8_block2above[4]) = *(ta + vp8_block2above[5]) = *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[1]) = *(tl + vp8_block2left[4]) = *(tl + vp8_block2left[5]) = *(tl + vp8_block2left[b]);
+ }
+ else if(b==4)
+ {
+ *(ta + vp8_block2above[2]) = *(ta + vp8_block2above[3]) = *(ta + vp8_block2above[6]) = *(ta + vp8_block2above[7]) = *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[2]) = *(tl + vp8_block2left[3]) = *(tl + vp8_block2left[6]) = *(tl + vp8_block2left[7]) = *(tl + vp8_block2left[b]);
+ *(ta + vp8_block2above[4]) = *(ta + vp8_block2above[1]);
+ *(tl + vp8_block2left[4]) = *(tl + vp8_block2left[1]);
+ }
+ else if(b==8)
+ {
+ *(ta + vp8_block2above[9]) = *(ta + vp8_block2above[12]) = *(ta + vp8_block2above[13]) = *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[9]) = *(tl + vp8_block2left[12]) = *(tl + vp8_block2left[13]) = *(tl + vp8_block2left[b]);
+
+ }
+ else if(b==12)
+ {
+ *(ta + vp8_block2above[10]) = *(ta + vp8_block2above[11]) = *(ta + vp8_block2above[14]) = *(ta + vp8_block2above[15]) = *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[10]) = *(tl + vp8_block2left[11]) = *(tl + vp8_block2left[14]) = *(tl + vp8_block2left[15]) = *(tl + vp8_block2left[b]);
+ *(ta + vp8_block2above[12]) = *(ta + vp8_block2above[8]);
+ *(tl + vp8_block2left[12]) = *(tl + vp8_block2left[8]);
+
+ }
+
+
+
+ }
+
+ for (b = 16; b < 20; b+=4)
+ {
+ optimize_b_8x8(x, b, PLANE_TYPE_UV, //vp8_block2type[b],
+ ta + vp8_block2above[b], tl + vp8_block2left[b],
+ ta + vp8_block2above[b+1], tl + vp8_block2left[b+2],
+ rtcd);
+ *(ta + vp8_block2above[b+1]) = *(ta + vp8_block2above[b+2]) = *(ta + vp8_block2above[b+3]) =
+ *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[b+1]) = *(tl + vp8_block2left[b+2]) = *(tl + vp8_block2left[b+3]) =
+ *(tl + vp8_block2left[b]);
+
+ }
+
+ for (b = 20; b < 24; b+=4)
+ {
+ optimize_b_8x8(x, b, PLANE_TYPE_UV, //vp8_block2type[b],
+ ta + vp8_block2above[b], tl + vp8_block2left[b],
+ ta + vp8_block2above[b+1], tl + vp8_block2left[b+2],
+ rtcd);
+ *(ta + vp8_block2above[b+1]) = *(ta + vp8_block2above[b+2]) = *(ta + vp8_block2above[b+3]) =
+ *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[b+1]) = *(tl + vp8_block2left[b+2]) = *(tl + vp8_block2left[b+3]) =
+ *(tl + vp8_block2left[b]);
+
+ }
+
+
+ /*
+ if (has_2nd_order)
+ {
+ vp8_setup_temp_context(&t, x->e_mbd.above_context[Y2CONTEXT],
+ x->e_mbd.left_context[Y2CONTEXT], 1);
+ optimize_b(x, 24, 1, t.a, t.l, rtcd);
+ }
+ */
+}
+
+void vp8_optimize_mby_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
+{
+ int b;
+ int type;
+ int has_2nd_order;
+
+ ENTROPY_CONTEXT_PLANES t_above, t_left;
+ ENTROPY_CONTEXT *ta;
+ ENTROPY_CONTEXT *tl;
+
+ if (!x->e_mbd.above_context)
+ return;
+
+ if (!x->e_mbd.left_context)
+ return;
+
+ vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
+ vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
+
+ ta = (ENTROPY_CONTEXT *)&t_above;
+ tl = (ENTROPY_CONTEXT *)&t_left;
+
+ has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
+ && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
+ type = has_2nd_order ? 0 : 3;
+
+ for (b = 0; b < 16; b+=4)
+ {
+ optimize_b_8x8(x, b, type,
+ ta + vp8_block2above[b], tl + vp8_block2left[b],
+ ta + vp8_block2above[b+1], tl + vp8_block2left[b+4],
+ rtcd);
+ if(b==0)
+ {
+ *(ta + vp8_block2above[1]) = *(ta + vp8_block2above[4]) = *(ta + vp8_block2above[5]) = *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[1]) = *(tl + vp8_block2left[4]) = *(tl + vp8_block2left[5]) = *(tl + vp8_block2left[b]);
+ }
+ else if(b==4)
+ {
+ *(ta + vp8_block2above[2]) = *(ta + vp8_block2above[3]) = *(ta + vp8_block2above[6]) = *(ta + vp8_block2above[7]) = *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[2]) = *(tl + vp8_block2left[3]) = *(tl + vp8_block2left[6]) = *(tl + vp8_block2left[7]) = *(tl + vp8_block2left[b]);
+ *(ta + vp8_block2above[4]) = *(ta + vp8_block2above[1]);
+ *(tl + vp8_block2left[4]) = *(tl + vp8_block2left[1]);
+ }
+ else if(b==8)
+ {
+ *(ta + vp8_block2above[9]) = *(ta + vp8_block2above[12]) = *(ta + vp8_block2above[13]) = *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[9]) = *(tl + vp8_block2left[12]) = *(tl + vp8_block2left[13]) = *(tl + vp8_block2left[b]);
+
+ }
+ else if(b==12)
+ {
+ *(ta + vp8_block2above[10]) = *(ta + vp8_block2above[11]) = *(ta + vp8_block2above[14]) = *(ta + vp8_block2above[15]) = *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[10]) = *(tl + vp8_block2left[11]) = *(tl + vp8_block2left[14]) = *(tl + vp8_block2left[15]) = *(tl + vp8_block2left[b]);
+ *(ta + vp8_block2above[12]) = *(ta + vp8_block2above[8]);
+ *(tl + vp8_block2left[12]) = *(tl + vp8_block2left[8]);
+
+ }
+
+
+ }
+
+ /*
+ if (has_2nd_order)
+ {
+ vp8_setup_temp_context(&t, x->e_mbd.above_context[Y2CONTEXT],
+ x->e_mbd.left_context[Y2CONTEXT], 1);
+ optimize_b(x, 24, 1, t.a, t.l, rtcd);
+ }
+ */
+}
+
+void vp8_optimize_mbuv_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
+{
+ int b;
+ ENTROPY_CONTEXT_PLANES t_above, t_left;
+ ENTROPY_CONTEXT *ta;
+ ENTROPY_CONTEXT *tl;
+
+ if (!x->e_mbd.above_context)
+ return;
+
+ if (!x->e_mbd.left_context)
+ return;
+
+ vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
+ vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
+
+ ta = (ENTROPY_CONTEXT *)&t_above;
+ tl = (ENTROPY_CONTEXT *)&t_left;
+
+ for (b = 16; b < 20; b+=4)
+ {
+ optimize_b_8x8(x, b, PLANE_TYPE_UV, //vp8_block2type[b],
+ ta + vp8_block2above[b], tl + vp8_block2left[b],
+ ta + vp8_block2above[b+1], tl + vp8_block2left[b+2],
+ rtcd);
+ *(ta + vp8_block2above[b+1]) = *(ta + vp8_block2above[b+2]) = *(ta + vp8_block2above[b+3]) =
+ *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[b+1]) = *(tl + vp8_block2left[b+2]) = *(tl + vp8_block2left[b+3]) =
+ *(tl + vp8_block2left[b]);
+
+ }
+
+ for (b = 20; b < 24; b+=4)
+ {
+ optimize_b_8x8(x, b, PLANE_TYPE_UV, //vp8_block2type[b],
+ ta + vp8_block2above[b], tl + vp8_block2left[b],
+ ta + vp8_block2above[b+1], tl + vp8_block2left[b+2],
+ rtcd);
+ *(ta + vp8_block2above[b+1]) = *(ta + vp8_block2above[b+2]) = *(ta + vp8_block2above[b+3]) =
+ *(ta + vp8_block2above[b]);
+ *(tl + vp8_block2left[b+1]) = *(tl + vp8_block2left[b+2]) = *(tl + vp8_block2left[b+3]) =
+ *(tl + vp8_block2left[b]);
+
+ }
+
+}
+#endif
+
void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
vp8_build_inter_predictors_mb(&x->e_mbd);
vp8_subtract_mb(rtcd, x);
- transform_mb(x);
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_transform_mb_8x8(x);
+ else
+#endif
+ transform_mb(x);
- vp8_quantize_mb(x);
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_quantize_mb_8x8(x);
+ else
+#endif
+ vp8_quantize_mb(x);
if (x->optimize)
+ {
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ optimize_mb_8x8(x, rtcd);
+ else
+#endif
optimize_mb(x, rtcd);
+ }
- vp8_inverse_transform_mb(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+ else
+#endif
+ vp8_inverse_transform_mb(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) {
+#ifdef ENC_DEBUG
+ if (enc_debug)
+ {
+ int i;
+ printf("qcoeff:\n");
+ printf("%d %d:\n", x->e_mbd.mb_to_left_edge, x->e_mbd.mb_to_top_edge);
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.qcoeff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("dqcoeff:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.dqcoeff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("diff:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.diff[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("predictor:\n");
+ for (i =0; i<400; i++) {
+ printf("%3d ", x->e_mbd.predictor[i]);
+ if (i%16 == 15) printf("\n");
+ }
+ printf("\n");
+ }
+#endif
+ }
RECON_INVOKE(&rtcd->common->recon, recon_mb)
(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
+#ifdef ENC_DEBUG
+ if (enc_debug) {
+ int i, j, k;
+ printf("Final Reconstruction\n");
+ for (i =0; i<16; i+=4) {
+ BLOCKD *b = &x->e_mbd.block[i];
+ unsigned char *d = *(b->base_dst) + b->dst;
+ for (k=0; k<4; k++) {
+ for (j=0; j<16; j++)
+ printf("%3d ", d[j]);
+ printf("\n");
+ d+=b->dst_stride;
+ }
+ }
+ }
+#endif
}
-/* this funciton is used by first pass only */
+/* this function is used by first pass only */
void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
BLOCK *b = &x->block[0];
@@ -606,22 +1250,34 @@ void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride);
- transform_mby(x);
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_transform_mby_8x8(x);
+ else
+#endif
+ transform_mby(x);
vp8_quantize_mby(x);
-
- vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+ else
+#endif
+ vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
RECON_INVOKE(&rtcd->common->recon, recon_mby)
(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
}
-
void vp8_encode_inter16x16uvrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
vp8_build_inter_predictors_mbuv(&x->e_mbd);
ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
-
+#if CONFIG_T8X8
+ if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+ vp8_transform_mbuv_8x8(x);
+ else
+#endif
vp8_transform_mbuv(x);
vp8_quantize_mbuv(x);
diff --git a/vp8/encoder/encodemb.h b/vp8/encoder/encodemb.h
index 47fc72dad..73f1ad223 100644
--- a/vp8/encoder/encodemb.h
+++ b/vp8/encoder/encodemb.h
@@ -103,4 +103,16 @@ void vp8_encode_inter16x16uvrd(const struct VP8_ENCODER_RTCD *rtcd, MACROBLOCK *
void vp8_optimize_mby(MACROBLOCK *x, const struct VP8_ENCODER_RTCD *rtcd);
void vp8_optimize_mbuv(MACROBLOCK *x, const struct VP8_ENCODER_RTCD *rtcd);
void vp8_encode_inter16x16y(const struct VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x);
+
+#if CONFIG_T8X8
+void vp8_transform_mb_8x8(MACROBLOCK *mb);
+void vp8_transform_mbuv_8x8(MACROBLOCK *x);
+void vp8_transform_intra_mby_8x8(MACROBLOCK *x);
+void vp8_build_dcblock_8x8(MACROBLOCK *b);
+void vp8_optimize_mby_8x8(MACROBLOCK *x, const struct VP8_ENCODER_RTCD *rtcd);
+void vp8_optimize_mbuv_8x8(MACROBLOCK *x, const struct VP8_ENCODER_RTCD *rtcd);
+#endif
+
+
+
#endif
diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c
index 1a37f03b9..6b9dff8d9 100644
--- a/vp8/encoder/ethreading.c
+++ b/vp8/encoder/ethreading.c
@@ -24,6 +24,14 @@ extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
extern void vp8_build_block_offsets(MACROBLOCK *x);
extern void vp8_setup_block_ptrs(MACROBLOCK *x);
+#ifdef MODE_STATS
+extern unsigned int inter_y_modes[10];
+extern unsigned int inter_uv_modes[4];
+extern unsigned int inter_b_modes[15];
+extern unsigned int y_modes[5];
+extern unsigned int uv_modes[4];
+extern unsigned int b_modes[14];
+#endif
extern void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);
static THREAD_FUNCTION loopfilter_thread(void *p_data)
@@ -175,7 +183,7 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data)
{
*totalrate += vp8cx_encode_intra_macro_block(cpi, x, &tp);
#ifdef MODE_STATS
- y_modes[xd->mbmi.mode] ++;
+ y_modes[xd->mode_info_context->mbmi.mode] ++;
#endif
}
else
@@ -183,15 +191,15 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data)
*totalrate += vp8cx_encode_inter_macroblock(cpi, x, &tp, recon_yoffset, recon_uvoffset);
#ifdef MODE_STATS
- inter_y_modes[xd->mbmi.mode] ++;
+ inter_y_modes[xd->mode_info_context->mbmi.mode] ++;
- if (xd->mbmi.mode == SPLITMV)
+ if (xd->mode_info_context->mbmi.mode == SPLITMV)
{
int b;
- for (b = 0; b < xd->mbmi.partition_count; b++)
+ for (b = 0; b < x->partition_info->count; b++)
{
- inter_b_modes[x->partition->bmi[b].mode] ++;
+ inter_b_modes[x->partition_info->bmi[b].mode] ++;
}
}
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 8559142c9..f2a1cd2d6 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -548,7 +548,7 @@ void vp8_first_pass(VP8_COMP *cpi)
//if ( 0 )
{
int flag[2] = {1, 1};
- vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
+ vp8_initialize_rd_consts(cpi, cm->base_qindex+cm->y1dc_delta_q);
vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
}
diff --git a/vp8/encoder/generic/csystemdependent.c b/vp8/encoder/generic/csystemdependent.c
index a14843a80..fb22be05b 100644
--- a/vp8/encoder/generic/csystemdependent.c
+++ b/vp8/encoder/generic/csystemdependent.c
@@ -71,6 +71,10 @@ void vp8_cmachine_specific_config(VP8_COMP *cpi)
cpi->rtcd.variance.get4x4sse_cs = vp8_get4x4sse_cs_c;
+#if CONFIG_T8X8
+ cpi->rtcd.fdct.short8x8 = vp8_short_fdct8x8_c;
+ cpi->rtcd.fdct.haar_short2x2 = vp8_short_fhaar2x2_c;
+#endif
cpi->rtcd.fdct.short4x4 = vp8_short_fdct4x4_c;
cpi->rtcd.fdct.short8x4 = vp8_short_fdct8x4_c;
cpi->rtcd.fdct.fast4x4 = vp8_short_fdct4x4_c;
@@ -88,6 +92,12 @@ void vp8_cmachine_specific_config(VP8_COMP *cpi)
cpi->rtcd.quantize.quantb_pair = vp8_regular_quantize_b_pair;
cpi->rtcd.quantize.fastquantb = vp8_fast_quantize_b_c;
cpi->rtcd.quantize.fastquantb_pair = vp8_fast_quantize_b_pair_c;
+#if CONFIG_T8X8
+ cpi->rtcd.quantize.quantb_8x8 = vp8_regular_quantize_b_8x8;
+ cpi->rtcd.quantize.fastquantb_8x8 = vp8_fast_quantize_b_8x8_c;
+ cpi->rtcd.quantize.quantb_2x2 = vp8_regular_quantize_b_2x2;
+ cpi->rtcd.quantize.fastquantb_2x2 = vp8_fast_quantize_b_2x2_c;
+#endif
cpi->rtcd.search.full_search = vp8_full_search_sad;
cpi->rtcd.search.refining_search = vp8_refining_search_sad;
cpi->rtcd.search.diamond_search = vp8_diamond_search_sad;
@@ -111,4 +121,12 @@ void vp8_cmachine_specific_config(VP8_COMP *cpi)
vp8_arch_arm_encoder_init(cpi);
#endif
+#if CONFIG_EXTEND_QRANGE
+ cpi->rtcd.fdct.short4x4 = vp8_short_fdct4x4_c;
+ cpi->rtcd.fdct.short8x4 = vp8_short_fdct8x4_c;
+ cpi->rtcd.fdct.fast4x4 = vp8_short_fdct4x4_c;
+ cpi->rtcd.fdct.fast8x4 = vp8_short_fdct8x4_c;
+ cpi->rtcd.fdct.walsh_short4x4 = vp8_short_walsh4x4_c;
+#endif
+
}
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 35e187e54..e2fd622f3 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -105,6 +105,9 @@ extern double vp8_calc_ssimg
#ifdef OUTPUT_YUV_SRC
FILE *yuv_file;
#endif
+#ifdef OUTPUT_YUV_REC
+FILE *yuv_rec_file;
+#endif
#if 0
FILE *framepsnr;
@@ -130,15 +133,21 @@ unsigned int tot_ef = 0;
unsigned int cnt_ef = 0;
#endif
+#if defined(SECTIONBITS_OUTPUT)
+extern unsigned __int64 Sectionbits[500];
+#endif
#ifdef MODE_STATS
extern unsigned __int64 Sectionbits[50];
extern int y_modes[5] ;
extern int uv_modes[4] ;
extern int b_modes[10] ;
-
extern int inter_y_modes[10] ;
extern int inter_uv_modes[4] ;
extern unsigned int inter_b_modes[15];
+#if CONFIG_SEGMENTATION
+extern int segment_modes_intra[MAX_MB_SEGMENTS];
+extern int segment_modes_inter[MAX_MB_SEGMENTS];
+#endif
#endif
extern void (*vp8_short_fdct4x4)(short *input, short *output, int pitch);
@@ -150,7 +159,7 @@ extern const int qrounding_factors[129];
extern const int qzbin_factors[129];
extern void vp8cx_init_quantizer(VP8_COMP *cpi);
extern const int vp8cx_base_skip_false_prob[128];
-
+#if !CONFIG_EXTEND_QRANGE
// Tables relating active max Q to active min Q
static const int kf_low_motion_minq[QINDEX_RANGE] =
{
@@ -218,7 +227,76 @@ static const int inter_minq[QINDEX_RANGE] =
71,72,73,74,75,75,76,77,78,79,80,81,82,83,84,85,
86,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
};
+#else
+static const int kf_low_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
+ 9, 9, 9, 10,10,11,11,12,12,13,13,14,14,15,15,16,
+ 16,17,17,18,18,19,19,20,20,21,21,22,23,23,24,24,
+ 25,25,26,27,28,29,30,30,31,32,33,34,35,35,36,36,
+ 38,38,39,40,40,41,42,42,43,44,44,45,46,46,47,48,
+ 49,49,50,50,51,52,52,53,54,55,56,57,58,59,60,61,
+};
+static const int kf_high_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6,
+ 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10,
+ 11,11,12,13,14,15,16,17,18,19,20,21,22,23,24,24,
+ 25,26,27,28,28,29,29,30,30,31,31,32,33,33,34,34,
+ 35,36,37,38,39,39,40,41,41,42,43,44,45,45,46,46,
+ 47,47,48,48,49,49,50,50,51,51,52,52,53,53,54,54,
+ 55,55,56,56,57,58,59,60,61,62,63,64,65,67,69,70,
+};
+static const int gf_low_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,
+ 10,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,
+ 17,18,18,19,19,20,21,22,23,24,25,26,27,29,29,30,
+ 31,32,33,34,35,36,37,38,39,40,41,41,42,42,43,43,
+ 44,44,45,45,46,46,47,47,48,48,49,49,50,50,51,51,
+ 52,52,53,53,54,54,55,55,56,56,57,57,58,59,60,61,
+ 62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,
+};
+static const int gf_mid_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4,
+ 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9,10,
+ 10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,
+ 18,19,19,20,20,21,22,23,24,25,26,27,28,29,30,31,
+ 32,33,34,35,35,36,36,37,37,38,38,39,39,40,40,41,
+ 41,42,42,43,43,44,44,45,45,46,46,47,48,49,50,51,
+ 52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,
+ 68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,
+};
+static const int gf_high_motion_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4,
+ 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9,10,10,
+ 11,11,12,12,13,14,15,16,17,18,18,19,19,20,20,21,
+ 22,23,24,25,26,26,27,28,29,30,31,32,33,34,35,36,
+ 37,38,39,39,40,40,40,41,41,41,42,42,43,43,44,44,
+ 44,45,45,45,46,46,47,47,47,48,48,48,49,49,49,50,
+ 50,50,51,51,52,53,54,54,55,56,57,57,58,59,60,61,
+ 62,63,64,66,68,69,72,74,77,80,82,85,87,89,91,93,
+};
+
+static const int inter_minq[QINDEX_RANGE] =
+{
+ 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
+ 8, 9,10,11,12,13,14,15,16,17,18,18,19,19,20,21,
+ 21,22,23,23,24,25,26,26,27,28,29,30,31,32,32,33,
+ 34,35,36,36,37,38,39,40,40,41,41,42,43,44,44,45,
+ 46,46,47,47,48,49,49,50,50,51,52,52,53,54,54,55,
+ 55,56,57,57,58,59,60,60,61,62,63,63,64,65,66,67,
+ 68,68,69,70,71,72,72,73,74,75,76,77,78,79,80,81,
+ 81,82,83,84,85,86,87,88,89,90,90,91,92,93,94,95,
+};
+#endif
void vp8_initialize()
{
static int init_done = 0;
@@ -240,7 +318,11 @@ extern FILE *vpxlogc;
static void setup_features(VP8_COMP *cpi)
{
// Set up default state for MB feature flags
+#if CONFIG_SEGMENTATION
+ cpi->mb.e_mbd.segmentation_enabled = 1;
+#else
cpi->mb.e_mbd.segmentation_enabled = 0;
+#endif
cpi->mb.e_mbd.update_mb_segmentation_map = 0;
cpi->mb.e_mbd.update_mb_segmentation_data = 0;
vpx_memset(cpi->mb.e_mbd.mb_segment_tree_probs, 255, sizeof(cpi->mb.e_mbd.mb_segment_tree_probs));
@@ -339,7 +421,6 @@ static void set_segmentation_map(VP8_PTR ptr, unsigned char *segmentation_map)
// Copy in the new segmentation map
vpx_memcpy(cpi->segmentation_map, segmentation_map, (cpi->common.mb_rows * cpi->common.mb_cols));
-
// Signal that the map should be updated.
cpi->mb.e_mbd.update_mb_segmentation_map = 1;
cpi->mb.e_mbd.update_mb_segmentation_data = 1;
@@ -365,12 +446,10 @@ static void set_segment_data(VP8_PTR ptr, signed char *feature_data, unsigned ch
static void segmentation_test_function(VP8_PTR ptr)
{
VP8_COMP *cpi = (VP8_COMP *)(ptr);
-
unsigned char *seg_map;
signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];
-
+ CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
// Create a temporary map for segmentation data.
- CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
// MB loop to set local segmentation map
/*for ( i = 0; i < cpi->common.mb_rows; i++ )
@@ -430,7 +509,7 @@ static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment)
int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols;
// Create a temporary map for segmentation data.
- CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+ CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
cpi->cyclic_refresh_q = Q;
@@ -1169,16 +1248,25 @@ void vp8_set_speed_features(VP8_COMP *cpi)
if (cpi->sf.improved_dct)
{
+#if CONFIG_T8X8
+ cpi->mb.vp8_short_fdct8x8 = FDCT_INVOKE(&cpi->rtcd.fdct, short8x8);
+#endif
cpi->mb.vp8_short_fdct8x4 = FDCT_INVOKE(&cpi->rtcd.fdct, short8x4);
cpi->mb.vp8_short_fdct4x4 = FDCT_INVOKE(&cpi->rtcd.fdct, short4x4);
}
else
{
+#if CONFIG_T8X8
+ cpi->mb.vp8_short_fdct8x8 = FDCT_INVOKE(&cpi->rtcd.fdct, short8x8);
+#endif
cpi->mb.vp8_short_fdct8x4 = FDCT_INVOKE(&cpi->rtcd.fdct, fast8x4);
cpi->mb.vp8_short_fdct4x4 = FDCT_INVOKE(&cpi->rtcd.fdct, fast4x4);
}
cpi->mb.short_walsh4x4 = FDCT_INVOKE(&cpi->rtcd.fdct, walsh_short4x4);
+#if CONFIG_T8X8
+ cpi->mb.short_fhaar2x2 = FDCT_INVOKE(&cpi->rtcd.fdct, haar_short2x2);
+#endif
if (cpi->sf.improved_quant)
{
@@ -1186,6 +1274,10 @@ void vp8_set_speed_features(VP8_COMP *cpi)
quantb);
cpi->mb.quantize_b_pair = QUANTIZE_INVOKE(&cpi->rtcd.quantize,
quantb_pair);
+#if CONFIG_T8X8
+ cpi->mb.quantize_b_8x8 = QUANTIZE_INVOKE(&cpi->rtcd.quantize, quantb_8x8);
+ cpi->mb.quantize_b_2x2 = QUANTIZE_INVOKE(&cpi->rtcd.quantize, quantb_2x2);
+#endif
}
else
{
@@ -1193,6 +1285,10 @@ void vp8_set_speed_features(VP8_COMP *cpi)
fastquantb);
cpi->mb.quantize_b_pair = QUANTIZE_INVOKE(&cpi->rtcd.quantize,
fastquantb_pair);
+#if CONFIG_T8X8
+ cpi->mb.quantize_b_8x8 = QUANTIZE_INVOKE(&cpi->rtcd.quantize, fastquantb_8x8);
+ cpi->mb.quantize_b_2x2 = QUANTIZE_INVOKE(&cpi->rtcd.quantize, fastquantb_2x2);
+#endif
}
if (cpi->sf.improved_quant != last_improved_quant)
vp8cx_init_quantizer(cpi);
@@ -1843,7 +1939,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
CHECK_MEM_ERROR(cpi->lf_ref_frame, vpx_calloc((cpi->common.mb_rows+2) * (cpi->common.mb_cols+2), sizeof(int)));
// Create the encoder segmentation map and set all entries to 0
- CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+ CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
cpi->active_map_enabled = 0;
@@ -1879,13 +1975,12 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
cpi->cyclic_refresh_q = 32;
if (cpi->cyclic_refresh_mode_enabled)
- {
CHECK_MEM_ERROR(cpi->cyclic_refresh_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
- }
else
cpi->cyclic_refresh_map = (signed char *) NULL;
// Test function for segmentation
+
//segmentation_test_function((VP8_PTR) cpi);
#ifdef ENTROPY_STATS
@@ -1976,6 +2071,9 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
#ifdef OUTPUT_YUV_SRC
yuv_file = fopen("bd.yuv", "ab");
#endif
+#ifdef OUTPUT_YUV_REC
+ yuv_rec_file = fopen("rec.yuv", "wb");
+#endif
#if 0
framepsnr = fopen("framepsnr.stt", "a");
@@ -2194,8 +2292,8 @@ void vp8_remove_compressor(VP8_PTR *ptr)
#ifdef MODE_STATS
{
extern int count_mb_seg[4];
- FILE *f = fopen("modes.stt", "a");
- double dr = (double)cpi->oxcf.frame_rate * (double)bytes * (double)8 / (double)count / (double)1000 ;
+ FILE *f = fopen("modes.stt", "w");
+ double dr = (double)cpi->oxcf.frame_rate * (double)cpi->bytes * (double)8 / (double)cpi->count / (double)1000 ;
fprintf(f, "intra_mode in Intra Frames:\n");
fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], y_modes[2], y_modes[3], y_modes[4]);
fprintf(f, "UV:%8d, %8d, %8d, %8d\n", uv_modes[0], uv_modes[1], uv_modes[2], uv_modes[3]);
@@ -2209,6 +2307,9 @@ void vp8_remove_compressor(VP8_PTR *ptr)
fprintf(f, "\n");
}
+#if CONFIG_SEGMENTATION
+ fprintf(f, "Segments:%8d, %8d, %8d, %8d\n", segment_modes_intra[0], segment_modes_intra[1], segment_modes_intra[2], segment_modes_intra[3]);
+#endif
fprintf(f, "Modes in Inter Frames:\n");
fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n",
@@ -2228,8 +2329,9 @@ void vp8_remove_compressor(VP8_PTR *ptr)
fprintf(f, "P:%8d, %8d, %8d, %8d\n", count_mb_seg[0], count_mb_seg[1], count_mb_seg[2], count_mb_seg[3]);
fprintf(f, "PB:%8d, %8d, %8d, %8d\n", inter_b_modes[LEFT4X4], inter_b_modes[ABOVE4X4], inter_b_modes[ZERO4X4], inter_b_modes[NEW4X4]);
-
-
+#if CONFIG_SEGMENTATION
+ fprintf(f, "Segments:%8d, %8d, %8d, %8d\n", segment_modes_inter[0], segment_modes_inter[1], segment_modes_inter[2], segment_modes_inter[3]);
+#endif
fclose(f);
}
#endif
@@ -2317,6 +2419,9 @@ void vp8_remove_compressor(VP8_PTR *ptr)
#ifdef OUTPUT_YUV_SRC
fclose(yuv_file);
#endif
+#ifdef OUTPUT_YUV_REC
+ fclose(yuv_rec_file);
+#endif
#if 0
@@ -2527,10 +2632,9 @@ int vp8_update_entropy(VP8_PTR comp, int update)
}
-#if OUTPUT_YUV_SRC
-void vp8_write_yuv_frame(const char *name, YV12_BUFFER_CONFIG *s)
+#ifdef OUTPUT_YUV_SRC
+void vp8_write_yuv_frame(YV12_BUFFER_CONFIG *s)
{
- FILE *yuv_file = fopen(name, "ab");
unsigned char *src = s->y_buffer;
int h = s->y_height;
@@ -2560,8 +2664,42 @@ void vp8_write_yuv_frame(const char *name, YV12_BUFFER_CONFIG *s)
src += s->uv_stride;
}
while (--h);
+}
+#endif
+
+#ifdef OUTPUT_YUV_REC
+void vp8_write_yuv_rec_frame(VP8_COMMON *cm)
+{
+ YV12_BUFFER_CONFIG *s = cm->frame_to_show;
+ unsigned char *src = s->y_buffer;
+ int h = cm->Height;
+
+ do
+ {
+ fwrite(src, s->y_width, 1, yuv_rec_file);
+ src += s->y_stride;
+ }
+ while (--h);
+
+ src = s->u_buffer;
+ h = (cm->Height+1)/2;
+
+ do
+ {
+ fwrite(src, s->uv_width, 1, yuv_rec_file);
+ src += s->uv_stride;
+ }
+ while (--h);
- fclose(yuv_file);
+ src = s->v_buffer;
+ h = (cm->Height+1)/2;
+
+ do
+ {
+ fwrite(src, s->uv_width, 1, yuv_rec_file);
+ src += s->uv_stride;
+ }
+ while (--h);
}
#endif
@@ -2972,6 +3110,12 @@ static int decide_key_frame(VP8_COMP *cpi)
return code_key_frame;
}
+#if !CONFIG_EXTEND_QRANGE
+#define FIRSTPASS_QINDEX 26
+#else
+#define FIRSTPASS_QINDEX 49
+#endif
+
#if !(CONFIG_REALTIME_ONLY)
static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags)
@@ -3236,6 +3380,10 @@ static void encode_frame_to_data_rate
// Test code for segmentation of gf/arf (0,0)
//segmentation_test_function((VP8_PTR) cpi);
+#if CONFIG_SEGMENTATION
+ cpi->mb.e_mbd.segmentation_enabled = 1;
+ cpi->mb.e_mbd.update_mb_segmentation_map = 1;
+#endif
if (cpi->compressor_speed == 2)
{
@@ -3772,6 +3920,17 @@ static void encode_frame_to_data_rate
vp8_clear_system_state(); //__asm emms;
+#if 0
+ if (cpi->pass != 1)
+ {
+ FILE *f = fopen("q_used.stt", "a");
+ fprintf(f, "%4d, %4d, %8d\n", cpi->common.current_video_frame,
+ cpi->common.base_qindex, cpi->projected_frame_size);
+ fclose(f);
+ }
+#endif
+
+
// Test to see if the stats generated for this frame indicate that we should have coded a key frame
// (assuming that we didn't)!
if (cpi->pass != 2 && cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME)
@@ -4450,10 +4609,9 @@ static void encode_frame_to_data_rate
fclose(recon_file);
}
#endif
-
- // DEBUG
- //vp8_write_yuv_frame("encoder_recon.yuv", cm->frame_to_show);
-
+#ifdef OUTPUT_YUV_REC
+ vp8_write_yuv_rec_frame(cm);
+#endif
}
@@ -4807,7 +4965,7 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
}
else
#endif
- encode_frame_to_data_rate(cpi, size, dest, frame_flags);
+ encode_frame_to_data_rate(cpi, size, dest, frame_flags);
if (cpi->compressor_speed == 2)
{
@@ -4946,7 +5104,15 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
cpi->summed_quality += frame_ssim2 * weight;
cpi->summed_weights += weight;
-
+#if 0
+ {
+ FILE *f = fopen("q_used.stt", "a");
+ fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
+ cpi->common.current_video_frame,y2, u2, v2,
+ frame_psnr2, frame_ssim2);
+ fclose(f);
+ }
+#endif
}
}
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index aead2fbb7..8519b8f81 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -193,7 +193,11 @@ typedef struct
typedef struct
{
MACROBLOCK mb;
+#if CONFIG_SEGMENTATION
+ int segment_counts[MAX_MB_SEGMENTS + 8];
+#else
int segment_counts[MAX_MB_SEGMENTS];
+#endif
int totalrate;
} MB_ROW_COMP;
@@ -403,6 +407,11 @@ typedef struct VP8_COMP
//save vp8_tree_probs_from_distribution result for each frame to avoid repeat calculation
vp8_prob frame_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
unsigned int frame_branch_ct [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES][2];
+#if CONFIG_T8X8
+ unsigned int coef_counts_8x8 [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; /* for this frame */
+ vp8_prob frame_coef_probs_8x8 [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
+ unsigned int frame_branch_ct_8x8 [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES][2];
+#endif
int gfu_boost;
int kf_boost;
@@ -461,6 +470,10 @@ typedef struct VP8_COMP
int gf_update_recommended;
int skip_true_count;
int skip_false_count;
+#if CONFIG_T8X8
+ int t4x4_count;
+ int t8x8_count;
+#endif
unsigned char *segmentation_map;
signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; // Segment data (can be deltas or absolute values)
diff --git a/vp8/encoder/psnr.c b/vp8/encoder/psnr.c
index 5119bb8aa..7ecf6d7cd 100644
--- a/vp8/encoder/psnr.c
+++ b/vp8/encoder/psnr.c
@@ -13,7 +13,7 @@
#include "math.h"
#include "vp8/common/systemdependent.h" /* for vp8_clear_system_state() */
-#define MAX_PSNR 60
+#define MAX_PSNR 100
double vp8_mse2psnr(double Samples, double Peak, double Mse)
{
diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c
index 503d24123..328eabbf9 100644
--- a/vp8/encoder/quantize.c
+++ b/vp8/encoder/quantize.c
@@ -16,6 +16,10 @@
#include "quantize.h"
#include "vp8/common/quant_common.h"
+#ifdef ENC_DEBUG
+extern int enc_debug;
+#endif
+
#define EXACT_QUANT
#ifdef EXACT_FASTQUANT
@@ -77,7 +81,11 @@ void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
short *qcoeff_ptr = d->qcoeff;
short *dqcoeff_ptr = d->dqcoeff;
short *dequant_ptr = d->dequant;
+#if CONFIG_T8X8
+ vpx_memset(qcoeff_ptr, 0, 32);
+ vpx_memset(dqcoeff_ptr, 0, 32);
+#endif
eob = -1;
for (i = 0; i < 16; i++)
{
@@ -267,7 +275,8 @@ void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
d->eob = eob + 1;
}
-#endif
+#endif //EXACT_QUANT
+
void vp8_quantize_mby_c(MACROBLOCK *x)
{
@@ -301,6 +310,592 @@ void vp8_quantize_mbuv_c(MACROBLOCK *x)
x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
}
+#if CONFIG_T8X8
+
+#ifdef EXACT_FASTQUANT
+void vp8_fast_quantize_b_2x2_c(BLOCK *b, BLOCKD *d)
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *coeff_ptr = b->coeff;
+ short *zbin_ptr = b->zbin;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ short *quant_shift_ptr = b->quant_shift;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+ //double q2nd = 4;
+
+
+ vpx_memset(qcoeff_ptr, 0, 32);
+ vpx_memset(dqcoeff_ptr, 0, 32);
+
+ eob = -1;
+
+ for (i = 0; i < 4; i++)
+ {
+ rc = vp8_default_zig_zag1d[i];
+ z = coeff_ptr[rc];
+ //zbin = zbin_ptr[rc]/q2nd ;
+ zbin = zbin_ptr[rc] ;
+
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ if (x >= zbin)
+ {
+ //x += (round_ptr[rc]/q2nd);
+ x += (round_ptr[rc]);
+ //y = ((int)((int)(x * quant_ptr[rc] * q2nd) >> 16) + x)
+ // >> quant_shift_ptr[rc]; // quantize (x)
+ y = ((int)((int)(x * quant_ptr[rc]) >> 16) + x)
+ >> quant_shift_ptr[rc]; // quantize (x)
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
+
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ }
+ }
+ }
+ d->eob = eob + 1;
+}
+
+void vp8_fast_quantize_b_8x8_c(BLOCK *b, BLOCKD *d)// only ac and dc difference, no difference among ac
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *coeff_ptr = b->coeff;
+ short *zbin_ptr = b->zbin;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ short *quant_shift_ptr = b->quant_shift;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+ //double q1st = 2;
+ vpx_memset(qcoeff_ptr, 0, 64*sizeof(short));
+ vpx_memset(dqcoeff_ptr, 0, 64*sizeof(short));
+
+ eob = -1;
+
+ for (i = 0; i < 64; i++)
+ {
+ rc = vp8_default_zig_zag1d_8x8[i];
+ z = coeff_ptr[rc];
+ //zbin = zbin_ptr[rc!=0]/q1st ;
+ zbin = zbin_ptr[rc!=0] ;
+
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ if (x >= zbin)
+ {
+ //x += round_ptr[rc]/q1st;
+ //y = ((int)(((int)((x * quant_ptr[rc!=0] * q1st)) >> 16) + x))
+ // >> quant_shift_ptr[rc!=0]; // quantize (x)
+ x += round_ptr[rc];
+ y = ((int)(((int)((x * quant_ptr[rc!=0])) >> 16) + x))
+ >> quant_shift_ptr[rc!=0]; // quantize (x)
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ //dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0] / q1st; // dequantized value
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0]; // dequantized value
+
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ }
+ }
+ }
+ d->eob = eob + 1;
+}
+
+#else
+
+void vp8_fast_quantize_b_2x2_c(BLOCK *b, BLOCKD *d)
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *coeff_ptr = b->coeff;
+ short *zbin_ptr = b->zbin;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+ //double q2nd = 4;
+ vpx_memset(qcoeff_ptr, 0, 32);
+ vpx_memset(dqcoeff_ptr, 0, 32);
+
+ eob = -1;
+
+ for (i = 0; i < 4; i++)
+ {
+ rc = vp8_default_zig_zag1d[i];
+ z = coeff_ptr[rc];
+ //zbin = zbin_ptr[rc]/q2nd;
+ zbin = zbin_ptr[rc];
+
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ if (x >= zbin)
+ {
+ //y = ((int)((x + round_ptr[rc]/q2nd) * quant_ptr[rc] * q2nd)) >> 16; // quantize (x)
+ y = ((int)((x + round_ptr[rc]) * quant_ptr[rc])) >> 16; // quantize (x)
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ //dqcoeff_ptr[rc] = x * dequant_ptr[rc] / q2nd; // dequantized value
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
+
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ }
+ }
+ }
+ d->eob = eob + 1;
+ //if (d->eob > 4) printf("Flag Fast 2 (%d)\n", d->eob);
+}
+
+void vp8_fast_quantize_b_8x8_c(BLOCK *b, BLOCKD *d)
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *coeff_ptr = b->coeff;
+ short *zbin_ptr = b->zbin;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+ //double q1st = 2;
+ vpx_memset(qcoeff_ptr, 0, 64*sizeof(short));
+ vpx_memset(dqcoeff_ptr, 0, 64*sizeof(short));
+
+ eob = -1;
+
+ for (i = 0; i < 64; i++)
+ {
+
+ rc = vp8_default_zig_zag1d_8x8[i];
+ z = coeff_ptr[rc];
+ //zbin = zbin_ptr[rc!=0]/q1st ;
+ zbin = zbin_ptr[rc!=0] ;
+
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ if (x >= zbin)
+ {
+ //y = ((int)((x + round_ptr[rc!=0] / q1st) * quant_ptr[rc!=0] * q1st)) >> 16;
+ y = ((int)((x + round_ptr[rc!=0]) * quant_ptr[rc!=0])) >> 16;
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ //dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0] / q1st; // dequantized value
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0]; // dequantized value
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ }
+ }
+ }
+ d->eob = eob + 1;
+}
+
+#endif //EXACT_FASTQUANT
+
+#ifdef EXACT_QUANT
+void vp8_regular_quantize_b_2x2(BLOCK *b, BLOCKD *d)
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *zbin_boost_ptr = b->zrun_zbin_boost;
+ short *coeff_ptr = b->coeff;
+ short *zbin_ptr = b->zbin;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ unsigned char *quant_shift_ptr = b->quant_shift;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+ short zbin_oq_value = b->zbin_extra;
+ //double q2nd = 4;
+ vpx_memset(qcoeff_ptr, 0, 32);
+ vpx_memset(dqcoeff_ptr, 0, 32);
+
+ eob = -1;
+
+ for (i = 0; i < 4; i++)
+ {
+ rc = vp8_default_zig_zag1d[i];
+ z = coeff_ptr[rc];
+
+ //zbin = (zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value)/q2nd;
+ zbin = (zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value);
+
+ zbin_boost_ptr ++;
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ if (x >= zbin)
+ {
+ //x += (round_ptr[rc]/q2nd);
+ x += (round_ptr[rc]);
+ y = ((int)((int)(x * quant_ptr[rc]) >> 16) + x)
+ >> quant_shift_ptr[rc]; // quantize (x)
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ //dqcoeff_ptr[rc] = x * dequant_ptr[rc]/q2nd; // dequantized value
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
+
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength
+ }
+ }
+ }
+
+ d->eob = eob + 1;
+}
+
+void vp8_regular_quantize_b_8x8(BLOCK *b, BLOCKD *d)
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *zbin_boost_ptr = b->zrun_zbin_boost;
+ short *coeff_ptr = b->coeff;
+ short *zbin_ptr = b->zbin;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ unsigned char *quant_shift_ptr = b->quant_shift;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+ short zbin_oq_value = b->zbin_extra;
+ //double q1st = 2;
+
+ vpx_memset(qcoeff_ptr, 0, 64*sizeof(short));
+ vpx_memset(dqcoeff_ptr, 0, 64*sizeof(short));
+
+ eob = -1;
+
+ for (i = 0; i < 64; i++)
+ {
+
+ rc = vp8_default_zig_zag1d_8x8[i];
+ z = coeff_ptr[rc];
+
+ //zbin = (zbin_ptr[rc!=0] + *zbin_boost_ptr + zbin_oq_value)/q1st;
+ zbin = (zbin_ptr[rc!=0] + *zbin_boost_ptr + zbin_oq_value);
+
+ zbin_boost_ptr ++;
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ if (x >= zbin)
+ {
+ //x += (round_ptr[rc!=0]/q1st);
+ //y = ((int)(((int)(x * quant_ptr[rc!=0] * q1st) >> 16) + x))
+ // >> quant_shift_ptr[rc!=0]; // quantize (x)
+ x += (round_ptr[rc!=0]);
+ y = ((int)(((int)(x * quant_ptr[rc!=0]) >> 16) + x))
+ >> quant_shift_ptr[rc!=0]; // quantize (x)
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ //dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0] / q1st; // dequantized value
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0]; // dequantized value
+
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength
+ }
+ }
+ }
+
+ d->eob = eob + 1;
+}
+
+void vp8_strict_quantize_b_2x2(BLOCK *b, BLOCKD *d)
+{
+ int i;
+ int rc;
+ int eob;
+ int x;
+ int y;
+ int z;
+ int sz;
+ short *coeff_ptr;
+ short *quant_ptr;
+ unsigned char *quant_shift_ptr;
+ short *qcoeff_ptr;
+ short *dqcoeff_ptr;
+ short *dequant_ptr;
+ //double q2nd = 4;
+ coeff_ptr = b->coeff;
+ quant_ptr = b->quant;
+ quant_shift_ptr = b->quant_shift;
+ qcoeff_ptr = d->qcoeff;
+ dqcoeff_ptr = d->dqcoeff;
+ dequant_ptr = d->dequant;
+ eob = - 1;
+ vpx_memset(qcoeff_ptr, 0, 32);
+ vpx_memset(dqcoeff_ptr, 0, 32);
+ for (i = 0; i < 4; i++)
+ {
+ int dq;
+ int round;
+
+ /*TODO: These arrays should be stored in zig-zag order.*/
+ rc = vp8_default_zig_zag1d[i];
+ z = coeff_ptr[rc];
+ //z = z * q2nd;
+ //dq = dequant_ptr[rc]/q2nd;
+ dq = dequant_ptr[rc];
+ round = dq >> 1;
+ /* Sign of z. */
+ sz = -(z < 0);
+ x = (z + sz) ^ sz;
+ x += round;
+ if (x >= dq)
+ {
+ /* Quantize x */
+ y = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc];
+ /* Put the sign back. */
+ x = (y + sz) ^ sz;
+ /* Save * the * coefficient and its dequantized value. */
+ qcoeff_ptr[rc] = x;
+ dqcoeff_ptr[rc] = x * dq;
+ /* Remember the last non-zero coefficient. */
+ if (y)
+ eob = i;
+ }
+ }
+
+ d->eob = eob + 1;
+}
+
+void vp8_strict_quantize_b_8x8(BLOCK *b, BLOCKD *d)
+{
+ int i;
+ int rc;
+ int eob;
+ int x;
+ int y;
+ int z;
+ int sz;
+ short *coeff_ptr;
+ short *quant_ptr;
+ unsigned char *quant_shift_ptr;
+ short *qcoeff_ptr;
+ short *dqcoeff_ptr;
+ short *dequant_ptr;
+ //double q1st = 2;
+ printf("call strict quantizer\n");
+ coeff_ptr = b->coeff;
+ quant_ptr = b->quant;
+ quant_shift_ptr = b->quant_shift;
+ qcoeff_ptr = d->qcoeff;
+ dqcoeff_ptr = d->dqcoeff;
+ dequant_ptr = d->dequant;
+ eob = - 1;
+ vpx_memset(qcoeff_ptr, 0, 64*sizeof(short));
+ vpx_memset(dqcoeff_ptr, 0, 64*sizeof(short));
+ for (i = 0; i < 64; i++)
+ {
+ int dq;
+ int round;
+
+ /*TODO: These arrays should be stored in zig-zag order.*/
+ rc = vp8_default_zig_zag1d_8x8[i];
+ z = coeff_ptr[rc];
+ //z = z * q1st;
+ //dq = dequant_ptr[rc!=0]/q1st;
+ dq = dequant_ptr[rc!=0];
+ round = dq >> 1;
+ /* Sign of z. */
+ sz = -(z < 0);
+ x = (z + sz) ^ sz;
+ x += round;
+ if (x >= dq)
+ {
+ /* Quantize x. */
+ y = ((int)(((int)((x * quant_ptr[rc!=0])) >> 16) + x)) >> quant_shift_ptr[rc!=0];
+ /* Put the sign back. */
+ x = (y + sz) ^ sz;
+ /* Save the coefficient and its dequantized value. * */
+ qcoeff_ptr[rc] = x;
+ dqcoeff_ptr[rc] = x * dq;
+ /* Remember the last non-zero coefficient. */
+ if (y)
+ eob = i;
+ }
+ }
+ d->eob = eob + 1;
+}
+
+#else
+
+void vp8_regular_quantize_b_2x2(BLOCK *b, BLOCKD *d)
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *zbin_boost_ptr = b->zrun_zbin_boost;
+ short *coeff_ptr = b->coeff;
+ short *zbin_ptr = b->zbin;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+ short zbin_oq_value = b->zbin_extra;
+ //double q2nd = 4;
+ vpx_memset(qcoeff_ptr, 0, 32);
+ vpx_memset(dqcoeff_ptr, 0, 32);
+
+ eob = -1;
+ for (i = 0; i < 4; i++)
+ {
+ rc = vp8_default_zig_zag1d[i];
+ z = coeff_ptr[rc];
+ //zbin = (zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value)/q2nd;
+ zbin = (zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value);
+ zbin_boost_ptr ++;
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ if (x >= zbin)
+ {
+ //y = (((x + round_ptr[rc]/q2nd) * quant_ptr[rc]*q2nd)) >> 16; // quantize (x)
+ y = (((x + round_ptr[rc]) * quant_ptr[rc])) >> 16; // quantize (x)
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ //dqcoeff_ptr[rc] = x * dequant_ptr[rc]/q2nd; // dequantized value
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
+
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength
+ }
+ }
+ }
+
+ d->eob = eob + 1;
+}
+
+void vp8_regular_quantize_b_8x8(BLOCK *b, BLOCKD *d)
+{
+ int i, rc, eob;
+ int zbin;
+ int x, y, z, sz;
+ short *zbin_boost_ptr = b->zrun_zbin_boost;
+ short *coeff_ptr = b->coeff;
+ short *zbin_ptr = b->zbin;
+ short *round_ptr = b->round;
+ short *quant_ptr = b->quant;
+ short *qcoeff_ptr = d->qcoeff;
+ short *dqcoeff_ptr = d->dqcoeff;
+ short *dequant_ptr = d->dequant;
+ short zbin_oq_value = b->zbin_extra;
+ //double q1st = 2;
+ vpx_memset(qcoeff_ptr, 0, 64*sizeof(short));
+ vpx_memset(dqcoeff_ptr, 0, 64*sizeof(short));
+
+ eob = -1;
+ for (i = 0; i < 64; i++)
+ {
+
+ rc = vp8_default_zig_zag1d_8x8[i];
+ z = coeff_ptr[rc];
+ //zbin = (zbin_ptr[rc!=0] + *zbin_boost_ptr + zbin_oq_value)/q1st;
+ zbin = (zbin_ptr[rc!=0] + *zbin_boost_ptr + zbin_oq_value);
+ zbin_boost_ptr ++;
+ sz = (z >> 31); // sign of z
+ x = (z ^ sz) - sz; // x = abs(z)
+
+ if (x >= zbin)
+ {
+ //y = ((x + round_ptr[rc!=0]/q1st) * quant_ptr[rc!=0] * q1st) >> 16;
+ y = ((x + round_ptr[rc!=0]) * quant_ptr[rc!=0]) >> 16;
+ x = (y ^ sz) - sz; // get the sign back
+ qcoeff_ptr[rc] = x; // write to destination
+ //dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0]/q1st; // dequantized value
+ dqcoeff_ptr[rc] = x * dequant_ptr[rc!=0]; // dequantized value
+
+ if (y)
+ {
+ eob = i; // last nonzero coeffs
+ zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength
+ }
+ }
+ }
+ d->eob = eob + 1;
+}
+
+#endif //EXACT_QUANT
+
+void vp8_quantize_mby_8x8(MACROBLOCK *x)
+{
+ int i;
+ int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED
+ && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
+ for(i = 0; i < 16; i ++)
+ {
+ x->e_mbd.block[i].eob = 0;
+ }
+ x->e_mbd.block[24].eob = 0;
+ for (i = 0; i < 16; i+=4)
+ x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]);
+
+ if (has_2nd_order)
+ x->quantize_b_2x2(&x->block[24], &x->e_mbd.block[24]);
+
+}
+
+void vp8_quantize_mb_8x8(MACROBLOCK *x)
+{
+ int i;
+ int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED
+ && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
+ for(i = 0; i < 25; i ++)
+ {
+ x->e_mbd.block[i].eob = 0;
+ }
+ for (i = 0; i < 24; i+=4)
+ x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]);
+
+ if (has_2nd_order)
+ x->quantize_b_2x2(&x->block[24], &x->e_mbd.block[24]);
+}
+
+void vp8_quantize_mbuv_8x8(MACROBLOCK *x)
+{
+ int i;
+
+ for(i = 16; i < 24; i ++)
+ {
+ x->e_mbd.block[i].eob = 0;
+ }
+ for (i = 16; i < 24; i+=4)
+ x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]);
+}
+
+#endif //CONFIG_T8X8
+
/* quantize_b_pair function pointer in MACROBLOCK structure is set to one of
* these two C functions if corresponding optimized routine is not available.
* NEON optimized version implements currently the fast quantization for pair
diff --git a/vp8/encoder/quantize.h b/vp8/encoder/quantize.h
index f1f0156d8..1a2bad667 100644
--- a/vp8/encoder/quantize.h
+++ b/vp8/encoder/quantize.h
@@ -45,6 +45,27 @@ extern prototype_quantize_block_pair(vp8_quantize_quantb_pair);
#define vp8_quantize_fastquantb vp8_fast_quantize_b_c
#endif
extern prototype_quantize_block(vp8_quantize_fastquantb);
+#if CONFIG_T8X8
+#ifndef vp8_quantize_quantb_8x8
+#define vp8_quantize_quantb_8x8 vp8_regular_quantize_b_8x8
+#endif
+extern prototype_quantize_block(vp8_quantize_quantb_8x8);
+
+#ifndef vp8_quantize_fastquantb_8x8
+#define vp8_quantize_fastquantb_8x8 vp8_fast_quantize_b_8x8_c
+#endif
+extern prototype_quantize_block(vp8_quantize_fastquantb_8x8);
+
+#ifndef vp8_quantize_quantb_2x2
+#define vp8_quantize_quantb_2x2 vp8_regular_quantize_b_2x2
+#endif
+extern prototype_quantize_block(vp8_quantize_quantb_2x2);
+
+#ifndef vp8_quantize_fastquantb_2x2
+#define vp8_quantize_fastquantb_2x2 vp8_fast_quantize_b_2x2_c
+#endif
+extern prototype_quantize_block(vp8_quantize_fastquantb_2x2);
+#endif
#ifndef vp8_quantize_fastquantb_pair
#define vp8_quantize_fastquantb_pair vp8_fast_quantize_b_pair_c
@@ -56,6 +77,12 @@ typedef struct
prototype_quantize_block(*quantb);
prototype_quantize_block_pair(*quantb_pair);
prototype_quantize_block(*fastquantb);
+#if CONFIG_T8X8
+ prototype_quantize_block(*quantb_8x8);
+ prototype_quantize_block(*fastquantb_8x8);
+ prototype_quantize_block(*quantb_2x2);
+ prototype_quantize_block(*fastquantb_2x2);
+#endif
prototype_quantize_block_pair(*fastquantb_pair);
} vp8_quantize_rtcd_vtable_t;
@@ -81,7 +108,10 @@ extern prototype_quantize_mb(vp8_quantize_mby);
#endif
extern void vp8_strict_quantize_b(BLOCK *b,BLOCKD *d);
-
+#if CONFIG_T8X8
+extern void vp8_strict_quantize_b_8x8(BLOCK *b,BLOCKD *d);
+extern void vp8_strict_quantize_b_2x2(BLOCK *b,BLOCKD *d);
+#endif
struct VP8_COMP;
extern void vp8_set_quantizer(struct VP8_COMP *cpi, int Q);
extern void vp8cx_frame_init_quantizer(struct VP8_COMP *cpi);
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index 46e1d9dd9..f3dccfd05 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -48,6 +48,7 @@ extern int inter_b_modes[10];
// Work in progress recalibration of baseline rate tables based on
// the assumption that bits per mb is inversely proportional to the
// quantizer value.
+#if !CONFIG_EXTEND_QRANGE
const int vp8_bits_per_mb[2][QINDEX_RANGE] =
{
// Intra case 450000/Qintra
@@ -89,10 +90,54 @@ const int vp8_bits_per_mb[2][QINDEX_RANGE] =
11445, 11220, 11003, 10795, 10594, 10401, 10215, 10035,
}
};
+#else
+const int vp8_bits_per_mb[2][QINDEX_RANGE] =
+{
+ // (Updated DEC 2010) Baseline estimate of Bits Per MB at each Q:
+ // 4500000/Qintra
+ {
+ 4500000,3600000,3000000,2571428,2250000,2000000,1800000,1636363,
+ 1500000,1384615,1285714,1200000,1125000,1058823,1000000, 947368,
+ 900000, 818181, 750000, 692307, 642857, 600000, 562500, 529411,
+ 500000, 473684, 450000, 428571, 409090, 391304, 375000, 352941,
+ 333333, 315789, 300000, 285714, 272727, 260869, 250000, 236842,
+ 225000, 214285, 204545, 195652, 187500, 180000, 171428, 163636,
+ 156521, 150000, 144000, 138461, 133333, 128571, 123287, 118421,
+ 113924, 109756, 105882, 102272, 98901, 95744, 92783, 90000,
+ 87378, 84905, 82568, 80357, 77586, 75000, 72580, 70312,
+ 68181, 66176, 64285, 62500, 60810, 59210, 57692, 56250,
+ 54545, 52941, 51428, 50000, 48648, 47368, 45918, 44554,
+ 43269, 42056, 40909, 39647, 38461, 37344, 36290, 35294,
+ 34351, 33333, 32374, 31468, 30612, 29801, 28938, 28125,
+ 27355, 26627, 25862, 25139, 24456, 23809, 23195, 22613,
+ 21951, 21327, 20737, 20179, 19650, 19067, 18518, 18000,
+ 17441, 16917, 16423, 15957, 15410, 14900, 14376, 13846,
+ },
+ //2850000/Qinter
+ {
+ 2850000,2280000,1900000,1628571,1425000,1266666,1140000,1036363,
+ 950000, 876923, 814285, 760000, 712500, 670588, 633333, 600000,
+ 570000, 518181, 475000, 438461, 407142, 380000, 356250, 335294,
+ 316666, 300000, 285000, 271428, 259090, 247826, 237500, 223529,
+ 211111, 200000, 190000, 180952, 172727, 165217, 158333, 150000,
+ 142500, 135714, 129545, 123913, 118750, 114000, 108571, 103636,
+ 99130, 95000, 91200, 87692, 84444, 81428, 78082, 75000,
+ 72151, 69512, 67058, 64772, 62637, 60638, 58762, 57000,
+ 55339, 53773, 52293, 50892, 49137, 47500, 45967, 44531,
+ 43181, 41911, 40714, 39583, 38513, 37500, 36538, 35625,
+ 34545, 33529, 32571, 31666, 30810, 30000, 29081, 28217,
+ 27403, 26635, 25909, 25110, 24358, 23651, 22983, 22352,
+ 21755, 21111, 20503, 19930, 19387, 18874, 18327, 17812,
+ 17325, 16863, 16379, 15921, 15489, 15079, 14690, 14321,
+ 13902, 13507, 13133, 12780, 12445, 12076, 11728, 11400,
+ 11046, 10714, 10401, 10106, 9760, 9437, 9105, 8769,
+ }
+ };
+ #endif
static const int kf_boost_qadjustment[QINDEX_RANGE] =
-{
- 128, 129, 130, 131, 132, 133, 134, 135,
+ {
+ 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151,
152, 153, 154, 155, 156, 157, 158, 159,
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 992df71c2..952977094 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -155,6 +155,48 @@ static int rd_iifactor [ 32 ] = { 4, 4, 3, 2, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
+// 3* dc_qlookup[Q]*dc_qlookup[Q];
+#if !CONFIG_EXTEND_QRANGE
+static int rdmult_lut[QINDEX_RANGE]=
+{
+ 48,75,108,147,192,243,300,300,
+ 363,432,507,588,675,768,867,867,
+ 972,1083,1200,1200,1323,1323,1452,1452,
+ 1587,1587,1728,1875,1875,2028,2187,2352,
+ 2523,2700,2883,3072,3267,3468,3675,3888,
+ 4107,4107,4332,4563,4800,5043,5292,5547,
+ 5808,6075,6348,6348,6627,6912,7203,7500,
+ 7803,8112,8427,8748,9075,9408,9747,10092,
+ 10443,10800,11163,11532,11907,12288,12675,13068,
+ 13467,13872,14283,14700,15123,15552,15987,16428,
+ 16875,17328,17328,17787,18252,18723,19200,19683,
+ 20172,20667,21168,21675,22188,22707,23232,23763,
+ 24843,25947,27075,27648,28812,30000,30603,31212,
+ 32448,33708,34992,36300,37632,38988,40368,41772,
+ 44652,46128,47628,49152,50700,52272,53868,55488,
+ 57132,58800,61347,63075,65712,68403,71148,73947,
+};
+#else
+static int rdmult_lut[QINDEX_RANGE]=
+{
+ 3,5,7,9,12,15,19,23,
+ 27,32,37,42,48,54,61,68,
+ 75,83,91,99,108,117,127,137,
+ 147,169,192,217,243,271,300,331,
+ 363,397,450,507,567,631,698,768,
+ 842,919,999,1083,1170,1261,1355,1452,
+ 1587,1728,1875,2028,2187,2352,2523,2700,
+ 2883,3072,3267,3468,3675,3888,4107,4332,
+ 4563,4800,5043,5292,5547,5808,6075,6348,
+ 6627,6912,7203,7500,7880,8269,8667,9075,
+ 9492,9919,10355,10800,11255,11719,12192,12675,
+ 13167,13669,14180,14700,15230,15769,16317,16875,
+ 18019,19200,20419,21675,22969,24300,25669,27075,
+ 28519,30000,31519,33075,34669,36300,37969,39675,
+ 41772,43923,46128,48387,50700,53067,55488,57963,
+ 61347,64827,69312,73947,78732,83667,89787,97200,
+};
+#endif
/* values are now correlated to quantizer */
static int sad_per_bit16lut[QINDEX_RANGE] =
{
@@ -201,12 +243,14 @@ void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex)
cpi->mb.sadperbit4 = sad_per_bit4lut[QIndex];
}
-void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
+
+
+
+
+void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex)
{
int q;
int i;
- double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0;
- double rdconst = 2.70;
vp8_clear_system_state(); //__asm emms;
@@ -214,19 +258,18 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
// for key frames, golden frames and arf frames.
// if (cpi->common.refresh_golden_frame ||
// cpi->common.refresh_alt_ref_frame)
- cpi->RDMULT = (int)(rdconst * (capped_q * capped_q));
+ QIndex=(QIndex<0)? 0 : ((QIndex>127)?127 : QIndex);
+ cpi->RDMULT = rdmult_lut[QIndex];
// Extend rate multiplier along side quantizer zbin increases
if (cpi->zbin_over_quant > 0)
{
double oq_factor;
- double modq;
// Experimental code using the same basic equation as used for Q above
// The units of cpi->zbin_over_quant are 1/128 of Q bin size
oq_factor = 1.0 + ((double)0.0015625 * cpi->zbin_over_quant);
- modq = (int)((double)capped_q * oq_factor);
- cpi->RDMULT = (int)(rdconst * (modq * modq));
+ cpi->RDMULT = (int)((double)cpi->RDMULT * oq_factor * oq_factor);
}
if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME))
@@ -238,16 +281,31 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
(cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
}
+#if !CONFIG_EXTEND_QRANGE
+#else
+ if (cpi->RDMULT < 7)
+ cpi->RDMULT = 7;
+#endif
cpi->mb.errorperbit = (cpi->RDMULT / 110);
cpi->mb.errorperbit += (cpi->mb.errorperbit==0);
+#if CONFIG_EXTEND_QRANGE
+ if(cpi->mb.errorperbit<1)
+ cpi->mb.errorperbit=1;
+#endif
vp8_set_speed_features(cpi);
- q = (int)pow(Qvalue, 1.25);
+ q = (int)pow(vp8_dc_quant(QIndex,0), 1.25);
if (q < 8)
q = 8;
+
+
+#if CONFIG_EXTEND_QRANGE
+ cpi->RDMULT *= 16;
+#endif
+
if (cpi->RDMULT > 1000)
{
cpi->RDDIV = 1;
@@ -568,7 +626,12 @@ static void macro_block_yrd( MACROBLOCK *mb,
// Distortion
d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 1) << 2;
+
+#if CONFIG_EXTEND_QRANGE
+ d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff)<<2;
+#else
d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff);
+#endif
*Distortion = (d >> 4);
diff --git a/vp8/encoder/rdopt.h b/vp8/encoder/rdopt.h
index 95134cb81..ea04cbf25 100644
--- a/vp8/encoder/rdopt.h
+++ b/vp8/encoder/rdopt.h
@@ -13,6 +13,7 @@
#define __INC_RDOPT_H
#define RDCOST(RM,DM,R,D) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
+#define RDCOST_8x8(RM,DM,R,D) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
extern void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue);
extern void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra);
diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c
index 15e7336b1..e1e124844 100644
--- a/vp8/encoder/tokenize.c
+++ b/vp8/encoder/tokenize.c
@@ -22,18 +22,27 @@
#ifdef ENTROPY_STATS
_int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
+#if CONFIG_T8X8
+_int64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
+#endif
#endif
void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
+#if CONFIG_T8X8
+void vp8_stuff_mb_8x8(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
+#endif
void vp8_fix_contexts(MACROBLOCKD *x);
static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE*2];
const TOKENVALUE *vp8_dct_value_tokens_ptr;
static int dct_value_cost[DCT_MAX_VALUE*2];
const int *vp8_dct_value_cost_ptr;
-#if 0
-int skip_true_count = 0;
-int skip_false_count = 0;
+
+#ifdef ENC_DEBUG
+extern int mb_row_debug;
+extern int mb_col_debug;
+extern int enc_debug;
#endif
+
static void fill_value_tokens()
{
@@ -93,6 +102,69 @@ static void fill_value_tokens()
vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
}
+#if CONFIG_T8X8
+static void tokenize2nd_order_b_8x8
+(
+ 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);
+
+ assert(eob<=4);
+
+ 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;
+ //printf("Token : %d\n", x);
+ t->context_tree = cpi->common.fc.coef_probs_8x8 [type] [band] [pt];
+
+ t->skip_eob_node = pt == 0 && ((band > 0 && type > 0) || (band > 1 && type == 0));
+
+#ifdef ENC_DEBUG
+ if (t->skip_eob_node && vp8_coef_encodings[x].Len==1)
+ printf("Trouble 2 x=%d Len=%d skip=%d eob=%d c=%d band=%d type=%d: [%d %d %d]\n",
+ x, vp8_coef_encodings[x].Len, t->skip_eob_node, eob, c, band, type,
+ cpi->count, mb_row_debug, mb_col_debug);
+#endif
+
+ ++cpi->coef_counts_8x8 [type] [band] [pt] [x];
+ }
+ while (pt = vp8_prev_token_class[x], ++t, c < eob && ++c < 4);
+
+ *tp = t;
+ pt = (c != !type); /* 0 <-> all coeff data is zero */
+ *a = *l = pt;
+
+}
+#endif
+
static void tokenize2nd_order_b
(
MACROBLOCKD *x,
@@ -153,6 +225,66 @@ static void tokenize2nd_order_b
*a = *l = pt;
}
+#if CONFIG_T8X8
+static void tokenize1st_order_b_8x8
+(
+ 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,
+ ENTROPY_CONTEXT *a1,
+ ENTROPY_CONTEXT *l1,
+ VP8_COMP *cpi
+)
+{
+ int pt; /* near block/prev token context index */
+ int c = type ? 0 : 1; /* 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;
+ VP8_COMBINEENTROPYCONTEXTS_8x8(pt, *a, *l, *a1, *l1);
+
+ do
+ {
+ const int band = vp8_coef_bands_8x8[c];
+
+ x = DCT_EOB_TOKEN;
+
+ if (c < eob)
+ {
+ int rc = vp8_default_zig_zag1d_8x8[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;
+ }
+
+ t->Token = x;
+ t->context_tree = cpi->common.fc.coef_probs_8x8 [type] [band] [pt];
+
+ t->skip_eob_node = pt == 0 && ((band > 0 && type > 0) || (band > 1 && type == 0));
+
+#ifdef ENC_DEBUG
+ if (t->skip_eob_node && vp8_coef_encodings[x].Len==1)
+ printf("Trouble 1 x=%d Len=%d skip=%d eob=%d c=%d band=%d type=%d: [%d %d %d]\n", x, vp8_coef_encodings[x].Len, t->skip_eob_node, eob, c, band, type, cpi->count, mb_row_debug, mb_col_debug);
+#endif
+
+ ++cpi->coef_counts_8x8 [type] [band] [pt] [x];
+ }
+ while (pt = vp8_prev_token_class[x], ++t, c < eob && ++c < 64);
+
+ *tp = t;
+ pt = (c != !type); /* 0 <-> all coeff data is zero */
+ *a = *l = pt;
+}
+
+#endif
+
static void tokenize1st_order_b
(
@@ -293,22 +425,59 @@ static int mb_is_skippable(MACROBLOCKD *x, int has_y2_block)
return skip;
}
+#if CONFIG_T8X8
+static int mb_is_skippable_8x8(MACROBLOCKD *x)
+{
+ int has_y2_block;
+ int skip = 1;
+ int i = 0;
+
+ has_y2_block = (x->mode_info_context->mbmi.mode != B_PRED
+ && x->mode_info_context->mbmi.mode != SPLITMV);
+ if (has_y2_block)
+ {
+ for (i = 0; i < 16; i+=4)
+ skip &= (x->block[i].eob < 2);
+ }
+
+ for (; i < 24 + has_y2_block; i+=4)
+ skip &= (!x->block[i].eob);
+
+ return skip;
+}
+#endif
void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
{
int plane_type;
int has_y2_block;
+ int b;
has_y2_block = (x->mode_info_context->mbmi.mode != B_PRED
&& x->mode_info_context->mbmi.mode != SPLITMV);
- x->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable(x, has_y2_block);
+ x->mode_info_context->mbmi.mb_skip_coeff =
+#if CONFIG_T8X8
+ (x->mode_info_context->mbmi.segment_id >= 2 ?
+ mb_is_skippable_8x8(x) :
+ mb_is_skippable(x, has_y2_block));
+#else
+ mb_is_skippable(x, has_y2_block);
+#endif
+
if (x->mode_info_context->mbmi.mb_skip_coeff)
{
cpi->skip_true_count++;
if (!cpi->common.mb_no_coeff_skip)
- vp8_stuff_mb(cpi, x, t) ;
+ {
+#if CONFIG_T8X8
+ if (x->mode_info_context->mbmi.segment_id >= 2)
+ vp8_stuff_mb_8x8(cpi, x, t) ;
+ else
+#endif
+ vp8_stuff_mb(cpi, x, t) ;
+ }
else
{
vp8_fix_contexts(x);
@@ -322,13 +491,82 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
plane_type = 3;
if(has_y2_block)
{
- tokenize2nd_order_b(x, t, cpi);
- plane_type = 0;
+#if CONFIG_T8X8
+ if (x->mode_info_context->mbmi.segment_id >= 2)
+ {
+ ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context;
+ ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context;
+ tokenize2nd_order_b_8x8(x->block + 24, t, 1, x->frame_type,
+ A + vp8_block2above[24], L + vp8_block2left[24], cpi);
+ }
+ else
+#endif
+ tokenize2nd_order_b(x, t, cpi);
+
+ plane_type = 0;
}
+#if CONFIG_T8X8
+ if (x->mode_info_context->mbmi.segment_id >= 2)
+ {
+ ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context;
+ ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context;
+ for (b = 0; b < 16; b+=4)
+ {
+ tokenize1st_order_b_8x8(x->block + b, t, plane_type, x->frame_type,
+ A + vp8_block2above[b],
+ L + vp8_block2left[b],
+ A + vp8_block2above[b+1],
+ L + vp8_block2left[b+4],
+ cpi);
+ /* *(A + vp8_block2above[b+1]) = *(A + vp8_block2above[b+2]) = *(A + vp8_block2above[b+3]) =
+ *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[b+1]) = *(L + vp8_block2left[b+2]) = *(L + vp8_block2left[b+3]) =
+ *(L + vp8_block2left[b]);*/
+ // build coeff context for 8x8 transform
+ if(b==0)
+ {
+ *(A + vp8_block2above[1]) = *(A + vp8_block2above[4]) = *(A + vp8_block2above[5]) = *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[1]) = *(L + vp8_block2left[4]) = *(L + vp8_block2left[5]) = *(L + vp8_block2left[b]);
+ }
+ else if(b==4)
+ {
+ *(A + vp8_block2above[2]) = *(A + vp8_block2above[3]) = *(A + vp8_block2above[6]) = *(A + vp8_block2above[7]) = *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[2]) = *(L + vp8_block2left[3]) = *(L + vp8_block2left[6]) = *(L + vp8_block2left[7]) = *(L + vp8_block2left[b]);
+ *(A + vp8_block2above[4]) = *(A + vp8_block2above[1]);
+ *(L + vp8_block2left[4]) = *(L + vp8_block2left[1]);
+ }
+ else if(b==8)
+ {
+ *(A + vp8_block2above[9]) = *(A + vp8_block2above[12]) = *(A + vp8_block2above[13]) = *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[9]) = *(L + vp8_block2left[12]) = *(L + vp8_block2left[13]) = *(L + vp8_block2left[b]);
+ }
+ else if(b==12)
+ {
+ *(A + vp8_block2above[10]) = *(A + vp8_block2above[11]) = *(A + vp8_block2above[14]) = *(A + vp8_block2above[15]) = *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[10]) = *(L + vp8_block2left[11]) = *(L + vp8_block2left[14]) = *(L + vp8_block2left[15]) = *(L + vp8_block2left[b]);
+ *(A + vp8_block2above[12]) = *(A + vp8_block2above[8]);
+ *(L + vp8_block2left[12]) = *(L + vp8_block2left[8]);
+ }
- tokenize1st_order_b(x, t, plane_type, cpi);
+ }
+ for (b = 16; b < 24; b+=4) {
+ tokenize1st_order_b_8x8(x->block + b, t, 2, x->frame_type,
+ A + vp8_block2above[b],
+ L + vp8_block2left[b],
+ A + vp8_block2above[b+1],
+ L + vp8_block2left[b+2],
+ cpi);
+ *(A + vp8_block2above[b+1]) = *(A + vp8_block2above[b+2]) = *(A + vp8_block2above[b+3]) =
+ *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[b+1]) = *(L + vp8_block2left[b+2]) = *(L + vp8_block2left[b+3]) =
+ *(L + vp8_block2left[b]);
+ }
+ }
+ else
+#endif
+ tokenize1st_order_b(x, t, plane_type, cpi);
}
@@ -337,6 +575,9 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
void init_context_counters(void)
{
vpx_memset(context_counters, 0, sizeof(context_counters));
+#if CONFIG_T8X8
+ vpx_memset(context_counters_8x8, 0, sizeof(context_counters_8x8));
+#endif
}
void print_context_counters()
@@ -381,6 +622,55 @@ void print_context_counters()
const _int64 x = context_counters [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);
+
+#if CONFIG_T8X8
+ fprintf(f, "int Contexts_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];\n\n");
+
+ fprintf(f, "const int default_contexts_8x8[BLOCK_TYPES] [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 [type] [band] [pt] [t];
+ const int y = (int) x;
+
assert(x == (_int64) y); /* no overflow handling yet */
fprintf(f, "%s %d", Comma(t), y);
@@ -399,6 +689,7 @@ void print_context_counters()
fprintf(f, "\n }");
}
while (++type < BLOCK_TYPES);
+#endif
fprintf(f, "\n};\n");
fclose(f);
@@ -411,6 +702,188 @@ void vp8_tokenize_initialize()
fill_value_tokens();
}
+#if CONFIG_T8X8
+static __inline void stuff2nd_order_b_8x8
+(
+ 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_8x8 [1] [0] [pt];
+ //t->section = 11;
+ t->skip_eob_node = 0;
+ ++cpi->coef_counts_8x8 [1] [0] [pt] [DCT_EOB_TOKEN];
+ ++t;
+
+ *tp = t;
+ pt = 0;
+ *a = *l = pt;
+
+}
+
+static __inline void stuff1st_order_b_8x8
+(
+ 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,
+ ENTROPY_CONTEXT *a1,
+ ENTROPY_CONTEXT *l1,
+ VP8_COMP *cpi
+)
+{
+ int pt; /* near block/prev token context index */
+ TOKENEXTRA *t = *tp; /* store tokens starting here */
+ VP8_COMBINEENTROPYCONTEXTS_8x8(pt, *a, *l, *a1, *l1);
+ (void) frametype;
+ (void) type;
+ (void) b;
+
+ t->Token = DCT_EOB_TOKEN;
+ t->context_tree = cpi->common.fc.coef_probs_8x8 [0] [1] [pt];
+ //t->section = 8;
+ t->skip_eob_node = 0;
+ ++cpi->coef_counts_8x8 [0] [1] [pt] [DCT_EOB_TOKEN];
+ ++t;
+ *tp = t;
+ pt = 0; /* 0 <-> all coeff data is zero */
+ *a = *l = pt;
+
+
+}
+
+static __inline
+void stuff1st_order_buv_8x8
+(
+ 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,
+ ENTROPY_CONTEXT *a1,
+ ENTROPY_CONTEXT *l1,
+ VP8_COMP *cpi
+)
+{
+ int pt; /* near block/prev token context index */
+ TOKENEXTRA *t = *tp; /* store tokens starting here */
+ VP8_COMBINEENTROPYCONTEXTS_8x8(pt, *a, *l, *a1, *l1);
+ (void) frametype;
+ (void) type;
+ (void) b;
+
+ t->Token = DCT_EOB_TOKEN;
+ t->context_tree = cpi->common.fc.coef_probs_8x8 [2] [0] [pt];
+ //t->section = 13;
+ t->skip_eob_node = 0;
+ ++cpi->coef_counts_8x8[2] [0] [pt] [DCT_EOB_TOKEN];
+ ++t;
+ *tp = t;
+ pt = 0; /* 0 <-> all coeff data is zero */
+ *a = *l = pt;
+
+}
+
+void vp8_stuff_mb_8x8(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
+{
+ ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context;
+ ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context;
+ int plane_type;
+ int b;
+
+ stuff2nd_order_b_8x8(x->block + 24, t, 1, x->frame_type,
+ A + vp8_block2above[24], L + vp8_block2left[24], cpi);
+ plane_type = 0;
+
+ for (b = 0; b < 16; b+=4) {
+ stuff1st_order_b_8x8(x->block + b, t, plane_type, x->frame_type,
+ A + vp8_block2above[b],
+ L + vp8_block2left[b],
+ A + vp8_block2above[b+1],
+ L + vp8_block2left[b+4],
+ cpi);
+ // build coeff context for 8x8 transform
+ if(b==0)
+ {
+ *(A + vp8_block2above[1]) = *(A + vp8_block2above[4]) = *(A + vp8_block2above[5]) = *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[1]) = *(L + vp8_block2left[4]) = *(L + vp8_block2left[5]) = *(L + vp8_block2left[b]);
+ }
+ else if(b==4)
+ {
+ *(A + vp8_block2above[2]) = *(A + vp8_block2above[3]) = *(A + vp8_block2above[6]) = *(A + vp8_block2above[7]) = *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[2]) = *(L + vp8_block2left[3]) = *(L + vp8_block2left[6]) = *(L + vp8_block2left[7]) = *(L + vp8_block2left[b]);
+ *(A + vp8_block2above[4]) = *(A + vp8_block2above[1]);
+ *(L + vp8_block2left[4]) = *(L + vp8_block2left[1]);
+ }
+ else if(b==8)
+ {
+ *(A + vp8_block2above[9]) = *(A + vp8_block2above[12]) = *(A + vp8_block2above[13]) = *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[9]) = *(L + vp8_block2left[12]) = *(L + vp8_block2left[13]) = *(L + vp8_block2left[b]);
+
+ }
+ else if(b==12)
+ {
+ *(A + vp8_block2above[10]) = *(A + vp8_block2above[11]) = *(A + vp8_block2above[14]) = *(A + vp8_block2above[15]) = *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[10]) = *(L + vp8_block2left[11]) = *(L + vp8_block2left[14]) = *(L + vp8_block2left[15]) = *(L + vp8_block2left[b]);
+ *(A + vp8_block2above[12]) = *(A + vp8_block2above[8]);
+ *(L + vp8_block2left[12]) = *(L + vp8_block2left[8]);
+
+ }
+
+ }
+ /*
+ for (b = 0; b < 16; b+=4) {
+ stuff1st_order_b_8x8(x->block + b, t, plane_type, x->frame_type,
+ A + vp8_block2above[b],
+ L + vp8_block2left[b], cpi);
+ *(A + vp8_block2above[b+1]) = *(A + vp8_block2above[b+2]) = *(A + vp8_block2above[b+3]) =
+ *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[b+1]) = *(L + vp8_block2left[b+2]) = *(L + vp8_block2left[b+3]) =
+ *(L + vp8_block2left[b]);
+ }
+ */
+
+ 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],
+ A + vp8_block2above[b+1],
+ L + vp8_block2left[b+2],
+ cpi);
+ *(A + vp8_block2above[b+1]) = *(A + vp8_block2above[b+2]) = *(A + vp8_block2above[b+3]) =
+ *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[b+1]) = *(L + vp8_block2left[b+2]) = *(L + vp8_block2left[b+3]) =
+ *(L + vp8_block2left[b]);
+ }
+ /*
+ 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[b+1]) = *(A + vp8_block2above[b+2]) = *(A + vp8_block2above[b+3]) =
+ *(A + vp8_block2above[b]);
+ *(L + vp8_block2left[b+1]) = *(L + vp8_block2left[b+2]) = *(L + vp8_block2left[b+3]) =
+ *(L + vp8_block2left[b]);
+ }
+ */
+}
+#endif
static __inline void stuff2nd_order_b
(
diff --git a/vp8/encoder/tokenize.h b/vp8/encoder/tokenize.h
index 04a8879cf..cd122f19c 100644
--- a/vp8/encoder/tokenize.h
+++ b/vp8/encoder/tokenize.h
@@ -38,8 +38,10 @@ void init_context_counters();
void print_context_counters();
extern _int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
+#if CONFIG_T8X8
+extern _int64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
+#endif
#endif
-
extern const int *vp8_dct_value_cost_ptr;
/* TODO: The Token field should be broken out into a separate char array to
* improve cache locality, since it's needed for costing when the rest of the