summaryrefslogtreecommitdiffstats
path: root/libswscale
diff options
context:
space:
mode:
Diffstat (limited to 'libswscale')
-rw-r--r--libswscale/Makefile4
-rw-r--r--libswscale/options.c (renamed from libswscale/swscale_avoption.c)0
-rw-r--r--libswscale/rgb2rgb_template.c2
-rw-r--r--libswscale/swscale.c215
-rw-r--r--libswscale/swscale.h36
-rw-r--r--libswscale/swscale_internal.h58
-rw-r--r--libswscale/swscale_template.c100
-rw-r--r--libswscale/yuv2rgb.c9
8 files changed, 267 insertions, 157 deletions
diff --git a/libswscale/Makefile b/libswscale/Makefile
index ce0f7cebc1..247ae8d239 100644
--- a/libswscale/Makefile
+++ b/libswscale/Makefile
@@ -5,7 +5,7 @@ FFLIBS = avutil
HEADERS = swscale.h
-OBJS = rgb2rgb.o swscale.o swscale_avoption.o yuv2rgb.o
+OBJS = options.o rgb2rgb.o swscale.o yuv2rgb.o
OBJS-$(ARCH_BFIN) += bfin/internal_bfin.o \
bfin/swscale_bfin.o \
@@ -16,8 +16,6 @@ OBJS-$(HAVE_VIS) += sparc/yuv2rgb_vis.o
MMX-OBJS-$(CONFIG_GPL) += x86/yuv2rgb_mmx.o \
-OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)
-
EXAMPLES = swscale
TESTPROGS = colorspace
diff --git a/libswscale/swscale_avoption.c b/libswscale/options.c
index 996843df1d..996843df1d 100644
--- a/libswscale/swscale_avoption.c
+++ b/libswscale/options.c
diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c
index 09a57cab81..56c9426430 100644
--- a/libswscale/rgb2rgb_template.c
+++ b/libswscale/rgb2rgb_template.c
@@ -323,8 +323,6 @@ static inline void RENAME(rgb16to15)(const uint8_t *src, uint8_t *dst, long src_
{
register uint16_t x= *((const uint16_t*)s);
*((uint16_t *)d) = ((x>>1)&0x7FE0) | (x&0x001F);
- s+=2;
- d+=2;
}
}
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index ca5e2d986f..a0954ad845 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -134,6 +134,12 @@ unsigned swscale_version(void)
|| (x)==PIX_FMT_YUV440P \
|| (x)==PIX_FMT_MONOWHITE \
|| (x)==PIX_FMT_MONOBLACK \
+ || (x)==PIX_FMT_YUV420PLE \
+ || (x)==PIX_FMT_YUV422PLE \
+ || (x)==PIX_FMT_YUV444PLE \
+ || (x)==PIX_FMT_YUV420PBE \
+ || (x)==PIX_FMT_YUV422PBE \
+ || (x)==PIX_FMT_YUV444PBE \
)
#define isSupportedOut(x) ( \
(x)==PIX_FMT_YUV420P \
@@ -152,6 +158,12 @@ unsigned swscale_version(void)
|| (x)==PIX_FMT_GRAY8 \
|| (x)==PIX_FMT_YUV410P \
|| (x)==PIX_FMT_YUV440P \
+ || (x)==PIX_FMT_YUV420PLE \
+ || (x)==PIX_FMT_YUV422PLE \
+ || (x)==PIX_FMT_YUV444PLE \
+ || (x)==PIX_FMT_YUV420PBE \
+ || (x)==PIX_FMT_YUV422PBE \
+ || (x)==PIX_FMT_YUV444PBE \
)
#define isPacked(x) ( \
(x)==PIX_FMT_PAL8 \
@@ -467,6 +479,18 @@ const char *sws_format_name(enum PixelFormat format)
return "vdpau_wmv3";
case PIX_FMT_VDPAU_VC1:
return "vdpau_vc1";
+ case PIX_FMT_YUV420PLE:
+ return "yuv420ple";
+ case PIX_FMT_YUV422PLE:
+ return "yuv422ple";
+ case PIX_FMT_YUV444PLE:
+ return "yuv444ple";
+ case PIX_FMT_YUV420PBE:
+ return "yuv420pbe";
+ case PIX_FMT_YUV422PBE:
+ return "yuv422pbe";
+ case PIX_FMT_YUV444PBE:
+ return "yuv444pbe";
default:
return "Unknown format";
}
@@ -2084,11 +2108,15 @@ static int yvu9toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int
}
if (c->dstFormat==PIX_FMT_YUV420P || c->dstFormat==PIX_FMT_YUVA420P){
- 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]);
+ planar2x(src[1], dst[1] + dstStride[1]*(srcSliceY >> 1), c->chrSrcW,
+ srcSliceH >> 2, srcStride[1], dstStride[1]);
+ planar2x(src[2], dst[2] + dstStride[2]*(srcSliceY >> 1), c->chrSrcW,
+ srcSliceH >> 2, srcStride[2], dstStride[2]);
}else{
- planar2x(src[1], dst[2], c->chrSrcW, c->chrSrcH, srcStride[1], dstStride[2]);
- planar2x(src[2], dst[1], c->chrSrcW, c->chrSrcH, srcStride[2], dstStride[1]);
+ planar2x(src[1], dst[2] + dstStride[2]*(srcSliceY >> 1), c->chrSrcW,
+ srcSliceH >> 2, srcStride[1], dstStride[2]);
+ planar2x(src[2], dst[1] + dstStride[1]*(srcSliceY >> 1), c->chrSrcW,
+ srcSliceH >> 2, srcStride[2], dstStride[1]);
}
if (dst[3])
fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
@@ -2126,27 +2154,55 @@ static int packedCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSli
static int planarCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[])
{
- int plane;
+ int plane, i, j;
for (plane=0; plane<4; plane++)
{
int length= (plane==0 || plane==3) ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample);
int y= (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample);
int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample);
+ uint8_t *srcPtr= src[plane];
+ uint8_t *dstPtr= dst[plane] + dstStride[plane]*y;
if (!dst[plane]) continue;
// ignore palette for GRAY8
if (plane == 1 && !dst[2]) continue;
- if (!src[plane] || (plane == 1 && !src[2]))
+ if (!src[plane] || (plane == 1 && !src[2])){
+ if(is16BPS(c->dstFormat))
+ length*=2;
fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128);
- else
+ }else
{
- if (dstStride[plane]==srcStride[plane] && srcStride[plane] > 0)
+ if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)){
+ if (!isBE(c->srcFormat)) srcPtr++;
+ for (i=0; i<height; i++){
+ for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
+ srcPtr+= srcStride[plane];
+ dstPtr+= dstStride[plane];
+ }
+ }else if(!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)){
+ 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[plane];
+ dstPtr+= dstStride[plane];
+ }
+ }else if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat)
+ && isBE(c->srcFormat) != isBE(c->dstFormat)){
+
+ for (i=0; i<height; i++){
+ for (j=0; j<length; j++)
+ ((uint16_t*)dstPtr)[j] = bswap_16(((uint16_t*)srcPtr)[j]);
+ srcPtr+= srcStride[plane];
+ dstPtr+= dstStride[plane];
+ }
+ } else if (dstStride[plane]==srcStride[plane] && srcStride[plane] > 0)
memcpy(dst[plane] + dstStride[plane]*y, src[plane], height*dstStride[plane]);
else
{
- int i;
- uint8_t *srcPtr= src[plane];
- uint8_t *dstPtr= dst[plane] + dstStride[plane]*y;
+ if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
+ length*=2;
for (i=0; i<height; i++)
{
memcpy(dstPtr, srcPtr, length);
@@ -2159,73 +2215,6 @@ static int planarCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSli
return srcSliceH;
}
-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++)
- {
- for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
- srcPtr+= srcStride[0];
- dstPtr+= dstStride[0];
- }
- if (dst[3])
- fillPlane(dst[3], dstStride[3], length, height, y, 255);
- 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= (uint16_t*)src[0];
- uint16_t *dstPtr= (uint16_t*)(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){
@@ -2235,6 +2224,8 @@ static void getSubSampleFactors(int *h, int *v, int format){
*v=0;
break;
case PIX_FMT_YUV420P:
+ case PIX_FMT_YUV420PLE:
+ case PIX_FMT_YUV420PBE:
case PIX_FMT_YUVA420P:
case PIX_FMT_GRAY16BE:
case PIX_FMT_GRAY16LE:
@@ -2253,10 +2244,14 @@ static void getSubSampleFactors(int *h, int *v, int format){
*v=2;
break;
case PIX_FMT_YUV444P:
+ case PIX_FMT_YUV444PLE:
+ case PIX_FMT_YUV444PBE:
*h=0;
*v=0;
break;
case PIX_FMT_YUV422P:
+ case PIX_FMT_YUV422PLE:
+ case PIX_FMT_YUV422PBE:
*h=1;
*v=0;
break;
@@ -2278,11 +2273,6 @@ static uint16_t roundToInt16(int64_t f){
else return r;
}
-/**
- * @param inv_table the yuv2rgb coefficients, normally ff_yuv2rgb_coeffs[x]
- * @param fullRange if 1 then the luma range is 0..255 if 0 it is 16..235
- * @return -1 if not supported
- */
int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation){
int64_t crv = inv_table[0];
int64_t cbu = inv_table[1];
@@ -2299,7 +2289,7 @@ int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange
c->saturation= saturation;
c->srcRange = srcRange;
c->dstRange = dstRange;
- if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return 0;
+ if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1;
c->uOffset= 0x0400040004000400LL;
c->vOffset= 0x0400040004000400LL;
@@ -2346,9 +2336,6 @@ int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange
return 0;
}
-/**
- * @return -1 if not supported
- */
int sws_getColorspaceDetails(SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation){
if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1;
@@ -2620,28 +2607,17 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d
|| (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P)
|| (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P)
|| (isPlanarYUV(srcFormat) && isGray(dstFormat))
- || (isPlanarYUV(dstFormat) && isGray(srcFormat)))
+ || (isPlanarYUV(dstFormat) && isGray(srcFormat))
+ || (isGray(dstFormat) && isGray(srcFormat))
+ || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat)
+ && c->chrDstHSubSample == c->chrSrcHSubSample
+ && c->chrDstVSubSample == c->chrSrcVSubSample))
{
if (isPacked(c->srcFormat))
c->swScale= packedCopy;
else /* Planar YUV or gray */
c->swScale= planarCopy;
}
-
- /* 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 ARCH_BFIN
if (flags & SWS_CPU_CAPS_BFIN)
ff_bfin_get_unscaled_swscale (c);
@@ -2939,6 +2915,21 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d
return c;
}
+static void reset_ptr(uint8_t* src[], int format){
+ if(!isALPHA(format))
+ src[3]=NULL;
+ if(!isPlanarYUV(format)){
+ src[3]=src[2]=NULL;
+ if( format != PIX_FMT_PAL8
+ && format != PIX_FMT_RGB8
+ && format != PIX_FMT_BGR8
+ && format != PIX_FMT_RGB4_BYTE
+ && format != PIX_FMT_BGR4_BYTE
+ )
+ src[1]= NULL;
+ }
+}
+
/**
* swscale wrapper, so we don't need to export the SwsContext.
* Assumes planar YUV to be in YUV order instead of YVU.
@@ -2947,6 +2938,7 @@ int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]){
int i;
uint8_t* src2[4]= {src[0], src[1], src[2], src[3]};
+ uint8_t* dst2[4]= {dst[0], dst[1], dst[2], dst[3]};
if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
@@ -3022,13 +3014,13 @@ int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
// slices go from top to bottom
int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2], srcStride[3]};
int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2], dstStride[3]};
- return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst, dstStride2);
+
+ reset_ptr(src2, c->srcFormat);
+ reset_ptr(dst2, c->dstFormat);
+
+ return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2);
} else {
// slices go from bottom to top => we flip the image internally
- uint8_t* dst2[4]= {dst[0] + (c->dstH-1)*dstStride[0],
- dst[1] + ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1],
- dst[2] + ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2],
- dst[3] + (c->dstH-1)*dstStride[3]};
int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2], -srcStride[3]};
int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2], -dstStride[3]};
@@ -3037,6 +3029,13 @@ int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1];
src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2];
src2[3] += (srcSliceH-1)*srcStride[3];
+ dst2[0] += ( c->dstH -1)*dstStride[0];
+ dst2[1] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1];
+ dst2[2] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2];
+ dst2[3] += ( c->dstH -1)*dstStride[3];
+
+ reset_ptr(src2, c->srcFormat);
+ reset_ptr(dst2, c->dstFormat);
return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2);
}
diff --git a/libswscale/swscale.h b/libswscale/swscale.h
index 6efd90fcda..4990ebf134 100644
--- a/libswscale/swscale.h
+++ b/libswscale/swscale.h
@@ -127,8 +127,10 @@ void sws_freeContext(struct SwsContext *swsContext);
* @param flags specify which algorithm and options to use for rescaling
* @return a pointer to an allocated context, or NULL in case of error
*/
-struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int dstW, int dstH, enum PixelFormat dstFormat, int flags,
- SwsFilter *srcFilter, SwsFilter *dstFilter, double *param);
+struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
+ int dstW, int dstH, enum PixelFormat dstFormat,
+ int flags, SwsFilter *srcFilter,
+ SwsFilter *dstFilter, double *param);
/**
* Scales the image slice in \p srcSlice and puts the resulting scaled
@@ -152,19 +154,32 @@ struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat
* the destination image
* @return the height of the output slice
*/
-int sws_scale(struct SwsContext *context, uint8_t* srcSlice[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[]);
+int sws_scale(struct SwsContext *context, uint8_t* srcSlice[], int srcStride[],
+ int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]);
#if LIBSWSCALE_VERSION_MAJOR < 1
/**
* @deprecated Use sws_scale() instead.
*/
-int sws_scale_ordered(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[]) attribute_deprecated;
+int sws_scale_ordered(struct SwsContext *context, uint8_t* src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t* dst[], int dstStride[]) attribute_deprecated;
#endif
+/**
+ * @param inv_table the yuv2rgb coefficients, normally ff_yuv2rgb_coeffs[x]
+ * @param fullRange if 1 then the luma range is 0..255 if 0 it is 16..235
+ * @return -1 if not supported
+ */
+int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
+ int srcRange, const int table[4], int dstRange,
+ int brightness, int contrast, int saturation);
-int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation);
-int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation);
+/**
+ * @return -1 if not supported
+ */
+int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
+ int *srcRange, int **table, int *dstRange,
+ int *brightness, int *contrast, int *saturation);
/**
* Returns a normalized Gaussian curve used to filter stuff
@@ -241,7 +256,8 @@ void sws_freeFilter(SwsFilter *filter);
*/
struct SwsContext *sws_getCachedContext(struct SwsContext *context,
int srcW, int srcH, enum PixelFormat srcFormat,
- int dstW, int dstH, enum PixelFormat dstFormat, int flags,
- SwsFilter *srcFilter, SwsFilter *dstFilter, double *param);
+ int dstW, int dstH, enum PixelFormat dstFormat,
+ int flags, SwsFilter *srcFilter,
+ SwsFilter *dstFilter, double *param);
#endif /* SWSCALE_SWSCALE_H */
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 070161900b..eb11166e25 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -33,7 +33,12 @@
#define MAX_FILTER_SIZE 256
-#define VOFW 2048
+#if ARCH_X86
+#define VOFW 5120
+#else
+#define VOFW 2048 // faster on PPC and not tested on others
+#endif
+
#define VOF (VOFW*2)
#ifdef WORDS_BIGENDIAN
@@ -54,8 +59,9 @@
struct SwsContext;
-typedef int (*SwsFunc)(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,
- int srcSliceH, uint8_t* dst[], int dstStride[]);
+typedef int (*SwsFunc)(struct SwsContext *context, uint8_t* src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t* dst[], int dstStride[]);
/* This struct should be aligned on at least a 32-byte boundary. */
typedef struct SwsContext{
@@ -183,7 +189,6 @@ typedef struct SwsContext{
int32_t alpMmxFilter[4*MAX_FILTER_SIZE];
#if HAVE_ALTIVEC
-
vector signed short CY;
vector signed short CRV;
vector signed short CBU;
@@ -192,10 +197,8 @@ typedef struct SwsContext{
vector signed short OY;
vector unsigned short CSHIFT;
vector signed short *vYCoeffsBank, *vCCoeffsBank;
-
#endif
-
#if ARCH_BFIN
uint32_t oy __attribute__((aligned(4)));
uint32_t oc __attribute__((aligned(4)));
@@ -252,6 +255,8 @@ typedef struct SwsContext{
void (*hyscale_internal)(uint8_t *dst, const uint8_t *src,
long width, uint32_t *pal);
+ void (*hascale_internal)(uint8_t *dst, const uint8_t *src,
+ long width, uint32_t *pal);
void (*hcscale_internal)(uint8_t *dstU, uint8_t *dstV,
const uint8_t *src1, const uint8_t *src2,
long width, uint32_t *pal);
@@ -260,18 +265,23 @@ typedef struct SwsContext{
const uint8_t *src, int srcW, int xInc);
void (*hcscale_fast)(struct SwsContext *c,
int16_t *dst, int dstWidth,
- const uint8_t *src1, const uint8_t *src2, int srcW, int xInc);
+ const uint8_t *src1, const uint8_t *src2,
+ int srcW, int xInc);
void (*hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW,
- int xInc, const int16_t *filter, const int16_t *filterPos, long filterSize);
+ int xInc, const int16_t *filter, const int16_t *filterPos,
+ long filterSize);
} SwsContext;
//FIXME check init (where 0)
SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c);
-int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation);
+int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4],
+ int fullRange, int brightness,
+ int contrast, int saturation);
-void ff_yuv2rgb_init_tables_altivec(SwsContext *c, const int inv_table[4], int brightness, int contrast, int saturation);
+void ff_yuv2rgb_init_tables_altivec(SwsContext *c, const int inv_table[4],
+ int brightness, int contrast, int saturation);
SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c);
SwsFunc ff_yuv2rgb_init_vis(SwsContext *c);
SwsFunc ff_yuv2rgb_init_mlib(SwsContext *c);
@@ -279,14 +289,25 @@ SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c);
SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c);
void ff_bfin_get_unscaled_swscale(SwsContext *c);
void ff_yuv2packedX_altivec(SwsContext *c,
- int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
- int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
- uint8_t *dest, int dstW, int dstY);
+ int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
+ int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
+ uint8_t *dest, int dstW, int dstY);
const char *sws_format_name(int format);
//FIXME replace this with something faster
-#define isPlanarYUV(x) ( \
+#define is16BPS(x) ( \
+ (x)==PIX_FMT_GRAY16BE \
+ || (x)==PIX_FMT_GRAY16LE \
+ || (x)==PIX_FMT_YUV420PLE \
+ || (x)==PIX_FMT_YUV422PLE \
+ || (x)==PIX_FMT_YUV444PLE \
+ || (x)==PIX_FMT_YUV420PBE \
+ || (x)==PIX_FMT_YUV422PBE \
+ || (x)==PIX_FMT_YUV444PBE \
+ )
+#define isBE(x) ((x)&1)
+#define isPlanar8YUV(x) ( \
(x)==PIX_FMT_YUV410P \
|| (x)==PIX_FMT_YUV420P \
|| (x)==PIX_FMT_YUVA420P \
@@ -297,6 +318,15 @@ const char *sws_format_name(int format);
|| (x)==PIX_FMT_NV12 \
|| (x)==PIX_FMT_NV21 \
)
+#define isPlanarYUV(x) ( \
+ isPlanar8YUV(x) \
+ || (x)==PIX_FMT_YUV420PLE \
+ || (x)==PIX_FMT_YUV422PLE \
+ || (x)==PIX_FMT_YUV444PLE \
+ || (x)==PIX_FMT_YUV420PBE \
+ || (x)==PIX_FMT_YUV422PBE \
+ || (x)==PIX_FMT_YUV444PBE \
+ )
#define isYUV(x) ( \
(x)==PIX_FMT_UYVY422 \
|| (x)==PIX_FMT_YUYV422 \
diff --git a/libswscale/swscale_template.c b/libswscale/swscale_template.c
index 49ce0d32d5..a605b9b663 100644
--- a/libswscale/swscale_template.c
+++ b/libswscale/swscale_template.c
@@ -1671,6 +1671,39 @@ static inline void RENAME(yuy2ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t
assert(src1 == src2);
}
+static inline void RENAME(LEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
+{
+#if HAVE_MMX
+ __asm__ volatile(
+ "mov %0, %%"REG_a" \n\t"
+ "1: \n\t"
+ "movq (%1, %%"REG_a",2), %%mm0 \n\t"
+ "movq 8(%1, %%"REG_a",2), %%mm1 \n\t"
+ "movq (%2, %%"REG_a",2), %%mm2 \n\t"
+ "movq 8(%2, %%"REG_a",2), %%mm3 \n\t"
+ "psrlw $8, %%mm0 \n\t"
+ "psrlw $8, %%mm1 \n\t"
+ "psrlw $8, %%mm2 \n\t"
+ "psrlw $8, %%mm3 \n\t"
+ "packuswb %%mm1, %%mm0 \n\t"
+ "packuswb %%mm3, %%mm2 \n\t"
+ "movq %%mm0, (%3, %%"REG_a") \n\t"
+ "movq %%mm2, (%4, %%"REG_a") \n\t"
+ "add $8, %%"REG_a" \n\t"
+ " js 1b \n\t"
+ : : "g" ((x86_reg)-width), "r" (src1+width*2), "r" (src2+width*2), "r" (dstU+width), "r" (dstV+width)
+ : "%"REG_a
+ );
+#else
+ int i;
+ for (i=0; i<width; i++)
+ {
+ dstU[i]= src1[2*i + 1];
+ dstV[i]= src2[2*i + 1];
+ }
+#endif
+}
+
/* This is almost identical to the previous, end exists only because
* yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
static inline void RENAME(uyvyToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
@@ -1732,6 +1765,40 @@ static inline void RENAME(uyvyToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t
assert(src1 == src2);
}
+static inline void RENAME(BEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
+{
+#if HAVE_MMX
+ __asm__ volatile(
+ "movq "MANGLE(bm01010101)", %%mm4 \n\t"
+ "mov %0, %%"REG_a" \n\t"
+ "1: \n\t"
+ "movq (%1, %%"REG_a",2), %%mm0 \n\t"
+ "movq 8(%1, %%"REG_a",2), %%mm1 \n\t"
+ "movq (%2, %%"REG_a",2), %%mm2 \n\t"
+ "movq 8(%2, %%"REG_a",2), %%mm3 \n\t"
+ "pand %%mm4, %%mm0 \n\t"
+ "pand %%mm4, %%mm1 \n\t"
+ "pand %%mm4, %%mm2 \n\t"
+ "pand %%mm4, %%mm3 \n\t"
+ "packuswb %%mm1, %%mm0 \n\t"
+ "packuswb %%mm3, %%mm2 \n\t"
+ "movq %%mm0, (%3, %%"REG_a") \n\t"
+ "movq %%mm2, (%4, %%"REG_a") \n\t"
+ "add $8, %%"REG_a" \n\t"
+ " js 1b \n\t"
+ : : "g" ((x86_reg)-width), "r" (src1+width*2), "r" (src2+width*2), "r" (dstU+width), "r" (dstV+width)
+ : "%"REG_a
+ );
+#else
+ int i;
+ for (i=0; i<width; i++)
+ {
+ dstU[i]= src1[2*i];
+ dstV[i]= src2[2*i];
+ }
+#endif
+}
+
#define BGR2Y(type, name, shr, shg, shb, maskr, maskg, maskb, RY, GY, BY, S)\
static inline void RENAME(name)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)\
{\
@@ -2272,6 +2339,7 @@ static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, long dstWidth,
int16_t *mmx2Filter = c->lumMmx2Filter;
int canMMX2BeUsed = c->canMMX2BeUsed;
void *funnyYCode = c->funnyYCode;
+ void (*internal_func)(uint8_t *, const uint8_t *, long, uint32_t *) = isAlpha ? c->hascale_internal : c->hyscale_internal;
if (isAlpha) {
if (srcFormat == PIX_FMT_RGB32 || srcFormat == PIX_FMT_BGR32 )
@@ -2281,8 +2349,8 @@ static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, long dstWidth,
src += ALT32_CORR;
}
- if (c->hyscale_internal) {
- c->hyscale_internal(formatConvBuffer, src, srcW, pal);
+ if (internal_func) {
+ internal_func(formatConvBuffer, src, srcW, pal);
src= formatConvBuffer;
}
@@ -2465,7 +2533,7 @@ inline static void RENAME(hcscale)(SwsContext *c, uint16_t *dst, long dstWidth,
if (isGray(srcFormat) || srcFormat==PIX_FMT_MONOBLACK || srcFormat==PIX_FMT_MONOWHITE)
return;
- if (srcFormat==PIX_FMT_RGB32_1) {
+ if (srcFormat==PIX_FMT_RGB32_1 || srcFormat==PIX_FMT_BGR32_1) {
src1 += ALT32_CORR;
src2 += ALT32_CORR;
}
@@ -3084,6 +3152,12 @@ static void RENAME(sws_init_swScale)(SwsContext *c)
case PIX_FMT_PAL8 :
case PIX_FMT_BGR4_BYTE:
case PIX_FMT_RGB4_BYTE: c->hcscale_internal = RENAME(palToUV); break;
+ case PIX_FMT_YUV420PBE:
+ case PIX_FMT_YUV422PBE:
+ case PIX_FMT_YUV444PBE: c->hcscale_internal = RENAME(BEToUV); break;
+ case PIX_FMT_YUV420PLE:
+ case PIX_FMT_YUV422PLE:
+ case PIX_FMT_YUV444PLE: c->hcscale_internal = RENAME(LEToUV); break;
}
if (c->chrSrcHSubSample) {
switch(srcFormat) {
@@ -3114,10 +3188,17 @@ static void RENAME(sws_init_swScale)(SwsContext *c)
}
c->hyscale_internal = NULL;
+ c->hascale_internal = NULL;
switch (srcFormat) {
case PIX_FMT_YUYV422 :
+ case PIX_FMT_YUV420PBE:
+ case PIX_FMT_YUV422PBE:
+ case PIX_FMT_YUV444PBE:
case PIX_FMT_GRAY16BE : c->hyscale_internal = RENAME(yuy2ToY); break;
case PIX_FMT_UYVY422 :
+ case PIX_FMT_YUV420PLE:
+ case PIX_FMT_YUV422PLE:
+ case PIX_FMT_YUV444PLE:
case PIX_FMT_GRAY16LE : c->hyscale_internal = RENAME(uyvyToY); break;
case PIX_FMT_BGR24 : c->hyscale_internal = RENAME(bgr24ToY); break;
case PIX_FMT_BGR565 : c->hyscale_internal = RENAME(bgr16ToY); break;
@@ -3132,20 +3213,17 @@ static void RENAME(sws_init_swScale)(SwsContext *c)
case PIX_FMT_RGB4_BYTE: c->hyscale_internal = RENAME(palToY); break;
case PIX_FMT_MONOBLACK: c->hyscale_internal = RENAME(monoblack2Y); break;
case PIX_FMT_MONOWHITE: c->hyscale_internal = RENAME(monowhite2Y); break;
+ case PIX_FMT_RGB32 :
+ case PIX_FMT_RGB32_1: c->hyscale_internal = RENAME(bgr32ToY); break;
+ case PIX_FMT_BGR32 :
+ case PIX_FMT_BGR32_1: c->hyscale_internal = RENAME(rgb32ToY); break;
}
if (c->alpPixBuf) {
switch (srcFormat) {
case PIX_FMT_RGB32 :
case PIX_FMT_RGB32_1:
case PIX_FMT_BGR32 :
- case PIX_FMT_BGR32_1: c->hyscale_internal = RENAME(abgrToA); break;
- }
- } else {
- switch (srcFormat) {
- case PIX_FMT_RGB32 :
- case PIX_FMT_RGB32_1: c->hyscale_internal = RENAME(bgr32ToY); break;
- case PIX_FMT_BGR32 :
- case PIX_FMT_BGR32_1: c->hyscale_internal = RENAME(rgb32ToY); break;
+ case PIX_FMT_BGR32_1: c->hascale_internal = RENAME(abgrToA); break;
}
}
}
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index d8438c0c66..d2389c71dd 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -137,9 +137,6 @@ YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0)
LOADCHROMA(1);
PUTRGB(dst_2,py_2,1,1);
PUTRGB(dst_1,py_1,1,0);
- LOADCHROMA(1);
- PUTRGB(dst_2,py_2,1,1);
- PUTRGB(dst_1,py_1,1,0);
LOADCHROMA(2);
PUTRGB(dst_1,py_1,2,0);
@@ -166,9 +163,6 @@ YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
LOADCHROMA(1);
PUTRGBA(dst_2,py_2,pa_1,1,1,24);
PUTRGBA(dst_1,py_1,pa_2,1,0,24);
- LOADCHROMA(1);
- PUTRGBA(dst_2,py_2,pa_1,1,1,24);
- PUTRGBA(dst_1,py_1,pa_2,1,0,24);
LOADCHROMA(2);
PUTRGBA(dst_1,py_1,pa_1,2,0,24);
@@ -197,9 +191,6 @@ YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
LOADCHROMA(1);
PUTRGBA(dst_2,py_2,pa_2,1,1,0);
PUTRGBA(dst_1,py_1,pa_1,1,0,0);
- LOADCHROMA(1);
- PUTRGBA(dst_2,py_2,pa_2,1,1,0);
- PUTRGBA(dst_1,py_1,pa_1,1,0,0);
LOADCHROMA(2);
PUTRGBA(dst_1,py_1,pa_1,2,0,0);