/*
- Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
-
- This program 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.
-
- This program 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 this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * 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 the swscaler which has been written
+ * by Michael Niedermayer can be used under the LGPL license too
+ */
/*
supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8/Y800, YVU9/IF09
#include "swscale_internal.h"
#include "x86_cpu.h"
#include "bswap.h"
-#include "img_format.h"
#include "rgb2rgb.h"
#ifdef USE_FASTMEMCPY
#include "libvo/fastmemcpy.h"
#define PI 3.14159265358979323846
#endif
-//FIXME replace this with something faster
-#define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YVU9 \
- || (x)==IMGFMT_NV12 || (x)==IMGFMT_NV21 \
- || (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P)
-#define isYUV(x) ((x)==IMGFMT_UYVY || (x)==IMGFMT_YUY2 || isPlanarYUV(x))
-#define isGray(x) ((x)==IMGFMT_Y800)
-#define isRGB(x) (((x)&IMGFMT_RGB_MASK)==IMGFMT_RGB)
-#define isBGR(x) (((x)&IMGFMT_BGR_MASK)==IMGFMT_BGR)
-#define isSupportedIn(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YUY2 || (x)==IMGFMT_UYVY\
- || (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15\
- || (x)==IMGFMT_RGB32|| (x)==IMGFMT_RGB24\
- || (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9\
- || (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P)
-#define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YUY2 || (x)==IMGFMT_UYVY\
- || (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P\
+#define isSupportedIn(x) ((x)==PIX_FMT_YUV420P || (x)==PIX_FMT_YUYV422 || (x)==PIX_FMT_UYVY422\
+ || (x)==PIX_FMT_RGB32|| (x)==PIX_FMT_BGR24|| (x)==PIX_FMT_BGR565|| (x)==PIX_FMT_BGR555\
+ || (x)==PIX_FMT_BGR32|| (x)==PIX_FMT_RGB24|| (x)==PIX_FMT_RGB565|| (x)==PIX_FMT_RGB555\
+ || (x)==PIX_FMT_GRAY8 || (x)==PIX_FMT_YUV410P\
+ || (x)==PIX_FMT_GRAY16BE || (x)==PIX_FMT_GRAY16LE\
+ || (x)==PIX_FMT_YUV444P || (x)==PIX_FMT_YUV422P || (x)==PIX_FMT_YUV411P)
+#define isSupportedOut(x) ((x)==PIX_FMT_YUV420P || (x)==PIX_FMT_YUYV422 || (x)==PIX_FMT_UYVY422\
+ || (x)==PIX_FMT_YUV444P || (x)==PIX_FMT_YUV422P || (x)==PIX_FMT_YUV411P\
|| isRGB(x) || isBGR(x)\
- || (x)==IMGFMT_NV12 || (x)==IMGFMT_NV21\
- || (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9)
-#define isPacked(x) ((x)==IMGFMT_YUY2 || (x)==IMGFMT_UYVY ||isRGB(x) || isBGR(x))
+ || (x)==PIX_FMT_NV12 || (x)==PIX_FMT_NV21\
+ || (x)==PIX_FMT_GRAY16BE || (x)==PIX_FMT_GRAY16LE\
+ || (x)==PIX_FMT_GRAY8 || (x)==PIX_FMT_YUV410P)
+#define isPacked(x) ((x)==PIX_FMT_YUYV422 || (x)==PIX_FMT_UYVY422 ||isRGB(x) || isBGR(x))
#define RGB2YUV_SHIFT 16
#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
write special BGR->BGR scaler
*/
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
static uint64_t attribute_used __attribute__((aligned(8))) bF8= 0xF8F8F8F8F8F8F8F8LL;
static uint64_t attribute_used __attribute__((aligned(8))) bFC= 0xFCFCFCFCFCFCFCFCLL;
static uint64_t __attribute__((aligned(8))) w10= 0x0010001000100010LL;
static const uint64_t bgr2YCoeff attribute_used __attribute__((aligned(8))) = 0x000020E540830C8BULL;
static const uint64_t bgr2UCoeff attribute_used __attribute__((aligned(8))) = 0x0000ED0FDAC23831ULL;
static const uint64_t bgr2VCoeff attribute_used __attribute__((aligned(8))) = 0x00003831D0E6F6EAULL;
-#endif
+#endif /* FAST_BGR2YV12 */
static const uint64_t bgr2YOffset attribute_used __attribute__((aligned(8))) = 0x1010101010101010ULL;
static const uint64_t bgr2UVOffset attribute_used __attribute__((aligned(8)))= 0x8080808080808080ULL;
static const uint64_t w1111 attribute_used __attribute__((aligned(8))) = 0x0001000100010001ULL;
-#endif
+#endif /* defined(ARCH_X86) */
// clipping helper table for C implementations:
static unsigned char clip_table[768];
extern const uint8_t dither_8x8_73[8][8];
extern const uint8_t dither_8x8_220[8][8];
-char *sws_format_name(int format)
+char *sws_format_name(enum PixelFormat format)
{
- static char fmt_name[64];
- char *res;
- static int buffer;
-
- res = fmt_name + buffer * 32;
- buffer = 1 - buffer;
- snprintf(res, 32, "0x%x (%c%c%c%c)", format,
- format >> 24, (format >> 16) & 0xFF,
- (format >> 8) & 0xFF,
- format & 0xFF);
-
- return res;
+ switch (format) {
+ case PIX_FMT_YUV420P:
+ return "yuv420p";
+ case PIX_FMT_YUYV422:
+ return "yuyv422";
+ case PIX_FMT_RGB24:
+ return "rgb24";
+ case PIX_FMT_BGR24:
+ return "bgr24";
+ case PIX_FMT_YUV422P:
+ return "yuv422p";
+ case PIX_FMT_YUV444P:
+ return "yuv444p";
+ case PIX_FMT_RGB32:
+ return "rgb32";
+ case PIX_FMT_YUV410P:
+ return "yuv410p";
+ case PIX_FMT_YUV411P:
+ return "yuv411p";
+ case PIX_FMT_RGB565:
+ return "rgb565";
+ case PIX_FMT_RGB555:
+ return "rgb555";
+ case PIX_FMT_GRAY16BE:
+ return "gray16be";
+ case PIX_FMT_GRAY16LE:
+ return "gray16le";
+ case PIX_FMT_GRAY8:
+ return "gray8";
+ case PIX_FMT_MONOWHITE:
+ return "mono white";
+ case PIX_FMT_MONOBLACK:
+ return "mono black";
+ case PIX_FMT_PAL8:
+ return "Palette";
+ case PIX_FMT_YUVJ420P:
+ return "yuvj420p";
+ case PIX_FMT_YUVJ422P:
+ return "yuvj422p";
+ case PIX_FMT_YUVJ444P:
+ return "yuvj444p";
+ case PIX_FMT_XVMC_MPEG2_MC:
+ return "xvmc_mpeg2_mc";
+ case PIX_FMT_XVMC_MPEG2_IDCT:
+ return "xvmc_mpeg2_idct";
+ case PIX_FMT_UYVY422:
+ return "uyvy422";
+ case PIX_FMT_UYYVYY411:
+ return "uyyvyy411";
+ case PIX_FMT_RGB32_1:
+ return "rgb32x";
+ case PIX_FMT_BGR32_1:
+ return "bgr32x";
+ case PIX_FMT_BGR32:
+ return "bgr32";
+ case PIX_FMT_BGR565:
+ return "bgr565";
+ case PIX_FMT_BGR555:
+ return "bgr555";
+ case PIX_FMT_BGR8:
+ return "bgr8";
+ case PIX_FMT_BGR4:
+ return "bgr4";
+ case PIX_FMT_BGR4_BYTE:
+ return "bgr4 byte";
+ case PIX_FMT_RGB8:
+ return "rgb8";
+ case PIX_FMT_RGB4:
+ return "rgb4";
+ case PIX_FMT_RGB4_BYTE:
+ return "rgb4 byte";
+ case PIX_FMT_NV12:
+ return "nv12";
+ case PIX_FMT_NV21:
+ return "nv21";
+ default:
+ return "Unknown format";
+ }
}
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
void in_asm_used_var_warning_killer()
{
volatile int i= bF8+bFC+w10+
if(uDest == NULL)
return;
- if(dstFormat == IMGFMT_NV12)
+ if(dstFormat == PIX_FMT_NV12)
for(i=0; i<chrDstW; i++)
{
int u=1<<18;
#define YSCALE_YUV_2_ANYRGB_C(func, func2)\
switch(c->dstFormat)\
{\
- case IMGFMT_BGR32:\
- case IMGFMT_RGB32:\
+ case PIX_FMT_RGB32:\
+ case PIX_FMT_BGR32:\
func(uint32_t)\
((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
} \
break;\
- case IMGFMT_RGB24:\
+ case PIX_FMT_RGB24:\
func(uint8_t)\
((uint8_t*)dest)[0]= r[Y1];\
((uint8_t*)dest)[1]= g[Y1];\
dest+=6;\
}\
break;\
- case IMGFMT_BGR24:\
+ case PIX_FMT_BGR24:\
func(uint8_t)\
((uint8_t*)dest)[0]= b[Y1];\
((uint8_t*)dest)[1]= g[Y1];\
dest+=6;\
}\
break;\
- case IMGFMT_RGB16:\
- case IMGFMT_BGR16:\
+ case PIX_FMT_RGB565:\
+ case PIX_FMT_BGR565:\
{\
const int dr1= dither_2x2_8[y&1 ][0];\
const int dg1= dither_2x2_4[y&1 ][0];\
}\
}\
break;\
- case IMGFMT_RGB15:\
- case IMGFMT_BGR15:\
+ case PIX_FMT_RGB555:\
+ case PIX_FMT_BGR555:\
{\
const int dr1= dither_2x2_8[y&1 ][0];\
const int dg1= dither_2x2_8[y&1 ][1];\
}\
}\
break;\
- case IMGFMT_RGB8:\
- case IMGFMT_BGR8:\
+ case PIX_FMT_RGB8:\
+ case PIX_FMT_BGR8:\
{\
const uint8_t * const d64= dither_8x8_73[y&7];\
const uint8_t * const d32= dither_8x8_32[y&7];\
}\
}\
break;\
- case IMGFMT_RGB4:\
- case IMGFMT_BGR4:\
+ case PIX_FMT_RGB4:\
+ case PIX_FMT_BGR4:\
{\
const uint8_t * const d64= dither_8x8_73 [y&7];\
const uint8_t * const d128=dither_8x8_220[y&7];\
}\
}\
break;\
- case IMGFMT_RG4B:\
- case IMGFMT_BG4B:\
+ case PIX_FMT_RGB4_BYTE:\
+ case PIX_FMT_BGR4_BYTE:\
{\
const uint8_t * const d64= dither_8x8_73 [y&7];\
const uint8_t * const d128=dither_8x8_220[y&7];\
}\
}\
break;\
- case IMGFMT_RGB1:\
- case IMGFMT_BGR1:\
+ case PIX_FMT_MONOBLACK:\
{\
const uint8_t * const d128=dither_8x8_220[y&7];\
uint8_t *g= c->table_gU[128] + c->table_gV[128];\
+ (last_new[y][i] - in3)*f/256;\
int new= old> 128 ? 255 : 0;\
\
- error_new+= ABS(last_new[y][i] - new);\
- error_in3+= ABS(last_in3[y][i] - in3);\
+ error_new+= FFABS(last_new[y][i] - new);\
+ error_in3+= FFABS(last_in3[y][i] - in3);\
f= error_new - error_in3*4;\
if(f<0) f=0;\
if(f>256) f=256;\
*/\
}\
break;\
- case IMGFMT_YUY2:\
+ case PIX_FMT_YUYV422:\
func2\
((uint8_t*)dest)[2*i2+0]= Y1;\
((uint8_t*)dest)[2*i2+1]= U;\
((uint8_t*)dest)[2*i2+3]= V;\
} \
break;\
- case IMGFMT_UYVY:\
+ case PIX_FMT_UYVY422:\
func2\
((uint8_t*)dest)[2*i2+0]= U;\
((uint8_t*)dest)[2*i2+1]= Y1;\
int i;
switch(c->dstFormat)
{
- case IMGFMT_RGB32:
- case IMGFMT_BGR32:
+ case PIX_FMT_BGR32:
+ case PIX_FMT_RGB32:
YSCALE_YUV_2_RGBX_C(uint32_t)
((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];
((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];
}
break;
- case IMGFMT_RGB24:
+ case PIX_FMT_RGB24:
YSCALE_YUV_2_RGBX_C(uint8_t)
((uint8_t*)dest)[0]= r[Y1];
((uint8_t*)dest)[1]= g[Y1];
dest+=6;
}
break;
- case IMGFMT_BGR24:
+ case PIX_FMT_BGR24:
YSCALE_YUV_2_RGBX_C(uint8_t)
((uint8_t*)dest)[0]= b[Y1];
((uint8_t*)dest)[1]= g[Y1];
dest+=6;
}
break;
- case IMGFMT_RGB16:
- case IMGFMT_BGR16:
+ case PIX_FMT_RGB565:
+ case PIX_FMT_BGR565:
{
const int dr1= dither_2x2_8[y&1 ][0];
const int dg1= dither_2x2_4[y&1 ][0];
}
}
break;
- case IMGFMT_RGB15:
- case IMGFMT_BGR15:
+ case PIX_FMT_RGB555:
+ case PIX_FMT_BGR555:
{
const int dr1= dither_2x2_8[y&1 ][0];
const int dg1= dither_2x2_8[y&1 ][1];
}
}
break;
- case IMGFMT_RGB8:
- case IMGFMT_BGR8:
+ case PIX_FMT_RGB8:
+ case PIX_FMT_BGR8:
{
const uint8_t * const d64= dither_8x8_73[y&7];
const uint8_t * const d32= dither_8x8_32[y&7];
}
}
break;
- case IMGFMT_RGB4:
- case IMGFMT_BGR4:
+ case PIX_FMT_RGB4:
+ case PIX_FMT_BGR4:
{
const uint8_t * const d64= dither_8x8_73 [y&7];
const uint8_t * const d128=dither_8x8_220[y&7];
}
}
break;
- case IMGFMT_RG4B:
- case IMGFMT_BG4B:
+ case PIX_FMT_RGB4_BYTE:
+ case PIX_FMT_BGR4_BYTE:
{
const uint8_t * const d64= dither_8x8_73 [y&7];
const uint8_t * const d128=dither_8x8_220[y&7];
}
}
break;
- case IMGFMT_RGB1:
- case IMGFMT_BGR1:
+ case PIX_FMT_MONOBLACK:
{
const uint8_t * const d128=dither_8x8_220[y&7];
uint8_t *g= c->table_gU[128] + c->table_gV[128];
}
}
break;
- case IMGFMT_YUY2:
+ case PIX_FMT_YUYV422:
YSCALE_YUV_2_PACKEDX_C(void)
((uint8_t*)dest)[2*i2+0]= Y1;
((uint8_t*)dest)[2*i2+1]= U;
((uint8_t*)dest)[2*i2+3]= V;
}
break;
- case IMGFMT_UYVY:
+ case PIX_FMT_UYVY422:
YSCALE_YUV_2_PACKEDX_C(void)
((uint8_t*)dest)[2*i2+0]= U;
((uint8_t*)dest)[2*i2+1]= Y1;
#endif //HAVE_ALTIVEC
#endif //ARCH_POWERPC
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
#if (defined (HAVE_MMX) && !defined (HAVE_3DNOW) && !defined (HAVE_MMX2)) || defined (RUNTIME_CPUDETECT)
#define COMPILE_MMX
#endif
#endif //ARCH_POWERPC
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
//X86 versions
/*
int minFilterSize;
double *filter=NULL;
double *filter2=NULL;
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
if(flags & SWS_CPU_CAPS_MMX)
asm volatile("emms\n\t"::: "memory"); //FIXME this shouldnt be required but it IS (even for non mmx versions)
#endif
// Note the +1 is for the MMXscaler which reads over the end
*filterPos = av_malloc((dstW+1)*sizeof(int16_t));
- if(ABS(xInc - 0x10000) <10) // unscaled
+ if(FFABS(xInc - 0x10000) <10) // unscaled
{
int i;
filterSize= 1;
//Bilinear upscale / linear interpolate / Area averaging
for(j=0; j<filterSize; j++)
{
- double d= ABS((xx<<16) - xDstInSrc)/(double)(1<<16);
+ double d= FFABS((xx<<16) - xDstInSrc)/(double)(1<<16);
double coeff= 1.0 - d;
if(coeff<0) coeff=0;
filter[i*filterSize + j]= coeff;
(*filterPos)[i]= xx;
for(j=0; j<filterSize; j++)
{
- double d= ABS(xx - xDstInSrc)/filterSizeInSrc*sizeFactor;
+ double d= FFABS(xx - xDstInSrc)/filterSizeInSrc*sizeFactor;
double coeff;
if(flags & SWS_BICUBIC)
{
for(j=0; j<filter2Size; j++)
{
int k;
- cutOff += ABS(filter2[i*filter2Size]);
+ cutOff += FFABS(filter2[i*filter2Size]);
if(cutOff > SWS_MAX_REDUCE_CUTOFF) break;
/* count near zeros on the right */
for(j=filter2Size-1; j>0; j--)
{
- cutOff += ABS(filter2[i*filter2Size + j]);
+ cutOff += FFABS(filter2[i*filter2Size + j]);
if(cutOff > SWS_MAX_REDUCE_CUTOFF) break;
min--;
return 0;
}
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#ifdef COMPILE_MMX2
static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *filter, int32_t *filterPos, int numSplits)
{
uint8_t *fragmentA;
}
filterPos[i/2]= xpos>>16; // needed to jump to the next part
}
-#endif // ARCH_X86 || ARCH_X86_64
+#endif /* COMPILE_MMX2 */
static void globalInit(void){
// generating tables:
static SwsFunc getSwsFunc(int flags){
#ifdef RUNTIME_CPUDETECT
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
// ordered per speed fasterst first
if(flags & SWS_CPU_CAPS_MMX2)
return swScale_MMX2;
return swScale_C;
#endif
return swScale_C;
-#endif
+#endif /* defined(ARCH_X86) */
#else //RUNTIME_CPUDETECT
#ifdef HAVE_MMX2
return swScale_MMX2;
}
}
dst = dstParam[1] + dstStride[1]*srcSliceY/2;
- if (c->dstFormat == IMGFMT_NV12)
+ if (c->dstFormat == PIX_FMT_NV12)
interleaveBytes( src[1],src[2],dst,c->srcW/2,srcSliceH/2,srcStride[1],srcStride[2],dstStride[0] );
else
interleaveBytes( src[2],src[1],dst,c->srcW/2,srcSliceH/2,srcStride[2],srcStride[1],dstStride[0] );
int srcSliceH, uint8_t* dst[], int dstStride[]){
const int srcFormat= c->srcFormat;
const int dstFormat= c->dstFormat;
- const int srcBpp= ((srcFormat&0xFF) + 7)>>3;
- const int dstBpp= ((dstFormat&0xFF) + 7)>>3;
- const int srcId= (srcFormat&0xFF)>>2; // 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8
- const int dstId= (dstFormat&0xFF)>>2;
+ const int srcBpp= (fmt_depth(srcFormat) + 7) >> 3;
+ const int dstBpp= (fmt_depth(dstFormat) + 7) >> 3;
+ const int srcId= fmt_depth(srcFormat) >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */
+ const int dstId= fmt_depth(dstFormat) >> 2;
void (*conv)(const uint8_t *src, uint8_t *dst, long src_size)=NULL;
/* BGR -> BGR */
}
}
- if(c->dstFormat==IMGFMT_YV12){
+ if(c->dstFormat==PIX_FMT_YUV420P){
planar2x(src[1], dst[1], c->chrSrcW, c->chrSrcH, srcStride[1], dstStride[1]);
planar2x(src[2], dst[2], c->chrSrcW, c->chrSrcH, srcStride[2], dstStride[2]);
}else{
return srcSliceH;
}
-/**
- * bring pointers in YUV order instead of YVU
- */
-static inline void sws_orderYUV(int format, uint8_t * sortedP[], int sortedStride[], uint8_t * p[], int stride[]){
- if(format == IMGFMT_YV12 || format == IMGFMT_YVU9
- || format == IMGFMT_444P || format == IMGFMT_422P || format == IMGFMT_411P){
- sortedP[0]= p[0];
- sortedP[1]= p[2];
- sortedP[2]= p[1];
- sortedStride[0]= stride[0];
- sortedStride[1]= stride[2];
- sortedStride[2]= stride[1];
- }
- else if(isPacked(format) || isGray(format) || format == IMGFMT_Y8)
- {
- sortedP[0]= p[0];
- sortedP[1]=
- sortedP[2]= NULL;
- sortedStride[0]= stride[0];
- sortedStride[1]=
- sortedStride[2]= 0;
- }
- else if(format == IMGFMT_I420 || format == IMGFMT_IYUV)
- {
- sortedP[0]= p[0];
- sortedP[1]= p[1];
- sortedP[2]= p[2];
- sortedStride[0]= stride[0];
- sortedStride[1]= stride[1];
- sortedStride[2]= stride[2];
- }
- else if(format == IMGFMT_NV12 || format == IMGFMT_NV21)
- {
- sortedP[0]= p[0];
- sortedP[1]= p[1];
- sortedP[2]= NULL;
- sortedStride[0]= stride[0];
- sortedStride[1]= stride[1];
- sortedStride[2]= 0;
- }else{
- MSG_ERR("internal error in orderYUV\n");
- }
-}
-
/* unscaled copy like stuff (assumes nearly identical formats) */
static int simpleCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]){
int length=0;
/* universal length finder */
- while(length+c->srcW <= ABS(dstStride[0])
- && length+c->srcW <= ABS(srcStride[0])) length+= c->srcW;
+ while(length+c->srcW <= FFABS(dstStride[0])
+ && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW;
ASSERT(length!=0);
for(i=0; i<srcSliceH; i++)
return srcSliceH;
}
-static int remove_dup_fourcc(int fourcc)
-{
- switch(fourcc)
+static int gray16togray(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
+ int srcSliceH, uint8_t* dst[], int dstStride[]){
+
+ int length= c->srcW;
+ int y= srcSliceY;
+ int height= srcSliceH;
+ int i, j;
+ uint8_t *srcPtr= src[0];
+ uint8_t *dstPtr= dst[0] + dstStride[0]*y;
+
+ if(!isGray(c->dstFormat)){
+ int height= -((-srcSliceH)>>c->chrDstVSubSample);
+ memset(dst[1], 128, dstStride[1]*height);
+ memset(dst[2], 128, dstStride[2]*height);
+ }
+ if(c->srcFormat == PIX_FMT_GRAY16LE) srcPtr++;
+ for(i=0; i<height; i++)
{
- case IMGFMT_I420:
- case IMGFMT_IYUV: return IMGFMT_YV12;
- case IMGFMT_Y8 : return IMGFMT_Y800;
- case IMGFMT_IF09: return IMGFMT_YVU9;
- default: return fourcc;
+ for(j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
+ srcPtr+= srcStride[0];
+ dstPtr+= dstStride[0];
}
+ return srcSliceH;
}
+static int graytogray16(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
+ int srcSliceH, uint8_t* dst[], int dstStride[]){
+
+ int length= c->srcW;
+ int y= srcSliceY;
+ int height= srcSliceH;
+ int i, j;
+ uint8_t *srcPtr= src[0];
+ uint8_t *dstPtr= dst[0] + dstStride[0]*y;
+ for(i=0; i<height; i++)
+ {
+ for(j=0; j<length; j++)
+ {
+ dstPtr[j<<1] = srcPtr[j];
+ dstPtr[(j<<1)+1] = srcPtr[j];
+ }
+ srcPtr+= srcStride[0];
+ dstPtr+= dstStride[0];
+ }
+ return srcSliceH;
+}
+
+static int gray16swap(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
+ int srcSliceH, uint8_t* dst[], int dstStride[]){
+
+ int length= c->srcW;
+ int y= srcSliceY;
+ int height= srcSliceH;
+ int i, j;
+ uint16_t *srcPtr= src[0];
+ uint16_t *dstPtr= dst[0] + dstStride[0]*y/2;
+ for(i=0; i<height; i++)
+ {
+ for(j=0; j<length; j++) dstPtr[j] = bswap_16(srcPtr[j]);
+ srcPtr+= srcStride[0]/2;
+ dstPtr+= dstStride[0]/2;
+ }
+ return srcSliceH;
+}
+
+
static void getSubSampleFactors(int *h, int *v, int format){
switch(format){
- case IMGFMT_UYVY:
- case IMGFMT_YUY2:
+ case PIX_FMT_UYVY422:
+ case PIX_FMT_YUYV422:
*h=1;
*v=0;
break;
- case IMGFMT_YV12:
- case IMGFMT_Y800: //FIXME remove after different subsamplings are fully implemented
- case IMGFMT_NV12:
- case IMGFMT_NV21:
+ case PIX_FMT_YUV420P:
+ case PIX_FMT_GRAY16BE:
+ case PIX_FMT_GRAY16LE:
+ case PIX_FMT_GRAY8: //FIXME remove after different subsamplings are fully implemented
+ case PIX_FMT_NV12:
+ case PIX_FMT_NV21:
*h=1;
*v=1;
break;
- case IMGFMT_YVU9:
+ case PIX_FMT_YUV410P:
*h=2;
*v=2;
break;
- case IMGFMT_444P:
+ case PIX_FMT_YUV444P:
*h=0;
*v=0;
break;
- case IMGFMT_422P:
+ case PIX_FMT_YUV422P:
*h=1;
*v=0;
break;
- case IMGFMT_411P:
+ case PIX_FMT_YUV411P:
*h=2;
*v=0;
break;
return 0;
}
-SwsContext *sws_getContext(int srcW, int srcH, int origSrcFormat, int dstW, int dstH, int origDstFormat, int flags,
+static int handle_jpeg(int *format)
+{
+ switch (*format) {
+ case PIX_FMT_YUVJ420P:
+ *format = PIX_FMT_YUV420P;
+ return 1;
+ case PIX_FMT_YUVJ422P:
+ *format = PIX_FMT_YUV422P;
+ return 1;
+ case PIX_FMT_YUVJ444P:
+ *format = PIX_FMT_YUV444P;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
SwsFilter *srcFilter, SwsFilter *dstFilter, double *param){
SwsContext *c;
int i;
int usesVFilter, usesHFilter;
int unscaled, needsDither;
- int srcFormat, dstFormat;
+ int srcRange, dstRange;
SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
if(flags & SWS_CPU_CAPS_MMX)
asm volatile("emms\n\t"::: "memory");
#endif
#elif defined (HAVE_ALTIVEC)
flags |= SWS_CPU_CAPS_ALTIVEC;
#endif
-#endif
+#endif /* RUNTIME_CPUDETECT */
if(clip_table[512] != 255) globalInit();
if(rgb15to16 == NULL) sws_rgb2rgb_init(flags);
- /* avoid duplicate Formats, so we don't need to check to much */
- srcFormat = remove_dup_fourcc(origSrcFormat);
- dstFormat = remove_dup_fourcc(origDstFormat);
-
unscaled = (srcW == dstW && srcH == dstH);
needsDither= (isBGR(dstFormat) || isRGB(dstFormat))
- && (dstFormat&0xFF)<24
- && ((dstFormat&0xFF)<(srcFormat&0xFF) || (!(isRGB(srcFormat) || isBGR(srcFormat))));
+ && (fmt_depth(dstFormat))<24
+ && ((fmt_depth(dstFormat))<(fmt_depth(srcFormat)) || (!(isRGB(srcFormat) || isBGR(srcFormat))));
+
+ srcRange = handle_jpeg(&srcFormat);
+ dstRange = handle_jpeg(&dstFormat);
if(!isSupportedIn(srcFormat))
{
c->flags= flags;
c->dstFormat= dstFormat;
c->srcFormat= srcFormat;
- c->origDstFormat= origDstFormat;
- c->origSrcFormat= origSrcFormat;
c->vRounder= 4* 0x0001000100010001ULL;
usesHFilter= usesVFilter= 0;
c->chrDstW= -((-dstW) >> c->chrDstHSubSample);
c->chrDstH= -((-dstH) >> c->chrDstVSubSample);
- sws_setColorspaceDetails(c, Inverse_Table_6_9[SWS_CS_DEFAULT], 0, Inverse_Table_6_9[SWS_CS_DEFAULT] /* FIXME*/, 0, 0, 1<<16, 1<<16);
+ sws_setColorspaceDetails(c, Inverse_Table_6_9[SWS_CS_DEFAULT], srcRange, Inverse_Table_6_9[SWS_CS_DEFAULT] /* FIXME*/, dstRange, 0, 1<<16, 1<<16);
/* unscaled special Cases */
if(unscaled && !usesHFilter && !usesVFilter)
{
/* yv12_to_nv12 */
- if(srcFormat == IMGFMT_YV12 && (dstFormat == IMGFMT_NV12 || dstFormat == IMGFMT_NV21))
+ if(srcFormat == PIX_FMT_YUV420P && (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21))
{
c->swScale= PlanarToNV12Wrapper;
}
/* yuv2bgr */
- if((srcFormat==IMGFMT_YV12 || srcFormat==IMGFMT_422P) && (isBGR(dstFormat) || isRGB(dstFormat)))
+ if((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P) && (isBGR(dstFormat) || isRGB(dstFormat)))
{
c->swScale= yuv2rgb_get_func_ptr(c);
}
- if( srcFormat==IMGFMT_YVU9 && dstFormat==IMGFMT_YV12 )
+ if( srcFormat==PIX_FMT_YUV410P && dstFormat==PIX_FMT_YUV420P )
{
c->swScale= yvu9toyv12Wrapper;
}
/* bgr24toYV12 */
- if(srcFormat==IMGFMT_BGR24 && dstFormat==IMGFMT_YV12)
+ if(srcFormat==PIX_FMT_BGR24 && dstFormat==PIX_FMT_YUV420P)
c->swScale= bgr24toyv12Wrapper;
/* rgb/bgr -> rgb/bgr (no dither needed forms) */
c->swScale= rgb2rgbWrapper;
/* yv12_to_yuy2 */
- if(srcFormat == IMGFMT_YV12 &&
- (dstFormat == IMGFMT_YUY2 || dstFormat == IMGFMT_UYVY))
+ if(srcFormat == PIX_FMT_YUV420P &&
+ (dstFormat == PIX_FMT_YUYV422 || dstFormat == PIX_FMT_UYVY422))
{
- if (dstFormat == IMGFMT_YUY2)
+ if (dstFormat == PIX_FMT_YUYV422)
c->swScale= PlanarToYuy2Wrapper;
else
c->swScale= PlanarToUyvyWrapper;
#ifdef COMPILE_ALTIVEC
if ((c->flags & SWS_CPU_CAPS_ALTIVEC) &&
- ((srcFormat == IMGFMT_YV12 &&
- (dstFormat == IMGFMT_YUY2 || dstFormat == IMGFMT_UYVY)))) {
+ ((srcFormat == PIX_FMT_YUV420P &&
+ (dstFormat == PIX_FMT_YUYV422 || dstFormat == PIX_FMT_UYVY422)))) {
// unscaled YV12 -> packed YUV, we want speed
- if (dstFormat == IMGFMT_YUY2)
+ if (dstFormat == PIX_FMT_YUYV422)
c->swScale= yv12toyuy2_unscaled_altivec;
else
c->swScale= yv12touyvy_unscaled_altivec;
c->swScale= simpleCopy;
}
+ /* gray16{le,be} conversions */
+ if(isGray16(srcFormat) && (isPlanarYUV(dstFormat) || (dstFormat == PIX_FMT_GRAY8)))
+ {
+ c->swScale= gray16togray;
+ }
+ if((isPlanarYUV(srcFormat) || (srcFormat == PIX_FMT_GRAY8)) && isGray16(dstFormat))
+ {
+ c->swScale= graytogray16;
+ }
+ if(srcFormat != dstFormat && isGray16(srcFormat) && isGray16(dstFormat))
+ {
+ c->swScale= gray16swap;
+ }
+
if(c->swScale){
if(flags&SWS_PRINT_INFO)
MSG_INFO("SwScaler: using unscaled %s -> %s special converter\n",
(flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,
srcFilter->chrH, dstFilter->chrH, c->param);
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#define MAX_FUNNY_CODE_SIZE 10000
+#if defined(COMPILE_MMX2)
// can't downscale !!!
if(c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR))
{
-#define MAX_FUNNY_CODE_SIZE 10000
#ifdef MAP_ANONYMOUS
c->funnyYCode = (uint8_t*)mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
c->funnyUVCode = (uint8_t*)mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
initMMX2HScaler( dstW, c->lumXInc, c->funnyYCode , c->lumMmx2Filter, c->lumMmx2FilterPos, 8);
initMMX2HScaler(c->chrDstW, c->chrXInc, c->funnyUVCode, c->chrMmx2Filter, c->chrMmx2FilterPos, 4);
}
-#endif
+#endif /* defined(COMPILE_MMX2) */
} // Init Horizontal stuff
else
MSG_INFO("\nSwScaler: ehh flags invalid?! ");
- if(dstFormat==IMGFMT_BGR15 || dstFormat==IMGFMT_BGR16)
+ if(dstFormat==PIX_FMT_BGR555 || dstFormat==PIX_FMT_BGR565)
MSG_INFO("from %s to%s %s ",
sws_format_name(srcFormat), dither, sws_format_name(dstFormat));
else
}
else
{
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
MSG_V("SwScaler: using X86-Asm scaler for horizontal scaling\n");
#else
if(flags & SWS_FAST_BILINEAR)
MSG_V("SwScaler: using n-tap %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
}
- if(dstFormat==IMGFMT_BGR24)
+ if(dstFormat==PIX_FMT_BGR24)
MSG_V("SwScaler: using %s YV12->BGR24 Converter\n",
(flags & SWS_CPU_CAPS_MMX2) ? "MMX2" : ((flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"));
- else if(dstFormat==IMGFMT_BGR32)
+ else if(dstFormat==PIX_FMT_RGB32)
MSG_V("SwScaler: using %s YV12->BGR32 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
- else if(dstFormat==IMGFMT_BGR16)
+ else if(dstFormat==PIX_FMT_BGR565)
MSG_V("SwScaler: using %s YV12->BGR16 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
- else if(dstFormat==IMGFMT_BGR15)
+ else if(dstFormat==PIX_FMT_BGR555)
MSG_V("SwScaler: using %s YV12->BGR15 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
MSG_V("SwScaler: %dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
/**
* swscale warper, so we don't need to export the SwsContext
*/
-int sws_scale(SwsContext *c, uint8_t* srcParam[], int srcStrideParam[], int srcSliceY,
- int srcSliceH, uint8_t* dstParam[], int dstStrideParam[]){
- int srcStride[3];
- int dstStride[3];
+int sws_scale(SwsContext *c, uint8_t* srcParam[], int srcStride[], int srcSliceY,
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]){
uint8_t *src[3];
uint8_t *dst[3];
- sws_orderYUV(c->origSrcFormat, src, srcStride, srcParam, srcStrideParam);
- sws_orderYUV(c->origDstFormat, dst, dstStride, dstParam, dstStrideParam);
+ src[0] = srcParam[0]; src[1] = srcParam[1]; src[2] = srcParam[2];
+ dst[0] = dstParam[0]; dst[1] = dstParam[1]; dst[2] = dstParam[2];
//printf("sws: slice %d %d\n", srcSliceY, srcSliceH);
return c->swScale(c, src, srcStride, srcSliceY, srcSliceH, dst, dstStride);
/* shift left / or right if "shift" is negative */
static SwsVector *sws_getShiftedVec(SwsVector *a, int shift){
- int length= a->length + ABS(shift)*2;
+ int length= a->length + FFABS(shift)*2;
double *coeff= av_malloc(length*sizeof(double));
int i;
SwsVector *vec= av_malloc(sizeof(SwsVector));
av_free(c->hChrFilterPos);
c->hChrFilterPos = NULL;
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
+#if defined(ARCH_X86)
#ifdef MAP_ANONYMOUS
if(c->funnyYCode) munmap(c->funnyYCode, MAX_FUNNY_CODE_SIZE);
if(c->funnyUVCode) munmap(c->funnyUVCode, MAX_FUNNY_CODE_SIZE);
#endif
c->funnyYCode=NULL;
c->funnyUVCode=NULL;
-#endif
+#endif /* defined(ARCH_X86) */
av_free(c->lumMmx2Filter);
c->lumMmx2Filter=NULL;
av_free(c);
}
+/**
+ * Checks if context is valid or reallocs a new one instead.
+ * If context is NULL, just calls sws_getContext() to get a new one.
+ * Otherwise, checks if the parameters are the same already saved in context.
+ * If that is the case, returns the current context.
+ * Otherwise, frees context and gets a new one.
+ *
+ * Be warned that srcFilter, dstFilter are not checked, they are
+ * asumed to remain valid.
+ */
+struct SwsContext *sws_getCachedContext(struct SwsContext *context,
+ int srcW, int srcH, int srcFormat,
+ int dstW, int dstH, int dstFormat, int flags,
+ SwsFilter *srcFilter, SwsFilter *dstFilter, double *param)
+{
+ if (context != NULL) {
+ if ((context->srcW != srcW) || (context->srcH != srcH) ||
+ (context->srcFormat != srcFormat) ||
+ (context->dstW != dstW) || (context->dstH != dstH) ||
+ (context->dstFormat != dstFormat) || (context->flags != flags) ||
+ (context->param != param))
+ {
+ sws_freeContext(context);
+ context = NULL;
+ }
+ }
+ if (context == NULL) {
+ return sws_getContext(srcW, srcH, srcFormat,
+ dstW, dstH, dstFormat, flags,
+ srcFilter, dstFilter, param);
+ }
+ return context;
+}
+