[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