From 5c057433ccd32f37ddc828d3f82c5b1ad7d3e3db Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 6 May 2013 15:13:53 +0000 Subject: libswscale: GBRAP input & output and GBRAP16 input support Signed-off-by: Paul B Mahol --- libswscale/input.c | 18 +++++++++++++++++- libswscale/output.c | 9 ++++++++- libswscale/swscale.c | 3 +++ libswscale/swscale_internal.h | 3 ++- libswscale/swscale_unscaled.c | 21 +++++++++++++++++++++ libswscale/utils.c | 6 +++--- 6 files changed, 54 insertions(+), 6 deletions(-) (limited to 'libswscale') diff --git a/libswscale/input.c b/libswscale/input.c index 21dfeca573..35caa322ee 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -720,6 +720,14 @@ static void planar_rgb_to_y(uint8_t *_dst, const uint8_t *src[4], int width, int } } +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, int32_t *rgb2yuv) { uint16_t *dstU = (uint16_t *)_dstU; @@ -835,6 +843,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP14LE: c->readChrPlanar = planar_rgb14le_to_uv; break; + case AV_PIX_FMT_GBRAP16LE: case AV_PIX_FMT_GBRP16LE: c->readChrPlanar = planar_rgb16le_to_uv; break; @@ -850,9 +859,11 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP14BE: c->readChrPlanar = planar_rgb14be_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; @@ -955,7 +966,8 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_BGR555BE: c->chrToYV12 = bgr15beToUV_half_c; break; - case AV_PIX_FMT_GBR24P : + case AV_PIX_FMT_GBRAP: + case AV_PIX_FMT_GBRP: c->chrToYV12 = gbr24pToUV_half_c; break; case AV_PIX_FMT_BGR444LE: @@ -1084,6 +1096,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP14LE: c->readLumPlanar = planar_rgb14le_to_y; break; + case AV_PIX_FMT_GBRAP16LE: case AV_PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; break; @@ -1099,9 +1112,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_GBRP14BE: c->readLumPlanar = planar_rgb14be_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 da760d2599..9669b4572b 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -1495,7 +1495,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 & PIX_FMT_ALPHA) && alpSrc; uint16_t **dest16 = (uint16_t**)dest; int SH = 22 + 7 - desc->comp[0].depth_minus1; @@ -1547,10 +1547,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)) { @@ -1558,6 +1562,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]); } } } @@ -1722,6 +1728,7 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, case AV_PIX_FMT_GBRP14LE: 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 c34c56ca62..827837eec7 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -256,6 +256,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, c->input_rgb2yuv_table); src = formatConvBuffer; + } else if (c->readAlpPlanar && isAlpha) { + c->readAlpPlanar(formatConvBuffer, src_in, srcW, NULL); + src = formatConvBuffer; } if (!c->hyscale_fast) { diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index c4ea26f694..5e3cc62e3a 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -504,12 +504,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, int32_t *rgb2yuv); void (*readChrPlanar)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width, int32_t *rgb2yuv); + void (*readAlpPlanar)(uint8_t *dst, const uint8_t *src[4], int width, int32_t *rgb2yuv); /** @} */ /** diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 8c24e560ee..d42bb08810 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -492,6 +492,22 @@ 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) @@ -1039,6 +1055,10 @@ void ff_get_unscaled_swscale(SwsContext *c) && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) c->swScale= rgbToRgbWrapper; + 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 || \ @@ -1066,6 +1086,7 @@ void ff_get_unscaled_swscale(SwsContext *c) IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP12) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP14) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP16) || + 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_RGBA64) || diff --git a/libswscale/utils.c b/libswscale/utils.c index b0a0f19110..5f4dabfad7 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -200,9 +200,9 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { [AV_PIX_FMT_GBRP16BE] = { 1, 0 }, [AV_PIX_FMT_XYZ12BE] = { 1, 0, 1 }, [AV_PIX_FMT_XYZ12LE] = { 1, 0, 1 }, - [AV_PIX_FMT_GBRAP] = { 0, 0 }, - [AV_PIX_FMT_GBRAP16LE] = { 0, 0 }, - [AV_PIX_FMT_GBRAP16BE] = { 0, 0 }, + [AV_PIX_FMT_GBRAP] = { 1, 1 }, + [AV_PIX_FMT_GBRAP16LE] = { 1, 0 }, + [AV_PIX_FMT_GBRAP16BE] = { 1, 0 }, }; int sws_isSupportedInput(enum AVPixelFormat pix_fmt) -- cgit v1.2.3