diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-11-25 01:38:21 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-11-25 04:34:44 +0100 |
commit | 92afb431621c79155fcb7171d26f137eb1bee028 (patch) | |
tree | 2beb660ea9fafc1d2d304c0f7df610ebf54117e0 /libswscale/swscale.c | |
parent | 3880b4541ace2697f380ae1f43cb2299efeb2cc7 (diff) | |
parent | 7f1b427018ecff59e0e14031eecc79aac0d91ec8 (diff) | |
download | ffmpeg-92afb431621c79155fcb7171d26f137eb1bee028.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
snow: split snow in snowdec and snowenc
tiffenc: deprecate using compression_level
swscale: fix failing fate tests.
swscale: add support for planar RGB input.
h264: add support for decoding planar RGB images.
Clean up swscale pixfmt macros using av_pix_fmt_descriptors[].
pixfmt: add planar RGB formats.
Conflicts:
libavcodec/h264.c
libavcodec/snow.c
libavcodec/utils.c
libavutil/avutil.h
libavutil/pixdesc.c
libavutil/pixfmt.h
libswscale/swscale.c
libswscale/swscale_internal.h
libswscale/swscale_unscaled.c
libswscale/utils.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libswscale/swscale.c')
-rw-r--r-- | libswscale/swscale.c | 147 |
1 files changed, 130 insertions, 17 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 4be9b800ae..afc510a75c 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1968,6 +1968,91 @@ static void rgb24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *unused } } +static void planar_rgb_to_y(uint16_t *dst, const uint8_t *src[4], int width) +{ + int i; + for (i = 0; i < width; i++) { + int g = src[0][i]; + int b = src[1][i]; + int r = src[2][i]; + + dst[i] = (RY*r + GY*g + BY*b + (0x801<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6); + } +} + +static void planar_rgb16le_to_y(uint8_t *_dst, const uint8_t *_src[4], int width) +{ + int i; + const uint16_t **src = (const uint16_t **) _src; + uint16_t *dst = (uint16_t *) _dst; + for (i = 0; i < width; i++) { + int g = AV_RL16(src[0] + i); + int b = AV_RL16(src[1] + i); + int r = AV_RL16(src[2] + i); + + dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT); + } +} + +static void planar_rgb16be_to_y(uint8_t *_dst, const uint8_t *_src[4], int width) +{ + int i; + const uint16_t **src = (const uint16_t **) _src; + uint16_t *dst = (uint16_t *) _dst; + for (i = 0; i < width; i++) { + int g = AV_RB16(src[0] + i); + int b = AV_RB16(src[1] + i); + int r = AV_RB16(src[2] + i); + + dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT); + } +} + +static void planar_rgb_to_uv(uint16_t *dstU, uint16_t *dstV, const uint8_t *src[4], int width) +{ + int i; + for (i = 0; i < width; i++) { + int g = src[0][i]; + int b = src[1][i]; + int r = src[2][i]; + + dstU[i] = (RU*r + GU*g + BU*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6); + dstV[i] = (RV*r + GV*g + BV*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6); + } +} + +static void planar_rgb16le_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src[4], int width) +{ + int i; + const uint16_t **src = (const uint16_t **) _src; + uint16_t *dstU = (uint16_t *) _dstU; + uint16_t *dstV = (uint16_t *) _dstV; + for (i = 0; i < width; i++) { + int g = AV_RL16(src[0] + i); + int b = AV_RL16(src[1] + i); + int r = AV_RL16(src[2] + i); + + dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1); + dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1); + } +} + +static void planar_rgb16be_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src[4], int width) +{ + int i; + const uint16_t **src = (const uint16_t **) _src; + uint16_t *dstU = (uint16_t *) _dstU; + uint16_t *dstV = (uint16_t *) _dstV; + for (i = 0; i < width; i++) { + int g = AV_RB16(src[0] + i); + int b = AV_RB16(src[1] + i); + int r = AV_RB16(src[2] + i); + + dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1); + dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1); + } +} + static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src, const int16_t *filter, const int16_t *filterPos, int filterSize) @@ -2139,8 +2224,7 @@ static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth, // *** horizontal scale Y line to temp buffer static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth, - const uint8_t *src, const uint8_t *src2, const uint8_t *src3, - int srcW, int xInc, + const uint8_t *src_in[4], int srcW, int xInc, const int16_t *hLumFilter, const int16_t *hLumFilterPos, int hLumFilterSize, uint8_t *formatConvBuffer, @@ -2148,10 +2232,14 @@ static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth, { void (*toYV12)(uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12; void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange; + const uint8_t *src = src_in[isAlpha ? 3 : 0]; if (toYV12) { - toYV12(formatConvBuffer, src, src2, src3, srcW, pal); + toYV12(formatConvBuffer, src, src_in[1], src_in[2], srcW, pal); src= formatConvBuffer; + } else if (c->readLumPlanar && !isAlpha) { + c->readLumPlanar(formatConvBuffer, src_in, srcW); + src = formatConvBuffer; } if (!c->hyscale_fast) { @@ -2184,14 +2272,20 @@ static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2, } static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, - const uint8_t *src0, const uint8_t *src1, const uint8_t *src2, + const uint8_t *src_in[4], int srcW, int xInc, const int16_t *hChrFilter, const int16_t *hChrFilterPos, int hChrFilterSize, uint8_t *formatConvBuffer, uint32_t *pal) { + const uint8_t *src1 = src_in[1], *src2 = src_in[2]; if (c->chrToYV12) { uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16); - c->chrToYV12(formatConvBuffer, buf2, src0, src1, src2, srcW, pal); + c->chrToYV12(formatConvBuffer, buf2, src_in[0], src1, src2, srcW, pal); + src1= formatConvBuffer; + src2= buf2; + } else if (c->readChrPlanar) { + uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16); + c->readChrPlanar(formatConvBuffer, buf2, src_in, srcW); src1= formatConvBuffer; src2= buf2; } @@ -2609,20 +2703,22 @@ static int swScale(SwsContext *c, const uint8_t* src[], //Do horizontal scaling while(lastInLumBuf < lastLumSrcY) { - const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0]; - const uint8_t *src2= src[1]+(lastInLumBuf + 1 - srcSliceY)*srcStride[1]; - const uint8_t *src3= src[2]+(lastInLumBuf + 1 - srcSliceY)*srcStride[2]; - const uint8_t *src4= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3]; + const uint8_t *src1[4] = { + src[0] + (lastInLumBuf + 1 - srcSliceY) * srcStride[0], + src[1] + (lastInLumBuf + 1 - srcSliceY) * srcStride[1], + src[2] + (lastInLumBuf + 1 - srcSliceY) * srcStride[2], + src[3] + (lastInLumBuf + 1 - srcSliceY) * srcStride[3], + }; lumBufIndex++; assert(lumBufIndex < 2*vLumBufSize); assert(lastInLumBuf + 1 - srcSliceY < srcSliceH); assert(lastInLumBuf + 1 - srcSliceY >= 0); - hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, src2, src3, srcW, lumXInc, + hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize, formatConvBuffer, pal, 0); if (CONFIG_SWSCALE_ALPHA && alpPixBuf) - hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src4, NULL, NULL, srcW, + hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize, formatConvBuffer, pal, 1); @@ -2631,9 +2727,12 @@ static int swScale(SwsContext *c, const uint8_t* src[], lumBufIndex, lastInLumBuf); } while(lastInChrBuf < lastChrSrcY) { - const uint8_t *src0= src[0]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[0]; - const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1]; - const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2]; + const uint8_t *src1[4] = { + src[0] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[0], + src[1] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[1], + src[2] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[2], + src[3] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[3], + }; chrBufIndex++; assert(chrBufIndex < 2*vChrBufSize); assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH)); @@ -2642,7 +2741,7 @@ static int swScale(SwsContext *c, const uint8_t* src[], if (c->needs_hcscale) hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex], - chrDstW, src0, src1, src2, chrSrcW, chrXInc, + chrDstW, src1, chrSrcW, chrXInc, hChrFilter, hChrFilterPos, hChrFilterSize, formatConvBuffer, pal); lastInChrBuf++; @@ -2796,6 +2895,13 @@ static av_cold void sws_init_swScale_c(SwsContext *c) case PIX_FMT_PAL8 : case PIX_FMT_BGR4_BYTE: case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break; + case PIX_FMT_GBRP9LE: + case PIX_FMT_GBRP10LE: + case PIX_FMT_GBRP16LE: c->readChrPlanar = planar_rgb16le_to_uv; break; + case PIX_FMT_GBRP9BE: + case PIX_FMT_GBRP10BE: + case PIX_FMT_GBRP16BE: c->readChrPlanar = planar_rgb16be_to_uv; break; + case PIX_FMT_GBRP: c->readChrPlanar = planar_rgb_to_uv; break; #if HAVE_BIGENDIAN case PIX_FMT_YUV444P9LE: case PIX_FMT_YUV422P9LE: @@ -2860,13 +2966,20 @@ static av_cold void sws_init_swScale_c(SwsContext *c) case PIX_FMT_RGB565BE: c->chrToYV12 = rgb16beToUV_c; break; case PIX_FMT_RGB555LE: c->chrToYV12 = rgb15leToUV_c; break; case PIX_FMT_RGB555BE: c->chrToYV12 = rgb15beToUV_c; break; - case PIX_FMT_GBR24P : c->chrToYV12 = gbr24pToUV_c; break; +// case PIX_FMT_GBR24P : c->chrToYV12 = gbr24pToUV_c; break; } } c->lumToYV12 = NULL; c->alpToYV12 = NULL; switch (srcFormat) { + case PIX_FMT_GBRP9LE: + case PIX_FMT_GBRP10LE: + case PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; break; + case PIX_FMT_GBRP9BE: + case PIX_FMT_GBRP10BE: + case PIX_FMT_GBRP16BE: c->readLumPlanar = planar_rgb16be_to_y; break; + case PIX_FMT_GBRP: c->readLumPlanar = planar_rgb_to_y; break; #if HAVE_BIGENDIAN case PIX_FMT_YUV444P9LE: case PIX_FMT_YUV422P9LE: @@ -2918,7 +3031,7 @@ static av_cold void sws_init_swScale_c(SwsContext *c) case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break; case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break; case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break; - case PIX_FMT_GBR24P : c->lumToYV12 = gbr24pToY_c ; break; +// case PIX_FMT_GBR24P : c->lumToYV12 = gbr24pToY_c ; break; } if (c->alpPixBuf) { switch (srcFormat) { |