diff options
Diffstat (limited to 'chromium/third_party/ffmpeg/libswscale/swscale_unscaled.c')
-rw-r--r-- | chromium/third_party/ffmpeg/libswscale/swscale_unscaled.c | 375 |
1 files changed, 373 insertions, 2 deletions
diff --git a/chromium/third_party/ffmpeg/libswscale/swscale_unscaled.c b/chromium/third_party/ffmpeg/libswscale/swscale_unscaled.c index 4181e0ded7f..6c24854e356 100644 --- a/chromium/third_party/ffmpeg/libswscale/swscale_unscaled.c +++ b/chromium/third_party/ffmpeg/libswscale/swscale_unscaled.c @@ -410,6 +410,192 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], return srcSliceH; } +static void packed16togbra16(const uint8_t *src, int srcStride, + uint16_t *dst[], int dstStride[], int srcSliceH, + int src_alpha, int swap, int shift, int width) +{ + int x, h, i; + int dst_alpha = dst[3] != NULL; + for (h = 0; h < srcSliceH; h++) { + uint16_t *src_line = (uint16_t *)(src + srcStride * h); + switch (swap) { + case 3: + if (src_alpha && dst_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[3][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + } + } else if (dst_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[3][x] = 0xFFFF; + } + } else if (src_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + src_line++; + } + } else { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift); + } + } + break; + case 2: + if (src_alpha && dst_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(*src_line++ >> shift); + dst[1][x] = av_bswap16(*src_line++ >> shift); + dst[2][x] = av_bswap16(*src_line++ >> shift); + dst[3][x] = av_bswap16(*src_line++ >> shift); + } + } else if (dst_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(*src_line++ >> shift); + dst[1][x] = av_bswap16(*src_line++ >> shift); + dst[2][x] = av_bswap16(*src_line++ >> shift); + dst[3][x] = 0xFFFF; + } + } else if (src_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(*src_line++ >> shift); + dst[1][x] = av_bswap16(*src_line++ >> shift); + dst[2][x] = av_bswap16(*src_line++ >> shift); + src_line++; + } + } else { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(*src_line++ >> shift); + dst[1][x] = av_bswap16(*src_line++ >> shift); + dst[2][x] = av_bswap16(*src_line++ >> shift); + } + } + break; + case 1: + if (src_alpha && dst_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(*src_line++) >> shift; + dst[1][x] = av_bswap16(*src_line++) >> shift; + dst[2][x] = av_bswap16(*src_line++) >> shift; + dst[3][x] = av_bswap16(*src_line++) >> shift; + } + } else if (dst_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(*src_line++) >> shift; + dst[1][x] = av_bswap16(*src_line++) >> shift; + dst[2][x] = av_bswap16(*src_line++) >> shift; + dst[3][x] = 0xFFFF; + } + } else if (src_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(*src_line++) >> shift; + dst[1][x] = av_bswap16(*src_line++) >> shift; + dst[2][x] = av_bswap16(*src_line++) >> shift; + src_line++; + } + } else { + for (x = 0; x < width; x++) { + dst[0][x] = av_bswap16(*src_line++) >> shift; + dst[1][x] = av_bswap16(*src_line++) >> shift; + dst[2][x] = av_bswap16(*src_line++) >> shift; + } + } + break; + default: + if (src_alpha && dst_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = *src_line++ >> shift; + dst[1][x] = *src_line++ >> shift; + dst[2][x] = *src_line++ >> shift; + dst[3][x] = *src_line++ >> shift; + } + } else if (dst_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = *src_line++ >> shift; + dst[1][x] = *src_line++ >> shift; + dst[2][x] = *src_line++ >> shift; + dst[3][x] = 0xFFFF; + } + } else if (src_alpha) { + for (x = 0; x < width; x++) { + dst[0][x] = *src_line++ >> shift; + dst[1][x] = *src_line++ >> shift; + dst[2][x] = *src_line++ >> shift; + src_line++; + } + } else { + for (x = 0; x < width; x++) { + dst[0][x] = *src_line++ >> shift; + dst[1][x] = *src_line++ >> shift; + dst[2][x] = *src_line++ >> shift; + } + } + } + for (i = 0; i < 4; i++) + dst[i] += dstStride[i] >> 1; + } +} + +static int Rgb16ToPlanarRgb16Wrapper(SwsContext *c, const uint8_t *src[], + int srcStride[], int srcSliceY, int srcSliceH, + uint8_t *dst[], int dstStride[]) +{ + uint16_t *dst2013[] = { (uint16_t *)dst[2], (uint16_t *)dst[0], (uint16_t *)dst[1], (uint16_t *)dst[3] }; + uint16_t *dst1023[] = { (uint16_t *)dst[1], (uint16_t *)dst[0], (uint16_t *)dst[2], (uint16_t *)dst[3] }; + int stride2013[] = { dstStride[2], dstStride[0], dstStride[1], dstStride[3] }; + int stride1023[] = { dstStride[1], dstStride[0], dstStride[2], dstStride[3] }; + const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat); + const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat); + int bpc = dst_format->comp[0].depth_minus1 + 1; + int alpha = src_format->flags & AV_PIX_FMT_FLAG_ALPHA; + int swap = 0; + if ( HAVE_BIGENDIAN && !(src_format->flags & AV_PIX_FMT_FLAG_BE) || + !HAVE_BIGENDIAN && src_format->flags & AV_PIX_FMT_FLAG_BE) + swap++; + if ( HAVE_BIGENDIAN && !(dst_format->flags & AV_PIX_FMT_FLAG_BE) || + !HAVE_BIGENDIAN && dst_format->flags & AV_PIX_FMT_FLAG_BE) + swap += 2; + + if ((dst_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) != + (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) || bpc < 9) { + av_log(c, AV_LOG_ERROR, "unsupported conversion to planar RGB %s -> %s\n", + src_format->name, dst_format->name); + return srcSliceH; + } + switch (c->srcFormat) { + case AV_PIX_FMT_RGB48LE: + case AV_PIX_FMT_RGB48BE: + case AV_PIX_FMT_RGBA64LE: + case AV_PIX_FMT_RGBA64BE: + packed16togbra16(src[0] + srcSliceY * srcStride[0], srcStride[0], + dst2013, stride2013, srcSliceH, alpha, swap, + 16 - bpc, c->srcW); + break; + case AV_PIX_FMT_BGR48LE: + case AV_PIX_FMT_BGR48BE: + case AV_PIX_FMT_BGRA64LE: + case AV_PIX_FMT_BGRA64BE: + packed16togbra16(src[0] + srcSliceY * srcStride[0], srcStride[0], + dst1023, stride1023, srcSliceH, alpha, swap, + 16 - bpc, c->srcW); + break; + default: + av_log(c, AV_LOG_ERROR, + "unsupported conversion to planar RGB %s -> %s\n", + src_format->name, dst_format->name); + } + + return srcSliceH; +} + static void gbr16ptopacked16(const uint16_t *src[], int srcStride[], uint8_t *dst, int dstStride, int srcSliceH, int alpha, int swap, int bpp, int width) @@ -782,6 +968,160 @@ static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[], return srcSliceH; } +#define BAYER_GBRG +#define BAYER_8 +#define BAYER_RENAME(x) bayer_gbrg8_to_##x +#include "bayer_template.c" + +#define BAYER_GBRG +#define BAYER_16LE +#define BAYER_RENAME(x) bayer_gbrg16le_to_##x +#include "bayer_template.c" + +#define BAYER_GBRG +#define BAYER_16BE +#define BAYER_RENAME(x) bayer_gbrg16be_to_##x +#include "bayer_template.c" + +#define BAYER_GRBG +#define BAYER_8 +#define BAYER_RENAME(x) bayer_grbg8_to_##x +#include "bayer_template.c" + +#define BAYER_GRBG +#define BAYER_16LE +#define BAYER_RENAME(x) bayer_grbg16le_to_##x +#include "bayer_template.c" + +#define BAYER_GRBG +#define BAYER_16BE +#define BAYER_RENAME(x) bayer_grbg16be_to_##x +#include "bayer_template.c" + +#define BAYER_BGGR +#define BAYER_8 +#define BAYER_RENAME(x) bayer_bggr8_to_##x +#include "bayer_template.c" + +#define BAYER_BGGR +#define BAYER_16LE +#define BAYER_RENAME(x) bayer_bggr16le_to_##x +#include "bayer_template.c" + +#define BAYER_BGGR +#define BAYER_16BE +#define BAYER_RENAME(x) bayer_bggr16be_to_##x +#include "bayer_template.c" + +#define BAYER_RGGB +#define BAYER_8 +#define BAYER_RENAME(x) bayer_rggb8_to_##x +#include "bayer_template.c" + +#define BAYER_RGGB +#define BAYER_16LE +#define BAYER_RENAME(x) bayer_rggb16le_to_##x +#include "bayer_template.c" + +#define BAYER_RGGB +#define BAYER_16BE +#define BAYER_RENAME(x) bayer_rggb16be_to_##x +#include "bayer_template.c" + +static int bayer_to_rgb24_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]) +{ + uint8_t *dstPtr= dst[0]; + const uint8_t *srcPtr= src[0]; + int i; + void (*copy) (const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width); + void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width); + + switch(c->srcFormat) { +#define CASE(pixfmt, prefix) \ + case pixfmt: copy = bayer_##prefix##_to_rgb24_copy; \ + interpolate = bayer_##prefix##_to_rgb24_interpolate; \ + break; + CASE(AV_PIX_FMT_BAYER_BGGR8, bggr8) + CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le) + CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be) + CASE(AV_PIX_FMT_BAYER_RGGB8, rggb8) + CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le) + CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be) + CASE(AV_PIX_FMT_BAYER_GBRG8, gbrg8) + CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le) + CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be) + CASE(AV_PIX_FMT_BAYER_GRBG8, grbg8) + CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le) + CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be) +#undef CASE + default: return 0; + } + + copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); + srcPtr += 2 * srcStride[0]; + dstPtr += 2 * dstStride[0]; + + for (i = 2; i < srcSliceH - 2; i += 2) { + interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); + srcPtr += 2 * srcStride[0]; + dstPtr += 2 * dstStride[0]; + } + + copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); + return srcSliceH; +} + +static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, + int srcSliceH, uint8_t* dst[], int dstStride[]) +{ + const uint8_t *srcPtr= src[0]; + uint8_t *dstY= dst[0]; + uint8_t *dstU= dst[1]; + uint8_t *dstV= dst[2]; + int i; + void (*copy) (const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv); + void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv); + + switch(c->srcFormat) { +#define CASE(pixfmt, prefix) \ + case pixfmt: copy = bayer_##prefix##_to_yv12_copy; \ + interpolate = bayer_##prefix##_to_yv12_interpolate; \ + break; + CASE(AV_PIX_FMT_BAYER_BGGR8, bggr8) + CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le) + CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be) + CASE(AV_PIX_FMT_BAYER_RGGB8, rggb8) + CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le) + CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be) + CASE(AV_PIX_FMT_BAYER_GBRG8, gbrg8) + CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le) + CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be) + CASE(AV_PIX_FMT_BAYER_GRBG8, grbg8) + CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le) + CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be) +#undef CASE + default: return 0; + } + + copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table); + srcPtr += 2 * srcStride[0]; + dstY += 2 * dstStride[0]; + dstU += dstStride[1]; + dstV += dstStride[1]; + + for (i = 2; i < srcSliceH - 2; i += 2) { + interpolate(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table); + srcPtr += 2 * srcStride[0]; + dstY += 2 * dstStride[0]; + dstU += dstStride[1]; + dstV += dstStride[1]; + } + + copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table); + return srcSliceH; +} + #define isRGBA32(x) ( \ (x) == AV_PIX_FMT_ARGB \ || (x) == AV_PIX_FMT_RGBA \ @@ -1245,7 +1585,7 @@ void ff_get_unscaled_swscale(SwsContext *c) c->swscale = ff_yuv2rgb_get_func_ptr(c); } - if (srcFormat == AV_PIX_FMT_YUV410P && + if (srcFormat == AV_PIX_FMT_YUV410P && !(dstH & 3) && (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) { c->swscale = yvu9ToYv12Wrapper; @@ -1277,6 +1617,18 @@ void ff_get_unscaled_swscale(SwsContext *c) if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat)) c->swscale = planarRgbToRgbWrapper; + if ((srcFormat == AV_PIX_FMT_RGB48LE || srcFormat == AV_PIX_FMT_RGB48BE || + srcFormat == AV_PIX_FMT_BGR48LE || srcFormat == AV_PIX_FMT_BGR48BE || + srcFormat == AV_PIX_FMT_RGBA64LE || srcFormat == AV_PIX_FMT_RGBA64BE || + srcFormat == AV_PIX_FMT_BGRA64LE || srcFormat == AV_PIX_FMT_BGRA64BE) && + (dstFormat == AV_PIX_FMT_GBRP9LE || dstFormat == AV_PIX_FMT_GBRP9BE || + dstFormat == AV_PIX_FMT_GBRP10LE || dstFormat == AV_PIX_FMT_GBRP10BE || + dstFormat == AV_PIX_FMT_GBRP12LE || dstFormat == AV_PIX_FMT_GBRP12BE || + dstFormat == AV_PIX_FMT_GBRP14LE || dstFormat == AV_PIX_FMT_GBRP14BE || + dstFormat == AV_PIX_FMT_GBRP16LE || dstFormat == AV_PIX_FMT_GBRP16BE || + dstFormat == AV_PIX_FMT_GBRAP16LE || dstFormat == AV_PIX_FMT_GBRAP16BE )) + c->swscale = Rgb16ToPlanarRgb16Wrapper; + if ((srcFormat == AV_PIX_FMT_GBRP9LE || srcFormat == AV_PIX_FMT_GBRP9BE || srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE || srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE || @@ -1293,12 +1645,28 @@ void ff_get_unscaled_swscale(SwsContext *c) isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP) c->swscale = rgbToPlanarRgbWrapper; + if (isBayer(srcFormat)) { + if (dstFormat == AV_PIX_FMT_RGB24) + c->swscale = bayer_to_rgb24_wrapper; + else if (dstFormat == AV_PIX_FMT_YUV420P) + c->swscale = bayer_to_yv12_wrapper; + else if (!isBayer(dstFormat)) { + av_log(c, AV_LOG_ERROR, "unsupported bayer conversion\n"); + av_assert0(0); + } + } + /* bswap 16 bits per pixel/component packed formats */ - if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) || + if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_BGGR16) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_RGGB16) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GBRG16) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GRBG16) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR48) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) || + 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_GBRP9) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP10) || @@ -1311,6 +1679,7 @@ void ff_get_unscaled_swscale(SwsContext *c) IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565) || + IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_XYZ12) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P9) || IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P10) || @@ -1384,6 +1753,8 @@ void ff_get_unscaled_swscale(SwsContext *c) ff_get_unscaled_swscale_bfin(c); if (ARCH_PPC) ff_get_unscaled_swscale_ppc(c); +// if (ARCH_ARM) +// ff_get_unscaled_swscale_arm(c); } /* Convert the palette to the same packed 32-bit format as the palette */ |