From: James Yu <[email protected]> Using NEON intrinsics to support ARMv7 and ARMv8 simultaneously. Rewrite ARMv7 assembly to intinsics version.
Toolchain: armv7: gcc-linaro-arm-linux-gnueabihf-4.8-2014.01_linux armv8: gcc-linaro-aarch64-linux-gnu-4.8-2013.10_linux [RFC] Currently, libavcodec had a aarch64 dir includes all related assembly code. However, I put this file under libavcodec/arm dir first, since this support ARMv7 and ARMv8 simultaneously. And RFC how could we port and optimize libav to aarch64. Add libavcodec/arm/mpegvideo_neon.c. Signed-off-by: James Yu <[email protected]> --- libavcodec/aarch64/Makefile | 1 + libavcodec/arm/mpegvideo_neon.c | 127 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 libavcodec/arm/mpegvideo_neon.c diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile index b0ebeb3..97dfb79 100644 --- a/libavcodec/aarch64/Makefile +++ b/libavcodec/aarch64/Makefile @@ -24,3 +24,4 @@ NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o NEON-OBJS-$(CONFIG_MDCT) += aarch64/mdct_neon.o NEON-OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_neon.o +NEON-OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_neon.o diff --git a/libavcodec/arm/mpegvideo_neon.c b/libavcodec/arm/mpegvideo_neon.c new file mode 100644 index 0000000..dcc1204 --- /dev/null +++ b/libavcodec/arm/mpegvideo_neon.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2010 Mans Rullgard + * Copyright (c) 2014 James Yu <[email protected]> + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <arm_neon.h> +#include "libavutil/avassert.h" +#include "libavcodec/mpegvideo.h" + +void ff_dct_unquantize_h263_inter_neon(MpegEncContext *s, int16_t *block, + int n, int qscale); +void ff_dct_unquantize_h263_intra_neon(MpegEncContext *s, int16_t *block, + int n, int qscale); + +static void inline ff_dct_unquantize_h263_neon(int qmul, int qadd, + int nCoeffs, int16_t *block) +{ + int16x8_t q0s16, q2s16, q3s16, q8s16, q10s16, q11s16, q13s16; + int16x8_t q14s16, q15s16, qzs16; + int16x4_t d0s16, d2s16, d3s16, dzs16; + uint16x8_t q1u16, q9u16; + uint16x4_t d1u16; + + dzs16 = vdup_n_s16(0); + qzs16 = vdupq_n_s16(0); + + q15s16 = vdupq_n_s16(qmul); + q14s16 = vdupq_n_s16(qadd); + q13s16 = vnegq_s16(q14s16); + + if (nCoeffs > 4) { + for (; nCoeffs > 8; nCoeffs -= 16, block += 16) { + q0s16 = vld1q_s16(block); + q3s16 = vreinterpretq_s16_u16(vcltq_s16(q0s16, qzs16)); + q8s16 = vld1q_s16(block + 8); + q1u16 = vceqq_s16(q0s16, qzs16); + q2s16 = vmulq_s16(q0s16, q15s16); + q11s16 = vreinterpretq_s16_u16(vcltq_s16(q8s16, qzs16)); + q10s16 = vmulq_s16(q8s16, q15s16); + q3s16 = vbslq_s16(vreinterpretq_u16_s16(q3s16), q13s16, q14s16); + q11s16 = vbslq_s16(vreinterpretq_u16_s16(q11s16), q13s16, q14s16); + q2s16 = vaddq_s16(q2s16, q3s16); + q9u16 = vceqq_s16(q8s16, qzs16); + q10s16 = vaddq_s16(q10s16, q11s16); + q0s16 = vbslq_s16(q1u16, q0s16, q2s16); + q8s16 = vbslq_s16(q9u16, q8s16, q10s16); + vst1q_s16(block, q0s16); + vst1q_s16(block + 8, q8s16); + } + } + if (nCoeffs <= 0) + return; + + d0s16 = vld1_s16(block); + d3s16 = vreinterpret_s16_u16(vclt_s16(d0s16, dzs16)); + d1u16 = vceq_s16(d0s16, dzs16); + d2s16 = vmul_s16(d0s16, vget_high_s16(q15s16)); + d3s16 = vbsl_s16(vreinterpret_u16_s16(d3s16), + vget_high_s16(q13s16), vget_high_s16(q14s16)); + d2s16 = vadd_s16(d2s16, d3s16); + d0s16 = vbsl_s16(d1u16, d0s16, d2s16); + vst1_s16(block, d0s16); +} + +void ff_dct_unquantize_h263_inter_neon(MpegEncContext *s, int16_t *block, + int n, int qscale) +{ + int qmul, qadd; + int nCoeffs; + + qadd = (qscale - 1) | 1; + qmul = qscale << 1; + + nCoeffs = s->inter_scantable.raster_end[s->block_last_index[n]]; + + ff_dct_unquantize_h263_neon(qmul, qadd, nCoeffs, block); +} + +void ff_dct_unquantize_h263_intra_neon(MpegEncContext *s, int16_t *block, + int n, int qscale) +{ + int qmul, qadd; + int nCoeffs, blk0; + + av_assert0(s->block_last_index[n] >= 0); + + qmul = qscale << 1; + + if (!s->h263_aic) { + if (n < 4) { + block[0] = block[0] * s->y_dc_scale; + } else + block[0] = block[0] * s->c_dc_scale; + qadd = (qscale - 1) | 1; + } else + qadd = 0; + + if (s->ac_pred) { + nCoeffs = 63; + } else { + nCoeffs = s->inter_scantable.raster_end[s->block_last_index[n]]; + if (nCoeffs <= 0) + return; + } + + blk0 = block[0]; + + ff_dct_unquantize_h263_neon(qmul, qadd, nCoeffs + 1, block); + + block[0] = blk0; +} -- 1.7.9.5 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
