From 21d82554236b7f566da93e83f87676129b530ffd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 17 Jul 2012 04:24:24 +0200 Subject: [PATCH] sws: handle non native rgb<->rgb convertions Signed-off-by: Michael Niedermayer --- libswscale/swscale_unscaled.c | 21 ++++++++++++++------- libswscale/utils.c | 3 ++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 307f4da8c9..74767ae534 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -542,10 +542,6 @@ static rgbConvFn findRgbConvFn(SwsContext *c) (((bpp + 7) >> 3) == 2 && \ (!(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_BE) != !HAVE_BIGENDIAN)) - /* if this is non-native rgb444/555/565, don't handle it here. */ - if (IS_NOT_NE(srcId, srcFormat) || IS_NOT_NE(dstId, dstFormat)) - return NULL; - #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst) if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) { @@ -632,6 +628,9 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], } else { const uint8_t *srcPtr = src[0]; uint8_t *dstPtr = dst[0]; + int src_bswap = IS_NOT_NE(c->srcFormatBpp, srcFormat); + int dst_bswap = IS_NOT_NE(c->dstFormatBpp, dstFormat); + if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) && !isRGBA32(dstFormat)) srcPtr += ALT32_CORR; @@ -641,15 +640,23 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], dstPtr += ALT32_CORR; if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 && - !(srcStride[0] % srcBpp)) + !(srcStride[0] % srcBpp) && !dst_bswap && !src_bswap) conv(srcPtr, dstPtr + dstStride[0] * srcSliceY, srcSliceH * srcStride[0]); else { - int i; + int i, j; dstPtr += dstStride[0] * srcSliceY; for (i = 0; i < srcSliceH; i++) { - conv(srcPtr, dstPtr, c->srcW * srcBpp); + if(src_bswap) { + for(j=0; jsrcW; j++) + ((uint16_t*)c->formatConvBuffer)[j] = av_bswap16(((uint16_t*)srcPtr)[j]); + conv(c->formatConvBuffer, dstPtr, c->srcW * srcBpp); + }else + conv(srcPtr, dstPtr, c->srcW * srcBpp); + if(dst_bswap) + for(j=0; jsrcW; j++) + ((uint16_t*)dstPtr)[j] = av_bswap16(((uint16_t*)dstPtr)[j]); srcPtr += srcStride[0]; dstPtr += dstStride[0]; } diff --git a/libswscale/utils.c b/libswscale/utils.c index 4047fb57ee..a6bb732024 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -996,6 +996,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) c->chrDstW = -((-dstW) >> c->chrDstHSubSample); c->chrDstH = -((-dstH) >> c->chrDstVSubSample); + FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); + /* unscaled special cases */ if (unscaled && !usesHFilter && !usesVFilter && (c->srcRange == c->dstRange || isAnyRGB(dstFormat))) { @@ -1020,7 +1022,6 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) c->srcBpc = 16; if (c->dstBpc == 16) dst_stride <<= 1; - FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2 && c->srcBpc == 8 && c->dstBpc <= 14) { c->canMMX2BeUsed = (dstW >= srcW && (dstW & 31) == 0 &&