Signed-off-by: Derek Buitenhuis <derek.buitenh...@gmail.com> --- Shame? I feel no shame. --- libswscale/swscale_unscaled.c | 151 +++++++++++++++++++++++++++++++++++++++++ libswscale/utils.c | 2 +- 2 files changed, 152 insertions(+), 1 deletion(-)
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 595edf8..c8ef9d4 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -446,6 +446,154 @@ static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t *src[], return srcSliceH; } +static void packed24togbr24p(const uint8_t *src, int srcStride, + uint8_t *dst[], int dstStride[], int srcSliceH, + int width) +{ + uint8_t *dest[3]; + int x, h; + + dest[0] = dst[0]; + dest[1] = dst[1]; + dest[2] = dst[2]; + + for (h = 0; h < srcSliceH; h++) { + for (x = 0; x < width; x++) { + dest[0][x] = *src++; + dest[1][x] = *src++; + dest[2][x] = *src++; + } + src += srcStride - width * 3; + dest[0] += dstStride[0]; + dest[1] += dstStride[1]; + dest[2] += dstStride[2]; + } +} + +static void packed32togbr24p(const uint8_t *src, int srcStride, + uint8_t *dst[], int dstStride[], int srcSliceH, + int alpha_first, int width) +{ + uint8_t *dest[4]; + int x, h; + + dest[0] = dst[0]; + dest[1] = dst[1]; + dest[2] = dst[2]; + + if (alpha_first) { + for (h = 0; h < srcSliceH; h++) { + for (x = 0; x < width; x++) { + src++; + dest[0][x] = *src++; + dest[1][x] = *src++; + dest[2][x] = *src++; + } + src += srcStride - width * 4; + dest[0] += dstStride[0]; + dest[1] += dstStride[1]; + dest[2] += dstStride[2]; + } + } else { + for (h = 0; h < srcSliceH; h++) { + for (x = 0; x < width; x++) { + dest[0][x] = *src++; + dest[1][x] = *src++; + dest[2][x] = *src++; + src++; + } + src += srcStride - width * 4; + dest[0] += dstStride[0]; + dest[1] += dstStride[1]; + dest[2] += dstStride[2]; + } + } +} + +static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[], + int srcStride[], int srcSliceY, int srcSliceH, + uint8_t *dst[], int dstStride[]) +{ + int alpha_first = 0; + + if (c->dstFormat != PIX_FMT_GBRP) { + av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n", + av_get_pix_fmt_name(c->srcFormat), + av_get_pix_fmt_name(c->dstFormat)); + return srcSliceH; + } + + switch (c->srcFormat) { + case PIX_FMT_RGB24: + packed24togbr24p((const uint8_t *) src[0], srcStride[0], + (uint8_t *[]) { + dst[2] + srcSliceY * dstStride[2], + dst[0] + srcSliceY * dstStride[0], + dst[1] + srcSliceY * dstStride[1] + }, + (int []) { + dstStride[2], + dstStride[0], + dstStride[1] + }, + srcSliceH, c->srcW); + break; + case PIX_FMT_BGR24: + packed24togbr24p((const uint8_t *) src[0], srcStride[0], + (uint8_t *[]) { + dst[1] + srcSliceY * dstStride[1], + dst[0] + srcSliceY * dstStride[0], + dst[2] + srcSliceY * dstStride[2] + }, + (int []) { + dstStride[1], + dstStride[0], + dstStride[2] + }, + srcSliceH, c->srcW); + break; + case PIX_FMT_ARGB: + alpha_first = 1; + case PIX_FMT_RGBA: + packed32togbr24p((const uint8_t *) src[0], srcStride[0], + (uint8_t *[]) { + dst[2] + srcSliceY * dstStride[2], + dst[0] + srcSliceY * dstStride[0], + dst[1] + srcSliceY * dstStride[1] + }, + (int []) { + dstStride[2], + dstStride[0], + dstStride[1], + }, + alpha_first, srcSliceH, c->srcW); + break; + case PIX_FMT_ABGR: + alpha_first = 1; + case PIX_FMT_BGRA: + packed32togbr24p((const uint8_t *) src[0], srcStride[0], + (uint8_t *[]) { + dst[1] + srcSliceY * dstStride[1], + dst[0] + srcSliceY * dstStride[0], + dst[2] + srcSliceY * dstStride[2] + }, + (int []) { + dstStride[1], + dstStride[0], + dstStride[2], + }, + alpha_first, srcSliceH, c->srcW); + break; + default: + av_log(c, AV_LOG_ERROR, + "unsupported planar RGB conversion %s -> %s\n", + av_get_pix_fmt_name(c->srcFormat), + av_get_pix_fmt_name(c->dstFormat)); + } + + return srcSliceH; +} + #define isRGBA32(x) ( \ (x) == PIX_FMT_ARGB \ || (x) == PIX_FMT_RGBA \ @@ -901,6 +1049,9 @@ void ff_get_unscaled_swscale(SwsContext *c) if (isPlanarRGB(srcFormat) && isPackedRGB(dstFormat)) c->swScale = planarRgbToRgbWrapper; + + if (isPackedRGB(srcFormat) && isPlanarRGB(dstFormat)) + c->swScale = rgbToPlanarRgbWrapper; /* bswap 16 bits per pixel/component packed formats */ if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR444) || diff --git a/libswscale/utils.c b/libswscale/utils.c index 0002e17..a5d596e 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -143,7 +143,7 @@ static const FormatEntry format_entries[PIX_FMT_NB] = { [PIX_FMT_YUV444P9LE] = { 1, 1 }, [PIX_FMT_YUV444P10BE] = { 1, 1 }, [PIX_FMT_YUV444P10LE] = { 1, 1 }, - [PIX_FMT_GBRP] = { 1, 0 }, + [PIX_FMT_GBRP] = { 1, 1 }, [PIX_FMT_GBRP9LE] = { 1, 0 }, [PIX_FMT_GBRP9BE] = { 1, 0 }, [PIX_FMT_GBRP10LE] = { 1, 0 }, -- 1.7.9.5 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel