diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c index 199afe989b..00e785f0c8 100644 --- a/libswscale/rgb2rgb.c +++ b/libswscale/rgb2rgb.c @@ -425,3 +425,61 @@ void rgb48to64_ ## need_bswap(const uint8_t *src, \ DEFINE_RGB48TO64(nobswap, 0) DEFINE_RGB48TO64(bswap, 1) + +#define DEFINE_X2RGB10TO16(need_bswap, swap, bits, alpha) \ +void x2rgb10to ## bits ## _ ## need_bswap(const uint8_t *src, \ + uint8_t *dst, int src_size) \ +{ \ + uint16_t *d = (uint16_t *)dst; \ + const uint32_t *s = (const uint32_t *)src; \ + int i, num_pixels = src_size >> 2; \ + unsigned component; \ + \ + for (i = 0; i < num_pixels; i++) { \ + unsigned p = AV_RL32(s + i); \ + component = (p >> 20) & 0x3FF; \ + d[(3 + alpha) * i + 0] = swap ? av_bswap16(component << 6 | component >> 4) \ + : component << 6 | component >> 4; \ + component = (p >> 10) & 0x3FF; \ + d[(3 + alpha) * i + 1] = swap ? av_bswap16(component << 6 | component >> 4) \ + : component << 6 | component >> 4; \ + component = p & 0x3FF; \ + d[(3 + alpha) * i + 2] = swap ? av_bswap16(component << 6 | component >> 4) \ + : component << 6 | component >> 4; \ + if (alpha) d[(3 + alpha) * i + 3] = 0xffff; \ + } \ +} + +DEFINE_X2RGB10TO16(nobswap, 0, 48, 0) +DEFINE_X2RGB10TO16(bswap, 1, 48, 0) +DEFINE_X2RGB10TO16(nobswap, 0, 64, 1) +DEFINE_X2RGB10TO16(bswap, 1, 64, 1) + +#define DEFINE_X2RGB10TOBGR16(need_bswap, swap, bits, alpha) \ +void x2rgb10tobgr ## bits ## _ ## need_bswap(const uint8_t *src, \ + uint8_t *dst, int src_size) \ +{ \ + uint16_t *d = (uint16_t *)dst; \ + const uint32_t *s = (const uint32_t *)src; \ + int i, num_pixels = src_size >> 2; \ + unsigned component; \ + \ + for (i = 0; i < num_pixels; i++) { \ + unsigned p = AV_RL32(s + i); \ + component = p & 0x3FF; \ + d[(3 + alpha) * i + 0] = swap ? av_bswap16(component << 6 | component >> 4) \ + : component << 6 | component >> 4; \ + component = (p >> 10) & 0x3FF; \ + d[(3 + alpha) * i + 1] = swap ? av_bswap16(component << 6 | component >> 4) \ + : component << 6 | component >> 4; \ + component = (p >> 20) & 0x3FF; \ + d[(3 + alpha) * i + 2] = swap ? av_bswap16(component << 6 | component >> 4) \ + : component << 6 | component >> 4; \ + if (alpha) d[(3 + alpha) * i + 3] = 0xffff; \ + } \ +} + +DEFINE_X2RGB10TOBGR16(nobswap, 0, 48, 0) +DEFINE_X2RGB10TOBGR16(bswap, 1, 48, 0) +DEFINE_X2RGB10TOBGR16(nobswap, 0, 64, 1) +DEFINE_X2RGB10TOBGR16(bswap, 1, 64, 1) diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h index c988e65256..0d0f7c3a28 100644 --- a/libswscale/rgb2rgb.h +++ b/libswscale/rgb2rgb.h @@ -80,6 +80,15 @@ void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size); void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size); void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size); +void x2rgb10to48_nobswap(const uint8_t *src, uint8_t *dst, int src_size); +void x2rgb10to48_bswap(const uint8_t *src, uint8_t *dst, int src_size); +void x2rgb10tobgr48_nobswap(const uint8_t *src, uint8_t *dst, int src_size); +void x2rgb10tobgr48_bswap(const uint8_t *src, uint8_t *dst, int src_size); +void x2rgb10to64_nobswap(const uint8_t *src, uint8_t *dst, int src_size); +void x2rgb10to64_bswap(const uint8_t *src, uint8_t *dst, int src_size); +void x2rgb10tobgr64_nobswap(const uint8_t *src, uint8_t *dst, int src_size); +void x2rgb10tobgr64_bswap(const uint8_t *src, uint8_t *dst, int src_size); + void ff_rgb24toyv12_c(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, int width, int height, int lumStride, int chromStride, int srcStride, const int32_t *rgb2yuv); diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 7fa513dc1e..174e131675 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1742,6 +1742,11 @@ static int bayer_to_yv12_wrapper(SwsInternal *c, const uint8_t *const src[], || (x) == AV_PIX_FMT_UYVA \ ) +#define isX2RGB(x) ( \ + (x) == AV_PIX_FMT_X2RGB10LE \ + || (x) == AV_PIX_FMT_X2BGR10LE \ + ) + /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int); static rgbConvFn findRgbConvFn(SwsInternal *c) @@ -1814,6 +1819,31 @@ static rgbConvFn findRgbConvFn(SwsInternal *c) || CONV_IS(BGRA64LE, BGR48BE) || CONV_IS(RGBA64BE, RGB48LE) || CONV_IS(BGRA64BE, BGR48LE)) conv = rgb64to48_bswap; + } else if (isX2RGB(srcFormat) && isRGB48(dstFormat)) { + if (CONV_IS(X2RGB10LE, RGB48LE) + || CONV_IS(X2BGR10LE, BGR48LE)) conv = HAVE_BIGENDIAN ? x2rgb10to48_bswap + : x2rgb10to48_nobswap; + else if (CONV_IS(X2RGB10LE, RGB48BE) + || CONV_IS(X2BGR10LE, BGR48BE)) conv = HAVE_BIGENDIAN ? x2rgb10to48_nobswap + : x2rgb10to48_bswap; + else if (CONV_IS(X2RGB10LE, BGR48LE) + || CONV_IS(X2BGR10LE, RGB48LE)) conv = HAVE_BIGENDIAN ? x2rgb10tobgr48_bswap + : x2rgb10tobgr48_nobswap; + else if (CONV_IS(X2RGB10LE, BGR48BE) + || CONV_IS(X2BGR10LE, RGB48BE)) conv = HAVE_BIGENDIAN ? x2rgb10tobgr48_nobswap + : x2rgb10tobgr48_bswap; + else if (CONV_IS(X2RGB10LE, RGBA64LE) + || CONV_IS(X2BGR10LE, BGRA64LE)) conv = HAVE_BIGENDIAN ? x2rgb10to64_bswap + : x2rgb10to64_nobswap; + else if (CONV_IS(X2RGB10LE, RGBA64BE) + || CONV_IS(X2BGR10LE, BGRA64BE)) conv = HAVE_BIGENDIAN ? x2rgb10to64_nobswap + : x2rgb10to64_bswap; + else if (CONV_IS(X2RGB10LE, BGRA64LE) + || CONV_IS(X2BGR10LE, RGBA64LE)) conv = HAVE_BIGENDIAN ? x2rgb10tobgr64_bswap + : x2rgb10tobgr64_nobswap; + else if (CONV_IS(X2RGB10LE, BGRA64BE) + || CONV_IS(X2BGR10LE, RGBA64BE)) conv = HAVE_BIGENDIAN ? x2rgb10tobgr64_nobswap + : x2rgb10tobgr64_bswap; } else if (isAYUV(srcFormat) && isAYUV(dstFormat)) { /* VUYX only for dst, to avoid copying undefined bytes */ if ( CONV_IS(AYUV, VUYA)