aboutsummaryrefslogtreecommitdiffstats
path: root/libswscale/x86/swscale_template.c
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2011-05-25 14:30:09 -0400
committerRonald S. Bultje <rsbultje@gmail.com>2011-05-26 09:31:27 -0400
commitb4a224c5e4109cb2cca8bac38628673d685fe763 (patch)
treed6f53aa8452c9f813452e242a1f9a758c74de399 /libswscale/x86/swscale_template.c
parent69645c021ad2cc503769b44b9008f98b014423de (diff)
downloadffmpeg-b4a224c5e4109cb2cca8bac38628673d685fe763.tar.gz
swscale: split chroma buffers into separate U/V planes.
Preparatory step to implement support for sizes > VOFW.
Diffstat (limited to 'libswscale/x86/swscale_template.c')
-rw-r--r--libswscale/x86/swscale_template.c380
1 files changed, 220 insertions, 160 deletions
diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c
index 06cc3eef5c..0de7e94c97 100644
--- a/libswscale/x86/swscale_template.c
+++ b/libswscale/x86/swscale_template.c
@@ -37,9 +37,8 @@
#endif
#define MOVNTQ(a,b) REAL_MOVNTQ(a,b)
-#define YSCALEYUV2YV12X(x, offset, dest, width) \
+#define YSCALEYUV2YV12X(offset, dest, end, pos) \
__asm__ volatile(\
- "xor %%"REG_a", %%"REG_a" \n\t"\
"movq "VROUNDER_OFFSET"(%0), %%mm3 \n\t"\
"movq %%mm3, %%mm4 \n\t"\
"lea " offset "(%0), %%"REG_d" \n\t"\
@@ -47,8 +46,8 @@
".p2align 4 \n\t" /* FIXME Unroll? */\
"1: \n\t"\
"movq 8(%%"REG_d"), %%mm0 \n\t" /* filterCoeff */\
- "movq " x "(%%"REG_S", %%"REG_a", 2), %%mm2 \n\t" /* srcData */\
- "movq 8+" x "(%%"REG_S", %%"REG_a", 2), %%mm5 \n\t" /* srcData */\
+ "movq (%%"REG_S", %3, 2), %%mm2 \n\t" /* srcData */\
+ "movq 8(%%"REG_S", %3, 2), %%mm5 \n\t" /* srcData */\
"add $16, %%"REG_d" \n\t"\
"mov (%%"REG_d"), %%"REG_S" \n\t"\
"test %%"REG_S", %%"REG_S" \n\t"\
@@ -61,40 +60,40 @@
"psraw $3, %%mm4 \n\t"\
"packuswb %%mm4, %%mm3 \n\t"\
MOVNTQ(%%mm3, (%1, %%REGa))\
- "add $8, %%"REG_a" \n\t"\
- "cmp %2, %%"REG_a" \n\t"\
+ "add $8, %3 \n\t"\
+ "cmp %2, %3 \n\t"\
"movq "VROUNDER_OFFSET"(%0), %%mm3 \n\t"\
"movq %%mm3, %%mm4 \n\t"\
"lea " offset "(%0), %%"REG_d" \n\t"\
"mov (%%"REG_d"), %%"REG_S" \n\t"\
"jb 1b \n\t"\
:: "r" (&c->redDither),\
- "r" (dest), "g" ((x86_reg)width)\
- : "%"REG_a, "%"REG_d, "%"REG_S\
+ "r" (dest), "g" ((x86_reg)(end)), "r"((x86_reg)(pos))\
+ : "%"REG_d, "%"REG_S\
);
static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
uint8_t *aDest, long dstW, long chrDstW)
{
if (uDest) {
- YSCALEYUV2YV12X( "0", CHR_MMX_FILTER_OFFSET, uDest, chrDstW)
- YSCALEYUV2YV12X(AV_STRINGIFY(VOF), CHR_MMX_FILTER_OFFSET, vDest, chrDstW)
+ YSCALEYUV2YV12X(CHR_MMX_FILTER_OFFSET, uDest, chrDstW, 0)
+ YSCALEYUV2YV12X(CHR_MMX_FILTER_OFFSET, vDest, chrDstW + c->uv_off, c->uv_off)
}
if (CONFIG_SWSCALE_ALPHA && aDest) {
- YSCALEYUV2YV12X( "0", ALP_MMX_FILTER_OFFSET, aDest, dstW)
+ YSCALEYUV2YV12X(ALP_MMX_FILTER_OFFSET, aDest, dstW, 0)
}
- YSCALEYUV2YV12X("0", LUM_MMX_FILTER_OFFSET, dest, dstW)
+ YSCALEYUV2YV12X(LUM_MMX_FILTER_OFFSET, dest, dstW, 0)
}
-#define YSCALEYUV2YV12X_ACCURATE(x, offset, dest, width) \
+#define YSCALEYUV2YV12X_ACCURATE(offset, dest, end, pos) \
__asm__ volatile(\
"lea " offset "(%0), %%"REG_d" \n\t"\
- "xor %%"REG_a", %%"REG_a" \n\t"\
"pxor %%mm4, %%mm4 \n\t"\
"pxor %%mm5, %%mm5 \n\t"\
"pxor %%mm6, %%mm6 \n\t"\
@@ -102,10 +101,10 @@ static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter,
"mov (%%"REG_d"), %%"REG_S" \n\t"\
".p2align 4 \n\t"\
"1: \n\t"\
- "movq " x "(%%"REG_S", %%"REG_a", 2), %%mm0 \n\t" /* srcData */\
- "movq 8+" x "(%%"REG_S", %%"REG_a", 2), %%mm2 \n\t" /* srcData */\
+ "movq (%%"REG_S", %3, 2), %%mm0 \n\t" /* srcData */\
+ "movq 8(%%"REG_S", %3, 2), %%mm2 \n\t" /* srcData */\
"mov "STR(APCK_PTR2)"(%%"REG_d"), %%"REG_S" \n\t"\
- "movq " x "(%%"REG_S", %%"REG_a", 2), %%mm1 \n\t" /* srcData */\
+ "movq (%%"REG_S", %3, 2), %%mm1 \n\t" /* srcData */\
"movq %%mm0, %%mm3 \n\t"\
"punpcklwd %%mm1, %%mm0 \n\t"\
"punpckhwd %%mm1, %%mm3 \n\t"\
@@ -114,7 +113,7 @@ static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter,
"pmaddwd %%mm1, %%mm3 \n\t"\
"paddd %%mm0, %%mm4 \n\t"\
"paddd %%mm3, %%mm5 \n\t"\
- "movq 8+" x "(%%"REG_S", %%"REG_a", 2), %%mm3 \n\t" /* srcData */\
+ "movq 8(%%"REG_S", %3, 2), %%mm3 \n\t" /* srcData */\
"mov "STR(APCK_SIZE)"(%%"REG_d"), %%"REG_S" \n\t"\
"add $"STR(APCK_SIZE)", %%"REG_d" \n\t"\
"test %%"REG_S", %%"REG_S" \n\t"\
@@ -139,8 +138,8 @@ static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter,
"psraw $3, %%mm6 \n\t"\
"packuswb %%mm6, %%mm4 \n\t"\
MOVNTQ(%%mm4, (%1, %%REGa))\
- "add $8, %%"REG_a" \n\t"\
- "cmp %2, %%"REG_a" \n\t"\
+ "add $8, %3 \n\t"\
+ "cmp %2, %3 \n\t"\
"lea " offset "(%0), %%"REG_d" \n\t"\
"pxor %%mm4, %%mm4 \n\t"\
"pxor %%mm5, %%mm5 \n\t"\
@@ -149,26 +148,27 @@ static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter,
"mov (%%"REG_d"), %%"REG_S" \n\t"\
"jb 1b \n\t"\
:: "r" (&c->redDither),\
- "r" (dest), "g" ((x86_reg)width)\
+ "r" (dest), "g" ((x86_reg)(end)), "r"((x86_reg)(pos))\
: "%"REG_a, "%"REG_d, "%"REG_S\
);
static inline void RENAME(yuv2yuvX_ar)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
uint8_t *aDest, long dstW, long chrDstW)
{
if (uDest) {
- YSCALEYUV2YV12X_ACCURATE( "0", CHR_MMX_FILTER_OFFSET, uDest, chrDstW)
- YSCALEYUV2YV12X_ACCURATE(AV_STRINGIFY(VOF), CHR_MMX_FILTER_OFFSET, vDest, chrDstW)
+ YSCALEYUV2YV12X_ACCURATE(CHR_MMX_FILTER_OFFSET, uDest, chrDstW, 0)
+ YSCALEYUV2YV12X_ACCURATE(CHR_MMX_FILTER_OFFSET, vDest, chrDstW + c->uv_off, c->uv_off)
}
if (CONFIG_SWSCALE_ALPHA && aDest) {
- YSCALEYUV2YV12X_ACCURATE( "0", ALP_MMX_FILTER_OFFSET, aDest, dstW)
+ YSCALEYUV2YV12X_ACCURATE(ALP_MMX_FILTER_OFFSET, aDest, dstW, 0)
}
- YSCALEYUV2YV12X_ACCURATE("0", LUM_MMX_FILTER_OFFSET, dest, dstW)
+ YSCALEYUV2YV12X_ACCURATE(LUM_MMX_FILTER_OFFSET, dest, dstW, 0)
}
#define YSCALEYUV2YV121 \
@@ -185,12 +185,13 @@ static inline void RENAME(yuv2yuvX_ar)(SwsContext *c, const int16_t *lumFilter,
"jnc 1b \n\t"
static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc,
- const int16_t *chrSrc, const int16_t *alpSrc,
+ const int16_t *chrUSrc, const int16_t *chrVSrc,
+ const int16_t *alpSrc,
uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
uint8_t *aDest, long dstW, long chrDstW)
{
long p= 4;
- const uint8_t *src[4]= { alpSrc + dstW, lumSrc + dstW, chrSrc + chrDstW, chrSrc + VOFW + chrDstW };
+ const uint8_t *src[4]= { alpSrc + dstW, lumSrc + dstW, chrUSrc + chrDstW, chrVSrc + chrDstW };
uint8_t *dst[4]= { aDest, dest, uDest, vDest };
x86_reg counter[4]= { dstW, dstW, chrDstW, chrDstW };
@@ -225,12 +226,13 @@ static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc,
"jnc 1b \n\t"
static inline void RENAME(yuv2yuv1_ar)(SwsContext *c, const int16_t *lumSrc,
- const int16_t *chrSrc, const int16_t *alpSrc,
+ const int16_t *chrUSrc, const int16_t *chrVSrc,
+ const int16_t *alpSrc,
uint8_t *dest, uint8_t *uDest, uint8_t *vDest,
uint8_t *aDest, long dstW, long chrDstW)
{
long p= 4;
- const uint8_t *src[4]= { alpSrc + dstW, lumSrc + dstW, chrSrc + chrDstW, chrSrc + VOFW + chrDstW };
+ const uint8_t *src[4]= { alpSrc + dstW, lumSrc + dstW, chrUSrc + chrDstW, chrVSrc + chrDstW };
uint8_t *dst[4]= { aDest, dest, uDest, vDest };
x86_reg counter[4]= { dstW, dstW, chrDstW, chrDstW };
@@ -260,7 +262,8 @@ static inline void RENAME(yuv2yuv1_ar)(SwsContext *c, const int16_t *lumSrc,
"2: \n\t"\
"movq 8(%%"REG_d"), %%mm0 \n\t" /* filterCoeff */\
"movq (%%"REG_S", %%"REG_a"), %%mm2 \n\t" /* UsrcData */\
- "movq "AV_STRINGIFY(VOF)"(%%"REG_S", %%"REG_a"), %%mm5 \n\t" /* VsrcData */\
+ "add %6, %%"REG_S" \n\t" \
+ "movq (%%"REG_S", %%"REG_a"), %%mm5 \n\t" /* VsrcData */\
"add $16, %%"REG_d" \n\t"\
"mov (%%"REG_d"), %%"REG_S" \n\t"\
"pmulhw %%mm0, %%mm2 \n\t"\
@@ -296,7 +299,7 @@ static inline void RENAME(yuv2yuv1_ar)(SwsContext *c, const int16_t *lumSrc,
#define YSCALEYUV2PACKEDX_END \
:: "r" (&c->redDither), \
"m" (dummy), "m" (dummy), "m" (dummy),\
- "r" (dest), "m" (dstW_reg) \
+ "r" (dest), "m" (dstW_reg), "m"(uv_off) \
: "%"REG_a, "%"REG_d, "%"REG_S \
);
@@ -315,7 +318,8 @@ static inline void RENAME(yuv2yuv1_ar)(SwsContext *c, const int16_t *lumSrc,
".p2align 4 \n\t"\
"2: \n\t"\
"movq (%%"REG_S", %%"REG_a"), %%mm0 \n\t" /* UsrcData */\
- "movq "AV_STRINGIFY(VOF)"(%%"REG_S", %%"REG_a"), %%mm2 \n\t" /* VsrcData */\
+ "add %6, %%"REG_S" \n\t" \
+ "movq (%%"REG_S", %%"REG_a"), %%mm2 \n\t" /* VsrcData */\
"mov "STR(APCK_PTR2)"(%%"REG_d"), %%"REG_S" \n\t"\
"movq (%%"REG_S", %%"REG_a"), %%mm1 \n\t" /* UsrcData */\
"movq %%mm0, %%mm3 \n\t"\
@@ -326,7 +330,8 @@ static inline void RENAME(yuv2yuv1_ar)(SwsContext *c, const int16_t *lumSrc,
"pmaddwd %%mm1, %%mm3 \n\t"\
"paddd %%mm0, %%mm4 \n\t"\
"paddd %%mm3, %%mm5 \n\t"\
- "movq "AV_STRINGIFY(VOF)"(%%"REG_S", %%"REG_a"), %%mm3 \n\t" /* VsrcData */\
+ "add %6, %%"REG_S" \n\t" \
+ "movq (%%"REG_S", %%"REG_a"), %%mm3 \n\t" /* VsrcData */\
"mov "STR(APCK_SIZE)"(%%"REG_d"), %%"REG_S" \n\t"\
"add $"STR(APCK_SIZE)", %%"REG_d" \n\t"\
"test %%"REG_S", %%"REG_S" \n\t"\
@@ -461,12 +466,14 @@ static inline void RENAME(yuv2yuv1_ar)(SwsContext *c, const int16_t *lumSrc,
static inline void RENAME(yuv2rgb32_X_ar)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
YSCALEYUV2PACKEDX_ACCURATE
@@ -492,12 +499,14 @@ static inline void RENAME(yuv2rgb32_X_ar)(SwsContext *c, const int16_t *lumFilte
static inline void RENAME(yuv2rgb32_X)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
YSCALEYUV2PACKEDX
@@ -547,12 +556,14 @@ static inline void RENAME(yuv2rgb32_X)(SwsContext *c, const int16_t *lumFilter,
static inline void RENAME(yuv2rgb565_X_ar)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
YSCALEYUV2PACKEDX_ACCURATE
YSCALEYUV2RGBX
@@ -569,12 +580,14 @@ static inline void RENAME(yuv2rgb565_X_ar)(SwsContext *c, const int16_t *lumFilt
static inline void RENAME(yuv2rgb565_X)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
YSCALEYUV2PACKEDX
YSCALEYUV2RGBX
@@ -620,12 +633,14 @@ static inline void RENAME(yuv2rgb565_X)(SwsContext *c, const int16_t *lumFilter,
static inline void RENAME(yuv2rgb555_X_ar)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
YSCALEYUV2PACKEDX_ACCURATE
YSCALEYUV2RGBX
@@ -642,12 +657,14 @@ static inline void RENAME(yuv2rgb555_X_ar)(SwsContext *c, const int16_t *lumFilt
static inline void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
YSCALEYUV2PACKEDX
YSCALEYUV2RGBX
@@ -773,12 +790,14 @@ static inline void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter,
static inline void RENAME(yuv2bgr24_X_ar)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
YSCALEYUV2PACKEDX_ACCURATE
YSCALEYUV2RGBX
@@ -788,19 +807,21 @@ static inline void RENAME(yuv2bgr24_X_ar)(SwsContext *c, const int16_t *lumFilte
WRITEBGR24(%%REGc, %5, %%REGa)
:: "r" (&c->redDither),
"m" (dummy), "m" (dummy), "m" (dummy),
- "r" (dest), "m" (dstW_reg)
+ "r" (dest), "m" (dstW_reg), "m"(uv_off)
: "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S
);
}
static inline void RENAME(yuv2bgr24_X)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
YSCALEYUV2PACKEDX
YSCALEYUV2RGBX
@@ -810,7 +831,7 @@ static inline void RENAME(yuv2bgr24_X)(SwsContext *c, const int16_t *lumFilter,
WRITEBGR24(%%REGc, %5, %%REGa)
:: "r" (&c->redDither),
"m" (dummy), "m" (dummy), "m" (dummy),
- "r" (dest), "m" (dstW_reg)
+ "r" (dest), "m" (dstW_reg), "m"(uv_off)
: "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S
);
}
@@ -834,12 +855,14 @@ static inline void RENAME(yuv2bgr24_X)(SwsContext *c, const int16_t *lumFilter,
static inline void RENAME(yuv2yuyv422_X_ar)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
YSCALEYUV2PACKEDX_ACCURATE
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
@@ -853,12 +876,14 @@ static inline void RENAME(yuv2yuyv422_X_ar)(SwsContext *c, const int16_t *lumFil
static inline void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
- const int16_t *chrFilter, const int16_t **chrSrc,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc,
int chrFilterSize, const int16_t **alpSrc,
uint8_t *dest, long dstW, long dstY)
{
x86_reg dummy=0;
x86_reg dstW_reg = dstW;
+ x86_reg uv_off = c->uv_off << 1;
YSCALEYUV2PACKEDX
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
@@ -870,14 +895,16 @@ static inline void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter
YSCALEYUV2PACKEDX_END
}
-#define REAL_YSCALEYUV2RGB_UV(index, c) \
+#define REAL_YSCALEYUV2RGB_UV(index, c, uv_off) \
"xor "#index", "#index" \n\t"\
".p2align 4 \n\t"\
"1: \n\t"\
"movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\
"movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\
- "movq "AV_STRINGIFY(VOF)"(%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
- "movq "AV_STRINGIFY(VOF)"(%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
+ "add "#uv_off", "#index" \n\t" \
+ "movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
+ "movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
+ "sub "#uv_off", "#index" \n\t" \
"psubw %%mm3, %%mm2 \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\
"psubw %%mm4, %%mm5 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\
"movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0 \n\t"\
@@ -940,8 +967,8 @@ static inline void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter
#define YSCALEYUV2RGB_YA(index, c, b1, b2) REAL_YSCALEYUV2RGB_YA(index, c, b1, b2)
-#define YSCALEYUV2RGB(index, c) \
- REAL_YSCALEYUV2RGB_UV(index, c) \
+#define YSCALEYUV2RGB(index, c, uv_off) \
+ REAL_YSCALEYUV2RGB_UV(index, c, uv_off) \
REAL_YSCALEYUV2RGB_YA(index, c, %0, %1) \
REAL_YSCALEYUV2RGB_COEFF(c)
@@ -949,23 +976,26 @@ static inline void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter
* vertical bilinear scale YV12 to RGB
*/
static inline void RENAME(yuv2rgb32_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *uvbuf0,
- const uint16_t *uvbuf1, const uint16_t *abuf0,
+ const uint16_t *buf1, const uint16_t *ubuf0,
+ const uint16_t *ubuf1, const uint16_t *vbuf0,
+ const uint16_t *vbuf1, const uint16_t *abuf0,
const uint16_t *abuf1, uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
+
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
#if ARCH_X86_64
__asm__ volatile(
- YSCALEYUV2RGB(%%r8, %5)
+ YSCALEYUV2RGB(%%r8, %5, %8)
YSCALEYUV2RGB_YA(%%r8, %5, %6, %7)
"psraw $3, %%mm1 \n\t" /* abuf0[eax] - abuf1[eax] >>7*/
"psraw $3, %%mm7 \n\t" /* abuf0[eax] - abuf1[eax] >>7*/
"packuswb %%mm7, %%mm1 \n\t"
WRITEBGR32(%4, 8280(%5), %%r8, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6)
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "r" (dest),
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "r" (dest),
"a" (&c->redDither),
- "r" (abuf0), "r" (abuf1)
+ "r" (abuf0), "r" (abuf1), "m"(uv_off)
: "%r8"
);
#else
@@ -975,7 +1005,7 @@ static inline void RENAME(yuv2rgb32_2)(SwsContext *c, const uint16_t *buf0,
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB(%%REGBP, %5)
+ YSCALEYUV2RGB(%%REGBP, %5, %6)
"push %0 \n\t"
"push %1 \n\t"
"mov "U_TEMP"(%5), %0 \n\t"
@@ -990,7 +1020,7 @@ static inline void RENAME(yuv2rgb32_2)(SwsContext *c, const uint16_t *buf0,
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
:: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ "a" (&c->redDither), "m"(uv_off)
);
#endif
} else {
@@ -998,50 +1028,56 @@ static inline void RENAME(yuv2rgb32_2)(SwsContext *c, const uint16_t *buf0,
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB(%%REGBP, %5)
+ YSCALEYUV2RGB(%%REGBP, %5, %6)
"pcmpeqd %%mm7, %%mm7 \n\t"
WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
}
static inline void RENAME(yuv2bgr24_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *uvbuf0,
- const uint16_t *uvbuf1, const uint16_t *abuf0,
+ const uint16_t *buf1, const uint16_t *ubuf0,
+ const uint16_t *ubuf1, const uint16_t *vbuf0,
+ const uint16_t *vbuf1, const uint16_t *abuf0,
const uint16_t *abuf1, uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
+
//Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB(%%REGBP, %5)
+ YSCALEYUV2RGB(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
WRITEBGR24(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
static inline void RENAME(yuv2rgb555_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *uvbuf0,
- const uint16_t *uvbuf1, const uint16_t *abuf0,
+ const uint16_t *buf1, const uint16_t *ubuf0,
+ const uint16_t *ubuf1, const uint16_t *vbuf0,
+ const uint16_t *vbuf1, const uint16_t *abuf0,
const uint16_t *abuf1, uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
+
//Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB(%%REGBP, %5)
+ YSCALEYUV2RGB(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
#ifdef DITHER1XBPP
@@ -1052,23 +1088,26 @@ static inline void RENAME(yuv2rgb555_2)(SwsContext *c, const uint16_t *buf0,
WRITERGB15(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
static inline void RENAME(yuv2rgb565_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *uvbuf0,
- const uint16_t *uvbuf1, const uint16_t *abuf0,
+ const uint16_t *buf1, const uint16_t *ubuf0,
+ const uint16_t *ubuf1, const uint16_t *vbuf0,
+ const uint16_t *vbuf1, const uint16_t *abuf0,
const uint16_t *abuf1, uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
+
//Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB(%%REGBP, %5)
+ YSCALEYUV2RGB(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
#ifdef DITHER1XBPP
@@ -1079,12 +1118,12 @@ static inline void RENAME(yuv2rgb565_2)(SwsContext *c, const uint16_t *buf0,
WRITERGB16(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
-#define REAL_YSCALEYUV2PACKED(index, c) \
+#define REAL_YSCALEYUV2PACKED(index, c, uv_off) \
"movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0 \n\t"\
"movq "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm1 \n\t"\
"psraw $3, %%mm0 \n\t"\
@@ -1096,8 +1135,10 @@ static inline void RENAME(yuv2rgb565_2)(SwsContext *c, const uint16_t *buf0,
"1: \n\t"\
"movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\
"movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\
- "movq "AV_STRINGIFY(VOF)"(%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
- "movq "AV_STRINGIFY(VOF)"(%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
+ "add "#uv_off", "#index" \n\t" \
+ "movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
+ "movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
+ "sub "#uv_off", "#index" \n\t" \
"psubw %%mm3, %%mm2 \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\
"psubw %%mm4, %%mm5 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\
"movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0 \n\t"\
@@ -1120,34 +1161,39 @@ static inline void RENAME(yuv2rgb565_2)(SwsContext *c, const uint16_t *buf0,
"paddw %%mm0, %%mm1 \n\t" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/\
"paddw %%mm6, %%mm7 \n\t" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/\
-#define YSCALEYUV2PACKED(index, c) REAL_YSCALEYUV2PACKED(index, c)
+#define YSCALEYUV2PACKED(index, c, uv_off) REAL_YSCALEYUV2PACKED(index, c, uv_off)
static inline void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *buf1, const uint16_t *uvbuf0,
- const uint16_t *uvbuf1, const uint16_t *abuf0,
+ const uint16_t *buf1, const uint16_t *ubuf0,
+ const uint16_t *ubuf1, const uint16_t *vbuf0,
+ const uint16_t *vbuf1, const uint16_t *abuf0,
const uint16_t *abuf1, uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
+
//Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2PACKED(%%REGBP, %5)
+ YSCALEYUV2PACKED(%%REGBP, %5, %6)
WRITEYUY2(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
-#define REAL_YSCALEYUV2RGB1(index, c) \
+#define REAL_YSCALEYUV2RGB1(index, c, uv_off) \
"xor "#index", "#index" \n\t"\
".p2align 4 \n\t"\
"1: \n\t"\
"movq (%2, "#index"), %%mm3 \n\t" /* uvbuf0[eax]*/\
- "movq "AV_STRINGIFY(VOF)"(%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\
+ "add "#uv_off", "#index" \n\t" \
+ "movq (%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\
+ "sub "#uv_off", "#index" \n\t" \
"psraw $4, %%mm3 \n\t" /* uvbuf0[eax] - uvbuf1[eax] >>4*/\
"psraw $4, %%mm4 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/\
"psubw "U_OFFSET"("#c"), %%mm3 \n\t" /* (U-128)8*/\
@@ -1189,17 +1235,19 @@ static inline void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,
"packuswb %%mm6, %%mm5 \n\t"\
"packuswb %%mm3, %%mm4 \n\t"\
-#define YSCALEYUV2RGB1(index, c) REAL_YSCALEYUV2RGB1(index, c)
+#define YSCALEYUV2RGB1(index, c, uv_off) REAL_YSCALEYUV2RGB1(index, c, uv_off)
// do vertical chrominance interpolation
-#define REAL_YSCALEYUV2RGB1b(index, c) \
+#define REAL_YSCALEYUV2RGB1b(index, c, uv_off) \
"xor "#index", "#index" \n\t"\
".p2align 4 \n\t"\
"1: \n\t"\
"movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\
"movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\
- "movq "AV_STRINGIFY(VOF)"(%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
- "movq "AV_STRINGIFY(VOF)"(%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
+ "add "#uv_off", "#index" \n\t" \
+ "movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
+ "movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
+ "sub "#uv_off", "#index" \n\t" \
"paddw %%mm2, %%mm3 \n\t" /* uvbuf0[eax] + uvbuf1[eax]*/\
"paddw %%mm5, %%mm4 \n\t" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/\
"psrlw $5, %%mm3 \n\t" /*FIXME might overflow*/\
@@ -1243,7 +1291,7 @@ static inline void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,
"packuswb %%mm6, %%mm5 \n\t"\
"packuswb %%mm3, %%mm4 \n\t"\
-#define YSCALEYUV2RGB1b(index, c) REAL_YSCALEYUV2RGB1b(index, c)
+#define YSCALEYUV2RGB1b(index, c, uv_off) REAL_YSCALEYUV2RGB1b(index, c, uv_off)
#define REAL_YSCALEYUV2RGB1_ALPHA(index) \
"movq (%1, "#index", 2), %%mm7 \n\t" /* abuf0[index ] */\
@@ -1257,11 +1305,13 @@ static inline void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,
* YV12 to RGB without scaling or interpolating
*/
static inline void RENAME(yuv2rgb32_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *uvbuf0, const uint16_t *uvbuf1,
+ const uint16_t *ubuf0, const uint16_t *ubuf1,
+ const uint16_t *vbuf0, const uint16_t *vbuf1,
const uint16_t *abuf0, uint8_t *dest,
int dstW, int uvalpha, enum PixelFormat dstFormat,
int flags, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
@@ -1270,26 +1320,26 @@ static inline void RENAME(yuv2rgb32_1)(SwsContext *c, const uint16_t *buf0,
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1(%%REGBP, %5)
+ YSCALEYUV2RGB1(%%REGBP, %5, %6)
YSCALEYUV2RGB1_ALPHA(%%REGBP)
WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (abuf0), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (abuf0), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
} else {
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1(%%REGBP, %5)
+ YSCALEYUV2RGB1(%%REGBP, %5, %6)
"pcmpeqd %%mm7, %%mm7 \n\t"
WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
} else {
@@ -1298,37 +1348,39 @@ static inline void RENAME(yuv2rgb32_1)(SwsContext *c, const uint16_t *buf0,
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1b(%%REGBP, %5)
+ YSCALEYUV2RGB1b(%%REGBP, %5, %6)
YSCALEYUV2RGB1_ALPHA(%%REGBP)
WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (abuf0), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (abuf0), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
} else {
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1b(%%REGBP, %5)
+ YSCALEYUV2RGB1b(%%REGBP, %5, %6)
"pcmpeqd %%mm7, %%mm7 \n\t"
WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
}
}
static inline void RENAME(yuv2bgr24_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *uvbuf0, const uint16_t *uvbuf1,
+ const uint16_t *ubuf0, const uint16_t *ubuf1,
+ const uint16_t *vbuf0, const uint16_t *vbuf1,
const uint16_t *abuf0, uint8_t *dest,
int dstW, int uvalpha, enum PixelFormat dstFormat,
int flags, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
@@ -1336,36 +1388,38 @@ static inline void RENAME(yuv2bgr24_1)(SwsContext *c, const uint16_t *buf0,
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1(%%REGBP, %5)
+ YSCALEYUV2RGB1(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
WRITEBGR24(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
} else {
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1b(%%REGBP, %5)
+ YSCALEYUV2RGB1b(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
WRITEBGR24(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
}
static inline void RENAME(yuv2rgb555_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *uvbuf0, const uint16_t *uvbuf1,
+ const uint16_t *ubuf0, const uint16_t *ubuf1,
+ const uint16_t *vbuf0, const uint16_t *vbuf1,
const uint16_t *abuf0, uint8_t *dest,
int dstW, int uvalpha, enum PixelFormat dstFormat,
int flags, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
@@ -1373,7 +1427,7 @@ static inline void RENAME(yuv2rgb555_1)(SwsContext *c, const uint16_t *buf0,
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1(%%REGBP, %5)
+ YSCALEYUV2RGB1(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
#ifdef DITHER1XBPP
@@ -1384,15 +1438,15 @@ static inline void RENAME(yuv2rgb555_1)(SwsContext *c, const uint16_t *buf0,
WRITERGB15(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
} else {
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1b(%%REGBP, %5)
+ YSCALEYUV2RGB1b(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
#ifdef DITHER1XBPP
@@ -1403,18 +1457,20 @@ static inline void RENAME(yuv2rgb555_1)(SwsContext *c, const uint16_t *buf0,
WRITERGB15(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
}
static inline void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *uvbuf0, const uint16_t *uvbuf1,
+ const uint16_t *ubuf0, const uint16_t *ubuf1,
+ const uint16_t *vbuf0, const uint16_t *vbuf1,
const uint16_t *abuf0, uint8_t *dest,
int dstW, int uvalpha, enum PixelFormat dstFormat,
int flags, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
@@ -1422,7 +1478,7 @@ static inline void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1(%%REGBP, %5)
+ YSCALEYUV2RGB1(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
#ifdef DITHER1XBPP
@@ -1433,15 +1489,15 @@ static inline void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
WRITERGB16(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
} else {
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2RGB1b(%%REGBP, %5)
+ YSCALEYUV2RGB1b(%%REGBP, %5, %6)
"pxor %%mm7, %%mm7 \n\t"
/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
#ifdef DITHER1XBPP
@@ -1452,18 +1508,20 @@ static inline void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
WRITERGB16(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
}
-#define REAL_YSCALEYUV2PACKED1(index, c) \
+#define REAL_YSCALEYUV2PACKED1(index, c, uv_off) \
"xor "#index", "#index" \n\t"\
".p2align 4 \n\t"\
"1: \n\t"\
"movq (%2, "#index"), %%mm3 \n\t" /* uvbuf0[eax]*/\
- "movq "AV_STRINGIFY(VOF)"(%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\
+ "add "#uv_off", "#index" \n\t" \
+ "movq (%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\
+ "sub "#uv_off", "#index" \n\t" \
"psraw $7, %%mm3 \n\t" \
"psraw $7, %%mm4 \n\t" \
"movq (%0, "#index", 2), %%mm1 \n\t" /*buf0[eax]*/\
@@ -1471,16 +1529,18 @@ static inline void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
"psraw $7, %%mm1 \n\t" \
"psraw $7, %%mm7 \n\t" \
-#define YSCALEYUV2PACKED1(index, c) REAL_YSCALEYUV2PACKED1(index, c)
+#define YSCALEYUV2PACKED1(index, c, uv_off) REAL_YSCALEYUV2PACKED1(index, c, uv_off)
-#define REAL_YSCALEYUV2PACKED1b(index, c) \
+#define REAL_YSCALEYUV2PACKED1b(index, c, uv_off) \
"xor "#index", "#index" \n\t"\
".p2align 4 \n\t"\
"1: \n\t"\
"movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\
"movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\
- "movq "AV_STRINGIFY(VOF)"(%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
- "movq "AV_STRINGIFY(VOF)"(%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
+ "add "#uv_off", "#index" \n\t" \
+ "movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
+ "movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
+ "sub "#uv_off", "#index" \n\t" \
"paddw %%mm2, %%mm3 \n\t" /* uvbuf0[eax] + uvbuf1[eax]*/\
"paddw %%mm5, %%mm4 \n\t" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/\
"psrlw $8, %%mm3 \n\t" \
@@ -1489,14 +1549,16 @@ static inline void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,
"movq 8(%0, "#index", 2), %%mm7 \n\t" /*buf0[eax]*/\
"psraw $7, %%mm1 \n\t" \
"psraw $7, %%mm7 \n\t"
-#define YSCALEYUV2PACKED1b(index, c) REAL_YSCALEYUV2PACKED1b(index, c)
+#define YSCALEYUV2PACKED1b(index, c, uv_off) REAL_YSCALEYUV2PACKED1b(index, c, uv_off)
static inline void RENAME(yuv2yuyv422_1)(SwsContext *c, const uint16_t *buf0,
- const uint16_t *uvbuf0, const uint16_t *uvbuf1,
+ const uint16_t *ubuf0, const uint16_t *ubuf1,
+ const uint16_t *vbuf0, const uint16_t *vbuf1,
const uint16_t *abuf0, uint8_t *dest,
int dstW, int uvalpha, enum PixelFormat dstFormat,
int flags, int y)
{
+ x86_reg uv_off = c->uv_off << 1;
const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
@@ -1504,24 +1566,24 @@ static inline void RENAME(yuv2yuyv422_1)(SwsContext *c, const uint16_t *buf0,
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2PACKED1(%%REGBP, %5)
+ YSCALEYUV2PACKED1(%%REGBP, %5, %6)
WRITEYUY2(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
} else {
__asm__ volatile(
"mov %%"REG_b", "ESP_OFFSET"(%5) \n\t"
"mov %4, %%"REG_b" \n\t"
"push %%"REG_BP" \n\t"
- YSCALEYUV2PACKED1b(%%REGBP, %5)
+ YSCALEYUV2PACKED1b(%%REGBP, %5, %6)
WRITEYUY2(%%REGb, 8280(%5), %%REGBP)
"pop %%"REG_BP" \n\t"
"mov "ESP_OFFSET"(%5), %%"REG_b" \n\t"
- :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
- "a" (&c->redDither)
+ :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),
+ "a" (&c->redDither), "m"(uv_off)
);
}
}
@@ -2074,7 +2136,7 @@ static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst,
dst[i] = src[srcW-1]*128;
}
-static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst,
+static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst1, int16_t *dst2,
long dstWidth, const uint8_t *src1,
const uint8_t *src2, int srcW, int xInc)
{
@@ -2089,7 +2151,7 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst,
__asm__ volatile(
#if defined(PIC)
- "mov %%"REG_b", %6 \n\t"
+ "mov %%"REG_b", %7 \n\t"
#endif
"pxor %%mm7, %%mm7 \n\t"
"mov %0, %%"REG_c" \n\t"
@@ -2107,8 +2169,7 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst,
CALL_MMX2_FILTER_CODE
"xor %%"REG_a", %%"REG_a" \n\t" // i
"mov %5, %%"REG_c" \n\t" // src
- "mov %1, %%"REG_D" \n\t" // buf1
- "add $"AV_STRINGIFY(VOF)", %%"REG_D" \n\t"
+ "mov %6, %%"REG_D" \n\t" // buf2
PREFETCH" (%%"REG_c") \n\t"
PREFETCH" 32(%%"REG_c") \n\t"
PREFETCH" 64(%%"REG_c") \n\t"
@@ -2119,10 +2180,10 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst,
CALL_MMX2_FILTER_CODE
#if defined(PIC)
- "mov %6, %%"REG_b" \n\t"
+ "mov %7, %%"REG_b" \n\t"
#endif
- :: "m" (src1), "m" (dst), "m" (filter), "m" (filterPos),
- "m" (mmx2FilterCode), "m" (src2)
+ :: "m" (src1), "m" (dst1), "m" (filter), "m" (filterPos),
+ "m" (mmx2FilterCode), "m" (src2), "m"(dst2)
#if defined(PIC)
,"m" (ebxsave)
#endif
@@ -2133,8 +2194,8 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst,
);
for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
- dst[i] = src1[srcW-1]*128;
- dst[i+VOFW] = src2[srcW-1]*128;
+ dst1[i] = src1[srcW-1]*128;
+ dst2[i] = src2[srcW-1]*128;
}
}
#endif /* COMPILE_TEMPLATE_MMX2 */
@@ -2146,7 +2207,8 @@ static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int
const int dstH= c->dstH;
const int flags= c->flags;
int16_t **lumPixBuf= c->lumPixBuf;
- int16_t **chrPixBuf= c->chrPixBuf;
+ int16_t **chrUPixBuf= c->chrUPixBuf;
+ int16_t **chrVPixBuf= c->chrVPixBuf;
int16_t **alpPixBuf= c->alpPixBuf;
const int vLumBufSize= c->vLumBufSize;
const int vChrBufSize= c->vChrBufSize;
@@ -2171,7 +2233,8 @@ static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int
c->redDither= ff_dither8[(dstY+1)&1];
if (dstY < dstH - 2) {
const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
- const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
+ const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
+ const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
int i;
if (flags & SWS_ACCURATE_RND) {
@@ -2190,29 +2253,26 @@ static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int
}
}
for (i=0; i<vChrFilterSize; i+=2) {
- *(const void**)&chrMmxFilter[s*i ]= chrSrcPtr[i ];
- *(const void**)&chrMmxFilter[s*i+APCK_PTR2/4 ]= chrSrcPtr[i+(vChrFilterSize>1)];
+ *(const void**)&chrMmxFilter[s*i ]= chrUSrcPtr[i ];
+ *(const void**)&chrMmxFilter[s*i+APCK_PTR2/4 ]= chrUSrcPtr[i+(vChrFilterSize>1)];
chrMmxFilter[s*i+APCK_COEF/4 ]=
chrMmxFilter[s*i+APCK_COEF/4+1]= vChrFilter[chrDstY*vChrFilterSize + i ]
+ (vChrFilterSize>1 ? vChrFilter[chrDstY*vChrFilterSize + i + 1]<<16 : 0);
}
} else {
for (i=0; i<vLumFilterSize; i++) {
- lumMmxFilter[4*i+0]= (int32_t)lumSrcPtr[i];
- lumMmxFilter[4*i+1]= (uint64_t)lumSrcPtr[i] >> 32;
+ *(const void**)&lumMmxFilter[4*i+0]= lumSrcPtr[i];
lumMmxFilter[4*i+2]=
lumMmxFilter[4*i+3]=
((uint16_t)vLumFilter[dstY*vLumFilterSize + i])*0x10001;
if (CONFIG_SWSCALE_ALPHA && alpPixBuf) {
- alpMmxFilter[4*i+0]= (int32_t)alpSrcPtr[i];
- alpMmxFilter[4*i+1]= (uint64_t)alpSrcPtr[i] >> 32;
+ *(const void**)&alpMmxFilter[4*i+0]= alpSrcPtr[i];
alpMmxFilter[4*i+2]=
alpMmxFilter[4*i+3]= lumMmxFilter[4*i+2];
}
}
for (i=0; i<vChrFilterSize; i++) {
- chrMmxFilter[4*i+0]= (int32_t)chrSrcPtr[i];
- chrMmxFilter[4*i+1]= (uint64_t)chrSrcPtr[i] >> 32;
+ *(const void**)&chrMmxFilter[4*i+0]= chrUSrcPtr[i];
chrMmxFilter[4*i+2]=
chrMmxFilter[4*i+3]=
((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001;