LCOV - code coverage report
Current view: top level - libavcodec/x86 - mpegvideoencdsp_init.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 41 50 82.0 %
Date: 2017-10-18 21:45:51 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This file is part of FFmpeg.
       3             :  *
       4             :  * FFmpeg is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU Lesser General Public
       6             :  * License as published by the Free Software Foundation; either
       7             :  * version 2.1 of the License, or (at your option) any later version.
       8             :  *
       9             :  * FFmpeg is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Lesser General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public
      15             :  * License along with FFmpeg; if not, write to the Free Software
      16             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      17             :  */
      18             : 
      19             : #include "libavutil/attributes.h"
      20             : #include "libavutil/avassert.h"
      21             : #include "libavutil/cpu.h"
      22             : #include "libavutil/x86/cpu.h"
      23             : #include "libavcodec/avcodec.h"
      24             : #include "libavcodec/mpegvideoencdsp.h"
      25             : 
      26             : int ff_pix_sum16_mmx(uint8_t *pix, int line_size);
      27             : int ff_pix_sum16_mmxext(uint8_t *pix, int line_size);
      28             : int ff_pix_sum16_sse2(uint8_t *pix, int line_size);
      29             : int ff_pix_sum16_xop(uint8_t *pix, int line_size);
      30             : int ff_pix_norm1_mmx(uint8_t *pix, int line_size);
      31             : int ff_pix_norm1_sse2(uint8_t *pix, int line_size);
      32             : 
      33             : #if HAVE_INLINE_ASM
      34             : 
      35             : #define PHADDD(a, t)                            \
      36             :     "movq  " #a ", " #t "               \n\t"   \
      37             :     "psrlq    $32, " #a "               \n\t"   \
      38             :     "paddd " #t ", " #a "               \n\t"
      39             : 
      40             : /*
      41             :  * pmulhw:   dst[0 - 15] = (src[0 - 15] * dst[0 - 15])[16 - 31]
      42             :  * pmulhrw:  dst[0 - 15] = (src[0 - 15] * dst[0 - 15] + 0x8000)[16 - 31]
      43             :  * pmulhrsw: dst[0 - 15] = (src[0 - 15] * dst[0 - 15] + 0x4000)[15 - 30]
      44             :  */
      45             : #define PMULHRW(x, y, s, o)                     \
      46             :     "pmulhw " #s ", " #x "              \n\t"   \
      47             :     "pmulhw " #s ", " #y "              \n\t"   \
      48             :     "paddw  " #o ", " #x "              \n\t"   \
      49             :     "paddw  " #o ", " #y "              \n\t"   \
      50             :     "psraw      $1, " #x "              \n\t"   \
      51             :     "psraw      $1, " #y "              \n\t"
      52             : #define DEF(x) x ## _mmx
      53             : #define SET_RND MOVQ_WONE
      54             : #define SCALE_OFFSET 1
      55             : 
      56             : #include "mpegvideoenc_qns_template.c"
      57             : 
      58             : #undef DEF
      59             : #undef SET_RND
      60             : #undef SCALE_OFFSET
      61             : #undef PMULHRW
      62             : 
      63             : #define DEF(x) x ## _3dnow
      64             : #define SET_RND(x)
      65             : #define SCALE_OFFSET 0
      66             : #define PMULHRW(x, y, s, o)                     \
      67             :     "pmulhrw " #s ", " #x "             \n\t"   \
      68             :     "pmulhrw " #s ", " #y "             \n\t"
      69             : 
      70             : #include "mpegvideoenc_qns_template.c"
      71             : 
      72             : #undef DEF
      73             : #undef SET_RND
      74             : #undef SCALE_OFFSET
      75             : #undef PMULHRW
      76             : 
      77             : #if HAVE_SSSE3_INLINE
      78             : #undef PHADDD
      79             : #define DEF(x) x ## _ssse3
      80             : #define SET_RND(x)
      81             : #define SCALE_OFFSET -1
      82             : 
      83             : #define PHADDD(a, t)                            \
      84             :     "pshufw $0x0E, " #a ", " #t "       \n\t"   \
      85             :     /* faster than phaddd on core2 */           \
      86             :     "paddd " #t ", " #a "               \n\t"
      87             : 
      88             : #define PMULHRW(x, y, s, o)                     \
      89             :     "pmulhrsw " #s ", " #x "            \n\t"   \
      90             :     "pmulhrsw " #s ", " #y "            \n\t"
      91             : 
      92             : #include "mpegvideoenc_qns_template.c"
      93             : 
      94             : #undef DEF
      95             : #undef SET_RND
      96             : #undef SCALE_OFFSET
      97             : #undef PMULHRW
      98             : #undef PHADDD
      99             : #endif /* HAVE_SSSE3_INLINE */
     100             : 
     101             : /* Draw the edges of width 'w' of an image of size width, height
     102             :  * this MMX version can only handle w == 8 || w == 16. */
     103         420 : static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
     104             :                            int w, int h, int sides)
     105             : {
     106             :     uint8_t *ptr, *last_line;
     107             :     int i;
     108             : 
     109         420 :     last_line = buf + (height - 1) * wrap;
     110             :     /* left and right */
     111         420 :     ptr = buf;
     112         420 :     if (w == 8) {
     113         280 :         __asm__ volatile (
     114             :             "1:                             \n\t"
     115             :             "movd            (%0), %%mm0    \n\t"
     116             :             "punpcklbw      %%mm0, %%mm0    \n\t"
     117             :             "punpcklwd      %%mm0, %%mm0    \n\t"
     118             :             "punpckldq      %%mm0, %%mm0    \n\t"
     119             :             "movq           %%mm0, -8(%0)   \n\t"
     120             :             "movq      -8(%0, %2), %%mm1    \n\t"
     121             :             "punpckhbw      %%mm1, %%mm1    \n\t"
     122             :             "punpckhwd      %%mm1, %%mm1    \n\t"
     123             :             "punpckhdq      %%mm1, %%mm1    \n\t"
     124             :             "movq           %%mm1, (%0, %2) \n\t"
     125             :             "add               %1, %0       \n\t"
     126             :             "cmp               %3, %0       \n\t"
     127             :             "jb                1b           \n\t"
     128             :             : "+r" (ptr)
     129         280 :             : "r" ((x86_reg) wrap), "r" ((x86_reg) width),
     130         280 :               "r" (ptr + wrap * height));
     131         140 :     } else if (w == 16) {
     132         140 :         __asm__ volatile (
     133             :             "1:                                 \n\t"
     134             :             "movd            (%0), %%mm0        \n\t"
     135             :             "punpcklbw      %%mm0, %%mm0        \n\t"
     136             :             "punpcklwd      %%mm0, %%mm0        \n\t"
     137             :             "punpckldq      %%mm0, %%mm0        \n\t"
     138             :             "movq           %%mm0, -8(%0)       \n\t"
     139             :             "movq           %%mm0, -16(%0)      \n\t"
     140             :             "movq      -8(%0, %2), %%mm1        \n\t"
     141             :             "punpckhbw      %%mm1, %%mm1        \n\t"
     142             :             "punpckhwd      %%mm1, %%mm1        \n\t"
     143             :             "punpckhdq      %%mm1, %%mm1        \n\t"
     144             :             "movq           %%mm1,  (%0, %2)    \n\t"
     145             :             "movq           %%mm1, 8(%0, %2)    \n\t"
     146             :             "add               %1, %0           \n\t"
     147             :             "cmp               %3, %0           \n\t"
     148             :             "jb                1b               \n\t"
     149             :             : "+r"(ptr)
     150         140 :             : "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
     151             :             );
     152             :     } else {
     153             :         av_assert1(w == 4);
     154           0 :         __asm__ volatile (
     155             :             "1:                             \n\t"
     156             :             "movd            (%0), %%mm0    \n\t"
     157             :             "punpcklbw      %%mm0, %%mm0    \n\t"
     158             :             "punpcklwd      %%mm0, %%mm0    \n\t"
     159             :             "movd           %%mm0, -4(%0)   \n\t"
     160             :             "movd      -4(%0, %2), %%mm1    \n\t"
     161             :             "punpcklbw      %%mm1, %%mm1    \n\t"
     162             :             "punpckhwd      %%mm1, %%mm1    \n\t"
     163             :             "punpckhdq      %%mm1, %%mm1    \n\t"
     164             :             "movd           %%mm1, (%0, %2) \n\t"
     165             :             "add               %1, %0       \n\t"
     166             :             "cmp               %3, %0       \n\t"
     167             :             "jb                1b           \n\t"
     168             :             : "+r" (ptr)
     169           0 :             : "r" ((x86_reg) wrap), "r" ((x86_reg) width),
     170           0 :               "r" (ptr + wrap * height));
     171             :     }
     172             : 
     173             :     /* top and bottom (and hopefully also the corners) */
     174         420 :     if (sides & EDGE_TOP) {
     175        1540 :         for (i = 0; i < h; i += 4) {
     176        1120 :             ptr = buf - (i + 1) * wrap - w;
     177        1120 :             __asm__ volatile (
     178             :                 "1:                             \n\t"
     179             :                 "movq (%1, %0), %%mm0           \n\t"
     180             :                 "movq    %%mm0, (%0)            \n\t"
     181             :                 "movq    %%mm0, (%0, %2)        \n\t"
     182             :                 "movq    %%mm0, (%0, %2, 2)     \n\t"
     183             :                 "movq    %%mm0, (%0, %3)        \n\t"
     184             :                 "add        $8, %0              \n\t"
     185             :                 "cmp        %4, %0              \n\t"
     186             :                 "jb         1b                  \n\t"
     187             :                 : "+r" (ptr)
     188        1120 :                 : "r" ((x86_reg) buf - (x86_reg) ptr - w),
     189        1120 :                   "r" ((x86_reg) - wrap), "r" ((x86_reg) - wrap * 3),
     190        1120 :                   "r" (ptr + width + 2 * w));
     191             :         }
     192             :     }
     193             : 
     194         420 :     if (sides & EDGE_BOTTOM) {
     195        1540 :         for (i = 0; i < h; i += 4) {
     196        1120 :             ptr = last_line + (i + 1) * wrap - w;
     197        1120 :             __asm__ volatile (
     198             :                 "1:                             \n\t"
     199             :                 "movq (%1, %0), %%mm0           \n\t"
     200             :                 "movq    %%mm0, (%0)            \n\t"
     201             :                 "movq    %%mm0, (%0, %2)        \n\t"
     202             :                 "movq    %%mm0, (%0, %2, 2)     \n\t"
     203             :                 "movq    %%mm0, (%0, %3)        \n\t"
     204             :                 "add        $8, %0              \n\t"
     205             :                 "cmp        %4, %0              \n\t"
     206             :                 "jb         1b                  \n\t"
     207             :                 : "+r" (ptr)
     208        1120 :                 : "r" ((x86_reg) last_line - (x86_reg) ptr - w),
     209        1120 :                   "r" ((x86_reg) wrap), "r" ((x86_reg) wrap * 3),
     210        1120 :                   "r" (ptr + width + 2 * w));
     211             :         }
     212             :     }
     213         420 : }
     214             : 
     215             : #endif /* HAVE_INLINE_ASM */
     216             : 
     217         329 : av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c,
     218             :                                          AVCodecContext *avctx)
     219             : {
     220         329 :     int cpu_flags = av_get_cpu_flags();
     221             : 
     222             : #if ARCH_X86_32
     223             :     if (EXTERNAL_MMX(cpu_flags)) {
     224             :         c->pix_sum   = ff_pix_sum16_mmx;
     225             :         c->pix_norm1 = ff_pix_norm1_mmx;
     226             :     }
     227             : 
     228             :     if (EXTERNAL_MMXEXT(cpu_flags)) {
     229             :         c->pix_sum     = ff_pix_sum16_mmxext;
     230             :     }
     231             : #endif
     232             : 
     233         329 :     if (EXTERNAL_SSE2(cpu_flags)) {
     234           1 :         c->pix_sum     = ff_pix_sum16_sse2;
     235           1 :         c->pix_norm1   = ff_pix_norm1_sse2;
     236             :     }
     237             : 
     238         329 :     if (EXTERNAL_XOP(cpu_flags)) {
     239           0 :         c->pix_sum     = ff_pix_sum16_xop;
     240             :     }
     241             : 
     242             : #if HAVE_INLINE_ASM
     243             : 
     244         329 :     if (INLINE_MMX(cpu_flags)) {
     245           1 :         if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) {
     246           0 :             c->try_8x8basis = try_8x8basis_mmx;
     247             :         }
     248           1 :         c->add_8x8basis = add_8x8basis_mmx;
     249             : 
     250           1 :         if (avctx->bits_per_raw_sample <= 8) {
     251           1 :             c->draw_edges = draw_edges_mmx;
     252             :         }
     253             :     }
     254             : 
     255         329 :     if (INLINE_AMD3DNOW(cpu_flags)) {
     256           0 :         if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) {
     257           0 :             c->try_8x8basis = try_8x8basis_3dnow;
     258             :         }
     259           0 :         c->add_8x8basis = add_8x8basis_3dnow;
     260             :     }
     261             : 
     262             : #if HAVE_SSSE3_INLINE
     263         329 :     if (INLINE_SSSE3(cpu_flags)) {
     264           1 :         if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) {
     265           0 :             c->try_8x8basis = try_8x8basis_ssse3;
     266             :         }
     267           1 :         c->add_8x8basis = add_8x8basis_ssse3;
     268             :     }
     269             : #endif /* HAVE_SSSE3_INLINE */
     270             : 
     271             : #endif /* HAVE_INLINE_ASM */
     272         329 : }

Generated by: LCOV version 1.13