diff options
author | Luca Barbato <lu_zero@gentoo.org> | 2012-10-29 19:07:01 +0100 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2012-10-30 12:02:41 +0100 |
commit | 26b5ad2543305f0b148e5b91e9773b6a9a185922 (patch) | |
tree | c045719e016118a600ee6c0b6fa77d6b2e608b92 | |
parent | f454e879238ce317c6d905d187e7608c461a7087 (diff) | |
download | ffmpeg-26b5ad2543305f0b148e5b91e9773b6a9a185922.tar.gz |
swscale: support gray to 9bit and 10bit formats
With the input of Kostya and Ronald.
-rw-r--r-- | libswscale/swscale.c | 38 | ||||
-rw-r--r-- | libswscale/swscale_unscaled.c | 32 |
2 files changed, 66 insertions, 4 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 3f54e4dc55..c1920de0a6 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -61,6 +61,28 @@ static av_always_inline void fillPlane(uint8_t *plane, int stride, int width, } } +static void fill_plane9or10(uint8_t *plane, int stride, int width, + int height, int y, uint8_t val, + const int dst_depth, const int big_endian) +{ + int i, j; + uint16_t *dst = (uint16_t *) (plane + stride * y); +#define FILL8TO9_OR_10(wfunc) \ + for (i = 0; i < height; i++) { \ + for (j = 0; j < width; j++) { \ + wfunc(&dst[j], (val << (dst_depth - 8)) | \ + (val >> (16 - dst_depth))); \ + } \ + dst += stride / 2; \ + } + if (big_endian) { + FILL8TO9_OR_10(AV_WB16); + } else { + FILL8TO9_OR_10(AV_WL16); + } +} + + static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize) @@ -658,8 +680,20 @@ static int swScale(SwsContext *c, const uint8_t *src[], } } - if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) - fillPlane(dst[3], dstStride[3], dstW, dstY - lastDstY, lastDstY, 255); + if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) { + int length = dstW; + int height = dstY - lastDstY; + if (is16BPS(c->dstFormat)) + length *= 2; + + if (is9_OR_10BPS(dstFormat)) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat); + fill_plane9or10(dst[3], dstStride[3], length, height, lastDstY, + 255, desc->comp[3].depth_minus1 + 1, + isBE(dstFormat)); + } else + fillPlane(dst[3], dstStride[3], length, height, lastDstY, 255); + } #if HAVE_MMXEXT_INLINE if (av_get_cpu_flags() & AV_CPU_FLAG_MMXEXT) diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 5efc647b08..9b919f8aa4 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -98,6 +98,27 @@ static void fillPlane(uint8_t *plane, int stride, int width, int height, int y, } } +static void fill_plane9or10(uint8_t *plane, int stride, int width, + int height, int y, uint8_t val, + const int dst_depth, const int big_endian) +{ + int i, j; + uint16_t *dst = (uint16_t *) (plane + stride * y); +#define FILL8TO9_OR_10(wfunc) \ + for (i = 0; i < height; i++) { \ + for (j = 0; j < width; j++) { \ + wfunc(&dst[j], (val << (dst_depth - 8)) | \ + (val >> (16 - dst_depth))); \ + } \ + dst += stride / 2; \ + } + if (big_endian) { + FILL8TO9_OR_10(AV_WB16); + } else { + FILL8TO9_OR_10(AV_WL16); + } +} + static void copyPlane(const uint8_t *src, int srcStride, int srcSliceY, int srcSliceH, int width, uint8_t *dst, int dstStride) @@ -677,10 +698,17 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], // ignore palette for GRAY8 if (plane == 1 && !dst[2]) continue; if (!src[plane] || (plane == 1 && !src[2])) { + int val = (plane == 3) ? 255 : 128; if (is16BPS(c->dstFormat)) length *= 2; - fillPlane(dst[plane], dstStride[plane], length, height, y, - (plane == 3) ? 255 : 128); + if (is9_OR_10BPS(c->dstFormat)) { + fill_plane9or10(dst[plane], dstStride[plane], + length, height, y, val, + desc_dst->comp[plane].depth_minus1 + 1, + isBE(c->dstFormat)); + } else + fillPlane(dst[plane], dstStride[plane], length, height, y, + val); } else { if (is9_OR_10BPS(c->srcFormat)) { const int src_depth = desc_src->comp[plane].depth_minus1 + 1; |