vpx/vp8/common/entropymv.c
Ronald S. Bultje 319dd1c0f5 Set a default mv entropy if no tokens are coded.
This doesn't affect the result, since there are no MVs coded using this
entropy. It does, however, silence valgrind warnings about uninitialized
variables.

Change-Id: I6e21ba92df6ce5381bf58b8c349ef4373294a0b6
2012-08-16 11:12:50 -07:00

403 lines
12 KiB
C

/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "onyxc_int.h"
#include "entropymv.h"
const MV_CONTEXT_HP vp8_mv_update_probs_hp[2] = {
{{
237,
246,
253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
254, 254, 254, 254, 254, 250, 250, 252, 254, 254, 254
}
},
{{
231,
243,
245, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
254, 254, 254, 254, 254, 251, 251, 254, 254, 254, 254
}
}
};
const MV_CONTEXT_HP vp8_default_mv_context_hp[2] = {
{{
/* row */
162, /* is short */
128, /* sign */
220, 204, 180, 192, 192, 119, 192, 192, 180, 140, 192, 192, 224, 224, 224, /* short tree */
128, 129, 132, 75, 145, 178, 206, 239, 254, 254, 254 /* long bits */
}
},
{{
/* same for column */
164, /* is short */
128,
220, 204, 180, 192, 192, 119, 192, 192, 180, 140, 192, 192, 224, 224, 224, /* short tree */
128, 130, 130, 74, 148, 180, 203, 236, 254, 254, 254 /* long bits */
}
}
};
const MV_CONTEXT vp8_mv_update_probs[2] = {
{{
237,
246,
253, 253, 254, 254, 254, 254, 254,
254, 254, 254, 254, 254, 250, 250, 252, 254, 254
}
},
{{
231,
243,
245, 253, 254, 254, 254, 254, 254,
254, 254, 254, 254, 254, 251, 251, 254, 254, 254
}
}
};
const MV_CONTEXT vp8_default_mv_context[2] = {
{{
/* row */
162, /* is short */
128, /* sign */
225, 146, 172, 147, 214, 39, 156, /* short tree */
128, 129, 132, 75, 145, 178, 206, 239, 254, 254 /* long bits */
}
},
{{
/* same for column */
164, /* is short */
128,
204, 170, 119, 235, 140, 230, 228,
128, 130, 130, 74, 148, 180, 203, 236, 254, 254 /* long bits */
}
}
};
const vp8_tree_index vp8_small_mvtree_hp [30] = {
2, 16,
4, 10,
6, 8,
-0, -1,
-2, -3,
12, 14,
-4, -5,
-6, -7,
18, 24,
20, 22,
-8, -9,
-10, -11,
26, 28,
-12, -13,
-14, -15
};
struct vp8_token_struct vp8_small_mvencodings_hp [16];
const vp8_tree_index vp8_small_mvtree [14] = {
2, 8,
4, 6,
-0, -1,
-2, -3,
10, 12,
-4, -5,
-6, -7
};
struct vp8_token_struct vp8_small_mvencodings [8];
__inline static void calc_prob(vp8_prob *p, const unsigned int ct[2], int pbits) {
const unsigned int tot = ct[0] + ct[1];
if (tot) {
const vp8_prob x = ((ct[0] * 255) / tot) & -(1 << (8 - pbits));
*p = x ? x : 1;
} else {
*p = 128;
}
}
static void compute_component_probs(
const unsigned int events [MVvals],
vp8_prob Pnew [MVPcount],
unsigned int is_short_ct[2],
unsigned int sign_ct[2],
unsigned int bit_ct [mvlong_width] [2],
unsigned int short_ct [mvnum_short],
unsigned int short_bct [mvnum_short - 1] [2]
) {
is_short_ct[0] = is_short_ct[1] = 0;
sign_ct[0] = sign_ct[1] = 0;
vpx_memset(bit_ct, 0, sizeof(unsigned int)*mvlong_width * 2);
vpx_memset(short_ct, 0, sizeof(unsigned int)*mvnum_short);
vpx_memset(short_bct, 0, sizeof(unsigned int) * (mvnum_short - 1) * 2);
{
const int c = events [mv_max];
is_short_ct [0] += c; // Short vector
short_ct [0] += c; // Magnitude distribution
}
{
int j = 1;
do {
const int c1 = events [mv_max + j]; // positive
const int c2 = events [mv_max - j]; // negative
const int c = c1 + c2;
int a = j;
sign_ct [0] += c1;
sign_ct [1] += c2;
if (a < mvnum_short) {
is_short_ct [0] += c; // Short vector
short_ct [a] += c; // Magnitude distribution
} else {
int k = mvlong_width - 1;
is_short_ct [1] += c; // Long vector
do
bit_ct [k] [(a >> k) & 1] += c;
while (--k >= 0);
}
} while (++j <= mv_max);
}
calc_prob(Pnew + mvpis_short, is_short_ct, 8);
calc_prob(Pnew + MVPsign, sign_ct, 8);
{
vp8_prob p [mvnum_short - 1]; /* actually only need branch ct */
int j = 0;
vp8_tree_probs_from_distribution(
mvnum_short, vp8_small_mvencodings, vp8_small_mvtree,
p, short_bct, short_ct,
256, 1
);
do
calc_prob(Pnew + MVPshort + j, short_bct[j], 8);
while (++j < mvnum_short - 1);
}
{
int j = 0;
do
calc_prob(Pnew + MVPbits + j, bit_ct[j], 8);
while (++j < mvlong_width);
}
}
static void compute_component_probs_hp(
const unsigned int events [MVvals_hp],
vp8_prob Pnew [MVPcount_hp],
unsigned int is_short_ct[2],
unsigned int sign_ct[2],
unsigned int bit_ct [mvlong_width_hp] [2],
unsigned int short_ct [mvnum_short_hp],
unsigned int short_bct [mvnum_short_hp - 1] [2]
) {
is_short_ct[0] = is_short_ct[1] = 0;
sign_ct[0] = sign_ct[1] = 0;
vpx_memset(bit_ct, 0, sizeof(unsigned int)*mvlong_width_hp * 2);
vpx_memset(short_ct, 0, sizeof(unsigned int)*mvnum_short_hp);
vpx_memset(short_bct, 0, sizeof(unsigned int) * (mvnum_short_hp - 1) * 2);
{
const int c = events [mv_max_hp];
is_short_ct [0] += c; // Short vector
short_ct [0] += c; // Magnitude distribution
}
{
int j = 1;
do {
const int c1 = events [mv_max_hp + j]; // positive
const int c2 = events [mv_max_hp - j]; // negative
const int c = c1 + c2;
int a = j;
sign_ct [0] += c1;
sign_ct [1] += c2;
if (a < mvnum_short_hp) {
is_short_ct [0] += c; // Short vector
short_ct [a] += c; // Magnitude distribution
} else {
int k = mvlong_width_hp - 1;
is_short_ct [1] += c; // Long vector
do
bit_ct [k] [(a >> k) & 1] += c;
while (--k >= 0);
}
} while (++j <= mv_max_hp);
}
calc_prob(Pnew + mvpis_short_hp, is_short_ct, 8);
calc_prob(Pnew + MVPsign_hp, sign_ct, 8);
{
vp8_prob p [mvnum_short_hp - 1]; /* actually only need branch ct */
int j = 0;
vp8_tree_probs_from_distribution(
mvnum_short_hp, vp8_small_mvencodings_hp, vp8_small_mvtree_hp,
p, short_bct, short_ct,
256, 1
);
do
calc_prob(Pnew + MVPshort_hp + j, short_bct[j], 8);
while (++j < mvnum_short_hp - 1);
}
{
int j = 0;
do
calc_prob(Pnew + MVPbits_hp + j, bit_ct[j], 8);
while (++j < mvlong_width_hp);
}
}
void vp8_entropy_mv_init() {
vp8_tokens_from_tree(vp8_small_mvencodings, vp8_small_mvtree);
vp8_tokens_from_tree(vp8_small_mvencodings_hp, vp8_small_mvtree_hp);
}
// #define MV_COUNT_TESTING
#define MV_COUNT_SAT 16
#define MV_MAX_UPDATE_FACTOR 128
void vp8_adapt_mv_probs(VP8_COMMON *cm) {
int i, t, count, factor;
#ifdef MV_COUNT_TESTING
printf("static const unsigned int\nMVcount[2][MVvals]={\n");
for (i = 0; i < 2; ++i) {
printf(" { ");
for (t = 0; t < MVvals; t++) {
printf("%d, ", cm->fc.MVcount[i][t]);
if (t % 16 == 15 && t != MVvals - 1) printf("\n ");
}
printf("},\n");
}
printf("};\n");
printf("static const unsigned int\nMVcount_hp[2][MVvals_hp]={\n");
for (i = 0; i < 2; ++i) {
printf(" { ");
for (t = 0; t < MVvals_hp; t++) {
printf("%d, ", cm->fc.MVcount_hp[i][t]);
if (t % 16 == 15 && t != MVvals_hp - 1) printf("\n ");
}
printf("},\n");
}
printf("};\n");
#endif /* MV_COUNT_TESTING */
for (i = 0; i < 2; ++i) {
int prob;
unsigned int is_short_ct[2];
unsigned int sign_ct[2];
unsigned int bit_ct [mvlong_width] [2];
unsigned int short_ct [mvnum_short];
unsigned int short_bct [mvnum_short - 1] [2];
vp8_prob Pnew [MVPcount];
compute_component_probs(cm->fc.MVcount[i], Pnew,
is_short_ct, sign_ct,
bit_ct, short_ct, short_bct);
count = is_short_ct[0] + is_short_ct[1];
count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count;
factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT);
prob = ((int)cm->fc.pre_mvc[i].prob[mvpis_short] * (256 - factor) +
(int)Pnew[mvpis_short] * factor + 128) >> 8;
if (prob <= 0) cm->fc.mvc[i].prob[mvpis_short] = 1;
else if (prob > 255) cm->fc.mvc[i].prob[mvpis_short] = 255;
else cm->fc.mvc[i].prob[mvpis_short] = prob;
count = sign_ct[0] + sign_ct[1];
count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count;
factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT);
prob = ((int)cm->fc.pre_mvc[i].prob[MVPsign] * (256 - factor) +
(int)Pnew[MVPsign] * factor + 128) >> 8;
if (prob <= 0) cm->fc.mvc[i].prob[MVPsign] = 1;
else if (prob > 255) cm->fc.mvc[i].prob[MVPsign] = 255;
else cm->fc.mvc[i].prob[MVPsign] = prob;
for (t = 0; t < mvnum_short - 1; ++t) {
count = short_bct[t][0] + short_bct[t][1];
count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count;
factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT);
prob = ((int)cm->fc.pre_mvc[i].prob[MVPshort + t] * (256 - factor) +
(int)Pnew[MVPshort + t] * factor + 128) >> 8;
if (prob <= 0) cm->fc.mvc[i].prob[MVPshort + t] = 1;
else if (prob > 255) cm->fc.mvc[i].prob[MVPshort + t] = 255;
else cm->fc.mvc[i].prob[MVPshort + t] = prob;
}
for (t = 0; t < mvlong_width; ++t) {
count = bit_ct[t][0] + bit_ct[t][1];
count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count;
factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT);
prob = ((int)cm->fc.pre_mvc[i].prob[MVPbits + t] * (256 - factor) +
(int)Pnew[MVPbits + t] * factor + 128) >> 8;
if (prob <= 0) cm->fc.mvc[i].prob[MVPbits + t] = 1;
else if (prob > 255) cm->fc.mvc[i].prob[MVPbits + t] = 255;
else cm->fc.mvc[i].prob[MVPbits + t] = prob;
}
}
for (i = 0; i < 2; ++i) {
int prob;
unsigned int is_short_ct[2];
unsigned int sign_ct[2];
unsigned int bit_ct [mvlong_width_hp] [2];
unsigned int short_ct [mvnum_short_hp];
unsigned int short_bct [mvnum_short_hp - 1] [2];
vp8_prob Pnew [MVPcount_hp];
compute_component_probs_hp(cm->fc.MVcount_hp[i], Pnew,
is_short_ct, sign_ct,
bit_ct, short_ct, short_bct);
count = is_short_ct[0] + is_short_ct[1];
count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count;
factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT);
prob = ((int)cm->fc.pre_mvc_hp[i].prob[mvpis_short_hp] * (256 - factor) +
(int)Pnew[mvpis_short_hp] * factor + 128) >> 8;
if (prob <= 0) cm->fc.mvc_hp[i].prob[mvpis_short_hp] = 1;
else if (prob > 255) cm->fc.mvc_hp[i].prob[mvpis_short_hp] = 255;
else cm->fc.mvc_hp[i].prob[mvpis_short_hp] = prob;
count = sign_ct[0] + sign_ct[1];
count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count;
factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT);
prob = ((int)cm->fc.pre_mvc_hp[i].prob[MVPsign_hp] * (256 - factor) +
(int)Pnew[MVPsign_hp] * factor + 128) >> 8;
if (prob <= 0) cm->fc.mvc_hp[i].prob[MVPsign_hp] = 1;
else if (prob > 255) cm->fc.mvc_hp[i].prob[MVPsign_hp] = 255;
else cm->fc.mvc_hp[i].prob[MVPsign_hp] = prob;
for (t = 0; t < mvnum_short_hp - 1; ++t) {
count = short_bct[t][0] + short_bct[t][1];
count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count;
factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT);
prob = ((int)cm->fc.pre_mvc_hp[i].prob[MVPshort_hp + t] * (256 - factor) +
(int)Pnew[MVPshort_hp + t] * factor + 128) >> 8;
if (prob <= 0) cm->fc.mvc_hp[i].prob[MVPshort_hp + t] = 1;
else if (prob > 255) cm->fc.mvc_hp[i].prob[MVPshort_hp + t] = 255;
else cm->fc.mvc_hp[i].prob[MVPshort_hp + t] = prob;
}
for (t = 0; t < mvlong_width_hp; ++t) {
count = bit_ct[t][0] + bit_ct[t][1];
count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count;
factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT);
prob = ((int)cm->fc.pre_mvc_hp[i].prob[MVPbits_hp + t] * (256 - factor) +
(int)Pnew[MVPbits_hp + t] * factor + 128) >> 8;
if (prob <= 0) cm->fc.mvc_hp[i].prob[MVPbits_hp + t] = 1;
else if (prob > 255) cm->fc.mvc_hp[i].prob[MVPbits_hp + t] = 255;
else cm->fc.mvc_hp[i].prob[MVPbits_hp + t] = prob;
}
}
}