[FFmpeg-devel] [PATCH] swscale: Add support for unscaled Planar RGB -> Packed RGB
Derek Buitenhuis
derek.buitenhuis at gmail.com
Sat Sep 22 04:33:54 CEST 2012
Signed-off-by: Derek Buitenhuis <derek.buitenhuis at gmail.com>
---
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 9180f2e..2152ee6 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -514,6 +514,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 \
@@ -988,6 +1136,9 @@ void ff_get_unscaled_swscale(SwsContext *c)
if (isAnyRGB(srcFormat) && isPlanar(srcFormat) && isByteRGB(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 4b14c73..90ebac0 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -167,7 +167,7 @@ static const FormatEntry format_entries[PIX_FMT_NB] = {
[PIX_FMT_YUV444P12LE] = { 1, 1 },
[PIX_FMT_YUV444P14BE] = { 1, 1 },
[PIX_FMT_YUV444P14LE] = { 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
More information about the ffmpeg-devel
mailing list