test widths all down to one. this tests whether the scalers correctly switch
[ffmpeg.git] / libswscale / rgb2rgb_template.c
index 1ebd43a..f06e4ed 100644 (file)
@@ -5,8 +5,27 @@
  *               Software YUV to YUV convertor
  *               Software YUV to RGB convertor
  *  Written by Nick Kurshev.
- *  palette & yuv & runtime cpu stuff by Michael (michaelni@gmx.at) (under GPL)
+ *  palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
  *  lot of big-endian byteorder fixes by Alex Beregszaszi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * 
+ * the C code (not assembly, mmx, ...) of this file can be used
+ * under the LGPL license too
  */
 
 #include <stddef.h>
@@ -44,8 +63,8 @@
 #define PREFETCH "#"
 #define PREFETCHW "#"
 #else
-#define PREFETCH "/nop"
-#define PREFETCHW "/nop"
+#define PREFETCH  " # nop"
+#define PREFETCHW " # nop"
 #endif
 #endif
 
 #define SFENCE "sfence"
 #else
 #define MOVNTQ "movq"
-#ifdef __APPLE__
-#define SFENCE "#"
-#else
-#define SFENCE "/nop"
-#endif
+#define SFENCE " # nop"
 #endif
 
 static inline void RENAME(rgb24to32)(const uint8_t *src,uint8_t *dst,long src_size)
@@ -341,6 +356,7 @@ static inline void RENAME(rgb32to16)(const uint8_t *src, uint8_t *dst, long src_
                "movq %3, %%mm5                 \n\t"
                "movq %4, %%mm6                 \n\t"
                "movq %5, %%mm7                 \n\t"
+               "jmp 2f                         \n\t"
                ASMALIGN(4)
                "1:                             \n\t"
                PREFETCH" 32(%1)                \n\t"
@@ -364,6 +380,7 @@ static inline void RENAME(rgb32to16)(const uint8_t *src, uint8_t *dst, long src_
                MOVNTQ" %%mm0, (%0)             \n\t"
                "add $16, %1                    \n\t"
                "add $8, %0                     \n\t"
+               "2:                             \n\t"
                "cmp %2, %1                     \n\t"
                " jb 1b                         \n\t"
                : "+r" (d), "+r"(s)
@@ -498,6 +515,7 @@ static inline void RENAME(rgb32to15)(const uint8_t *src, uint8_t *dst, long src_
                "movq %3, %%mm5                 \n\t"
                "movq %4, %%mm6                 \n\t"
                "movq %5, %%mm7                 \n\t"
+               "jmp 2f                         \n\t"
                ASMALIGN(4)
                "1:                             \n\t"
                PREFETCH" 32(%1)                \n\t"
@@ -521,6 +539,7 @@ static inline void RENAME(rgb32to15)(const uint8_t *src, uint8_t *dst, long src_
                MOVNTQ" %%mm0, (%0)             \n\t"
                "add $16, %1                    \n\t"
                "add $8, %0                     \n\t"
+               "2:                             \n\t"
                "cmp %2, %1                     \n\t"
                " jb 1b                         \n\t"
                : "+r" (d), "+r"(s)
@@ -1349,49 +1368,65 @@ static inline void RENAME(rgb16to32)(const uint8_t *src, uint8_t *dst, long src_
 
 static inline void RENAME(rgb32tobgr32)(const uint8_t *src, uint8_t *dst, long src_size)
 {
+       long idx = 15 - src_size;
+       uint8_t *s = (uint8_t *) src-idx, *d = dst-idx;
 #ifdef HAVE_MMX
-/* TODO: unroll this loop */
-       asm volatile (
-               "xor %%"REG_a", %%"REG_a"       \n\t"
-               ASMALIGN(4)
-               "1:                             \n\t"
-               PREFETCH" 32(%0, %%"REG_a")     \n\t"
-               "movq (%0, %%"REG_a"), %%mm0    \n\t"
-               "movq %%mm0, %%mm1              \n\t"
-               "movq %%mm0, %%mm2              \n\t"
-               "pslld $16, %%mm0               \n\t"
-               "psrld $16, %%mm1               \n\t"
-               "pand "MANGLE(mask32r)", %%mm0  \n\t"
-               "pand "MANGLE(mask32g)", %%mm2  \n\t"
-               "pand "MANGLE(mask32b)", %%mm1  \n\t"
-               "por %%mm0, %%mm2               \n\t"
-               "por %%mm1, %%mm2               \n\t"
-               MOVNTQ" %%mm2, (%1, %%"REG_a")  \n\t"
-               "add $8, %%"REG_a"              \n\t"
-               "cmp %2, %%"REG_a"              \n\t"
-               " jb 1b                         \n\t"
-               :: "r" (src), "r"(dst), "r" (src_size-7)
-               : "%"REG_a
-       );
-
-       __asm __volatile(SFENCE:::"memory");
-       __asm __volatile(EMMS:::"memory");
-#else
-       unsigned i;
-       unsigned num_pixels = src_size >> 2;
-       for(i=0; i<num_pixels; i++)
-       {
-#ifdef WORDS_BIGENDIAN  
-         dst[4*i + 1] = src[4*i + 3];
-         dst[4*i + 2] = src[4*i + 2];
-         dst[4*i + 3] = src[4*i + 1];
-#else
-         dst[4*i + 0] = src[4*i + 2];
-         dst[4*i + 1] = src[4*i + 1];
-         dst[4*i + 2] = src[4*i + 0];
-#endif
+       __asm __volatile(
+               "       test %0, %0                     \n"
+               "       jns 2f                          \n"
+               "       "PREFETCH" (%1, %0)             \n"
+               "       movq %3, %%mm7                  \n"
+               "       pxor %4, %%mm7                  \n"
+               "       movq %%mm7, %%mm6               \n"
+               "       pxor %5, %%mm7                  \n"
+                       ASMALIGN(4)
+               "1:                                     \n"
+               "       "PREFETCH" 32(%1, %0)           \n"
+               "       movq (%1, %0), %%mm0            \n"
+               "       movq 8(%1, %0), %%mm1           \n"
+# ifdef HAVE_MMX2
+               "       pshufw $177, %%mm0, %%mm3       \n"
+               "       pshufw $177, %%mm1, %%mm5       \n"
+               "       pand %%mm7, %%mm0               \n"
+               "       pand %%mm6, %%mm3               \n"
+               "       pand %%mm7, %%mm1               \n"
+               "       pand %%mm6, %%mm5               \n"
+               "       por %%mm3, %%mm0                \n"
+               "       por %%mm5, %%mm1                \n"
+# else
+               "       movq %%mm0, %%mm2               \n"
+               "       movq %%mm1, %%mm4               \n"
+               "       pand %%mm7, %%mm0               \n"
+               "       pand %%mm6, %%mm2               \n"
+               "       pand %%mm7, %%mm1               \n"
+               "       pand %%mm6, %%mm4               \n"
+               "       movq %%mm2, %%mm3               \n"
+               "       movq %%mm4, %%mm5               \n"
+               "       pslld $16, %%mm2                \n"
+               "       psrld $16, %%mm3                \n"
+               "       pslld $16, %%mm4                \n"
+               "       psrld $16, %%mm5                \n"
+               "       por %%mm2, %%mm0                \n"
+               "       por %%mm4, %%mm1                \n"
+               "       por %%mm3, %%mm0                \n"
+               "       por %%mm5, %%mm1                \n"
+# endif
+               "       "MOVNTQ" %%mm0, (%2, %0)        \n"
+               "       "MOVNTQ" %%mm1, 8(%2, %0)       \n"
+               "       add $16, %0                     \n"
+               "       js 1b                           \n"
+               "       "SFENCE"                        \n"
+               "       "EMMS"                          \n"
+               "2:                                     \n"
+               : "+&r"(idx)
+               : "r" (s), "r" (d), "m" (mask32b), "m" (mask32r), "m" (mmx_one)
+               : "memory");
+#endif
+       for (; idx<15; idx+=4) {
+               register int v = *(uint32_t *)&s[idx], g = v & 0xff00;
+               v &= 0xff00ff;
+               *(uint32_t *)&d[idx] = (v>>16) + g + (v<<16);
        }
-#endif
 }
 
 static inline void RENAME(rgb24tobgr24)(const uint8_t *src, uint8_t *dst, long src_size)
@@ -1400,6 +1435,8 @@ static inline void RENAME(rgb24tobgr24)(const uint8_t *src, uint8_t *dst, long s
 #ifdef HAVE_MMX
        long mmx_size= 23 - src_size;
        asm volatile (
+               "test %%"REG_a", %%"REG_a"      \n\t"
+               "jns 2f                         \n\t"
                "movq "MANGLE(mask24r)", %%mm5  \n\t"
                "movq "MANGLE(mask24g)", %%mm6  \n\t"
                "movq "MANGLE(mask24b)", %%mm7  \n\t"
@@ -1436,6 +1473,7 @@ static inline void RENAME(rgb24tobgr24)(const uint8_t *src, uint8_t *dst, long s
                MOVNTQ" %%mm1, 16(%2, %%"REG_a")\n\t"
                "add $24, %%"REG_a"             \n\t"
                " js 1b                         \n\t"
+               "2:                             \n\t"
                : "+a" (mmx_size)
                : "r" (src-mmx_size), "r"(dst-mmx_size)
        );
@@ -2671,3 +2709,35 @@ static inline void RENAME(yvu9_to_yuy2)(const uint8_t *src1, const uint8_t *src2
                );
 #endif
 }
+
+static inline void RENAME(rgb2rgb_init)(void){
+       rgb15to16= RENAME(rgb15to16);
+       rgb15to24= RENAME(rgb15to24);
+       rgb15to32= RENAME(rgb15to32);
+       rgb16to24= RENAME(rgb16to24);
+       rgb16to32= RENAME(rgb16to32);
+       rgb16to15= RENAME(rgb16to15);
+       rgb24to16= RENAME(rgb24to16);
+       rgb24to15= RENAME(rgb24to15);
+       rgb24to32= RENAME(rgb24to32);
+       rgb32to16= RENAME(rgb32to16);
+       rgb32to15= RENAME(rgb32to15);
+       rgb32to24= RENAME(rgb32to24);
+       rgb24tobgr15= RENAME(rgb24tobgr15);
+       rgb24tobgr16= RENAME(rgb24tobgr16);
+       rgb24tobgr24= RENAME(rgb24tobgr24);
+       rgb32tobgr32= RENAME(rgb32tobgr32);
+       rgb32tobgr16= RENAME(rgb32tobgr16);
+       rgb32tobgr15= RENAME(rgb32tobgr15);
+       yv12toyuy2= RENAME(yv12toyuy2);
+       yv12touyvy= RENAME(yv12touyvy);
+       yuv422ptoyuy2= RENAME(yuv422ptoyuy2);
+       yuy2toyv12= RENAME(yuy2toyv12);
+//     uyvytoyv12= RENAME(uyvytoyv12);
+//     yvu9toyv12= RENAME(yvu9toyv12);
+       planar2x= RENAME(planar2x);
+       rgb24toyv12= RENAME(rgb24toyv12);
+       interleaveBytes= RENAME(interleaveBytes);
+       vu9_to_vu12= RENAME(vu9_to_vu12);
+       yvu9_to_yuy2= RENAME(yvu9_to_yuy2);
+}