Commit de5546c3 authored by John Koleszar's avatar John Koleszar
Browse files

Merge branch 'experimental' of review:webm/libvpx

Change-Id: Ib2c2236349c2ae8ee81bd01c5067dddcbac713ca
parents 652589d5 9bf73f46
......@@ -436,10 +436,10 @@ RTCD_OPTIONS = ${RTCD_OPTIONS}
EOF
if enabled rvct; then cat >> $1 << EOF
fmt_deps = sed -e 's;^__image.axf;\$\${@:.d=.o} \$\$@;' #hide
fmt_deps = sed -e 's;^__image.axf;\${@:.d=.o} \$@;' #hide
EOF
else cat >> $1 << EOF
fmt_deps = sed -e 's;^\([a-zA-Z0-9_]*\)\.o;\$\${@:.d=.o} \$\$@;'
fmt_deps = sed -e 's;^\([a-zA-Z0-9_]*\)\.o;\${@:.d=.o} \$@;'
EOF
fi
......
......@@ -239,15 +239,17 @@ HAVE_LIST="
"
EXPERIMENT_LIST="
csm
comp_intra_pred
superblocks
pred_filter
lossless
subpelrefmv
new_mvref
implicit_segmentation
newbintramodes
comp_interintra_pred
tx64x64
dwtdcthybrid
cnvcontext
newcoefcontext
enable_6tap
abovesprefmv
"
CONFIG_LIST="
external_build
......
/*
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
extern "C" {
#include "vp9/common/vp9_entropy.h"
#include "./vp9_rtcd.h"
void vp9_short_fdct32x32_c(int16_t *input, int16_t *out, int pitch);
void vp9_short_idct32x32_c(short *input, short *output, int pitch);
}
#include "test/acm_random.h"
#include "vpx/vpx_integer.h"
using libvpx_test::ACMRandom;
namespace {
#ifdef _MSC_VER
static int round(double x) {
if (x < 0)
return (int)ceil(x - 0.5);
else
return (int)floor(x + 0.5);
}
#endif
#if !CONFIG_DWTDCTHYBRID
static const double kPi = 3.141592653589793238462643383279502884;
static void reference2_32x32_idct_2d(double *input, double *output) {
double x;
for (int l = 0; l < 32; ++l) {
for (int k = 0; k < 32; ++k) {
double s = 0;
for (int i = 0; i < 32; ++i) {
for (int j = 0; j < 32; ++j) {
x = cos(kPi * j * (l + 0.5) / 32.0) *
cos(kPi * i * (k + 0.5) / 32.0) * input[i * 32 + j] / 1024;
if (i != 0)
x *= sqrt(2.0);
if (j != 0)
x *= sqrt(2.0);
s += x;
}
}
output[k * 32 + l] = s / 4;
}
}
}
static void reference_32x32_dct_1d(double in[32], double out[32], int stride) {
const double kInvSqrt2 = 0.707106781186547524400844362104;
for (int k = 0; k < 32; k++) {
out[k] = 0.0;
for (int n = 0; n < 32; n++)
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0);
if (k == 0)
out[k] = out[k] * kInvSqrt2;
}
}
static void reference_32x32_dct_2d(int16_t input[32*32], double output[32*32]) {
// First transform columns
for (int i = 0; i < 32; ++i) {
double temp_in[32], temp_out[32];
for (int j = 0; j < 32; ++j)
temp_in[j] = input[j*32 + i];
reference_32x32_dct_1d(temp_in, temp_out, 1);
for (int j = 0; j < 32; ++j)
output[j * 32 + i] = temp_out[j];
}
// Then transform rows
for (int i = 0; i < 32; ++i) {
double temp_in[32], temp_out[32];
for (int j = 0; j < 32; ++j)
temp_in[j] = output[j + i*32];
reference_32x32_dct_1d(temp_in, temp_out, 1);
// Scale by some magic number
for (int j = 0; j < 32; ++j)
output[j + i * 32] = temp_out[j] / 4;
}
}
TEST(VP9Idct32x32Test, AccuracyCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
for (int i = 0; i < count_test_block; ++i) {
int16_t in[1024], coeff[1024];
int16_t out_c[1024];
double out_r[1024];
// Initialize a test block with input range [-255, 255].
for (int j = 0; j < 1024; ++j)
in[j] = rnd.Rand8() - rnd.Rand8();
reference_32x32_dct_2d(in, out_r);
for (int j = 0; j < 1024; j++)
coeff[j] = round(out_r[j]);
vp9_short_idct32x32_c(coeff, out_c, 64);
for (int j = 0; j < 1024; ++j) {
const int diff = out_c[j] - in[j];
const int error = diff * diff;
EXPECT_GE(1, error)
<< "Error: 3x32 IDCT has error " << error
<< " at index " << j;
}
vp9_short_fdct32x32_c(in, out_c, 64);
for (int j = 0; j < 1024; ++j) {
const double diff = coeff[j] - out_c[j];
const double error = diff * diff;
EXPECT_GE(1.0, error)
<< "Error: 32x32 FDCT has error " << error
<< " at index " << j;
}
}
}
#else // CONFIG_DWTDCTHYBRID
// TODO(rbultje/debargha): add DWT-specific tests
#endif // CONFIG_DWTDCTHYBRID
TEST(VP9Fdct32x32Test, AccuracyCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
unsigned int max_error = 0;
int64_t total_error = 0;
const int count_test_block = 1000;
for (int i = 0; i < count_test_block; ++i) {
int16_t test_input_block[1024];
int16_t test_temp_block[1024];
int16_t test_output_block[1024];
// Initialize a test block with input range [-255, 255].
for (int j = 0; j < 1024; ++j)
test_input_block[j] = rnd.Rand8() - rnd.Rand8();
const int pitch = 64;
vp9_short_fdct32x32_c(test_input_block, test_temp_block, pitch);
vp9_short_idct32x32_c(test_temp_block, test_output_block, pitch);
for (int j = 0; j < 1024; ++j) {
const unsigned diff = test_input_block[j] - test_output_block[j];
const unsigned error = diff * diff;
if (max_error < error)
max_error = error;
total_error += error;
}
}
EXPECT_GE(1u, max_error)
<< "Error: 32x32 FDCT/IDCT has an individual roundtrip error > 1";
EXPECT_GE(count_test_block/10, total_error)
<< "Error: 32x32 FDCT/IDCT has average roundtrip error > 1/10 per block";
}
TEST(VP9Fdct32x32Test, CoeffSizeCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
for (int i = 0; i < count_test_block; ++i) {
int16_t input_block[1024], input_extreme_block[1024];
int16_t output_block[1024], output_extreme_block[1024];
// Initialize a test block with input range [-255, 255].
for (int j = 0; j < 1024; ++j) {
input_block[j] = rnd.Rand8() - rnd.Rand8();
input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255;
}
if (i == 0)
for (int j = 0; j < 1024; ++j)
input_extreme_block[j] = 255;
const int pitch = 64;
vp9_short_fdct32x32_c(input_block, output_block, pitch);
vp9_short_fdct32x32_c(input_extreme_block, output_extreme_block, pitch);
// The minimum quant value is 4.
for (int j = 0; j < 1024; ++j) {
EXPECT_GE(4*DCT_MAX_VALUE, abs(output_block[j]))
<< "Error: 32x32 FDCT has coefficient larger than 4*DCT_MAX_VALUE";
EXPECT_GE(4*DCT_MAX_VALUE, abs(output_extreme_block[j]))
<< "Error: 32x32 FDCT extreme has coefficient larger than "
"4*DCT_MAX_VALUE";
}
}
}
} // namespace
......@@ -69,6 +69,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct4x4_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct8x8_test.cc
#LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
endif # VP9
......
......@@ -15,7 +15,7 @@
#include "vpx_scale/yv12config.h"
#include "postproc.h"
#include "common.h"
#include "vpx_scale/vpxscale.h"
#include "vpx_scale/vpx_scale.h"
#include "systemdependent.h"
#include <limits.h>
......
......@@ -21,7 +21,7 @@
#include "vp8/common/alloccommon.h"
#include "vp8/common/entropymode.h"
#include "vp8/common/quant_common.h"
#include "vpx_scale/vpxscale.h"
#include "vpx_scale/vpx_scale.h"
#include "vp8/common/setupintrarecon.h"
#include "decodemv.h"
......
......@@ -26,7 +26,7 @@
#include "vp8/common/quant_common.h"
#include "./vpx_scale_rtcd.h"
#include "vpx_scale/vpxscale.h"
#include "vpx_scale/vpx_scale.h"
#include "vp8/common/systemdependent.h"
#include "vpx_ports/vpx_timer.h"
#include "detokenize.h"
......
......@@ -21,7 +21,7 @@
#include "vp8/common/systemdependent.h"
#include "mcomp.h"
#include "firstpass.h"
#include "vpx_scale/vpxscale.h"
#include "vpx_scale/vpx_scale.h"
#include "encodemb.h"
#include "vp8/common/extend.h"
#include "vpx_mem/vpx_mem.h"
......
......@@ -20,7 +20,7 @@
#include "mcomp.h"
#include "firstpass.h"
#include "psnr.h"
#include "vpx_scale/vpxscale.h"
#include "vpx_scale/vpx_scale.h"
#include "vp8/common/extend.h"
#include "ratectrl.h"
#include "vp8/common/quant_common.h"
......@@ -2588,7 +2588,7 @@ static void scale_and_extend_source(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
Scale2Ratio(cm->horiz_scale, &hr, &hs);
Scale2Ratio(cm->vert_scale, &vr, &vs);
vp8_scale_frame(sd, &cpi->scaled_source, cm->temp_scale_frame.y_buffer,
vpx_scale_frame(sd, &cpi->scaled_source, cm->temp_scale_frame.y_buffer,
tmp_height, hs, hr, vs, vr, 0);
vp8_yv12_extend_frame_borders(&cpi->scaled_source);
......@@ -3466,7 +3466,7 @@ static void encode_frame_to_data_rate
/* Note that we should not throw out a key frame (especially when
* spatial resampling is enabled).
*/
if ((cm->frame_type == KEY_FRAME))
if (cm->frame_type == KEY_FRAME)
{
cpi->decimation_count = cpi->decimation_factor;
}
......
......@@ -14,7 +14,7 @@
#include "onyx_int.h"
#include "quantize.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpxscale.h"
#include "vpx_scale/vpx_scale.h"
#include "vp8/common/alloccommon.h"
#include "vp8/common/loopfilter.h"
#if ARCH_ARM
......
......@@ -13,7 +13,7 @@
#include "math.h"
#include "vp8/common/systemdependent.h" /* for vp8_clear_system_state() */
#define MAX_PSNR 60
#define MAX_PSNR 100
double vp8_mse2psnr(double Samples, double Peak, double Mse)
{
......
......@@ -17,7 +17,7 @@
#include "mcomp.h"
#include "firstpass.h"
#include "psnr.h"
#include "vpx_scale/vpxscale.h"
#include "vpx_scale/vpx_scale.h"
#include "vp8/common/extend.h"
#include "ratectrl.h"
#include "vp8/common/quant_common.h"
......
......@@ -1178,7 +1178,9 @@ static vpx_codec_err_t vp8e_set_scalemode(vpx_codec_alg_priv_t *ctx,
{
int res;
vpx_scaling_mode_t scalemode = *(vpx_scaling_mode_t *)data ;
res = vp8_set_internal_size(ctx->cpi, scalemode.h_scaling_mode, scalemode.v_scaling_mode);
res = vp8_set_internal_size(ctx->cpi,
(VPX_SCALING)scalemode.h_scaling_mode,
(VPX_SCALING)scalemode.v_scaling_mode);
if (!res)
{
......
......@@ -220,4 +220,8 @@ void vp9_initialize_common() {
vp9_entropy_mode_init();
vp9_entropy_mv_init();
#if CONFIG_NEWCOEFCONTEXT
vp9_init_neighbors();
#endif
}
......@@ -23,4 +23,4 @@ void vp9_setup_version(VP9_COMMON *oci);
void vp9_update_mode_info_border(VP9_COMMON *cpi, MODE_INFO *mi_base);
void vp9_update_mode_info_in_image(VP9_COMMON *cpi, MODE_INFO *mi);
#endif
#endif // VP9_COMMON_VP9_ALLOCCOMMON_H_
......@@ -12,18 +12,15 @@
#include "vp9/common/vp9_blockd.h"
#include "vpx_mem/vpx_mem.h"
const unsigned char vp9_block2left[25] = {
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8
};
const unsigned char vp9_block2above[25] = {
0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8
const uint8_t vp9_block2left[TX_SIZE_MAX_SB][25] = {
{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8},
{0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 8},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 6, 6, 6, 6, 8},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 6, 6, 6, 6, 8}
};
const unsigned char vp9_block2left_8x8[25] = {
0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 8
const uint8_t vp9_block2above[TX_SIZE_MAX_SB][25] = {
{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8},
{0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 8},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 6, 6, 6, 6, 8},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 6, 6, 6, 6, 8}
};
const unsigned char vp9_block2above_8x8[25] = {
0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 8
};
......@@ -45,6 +45,19 @@ void vpx_log(const char *format, ...);
#define SEGMENT_DELTADATA 0
#define SEGMENT_ABSDATA 1
#define MAX_MV_REFS 9
#define MAX_MV_REF_CANDIDATES 4
#if CONFIG_DWTDCTHYBRID
#define DWT_MAX_LENGTH 64
#define DWT_TYPE 26 // 26/53/97
#define DWT_PRECISION_BITS 2
#define DWT_PRECISION_RND ((1 << DWT_PRECISION_BITS) / 2)
#define DWTDCT16X16 0
#define DWTDCT16X16_LEAN 1
#define DWTDCT8X8 2
#define DWTDCT_TYPE DWTDCT16X16_LEAN
#endif
typedef struct {
int r, c;
......@@ -65,11 +78,6 @@ typedef struct {
ENTROPY_CONTEXT y2;
} ENTROPY_CONTEXT_PLANES;
extern const unsigned char vp9_block2left[25];
extern const unsigned char vp9_block2above[25];
extern const unsigned char vp9_block2left_8x8[25];
extern const unsigned char vp9_block2above_8x8[25];
#define VP9_COMBINEENTROPYCONTEXTS( Dest, A, B) \
Dest = ((A)!=0) + ((B)!=0);
......@@ -80,10 +88,13 @@ typedef enum {
typedef enum
{
SIXTAP = 0,
BILINEAR = 1,
EIGHTTAP = 2,
EIGHTTAP_SHARP = 3,
#if CONFIG_ENABLE_6TAP
SIXTAP,
#endif
EIGHTTAP_SMOOTH,
EIGHTTAP,
EIGHTTAP_SHARP,
BILINEAR,
SWITCHABLE /* should be the last one */
} INTERPOLATIONFILTERTYPE;
......@@ -101,13 +112,11 @@ typedef enum
TM_PRED, /* Truemotion prediction */
I8X8_PRED, /* 8x8 based prediction, each 8x8 has its own prediction mode */
B_PRED, /* block based prediction, each block has its own prediction mode */
NEARESTMV,
NEARMV,
ZEROMV,
NEWMV,
SPLITMV,
MB_MODE_COUNT
} MB_PREDICTION_MODE;
......@@ -120,15 +129,16 @@ typedef enum {
SEG_LVL_EOB = 4, // EOB end stop marker.
SEG_LVL_TRANSFORM = 5, // Block transform size.
SEG_LVL_MAX = 6 // Number of MB level features supported
} SEG_LVL_FEATURES;
// Segment level features.
typedef enum {
TX_4X4, // 4x4 dct transform
TX_8X8, // 8x8 dct transform
TX_16X16, // 16x16 dct transform
TX_SIZE_MAX // Number of different transforms available
TX_4X4 = 0, // 4x4 dct transform
TX_8X8 = 1, // 8x8 dct transform
TX_16X16 = 2, // 16x16 dct transform
TX_SIZE_MAX_MB = 3, // Number of different transforms available
TX_32X32 = TX_SIZE_MAX_MB, // 32x32 dct transform
TX_SIZE_MAX_SB, // Number of transforms available to SBs
} TX_SIZE;
typedef enum {
......@@ -205,9 +215,6 @@ union b_mode_info {
struct {
B_PREDICTION_MODE first;
TX_TYPE tx_type;
#if CONFIG_COMP_INTRA_PRED
B_PREDICTION_MODE second;
#endif
#if CONFIG_NEWBINTRAMODES
B_PREDICTION_MODE context;
#endif
......@@ -227,18 +234,21 @@ typedef enum {
MAX_REF_FRAMES = 4
} MV_REFERENCE_FRAME;
typedef enum {
BLOCK_SIZE_MB16X16 = 0,
BLOCK_SIZE_SB32X32 = 1,
BLOCK_SIZE_SB64X64 = 2,
} BLOCK_SIZE_TYPE;
typedef struct {
MB_PREDICTION_MODE mode, uv_mode;
#if CONFIG_COMP_INTRA_PRED
MB_PREDICTION_MODE second_mode, second_uv_mode;
#endif
#if CONFIG_COMP_INTERINTRA_PRED
MB_PREDICTION_MODE interintra_mode, interintra_uv_mode;
#endif
MV_REFERENCE_FRAME ref_frame, second_ref_frame;
TX_SIZE txfm_size;
int_mv mv[2]; // for each reference frame used
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REFS];
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
int_mv best_mv, best_second_mv;
#if CONFIG_NEW_MVREF
int best_index, best_second_index;
......@@ -261,17 +271,9 @@ typedef struct {
// a valid predictor
unsigned char mb_in_image;
#if CONFIG_PRED_FILTER
// Flag to turn prediction signal filter on(1)/off(0 ) at the MB level
unsigned int pred_filter_enabled;
#endif
INTERPOLATIONFILTERTYPE interp_filter;
INTERPOLATIONFILTERTYPE interp_filter;
#if CONFIG_SUPERBLOCKS
// FIXME need a SB array of 4 MB_MODE_INFOs that
// only needs one encoded_as_sb.
unsigned char encoded_as_sb;
#endif
BLOCK_SIZE_TYPE sb_type;
} MB_MODE_INFO;
typedef struct {
......@@ -280,19 +282,19 @@ typedef struct {
} MODE_INFO;
typedef struct blockd {
short *qcoeff;
short *dqcoeff;
unsigned char *predictor;
short *diff;
short *dequant;
int16_t *qcoeff;
int16_t *dqcoeff;
uint8_t *predictor;
int16_t *diff;
int16_t *dequant;
/* 16 Y blocks, 4 U blocks, 4 V blocks each with 16 entries */
unsigned char **base_pre;
unsigned char **base_second_pre;
uint8_t **base_pre;
uint8_t **base_second_pre;
int pre;
int pre_stride;
unsigned char **base_dst;
uint8_t **base_dst;
int dst;
int dst_stride;
......@@ -301,12 +303,21 @@ typedef struct blockd {
union b_mode_info bmi;
} BLOCKD;
typedef struct superblockd {
/* 32x32 Y and 16x16 U/V. No 2nd order transform yet. */
DECLARE_ALIGNED(16, int16_t, diff[32*32+16*16*2]);
DECLARE_ALIGNED(16, int16_t, qcoeff[32*32+16*16*2]);
DECLARE_ALIGNED(16, int16_t, dqcoeff[32*32+16*16*2]);
} SUPERBLOCKD;
typedef struct macroblockd {
DECLARE_ALIGNED(16, short, diff[400]); /* from idct diff */
DECLARE_ALIGNED(16, unsigned char, predictor[384]);
DECLARE_ALIGNED(16, short, qcoeff[400]);
DECLARE_ALIGNED(16, short, dqcoeff[400]);
DECLARE_ALIGNED(16, unsigned short, eobs[25]);
DECLARE_ALIGNED(16, int16_t, diff[400]); /* from idct diff */
DECLARE_ALIGNED(16, uint8_t, predictor[384]);
DECLARE_ALIGNED(16, int16_t, qcoeff[400]);
DECLARE_ALIGNED(16, int16_t, dqcoeff[400]);
DECLARE_ALIGNED(16, uint16_t, eobs[25]);
SUPERBLOCKD sb_coeff_data;
/* 16 Y blocks, 4 U, 4 V, 1 DC 2nd order block, each with 16 entries. */
BLOCKD block[25];
......@@ -350,7 +361,7 @@ typedef struct macroblockd {
vp9_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
#if CONFIG_NEW_MVREF
vp9_prob mb_mv_ref_id_probs[MAX_REF_FRAMES][3];
vp9_prob mb_mv_ref_probs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES-1];
#endif
// Segment features
......@@ -377,17 +388,17 @@ typedef struct macroblockd {
unsigned int frames_till_alt_ref_frame;
/* Inverse transform function pointers. */
void (*inv_xform4x4_1_x8)(short *input, short *output, int pitch);
void (*inv_xform4x4_x8)(short *input, short *output, int pitch);
void (*inv_walsh4x4_1)(short *in, short *out);
void (*inv_walsh4x4_lossless)(short *in, short *out);
void (*inv_xform4x4_1_x8)(int16_t *input, int16_t *output, int pitch);
void (*inv_xform4x4_x8)(int16_t *input, int16_t *output, int pitch);
void (*inv_walsh4x4_1)(int16_t *in, int16_t *out);
void (*inv_walsh4x4_lossless)(int16_t *in, int16_t *out