mirror of
https://github.com/mpv-player/mpv
synced 2025-01-01 04:36:24 +01:00
yvu9 -> yv12 unscaled converter with linear chroma scaling
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6583 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
f3cb6e1597
commit
e02775f59a
@ -512,6 +512,19 @@ void yvu9toyv12(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc,
|
||||
#endif
|
||||
}
|
||||
|
||||
void planar2x(const uint8_t *src, uint8_t *dst, int width, int height, int srcStride, int dstStride)
|
||||
{
|
||||
#ifdef CAN_COMPILE_X86_ASM
|
||||
// ordered per speed fasterst first
|
||||
if(gCpuCaps.hasMMX2)
|
||||
planar2x_MMX2(src, dst, width, height, srcStride, dstStride);
|
||||
else if(gCpuCaps.has3DNow)
|
||||
planar2x_3DNow(src, dst, width, height, srcStride, dstStride);
|
||||
else
|
||||
#endif
|
||||
planar2x_C(src, dst, width, height, srcStride, dstStride);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* height should be a multiple of 2 and width should be a multiple of 2 (if this is a
|
||||
|
@ -41,6 +41,7 @@ extern void yuy2toyv12(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t
|
||||
extern void rgb24toyv12(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
|
||||
unsigned int width, unsigned int height,
|
||||
unsigned int lumStride, unsigned int chromStride, unsigned int srcStride);
|
||||
extern void planar2x(const uint8_t *src, uint8_t *dst, int width, int height, int srcStride, int dstStride);
|
||||
|
||||
extern void interleaveBytes(uint8_t *src1, uint8_t *src2, uint8_t *dst,
|
||||
unsigned width, unsigned height, unsigned src1Stride,
|
||||
|
@ -1295,6 +1295,95 @@ static inline void RENAME(yvu9toyv12)(const uint8_t *ysrc, const uint8_t *usrc,
|
||||
/* XXX: implement upscaling for U,V */
|
||||
}
|
||||
|
||||
static inline void RENAME(planar2x)(const uint8_t *src, uint8_t *dst, int srcWidth, int srcHeight, int srcStride, int dstStride)
|
||||
{
|
||||
int x,y;
|
||||
|
||||
// first line
|
||||
for(x=0; x<srcWidth; x++){
|
||||
dst[2*x+0]=
|
||||
dst[2*x+1]= src[x];
|
||||
}
|
||||
dst+= dstStride;
|
||||
|
||||
for(y=1; y<srcHeight; y++){
|
||||
#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
|
||||
const int mmxSize= srcWidth;
|
||||
asm volatile(
|
||||
"movl %4, %%eax \n\t"
|
||||
"1: \n\t"
|
||||
"movq (%0, %%eax), %%mm0 \n\t"
|
||||
"movq (%1, %%eax), %%mm1 \n\t"
|
||||
"movq 1(%0, %%eax), %%mm2 \n\t"
|
||||
"movq 1(%1, %%eax), %%mm3 \n\t"
|
||||
"movq %%mm0, %%mm4 \n\t"
|
||||
"movq %%mm1, %%mm5 \n\t"
|
||||
PAVGB" %%mm3, %%mm0 \n\t"
|
||||
PAVGB" %%mm3, %%mm0 \n\t"
|
||||
PAVGB" %%mm4, %%mm3 \n\t"
|
||||
PAVGB" %%mm4, %%mm3 \n\t"
|
||||
PAVGB" %%mm2, %%mm1 \n\t"
|
||||
PAVGB" %%mm2, %%mm1 \n\t"
|
||||
PAVGB" %%mm5, %%mm2 \n\t"
|
||||
PAVGB" %%mm5, %%mm2 \n\t"
|
||||
"movq %%mm3, %%mm4 \n\t"
|
||||
"movq %%mm2, %%mm5 \n\t"
|
||||
"punpcklbw %%mm1, %%mm3 \n\t"
|
||||
"punpckhbw %%mm1, %%mm4 \n\t"
|
||||
"punpcklbw %%mm0, %%mm2 \n\t"
|
||||
"punpckhbw %%mm0, %%mm5 \n\t"
|
||||
#if 1
|
||||
MOVNTQ" %%mm3, (%2, %%eax, 2) \n\t"
|
||||
MOVNTQ" %%mm4, 8(%2, %%eax, 2) \n\t"
|
||||
MOVNTQ" %%mm2, (%3, %%eax, 2) \n\t"
|
||||
MOVNTQ" %%mm5, 8(%3, %%eax, 2) \n\t"
|
||||
#else
|
||||
"movq %%mm3, (%2, %%eax, 2) \n\t"
|
||||
"movq %%mm4, 8(%2, %%eax, 2) \n\t"
|
||||
"movq %%mm2, (%3, %%eax, 2) \n\t"
|
||||
"movq %%mm5, 8(%3, %%eax, 2) \n\t"
|
||||
#endif
|
||||
"addl $8, %%eax \n\t"
|
||||
" js 1b \n\t"
|
||||
:: "r" (src + mmxSize-1), "r" (src + srcStride + mmxSize-1),
|
||||
"r" (dst + mmxSize*2), "r" (dst + dstStride + mmxSize*2),
|
||||
"g" (-mmxSize)
|
||||
: "%eax"
|
||||
|
||||
);
|
||||
dst[0]=
|
||||
dst[dstStride]= src[0];
|
||||
#else
|
||||
dst[0]=
|
||||
dst[dstStride]= src[0];
|
||||
|
||||
for(x=0; x<srcWidth-1; x++){
|
||||
dst[2*x +1]= (3*src[x+0] + src[x+srcStride+1])>>2;
|
||||
dst[2*x+dstStride+2]= ( src[x+0] + 3*src[x+srcStride+1])>>2;
|
||||
dst[2*x+dstStride+1]= ( src[x+1] + 3*src[x+srcStride ])>>2;
|
||||
dst[2*x +2]= (3*src[x+1] + src[x+srcStride ])>>2;
|
||||
}
|
||||
#endif
|
||||
dst[srcWidth*2 -1]=
|
||||
dst[srcWidth*2 -1 + dstStride]= src[srcWidth-1];
|
||||
|
||||
dst+=dstStride*2;
|
||||
src+=srcStride;
|
||||
}
|
||||
src-=srcStride;
|
||||
|
||||
// last line
|
||||
for(x=0; x<srcWidth; x++){
|
||||
dst[2*x+0]=
|
||||
dst[2*x+1]= src[x];
|
||||
}
|
||||
#ifdef HAVE_MMX
|
||||
asm volatile( EMMS" \n\t"
|
||||
SFENCE" \n\t"
|
||||
:::"memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* height should be a multiple of 2 and width should be a multiple of 16 (if this is a
|
||||
|
@ -1777,6 +1777,34 @@ static void bgr24toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], i
|
||||
dstStride[0], dstStride[1], srcStride[0]);
|
||||
}
|
||||
|
||||
static void yvu9toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
|
||||
int srcSliceH, uint8_t* dst[], int dstStride[]){
|
||||
int i;
|
||||
|
||||
/* copy Y */
|
||||
if(srcStride[0]==dstStride[0])
|
||||
memcpy(dst[0]+ srcSliceY*dstStride[0], src[0], srcStride[0]*srcSliceH);
|
||||
else{
|
||||
uint8_t *srcPtr= src[0];
|
||||
uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
|
||||
|
||||
for(i=0; i<srcSliceH; i++)
|
||||
{
|
||||
memcpy(dstPtr, srcPtr, c->srcW);
|
||||
srcPtr+= srcStride[0];
|
||||
dstPtr+= dstStride[0];
|
||||
}
|
||||
}
|
||||
|
||||
if(c->dstFormat==IMGFMT_YV12){
|
||||
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{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* bring pointers in YUV order instead of YVU
|
||||
*/
|
||||
@ -2051,7 +2079,7 @@ SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH,
|
||||
vo_format_name(srcFormat), vo_format_name(dstFormat));
|
||||
return c;
|
||||
}
|
||||
#if 1
|
||||
|
||||
/* simple copy */
|
||||
if( srcFormat == dstFormat
|
||||
|| (srcFormat==IMGFMT_YV12 && dstFormat==IMGFMT_I420)
|
||||
@ -2067,7 +2095,17 @@ SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH,
|
||||
vo_format_name(srcFormat), vo_format_name(dstFormat));
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( srcFormat==IMGFMT_YVU9 && (dstFormat==IMGFMT_YV12 || dstFormat==IMGFMT_I420) )
|
||||
{
|
||||
c->swScale= yvu9toyv12Wrapper;
|
||||
|
||||
if(flags&SWS_PRINT_INFO)
|
||||
MSG_INFO("SwScaler: using unscaled %s -> %s special converter\n",
|
||||
vo_format_name(srcFormat), vo_format_name(dstFormat));
|
||||
return c;
|
||||
}
|
||||
|
||||
/* bgr32to24 & rgb32to24*/
|
||||
if((srcFormat==IMGFMT_BGR32 && dstFormat==IMGFMT_BGR24)
|
||||
||(srcFormat==IMGFMT_RGB32 && dstFormat==IMGFMT_RGB24))
|
||||
|
Loading…
Reference in New Issue
Block a user