diff --git a/configure b/configure index 1894cb47d..bfbe73d4f 100755 --- a/configure +++ b/configure @@ -223,6 +223,7 @@ EXPERIMENT_LIST=" high_precision_mv sixteenth_subpel_uv comp_intra_pred + newentropy " CONFIG_LIST=" external_build diff --git a/vp8/common/arm/arm_systemdependent.c b/vp8/common/arm/arm_systemdependent.c index c0467cd84..1b6f27970 100644 --- a/vp8/common/arm/arm_systemdependent.c +++ b/vp8/common/arm/arm_systemdependent.c @@ -40,6 +40,7 @@ void vp8_arch_arm_common_init(VP8_COMMON *ctx) rtcd->subpix.sixtap8x8 = vp8_sixtap_predict8x8_armv6; rtcd->subpix.sixtap8x4 = vp8_sixtap_predict8x4_armv6; rtcd->subpix.sixtap4x4 = vp8_sixtap_predict_armv6; + rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_armv6; rtcd->subpix.bilinear8x8 = vp8_bilinear_predict8x8_armv6; rtcd->subpix.bilinear8x4 = vp8_bilinear_predict8x4_armv6; @@ -77,6 +78,7 @@ void vp8_arch_arm_common_init(VP8_COMMON *ctx) rtcd->subpix.sixtap8x8 = vp8_sixtap_predict8x8_neon; rtcd->subpix.sixtap8x4 = vp8_sixtap_predict8x4_neon; rtcd->subpix.sixtap4x4 = vp8_sixtap_predict_neon; + rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_neon; rtcd->subpix.bilinear8x8 = vp8_bilinear_predict8x8_neon; rtcd->subpix.bilinear8x4 = vp8_bilinear_predict8x4_neon; diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index 88773e902..4504282f5 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -34,6 +34,10 @@ void vpx_log(const char *format, ...); #define MB_FEATURE_TREE_PROBS 3 #define PREDICTION_PROBS 3 +#if CONFIG_NEWENTROPY +#define MBSKIP_CONTEXTS 3 +#endif + #define MAX_MB_SEGMENTS 4 #define MAX_REF_LF_DELTAS 4 diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index 535eabb42..68ebb67d9 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -233,6 +233,10 @@ typedef struct VP8Common vp8_prob prob_comppred[COMP_PRED_CONTEXTS]; +#if CONFIG_NEWENTROPY + vp8_prob mbskip_pred_probs[MBSKIP_CONTEXTS]; +#endif + FRAME_CONTEXT lfc_a; /* last alt ref entropy */ FRAME_CONTEXT lfc; /* last frame entropy */ FRAME_CONTEXT fc; /* this frame entropy */ diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c index 6bbb619e5..0e01e6c8a 100644 --- a/vp8/common/pred_common.c +++ b/vp8/common/pred_common.c @@ -58,6 +58,13 @@ unsigned char get_pred_context( VP8_COMMON *const cm, break; +#if CONFIG_NEWENTROPY + case PRED_MBSKIP: + pred_context = (m - 1)->mbmi.mb_skip_coeff + + (m - cm->mode_info_stride)->mbmi.mb_skip_coeff; + break; +#endif + default: // TODO *** add error trap code. pred_context = 0; @@ -96,6 +103,12 @@ vp8_prob get_pred_prob( VP8_COMMON *const cm, pred_probability = cm->prob_comppred[pred_context]; break; +#if CONFIG_NEWENTROPY + case PRED_MBSKIP: + pred_probability = cm->mbskip_pred_probs[pred_context]; + break; +#endif + default: // TODO *** add error trap code. pred_probability = 128; @@ -122,11 +135,17 @@ unsigned char get_pred_flag( MACROBLOCKD *const xd, pred_flag = xd->mode_info_context->mbmi.ref_predicted; break; +#if CONFIG_NEWENTROPY + case PRED_MBSKIP: + pred_flag = xd->mode_info_context->mbmi.mb_skip_coeff; + break; +#endif + default: // TODO *** add error trap code. pred_flag = 0; break; -} + } return pred_flag; } @@ -147,6 +166,12 @@ void set_pred_flag( MACROBLOCKD *const xd, xd->mode_info_context->mbmi.ref_predicted = pred_flag; break; +#if CONFIG_NEWENTROPY + case PRED_MBSKIP: + xd->mode_info_context->mbmi.mb_skip_coeff = pred_flag; + break; +#endif + default: // TODO *** add error trap code. break; diff --git a/vp8/common/pred_common.h b/vp8/common/pred_common.h index cd68035b8..3499b0d41 100644 --- a/vp8/common/pred_common.h +++ b/vp8/common/pred_common.h @@ -21,7 +21,10 @@ typedef enum { PRED_SEG_ID = 0, // Segment identifier PRED_REF = 1, - PRED_COMP = 2 + PRED_COMP = 2, +#if CONFIG_NEWENTROPY + PRED_MBSKIP = 3, +#endif } PRED_ID; diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 07e4c9039..cc81c6883 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -17,6 +17,7 @@ #include "vp8/common/seg_common.h" #include "vp8/common/pred_common.h" +#include "vp8/common/entropy.h" #if CONFIG_DEBUG #include @@ -77,12 +78,14 @@ static void vp8_read_mb_segid(vp8_reader *r, MB_MODE_INFO *mi, MACROBLOCKD *x) mi->segment_id = (unsigned char)(vp8_read(r, x->mb_segment_tree_probs[1])); } } + extern const int vp8_i8x8_block[4]; static void vp8_kfread_modes(VP8D_COMP *pbi, MODE_INFO *m, int mb_row, int mb_col) { + VP8_COMMON *const cm = & pbi->common; vp8_reader *const bc = & pbi->bc; const int mis = pbi->common.mode_info_stride; int map_index = mb_row * pbi->common.mb_cols + mb_col; @@ -97,13 +100,20 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, pbi->common.last_frame_seg_map[map_index] = m->mbmi.segment_id; } + m->mbmi.mb_skip_coeff = 0; if ( pbi->common.mb_no_coeff_skip && ( !segfeature_active( &pbi->mb, m->mbmi.segment_id, SEG_LVL_EOB ) || ( get_segdata( &pbi->mb, m->mbmi.segment_id, SEG_LVL_EOB ) != 0 ) ) ) { +#if CONFIG_NEWENTROPY + MACROBLOCKD *const xd = & pbi->mb; + xd->mode_info_context = m; + m->mbmi.mb_skip_coeff = vp8_read(bc, get_pred_prob(cm, xd, PRED_MBSKIP)); +#else m->mbmi.mb_skip_coeff = vp8_read(bc, pbi->prob_skip_false); +#endif } else { @@ -511,9 +521,21 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) MACROBLOCKD *const xd = & pbi->mb; #endif +#if CONFIG_NEWENTROPY + vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs)); +#else pbi->prob_skip_false = 0; +#endif if (pbi->common.mb_no_coeff_skip) + { +#if CONFIG_NEWENTROPY + int k; + for (k=0; kmbskip_pred_probs[k] = (vp8_prob)vp8_read_literal(bc, 8); +#else pbi->prob_skip_false = (vp8_prob)vp8_read_literal(bc, 8); +#endif + } if(pbi->common.frame_type != KEY_FRAME) { @@ -683,7 +705,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, { // Read the macroblock coeff skip flag if this feature is in use, // else default to 0 +#if CONFIG_NEWENTROPY + mbmi->mb_skip_coeff = vp8_read(bc, get_pred_prob(cm, xd, PRED_MBSKIP)); +#else mbmi->mb_skip_coeff = vp8_read(bc, pbi->prob_skip_false); +#endif } else { @@ -1034,11 +1060,16 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi) { /*read_mb_modes_mv(pbi, xd->mode_info_context, &xd->mode_info_context->mbmi, mb_row, mb_col);*/ if(pbi->common.frame_type == KEY_FRAME) + { + //printf("<%d %d> \n", mb_row, mb_col); vp8_kfread_modes(pbi, mi, mb_row, mb_col); + } else + { read_mb_modes_mv(pbi, mi, &mi->mbmi, prev_mi, mb_row, mb_col); + } //printf("%3d", mi->mbmi.mode); diff --git a/vp8/decoder/detokenize.c b/vp8/decoder/detokenize.c index ae105b139..6ce39e194 100644 --- a/vp8/decoder/detokenize.c +++ b/vp8/decoder/detokenize.c @@ -97,6 +97,7 @@ void vp8_reset_mb_tokens_context(MACROBLOCKD *x) } DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); + #define FILL \ if(count < 0) \ VP8DX_BOOL_DECODER_FILL(count, value, bufptr, bufend); @@ -289,7 +290,7 @@ int vp8_decode_mb_tokens_8x8(VP8D_COMP *dx, MACROBLOCKD *x) INT16 val, bits_count; INT16 c; INT16 v; - const vp8_prob *Prob;// + const vp8_prob *Prob; int seg_eob; int segment_id = x->mode_info_context->mbmi.segment_id; @@ -323,6 +324,7 @@ BLOCK_LOOP_8x8: a = A + vp8_block2above_8x8[i]; l = L + vp8_block2left_8x8[i]; + c = (INT16)(!type); // Dest = ((A)!=0) + ((B)!=0); @@ -363,11 +365,11 @@ DO_WHILE_8x8: CHECK_0_8x8_: if (i==24) { - DECODE_AND_LOOP_IF_ZERO_8x8_2(Prob[ZERO_CONTEXT_NODE], CHECK_0_8x8_); + DECODE_AND_LOOP_IF_ZERO_8x8_2(Prob[ZERO_CONTEXT_NODE], CHECK_0_8x8_); } else { - DECODE_AND_LOOP_IF_ZERO_8X8(Prob[ZERO_CONTEXT_NODE], CHECK_0_8x8_); + DECODE_AND_LOOP_IF_ZERO_8X8(Prob[ZERO_CONTEXT_NODE], CHECK_0_8x8_); } DECODE_AND_BRANCH_IF_ZERO(Prob[ONE_CONTEXT_NODE], ONE_CONTEXT_NODE_0_8x8_); DECODE_AND_BRANCH_IF_ZERO(Prob[LOW_VAL_CONTEXT_NODE], @@ -516,6 +518,7 @@ ONE_CONTEXT_NODE_0_8x8_: { qcoeff_ptr [ scan[c] ] = (INT16) v; ++c; + goto DO_WHILE_8x8; } } @@ -539,7 +542,7 @@ BLOCK_FINISHED_8x8: *a = *l = ((eobs[i] = c) != !type); // any nonzero data? if (i!=24) { - *(a + 1) = *a; + *(a + 1) = *a; *(l + 1) = *l; } @@ -757,6 +760,7 @@ ONE_CONTEXT_NODE_0_: qcoeff_ptr [ 15 ] = (INT16) v; BLOCK_FINISHED: *a = *l = ((eobs[i] = c) != !type); /* any nonzero data? */ + eobtotal += c; qcoeff_ptr += 16; diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 8906f93fd..95bf3c3a2 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -151,6 +151,18 @@ static void write_split(vp8_writer *bc, int x) ); } +static int prob_update_savings(const unsigned int *ct, + const vp8_prob oldp, const vp8_prob newp, + const vp8_prob upd) +{ + const int old_b = vp8_cost_branch(ct, oldp); + const int new_b = vp8_cost_branch(ct, newp); + const int update_b = 8 + + ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8); + + return old_b - new_b - update_b; +} + static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount) { const TOKENEXTRA *const stop = p + xcount; @@ -170,10 +182,11 @@ static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount) int v = a->value; int n = a->Len; + /* skip one or two nodes */ if (p->skip_eob_node) { - n--; - i = 2; + n-=p->skip_eob_node; + i = 2*p->skip_eob_node; } do @@ -581,7 +594,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) const int mis = pc->mode_info_stride; int mb_row = -1; +#if CONFIG_NEWENTROPY + int prob_skip_false[3] = {0, 0, 0}; +#else int prob_skip_false = 0; +#endif // Values used in prediction model coding vp8_prob pred_prob; @@ -599,6 +616,28 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) if (pc->mb_no_coeff_skip) { // Divide by 0 check. 0 case possible with segment features +#if CONFIG_NEWENTROPY + int k; + for (k=0;kskip_false_count[k] + cpi->skip_true_count[k]) ) + { + prob_skip_false[k] = cpi->skip_false_count[k] * 256 / + (cpi->skip_false_count[k] + cpi->skip_true_count[k]); + + if (prob_skip_false[k] <= 1) + prob_skip_false[k] = 1; + + if (prob_skip_false[k] > 255) + prob_skip_false[k] = 255; + } + else + prob_skip_false[k] = 255; + + pc->mbskip_pred_probs[k] = prob_skip_false[k]; + vp8_write_literal(w, prob_skip_false[k], 8); + } +#else if ( (cpi->skip_false_count + cpi->skip_true_count) ) { prob_skip_false = cpi->skip_false_count * 256 / @@ -615,6 +654,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) cpi->prob_skip_false = prob_skip_false; vp8_write_literal(w, prob_skip_false, 8); +#endif } vp8_write_literal(w, pc->prob_intra_coded, 8); @@ -715,7 +755,12 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) ( !segfeature_active( xd, segment_id, SEG_LVL_EOB ) || ( get_segdata( xd, segment_id, SEG_LVL_EOB ) != 0 ) ) ) { +#if CONFIG_NEWENTROPY + vp8_encode_bool(w, mi->mb_skip_coeff, + get_pred_prob(pc, xd, PRED_MBSKIP)); +#else vp8_encode_bool(w, mi->mb_skip_coeff, prob_skip_false); +#endif } // Encode the reference frame. @@ -920,17 +965,44 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) static void write_kfmodes(VP8_COMP *cpi) { vp8_writer *const bc = & cpi->bc; - const VP8_COMMON *const c = & cpi->common; + VP8_COMMON *const c = & cpi->common; + const int mis = c->mode_info_stride; /* const */ MODE_INFO *m = c->mi; int mb_row = -1; +#if CONFIG_NEWENTROPY + int prob_skip_false[3] = {0, 0, 0}; +#else int prob_skip_false = 0; +#endif MACROBLOCKD *xd = &cpi->mb.e_mbd; if (c->mb_no_coeff_skip) { // Divide by 0 check. 0 case possible with segment features +#if CONFIG_NEWENTROPY + int k; + for (k=0;kskip_false_count[k] + cpi->skip_true_count[k]) ) + { + prob_skip_false[k] = cpi->skip_false_count[k] * 256 / + (cpi->skip_false_count[k] + cpi->skip_true_count[k]); + + if (prob_skip_false[k] <= 1) + prob_skip_false[k] = 1; + + if (prob_skip_false[k] > 255) + prob_skip_false[k] = 255; + } + else + prob_skip_false[k] = 255; + + c->mbskip_pred_probs[k] = prob_skip_false[k]; + vp8_write_literal(bc, prob_skip_false[k], 8); + } +#else if ( (cpi->skip_false_count + cpi->skip_true_count) ) { prob_skip_false = cpi->skip_false_count * 256 / @@ -947,6 +1019,7 @@ static void write_kfmodes(VP8_COMP *cpi) cpi->prob_skip_false = prob_skip_false; vp8_write_literal(bc, prob_skip_false, 8); +#endif } #if CONFIG_QIMODE @@ -965,6 +1038,8 @@ static void write_kfmodes(VP8_COMP *cpi) const int ym = m->mbmi.mode; int segment_id = m->mbmi.segment_id; + xd->mode_info_context = m; + if (cpi->mb.e_mbd.update_mb_segmentation_map) { write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd); @@ -974,7 +1049,12 @@ static void write_kfmodes(VP8_COMP *cpi) ( !segfeature_active( xd, segment_id, SEG_LVL_EOB ) || (get_segdata( xd, segment_id, SEG_LVL_EOB ) != 0) ) ) { +#if CONFIG_NEWENTROPY + vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, + get_pred_prob(c, xd, PRED_MBSKIP)); +#else vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false); +#endif } #if CONFIG_QIMODE kfwrite_ymode(bc, ym, c->kf_ymode_prob[c->kf_ymode_probs_index]); @@ -1018,14 +1098,15 @@ static void write_kfmodes(VP8_COMP *cpi) write_i8x8_mode(bc, m->bmi[2].as_mode.first, c->i8x8_mode_prob); write_i8x8_mode(bc, m->bmi[8].as_mode.first, c->i8x8_mode_prob); write_i8x8_mode(bc, m->bmi[10].as_mode.first, c->i8x8_mode_prob); - m++; } else #if CONFIG_UVINTRA - write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob[ym]); + write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]); #else - write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob); + write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob); #endif + + m++; } //printf("\n"); m++; // skip L prediction border @@ -1083,18 +1164,6 @@ static void sum_probs_over_prev_coef_context( } } -static int prob_update_savings(const unsigned int *ct, - const vp8_prob oldp, const vp8_prob newp, - const vp8_prob upd) -{ - const int old_b = vp8_cost_branch(ct, oldp); - const int new_b = vp8_cost_branch(ct, newp); - const int update_b = 8 + - ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8); - - return old_b - new_b - update_b; -} - static int default_coef_context_savings(VP8_COMP *cpi) { int savings = 0; @@ -1599,7 +1668,7 @@ static void decide_kf_ymode_entropy(VP8_COMP *cpi) } #endif -static segment_reference_frames(VP8_COMP *cpi) +static void segment_reference_frames(VP8_COMP *cpi) { VP8_COMMON *oci = &cpi->common; MODE_INFO *mi = oci->mi; @@ -1624,6 +1693,7 @@ static segment_reference_frames(VP8_COMP *cpi) } + void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) { int i, j; diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index a59dd6324..639c1fa8d 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -693,8 +693,13 @@ static void encode_frame_internal(VP8_COMP *cpi) cpi->prediction_error = 0; cpi->intra_error = 0; +#if CONFIG_NEWENTROPY + cpi->skip_true_count[0] = cpi->skip_true_count[1] = cpi->skip_true_count[2] = 0; + cpi->skip_false_count[0] = cpi->skip_false_count[1] = cpi->skip_false_count[2] = 0; +#else cpi->skip_true_count = 0; cpi->skip_false_count = 0; +#endif #if 0 // Experimental code @@ -1052,7 +1057,8 @@ static void adjust_act_zbin( VP8_COMP *cpi, MACROBLOCK *x ) int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) { - int rate; + int rate, i; + int mb_skip_context; // Non rd path deprecated in test code base //if (cpi->sf.RD && cpi->compressor_speed != 2) @@ -1094,7 +1100,6 @@ int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x); sum_intra_stats(cpi, x); vp8_tokenize_mb(cpi, &x->e_mbd, t); - return rate; } #ifdef SPEEDSTATS @@ -1116,7 +1121,7 @@ int vp8cx_encode_inter_macroblock int distortion; unsigned char *segment_id = &xd->mode_info_context->mbmi.segment_id; int seg_ref_active; - unsigned char ref_pred_flag; + unsigned char ref_pred_flag; x->skip = 0; @@ -1363,17 +1368,32 @@ int vp8cx_encode_inter_macroblock } else { +#if CONFIG_NEWENTROPY + int mb_skip_context = + cpi->common.mb_no_coeff_skip ? + (x->e_mbd.mode_info_context-1)->mbmi.mb_skip_coeff + + (x->e_mbd.mode_info_context-cpi->common.mode_info_stride)->mbmi.mb_skip_coeff : + 0; +#endif if (cpi->common.mb_no_coeff_skip) { xd->mode_info_context->mbmi.mb_skip_coeff = 1; +#if CONFIG_NEWENTROPY + cpi->skip_true_count[mb_skip_context] ++; +#else cpi->skip_true_count ++; +#endif vp8_fix_contexts(xd); } else { vp8_stuff_mb(cpi, xd, t); xd->mode_info_context->mbmi.mb_skip_coeff = 0; +#if CONFIG_NEWENTROPY + cpi->skip_false_count[mb_skip_context] ++; +#else cpi->skip_false_count ++; +#endif } } return rate; diff --git a/vp8/encoder/encodeintra.c b/vp8/encoder/encodeintra.c index f34de6f75..b24f9b4a9 100644 --- a/vp8/encoder/encodeintra.c +++ b/vp8/encoder/encodeintra.c @@ -144,9 +144,9 @@ void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) } if(tx_type == TX_8X8) - vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd); + vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd); else - vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd); + vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd); #ifdef ENC_DEBUG if (enc_debug) { diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 0d126067e..455224c22 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -166,7 +166,11 @@ extern void (*vp8_short_fdct8x4)(short *input, short *output, int pitch); extern void vp8cx_init_quantizer(VP8_COMP *cpi); +#if CONFIG_NEWENTROPY +int vp8cx_base_skip_false_prob[QINDEX_RANGE][3]; +#else int vp8cx_base_skip_false_prob[QINDEX_RANGE]; +#endif // Tables relating active max Q to active min Q static int kf_low_motion_minq[QINDEX_RANGE]; @@ -253,7 +257,7 @@ void init_base_skip_probs() { int i; double q; - int skip_prob; + int skip_prob, t; for ( i = 0; i < QINDEX_RANGE; i++ ) { @@ -261,13 +265,32 @@ void init_base_skip_probs() // Exponential decay caluclation of baseline skip prob with clamping // Based on crude best fit of old table. - skip_prob = (int)( 564.25 * pow( 2.71828, (-0.012*q) ) ); + t = (int)( 564.25 * pow( 2.71828, (-0.012*q) ) ); + + skip_prob = t; if ( skip_prob < 1 ) skip_prob = 1; else if ( skip_prob > 255 ) skip_prob = 255; +#if CONFIG_NEWENTROPY + vp8cx_base_skip_false_prob[i][1] = skip_prob; + skip_prob = t * 0.75; + if ( skip_prob < 1 ) + skip_prob = 1; + else if ( skip_prob > 255 ) + skip_prob = 255; + vp8cx_base_skip_false_prob[i][2] = skip_prob; + + skip_prob = t * 1.25; + if ( skip_prob < 1 ) + skip_prob = 1; + else if ( skip_prob > 255 ) + skip_prob = 255; + vp8cx_base_skip_false_prob[i][0] = skip_prob; +#else vp8cx_base_skip_false_prob[i] = skip_prob; +#endif } } @@ -1826,12 +1849,10 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) vp8_zero(cpi->y_uv_mode_count) #endif - return (VP8_PTR) cpi; } - void vp8_remove_compressor(VP8_PTR *ptr) { VP8_COMP *cpi = (VP8_COMP *)(*ptr); @@ -1857,7 +1878,7 @@ void vp8_remove_compressor(VP8_PTR *ptr) vp8_clear_system_state(); - printf("\n8x8-4x4:%d-%d\n", cpi->t8x8_count, cpi->t4x4_count); + //printf("\n8x8-4x4:%d-%d\n", cpi->t8x8_count, cpi->t4x4_count); if (cpi->pass != 1) { FILE *f = fopen("opsnr.stt", "a"); @@ -3120,14 +3141,28 @@ static void encode_frame_to_data_rate // setup skip prob for costing in mode/mv decision if (cpi->common.mb_no_coeff_skip) { +#if CONFIG_NEWENTROPY + int k; + for (k=0; kmbskip_pred_probs[k] = cpi->base_skip_false_prob[Q][k]; +#else cpi->prob_skip_false = cpi->base_skip_false_prob[Q]; +#endif if (cm->frame_type != KEY_FRAME) { if (cpi->common.refresh_alt_ref_frame) { +#if CONFIG_NEWENTROPY + for (k=0; klast_skip_false_probs[2][k] != 0) + cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k]; + } +#else if (cpi->last_skip_false_probs[2] != 0) cpi->prob_skip_false = cpi->last_skip_false_probs[2]; +#endif /* if(cpi->last_skip_false_probs[2]!=0 && abs(Q- cpi->last_skip_probs_q[2])<=16 ) @@ -3138,8 +3173,16 @@ static void encode_frame_to_data_rate } else if (cpi->common.refresh_golden_frame) { +#if CONFIG_NEWENTROPY + for (k=0; klast_skip_false_probs[1][k] != 0) + cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k]; + } +#else if (cpi->last_skip_false_probs[1] != 0) cpi->prob_skip_false = cpi->last_skip_false_probs[1]; +#endif /* if(cpi->last_skip_false_probs[1]!=0 && abs(Q- cpi->last_skip_probs_q[1])<=16 ) @@ -3150,8 +3193,17 @@ static void encode_frame_to_data_rate } else { +#if CONFIG_NEWENTROPY + int k; + for (k=0; klast_skip_false_probs[0][k] != 0) + cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k]; + } +#else if (cpi->last_skip_false_probs[0] != 0) cpi->prob_skip_false = cpi->last_skip_false_probs[0]; +#endif /* if(cpi->last_skip_false_probs[0]!=0 && abs(Q- cpi->last_skip_probs_q[0])<=16 ) @@ -3163,6 +3215,22 @@ static void encode_frame_to_data_rate // as this is for cost estimate, let's make sure it does not // get extreme either way +#if CONFIG_NEWENTROPY + { + int k; + for (k=0; kmbskip_pred_probs[k] < 5) + cm->mbskip_pred_probs[k] = 5; + + if (cm->mbskip_pred_probs[k] > 250) + cm->mbskip_pred_probs[k] = 250; + + if (cpi->is_src_frame_alt_ref) + cm->mbskip_pred_probs[k] = 1; + } + } +#else if (cpi->prob_skip_false < 5) cpi->prob_skip_false = 5; @@ -3171,6 +3239,7 @@ static void encode_frame_to_data_rate if (cpi->is_src_frame_alt_ref) cpi->prob_skip_false = 1; +#endif } @@ -3588,21 +3657,44 @@ static void encode_frame_to_data_rate { if (cpi->common.refresh_alt_ref_frame) { +#if CONFIG_NEWENTROPY + int k; + for (k=0; klast_skip_false_probs[2][k] = cm->mbskip_pred_probs[k]; +#else cpi->last_skip_false_probs[2] = cpi->prob_skip_false; +#endif cpi->last_skip_probs_q[2] = cm->base_qindex; } else if (cpi->common.refresh_golden_frame) { +#if CONFIG_NEWENTROPY + int k; + for (k=0; klast_skip_false_probs[1][k] = cm->mbskip_pred_probs[k]; +#else cpi->last_skip_false_probs[1] = cpi->prob_skip_false; +#endif cpi->last_skip_probs_q[1] = cm->base_qindex; } else { +#if CONFIG_NEWENTROPY + int k; + for (k=0; klast_skip_false_probs[0][k] = cm->mbskip_pred_probs[k]; +#else cpi->last_skip_false_probs[0] = cpi->prob_skip_false; +#endif cpi->last_skip_probs_q[0] = cm->base_qindex; //update the baseline +#if CONFIG_NEWENTROPY + for (k=0; kbase_skip_false_prob[cm->base_qindex][k] = cm->mbskip_pred_probs[k]; +#else cpi->base_skip_false_prob[cm->base_qindex] = cpi->prob_skip_false; +#endif } } diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 9c655b845..158f5613f 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -491,8 +491,12 @@ typedef struct VP8_COMP int vert_scale; int pass; +#if CONFIG_NEWENTROPY + int last_skip_false_probs[3][MBSKIP_CONTEXTS]; +#else int prob_skip_false; int last_skip_false_probs[3]; +#endif int last_skip_probs_q[3]; int recent_ref_frame_usage[MAX_REF_FRAMES]; @@ -510,8 +514,13 @@ typedef struct VP8_COMP int inter_zz_count; int gf_bad_count; int gf_update_recommended; +#if CONFIG_NEWENTROPY + int skip_true_count[3]; + int skip_false_count[3]; +#else int skip_true_count; int skip_false_count; +#endif int t4x4_count; int t8x8_count; @@ -539,7 +548,11 @@ typedef struct VP8_COMP unsigned int time_pick_lpf; unsigned int time_encode_mb_row; +#if CONFIG_NEWENTROPY + int base_skip_false_prob[QINDEX_RANGE][3]; +#else int base_skip_false_prob[QINDEX_RANGE]; +#endif struct twopass_rc { diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 636ed3a67..c22fdab06 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -25,7 +25,7 @@ extern int enc_debug; #define EXACT_QUANT void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) { - int i, rc, eob, nonzeros; + int i, rc, eob; int x, y, z, sz; short *coeff_ptr = b->coeff; short *round_ptr = b->round; @@ -33,7 +33,6 @@ 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; - vpx_memset(qcoeff_ptr, 0, 32); vpx_memset(dqcoeff_ptr, 0, 32); @@ -165,7 +164,9 @@ void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d) dqcoeff_ptr[rc] = x * dq; /* Remember the last non-zero coefficient. */ if (y) + { eob = i; + } } } @@ -264,9 +265,6 @@ void vp8_quantize_mbuv_c(MACROBLOCK *x) x->quantize_b(&x->block[i], &x->e_mbd.block[i]); } - - - void vp8_fast_quantize_b_2x2_c(BLOCK *b, BLOCKD *d) { int i, rc, eob; @@ -312,7 +310,6 @@ void vp8_fast_quantize_b_2x2_c(BLOCK *b, BLOCKD *d) } } 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) @@ -537,7 +534,9 @@ void vp8_strict_quantize_b_2x2(BLOCK *b, BLOCKD *d) dqcoeff_ptr[rc] = x * dq; /* Remember the last non-zero coefficient. */ if (y) + { eob = i; + } } } d->eob = eob + 1; @@ -596,14 +595,14 @@ void vp8_strict_quantize_b_8x8(BLOCK *b, BLOCKD *d) dqcoeff_ptr[rc] = x * dq; /* Remember the last non-zero coefficient. */ if (y) + { eob = i; + } } } d->eob = eob + 1; } - - void vp8_quantize_mby_8x8(MACROBLOCK *x) { int i; diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 1f02f55d9..c798a7ee6 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -3225,7 +3225,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int // cost of signallying a skip if (cpi->common.mb_no_coeff_skip) { +#if CONFIG_NEWENTROPY + int prob_skip_cost = vp8_cost_bit( + get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP), 0); +#else int prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 0); +#endif other_cost += prob_skip_cost; rate2 += prob_skip_cost; } @@ -3268,20 +3273,32 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int if (mb_skippable) { +#if CONFIG_NEWENTROPY + vp8_prob skip_prob = get_pred_prob(cm, &x->e_mbd, PRED_MBSKIP); +#endif + int prob_skip_cost; rate2 -= (rate_y + rate_uv); //for best_yrd calculation rate_uv = 0; +#if CONFIG_NEWENTROPY + if (skip_prob) + { + prob_skip_cost = vp8_cost_bit(skip_prob, 1); + prob_skip_cost -= vp8_cost_bit(skip_prob, 0); + rate2 += prob_skip_cost; + other_cost += prob_skip_cost; + } +#else // Back out no skip flag costing and add in skip flag costing if (cpi->prob_skip_false) { - int prob_skip_cost; - prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 1); prob_skip_cost -= vp8_cost_bit(cpi->prob_skip_false, 0); rate2 += prob_skip_cost; other_cost += prob_skip_cost; } +#endif } } // Calculate the final RD estimate for this mode diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c index c86e022ba..6d65d5e3f 100644 --- a/vp8/encoder/tokenize.c +++ b/vp8/encoder/tokenize.c @@ -17,14 +17,15 @@ #include "tokenize.h" #include "vpx_mem/vpx_mem.h" +#include "vp8/common/pred_common.h" #include "vp8/common/seg_common.h" /* Global event counters used for accumulating statistics across several compressions, then generating context.c = initial stats. */ #ifdef ENTROPY_STATS -_int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; -_int64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; +INT64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; +INT64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; #endif void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ; void vp8_stuff_mb_8x8(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ; @@ -102,7 +103,7 @@ static void fill_value_tokens() static void tokenize2nd_order_b_8x8 ( - MACROBLOCKD *xd, + MACROBLOCKD *xd, const BLOCKD *const b, TOKENEXTRA **tp, const int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */ @@ -127,7 +128,6 @@ static void tokenize2nd_order_b_8x8 seg_eob = get_segdata( xd, segment_id, SEG_LVL_EOB ); } - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); assert(eob<=4); @@ -135,11 +135,12 @@ static void tokenize2nd_order_b_8x8 do { const int band = vp8_coef_bands[c]; + int v = 0; if (c < eob) { int rc = vp8_default_zig_zag1d[c]; - const int v = qcoeff_ptr[rc]; + v = qcoeff_ptr[rc]; assert(-DCT_MAX_VALUE <= v && v < (DCT_MAX_VALUE)); @@ -166,6 +167,7 @@ static void tokenize2nd_order_b_8x8 } while (pt = vp8_prev_token_class[x], ++t, c < eob && ++c all coeff data is zero */ *a = *l = pt; @@ -236,6 +238,7 @@ static void tokenize2nd_order_b t++; } + *tp = t; pt = (c != 0); /* 0 <-> all coeff data is zero */ *a = *l = pt; @@ -244,7 +247,7 @@ static void tokenize2nd_order_b static void tokenize1st_order_b_8x8 ( - MACROBLOCKD *xd, + MACROBLOCKD *xd, const BLOCKD *const b, TOKENEXTRA **tp, const int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */ @@ -274,13 +277,14 @@ static void tokenize1st_order_b_8x8 do { const int band = vp8_coef_bands_8x8[c]; + int v; x = DCT_EOB_TOKEN; if (c < eob) { int rc = vp8_default_zig_zag1d_8x8[c]; - const int v = qcoeff_ptr[rc]; + v = qcoeff_ptr[rc]; assert(-DCT_MAX_VALUE <= v && v < (DCT_MAX_VALUE)); @@ -307,9 +311,6 @@ static void tokenize1st_order_b_8x8 *a = *l = pt; } - - - static void tokenize1st_order_b ( MACROBLOCKD *xd, @@ -347,7 +348,6 @@ static void tokenize1st_order_b qcoeff_ptr = b->qcoeff; a = (ENTROPY_CONTEXT *)xd->above_context + tmp1; l = (ENTROPY_CONTEXT *)xd->left_context + tmp2; - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); c = type ? 0 : 1; @@ -438,7 +438,6 @@ static void tokenize1st_order_b pt = (c != 0); /* 0 <-> all coeff data is zero */ *a = *l = pt; } - } @@ -505,6 +504,9 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) int has_y2_block; int b; int tx_type = x->mode_info_context->mbmi.txfm_size; +#if CONFIG_NEWENTROPY + int mb_skip_context = get_pred_context(&cpi->common, x, PRED_MBSKIP); +#endif // If the MB is going to be skipped because of a segment level flag // exclude this from the skip count stats used to calculate the @@ -531,7 +533,11 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) if (x->mode_info_context->mbmi.mb_skip_coeff) { +#if CONFIG_NEWENTROPY + cpi->skip_true_count[mb_skip_context] += skip_inc; +#else cpi->skip_true_count += skip_inc; +#endif if (!cpi->common.mb_no_coeff_skip) { @@ -548,7 +554,11 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) return; } +#if CONFIG_NEWENTROPY + cpi->skip_false_count[mb_skip_context] += skip_inc; +#else cpi->skip_false_count += skip_inc; +#endif plane_type = 3; if(has_y2_block) @@ -647,7 +657,7 @@ void print_context_counters() do { - const _int64 x = context_counters [type] [band] [pt] [t]; + const INT64 x = context_counters [type] [band] [pt] [t]; const int y = (int) x; assert(x == (INT64) y); /* no overflow handling yet */ @@ -695,10 +705,10 @@ void print_context_counters() do { - const _int64 x = context_counters [type] [band] [pt] [t]; + const INT64 x = context_counters [type] [band] [pt] [t]; const int y = (int) x; - assert(x == (_int64) y); /* no overflow handling yet */ + assert(x == (INT64) y); /* no overflow handling yet */ fprintf(f, "%s %d", Comma(t), y); } @@ -720,6 +730,7 @@ void print_context_counters() fprintf(f, "\n};\n"); fclose(f); } + #endif @@ -751,10 +762,10 @@ static __inline void stuff2nd_order_b_8x8 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; + ++cpi->coef_counts_8x8 [1] [0] [pt] [DCT_EOB_TOKEN]; pt = 0; *a = *l = pt; @@ -782,9 +793,9 @@ static __inline void stuff1st_order_b_8x8 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; + ++cpi->coef_counts_8x8 [0] [1] [pt] [DCT_EOB_TOKEN]; pt = 0; /* 0 <-> all coeff data is zero */ *a = *l = pt; @@ -814,9 +825,9 @@ void stuff1st_order_buv_8x8 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; + ++cpi->coef_counts_8x8[2] [0] [pt] [DCT_EOB_TOKEN]; pt = 0; /* 0 <-> all coeff data is zero */ *a = *l = pt; @@ -871,10 +882,10 @@ static __inline void stuff2nd_order_b t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt]; t->skip_eob_node = 0; - ++cpi->coef_counts [1] [0] [pt] [DCT_EOB_TOKEN]; ++t; - *tp = t; + ++cpi->coef_counts [1] [0] [pt] [DCT_EOB_TOKEN]; + pt = 0; *a = *l = pt; @@ -895,9 +906,9 @@ static __inline void stuff1st_order_b t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [0] [1] [pt]; t->skip_eob_node = 0; - ++cpi->coef_counts [0] [1] [pt] [DCT_EOB_TOKEN]; ++t; *tp = t; + ++cpi->coef_counts [0] [1] [pt] [DCT_EOB_TOKEN]; pt = 0; /* 0 <-> all coeff data is zero */ *a = *l = pt; @@ -918,9 +929,9 @@ void stuff1st_order_buv t->Token = DCT_EOB_TOKEN; t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt]; t->skip_eob_node = 0; - ++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN]; ++t; *tp = t; + ++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN]; pt = 0; /* 0 <-> all coeff data is zero */ *a = *l = pt; @@ -963,5 +974,4 @@ void vp8_fix_contexts(MACROBLOCKD *x) vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1); vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1); } - } diff --git a/vp8/encoder/tokenize.h b/vp8/encoder/tokenize.h index 0608102d0..7503188ed 100644 --- a/vp8/encoder/tokenize.h +++ b/vp8/encoder/tokenize.h @@ -44,8 +44,29 @@ extern int mb_is_skippable_8x8(MACROBLOCKD *x); void init_context_counters(); void print_context_counters(); -extern _int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; -extern _int64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; +extern INT64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; +extern INT64 context_counters_8x8[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; + +#if CONFIG_NEWENTROPY +void init_nzc_counters(); +void print_nzc_counters(); +extern INT64 nzc4x4y_counters[MAX_NZC_CONTEXTS][NZC4X4_TOKENS]; +extern INT64 nzc4x4y2_counters[MAX_NZC_CONTEXTS][NZC4X4_TOKENS]; +extern INT64 nzc4x4uv_counters[MAX_NZC_CONTEXTS][NZC4X4_TOKENS]; +extern INT64 nzc8x8y_counters[MAX_NZC_CONTEXTS][NZC8X8_TOKENS]; +extern INT64 nzc8x8uv_counters[MAX_NZC_CONTEXTS][NZC8X8_TOKENS]; +extern INT64 nzc2x2y2_counters[MAX_NZC_CONTEXTS][NZC2X2_TOKENS]; +void init_nzb_counters(); +void print_nzb_counters(); +extern INT64 nzby_counters[MAX_NZB_CONTEXTS][NZBY_TOKENS]; +extern INT64 nzbuv_counters[MAX_NZB_CONTEXTS][NZBUV_TOKENS]; +extern INT64 nzby2_counters[MAX_NZB_CONTEXTS][2]; +void init_nzb2_counters(); +void print_nzb2_counters(); +extern INT64 nzb2y_counters[MAX_NZB_CONTEXTS][2]; +extern INT64 nzb2uv_counters[MAX_NZB_CONTEXTS][2]; +extern INT64 nzb2y2_counters[MAX_NZB_CONTEXTS][2]; +#endif #endif extern const int *vp8_dct_value_cost_ptr; /* TODO: The Token field should be broken out into a separate char array to diff --git a/vp8/encoder/treewriter.c b/vp8/encoder/treewriter.c index 3a777f222..6d46d369f 100644 --- a/vp8/encoder/treewriter.c +++ b/vp8/encoder/treewriter.c @@ -42,4 +42,3 @@ void vp8_cost_tokens_skip(int *c, const vp8_prob *p, vp8_tree t) { cost(c, t, p, 2, 0); } -