2010-05-18 19:58:33 +04:00
|
|
|
/*
|
2010-09-09 16:16:39 +04:00
|
|
|
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
2010-05-18 19:58:33 +04:00
|
|
|
*
|
2010-06-18 20:39:21 +04:00
|
|
|
* Use of this source code is governed by a BSD-style license
|
2010-06-05 00:19:40 +04:00
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
2010-06-18 20:39:21 +04:00
|
|
|
* in the file PATENTS. All contributing project authors may
|
2010-06-05 00:19:40 +04:00
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
2010-05-18 19:58:33 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2012-11-28 01:59:17 +04:00
|
|
|
#include "vp9/common/vp9_type_aliases.h"
|
|
|
|
#include "vp9/common/vp9_blockd.h"
|
2012-11-28 22:41:40 +04:00
|
|
|
#include "vp9/decoder/vp9_onyxd_int.h"
|
2010-05-18 19:58:33 +04:00
|
|
|
#include "vpx_mem/vpx_mem.h"
|
|
|
|
#include "vpx_ports/mem.h"
|
2012-11-28 22:41:40 +04:00
|
|
|
#include "vp9/decoder/vp9_detokenize.h"
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-11-28 01:59:17 +04:00
|
|
|
#include "vp9/common/vp9_seg_common.h"
|
2011-10-05 14:26:00 +04:00
|
|
|
|
2010-05-18 19:58:33 +04:00
|
|
|
#define EOB_CONTEXT_NODE 0
|
|
|
|
#define ZERO_CONTEXT_NODE 1
|
|
|
|
#define ONE_CONTEXT_NODE 2
|
|
|
|
#define LOW_VAL_CONTEXT_NODE 3
|
|
|
|
#define TWO_CONTEXT_NODE 4
|
|
|
|
#define THREE_CONTEXT_NODE 5
|
|
|
|
#define HIGH_LOW_CONTEXT_NODE 6
|
|
|
|
#define CAT_ONE_CONTEXT_NODE 7
|
|
|
|
#define CAT_THREEFOUR_CONTEXT_NODE 8
|
|
|
|
#define CAT_THREE_CONTEXT_NODE 9
|
|
|
|
#define CAT_FIVE_CONTEXT_NODE 10
|
|
|
|
|
2011-07-26 01:11:24 +04:00
|
|
|
#define CAT1_MIN_VAL 5
|
|
|
|
#define CAT2_MIN_VAL 7
|
|
|
|
#define CAT3_MIN_VAL 11
|
|
|
|
#define CAT4_MIN_VAL 19
|
|
|
|
#define CAT5_MIN_VAL 35
|
|
|
|
#define CAT6_MIN_VAL 67
|
|
|
|
#define CAT1_PROB0 159
|
|
|
|
#define CAT2_PROB0 145
|
|
|
|
#define CAT2_PROB1 165
|
|
|
|
|
|
|
|
#define CAT3_PROB0 140
|
|
|
|
#define CAT3_PROB1 148
|
|
|
|
#define CAT3_PROB2 173
|
|
|
|
|
|
|
|
#define CAT4_PROB0 135
|
|
|
|
#define CAT4_PROB1 140
|
|
|
|
#define CAT4_PROB2 155
|
|
|
|
#define CAT4_PROB3 176
|
|
|
|
|
|
|
|
#define CAT5_PROB0 130
|
|
|
|
#define CAT5_PROB1 134
|
|
|
|
#define CAT5_PROB2 141
|
|
|
|
#define CAT5_PROB3 157
|
|
|
|
#define CAT5_PROB4 180
|
|
|
|
|
32x32 transform for superblocks.
This adds Debargha's DCT/DWT hybrid and a regular 32x32 DCT, and adds
code all over the place to wrap that in the bitstream/encoder/decoder/RD.
Some implementation notes (these probably need careful review):
- token range is extended by 1 bit, since the value range out of this
transform is [-16384,16383].
- the coefficients coming out of the FDCT are manually scaled back by
1 bit, or else they won't fit in int16_t (they are 17 bits). Because
of this, the RD error scoring does not right-shift the MSE score by
two (unlike for 4x4/8x8/16x16).
- to compensate for this loss in precision, the quantizer is halved
also. This is currently a little hacky.
- FDCT and IDCT is double-only right now. Needs a fixed-point impl.
- There are no default probabilities for the 32x32 transform yet; I'm
simply using the 16x16 luma ones. A future commit will add newly
generated probabilities for all transforms.
- No ADST version. I don't think we'll add one for this level; if an
ADST is desired, transform-size selection can scale back to 16x16
or lower, and use an ADST at that level.
Additional notes specific to Debargha's DWT/DCT hybrid:
- coefficient scale is different for the top/left 16x16 (DCT-over-DWT)
block than for the rest (DWT pixel differences) of the block. Therefore,
RD error scoring isn't easily scalable between coefficient and pixel
domain. Thus, unfortunately, we need to compute the RD distortion in
the pixel domain until we figure out how to scale these appropriately.
Change-Id: I00386f20f35d7fabb19aba94c8162f8aee64ef2b
2012-12-08 02:45:05 +04:00
|
|
|
static const unsigned char cat6_prob[15] = {
|
|
|
|
254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0
|
|
|
|
};
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-11-06 02:22:59 +04:00
|
|
|
void vp9_reset_mb_tokens_context(MACROBLOCKD* const xd) {
|
2012-11-16 03:14:38 +04:00
|
|
|
/* Clear entropy contexts */
|
2012-08-14 14:32:29 +04:00
|
|
|
if ((xd->mode_info_context->mbmi.mode != B_PRED &&
|
2012-11-16 03:14:38 +04:00
|
|
|
xd->mode_info_context->mbmi.mode != I8X8_PRED &&
|
|
|
|
xd->mode_info_context->mbmi.mode != SPLITMV)
|
|
|
|
|| xd->mode_info_context->mbmi.txfm_size == TX_16X16) {
|
2012-08-14 14:32:29 +04:00
|
|
|
vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
|
|
|
|
vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
|
2012-07-14 02:21:29 +04:00
|
|
|
} else {
|
2012-08-14 14:32:29 +04:00
|
|
|
vpx_memset(xd->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
|
|
|
|
vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1);
|
2012-11-28 04:02:35 +04:00
|
|
|
xd->above_context->y2 = 1;
|
|
|
|
xd->left_context->y2 = 1;
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
2010-05-18 19:58:33 +04:00
|
|
|
}
|
2010-08-12 17:05:37 +04:00
|
|
|
|
2012-10-31 04:12:12 +04:00
|
|
|
DECLARE_ALIGNED(16, extern const unsigned char, vp9_norm[256]);
|
2012-03-19 22:02:04 +04:00
|
|
|
|
2012-11-01 01:40:53 +04:00
|
|
|
static int get_signed(BOOL_DECODER *br, int value_to_sign) {
|
2012-07-14 02:21:29 +04:00
|
|
|
const int split = (br->range + 1) >> 1;
|
2012-11-01 01:40:53 +04:00
|
|
|
const VP9_BD_VALUE bigsplit = (VP9_BD_VALUE)split << (VP9_BD_VALUE_SIZE - 8);
|
2012-07-14 02:21:29 +04:00
|
|
|
int v;
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-07-14 02:21:29 +04:00
|
|
|
if (br->count < 0)
|
2012-10-31 03:16:28 +04:00
|
|
|
vp9_bool_decoder_fill(br);
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-07-14 02:21:29 +04:00
|
|
|
if (br->value < bigsplit) {
|
|
|
|
br->range = split;
|
|
|
|
v = value_to_sign;
|
|
|
|
} else {
|
|
|
|
br->range = br->range - split;
|
|
|
|
br->value = br->value - bigsplit;
|
|
|
|
v = -value_to_sign;
|
|
|
|
}
|
|
|
|
br->range += br->range;
|
|
|
|
br->value += br->value;
|
|
|
|
--br->count;
|
2010-08-20 21:58:19 +04:00
|
|
|
|
2012-07-14 02:21:29 +04:00
|
|
|
return v;
|
2012-07-10 20:36:56 +04:00
|
|
|
}
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-11-17 22:35:47 +04:00
|
|
|
#define INCREMENT_COUNT(token) \
|
|
|
|
do { \
|
|
|
|
coef_counts[coef_bands[c]][pt][token]++; \
|
|
|
|
pt = vp9_prev_token_class[token]; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define WRITE_COEF_CONTINUE(val, token) \
|
2012-08-03 04:03:14 +04:00
|
|
|
{ \
|
2012-11-01 01:40:53 +04:00
|
|
|
qcoeff_ptr[scan[c]] = (INT16) get_signed(br, val); \
|
2012-11-17 22:35:47 +04:00
|
|
|
INCREMENT_COUNT(token); \
|
2012-07-14 02:21:29 +04:00
|
|
|
c++; \
|
|
|
|
continue; \
|
|
|
|
}
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-08-03 04:03:14 +04:00
|
|
|
#define ADJUST_COEF(prob, bits_count) \
|
|
|
|
do { \
|
2012-11-01 01:40:53 +04:00
|
|
|
if (vp9_read(br, prob)) \
|
2012-07-14 02:21:29 +04:00
|
|
|
val += (UINT16)(1 << bits_count);\
|
|
|
|
} while (0);
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-10-31 04:53:32 +04:00
|
|
|
static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
|
2012-10-18 03:47:38 +04:00
|
|
|
BOOL_DECODER* const br,
|
|
|
|
ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
|
|
|
|
PLANE_TYPE type,
|
|
|
|
TX_TYPE tx_type,
|
2012-11-17 23:11:06 +04:00
|
|
|
int seg_eob, INT16 *qcoeff_ptr,
|
2012-11-18 06:32:33 +04:00
|
|
|
const int *const scan, TX_SIZE txfm_size,
|
2012-10-18 03:47:38 +04:00
|
|
|
const int *coef_bands) {
|
2012-07-14 02:21:29 +04:00
|
|
|
FRAME_CONTEXT *const fc = &dx->common.fc;
|
2012-11-17 22:35:47 +04:00
|
|
|
int pt, c = (type == PLANE_TYPE_Y_NO_DC);
|
2012-11-17 23:07:23 +04:00
|
|
|
vp9_prob (*coef_probs)[PREV_COEF_CONTEXTS][ENTROPY_NODES], *prob;
|
2012-11-17 22:18:41 +04:00
|
|
|
unsigned int (*coef_counts)[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
|
2012-08-03 04:03:14 +04:00
|
|
|
|
2012-11-18 06:32:33 +04:00
|
|
|
switch (txfm_size) {
|
2012-08-22 02:08:54 +04:00
|
|
|
default:
|
2012-08-03 04:03:14 +04:00
|
|
|
case TX_4X4:
|
2012-11-17 22:18:41 +04:00
|
|
|
if (tx_type == DCT_DCT) {
|
2012-11-17 23:07:23 +04:00
|
|
|
coef_probs = fc->coef_probs[type];
|
2012-11-17 22:18:41 +04:00
|
|
|
coef_counts = fc->coef_counts[type];
|
|
|
|
} else {
|
2012-11-17 23:07:23 +04:00
|
|
|
coef_probs = fc->hybrid_coef_probs[type];
|
2012-11-17 22:18:41 +04:00
|
|
|
coef_counts = fc->hybrid_coef_counts[type];
|
|
|
|
}
|
2012-08-03 04:03:14 +04:00
|
|
|
break;
|
|
|
|
case TX_8X8:
|
2012-11-17 22:18:41 +04:00
|
|
|
if (tx_type == DCT_DCT) {
|
2012-11-17 23:07:23 +04:00
|
|
|
coef_probs = fc->coef_probs_8x8[type];
|
2012-11-17 22:18:41 +04:00
|
|
|
coef_counts = fc->coef_counts_8x8[type];
|
|
|
|
} else {
|
2012-11-17 23:07:23 +04:00
|
|
|
coef_probs = fc->hybrid_coef_probs_8x8[type];
|
2012-11-17 22:18:41 +04:00
|
|
|
coef_counts = fc->hybrid_coef_counts_8x8[type];
|
|
|
|
}
|
2012-08-03 04:03:14 +04:00
|
|
|
break;
|
2012-08-22 02:08:54 +04:00
|
|
|
case TX_16X16:
|
2012-11-17 22:18:41 +04:00
|
|
|
if (tx_type == DCT_DCT) {
|
2012-11-17 23:07:23 +04:00
|
|
|
coef_probs = fc->coef_probs_16x16[type];
|
2012-11-17 22:18:41 +04:00
|
|
|
coef_counts = fc->coef_counts_16x16[type];
|
|
|
|
} else {
|
2012-11-17 23:07:23 +04:00
|
|
|
coef_probs = fc->hybrid_coef_probs_16x16[type];
|
2012-11-17 22:18:41 +04:00
|
|
|
coef_counts = fc->hybrid_coef_counts_16x16[type];
|
|
|
|
}
|
2012-08-03 04:03:14 +04:00
|
|
|
break;
|
32x32 transform for superblocks.
This adds Debargha's DCT/DWT hybrid and a regular 32x32 DCT, and adds
code all over the place to wrap that in the bitstream/encoder/decoder/RD.
Some implementation notes (these probably need careful review):
- token range is extended by 1 bit, since the value range out of this
transform is [-16384,16383].
- the coefficients coming out of the FDCT are manually scaled back by
1 bit, or else they won't fit in int16_t (they are 17 bits). Because
of this, the RD error scoring does not right-shift the MSE score by
two (unlike for 4x4/8x8/16x16).
- to compensate for this loss in precision, the quantizer is halved
also. This is currently a little hacky.
- FDCT and IDCT is double-only right now. Needs a fixed-point impl.
- There are no default probabilities for the 32x32 transform yet; I'm
simply using the 16x16 luma ones. A future commit will add newly
generated probabilities for all transforms.
- No ADST version. I don't think we'll add one for this level; if an
ADST is desired, transform-size selection can scale back to 16x16
or lower, and use an ADST at that level.
Additional notes specific to Debargha's DWT/DCT hybrid:
- coefficient scale is different for the top/left 16x16 (DCT-over-DWT)
block than for the rest (DWT pixel differences) of the block. Therefore,
RD error scoring isn't easily scalable between coefficient and pixel
domain. Thus, unfortunately, we need to compute the RD distortion in
the pixel domain until we figure out how to scale these appropriately.
Change-Id: I00386f20f35d7fabb19aba94c8162f8aee64ef2b
2012-12-08 02:45:05 +04:00
|
|
|
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
|
|
|
|
case TX_32X32:
|
|
|
|
coef_probs = fc->coef_probs_32x32[type];
|
|
|
|
coef_counts = fc->coef_counts_32x32[type];
|
|
|
|
break;
|
|
|
|
#endif
|
2012-08-03 04:03:14 +04:00
|
|
|
}
|
2012-07-14 02:21:29 +04:00
|
|
|
|
2012-11-17 22:35:47 +04:00
|
|
|
VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
|
2012-07-14 02:21:29 +04:00
|
|
|
while (1) {
|
|
|
|
int val;
|
|
|
|
const uint8_t *cat6 = cat6_prob;
|
2012-11-14 21:51:23 +04:00
|
|
|
if (c >= seg_eob) break;
|
2012-11-17 23:07:23 +04:00
|
|
|
prob = coef_probs[coef_bands[c]][pt];
|
2012-11-01 01:40:53 +04:00
|
|
|
if (!vp9_read(br, prob[EOB_CONTEXT_NODE]))
|
2012-07-14 02:21:29 +04:00
|
|
|
break;
|
2012-08-03 04:03:14 +04:00
|
|
|
SKIP_START:
|
2012-11-14 21:51:23 +04:00
|
|
|
if (c >= seg_eob) break;
|
2012-11-01 01:40:53 +04:00
|
|
|
if (!vp9_read(br, prob[ZERO_CONTEXT_NODE])) {
|
2012-11-17 22:35:47 +04:00
|
|
|
INCREMENT_COUNT(ZERO_TOKEN);
|
2012-07-14 02:21:29 +04:00
|
|
|
++c;
|
2012-11-17 23:07:23 +04:00
|
|
|
prob = coef_probs[coef_bands[c]][pt];
|
2012-07-14 02:21:29 +04:00
|
|
|
goto SKIP_START;
|
|
|
|
}
|
|
|
|
// ONE_CONTEXT_NODE_0_
|
2012-11-01 01:40:53 +04:00
|
|
|
if (!vp9_read(br, prob[ONE_CONTEXT_NODE])) {
|
2012-11-17 23:07:23 +04:00
|
|
|
WRITE_COEF_CONTINUE(1, ONE_TOKEN);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
|
|
|
// LOW_VAL_CONTEXT_NODE_0_
|
2012-11-01 01:40:53 +04:00
|
|
|
if (!vp9_read(br, prob[LOW_VAL_CONTEXT_NODE])) {
|
|
|
|
if (!vp9_read(br, prob[TWO_CONTEXT_NODE])) {
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(2, TWO_TOKEN);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
2012-11-01 01:40:53 +04:00
|
|
|
if (!vp9_read(br, prob[THREE_CONTEXT_NODE])) {
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(3, THREE_TOKEN);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
|
|
|
// HIGH_LOW_CONTEXT_NODE_0_
|
2012-11-01 01:40:53 +04:00
|
|
|
if (!vp9_read(br, prob[HIGH_LOW_CONTEXT_NODE])) {
|
|
|
|
if (!vp9_read(br, prob[CAT_ONE_CONTEXT_NODE])) {
|
2012-07-14 02:21:29 +04:00
|
|
|
val = CAT1_MIN_VAL;
|
|
|
|
ADJUST_COEF(CAT1_PROB0, 0);
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
|
|
|
val = CAT2_MIN_VAL;
|
|
|
|
ADJUST_COEF(CAT2_PROB1, 1);
|
|
|
|
ADJUST_COEF(CAT2_PROB0, 0);
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
|
2012-07-10 20:36:56 +04:00
|
|
|
}
|
2012-07-14 02:21:29 +04:00
|
|
|
// CAT_THREEFOUR_CONTEXT_NODE_0_
|
2012-11-01 01:40:53 +04:00
|
|
|
if (!vp9_read(br, prob[CAT_THREEFOUR_CONTEXT_NODE])) {
|
|
|
|
if (!vp9_read(br, prob[CAT_THREE_CONTEXT_NODE])) {
|
2012-07-14 02:21:29 +04:00
|
|
|
val = CAT3_MIN_VAL;
|
|
|
|
ADJUST_COEF(CAT3_PROB2, 2);
|
|
|
|
ADJUST_COEF(CAT3_PROB1, 1);
|
|
|
|
ADJUST_COEF(CAT3_PROB0, 0);
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
|
|
|
val = CAT4_MIN_VAL;
|
|
|
|
ADJUST_COEF(CAT4_PROB3, 3);
|
|
|
|
ADJUST_COEF(CAT4_PROB2, 2);
|
|
|
|
ADJUST_COEF(CAT4_PROB1, 1);
|
|
|
|
ADJUST_COEF(CAT4_PROB0, 0);
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
|
|
|
// CAT_FIVE_CONTEXT_NODE_0_:
|
2012-11-01 01:40:53 +04:00
|
|
|
if (!vp9_read(br, prob[CAT_FIVE_CONTEXT_NODE])) {
|
2012-07-14 02:21:29 +04:00
|
|
|
val = CAT5_MIN_VAL;
|
|
|
|
ADJUST_COEF(CAT5_PROB4, 4);
|
|
|
|
ADJUST_COEF(CAT5_PROB3, 3);
|
|
|
|
ADJUST_COEF(CAT5_PROB2, 2);
|
|
|
|
ADJUST_COEF(CAT5_PROB1, 1);
|
|
|
|
ADJUST_COEF(CAT5_PROB0, 0);
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
|
|
|
val = 0;
|
|
|
|
while (*cat6) {
|
2012-11-01 01:40:53 +04:00
|
|
|
val = (val << 1) | vp9_read(br, *cat6++);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
|
|
|
val += CAT6_MIN_VAL;
|
2012-11-17 22:35:47 +04:00
|
|
|
WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
2012-06-25 23:26:09 +04:00
|
|
|
|
2012-11-17 22:35:47 +04:00
|
|
|
if (c < seg_eob)
|
|
|
|
coef_counts[coef_bands[c]][pt][DCT_EOB_TOKEN]++;
|
2012-11-17 22:18:41 +04:00
|
|
|
|
2012-11-29 05:34:02 +04:00
|
|
|
a[0] = l[0] = (c > !type);
|
2012-11-17 23:22:38 +04:00
|
|
|
|
2012-07-14 02:21:29 +04:00
|
|
|
return c;
|
2012-07-10 20:36:56 +04:00
|
|
|
}
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-11-23 20:17:06 +04:00
|
|
|
static int get_eob(MACROBLOCKD* const xd, int segment_id, int eob_max) {
|
2012-11-14 21:51:23 +04:00
|
|
|
int active = vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB);
|
|
|
|
int eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB);
|
|
|
|
|
|
|
|
if (!active || eob > eob_max)
|
|
|
|
eob = eob_max;
|
|
|
|
return eob;
|
|
|
|
}
|
|
|
|
|
32x32 transform for superblocks.
This adds Debargha's DCT/DWT hybrid and a regular 32x32 DCT, and adds
code all over the place to wrap that in the bitstream/encoder/decoder/RD.
Some implementation notes (these probably need careful review):
- token range is extended by 1 bit, since the value range out of this
transform is [-16384,16383].
- the coefficients coming out of the FDCT are manually scaled back by
1 bit, or else they won't fit in int16_t (they are 17 bits). Because
of this, the RD error scoring does not right-shift the MSE score by
two (unlike for 4x4/8x8/16x16).
- to compensate for this loss in precision, the quantizer is halved
also. This is currently a little hacky.
- FDCT and IDCT is double-only right now. Needs a fixed-point impl.
- There are no default probabilities for the 32x32 transform yet; I'm
simply using the 16x16 luma ones. A future commit will add newly
generated probabilities for all transforms.
- No ADST version. I don't think we'll add one for this level; if an
ADST is desired, transform-size selection can scale back to 16x16
or lower, and use an ADST at that level.
Additional notes specific to Debargha's DWT/DCT hybrid:
- coefficient scale is different for the top/left 16x16 (DCT-over-DWT)
block than for the rest (DWT pixel differences) of the block. Therefore,
RD error scoring isn't easily scalable between coefficient and pixel
domain. Thus, unfortunately, we need to compute the RD distortion in
the pixel domain until we figure out how to scale these appropriately.
Change-Id: I00386f20f35d7fabb19aba94c8162f8aee64ef2b
2012-12-08 02:45:05 +04:00
|
|
|
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
|
|
|
|
int vp9_decode_sb_tokens(VP9D_COMP* const pbi,
|
|
|
|
MACROBLOCKD* const xd,
|
|
|
|
BOOL_DECODER* const bc) {
|
|
|
|
ENTROPY_CONTEXT* const A = (ENTROPY_CONTEXT *)xd->above_context;
|
|
|
|
ENTROPY_CONTEXT* const L = (ENTROPY_CONTEXT *)xd->left_context;
|
|
|
|
unsigned short* const eobs = xd->eobs;
|
|
|
|
const int segment_id = xd->mode_info_context->mbmi.segment_id;
|
|
|
|
int c, i, eobtotal = 0, seg_eob;
|
|
|
|
|
|
|
|
// Luma block
|
|
|
|
eobs[0] = c = decode_coefs(pbi, xd, bc, A, L, PLANE_TYPE_Y_WITH_DC,
|
|
|
|
DCT_DCT, get_eob(xd, segment_id, 1024),
|
|
|
|
xd->sb_coeff_data.qcoeff,
|
|
|
|
vp9_default_zig_zag1d_32x32,
|
|
|
|
TX_32X32, vp9_coef_bands_32x32);
|
|
|
|
A[1] = A[2] = A[3] = A[0];
|
|
|
|
L[1] = L[2] = L[3] = L[0];
|
|
|
|
eobtotal += c;
|
|
|
|
|
|
|
|
// 16x16 chroma blocks
|
|
|
|
seg_eob = get_eob(xd, segment_id, 256);
|
|
|
|
for (i = 16; i < 24; i += 4) {
|
|
|
|
ENTROPY_CONTEXT* const a = A + vp9_block2above_8x8[i];
|
|
|
|
ENTROPY_CONTEXT* const l = L + vp9_block2left_8x8[i];
|
|
|
|
|
|
|
|
eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_UV,
|
|
|
|
DCT_DCT, seg_eob,
|
|
|
|
xd->sb_coeff_data.qcoeff + 1024 + (i - 16) * 64,
|
|
|
|
vp9_default_zig_zag1d_16x16,
|
|
|
|
TX_16X16, vp9_coef_bands_16x16);
|
|
|
|
a[1] = a[0];
|
|
|
|
l[1] = l[0];
|
|
|
|
eobtotal += c;
|
|
|
|
}
|
|
|
|
|
|
|
|
// no Y2 block
|
|
|
|
vpx_memset(&A[8], 0, sizeof(A[8]));
|
|
|
|
vpx_memset(&L[8], 0, sizeof(L[8]));
|
|
|
|
|
|
|
|
vpx_memcpy(xd->above_context + 1, xd->above_context,
|
|
|
|
sizeof(ENTROPY_CONTEXT_PLANES));
|
|
|
|
vpx_memcpy(xd->left_context + 1, xd->left_context,
|
|
|
|
sizeof(ENTROPY_CONTEXT_PLANES));
|
|
|
|
|
|
|
|
return eobtotal;
|
|
|
|
}
|
|
|
|
#endif
|
2012-11-14 21:51:23 +04:00
|
|
|
|
2012-11-23 23:23:50 +04:00
|
|
|
static int vp9_decode_mb_tokens_16x16(VP9D_COMP* const pbi,
|
|
|
|
MACROBLOCKD* const xd,
|
|
|
|
BOOL_DECODER* const bc) {
|
2012-08-03 04:03:14 +04:00
|
|
|
ENTROPY_CONTEXT* const A = (ENTROPY_CONTEXT *)xd->above_context;
|
|
|
|
ENTROPY_CONTEXT* const L = (ENTROPY_CONTEXT *)xd->left_context;
|
2012-11-03 00:06:51 +04:00
|
|
|
unsigned short* const eobs = xd->eobs;
|
2012-08-03 04:03:14 +04:00
|
|
|
const int segment_id = xd->mode_info_context->mbmi.segment_id;
|
2012-11-23 21:11:12 +04:00
|
|
|
int c, i, eobtotal = 0, seg_eob;
|
2012-08-03 04:03:14 +04:00
|
|
|
|
|
|
|
// Luma block
|
2012-11-23 21:11:12 +04:00
|
|
|
eobs[0] = c = decode_coefs(pbi, xd, bc, A, L, PLANE_TYPE_Y_WITH_DC,
|
|
|
|
get_tx_type(xd, &xd->block[0]),
|
|
|
|
get_eob(xd, segment_id, 256),
|
|
|
|
xd->qcoeff, vp9_default_zig_zag1d_16x16,
|
|
|
|
TX_16X16, vp9_coef_bands_16x16);
|
|
|
|
A[1] = A[2] = A[3] = A[0];
|
|
|
|
L[1] = L[2] = L[3] = L[0];
|
|
|
|
eobtotal += c;
|
2012-08-03 04:03:14 +04:00
|
|
|
|
|
|
|
// 8x8 chroma blocks
|
2012-11-14 21:51:23 +04:00
|
|
|
seg_eob = get_eob(xd, segment_id, 64);
|
2012-08-03 04:03:14 +04:00
|
|
|
for (i = 16; i < 24; i += 4) {
|
2012-10-31 04:12:12 +04:00
|
|
|
ENTROPY_CONTEXT* const a = A + vp9_block2above_8x8[i];
|
|
|
|
ENTROPY_CONTEXT* const l = L + vp9_block2left_8x8[i];
|
2012-08-03 04:03:14 +04:00
|
|
|
|
2012-11-23 21:11:12 +04:00
|
|
|
eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_UV,
|
|
|
|
DCT_DCT, seg_eob, xd->block[i].qcoeff,
|
|
|
|
vp9_default_zig_zag1d_8x8,
|
|
|
|
TX_8X8, vp9_coef_bands_8x8);
|
2012-08-03 04:03:14 +04:00
|
|
|
a[1] = a[0];
|
|
|
|
l[1] = l[0];
|
|
|
|
eobtotal += c;
|
|
|
|
}
|
2012-11-29 05:34:02 +04:00
|
|
|
A[8] = 0;
|
|
|
|
L[8] = 0;
|
2012-08-03 04:03:14 +04:00
|
|
|
return eobtotal;
|
|
|
|
}
|
|
|
|
|
2012-11-23 23:23:50 +04:00
|
|
|
static int vp9_decode_mb_tokens_8x8(VP9D_COMP* const pbi,
|
|
|
|
MACROBLOCKD* const xd,
|
|
|
|
BOOL_DECODER* const bc) {
|
2012-07-14 02:21:29 +04:00
|
|
|
ENTROPY_CONTEXT *const A = (ENTROPY_CONTEXT *)xd->above_context;
|
|
|
|
ENTROPY_CONTEXT *const L = (ENTROPY_CONTEXT *)xd->left_context;
|
2012-11-03 00:06:51 +04:00
|
|
|
unsigned short *const eobs = xd->eobs;
|
2012-10-15 02:29:56 +04:00
|
|
|
PLANE_TYPE type;
|
|
|
|
int c, i, eobtotal = 0, seg_eob;
|
2012-07-14 02:21:29 +04:00
|
|
|
const int segment_id = xd->mode_info_context->mbmi.segment_id;
|
2012-08-01 21:18:25 +04:00
|
|
|
|
2012-11-16 03:14:38 +04:00
|
|
|
int has_2nd_order = get_2nd_order_usage(xd);
|
2012-11-23 21:43:13 +04:00
|
|
|
// 2nd order DC block
|
2012-11-16 03:14:38 +04:00
|
|
|
if (has_2nd_order) {
|
2012-10-31 04:12:12 +04:00
|
|
|
ENTROPY_CONTEXT *const a = A + vp9_block2above_8x8[24];
|
|
|
|
ENTROPY_CONTEXT *const l = L + vp9_block2left_8x8[24];
|
2012-07-14 02:21:29 +04:00
|
|
|
|
2012-11-23 21:43:13 +04:00
|
|
|
eobs[24] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_Y2,
|
|
|
|
DCT_DCT, get_eob(xd, segment_id, 4),
|
|
|
|
xd->block[24].qcoeff,
|
|
|
|
vp9_default_zig_zag1d, TX_8X8, vp9_coef_bands);
|
2012-07-14 02:21:29 +04:00
|
|
|
eobtotal += c - 4;
|
|
|
|
type = PLANE_TYPE_Y_NO_DC;
|
2012-11-23 21:43:13 +04:00
|
|
|
} else {
|
2012-11-28 04:02:35 +04:00
|
|
|
xd->above_context->y2 = 1;
|
|
|
|
xd->left_context->y2 = 1;
|
2012-11-16 03:14:38 +04:00
|
|
|
eobs[24] = 0;
|
2012-07-14 02:21:29 +04:00
|
|
|
type = PLANE_TYPE_Y_WITH_DC;
|
2012-11-23 21:43:13 +04:00
|
|
|
}
|
2012-07-14 02:21:29 +04:00
|
|
|
|
2012-11-23 21:43:13 +04:00
|
|
|
// luma blocks
|
2012-11-14 21:51:23 +04:00
|
|
|
seg_eob = get_eob(xd, segment_id, 64);
|
2012-11-23 21:43:13 +04:00
|
|
|
for (i = 0; i < 16; i += 4) {
|
2012-10-31 04:12:12 +04:00
|
|
|
ENTROPY_CONTEXT *const a = A + vp9_block2above_8x8[i];
|
|
|
|
ENTROPY_CONTEXT *const l = L + vp9_block2left_8x8[i];
|
2012-07-14 02:21:29 +04:00
|
|
|
|
2012-11-17 23:22:38 +04:00
|
|
|
eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, type,
|
2012-11-23 21:43:13 +04:00
|
|
|
type == PLANE_TYPE_Y_WITH_DC ?
|
2012-11-16 03:14:38 +04:00
|
|
|
get_tx_type(xd, xd->block + i) : DCT_DCT,
|
2012-11-23 21:43:13 +04:00
|
|
|
seg_eob, xd->block[i].qcoeff,
|
|
|
|
vp9_default_zig_zag1d_8x8,
|
|
|
|
TX_8X8, vp9_coef_bands_8x8);
|
2012-07-14 02:21:29 +04:00
|
|
|
a[1] = a[0];
|
|
|
|
l[1] = l[0];
|
|
|
|
eobtotal += c;
|
|
|
|
}
|
|
|
|
|
2012-11-23 21:43:13 +04:00
|
|
|
// chroma blocks
|
|
|
|
if (xd->mode_info_context->mbmi.mode == I8X8_PRED ||
|
|
|
|
xd->mode_info_context->mbmi.mode == SPLITMV) {
|
|
|
|
// use 4x4 transform for U, V components in I8X8/splitmv prediction mode
|
2012-11-14 21:51:23 +04:00
|
|
|
seg_eob = get_eob(xd, segment_id, 16);
|
2012-08-01 21:18:25 +04:00
|
|
|
for (i = 16; i < 24; i++) {
|
2012-10-31 04:12:12 +04:00
|
|
|
ENTROPY_CONTEXT *const a = A + vp9_block2above[i];
|
|
|
|
ENTROPY_CONTEXT *const l = L + vp9_block2left[i];
|
2012-08-01 21:18:25 +04:00
|
|
|
|
2012-11-23 21:43:13 +04:00
|
|
|
eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_UV,
|
|
|
|
DCT_DCT, seg_eob, xd->block[i].qcoeff,
|
|
|
|
vp9_default_zig_zag1d, TX_4X4, vp9_coef_bands);
|
|
|
|
eobtotal += c;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 16; i < 24; i += 4) {
|
|
|
|
ENTROPY_CONTEXT *const a = A + vp9_block2above_8x8[i];
|
|
|
|
ENTROPY_CONTEXT *const l = L + vp9_block2left_8x8[i];
|
|
|
|
|
|
|
|
eobs[i] = c = decode_coefs(pbi, xd, bc, a, l, PLANE_TYPE_UV,
|
|
|
|
DCT_DCT, seg_eob, xd->block[i].qcoeff,
|
|
|
|
vp9_default_zig_zag1d_8x8,
|
|
|
|
TX_8X8, vp9_coef_bands_8x8);
|
|
|
|
a[1] = a[0];
|
|
|
|
l[1] = l[0];
|
2012-08-01 21:18:25 +04:00
|
|
|
eobtotal += c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 02:21:29 +04:00
|
|
|
return eobtotal;
|
2012-07-11 04:23:38 +04:00
|
|
|
}
|
|
|
|
|
2012-11-22 00:39:55 +04:00
|
|
|
int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd,
|
|
|
|
BOOL_DECODER* const bc,
|
|
|
|
PLANE_TYPE type, int i) {
|
2012-07-14 02:21:29 +04:00
|
|
|
ENTROPY_CONTEXT *const A = (ENTROPY_CONTEXT *)xd->above_context;
|
|
|
|
ENTROPY_CONTEXT *const L = (ENTROPY_CONTEXT *)xd->left_context;
|
2012-10-10 00:19:15 +04:00
|
|
|
ENTROPY_CONTEXT *const a = A + vp9_block2above[i];
|
|
|
|
ENTROPY_CONTEXT *const l = L + vp9_block2left[i];
|
2012-07-14 02:21:29 +04:00
|
|
|
INT16 *qcoeff_ptr = &xd->qcoeff[0];
|
2012-10-10 00:19:15 +04:00
|
|
|
const int *scan = vp9_default_zig_zag1d;
|
|
|
|
unsigned short *const eobs = xd->eobs;
|
2012-07-14 02:21:29 +04:00
|
|
|
int segment_id = xd->mode_info_context->mbmi.segment_id;
|
2012-11-17 10:26:12 +04:00
|
|
|
int c, seg_eob = get_eob(xd, segment_id, 16);
|
|
|
|
TX_TYPE tx_type = DCT_DCT;
|
2012-10-10 00:19:15 +04:00
|
|
|
|
|
|
|
if (type == PLANE_TYPE_Y_WITH_DC)
|
2012-11-16 03:14:38 +04:00
|
|
|
tx_type = get_tx_type_4x4(xd, &xd->block[i]);
|
2012-10-10 00:19:15 +04:00
|
|
|
switch (tx_type) {
|
|
|
|
case ADST_DCT :
|
|
|
|
scan = vp9_row_scan;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DCT_ADST :
|
|
|
|
scan = vp9_col_scan;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default :
|
|
|
|
scan = vp9_default_zig_zag1d;
|
|
|
|
break;
|
|
|
|
}
|
2012-11-17 23:22:38 +04:00
|
|
|
eobs[i] = c = decode_coefs(dx, xd, bc, a, l, type,
|
|
|
|
tx_type, seg_eob, qcoeff_ptr + i * 16,
|
|
|
|
scan, TX_4X4, vp9_coef_bands);
|
2012-10-10 00:19:15 +04:00
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2012-11-22 00:39:55 +04:00
|
|
|
int vp9_decode_mb_tokens_4x4_uv(VP9D_COMP* const dx,
|
|
|
|
MACROBLOCKD* const xd,
|
|
|
|
BOOL_DECODER* const bc) {
|
|
|
|
int eobtotal = 0, i;
|
|
|
|
|
|
|
|
for (i = 16; i < 24; i++)
|
|
|
|
eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_UV, i);
|
|
|
|
|
|
|
|
return eobtotal;
|
|
|
|
}
|
|
|
|
|
2012-11-23 23:23:50 +04:00
|
|
|
static int vp9_decode_mb_tokens_4x4(VP9D_COMP* const dx,
|
|
|
|
MACROBLOCKD* const xd,
|
|
|
|
BOOL_DECODER* const bc) {
|
2012-11-17 10:26:12 +04:00
|
|
|
int i, eobtotal = 0;
|
|
|
|
PLANE_TYPE type;
|
2012-10-10 00:19:15 +04:00
|
|
|
|
2012-11-16 03:14:38 +04:00
|
|
|
int has_2nd_order = get_2nd_order_usage(xd);
|
|
|
|
|
|
|
|
if (has_2nd_order) {
|
2012-11-22 00:39:55 +04:00
|
|
|
eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_Y2, 24) - 16;
|
2012-07-14 02:21:29 +04:00
|
|
|
type = PLANE_TYPE_Y_NO_DC;
|
|
|
|
} else {
|
2012-11-28 04:02:35 +04:00
|
|
|
xd->above_context->y2 = 1;
|
|
|
|
xd->left_context->y2 = 1;
|
2012-11-16 03:14:38 +04:00
|
|
|
xd->eobs[24] = 0;
|
2012-07-14 02:21:29 +04:00
|
|
|
type = PLANE_TYPE_Y_WITH_DC;
|
|
|
|
}
|
2010-05-18 19:58:33 +04:00
|
|
|
|
2012-11-17 10:26:12 +04:00
|
|
|
for (i = 0; i < 16; ++i) {
|
2012-11-22 00:39:55 +04:00
|
|
|
eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, type, i);
|
2012-07-14 02:21:29 +04:00
|
|
|
}
|
2012-11-22 00:39:55 +04:00
|
|
|
|
|
|
|
return eobtotal + vp9_decode_mb_tokens_4x4_uv(dx, xd, bc);
|
2010-05-18 19:58:33 +04:00
|
|
|
}
|
2012-11-23 23:23:50 +04:00
|
|
|
|
|
|
|
int vp9_decode_mb_tokens(VP9D_COMP* const dx,
|
|
|
|
MACROBLOCKD* const xd,
|
|
|
|
BOOL_DECODER* const bc) {
|
|
|
|
const TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
|
|
|
|
int eobtotal;
|
|
|
|
|
|
|
|
if (tx_size == TX_16X16) {
|
|
|
|
eobtotal = vp9_decode_mb_tokens_16x16(dx, xd, bc);
|
|
|
|
} else if (tx_size == TX_8X8) {
|
|
|
|
eobtotal = vp9_decode_mb_tokens_8x8(dx, xd, bc);
|
|
|
|
} else {
|
|
|
|
assert(tx_size == TX_4X4);
|
|
|
|
eobtotal = vp9_decode_mb_tokens_4x4(dx, xd, bc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return eobtotal;
|
|
|
|
}
|