[FFmpeg-cvslog] swscale/swscale_unscaled: add unscaled rgb to planar rgba
James Almer
git at videolan.org
Sat Nov 2 20:06:10 EET 2024
ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Thu Oct 31 13:33:24 2024 -0300| [c029a2f7ddea8e2b3c99f629c1bb54ff5a50cac1] | committer: James Almer
swscale/swscale_unscaled: add unscaled rgb to planar rgba
The fate test reference changes are due to the conversion being a simple
lossless deinterleave, instead of going through a RGB -> YUV -> RGB roundtrip.
Signed-off-by: James Almer <jamrial at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c029a2f7ddea8e2b3c99f629c1bb54ff5a50cac1
---
libswscale/swscale_unscaled.c | 114 ++++++++++++++++++++++++++++++
tests/ref/fate/filter-overlay_gbrap_gbrap | 2 +-
tests/ref/fate/filter-overlay_gbrp_gbrap | 2 +-
tests/ref/fate/vbn-dxt1 | 8 +--
4 files changed, 120 insertions(+), 6 deletions(-)
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 6eb7867ff9..c87a70e95e 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -1305,6 +1305,116 @@ static int rgbToPlanarRgbWrapper(SwsInternal *c, const uint8_t *const src[],
return srcSliceH;
}
+static void packed24togbrap(const uint8_t *src, int srcStride,
+ uint8_t *const dst[], const int dstStride[],
+ int srcSliceH, int width)
+{
+ uint8_t *dest[4];
+ int x, h;
+
+ dest[0] = dst[0];
+ dest[1] = dst[1];
+ dest[2] = dst[2];
+ dest[3] = dst[3];
+
+ for (h = 0; h < srcSliceH; h++) {
+ for (x = 0; x < width; x++) {
+ dest[0][x] = src[x * 3 + 0];
+ dest[1][x] = src[x * 3 + 1];
+ dest[2][x] = src[x * 3 + 2];
+ dest[3][x] = 0xff;
+ }
+ src += srcStride;
+ dest[0] += dstStride[0];
+ dest[1] += dstStride[1];
+ dest[2] += dstStride[2];
+ dest[3] += dstStride[3];
+ }
+}
+
+static void packed32togbrap(const uint8_t *src, int srcStride,
+ uint8_t *const dst[], const 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];
+ dest[3] = dst[3];
+
+ for (h = 0; h < srcSliceH; h++) {
+ if (alpha_first) {
+ for (x = 0; x < width; x++) {
+ dest[0][x] = src[x * 4 + 1];
+ dest[1][x] = src[x * 4 + 2];
+ dest[2][x] = src[x * 4 + 3];
+ dest[3][x] = src[x * 4 + 0];
+ }
+ } else {
+ for (x = 0; x < width; x++) {
+ dest[0][x] = src[x * 4 + 0];
+ dest[1][x] = src[x * 4 + 1];
+ dest[2][x] = src[x * 4 + 2];
+ dest[3][x] = src[x * 4 + 3];
+ }
+ }
+ src += srcStride;
+ dest[0] += dstStride[0];
+ dest[1] += dstStride[1];
+ dest[2] += dstStride[2];
+ dest[3] += dstStride[3];
+ }
+}
+
+static int rgbToPlanarRgbaWrapper(SwsInternal *c, const uint8_t *const src[],
+ const int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *const dst[], const int dstStride[])
+{
+ int alpha_first = 0;
+ int stride102[] = { dstStride[1], dstStride[0], dstStride[2], dstStride[3] };
+ int stride201[] = { dstStride[2], dstStride[0], dstStride[1], dstStride[3] };
+ uint8_t *dst102[] = { dst[1] + srcSliceY * dstStride[1],
+ dst[0] + srcSliceY * dstStride[0],
+ dst[2] + srcSliceY * dstStride[2],
+ dst[3] + srcSliceY * dstStride[3] };
+ uint8_t *dst201[] = { dst[2] + srcSliceY * dstStride[2],
+ dst[0] + srcSliceY * dstStride[0],
+ dst[1] + srcSliceY * dstStride[1],
+ dst[3] + srcSliceY * dstStride[3] };
+
+ switch (c->srcFormat) {
+ case AV_PIX_FMT_RGB24:
+ packed24togbrap((const uint8_t *) src[0], srcStride[0], dst201,
+ stride201, srcSliceH, c->srcW);
+ break;
+ case AV_PIX_FMT_BGR24:
+ packed24togbrap((const uint8_t *) src[0], srcStride[0], dst102,
+ stride102, srcSliceH, c->srcW);
+ break;
+ case AV_PIX_FMT_ARGB:
+ alpha_first = 1;
+ case AV_PIX_FMT_RGBA:
+ packed32togbrap((const uint8_t *) src[0], srcStride[0], dst201,
+ stride201, srcSliceH, alpha_first, c->srcW);
+ break;
+ case AV_PIX_FMT_ABGR:
+ alpha_first = 1;
+ case AV_PIX_FMT_BGRA:
+ packed32togbrap((const uint8_t *) src[0], srcStride[0], dst102,
+ stride102, srcSliceH, alpha_first, 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 BAYER_GBRG
#define BAYER_8
#define BAYER_RENAME(x) bayer_gbrg8_to_##x
@@ -2215,6 +2325,10 @@ void ff_get_unscaled_swscale(SwsInternal *c)
isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
c->convert_unscaled = rgbToPlanarRgbWrapper;
+ if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth == 8 &&
+ isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRAP)
+ c->convert_unscaled = rgbToPlanarRgbaWrapper;
+
if (isBayer(srcFormat)) {
c->dst_slice_align = 2;
if (dstFormat == AV_PIX_FMT_RGB24)
diff --git a/tests/ref/fate/filter-overlay_gbrap_gbrap b/tests/ref/fate/filter-overlay_gbrap_gbrap
index 5048a346ae..49e14c643c 100644
--- a/tests/ref/fate/filter-overlay_gbrap_gbrap
+++ b/tests/ref/fate/filter-overlay_gbrap_gbrap
@@ -3,4 +3,4 @@
#codec_id 0: rawvideo
#dimensions 0: 128x128
#sar 0: 1/1
-0, 0, 0, 1, 65536, 0x821bcb9b
+0, 0, 0, 1, 65536, 0xbac99946
diff --git a/tests/ref/fate/filter-overlay_gbrp_gbrap b/tests/ref/fate/filter-overlay_gbrp_gbrap
index 99524c3355..204c9d0625 100644
--- a/tests/ref/fate/filter-overlay_gbrp_gbrap
+++ b/tests/ref/fate/filter-overlay_gbrp_gbrap
@@ -3,4 +3,4 @@
#codec_id 0: rawvideo
#dimensions 0: 128x128
#sar 0: 1/1
-0, 0, 0, 1, 49152, 0x738d07ea
+0, 0, 0, 1, 49152, 0xa905d586
diff --git a/tests/ref/fate/vbn-dxt1 b/tests/ref/fate/vbn-dxt1
index e33d9b63e1..8ff8da3406 100644
--- a/tests/ref/fate/vbn-dxt1
+++ b/tests/ref/fate/vbn-dxt1
@@ -5,7 +5,7 @@ lavfi.psnr.mse.g=33.508362
lavfi.psnr.psnr.g=32.879272
lavfi.psnr.mse.b=27.947266
lavfi.psnr.psnr.b=33.667412
-lavfi.psnr.mse.a=21186.988281
-lavfi.psnr.psnr.a=4.870111
-lavfi.psnr.mse_avg=5321.285645
-lavfi.psnr.psnr_avg=10.870638
+lavfi.psnr.mse.a=21248.300781
+lavfi.psnr.psnr.a=4.857562
+lavfi.psnr.mse_avg=5336.613770
+lavfi.psnr.psnr_avg=10.858146
More information about the ffmpeg-cvslog
mailing list