]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/h264_idct_10bit.asm
Use av_packet_rescale_ts() to simplify code.
[ffmpeg] / libavcodec / x86 / h264_idct_10bit.asm
1 ;*****************************************************************************
2 ;* MMX/SSE2/AVX-optimized 10-bit H.264 iDCT code
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2011 x264 project
5 ;*
6 ;* Authors: Daniel Kang <daniel.d.kang@gmail.com>
7 ;*
8 ;* This file is part of Libav.
9 ;*
10 ;* Libav 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.
14 ;*
15 ;* Libav 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.
19 ;*
20 ;* You should have received a copy of the GNU Lesser General Public
21 ;* License along with Libav; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
24
25 %include "libavutil/x86/x86util.asm"
26
27 SECTION_RODATA
28
29 pw_pixel_max: times 8 dw ((1 << 10)-1)
30 pd_32:        times 4 dd 32
31
32 SECTION .text
33
34 ;-----------------------------------------------------------------------------
35 ; void ff_h264_idct_add_10(pixel *dst, int16_t *block, int stride)
36 ;-----------------------------------------------------------------------------
37 %macro STORE_DIFFx2 6
38     psrad       %1, 6
39     psrad       %2, 6
40     packssdw    %1, %2
41     movq        %3, [%5]
42     movhps      %3, [%5+%6]
43     paddsw      %1, %3
44     CLIPW       %1, %4, [pw_pixel_max]
45     movq      [%5], %1
46     movhps [%5+%6], %1
47 %endmacro
48
49 %macro STORE_DIFF16 5
50     psrad       %1, 6
51     psrad       %2, 6
52     packssdw    %1, %2
53     paddsw      %1, [%5]
54     CLIPW       %1, %3, %4
55     mova      [%5], %1
56 %endmacro
57
58 ;dst, in, stride
59 %macro IDCT4_ADD_10 3
60     mova  m0, [%2+ 0]
61     mova  m1, [%2+16]
62     mova  m2, [%2+32]
63     mova  m3, [%2+48]
64     IDCT4_1D d,0,1,2,3,4,5
65     TRANSPOSE4x4D 0,1,2,3,4
66     paddd m0, [pd_32]
67     IDCT4_1D d,0,1,2,3,4,5
68     pxor  m5, m5
69     mova [%2+ 0], m5
70     mova [%2+16], m5
71     mova [%2+32], m5
72     mova [%2+48], m5
73     STORE_DIFFx2 m0, m1, m4, m5, %1, %3
74     lea   %1, [%1+%3*2]
75     STORE_DIFFx2 m2, m3, m4, m5, %1, %3
76 %endmacro
77
78 %macro IDCT_ADD_10 0
79 cglobal h264_idct_add_10, 3,3
80     IDCT4_ADD_10 r0, r1, r2
81     RET
82 %endmacro
83
84 INIT_XMM sse2
85 IDCT_ADD_10
86 INIT_XMM avx
87 IDCT_ADD_10
88
89 ;-----------------------------------------------------------------------------
90 ; void ff_h264_idct_add16_10(pixel *dst, const int *block_offset,
91 ;                            int16_t *block, int stride,
92 ;                            const uint8_t nnzc[6*8])
93 ;-----------------------------------------------------------------------------
94 ;;;;;;; NO FATE SAMPLES TRIGGER THIS
95 %macro ADD4x4IDCT 0
96 add4x4_idct %+ SUFFIX:
97     add   r5, r0
98     mova  m0, [r2+ 0]
99     mova  m1, [r2+16]
100     mova  m2, [r2+32]
101     mova  m3, [r2+48]
102     IDCT4_1D d,0,1,2,3,4,5
103     TRANSPOSE4x4D 0,1,2,3,4
104     paddd m0, [pd_32]
105     IDCT4_1D d,0,1,2,3,4,5
106     pxor  m5, m5
107     mova  [r2+ 0], m5
108     mova  [r2+16], m5
109     mova  [r2+32], m5
110     mova  [r2+48], m5
111     STORE_DIFFx2 m0, m1, m4, m5, r5, r3
112     lea   r5, [r5+r3*2]
113     STORE_DIFFx2 m2, m3, m4, m5, r5, r3
114     ret
115 %endmacro
116
117 INIT_XMM sse2
118 ALIGN 16
119 ADD4x4IDCT
120 INIT_XMM avx
121 ALIGN 16
122 ADD4x4IDCT
123
124 %macro ADD16_OP 2
125     cmp          byte [r4+%2], 0
126     jz .skipblock%1
127     mov         r5d, [r1+%1*4]
128     call add4x4_idct %+ SUFFIX
129 .skipblock%1:
130 %if %1<15
131     add          r2, 64
132 %endif
133 %endmacro
134
135 %macro IDCT_ADD16_10 0
136 cglobal h264_idct_add16_10, 5,6
137     ADD16_OP 0, 4+1*8
138     ADD16_OP 1, 5+1*8
139     ADD16_OP 2, 4+2*8
140     ADD16_OP 3, 5+2*8
141     ADD16_OP 4, 6+1*8
142     ADD16_OP 5, 7+1*8
143     ADD16_OP 6, 6+2*8
144     ADD16_OP 7, 7+2*8
145     ADD16_OP 8, 4+3*8
146     ADD16_OP 9, 5+3*8
147     ADD16_OP 10, 4+4*8
148     ADD16_OP 11, 5+4*8
149     ADD16_OP 12, 6+3*8
150     ADD16_OP 13, 7+3*8
151     ADD16_OP 14, 6+4*8
152     ADD16_OP 15, 7+4*8
153     REP_RET
154 %endmacro
155
156 INIT_XMM sse2
157 IDCT_ADD16_10
158 INIT_XMM avx
159 IDCT_ADD16_10
160
161 ;-----------------------------------------------------------------------------
162 ; void ff_h264_idct_dc_add_10(pixel *dst, int16_t *block, int stride)
163 ;-----------------------------------------------------------------------------
164 %macro IDCT_DC_ADD_OP_10 3
165     pxor      m5, m5
166 %if avx_enabled
167     paddw     m1, m0, [%1+0   ]
168     paddw     m2, m0, [%1+%2  ]
169     paddw     m3, m0, [%1+%2*2]
170     paddw     m4, m0, [%1+%3  ]
171 %else
172     mova      m1, [%1+0   ]
173     mova      m2, [%1+%2  ]
174     mova      m3, [%1+%2*2]
175     mova      m4, [%1+%3  ]
176     paddw     m1, m0
177     paddw     m2, m0
178     paddw     m3, m0
179     paddw     m4, m0
180 %endif
181     CLIPW     m1, m5, m6
182     CLIPW     m2, m5, m6
183     CLIPW     m3, m5, m6
184     CLIPW     m4, m5, m6
185     mova [%1+0   ], m1
186     mova [%1+%2  ], m2
187     mova [%1+%2*2], m3
188     mova [%1+%3  ], m4
189 %endmacro
190
191 INIT_MMX mmxext
192 cglobal h264_idct_dc_add_10,3,3
193     movd      m0, [r1]
194     mov dword [r1], 0
195     paddd     m0, [pd_32]
196     psrad     m0, 6
197     lea       r1, [r2*3]
198     pshufw    m0, m0, 0
199     mova      m6, [pw_pixel_max]
200     IDCT_DC_ADD_OP_10 r0, r2, r1
201     RET
202
203 ;-----------------------------------------------------------------------------
204 ; void ff_h264_idct8_dc_add_10(pixel *dst, int16_t *block, int stride)
205 ;-----------------------------------------------------------------------------
206 %macro IDCT8_DC_ADD 0
207 cglobal h264_idct8_dc_add_10,3,4,7
208     movd      m0, [r1]
209     mov dword[r1], 0
210     paddd     m0, [pd_32]
211     psrad     m0, 6
212     lea       r1, [r2*3]
213     SPLATW    m0, m0, 0
214     mova      m6, [pw_pixel_max]
215     IDCT_DC_ADD_OP_10 r0, r2, r1
216     lea       r0, [r0+r2*4]
217     IDCT_DC_ADD_OP_10 r0, r2, r1
218     RET
219 %endmacro
220
221 INIT_XMM sse2
222 IDCT8_DC_ADD
223 INIT_XMM avx
224 IDCT8_DC_ADD
225
226 ;-----------------------------------------------------------------------------
227 ; void ff_h264_idct_add16intra_10(pixel *dst, const int *block_offset,
228 ;                                 int16_t *block, int stride,
229 ;                                 const uint8_t nnzc[6*8])
230 ;-----------------------------------------------------------------------------
231 %macro AC 1
232 .ac%1:
233     mov  r5d, [r1+(%1+0)*4]
234     call add4x4_idct %+ SUFFIX
235     mov  r5d, [r1+(%1+1)*4]
236     add  r2, 64
237     call add4x4_idct %+ SUFFIX
238     add  r2, 64
239     jmp .skipadd%1
240 %endmacro
241
242 %assign last_block 16
243 %macro ADD16_OP_INTRA 2
244     cmp      word [r4+%2], 0
245     jnz .ac%1
246     mov      r5d, [r2+ 0]
247     or       r5d, [r2+64]
248     jz .skipblock%1
249     mov      r5d, [r1+(%1+0)*4]
250     call idct_dc_add %+ SUFFIX
251 .skipblock%1:
252 %if %1<last_block-2
253     add       r2, 128
254 %endif
255 .skipadd%1:
256 %endmacro
257
258 %macro IDCT_ADD16INTRA_10 0
259 idct_dc_add %+ SUFFIX:
260     add       r5, r0
261     movq      m0, [r2+ 0]
262     movhps    m0, [r2+64]
263     mov dword [r2+ 0], 0
264     mov dword [r2+64], 0
265     paddd     m0, [pd_32]
266     psrad     m0, 6
267     pshufhw   m0, m0, 0
268     pshuflw   m0, m0, 0
269     lea       r6, [r3*3]
270     mova      m6, [pw_pixel_max]
271     IDCT_DC_ADD_OP_10 r5, r3, r6
272     ret
273
274 cglobal h264_idct_add16intra_10,5,7,8
275     ADD16_OP_INTRA 0, 4+1*8
276     ADD16_OP_INTRA 2, 4+2*8
277     ADD16_OP_INTRA 4, 6+1*8
278     ADD16_OP_INTRA 6, 6+2*8
279     ADD16_OP_INTRA 8, 4+3*8
280     ADD16_OP_INTRA 10, 4+4*8
281     ADD16_OP_INTRA 12, 6+3*8
282     ADD16_OP_INTRA 14, 6+4*8
283     REP_RET
284     AC 8
285     AC 10
286     AC 12
287     AC 14
288     AC 0
289     AC 2
290     AC 4
291     AC 6
292 %endmacro
293
294 INIT_XMM sse2
295 IDCT_ADD16INTRA_10
296 INIT_XMM avx
297 IDCT_ADD16INTRA_10
298
299 %assign last_block 36
300 ;-----------------------------------------------------------------------------
301 ; void ff_h264_idct_add8_10(pixel **dst, const int *block_offset,
302 ;                           int16_t *block, int stride,
303 ;                           const uint8_t nnzc[6*8])
304 ;-----------------------------------------------------------------------------
305 %macro IDCT_ADD8 0
306 cglobal h264_idct_add8_10,5,8,7
307 %if ARCH_X86_64
308     mov      r7, r0
309 %endif
310     add      r2, 1024
311     mov      r0, [r0]
312     ADD16_OP_INTRA 16, 4+ 6*8
313     ADD16_OP_INTRA 18, 4+ 7*8
314     add      r2, 1024-128*2
315 %if ARCH_X86_64
316     mov      r0, [r7+gprsize]
317 %else
318     mov      r0, r0m
319     mov      r0, [r0+gprsize]
320 %endif
321     ADD16_OP_INTRA 32, 4+11*8
322     ADD16_OP_INTRA 34, 4+12*8
323     REP_RET
324     AC 16
325     AC 18
326     AC 32
327     AC 34
328
329 %endmacro ; IDCT_ADD8
330
331 INIT_XMM sse2
332 IDCT_ADD8
333 INIT_XMM avx
334 IDCT_ADD8
335
336 ;-----------------------------------------------------------------------------
337 ; void ff_h264_idct8_add_10(pixel *dst, int16_t *block, int stride)
338 ;-----------------------------------------------------------------------------
339 %macro IDCT8_1D 2
340     SWAP      0, 1
341     psrad     m4, m5, 1
342     psrad     m1, m0, 1
343     paddd     m4, m5
344     paddd     m1, m0
345     paddd     m4, m7
346     paddd     m1, m5
347     psubd     m4, m0
348     paddd     m1, m3
349
350     psubd     m0, m3
351     psubd     m5, m3
352     paddd     m0, m7
353     psubd     m5, m7
354     psrad     m3, 1
355     psrad     m7, 1
356     psubd     m0, m3
357     psubd     m5, m7
358
359     SWAP      1, 7
360     psrad     m1, m7, 2
361     psrad     m3, m4, 2
362     paddd     m3, m0
363     psrad     m0, 2
364     paddd     m1, m5
365     psrad     m5, 2
366     psubd     m0, m4
367     psubd     m7, m5
368
369     SWAP      5, 6
370     psrad     m4, m2, 1
371     psrad     m6, m5, 1
372     psubd     m4, m5
373     paddd     m6, m2
374
375     mova      m2, %1
376     mova      m5, %2
377     SUMSUB_BA d, 5, 2
378     SUMSUB_BA d, 6, 5
379     SUMSUB_BA d, 4, 2
380     SUMSUB_BA d, 7, 6
381     SUMSUB_BA d, 0, 4
382     SUMSUB_BA d, 3, 2
383     SUMSUB_BA d, 1, 5
384     SWAP      7, 6, 4, 5, 2, 3, 1, 0 ; 70315246 -> 01234567
385 %endmacro
386
387 %macro IDCT8_1D_FULL 1
388     mova         m7, [%1+112*2]
389     mova         m6, [%1+ 96*2]
390     mova         m5, [%1+ 80*2]
391     mova         m3, [%1+ 48*2]
392     mova         m2, [%1+ 32*2]
393     mova         m1, [%1+ 16*2]
394     IDCT8_1D   [%1], [%1+ 64*2]
395 %endmacro
396
397 ; %1=int16_t *block, %2=int16_t *dstblock
398 %macro IDCT8_ADD_SSE_START 2
399     IDCT8_1D_FULL %1
400 %if ARCH_X86_64
401     TRANSPOSE4x4D  0,1,2,3,8
402     mova    [%2    ], m0
403     TRANSPOSE4x4D  4,5,6,7,8
404     mova    [%2+8*2], m4
405 %else
406     mova         [%1], m7
407     TRANSPOSE4x4D   0,1,2,3,7
408     mova           m7, [%1]
409     mova    [%2     ], m0
410     mova    [%2+16*2], m1
411     mova    [%2+32*2], m2
412     mova    [%2+48*2], m3
413     TRANSPOSE4x4D   4,5,6,7,3
414     mova    [%2+ 8*2], m4
415     mova    [%2+24*2], m5
416     mova    [%2+40*2], m6
417     mova    [%2+56*2], m7
418 %endif
419 %endmacro
420
421 ; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
422 %macro IDCT8_ADD_SSE_END 3
423     IDCT8_1D_FULL %2
424     mova  [%2     ], m6
425     mova  [%2+16*2], m7
426
427     pxor         m7, m7
428     STORE_DIFFx2 m0, m1, m6, m7, %1, %3
429     lea          %1, [%1+%3*2]
430     STORE_DIFFx2 m2, m3, m6, m7, %1, %3
431     mova         m0, [%2     ]
432     mova         m1, [%2+16*2]
433     lea          %1, [%1+%3*2]
434     STORE_DIFFx2 m4, m5, m6, m7, %1, %3
435     lea          %1, [%1+%3*2]
436     STORE_DIFFx2 m0, m1, m6, m7, %1, %3
437 %endmacro
438
439 %macro IDCT8_ADD 0
440 cglobal h264_idct8_add_10, 3,4,16
441 %if UNIX64 == 0
442     %assign pad 16-gprsize-(stack_offset&15)
443     sub  rsp, pad
444     call h264_idct8_add1_10 %+ SUFFIX
445     add  rsp, pad
446     RET
447 %endif
448
449 ALIGN 16
450 ; TODO: does not need to use stack
451 h264_idct8_add1_10 %+ SUFFIX:
452 %assign pad 256+16-gprsize
453     sub          rsp, pad
454     add   dword [r1], 32
455
456 %if ARCH_X86_64
457     IDCT8_ADD_SSE_START r1, rsp
458     SWAP 1,  9
459     SWAP 2, 10
460     SWAP 3, 11
461     SWAP 5, 13
462     SWAP 6, 14
463     SWAP 7, 15
464     IDCT8_ADD_SSE_START r1+16, rsp+128
465     PERMUTE 1,9, 2,10, 3,11, 5,1, 6,2, 7,3, 9,13, 10,14, 11,15, 13,5, 14,6, 15,7
466     IDCT8_1D [rsp], [rsp+128]
467     SWAP 0,  8
468     SWAP 1,  9
469     SWAP 2, 10
470     SWAP 3, 11
471     SWAP 4, 12
472     SWAP 5, 13
473     SWAP 6, 14
474     SWAP 7, 15
475     IDCT8_1D [rsp+16], [rsp+144]
476     psrad         m8, 6
477     psrad         m0, 6
478     packssdw      m8, m0
479     paddsw        m8, [r0]
480     pxor          m0, m0
481     mova    [r1+  0], m0
482     mova    [r1+ 16], m0
483     mova    [r1+ 32], m0
484     mova    [r1+ 48], m0
485     mova    [r1+ 64], m0
486     mova    [r1+ 80], m0
487     mova    [r1+ 96], m0
488     mova    [r1+112], m0
489     mova    [r1+128], m0
490     mova    [r1+144], m0
491     mova    [r1+160], m0
492     mova    [r1+176], m0
493     mova    [r1+192], m0
494     mova    [r1+208], m0
495     mova    [r1+224], m0
496     mova    [r1+240], m0
497     CLIPW         m8, m0, [pw_pixel_max]
498     mova        [r0], m8
499     mova          m8, [pw_pixel_max]
500     STORE_DIFF16  m9, m1, m0, m8, r0+r2
501     lea           r0, [r0+r2*2]
502     STORE_DIFF16 m10, m2, m0, m8, r0
503     STORE_DIFF16 m11, m3, m0, m8, r0+r2
504     lea           r0, [r0+r2*2]
505     STORE_DIFF16 m12, m4, m0, m8, r0
506     STORE_DIFF16 m13, m5, m0, m8, r0+r2
507     lea           r0, [r0+r2*2]
508     STORE_DIFF16 m14, m6, m0, m8, r0
509     STORE_DIFF16 m15, m7, m0, m8, r0+r2
510 %else
511     IDCT8_ADD_SSE_START r1,    rsp
512     IDCT8_ADD_SSE_START r1+16, rsp+128
513     lea           r3, [r0+8]
514     IDCT8_ADD_SSE_END r0, rsp,    r2
515     IDCT8_ADD_SSE_END r3, rsp+16, r2
516     mova    [r1+  0], m7
517     mova    [r1+ 16], m7
518     mova    [r1+ 32], m7
519     mova    [r1+ 48], m7
520     mova    [r1+ 64], m7
521     mova    [r1+ 80], m7
522     mova    [r1+ 96], m7
523     mova    [r1+112], m7
524     mova    [r1+128], m7
525     mova    [r1+144], m7
526     mova    [r1+160], m7
527     mova    [r1+176], m7
528     mova    [r1+192], m7
529     mova    [r1+208], m7
530     mova    [r1+224], m7
531     mova    [r1+240], m7
532 %endif ; ARCH_X86_64
533
534     add          rsp, pad
535     ret
536 %endmacro
537
538 INIT_XMM sse2
539 IDCT8_ADD
540 INIT_XMM avx
541 IDCT8_ADD
542
543 ;-----------------------------------------------------------------------------
544 ; void ff_h264_idct8_add4_10(pixel **dst, const int *block_offset,
545 ;                            int16_t *block, int stride,
546 ;                            const uint8_t nnzc[6*8])
547 ;-----------------------------------------------------------------------------
548 ;;;;;;; NO FATE SAMPLES TRIGGER THIS
549 %macro IDCT8_ADD4_OP 2
550     cmp       byte [r4+%2], 0
551     jz .skipblock%1
552     mov      r0d, [r6+%1*4]
553     add       r0, r5
554     call h264_idct8_add1_10 %+ SUFFIX
555 .skipblock%1:
556 %if %1<12
557     add       r1, 256
558 %endif
559 %endmacro
560
561 %macro IDCT8_ADD4 0
562 cglobal h264_idct8_add4_10, 0,7,16
563     %assign pad 16-gprsize-(stack_offset&15)
564     SUB      rsp, pad
565     mov       r5, r0mp
566     mov       r6, r1mp
567     mov       r1, r2mp
568     mov      r2d, r3m
569     movifnidn r4, r4mp
570     IDCT8_ADD4_OP  0, 4+1*8
571     IDCT8_ADD4_OP  4, 6+1*8
572     IDCT8_ADD4_OP  8, 4+3*8
573     IDCT8_ADD4_OP 12, 6+3*8
574     ADD       rsp, pad
575     RET
576 %endmacro ; IDCT8_ADD4
577
578 INIT_XMM sse2
579 IDCT8_ADD4
580 INIT_XMM avx
581 IDCT8_ADD4