From 928061670e873e816daa14827853b7e11221ff5f Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 17 Dec 2014 14:54:43 +0100 Subject: 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 +++ 6 files changed, 54 insertions(+), 2 deletions(-) (limited to 'libswscale') diff --git a/libswscale/input.c b/libswscale/input.c index f583b3f..6acd2bb 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 125d998..1670f4a 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 7756e1b..f6427bf 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 a0daa07..fdaaeeb 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 ddf177a..bfcc1a3 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 32e304c..b3df1af 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 }, }; -- cgit v1.1