Commit b4a224c5 authored by Ronald S. Bultje's avatar Ronald S. Bultje
Browse files

swscale: split chroma buffers into separate U/V planes.

Preparatory step to implement support for sizes > VOFW.
parent 69645c02
......@@ -207,7 +207,8 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
#endif
static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest,
int dstW, int chrDstW, int big_endian, int output_bits)
{
......@@ -246,8 +247,8 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
int j;
for (j = 0; j < chrFilterSize; j++) {
u += chrSrc[j][i ] * chrFilter[j];
v += chrSrc[j][i + VOFW] * chrFilter[j];
u += chrUSrc[j][i] * chrFilter[j];
v += chrVSrc[j][i] * chrFilter[j];
}
output_pixel(&uDest[i], u);
......@@ -271,13 +272,14 @@ static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, co
#define yuv2NBPS(bits, BE_LE, is_be) \
static void yuv2yuvX ## bits ## BE_LE ## _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, \
uint16_t *dest, uint16_t *uDest, uint16_t *vDest, \
uint16_t *aDest, int dstW, int chrDstW) \
{ \
yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize, \
chrFilter, chrSrc, chrFilterSize, \
chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
alpSrc, \
dest, uDest, vDest, aDest, \
dstW, chrDstW, is_be, bits); \
......@@ -290,20 +292,20 @@ yuv2NBPS(16, BE, 1);
yuv2NBPS(16, LE, 0);
static inline void yuv2yuvX16inC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest, int dstW, int chrDstW,
enum PixelFormat dstFormat)
{
#define conv16(bits) \
if (isBE(dstFormat)) { \
yuv2yuvX ## bits ## BE_c(lumFilter, lumSrc, lumFilterSize, \
chrFilter, chrSrc, chrFilterSize, \
chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
alpSrc, \
dest, uDest, vDest, aDest, \
dstW, chrDstW); \
} else { \
yuv2yuvX ## bits ## LE_c(lumFilter, lumSrc, lumFilterSize, \
chrFilter, chrSrc, chrFilterSize, \
chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
alpSrc, \
dest, uDest, vDest, aDest, \
dstW, chrDstW); \
......@@ -319,7 +321,8 @@ static inline void yuv2yuvX16inC(const int16_t *lumFilter, const int16_t **lumSr
}
static inline void yuv2yuvXinC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
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, int dstW, int chrDstW)
{
//FIXME Optimize (just quickly written not optimized..)
......@@ -339,8 +342,8 @@ static inline void yuv2yuvXinC(const int16_t *lumFilter, const int16_t **lumSrc,
int v=1<<18;
int j;
for (j=0; j<chrFilterSize; j++) {
u += chrSrc[j][i] * chrFilter[j];
v += chrSrc[j][i + VOFW] * chrFilter[j];
u += chrUSrc[j][i] * chrFilter[j];
v += chrVSrc[j][i] * chrFilter[j];
}
uDest[i]= av_clip_uint8(u>>19);
......@@ -360,7 +363,8 @@ static inline void yuv2yuvXinC(const int16_t *lumFilter, const int16_t **lumSrc,
}
static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
{
//FIXME Optimize (just quickly written not optimized..)
......@@ -383,8 +387,8 @@ static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc
int v=1<<18;
int j;
for (j=0; j<chrFilterSize; j++) {
u += chrSrc[j][i] * chrFilter[j];
v += chrSrc[j][i + VOFW] * chrFilter[j];
u += chrUSrc[j][i] * chrFilter[j];
v += chrVSrc[j][i] * chrFilter[j];
}
uDest[2*i]= av_clip_uint8(u>>19);
......@@ -396,8 +400,8 @@ static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc
int v=1<<18;
int j;
for (j=0; j<chrFilterSize; j++) {
u += chrSrc[j][i] * chrFilter[j];
v += chrSrc[j][i + VOFW] * chrFilter[j];
u += chrUSrc[j][i] * chrFilter[j];
v += chrVSrc[j][i] * chrFilter[j];
}
uDest[2*i]= av_clip_uint8(v>>19);
......@@ -421,8 +425,8 @@ static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc
Y2 += lumSrc[j][i2+1] * lumFilter[j];\
}\
for (j=0; j<chrFilterSize; j++) {\
U += chrSrc[j][i] * chrFilter[j];\
V += chrSrc[j][i+VOFW] * chrFilter[j];\
U += chrUSrc[j][i] * chrFilter[j];\
V += chrVSrc[j][i] * chrFilter[j];\
}\
Y1>>=19;\
Y2>>=19;\
......@@ -469,8 +473,8 @@ static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc
Y += lumSrc[j][i ] * lumFilter[j];\
}\
for (j=0; j<chrFilterSize; j++) {\
U += chrSrc[j][i ] * chrFilter[j];\
V += chrSrc[j][i+VOFW] * chrFilter[j];\
U += chrUSrc[j][i] * chrFilter[j];\
V += chrVSrc[j][i] * chrFilter[j];\
}\
Y >>=10;\
U >>=10;\
......@@ -535,8 +539,8 @@ static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc
const int i2= 2*i; \
int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19; \
int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19; \
int U= (uvbuf0[i ]*uvalpha1+uvbuf1[i ]*uvalpha)>>19; \
int V= (uvbuf0[i+VOFW]*uvalpha1+uvbuf1[i+VOFW]*uvalpha)>>19; \
int U= (ubuf0[i]*uvalpha1+ubuf1[i]*uvalpha)>>19; \
int V= (vbuf0[i]*uvalpha1+vbuf1[i]*uvalpha)>>19; \
type av_unused *r, *b, *g; \
int av_unused A1, A2; \
if (alpha) {\
......@@ -561,8 +565,8 @@ static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc
const int i2= 2*i;\
int Y1= buf0[i2 ]>>7;\
int Y2= buf0[i2+1]>>7;\
int U= (uvbuf1[i ])>>7;\
int V= (uvbuf1[i+VOFW])>>7;\
int U= (ubuf1[i])>>7;\
int V= (vbuf1[i])>>7;\
type av_unused *r, *b, *g;\
int av_unused A1, A2;\
if (alpha) {\
......@@ -587,8 +591,8 @@ static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc
const int i2= 2*i;\
int Y1= buf0[i2 ]>>7;\
int Y2= buf0[i2+1]>>7;\
int U= (uvbuf0[i ] + uvbuf1[i ])>>8;\
int V= (uvbuf0[i+VOFW] + uvbuf1[i+VOFW])>>8;\
int U= (ubuf0[i] + ubuf1[i])>>8;\
int V= (vbuf0[i] + vbuf1[i])>>8;\
type av_unused *r, *b, *g;\
int av_unused A1, A2;\
if (alpha) {\
......@@ -870,16 +874,20 @@ static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc
break;\
}
static inline void yuv2packedXinC(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
static inline void yuv2packedXinC(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
{
int i;
YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C, YSCALE_YUV_2_PACKEDX_C(void,0), YSCALE_YUV_2_GRAY16_C, YSCALE_YUV_2_MONOX_C)
}
static inline void yuv2rgbXinC_full(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
static inline void yuv2rgbXinC_full(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
{
int i;
......
......@@ -112,7 +112,8 @@ typedef struct SwsContext {
*/
//@{
int16_t **lumPixBuf; ///< Ring buffer for scaled horizontal luma plane lines to be fed to the vertical scaler.
int16_t **chrPixBuf; ///< Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.
int16_t **chrUPixBuf; ///< Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.
int16_t **chrVPixBuf; ///< Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.
int16_t **alpPixBuf; ///< Ring buffer for scaled horizontal alpha plane lines to be fed to the vertical scaler.
int vLumBufSize; ///< Number of vertical luma/alpha lines allocated in the ring buffer.
int vChrBufSize; ///< Number of vertical chroma lines allocated in the ring buffer.
......@@ -200,6 +201,7 @@ typedef struct SwsContext {
#define V_TEMP "11*8+4*4*256*2+32"
#define Y_TEMP "11*8+4*4*256*2+40"
#define ALP_MMX_FILTER_OFFSET "11*8+4*4*256*2+48"
#define UV_OFF "11*8+4*4*256*3+48"
DECLARE_ALIGNED(8, uint64_t, redDither);
DECLARE_ALIGNED(8, uint64_t, greenDither);
......@@ -222,6 +224,7 @@ typedef struct SwsContext {
DECLARE_ALIGNED(8, uint64_t, v_temp);
DECLARE_ALIGNED(8, uint64_t, y_temp);
int32_t alpMmxFilter[4*MAX_FILTER_SIZE];
DECLARE_ALIGNED(8, ptrdiff_t, uv_off); ///< offset (in pixels) between u and v planes
#if HAVE_ALTIVEC
vector signed short CY;
......@@ -255,36 +258,42 @@ typedef struct SwsContext {
/* function pointers for swScale() */
void (*yuv2nv12X )(struct SwsContext *c,
const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
uint8_t *dest, uint8_t *uDest,
int dstW, int chrDstW, int dstFormat);
void (*yuv2yuv1 )(struct SwsContext *c,
const int16_t *lumSrc, const int16_t *chrSrc, const int16_t *alpSrc,
const int16_t *lumSrc, 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);
void (*yuv2yuvX )(struct SwsContext *c,
const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
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);
void (*yuv2packed1)(struct 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, int dstFormat, int flags, int y);
void (*yuv2packed2)(struct SwsContext *c,
const uint16_t *buf0, const uint16_t *buf1,
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, const uint16_t *abuf1,
uint8_t *dest,
int dstW, int yalpha, int uvalpha, int y);
void (*yuv2packedX)(struct SwsContext *c,
const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
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);
......@@ -299,7 +308,7 @@ typedef struct SwsContext {
int16_t *dst, long dstWidth,
const uint8_t *src, int srcW, int xInc);
void (*hcscale_fast)(struct SwsContext *c,
int16_t *dst, long dstWidth,
int16_t *dst1, int16_t *dst2, long dstWidth,
const uint8_t *src1, const uint8_t *src2,
int srcW, int xInc);
......@@ -308,7 +317,7 @@ typedef struct SwsContext {
long filterSize);
void (*lumConvertRange)(uint16_t *dst, int width); ///< Color range conversion function for luma plane if needed.
void (*chrConvertRange)(uint16_t *dst, int width); ///< Color range conversion function for chroma planes if needed.
void (*chrConvertRange)(uint16_t *dst1, uint16_t *dst2, int width); ///< Color range conversion function for chroma planes if needed.
int lumSrcOffset; ///< Offset given to luma src pointers passed to horizontal input functions.
int chrSrcOffset; ///< Offset given to chroma src pointers passed to horizontal input functions.
......
This diff is collapsed.
......@@ -989,7 +989,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
// allocate pixbufs (we use dynamic allocation because otherwise we would need to
// allocate several megabytes to handle all possible cases)
FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize*2*sizeof(int16_t*), fail);
FF_ALLOC_OR_GOTO(c, c->chrPixBuf, c->vChrBufSize*2*sizeof(int16_t*), fail);
FF_ALLOC_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize*2*sizeof(int16_t*), fail);
FF_ALLOC_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize*2*sizeof(int16_t*), fail);
if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat))
FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize*2*sizeof(int16_t*), fail);
//Note we need at least one pixel more at the end because of the MMX code (just in case someone wanna replace the 4000/8000)
......@@ -998,9 +999,11 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf[i+c->vLumBufSize], VOF+1, fail);
c->lumPixBuf[i] = c->lumPixBuf[i+c->vLumBufSize];
}
c->uv_off = VOFW;
for (i=0; i<c->vChrBufSize; i++) {
FF_ALLOC_OR_GOTO(c, c->chrPixBuf[i+c->vChrBufSize], (VOF+1)*2, fail);
c->chrPixBuf[i] = c->chrPixBuf[i+c->vChrBufSize];
FF_ALLOC_OR_GOTO(c, c->chrUPixBuf[i+c->vChrBufSize], VOF*2+1, fail);
c->chrUPixBuf[i] = c->chrUPixBuf[i+c->vChrBufSize];
c->chrVPixBuf[i] = c->chrVPixBuf[i+c->vChrBufSize] = c->chrUPixBuf[i] + VOFW;
}
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
for (i=0; i<c->vLumBufSize; i++) {
......@@ -1009,7 +1012,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
}
//try to avoid drawing green stuff between the right end and the stride end
for (i=0; i<c->vChrBufSize; i++) memset(c->chrPixBuf[i], 64, (VOF+1)*2);
for (i=0; i<c->vChrBufSize; i++)
memset(c->chrUPixBuf[i], 64, VOF*2+1);
assert(2*VOFW == VOF);
......@@ -1462,10 +1466,11 @@ void sws_freeContext(SwsContext *c)
av_freep(&c->lumPixBuf);
}
if (c->chrPixBuf) {
if (c->chrUPixBuf) {
for (i=0; i<c->vChrBufSize; i++)
av_freep(&c->chrPixBuf[i]);
av_freep(&c->chrPixBuf);
av_freep(&c->chrUPixBuf[i]);
av_freep(&c->chrUPixBuf);
av_freep(&c->chrVPixBuf);
}
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment