Compare commits

...

2 Commits

Author SHA1 Message Date
Yongzhe Wang
f708a843b7 enabled alternative transform for inter blocks using ADST_ADST.
DST 32X32 included but not used.

Change-Id: I0183c48a7b43087562a9f048360c139414ec54e0
2014-04-30 17:32:26 -07:00
Yue Chen
a2d6abacf7 Migrating expts from experimental into playground
Migrates experiments from expeirmental to playground.
Included experiments are FILTERINTRA, MASKED_INTERINTER, INTERINTRA
and MASKED_INTERINTRA. Bugs in masked sub-pixel variance calculation
and masked sub-pixel motion search are fixed. Recursive filters for
intra prediction are upgraded to 4-tap filters.

Change-Id: I9964a7ebfefc1efa70bb66be7b35d975c3f66e23
2014-04-11 14:46:40 -07:00
37 changed files with 5307 additions and 30 deletions

7
configure vendored
View File

@@ -256,7 +256,14 @@ EXPERIMENT_LIST="
multiple_arf
non420
alpha
masked_interinter
interintra
masked_interintra
filterintra
ext_tx
ext_tx_dst32
"
CONFIG_LIST="
external_build
install_docs

View File

@@ -71,7 +71,7 @@ TEST_P(PartialIDctTest, ResultsMatch) {
size = 32;
break;
default:
ASSERT_TRUE(0) << "Wrong Size!";
FAIL() << "Wrong Size!";
break;
}
DECLARE_ALIGNED_ARRAY(16, int16_t, test_coef_block1, kMaxNumCoeffs);

View File

@@ -22,8 +22,10 @@ extern void vp9_rtcd();
}
#include "third_party/googletest/src/include/gtest/gtest.h"
static void append_gtest_filter(const char *str) {
static void append_negative_gtest_filter(const char *str) {
std::string filter = ::testing::FLAGS_gtest_filter;
// Negative patterns begin with one '-' followed by a ':' separated list.
if (filter.find('-') == std::string::npos) filter += '-';
filter += str;
::testing::FLAGS_gtest_filter = filter;
}
@@ -34,21 +36,21 @@ int main(int argc, char **argv) {
#if ARCH_X86 || ARCH_X86_64
const int simd_caps = x86_simd_caps();
if (!(simd_caps & HAS_MMX))
append_gtest_filter(":-MMX/*");
append_negative_gtest_filter(":-MMX/*");
if (!(simd_caps & HAS_SSE))
append_gtest_filter(":-SSE/*");
append_negative_gtest_filter(":-SSE/*");
if (!(simd_caps & HAS_SSE2))
append_gtest_filter(":-SSE2/*");
append_negative_gtest_filter(":-SSE2/*");
if (!(simd_caps & HAS_SSE3))
append_gtest_filter(":-SSE3/*");
append_negative_gtest_filter(":-SSE3/*");
if (!(simd_caps & HAS_SSSE3))
append_gtest_filter(":-SSSE3/*");
append_negative_gtest_filter(":-SSSE3/*");
if (!(simd_caps & HAS_SSE4_1))
append_gtest_filter(":-SSE4_1/*");
append_negative_gtest_filter(":-SSE4_1/*");
if (!(simd_caps & HAS_AVX))
append_gtest_filter(":-AVX/*");
append_negative_gtest_filter(":AVX/*");
if (!(simd_caps & HAS_AVX2))
append_gtest_filter(":-AVX2/*");
append_negative_gtest_filter(":AVX2/*");
#endif
#if !CONFIG_SHARED

View File

@@ -1401,6 +1401,7 @@ static void update_layer_contexts (VP8_COMP *cpi)
unsigned int i;
double prev_layer_framerate=0;
assert(oxcf->number_of_layers <= VPX_TS_MAX_LAYERS);
for (i=0; i<oxcf->number_of_layers; i++)
{
LAYER_CONTEXT *lc = &cpi->layer_context[i];
@@ -1623,6 +1624,12 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
cpi->oxcf.maximum_buffer_size =
rescale((int)cpi->oxcf.maximum_buffer_size,
cpi->oxcf.target_bandwidth, 1000);
// Under a configuration change, where maximum_buffer_size may change,
// keep buffer level clipped to the maximum allowed buffer size.
if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size) {
cpi->bits_off_target = cpi->oxcf.maximum_buffer_size;
cpi->buffer_level = cpi->bits_off_target;
}
/* Set up frame rate and related parameters rate control values. */
vp8_new_framerate(cpi, cpi->framerate);
@@ -2164,10 +2171,12 @@ void vp8_remove_compressor(VP8_COMP **ptr)
8.0 / 1000.0 / time_encoded;
double samples = 3.0 / 2 * cpi->frames_in_layer[i] *
lst_yv12->y_width * lst_yv12->y_height;
double total_psnr = vp8_mse2psnr(samples, 255.0,
cpi->total_error2[i]);
double total_psnr2 = vp8_mse2psnr(samples, 255.0,
cpi->total_error2_p[i]);
double total_psnr =
vp8_mse2psnr(samples, 255.0,
cpi->total_error2[i]);
double total_psnr2 =
vp8_mse2psnr(samples, 255.0,
cpi->total_error2_p[i]);
double total_ssim = 100 * pow(cpi->sum_ssim[i] /
cpi->sum_weights[i], 8.0);
@@ -2185,9 +2194,9 @@ void vp8_remove_compressor(VP8_COMP **ptr)
double samples = 3.0 / 2 * cpi->count *
lst_yv12->y_width * lst_yv12->y_height;
double total_psnr = vp8_mse2psnr(samples, 255.0,
cpi->total_sq_error);
cpi->total_sq_error);
double total_psnr2 = vp8_mse2psnr(samples, 255.0,
cpi->total_sq_error2);
cpi->total_sq_error2);
double total_ssim = 100 * pow(cpi->summed_quality /
cpi->summed_weights, 8.0);
@@ -2516,8 +2525,8 @@ static void generate_psnr_packet(VP8_COMP *cpi)
pkt.data.psnr.samples[3] = width * height;
for (i = 0; i < 4; i++)
pkt.data.psnr.psnr[i] = vp8_mse2psnr(pkt.data.psnr.samples[i], 255.0,
(double)(pkt.data.psnr.sse[i]));
pkt.data.psnr.psnr[i] = vp8_mse2psnr(pkt.data.psnr.samples[i], 255.0,
(double)(pkt.data.psnr.sse[i]));
vpx_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
}
@@ -2675,8 +2684,8 @@ static int resize_key_frame(VP8_COMP *cpi)
VP8_COMMON *cm = &cpi->common;
/* Do we need to apply resampling for one pass cbr.
* In one pass this is more limited than in two pass cbr
* The test and any change is only made one per key frame sequence
* In one pass this is more limited than in two pass cbr.
* The test and any change is only made once per key frame sequence.
*/
if (cpi->oxcf.allow_spatial_resampling && (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER))
{
@@ -2699,7 +2708,7 @@ static int resize_key_frame(VP8_COMP *cpi)
cm->vert_scale = (cm->vert_scale > NORMAL) ? cm->vert_scale - 1 : NORMAL;
}
/* Get the new hieght and width */
/* Get the new height and width */
Scale2Ratio(cm->horiz_scale, &hr, &hs);
Scale2Ratio(cm->vert_scale, &vr, &vs);
new_width = ((hs - 1) + (cpi->oxcf.Width * hr)) / hs;
@@ -5063,6 +5072,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, unsigned l
unsigned int i;
/* Update frame rates for each layer */
assert(cpi->oxcf.number_of_layers <= VPX_TS_MAX_LAYERS);
for (i=0; i<cpi->oxcf.number_of_layers; i++)
{
LAYER_CONTEXT *lc = &cpi->layer_context[i];

View File

@@ -120,9 +120,73 @@ static INLINE int mi_height_log2(BLOCK_SIZE sb_type) {
return mi_height_log2_lookup[sb_type];
}
#if CONFIG_MASKED_INTERINTER
#define MASK_BITS_SML 3
#define MASK_BITS_MED 4
#define MASK_BITS_BIG 5
#define MASK_NONE -1
static inline int get_mask_bits(BLOCK_SIZE sb_type) {
if (sb_type < BLOCK_8X8)
return 0;
if (sb_type <= BLOCK_8X8)
return MASK_BITS_SML;
else if (sb_type <= BLOCK_32X32)
return MASK_BITS_MED;
else
return MASK_BITS_BIG;
}
#endif
#if CONFIG_INTERINTRA
static INLINE TX_SIZE intra_size_log2_for_interintra(int bs) {
switch (bs) {
case 4:
return TX_4X4;
break;
case 8:
return TX_8X8;
break;
case 16:
return TX_16X16;
break;
case 32:
return TX_32X32;
break;
default:
return TX_32X32;
break;
}
}
static INLINE int is_interintra_allowed(BLOCK_SIZE sb_type) {
return ((sb_type >= BLOCK_8X8) && (sb_type < BLOCK_64X64));
}
#if CONFIG_MASKED_INTERINTRA
#define MASK_BITS_SML_INTERINTRA 3
#define MASK_BITS_MED_INTERINTRA 4
#define MASK_BITS_BIG_INTERINTRA 5
#define MASK_NONE_INTERINTRA -1
static INLINE int get_mask_bits_interintra(BLOCK_SIZE sb_type) {
if (sb_type == BLOCK_4X4)
return 0;
if (sb_type <= BLOCK_8X8)
return MASK_BITS_SML_INTERINTRA;
else if (sb_type <= BLOCK_32X32)
return MASK_BITS_MED_INTERINTRA;
else
return MASK_BITS_BIG_INTERINTRA;
}
#endif
#endif
// This structure now relates to 8x8 block regions.
typedef struct {
MB_PREDICTION_MODE mode, uv_mode;
#if CONFIG_FILTERINTRA
int filterbit, uv_filterbit;
#endif
MV_REFERENCE_FRAME ref_frame[2];
TX_SIZE tx_size;
int_mv mv[2]; // for each reference frame used
@@ -139,11 +203,30 @@ typedef struct {
INTERPOLATION_TYPE interp_filter;
#if CONFIG_EXT_TX
EXT_TX_TYPE ext_txfrm;
#endif
BLOCK_SIZE sb_type;
#if CONFIG_MASKED_INTERINTER
int use_masked_interinter;
int mask_index;
#endif
#if CONFIG_INTERINTRA
MB_PREDICTION_MODE interintra_mode, interintra_uv_mode;
#if CONFIG_MASKED_INTERINTRA
int interintra_mask_index;
int interintra_uv_mask_index;
int use_masked_interintra;
#endif
#endif
} MB_MODE_INFO;
typedef struct {
MB_MODE_INFO mbmi;
#if CONFIG_FILTERINTRA
int b_filter_info[4];
#endif
b_mode_info bmi[4];
} MODE_INFO;
@@ -151,6 +234,17 @@ static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) {
return mbmi->ref_frame[0] > INTRA_FRAME;
}
#if CONFIG_FILTERINTRA
static INLINE int
is_filter_allowed(MB_PREDICTION_MODE mode) {
return 1;
}
static INLINE int is_filter_enabled(TX_SIZE txsize) {
return (txsize <= TX_32X32);
}
#endif
static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) {
return mbmi->ref_frame[1] > INTRA_FRAME;
}
@@ -267,6 +361,7 @@ static BLOCK_SIZE get_subsize(BLOCK_SIZE bsize, PARTITION_TYPE partition) {
extern const TX_TYPE mode2txfm_map[MB_MODE_COUNT];
#if !CONFIG_EXT_TX
static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type,
const MACROBLOCKD *xd, int ib) {
const MODE_INFO *const mi = xd->mi_8x8[0];
@@ -278,18 +373,85 @@ static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type,
return mode2txfm_map[mbmi->sb_type < BLOCK_8X8 ? mi->bmi[ib].as_mode
: mbmi->mode];
}
#else
static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type,
const MACROBLOCKD *xd, int ib) {
const MODE_INFO *const mi = xd->mi_8x8[0];
const MB_MODE_INFO *const mbmi = &mi->mbmi;
if (plane_type != PLANE_TYPE_Y || xd->lossless)
return DCT_DCT;
if (is_inter_block(mbmi)) {
if (mbmi->ext_txfrm == NORM)
return DCT_DCT;
else
return ADST_ADST;
}
return mode2txfm_map[mbmi->sb_type < BLOCK_8X8 ? mi->bmi[ib].as_mode
: mbmi->mode];
}
#endif
#if !CONFIG_EXT_TX
static INLINE TX_TYPE get_tx_type_8x8(PLANE_TYPE plane_type,
const MACROBLOCKD *xd) {
return plane_type == PLANE_TYPE_Y ? mode2txfm_map[xd->mi_8x8[0]->mbmi.mode]
: DCT_DCT;
}
#else
static INLINE TX_TYPE get_tx_type_8x8(PLANE_TYPE plane_type,
const MACROBLOCKD *xd) {
const MODE_INFO *const mi = xd->mi_8x8[0];
const MB_MODE_INFO *const mbmi = &mi->mbmi;
if (!is_inter_block(mbmi) || plane_type != PLANE_TYPE_Y) {
return plane_type == PLANE_TYPE_Y ? mode2txfm_map[xd->mi_8x8[0]->mbmi.mode]
: DCT_DCT;
} else {
if (mbmi->ext_txfrm == NORM)
return DCT_DCT;
else
return ADST_ADST;
}
}
#endif
#if !CONFIG_EXT_TX
static INLINE TX_TYPE get_tx_type_16x16(PLANE_TYPE plane_type,
const MACROBLOCKD *xd) {
return plane_type == PLANE_TYPE_Y ? mode2txfm_map[xd->mi_8x8[0]->mbmi.mode]
: DCT_DCT;
}
#else
static INLINE TX_TYPE get_tx_type_16x16(PLANE_TYPE plane_type,
const MACROBLOCKD *xd) {
const MODE_INFO *const mi = xd->mi_8x8[0];
const MB_MODE_INFO *const mbmi = &mi->mbmi;
if (!is_inter_block(mbmi) || plane_type != PLANE_TYPE_Y) {
return plane_type == PLANE_TYPE_Y ? mode2txfm_map[xd->mi_8x8[0]->mbmi.mode]
: DCT_DCT;
} else {
if (mbmi->ext_txfrm == NORM)
return DCT_DCT;
else
return ADST_ADST;
}
}
static INLINE TX_TYPE get_tx_type_32x32(PLANE_TYPE plane_type,
const MACROBLOCKD *xd) {
const MODE_INFO *const mi = xd->mi_8x8[0];
const MB_MODE_INFO *const mbmi = &mi->mbmi;
if (!is_inter_block(mbmi) || plane_type != PLANE_TYPE_Y) {
return DCT_DCT;
} else {
if (mbmi->ext_txfrm == NORM)
return DCT_DCT;
else
return ADST_ADST;
}
}
#endif
static void setup_block_dptrs(MACROBLOCKD *xd, int ss_x, int ss_y) {
int i;

View File

@@ -97,6 +97,10 @@ struct VP9Common;
void vp9_default_coef_probs(struct VP9Common *cm);
void vp9_adapt_coef_probs(struct VP9Common *cm);
#if CONFIG_EXT_TX
void vp9_init_ext_tx_prob(struct VP9Common *cm);
#endif
static INLINE void reset_skip_context(MACROBLOCKD *xd, BLOCK_SIZE bsize) {
int i;
for (i = 0; i < MAX_MB_PLANE; i++) {

View File

@@ -14,6 +14,26 @@
#include "vp9/common/vp9_onyxc_int.h"
#include "vp9/common/vp9_seg_common.h"
#if CONFIG_MASKED_INTERINTER
static const vp9_prob default_masked_interinter_prob[BLOCK_SIZES] = {
192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
};
#endif
#if CONFIG_INTERINTRA
static const vp9_prob default_interintra_prob[BLOCK_SIZES] = {
192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
};
#if CONFIG_MASKED_INTERINTRA
static const vp9_prob default_masked_interintra_prob[BLOCK_SIZES] = {
192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
};
#endif
#endif
#if CONFIG_EXT_TX
const vp9_prob default_ext_tx_prob = 204; // 0.6 = 153, 0.7 = 178, 0.8 = 204
#endif
const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = {
{ // above = dc
{ 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
@@ -161,6 +181,16 @@ static const vp9_prob default_if_uv_probs[INTRA_MODES][INTRA_MODES - 1] = {
{ 101, 21, 107, 181, 192, 103, 19, 67, 125 } // y = tm
};
#if CONFIG_FILTERINTRA
const vp9_prob vp9_default_filterintra_prob[TX_SIZES][INTRA_MODES] = {
// DC V H D45 D135 D117 D153 D207 D63 TM
{153, 171, 147, 150, 129, 101, 100, 153, 132, 111},
{171, 173, 185, 131, 70, 53, 70, 148, 127, 114},
{175, 203, 213, 86, 45, 71, 41, 150, 125, 154},
{235, 230, 154, 202, 154, 205, 37, 128, 0, 202}
};
#endif
const vp9_prob vp9_kf_partition_probs[PARTITION_CONTEXTS]
[PARTITION_TYPES - 1] = {
// 8x8 -> 4x4
@@ -327,6 +357,21 @@ void vp9_init_mbmode_probs(VP9_COMMON *cm) {
cm->fc.tx_probs = default_tx_probs;
vp9_copy(cm->fc.mbskip_probs, default_mbskip_probs);
vp9_copy(cm->fc.inter_mode_probs, default_inter_mode_probs);
#if CONFIG_FILTERINTRA
vp9_copy(cm->fc.filterintra_prob, vp9_default_filterintra_prob);
#endif
#if CONFIG_MASKED_INTERINTER
vp9_copy(cm->fc.masked_interinter_prob, default_masked_interinter_prob);
#endif
#if CONFIG_INTERINTRA
vp9_copy(cm->fc.interintra_prob, default_interintra_prob);
#if CONFIG_MASKED_INTERINTRA
vp9_copy(cm->fc.masked_interintra_prob, default_masked_interintra_prob);
#endif
#endif
#if CONFIG_EXT_TX
cm->fc.ext_tx_prob = default_ext_tx_prob;
#endif
}
const vp9_tree_index vp9_switchable_interp_tree
@@ -386,9 +431,10 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
counts->partition[i], fc->partition_prob[i]);
if (cm->mcomp_filter_type == SWITCHABLE) {
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
adapt_probs(vp9_switchable_interp_tree, pre_fc->switchable_interp_prob[i],
counts->switchable_interp[i], fc->switchable_interp_prob[i]);
}
}
if (cm->tx_mode == TX_MODE_SELECT) {
@@ -418,6 +464,48 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
for (i = 0; i < MBSKIP_CONTEXTS; ++i)
fc->mbskip_probs[i] = adapt_prob(pre_fc->mbskip_probs[i],
counts->mbskip[i]);
#if CONFIG_FILTERINTRA
for (i = 0; i < TX_SIZES; ++i)
for (j = 0; j < INTRA_MODES; ++j)
fc->filterintra_prob[i][j] = adapt_prob(pre_fc->filterintra_prob[i][j],
counts->filterintra[i][j]);
#endif
#if CONFIG_MASKED_INTERINTER
if (cm->use_masked_interinter) {
for (i = 0; i < BLOCK_SIZES; ++i) {
if (get_mask_bits(i))
fc->masked_interinter_prob[i] = adapt_prob
(pre_fc->masked_interinter_prob[i],
counts->masked_interinter[i]);
}
}
#endif
#if CONFIG_INTERINTRA
if (cm->use_interintra) {
for (i = 0; i < BLOCK_SIZES; ++i) {
if (is_interintra_allowed(i))
fc->interintra_prob[i] = adapt_prob(pre_fc->interintra_prob[i],
counts->interintra[i]);
}
#if CONFIG_MASKED_INTERINTRA
if (cm->use_masked_interintra) {
for (i = 0; i < BLOCK_SIZES; ++i) {
if (is_interintra_allowed(i) && get_mask_bits_interintra(i))
fc->masked_interintra_prob[i] = adapt_prob(
pre_fc->masked_interintra_prob[i],
counts->masked_interintra[i]);
}
}
#endif
}
#endif
#if CONFIG_EXT_TX
fc->ext_tx_prob = adapt_prob(pre_fc->ext_tx_prob, counts->ext_tx);
#endif
}
static void set_default_lf_deltas(struct loopfilter *lf) {

View File

@@ -18,6 +18,10 @@
#define SWITCHABLE_FILTERS 3 // number of switchable filters
#define SWITCHABLE_FILTER_CONTEXTS (SWITCHABLE_FILTERS + 1)
#if CONFIG_INTERINTRA
#define SEPARATE_INTERINTRA_UV 0
#endif
// #define MODE_STATS
struct VP9Common;

View File

@@ -234,3 +234,4 @@ void vp9_adapt_mv_probs(VP9_COMMON *cm, int allow_hp) {
void vp9_init_mv_probs(VP9_COMMON *cm) {
cm->fc.nmvc = default_nmv_context;
}

View File

@@ -79,6 +79,14 @@ typedef enum {
TX_TYPES = 4
} TX_TYPE;
#if CONFIG_EXT_TX
typedef enum {
NORM = 0,
ALT = 1,
EXT_TX_TYPES = 2
} EXT_TX_TYPE;
#endif
typedef enum {
UNKNOWN = 0,
BT_601 = 1, // YUV

View File

@@ -1378,6 +1378,54 @@ void vp9_idct32x32_add(const int16_t *input, uint8_t *dest, int stride,
vp9_idct32x32_1024_add(input, dest, stride);
}
#if CONFIG_EXT_TX
static double tmp[32*32];
static double tmp2[32*32];
extern double dstmtx32[32*32];
void vp9_idst_add(const int16_t *input, uint8_t *dest, int stride,
int eob, int size) {
int i, j, k;
double *basis;
int factor = (size == 32) ? 4 : 8;
switch (size) {
case 32:
basis = dstmtx32;
break;
default:
assert(0);
break;
}
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
tmp[i*size+j] = 0;
for (k = 0; k < size; k++) {
tmp[i*size+j] += input[i*size+k] * basis[j*size+k]; // row
}
}
}
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
tmp2[i*size+j] = 0;
for (k = 0; k < size; k++) {
tmp2[i*size+j] += basis[i*size+k] * tmp[k*size+j]; // col
}
if (tmp2[i*size+j] >= 0)
dest[i*stride+j] = clip_pixel((int)dest[i*stride+j] +
(int)(tmp2[i*size+j] / factor + 0.5));
else
dest[i*stride+j] = clip_pixel((int)dest[i*stride+j] +
(int)(tmp2[i*size+j] / factor - 0.5));
}
}
}
#endif
// iht
void vp9_iht4x4_add(TX_TYPE tx_type, const int16_t *input, uint8_t *dest,
int stride, int eob) {

View File

@@ -95,6 +95,12 @@ void vp9_idct16x16_add(const int16_t *input, uint8_t *dest, int stride, int
void vp9_idct32x32_add(const int16_t *input, uint8_t *dest, int stride,
int eob);
#if CONFIG_EXT_TX
void vp9_idst_add(const int16_t *input, uint8_t *dest, int stride,
int eob, int size);
#endif
void vp9_iht4x4_add(TX_TYPE tx_type, const int16_t *input, uint8_t *dest,
int stride, int eob);
void vp9_iht8x8_add(TX_TYPE tx_type, const int16_t *input, uint8_t *dest,

View File

@@ -58,6 +58,21 @@ typedef struct frame_contexts {
struct tx_probs tx_probs;
vp9_prob mbskip_probs[MBSKIP_CONTEXTS];
nmv_context nmvc;
#if CONFIG_FILTERINTRA
vp9_prob filterintra_prob[TX_SIZES][INTRA_MODES];
#endif
#if CONFIG_MASKED_INTERINTER
vp9_prob masked_interinter_prob[BLOCK_SIZES];
#endif
#if CONFIG_INTERINTRA
vp9_prob interintra_prob[BLOCK_SIZES];
#if CONFIG_MASKED_INTERINTRA
vp9_prob masked_interintra_prob[BLOCK_SIZES];
#endif
#endif
#if CONFIG_EXT_TX
vp9_prob ext_tx_prob;
#endif
} FRAME_CONTEXT;
typedef struct {
@@ -77,6 +92,21 @@ typedef struct {
struct tx_counts tx;
unsigned int mbskip[MBSKIP_CONTEXTS][2];
nmv_context_counts mv;
#if CONFIG_FILTERINTRA
unsigned int filterintra[TX_SIZES][INTRA_MODES][2];
#endif
#if CONFIG_MASKED_INTERINTER
unsigned int masked_interinter[BLOCK_SIZES][2];
#endif
#if CONFIG_INTERINTRA
unsigned int interintra[BLOCK_SIZES][2];
#if CONFIG_MASKED_INTERINTRA
unsigned int masked_interintra[BLOCK_SIZES][2];
#endif
#endif
#if CONFIG_EXT_TX
unsigned int ext_tx[2];
#endif
} FRAME_COUNTS;
@@ -222,6 +252,15 @@ typedef struct VP9Common {
int fb_lru; // Flag telling if lru is on/off
uint32_t *fb_idx_ref_lru; // Frame buffer lru cache
uint32_t fb_idx_ref_lru_count;
#if CONFIG_MASKED_INTERINTER
int use_masked_interinter;
#endif
#if CONFIG_INTERINTRA
int use_interintra;
#if CONFIG_MASKED_INTERINTRA
int use_masked_interintra;
#endif
#endif
} VP9_COMMON;
// ref == 0 => LAST_FRAME

View File

@@ -139,6 +139,302 @@ MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd, const MV *src_mv,
return clamped_mv;
}
#if CONFIG_MASKED_INTERINTER
#define MASK_WEIGHT_BITS 6
static int get_masked_weight(int m) {
#define SMOOTHER_LEN 32
static const uint8_t smoothfn[2 * SMOOTHER_LEN + 1] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 2, 2, 3, 4, 5, 6,
8, 9, 12, 14, 17, 21, 24, 28,
32,
36, 40, 43, 47, 50, 52, 55, 56,
58, 59, 60, 61, 62, 62, 63, 63,
63, 63, 63, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
};
if (m < -SMOOTHER_LEN)
return 0;
else if (m > SMOOTHER_LEN)
return (1 << MASK_WEIGHT_BITS);
else
return smoothfn[m + SMOOTHER_LEN];
}
static int get_hard_mask(int m) {
return m > 0;
}
// Equation of line: f(x, y) = a[0]*(x - a[2]*w/4) + a[1]*(y - a[3]*h/4) = 0
// The soft mask is obtained by computing f(x, y) and then calling
// get_masked_weight(f(x, y)).
static const int mask_params_sml[1 << MASK_BITS_SML][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
};
static const int mask_params_med_hgtw[1 << MASK_BITS_MED][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
};
static const int mask_params_med_hltw[1 << MASK_BITS_MED][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
};
static const int mask_params_med_heqw[1 << MASK_BITS_MED][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int mask_params_big_hgtw[1 << MASK_BITS_BIG][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 2},
{ 0, -2, 0, 2},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 2, 0},
{-2, 0, 2, 0},
};
static const int mask_params_big_hltw[1 << MASK_BITS_BIG][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 2},
{ 0, -2, 0, 2},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 2, 0},
{-2, 0, 2, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int mask_params_big_heqw[1 << MASK_BITS_BIG][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int *get_mask_params(int mask_index,
BLOCK_SIZE sb_type,
int h, int w) {
const int *a;
const int mask_bits = get_mask_bits(sb_type);
if (mask_index == MASK_NONE)
return NULL;
if (mask_bits == MASK_BITS_SML) {
a = mask_params_sml[mask_index];
} else if (mask_bits == MASK_BITS_MED) {
if (h > w)
a = mask_params_med_hgtw[mask_index];
else if (h < w)
a = mask_params_med_hltw[mask_index];
else
a = mask_params_med_heqw[mask_index];
} else if (mask_bits == MASK_BITS_BIG) {
if (h > w)
a = mask_params_big_hgtw[mask_index];
else if (h < w)
a = mask_params_big_hltw[mask_index];
else
a = mask_params_big_heqw[mask_index];
} else {
assert(0);
}
return a;
}
void vp9_generate_masked_weight(int mask_index,
BLOCK_SIZE sb_type,
int h, int w,
uint8_t *mask, int stride) {
int i, j;
const int *a = get_mask_params(mask_index, sb_type, h, w);
if (!a) return;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int x = (j - (a[2] * w) / 4);
int y = (i - (a[3] * h) / 4);
int m = a[0] * x + a[1] * y;
mask[i * stride + j] = get_masked_weight(m);
}
}
void vp9_generate_hard_mask(int mask_index, BLOCK_SIZE sb_type,
int h, int w, uint8_t *mask, int stride) {
int i, j;
const int *a = get_mask_params(mask_index, sb_type, h, w);
if (!a) return;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int x = (j - (a[2] * w) / 4);
int y = (i - (a[3] * h) / 4);
int m = a[0] * x + a[1] * y;
mask[i * stride + j] = get_hard_mask(m);
}
}
static void build_masked_compound(uint8_t *dst, int dst_stride,
uint8_t *dst2, int dst2_stride,
int mask_index, BLOCK_SIZE sb_type,
int h, int w) {
int i, j;
uint8_t mask[4096];
vp9_generate_masked_weight(mask_index, sb_type, h, w, mask, 64);
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int m = mask[i * 64 + j];
dst[i * dst_stride + j] = (dst[i * dst_stride + j] * m +
dst2[i * dst2_stride + j] *
((1 << MASK_WEIGHT_BITS) - m) +
(1 << (MASK_WEIGHT_BITS - 1))) >>
MASK_WEIGHT_BITS;
}
}
#endif
// TODO(jkoleszar): In principle, pred_w, pred_h are unnecessary, as we could
// calculate the subsampled BLOCK_SIZE, but that type isn't defined for
// sizes smaller than 16x16 yet.
@@ -196,8 +492,21 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride
+ (scaled_mv.col >> SUBPEL_BITS);
#if CONFIG_MASKED_INTERINTER
if (ref && get_mask_bits(mi->mbmi.sb_type)
&& mi->mbmi.use_masked_interinter) {
uint8_t tmp_dst[4096];
inter_predictor(pre, pre_buf->stride, tmp_dst, 64,
subpel_x, subpel_y, scale, w, h, 0, &xd->subpix, xs, ys);
build_masked_compound(dst, dst_buf->stride, tmp_dst, 64,
mi->mbmi.mask_index, mi->mbmi.sb_type, h, w);
} else {
#endif
inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, scale, w, h, ref, &xd->subpix, xs, ys);
#if CONFIG_MASKED_INTERINTER
}
#endif
}
}
@@ -240,8 +549,22 @@ void vp9_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
}
void vp9_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize) {
#if CONFIG_INTERINTRA
uint8_t *const y = xd->plane[0].dst.buf;
uint8_t *const u = xd->plane[1].dst.buf;
uint8_t *const v = xd->plane[2].dst.buf;
const int y_stride = xd->plane[0].dst.stride;
const int uv_stride = xd->plane[1].dst.stride;
#endif
build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0,
MAX_MB_PLANE - 1);
#if CONFIG_INTERINTRA
if (xd->mi_8x8[0]->mbmi.ref_frame[1] == INTRA_FRAME &&
is_interintra_allowed(xd->mi_8x8[0]->mbmi.sb_type)) {
vp9_build_interintra_predictors(xd, y, u, v,
y_stride, uv_stride, bsize);
}
#endif
}
// TODO(jingning): This function serves as a placeholder for decoder prediction
@@ -360,8 +683,21 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
}
}
#if CONFIG_MASKED_INTERINTER
if (ref && get_mask_bits(mi->mbmi.sb_type)
&& mi->mbmi.use_masked_interinter) {
uint8_t tmp_dst[4096];
inter_predictor(buf_ptr, pre_buf->stride, tmp_dst, 64,
subpel_x, subpel_y, scale, w, h, 0, &xd->subpix, xs, ys);
build_masked_compound(dst, dst_buf->stride, tmp_dst, 64,
mi->mbmi.mask_index, mi->mbmi.sb_type, h, w);
} else {
#endif
inter_predictor(buf_ptr, pre_buf->stride, dst, dst_buf->stride, subpel_x,
subpel_y, scale, w, h, ref, &xd->subpix, xs, ys);
#if CONFIG_MASKED_INTERINTER
}
#endif
}
}
@@ -370,6 +706,13 @@ void vp9_dec_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
int plane;
const int mi_x = mi_col * MI_SIZE;
const int mi_y = mi_row * MI_SIZE;
#if CONFIG_INTERINTRA
uint8_t *const y = xd->plane[0].dst.buf;
uint8_t *const u = xd->plane[1].dst.buf;
uint8_t *const v = xd->plane[2].dst.buf;
const int y_stride = xd->plane[0].dst.stride;
const int uv_stride = xd->plane[1].dst.stride;
#endif
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize,
&xd->plane[plane]);
@@ -390,6 +733,13 @@ void vp9_dec_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
0, 0, bw, bh, mi_x, mi_y);
}
}
#if CONFIG_INTERINTRA
if (xd->mi_8x8[0]->mbmi.ref_frame[1] == INTRA_FRAME &&
is_interintra_allowed(xd->mi_8x8[0]->mbmi.sb_type)) {
vp9_build_interintra_predictors(xd, y, u, v,
y_stride, uv_stride, bsize);
}
#endif
}
// TODO(dkovalev: find better place for this function)

View File

@@ -99,4 +99,11 @@ static void set_scale_factors(MACROBLOCKD *xd, int ref0, int ref1,
void vp9_setup_scale_factors(VP9_COMMON *cm, int i);
#if CONFIG_MASKED_INTERINTER
void vp9_generate_masked_weight(int mask_index, BLOCK_SIZE sb_type,
int h, int w, uint8_t *mask, int stride);
void vp9_generate_hard_mask(int mask_index, BLOCK_SIZE sb_type,
int h, int w, uint8_t *mask, int stride);
#endif
#endif // VP9_COMMON_VP9_RECONINTER_H_

View File

@@ -437,8 +437,226 @@ static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
}
}
#if CONFIG_FILTERINTRA
static void filter_intra_predictors_4tap(uint8_t *ypred_ptr, int y_stride,
int bs,
const uint8_t *yabove_row,
const uint8_t *yleft_col,
int mode) {
static const int prec_bits = 10;
static const int round_val = 511;
int k, r, c;
int pred[33][33];
int mean, ipred;
int taps4_4[10][4] = {
{735, 881, -537, -54},
{1005, 519, -488, -11},
{383, 990, -343, -6},
{442, 805, -542, 319},
{658, 616, -133, -116},
{875, 442, -141, -151},
{386, 741, -23, -80},
{390, 1027, -446, 51},
{679, 606, -523, 262},
{903, 922, -778, -23}
};
int taps4_8[10][4] = {
{648, 803, -444, 16},
{972, 620, -576, 7},
{561, 967, -499, -5},
{585, 762, -468, 144},
{596, 619, -182, -9},
{895, 459, -176, -153},
{557, 722, -126, -129},
{601, 839, -523, 105},
{562, 709, -499, 251},
{803, 872, -695, 43}
};
int taps4_16[10][4] = {
{423, 728, -347, 111},
{963, 685, -665, 23},
{281, 1024, -480, 216},
{640, 596, -437, 78},
{429, 669, -259, 99},
{740, 646, -415, 23},
{568, 771, -346, 40},
{404, 833, -486, 209},
{398, 712, -423, 307},
{939, 935, -887, 17}
};
int taps4_32[10][4] = {
{477, 737, -393, 150},
{881, 630, -546, 67},
{506, 984, -443, -20},
{114, 459, -270, 528},
{433, 528, 14, 3},
{837, 470, -301, -30},
{181, 777, 89, -107},
{-29, 716, -232, 259},
{589, 646, -495, 255},
{740, 884, -728, 77}
};
const int c1 = (bs >= 32) ? taps4_32[mode][0] : ((bs >= 16) ?
taps4_16[mode][0] : ((bs >= 8) ? taps4_8[mode][0] : taps4_4[mode][0]));
const int c2 = (bs >= 32) ? taps4_32[mode][1] : ((bs >= 16) ?
taps4_16[mode][1] : ((bs >= 8) ? taps4_8[mode][1] : taps4_4[mode][1]));
const int c3 = (bs >= 32) ? taps4_32[mode][2] : ((bs >= 16) ?
taps4_16[mode][2] : ((bs >= 8) ? taps4_8[mode][2] : taps4_4[mode][2]));
const int c4 = (bs >= 32) ? taps4_32[mode][3] : ((bs >= 16) ?
taps4_16[mode][3] : ((bs >= 8) ? taps4_8[mode][3] : taps4_4[mode][3]));
k = 0;
mean = 0;
while (k < bs) {
mean = mean + (int)yleft_col[k];
mean = mean + (int)yabove_row[k];
k++;
}
mean = (mean + bs) / (2 * bs);
for (r = 0; r < bs; r++)
pred[r + 1][0] = (int)yleft_col[r] - mean;
for (c = 0; c < 2 * bs + 1; c++)
pred[0][c] = (int)yabove_row[c - 1] - mean;
for (r = 1; r < bs + 1; r++)
for (c = 1; c < 2 * bs + 1 - r; c++) {
ipred = c1 * pred[r - 1][c] + c2 * pred[r][c - 1]
+ c3 * pred[r - 1][c - 1] + c4 * pred[r - 1][c + 1];
pred[r][c] = ipred < 0 ? -((-ipred + round_val) >> prec_bits) :
((ipred + round_val) >> prec_bits);
}
for (r = 0; r < bs; r++) {
for (c = 0; c < bs; c++) {
ipred = pred[r + 1][c + 1] + mean;
ypred_ptr[c] = clip_pixel(ipred);
}
ypred_ptr += y_stride;
}
}
static void build_filter_intra_predictors(const MACROBLOCKD *xd,
const uint8_t *ref, int ref_stride,
uint8_t *dst, int dst_stride,
MB_PREDICTION_MODE mode, TX_SIZE txsz,
int up_available, int left_available,
int right_available, int x, int y,
int plane) {
int i;
DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64);
DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16);
uint8_t *above_row = above_data + 16;
const uint8_t *const_above_row = above_row;
const int bs = 4 << txsz;
int frame_width, frame_height;
int x0, y0;
const struct macroblockd_plane *const pd = &xd->plane[plane];
// Get current frame pointer, width and height.
if (plane == 0) {
frame_width = xd->cur_buf->y_width;
frame_height = xd->cur_buf->y_height;
} else {
frame_width = xd->cur_buf->uv_width;
frame_height = xd->cur_buf->uv_height;
}
// Get block position in current frame.
x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
// left
if (left_available) {
if (xd->mb_to_bottom_edge < 0) {
/* slower path if the block needs border extension */
if (y0 + bs <= frame_height) {
for (i = 0; i < bs; ++i)
left_col[i] = ref[i * ref_stride - 1];
} else {
const int extend_bottom = frame_height - y0;
for (i = 0; i < extend_bottom; ++i)
left_col[i] = ref[i * ref_stride - 1];
for (; i < bs; ++i)
left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
}
} else {
/* faster path if the block does not need extension */
for (i = 0; i < bs; ++i)
left_col[i] = ref[i * ref_stride - 1];
}
} else {
vpx_memset(left_col, 129, bs);
}
// TODO(hkuang) do not extend 2*bs pixels for all modes.
// above
if (up_available) {
const uint8_t *above_ref = ref - ref_stride;
if (xd->mb_to_right_edge < 0) {
/* slower path if the block needs border extension */
if (x0 + 2 * bs <= frame_width) {
if (right_available && bs == 4) {
vpx_memcpy(above_row - 1, above_ref - 1, 2 * bs + 1);
} else {
vpx_memcpy(above_row - 1, above_ref - 1, bs + 1);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 + bs <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
vpx_memcpy(above_row - 1, above_ref - 1, r + 1);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
vpx_memcpy(above_row - 1, above_ref - 1, bs + 1);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
vpx_memcpy(above_row - 1, above_ref - 1, r + 1);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
vpx_memcpy(above_row - 1, above_ref - 1, r + 1);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
}
above_row[-1] = left_available ? above_ref[-1] : 129;
}
} else {
/* faster path if the block does not need extension */
if (bs == 4 && right_available && left_available) {
const_above_row = above_ref;
} else {
vpx_memcpy(above_row, above_ref, bs);
if (bs == 4 && right_available)
vpx_memcpy(above_row + bs, above_ref + bs, bs);
else
vpx_memset(above_row + bs, above_row[bs - 1], bs);
above_row[-1] = left_available ? above_ref[-1] : 129;
}
}
} else {
vpx_memset(above_row, 127, bs * 2);
above_row[-1] = 127;
}
filter_intra_predictors_4tap(dst, dst_stride, bs, const_above_row, left_col,
mode);
}
#endif
void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
TX_SIZE tx_size, int mode,
#if CONFIG_FILTERINTRA
int filterbit,
#endif
const uint8_t *ref, int ref_stride,
uint8_t *dst, int dst_stride,
int aoff, int loff, int plane) {
@@ -449,8 +667,768 @@ void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
const int have_right = ((block_idx & wmask) != wmask);
const int x = aoff * 4;
const int y = loff * 4;
#if CONFIG_FILTERINTRA
const int filterflag = is_filter_allowed(mode) && is_filter_enabled(tx_size)
&& filterbit;
#endif
assert(bwl >= 0);
#if CONFIG_FILTERINTRA
if (!filterflag) {
#endif
build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size,
have_top, have_left, have_right, x, y, plane);
#if CONFIG_FILTERINTRA
} else {
build_filter_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode,
tx_size, have_top, have_left, have_right, x, y, plane);
}
#endif
}
#if CONFIG_INTERINTRA
#if CONFIG_MASKED_INTERINTRA
#define MASK_WEIGHT_BITS_INTERINTRA 6
static int get_masked_weight_interintra(int m) {
#define SMOOTHER_LEN_INTERINTRA 32
static const uint8_t smoothfn[2 * SMOOTHER_LEN_INTERINTRA + 1] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 2, 2, 3, 4, 5, 6,
8, 9, 12, 14, 17, 21, 24, 28,
32,
36, 40, 43, 47, 50, 52, 55, 56,
58, 59, 60, 61, 62, 62, 63, 63,
63, 63, 63, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
};
if (m < -SMOOTHER_LEN_INTERINTRA)
return 0;
else if (m > SMOOTHER_LEN_INTERINTRA)
return (1 << MASK_WEIGHT_BITS_INTERINTRA);
else
return smoothfn[m + SMOOTHER_LEN_INTERINTRA];
}
static int get_hard_mask_interintra(int m) {
return m > 0;
}
// Equation of line: f(x, y) = a[0]*(x - a[2]*w/4) + a[1]*(y - a[3]*h/4) = 0
// The soft mask is obtained by computing f(x, y) and then calling
// get_masked_weight(f(x, y)).
static const int mask_params_sml_interintra[1 << MASK_BITS_SML_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
};
static const int mask_params_med_hgtw_interintra[1 << MASK_BITS_MED_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
};
static const int mask_params_med_hltw_interintra[1 << MASK_BITS_MED_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
};
static const int mask_params_med_heqw_interintra[1 << MASK_BITS_MED_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int mask_params_big_hgtw_interintra[1 << MASK_BITS_BIG_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 2},
{ 0, -2, 0, 2},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 2, 0},
{-2, 0, 2, 0},
};
static const int mask_params_big_hltw_interintra[1 << MASK_BITS_BIG_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 2},
{ 0, -2, 0, 2},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 2, 0},
{-2, 0, 2, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int mask_params_big_heqw_interintra[1 << MASK_BITS_BIG_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int *get_mask_params_interintra(int mask_index,
BLOCK_SIZE sb_type,
int h, int w) {
const int *a;
const int mask_bits = get_mask_bits_interintra(sb_type);
if (mask_index == MASK_NONE_INTERINTRA)
return NULL;
if (mask_bits == MASK_BITS_SML_INTERINTRA) {
a = mask_params_sml_interintra[mask_index];
} else if (mask_bits == MASK_BITS_MED_INTERINTRA) {
if (h > w)
a = mask_params_med_hgtw_interintra[mask_index];
else if (h < w)
a = mask_params_med_hltw_interintra[mask_index];
else
a = mask_params_med_heqw_interintra[mask_index];
} else if (mask_bits == MASK_BITS_BIG_INTERINTRA) {
if (h > w)
a = mask_params_big_hgtw_interintra[mask_index];
else if (h < w)
a = mask_params_big_hltw_interintra[mask_index];
else
a = mask_params_big_heqw_interintra[mask_index];
} else {
assert(0);
}
return a;
}
void vp9_generate_masked_weight_interintra(int mask_index,
BLOCK_SIZE sb_type,
int h, int w,
uint8_t *mask, int stride) {
int i, j;
const int *a = get_mask_params_interintra(mask_index, sb_type, h, w);
if (!a) return;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int x = (j - (a[2] * w) / 4);
int y = (i - (a[3] * h) / 4);
int m = a[0] * x + a[1] * y;
mask[i * stride + j] = get_masked_weight_interintra(m);
}
}
void vp9_generate_hard_mask_interintra(int mask_index, BLOCK_SIZE sb_type,
int h, int w, uint8_t *mask, int stride) {
int i, j;
const int *a = get_mask_params_interintra(mask_index, sb_type, h, w);
if (!a) return;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int x = (j - (a[2] * w) / 4);
int y = (i - (a[3] * h) / 4);
int m = a[0] * x + a[1] * y;
mask[i * stride + j] = get_hard_mask_interintra(m);
}
}
#endif
static void combine_interintra(MB_PREDICTION_MODE mode,
#if CONFIG_MASKED_INTERINTRA
int use_masked_interintra,
int mask_index,
BLOCK_SIZE bsize,
#endif
uint8_t *interpred,
int interstride,
uint8_t *intrapred,
int intrastride,
int bw, int bh) {
static const int scale_bits = 8;
static const int scale_max = 256;
static const int scale_round = 127;
static const int weights1d[64] = {
128, 125, 122, 119, 116, 114, 111, 109,
107, 105, 103, 101, 99, 97, 96, 94,
93, 91, 90, 89, 88, 86, 85, 84,
83, 82, 81, 81, 80, 79, 78, 78,
77, 76, 76, 75, 75, 74, 74, 73,
73, 72, 72, 71, 71, 71, 70, 70,
70, 70, 69, 69, 69, 69, 68, 68,
68, 68, 68, 67, 67, 67, 67, 67,
};
int size = MAX(bw, bh);
int size_scale = (size >= 64 ? 1 :
size == 32 ? 2 :
size == 16 ? 4 :
size == 8 ? 8 : 16);
int i, j;
#if CONFIG_MASKED_INTERINTRA
uint8_t mask[4096];
if (use_masked_interintra && get_mask_bits_interintra(bsize))
vp9_generate_masked_weight_interintra(mask_index, bsize, bh, bw, mask, bw);
#endif
switch (mode) {
case V_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int k = i * interstride + j;
int scale = weights1d[i * size_scale];
#if CONFIG_MASKED_INTERINTRA
int m = mask[i * bw + j];
if (use_masked_interintra && get_mask_bits_interintra(bsize))
interpred[k] = (intrapred[i * intrastride + j] * m +
interpred[k] *
((1 << MASK_WEIGHT_BITS_INTERINTRA) - m) +
(1 << (MASK_WEIGHT_BITS_INTERINTRA - 1))) >>
MASK_WEIGHT_BITS_INTERINTRA;
else
#endif
interpred[k] =
((scale_max - scale) * interpred[k] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case H_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int k = i * interstride + j;
int scale = weights1d[j * size_scale];
#if CONFIG_MASKED_INTERINTRA
int m = mask[i * bw + j];
if (use_masked_interintra && get_mask_bits_interintra(bsize))
interpred[k] = (intrapred[i * intrastride + j] * m +
interpred[k] *
((1 << MASK_WEIGHT_BITS_INTERINTRA) - m) +
(1 << (MASK_WEIGHT_BITS_INTERINTRA - 1))) >>
MASK_WEIGHT_BITS_INTERINTRA;
else
#endif
interpred[k] =
((scale_max - scale) * interpred[k] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case D63_PRED:
case D117_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int k = i * interstride + j;
int scale = (weights1d[i * size_scale] * 3 +
weights1d[j * size_scale]) >> 2;
#if CONFIG_MASKED_INTERINTRA
int m = mask[i * bw + j];
if (use_masked_interintra && get_mask_bits_interintra(bsize))
interpred[k] = (intrapred[i * intrastride + j] * m +
interpred[k] *
((1 << MASK_WEIGHT_BITS_INTERINTRA) - m) +
(1 << (MASK_WEIGHT_BITS_INTERINTRA - 1))) >>
MASK_WEIGHT_BITS_INTERINTRA;
else
#endif
interpred[k] =
((scale_max - scale) * interpred[k] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case D207_PRED:
case D153_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int k = i * interstride + j;
int scale = (weights1d[j * size_scale] * 3 +
weights1d[i * size_scale]) >> 2;
#if CONFIG_MASKED_INTERINTRA
int m = mask[i * bw + j];
if (use_masked_interintra && get_mask_bits_interintra(bsize))
interpred[k] = (intrapred[i * intrastride + j] * m +
interpred[k] *
((1 << MASK_WEIGHT_BITS_INTERINTRA) - m) +
(1 << (MASK_WEIGHT_BITS_INTERINTRA - 1))) >>
MASK_WEIGHT_BITS_INTERINTRA;
else
#endif
interpred[k] =
((scale_max - scale) * interpred[k] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case D135_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int k = i * interstride + j;
int scale = weights1d[(i < j ? i : j) * size_scale];
#if CONFIG_MASKED_INTERINTRA
int m = mask[i * bw + j];
if (use_masked_interintra && get_mask_bits_interintra(bsize))
interpred[k] = (intrapred[i * intrastride + j] * m +
interpred[k] *
((1 << MASK_WEIGHT_BITS_INTERINTRA) - m) +
(1 << (MASK_WEIGHT_BITS_INTERINTRA - 1))) >>
MASK_WEIGHT_BITS_INTERINTRA;
else
#endif
interpred[k] =
((scale_max - scale) * interpred[k] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case D45_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int k = i * interstride + j;
int scale = (weights1d[i * size_scale] +
weights1d[j * size_scale]) >> 1;
#if CONFIG_MASKED_INTERINTRA
int m = mask[i * bw + j];
if (use_masked_interintra && get_mask_bits_interintra(bsize))
interpred[k] = (intrapred[i * intrastride + j] * m +
interpred[k] *
((1 << MASK_WEIGHT_BITS_INTERINTRA) - m) +
(1 << (MASK_WEIGHT_BITS_INTERINTRA - 1))) >>
MASK_WEIGHT_BITS_INTERINTRA;
else
#endif
interpred[k] =
((scale_max - scale) * interpred[k] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case TM_PRED:
case DC_PRED:
default:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int k = i * interstride + j;
#if CONFIG_MASKED_INTERINTRA
int m = mask[i * bw + j];
if (use_masked_interintra && get_mask_bits_interintra(bsize))
interpred[k] = (intrapred[i * intrastride + j] * m +
interpred[k] *
((1 << MASK_WEIGHT_BITS_INTERINTRA) - m) +
(1 << (MASK_WEIGHT_BITS_INTERINTRA - 1))) >>
MASK_WEIGHT_BITS_INTERINTRA;
else
#endif
interpred[k] = (interpred[k] + intrapred[i * intrastride + j]) >> 1;
}
}
break;
}
}
// Intra predictor for the second square block in interintra prediction.
// Prediction of the first block (in pred_ptr) will be used to generate half of
// the boundary values.
static void build_intra_predictors_for_2nd_block_interintra
(const MACROBLOCKD *xd, const uint8_t *ref,
int ref_stride, uint8_t *dst, int dst_stride,
MB_PREDICTION_MODE mode, TX_SIZE tx_size,
int up_available, int left_available,
int right_available, int bwltbh,
int x, int y, int plane) {
int i;
DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64);
DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16);
uint8_t *above_row = above_data + 16;
const uint8_t *const_above_row = above_row;
const int bs = 4 << tx_size;
int frame_width, frame_height;
int x0, y0;
const struct macroblockd_plane *const pd = &xd->plane[plane];
const uint8_t *ref_fi;
int ref_stride_fi;
// 127 127 127 .. 127 127 127 127 127 127
// 129 A B .. Y Z
// 129 C D .. W X
// 129 E F .. U V
// 129 G H .. S T T T T T
// ..
once(init_intra_pred_fn_ptrs);
// Get current frame pointer, width and height.
if (plane == 0) {
frame_width = xd->cur_buf->y_width;
frame_height = xd->cur_buf->y_height;
} else {
frame_width = xd->cur_buf->uv_width;
frame_height = xd->cur_buf->uv_height;
}
// Get block position in current frame.
x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
// left
if (left_available) {
if (bwltbh) {
ref_fi = ref;
ref_stride_fi = ref_stride;
} else {
ref_fi = dst;
ref_stride_fi = dst_stride;
}
if (xd->mb_to_bottom_edge < 0) {
/* slower path if the block needs border extension */
if (y0 + bs <= frame_height) {
for (i = 0; i < bs; ++i)
left_col[i] = ref_fi[i * ref_stride_fi - 1];
} else {
const int extend_bottom = frame_height - y0;
for (i = 0; i < extend_bottom; ++i)
left_col[i] = ref_fi[i * ref_stride_fi - 1];
for (; i < bs; ++i)
left_col[i] = ref_fi[(extend_bottom - 1) * ref_stride_fi - 1];
}
} else {
/* faster path if the block does not need extension */
for (i = 0; i < bs; ++i)
left_col[i] = ref_fi[i * ref_stride_fi - 1];
}
} else {
vpx_memset(left_col, 129, bs);
}
// TODO(hkuang) do not extend 2*bs pixels for all modes.
// above
if (up_available) {
const uint8_t *above_ref;
if (bwltbh) {
ref_fi = dst;
ref_stride_fi = dst_stride;
above_row[-1] = left_available ? ref[-ref_stride-1] : 129;
} else {
ref_fi = ref;
ref_stride_fi = ref_stride;
above_row[-1] = ref[-ref_stride-1];
}
above_ref = ref_fi - ref_stride_fi;
if (xd->mb_to_right_edge < 0) {
/* slower path if the block needs border extension */
if (x0 + 2 * bs <= frame_width) {
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, 2 * bs);
} else {
vpx_memcpy(above_row, above_ref, bs);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 + bs <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
vpx_memcpy(above_row, above_ref, bs);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
}
// above_row[-1] = left_available ? above_ref[-1] : 129;
}
} else {
/* faster path if the block does not need extension */
if (bs == 4 && right_available && left_available) {
const_above_row = above_ref;
} else {
vpx_memcpy(above_row, above_ref, bs);
if (bs == 4 && right_available)
vpx_memcpy(above_row + bs, above_ref + bs, bs);
else
vpx_memset(above_row + bs, above_row[bs - 1], bs);
// above_row[-1] = left_available ? above_ref[-1] : 129;
}
}
} else {
vpx_memset(above_row, 127, bs * 2);
above_row[-1] = 127;
}
// predict
if (mode == DC_PRED) {
dc_pred[left_available][up_available][tx_size](dst, dst_stride,
const_above_row, left_col);
} else {
pred[mode][tx_size](dst, dst_stride, const_above_row, left_col);
}
}
// Break down rectangular intra prediction for joint spatio-temporal prediction
// into two square intra predictions.
static void build_intra_predictors_for_interintra(MACROBLOCKD *xd,
uint8_t *src, int src_stride,
uint8_t *pred_ptr, int stride,
MB_PREDICTION_MODE mode,
int bw, int bh,
int up_available, int left_available,
int right_available, int plane) {
if (bw == bh) {
build_intra_predictors(xd, src, src_stride, pred_ptr, stride,
mode, intra_size_log2_for_interintra(bw),
up_available, left_available, right_available,
0, 0, plane);
} else if (bw < bh) {
uint8_t *src_bottom = src + bw * src_stride;
uint8_t *pred_ptr_bottom = pred_ptr + bw * stride;
build_intra_predictors(xd, src, src_stride, pred_ptr, stride,
mode, intra_size_log2_for_interintra(bw),
up_available, left_available, right_available,
0, 0, plane);
build_intra_predictors_for_2nd_block_interintra(xd, src_bottom, src_stride,
pred_ptr_bottom, stride,
mode, intra_size_log2_for_interintra(bw),
up_available, left_available, 0, 1,
0, bw, plane);
} else {
uint8_t *src_right = src + bh;
uint8_t *pred_ptr_right = pred_ptr + bh;
build_intra_predictors(xd, src, src_stride, pred_ptr, stride,
mode, intra_size_log2_for_interintra(bh),
up_available, left_available, 1,
0, 0, plane);
build_intra_predictors_for_2nd_block_interintra(xd, src_right, src_stride,
pred_ptr_right, stride,
mode, intra_size_log2_for_interintra(bh),
up_available, left_available, right_available, 0,
bh, 0, plane);
}
}
void vp9_build_interintra_predictors_sby(MACROBLOCKD *xd,
uint8_t *ypred,
int ystride,
BLOCK_SIZE bsize) {
int bw = 4 << b_width_log2(bsize);
int bh = 4 << b_height_log2(bsize);
uint8_t intrapredictor[4096];
build_intra_predictors_for_interintra(
xd, xd->plane[0].dst.buf, xd->plane[0].dst.stride,
intrapredictor, bw,
xd->mi_8x8[0]->mbmi.interintra_mode, bw, bh,
xd->up_available, xd->left_available, 0, 0);
combine_interintra(xd->mi_8x8[0]->mbmi.interintra_mode,
#if CONFIG_MASKED_INTERINTRA
xd->mi_8x8[0]->mbmi.use_masked_interintra,
xd->mi_8x8[0]->mbmi.interintra_mask_index,
bsize,
#endif
ypred, ystride, intrapredictor, bw, bw, bh);
}
void vp9_build_interintra_predictors_sbuv(MACROBLOCKD *xd,
uint8_t *upred,
uint8_t *vpred,
int uvstride,
BLOCK_SIZE bsize) {
int bwl = b_width_log2(bsize), bw = 2 << bwl;
int bhl = b_height_log2(bsize), bh = 2 << bhl;
uint8_t uintrapredictor[1024];
uint8_t vintrapredictor[1024];
build_intra_predictors_for_interintra(
xd, xd->plane[1].dst.buf, xd->plane[1].dst.stride,
uintrapredictor, bw,
xd->mi_8x8[0]->mbmi.interintra_uv_mode, bw, bh,
xd->up_available, xd->left_available, 0, 1);
build_intra_predictors_for_interintra(
xd, xd->plane[2].dst.buf, xd->plane[1].dst.stride,
vintrapredictor, bw,
xd->mi_8x8[0]->mbmi.interintra_uv_mode, bw, bh,
xd->up_available, xd->left_available, 0, 2);
combine_interintra(xd->mi_8x8[0]->mbmi.interintra_uv_mode,
#if CONFIG_MASKED_INTERINTRA
xd->mi_8x8[0]->mbmi.use_masked_interintra,
xd->mi_8x8[0]->mbmi.interintra_uv_mask_index,
bsize,
#endif
upred, uvstride, uintrapredictor, bw, bw, bh);
combine_interintra(xd->mi_8x8[0]->mbmi.interintra_uv_mode,
#if CONFIG_MASKED_INTERINTRA
xd->mi_8x8[0]->mbmi.use_masked_interintra,
xd->mi_8x8[0]->mbmi.interintra_uv_mask_index,
bsize,
#endif
vpred, uvstride, vintrapredictor, bw, bw, bh);
}
void vp9_build_interintra_predictors(MACROBLOCKD *xd,
uint8_t *ypred,
uint8_t *upred,
uint8_t *vpred,
int ystride, int uvstride,
BLOCK_SIZE bsize) {
vp9_build_interintra_predictors_sby(xd, ypred, ystride, bsize);
vp9_build_interintra_predictors_sbuv(xd, upred, vpred, uvstride, bsize);
}
#endif

View File

@@ -16,7 +16,26 @@
void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
TX_SIZE tx_size, int mode,
#if CONFIG_FILTERINTRA
int filterbit,
#endif
const uint8_t *ref, int ref_stride,
uint8_t *dst, int dst_stride,
int aoff, int loff, int plane);
#endif // VP9_COMMON_VP9_RECONINTRA_H_
#if CONFIG_INTERINTRA
void vp9_build_interintra_predictors(MACROBLOCKD *xd,
uint8_t *ypred,
uint8_t *upred,
uint8_t *vpred,
int ystride,
int uvstride,
BLOCK_SIZE bsize);
#if CONFIG_MASKED_INTERINTRA
void vp9_generate_masked_weight_interintra(int mask_index,
BLOCK_SIZE sb_type,
int h, int w,
uint8_t *mask, int stride);
#endif
#endif

View File

@@ -543,6 +543,113 @@ specialize vp9_sad4x8_avg $sse_x86inc
prototype unsigned int vp9_sad4x4_avg "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred, unsigned int max_sad"
specialize vp9_sad4x4_avg $sse_x86inc
if [ "$CONFIG_MASKED_INTERINTER" = "yes" ] || ([ "$CONFIG_MASKED_INTERINTRA" = "yes" ] && [ "$CONFIG_INTERINTRA" = "yes" ]); then
prototype int vp9_masked_diamond_search_sad "struct macroblock *x, uint8_t *mask, int mask_stride, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, const struct mv *center_mv, int is_second"
specialize vp9_masked_diamond_search_sad
prototype int vp9_masked_refining_search_sad "struct macroblock *x, uint8_t *mask, int mask_stride, struct mv *ref_mv, int sad_per_bit, int distance, struct vp9_variance_vtable *fn_ptr, DEC_MVCOSTS, const struct mv *center_mv, int is_second"
specialize vp9_masked_refining_search_sad
prototype unsigned int vp9_masked_variance32x16 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance32x16
prototype unsigned int vp9_masked_variance16x32 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance16x32
prototype unsigned int vp9_masked_variance64x32 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance64x32
prototype unsigned int vp9_masked_variance32x64 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance32x64
prototype unsigned int vp9_masked_variance32x32 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance32x32
prototype unsigned int vp9_masked_variance64x64 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance64x64
prototype unsigned int vp9_masked_variance16x16 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance16x16
prototype unsigned int vp9_masked_variance16x8 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance16x8
prototype unsigned int vp9_masked_variance8x16 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance8x16
prototype unsigned int vp9_masked_variance8x8 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance8x8
prototype unsigned int vp9_masked_variance4x4 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_variance4x4
prototype unsigned int vp9_masked_sub_pixel_variance64x64 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance64x64
prototype unsigned int vp9_masked_sub_pixel_variance32x64 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance32x64
prototype unsigned int vp9_masked_sub_pixel_variance64x32 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance64x32
prototype unsigned int vp9_masked_sub_pixel_variance32x16 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance32x16
prototype unsigned int vp9_masked_sub_pixel_variance16x32 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance16x32
prototype unsigned int vp9_masked_sub_pixel_variance32x32 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance32x32
prototype unsigned int vp9_masked_sub_pixel_variance16x16 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance16x16
prototype unsigned int vp9_masked_sub_pixel_variance8x16 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance8x16
prototype unsigned int vp9_masked_sub_pixel_variance16x8 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance16x8
prototype unsigned int vp9_masked_sub_pixel_variance8x8 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance8x8
prototype unsigned int vp9_masked_sub_pixel_variance4x4 "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int *sse"
specialize vp9_masked_sub_pixel_variance4x4
prototype unsigned int vp9_masked_sad64x64 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad64x64
prototype unsigned int vp9_masked_sad32x64 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad32x64
prototype unsigned int vp9_masked_sad64x32 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad64x32
prototype unsigned int vp9_masked_sad32x16 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad32x16
prototype unsigned int vp9_masked_sad16x32 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad16x32
prototype unsigned int vp9_masked_sad32x32 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad32x32
prototype unsigned int vp9_masked_sad16x16 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad16x16
prototype unsigned int vp9_masked_sad16x8 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad16x8
prototype unsigned int vp9_masked_sad8x16 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad8x16
prototype unsigned int vp9_masked_sad8x8 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad8x8
prototype unsigned int vp9_masked_sad4x4 "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *msk_ptr, int msk_stride, unsigned int max_sad"
specialize vp9_masked_sad4x4
fi
prototype unsigned int vp9_variance_halfpixvar16x16_h "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse"
specialize vp9_variance_halfpixvar16x16_h $sse2_x86inc

View File

@@ -140,15 +140,18 @@ static void read_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) {
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
vp9_diff_update_prob(r, &cm->fc.comp_inter_prob[i]);
if (cm->reference_mode != COMPOUND_REFERENCE)
if (cm->reference_mode != COMPOUND_REFERENCE) {
for (i = 0; i < REF_CONTEXTS; i++) {
vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][0]);
vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][1]);
}
}
if (cm->reference_mode != SINGLE_REFERENCE)
for (i = 0; i < REF_CONTEXTS; i++)
if (cm->reference_mode != SINGLE_REFERENCE) {
for (i = 0; i < REF_CONTEXTS; i++) {
vp9_diff_update_prob(r, &cm->fc.comp_ref_prob[i]);
}
}
}
static void update_mv_probs(vp9_prob *p, int n, vp9_reader *r) {
@@ -261,8 +264,19 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob);
break;
case TX_32X32:
#if !CONFIG_EXT_TX
tx_type = DCT_DCT;
vp9_idct32x32_add(dqcoeff, dst, stride, eob);
#else
tx_type = get_tx_type_32x32(plane_type, xd);
if (tx_type == DCT_DCT)
vp9_idct32x32_add(dqcoeff, dst, stride, eob);
else if (tx_type == ADST_ADST)
// yongzhe: temporarily signaled as ADST_ADST
vp9_idst_add(dqcoeff, dst, stride, eob, 32);
else
assert(0 && "Invalid transform type");
#endif
break;
default:
assert(0 && "Invalid transform size");
@@ -301,11 +315,24 @@ static void predict_and_reconstruct_intra_block(int plane, int block,
: mi->mbmi.uv_mode;
int x, y;
uint8_t *dst;
#if CONFIG_FILTERINTRA
int fbit;
if (plane == 0)
if (mi->mbmi.sb_type < BLOCK_8X8)
fbit = mi->b_filter_info[block];
else
fbit = is_filter_enabled(tx_size) ? mi->mbmi.filterbit : 0;
else
fbit = is_filter_enabled(tx_size) ? mi->mbmi.uv_filterbit : 0;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
dst = &pd->dst.buf[4 * y * pd->dst.stride + 4 * x];
vp9_predict_intra_block(xd, block >> (tx_size << 1),
b_width_log2(plane_bsize), tx_size, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
dst, pd->dst.stride, dst, pd->dst.stride,
x, y, plane);
@@ -1261,6 +1288,10 @@ static int read_compressed_header(VP9D_COMP *pbi, const uint8_t *data,
nmv_context *const nmvc = &fc->nmvc;
int i, j;
#if CONFIG_EXT_TX
vp9_diff_update_prob(&r, &fc->ext_tx_prob);
#endif
read_inter_mode_probs(fc, &r);
if (cm->mcomp_filter_type == SWITCHABLE)
@@ -1272,6 +1303,50 @@ static int read_compressed_header(VP9D_COMP *pbi, const uint8_t *data,
cm->reference_mode = read_reference_mode(cm, &r);
read_reference_mode_probs(cm, &r);
#if CONFIG_MASKED_INTERINTER
if (cm->reference_mode != SINGLE_REFERENCE) {
cm->use_masked_interinter = vp9_read_bit(&r);
if (cm->use_masked_interinter) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (get_mask_bits(i)) {
vp9_diff_update_prob(&r, &fc->masked_interinter_prob[i]);
}
}
}
} else {
cm->use_masked_interinter = 0;
}
#endif
#if CONFIG_INTERINTRA
if (cm->reference_mode != COMPOUND_REFERENCE) {
cm->use_interintra = vp9_read_bit(&r);
if (cm->use_interintra) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i)) {
vp9_diff_update_prob(&r, &fc->interintra_prob[i]);
}
}
#if CONFIG_MASKED_INTERINTRA
cm->use_masked_interintra = vp9_read_bit(&r);
if (cm->use_masked_interintra) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i) && get_mask_bits_interintra(i))
vp9_diff_update_prob(&r, &fc->masked_interintra_prob[i]);
}
}
} else {
cm->use_masked_interintra = 0;
#endif
}
} else {
cm->use_interintra = 0;
#if CONFIG_MASKED_INTERINTRA
cm->use_masked_interintra = 0;
#endif
}
#endif
for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
for (i = 0; i < INTRA_MODES - 1; ++i)
vp9_diff_update_prob(&r, &fc->y_mode_prob[j][i]);
@@ -1319,6 +1394,10 @@ static void debug_check_frame_counts(const VP9_COMMON *const cm) {
sizeof(cm->counts.eob_branch)));
assert(!memcmp(cm->counts.switchable_interp, zero_counts.switchable_interp,
sizeof(cm->counts.switchable_interp)));
#if CONFIG_EXT_TX
assert(!memcmp(cm->counts.ext_tx, zero_counts.ext_tx,
sizeof(cm->counts.ext_tx)));
#endif
assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode,
sizeof(cm->counts.inter_mode)));
assert(!memcmp(cm->counts.intra_inter, zero_counts.intra_inter,

View File

@@ -179,6 +179,13 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
const MB_PREDICTION_MODE A = above_block_mode(mi, above_mi, 0);
const MB_PREDICTION_MODE L = left_block_mode(mi, left_mi, 0);
mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
#if CONFIG_FILTERINTRA
if (is_filter_enabled(mbmi->tx_size) && is_filter_allowed(mbmi->mode))
mbmi->filterbit = vp9_read(r,
cm->fc.filterintra_prob[mbmi->tx_size][mbmi->mode]);
else
mbmi->filterbit = 0;
#endif
} else {
// Only 4x4, 4x8, 8x4 blocks
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; // 1 or 2
@@ -197,13 +204,35 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
mi->bmi[ib + 2].as_mode = b_mode;
if (num_4x4_w == 2)
mi->bmi[ib + 1].as_mode = b_mode;
#if CONFIG_FILTERINTRA
if (is_filter_allowed(b_mode))
mi->b_filter_info[ib] = vp9_read(r,
cm->fc.filterintra_prob[0][b_mode]);
else
mi->b_filter_info[ib] = 0;
if (num_4x4_h == 2)
mi->b_filter_info[ib + 2] = mi->b_filter_info[ib];
if (num_4x4_w == 2)
mi->b_filter_info[ib + 1] = mi->b_filter_info[ib];
#endif
}
}
mbmi->mode = mi->bmi[3].as_mode;
#if CONFIG_FILTERINTRA
mbmi->filterbit = mi->b_filter_info[3];
#endif
}
mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
#if CONFIG_FILTERINTRA
if (is_filter_enabled(get_uv_tx_size(mbmi)) &&
is_filter_allowed(mbmi->uv_mode))
mbmi->uv_filterbit = vp9_read(r,
cm->fc.filterintra_prob[get_uv_tx_size(mbmi)][mbmi->uv_mode]);
else
mbmi->uv_filterbit = 0;
#endif
}
static int read_mv_component(vp9_reader *r,
@@ -334,6 +363,15 @@ static void read_intra_block_mode_info(VP9_COMMON *const cm, MODE_INFO *mi,
if (bsize >= BLOCK_8X8) {
mbmi->mode = read_intra_mode_y(cm, r, size_group_lookup[bsize]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->mode) && is_filter_enabled(mbmi->tx_size)) {
mbmi->filterbit = vp9_read(r,
cm->fc.filterintra_prob[mbmi->tx_size][mbmi->mode]);
cm->counts.filterintra[mbmi->tx_size][mbmi->mode][mbmi->filterbit]++;
} else {
mbmi->filterbit = 0;
}
#endif
} else {
// Only 4x4, 4x8, 8x4 blocks
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; // 1 or 2
@@ -349,12 +387,40 @@ static void read_intra_block_mode_info(VP9_COMMON *const cm, MODE_INFO *mi,
mi->bmi[ib + 2].as_mode = b_mode;
if (num_4x4_w == 2)
mi->bmi[ib + 1].as_mode = b_mode;
#if CONFIG_FILTERINTRA
if (is_filter_allowed(b_mode)) {
mi->b_filter_info[ib] = vp9_read(r,
cm->fc.filterintra_prob[0][b_mode]);
cm->counts.filterintra[0][b_mode][mi->b_filter_info[ib]]++;
} else {
mi->b_filter_info[ib] = 0;
}
if (num_4x4_h == 2)
mi->b_filter_info[ib + 2] = mi->b_filter_info[ib];
if (num_4x4_w == 2)
mi->b_filter_info[ib + 1] = mi->b_filter_info[ib];
#endif
}
}
mbmi->mode = mi->bmi[3].as_mode;
#if CONFIG_FILTERINTRA
mbmi->filterbit = mi->b_filter_info[3];
#endif
}
mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->uv_mode) &&
is_filter_enabled(get_uv_tx_size(mbmi))) {
mbmi->uv_filterbit = vp9_read(r,
cm->fc.filterintra_prob[get_uv_tx_size(mbmi)][mbmi->uv_mode]);
cm->counts.filterintra[get_uv_tx_size(mbmi)]
[mbmi->uv_mode][mbmi->uv_filterbit]++;
} else {
mbmi->uv_filterbit = 0;
}
#endif
}
static INLINE int assign_mv(VP9_COMMON *cm, MB_PREDICTION_MODE mode,
@@ -428,6 +494,23 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
int inter_mode_ctx, ref, is_compound;
read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
#if CONFIG_EXT_TX
assert(is_inter_block(mbmi));
#if CONFIG_EXT_TX_DST32
if (
#else
if (mbmi->tx_size <= TX_16X16 &&
#endif
!mbmi->skip_coeff) {
mbmi->ext_txfrm = vp9_read(r, cm->fc.ext_tx_prob);
if (!cm->frame_parallel_decoding_mode)
++cm->counts.ext_tx[mbmi->ext_txfrm];
} else {
mbmi->ext_txfrm = NORM;
}
#endif
is_compound = has_second_ref(mbmi);
for (ref = 0; ref < 1 + is_compound; ++ref) {
@@ -462,6 +545,44 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
? read_switchable_filter_type(cm, xd, r)
: cm->mcomp_filter_type;
#if CONFIG_INTERINTRA
if ((cm->use_interintra) &&
is_interintra_allowed(bsize) &&
is_inter_mode(mbmi->mode) &&
(mbmi->ref_frame[1] <= INTRA_FRAME)) {
mbmi->ref_frame[1] = vp9_read(r, cm->fc.interintra_prob[bsize]) ?
INTRA_FRAME : NONE;
cm->counts.interintra[bsize][mbmi->ref_frame[1] == INTRA_FRAME]++;
#if CONFIG_MASKED_INTERINTRA
mbmi->use_masked_interintra = 0;
#endif
if (mbmi->ref_frame[1] == NONE)
mbmi->interintra_mode = -1;
if (mbmi->ref_frame[1] == INTRA_FRAME) {
mbmi->interintra_mode =
read_intra_mode_y(cm, r, size_group_lookup[bsize]);
#if SEPARATE_INTERINTRA_UV
mbmi->interintra_uv_mode =
read_intra_mode_uv(cm, r, mbmi->interintra_mode);
#else
mbmi->interintra_uv_mode = mbmi->interintra_mode;
#endif
#if CONFIG_MASKED_INTERINTRA
if (cm->use_masked_interintra && get_mask_bits_interintra(bsize)) {
mbmi->use_masked_interintra = vp9_read(r,
cm->fc.masked_interintra_prob[bsize]);
cm->counts.masked_interintra[bsize][mbmi->use_masked_interintra]++;
if (mbmi->use_masked_interintra) {
mbmi->interintra_mask_index = vp9_read_literal(r,
get_mask_bits_interintra(bsize));
mbmi->interintra_uv_mask_index = mbmi->interintra_mask_index;
}
}
#endif
}
}
#endif
if (bsize < BLOCK_8X8) {
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; // 1 or 2
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; // 1 or 2
@@ -504,6 +625,21 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
best, nearest, nearmv,
is_compound, allow_hp, r);
}
#if CONFIG_MASKED_INTERINTER
mbmi->use_masked_interinter = 0;
if (cm->use_masked_interinter &&
cm->reference_mode != SINGLE_REFERENCE &&
is_inter_mode(mbmi->mode) &&
get_mask_bits(bsize) &&
mbmi->ref_frame[1] > INTRA_FRAME) {
mbmi->use_masked_interinter =
vp9_read(r, cm->fc.masked_interinter_prob[bsize]);
cm->counts.masked_interinter[bsize][mbmi->use_masked_interinter]++;
if (mbmi->use_masked_interinter) {
mbmi->mask_index = vp9_read_literal(r, get_mask_bits(bsize));
}
}
#endif
}
static void read_inter_frame_mode_info(VP9_COMMON *const cm,

View File

@@ -307,6 +307,12 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
if (bsize >= BLOCK_8X8) {
write_intra_mode(bc, mode, cm->fc.y_mode_prob[size_group_lookup[bsize]]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mode) && is_filter_enabled(mi->tx_size)) {
vp9_write(bc, mi->filterbit,
cm->fc.filterintra_prob[mi->tx_size][mode]);
}
#endif
} else {
int idx, idy;
const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
@@ -315,15 +321,42 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
const MB_PREDICTION_MODE bm = m->bmi[idy * 2 + idx].as_mode;
write_intra_mode(bc, bm, cm->fc.y_mode_prob[0]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(bm)) {
vp9_write(bc, m->b_filter_info[idy * 2 + idx],
cm->fc.filterintra_prob[0][bm]);
}
#endif
}
}
}
write_intra_mode(bc, mi->uv_mode, cm->fc.uv_mode_prob[mode]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->uv_mode) &&
is_filter_enabled(get_uv_tx_size(mi))) {
vp9_write(bc, mi->uv_filterbit,
cm->fc.filterintra_prob[get_uv_tx_size(mi)][mi->uv_mode]);
}
#endif
} else {
vp9_prob *mv_ref_p;
encode_ref_frame(cpi, bc);
mv_ref_p = cpi->common.fc.inter_mode_probs[mi->mode_context[rf]];
#if CONFIG_EXT_TX
assert(is_inter_block(mi));
#if CONFIG_EXT_TX_DST32
if (
#else
if (mi->tx_size <= TX_16X16 &&
#endif
!mi->skip_coeff &&
!vp9_segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP)) {
// printf("enc: writing bit\n");
vp9_write(bc, mi->ext_txfrm, cm->fc.ext_tx_prob);
}
#endif
#ifdef ENTROPY_STATS
active_section = 3;
#endif
@@ -345,6 +378,38 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
assert(mi->interp_filter == cm->mcomp_filter_type);
}
#if CONFIG_INTERINTRA
if ((cm->use_interintra) &&
cpi->common.reference_mode != COMPOUND_REFERENCE &&
is_interintra_allowed(bsize) &&
is_inter_mode(mode) &&
(mi->ref_frame[1] <= INTRA_FRAME)) {
vp9_write(bc, mi->ref_frame[1] == INTRA_FRAME,
cm->fc.interintra_prob[bsize]);
if (mi->ref_frame[1] == NONE)
mi->interintra_mode = -1;
if (mi->ref_frame[1] == INTRA_FRAME) {
write_intra_mode(bc, mi->interintra_mode,
cm->fc.y_mode_prob[size_group_lookup[bsize]]);
#if SEPARATE_INTERINTRA_UV
write_intra_mode(bc, mi->interintra_uv_mode,
cm->fc.uv_mode_prob[mi->interintra_mode]);
#endif
#if CONFIG_MASKED_INTERINTRA
if (get_mask_bits_interintra(bsize) &&
cm->use_masked_interintra) {
vp9_write(bc, mi->use_masked_interintra,
cm->fc.masked_interintra_prob[bsize]);
if (mi->use_masked_interintra) {
vp9_write_literal(bc, mi->interintra_mask_index,
get_mask_bits_interintra(bsize));
}
}
#endif
}
}
#endif
if (bsize < BLOCK_8X8) {
const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
@@ -381,6 +446,19 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc) {
vp9_encode_mv(cpi, bc, &mi->mv[1].as_mv,
&mi->best_mv[1].as_mv, nmvc, allow_hp);
}
#if CONFIG_MASKED_INTERINTER
if (cpi->common.use_masked_interinter &&
cpi->common.reference_mode != SINGLE_REFERENCE &&
is_inter_mode(mode) &&
get_mask_bits(mi->sb_type) &&
mi->ref_frame[1] > INTRA_FRAME) {
vp9_write(bc, mi->use_masked_interinter,
cpi->common.fc.masked_interinter_prob[bsize]);
if (mi->use_masked_interinter) {
vp9_write_literal(bc, mi->mask_index, get_mask_bits(mi->sb_type));
}
}
#endif
}
}
@@ -407,6 +485,11 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, MODE_INFO **mi_8x8,
const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, 0);
const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, 0);
write_intra_mode(bc, ym, vp9_kf_y_mode_prob[A][L]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(ym) && is_filter_enabled(m->mbmi.tx_size))
vp9_write(bc, m->mbmi.filterbit,
cm->fc.filterintra_prob[m->mbmi.tx_size][ym]);
#endif
} else {
int idx, idy;
const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[m->mbmi.sb_type];
@@ -421,11 +504,21 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, MODE_INFO **mi_8x8,
++intra_mode_stats[A][L][bm];
#endif
write_intra_mode(bc, bm, vp9_kf_y_mode_prob[A][L]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(bm))
vp9_write(bc, m->b_filter_info[i], cm->fc.filterintra_prob[0][bm]);
#endif
}
}
}
write_intra_mode(bc, m->mbmi.uv_mode, vp9_kf_uv_mode_prob[ym]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(m->mbmi.uv_mode) &&
is_filter_enabled(get_uv_tx_size(&(m->mbmi))))
vp9_write(bc, m->mbmi.uv_filterbit,
cm->fc.filterintra_prob[get_uv_tx_size(&(m->mbmi))][m->mbmi.uv_mode]);
#endif
}
static void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile,
@@ -1232,6 +1325,10 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
active_section = 1;
#endif
#if CONFIG_EXT_TX
vp9_cond_prob_diff_update(&header_bc, &fc->ext_tx_prob, cm->counts.ext_tx);
#endif
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
prob_diff_update(vp9_inter_mode_tree, cm->fc.inter_mode_probs[i],
cm->counts.inter_mode[i], INTER_MODES, &header_bc);
@@ -1269,10 +1366,100 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
}
}
if (cm->reference_mode != SINGLE_REFERENCE)
for (i = 0; i < REF_CONTEXTS; i++)
if (cm->reference_mode != SINGLE_REFERENCE) {
for (i = 0; i < REF_CONTEXTS; i++) {
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
cpi->comp_ref_count[i]);
}
}
#if CONFIG_MASKED_INTERINTER
if (cm->reference_mode != SINGLE_REFERENCE) {
if (!cpi->dummy_packing && cm->use_masked_interinter) {
cm->use_masked_interinter = 0;
for (i = 0; i < BLOCK_SIZES; i++) {
if (get_mask_bits(i) && (cpi->masked_interinter_counts[i][1] > 0)) {
cm->use_masked_interinter = 1;
break;
}
}
}
vp9_write_bit(&header_bc, cm->use_masked_interinter);
if (cm->use_masked_interinter) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (get_mask_bits(i)) {
vp9_cond_prob_diff_update(&header_bc,
&fc->masked_interinter_prob[i],
cpi->masked_interinter_counts[i]);
}
}
} else {
vp9_zero(cpi->masked_interinter_counts);
}
} else {
if (!cpi->dummy_packing)
cm->use_masked_interinter = 0;
vp9_zero(cpi->masked_interinter_counts);
}
#endif
#if CONFIG_INTERINTRA
if (cm->reference_mode != COMPOUND_REFERENCE) {
if (!cpi->dummy_packing && cm->use_interintra) {
cm->use_interintra = 0;
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i) && (cpi->interintra_count[i][1] > 0)) {
cm->use_interintra = 1;
break;
}
}
}
vp9_write_bit(&header_bc, cm->use_interintra);
if (cm->use_interintra) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i)) {
vp9_cond_prob_diff_update(&header_bc,
&fc->interintra_prob[i],
cpi->interintra_count[i]);
}
}
#if CONFIG_MASKED_INTERINTRA
if (!cpi->dummy_packing && cm->use_masked_interintra) {
cm->use_masked_interintra = 0;
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i) && get_mask_bits_interintra(i) &&
(cpi->masked_interintra_count[i][1] > 0)) {
cm->use_masked_interintra = 1;
break;
}
}
}
vp9_write_bit(&header_bc, cm->use_masked_interintra);
if (cm->use_masked_interintra) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i) && get_mask_bits_interintra(i))
vp9_cond_prob_diff_update(&header_bc,
&fc->masked_interintra_prob[i],
cpi->masked_interintra_count[i]);
}
} else {
vp9_zero(cpi->masked_interintra_count);
}
#endif
} else {
vp9_zero(cpi->interintra_count);
}
} else {
if (!cpi->dummy_packing)
cm->use_interintra = 0;
vp9_zero(cpi->interintra_count);
#if CONFIG_MASKED_INTERINTRA
if (!cpi->dummy_packing)
cm->use_masked_interintra = 0;
vp9_zero(cpi->masked_interintra_count);
#endif
}
#endif
for (i = 0; i < BLOCK_SIZE_GROUPS; ++i)
prob_diff_update(vp9_intra_mode_tree, cm->fc.y_mode_prob[i],

View File

@@ -1345,6 +1345,403 @@ void vp9_fdct32x32_c(const int16_t *input, int16_t *out, int stride) {
}
}
#if CONFIG_EXT_TX
static double tmp[32*32];
static double tmp2[32*32];
double dstmtx32[32*32] = {
0.0122669185818545, 0.0245042850823902, 0.0366826186138404,
0.0487725805040321, 0.0607450449758160, 0.0725711693136156,
0.0842224633480550, 0.0956708580912724, 0.1068887733575705,
0.1178491842064994, 0.1285256860483054, 0.1388925582549005,
0.1489248261231083, 0.1585983210409114, 0.1678897387117546,
0.1767766952966369, 0.1852377813387398, 0.1932526133406842,
0.2008018828701612, 0.2078674030756363, 0.2144321525000680,
0.2204803160870887, 0.2259973232808608, 0.2309698831278217,
0.2353860162957552, 0.2392350839330522, 0.2425078132986360,
0.2451963201008076, 0.2472941274911953, 0.2487961816680492,
0.2496988640512931, 0.1767766952966369,
0.0366826186138404, 0.0725711693136156, 0.1068887733575705,
0.1388925582549005, 0.1678897387117546, 0.1932526133406842,
0.2144321525000680, 0.2309698831278217, 0.2425078132986360,
0.2487961816680492, 0.2496988640512931, 0.2451963201008076,
0.2353860162957552, 0.2204803160870888, 0.2008018828701612,
0.1767766952966369, 0.1489248261231084, 0.1178491842064995,
0.0842224633480551, 0.0487725805040322, 0.0122669185818545,
-0.0245042850823901, -0.0607450449758160, -0.0956708580912724,
-0.1285256860483054, -0.1585983210409113, -0.1852377813387397,
-0.2078674030756363, -0.2259973232808608, -0.2392350839330522,
-0.2472941274911952, -0.1767766952966369,
0.0607450449758160, 0.1178491842064994, 0.1678897387117546,
0.2078674030756363, 0.2353860162957552, 0.2487961816680492,
0.2472941274911953, 0.2309698831278217, 0.2008018828701612,
0.1585983210409114, 0.1068887733575705, 0.0487725805040322,
-0.0122669185818544, -0.0725711693136155, -0.1285256860483054,
-0.1767766952966369, -0.2144321525000680, -0.2392350839330522,
-0.2496988640512931, -0.2451963201008076, -0.2259973232808608,
-0.1932526133406842, -0.1489248261231083, -0.0956708580912726,
-0.0366826186138406, 0.0245042850823900, 0.0842224633480549,
0.1388925582549005, 0.1852377813387397, 0.2204803160870887,
0.2425078132986360, 0.1767766952966369,
0.0842224633480550, 0.1585983210409114, 0.2144321525000680,
0.2451963201008076, 0.2472941274911953, 0.2204803160870888,
0.1678897387117546, 0.0956708580912725, 0.0122669185818545,
-0.0725711693136155, -0.1489248261231083, -0.2078674030756363,
-0.2425078132986360, -0.2487961816680492, -0.2259973232808608,
-0.1767766952966369, -0.1068887733575706, -0.0245042850823901,
0.0607450449758159, 0.1388925582549005, 0.2008018828701612,
0.2392350839330522, 0.2496988640512931, 0.2309698831278217,
0.1852377813387399, 0.1178491842064995, 0.0366826186138404,
-0.0487725805040318, -0.1285256860483053, -0.1932526133406843,
-0.2353860162957551, -0.1767766952966369,
0.1068887733575705, 0.1932526133406842, 0.2425078132986360,
0.2451963201008076, 0.2008018828701612, 0.1178491842064995,
0.0122669185818545, -0.0956708580912724, -0.1852377813387397,
-0.2392350839330522, -0.2472941274911952, -0.2078674030756364,
-0.1285256860483055, -0.0245042850823901, 0.0842224633480549,
0.1767766952966368, 0.2353860162957552, 0.2487961816680492,
0.2144321525000681, 0.1388925582549006, 0.0366826186138404,
-0.0725711693136157, -0.1678897387117544, -0.2309698831278216,
-0.2496988640512931, -0.2204803160870888, -0.1489248261231083,
-0.0487725805040320, 0.0607450449758156, 0.1585983210409112,
0.2259973232808608, 0.1767766952966369,
0.1285256860483054, 0.2204803160870887, 0.2496988640512931,
0.2078674030756363, 0.1068887733575706, -0.0245042850823900,
-0.1489248261231082, -0.2309698831278216, -0.2472941274911953,
-0.1932526133406844, -0.0842224633480552, 0.0487725805040318,
0.1678897387117544, 0.2392350839330522, 0.2425078132986361,
0.1767766952966371, 0.0607450449758163, -0.0725711693136153,
-0.1852377813387395, -0.2451963201008076, -0.2353860162957553,
-0.1585983210409117, -0.0366826186138409, 0.0956708580912720,
0.2008018828701609, 0.2487961816680492, 0.2259973232808611,
0.1388925582549010, 0.0122669185818551, -0.1178491842064989,
-0.2144321525000677, -0.1767766952966369,
0.1489248261231083, 0.2392350839330522, 0.2353860162957552,
0.1388925582549005, -0.0122669185818545, -0.1585983210409114,
-0.2425078132986360, -0.2309698831278217, -0.1285256860483055,
0.0245042850823902, 0.1678897387117547, 0.2451963201008076,
0.2259973232808608, 0.1178491842064991, -0.0366826186138407,
-0.1767766952966370, -0.2472941274911953, -0.2204803160870888,
-0.1068887733575703, 0.0487725805040322, 0.1852377813387398,
0.2487961816680493, 0.2144321525000679, 0.0956708580912723,
-0.0607450449758161, -0.1932526133406842, -0.2496988640512931,
-0.2078674030756359, -0.0842224633480545, 0.0725711693136160,
0.2008018828701614, 0.1767766952966369,
0.1678897387117546, 0.2487961816680492, 0.2008018828701613,
0.0487725805040322, -0.1285256860483054, -0.2392350839330522,
-0.2259973232808609, -0.0956708580912726, 0.0842224633480549,
0.2204803160870887, 0.2425078132986361, 0.1388925582549010,
-0.0366826186138402, -0.1932526133406840, -0.2496988640512931,
-0.1767766952966371, -0.0122669185818550, 0.1585983210409112,
0.2472941274911952, 0.2078674030756364, 0.0607450449758163,
-0.1178491842064989, -0.2353860162957550, -0.2309698831278220,
-0.1068887733575707, 0.0725711693136152, 0.2144321525000677,
0.2451963201008078, 0.1489248261231091, -0.0245042850823899,
-0.1852377813387394, -0.1767766952966369,
0.1852377813387398, 0.2487961816680492, 0.1489248261231083,
-0.0487725805040321, -0.2144321525000680, -0.2392350839330522,
-0.1068887733575704, 0.0956708580912725, 0.2353860162957552,
0.2204803160870888, 0.0607450449758159, -0.1388925582549008,
-0.2472941274911953, -0.1932526133406841, -0.0122669185818546,
0.1767766952966369, 0.2496988640512931, 0.1585983210409114,
-0.0366826186138406, -0.2078674030756363, -0.2425078132986359,
-0.1178491842064992, 0.0842224633480550, 0.2309698831278219,
0.2259973232808607, 0.0725711693136156, -0.1285256860483052,
-0.2451963201008077, -0.2008018828701612, -0.0245042850823903,
0.1678897387117549, 0.1767766952966369,
0.2008018828701612, 0.2392350839330522, 0.0842224633480551,
-0.1388925582549005, -0.2496988640512931, -0.1585983210409115,
0.0607450449758157, 0.2309698831278216, 0.2144321525000681,
0.0245042850823902, -0.1852377813387395, -0.2451963201008077,
-0.1068887733575707, 0.1178491842064989, 0.2472941274911952,
0.1767766952966371, -0.0366826186138402, -0.2204803160870887,
-0.2259973232808611, -0.0487725805040321, 0.1678897387117543,
0.2487961816680493, 0.1285256860483056, -0.0956708580912719,
-0.2425078132986358, -0.1932526133406845, 0.0122669185818538,
0.2078674030756357, 0.2353860162957554, 0.0725711693136165,
-0.1489248261231080, -0.1767766952966369,
0.2144321525000680, 0.2204803160870888, 0.0122669185818545,
-0.2078674030756363, -0.2259973232808608, -0.0245042850823901,
0.2008018828701612, 0.2309698831278217, 0.0366826186138404,
-0.1932526133406843, -0.2353860162957552, -0.0487725805040320,
0.1852377813387398, 0.2392350839330522, 0.0607450449758159,
-0.1767766952966369, -0.2425078132986359, -0.0725711693136155,
0.1678897387117543, 0.2451963201008076, 0.0842224633480545,
-0.1585983210409114, -0.2472941274911953, -0.0956708580912724,
0.1489248261231088, 0.2487961816680492, 0.1068887733575708,
-0.1388925582549007, -0.2496988640512931, -0.1178491842064993,
0.1285256860483052, 0.1767766952966369,
0.2259973232808608, 0.1932526133406843, -0.0607450449758160,
-0.2451963201008076, -0.1489248261231085, 0.1178491842064994,
0.2496988640512931, 0.0956708580912726, -0.1678897387117544,
-0.2392350839330523, -0.0366826186138409, 0.2078674030756363,
0.2144321525000681, -0.0245042850823899, -0.2353860162957550,
-0.1767766952966372, 0.0842224633480550, 0.2487961816680492,
0.1285256860483056, -0.1388925582549000, -0.2472941274911953,
-0.0725711693136164, 0.1852377813387394, 0.2309698831278217,
0.0122669185818552, -0.2204803160870886, -0.2008018828701617,
0.0487725805040316, 0.2425078132986357, 0.1585983210409125,
-0.1068887733575703, -0.1767766952966369,
0.2353860162957552, 0.1585983210409114, -0.1285256860483054,
-0.2451963201008076, -0.0366826186138404, 0.2204803160870887,
0.1852377813387396, -0.0956708580912725, -0.2496988640512931,
-0.0725711693136155, 0.2008018828701612, 0.2078674030756364,
-0.0607450449758161, -0.2487961816680493, -0.1068887733575707,
0.1767766952966369, 0.2259973232808607, -0.0245042850823899,
-0.2425078132986360, -0.1388925582549004, 0.1489248261231081,
0.2392350839330522, 0.0122669185818543, -0.2309698831278215,
-0.1678897387117547, 0.1178491842064995, 0.2472941274911952,
0.0487725805040314, -0.2144321525000676, -0.1932526133406846,
0.0842224633480548, 0.1767766952966369,
0.2425078132986360, 0.1178491842064995, -0.1852377813387397,
-0.2078674030756364, 0.0842224633480549, 0.2487961816680492,
0.0366826186138408, -0.2309698831278216, -0.1489248261231083,
0.1585983210409112, 0.2259973232808611, -0.0487725805040317,
-0.2496988640512931, -0.0725711693136164, 0.2144321525000677,
0.1767766952966372, -0.1285256860483052, -0.2392350839330522,
0.0122669185818538, 0.2451963201008075, 0.1068887733575708,
-0.1932526133406836, -0.2008018828701617, 0.0956708580912718,
0.2472941274911954, 0.0245042850823904, -0.2353860162957549,
-0.1388925582549019, 0.1678897387117542, 0.2204803160870893,
-0.0607450449758158, -0.1767766952966369,
0.2472941274911953, 0.0725711693136156, -0.2259973232808608,
-0.1388925582549005, 0.1852377813387399, 0.1932526133406844,
-0.1285256860483053, -0.2309698831278217, 0.0607450449758161,
0.2487961816680492, 0.0122669185818546, -0.2451963201008075,
-0.0842224633480553, 0.2204803160870887, 0.1489248261231084,
-0.1767766952966369, -0.2008018828701612, 0.1178491842064996,
0.2353860162957551, -0.0487725805040325, -0.2496988640512931,
-0.0245042850823904, 0.2425078132986362, 0.0956708580912733,
-0.2144321525000676, -0.1585983210409119, 0.1678897387117542,
0.2078674030756366, -0.1068887733575702, -0.2392350839330523,
0.0366826186138403, 0.1767766952966369,
0.2496988640512931, 0.0245042850823902, -0.2472941274911952,
-0.0487725805040322, 0.2425078132986360, 0.0725711693136159,
-0.2353860162957551, -0.0956708580912727, 0.2259973232808608,
0.1178491842064996, -0.2144321525000677, -0.1388925582549010,
0.2008018828701609, 0.1585983210409118, -0.1852377813387394,
-0.1767766952966372, 0.1678897387117543, 0.1932526133406845,
-0.1489248261231080, -0.2078674030756365, 0.1285256860483052,
0.2204803160870893, -0.1068887733575703, -0.2309698831278221,
0.0842224633480548, 0.2392350839330525, -0.0607450449758158,
-0.2451963201008078, 0.0366826186138403, 0.2487961816680493,
-0.0122669185818544, -0.1767766952966369,
0.2496988640512931, -0.0245042850823901, -0.2472941274911952,
0.0487725805040321, 0.2425078132986360, -0.0725711693136157,
-0.2353860162957552, 0.0956708580912724, 0.2259973232808609,
-0.1178491842064997, -0.2144321525000679, 0.1388925582549007,
0.2008018828701612, -0.1585983210409114, -0.1852377813387397,
0.1767766952966369, 0.1678897387117547, -0.1932526133406841,
-0.1489248261231085, 0.2078674030756367, 0.1285256860483049,
-0.2204803160870890, -0.1068887733575701, 0.2309698831278219,
0.0842224633480547, -0.2392350839330523, -0.0607450449758158,
0.2451963201008076, 0.0366826186138403, -0.2487961816680492,
-0.0122669185818545, 0.1767766952966369,
0.2472941274911953, -0.0725711693136155, -0.2259973232808608,
0.1388925582549005, 0.1852377813387399, -0.1932526133406843,
-0.1285256860483055, 0.2309698831278216, 0.0607450449758163,
-0.2487961816680492, 0.0122669185818538, 0.2451963201008076,
-0.0842224633480550, -0.2204803160870888, 0.1489248261231081,
0.1767766952966372, -0.2008018828701608, -0.1178491842065001,
0.2353860162957552, 0.0487725805040331, -0.2496988640512931,
0.0245042850823888, 0.2425078132986361, -0.0956708580912726,
-0.2144321525000685, 0.1585983210409113, 0.1678897387117555,
-0.2078674030756361, -0.1068887733575718, 0.2392350839330520,
0.0366826186138421, -0.1767766952966369,
0.2425078132986360, -0.1178491842064994, -0.1852377813387398,
0.2078674030756363, 0.0842224633480552, -0.2487961816680492,
0.0366826186138406, 0.2309698831278217, -0.1489248261231081,
-0.1585983210409118, 0.2259973232808609, 0.0487725805040321,
-0.2496988640512931, 0.0725711693136160, 0.2144321525000679,
-0.1767766952966368, -0.1285256860483057, 0.2392350839330521,
0.0122669185818552, -0.2451963201008078, 0.1068887733575710,
0.1932526133406840, -0.2008018828701613, -0.0956708580912725,
0.2472941274911952, -0.0245042850823896, -0.2353860162957555,
0.1388925582549012, 0.1678897387117542, -0.2204803160870889,
-0.0607450449758159, 0.1767766952966369,
0.2353860162957552, -0.1585983210409113, -0.1285256860483055,
0.2451963201008076, -0.0366826186138402, -0.2204803160870888,
0.1852377813387395, 0.0956708580912727, -0.2496988640512931,
0.0725711693136152, 0.2008018828701617, -0.2078674030756362,
-0.0607450449758164, 0.2487961816680493, -0.1068887733575703,
-0.1767766952966373, 0.2259973232808605, 0.0245042850823904,
-0.2425078132986364, 0.1388925582548998, 0.1489248261231086,
-0.2392350839330518, 0.0122669185818536, 0.2309698831278218,
-0.1678897387117535, -0.1178491842065003, 0.2472941274911952,
-0.0487725805040305, -0.2144321525000685, 0.1932526133406840,
0.0842224633480565, -0.1767766952966369,
0.2259973232808609, -0.1932526133406842, -0.0607450449758163,
0.2451963201008077, -0.1489248261231082, -0.1178491842064999,
0.2496988640512931, -0.0956708580912720, -0.1678897387117552,
0.2392350839330521, -0.0366826186138397, -0.2078674030756370,
0.2144321525000677, 0.0245042850823912, -0.2353860162957554,
0.1767766952966362, 0.0842224633480563, -0.2487961816680494,
0.1285256860483051, 0.1388925582549012, -0.2472941274911951,
0.0725711693136141, 0.1852377813387411, -0.2309698831278208,
0.0122669185818535, 0.2204803160870894, -0.2008018828701602,
-0.0487725805040342, 0.2425078132986366, -0.1585983210409105,
-0.1068887733575719, 0.1767766952966369,
0.2144321525000680, -0.2204803160870887, 0.0122669185818544,
0.2078674030756364, -0.2259973232808608, 0.0245042850823899,
0.2008018828701614, -0.2309698831278216, 0.0366826186138406,
0.1932526133406845, -0.2353860162957549, 0.0487725805040317,
0.1852377813387398, -0.2392350839330521, 0.0607450449758150,
0.1767766952966373, -0.2425078132986360, 0.0725711693136158,
0.1678897387117554, -0.2451963201008075, 0.0842224633480547,
0.1585983210409126, -0.2472941274911951, 0.0956708580912717,
0.1489248261231087, -0.2487961816680492, 0.1068887733575693,
0.1388925582549013, -0.2496988640512931, 0.1178491842064977,
0.1285256860483052, -0.1767766952966369,
0.2008018828701612, -0.2392350839330522, 0.0842224633480551,
0.1388925582549006, -0.2496988640512931, 0.1585983210409115,
0.0607450449758159, -0.2309698831278217, 0.2144321525000682,
-0.0245042850823899, -0.1852377813387397, 0.2451963201008077,
-0.1068887733575703, -0.1178491842064993, 0.2472941274911952,
-0.1767766952966368, -0.0366826186138411, 0.2204803160870885,
-0.2259973232808608, 0.0487725805040315, 0.1678897387117541,
-0.2487961816680492, 0.1285256860483050, 0.0956708580912718,
-0.2425078132986360, 0.1932526133406840, 0.0122669185818555,
-0.2078674030756362, 0.2353860162957551, -0.0725711693136164,
-0.1489248261231095, 0.1767766952966369,
0.1852377813387397, -0.2487961816680492, 0.1489248261231084,
0.0487725805040320, -0.2144321525000679, 0.2392350839330523,
-0.1068887733575704, -0.0956708580912723, 0.2353860162957551,
-0.2204803160870891, 0.0607450449758160, 0.1388925582549004,
-0.2472941274911952, 0.1932526133406841, -0.0122669185818546,
-0.1767766952966367, 0.2496988640512931, -0.1585983210409120,
-0.0366826186138394, 0.2078674030756356, -0.2425078132986359,
0.1178491842064994, 0.0842224633480548, -0.2309698831278215,
0.2259973232808611, -0.0725711693136165, -0.1285256860483044,
0.2451963201008077, -0.2008018828701612, 0.0245042850823903,
0.1678897387117543, -0.1767766952966369,
0.1678897387117546, -0.2487961816680492, 0.2008018828701611,
-0.0487725805040318, -0.1285256860483055, 0.2392350839330523,
-0.2259973232808606, 0.0956708580912720, 0.0842224633480554,
-0.2204803160870888, 0.2425078132986358, -0.1388925582548999,
-0.0366826186138411, 0.1932526133406851, -0.2496988640512931,
0.1767766952966361, -0.0122669185818527, -0.1585983210409119,
0.2472941274911954, -0.2078674030756361, 0.0607450449758149,
0.1178491842065011, -0.2353860162957555, 0.2309698831278211,
-0.1068887733575685, -0.0725711693136168, 0.2144321525000690,
-0.2451963201008071, 0.1489248261231056, 0.0245042850823908,
-0.1852377813387407, 0.1767766952966369,
0.1489248261231084, -0.2392350839330522, 0.2353860162957551,
-0.1388925582549004, -0.0122669185818546, 0.1585983210409117,
-0.2425078132986361, 0.2309698831278216, -0.1285256860483052,
-0.0245042850823903, 0.1678897387117547, -0.2451963201008078,
0.2259973232808605, -0.1178491842064987, -0.0366826186138411,
0.1767766952966373, -0.2472941274911953, 0.2204803160870885,
-0.1068887733575702, -0.0487725805040324, 0.1852377813387399,
-0.2487961816680492, 0.2144321525000680, -0.0956708580912708,
-0.0607450449758177, 0.1932526133406853, -0.2496988640512931,
0.2078674030756355, -0.0842224633480553, -0.0725711693136169,
0.2008018828701609, -0.1767766952966369,
0.1285256860483054, -0.2204803160870888, 0.2496988640512931,
-0.2078674030756363, 0.1068887733575705, 0.0245042850823902,
-0.1489248261231084, 0.2309698831278217, -0.2472941274911952,
0.1932526133406842, -0.0842224633480549, -0.0487725805040322,
0.1678897387117541, -0.2392350839330523, 0.2425078132986357,
-0.1767766952966368, 0.0607450449758166, 0.0725711693136158,
-0.1852377813387405, 0.2451963201008077, -0.2353860162957554,
0.1585983210409112, -0.0366826186138393, -0.0956708580912727,
0.2008018828701609, -0.2487961816680491, 0.2259973232808603,
-0.1388925582549003, 0.0122669185818551, 0.1178491842065013,
-0.2144321525000687, 0.1767766952966369,
0.1068887733575705, -0.1932526133406842, 0.2425078132986360,
-0.2451963201008076, 0.2008018828701612, -0.1178491842064997,
0.0122669185818547, 0.0956708580912723, -0.1852377813387397,
0.2392350839330522, -0.2472941274911952, 0.2078674030756367,
-0.1285256860483059, 0.0245042850823906, 0.0842224633480547,
-0.1767766952966367, 0.2353860162957551, -0.2487961816680492,
0.2144321525000680, -0.1388925582549004, 0.0366826186138402,
0.0725711693136159, -0.1678897387117549, 0.2309698831278212,
-0.2496988640512932, 0.2204803160870893, -0.1489248261231091,
0.0487725805040329, 0.0607450449758152, -0.1585983210409108,
0.2259973232808606, -0.1767766952966369,
0.0842224633480551, -0.1585983210409115, 0.2144321525000681,
-0.2451963201008077, 0.2472941274911952, -0.2204803160870887,
0.1678897387117543, -0.0956708580912719, 0.0122669185818538,
0.0725711693136165, -0.1489248261231092, 0.2078674030756365,
-0.2425078132986364, 0.2487961816680491, -0.2259973232808601,
0.1767766952966361, -0.1068887733575702, 0.0245042850823887,
0.0607450449758167, -0.1388925582549021, 0.2008018828701619,
-0.2392350839330528, 0.2496988640512929, -0.2309698831278214,
0.1852377813387385, -0.1178491842064969, 0.0366826186138400,
0.0487725805040335, -0.1285256860483076, 0.1932526133406866,
-0.2353860162957556, 0.1767766952966369,
0.0607450449758160, -0.1178491842064995, 0.1678897387117545,
-0.2078674030756364, 0.2353860162957553, -0.2487961816680492,
0.2472941274911952, -0.2309698831278216, 0.2008018828701609,
-0.1585983210409107, 0.1068887733575703, -0.0487725805040324,
-0.0122669185818544, 0.0725711693136157, -0.1285256860483058,
0.1767766952966374, -0.2144321525000685, 0.2392350839330526,
-0.2496988640512932, 0.2451963201008073, -0.2259973232808608,
0.1932526133406839, -0.1489248261231077, 0.0956708580912732,
-0.0366826186138392, -0.0245042850823899, 0.0842224633480567,
-0.1388925582549008, 0.1852377813387413, -0.2204803160870892,
0.2425078132986367, -0.1767766952966369,
0.0366826186138405, -0.0725711693136156, 0.1068887733575707,
-0.1388925582549006, 0.1678897387117546, -0.1932526133406844,
0.2144321525000679, -0.2309698831278217, 0.2425078132986361,
-0.2487961816680492, 0.2496988640512931, -0.2451963201008075,
0.2353860162957552, -0.2204803160870890, 0.2008018828701608,
-0.1767766952966367, 0.1489248261231086, -0.1178491842064986,
0.0842224633480546, -0.0487725805040322, 0.0122669185818534,
0.0245042850823889, -0.0607450449758177, 0.0956708580912736,
-0.1285256860483061, 0.1585983210409115, -0.1852377813387395,
0.2078674030756358, -0.2259973232808617, 0.2392350839330527,
-0.2472941274911954, 0.1767766952966369,
0.0122669185818545, -0.0245042850823901, 0.0366826186138404,
-0.0487725805040320, 0.0607450449758159, -0.0725711693136155,
0.0842224633480545, -0.0956708580912724, 0.1068887733575708,
-0.1178491842064993, 0.1285256860483049, -0.1388925582549004,
0.1489248261231086, -0.1585983210409106, 0.1678897387117541,
-0.1767766952966368, 0.1852377813387399, -0.1932526133406847,
0.2008018828701608, -0.2078674030756362, 0.2144321525000672,
-0.2204803160870882, 0.2259973232808605, -0.2309698831278216,
0.2353860162957553, -0.2392350839330524, 0.2425078132986362,
-0.2451963201008072, 0.2472941274911950, -0.2487961816680491,
0.2496988640512930, -0.1767766952966369,
};
void vp9_fdst(const int16_t *input, int16_t *output, int stride, int size) {
int i, j, k;
double *basis;
int factor = (size == 32) ? 4 : 8;
switch (size) {
case 32:
basis = dstmtx32;
break;
default:
assert(0);
break;
}
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
tmp[i*size+j] = 0;
for (k = 0; k < size; k++) {
tmp[i*size+j] += input[i*stride+k] * basis[k*size+j]; // row
}
}
}
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
tmp2[i*size+j] = 0;
for (k = 0; k < size; k++) {
tmp2[i*size+j] += basis[k*size+i] * tmp[k*size+j]; // col
}
if (tmp2[i*size+j] >= 0)
output[i*size+j] = (int16_t)(tmp2[i*size+j] * factor + 0.5);
else
output[i*size+j] = (int16_t)(tmp2[i*size+j] * factor - 0.5);
}
}
}
#endif
// Note that although we use dct_32_round in dct32_1d computation flow,
// this 2d fdct32x32 for rate-distortion optimization loop is operating
// within 16 bits precision.

View File

@@ -12,6 +12,10 @@
#ifndef VP9_ENCODER_VP9_DCT_H_
#define VP9_ENCODER_VP9_DCT_H_
#if CONFIG_EXT_TX
int block_index;
#endif
void vp9_fht4x4(TX_TYPE tx_type, const int16_t *input, int16_t *output,
int stride);

View File

@@ -526,6 +526,40 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
vp9_update_mv_count(cpi, x, best_mv);
}
#if CONFIG_MASKED_INTERINTER
if (cm->use_masked_interinter &&
cm->reference_mode != SINGLE_REFERENCE &&
is_inter_mode(mbmi->mode) &&
get_mask_bits(bsize) &&
mbmi->ref_frame[1] > INTRA_FRAME) {
++cpi->masked_interinter_counts[bsize][mbmi->use_masked_interinter];
}
#endif
#if CONFIG_INTERINTRA
if (cm->use_interintra &&
is_interintra_allowed(mbmi->sb_type) &&
is_inter_mode(mbmi->mode) &&
(mbmi->ref_frame[1] <= INTRA_FRAME)) {
if (mbmi->ref_frame[1] == INTRA_FRAME) {
++cpi->y_mode_count[size_group_lookup[mbmi->sb_type]]
[mbmi->interintra_mode];
#if SEPARATE_INTERINTRA_UV
++cpi->y_uv_mode_count[mbmi->interintra_mode][mbmi->interintra_uv_mode];
#endif
++cpi->interintra_count[mbmi->sb_type][1];
#if CONFIG_MASKED_INTERINTRA
if (cm->use_masked_interintra &&
get_mask_bits_interintra(mbmi->sb_type))
++cpi->masked_interintra_count[mbmi->sb_type]
[mbmi->use_masked_interintra];
#endif
} else {
++cpi->interintra_count[mbmi->sb_type][0];
}
}
#endif
if (cm->mcomp_filter_type == SWITCHABLE && is_inter_mode(mbmi->mode)) {
const int ctx = vp9_get_pred_context_switchable_interp(xd);
++cm->counts.switchable_interp[ctx][mbmi->interp_filter];
@@ -2005,6 +2039,10 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
xd->mi_8x8[0]->mbmi.mode = DC_PRED;
xd->mi_8x8[0]->mbmi.uv_mode = DC_PRED;
#if CONFIG_FILTERINTRA
xd->mi_8x8[0]->mbmi.filterbit = 0;
xd->mi_8x8[0]->mbmi.uv_filterbit = 0;
#endif
vp9_zero(cpi->y_mode_count);
vp9_zero(cpi->y_uv_mode_count);
@@ -2017,6 +2055,25 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
vp9_zero(cm->counts.tx);
vp9_zero(cm->counts.mbskip);
#if CONFIG_FILTERINTRA
vp9_zero(cm->counts.filterintra);
#endif
#if CONFIG_MASKED_INTERINTER
vp9_zero(cpi->masked_interinter_counts);
vp9_zero(cpi->masked_interinter_select_counts);
#endif
#if CONFIG_INTERINTRA
vp9_zero(cpi->interintra_count);
vp9_zero(cpi->interintra_select_count);
#if CONFIG_MASKED_INTERINTRA
vp9_zero(cpi->masked_interintra_count);
vp9_zero(cpi->masked_interintra_select_count);
#endif
#endif
#if CONFIG_EXT_TX
vp9_zero(cm->counts.ext_tx);
#endif
// Note: this memset assumes above_context[0], [1] and [2]
// are allocated as part of the same buffer.
vpx_memset(cpi->above_context[0], 0,
@@ -2069,6 +2126,9 @@ static void encode_frame_internal(VP9_COMP *cpi) {
#endif
vp9_zero(cm->counts.switchable_interp);
#if CONFIG_EXT_TX
vp9_zero(cm->counts.ext_tx);
#endif
vp9_zero(cpi->tx_stepdown_count);
xd->mi_8x8 = cm->mi_grid_visible;
@@ -2488,8 +2548,19 @@ static void sum_intra_stats(VP9_COMP *cpi, const MODE_INFO *mi) {
const MB_PREDICTION_MODE y_mode = mi->mbmi.mode;
const MB_PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
const BLOCK_SIZE bsize = mi->mbmi.sb_type;
#if CONFIG_FILTERINTRA
const int uv_fbit = mi->mbmi.uv_filterbit;
int fbit = mi->mbmi.filterbit;
#endif
++cpi->y_uv_mode_count[y_mode][uv_mode];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(uv_mode) &&
is_filter_enabled(get_uv_tx_size(&(mi->mbmi))))
++cpi->common.counts.filterintra[get_uv_tx_size(&(mi->mbmi))]
[uv_mode][uv_fbit];
#endif
if (bsize < BLOCK_8X8) {
int idx, idy;
@@ -2497,9 +2568,24 @@ static void sum_intra_stats(VP9_COMP *cpi, const MODE_INFO *mi) {
const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
for (idy = 0; idy < 2; idy += num_4x4_blocks_high)
for (idx = 0; idx < 2; idx += num_4x4_blocks_wide)
#if CONFIG_FILTERINTRA
{
#endif
++cpi->y_mode_count[0][mi->bmi[idy * 2 + idx].as_mode];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[idy * 2 + idx].as_mode)) {
fbit = mi->b_filter_info[idy * 2 + idx];
++cpi->common.counts.filterintra[0][mi->bmi[idy * 2 + idx].as_mode]
[fbit];
}
}
#endif
} else {
++cpi->y_mode_count[size_group_lookup[bsize]][y_mode];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(y_mode) && is_filter_enabled(mi->mbmi.tx_size))
++cpi->common.counts.filterintra[mi->mbmi.tx_size][y_mode][fbit];
#endif
}
}
@@ -2645,5 +2731,19 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
mi_8x8[mis * y + x]->mbmi.tx_size = tx_size;
}
#if CONFIG_EXT_TX
#if CONFIG_EXT_TX_DST32
if (is_inter_block(mbmi) &&
!mbmi->skip_coeff &&
!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
#else
if (is_inter_block(mbmi) && mbmi->tx_size <= TX_16X16 &&
!mbmi->skip_coeff &&
!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
#endif
++cm->counts.ext_tx[mbmi->ext_txfrm];
}
#endif
}
}

View File

@@ -25,6 +25,8 @@
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_tokenize.h"
void vp9_setup_interp_filters(MACROBLOCKD *xd,
INTERPOLATION_TYPE mcomp_filter_type,
VP9_COMMON *cm) {
@@ -359,6 +361,7 @@ static void optimize_init_b(int plane, BLOCK_SIZE bsize,
num_4x4_w, num_4x4_h);
}
#if !CONFIG_EXT_TX
void vp9_xform_quant(int plane, int block, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, void *arg) {
struct encode_b_args* const args = arg;
@@ -417,7 +420,161 @@ void vp9_xform_quant(int plane, int block, BLOCK_SIZE plane_bsize,
assert(0);
}
}
#else
void vp9_xform_quant(int plane, int block, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, void *arg) {
struct encode_b_args* const args = arg;
MACROBLOCK* const x = args->x;
MACROBLOCKD* const xd = &x->e_mbd;
struct macroblock_plane *const p = &x->plane[plane];
struct macroblockd_plane *const pd = &xd->plane[plane];
int16_t *coeff = BLOCK_OFFSET(p->coeff, block);
int16_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
int16_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
const scan_order *scan_order;
uint16_t *eob = &p->eobs[block];
const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
int i, j;
int16_t *src_diff;
MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
if (plane == 0) {
switch (mbmi->ext_txfrm) {
case NORM:
switch (tx_size) {
case TX_32X32:
scan_order = &vp9_default_scan_orders[TX_32X32];
if (x->use_lp32x32fdct)
vp9_fdct32x32_rd(src_diff, coeff, diff_stride);
else
vp9_fdct32x32(src_diff, coeff, diff_stride);
vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_16X16:
scan_order = &vp9_default_scan_orders[TX_16X16];
vp9_fdct16x16(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_8X8:
scan_order = &vp9_default_scan_orders[TX_8X8];
vp9_fdct8x8(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_4X4:
scan_order = &vp9_default_scan_orders[TX_4X4];
x->fwd_txm4x4(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
default:
assert(0);
}
break;
case ALT:
switch (tx_size) {
case TX_32X32:
scan_order = &vp9_default_scan_orders[TX_32X32];
#if CONFIG_EXT_TX_DST32
vp9_fdst(src_diff, coeff, diff_stride, 32);
#else
if (x->use_lp32x32fdct)
vp9_fdct32x32_rd(src_diff, coeff, diff_stride);
else
vp9_fdct32x32(src_diff, coeff, diff_stride);
#endif
vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_16X16:
scan_order = &vp9_scan_orders[TX_16X16][ADST_ADST];
vp9_fht16x16(ADST_ADST, src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_8X8:
scan_order = &vp9_scan_orders[TX_8X8][ADST_ADST];
vp9_fht8x8(ADST_ADST, src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_4X4:
scan_order = &vp9_scan_orders[TX_4X4][ADST_ADST];
vp9_fht4x4(ADST_ADST, src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
default:
assert(0);
}
break;
default:
assert(0);
}
} else {
switch (tx_size) {
case TX_32X32:
scan_order = &vp9_default_scan_orders[TX_32X32];
if (x->use_lp32x32fdct)
vp9_fdct32x32_rd(src_diff, coeff, diff_stride);
else
vp9_fdct32x32(src_diff, coeff, diff_stride);
vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob, scan_order->scan,
scan_order->iscan);
break;
case TX_16X16:
scan_order = &vp9_default_scan_orders[TX_16X16];
vp9_fdct16x16(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_8X8:
scan_order = &vp9_default_scan_orders[TX_8X8];
vp9_fdct8x8(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_4X4:
scan_order = &vp9_default_scan_orders[TX_4X4];
x->fwd_txm4x4(src_diff, coeff, diff_stride);
vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
default:
assert(0);
}
}
}
#endif
#if !CONFIG_EXT_TX
static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, void *arg) {
struct encode_b_args *const args = arg;
@@ -474,6 +631,115 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
assert(0 && "Invalid transform size");
}
}
#else
static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, void *arg) {
struct encode_b_args *const args = arg;
MACROBLOCK *const x = args->x;
MACROBLOCKD *const xd = &x->e_mbd;
struct optimize_ctx *const ctx = args->ctx;
struct macroblock_plane *const p = &x->plane[plane];
struct macroblockd_plane *const pd = &xd->plane[plane];
int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
int i, j;
uint8_t *dst;
MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
// TODO(jingning): per transformed block zero forcing only enabled for
// luma component. will integrate chroma components as well.
if (x->zcoeff_blk[tx_size][block] && plane == 0) {
p->eobs[block] = 0;
ctx->ta[plane][i] = 0;
ctx->tl[plane][j] = 0;
return;
}
if (!x->skip_recode)
vp9_xform_quant(plane, block, plane_bsize, tx_size, arg);
if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
vp9_optimize_b(plane, block, plane_bsize, tx_size, x, ctx);
} else {
ctx->ta[plane][i] = p->eobs[block] > 0;
ctx->tl[plane][j] = p->eobs[block] > 0;
}
if (x->skip_encode || p->eobs[block] == 0)
return;
if (plane == PLANE_TYPE_Y) {
switch (mbmi->ext_txfrm) {
case NORM:
switch (tx_size) {
case TX_32X32:
vp9_idct32x32_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
case TX_16X16:
vp9_idct16x16_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
case TX_8X8:
vp9_idct8x8_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
case TX_4X4:
xd->itxm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
default:
assert(0 && "Invalid transform size");
}
break;
case ALT:
switch (tx_size) {
case TX_32X32:
#if CONFIG_EXT_TX_DST32
vp9_idst_add(dqcoeff, dst, pd->dst.stride, p->eobs[block], 32);
#else
vp9_idct32x32_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
#endif
break;
case TX_16X16:
vp9_iht16x16_add(ADST_ADST, dqcoeff, dst, pd->dst.stride,
p->eobs[block]);
break;
case TX_8X8:
vp9_iht8x8_add(ADST_ADST, dqcoeff, dst, pd->dst.stride,
p->eobs[block]);
break;
case TX_4X4:
vp9_iht4x4_add(ADST_ADST, dqcoeff, dst, pd->dst.stride,
p->eobs[block]);
break;
default:
assert(0 && "Invalid transform size");
}
break;
default:
assert(0 && "Invalid ext transform type");
}
} else {
switch (tx_size) {
case TX_32X32:
vp9_idct32x32_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
case TX_16X16:
vp9_idct16x16_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
case TX_8X8:
vp9_idct8x8_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
case TX_4X4:
// this is like vp9_short_idct4x4 but has a special case around eob<=1
// which is significant (not just an optimization) for the lossless
// case.
xd->itxm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
default:
assert(0 && "Invalid transform size");
}
}
}
#endif
static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, void *arg) {
@@ -485,6 +751,10 @@ static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
int i, j;
uint8_t *dst;
#if CONFIG_EXT_TX
MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
mbmi->ext_txfrm = NORM;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
@@ -539,6 +809,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
const scan_order *scan_order;
TX_TYPE tx_type;
MB_PREDICTION_MODE mode;
#if CONFIG_FILTERINTRA
int fbit = 0;
#endif
const int bwl = b_width_log2(plane_bsize);
const int diff_stride = 4 * (1 << bwl);
uint8_t *src, *dst;
@@ -552,12 +825,21 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
// if (x->optimize)
// vp9_optimize_b(plane, block, plane_bsize, tx_size, x, args->ctx);
#if CONFIG_FILTERINTRA
if (mbmi->sb_type < BLOCK_8X8 && plane == 0)
fbit = xd->mi_8x8[0]->b_filter_info[block];
else
fbit = plane == 0 ? mbmi->filterbit : mbmi->uv_filterbit;
#endif
switch (tx_size) {
case TX_32X32:
scan_order = &vp9_default_scan_orders[TX_32X32];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 6, bwl, TX_32X32, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? p->src.stride : pd->dst.stride,
dst, pd->dst.stride, i, j, plane);
@@ -581,6 +863,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
scan_order = &vp9_scan_orders[TX_16X16][tx_type];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 4, bwl, TX_16X16, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? p->src.stride : pd->dst.stride,
dst, pd->dst.stride, i, j, plane);
@@ -601,6 +886,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
scan_order = &vp9_scan_orders[TX_8X8][tx_type];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 2, bwl, TX_8X8, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? p->src.stride : pd->dst.stride,
dst, pd->dst.stride, i, j, plane);
@@ -625,6 +913,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block, bwl, TX_4X4, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? p->src.stride : pd->dst.stride,
dst, pd->dst.stride, i, j, plane);

View File

@@ -544,7 +544,6 @@ void vp9_first_pass(VP9_COMP *cpi) {
}
x->skip_recode = 0;
// Initialise the MV cost table to the defaults
// if( cm->current_video_frame == 0)
// if ( 0 )

View File

@@ -150,7 +150,13 @@ static int find_best_16x16_intra(VP9_COMP *cpi,
unsigned int err;
xd->mi_8x8[0]->mbmi.mode = mode;
#if CONFIG_FILTERINTRA
xd->mi_8x8[0]->mbmi.filterbit = 0;
#endif
vp9_predict_intra_block(xd, 0, 2, TX_16X16, mode,
#if CONFIG_FILTERINTRA
0,
#endif
x->plane[0].src.buf, x->plane[0].src.stride,
xd->plane[0].dst.buf, xd->plane[0].dst.stride,
0, 0, 0);

View File

@@ -2225,3 +2225,531 @@ int vp9_refining_search_8p_c(MACROBLOCK *x,
return INT_MAX;
}
}
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
#define MVC(r, c) \
(mvcost ? \
((mvjcost[((r) != rr) * 2 + ((c) != rc)] + \
mvcost[0][((r) - rr)] + mvcost[1][((c) - rc)]) * \
error_per_bit + 4096) >> 13 : 0)
#define SP(x) (((x) & 7) << 1) // convert motion vector component to offset
// for svf calc
#define IFMVCV(r, c, s, e) \
if (c >= minc && c <= maxc && r >= minr && r <= maxr) \
s \
else \
e;
/* pointer to predictor base of a motion vector */
#define PRE(r, c) (y + (((r) >> 3) * y_stride + ((c) >> 3) -(offset)))
/* returns subpixel variance error function */
#define DIST(r, c) \
vfp->msvf(PRE(r, c), y_stride, SP(c), SP(r), z, src_stride, \
mask, mask_stride, &sse)
/* checks if (r, c) has better score than previous best */
#define CHECK_BETTER(v, r, c) \
IFMVCV(r, c, { \
thismse = (DIST(r, c)); \
if ((v = MVC(r, c) + thismse) < besterr) { \
besterr = v; \
br = r; \
bc = c; \
*distortion = thismse; \
*sse1 = sse; \
} \
}, \
v = INT_MAX;)
int vp9_find_best_masked_sub_pixel_iterative(MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *bestmv, const MV *ref_mv,
int allow_hp,
int error_per_bit,
const vp9_variance_fn_ptr_t *vfp,
int forced_stop,
int iters_per_step,
int *mvjcost, int *mvcost[2],
int *distortion,
unsigned int *sse1,
int is_second) {
uint8_t *z = x->plane[0].src.buf;
int src_stride = x->plane[0].src.stride;
MACROBLOCKD *xd = &x->e_mbd;
unsigned int besterr = INT_MAX;
unsigned int sse;
unsigned int whichdir;
unsigned int halfiters = iters_per_step;
unsigned int quarteriters = iters_per_step;
unsigned int eighthiters = iters_per_step;
int thismse;
const int y_stride = xd->plane[0].pre[is_second].stride;
const int offset = bestmv->row * y_stride + bestmv->col;
uint8_t *y = xd->plane[0].pre[is_second].buf + offset;
int rr = ref_mv->row;
int rc = ref_mv->col;
int br = bestmv->row * 8;
int bc = bestmv->col * 8;
int hstep = 4;
const int minc = MAX(x->mv_col_min * 8, ref_mv->col - MV_MAX);
const int maxc = MIN(x->mv_col_max * 8, ref_mv->col + MV_MAX);
const int minr = MAX(x->mv_row_min * 8, ref_mv->row - MV_MAX);
const int maxr = MIN(x->mv_row_max * 8, ref_mv->row + MV_MAX);
int tr = br;
int tc = bc;
// central mv
bestmv->row <<= 3;
bestmv->col <<= 3;
// calculate central point error
besterr = vfp->mvf(y, y_stride, z, src_stride, mask, mask_stride, sse1);
*distortion = besterr;
besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit);
while (halfiters--) {
// 1/2 pel
FIRST_LEVEL_CHECKS;
// no reason to check the same one again.
if (tr == br && tc == bc)
break;
tr = br;
tc = bc;
}
// Note forced_stop: 0 - full, 1 - qtr only, 2 - half only
if (forced_stop != 2) {
hstep >>= 1;
while (quarteriters--) {
FIRST_LEVEL_CHECKS;
// no reason to check the same one again.
if (tr == br && tc == bc)
break;
tr = br;
tc = bc;
}
}
if (allow_hp && vp9_use_mv_hp(ref_mv) && forced_stop == 0) {
hstep >>= 1;
while (eighthiters--) {
FIRST_LEVEL_CHECKS;
// no reason to check the same one again.
if (tr == br && tc == bc)
break;
tr = br;
tc = bc;
}
}
bestmv->row = br;
bestmv->col = bc;
if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
(abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
return INT_MAX;
return besterr;
}
int vp9_find_best_masked_sub_pixel_tree(MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *bestmv, const MV *ref_mv,
int allow_hp,
int error_per_bit,
const vp9_variance_fn_ptr_t *vfp,
int forced_stop,
int iters_per_step,
int *mvjcost, int *mvcost[2],
int *distortion,
unsigned int *sse1,
int is_second) {
uint8_t *z = x->plane[0].src.buf;
const int src_stride = x->plane[0].src.stride;
MACROBLOCKD *xd = &x->e_mbd;
unsigned int besterr = INT_MAX;
unsigned int sse;
unsigned int whichdir;
int thismse;
unsigned int halfiters = iters_per_step;
unsigned int quarteriters = iters_per_step;
unsigned int eighthiters = iters_per_step;
const int y_stride = xd->plane[0].pre[is_second].stride;
const int offset = bestmv->row * y_stride + bestmv->col;
uint8_t *y = xd->plane[0].pre[is_second].buf + offset;
int rr = ref_mv->row;
int rc = ref_mv->col;
int br = bestmv->row * 8;
int bc = bestmv->col * 8;
int hstep = 4;
const int minc = MAX(x->mv_col_min * 8, ref_mv->col - MV_MAX);
const int maxc = MIN(x->mv_col_max * 8, ref_mv->col + MV_MAX);
const int minr = MAX(x->mv_row_min * 8, ref_mv->row - MV_MAX);
const int maxr = MIN(x->mv_row_max * 8, ref_mv->row + MV_MAX);
int tr = br;
int tc = bc;
// central mv
bestmv->row *= 8;
bestmv->col *= 8;
// calculate central point error
besterr = vfp->mvf(y, y_stride, z, src_stride, mask, mask_stride, sse1);
*distortion = besterr;
besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit);
// 1/2 pel
FIRST_LEVEL_CHECKS;
if (halfiters > 1) {
SECOND_LEVEL_CHECKS;
}
tr = br;
tc = bc;
// Note forced_stop: 0 - full, 1 - qtr only, 2 - half only
if (forced_stop != 2) {
hstep >>= 1;
FIRST_LEVEL_CHECKS;
if (quarteriters > 1) {
SECOND_LEVEL_CHECKS;
}
tr = br;
tc = bc;
}
if (allow_hp && vp9_use_mv_hp(ref_mv) && forced_stop == 0) {
hstep >>= 1;
FIRST_LEVEL_CHECKS;
if (eighthiters > 1) {
SECOND_LEVEL_CHECKS;
}
tr = br;
tc = bc;
}
bestmv->row = br;
bestmv->col = bc;
if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
(abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
return INT_MAX;
return besterr;
}
#undef MVC
#undef SP
#undef IFMVCV
#undef PRE
#undef DIST
#undef CHECK_BETTER
int vp9_masked_refining_search_sad_c(MACROBLOCK *x,
uint8_t * mask, int mask_stride,
MV *ref_mv, int error_per_bit,
int search_range,
vp9_variance_fn_ptr_t *fn_ptr,
int *mvjcost, int *mvcost[2],
const MV *center_mv, int is_second) {
const MACROBLOCKD* const xd = &x->e_mbd;
MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}};
int i, j;
int this_row_offset, this_col_offset;
int what_stride = x->plane[0].src.stride;
int in_what_stride = xd->plane[0].pre[is_second].stride;
uint8_t *what = x->plane[0].src.buf;
uint8_t *best_address = xd->plane[0].pre[is_second].buf +
(ref_mv->row * xd->plane[0].pre[is_second].stride) +
ref_mv->col;
uint8_t *check_here;
unsigned int thissad;
MV this_mv;
unsigned int bestsad = INT_MAX;
MV fcenter_mv;
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
fcenter_mv.row = center_mv->row >> 3;
fcenter_mv.col = center_mv->col >> 3;
bestsad = fn_ptr->msdf(what, what_stride, best_address,
in_what_stride, mask, mask_stride, 0x7fffffff) +
mvsad_err_cost(ref_mv, &fcenter_mv,
mvjsadcost, mvsadcost, error_per_bit);
for (i = 0; i < search_range; i++) {
int best_site = -1;
for (j = 0; j < 4; j++) {
this_row_offset = ref_mv->row + neighbors[j].row;
this_col_offset = ref_mv->col + neighbors[j].col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
(this_row_offset > x->mv_row_min) &&
(this_row_offset < x->mv_row_max)) {
check_here = (neighbors[j].row) * in_what_stride + neighbors[j].col +
best_address;
thissad = fn_ptr->msdf(what, what_stride, check_here, in_what_stride,
mask, mask_stride, bestsad);
if (thissad < bestsad) {
this_mv.row = this_row_offset;
this_mv.col = this_col_offset;
thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, error_per_bit);
if (thissad < bestsad) {
bestsad = thissad;
best_site = j;
}
}
}
}
if (best_site == -1) {
break;
} else {
ref_mv->row += neighbors[best_site].row;
ref_mv->col += neighbors[best_site].col;
best_address += (neighbors[best_site].row) * in_what_stride +
neighbors[best_site].col;
}
}
this_mv.row = ref_mv->row * 8;
this_mv.col = ref_mv->col * 8;
if (bestsad < INT_MAX)
return fn_ptr->mvf(what, what_stride, best_address, in_what_stride,
mask, mask_stride,
(unsigned int *)(&thissad)) +
mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
else
return INT_MAX;
}
int vp9_masked_diamond_search_sad_c(MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *ref_mv, MV *best_mv,
int search_param, int sad_per_bit,
int *num00, vp9_variance_fn_ptr_t *fn_ptr,
int *mvjcost, int *mvcost[2],
const MV *center_mv, int is_second) {
int i, j, step;
const MACROBLOCKD* const xd = &x->e_mbd;
uint8_t *what = x->plane[0].src.buf;
int what_stride = x->plane[0].src.stride;
uint8_t *in_what;
int in_what_stride = xd->plane[0].pre[is_second].stride;
uint8_t *best_address;
int tot_steps;
MV this_mv;
int bestsad = INT_MAX;
int best_site = 0;
int last_site = 0;
int ref_row, ref_col;
int this_row_offset, this_col_offset;
search_site *ss;
uint8_t *check_here;
int thissad;
MV fcenter_mv;
int *mvjsadcost = x->nmvjointsadcost;
int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
fcenter_mv.row = center_mv->row >> 3;
fcenter_mv.col = center_mv->col >> 3;
clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
ref_row = ref_mv->row;
ref_col = ref_mv->col;
*num00 = 0;
best_mv->row = ref_row;
best_mv->col = ref_col;
// Work out the start point for the search
in_what = (uint8_t *)(xd->plane[0].pre[is_second].buf +
ref_row * in_what_stride + ref_col);
best_address = in_what;
// Check the starting position
bestsad = fn_ptr->msdf(what, what_stride, in_what, in_what_stride,
mask, mask_stride, 0x7fffffff)
+ mvsad_err_cost(best_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
// search_param determines the length of the initial step and hence the number
// of iterations
// 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 =
// (MAX_FIRST_STEP/4) pel... etc.
ss = &x->ss[search_param * x->searches_per_step];
tot_steps = (x->ss_count / x->searches_per_step) - search_param;
i = 1;
for (step = 0; step < tot_steps; step++) {
for (j = 0; j < x->searches_per_step; j++) {
// Trap illegal vectors
this_row_offset = best_mv->row + ss[i].mv.row;
this_col_offset = best_mv->col + ss[i].mv.col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
(this_row_offset > x->mv_row_min) &&
(this_row_offset < x->mv_row_max)) {
check_here = ss[i].offset + best_address;
thissad = fn_ptr->msdf(what, what_stride, check_here, in_what_stride,
mask, mask_stride, bestsad);
if (thissad < bestsad) {
this_mv.row = this_row_offset;
this_mv.col = this_col_offset;
thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
bestsad = thissad;
best_site = i;
}
}
}
i++;
}
if (best_site != last_site) {
best_mv->row += ss[best_site].mv.row;
best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
last_site = best_site;
#if defined(NEW_DIAMOND_SEARCH)
while (1) {
this_row_offset = best_mv->row + ss[best_site].mv.row;
this_col_offset = best_mv->col + ss[best_site].mv.col;
if ((this_col_offset > x->mv_col_min) &&
(this_col_offset < x->mv_col_max) &&
(this_row_offset > x->mv_row_min) &&
(this_row_offset < x->mv_row_max)) {
check_here = ss[best_site].offset + best_address;
thissad = fn_ptr->msdf(what, what_stride, check_here, in_what_stride,
mask, mask_stride, bestsad);
if (thissad < bestsad) {
this_mv.row = this_row_offset;
this_mv.col = this_col_offset;
thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
mvjsadcost, mvsadcost, sad_per_bit);
if (thissad < bestsad) {
bestsad = thissad;
best_mv->row += ss[best_site].mv.row;
best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
continue;
}
}
}
break;
};
#endif
} else if (best_address == in_what) {
(*num00)++;
}
}
this_mv.row = best_mv->row * 8;
this_mv.col = best_mv->col * 8;
if (bestsad == INT_MAX)
return INT_MAX;
return fn_ptr->mvf(what, what_stride, best_address, in_what_stride,
mask, mask_stride, (unsigned int *)(&thissad)) +
mv_err_cost(&this_mv, center_mv,
mvjcost, mvcost, x->errorperbit);
}
int vp9_masked_full_pixel_diamond(VP9_COMP *cpi, MACROBLOCK *x,
uint8_t *mask, int mask_stride,
int_mv *mvp_full, int step_param,
int sadpb, int further_steps,
int do_refine, vp9_variance_fn_ptr_t *fn_ptr,
int_mv *ref_mv, int_mv *dst_mv,
int is_second) {
int_mv temp_mv;
int thissme, n, num00;
int bestsme = vp9_masked_diamond_search_sad_c(x, mask, mask_stride,
&mvp_full->as_mv, &temp_mv.as_mv,
step_param, sadpb, &num00,
fn_ptr, x->nmvjointcost,
x->mvcost, &ref_mv->as_mv,
is_second);
dst_mv->as_int = temp_mv.as_int;
n = num00;
num00 = 0;
/* If there won't be more n-step search, check to see if refining search is
* needed. */
if (n > further_steps)
do_refine = 0;
while (n < further_steps) {
n++;
if (num00) {
num00--;
} else {
thissme = vp9_masked_diamond_search_sad_c(x, mask, mask_stride,
&mvp_full->as_mv, &temp_mv.as_mv,
step_param + n, sadpb, &num00,
fn_ptr, x->nmvjointcost, x->mvcost,
&ref_mv->as_mv, is_second);
/* check to see if refining search is needed. */
if (num00 > (further_steps - n))
do_refine = 0;
if (thissme < bestsme) {
bestsme = thissme;
dst_mv->as_int = temp_mv.as_int;
}
}
}
/* final 1-away diamond refining search */
if (do_refine == 1) {
int search_range = 8;
int_mv best_mv;
best_mv.as_int = dst_mv->as_int;
thissme = vp9_masked_refining_search_sad_c(x, mask, mask_stride,
&best_mv.as_mv, sadpb, search_range,
fn_ptr, x->nmvjointcost, x->mvcost,
&ref_mv->as_mv, is_second);
if (thissme < bestsme) {
bestsme = thissme;
dst_mv->as_int = best_mv.as_int;
}
}
return bestsme;
}
#endif

View File

@@ -129,4 +129,38 @@ int vp9_refining_search_8p_c(MACROBLOCK *x,
int *mvjcost, int *mvcost[2],
const MV *center_mv, const uint8_t *second_pred,
int w, int h);
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
int vp9_find_best_masked_sub_pixel_iterative(MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *bestmv, const MV *ref_mv,
int allow_hp,
int error_per_bit,
const vp9_variance_fn_ptr_t *vfp,
int forced_stop,
int iters_per_step,
int *mvjcost, int *mvcost[2],
int *distortion,
unsigned int *sse1,
int is_second);
int vp9_find_best_masked_sub_pixel_tree(MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *bestmv, const MV *ref_mv,
int allow_hp,
int error_per_bit,
const vp9_variance_fn_ptr_t *vfp,
int forced_stop,
int iters_per_step,
int *mvjcost, int *mvcost[2],
int *distortion,
unsigned int *sse1,
int is_second);
int vp9_masked_full_pixel_diamond(
struct VP9_COMP *cpi, MACROBLOCK *x, uint8_t *mask, int mask_stride,
int_mv *mvp_full, int step_param, int sadpb, int further_steps,
int do_refine, vp9_variance_fn_ptr_t *fn_ptr, int_mv *ref_mv,
int_mv *dst_mv, int is_second);
#endif
#endif // VP9_ENCODER_VP9_MCOMP_H_

View File

@@ -521,24 +521,60 @@ static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode) {
sf->thresh_mult[THR_D207_PRED] += 2500;
sf->thresh_mult[THR_D63_PRED] += 2500;
#if CONFIG_INTERINTRA
sf->thresh_mult[THR_COMP_INTERINTRA_ZEROL ] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_ZEROG ] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_ZEROA ] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTL] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTG] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTA] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARL ] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARG ] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARA ] += 1500;
sf->thresh_mult[THR_COMP_INTERINTRA_NEWL ] += 2000;
sf->thresh_mult[THR_COMP_INTERINTRA_NEWG ] += 2000;
sf->thresh_mult[THR_COMP_INTERINTRA_NEWA ] += 2000;
#endif
/* disable frame modes if flags not set */
if (!(cpi->ref_frame_flags & VP9_LAST_FLAG)) {
sf->thresh_mult[THR_NEWMV ] = INT_MAX;
sf->thresh_mult[THR_NEARESTMV] = INT_MAX;
sf->thresh_mult[THR_ZEROMV ] = INT_MAX;
sf->thresh_mult[THR_NEARMV ] = INT_MAX;
#if CONFIG_INTERINTRA
sf->thresh_mult[THR_COMP_INTERINTRA_ZEROL ] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTL] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARL ] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEWL ] = INT_MAX;
#endif
}
if (!(cpi->ref_frame_flags & VP9_GOLD_FLAG)) {
sf->thresh_mult[THR_NEARESTG ] = INT_MAX;
sf->thresh_mult[THR_ZEROG ] = INT_MAX;
sf->thresh_mult[THR_NEARG ] = INT_MAX;
sf->thresh_mult[THR_NEWG ] = INT_MAX;
#if CONFIG_INTERINTRA
sf->thresh_mult[THR_COMP_INTERINTRA_ZEROG ] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTG] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARG ] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEWG ] = INT_MAX;
#endif
}
if (!(cpi->ref_frame_flags & VP9_ALT_FLAG)) {
sf->thresh_mult[THR_NEARESTA ] = INT_MAX;
sf->thresh_mult[THR_ZEROA ] = INT_MAX;
sf->thresh_mult[THR_NEARA ] = INT_MAX;
sf->thresh_mult[THR_NEWA ] = INT_MAX;
#if CONFIG_INTERINTRA
sf->thresh_mult[THR_COMP_INTERINTRA_ZEROA ] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTA] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEARA ] = INT_MAX;
sf->thresh_mult[THR_COMP_INTERINTRA_NEWA ] = INT_MAX;
#endif
}
if ((cpi->ref_frame_flags & (VP9_LAST_FLAG | VP9_ALT_FLAG)) !=
@@ -1760,6 +1796,37 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
vp9_sub_pixel_avg_variance4x4, NULL, NULL, NULL,
vp9_sad4x4x3, vp9_sad4x4x8, vp9_sad4x4x4d)
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
#define MBFP(BT, MSDF, MVF, MSVF) \
cpi->fn_ptr[BT].msdf = MSDF; \
cpi->fn_ptr[BT].mvf = MVF; \
cpi->fn_ptr[BT].msvf = MSVF;
MBFP(BLOCK_64X64, vp9_masked_sad64x64, vp9_masked_variance64x64,
vp9_masked_sub_pixel_variance64x64)
MBFP(BLOCK_64X32, vp9_masked_sad64x32, vp9_masked_variance64x32,
vp9_masked_sub_pixel_variance64x32)
MBFP(BLOCK_32X64, vp9_masked_sad32x64, vp9_masked_variance32x64,
vp9_masked_sub_pixel_variance32x64)
MBFP(BLOCK_32X32, vp9_masked_sad32x32, vp9_masked_variance32x32,
vp9_masked_sub_pixel_variance32x32)
MBFP(BLOCK_32X16, vp9_masked_sad32x16, vp9_masked_variance32x16,
vp9_masked_sub_pixel_variance32x16)
MBFP(BLOCK_16X32, vp9_masked_sad16x32, vp9_masked_variance16x32,
vp9_masked_sub_pixel_variance16x32)
MBFP(BLOCK_16X16, vp9_masked_sad16x16, vp9_masked_variance16x16,
vp9_masked_sub_pixel_variance16x16)
MBFP(BLOCK_16X8, vp9_masked_sad16x8, vp9_masked_variance16x8,
vp9_masked_sub_pixel_variance16x8)
MBFP(BLOCK_8X16, vp9_masked_sad8x16, vp9_masked_variance8x16,
vp9_masked_sub_pixel_variance8x16)
MBFP(BLOCK_8X8, vp9_masked_sad8x8, vp9_masked_variance8x8,
vp9_masked_sub_pixel_variance8x8)
MBFP(BLOCK_4X4, vp9_masked_sad4x4, vp9_masked_variance4x4,
vp9_masked_sub_pixel_variance4x4)
#endif
cpi->full_search_sad = vp9_full_search_sad;
cpi->diamond_search_sad = vp9_diamond_search_sad;
cpi->refining_search_sad = vp9_refining_search_sad;
@@ -2234,6 +2301,44 @@ void vp9_write_yuv_rec_frame(VP9_COMMON *cm) {
}
#endif
#if CONFIG_MASKED_INTERINTER
static void select_masked_interinter_mode(VP9_COMP *cpi) {
static const double threshold = 1/128.0;
VP9_COMMON *cm = &cpi->common;
int sum = cpi->masked_interinter_select_counts[1] +
cpi->masked_interinter_select_counts[0];
if (sum) {
double fraction = (double) cpi->masked_interinter_select_counts[1] / sum;
cm->use_masked_interinter = (fraction > threshold);
}
}
#endif
#if CONFIG_INTERINTRA
static void select_interintra_mode(VP9_COMP *cpi) {
static const double threshold = 0.007;
VP9_COMMON *cm = &cpi->common;
int sum = cpi->interintra_select_count[1] + cpi->interintra_select_count[0];
if (sum) {
double fraction = (double)cpi->interintra_select_count[1] / (double)sum;
cm->use_interintra = (fraction > threshold);
}
}
#if CONFIG_MASKED_INTERINTRA
static void select_masked_interintra_mode(VP9_COMP *cpi) {
static const double threshold = 1/100.0;
VP9_COMMON *cm = &cpi->common;
int sum = cpi->masked_interintra_select_count[1] +
cpi->masked_interintra_select_count[0];
if (sum) {
double fraction = (double) cpi->masked_interintra_select_count[1] / sum;
cm->use_masked_interintra = (fraction > threshold);
}
}
#endif
#endif
static void scale_and_extend_frame(YV12_BUFFER_CONFIG *src_fb,
YV12_BUFFER_CONFIG *dst_fb) {
const int in_w = src_fb->y_crop_width;
@@ -3023,6 +3128,21 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
set_high_precision_mv(cpi, (q < HIGH_PRECISION_MV_QTHRESH));
}
#if CONFIG_MASKED_INTERINTER
if (cm->current_video_frame == 0) {
cm->use_masked_interinter = 0;
}
#endif
#if CONFIG_INTERINTRA
if (cm->current_video_frame == 0) {
cm->use_interintra = 1;
#if CONFIG_MASKED_INTERINTRA
cm->use_masked_interintra = 1;
#endif
}
#endif
encode_with_recode_loop(cpi,
size,
dest,
@@ -3092,11 +3212,32 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_copy(counts->comp_inter, cpi->comp_inter_count);
vp9_copy(counts->single_ref, cpi->single_ref_count);
vp9_copy(counts->comp_ref, cpi->comp_ref_count);
#if CONFIG_MASKED_INTERINTER
vp9_copy(counts->masked_interinter, cpi->masked_interinter_counts);
#endif
#if CONFIG_INTERINTRA
vp9_copy(counts->interintra, cpi->interintra_count);
#if CONFIG_MASKED_INTERINTRA
vp9_copy(counts->masked_interintra, cpi->masked_interintra_count);
#endif
#endif
if (!cpi->common.error_resilient_mode &&
!cpi->common.frame_parallel_decoding_mode) {
vp9_adapt_mode_probs(&cpi->common);
vp9_adapt_mv_probs(&cpi->common, cpi->common.allow_high_precision_mv);
}
#if CONFIG_MASKED_INTERINTER
select_masked_interinter_mode(cpi);
#endif
#if CONFIG_INTERINTRA
select_interintra_mode(cpi);
#if CONFIG_MASKED_INTERINTRA
if (cpi->common.use_interintra)
select_masked_interintra_mode(cpi);
else
cpi->common.use_masked_interintra = 0;
#endif
#endif
}
#ifdef ENTROPY_STATS

View File

@@ -43,7 +43,11 @@
#define KEY_FRAME_CONTEXT 5
#if CONFIG_INTERINTRA
#define MAX_MODES 42
#else
#define MAX_MODES 30
#endif
#define MAX_REFS 6
#define MIN_THRESHMULT 32
@@ -161,6 +165,23 @@ typedef enum {
THR_D63_PRED,
THR_D117_PRED,
THR_D45_PRED,
#if CONFIG_INTERINTRA
THR_COMP_INTERINTRA_ZEROL,
THR_COMP_INTERINTRA_NEARESTL,
THR_COMP_INTERINTRA_NEARL,
THR_COMP_INTERINTRA_NEWL,
THR_COMP_INTERINTRA_ZEROG,
THR_COMP_INTERINTRA_NEARESTG,
THR_COMP_INTERINTRA_NEARG,
THR_COMP_INTERINTRA_NEWG,
THR_COMP_INTERINTRA_ZEROA,
THR_COMP_INTERINTRA_NEARESTA,
THR_COMP_INTERINTRA_NEARA,
THR_COMP_INTERINTRA_NEWA,
#endif
} THR_MODES;
typedef enum {
@@ -471,6 +492,19 @@ typedef struct VP9_COMP {
vp9_coeff_probs_model frame_coef_probs[TX_SIZES][PLANE_TYPES];
vp9_coeff_stats frame_branch_ct[TX_SIZES][PLANE_TYPES];
#if CONFIG_MASKED_INTERINTER
unsigned int masked_interinter_counts[BLOCK_SIZES][2];
unsigned int masked_interinter_select_counts[2];
#endif
#if CONFIG_INTERINTRA
unsigned int interintra_count[BLOCK_SIZES][2];
unsigned int interintra_select_count[2];
#if CONFIG_MASKED_INTERINTRA
unsigned int masked_interintra_count[BLOCK_SIZES][2];
unsigned int masked_interintra_select_count[2];
#endif
#endif
int64_t target_bandwidth;
struct vpx_codec_pkt_list *output_pkt_list;

File diff suppressed because it is too large Load Diff

View File

@@ -613,3 +613,127 @@ void vp9_sad4x4x4d_c(const uint8_t *src_ptr,
sad_array[3] = vp9_sad4x4(src_ptr, src_stride,
ref_ptr[3], ref_stride, 0x7fffffff);
}
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
unsigned int vp9_masked_sad64x64_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 64, 64);
}
unsigned int vp9_masked_sad64x32_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 64, 32);
}
unsigned int vp9_masked_sad32x64_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 32, 64);
}
unsigned int vp9_masked_sad32x32_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 32, 32);
}
unsigned int vp9_masked_sad16x32_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 16, 32);
}
unsigned int vp9_masked_sad32x16_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 32, 16);
}
unsigned int vp9_masked_sad16x16_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 16, 16);
}
unsigned int vp9_masked_sad8x16_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 8, 16);
}
unsigned int vp9_masked_sad16x8_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 16, 8);
}
unsigned int vp9_masked_sad8x8_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 8, 8);
}
unsigned int vp9_masked_sad4x4_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad) {
return masked_sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride, 4, 4);
}
#endif

View File

@@ -35,4 +35,31 @@ static INLINE unsigned int sad_mx_n_c(const uint8_t *src_ptr,
return sad;
}
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
static INLINE unsigned int masked_sad_mx_n_c(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
int m,
int n) {
int r, c;
unsigned int sad = 0;
for (r = 0; r < n; r++) {
for (c = 0; c < m; c++) {
sad += (msk_ptr[c]) * abs(src_ptr[c] - ref_ptr[c]);
}
src_ptr += src_stride;
ref_ptr += ref_stride;
msk_ptr += msk_stride;
}
sad = (sad + 31) >> 6;
return sad;
}
#endif
#endif // VP9_ENCODER_VP9_SADMXN_H_

View File

@@ -76,6 +76,33 @@ typedef unsigned int (*vp9_subp_avg_variance_fn_t)(const uint8_t *src_ptr,
unsigned int *sse,
const uint8_t *second_pred);
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
typedef unsigned int(*vp9_masked_sad_fn_t)(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int max_sad);
typedef unsigned int (*vp9_masked_variance_fn_t)(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse);
typedef unsigned int (*vp9_masked_subpixvariance_fn_t)(const uint8_t *src_ptr,
int source_stride,
int xoffset,
int yoffset,
const uint8_t *ref_ptr,
int Refstride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse);
#endif
typedef unsigned int (*vp9_getmbss_fn_t)(const short *);
typedef unsigned int (*vp9_get16x16prederror_fn_t)(const uint8_t *src_ptr,
@@ -95,6 +122,12 @@ typedef struct vp9_variance_vtable {
vp9_sad_multi_fn_t sdx3f;
vp9_sad_multi1_fn_t sdx8f;
vp9_sad_multi_d_fn_t sdx4df;
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
vp9_masked_sad_fn_t msdf;
vp9_masked_variance_fn_t mvf;
vp9_masked_subpixvariance_fn_t msvf;
#endif
} vp9_variance_fn_ptr_t;
static void comp_avg_pred(uint8_t *comp_pred, const uint8_t *pred, int width,

View File

@@ -44,6 +44,40 @@ void variance(const uint8_t *src_ptr,
}
}
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
static void masked_variance(const uint8_t *src_ptr,
int src_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
int w,
int h,
unsigned int *sse,
int *sum) {
int i, j;
int diff;
*sum = 0;
*sse = 0;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
diff = (src_ptr[j] - ref_ptr[j]) * (msk_ptr[j]);
*sum += diff;
*sse += diff * diff;
}
src_ptr += src_stride;
ref_ptr += ref_stride;
msk_ptr += msk_stride;
}
*sum = (*sum >= 0) ? ((*sum + 31) >> 6) : -((-*sum + 31) >> 6);
*sse = (*sse + 2047) >> 12;
}
#endif
/****************************************************************************
*
* ROUTINE : filter_block2d_bil_first_pass
@@ -1092,3 +1126,449 @@ unsigned int vp9_sub_pixel_avg_variance4x8_c(const uint8_t *src_ptr,
comp_avg_pred(temp3, second_pred, 4, 8, temp2, 4);
return vp9_variance4x8(temp3, 4, dst_ptr, dst_pixels_per_line, sse);
}
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
unsigned int vp9_masked_variance64x64_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 64, 64, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 12));
}
unsigned int vp9_masked_variance64x32_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 64, 32, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 11));
}
unsigned int vp9_masked_variance32x64_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 32, 64, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 11));
}
unsigned int vp9_masked_variance32x32_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 32, 32, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 10));
}
unsigned int vp9_masked_variance32x16_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 32, 16, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 9));
}
unsigned int vp9_masked_variance16x32_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 16, 32, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 9));
}
unsigned int vp9_masked_variance16x16_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 16, 16, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 8));
}
unsigned int vp9_masked_variance16x8_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 16, 8, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 7));
}
unsigned int vp9_masked_variance8x16_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 8, 16, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 7));
}
unsigned int vp9_masked_variance8x8_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 8, 8, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 6));
}
unsigned int vp9_masked_variance4x4_c(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int recon_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
unsigned int var;
int avg;
masked_variance(src_ptr, source_stride, ref_ptr, recon_stride,
msk_ptr, msk_stride, 4, 4, &var, &avg);
*sse = var;
return (var - (((int64_t)avg * avg) >> 4));
}
unsigned int vp9_masked_sub_pixel_variance64x64_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[65 * 64]; // Temp data bufffer used in filtering
uint8_t temp2[68 * 64];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 65, 64, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 64, 64, 64, 64, vfilter);
return vp9_masked_variance64x64_c(temp2, 64, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance64x32_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[65 * 64]; // Temp data bufffer used in filtering
uint8_t temp2[68 * 64];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 33, 64, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 64, 64, 32, 64, vfilter);
return vp9_masked_variance64x32_c(temp2, 64, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance32x64_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[65 * 64]; // Temp data bufffer used in filtering
uint8_t temp2[68 * 64];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 65, 32, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 64, 32, vfilter);
return vp9_masked_variance32x64_c(temp2, 32, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance32x32_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[33 * 32]; // Temp data bufffer used in filtering
uint8_t temp2[36 * 32];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 33, 32, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 32, 32, vfilter);
return vp9_masked_variance32x32_c(temp2, 32, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance32x16_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[33 * 32]; // Temp data bufffer used in filtering
uint8_t temp2[36 * 32];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 17, 32, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 32, 32, 16, 32, vfilter);
return vp9_masked_variance32x16_c(temp2, 32, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance16x32_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[33 * 32]; // Temp data bufffer used in filtering
uint8_t temp2[36 * 32];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 33, 16, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 32, 16, vfilter);
return vp9_masked_variance16x32_c(temp2, 16, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance16x16_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[17 * 16]; // Temp data bufffer used in filtering
uint8_t temp2[20 * 16];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 17, 16, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 16, 16, vfilter);
return vp9_masked_variance16x16_c(temp2, 16, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance16x8_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[16 * 9]; // Temp data bufffer used in filtering
uint8_t temp2[20 * 16];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 9, 16, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 16, 16, 8, 16, vfilter);
return vp9_masked_variance16x8_c(temp2, 16, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance8x16_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[9 * 16]; // Temp data bufffer used in filtering
uint8_t temp2[20 * 16];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 17, 8, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 8, 8, 16, 8, vfilter);
return vp9_masked_variance8x16_c(temp2, 8, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance8x8_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint16_t fdata3[9 * 8]; // Temp data bufffer used in filtering
uint8_t temp2[20 * 16];
const int16_t *hfilter, *vfilter;
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 9, 8, hfilter);
var_filter_block2d_bil_second_pass(fdata3, temp2, 8, 8, 8, 8, vfilter);
return vp9_masked_variance8x8_c(temp2, 8, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
unsigned int vp9_masked_sub_pixel_variance4x4_c(const uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
const uint8_t *dst_ptr,
int dst_pixels_per_line,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse) {
uint8_t temp2[20 * 16];
const int16_t *hfilter, *vfilter;
uint16_t fdata3[5 * 4]; // Temp data bufffer used in filtering
hfilter = BILINEAR_FILTERS_2TAP(xoffset);
vfilter = BILINEAR_FILTERS_2TAP(yoffset);
// First filter 1d Horizontal
var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_pixels_per_line,
1, 5, 4, hfilter);
// Now filter Verticaly
var_filter_block2d_bil_second_pass(fdata3, temp2, 4, 4, 4, 4, vfilter);
return vp9_masked_variance4x4_c(temp2, 4, dst_ptr, dst_pixels_per_line,
msk_ptr, msk_stride, sse);
}
#endif

View File

@@ -44,6 +44,10 @@
#include "./webmenc.h"
#include "./y4minput.h"
#if CONFIG_EXT_TX
extern int block_index;
#endif
/* Swallow warnings about unused results of fread/fwrite */
static size_t wrap_fread(void *ptr, size_t size, size_t nmemb,
FILE *stream) {