diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2009-04-21 05:08:03 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2009-04-21 05:08:03 +0400 |
commit | de1275d5e89b1988ffffa82fb37874d1bef6d771 (patch) | |
tree | f3fd8af32081387ff730dc0c92b66b4d6f94d75d | |
parent | 6c2a860875071c609ae4a26b8ed4125e1047a5f6 (diff) |
Planar 16bit 420 422 444 YUV support (output is only supported in some
unscaled convertions).
This, like gray16 converts down to 8bit, which is a big FIXME & patch welcome,
we should preserve more bits.
Originally committed as revision 29217 to svn://svn.mplayerhq.hu/mplayer/trunk/libswscale
-rw-r--r-- | libswscale/swscale.c | 35 | ||||
-rw-r--r-- | libswscale/swscale_internal.h | 17 | ||||
-rw-r--r-- | libswscale/swscale_template.c | 79 |
3 files changed, 129 insertions, 2 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 0583cb0173..fcd809e828 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"; } @@ -2196,6 +2220,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: @@ -2214,10 +2240,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; @@ -2574,7 +2604,10 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int d || (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P) || (isPlanarYUV(srcFormat) && isGray(dstFormat)) || (isPlanarYUV(dstFormat) && isGray(srcFormat)) - || (isGray(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; diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 5c56ffe7ba..3995887f45 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -294,9 +294,15 @@ const char *sws_format_name(int format); #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 isPlanarYUV(x) ( \ +#define isPlanar8YUV(x) ( \ (x)==PIX_FMT_YUV410P \ || (x)==PIX_FMT_YUV420P \ || (x)==PIX_FMT_YUVA420P \ @@ -307,6 +313,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 a5bd2f5e46..fe68c16b3d 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)\ {\ @@ -3085,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) { @@ -3118,8 +3191,14 @@ static void RENAME(sws_init_swScale)(SwsContext *c) 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; |