]> git.sesse.net Git - ffmpeg/blobdiff - libswscale/swscale.c
MMX2 horizontal scaler: Determine code size at runtime.
[ffmpeg] / libswscale / swscale.c
index 59d4d841fe5f08475b3dc3b92501864ea19cd0d7..f185d2354a730b171dde700d6ef97bc9375e5bd6 100644 (file)
@@ -302,19 +302,6 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32[8][8])={
 {  1,  25,   7,  31,   0,  24,   6,  30, },
 };
 
-#if 0
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_64[8][8])={
-{  0,  48,  12,  60,   3,  51,  15,  63, },
-{ 32,  16,  44,  28,  35,  19,  47,  31, },
-{  8,  56,   4,  52,  11,  59,   7,  55, },
-{ 40,  24,  36,  20,  43,  27,  39,  23, },
-{  2,  50,  14,  62,   1,  49,  13,  61, },
-{ 34,  18,  46,  30,  33,  17,  45,  29, },
-{ 10,  58,   6,  54,   9,  57,   5,  53, },
-{ 42,  26,  38,  22,  41,  25,  37,  21, },
-};
-#endif
-
 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73[8][8])={
 {  0,  55,  14,  68,   3,  58,  17,  72, },
 { 37,  18,  50,  32,  40,  22,  54,  35, },
@@ -326,19 +313,6 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73[8][8])={
 { 48,  30,  43,  25,  47,  29,  42,  24, },
 };
 
-#if 0
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128[8][8])={
-{ 68,  36,  92,  60,  66,  34,  90,  58, },
-{ 20, 116,  12, 108,  18, 114,  10, 106, },
-{ 84,  52,  76,  44,  82,  50,  74,  42, },
-{  0,  96,  24, 120,   6, 102,  30, 126, },
-{ 64,  32,  88,  56,  70,  38,  94,  62, },
-{ 16, 112,   8, 104,  22, 118,  14, 110, },
-{ 80,  48,  72,  40,  86,  54,  78,  46, },
-{  4, 100,  28, 124,   2,  98,  26, 122, },
-};
-#endif
-
 #if 1
 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220[8][8])={
 {117,  62, 158, 103, 113,  58, 155, 100, },
@@ -1779,7 +1753,7 @@ error:
 }
 
 #ifdef COMPILE_MMX2
-static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *filter, int32_t *filterPos, int numSplits)
+static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *filter, int32_t *filterPos, int numSplits)
 {
     uint8_t *fragmentA;
     x86_reg imm8OfPShufW1A;
@@ -1896,17 +1870,18 @@ static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *fil
             int maxShift= 3-(d+inc);
             int shift=0;
 
+            if (filterCode) {
             filter[i  ] = (( xpos         & 0xFFFF) ^ 0xFFFF)>>9;
             filter[i+1] = (((xpos+xInc  ) & 0xFFFF) ^ 0xFFFF)>>9;
             filter[i+2] = (((xpos+xInc*2) & 0xFFFF) ^ 0xFFFF)>>9;
             filter[i+3] = (((xpos+xInc*3) & 0xFFFF) ^ 0xFFFF)>>9;
             filterPos[i/2]= xx;
 
-            memcpy(funnyCode + fragmentPos, fragment, fragmentLength);
+            memcpy(filterCode + fragmentPos, fragment, fragmentLength);
 
-            funnyCode[fragmentPos + imm8OfPShufW1]=
+            filterCode[fragmentPos + imm8OfPShufW1]=
                 (a+inc) | ((b+inc)<<2) | ((c+inc)<<4) | ((d+inc)<<6);
-            funnyCode[fragmentPos + imm8OfPShufW2]=
+            filterCode[fragmentPos + imm8OfPShufW2]=
                 a | (b<<2) | (c<<4) | (d<<6);
 
             if (i+4-inc>=dstW) shift=maxShift; //avoid overread
@@ -1914,18 +1889,23 @@ static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *fil
 
             if (shift && i>=shift)
             {
-                funnyCode[fragmentPos + imm8OfPShufW1]+= 0x55*shift;
-                funnyCode[fragmentPos + imm8OfPShufW2]+= 0x55*shift;
+                filterCode[fragmentPos + imm8OfPShufW1]+= 0x55*shift;
+                filterCode[fragmentPos + imm8OfPShufW2]+= 0x55*shift;
                 filterPos[i/2]-=shift;
             }
+            }
 
             fragmentPos+= fragmentLength;
 
-            funnyCode[fragmentPos]= RET;
+            if (filterCode)
+            filterCode[fragmentPos]= RET;
         }
         xpos+=xInc;
     }
+    if (filterCode)
     filterPos[((i/2)+1)&(~1)]= xpos>>16; // needed to jump to the next part
+
+    return fragmentPos + 1;
 }
 #endif /* COMPILE_MMX2 */
 
@@ -2759,7 +2739,9 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d
             || (isGray(dstFormat) && isGray(srcFormat))
             || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat)
                 && c->chrDstHSubSample == c->chrSrcHSubSample
-                && c->chrDstVSubSample == c->chrSrcVSubSample))
+                && c->chrDstVSubSample == c->chrSrcVSubSample
+                && dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21
+                && srcFormat != PIX_FMT_NV12 && srcFormat != PIX_FMT_NV21))
         {
             if (isPacked(c->srcFormat))
                 c->swScale= packedCopy;
@@ -2832,20 +2814,22 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d
                    (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,
                    srcFilter->chrH, dstFilter->chrH, c->param);
 
-#define MAX_FUNNY_CODE_SIZE 10000
 #if defined(COMPILE_MMX2)
 // can't downscale !!!
         if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR))
         {
+            c->lumMmx2FilterCodeSize = initMMX2HScaler(      dstW, c->lumXInc, NULL, NULL, NULL, 8);
+            c->chrMmx2FilterCodeSize = initMMX2HScaler(c->chrDstW, c->chrXInc, NULL, NULL, NULL, 4);
+
 #ifdef MAP_ANONYMOUS
-            c->funnyYCode  = mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
-            c->funnyUVCode = mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+            c->lumMmx2FilterCode = mmap(NULL, c->lumMmx2FilterCodeSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+            c->chrMmx2FilterCode = mmap(NULL, c->chrMmx2FilterCodeSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
 #elif HAVE_VIRTUALALLOC
-            c->funnyYCode  = VirtualAlloc(NULL, MAX_FUNNY_CODE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-            c->funnyUVCode = VirtualAlloc(NULL, MAX_FUNNY_CODE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+            c->lumMmx2FilterCode = VirtualAlloc(NULL, c->lumMmx2FilterCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+            c->chrMmx2FilterCode = VirtualAlloc(NULL, c->chrMmx2FilterCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 #else
-            c->funnyYCode  = av_malloc(MAX_FUNNY_CODE_SIZE);
-            c->funnyUVCode = av_malloc(MAX_FUNNY_CODE_SIZE);
+            c->lumMmx2FilterCode = av_malloc(c->lumMmx2FilterCodeSize);
+            c->chrMmx2FilterCode = av_malloc(c->chrMmx2FilterCodeSize);
 #endif
 
             c->lumMmx2Filter   = av_malloc((dstW        /8+8)*sizeof(int16_t));
@@ -2853,8 +2837,13 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d
             c->lumMmx2FilterPos= av_malloc((dstW      /2/8+8)*sizeof(int32_t));
             c->chrMmx2FilterPos= av_malloc((c->chrDstW/2/4+8)*sizeof(int32_t));
 
-            initMMX2HScaler(      dstW, c->lumXInc, c->funnyYCode , c->lumMmx2Filter, c->lumMmx2FilterPos, 8);
-            initMMX2HScaler(c->chrDstW, c->chrXInc, c->funnyUVCode, c->chrMmx2Filter, c->chrMmx2FilterPos, 4);
+            initMMX2HScaler(      dstW, c->lumXInc, c->lumMmx2FilterCode, c->lumMmx2Filter, c->lumMmx2FilterPos, 8);
+            initMMX2HScaler(c->chrDstW, c->chrXInc, c->chrMmx2FilterCode, c->chrMmx2Filter, c->chrMmx2FilterPos, 4);
+
+#ifdef MAP_ANONYMOUS
+            mprotect(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize, PROT_EXEC | PROT_READ);
+            mprotect(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, PROT_EXEC | PROT_READ);
+#endif
         }
 #endif /* defined(COMPILE_MMX2) */
     } // initialize horizontal stuff
@@ -2877,7 +2866,7 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d
                    (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,
                    srcFilter->chrV, dstFilter->chrV, c->param);
 
-#if HAVE_ALTIVEC
+#ifdef COMPILE_ALTIVEC
         c->vYCoeffsBank = av_malloc(sizeof (vector signed short)*c->vLumFilterSize*c->dstH);
         c->vCCoeffsBank = av_malloc(sizeof (vector signed short)*c->vChrFilterSize*c->chrDstH);
 
@@ -3511,7 +3500,7 @@ void sws_freeContext(SwsContext *c){
     av_freep(&c->vChrFilter);
     av_freep(&c->hLumFilter);
     av_freep(&c->hChrFilter);
-#if HAVE_ALTIVEC
+#ifdef COMPILE_ALTIVEC
     av_freep(&c->vYCoeffsBank);
     av_freep(&c->vCCoeffsBank);
 #endif
@@ -3523,17 +3512,17 @@ void sws_freeContext(SwsContext *c){
 
 #if ARCH_X86 && CONFIG_GPL
 #ifdef MAP_ANONYMOUS
-    if (c->funnyYCode ) munmap(c->funnyYCode , MAX_FUNNY_CODE_SIZE);
-    if (c->funnyUVCode) munmap(c->funnyUVCode, MAX_FUNNY_CODE_SIZE);
+    if (c->lumMmx2FilterCode) munmap(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize);
+    if (c->chrMmx2FilterCode) munmap(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize);
 #elif HAVE_VIRTUALALLOC
-    if (c->funnyYCode ) VirtualFree(c->funnyYCode , MAX_FUNNY_CODE_SIZE, MEM_RELEASE);
-    if (c->funnyUVCode) VirtualFree(c->funnyUVCode, MAX_FUNNY_CODE_SIZE, MEM_RELEASE);
+    if (c->lumMmx2FilterCode) VirtualFree(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize, MEM_RELEASE);
+    if (c->chrMmx2FilterCode) VirtualFree(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, MEM_RELEASE);
 #else
-    av_free(c->funnyYCode );
-    av_free(c->funnyUVCode);
+    av_free(c->lumMmx2FilterCode);
+    av_free(c->chrMmx2FilterCode);
 #endif
-    c->funnyYCode=NULL;
-    c->funnyUVCode=NULL;
+    c->lumMmx2FilterCode=NULL;
+    c->chrMmx2FilterCode=NULL;
 #endif /* ARCH_X86 && CONFIG_GPL */
 
     av_freep(&c->lumMmx2Filter);