...
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
clean::
|
||||
$(RM) $(CLEANSUFFIXES:%=libavcodec/x86/hevc/%) $(CLEANSUFFIXES:%=libavcodec/x86/h26x/%)
|
||||
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc/dsp_init.o \
|
||||
x86/h26x/h2656dsp.o
|
||||
X86ASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc/add_res.o \
|
||||
x86/hevc/deblock.o \
|
||||
x86/hevc/idct.o \
|
||||
x86/hevc/mc.o \
|
||||
x86/hevc/sao.o \
|
||||
x86/hevc/sao_10bit.o \
|
||||
x86/h26x/h2656_inter.o
|
||||
@@ -0,0 +1,369 @@
|
||||
; *****************************************************************************
|
||||
; * Provide SIMD optimizations for add_residual functions for HEVC decoding
|
||||
; * Copyright (c) 2014 Pierre-Edouard LEPERE
|
||||
; *
|
||||
; * This file is part of FFmpeg.
|
||||
; *
|
||||
; * FFmpeg 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.
|
||||
; *
|
||||
; * FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
; * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
; ******************************************************************************
|
||||
|
||||
%include "libavutil/x86/x86util.asm"
|
||||
|
||||
SECTION .text
|
||||
|
||||
cextern pw_1023
|
||||
%define max_pixels_10 pw_1023
|
||||
|
||||
; the add_res macros and functions were largely inspired by h264_idct.asm from the x264 project
|
||||
%macro ADD_RES_MMX_4_8 0
|
||||
mova m0, [r1]
|
||||
mova m2, [r1+8]
|
||||
|
||||
movd m1, [r0]
|
||||
movd m3, [r0+r2]
|
||||
punpcklbw m1, m4
|
||||
punpcklbw m3, m4
|
||||
|
||||
paddsw m0, m1
|
||||
paddsw m2, m3
|
||||
packuswb m0, m4
|
||||
packuswb m2, m4
|
||||
|
||||
movd [r0], m0
|
||||
movd [r0+r2], m2
|
||||
%endmacro
|
||||
|
||||
|
||||
INIT_MMX mmxext
|
||||
; void ff_hevc_add_residual_4_8_mmxext(uint8_t *dst, const int16_t *res, ptrdiff_t stride)
|
||||
cglobal hevc_add_residual_4_8, 3, 3, 6
|
||||
pxor m4, m4
|
||||
ADD_RES_MMX_4_8
|
||||
add r1, 16
|
||||
lea r0, [r0+r2*2]
|
||||
ADD_RES_MMX_4_8
|
||||
RET
|
||||
|
||||
%macro ADD_RES_SSE_8_8 0
|
||||
movq m0, [r0]
|
||||
movq m1, [r0+r2]
|
||||
punpcklbw m0, m4
|
||||
punpcklbw m1, m4
|
||||
mova m2, [r1]
|
||||
mova m3, [r1+16]
|
||||
paddsw m0, m2
|
||||
paddsw m1, m3
|
||||
packuswb m0, m1
|
||||
|
||||
movq m2, [r0+r2*2]
|
||||
movq m3, [r0+r3]
|
||||
punpcklbw m2, m4
|
||||
punpcklbw m3, m4
|
||||
mova m6, [r1+32]
|
||||
mova m7, [r1+48]
|
||||
paddsw m2, m6
|
||||
paddsw m3, m7
|
||||
packuswb m2, m3
|
||||
|
||||
movq [r0], m0
|
||||
movhps [r0+r2], m0
|
||||
movq [r0+r2*2], m2
|
||||
movhps [r0+r3], m2
|
||||
%endmacro
|
||||
|
||||
%macro ADD_RES_SSE_16_32_8 3
|
||||
mova m1, [%2]
|
||||
mova m2, m1
|
||||
punpcklbw m1, m0
|
||||
punpckhbw m2, m0
|
||||
mova xm5, [r1+%1]
|
||||
mova xm6, [r1+%1+16]
|
||||
%if cpuflag(avx2)
|
||||
vinserti128 m5, m5, [r1+%1+32], 1
|
||||
vinserti128 m6, m6, [r1+%1+48], 1
|
||||
%endif
|
||||
paddsw m1, m5
|
||||
paddsw m2, m6
|
||||
|
||||
mova m3, [%3]
|
||||
mova m4, m3
|
||||
punpcklbw m3, m0
|
||||
punpckhbw m4, m0
|
||||
mova xm5, [r1+%1+mmsize*2]
|
||||
mova xm6, [r1+%1+mmsize*2+16]
|
||||
%if cpuflag(avx2)
|
||||
vinserti128 m5, m5, [r1+%1+96], 1
|
||||
vinserti128 m6, m6, [r1+%1+112], 1
|
||||
%endif
|
||||
paddsw m3, m5
|
||||
paddsw m4, m6
|
||||
|
||||
packuswb m1, m2
|
||||
packuswb m3, m4
|
||||
mova [%2], m1
|
||||
mova [%3], m3
|
||||
%endmacro
|
||||
|
||||
|
||||
%macro TRANSFORM_ADD_8 0
|
||||
; void ff_hevc_add_residual_8_8_<opt>(uint8_t *dst, const int16_t *res, ptrdiff_t stride)
|
||||
cglobal hevc_add_residual_8_8, 3, 4, 8
|
||||
pxor m4, m4
|
||||
lea r3, [r2*3]
|
||||
ADD_RES_SSE_8_8
|
||||
add r1, 64
|
||||
lea r0, [r0+r2*4]
|
||||
ADD_RES_SSE_8_8
|
||||
RET
|
||||
|
||||
; void ff_hevc_add_residual_16_8_<opt>(uint8_t *dst, const int16_t *res, ptrdiff_t stride)
|
||||
cglobal hevc_add_residual_16_8, 3, 5, 7
|
||||
pxor m0, m0
|
||||
lea r3, [r2*3]
|
||||
mov r4d, 4
|
||||
.loop:
|
||||
ADD_RES_SSE_16_32_8 0, r0, r0+r2
|
||||
ADD_RES_SSE_16_32_8 64, r0+r2*2, r0+r3
|
||||
add r1, 128
|
||||
lea r0, [r0+r2*4]
|
||||
dec r4d
|
||||
jg .loop
|
||||
RET
|
||||
|
||||
; void ff_hevc_add_residual_32_8_<opt>(uint8_t *dst, const int16_t *res, ptrdiff_t stride)
|
||||
cglobal hevc_add_residual_32_8, 3, 5, 7
|
||||
pxor m0, m0
|
||||
mov r4d, 16
|
||||
.loop:
|
||||
ADD_RES_SSE_16_32_8 0, r0, r0+16
|
||||
ADD_RES_SSE_16_32_8 64, r0+r2, r0+r2+16
|
||||
add r1, 128
|
||||
lea r0, [r0+r2*2]
|
||||
dec r4d
|
||||
jg .loop
|
||||
RET
|
||||
%endmacro
|
||||
|
||||
INIT_XMM sse2
|
||||
TRANSFORM_ADD_8
|
||||
INIT_XMM avx
|
||||
TRANSFORM_ADD_8
|
||||
|
||||
%if HAVE_AVX2_EXTERNAL
|
||||
INIT_YMM avx2
|
||||
; void ff_hevc_add_residual_32_8_avx2(uint8_t *dst, const int16_t *res, ptrdiff_t stride)
|
||||
cglobal hevc_add_residual_32_8, 3, 5, 7
|
||||
pxor m0, m0
|
||||
lea r3, [r2*3]
|
||||
mov r4d, 8
|
||||
.loop:
|
||||
ADD_RES_SSE_16_32_8 0, r0, r0+r2
|
||||
ADD_RES_SSE_16_32_8 128, r0+r2*2, r0+r3
|
||||
add r1, 256
|
||||
lea r0, [r0+r2*4]
|
||||
dec r4d
|
||||
jg .loop
|
||||
RET
|
||||
%endif ;HAVE_AVX2_EXTERNAL
|
||||
|
||||
%macro ADD_RES_SSE_8_10 4
|
||||
mova m0, [%4]
|
||||
mova m1, [%4+16]
|
||||
mova m2, [%4+32]
|
||||
mova m3, [%4+48]
|
||||
paddw m0, [%1+0]
|
||||
paddw m1, [%1+%2]
|
||||
paddw m2, [%1+%2*2]
|
||||
paddw m3, [%1+%3]
|
||||
CLIPW m0, m4, m5
|
||||
CLIPW m1, m4, m5
|
||||
CLIPW m2, m4, m5
|
||||
CLIPW m3, m4, m5
|
||||
mova [%1+0], m0
|
||||
mova [%1+%2], m1
|
||||
mova [%1+%2*2], m2
|
||||
mova [%1+%3], m3
|
||||
%endmacro
|
||||
|
||||
%macro ADD_RES_MMX_4_10 3
|
||||
mova m0, [%1+0]
|
||||
mova m1, [%1+%2]
|
||||
paddw m0, [%3]
|
||||
paddw m1, [%3+8]
|
||||
CLIPW m0, m2, m3
|
||||
CLIPW m1, m2, m3
|
||||
mova [%1+0], m0
|
||||
mova [%1+%2], m1
|
||||
%endmacro
|
||||
|
||||
%macro ADD_RES_SSE_16_10 3
|
||||
mova m0, [%3]
|
||||
mova m1, [%3+16]
|
||||
mova m2, [%3+32]
|
||||
mova m3, [%3+48]
|
||||
paddw m0, [%1]
|
||||
paddw m1, [%1+16]
|
||||
paddw m2, [%1+%2]
|
||||
paddw m3, [%1+%2+16]
|
||||
CLIPW m0, m4, m5
|
||||
CLIPW m1, m4, m5
|
||||
CLIPW m2, m4, m5
|
||||
CLIPW m3, m4, m5
|
||||
mova [%1], m0
|
||||
mova [%1+16], m1
|
||||
mova [%1+%2], m2
|
||||
mova [%1+%2+16], m3
|
||||
%endmacro
|
||||
|
||||
%macro ADD_RES_SSE_32_10 2
|
||||
mova m0, [%2]
|
||||
mova m1, [%2+16]
|
||||
mova m2, [%2+32]
|
||||
mova m3, [%2+48]
|
||||
|
||||
paddw m0, [%1]
|
||||
paddw m1, [%1+16]
|
||||
paddw m2, [%1+32]
|
||||
paddw m3, [%1+48]
|
||||
CLIPW m0, m4, m5
|
||||
CLIPW m1, m4, m5
|
||||
CLIPW m2, m4, m5
|
||||
CLIPW m3, m4, m5
|
||||
mova [%1], m0
|
||||
mova [%1+16], m1
|
||||
mova [%1+32], m2
|
||||
mova [%1+48], m3
|
||||
%endmacro
|
||||
|
||||
%macro ADD_RES_AVX2_16_10 4
|
||||
mova m0, [%4]
|
||||
mova m1, [%4+32]
|
||||
mova m2, [%4+64]
|
||||
mova m3, [%4+96]
|
||||
|
||||
paddw m0, [%1+0]
|
||||
paddw m1, [%1+%2]
|
||||
paddw m2, [%1+%2*2]
|
||||
paddw m3, [%1+%3]
|
||||
|
||||
CLIPW m0, m4, m5
|
||||
CLIPW m1, m4, m5
|
||||
CLIPW m2, m4, m5
|
||||
CLIPW m3, m4, m5
|
||||
mova [%1+0], m0
|
||||
mova [%1+%2], m1
|
||||
mova [%1+%2*2], m2
|
||||
mova [%1+%3], m3
|
||||
%endmacro
|
||||
|
||||
%macro ADD_RES_AVX2_32_10 3
|
||||
mova m0, [%3]
|
||||
mova m1, [%3+32]
|
||||
mova m2, [%3+64]
|
||||
mova m3, [%3+96]
|
||||
|
||||
paddw m0, [%1]
|
||||
paddw m1, [%1+32]
|
||||
paddw m2, [%1+%2]
|
||||
paddw m3, [%1+%2+32]
|
||||
|
||||
CLIPW m0, m4, m5
|
||||
CLIPW m1, m4, m5
|
||||
CLIPW m2, m4, m5
|
||||
CLIPW m3, m4, m5
|
||||
mova [%1], m0
|
||||
mova [%1+32], m1
|
||||
mova [%1+%2], m2
|
||||
mova [%1+%2+32], m3
|
||||
%endmacro
|
||||
|
||||
; void ff_hevc_add_residual_<4|8|16|32>_10(pixel *dst, const int16_t *block, ptrdiff_t stride)
|
||||
INIT_MMX mmxext
|
||||
cglobal hevc_add_residual_4_10, 3, 3, 6
|
||||
pxor m2, m2
|
||||
mova m3, [max_pixels_10]
|
||||
ADD_RES_MMX_4_10 r0, r2, r1
|
||||
add r1, 16
|
||||
lea r0, [r0+2*r2]
|
||||
ADD_RES_MMX_4_10 r0, r2, r1
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal hevc_add_residual_8_10, 3, 4, 6
|
||||
pxor m4, m4
|
||||
mova m5, [max_pixels_10]
|
||||
lea r3, [r2*3]
|
||||
|
||||
ADD_RES_SSE_8_10 r0, r2, r3, r1
|
||||
lea r0, [r0+r2*4]
|
||||
add r1, 64
|
||||
ADD_RES_SSE_8_10 r0, r2, r3, r1
|
||||
RET
|
||||
|
||||
cglobal hevc_add_residual_16_10, 3, 5, 6
|
||||
pxor m4, m4
|
||||
mova m5, [max_pixels_10]
|
||||
|
||||
mov r4d, 8
|
||||
.loop:
|
||||
ADD_RES_SSE_16_10 r0, r2, r1
|
||||
lea r0, [r0+r2*2]
|
||||
add r1, 64
|
||||
dec r4d
|
||||
jg .loop
|
||||
RET
|
||||
|
||||
cglobal hevc_add_residual_32_10, 3, 5, 6
|
||||
pxor m4, m4
|
||||
mova m5, [max_pixels_10]
|
||||
|
||||
mov r4d, 32
|
||||
.loop:
|
||||
ADD_RES_SSE_32_10 r0, r1
|
||||
lea r0, [r0+r2]
|
||||
add r1, 64
|
||||
dec r4d
|
||||
jg .loop
|
||||
RET
|
||||
|
||||
%if HAVE_AVX2_EXTERNAL
|
||||
INIT_YMM avx2
|
||||
cglobal hevc_add_residual_16_10, 3, 5, 6
|
||||
pxor m4, m4
|
||||
mova m5, [max_pixels_10]
|
||||
lea r3, [r2*3]
|
||||
|
||||
mov r4d, 4
|
||||
.loop:
|
||||
ADD_RES_AVX2_16_10 r0, r2, r3, r1
|
||||
lea r0, [r0+r2*4]
|
||||
add r1, 128
|
||||
dec r4d
|
||||
jg .loop
|
||||
RET
|
||||
|
||||
cglobal hevc_add_residual_32_10, 3, 5, 6
|
||||
pxor m4, m4
|
||||
mova m5, [max_pixels_10]
|
||||
|
||||
mov r4d, 16
|
||||
.loop:
|
||||
ADD_RES_AVX2_32_10 r0, r2, r1
|
||||
lea r0, [r0+r2*2]
|
||||
add r1, 128
|
||||
dec r4d
|
||||
jg .loop
|
||||
RET
|
||||
%endif ;HAVE_AVX2_EXTERNAL
|
||||
@@ -0,0 +1,893 @@
|
||||
;*****************************************************************************
|
||||
;* SSE2-optimized HEVC deblocking code
|
||||
;*****************************************************************************
|
||||
;* Copyright (C) 2013 VTT
|
||||
;*
|
||||
;* Authors: Seppo Tomperi <seppo.tomperi@vtt.fi>
|
||||
;*
|
||||
;* This file is part of FFmpeg.
|
||||
;*
|
||||
;* FFmpeg 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.
|
||||
;*
|
||||
;* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
;******************************************************************************
|
||||
|
||||
%include "libavutil/x86/x86util.asm"
|
||||
|
||||
SECTION_RODATA
|
||||
|
||||
cextern pw_1023
|
||||
%define pw_pixel_max_10 pw_1023
|
||||
pw_pixel_max_12: times 8 dw ((1 << 12)-1)
|
||||
pw_m2: times 8 dw -2
|
||||
pd_1 : times 4 dd 1
|
||||
|
||||
cextern pw_4
|
||||
cextern pw_8
|
||||
cextern pw_m1
|
||||
|
||||
SECTION .text
|
||||
INIT_XMM sse2
|
||||
|
||||
; in: 8 rows of 4 bytes in %4..%11
|
||||
; out: 4 rows of 8 words in m0..m3
|
||||
%macro TRANSPOSE4x8B_LOAD 8
|
||||
movd m0, %1
|
||||
movd m2, %2
|
||||
movd m1, %3
|
||||
movd m3, %4
|
||||
|
||||
punpcklbw m0, m2
|
||||
punpcklbw m1, m3
|
||||
punpcklwd m0, m1
|
||||
|
||||
movd m4, %5
|
||||
movd m6, %6
|
||||
movd m5, %7
|
||||
movd m3, %8
|
||||
|
||||
punpcklbw m4, m6
|
||||
punpcklbw m5, m3
|
||||
punpcklwd m4, m5
|
||||
|
||||
punpckhdq m2, m0, m4
|
||||
punpckldq m0, m4
|
||||
|
||||
pxor m5, m5
|
||||
punpckhbw m1, m0, m5
|
||||
punpcklbw m0, m5
|
||||
punpckhbw m3, m2, m5
|
||||
punpcklbw m2, m5
|
||||
%endmacro
|
||||
|
||||
; in: 4 rows of 8 words in m0..m3
|
||||
; out: 8 rows of 4 bytes in %1..%8
|
||||
%macro TRANSPOSE8x4B_STORE 8
|
||||
packuswb m0, m2
|
||||
packuswb m1, m3
|
||||
SBUTTERFLY bw, 0, 1, 2
|
||||
SBUTTERFLY wd, 0, 1, 2
|
||||
|
||||
movd %1, m0
|
||||
pshufd m0, m0, 0x39
|
||||
movd %2, m0
|
||||
pshufd m0, m0, 0x39
|
||||
movd %3, m0
|
||||
pshufd m0, m0, 0x39
|
||||
movd %4, m0
|
||||
|
||||
movd %5, m1
|
||||
pshufd m1, m1, 0x39
|
||||
movd %6, m1
|
||||
pshufd m1, m1, 0x39
|
||||
movd %7, m1
|
||||
pshufd m1, m1, 0x39
|
||||
movd %8, m1
|
||||
%endmacro
|
||||
|
||||
; in: 8 rows of 4 words in %4..%11
|
||||
; out: 4 rows of 8 words in m0..m3
|
||||
%macro TRANSPOSE4x8W_LOAD 8
|
||||
movq m0, %1
|
||||
movq m2, %2
|
||||
movq m1, %3
|
||||
movq m3, %4
|
||||
|
||||
punpcklwd m0, m2
|
||||
punpcklwd m1, m3
|
||||
punpckhdq m2, m0, m1
|
||||
punpckldq m0, m1
|
||||
|
||||
movq m4, %5
|
||||
movq m6, %6
|
||||
movq m5, %7
|
||||
movq m3, %8
|
||||
|
||||
punpcklwd m4, m6
|
||||
punpcklwd m5, m3
|
||||
punpckhdq m6, m4, m5
|
||||
punpckldq m4, m5
|
||||
|
||||
punpckhqdq m1, m0, m4
|
||||
punpcklqdq m0, m4
|
||||
punpckhqdq m3, m2, m6
|
||||
punpcklqdq m2, m6
|
||||
|
||||
%endmacro
|
||||
|
||||
; in: 4 rows of 8 words in m0..m3
|
||||
; out: 8 rows of 4 words in %1..%8
|
||||
%macro TRANSPOSE8x4W_STORE 9
|
||||
TRANSPOSE4x4W 0, 1, 2, 3, 4
|
||||
|
||||
pxor m5, m5; zeros reg
|
||||
CLIPW m0, m5, %9
|
||||
CLIPW m1, m5, %9
|
||||
CLIPW m2, m5, %9
|
||||
CLIPW m3, m5, %9
|
||||
|
||||
movq %1, m0
|
||||
movhps %2, m0
|
||||
movq %3, m1
|
||||
movhps %4, m1
|
||||
movq %5, m2
|
||||
movhps %6, m2
|
||||
movq %7, m3
|
||||
movhps %8, m3
|
||||
%endmacro
|
||||
|
||||
; in: 8 rows of 8 bytes in %1..%8
|
||||
; out: 8 rows of 8 words in m0..m7
|
||||
%macro TRANSPOSE8x8B_LOAD 8
|
||||
movq m7, %1
|
||||
movq m2, %2
|
||||
movq m1, %3
|
||||
movq m3, %4
|
||||
|
||||
punpcklbw m7, m2
|
||||
punpcklbw m1, m3
|
||||
punpcklwd m3, m7, m1
|
||||
punpckhwd m7, m1
|
||||
|
||||
movq m4, %5
|
||||
movq m6, %6
|
||||
movq m5, %7
|
||||
movq m15, %8
|
||||
|
||||
punpcklbw m4, m6
|
||||
punpcklbw m5, m15
|
||||
punpcklwd m9, m4, m5
|
||||
punpckhwd m4, m5
|
||||
|
||||
punpckldq m1, m3, m9; 0, 1
|
||||
punpckhdq m3, m9; 2, 3
|
||||
|
||||
punpckldq m5, m7, m4; 4, 5
|
||||
punpckhdq m7, m4; 6, 7
|
||||
|
||||
pxor m13, m13
|
||||
|
||||
punpcklbw m0, m1, m13; 0 in 16 bit
|
||||
punpckhbw m1, m13; 1 in 16 bit
|
||||
|
||||
punpcklbw m2, m3, m13; 2
|
||||
punpckhbw m3, m13; 3
|
||||
|
||||
punpcklbw m4, m5, m13; 4
|
||||
punpckhbw m5, m13; 5
|
||||
|
||||
punpcklbw m6, m7, m13; 6
|
||||
punpckhbw m7, m13; 7
|
||||
%endmacro
|
||||
|
||||
|
||||
; in: 8 rows of 8 words in m0..m8
|
||||
; out: 8 rows of 8 bytes in %1..%8
|
||||
%macro TRANSPOSE8x8B_STORE 8
|
||||
packuswb m0, m4
|
||||
packuswb m1, m5
|
||||
packuswb m2, m6
|
||||
packuswb m3, m7
|
||||
TRANSPOSE2x4x4B 0, 1, 2, 3, 4
|
||||
|
||||
movq %1, m0
|
||||
movhps %2, m0
|
||||
movq %3, m1
|
||||
movhps %4, m1
|
||||
movq %5, m2
|
||||
movhps %6, m2
|
||||
movq %7, m3
|
||||
movhps %8, m3
|
||||
%endmacro
|
||||
|
||||
; in: 8 rows of 8 words in %1..%8
|
||||
; out: 8 rows of 8 words in m0..m7
|
||||
%macro TRANSPOSE8x8W_LOAD 8
|
||||
movdqu m0, %1
|
||||
movdqu m1, %2
|
||||
movdqu m2, %3
|
||||
movdqu m3, %4
|
||||
movdqu m4, %5
|
||||
movdqu m5, %6
|
||||
movdqu m6, %7
|
||||
movdqu m7, %8
|
||||
TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8
|
||||
%endmacro
|
||||
|
||||
; in: 8 rows of 8 words in m0..m8
|
||||
; out: 8 rows of 8 words in %1..%8
|
||||
%macro TRANSPOSE8x8W_STORE 9
|
||||
TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8
|
||||
|
||||
pxor m8, m8
|
||||
CLIPW m0, m8, %9
|
||||
CLIPW m1, m8, %9
|
||||
CLIPW m2, m8, %9
|
||||
CLIPW m3, m8, %9
|
||||
CLIPW m4, m8, %9
|
||||
CLIPW m5, m8, %9
|
||||
CLIPW m6, m8, %9
|
||||
CLIPW m7, m8, %9
|
||||
|
||||
movdqu %1, m0
|
||||
movdqu %2, m1
|
||||
movdqu %3, m2
|
||||
movdqu %4, m3
|
||||
movdqu %5, m4
|
||||
movdqu %6, m5
|
||||
movdqu %7, m6
|
||||
movdqu %8, m7
|
||||
%endmacro
|
||||
|
||||
|
||||
; in: %2 clobbered
|
||||
; out: %1
|
||||
; mask in m11
|
||||
; clobbers m10
|
||||
%macro MASKED_COPY 2
|
||||
pand %2, m11 ; and mask
|
||||
pandn m10, m11, %1; and -mask
|
||||
por %2, m10
|
||||
mova %1, %2
|
||||
%endmacro
|
||||
|
||||
; in: %2 clobbered
|
||||
; out: %1
|
||||
; mask in %3, will be clobbered
|
||||
%macro MASKED_COPY2 3
|
||||
pand %2, %3 ; and mask
|
||||
pandn %3, %1; and -mask
|
||||
por %2, %3
|
||||
mova %1, %2
|
||||
%endmacro
|
||||
|
||||
ALIGN 16
|
||||
; input in m0 ... m3 and tcs in r2. Output in m1 and m2
|
||||
%macro CHROMA_DEBLOCK_BODY 1
|
||||
psubw m4, m2, m1; q0 - p0
|
||||
psubw m5, m0, m3; p1 - q1
|
||||
psllw m4, 2; << 2
|
||||
paddw m5, m4;
|
||||
|
||||
;tc calculations
|
||||
movq m6, [tcq]; tc0
|
||||
punpcklwd m6, m6
|
||||
pshufd m6, m6, 0xA0; tc0, tc1
|
||||
%if cpuflag(ssse3)
|
||||
psignw m4, m6, [pw_m1]; -tc0, -tc1
|
||||
%else
|
||||
pmullw m4, m6, [pw_m1]; -tc0, -tc1
|
||||
%endif
|
||||
;end tc calculations
|
||||
|
||||
paddw m5, [pw_4]; +4
|
||||
psraw m5, 3; >> 3
|
||||
|
||||
%if %1 > 8
|
||||
psllw m4, %1-8; << (BIT_DEPTH - 8)
|
||||
psllw m6, %1-8; << (BIT_DEPTH - 8)
|
||||
%endif
|
||||
pmaxsw m5, m4
|
||||
pminsw m5, m6
|
||||
paddw m1, m5; p0 + delta0
|
||||
psubw m2, m5; q0 - delta0
|
||||
%endmacro
|
||||
|
||||
; input in m0 ... m7, beta in r2 tcs in r3. Output in m1...m6
|
||||
%macro LUMA_DEBLOCK_BODY 2
|
||||
psllw m9, m2, 1; *2
|
||||
psubw m10, m1, m9
|
||||
paddw m10, m3
|
||||
ABS1 m10, m11 ; 0dp0, 0dp3 , 1dp0, 1dp3
|
||||
|
||||
psllw m9, m5, 1; *2
|
||||
psubw m11, m6, m9
|
||||
paddw m11, m4
|
||||
ABS1 m11, m13 ; 0dq0, 0dq3 , 1dq0, 1dq3
|
||||
|
||||
;beta calculations
|
||||
%if %1 > 8
|
||||
shl betaq, %1 - 8
|
||||
%endif
|
||||
movd m13, betad
|
||||
SPLATW m13, m13, 0
|
||||
;end beta calculations
|
||||
|
||||
paddw m9, m10, m11; 0d0, 0d3 , 1d0, 1d3
|
||||
|
||||
pshufhw m14, m9, 0x0f ;0b00001111; 0d3 0d3 0d0 0d0 in high
|
||||
pshuflw m14, m14, 0x0f ;0b00001111; 1d3 1d3 1d0 1d0 in low
|
||||
|
||||
pshufhw m9, m9, 0xf0 ;0b11110000; 0d0 0d0 0d3 0d3
|
||||
pshuflw m9, m9, 0xf0 ;0b11110000; 1d0 1d0 1d3 1d3
|
||||
|
||||
paddw m14, m9; 0d0+0d3, 1d0+1d3
|
||||
|
||||
;compare
|
||||
pcmpgtw m15, m13, m14
|
||||
movmskps r13, m15 ;filtering mask 0d0 + 0d3 < beta0 (bit 2 or 3) , 1d0 + 1d3 < beta1 (bit 0 or 1)
|
||||
test r13, r13
|
||||
je .bypassluma
|
||||
|
||||
;weak / strong decision compare to beta_2
|
||||
psraw m15, m13, 2; beta >> 2
|
||||
psllw m8, m9, 1;
|
||||
pcmpgtw m15, m8; (d0 << 1) < beta_2, (d3 << 1) < beta_2
|
||||
movmskps r6, m15;
|
||||
;end weak / strong decision
|
||||
|
||||
; weak filter nd_p/q calculation
|
||||
pshufd m8, m10, 0x31
|
||||
psrld m8, 16
|
||||
paddw m8, m10
|
||||
movd r7d, m8
|
||||
pshufd m8, m8, 0x4E
|
||||
movd r8d, m8
|
||||
|
||||
pshufd m8, m11, 0x31
|
||||
psrld m8, 16
|
||||
paddw m8, m11
|
||||
movd r9d, m8
|
||||
pshufd m8, m8, 0x4E
|
||||
movd r10d, m8
|
||||
; end calc for weak filter
|
||||
|
||||
; filtering mask
|
||||
mov r11, r13
|
||||
shr r11, 3
|
||||
movd m15, r11d
|
||||
and r13, 1
|
||||
movd m11, r13d
|
||||
shufps m11, m15, 0
|
||||
shl r11, 1
|
||||
or r13, r11
|
||||
|
||||
pcmpeqd m11, [pd_1]; filtering mask
|
||||
|
||||
;decide between strong and weak filtering
|
||||
;tc25 calculations
|
||||
mov r11d, [tcq];
|
||||
%if %1 > 8
|
||||
shl r11, %1 - 8
|
||||
%endif
|
||||
movd m8, r11d; tc0
|
||||
mov r3d, [tcq+4];
|
||||
%if %1 > 8
|
||||
shl r3, %1 - 8
|
||||
%endif
|
||||
add r11d, r3d; tc0 + tc1
|
||||
jz .bypassluma
|
||||
movd m9, r3d; tc1
|
||||
punpcklwd m8, m8
|
||||
punpcklwd m9, m9
|
||||
shufps m8, m9, 0; tc0, tc1
|
||||
mova m9, m8
|
||||
psllw m8, 2; tc << 2
|
||||
pavgw m8, m9; tc25 = ((tc * 5 + 1) >> 1)
|
||||
;end tc25 calculations
|
||||
|
||||
;----beta_3 comparison-----
|
||||
psubw m12, m0, m3; p3 - p0
|
||||
ABS1 m12, m14; abs(p3 - p0)
|
||||
|
||||
psubw m15, m7, m4; q3 - q0
|
||||
ABS1 m15, m14; abs(q3 - q0)
|
||||
|
||||
paddw m12, m15; abs(p3 - p0) + abs(q3 - q0)
|
||||
|
||||
pshufhw m12, m12, 0xf0 ;0b11110000;
|
||||
pshuflw m12, m12, 0xf0 ;0b11110000;
|
||||
|
||||
psraw m13, 3; beta >> 3
|
||||
pcmpgtw m13, m12;
|
||||
movmskps r11, m13;
|
||||
and r6, r11; strong mask , beta_2 and beta_3 comparisons
|
||||
;----beta_3 comparison end-----
|
||||
;----tc25 comparison---
|
||||
psubw m12, m3, m4; p0 - q0
|
||||
ABS1 m12, m14; abs(p0 - q0)
|
||||
|
||||
pshufhw m12, m12, 0xf0 ;0b11110000;
|
||||
pshuflw m12, m12, 0xf0 ;0b11110000;
|
||||
|
||||
pcmpgtw m8, m12; tc25 comparisons
|
||||
movmskps r11, m8;
|
||||
and r6, r11; strong mask, beta_2, beta_3 and tc25 comparisons
|
||||
;----tc25 comparison end---
|
||||
mov r11, r6;
|
||||
shr r11, 1;
|
||||
and r6, r11; strong mask, bits 2 and 0
|
||||
|
||||
pmullw m14, m9, [pw_m2]; -tc * 2
|
||||
paddw m9, m9
|
||||
|
||||
and r6, 5; 0b101
|
||||
mov r11, r6; strong mask
|
||||
shr r6, 2;
|
||||
movd m12, r6d; store to xmm for mask generation
|
||||
shl r6, 1
|
||||
and r11, 1
|
||||
movd m10, r11d; store to xmm for mask generation
|
||||
or r6, r11; final strong mask, bits 1 and 0
|
||||
jz .weakfilter
|
||||
|
||||
shufps m10, m12, 0
|
||||
pcmpeqd m10, [pd_1]; strong mask
|
||||
|
||||
mova m13, [pw_4]; 4 in every cell
|
||||
pand m11, m10; combine filtering mask and strong mask
|
||||
paddw m12, m2, m3; p1 + p0
|
||||
paddw m12, m4; p1 + p0 + q0
|
||||
mova m10, m12; copy
|
||||
paddw m12, m12; 2*p1 + 2*p0 + 2*q0
|
||||
paddw m12, m1; p2 + 2*p1 + 2*p0 + 2*q0
|
||||
paddw m12, m5; p2 + 2*p1 + 2*p0 + 2*q0 + q1
|
||||
paddw m12, m13; p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4
|
||||
psraw m12, 3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3)
|
||||
psubw m12, m3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3) - p0
|
||||
pmaxsw m12, m14
|
||||
pminsw m12, m9; av_clip( , -2 * tc, 2 * tc)
|
||||
paddw m12, m3; p0'
|
||||
|
||||
paddw m15, m1, m10; p2 + p1 + p0 + q0
|
||||
psrlw m13, 1; 2 in every cell
|
||||
paddw m15, m13; p2 + p1 + p0 + q0 + 2
|
||||
psraw m15, 2; (p2 + p1 + p0 + q0 + 2) >> 2
|
||||
psubw m15, m2;((p2 + p1 + p0 + q0 + 2) >> 2) - p1
|
||||
pmaxsw m15, m14
|
||||
pminsw m15, m9; av_clip( , -2 * tc, 2 * tc)
|
||||
paddw m15, m2; p1'
|
||||
|
||||
paddw m8, m1, m0; p3 + p2
|
||||
paddw m8, m8; 2*p3 + 2*p2
|
||||
paddw m8, m1; 2*p3 + 3*p2
|
||||
paddw m8, m10; 2*p3 + 3*p2 + p1 + p0 + q0
|
||||
paddw m13, m13
|
||||
paddw m8, m13; 2*p3 + 3*p2 + p1 + p0 + q0 + 4
|
||||
psraw m8, 3; (2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3
|
||||
psubw m8, m1; ((2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3) - p2
|
||||
pmaxsw m8, m14
|
||||
pminsw m8, m9; av_clip( , -2 * tc, 2 * tc)
|
||||
paddw m8, m1; p2'
|
||||
MASKED_COPY m1, m8
|
||||
|
||||
paddw m8, m3, m4; p0 + q0
|
||||
paddw m8, m5; p0 + q0 + q1
|
||||
paddw m8, m8; 2*p0 + 2*q0 + 2*q1
|
||||
paddw m8, m2; p1 + 2*p0 + 2*q0 + 2*q1
|
||||
paddw m8, m6; p1 + 2*p0 + 2*q0 + 2*q1 + q2
|
||||
paddw m8, m13; p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4
|
||||
psraw m8, 3; (p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4) >>3
|
||||
psubw m8, m4;
|
||||
pmaxsw m8, m14
|
||||
pminsw m8, m9; av_clip( , -2 * tc, 2 * tc)
|
||||
paddw m8, m4; q0'
|
||||
MASKED_COPY m2, m15
|
||||
|
||||
paddw m15, m3, m4; p0 + q0
|
||||
paddw m15, m5; p0 + q0 + q1
|
||||
mova m10, m15;
|
||||
paddw m15, m6; p0 + q0 + q1 + q2
|
||||
psrlw m13, 1; 2 in every cell
|
||||
paddw m15, m13; p0 + q0 + q1 + q2 + 2
|
||||
psraw m15, 2; (p0 + q0 + q1 + q2 + 2) >> 2
|
||||
psubw m15, m5; ((p0 + q0 + q1 + q2 + 2) >> 2) - q1
|
||||
pmaxsw m15, m14
|
||||
pminsw m15, m9; av_clip( , -2 * tc, 2 * tc)
|
||||
paddw m15, m5; q1'
|
||||
|
||||
paddw m13, m7; q3 + 2
|
||||
paddw m13, m6; q3 + q2 + 2
|
||||
paddw m13, m13; 2*q3 + 2*q2 + 4
|
||||
paddw m13, m6; 2*q3 + 3*q2 + 4
|
||||
paddw m13, m10; 2*q3 + 3*q2 + q1 + q0 + p0 + 4
|
||||
psraw m13, 3; (2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3
|
||||
psubw m13, m6; ((2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3) - q2
|
||||
pmaxsw m13, m14
|
||||
pminsw m13, m9; av_clip( , -2 * tc, 2 * tc)
|
||||
paddw m13, m6; q2'
|
||||
|
||||
MASKED_COPY m6, m13
|
||||
MASKED_COPY m5, m15
|
||||
MASKED_COPY m4, m8
|
||||
MASKED_COPY m3, m12
|
||||
|
||||
.weakfilter:
|
||||
not r6; strong mask -> weak mask
|
||||
and r6, r13; final weak filtering mask, bits 0 and 1
|
||||
jz .store
|
||||
|
||||
; weak filtering mask
|
||||
mov r11, r6
|
||||
shr r11, 1
|
||||
movd m12, r11d
|
||||
and r6, 1
|
||||
movd m11, r6d
|
||||
shufps m11, m12, 0
|
||||
pcmpeqd m11, [pd_1]; filtering mask
|
||||
|
||||
mov r13, betaq
|
||||
shr r13, 1;
|
||||
add betaq, r13
|
||||
shr betaq, 3; ((beta + (beta >> 1)) >> 3))
|
||||
|
||||
psubw m12, m4, m3 ; q0 - p0
|
||||
paddw m10, m12, m12
|
||||
paddw m12, m10 ; 3 * (q0 - p0)
|
||||
psubw m10, m5, m2 ; q1 - p1
|
||||
psubw m12, m10 ; 3 * (q0 - p0) - (q1 - p1)
|
||||
%if %1 < 12
|
||||
paddw m10, m12, m12
|
||||
paddw m12, [pw_8]; + 8
|
||||
paddw m12, m10 ; 9 * (q0 - p0) - 3 * ( q1 - p1 )
|
||||
psraw m12, 4; >> 4 , delta0
|
||||
PABSW m13, m12; abs(delta0)
|
||||
%elif cpuflag(ssse3)
|
||||
pabsw m13, m12
|
||||
paddw m10, m13, m13
|
||||
paddw m13, [pw_8]
|
||||
paddw m13, m10 ; abs(9 * (q0 - p0) - 3 * ( q1 - p1 ))
|
||||
pxor m10, m10
|
||||
pcmpgtw m10, m12
|
||||
paddw m13, m10
|
||||
psrlw m13, 4; >> 4, abs(delta0)
|
||||
psignw m10, m13, m12
|
||||
SWAP 10, 12
|
||||
%else
|
||||
pxor m10, m10
|
||||
pcmpgtw m10, m12
|
||||
pxor m12, m10
|
||||
psubw m12, m10 ; abs()
|
||||
paddw m13, m12, m12
|
||||
paddw m12, [pw_8]
|
||||
paddw m13, m12 ; 3*abs(m12)
|
||||
paddw m13, m10
|
||||
psrlw m13, 4
|
||||
pxor m12, m13, m10
|
||||
psubw m12, m10
|
||||
%endif
|
||||
|
||||
psllw m10, m9, 2; 8 * tc
|
||||
paddw m10, m9; 10 * tc
|
||||
pcmpgtw m10, m13
|
||||
pand m11, m10
|
||||
|
||||
psraw m9, 1; tc * 2 -> tc
|
||||
psraw m14, 1; -tc * 2 -> -tc
|
||||
|
||||
pmaxsw m12, m14
|
||||
pminsw m12, m9; av_clip(delta0, -tc, tc)
|
||||
|
||||
psraw m9, 1; tc -> tc / 2
|
||||
%if cpuflag(ssse3)
|
||||
psignw m14, m9, [pw_m1]; -tc / 2
|
||||
%else
|
||||
pmullw m14, m9, [pw_m1]; -tc / 2
|
||||
%endif
|
||||
|
||||
pavgw m15, m1, m3; (p2 + p0 + 1) >> 1
|
||||
psubw m15, m2; ((p2 + p0 + 1) >> 1) - p1
|
||||
paddw m15, m12; ((p2 + p0 + 1) >> 1) - p1 + delta0
|
||||
psraw m15, 1; (((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1
|
||||
pmaxsw m15, m14
|
||||
pminsw m15, m9; av_clip(deltap1, -tc/2, tc/2)
|
||||
paddw m15, m2; p1'
|
||||
|
||||
;beta calculations
|
||||
movd m10, betad
|
||||
SPLATW m10, m10, 0
|
||||
|
||||
movd m13, r7d; 1dp0 + 1dp3
|
||||
movd m8, r8d; 0dp0 + 0dp3
|
||||
punpcklwd m8, m8
|
||||
punpcklwd m13, m13
|
||||
shufps m13, m8, 0;
|
||||
pcmpgtw m8, m10, m13
|
||||
pand m8, m11
|
||||
;end beta calculations
|
||||
MASKED_COPY2 m2, m15, m8; write p1'
|
||||
|
||||
pavgw m8, m6, m4; (q2 + q0 + 1) >> 1
|
||||
psubw m8, m5; ((q2 + q0 + 1) >> 1) - q1
|
||||
psubw m8, m12; ((q2 + q0 + 1) >> 1) - q1 - delta0)
|
||||
psraw m8, 1; ((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1
|
||||
pmaxsw m8, m14
|
||||
pminsw m8, m9; av_clip(deltaq1, -tc/2, tc/2)
|
||||
paddw m8, m5; q1'
|
||||
|
||||
movd m13, r9d;
|
||||
movd m15, r10d;
|
||||
punpcklwd m15, m15
|
||||
punpcklwd m13, m13
|
||||
shufps m13, m15, 0; dq0 + dq3
|
||||
|
||||
pcmpgtw m10, m13; compare to ((beta+(beta>>1))>>3)
|
||||
pand m10, m11
|
||||
MASKED_COPY2 m5, m8, m10; write q1'
|
||||
|
||||
paddw m15, m3, m12 ; p0 + delta0
|
||||
MASKED_COPY m3, m15
|
||||
|
||||
psubw m8, m4, m12 ; q0 - delta0
|
||||
MASKED_COPY m4, m8
|
||||
%endmacro
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; void ff_hevc_v_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int32_t *tc,
|
||||
; uint8_t *_no_p, uint8_t *_no_q);
|
||||
;-----------------------------------------------------------------------------
|
||||
%macro LOOP_FILTER_CHROMA 0
|
||||
cglobal hevc_v_loop_filter_chroma_8, 3, 5, 7, pix, stride, tc, pix0, r3stride
|
||||
sub pixq, 2
|
||||
lea r3strideq, [3*strideq]
|
||||
mov pix0q, pixq
|
||||
add pixq, r3strideq
|
||||
TRANSPOSE4x8B_LOAD PASS8ROWS(pix0q, pixq, strideq, r3strideq)
|
||||
CHROMA_DEBLOCK_BODY 8
|
||||
TRANSPOSE8x4B_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq)
|
||||
RET
|
||||
|
||||
cglobal hevc_v_loop_filter_chroma_10, 3, 5, 7, pix, stride, tc, pix0, r3stride
|
||||
sub pixq, 4
|
||||
lea r3strideq, [3*strideq]
|
||||
mov pix0q, pixq
|
||||
add pixq, r3strideq
|
||||
TRANSPOSE4x8W_LOAD PASS8ROWS(pix0q, pixq, strideq, r3strideq)
|
||||
CHROMA_DEBLOCK_BODY 10
|
||||
TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_10]
|
||||
RET
|
||||
|
||||
cglobal hevc_v_loop_filter_chroma_12, 3, 5, 7, pix, stride, tc, pix0, r3stride
|
||||
sub pixq, 4
|
||||
lea r3strideq, [3*strideq]
|
||||
mov pix0q, pixq
|
||||
add pixq, r3strideq
|
||||
TRANSPOSE4x8W_LOAD PASS8ROWS(pix0q, pixq, strideq, r3strideq)
|
||||
CHROMA_DEBLOCK_BODY 12
|
||||
TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_12]
|
||||
RET
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; void ff_hevc_h_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int32_t *tc,
|
||||
; uint8_t *_no_p, uint8_t *_no_q);
|
||||
;-----------------------------------------------------------------------------
|
||||
cglobal hevc_h_loop_filter_chroma_8, 3, 4, 7, pix, stride, tc, pix0
|
||||
mov pix0q, pixq
|
||||
sub pix0q, strideq
|
||||
sub pix0q, strideq
|
||||
movq m0, [pix0q]; p1
|
||||
movq m1, [pix0q+strideq]; p0
|
||||
movq m2, [pixq]; q0
|
||||
movq m3, [pixq+strideq]; q1
|
||||
pxor m5, m5; zeros reg
|
||||
punpcklbw m0, m5
|
||||
punpcklbw m1, m5
|
||||
punpcklbw m2, m5
|
||||
punpcklbw m3, m5
|
||||
CHROMA_DEBLOCK_BODY 8
|
||||
packuswb m1, m2
|
||||
movh[pix0q+strideq], m1
|
||||
movhps [pixq], m1
|
||||
RET
|
||||
|
||||
cglobal hevc_h_loop_filter_chroma_10, 3, 4, 7, pix, stride, tc, pix0
|
||||
mov pix0q, pixq
|
||||
sub pix0q, strideq
|
||||
sub pix0q, strideq
|
||||
movu m0, [pix0q]; p1
|
||||
movu m1, [pix0q+strideq]; p0
|
||||
movu m2, [pixq]; q0
|
||||
movu m3, [pixq+strideq]; q1
|
||||
CHROMA_DEBLOCK_BODY 10
|
||||
pxor m5, m5; zeros reg
|
||||
CLIPW m1, m5, [pw_pixel_max_10]
|
||||
CLIPW m2, m5, [pw_pixel_max_10]
|
||||
movu [pix0q+strideq], m1
|
||||
movu [pixq], m2
|
||||
RET
|
||||
|
||||
cglobal hevc_h_loop_filter_chroma_12, 3, 4, 7, pix, stride, tc, pix0
|
||||
mov pix0q, pixq
|
||||
sub pix0q, strideq
|
||||
sub pix0q, strideq
|
||||
movu m0, [pix0q]; p1
|
||||
movu m1, [pix0q+strideq]; p0
|
||||
movu m2, [pixq]; q0
|
||||
movu m3, [pixq+strideq]; q1
|
||||
CHROMA_DEBLOCK_BODY 12
|
||||
pxor m5, m5; zeros reg
|
||||
CLIPW m1, m5, [pw_pixel_max_12]
|
||||
CLIPW m2, m5, [pw_pixel_max_12]
|
||||
movu [pix0q+strideq], m1
|
||||
movu [pixq], m2
|
||||
RET
|
||||
%endmacro
|
||||
|
||||
INIT_XMM sse2
|
||||
LOOP_FILTER_CHROMA
|
||||
INIT_XMM avx
|
||||
LOOP_FILTER_CHROMA
|
||||
|
||||
%if ARCH_X86_64
|
||||
%macro LOOP_FILTER_LUMA 0
|
||||
;-----------------------------------------------------------------------------
|
||||
; void ff_hevc_v_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
|
||||
; int32_t *tc, uint8_t *_no_p, uint8_t *_no_q);
|
||||
;-----------------------------------------------------------------------------
|
||||
cglobal hevc_v_loop_filter_luma_8, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
|
||||
sub pixq, 4
|
||||
lea pix0q, [3 * r1]
|
||||
mov src3strideq, pixq
|
||||
add pixq, pix0q
|
||||
TRANSPOSE8x8B_LOAD PASS8ROWS(src3strideq, pixq, r1, pix0q)
|
||||
LUMA_DEBLOCK_BODY 8, v
|
||||
.store:
|
||||
TRANSPOSE8x8B_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q)
|
||||
.bypassluma:
|
||||
RET
|
||||
|
||||
cglobal hevc_v_loop_filter_luma_10, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
|
||||
sub pixq, 8
|
||||
lea pix0q, [3 * strideq]
|
||||
mov src3strideq, pixq
|
||||
add pixq, pix0q
|
||||
TRANSPOSE8x8W_LOAD PASS8ROWS(src3strideq, pixq, strideq, pix0q)
|
||||
LUMA_DEBLOCK_BODY 10, v
|
||||
.store:
|
||||
TRANSPOSE8x8W_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q), [pw_pixel_max_10]
|
||||
.bypassluma:
|
||||
RET
|
||||
|
||||
cglobal hevc_v_loop_filter_luma_12, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
|
||||
sub pixq, 8
|
||||
lea pix0q, [3 * strideq]
|
||||
mov src3strideq, pixq
|
||||
add pixq, pix0q
|
||||
TRANSPOSE8x8W_LOAD PASS8ROWS(src3strideq, pixq, strideq, pix0q)
|
||||
LUMA_DEBLOCK_BODY 12, v
|
||||
.store:
|
||||
TRANSPOSE8x8W_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q), [pw_pixel_max_12]
|
||||
.bypassluma:
|
||||
RET
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; void ff_hevc_h_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
|
||||
; int32_t *tc, uint8_t *_no_p, uint8_t *_no_q);
|
||||
;-----------------------------------------------------------------------------
|
||||
cglobal hevc_h_loop_filter_luma_8, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
|
||||
lea src3strideq, [3 * strideq]
|
||||
mov pix0q, pixq
|
||||
sub pix0q, src3strideq
|
||||
sub pix0q, strideq
|
||||
movq m0, [pix0q]; p3
|
||||
movq m1, [pix0q + strideq]; p2
|
||||
movq m2, [pix0q + 2 * strideq]; p1
|
||||
movq m3, [pix0q + src3strideq]; p0
|
||||
movq m4, [pixq]; q0
|
||||
movq m5, [pixq + strideq]; q1
|
||||
movq m6, [pixq + 2 * strideq]; q2
|
||||
movq m7, [pixq + src3strideq]; q3
|
||||
pxor m8, m8
|
||||
punpcklbw m0, m8
|
||||
punpcklbw m1, m8
|
||||
punpcklbw m2, m8
|
||||
punpcklbw m3, m8
|
||||
punpcklbw m4, m8
|
||||
punpcklbw m5, m8
|
||||
punpcklbw m6, m8
|
||||
punpcklbw m7, m8
|
||||
LUMA_DEBLOCK_BODY 8, h
|
||||
.store:
|
||||
packuswb m1, m2
|
||||
packuswb m3, m4
|
||||
packuswb m5, m6
|
||||
movh [pix0q + strideq], m1
|
||||
movhps [pix0q + 2 * strideq], m1
|
||||
movh [pix0q + src3strideq], m3
|
||||
movhps [pixq ], m3
|
||||
movh [pixq + strideq], m5
|
||||
movhps [pixq + 2 * strideq], m5
|
||||
.bypassluma:
|
||||
RET
|
||||
|
||||
cglobal hevc_h_loop_filter_luma_10, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
|
||||
lea src3strideq, [3 * strideq]
|
||||
mov pix0q, pixq
|
||||
sub pix0q, src3strideq
|
||||
sub pix0q, strideq
|
||||
movdqu m0, [pix0q]; p3
|
||||
movdqu m1, [pix0q + strideq]; p2
|
||||
movdqu m2, [pix0q + 2 * strideq]; p1
|
||||
movdqu m3, [pix0q + src3strideq]; p0
|
||||
movdqu m4, [pixq]; q0
|
||||
movdqu m5, [pixq + strideq]; q1
|
||||
movdqu m6, [pixq + 2 * strideq]; q2
|
||||
movdqu m7, [pixq + src3strideq]; q3
|
||||
LUMA_DEBLOCK_BODY 10, h
|
||||
.store:
|
||||
pxor m8, m8; zeros reg
|
||||
CLIPW m1, m8, [pw_pixel_max_10]
|
||||
CLIPW m2, m8, [pw_pixel_max_10]
|
||||
CLIPW m3, m8, [pw_pixel_max_10]
|
||||
CLIPW m4, m8, [pw_pixel_max_10]
|
||||
CLIPW m5, m8, [pw_pixel_max_10]
|
||||
CLIPW m6, m8, [pw_pixel_max_10]
|
||||
movdqu [pix0q + strideq], m1; p2
|
||||
movdqu [pix0q + 2 * strideq], m2; p1
|
||||
movdqu [pix0q + src3strideq], m3; p0
|
||||
movdqu [pixq ], m4; q0
|
||||
movdqu [pixq + strideq], m5; q1
|
||||
movdqu [pixq + 2 * strideq], m6; q2
|
||||
.bypassluma:
|
||||
RET
|
||||
|
||||
cglobal hevc_h_loop_filter_luma_12, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
|
||||
lea src3strideq, [3 * strideq]
|
||||
mov pix0q, pixq
|
||||
sub pix0q, src3strideq
|
||||
sub pix0q, strideq
|
||||
movdqu m0, [pix0q]; p3
|
||||
movdqu m1, [pix0q + strideq]; p2
|
||||
movdqu m2, [pix0q + 2 * strideq]; p1
|
||||
movdqu m3, [pix0q + src3strideq]; p0
|
||||
movdqu m4, [pixq]; q0
|
||||
movdqu m5, [pixq + strideq]; q1
|
||||
movdqu m6, [pixq + 2 * strideq]; q2
|
||||
movdqu m7, [pixq + src3strideq]; q3
|
||||
LUMA_DEBLOCK_BODY 12, h
|
||||
.store:
|
||||
pxor m8, m8; zeros reg
|
||||
CLIPW m1, m8, [pw_pixel_max_12]
|
||||
CLIPW m2, m8, [pw_pixel_max_12]
|
||||
CLIPW m3, m8, [pw_pixel_max_12]
|
||||
CLIPW m4, m8, [pw_pixel_max_12]
|
||||
CLIPW m5, m8, [pw_pixel_max_12]
|
||||
CLIPW m6, m8, [pw_pixel_max_12]
|
||||
movdqu [pix0q + strideq], m1; p2
|
||||
movdqu [pix0q + 2 * strideq], m2; p1
|
||||
movdqu [pix0q + src3strideq], m3; p0
|
||||
movdqu [pixq ], m4; q0
|
||||
movdqu [pixq + strideq], m5; q1
|
||||
movdqu [pixq + 2 * strideq], m6; q2
|
||||
.bypassluma:
|
||||
RET
|
||||
|
||||
%endmacro
|
||||
|
||||
INIT_XMM sse2
|
||||
LOOP_FILTER_LUMA
|
||||
INIT_XMM ssse3
|
||||
LOOP_FILTER_LUMA
|
||||
INIT_XMM avx
|
||||
LOOP_FILTER_LUMA
|
||||
%endif
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* HEVC video decoder
|
||||
*
|
||||
* Copyright (C) 2012 - 2013 Guillaume Martres
|
||||
* Copyright (C) 2013 - 2014 Pierre-Edouard Lepere
|
||||
*
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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.
|
||||
*
|
||||
* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_X86_HEVC_DSP_H
|
||||
#define AVCODEC_X86_HEVC_DSP_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void bi_pel_func(uint8_t *_dst, ptrdiff_t _dststride,
|
||||
const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2,
|
||||
int height, intptr_t mx, intptr_t my, int width);
|
||||
|
||||
#define BI_PEL_PROTOTYPE(name, W, D, opt) \
|
||||
bi_pel_func ff_hevc_put_bi_ ## name ## W ## _ ## D ## _##opt
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MC functions
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define WEIGHTING_PROTOTYPE(width, bitd, opt) \
|
||||
void ff_hevc_put_uni_w##width##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, const int16_t *_src, int height, int denom, int _wx, int _ox); \
|
||||
void ff_hevc_put_bi_w##width##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, const int16_t *_src, const int16_t *_src2, int height, int denom, int _wx0, int _wx1, int _ox0, int _ox1)
|
||||
|
||||
#define WEIGHTING_PROTOTYPES(bitd, opt) \
|
||||
WEIGHTING_PROTOTYPE(4, bitd, opt); \
|
||||
WEIGHTING_PROTOTYPE(6, bitd, opt); \
|
||||
WEIGHTING_PROTOTYPE(8, bitd, opt); \
|
||||
WEIGHTING_PROTOTYPE(12, bitd, opt); \
|
||||
WEIGHTING_PROTOTYPE(16, bitd, opt); \
|
||||
WEIGHTING_PROTOTYPE(24, bitd, opt); \
|
||||
WEIGHTING_PROTOTYPE(32, bitd, opt); \
|
||||
WEIGHTING_PROTOTYPE(48, bitd, opt); \
|
||||
WEIGHTING_PROTOTYPE(64, bitd, opt)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// EPEL_PIXELS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 4, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 4, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 4, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 6, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 6, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 6, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 8, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 8, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 8, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 12, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 16, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 16, 10, avx2);
|
||||
BI_PEL_PROTOTYPE(pel_pixels, 32, 8, avx2);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// EPEL
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BI_PEL_PROTOTYPE(epel_h, 4, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 4, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 4, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 6, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 6, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 6, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 8, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 8, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 8, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 12, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 16, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_h, 16, 10, avx2);
|
||||
BI_PEL_PROTOTYPE(epel_h, 32, 8, avx2);
|
||||
|
||||
BI_PEL_PROTOTYPE(epel_hv, 4, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 4, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 4, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 6, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 6, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 6, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 8, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 8, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 8, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 16, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 16, 10, avx2);
|
||||
BI_PEL_PROTOTYPE(epel_hv, 32, 8, avx2);
|
||||
|
||||
BI_PEL_PROTOTYPE(epel_v, 4, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 4, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 4, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 6, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 6, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 6, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 8, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 8, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 8, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 12, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 16, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(epel_v, 16, 10, avx2);
|
||||
BI_PEL_PROTOTYPE(epel_v, 32, 8, avx2);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// QPEL
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BI_PEL_PROTOTYPE(qpel_h, 4, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 4, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 4, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 8, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 8, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 8, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 12, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 16, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 16, 10, avx2);
|
||||
BI_PEL_PROTOTYPE(qpel_h, 32, 8, avx2);
|
||||
|
||||
BI_PEL_PROTOTYPE(qpel_hv, 4, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_hv, 4, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_hv, 4, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_hv, 8, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_hv, 8, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_hv, 8, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_hv, 16, 10, avx2);
|
||||
|
||||
BI_PEL_PROTOTYPE(qpel_v, 4, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 4, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 4, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 8, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 8, 10, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 8, 12, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 12, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 16, 8, sse4);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 16, 10, avx2);
|
||||
BI_PEL_PROTOTYPE(qpel_v, 32, 8, avx2);
|
||||
|
||||
WEIGHTING_PROTOTYPES(8, sse4);
|
||||
WEIGHTING_PROTOTYPES(10, sse4);
|
||||
WEIGHTING_PROTOTYPES(12, sse4);
|
||||
|
||||
void ff_hevc_put_qpel_h4_8_avx512icl(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my, int width);
|
||||
void ff_hevc_put_qpel_h8_8_avx512icl(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my, int width);
|
||||
void ff_hevc_put_qpel_h16_8_avx512icl(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my, int width);
|
||||
void ff_hevc_put_qpel_h32_8_avx512icl(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my, int width);
|
||||
void ff_hevc_put_qpel_h64_8_avx512icl(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my, int width);
|
||||
void ff_hevc_put_qpel_hv8_8_avx512icl(int16_t *dst, const uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my, int width);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TRANSFORM_ADD
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ff_hevc_add_residual_4_8_mmxext(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_8_8_sse2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_16_8_sse2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_32_8_sse2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
|
||||
void ff_hevc_add_residual_8_8_avx(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_16_8_avx(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_32_8_avx(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
|
||||
void ff_hevc_add_residual_32_8_avx2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
|
||||
void ff_hevc_add_residual_4_10_mmxext(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_8_10_sse2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_16_10_sse2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_32_10_sse2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
|
||||
void ff_hevc_add_residual_16_10_avx2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
void ff_hevc_add_residual_32_10_avx2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||
|
||||
#endif // AVCODEC_X86_HEVC_DSP_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,852 @@
|
||||
;*******************************************************************************
|
||||
;* SIMD-optimized IDCT functions for HEVC decoding
|
||||
;* Copyright (c) 2014 Pierre-Edouard LEPERE
|
||||
;* Copyright (c) 2014 James Almer
|
||||
;* Copyright (c) 2016 Alexandra Hájková
|
||||
;*
|
||||
;* This file is part of FFmpeg.
|
||||
;*
|
||||
;* FFmpeg 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.
|
||||
;*
|
||||
;* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
;******************************************************************************
|
||||
|
||||
%include "libavutil/x86/x86util.asm"
|
||||
|
||||
SECTION_RODATA
|
||||
|
||||
cextern pd_64
|
||||
pd_2048: times 4 dd 2048
|
||||
pd_512: times 4 dd 512
|
||||
|
||||
; 4x4 transform coeffs
|
||||
cextern pw_64
|
||||
pw_64_m64: times 4 dw 64, -64
|
||||
pw_83_36: times 4 dw 83, 36
|
||||
pw_36_m83: times 4 dw 36, -83
|
||||
|
||||
; 8x8 transform coeffs
|
||||
pw_89_75: times 4 dw 89, 75
|
||||
pw_50_18: times 4 dw 50, 18
|
||||
|
||||
pw_75_m18: times 4 dw 75, -18
|
||||
pw_m89_m50: times 4 dw -89, -50
|
||||
|
||||
pw_50_m89: times 4 dw 50, -89
|
||||
pw_18_75: times 4 dw 18, 75
|
||||
|
||||
pw_18_m50: times 4 dw 18, -50
|
||||
pw_75_m89: times 4 dw 75, -89
|
||||
|
||||
; 16x16 transformation coeffs
|
||||
trans_coeffs16: times 4 dw 90, 87
|
||||
times 4 dw 80, 70
|
||||
times 4 dw 57, 43
|
||||
times 4 dw 25, 9
|
||||
|
||||
times 4 dw 87, 57
|
||||
times 4 dw 9, -43
|
||||
times 4 dw -80, -90
|
||||
times 4 dw -70, -25
|
||||
|
||||
times 4 dw 80, 9
|
||||
times 4 dw -70, -87
|
||||
times 4 dw -25, 57
|
||||
times 4 dw 90, 43
|
||||
|
||||
times 4 dw 70, -43
|
||||
times 4 dw -87, 9
|
||||
times 4 dw 90, 25
|
||||
times 4 dw -80, -57
|
||||
|
||||
times 4 dw 57, -80
|
||||
times 4 dw -25, 90
|
||||
times 4 dw -9, -87
|
||||
times 4 dw 43, 70
|
||||
|
||||
times 4 dw 43, -90
|
||||
times 4 dw 57, 25
|
||||
times 4 dw -87, 70
|
||||
times 4 dw 9, -80
|
||||
|
||||
times 4 dw 25, -70
|
||||
times 4 dw 90, -80
|
||||
times 4 dw 43, 9
|
||||
times 4 dw -57, 87
|
||||
|
||||
times 4 dw 9, -25
|
||||
times 4 dw 43, -57
|
||||
times 4 dw 70, -80
|
||||
times 4 dw 87, -90
|
||||
|
||||
; 32x32 transform coeffs
|
||||
trans_coeff32: times 8 dw 90
|
||||
times 4 dw 88, 85
|
||||
times 4 dw 82, 78
|
||||
times 4 dw 73, 67
|
||||
times 4 dw 61, 54
|
||||
times 4 dw 46, 38
|
||||
times 4 dw 31, 22
|
||||
times 4 dw 13, 4
|
||||
|
||||
times 4 dw 90, 82
|
||||
times 4 dw 67, 46
|
||||
times 4 dw 22, -4
|
||||
times 4 dw -31, -54
|
||||
times 4 dw -73, -85
|
||||
times 4 dw -90, -88
|
||||
times 4 dw -78, -61
|
||||
times 4 dw -38, -13
|
||||
|
||||
times 4 dw 88, 67
|
||||
times 4 dw 31, -13
|
||||
times 4 dw -54, -82
|
||||
times 4 dw -90, -78
|
||||
times 4 dw -46, -4
|
||||
times 4 dw 38, 73
|
||||
times 4 dw 90, 85
|
||||
times 4 dw 61, 22
|
||||
|
||||
times 4 dw 85, 46
|
||||
times 4 dw -13, -67
|
||||
times 4 dw -90, -73
|
||||
times 4 dw -22, 38
|
||||
times 4 dw 82, 88
|
||||
times 4 dw 54, -4
|
||||
times 4 dw -61, -90
|
||||
times 4 dw -78, -31
|
||||
|
||||
times 4 dw 82, 22
|
||||
times 4 dw -54, -90
|
||||
times 4 dw -61, 13
|
||||
times 4 dw 78, 85
|
||||
times 4 dw 31, -46
|
||||
times 4 dw -90, -67
|
||||
times 4 dw 4, 73
|
||||
times 4 dw 88, 38
|
||||
|
||||
times 4 dw 78, -4
|
||||
times 4 dw -82, -73
|
||||
times 4 dw 13, 85
|
||||
times 4 dw 67, -22
|
||||
times 4 dw -88, -61
|
||||
times 4 dw 31, 90
|
||||
times 4 dw 54, -38
|
||||
times 4 dw -90, -46
|
||||
|
||||
times 4 dw 73, -31
|
||||
times 4 dw -90, -22
|
||||
times 4 dw 78, 67
|
||||
times 4 dw -38, -90
|
||||
times 4 dw -13, 82
|
||||
times 4 dw 61, -46
|
||||
times 4 dw -88, -4
|
||||
times 4 dw 85, 54
|
||||
|
||||
times 4 dw 67, -54
|
||||
times 4 dw -78, 38
|
||||
times 4 dw 85, -22
|
||||
times 4 dw -90, 4
|
||||
times 4 dw 90, 13
|
||||
times 4 dw -88, -31
|
||||
times 4 dw 82, 46
|
||||
times 4 dw -73, -61
|
||||
|
||||
times 4 dw 61, -73
|
||||
times 4 dw -46, 82
|
||||
times 4 dw 31, -88
|
||||
times 4 dw -13, 90
|
||||
times 4 dw -4, -90
|
||||
times 4 dw 22, 85
|
||||
times 4 dw -38, -78
|
||||
times 4 dw 54, 67
|
||||
|
||||
times 4 dw 54, -85
|
||||
times 4 dw -4, 88
|
||||
times 4 dw -46, -61
|
||||
times 4 dw 82, 13
|
||||
times 4 dw -90, 38
|
||||
times 4 dw 67, -78
|
||||
times 4 dw -22, 90
|
||||
times 4 dw -31, -73
|
||||
|
||||
times 4 dw 46, -90
|
||||
times 4 dw 38, 54
|
||||
times 4 dw -90, 31
|
||||
times 4 dw 61, -88
|
||||
times 4 dw 22, 67
|
||||
times 4 dw -85, 13
|
||||
times 4 dw 73, -82
|
||||
times 4 dw 4, 78
|
||||
|
||||
times 4 dw 38, -88
|
||||
times 4 dw 73, -4
|
||||
times 4 dw -67, 90
|
||||
times 4 dw -46, -31
|
||||
times 4 dw 85, -78
|
||||
times 4 dw 13, 61
|
||||
times 4 dw -90, 54
|
||||
times 4 dw 22, -82
|
||||
|
||||
times 4 dw 31, -78
|
||||
times 4 dw 90, -61
|
||||
times 4 dw 4, 54
|
||||
times 4 dw -88, 82
|
||||
times 4 dw -38, -22
|
||||
times 4 dw 73, -90
|
||||
times 4 dw 67, -13
|
||||
times 4 dw -46, 85
|
||||
|
||||
times 4 dw 22, -61
|
||||
times 4 dw 85, -90
|
||||
times 4 dw 73, -38
|
||||
times 4 dw -4, 46
|
||||
times 4 dw -78, 90
|
||||
times 4 dw -82, 54
|
||||
times 4 dw -13, -31
|
||||
times 4 dw 67, -88
|
||||
|
||||
times 4 dw 13, -38
|
||||
times 4 dw 61, -78
|
||||
times 4 dw 88, -90
|
||||
times 4 dw 85, -73
|
||||
times 4 dw 54, -31
|
||||
times 4 dw 4, 22
|
||||
times 4 dw -46, 67
|
||||
times 4 dw -82, 90
|
||||
|
||||
times 4 dw 4, -13
|
||||
times 4 dw 22, -31
|
||||
times 4 dw 38, -46
|
||||
times 4 dw 54, -61
|
||||
times 4 dw 67, -73
|
||||
times 4 dw 78, -82
|
||||
times 4 dw 85, -88
|
||||
times 4 dw 90, -90
|
||||
|
||||
SECTION .text
|
||||
|
||||
; void ff_hevc_idct_HxW_dc_{8,10}_<opt>(int16_t *coeffs)
|
||||
; %1 = HxW
|
||||
; %2 = number of loops
|
||||
; %3 = bitdepth
|
||||
%macro IDCT_DC 3
|
||||
cglobal hevc_idct_%1x%1_dc_%3, 1, 2, 1, coeff, tmp
|
||||
movsx tmpd, word [coeffq]
|
||||
add tmpd, (1 << (14 - %3)) + 1
|
||||
sar tmpd, (15 - %3)
|
||||
movd xm0, tmpd
|
||||
SPLATW m0, xm0
|
||||
DEFINE_ARGS coeff, cnt
|
||||
mov cntd, %2
|
||||
.loop:
|
||||
mova [coeffq+mmsize*0], m0
|
||||
mova [coeffq+mmsize*1], m0
|
||||
mova [coeffq+mmsize*2], m0
|
||||
mova [coeffq+mmsize*3], m0
|
||||
add coeffq, mmsize*8
|
||||
mova [coeffq+mmsize*-4], m0
|
||||
mova [coeffq+mmsize*-3], m0
|
||||
mova [coeffq+mmsize*-2], m0
|
||||
mova [coeffq+mmsize*-1], m0
|
||||
dec cntd
|
||||
jg .loop
|
||||
RET
|
||||
%endmacro
|
||||
|
||||
; %1 = HxW
|
||||
; %2 = bitdepth
|
||||
%macro IDCT_DC_NL 2 ; No loop
|
||||
cglobal hevc_idct_%1x%1_dc_%2, 1, 2, 1, coeff, tmp
|
||||
movsx tmpd, word [coeffq]
|
||||
add tmpd, (1 << (14 - %2)) + 1
|
||||
sar tmpd, (15 - %2)
|
||||
movd m0, tmpd
|
||||
SPLATW m0, xm0
|
||||
mova [coeffq+mmsize*0], m0
|
||||
mova [coeffq+mmsize*1], m0
|
||||
mova [coeffq+mmsize*2], m0
|
||||
mova [coeffq+mmsize*3], m0
|
||||
%if mmsize == 16
|
||||
mova [coeffq+mmsize*4], m0
|
||||
mova [coeffq+mmsize*5], m0
|
||||
mova [coeffq+mmsize*6], m0
|
||||
mova [coeffq+mmsize*7], m0
|
||||
%endif
|
||||
RET
|
||||
%endmacro
|
||||
|
||||
; IDCT 4x4, expects input in m0, m1
|
||||
; %1 - shift
|
||||
; %2 - 1/0 - SCALE and Transpose or not
|
||||
; %3 - 1/0 add constant or not
|
||||
%macro TR_4x4 3
|
||||
; interleaves src0 with src2 to m0
|
||||
; and src1 with scr3 to m2
|
||||
; src0: 00 01 02 03 m0: 00 20 01 21 02 22 03 23
|
||||
; src1: 10 11 12 13 -->
|
||||
; src2: 20 21 22 23 m1: 10 30 11 31 12 32 13 33
|
||||
; src3: 30 31 32 33
|
||||
|
||||
SBUTTERFLY wd, 0, 1, 2
|
||||
|
||||
pmaddwd m2, m0, [pw_64] ; e0
|
||||
pmaddwd m3, m1, [pw_83_36] ; o0
|
||||
pmaddwd m0, [pw_64_m64] ; e1
|
||||
pmaddwd m1, [pw_36_m83] ; o1
|
||||
|
||||
%if %3 == 1
|
||||
%assign %%add 1 << (%1 - 1)
|
||||
mova m4, [pd_ %+ %%add]
|
||||
paddd m2, m4
|
||||
paddd m0, m4
|
||||
%endif
|
||||
|
||||
SUMSUB_BADC d, 3, 2, 1, 0, 4
|
||||
|
||||
%if %2 == 1
|
||||
psrad m3, %1 ; e0 + o0
|
||||
psrad m1, %1 ; e1 + o1
|
||||
psrad m2, %1 ; e0 - o0
|
||||
psrad m0, %1 ; e1 - o1
|
||||
;clip16
|
||||
packssdw m3, m1
|
||||
packssdw m0, m2
|
||||
; Transpose
|
||||
SBUTTERFLY wd, 3, 0, 1
|
||||
SBUTTERFLY wd, 3, 0, 1
|
||||
SWAP 3, 1, 0
|
||||
%else
|
||||
SWAP 3, 2, 0
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro DEFINE_BIAS 1
|
||||
%assign shift (20 - %1)
|
||||
%assign c_add (1 << (shift - 1))
|
||||
%define arr_add pd_ %+ c_add
|
||||
%endmacro
|
||||
|
||||
; %1 - bit_depth
|
||||
; %2 - register add constant
|
||||
; is loaded to
|
||||
; shift = 20 - bit_depth
|
||||
%macro LOAD_BIAS 2
|
||||
DEFINE_BIAS %1
|
||||
mova %2, [arr_add]
|
||||
%endmacro
|
||||
|
||||
; %1, %2 - registers to load packed 16 bit values to
|
||||
; %3, %4, %5, %6 - vertical offsets
|
||||
; %7 - horizontal offset
|
||||
%macro LOAD_BLOCK 7
|
||||
movq %1, [r0 + %3 + %7]
|
||||
movhps %1, [r0 + %5 + %7]
|
||||
movq %2, [r0 + %4 + %7]
|
||||
movhps %2, [r0 + %6 + %7]
|
||||
%endmacro
|
||||
|
||||
; void ff_hevc_idct_4x4__{8,10}_<opt>(int16_t *coeffs, int col_limit)
|
||||
; %1 = bitdepth
|
||||
%macro IDCT_4x4 1
|
||||
cglobal hevc_idct_4x4_%1, 1, 1, 5, coeffs
|
||||
mova m0, [coeffsq]
|
||||
mova m1, [coeffsq + 16]
|
||||
|
||||
TR_4x4 7, 1, 1
|
||||
TR_4x4 20 - %1, 1, 1
|
||||
|
||||
mova [coeffsq], m0
|
||||
mova [coeffsq + 16], m1
|
||||
RET
|
||||
%endmacro
|
||||
|
||||
; scale, pack (clip16) and store the residuals 0 e8[0] + o8[0] --> + %1
|
||||
; 4 at one time (4 columns) 1 e8[1] + o8[1]
|
||||
; from %5: e8/16 + o8/16, with %1 offset ...
|
||||
; and %3: e8/16 - o8/16, with %2 offset 6 e8[1] - o8[1]
|
||||
; %4 - shift 7 e8[0] - o8[0] --> + %2
|
||||
%macro STORE_8 7
|
||||
psrad %5, %4
|
||||
psrad %3, %4
|
||||
packssdw %5, %3
|
||||
movq [coeffsq + %1], %5
|
||||
movhps [coeffsq + %2], %5
|
||||
%endmacro
|
||||
|
||||
; %1 - horizontal offset
|
||||
; %2 - shift
|
||||
; %3, %4 - transform coeffs
|
||||
; %5 - vertical offset for e8 + o8
|
||||
; %6 - vertical offset for e8 - o8
|
||||
; %7 - register with e8 inside
|
||||
; %8 - block_size
|
||||
; %9 - register to store e8 +o8
|
||||
; %10 - register to store e8 - o8
|
||||
%macro E8_O8 10
|
||||
pmaddwd m6, m4, %3
|
||||
pmaddwd m7, m5, %4
|
||||
|
||||
paddd m6, m7
|
||||
paddd m7, m6, %7 ; o8 + e8
|
||||
psubd %7, m6 ; e8 - o8
|
||||
%if %8 == 8
|
||||
STORE_8 %5 + %1, %6 + %1, %7, %2, m7, 0, 0
|
||||
%else
|
||||
SWAP m7, %9
|
||||
SWAP %7, %10
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
; 8x4 residuals are processed and stored
|
||||
; %1 - horizontal offset
|
||||
; %2 - shift
|
||||
; %3 - offset of the even row
|
||||
; %4 - step: 1 for 8x8, 2 for 16x16, 4 for 32x32
|
||||
; %5 - offset of the odd row
|
||||
; %6 - block size
|
||||
; %7 - 1/0 add a constant in TR_4x4 or not
|
||||
; I want to add a constant for 8x8 transform but not for 16x16 and 32x32
|
||||
%macro TR_8x4 7
|
||||
; load 4 columns of even rows
|
||||
LOAD_BLOCK m0, m1, 0, 2 * %4 * %3, %4 * %3, 3 * %4 * %3, %1
|
||||
|
||||
TR_4x4 %2, 0, %7 ; e8: m0, m1, m2, m3, for 4 columns only
|
||||
|
||||
; load 4 columns of odd rows
|
||||
LOAD_BLOCK m4, m5, %4 * %5, 3 * %4 * %5, 5 * %4 * %5, 7 * %4 * %5, %1
|
||||
|
||||
; 00 01 02 03
|
||||
; 10 11 12 13 m4: 10 30 11 31 12 32 13 33
|
||||
|
||||
; ... -- >
|
||||
; m5: 50 70 51 71 52 72 53 73
|
||||
; 70 71 72 73
|
||||
SBUTTERFLY wd, 4, 5, 6
|
||||
|
||||
E8_O8 %1, %2, [pw_89_75], [pw_50_18], 0, %5 * 7, m0, %6, m8, m15
|
||||
E8_O8 %1, %2, [pw_75_m18], [pw_m89_m50], %5, %5 * 6, m1, %6, m9, m14
|
||||
E8_O8 %1, %2, [pw_50_m89], [pw_18_75], %5 * 2, %5 * 5, m2, %6, m10, m13
|
||||
E8_O8 %1, %2, [pw_18_m50], [pw_75_m89], %5 * 3, %5 * 4, m3, %6, m11, m12
|
||||
%endmacro
|
||||
|
||||
%macro STORE_PACKED 7
|
||||
movq [r0 + %3 + %7], %1
|
||||
movhps [r0 + %4 + %7], %1
|
||||
movq [r0 + %5 + %7], %2
|
||||
movhps [r0 + %6 + %7], %2
|
||||
%endmacro
|
||||
|
||||
; transpose 4x4 block packed
|
||||
; in %1 and %2 registers
|
||||
; %3 - temporary register
|
||||
%macro TRANSPOSE_4x4 3
|
||||
SBUTTERFLY wd, %1, %2, %3
|
||||
SBUTTERFLY dq, %1, %2, %3
|
||||
%endmacro
|
||||
|
||||
; %1 - horizontal offset of the block i
|
||||
; %2 - vertical offset of the block i
|
||||
; %3 - width in bytes
|
||||
; %4 - vertical offset for the block j
|
||||
; %5 - horizontal offset for the block j
|
||||
%macro SWAP_BLOCKS 5
|
||||
; M_j
|
||||
LOAD_BLOCK m4, m5, %4, %4 + %3, %4 + 2 * %3, %4 + 3 * %3, %5
|
||||
TRANSPOSE_4x4 4, 5, 6
|
||||
|
||||
; M_i
|
||||
LOAD_BLOCK m6, m7, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1
|
||||
|
||||
STORE_PACKED m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1
|
||||
|
||||
; transpose and store M_i
|
||||
SWAP m6, m4
|
||||
SWAP m7, m5
|
||||
TRANSPOSE_4x4 4, 5, 6
|
||||
STORE_PACKED m4, m5, %4, %4 + %3, %4 + 2 * %3, %4 + 3 * %3, %5
|
||||
%endmacro
|
||||
|
||||
; %1 - horizontal offset
|
||||
; %2 - vertical offset of the block
|
||||
; %3 - width in bytes
|
||||
%macro TRANSPOSE_BLOCK 3
|
||||
LOAD_BLOCK m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1
|
||||
TRANSPOSE_4x4 4, 5, 6
|
||||
STORE_PACKED m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1
|
||||
%endmacro
|
||||
|
||||
%macro TRANSPOSE_8x8 0
|
||||
cglobal hevc_idct_transpose_8x8, 0, 0, 0
|
||||
; M1 M2 ^T = M1^t M3^t
|
||||
; M3 M4 M2^t M4^t
|
||||
|
||||
; M1 4x4 block
|
||||
TRANSPOSE_BLOCK 0, 0, 16
|
||||
|
||||
; M2 and M3
|
||||
SWAP_BLOCKS 0, 64, 16, 0, 8
|
||||
|
||||
; M4
|
||||
TRANSPOSE_BLOCK 8, 64, 16
|
||||
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
; void ff_hevc_idct_8x8_{8,10}_<opt>(int16_t *coeffs, int col_limit)
|
||||
; %1 = bitdepth
|
||||
%macro IDCT_8x8 1
|
||||
cglobal hevc_idct_8x8_%1, 1, 1, 8, coeffs
|
||||
TR_8x4 0, 7, 32, 1, 16, 8, 1
|
||||
TR_8x4 8, 7, 32, 1, 16, 8, 1
|
||||
|
||||
call hevc_idct_transpose_8x8_ %+ cpuname
|
||||
|
||||
DEFINE_BIAS %1
|
||||
TR_8x4 0, shift, 32, 1, 16, 8, 1
|
||||
TR_8x4 8, shift, 32, 1, 16, 8, 1
|
||||
|
||||
TAIL_CALL hevc_idct_transpose_8x8_ %+ cpuname, 1
|
||||
%endmacro
|
||||
|
||||
; store intermedite e32 coeffs on stack
|
||||
; as 16x4 matrix
|
||||
; from m10: e8 + o8, with %6 offset
|
||||
; and %3: e8 - o8, with %7 offset
|
||||
; %4 - shift, unused here
|
||||
%macro STORE_16 7
|
||||
mova [rsp + %6], %5
|
||||
mova [rsp + %7], %3
|
||||
%endmacro
|
||||
|
||||
; %1, %2 - transform constants
|
||||
; %3, %4 - regs with interleaved coeffs
|
||||
; %5 - 1/0 SWAP or add
|
||||
; %6, %7 - registers for intermediate sums
|
||||
; %8 - accumulator register
|
||||
%macro ADD_ROWS 8
|
||||
pmaddwd %6, %3, %1
|
||||
pmaddwd %7, %4, %2
|
||||
paddd %6, %7
|
||||
%if %5 == 1
|
||||
SWAP %6, %8
|
||||
%else
|
||||
paddd %8, %6
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
; %1 - transform coeffs
|
||||
; %2, %3 offsets for storing e+o/e-o back to coeffsq
|
||||
; %4 - shift
|
||||
; %5 - add
|
||||
; %6 - block_size
|
||||
; %7 - register with e16
|
||||
; %8, %9 - stack offsets for storing e+o/e-o
|
||||
%macro E16_O16 9
|
||||
ADD_ROWS [%1], [%1 + 16], m0, m1, 1, m5, m6, m7
|
||||
ADD_ROWS [%1 + 2 * 16], [%1 + 3 * 16], m2, m3, 0, m5, m6, m7
|
||||
|
||||
%if %6 == 8
|
||||
paddd %7, %5
|
||||
%endif
|
||||
|
||||
paddd m4, m7, %7 ; o16 + e16
|
||||
psubd %7, m7 ; e16 - o16
|
||||
STORE_%6 %2, %3, %7, %4, m4, %8, %9
|
||||
%endmacro
|
||||
|
||||
%macro TR_16x4 10
|
||||
; produce 8x4 matrix of e16 coeffs
|
||||
; for 4 first rows and store it on stack (128 bytes)
|
||||
TR_8x4 %1, 7, %4, %5, %6, %8, 0
|
||||
|
||||
; load 8 even rows
|
||||
LOAD_BLOCK m0, m1, %9 * %6, %9 * 3 * %6, %9 * 5 * %6, %9 * 7 * %6, %1
|
||||
LOAD_BLOCK m2, m3, %9 * 9 * %6, %9 * 11 * %6, %9 * 13 * %6, %9 * 15 * %6, %1
|
||||
|
||||
SBUTTERFLY wd, 0, 1, 4
|
||||
SBUTTERFLY wd, 2, 3, 4
|
||||
|
||||
E16_O16 trans_coeffs16, 0 + %1, 15 * %6 + %1, %2, %3, %7, m8, 0, 15 * 16
|
||||
mova m8, %3
|
||||
E16_O16 trans_coeffs16 + 64, %6 + %1, 14 * %6 + %1, %2, m8, %7, m9, 16, 14 * 16
|
||||
E16_O16 trans_coeffs16 + 2 * 64, 2 * %6 + %1, 13 * %6 + %1, %2, m8, %7, m10, 2 * 16, 13 * 16
|
||||
E16_O16 trans_coeffs16 + 3 * 64, 3 * %6 + %1, 12 * %6 + %1, %2, m8, %7, m11, 3 * 16, 12 * 16
|
||||
E16_O16 trans_coeffs16 + 4 * 64, 4 * %6 + %1, 11 * %6 + %1, %2, m8, %7, m12, 4 * 16, 11 * 16
|
||||
E16_O16 trans_coeffs16 + 5 * 64, 5 * %6 + %1, 10 * %6 + %1, %2, m8, %7, m13, 5 * 16, 10 * 16
|
||||
E16_O16 trans_coeffs16 + 6 * 64, 6 * %6 + %1, 9 * %6 + %1, %2, m8, %7, m14, 6 * 16, 9 * 16
|
||||
E16_O16 trans_coeffs16 + 7 * 64, 7 * %6 + %1, 8 * %6 + %1, %2, m8, %7, m15, 7 * 16, 8 * 16
|
||||
%endmacro
|
||||
|
||||
%macro TRANSPOSE_16x16 0
|
||||
cglobal hevc_idct_transpose_16x16, 0, 0, 0
|
||||
; M1 M2 M3 M4 ^T m1 m5 m9 m13 M_i^T = m_i
|
||||
; M5 M6 M7 M8 --> m2 m6 m10 m14
|
||||
; M9 M10 M11 M12 m3 m7 m11 m15
|
||||
; M13 M14 M15 M16 m4 m8 m12 m16
|
||||
|
||||
; M1 4x4 block
|
||||
TRANSPOSE_BLOCK 0, 0, 32
|
||||
|
||||
; M5, M2
|
||||
SWAP_BLOCKS 0, 128, 32, 0, 8
|
||||
; M9, M3
|
||||
SWAP_BLOCKS 0, 256, 32, 0, 16
|
||||
; M13, M4
|
||||
SWAP_BLOCKS 0, 384, 32, 0, 24
|
||||
|
||||
;M6
|
||||
TRANSPOSE_BLOCK 8, 128, 32
|
||||
|
||||
; M10, M7
|
||||
SWAP_BLOCKS 8, 256, 32, 128, 16
|
||||
; M14, M8
|
||||
SWAP_BLOCKS 8, 384, 32, 128, 24
|
||||
|
||||
;M11
|
||||
TRANSPOSE_BLOCK 16, 256, 32
|
||||
|
||||
; M15, M12
|
||||
SWAP_BLOCKS 16, 384, 32, 256, 24
|
||||
|
||||
;M16
|
||||
TRANSPOSE_BLOCK 24, 384, 32
|
||||
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
; void ff_hevc_idct_16x16_{8,10}_<opt>(int16_t *coeffs, int col_limit)
|
||||
; %1 = bitdepth
|
||||
%macro IDCT_16x16 1
|
||||
cglobal hevc_idct_16x16_%1, 1, 2, 16, coeffs
|
||||
mov r1d, 3
|
||||
.loop16:
|
||||
TR_16x4 8 * r1, 7, [pd_64], 64, 2, 32, 8, 16, 1, 0
|
||||
dec r1d
|
||||
jge .loop16
|
||||
|
||||
call hevc_idct_transpose_16x16_ %+ cpuname
|
||||
|
||||
DEFINE_BIAS %1
|
||||
mov r1d, 3
|
||||
.loop16_2:
|
||||
TR_16x4 8 * r1, shift, [arr_add], 64, 2, 32, 8, 16, 1, 1
|
||||
dec r1d
|
||||
jge .loop16_2
|
||||
|
||||
TAIL_CALL hevc_idct_transpose_16x16_ %+ cpuname, 1
|
||||
%endmacro
|
||||
|
||||
; scale, pack (clip16) and store the residuals 0 e32[0] + o32[0] --> %1
|
||||
; 4 at one time (4 columns) 1 e32[1] + o32[1]
|
||||
; %1 - address to store e32 + o32
|
||||
; %2 - address to store e32 - e32
|
||||
; %5 - reg with e32 + o32 ...
|
||||
; %3 - reg with e32 - o32 30 e32[1] - o32[1]
|
||||
; %4 - shift 31 e32[0] - o32[0] --> %2
|
||||
%macro STORE_32 5
|
||||
psrad %5, %4
|
||||
psrad %3, %4
|
||||
packssdw %5, %3
|
||||
movq [%1], %5
|
||||
movhps [%2], %5
|
||||
%endmacro
|
||||
|
||||
; %1 - transform coeffs
|
||||
; %2 - stack offset for e32
|
||||
; %2, %3 offsets for storing e+o/e-o back to coeffsq
|
||||
; %4 - shift
|
||||
; %5 - stack offset of e32
|
||||
%macro E32_O32 5
|
||||
ADD_ROWS [%1], [%1 + 16], m0, m1, 1, m8, m9, m10
|
||||
ADD_ROWS [%1 + 2 * 16], [%1 + 3 * 16], m2, m3, 0, m8, m9, m10
|
||||
ADD_ROWS [%1 + 4 * 16], [%1 + 5 * 16], m4, m5, 0, m8, m9, m10
|
||||
ADD_ROWS [%1 + 6 * 16], [%1 + 7 * 16], m6, m7, 0, m8, m9, m10
|
||||
|
||||
paddd m11, m14, [rsp + %5]
|
||||
paddd m12, m10, m11 ; o32 + e32
|
||||
psubd m11, m10 ; e32 - o32
|
||||
STORE_32 %2, %3, m11, %4, m12
|
||||
%endmacro
|
||||
|
||||
; %1 - horizontal offset
|
||||
; %2 - bitdepth
|
||||
%macro TR_32x4 3
|
||||
TR_16x4 %1, 7, [pd_64], 128, 4, 64, 16, 16, 2, 0
|
||||
|
||||
LOAD_BLOCK m0, m1, 64, 3 * 64, 5 * 64, 7 * 64, %1
|
||||
LOAD_BLOCK m2, m3, 9 * 64, 11 * 64, 13 * 64, 15 * 64, %1
|
||||
LOAD_BLOCK m4, m5, 17 * 64, 19 * 64, 21 * 64, 23 * 64, %1
|
||||
LOAD_BLOCK m6, m7, 25 * 64, 27 * 64, 29 * 64, 31 * 64, %1
|
||||
|
||||
SBUTTERFLY wd, 0, 1, 8
|
||||
SBUTTERFLY wd, 2, 3, 8
|
||||
SBUTTERFLY wd, 4, 5, 8
|
||||
SBUTTERFLY wd, 6, 7, 8
|
||||
|
||||
%if %3 == 1
|
||||
%assign shift 7
|
||||
mova m14, [pd_64]
|
||||
%else
|
||||
LOAD_BIAS %2, m14
|
||||
%endif
|
||||
|
||||
lea r2, [trans_coeff32 + 15 * 128]
|
||||
lea r3, [coeffsq + %1]
|
||||
lea r4, [r3 + 16 * 64]
|
||||
mov r5d, 15 * 16
|
||||
%%loop:
|
||||
E32_O32 r2, r3 + r5 * 4, r4, shift, r5
|
||||
sub r2, 128
|
||||
add r4, 64
|
||||
sub r5d, 16
|
||||
jge %%loop
|
||||
%endmacro
|
||||
|
||||
%macro TRANSPOSE_32x32 0
|
||||
cglobal hevc_idct_transpose_32x32, 0, 0, 0
|
||||
; M0 M1 ... M7
|
||||
; M8 M15
|
||||
;
|
||||
; ...
|
||||
;
|
||||
; M56 M63
|
||||
|
||||
TRANSPOSE_BLOCK 0, 0, 64 ; M1
|
||||
mov r1d, 7
|
||||
mov r2d, 7 * 256
|
||||
.loop_transpose:
|
||||
SWAP_BLOCKS 0, r2, 64, 0, r1 * 8
|
||||
sub r2d, 256
|
||||
dec r1d
|
||||
jg .loop_transpose
|
||||
|
||||
TRANSPOSE_BLOCK 8, 256, 64 ; M9
|
||||
mov r1d, 6
|
||||
mov r2d, 512
|
||||
mov r3d, 16
|
||||
.loop_transpose2:
|
||||
SWAP_BLOCKS 8, r2, 64, 256, r3
|
||||
add r3d, 8
|
||||
add r2d, 256
|
||||
dec r1d
|
||||
jg .loop_transpose2
|
||||
|
||||
TRANSPOSE_BLOCK 2 * 8, 2 * 256, 64 ; M9
|
||||
mov r1d, 5
|
||||
mov r2d, 768
|
||||
mov r3d, 24
|
||||
.loop_transpose3:
|
||||
SWAP_BLOCKS 2 * 8, r2, 64, 2 * 256, r3
|
||||
add r3d, 8
|
||||
add r2d, 256
|
||||
dec r1d
|
||||
jg .loop_transpose3
|
||||
|
||||
TRANSPOSE_BLOCK 3 * 8, 3 * 256, 64 ; M27
|
||||
mov r1d, 4
|
||||
mov r2d, 1024
|
||||
mov r3d, 32
|
||||
.loop_transpose4:
|
||||
SWAP_BLOCKS 3 * 8, r2, 64, 3 * 256, r3
|
||||
add r3d, 8
|
||||
add r2d, 256
|
||||
dec r1d
|
||||
jg .loop_transpose4
|
||||
|
||||
TRANSPOSE_BLOCK 4 * 8, 4 * 256, 64 ; M36
|
||||
mov r1d, 3
|
||||
mov r2d, 1280
|
||||
mov r3d, 40
|
||||
.loop_transpose5:
|
||||
SWAP_BLOCKS 4 * 8, r2, 64, 4 * 256, r3
|
||||
add r3d, 8
|
||||
add r2d, 256
|
||||
dec r1d
|
||||
jg .loop_transpose5
|
||||
|
||||
TRANSPOSE_BLOCK 5 * 8, 5 * 256, 64 ; M45
|
||||
SWAP_BLOCKS 5 * 8, 6 * 256, 64, 5 * 256, 6 * 8
|
||||
SWAP_BLOCKS 5 * 8, 7 * 256, 64, 5 * 256, 7 * 8
|
||||
|
||||
TRANSPOSE_BLOCK 6 * 8, 6 * 256, 64 ; M54
|
||||
SWAP_BLOCKS 6 * 8, 7 * 256, 64, 6 * 256, 7 * 8
|
||||
|
||||
TRANSPOSE_BLOCK 7 * 8, 7 * 256, 64 ; M63
|
||||
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
; void ff_hevc_idct_32x32_{8,10}_<opt>(int16_t *coeffs, int col_limit)
|
||||
; %1 = bitdepth
|
||||
%macro IDCT_32x32 1
|
||||
cglobal hevc_idct_32x32_%1, 1, 6, 16, 256, coeffs
|
||||
mov r1d, 7
|
||||
.loop32:
|
||||
TR_32x4 8 * r1, %1, 1
|
||||
dec r1d
|
||||
jge .loop32
|
||||
|
||||
call hevc_idct_transpose_32x32_ %+ cpuname
|
||||
|
||||
mov r1d, 7
|
||||
.loop32_2:
|
||||
TR_32x4 8 * r1, %1, 0
|
||||
dec r1d
|
||||
jge .loop32_2
|
||||
|
||||
TAIL_CALL hevc_idct_transpose_32x32_ %+ cpuname, 1
|
||||
%endmacro
|
||||
|
||||
%macro INIT_IDCT_DC 1
|
||||
INIT_MMX mmxext
|
||||
IDCT_DC_NL 4, %1
|
||||
|
||||
INIT_XMM sse2
|
||||
IDCT_DC_NL 8, %1
|
||||
IDCT_DC 16, 4, %1
|
||||
IDCT_DC 32, 16, %1
|
||||
|
||||
%if HAVE_AVX2_EXTERNAL
|
||||
INIT_YMM avx2
|
||||
IDCT_DC 16, 2, %1
|
||||
IDCT_DC 32, 8, %1
|
||||
%endif ;HAVE_AVX2_EXTERNAL
|
||||
%endmacro
|
||||
|
||||
%macro INIT_IDCT 2
|
||||
INIT_XMM %2
|
||||
%if %1 == 8
|
||||
TRANSPOSE_8x8
|
||||
%if ARCH_X86_64
|
||||
TRANSPOSE_16x16
|
||||
TRANSPOSE_32x32
|
||||
%endif
|
||||
%endif
|
||||
%if ARCH_X86_64
|
||||
IDCT_32x32 %1
|
||||
IDCT_16x16 %1
|
||||
%endif
|
||||
IDCT_8x8 %1
|
||||
IDCT_4x4 %1
|
||||
%endmacro
|
||||
|
||||
INIT_IDCT_DC 8
|
||||
INIT_IDCT_DC 10
|
||||
INIT_IDCT_DC 12
|
||||
INIT_IDCT 8, sse2
|
||||
INIT_IDCT 8, avx
|
||||
INIT_IDCT 10, sse2
|
||||
INIT_IDCT 10, avx
|
||||
;INIT_IDCT 12, sse2
|
||||
;INIT_IDCT 12, avx
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
||||
;******************************************************************************
|
||||
;* SIMD optimized SAO functions for HEVC 8bit decoding
|
||||
;*
|
||||
;* Copyright (c) 2013 Pierre-Edouard LEPERE
|
||||
;* Copyright (c) 2014 James Almer
|
||||
;*
|
||||
;* This file is part of FFmpeg.
|
||||
;*
|
||||
;* FFmpeg 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.
|
||||
;*
|
||||
;* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
;******************************************************************************
|
||||
|
||||
%define MAX_PB_SIZE 64
|
||||
%include "libavcodec/x86/h26x/h2656_sao.asm"
|
||||
|
||||
%macro HEVC_SAO_BAND_FILTER 2
|
||||
H2656_SAO_BAND_FILTER hevc, %1, %2
|
||||
%endmacro
|
||||
|
||||
%macro HEVC_SAO_BAND_FILTER_FUNCS 0
|
||||
HEVC_SAO_BAND_FILTER 8, 0
|
||||
HEVC_SAO_BAND_FILTER 16, 1
|
||||
HEVC_SAO_BAND_FILTER 32, 2
|
||||
HEVC_SAO_BAND_FILTER 48, 2
|
||||
HEVC_SAO_BAND_FILTER 64, 4
|
||||
%endmacro
|
||||
|
||||
INIT_XMM sse2
|
||||
HEVC_SAO_BAND_FILTER_FUNCS
|
||||
INIT_XMM avx
|
||||
HEVC_SAO_BAND_FILTER_FUNCS
|
||||
|
||||
%if HAVE_AVX2_EXTERNAL
|
||||
INIT_XMM avx2
|
||||
HEVC_SAO_BAND_FILTER 8, 0
|
||||
HEVC_SAO_BAND_FILTER 16, 1
|
||||
INIT_YMM avx2
|
||||
HEVC_SAO_BAND_FILTER 32, 1
|
||||
HEVC_SAO_BAND_FILTER 48, 1
|
||||
HEVC_SAO_BAND_FILTER 64, 2
|
||||
%endif
|
||||
|
||||
%macro HEVC_SAO_EDGE_FILTER 2-3
|
||||
H2656_SAO_EDGE_FILTER hevc, %{1:-1}
|
||||
%endmacro
|
||||
|
||||
INIT_XMM ssse3
|
||||
HEVC_SAO_EDGE_FILTER 8, 0
|
||||
HEVC_SAO_EDGE_FILTER 16, 1, a
|
||||
HEVC_SAO_EDGE_FILTER 32, 2, a
|
||||
HEVC_SAO_EDGE_FILTER 48, 2, a
|
||||
HEVC_SAO_EDGE_FILTER 64, 4, a
|
||||
|
||||
%if HAVE_AVX2_EXTERNAL
|
||||
INIT_YMM avx2
|
||||
HEVC_SAO_EDGE_FILTER 32, 1, a
|
||||
HEVC_SAO_EDGE_FILTER 48, 1, u
|
||||
HEVC_SAO_EDGE_FILTER 64, 2, a
|
||||
%endif
|
||||
@@ -0,0 +1,97 @@
|
||||
;******************************************************************************
|
||||
;* SIMD optimized SAO functions for HEVC 10/12bit decoding
|
||||
;*
|
||||
;* Copyright (c) 2013 Pierre-Edouard LEPERE
|
||||
;* Copyright (c) 2014 James Almer
|
||||
;*
|
||||
;* This file is part of FFmpeg.
|
||||
;*
|
||||
;* FFmpeg 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.
|
||||
;*
|
||||
;* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
;******************************************************************************
|
||||
|
||||
%define MAX_PB_SIZE 64
|
||||
%include "libavcodec/x86/h26x/h2656_sao_10bit.asm"
|
||||
|
||||
%macro HEVC_SAO_BAND_FILTER 3
|
||||
H2656_SAO_BAND_FILTER hevc, %1, %2, %3
|
||||
%endmacro
|
||||
|
||||
%macro HEVC_SAO_BAND_FILTER_FUNCS 1
|
||||
HEVC_SAO_BAND_FILTER %1, 8, 1
|
||||
HEVC_SAO_BAND_FILTER %1, 16, 2
|
||||
HEVC_SAO_BAND_FILTER %1, 32, 4
|
||||
HEVC_SAO_BAND_FILTER %1, 48, 6
|
||||
HEVC_SAO_BAND_FILTER %1, 64, 8
|
||||
%endmacro
|
||||
|
||||
%macro HEVC_SAO_BAND_FILTER_FUNCS 0
|
||||
HEVC_SAO_BAND_FILTER_FUNCS 10
|
||||
HEVC_SAO_BAND_FILTER_FUNCS 12
|
||||
%endmacro
|
||||
|
||||
INIT_XMM sse2
|
||||
HEVC_SAO_BAND_FILTER_FUNCS
|
||||
INIT_XMM avx
|
||||
HEVC_SAO_BAND_FILTER_FUNCS
|
||||
|
||||
%if HAVE_AVX2_EXTERNAL
|
||||
|
||||
%macro HEVC_SAO_BAND_FILTER_FUNCS_AVX2 1
|
||||
INIT_XMM avx2
|
||||
HEVC_SAO_BAND_FILTER %1, 8, 1
|
||||
INIT_YMM avx2
|
||||
HEVC_SAO_BAND_FILTER %1, 16, 1
|
||||
HEVC_SAO_BAND_FILTER %1, 32, 2
|
||||
HEVC_SAO_BAND_FILTER %1, 48, 3
|
||||
HEVC_SAO_BAND_FILTER %1, 64, 4
|
||||
%endmacro
|
||||
|
||||
HEVC_SAO_BAND_FILTER_FUNCS_AVX2 10
|
||||
HEVC_SAO_BAND_FILTER_FUNCS_AVX2 12
|
||||
|
||||
%endif
|
||||
|
||||
%macro HEVC_SAO_EDGE_FILTER 3
|
||||
H2656_SAO_EDGE_FILTER hevc, %1, %2, %3
|
||||
%endmacro
|
||||
|
||||
%macro HEVC_SAO_EDGE_FILTER_FUNCS 1
|
||||
HEVC_SAO_EDGE_FILTER %1, 8, 1
|
||||
HEVC_SAO_EDGE_FILTER %1, 16, 2
|
||||
HEVC_SAO_EDGE_FILTER %1, 32, 4
|
||||
HEVC_SAO_EDGE_FILTER %1, 48, 6
|
||||
HEVC_SAO_EDGE_FILTER %1, 64, 8
|
||||
%endmacro
|
||||
|
||||
INIT_XMM sse2
|
||||
HEVC_SAO_EDGE_FILTER_FUNCS 10
|
||||
HEVC_SAO_EDGE_FILTER_FUNCS 12
|
||||
|
||||
%if HAVE_AVX2_EXTERNAL
|
||||
|
||||
%macro HEVC_SAO_EDGE_FILTER_FUNCS_AVX2 1
|
||||
INIT_XMM avx2
|
||||
HEVC_SAO_EDGE_FILTER %1, 8, 1
|
||||
INIT_YMM avx2
|
||||
HEVC_SAO_EDGE_FILTER %1, 16, 1
|
||||
HEVC_SAO_EDGE_FILTER %1, 32, 2
|
||||
HEVC_SAO_EDGE_FILTER %1, 48, 3
|
||||
HEVC_SAO_EDGE_FILTER %1, 64, 4
|
||||
%endmacro
|
||||
|
||||
HEVC_SAO_EDGE_FILTER_FUNCS_AVX2 10
|
||||
HEVC_SAO_EDGE_FILTER_FUNCS_AVX2 12
|
||||
|
||||
%endif
|
||||
Reference in New Issue
Block a user