X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/0b8b3387a977dcdb6fb9e53bcc9966d34b2e4cec..3c172a41065dd3fe1d11af9f0eb16d789d08daf2:/libswscale/swscale_unscaled.c diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 5769548..5fe2b14 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -352,17 +352,22 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], ) /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ -static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], - int srcSliceY, int srcSliceH, uint8_t *dst[], - int dstStride[]) +typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int); +static rgbConvFn findRgbConvFn(SwsContext *c) { const enum PixelFormat srcFormat = c->srcFormat; const enum PixelFormat dstFormat = c->dstFormat; - const int srcBpp = (c->srcFormatBpp + 7) >> 3; - const int dstBpp = (c->dstFormatBpp + 7) >> 3; const int srcId = c->srcFormatBpp; const int dstId = c->dstFormatBpp; - void (*conv)(const uint8_t *src, uint8_t *dst, int src_size) = NULL; + rgbConvFn conv = NULL; + +#define IS_NOT_NE(bpp, fmt) \ + (((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) @@ -384,6 +389,7 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) { switch (srcId | (dstId << 16)) { + case 0x000F000C: conv = rgb12to15; break; case 0x000F0010: conv = rgb16to15; break; case 0x000F0018: conv = rgb24to15; break; case 0x000F0020: conv = rgb32to15; break; @@ -400,6 +406,7 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], } else if ((isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) || (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) { switch (srcId | (dstId << 16)) { + case 0x000C000C: conv = rgb12tobgr12; break; case 0x000F000F: conv = rgb15tobgr15; break; case 0x000F0010: conv = rgb16tobgr15; break; case 0x000F0018: conv = rgb24tobgr15; break; @@ -418,6 +425,21 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], } } + return conv; +} + +/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ +static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t *dst[], + int dstStride[]) + +{ + const enum PixelFormat srcFormat = c->srcFormat; + const enum PixelFormat dstFormat = c->dstFormat; + const int srcBpp = (c->srcFormatBpp + 7) >> 3; + const int dstBpp = (c->dstFormatBpp + 7) >> 3; + rgbConvFn conv = findRgbConvFn(c); + if (!conv) { av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", sws_format_name(srcFormat), sws_format_name(dstFormat)); @@ -715,6 +737,8 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], } else { if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) length *= 2; + else if (!av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1) + length >>= 3; // monowhite/black for (i = 0; i < height; i++) { memcpy(dstPtr, srcPtr, length); srcPtr += srcStride[plane]; @@ -769,20 +793,7 @@ void ff_get_unscaled_swscale(SwsContext *c) c->swScale = bgr24ToYv12Wrapper; /* RGB/BGR -> RGB/BGR (no dither needed forms) */ - if ( isAnyRGB(srcFormat) - && isAnyRGB(dstFormat) - && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8 - && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8 - && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4 - && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4 - && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE - && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE - && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK - && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE - && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE - && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE - && srcFormat != PIX_FMT_BGR48LE && dstFormat != PIX_FMT_BGR48LE - && srcFormat != PIX_FMT_BGR48BE && dstFormat != PIX_FMT_BGR48BE + if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c) && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) c->swScale= rgbToRgbWrapper;