From 928061670e873e816daa14827853b7e11221ff5f Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 17 Dec 2014 14:54:43 +0100 Subject: [PATCH] libswscale: GBRAP input & output and GBRAP16 input support Signed-off-by: Vittorio Giovara --- libswscale/input.c | 15 +++++++++++++++ libswscale/output.c | 9 ++++++++- libswscale/swscale.c | 3 +++ libswscale/swscale_internal.h | 3 ++- libswscale/swscale_unscaled.c | 23 +++++++++++++++++++++++ libswscale/utils.c | 3 +++ tests/ref/fate/filter-pixdesc-gbrap | 1 + tests/ref/fate/filter-pixfmts-copy | 1 + tests/ref/fate/filter-pixfmts-null | 1 + tests/ref/fate/filter-pixfmts-scale | 1 + tests/ref/fate/filter-pixfmts-vflip | 1 + 11 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/filter-pixdesc-gbrap diff --git a/libswscale/input.c b/libswscale/input.c index f583b3f214..6acd2bb3ee 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -596,6 +596,14 @@ static void planar_rgb_to_y(uint8_t *dst, const uint8_t *src[4], int width) } } +static void planar_rgb_to_a(uint8_t *_dst, const uint8_t *src[4], int width, int32_t *unused) +{ + uint16_t *dst = (uint16_t *)_dst; + int i; + for (i = 0; i < width; i++) + dst[i] = src[3][i] << 6; +} + static void planar_rgb_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width) { int i; @@ -745,6 +753,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10LE: c->readChrPlanar = planar_rgb10le_to_uv; break; + case AV_PIX_FMT_GBRAP16LE: case AV_PIX_FMT_GBRP16LE: c->readChrPlanar = planar_rgb16le_to_uv; break; @@ -754,9 +763,11 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10BE: c->readChrPlanar = planar_rgb10be_to_uv; break; + case AV_PIX_FMT_GBRAP16BE: case AV_PIX_FMT_GBRP16BE: c->readChrPlanar = planar_rgb16be_to_uv; break; + case AV_PIX_FMT_GBRAP: case AV_PIX_FMT_GBRP: c->readChrPlanar = planar_rgb_to_uv; break; @@ -953,6 +964,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10LE: c->readLumPlanar = planar_rgb10le_to_y; break; + case AV_PIX_FMT_GBRAP16LE: case AV_PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; break; @@ -962,9 +974,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP10BE: c->readLumPlanar = planar_rgb10be_to_y; break; + case AV_PIX_FMT_GBRAP16BE: case AV_PIX_FMT_GBRP16BE: c->readLumPlanar = planar_rgb16be_to_y; break; + case AV_PIX_FMT_GBRAP: + c->readAlpPlanar = planar_rgb_to_a; case AV_PIX_FMT_GBRP: c->readLumPlanar = planar_rgb_to_y; break; diff --git a/libswscale/output.c b/libswscale/output.c index 125d998836..1670f4a2b9 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -1277,7 +1277,7 @@ yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter, { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat); int i; - int hasAlpha = 0; + int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrc; uint16_t **dest16 = (uint16_t**)dest; int SH = 22 + 7 - desc->comp[0].depth_minus1; @@ -1329,10 +1329,14 @@ yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter, dest16[0][i] = G >> SH; dest16[1][i] = B >> SH; dest16[2][i] = R >> SH; + if (hasAlpha) + dest16[3][i] = A; } else { dest[0][i] = G >> 22; dest[1][i] = B >> 22; dest[2][i] = R >> 22; + if (hasAlpha) + dest[3][i] = A; } } if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) { @@ -1340,6 +1344,8 @@ yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter, dest16[0][i] = av_bswap16(dest16[0][i]); dest16[1][i] = av_bswap16(dest16[1][i]); dest16[2][i] = av_bswap16(dest16[2][i]); + if (hasAlpha) + dest16[3][i] = av_bswap16(dest16[3][i]); } } } @@ -1445,6 +1451,7 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, case AV_PIX_FMT_GBRP10LE: case AV_PIX_FMT_GBRP16BE: case AV_PIX_FMT_GBRP16LE: + case AV_PIX_FMT_GBRAP: *yuv2anyX = yuv2gbrp_full_X_c; break; } diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 7756e1b52e..f6427bfb55 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -269,6 +269,9 @@ static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth, } else if (c->readLumPlanar && !isAlpha) { c->readLumPlanar(formatConvBuffer, src_in, srcW); src = formatConvBuffer; + } else if (c->readAlpPlanar && isAlpha) { + c->readAlpPlanar(formatConvBuffer, src_in, srcW); + src = formatConvBuffer; } if (!c->hyscale_fast) { diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index a0daa071e9..fdaaeeb67f 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -458,12 +458,13 @@ typedef struct SwsContext { /** * Functions to read planar input, such as planar RGB, and convert - * internally to Y/UV. + * internally to Y/UV/A. */ /** @{ */ void (*readLumPlanar)(uint8_t *dst, const uint8_t *src[4], int width); void (*readChrPlanar)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width); + void (*readAlpPlanar)(uint8_t *dst, const uint8_t *src[4], int width); /** @} */ /** diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index ddf177ae65..bfcc1a3ca5 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -488,6 +488,23 @@ static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t *src[], return srcSliceH; } +static int planarRgbToplanarRgbWrapper(SwsContext *c, + const uint8_t *src[], int srcStride[], + int srcSliceY, int srcSliceH, + uint8_t *dst[], int dstStride[]) +{ + copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, + dst[0], dstStride[0]); + copyPlane(src[1], srcStride[1], srcSliceY, srcSliceH, c->srcW, + dst[1], dstStride[1]); + copyPlane(src[2], srcStride[2], srcSliceY, srcSliceH, c->srcW, + dst[2], dstStride[2]); + if (dst[3]) + fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); + + return srcSliceH; +} + static void packedtogbr24p(const uint8_t *src, int srcStride, uint8_t *dst[], int dstStride[], int srcSliceH, int alpha_first, int inc_size, int width) @@ -1054,6 +1071,11 @@ void ff_get_unscaled_swscale(SwsContext *c) && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) c->swscale = rgbToRgbWrapper; + /* RGB to planar RGB */ + if ((srcFormat == AV_PIX_FMT_GBRP && dstFormat == AV_PIX_FMT_GBRAP) || + (srcFormat == AV_PIX_FMT_GBRAP && dstFormat == AV_PIX_FMT_GBRP)) + c->swscale = planarRgbToplanarRgbWrapper; + #define isByteRGB(f) ( \ f == AV_PIX_FMT_RGB32 || \ f == AV_PIX_FMT_RGB32_1 || \ @@ -1077,6 +1099,7 @@ void ff_get_unscaled_swscale(SwsContext *c) IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YA16) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP16)|| IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) || diff --git a/libswscale/utils.c b/libswscale/utils.c index 32e304c66a..b3df1afc27 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -180,6 +180,9 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_GBRP10BE] = { 1, 1 }, [AV_PIX_FMT_GBRP16LE] = { 1, 0 }, [AV_PIX_FMT_GBRP16BE] = { 1, 0 }, + [AV_PIX_FMT_GBRAP] = { 1, 1 }, + [AV_PIX_FMT_GBRAP16LE] = { 1, 0 }, + [AV_PIX_FMT_GBRAP16BE] = { 1, 0 }, [AV_PIX_FMT_XYZ12BE] = { 0, 0, 1 }, [AV_PIX_FMT_XYZ12LE] = { 0, 0, 1 }, }; diff --git a/tests/ref/fate/filter-pixdesc-gbrap b/tests/ref/fate/filter-pixdesc-gbrap new file mode 100644 index 0000000000..2f77f37e65 --- /dev/null +++ b/tests/ref/fate/filter-pixdesc-gbrap @@ -0,0 +1 @@ +pixdesc-gbrap 28d63d5ac84bb33bf3aea48785baa876 diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy index 5f550250de..2e2f593862 100644 --- a/tests/ref/fate/filter-pixfmts-copy +++ b/tests/ref/fate/filter-pixfmts-copy @@ -12,6 +12,7 @@ bgr565be 257cf78afa35dc31e9696f139c916715 bgr565le 1dfdd03995c287e3c754b164bf26a355 bgr8 24bd566170343d06fec6fccfff5abc54 bgra 76a18a5151242fa137133f604cd624d2 +gbrap 28d63d5ac84bb33bf3aea48785baa876 gbrp 76204621e200a3cc633012f6720c7005 gbrp10be 2ca4a4a589a7dc461ff186913c7a69e5 gbrp10le 46176f1fcc6e67f9862115fe373f73d3 diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null index 5f550250de..2e2f593862 100644 --- a/tests/ref/fate/filter-pixfmts-null +++ b/tests/ref/fate/filter-pixfmts-null @@ -12,6 +12,7 @@ bgr565be 257cf78afa35dc31e9696f139c916715 bgr565le 1dfdd03995c287e3c754b164bf26a355 bgr8 24bd566170343d06fec6fccfff5abc54 bgra 76a18a5151242fa137133f604cd624d2 +gbrap 28d63d5ac84bb33bf3aea48785baa876 gbrp 76204621e200a3cc633012f6720c7005 gbrp10be 2ca4a4a589a7dc461ff186913c7a69e5 gbrp10le 46176f1fcc6e67f9862115fe373f73d3 diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale index a06aa490aa..712754cb2b 100644 --- a/tests/ref/fate/filter-pixfmts-scale +++ b/tests/ref/fate/filter-pixfmts-scale @@ -12,6 +12,7 @@ bgr565be 922a2503767036ae9536f4f7823c04ee bgr565le 3a514a298c6161a071ddf9963c06509d bgr8 7f007fa6c153a16e808a9c51605a4016 bgra a5e7040f9a80cccd65e5acf2ca09ace5 +gbrap 08ea11431bc436d788494d678b3edc6f gbrp 205c50f8359cb4ba2827a7711dea2cc6 gbrp10be 30b7f9d5ef5da474fb794743146236aa gbrp10le 2e9949a01fe4c38774728e34795165cc diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip index 819c507df6..e6ed475224 100644 --- a/tests/ref/fate/filter-pixfmts-vflip +++ b/tests/ref/fate/filter-pixfmts-vflip @@ -12,6 +12,7 @@ bgr565be f19e9a4786395e1ddcd51399c98c9f6c bgr565le fdb617533e1e7ff512ea5b6b6233e738 bgr8 c60f93fd152c6903391d1fe9decd3547 bgra 7f9b799fb48544e49ce93e91d7f9fca8 +gbrap cb0d9cb2813c04a19a346c316c1ffbb9 gbrp 25c1bce192daefab910d51a56b52199e gbrp10be 6fe980f9ca94cbcdb9e01f4e906fdf19 gbrp10le f793a1d96d3524c6a17e53356c415c4e