From: Meng Wang <wangmeng.k...@bytedance.com> Signed-off-by: Meng Wang <wangmeng.k...@bytedance.com> --- libavcodec/arm/hevcdsp_init_neon.c | 67 +++++ libavcodec/arm/hevcdsp_qpel_neon.S | 509 +++++++++++++++++++++++++++++++++++++ 2 files changed, 576 insertions(+)
diff --git a/libavcodec/arm/hevcdsp_init_neon.c b/libavcodec/arm/hevcdsp_init_neon.c index a4628d2a93..183162803e 100644 --- a/libavcodec/arm/hevcdsp_init_neon.c +++ b/libavcodec/arm/hevcdsp_init_neon.c @@ -81,6 +81,8 @@ static void (*put_hevc_qpel_neon[4][4])(int16_t *dst, ptrdiff_t dststride, uint8 int height, int width); static void (*put_hevc_qpel_uw_neon[4][4])(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride, int width, int height, int16_t* src2, ptrdiff_t src2stride); +static void (*put_hevc_qpel_wt_neon[4][4])(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, + int width, int height, int denom, int wx1, int ox1, int wx0, int ox0, int16_t* src2, ptrdiff_t src2stride); void ff_hevc_put_qpel_neon_wrapper(int16_t *dst, uint8_t *src, ptrdiff_t srcstride, int height, intptr_t mx, intptr_t my, int width); void ff_hevc_put_qpel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, @@ -88,6 +90,15 @@ void ff_hevc_put_qpel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_ void ff_hevc_put_qpel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_qpel_uni_w_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int denom, int wx, int ox, + intptr_t mx, intptr_t my, int width); +void ff_hevc_put_qpel_bi_w_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int16_t *src2, + int height, int denom, int wx0, int wx1, + int ox0, int ox1, intptr_t mx, intptr_t my, int width); + #define QPEL_FUNC(name) \ void name(int16_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, \ int height, int width) @@ -142,6 +153,26 @@ QPEL_FUNC_UW(ff_hevc_put_qpel_uw_h3v2_neon_8); QPEL_FUNC_UW(ff_hevc_put_qpel_uw_h3v3_neon_8); #undef QPEL_FUNC_UW +#define QPEL_FUNC_WT(name) \ +void name(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, \ + int width, int height, int denom, int wx1, int ox1, int wx0, int ox0, int16_t* src2, ptrdiff_t src2stride); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_v1_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_v2_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_v3_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h1_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h2_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h3_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h1v1_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h1v2_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h1v3_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h2v1_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h2v2_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h2v3_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h3v1_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h3v2_neon_8); +QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h3v3_neon_8); +#undef QPEL_FUNC_WT + void ff_hevc_put_qpel_neon_wrapper(int16_t *dst, uint8_t *src, ptrdiff_t srcstride, int height, intptr_t mx, intptr_t my, int width) { @@ -160,6 +191,21 @@ void ff_hevc_put_qpel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t put_hevc_qpel_uw_neon[my][mx](dst, dststride, src, srcstride, width, height, src2, MAX_PB_SIZE); } +void ff_hevc_put_qpel_uni_w_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int denom, int wx, int ox, + intptr_t mx, intptr_t my, int width) { + put_hevc_qpel_wt_neon[my][mx](dst, dststride, src, srcstride, width, height, denom, wx, ox, 0, 0, NULL, 0); +} + +void ff_hevc_put_qpel_bi_w_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, + int16_t *src2, + int height, int denom, int wx0, int wx1, + int ox0, int ox1, intptr_t mx, intptr_t my, int width) { + put_hevc_qpel_wt_neon[my][mx](dst, dststride, src, srcstride, width, height, denom, wx1, ox1, wx0, ox0, src2, MAX_PB_SIZE); +} + + av_cold void ff_hevc_dsp_init_neon(HEVCDSPContext *c, const int bit_depth) { if (bit_depth == 8) { @@ -211,6 +257,21 @@ av_cold void ff_hevc_dsp_init_neon(HEVCDSPContext *c, const int bit_depth) put_hevc_qpel_uw_neon[3][1] = ff_hevc_put_qpel_uw_h1v3_neon_8; put_hevc_qpel_uw_neon[3][2] = ff_hevc_put_qpel_uw_h2v3_neon_8; put_hevc_qpel_uw_neon[3][3] = ff_hevc_put_qpel_uw_h3v3_neon_8; + put_hevc_qpel_wt_neon[1][0] = ff_hevc_put_qpel_wt_v1_neon_8; + put_hevc_qpel_wt_neon[2][0] = ff_hevc_put_qpel_wt_v2_neon_8; + put_hevc_qpel_wt_neon[3][0] = ff_hevc_put_qpel_wt_v3_neon_8; + put_hevc_qpel_wt_neon[0][1] = ff_hevc_put_qpel_wt_h1_neon_8; + put_hevc_qpel_wt_neon[0][2] = ff_hevc_put_qpel_wt_h2_neon_8; + put_hevc_qpel_wt_neon[0][3] = ff_hevc_put_qpel_wt_h3_neon_8; + put_hevc_qpel_wt_neon[1][1] = ff_hevc_put_qpel_wt_h1v1_neon_8; + put_hevc_qpel_wt_neon[1][2] = ff_hevc_put_qpel_wt_h2v1_neon_8; + put_hevc_qpel_wt_neon[1][3] = ff_hevc_put_qpel_wt_h3v1_neon_8; + put_hevc_qpel_wt_neon[2][1] = ff_hevc_put_qpel_wt_h1v2_neon_8; + put_hevc_qpel_wt_neon[2][2] = ff_hevc_put_qpel_wt_h2v2_neon_8; + put_hevc_qpel_wt_neon[2][3] = ff_hevc_put_qpel_wt_h3v2_neon_8; + put_hevc_qpel_wt_neon[3][1] = ff_hevc_put_qpel_wt_h1v3_neon_8; + put_hevc_qpel_wt_neon[3][2] = ff_hevc_put_qpel_wt_h2v3_neon_8; + put_hevc_qpel_wt_neon[3][3] = ff_hevc_put_qpel_wt_h3v3_neon_8; for (x = 0; x < 10; x++) { c->put_hevc_qpel[x][1][0] = ff_hevc_put_qpel_neon_wrapper; c->put_hevc_qpel[x][0][1] = ff_hevc_put_qpel_neon_wrapper; @@ -221,6 +282,12 @@ av_cold void ff_hevc_dsp_init_neon(HEVCDSPContext *c, const int bit_depth) c->put_hevc_qpel_bi[x][1][0] = ff_hevc_put_qpel_bi_neon_wrapper; c->put_hevc_qpel_bi[x][0][1] = ff_hevc_put_qpel_bi_neon_wrapper; c->put_hevc_qpel_bi[x][1][1] = ff_hevc_put_qpel_bi_neon_wrapper; + c->put_hevc_qpel_uni_w[x][1][0] = ff_hevc_put_qpel_uni_w_neon_wrapper; + c->put_hevc_qpel_uni_w[x][0][1] = ff_hevc_put_qpel_uni_w_neon_wrapper; + c->put_hevc_qpel_uni_w[x][1][1] = ff_hevc_put_qpel_uni_w_neon_wrapper; + c->put_hevc_qpel_bi_w[x][1][0] = ff_hevc_put_qpel_bi_w_neon_wrapper; + c->put_hevc_qpel_bi_w[x][0][1] = ff_hevc_put_qpel_bi_w_neon_wrapper; + c->put_hevc_qpel_bi_w[x][1][1] = ff_hevc_put_qpel_bi_w_neon_wrapper; } c->put_hevc_qpel[0][0][0] = ff_hevc_put_pixels_w2_neon_8; c->put_hevc_qpel[1][0][0] = ff_hevc_put_pixels_w4_neon_8; diff --git a/libavcodec/arm/hevcdsp_qpel_neon.S b/libavcodec/arm/hevcdsp_qpel_neon.S index 86f92cf75a..e188b215ba 100644 --- a/libavcodec/arm/hevcdsp_qpel_neon.S +++ b/libavcodec/arm/hevcdsp_qpel_neon.S @@ -333,6 +333,139 @@ bx lr .endm +.macro hevc_put_qpel_wt_vX_neon_8 filter + push {r4-r12} + ldr r5, [sp, #36] // width + ldr r4, [sp, #40] // height + ldr r8, [sp, #44] // denom + ldr r9, [sp, #48] // wx1 + ldr r10,[sp, #52] // ox1 + ldr r11,[sp, #64] // src2 + vpush {d8-d15} + sub r2, r2, r3, lsl #1 // r2 - 3*stride + sub r2, r3 + mov r12, r4 + mov r6, r0 + mov r7, r2 + add r8, #6 // weight shift = denom + 6 + vdup.32 q5, r8 // shift is a 32 bit action + vneg.s32 q4, q5 // q4 = -q5 + vdup.32 q6, r9 // q6 wx + vdup.32 q5, r10 // q5 ox + cmp r11, #0 // if src2 != 0 goto bi mode + bne .Lbi\@ +0: loadin8 + cmp r5, #4 + beq 4f +8: subs r4, #1 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmovl.s16 q13, d15 + vmul.s32 q14, q12, q6 // src * wx + vmul.s32 q15, q13, q6 // src * wx + vqrshl.s32 q12, q14, q4 // src * wx >> shift + vqrshl.s32 q13, q15, q4 // src * wx >> shift + vadd.s32 q14, q12, q5 // src * wx >> shift + ox + vadd.s32 q15, q13, q5 // src * wx >> shift + ox + vqmovun.s32 d2, q14 // narrow signed 4x32bit to unsigned 4x16bit + vqmovun.s32 d3, q15 // narrow signed 4x32bit to unsigned 4x16bit + vqmovn.u16 d0, q1 // narrow unsigned 8x16bit to unsigned 8x8bit + vst1.8 d0, [r0], r1 + regshuffle_d8 + vld1.8 {d23}, [r2], r3 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #8 + mov r0, r6 + add r7, #8 + mov r2, r7 + b 0b +4: subs r4, #1 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmul.s32 q14, q12, q6 + vqrshl.s32 q12, q14, q4 + vadd.s32 q14, q12, q5 + vqmovun.s32 d14, q14 + vqmovn.u16 d0, q7 + vst1.32 d0[0], [r0], r1 + regshuffle_d8 + vld1.32 {d23[0]}, [r2], r3 + bne 4b + b 99f +.Lbi\@: ldr r8, [sp, #120] // w0 + vdup.32 q1, r8 // q1 wx0 + ldr r8, [sp, #124] // ox0 + vdup.32 q2, r8 // q2 ox0 + vadd.s32 q2, q5 // q2 = ox0 +ox1 + vmov.s32 q10, #1 + vadd.s32 q2, q10 // q2 = ox0 +ox1 + 1 + vneg.s32 q15, q4 // q15 = - q4, preperation for left shift + vqrshl.s32 q3, q2, q15 // q3 = (ox0 + ox1 + 1)<<shift + vsub.s32 q4, q10 + ldr r9, [sp, #132] // src2stride + lsl r9, #1 + mov r10, r11 // r10 store startpoint src2 +0: loadin8 + cmp r5, #4 + beq 4f +8: subs r4, #1 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmovl.s16 q13, d15 + vmul.s32 q14, q12, q6 // src * w1 + vmul.s32 q15, q13, q6 // src * w1 + vld1.16 {q0}, [r11], r9 // load 8x16 bit pixels from src2 to q0 + vmovl.s16 q2, d0 // extend signed 4x16bit to 4x32 bit + vmovl.s16 q5, d1 + vmul.s32 q2, q1 // src2 * w0 + vmul.s32 q5, q1 // src2 * w0 + vadd.s32 q14, q2 // src * w1 + src2 * w0 + vadd.s32 q15, q5 // src * w1 + src2 * w0 + vadd.s32 q14, q3 // (src* w1 + src2 * w0 +(ox0 + ox1 + 1))<<shift + vadd.s32 q15, q3 + vqshl.s32 q12, q14, q4 // shift + vqshl.s32 q13, q15, q4 // shift + vqmovun.s32 d28, q12 // narrow + vqmovun.s32 d29, q13 // narrow + vqmovn.u16 d0, q14 // narrow + vst1.8 d0, [r0], r1 + regshuffle_d8 + vld1.8 {d23}, [r2], r3 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #8 + mov r0, r6 + add r10, #16 + mov r11, r10 + add r7, #8 + mov r2, r7 + b 0b +4: subs r4, #1 + \filter + vmovl.s16 q12, d14 + vmul.s32 q14, q12, q6 + vld1.16 d0, [r11], r9 + vmovl.s16 q2, d0 + vmul.s32 q2, q1 + vadd.s32 q14, q2 + vadd.s32 q14, q3 + vqshl.s32 q12, q14, q4 // shift + vqmovun.s32 d28, q12 // narrow + vqmovn.u16 d0, q14 // narrow + vst1.32 d0[0], [r0], r1 + regshuffle_d8 + vld1.32 {d23[0]}, [r2], r3 + bne 4b +99: vpop {d8-d15} + pop {r4-r12} + bx lr +.endm + function ff_hevc_put_qpel_v1_neon_8, export=1 hevc_put_qpel_vX_neon_8 qpel_filter_1 endfunc @@ -358,6 +491,19 @@ function ff_hevc_put_qpel_uw_v3_neon_8, export=1 hevc_put_qpel_uw_vX_neon_8 qpel_filter_3 endfunc +function ff_hevc_put_qpel_wt_v1_neon_8, export=1 + hevc_put_qpel_wt_vX_neon_8 qpel_filter_1 +endfunc + +function ff_hevc_put_qpel_wt_v2_neon_8, export=1 + hevc_put_qpel_wt_vX_neon_8 qpel_filter_2 +endfunc + +function ff_hevc_put_qpel_wt_v3_neon_8, export=1 + hevc_put_qpel_wt_vX_neon_8 qpel_filter_3 +endfunc + + .macro hevc_put_qpel_hX_neon_8 filter push {r4, r5, r6, r7} ldr r4, [sp, #16] // height @@ -469,6 +615,135 @@ endfunc bx lr .endm +.macro hevc_put_qpel_wt_hX_neon_8 filter + push {r4-r12} + ldr r5, [sp, #36] // width + ldr r4, [sp, #40] // height + ldr r8, [sp, #44] // denom + ldr r9, [sp, #48] // wx1 + ldr r10,[sp, #52] // ox1 + ldr r11,[sp, #64] // src2 + vpush {d8-d15} + sub r2, #4 + mov r12, r4 + mov r6, r0 + mov r7, r2 + add r8, #6 // weight shift = denom + 6 + vdup.32 q5, r8 // dup shift to 32 bit + vneg.s32 q4, q5 // q4 = -q5 shift + vdup.32 q6, r9 // q6 wx + vdup.32 q5, r10 // q5 ox + cmp r11, #0 // if src2 != 0 goto bi mode + bne .Lbi\@ + cmp r5, #4 + beq 4f +8: subs r4, #1 + vextin8 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmovl.s16 q13, d15 + vmul.s32 q14, q12, q6 + vmul.s32 q15, q13, q6 + vqrshl.s32 q12, q14, q4 + vqrshl.s32 q13, q15, q4 + vadd.s32 q14, q12, q5 + vadd.s32 q15, q13, q5 + vqmovun.s32 d2, q14 // narrow + vqmovun.s32 d3, q15 // narrow + vqmovn.u16 d0, q1 + vst1.8 d0, [r0], r1 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #8 + mov r0, r6 + add r7, #8 + mov r2, r7 + cmp r5, #4 + bne 8b +4: subs r4, #1 + vextin8 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmul.s32 q14, q12, q6 + vqrshl.s32 q12, q14, q4 + vadd.s32 q14, q12, q5 + vqmovun.s32 d14, q14 + vqmovn.u16 d0, q7 + vst1.32 d0[0], [r0], r1 + bne 4b + b 99f +.Lbi\@: + ldr r8, [sp, #120] // w0 + vdup.32 q1, r8 // q1 wx0 + ldr r8, [sp, #124] // ox0 + vdup.32 q2, r8 // q2 ox0 + vadd.s32 q2, q5 // q2 = ox0 +ox1 + vmov.s32 q10, #1 + vadd.s32 q2, q10 // q2 = ox0 +ox1 + 1 + vneg.s32 q15, q4 // q15 = - q4, preperation for left shift + vqrshl.s32 q3, q2, q15 // q3 = (ox0 + ox1 + 1)<<shift + vsub.s32 q4, q10 + ldr r9, [sp, #132] // src2stride + lsl r9, #1 + cmp r5, #4 + beq 4f + mov r10, r11 +8: subs r4, #1 + vextin8 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmovl.s16 q13, d15 + vmul.s32 q14, q12, q6 // src * w1 + vmul.s32 q15, q13, q6 // src * w1 + vld1.16 {q0}, [r11], r9 // load 8x16 bit pixels from src2 to q0 + vmovl.s16 q2, d0 // extend signed 4x16bit to 4x32 bit + vmovl.s16 q5, d1 + vmul.s32 q2, q1 // src2 * w0 + vmul.s32 q5, q1 // src2 * w0 + vadd.s32 q14, q2 // src * w1 + src2 * w0 + vadd.s32 q15, q5 // src * w1 + src2 * w0 + vadd.s32 q14, q3 // (src* w1 + src2 * w0 +(ox0 + ox1 + 1))<<shift + vadd.s32 q15, q3 + vqshl.s32 q12, q14, q4 // shift + vqshl.s32 q13, q15, q4 // shift + vqmovun.s32 d28, q12 // narrow + vqmovun.s32 d29, q13 // narrow + vqmovn.u16 d0, q14 // narrow + vst1.8 d0, [r0], r1 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #8 + add r10, #16 + mov r11, r10 + mov r0, r6 + add r7, #8 + mov r2, r7 + cmp r5, #4 + bne 8b +4: subs r4, #1 + vextin8 + \filter + vmovl.s16 q12, d14 + vmul.s32 q14, q12, q6 + vld1.16 d0, [r11], r9 + vmovl.s16 q2, d0 + vmul.s32 q2, q1 + vadd.s32 q14, q2 + vadd.s32 q14, q3 + vqshl.s32 q12, q14, q4 // shift + vqmovun.s32 d28, q12 // narrow + vqmovn.u16 d0, q14 // narrow + vst1.32 d0[0], [r0], r1 + bne 4b +99: vpop {d8-d15} + pop {r4-r12} + bx lr +.endm + function ff_hevc_put_qpel_h1_neon_8, export=1 hevc_put_qpel_hX_neon_8 qpel_filter_1 endfunc @@ -494,6 +769,18 @@ function ff_hevc_put_qpel_uw_h3_neon_8, export=1 hevc_put_qpel_uw_hX_neon_8 qpel_filter_3 endfunc +function ff_hevc_put_qpel_wt_h1_neon_8, export=1 + hevc_put_qpel_wt_hX_neon_8 qpel_filter_1 +endfunc + +function ff_hevc_put_qpel_wt_h2_neon_8, export=1 + hevc_put_qpel_wt_hX_neon_8 qpel_filter_2 +endfunc + +function ff_hevc_put_qpel_wt_h3_neon_8, export=1 + hevc_put_qpel_wt_hX_neon_8 qpel_filter_3 +endfunc + .macro hevc_put_qpel_hXvY_neon_8 filterh filterv push {r4, r5, r6, r7} ldr r4, [sp, #16] // height @@ -665,6 +952,192 @@ endfunc bx lr .endm +.macro hevc_put_qpel_wt_hXvY_neon_8 filterh filterv + push {r4-r12} + ldr r5, [sp, #36] // width + ldr r4, [sp, #40] // height + ldr r8, [sp, #44] // denom + ldr r9, [sp, #48] // wx + ldr r10,[sp, #52] // ox + ldr r11,[sp, #64] //src2 + vpush {d8-d15} + sub r2, #4 + sub r2, r2, r3, lsl #1 + sub r2, r3 // extra_before 3 + mov r12, r4 + mov r6, r0 + mov r7, r2 + add r8, #6 + vdup.32 q6, r8 + vneg.s32 q5, q6 // q5 shift + vdup.32 q4, r9 // q4 wx + vdup.32 q6, r10 // q6 ox + vpush {q4-q6} + cmp r11, #0 + bne .Lbi\@ +0: vextin8 + \filterh q0 + vextin8 + \filterh q1 + vextin8 + \filterh q2 + vextin8 + \filterh q3 + vextin8 + \filterh q4 + vextin8 + \filterh q5 + vextin8 + \filterh q6 + vextin8 + \filterh q7 + cmp r5, #4 + beq 4f +8: subs r4, #1 + \filterv + vpop {q9-q11} // q9: wx q10: shift q11: ox + vmovl.s16 q12, d16 + vmovl.s16 q13, d17 + vmul.s32 q14, q12, q9 + vmul.s32 q15, q13, q9 + vqrshl.s32 q12, q14, q10 + vqrshl.s32 q13, q15, q10 + vadd.s32 q14, q12, q11 + vadd.s32 q15, q13, q11 + vqmovun.s32 d24, q14 + vqmovun.s32 d25, q15 + vqmovn.u16 d0, q12 + vst1.8 d0, [r0], r1 + vpush {q9-q11} + regshuffle_q8 + vextin8 + \filterh q7 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #8 + mov r0, r6 + add r7, #8 + mov r2, r7 + b 0b +4: subs r4, #1 + \filterv + vpop {q9-q11} // q9: wx q10: shift q11: ox + vmovl.s16 q12, d16 + vmul.s32 q14, q12, q9 + vqrshl.s32 q12, q14, q10 + vadd.s32 q14, q12, q11 + vqmovun.s32 d24, q14 + vqmovn.u16 d0, q12 + vst1.32 d0[0], [r0], r1 + vpush {q9-q11} + regshuffle_q8 + vextin8 + \filterh q7 + bne 4b + b 99f +.Lbi\@: ldr r8, [sp, #168] // w0 + vdup.32 q1, r8 // q1 wx0 + ldr r8, [sp, #172] // ox0 + vdup.32 q3, r8 // dup ox0 to q3 + ldr r9, [sp, #180] // src2stride + lsl r9, #1 + vpop {q9-q11} // q9: wx q10: shift q11: ox + vadd.s32 q3, q11 // q3 = ox0 + ox1 + vmov.s32 q4, #1 + vadd.s32 q3, q4 // q3 = ox0 + ox1 + 1 + vneg.s32 q15, q10 // q15 = -shift, prepare for left shift + vqrshl.s32 q2, q3, q15 // q2 = (ox0 + ox1 + 1)<<shift + vsub.s32 q10, q4 // q10 final shift = demon + #7 + vmov.s32 q3, q10 + vmov.s32 q4, q9 + vpush {q1-q4} // q1: wx0, q2: final offset, q3: final shift, q4: wx1 + mov r10, r11 // r10 store startpoint src2 +0: vextin8 + \filterh q0 + vextin8 + \filterh q1 + vextin8 + \filterh q2 + vextin8 + \filterh q3 + vextin8 + \filterh q4 + vextin8 + \filterh q5 + vextin8 + \filterh q6 + vextin8 + \filterh q7 + cmp r5, #4 + beq 4f +8: subs r4, #1 + \filterv + vpop {q9-q12} // q9: wx0, q10: final offset, q11: final shift, q4: wx1 + vmovl.s16 q13, d16 // move long filter result from q8 to q12 + vmovl.s16 q14, d17 // move long filter result from q8 to q13 + vmul.s32 q13, q12 // src * wx1 + vmul.s32 q14, q12 // src * wx1 + vld1.16 {q0}, [r11], r9 + vmovl.s16 q8, d0 + vmovl.s16 q15, d1 + vmul.s32 q8, q9 // src2 * wx0 + vmul.s32 q15, q9 // src2 * wx0 + vadd.s32 q13, q8 // src * wx1 + src2 * wx0 + vadd.s32 q14, q15 // src * wx1 + src2 * wx0 + vadd.s32 q13, q10 // src * wx1 + src2 * wx0 + offset + vadd.s32 q14, q10 // src * wx1 + src2 * wx0 + offset + vqshl.s32 q8, q13, q11 // shift + vqshl.s32 q15, q14, q11 // shift + vqmovun.s32 d28, q8 // narrow + vqmovun.s32 d29, q15 // narrow + vqmovn.u16 d0, q14 // narrow + vst1.8 d0, [r0], r1 // store + vpush {q9-q12} // push + regshuffle_q8 + vextin8 + \filterh q7 + bne 8b + subs r5, #8 + beq 98f + mov r4, r12 + add r6, #8 + mov r0, r6 + add r10, #16 + mov r11, r10 + add r7, #8 + mov r2, r7 + b 0b +4: subs r4, #1 + \filterv + vpop {q9-q12} // q9: wx0, q10: final offset, q11: final shift, q4: wx1 + vmovl.s16 q13, d16 // move long filter result from q8 to q12 + vmul.s32 q13, q12 // src * wx1 + vld1.16 d0, [r11], r9 + vmovl.s16 q8, d0 + vmul.s32 q8, q9 // src2 * wx0 + vadd.s32 q13, q8 // src * wx1 + src2 * wx0 + vadd.s32 q13, q10 // src * wx1 + src2 * wx0 + offset + vqshl.s32 q8, q13, q11 // shift + vqmovun.s32 d28, q8 // narrow + vqmovn.u16 d0, q14 // narrow + vst1.32 d0[0], [r0], r1 + vpush {q9-q12} // push + regshuffle_q8 + vextin8 + \filterh q7 + bne 4b +98: vpop {q9-q12} + vpop {d8-d15} + pop {r4-r12} + bx lr +99: vpop {q9-q11} + vpop {d8-d15} + pop {r4-r12} + bx lr +.endm + function ff_hevc_put_qpel_h1v1_neon_8, export=1 hevc_put_qpel_hXvY_neon_8 qpel_filter_1 qpel_filter_1_32b @@ -739,6 +1212,42 @@ function ff_hevc_put_qpel_uw_h3v3_neon_8, export=1 hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_3 qpel_filter_3_32b endfunc +function ff_hevc_put_qpel_wt_h1v1_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_1 qpel_filter_1_32b +endfunc + +function ff_hevc_put_qpel_wt_h2v1_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_2 qpel_filter_1_32b +endfunc + +function ff_hevc_put_qpel_wt_h3v1_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_3 qpel_filter_1_32b +endfunc + +function ff_hevc_put_qpel_wt_h1v2_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_1 qpel_filter_2_32b +endfunc + +function ff_hevc_put_qpel_wt_h2v2_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_2 qpel_filter_2_32b +endfunc + +function ff_hevc_put_qpel_wt_h3v2_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_3 qpel_filter_2_32b +endfunc + +function ff_hevc_put_qpel_wt_h1v3_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_1 qpel_filter_3_32b +endfunc + +function ff_hevc_put_qpel_wt_h2v3_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_2 qpel_filter_3_32b +endfunc + +function ff_hevc_put_qpel_wt_h3v3_neon_8, export=1 + hevc_put_qpel_wt_hXvY_neon_8 qpel_filter_3 qpel_filter_3_32b +endfunc + .macro init_put_pixels pld [r1] pld [r1, r2] -- 2.13.6 (Apple Git-96) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel