vpx/vp10/common/entropymv.h
Ronald S. Bultje 1e9e9ce2dc vp10: fix entropy counts for the hp bit.
The counts didn't take usehp into account, which means that if the
scope of the refmv is too large for the hp bit to be coded, the value
(always 1) is still included in the stats. Therefore, the final
counts will not reflect the entropy of the coded bits, but rather the
entropy of the combination of coded bits and the implied value (which
is always 1). Fix that by only including counts if the hp bit is
actually coded.

See issue 1060.

Change-Id: I19a3adda4a8662a05f08a9e58d7e56ff979be11e
2015-09-14 16:13:59 -04:00

134 lines
3.9 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.
*/
#ifndef VP10_COMMON_ENTROPYMV_H_
#define VP10_COMMON_ENTROPYMV_H_
#include "./vpx_config.h"
#include "vpx_dsp/prob.h"
#include "vp10/common/mv.h"
#ifdef __cplusplus
extern "C" {
#endif
struct VP10Common;
void vp10_init_mv_probs(struct VP10Common *cm);
void vp10_adapt_mv_probs(struct VP10Common *cm, int usehp);
int vp10_use_mv_hp(const MV *ref);
#define MV_UPDATE_PROB 252
/* Symbols for coding which components are zero jointly */
#define MV_JOINTS 4
typedef enum {
MV_JOINT_ZERO = 0, /* Zero vector */
MV_JOINT_HNZVZ = 1, /* Vert zero, hor nonzero */
MV_JOINT_HZVNZ = 2, /* Hor zero, vert nonzero */
MV_JOINT_HNZVNZ = 3, /* Both components nonzero */
} MV_JOINT_TYPE;
static INLINE int mv_joint_vertical(MV_JOINT_TYPE type) {
return type == MV_JOINT_HZVNZ || type == MV_JOINT_HNZVNZ;
}
static INLINE int mv_joint_horizontal(MV_JOINT_TYPE type) {
return type == MV_JOINT_HNZVZ || type == MV_JOINT_HNZVNZ;
}
/* Symbols for coding magnitude class of nonzero components */
#define MV_CLASSES 11
typedef enum {
MV_CLASS_0 = 0, /* (0, 2] integer pel */
MV_CLASS_1 = 1, /* (2, 4] integer pel */
MV_CLASS_2 = 2, /* (4, 8] integer pel */
MV_CLASS_3 = 3, /* (8, 16] integer pel */
MV_CLASS_4 = 4, /* (16, 32] integer pel */
MV_CLASS_5 = 5, /* (32, 64] integer pel */
MV_CLASS_6 = 6, /* (64, 128] integer pel */
MV_CLASS_7 = 7, /* (128, 256] integer pel */
MV_CLASS_8 = 8, /* (256, 512] integer pel */
MV_CLASS_9 = 9, /* (512, 1024] integer pel */
MV_CLASS_10 = 10, /* (1024,2048] integer pel */
} MV_CLASS_TYPE;
#define CLASS0_BITS 1 /* bits at integer precision for class 0 */
#define CLASS0_SIZE (1 << CLASS0_BITS)
#define MV_OFFSET_BITS (MV_CLASSES + CLASS0_BITS - 2)
#define MV_FP_SIZE 4
#define MV_MAX_BITS (MV_CLASSES + CLASS0_BITS + 2)
#define MV_MAX ((1 << MV_MAX_BITS) - 1)
#define MV_VALS ((MV_MAX << 1) + 1)
#define MV_IN_USE_BITS 14
#define MV_UPP ((1 << MV_IN_USE_BITS) - 1)
#define MV_LOW (-(1 << MV_IN_USE_BITS))
extern const vpx_tree_index vp10_mv_joint_tree[];
extern const vpx_tree_index vp10_mv_class_tree[];
extern const vpx_tree_index vp10_mv_class0_tree[];
extern const vpx_tree_index vp10_mv_fp_tree[];
typedef struct {
vpx_prob sign;
vpx_prob classes[MV_CLASSES - 1];
vpx_prob class0[CLASS0_SIZE - 1];
vpx_prob bits[MV_OFFSET_BITS];
vpx_prob class0_fp[CLASS0_SIZE][MV_FP_SIZE - 1];
vpx_prob fp[MV_FP_SIZE - 1];
vpx_prob class0_hp;
vpx_prob hp;
} nmv_component;
typedef struct {
vpx_prob joints[MV_JOINTS - 1];
nmv_component comps[2];
} nmv_context;
static INLINE MV_JOINT_TYPE vp10_get_mv_joint(const MV *mv) {
if (mv->row == 0) {
return mv->col == 0 ? MV_JOINT_ZERO : MV_JOINT_HNZVZ;
} else {
return mv->col == 0 ? MV_JOINT_HZVNZ : MV_JOINT_HNZVNZ;
}
}
MV_CLASS_TYPE vp10_get_mv_class(int z, int *offset);
typedef struct {
unsigned int sign[2];
unsigned int classes[MV_CLASSES];
unsigned int class0[CLASS0_SIZE];
unsigned int bits[MV_OFFSET_BITS][2];
unsigned int class0_fp[CLASS0_SIZE][MV_FP_SIZE];
unsigned int fp[MV_FP_SIZE];
unsigned int class0_hp[2];
unsigned int hp[2];
} nmv_component_counts;
typedef struct {
unsigned int joints[MV_JOINTS];
nmv_component_counts comps[2];
} nmv_context_counts;
void vp10_inc_mv(const MV *mv, nmv_context_counts *mvctx, const int usehp);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VP10_COMMON_ENTROPYMV_H_