1 ;*****************************************************************************
2 ;* MMX/SSE2/AVX-optimized 10-bit H.264 intra prediction code
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2011 x264 project
6 ;* Authors: Daniel Kang <daniel.d.kang@gmail.com>
8 ;* This file is part of FFmpeg.
10 ;* FFmpeg is free software; you can redistribute it and/or
11 ;* modify it under the terms of the GNU Lesser General Public
12 ;* License as published by the Free Software Foundation; either
13 ;* version 2.1 of the License, or (at your option) any later version.
15 ;* FFmpeg is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;* Lesser General Public License for more details.
20 ;* You should have received a copy of the GNU Lesser General Public
21 ;* License along with FFmpeg; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
25 %include "libavutil/x86/x86util.asm"
35 pw_m32101234: dw -3, -2, -1, 0, 1, 2, 3, 4
37 pw_pixel_max: times 8 dw ((1 << 10)-1)
38 pw_512: times 8 dw 512
44 ; dest, left, right, src
45 ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
46 %macro PRED4x4_LOWPASS 4
52 ;-----------------------------------------------------------------------------
53 ; void ff_pred4x4_down_right(pixel *src, const pixel *topright, int stride)
54 ;-----------------------------------------------------------------------------
56 cglobal pred4x4_down_right_10, 3, 3
60 movhps m2, [r0+r2*1-8]
65 PALIGNR m3, m1, 10, m1
66 movhps m4, [r1+r2*1-8]
67 PALIGNR m0, m3, m4, 14, m4
68 movhps m4, [r1+r2*2-8]
69 PALIGNR m2, m0, m4, 14, m4
70 PRED4x4_LOWPASS m0, m2, m3, m0
90 ;------------------------------------------------------------------------------
91 ; void ff_pred4x4_vertical_right(pixel *src, const pixel *topright, int stride)
92 ;------------------------------------------------------------------------------
94 cglobal pred4x4_vertical_right_10, 3, 3, 6
97 movq m5, [r0] ; ........t3t2t1t0
99 PALIGNR m0, m5, m1, 14, m1 ; ......t3t2t1t0lt
101 movhps m1, [r0+r2*1-8]
102 PALIGNR m0, m1, 14, m1 ; ....t3t2t1t0ltl0
103 movhps m2, [r0+r2*2-8]
104 PALIGNR m1, m0, m2, 14, m2 ; ..t3t2t1t0ltl0l1
105 movhps m3, [r1+r2*1-8]
106 PALIGNR m2, m1, m3, 14, m3 ; t3t2t1t0ltl0l1l2
107 PRED4x4_LOWPASS m1, m0, m2, m1
112 PALIGNR m5, m0, 14, m2
115 PALIGNR m1, m0, 14, m0
124 %if HAVE_AVX_EXTERNAL
129 ;-------------------------------------------------------------------------------
130 ; void ff_pred4x4_horizontal_down(pixel *src, const pixel *topright, int stride)
131 ;-------------------------------------------------------------------------------
133 cglobal pred4x4_horizontal_down_10, 3, 3
136 movq m0, [r0-8] ; lt ..
138 pslldq m0, 2 ; t2 t1 t0 lt .. .. .. ..
139 movq m1, [r1+r2*2-8] ; l3
141 punpcklwd m1, m3 ; l2 l3
142 movq m2, [r0+r2*2-8] ; l1
144 punpcklwd m2, m3 ; l0 l1
145 punpckhdq m1, m2 ; l0 l1 l2 l3
146 punpckhqdq m1, m0 ; t2 t1 t0 lt l0 l1 l2 l3
147 psrldq m0, m1, 4 ; .. .. t2 t1 t0 lt l0 l1
148 psrldq m3, m1, 2 ; .. t2 t1 t0 lt l0 l1 l2
150 PRED4x4_LOWPASS m3, m1, m0, m3
153 PALIGNR m3, m5, 12, m4
166 %if HAVE_AVX_EXTERNAL
171 ;-----------------------------------------------------------------------------
172 ; void ff_pred4x4_dc(pixel *src, const pixel *topright, int stride)
173 ;-----------------------------------------------------------------------------
174 %macro HADDD 2 ; sum junk
192 cglobal pred4x4_dc_10, 3, 3
196 paddw m2, [r0+r2*2-8]
197 paddw m2, [r1+r2*1-8]
198 paddw m2, [r1+r2*2-8]
212 ;-----------------------------------------------------------------------------
213 ; void ff_pred4x4_down_left(pixel *src, const pixel *topright, int stride)
214 ;-----------------------------------------------------------------------------
216 cglobal pred4x4_down_left_10, 3, 3
222 pshufhw m2, m2, 10100100b
223 PRED4x4_LOWPASS m0, m3, m2, m0
237 %if HAVE_AVX_EXTERNAL
242 ;-----------------------------------------------------------------------------
243 ; void ff_pred4x4_vertical_left(pixel *src, const pixel *topright, int stride)
244 ;-----------------------------------------------------------------------------
246 cglobal pred4x4_vertical_left_10, 3, 3
253 PRED4x4_LOWPASS m0, m1, m2, m0
266 %if HAVE_AVX_EXTERNAL
271 ;-----------------------------------------------------------------------------
272 ; void ff_pred4x4_horizontal_up(pixel *src, const pixel *topright, int stride)
273 ;-----------------------------------------------------------------------------
275 cglobal pred4x4_horizontal_up_10, 3, 3
279 punpckhwd m0, [r0+r2*2-8]
281 punpckhwd m1, [r1+r2*2-8]
286 pshufw m2, m0, 11111001b
290 pshufw m5, m0, 11111110b
291 PRED4x4_LOWPASS m1, m0, m5, m1
305 ;-----------------------------------------------------------------------------
306 ; void ff_pred8x8_vertical(pixel *src, int stride)
307 ;-----------------------------------------------------------------------------
309 cglobal pred8x8_vertical_10, 2, 2
321 ;-----------------------------------------------------------------------------
322 ; void ff_pred8x8_horizontal(pixel *src, int stride)
323 ;-----------------------------------------------------------------------------
325 cglobal pred8x8_horizontal_10, 2, 3
341 ;-----------------------------------------------------------------------------
342 ; void ff_predict_8x8_dc(pixel *src, int stride)
343 ;-----------------------------------------------------------------------------
345 ; sort of a hack, but it works
355 cglobal pred8x8_dc_10, 2, 6
365 pshufw m2, m0, 00001110b
366 pshufw m3, m1, 00001110b
376 movzx r2d, word [r0+r1*1-2]
377 movzx r3d, word [r0+r1*2-2]
379 movzx r3d, word [r0+r5*1-2]
381 movzx r3d, word [r4-2]
385 movzx r2d, word [r4+r1*1-2]
386 movzx r3d, word [r4+r1*2-2]
388 movzx r3d, word [r4+r5*1-2]
390 movzx r3d, word [r4+r1*4-2]
395 punpckldq m0, m2 ; s0, s1, s2, s3
396 %1 m3, m0, 11110110b ; s2, s1, s3, s3
397 %1 m0, m0, 01110100b ; s0, s1, s3, s1
400 pavgw m0, m4 ; s0+s2, s1, s3, s1+s3
403 pshufd m3, m0, 11111010b
428 ;-----------------------------------------------------------------------------
429 ; void ff_pred8x8_top_dc(pixel *src, int stride)
430 ;-----------------------------------------------------------------------------
432 cglobal pred8x8_top_dc_10, 2, 4
455 ;-----------------------------------------------------------------------------
456 ; void ff_pred8x8_plane(pixel *src, int stride)
457 ;-----------------------------------------------------------------------------
459 cglobal pred8x8_plane_10, 2, 7, 7
464 pmaddwd m2, [pw_m32101234]
472 psllw m0, 4 ; 16*(src[7*stride-1] + src[-stride+7])
473 movzx r4d, word [r3+r1*1-2] ; src[4*stride-1]
474 movzx r5d, word [r0+r2*1-2] ; src[2*stride-1]
476 movzx r6d, word [r3+r1*2-2] ; src[5*stride-1]
477 movzx r5d, word [r0+r1*2-2] ; src[1*stride-1]
480 movzx r5d, word [r3+r2*1-2] ; src[6*stride-1]
481 movzx r6d, word [r0+r1*1-2] ; src[0*stride-1]
485 movzx r6d, word [r3+r1*4-2] ; src[7*stride-1]
486 movzx r5d, word [r0+r1*0-2] ; src[ -stride-1]
495 mova m3, [pw_pixel_max]
500 pmullw m2, [pw_m32101234] ; b
501 pmullw m5, m4, [pw_m3] ; c
518 ;-----------------------------------------------------------------------------
519 ; void ff_pred8x8l_128_dc(pixel *src, int has_topleft, int has_topright,
521 ;-----------------------------------------------------------------------------
522 %macro PRED8x8L_128_DC 0
523 cglobal pred8x8l_128_dc_10, 4, 4
524 mova m0, [pw_512] ; (1<<(BIT_DEPTH-1))
543 ;-----------------------------------------------------------------------------
544 ; void ff_pred8x8l_top_dc(pixel *src, int has_topleft, int has_topright,
546 ;-----------------------------------------------------------------------------
547 %macro PRED8x8L_TOP_DC 0
548 cglobal pred8x8l_top_dc_10, 4, 4, 6
556 pinsrw m1, [r0+r1], 0
557 pinsrw m2, [r0+r2+14], 7
560 PRED4x4_LOWPASS m0, m2, m1, m0
578 %if HAVE_AVX_EXTERNAL
583 ;-------------------------------------------------------------------------------
584 ; void ff_pred8x8l_dc(pixel *src, int has_topleft, int has_topright, int stride)
585 ;-------------------------------------------------------------------------------
586 ;TODO: see if scalar is faster
588 cglobal pred8x8l_dc_10, 4, 6, 6
592 mova m0, [r0+r3*2-16]
593 punpckhwd m0, [r0+r3*1-16]
594 mova m1, [r4+r3*0-16]
595 punpckhwd m1, [r0+r5*1-16]
597 mova m2, [r4+r3*2-16]
598 punpckhwd m2, [r4+r3*1-16]
599 mova m3, [r4+r3*4-16]
600 punpckhwd m3, [r4+r5*1-16]
609 pinsrw m1, [r0+r1], 0
610 pinsrw m2, [r0+r2+14], 7
615 pshuflw m4, m4, 11100101b
616 pinsrw m5, [r0+r1-2], 7
617 PRED4x4_LOWPASS m3, m4, m5, m3
618 PRED4x4_LOWPASS m0, m2, m1, m0
637 %if HAVE_AVX_EXTERNAL
642 ;-----------------------------------------------------------------------------
643 ; void ff_pred8x8l_vertical(pixel *src, int has_topleft, int has_topright,
645 ;-----------------------------------------------------------------------------
646 %macro PRED8x8L_VERTICAL 0
647 cglobal pred8x8l_vertical_10, 4, 4, 6
655 pinsrw m1, [r0+r1], 0
656 pinsrw m2, [r0+r2+14], 7
659 PRED4x4_LOWPASS m0, m2, m1, m0
673 %if HAVE_AVX_EXTERNAL
678 ;-----------------------------------------------------------------------------
679 ; void ff_pred8x8l_horizontal(uint8_t *src, int has_topleft, int has_topright,
681 ;-----------------------------------------------------------------------------
682 %macro PRED8x8L_HORIZONTAL 0
683 cglobal pred8x8l_horizontal_10, 4, 4, 5
689 punpckhwd m0, [r0+r1-16]
690 mova m1, [r0+r3*2-16]
691 punpckhwd m1, [r0+r3*1-16]
695 mova m2, [r2+r3*0-16]
696 punpckhwd m2, [r0+r1-16]
697 mova m3, [r2+r3*2-16]
698 punpckhwd m3, [r2+r3*1-16]
701 PALIGNR m4, m3, [r2+r1-16], 14, m0
703 pshuflw m0, m0, 11100101b
704 PRED4x4_LOWPASS m4, m3, m0, m4
730 %if HAVE_AVX_EXTERNAL
735 ;-----------------------------------------------------------------------------
736 ; void ff_pred8x8l_down_left(pixel *src, int has_topleft, int has_topright,
738 ;-----------------------------------------------------------------------------
739 %macro PRED8x8L_DOWN_LEFT 0
740 cglobal pred8x8l_down_left_10, 4, 4, 7
748 pinsrw m1, [r0+r1], 0
749 pinsrw m2, [r0+r2+14], 7
750 PRED4x4_LOWPASS m6, m2, m1, m3
751 jz .fix_tr ; flags from shr r2d
754 PALIGNR m2, m1, m3, 14, m3
755 pshufhw m5, m5, 10100100b
756 PRED4x4_LOWPASS m1, m2, m5, m1
761 PALIGNR m2, m1, m6, 2, m0
762 PALIGNR m3, m1, m6, 14, m0
763 PALIGNR m5, m1, 2, m0
765 PRED4x4_LOWPASS m6, m4, m2, m6
766 PRED4x4_LOWPASS m1, m3, m5, m1
768 PALIGNR m1, m6, 14, m2
771 PALIGNR m1, m6, 14, m2
774 PALIGNR m1, m6, 14, m2
777 PALIGNR m1, m6, 14, m2
780 PALIGNR m1, m6, 14, m2
783 PALIGNR m1, m6, 14, m2
786 PALIGNR m1, m6, 14, m6
799 %if HAVE_AVX_EXTERNAL
804 ;-----------------------------------------------------------------------------
805 ; void ff_pred8x8l_down_right(pixel *src, int has_topleft, int has_topright,
807 ;-----------------------------------------------------------------------------
808 %macro PRED8x8L_DOWN_RIGHT 0
809 ; standard forbids this when has_topleft is false
811 cglobal pred8x8l_down_right_10, 4, 5, 8
815 mova m0, [r0+r3*1-16]
816 punpckhwd m0, [r0+r3*0-16]
817 mova m1, [r0+r1*1-16]
818 punpckhwd m1, [r0+r3*2-16]
820 mova m2, [r4+r3*1-16]
821 punpckhwd m2, [r4+r3*0-16]
822 mova m3, [r4+r1*1-16]
823 punpckhwd m3, [r4+r3*2-16]
826 mova m0, [r4+r3*4-16]
828 PALIGNR m4, m3, m0, 14, m0
829 PALIGNR m1, m3, 2, m2
831 pshuflw m0, m0, 11100101b
832 PRED4x4_LOWPASS m6, m1, m4, m3
833 PRED4x4_LOWPASS m4, m3, m0, m4
839 pinsrw m2, [r0+r2+14], 7
840 PRED4x4_LOWPASS m3, m2, m1, m3
841 PALIGNR m2, m3, m6, 2, m0
842 PALIGNR m5, m3, m6, 14, m0
844 PRED4x4_LOWPASS m6, m4, m2, m6
845 PRED4x4_LOWPASS m3, m5, m7, m3
847 PALIGNR m3, m6, 14, m2
850 PALIGNR m3, m6, 14, m2
853 PALIGNR m3, m6, 14, m2
856 PALIGNR m3, m6, 14, m2
859 PALIGNR m3, m6, 14, m2
862 PALIGNR m3, m6, 14, m2
865 PALIGNR m3, m6, 14, m6
874 %if HAVE_AVX_EXTERNAL
879 ;-----------------------------------------------------------------------------
880 ; void ff_pred8x8l_vertical_right(pixel *src, int has_topleft,
881 ; int has_topright, int stride)
882 ;-----------------------------------------------------------------------------
883 %macro PRED8x8L_VERTICAL_RIGHT 0
884 ; likewise with 8x8l_down_right
885 cglobal pred8x8l_vertical_right_10, 4, 5, 7
889 mova m0, [r0+r3*1-16]
890 punpckhwd m0, [r0+r3*0-16]
891 mova m1, [r0+r1*1-16]
892 punpckhwd m1, [r0+r3*2-16]
894 mova m2, [r4+r3*1-16]
895 punpckhwd m2, [r4+r3*0-16]
896 mova m3, [r4+r1*1-16]
897 punpckhwd m3, [r4+r3*2-16]
900 mova m0, [r4+r3*4-16]
902 PALIGNR m4, m3, m0, 14, m0
903 PALIGNR m1, m3, 2, m2
904 PRED4x4_LOWPASS m3, m1, m4, m3
910 pinsrw m5, [r0+r2+14], 7
911 PRED4x4_LOWPASS m2, m5, m1, m2
912 PALIGNR m6, m2, m3, 12, m1
913 PALIGNR m5, m2, m3, 14, m0
914 PRED4x4_LOWPASS m0, m6, m2, m5
920 PRED4x4_LOWPASS m1, m3, m6, m1
921 PALIGNR m2, m1, 14, m4
924 PALIGNR m0, m1, 14, m3
927 PALIGNR m2, m1, 14, m4
930 PALIGNR m0, m1, 14, m3
933 PALIGNR m2, m1, 14, m4
936 PALIGNR m0, m1, 14, m1
942 PRED8x8L_VERTICAL_RIGHT
944 PRED8x8L_VERTICAL_RIGHT
945 %if HAVE_AVX_EXTERNAL
947 PRED8x8L_VERTICAL_RIGHT
950 ;-----------------------------------------------------------------------------
951 ; void ff_pred8x8l_horizontal_up(pixel *src, int has_topleft,
952 ; int has_topright, int stride)
953 ;-----------------------------------------------------------------------------
954 %macro PRED8x8L_HORIZONTAL_UP 0
955 cglobal pred8x8l_horizontal_up_10, 4, 4, 6
956 mova m0, [r0+r3*0-16]
957 punpckhwd m0, [r0+r3*1-16]
962 mova m4, [r0+r1*1-16]
965 mova m1, [r0+r3*2-16]
966 punpckhwd m1, [r0+r1*1-16]
968 mova m2, [r2+r3*0-16]
969 punpckhwd m2, [r2+r3*1-16]
970 mova m3, [r2+r3*2-16]
971 punpckhwd m3, [r2+r1*1-16]
974 PALIGNR m1, m0, m4, 14, m4
976 pshufhw m2, m2, 10100100b
977 PRED4x4_LOWPASS m0, m1, m2, m0
980 pshufhw m1, m1, 10100100b
981 pshufhw m2, m2, 01010100b
983 PRED4x4_LOWPASS m1, m2, m0, m1
988 pshufd m0, m5, 11111001b
989 pshufd m1, m5, 11111110b
990 pshufd m2, m5, 11111111b
994 PALIGNR m2, m5, m4, 4, m0
995 PALIGNR m3, m5, m4, 8, m1
996 PALIGNR m5, m5, m4, 12, m4
1004 PRED8x8L_HORIZONTAL_UP
1006 PRED8x8L_HORIZONTAL_UP
1007 %if HAVE_AVX_EXTERNAL
1009 PRED8x8L_HORIZONTAL_UP
1013 ;-----------------------------------------------------------------------------
1014 ; void ff_pred16x16_vertical(pixel *src, int stride)
1015 ;-----------------------------------------------------------------------------
1018 mova [%1+mmsize], %3
1025 %macro PRED16x16_VERTICAL 0
1026 cglobal pred16x16_vertical_10, 2, 3
1030 mova m1, [r0+mmsize]
1036 MOV16 r0+r1*1, m0, m1, m2, m3
1037 MOV16 r0+r1*2, m0, m1, m2, m3
1049 ;-----------------------------------------------------------------------------
1050 ; void ff_pred16x16_horizontal(pixel *src, int stride)
1051 ;-----------------------------------------------------------------------------
1052 %macro PRED16x16_HORIZONTAL 0
1053 cglobal pred16x16_horizontal_10, 2, 3
1056 movd m0, [r0+r1*0-4]
1057 movd m1, [r0+r1*1-4]
1060 MOV16 r0+r1*0, m0, m0, m0, m0
1061 MOV16 r0+r1*1, m1, m1, m1, m1
1069 PRED16x16_HORIZONTAL
1071 PRED16x16_HORIZONTAL
1073 ;-----------------------------------------------------------------------------
1074 ; void ff_pred16x16_dc(pixel *src, int stride)
1075 ;-----------------------------------------------------------------------------
1076 %macro PRED16x16_DC 0
1077 cglobal pred16x16_dc_10, 2, 6
1081 paddw m0, [r0+mmsize]
1089 movzx r3d, word [r0]
1090 movzx r4d, word [r0+r1]
1093 movzx r2d, word [r0]
1095 movzx r2d, word [r0+r1]
1106 MOV16 r5+r1*0, m0, m0, m0, m0
1107 MOV16 r5+r1*1, m0, m0, m0, m0
1119 ;-----------------------------------------------------------------------------
1120 ; void ff_pred16x16_top_dc(pixel *src, int stride)
1121 ;-----------------------------------------------------------------------------
1122 %macro PRED16x16_TOP_DC 0
1123 cglobal pred16x16_top_dc_10, 2, 3
1126 paddw m0, [r0+mmsize]
1138 MOV16 r0+r1*1, m0, m0, m0, m0
1139 MOV16 r0+r1*2, m0, m0, m0, m0
1151 ;-----------------------------------------------------------------------------
1152 ; void ff_pred16x16_left_dc(pixel *src, int stride)
1153 ;-----------------------------------------------------------------------------
1154 %macro PRED16x16_LEFT_DC 0
1155 cglobal pred16x16_left_dc_10, 2, 6
1159 movzx r3d, word [r0]
1160 movzx r4d, word [r0+r1]
1163 movzx r2d, word [r0]
1165 movzx r2d, word [r0+r1]
1175 MOV16 r5+r1*0, m0, m0, m0, m0
1176 MOV16 r5+r1*1, m0, m0, m0, m0
1188 ;-----------------------------------------------------------------------------
1189 ; void ff_pred16x16_128_dc(pixel *src, int stride)
1190 ;-----------------------------------------------------------------------------
1191 %macro PRED16x16_128_DC 0
1192 cglobal pred16x16_128_dc_10, 2,3
1196 MOV16 r0+r1*0, m0, m0, m0, m0
1197 MOV16 r0+r1*1, m0, m0, m0, m0