summaryrefslogtreecommitdiff
path: root/libswscale
diff options
context:
space:
mode:
authorOskar Arvidsson <oskar@irock.se>2011-03-29 17:48:47 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-04-10 22:33:41 +0200
commitd4497f6dfb8dddf25b7be441f16d387aa18a65d6 (patch)
treea688c802bf50f533e5c66798c2aecc247c0e3a20 /libswscale
parentaf0b2d6736a99203fed3014a3e83f8226dade2af (diff)
Add pixel formats for 9- and 10-bit yuv420p.
Also add support for these formats in libswscale. Needed for high bit depth h264 decoding. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libswscale')
-rw-r--r--libswscale/swscale.c23
-rw-r--r--libswscale/swscale_internal.h10
-rw-r--r--libswscale/swscale_template.c27
-rw-r--r--libswscale/utils.c2
4 files changed, 61 insertions, 1 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index e0e48088fc..7047bb80f4 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -1747,7 +1747,28 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[
length*=2;
fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128);
} else {
- if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
+ if(isNBPS(c->srcFormat)) {
+ const int depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1;
+ uint16_t *srcPtr2 = (uint16_t*)srcPtr;
+
+ if (is16BPS(c->dstFormat)) {
+ uint16_t *dstPtr2 = (uint16_t*)dstPtr;
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < length; j++)
+ dstPtr2[j] = (srcPtr2[j]<<(16-depth)) | (srcPtr2[j]>>(2*depth-16));
+ dstPtr2 += dstStride[plane]/2;
+ srcPtr2 += srcStride[plane]/2;
+ }
+ } else {
+ // FIXME Maybe dither instead.
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < length; j++)
+ dstPtr[j] = srcPtr2[j]>>(depth-8);
+ dstPtr += dstStride[plane];
+ srcPtr2 += srcStride[plane]/2;
+ }
+ }
+ } else 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];
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 16c23d2740..6604cae67d 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -352,6 +352,12 @@ const char *sws_format_name(enum PixelFormat format);
|| (x)==PIX_FMT_YUV422P16BE \
|| (x)==PIX_FMT_YUV444P16BE \
)
+#define isNBPS(x) ( \
+ (x)==PIX_FMT_YUV420P9LE \
+ || (x)==PIX_FMT_YUV420P9BE \
+ || (x)==PIX_FMT_YUV420P10LE \
+ || (x)==PIX_FMT_YUV420P10BE \
+ )
#define isBE(x) ((x)&1)
#define isPlanar8YUV(x) ( \
(x)==PIX_FMT_YUV410P \
@@ -366,9 +372,13 @@ const char *sws_format_name(enum PixelFormat format);
)
#define isPlanarYUV(x) ( \
isPlanar8YUV(x) \
+ || (x)==PIX_FMT_YUV420P9LE \
+ || (x)==PIX_FMT_YUV420P10LE \
|| (x)==PIX_FMT_YUV420P16LE \
|| (x)==PIX_FMT_YUV422P16LE \
|| (x)==PIX_FMT_YUV444P16LE \
+ || (x)==PIX_FMT_YUV420P9BE \
+ || (x)==PIX_FMT_YUV420P10BE \
|| (x)==PIX_FMT_YUV420P16BE \
|| (x)==PIX_FMT_YUV422P16BE \
|| (x)==PIX_FMT_YUV444P16BE \
diff --git a/libswscale/swscale_template.c b/libswscale/swscale_template.c
index 0ee5181e2e..d616036646 100644
--- a/libswscale/swscale_template.c
+++ b/libswscale/swscale_template.c
@@ -1826,6 +1826,29 @@ static inline void RENAME(nv21ToUV)(uint8_t *dstU, uint8_t *dstV,
RENAME(nvXXtoUV)(dstV, dstU, src1, width);
}
+// FIXME Maybe dither instead.
+#define YUV_NBPS(depth) \
+static inline void RENAME(yuv ## depth ## ToUV)(uint8_t *dstU, uint8_t *dstV, \
+ const uint16_t *srcU, const uint16_t *srcV, \
+ long width, uint32_t *unused) \
+{ \
+ int i; \
+ for (i = 0; i < width; i++) { \
+ dstU[i] = srcU[i]>>(depth-8); \
+ dstV[i] = srcV[i]>>(depth-8); \
+ } \
+} \
+\
+static inline void RENAME(yuv ## depth ## ToY)(uint8_t *dstY, const uint16_t *srcY, long width, uint32_t *unused) \
+{ \
+ int i; \
+ for (i = 0; i < width; i++) \
+ dstY[i] = srcY[i]>>(depth-8); \
+} \
+
+YUV_NBPS( 9)
+YUV_NBPS(10)
+
#if COMPILE_TEMPLATE_MMX
static inline void RENAME(bgr24ToY_mmx)(uint8_t *dst, const uint8_t *src, long width, enum PixelFormat srcFormat)
{
@@ -2955,6 +2978,8 @@ static void RENAME(sws_init_swScale)(SwsContext *c)
case PIX_FMT_PAL8 :
case PIX_FMT_BGR4_BYTE:
case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV; break;
+ case PIX_FMT_YUV420P9 : c->chrToYV12 = (void*)RENAME(yuv9ToUV ); break;
+ case PIX_FMT_YUV420P10: c->chrToYV12 = (void*)RENAME(yuv10ToUV); break;
case PIX_FMT_YUV420P16BE:
case PIX_FMT_YUV422P16BE:
case PIX_FMT_YUV444P16BE: c->chrToYV12 = RENAME(BEToUV); break;
@@ -3001,6 +3026,8 @@ static void RENAME(sws_init_swScale)(SwsContext *c)
c->lumToYV12 = NULL;
c->alpToYV12 = NULL;
switch (srcFormat) {
+ case PIX_FMT_YUV420P9 : c->lumToYV12 = (void*)RENAME(yuv9ToY ); break;
+ case PIX_FMT_YUV420P10: c->lumToYV12 = (void*)RENAME(yuv10ToY); break;
case PIX_FMT_YUYV422 :
case PIX_FMT_YUV420P16BE:
case PIX_FMT_YUV422P16BE:
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 9accfdadd0..a343bf2570 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -112,6 +112,8 @@ const char *swscale_license(void)
|| (x)==PIX_FMT_YUV420P16BE \
|| (x)==PIX_FMT_YUV422P16BE \
|| (x)==PIX_FMT_YUV444P16BE \
+ || (x)==PIX_FMT_YUV420P9 \
+ || (x)==PIX_FMT_YUV420P10 \
)
int sws_isSupportedInput(enum PixelFormat pix_fmt)