]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/x86/h264_deblock.asm
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / x86 / h264_deblock.asm
index ea422e3b3a2ee66bdd62a1a705ca207cf56bdc10..6abdba2628efe4d3db15f4c1a551f2310a642392 100644 (file)
 %include "libavutil/x86/x86inc.asm"
 %include "libavutil/x86/x86util.asm"
 
+SECTION_RODATA
+
+pb_3_1: times 4 db 3, 1
+
 SECTION .text
 
 cextern pb_0
@@ -386,7 +390,7 @@ cglobal deblock_h_luma_8, 5,9
 
 INIT_XMM sse2
 DEBLOCK_LUMA
-%if HAVE_AVX
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA
 %endif
@@ -507,7 +511,7 @@ INIT_MMX mmx2
 DEBLOCK_LUMA v8, 8
 INIT_XMM sse2
 DEBLOCK_LUMA v, 16
-%if HAVE_AVX
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA v, 16
 %endif
@@ -781,7 +785,7 @@ cglobal deblock_h_luma_intra_8, 2,4
 
 INIT_XMM sse2
 DEBLOCK_LUMA_INTRA v
-%if HAVE_AVX
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA_INTRA v
 %endif
@@ -921,3 +925,167 @@ ff_chroma_intra_body_mmx2:
     paddb  m1, m5
     paddb  m2, m6
     ret
+
+;-----------------------------------------------------------------------------
+; void h264_loop_filter_strength(int16_t bs[2][4][4], uint8_t nnz[40],
+;                                int8_t ref[2][40], int16_t mv[2][40][2],
+;                                int bidir,    int edges,    int step,
+;                                int mask_mv0, int mask_mv1, int field);
+;
+; bidir    is 0 or 1
+; edges    is 1 or 4
+; step     is 1 or 2
+; mask_mv0 is 0 or 3
+; mask_mv1 is 0 or 1
+; field    is 0 or 1
+;-----------------------------------------------------------------------------
+%macro loop_filter_strength_iteration 7 ; edges, step, mask_mv,
+                                        ; dir, d_idx, mask_dir, bidir
+%define edgesd    %1
+%define stepd     %2
+%define mask_mvd  %3
+%define dir       %4
+%define d_idx     %5
+%define mask_dir  %6
+%define bidir     %7
+    xor          b_idxd, b_idxd ; for (b_idx = 0; b_idx < edges; b_idx += step)
+%%.b_idx_loop:
+%if mask_dir == 0
+    pxor             m0, m0
+%endif
+    test         b_idxd, dword mask_mvd
+    jnz %%.skip_loop_iter                       ; if (!(b_idx & mask_mv))
+%if bidir == 1
+    movd             m2, [refq+b_idxq+d_idx+12] ; { ref0[bn] }
+    punpckldq        m2, [refq+b_idxq+d_idx+52] ; { ref0[bn], ref1[bn] }
+    pshufw           m0, [refq+b_idxq+12], 0x44 ; { ref0[b],  ref0[b]  }
+    pshufw           m1, [refq+b_idxq+52], 0x44 ; { ref1[b],  ref1[b]  }
+    pshufw           m3, m2, 0x4E               ; { ref1[bn], ref0[bn] }
+    psubb            m0, m2                     ; { ref0[b] != ref0[bn],
+                                                ;   ref0[b] != ref1[bn] }
+    psubb            m1, m3                     ; { ref1[b] != ref1[bn],
+                                                ;   ref1[b] != ref0[bn] }
+
+    por              m0, m1
+    mova             m1, [mvq+b_idxq*4+(d_idx+12)*4]
+    mova             m2, [mvq+b_idxq*4+(d_idx+12)*4+mmsize]
+    mova             m3, m1
+    mova             m4, m2
+    psubw            m1, [mvq+b_idxq*4+12*4]
+    psubw            m2, [mvq+b_idxq*4+12*4+mmsize]
+    psubw            m3, [mvq+b_idxq*4+52*4]
+    psubw            m4, [mvq+b_idxq*4+52*4+mmsize]
+    packsswb         m1, m2
+    packsswb         m3, m4
+    paddb            m1, m6
+    paddb            m3, m6
+    psubusb          m1, m5 ; abs(mv[b] - mv[bn]) >= limit
+    psubusb          m3, m5
+    packsswb         m1, m3
+
+    por              m0, m1
+    mova             m1, [mvq+b_idxq*4+(d_idx+52)*4]
+    mova             m2, [mvq+b_idxq*4+(d_idx+52)*4+mmsize]
+    mova             m3, m1
+    mova             m4, m2
+    psubw            m1, [mvq+b_idxq*4+12*4]
+    psubw            m2, [mvq+b_idxq*4+12*4+mmsize]
+    psubw            m3, [mvq+b_idxq*4+52*4]
+    psubw            m4, [mvq+b_idxq*4+52*4+mmsize]
+    packsswb         m1, m2
+    packsswb         m3, m4
+    paddb            m1, m6
+    paddb            m3, m6
+    psubusb          m1, m5 ; abs(mv[b] - mv[bn]) >= limit
+    psubusb          m3, m5
+    packsswb         m1, m3
+
+    pshufw           m1, m1, 0x4E
+    por              m0, m1
+    pshufw           m1, m0, 0x4E
+    pminub           m0, m1
+%else ; bidir == 0
+    movd             m0, [refq+b_idxq+12]
+    psubb            m0, [refq+b_idxq+d_idx+12] ; ref[b] != ref[bn]
+
+    mova             m1, [mvq+b_idxq*4+12*4]
+    mova             m2, [mvq+b_idxq*4+12*4+mmsize]
+    psubw            m1, [mvq+b_idxq*4+(d_idx+12)*4]
+    psubw            m2, [mvq+b_idxq*4+(d_idx+12)*4+mmsize]
+    packsswb         m1, m2
+    paddb            m1, m6
+    psubusb          m1, m5 ; abs(mv[b] - mv[bn]) >= limit
+    packsswb         m1, m1
+    por              m0, m1
+%endif ; bidir == 1/0
+
+%%.skip_loop_iter:
+    movd             m1, [nnzq+b_idxq+12]
+    por              m1, [nnzq+b_idxq+d_idx+12] ; nnz[b] || nnz[bn]
+
+    pminub           m1, m7
+    pminub           m0, m7
+    psllw            m1, 1
+    pxor             m2, m2
+    pmaxub           m1, m0
+    punpcklbw        m1, m2
+    movq [bsq+b_idxq+32*dir], m1
+
+    add          b_idxd, dword stepd
+    cmp          b_idxd, dword edgesd
+    jl %%.b_idx_loop
+%endmacro
+
+INIT_MMX mmx2
+cglobal h264_loop_filter_strength, 9, 9, 0, bs, nnz, ref, mv, bidir, edges, \
+                                            step, mask_mv0, mask_mv1, field
+%define b_idxq bidirq
+%define b_idxd bidird
+    cmp    dword fieldm, 0
+    mova             m7, [pb_1]
+    mova             m5, [pb_3]
+    je .nofield
+    mova             m5, [pb_3_1]
+.nofield:
+    mova             m6, m5
+    paddb            m5, m5
+
+    shl     dword stepd, 3
+    shl    dword edgesd, 3
+%if ARCH_X86_32
+%define mask_mv0d mask_mv0m
+%define mask_mv1d mask_mv1m
+%endif
+    shl dword mask_mv1d, 3
+    shl dword mask_mv0d, 3
+
+    cmp    dword bidird, 0
+    jne .bidir
+    loop_filter_strength_iteration edgesd, stepd, mask_mv1d, 1, -8,  0, 0
+    loop_filter_strength_iteration     32,     8, mask_mv0d, 0, -1, -1, 0
+
+    mova             m0, [bsq+mmsize*0]
+    mova             m1, [bsq+mmsize*1]
+    mova             m2, [bsq+mmsize*2]
+    mova             m3, [bsq+mmsize*3]
+    TRANSPOSE4x4W 0, 1, 2, 3, 4
+    mova  [bsq+mmsize*0], m0
+    mova  [bsq+mmsize*1], m1
+    mova  [bsq+mmsize*2], m2
+    mova  [bsq+mmsize*3], m3
+    RET
+
+.bidir:
+    loop_filter_strength_iteration edgesd, stepd, mask_mv1d, 1, -8,  0, 1
+    loop_filter_strength_iteration     32,     8, mask_mv0d, 0, -1, -1, 1
+
+    mova             m0, [bsq+mmsize*0]
+    mova             m1, [bsq+mmsize*1]
+    mova             m2, [bsq+mmsize*2]
+    mova             m3, [bsq+mmsize*3]
+    TRANSPOSE4x4W 0, 1, 2, 3, 4
+    mova  [bsq+mmsize*0], m0
+    mova  [bsq+mmsize*1], m1
+    mova  [bsq+mmsize*2], m2
+    mova  [bsq+mmsize*3], m3
+    RET