diff --git a/vp9/common/vp9_modecont.c b/vp9/common/vp9_modecont.c index 73cb5e15e39ec97459588a05741cfacbacc85b53..86a8fb85013b4431e57ab51d474002802c1b104b 100644 --- a/vp9/common/vp9_modecont.c +++ b/vp9/common/vp9_modecont.c @@ -12,11 +12,11 @@ #include "vp9/common/vp9_entropy.h" const int vp9_default_mode_contexts[INTER_MODE_CONTEXTS][4] = { - {1, 223, 1, 237}, // 0,0 best: Only candidate - {87, 166, 26, 219}, // 0,0 best: non zero candidates - {89, 67, 18, 125}, // 0,0 best: non zero candidates, split - {16, 141, 69, 226}, // strong nz candidate(s), no split - {35, 122, 14, 227}, // weak nz candidate(s), no split - {14, 122, 22, 164}, // strong nz candidate(s), split - {16, 70, 9, 183}, // weak nz candidate(s), split + {2, 173, 34, 229}, // 0 = both zero mv + {7, 145, 85, 225}, // 1 = one zero mv + one a predicted mv + {7, 166, 63, 231}, // 2 = two predicted mvs + {7, 94, 66, 219}, // 3 = one predicted/zero and one new mv + {8, 64, 46, 213}, // 4 = two new mvs + {17, 81, 31, 231}, // 5 = one intra neighbour + x + {25, 29, 30, 246}, // 6 = two intra neighbours }; diff --git a/vp9/common/vp9_mvref_common.c b/vp9/common/vp9_mvref_common.c index 3f18c6961fafda22e74f8b172be43bd979e57d7d..fa84ce6bd47a07b989e0c459b212f99713cbc94f 100644 --- a/vp9/common/vp9_mvref_common.c +++ b/vp9/common/vp9_mvref_common.c @@ -165,6 +165,10 @@ void vp9_find_mv_refs(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here, int split_count = 0; int (*mv_ref_search)[2]; const int mi_col = get_mi_col(xd); + int intra_count = 0; + int zero_count = 0; + int newmv_count = 0; + // Blank the reference vector lists and other local structures. vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES); vpx_memset(candidate_scores, 0, sizeof(candidate_scores)); @@ -196,9 +200,24 @@ void vp9_find_mv_refs(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here, &refmv_count, c_refmv, 16); } split_count += (candidate_mi->mbmi.mode == SPLITMV); + + // Count number of neihgbours coded intra and zeromv + intra_count += (candidate_mi->mbmi.mode < NEARESTMV); + zero_count += (candidate_mi->mbmi.mode == ZEROMV); + newmv_count += (candidate_mi->mbmi.mode >= NEWMV); } } + // If at this stage wwe have a 0 vector and a non zero vector from the + // correct reference frame then make sure that the non zero one is given + // precedence as we have other options for coding 0,0 + /* if (refmv_count == MAX_MV_REF_CANDIDATES) { + if (mv_ref_list[1].as_int && !mv_ref_list[0].as_int) { + mv_ref_list[0].as_int = mv_ref_list[1].as_int; + mv_ref_list[1].as_int = 0; + } + } */ + // More distant neigbours for (i = 2; (i < MVREF_NEIGHBOURS) && (refmv_count < MAX_MV_REF_CANDIDATES); ++i) { @@ -278,24 +297,21 @@ void vp9_find_mv_refs(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here, } } - // Define inter mode coding context. - // 0,0 was best - if (mv_ref_list[0].as_int == 0) { - // 0,0 is only candidate - if (refmv_count <= 1) { - mbmi->mb_mode_context[ref_frame] = 0; - // non zero candidates candidates available - } else if (split_count == 0) { - mbmi->mb_mode_context[ref_frame] = 1; + if (!intra_count) { + if (!newmv_count) { + // 0 = both zero mv + // 1 = one zero mv + one a predicted mv + // 2 = two predicted mvs + mbmi->mb_mode_context[ref_frame] = 2 - zero_count; } else { - mbmi->mb_mode_context[ref_frame] = 2; + // 3 = one predicted/zero and one new mv + // 4 = two new mvs + mbmi->mb_mode_context[ref_frame] = 2 + newmv_count; } - } else if (split_count == 0) { - // Non zero best, No Split MV cases - mbmi->mb_mode_context[ref_frame] = candidate_scores[0] >= 16 ? 3 : 4; } else { - // Non zero best, some split mv - mbmi->mb_mode_context[ref_frame] = candidate_scores[0] >= 16 ? 5 : 6; + // 5 = one intra neighbour + x + // 6 = two intra neighbours + mbmi->mb_mode_context[ref_frame] = 4 + intra_count; } // Clamp vectors diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 9ced27b88c1c0bd46bd090c7c38fd2866fdca9cc..c17f1db72282ddd315f3e16ceae80bbe3b0c1e3c 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -804,9 +804,9 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, left_block_mode(m, i) : B_DC_PRED; const int bm = m->bmi[i].as_mode.first; -#ifdef ENTROPY_STATS +/*#ifdef ENTROPY_STATS ++intra_mode_stats [A] [L] [bm]; -#endif +#endif*/ write_kf_bmode(bc, bm, c->kf_bmode_prob[a][l]); } while (++i < 4); } diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c index aff5637e1d61f936d24390f557a86d6424336fe2..75e6e6757e8b948c8864b3fd307c1444b226a7c7 100644 --- a/vp9/encoder/vp9_mcomp.c +++ b/vp9/encoder/vp9_mcomp.c @@ -2430,32 +2430,3 @@ int vp9_refining_search_8p_c(MACROBLOCK *x, } } #endif // CONFIG_COMP_INTER_JOINT_SEARCH - -#ifdef ENTROPY_STATS -void print_mode_context(VP9_COMMON *pc) { - FILE *f = fopen("vp9_modecont.c", "a"); - int i, j; - - fprintf(f, "#include \"vp9_entropy.h\"\n"); - fprintf(f, "const int vp9_mode_contexts[INTER_MODE_CONTEXTS][4] ="); - fprintf(f, "{\n"); - for (j = 0; j < INTER_MODE_CONTEXTS; j++) { - fprintf(f, " {/* %d */ ", j); - fprintf(f, " "); - for (i = 0; i < 4; i++) { - int this_prob; - - // context probs - this_prob = get_binary_prob(pc->fc.mv_ref_ct[j][i][0], - pc->fc.mv_ref_ct[j][i][1]); - - fprintf(f, "%5d, ", this_prob); - } - fprintf(f, " },\n"); - } - - fprintf(f, "};\n"); - fclose(f); -} - -#endif/* END MV ref count ENTROPY_STATS stats code */ diff --git a/vp9/encoder/vp9_mcomp.h b/vp9/encoder/vp9_mcomp.h index cdbd29aa5d1414fd838c41a90e47c5087baedae7..33e688b973dd6f5a864dbed2c6922bbbf3e0691c 100644 --- a/vp9/encoder/vp9_mcomp.h +++ b/vp9/encoder/vp9_mcomp.h @@ -15,10 +15,6 @@ #include "vp9/encoder/vp9_block.h" #include "vp9/encoder/vp9_variance.h" -#ifdef ENTROPY_STATS -void print_mode_context(VP9_COMMON *pc); -#endif - // The maximum number of steps in a step search given the largest // allowed initial step #define MAX_MVSEARCH_STEPS 11 diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 859fff17d11f9bced0d8b3cc6f181760c646ca7c..1aefa2c01d851ec9ba86fc4789092d2ebd937e88 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -522,6 +522,66 @@ static void configure_implicit_segmentation(VP9_COMP *cpi, int frame_qindex) { } #endif +#ifdef ENTROPY_STATS +void vp9_update_mode_context_stats(VP9_COMP *cpi) { + VP9_COMMON *cm = &cpi->common; + int i, j; + unsigned int (*mv_ref_ct)[4][2] = cm->fc.mv_ref_ct; + int64_t (*mv_ref_stats)[4][2] = cpi->mv_ref_stats; + FILE *f; + + // Read the past stats counters + f = fopen("mode_context.bin", "rb"); + if (!f) { + vpx_memset(cpi->mv_ref_stats, 0, sizeof(cpi->mv_ref_stats)); + } else { + fread(cpi->mv_ref_stats, sizeof(cpi->mv_ref_stats), 1, f); + fclose(f); + } + + // Add in the values for this frame + for (i = 0; i < INTER_MODE_CONTEXTS; i++) { + for (j = 0; j < 4; j++) { + mv_ref_stats[i][j][0] += (int64_t)mv_ref_ct[i][j][0]; + mv_ref_stats[i][j][1] += (int64_t)mv_ref_ct[i][j][1]; + } + } + + // Write back the accumulated stats + f = fopen("mode_context.bin", "wb"); + fwrite(cpi->mv_ref_stats, sizeof(cpi->mv_ref_stats), 1, f); + fclose(f); +} + +void print_mode_context(VP9_COMP *cpi) { + FILE *f = fopen("vp9_modecont.c", "a"); + int i, j; + + fprintf(f, "#include \"vp9_entropy.h\"\n"); + fprintf(f, "const int vp9_mode_contexts[INTER_MODE_CONTEXTS][4] ="); + fprintf(f, "{\n"); + for (j = 0; j < INTER_MODE_CONTEXTS; j++) { + fprintf(f, " {/* %d */ ", j); + fprintf(f, " "); + for (i = 0; i < 4; i++) { + int this_prob; + int64_t count = cpi->mv_ref_stats[j][i][0] + cpi->mv_ref_stats[j][i][1]; + if (count) + this_prob = ((cpi->mv_ref_stats[j][i][0] * 256) + (count >> 1)) / count; + else + this_prob = 128; + + // context probs + fprintf(f, "%5d, ", this_prob); + } + fprintf(f, " },\n"); + } + + fprintf(f, "};\n"); + fclose(f); +} +#endif // ENTROPY_STATS + // DEBUG: Print out the segment id of each MB in the current frame. static void print_seg_map(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; @@ -1630,7 +1690,7 @@ void vp9_remove_compressor(VP9_PTR *ptr) { if (cpi->pass != 1) { print_context_counters(); print_tree_update_probs(); - print_mode_context(&cpi->common); + print_mode_context(cpi); } #endif #ifdef NMV_STATS @@ -3139,6 +3199,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } } +#ifdef ENTROPY_STATS + vp9_update_mode_context_stats(cpi); +#endif + /* Move storing frame_type out of the above loop since it is also * needed in motion search besides loopfilter */ cm->last_frame_type = cm->frame_type; diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index c6808ae2b106d210243f6e6659c17e509ee4d449..54caf1d1ad869e4095d8deff8cd92211a2fc6a35 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -611,6 +611,10 @@ typedef struct VP9_COMP { int this_frame_weight; int max_arf_level; #endif + +#ifdef ENTROPY_STATS + int64_t mv_ref_stats[INTER_MODE_CONTEXTS][4][2]; +#endif } VP9_COMP; void vp9_encode_frame(VP9_COMP *cpi);