[FFmpeg-cvslog] swscale/swscale_unscaled: add unscaled x2rgb10le to planar RGB

James Almer git at videolan.org
Thu Nov 7 03:19:51 EET 2024


ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Sat Nov  2 23:36:47 2024 -0300| [ae8ef645ecb2c1969f58acb869e5a92d72c3716f] | committer: James Almer

swscale/swscale_unscaled: add unscaled x2rgb10le to planar RGB

Signed-off-by: James Almer <jamrial at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ae8ef645ecb2c1969f58acb869e5a92d72c3716f
---

 libswscale/swscale_unscaled.c     | 88 +++++++++++++++++++++++++++++++++++++++
 tests/ref/pixfmt/gbrp10-x2bgr10le |  2 +-
 tests/ref/pixfmt/gbrp10-x2rgb10le |  2 +-
 3 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index c87a70e95e..7fa513dc1e 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -742,6 +742,77 @@ static void packed16togbra16(const uint8_t *src, int srcStride,
     }
 }
 
+static void packed30togbra10(const uint8_t *src, int srcStride,
+                             uint16_t *dst[], const int dstStride[], int srcSliceH,
+                             int swap, int bpc, int width)
+{
+    int x, h, i;
+    int dst_alpha = dst[3] != NULL;
+    int scale_high = bpc - 10, scale_low = 10 - scale_high;
+    for (h = 0; h < srcSliceH; h++) {
+        uint32_t *src_line = (uint32_t *)(src + srcStride * h);
+        unsigned component;
+
+        switch (swap) {
+        case 3:
+        case 2:
+            if (dst_alpha) {
+                for (x = 0; x < width; x++) {
+                    unsigned p = AV_RL32(src_line);
+                    component = (p >> 20) & 0x3FF;
+                    dst[0][x] = av_bswap16(component << scale_high | component >> scale_low);
+                    component = (p >> 10) & 0x3FF;
+                    dst[1][x] = av_bswap16(component << scale_high | component >> scale_low);
+                    component =  p        & 0x3FF;
+                    dst[2][x] = av_bswap16(component << scale_high | component >> scale_low);
+                    dst[3][x] = 0xFFFF;
+                    src_line++;
+                }
+            } else {
+                for (x = 0; x < width; x++) {
+                    unsigned p = AV_RL32(src_line);
+                    component = (p >> 20) & 0x3FF;
+                    dst[0][x] = av_bswap16(component << scale_high | component >> scale_low);
+                    component = (p >> 10) & 0x3FF;
+                    dst[1][x] = av_bswap16(component << scale_high | component >> scale_low);
+                    component =  p        & 0x3FF;
+                    dst[2][x] = av_bswap16(component << scale_high | component >> scale_low);
+                    src_line++;
+                }
+            }
+            break;
+        default:
+            if (dst_alpha) {
+                for (x = 0; x < width; x++) {
+                    unsigned p = AV_RL32(src_line);
+                    component = (p >> 20) & 0x3FF;
+                    dst[0][x] = component << scale_high | component >> scale_low;
+                    component = (p >> 10) & 0x3FF;
+                    dst[1][x] = component << scale_high | component >> scale_low;
+                    component =  p        & 0x3FF;
+                    dst[2][x] = component << scale_high | component >> scale_low;
+                    dst[3][x] = 0xFFFF;
+                    src_line++;
+                }
+            } else {
+                for (x = 0; x < width; x++) {
+                    unsigned p = AV_RL32(src_line);
+                    component = (p >> 20) & 0x3FF;
+                    dst[0][x] = component << scale_high | component >> scale_low;
+                    component = (p >> 10) & 0x3FF;
+                    dst[1][x] = component << scale_high | component >> scale_low;
+                    component =  p        & 0x3FF;
+                    dst[2][x] = component << scale_high | component >> scale_low;
+                    src_line++;
+                }
+            }
+            break;
+        }
+        for (i = 0; i < 4; i++)
+            dst[i] += dstStride[i] >> 1;
+    }
+}
+
 static int Rgb16ToPlanarRgb16Wrapper(SwsInternal *c, const uint8_t *const src[],
                                      const int srcStride[], int srcSliceY, int srcSliceH,
                                      uint8_t *const dst[], const int dstStride[])
@@ -785,6 +856,12 @@ static int Rgb16ToPlanarRgb16Wrapper(SwsInternal *c, const uint8_t *const src[],
                          dst2013, stride2013, srcSliceH, alpha, swap,
                          16 - bpc, c->srcW);
         break;
+    case AV_PIX_FMT_X2RGB10LE:
+        av_assert0(bpc >= 10);
+        packed30togbra10(src[0], srcStride[0],
+                         dst2013, stride2013, srcSliceH, swap,
+                         bpc, c->srcW);
+        break;
     case AV_PIX_FMT_BGR48LE:
     case AV_PIX_FMT_BGR48BE:
     case AV_PIX_FMT_BGRA64LE:
@@ -793,6 +870,12 @@ static int Rgb16ToPlanarRgb16Wrapper(SwsInternal *c, const uint8_t *const src[],
                          dst1023, stride1023, srcSliceH, alpha, swap,
                          16 - bpc, c->srcW);
         break;
+    case AV_PIX_FMT_X2BGR10LE:
+        av_assert0(bpc >= 10);
+        packed30togbra10(src[0], srcStride[0],
+                         dst1023, stride1023, srcSliceH, swap,
+                         bpc, c->srcW);
+        break;
     default:
         av_log(c, AV_LOG_ERROR,
                "unsupported conversion to planar RGB %s -> %s\n",
@@ -2301,6 +2384,11 @@ void ff_get_unscaled_swscale(SwsInternal *c)
          dstFormat == AV_PIX_FMT_GBRAP16LE || dstFormat == AV_PIX_FMT_GBRAP16BE ))
         c->convert_unscaled = Rgb16ToPlanarRgb16Wrapper;
 
+    if (av_pix_fmt_desc_get(dstFormat)->comp[0].depth >= 10 &&
+        isPlanarRGB(dstFormat) && !isFloat(dstFormat) &&
+        (srcFormat == AV_PIX_FMT_X2RGB10LE || srcFormat == AV_PIX_FMT_X2BGR10LE))
+        c->convert_unscaled = Rgb16ToPlanarRgb16Wrapper;
+
     if ((srcFormat == AV_PIX_FMT_GBRP9LE  || srcFormat == AV_PIX_FMT_GBRP9BE  ||
          srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ||
          srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE ||
diff --git a/tests/ref/pixfmt/gbrp10-x2bgr10le b/tests/ref/pixfmt/gbrp10-x2bgr10le
index 51e9c5e4f0..568039f4ae 100644
--- a/tests/ref/pixfmt/gbrp10-x2bgr10le
+++ b/tests/ref/pixfmt/gbrp10-x2bgr10le
@@ -1,2 +1,2 @@
-909448714837e324484d85f3da37e2ba *tests/data/pixfmt/gbrp10-x2bgr10le.yuv
+1f9cc212a4081b6e35811df461b18fec *tests/data/pixfmt/gbrp10-x2bgr10le.yuv
 15206400 tests/data/pixfmt/gbrp10-x2bgr10le.yuv
diff --git a/tests/ref/pixfmt/gbrp10-x2rgb10le b/tests/ref/pixfmt/gbrp10-x2rgb10le
index 4cd95358df..bcb2208022 100644
--- a/tests/ref/pixfmt/gbrp10-x2rgb10le
+++ b/tests/ref/pixfmt/gbrp10-x2rgb10le
@@ -1,2 +1,2 @@
-909448714837e324484d85f3da37e2ba *tests/data/pixfmt/gbrp10-x2rgb10le.yuv
+1f9cc212a4081b6e35811df461b18fec *tests/data/pixfmt/gbrp10-x2rgb10le.yuv
 15206400 tests/data/pixfmt/gbrp10-x2rgb10le.yuv



More information about the ffmpeg-cvslog mailing list