mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-30 15:28:23 +01:00
Merge "dsp: reuse wht transform from dec in encoder"
This commit is contained in:
commit
fbed36433d
@ -67,7 +67,6 @@ typedef void (*VP8Fdct)(const uint8_t* src, const uint8_t* ref, int16_t* out);
|
|||||||
typedef void (*VP8WHT)(const int16_t* in, int16_t* out);
|
typedef void (*VP8WHT)(const int16_t* in, int16_t* out);
|
||||||
extern VP8Idct VP8ITransform;
|
extern VP8Idct VP8ITransform;
|
||||||
extern VP8Fdct VP8FTransform;
|
extern VP8Fdct VP8FTransform;
|
||||||
extern VP8WHT VP8ITransformWHT;
|
|
||||||
extern VP8WHT VP8FTransformWHT;
|
extern VP8WHT VP8FTransformWHT;
|
||||||
// Predictions
|
// Predictions
|
||||||
// *dst is the destination block. *top and *left can be NULL.
|
// *dst is the destination block. *top and *left can be NULL.
|
||||||
|
@ -159,33 +159,6 @@ static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ITransformWHT(const int16_t* in, int16_t* out) {
|
|
||||||
int tmp[16];
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4; ++i) {
|
|
||||||
const int a0 = in[0 + i] + in[12 + i];
|
|
||||||
const int a1 = in[4 + i] + in[ 8 + i];
|
|
||||||
const int a2 = in[4 + i] - in[ 8 + i];
|
|
||||||
const int a3 = in[0 + i] - in[12 + i];
|
|
||||||
tmp[0 + i] = a0 + a1;
|
|
||||||
tmp[8 + i] = a0 - a1;
|
|
||||||
tmp[4 + i] = a3 + a2;
|
|
||||||
tmp[12 + i] = a3 - a2;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 4; ++i) {
|
|
||||||
const int dc = tmp[0 + i * 4] + 3; // w/ rounder
|
|
||||||
const int a0 = dc + tmp[3 + i * 4];
|
|
||||||
const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4];
|
|
||||||
const int a2 = tmp[1 + i * 4] - tmp[2 + i * 4];
|
|
||||||
const int a3 = dc - tmp[3 + i * 4];
|
|
||||||
out[ 0] = (a0 + a1) >> 3;
|
|
||||||
out[16] = (a3 + a2) >> 3;
|
|
||||||
out[32] = (a0 - a1) >> 3;
|
|
||||||
out[48] = (a3 - a2) >> 3;
|
|
||||||
out += 64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FTransformWHT(const int16_t* in, int16_t* out) {
|
static void FTransformWHT(const int16_t* in, int16_t* out) {
|
||||||
// input is 12b signed
|
// input is 12b signed
|
||||||
int32_t tmp[16];
|
int32_t tmp[16];
|
||||||
@ -699,7 +672,6 @@ static void Copy4x4(const uint8_t* src, uint8_t* dst) { Copy(src, dst, 4); }
|
|||||||
VP8CHisto VP8CollectHistogram;
|
VP8CHisto VP8CollectHistogram;
|
||||||
VP8Idct VP8ITransform;
|
VP8Idct VP8ITransform;
|
||||||
VP8Fdct VP8FTransform;
|
VP8Fdct VP8FTransform;
|
||||||
VP8WHT VP8ITransformWHT;
|
|
||||||
VP8WHT VP8FTransformWHT;
|
VP8WHT VP8FTransformWHT;
|
||||||
VP8Intra4Preds VP8EncPredLuma4;
|
VP8Intra4Preds VP8EncPredLuma4;
|
||||||
VP8IntraPreds VP8EncPredLuma16;
|
VP8IntraPreds VP8EncPredLuma16;
|
||||||
@ -718,13 +690,13 @@ extern void VP8EncDspInitSSE2(void);
|
|||||||
extern void VP8EncDspInitNEON(void);
|
extern void VP8EncDspInitNEON(void);
|
||||||
|
|
||||||
void VP8EncDspInit(void) {
|
void VP8EncDspInit(void) {
|
||||||
|
VP8DspInit(); // common inverse transforms
|
||||||
InitTables();
|
InitTables();
|
||||||
|
|
||||||
// default C implementations
|
// default C implementations
|
||||||
VP8CollectHistogram = CollectHistogram;
|
VP8CollectHistogram = CollectHistogram;
|
||||||
VP8ITransform = ITransform;
|
VP8ITransform = ITransform;
|
||||||
VP8FTransform = FTransform;
|
VP8FTransform = FTransform;
|
||||||
VP8ITransformWHT = ITransformWHT;
|
|
||||||
VP8FTransformWHT = FTransformWHT;
|
VP8FTransformWHT = FTransformWHT;
|
||||||
VP8EncPredLuma4 = Intra4Preds;
|
VP8EncPredLuma4 = Intra4Preds;
|
||||||
VP8EncPredLuma16 = Intra16Preds;
|
VP8EncPredLuma16 = Intra16Preds;
|
||||||
|
@ -145,74 +145,6 @@ static void ITransform(const uint8_t* ref,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same code as dec_neon.c
|
|
||||||
static void ITransformWHT(const int16_t* in, int16_t* out) {
|
|
||||||
const int kStep = 32; // The store is only incrementing the pointer as if we
|
|
||||||
// had stored a single byte.
|
|
||||||
__asm__ volatile (
|
|
||||||
// part 1
|
|
||||||
// load data into q0, q1
|
|
||||||
"vld1.16 {q0, q1}, [%[in]] \n"
|
|
||||||
|
|
||||||
"vaddl.s16 q2, d0, d3 \n" // a0 = in[0] + in[12]
|
|
||||||
"vaddl.s16 q3, d1, d2 \n" // a1 = in[4] + in[8]
|
|
||||||
"vsubl.s16 q4, d1, d2 \n" // a2 = in[4] - in[8]
|
|
||||||
"vsubl.s16 q5, d0, d3 \n" // a3 = in[0] - in[12]
|
|
||||||
|
|
||||||
"vadd.s32 q0, q2, q3 \n" // tmp[0] = a0 + a1
|
|
||||||
"vsub.s32 q2, q2, q3 \n" // tmp[8] = a0 - a1
|
|
||||||
"vadd.s32 q1, q5, q4 \n" // tmp[4] = a3 + a2
|
|
||||||
"vsub.s32 q3, q5, q4 \n" // tmp[12] = a3 - a2
|
|
||||||
|
|
||||||
// Transpose
|
|
||||||
// q0 = tmp[0, 4, 8, 12], q1 = tmp[2, 6, 10, 14]
|
|
||||||
// q2 = tmp[1, 5, 9, 13], q3 = tmp[3, 7, 11, 15]
|
|
||||||
"vswp d1, d4 \n" // vtrn.64 q0, q2
|
|
||||||
"vswp d3, d6 \n" // vtrn.64 q1, q3
|
|
||||||
"vtrn.32 q0, q1 \n"
|
|
||||||
"vtrn.32 q2, q3 \n"
|
|
||||||
|
|
||||||
"vmov.s32 q4, #3 \n" // dc = 3
|
|
||||||
"vadd.s32 q0, q0, q4 \n" // dc = tmp[0] + 3
|
|
||||||
"vadd.s32 q6, q0, q3 \n" // a0 = dc + tmp[3]
|
|
||||||
"vadd.s32 q7, q1, q2 \n" // a1 = tmp[1] + tmp[2]
|
|
||||||
"vsub.s32 q8, q1, q2 \n" // a2 = tmp[1] - tmp[2]
|
|
||||||
"vsub.s32 q9, q0, q3 \n" // a3 = dc - tmp[3]
|
|
||||||
|
|
||||||
"vadd.s32 q0, q6, q7 \n"
|
|
||||||
"vshrn.s32 d0, q0, #3 \n" // (a0 + a1) >> 3
|
|
||||||
"vadd.s32 q1, q9, q8 \n"
|
|
||||||
"vshrn.s32 d1, q1, #3 \n" // (a3 + a2) >> 3
|
|
||||||
"vsub.s32 q2, q6, q7 \n"
|
|
||||||
"vshrn.s32 d2, q2, #3 \n" // (a0 - a1) >> 3
|
|
||||||
"vsub.s32 q3, q9, q8 \n"
|
|
||||||
"vshrn.s32 d3, q3, #3 \n" // (a3 - a2) >> 3
|
|
||||||
|
|
||||||
// set the results to output
|
|
||||||
"vst1.16 d0[0], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d1[0], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d2[0], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d3[0], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d0[1], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d1[1], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d2[1], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d3[1], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d0[2], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d1[2], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d2[2], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d3[2], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d0[3], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d1[3], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d2[3], [%[out]], %[kStep] \n"
|
|
||||||
"vst1.16 d3[3], [%[out]], %[kStep] \n"
|
|
||||||
|
|
||||||
: [out] "+r"(out) // modified registers
|
|
||||||
: [in] "r"(in), [kStep] "r"(kStep) // constants
|
|
||||||
: "memory", "q0", "q1", "q2", "q3", "q4",
|
|
||||||
"q5", "q6", "q7", "q8", "q9" // clobbered
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward transform.
|
// Forward transform.
|
||||||
|
|
||||||
// adapted from vp8/encoder/arm/neon/shortfdct_neon.asm
|
// adapted from vp8/encoder/arm/neon/shortfdct_neon.asm
|
||||||
@ -622,7 +554,6 @@ void VP8EncDspInitNEON(void) {
|
|||||||
VP8ITransform = ITransform;
|
VP8ITransform = ITransform;
|
||||||
VP8FTransform = FTransform;
|
VP8FTransform = FTransform;
|
||||||
|
|
||||||
VP8ITransformWHT = ITransformWHT;
|
|
||||||
VP8FTransformWHT = FTransformWHT;
|
VP8FTransformWHT = FTransformWHT;
|
||||||
|
|
||||||
VP8TDisto4x4 = Disto4x4;
|
VP8TDisto4x4 = Disto4x4;
|
||||||
|
@ -751,7 +751,7 @@ static int ReconstructIntra16(VP8EncIterator* const it,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Transform back
|
// Transform back
|
||||||
VP8ITransformWHT(dc_tmp, tmp[0]);
|
VP8TransformWHT(dc_tmp, tmp[0]);
|
||||||
for (n = 0; n < 16; n += 2) {
|
for (n = 0; n < 16; n += 2) {
|
||||||
VP8ITransform(ref + VP8Scan[n], tmp[n], yuv_out + VP8Scan[n], 1);
|
VP8ITransform(ref + VP8Scan[n], tmp[n], yuv_out + VP8Scan[n], 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user