c456b35fdf
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
113 lines
3.9 KiB
C
113 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.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include "vp9/common/vp9_blockd.h"
|
|
#include "vp9/common/vp9_seg_common.h"
|
|
|
|
static const int segfeaturedata_signed[SEG_LVL_MAX] = { 1, 1, 0, 0, 0, 0 };
|
|
static const int seg_feature_data_max[SEG_LVL_MAX] =
|
|
{ MAXQ, 63, 0xf, MB_MODE_COUNT - 1, 255, TX_SIZE_MAX_SB - 1};
|
|
|
|
// These functions provide access to new segment level features.
|
|
// Eventually these function may be "optimized out" but for the moment,
|
|
// the coding mechanism is still subject to change so these provide a
|
|
// convenient single point of change.
|
|
|
|
int vp9_segfeature_active(const MACROBLOCKD *xd,
|
|
int segment_id,
|
|
SEG_LVL_FEATURES feature_id) {
|
|
// Return true if mask bit set and segmentation enabled.
|
|
return (xd->segmentation_enabled &&
|
|
(xd->segment_feature_mask[segment_id] &
|
|
(0x01 << feature_id)));
|
|
}
|
|
|
|
void vp9_clearall_segfeatures(MACROBLOCKD *xd) {
|
|
vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
|
|
vpx_memset(xd->segment_feature_mask, 0, sizeof(xd->segment_feature_mask));
|
|
}
|
|
|
|
void vp9_enable_segfeature(MACROBLOCKD *xd,
|
|
int segment_id,
|
|
SEG_LVL_FEATURES feature_id) {
|
|
xd->segment_feature_mask[segment_id] |= (0x01 << feature_id);
|
|
}
|
|
|
|
void vp9_disable_segfeature(MACROBLOCKD *xd,
|
|
int segment_id,
|
|
SEG_LVL_FEATURES feature_id) {
|
|
xd->segment_feature_mask[segment_id] &= ~(1 << feature_id);
|
|
}
|
|
|
|
int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id) {
|
|
return seg_feature_data_max[feature_id];
|
|
}
|
|
|
|
int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id) {
|
|
return (segfeaturedata_signed[feature_id]);
|
|
}
|
|
|
|
void vp9_clear_segdata(MACROBLOCKD *xd,
|
|
int segment_id,
|
|
SEG_LVL_FEATURES feature_id) {
|
|
xd->segment_feature_data[segment_id][feature_id] = 0;
|
|
}
|
|
|
|
void vp9_set_segdata(MACROBLOCKD *xd,
|
|
int segment_id,
|
|
SEG_LVL_FEATURES feature_id,
|
|
int seg_data) {
|
|
assert(seg_data <= seg_feature_data_max[feature_id]);
|
|
if (seg_data < 0) {
|
|
assert(segfeaturedata_signed[feature_id]);
|
|
assert(-seg_data <= seg_feature_data_max[feature_id]);
|
|
}
|
|
|
|
xd->segment_feature_data[segment_id][feature_id] = seg_data;
|
|
}
|
|
|
|
int vp9_get_segdata(const MACROBLOCKD *xd,
|
|
int segment_id,
|
|
SEG_LVL_FEATURES feature_id) {
|
|
return xd->segment_feature_data[segment_id][feature_id];
|
|
}
|
|
|
|
void vp9_clear_segref(MACROBLOCKD *xd, int segment_id) {
|
|
xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] = 0;
|
|
}
|
|
|
|
void vp9_set_segref(MACROBLOCKD *xd,
|
|
int segment_id,
|
|
MV_REFERENCE_FRAME ref_frame) {
|
|
xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] |=
|
|
(1 << ref_frame);
|
|
}
|
|
|
|
int vp9_check_segref(const MACROBLOCKD *xd,
|
|
int segment_id,
|
|
MV_REFERENCE_FRAME ref_frame) {
|
|
return (xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] &
|
|
(1 << ref_frame)) ? 1 : 0;
|
|
}
|
|
|
|
int vp9_check_segref_inter(MACROBLOCKD *xd, int segment_id) {
|
|
return (xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] &
|
|
~(1 << INTRA_FRAME)) ? 1 : 0;
|
|
}
|
|
|
|
int vp9_get_seg_tx_type(MACROBLOCKD *xd, int segment_id) {
|
|
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_TRANSFORM))
|
|
return vp9_get_segdata(xd, segment_id, SEG_LVL_TRANSFORM);
|
|
else
|
|
return TX_4X4;
|
|
}
|
|
// TBD? Functions to read and write segment data with range / validity checking
|