diff options
author | Oskar Arvidsson <oskar@irock.se> | 2011-03-29 17:48:47 +0200 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2011-05-10 07:24:19 -0400 |
commit | 42239ced656ddddb85eb9655e8a66d29065f0dad (patch) | |
tree | d90980a25e0338c70b9b1c22ffe9edbb21c1cb26 /libswscale | |
parent | e39e3abad4ce667f06d41097428695a7aad095fb (diff) | |
download | ffmpeg-42239ced656ddddb85eb9655e8a66d29065f0dad.tar.gz |
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: Ronald S. Bultje <rsbultje@gmail.com>
Diffstat (limited to 'libswscale')
-rw-r--r-- | libswscale/swscale.c | 23 | ||||
-rw-r--r-- | libswscale/swscale_internal.h | 10 | ||||
-rw-r--r-- | libswscale/swscale_template.c | 34 | ||||
-rw-r--r-- | libswscale/utils.c | 4 |
4 files changed, 70 insertions, 1 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 93c6a13b9d..2830f26ce5 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1669,7 +1669,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 292e42fa0d..2d40215ea9 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -354,6 +354,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 \ @@ -368,9 +374,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 234e61871b..81a8d66277 100644 --- a/libswscale/swscale_template.c +++ b/libswscale/swscale_template.c @@ -225,6 +225,32 @@ static inline void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV, nvXXtoUV_c(dstV, dstU, src1, width); } +// FIXME Maybe dither instead. +#define YUV_NBPS(depth) \ +static inline void yuv ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \ + const uint8_t *_srcU, const uint8_t *_srcV, \ + long width, uint32_t *unused) \ +{ \ + int i; \ + const uint16_t *srcU = (const uint16_t*)_srcU; \ + const uint16_t *srcV = (const uint16_t*)_srcV; \ + for (i = 0; i < width; i++) { \ + dstU[i] = srcU[i]>>(depth-8); \ + dstV[i] = srcV[i]>>(depth-8); \ + } \ +} \ +\ +static inline void yuv ## depth ## ToY_c(uint8_t *dstY, const uint8_t *_srcY, long width, uint32_t *unused) \ +{ \ + int i; \ + const uint16_t *srcY = (const uint16_t*)_srcY; \ + for (i = 0; i < width; i++) \ + dstY[i] = srcY[i]>>(depth-8); \ +} \ + +YUV_NBPS( 9) +YUV_NBPS(10) + static inline void bgr24ToY_c(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused) { @@ -790,6 +816,10 @@ static void sws_init_swScale_c(SwsContext *c) case PIX_FMT_PAL8 : case PIX_FMT_BGR4_BYTE: case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV; break; + case PIX_FMT_YUV420P9BE: + case PIX_FMT_YUV420P9LE: c->chrToYV12 = yuv9ToUV_c; break; + case PIX_FMT_YUV420P10BE: + case PIX_FMT_YUV420P10LE: c->chrToYV12 = yuv10ToUV_c; break; case PIX_FMT_YUV420P16BE: case PIX_FMT_YUV422P16BE: case PIX_FMT_YUV444P16BE: c->chrToYV12 = BEToUV_c; break; @@ -836,6 +866,10 @@ static void sws_init_swScale_c(SwsContext *c) c->lumToYV12 = NULL; c->alpToYV12 = NULL; switch (srcFormat) { + case PIX_FMT_YUV420P9BE: + case PIX_FMT_YUV420P9LE: c->lumToYV12 = yuv9ToY_c; break; + case PIX_FMT_YUV420P10BE: + case PIX_FMT_YUV420P10LE: c->lumToYV12 = yuv10ToY_c; break; case PIX_FMT_YUYV422 : case PIX_FMT_YUV420P16BE: case PIX_FMT_YUV422P16BE: diff --git a/libswscale/utils.c b/libswscale/utils.c index 5f5eb322bf..4f9f269731 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -106,9 +106,13 @@ const char *swscale_license(void) || (x)==PIX_FMT_YUV440P \ || (x)==PIX_FMT_MONOWHITE \ || (x)==PIX_FMT_MONOBLACK \ + || (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 \ |