mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-23 19:30:05 +00:00
Add unscaled converter from GBRP > 8bit to RGBx48/64.
Fixes ticket #2633. Tested-by: Michael Cinquin
This commit is contained in:
parent
86005184e3
commit
d5978c8678
@ -389,6 +389,151 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
|
||||
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)
|
||||
{
|
||||
int x, h, i;
|
||||
int scale_high = 16 - bpp, scale_low = (bpp - 8) * 2;
|
||||
for (h = 0; h < srcSliceH; h++) {
|
||||
uint16_t *dest = (uint16_t *)(dst + dstStride * h);
|
||||
uint16_t component;
|
||||
|
||||
switch(swap) {
|
||||
case 3:
|
||||
if (alpha) {
|
||||
for (x = 0; x < width; x++) {
|
||||
component = av_bswap16(src[0][x]);
|
||||
*dest++ = av_bswap16(component << scale_high | component >> scale_low);
|
||||
component = av_bswap16(src[1][x]);
|
||||
*dest++ = av_bswap16(component << scale_high | component >> scale_low);
|
||||
component = av_bswap16(src[2][x]);
|
||||
*dest++ = av_bswap16(component << scale_high | component >> scale_low);
|
||||
*dest++ = 0xffff;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < width; x++) {
|
||||
component = av_bswap16(src[0][x]);
|
||||
*dest++ = av_bswap16(component << scale_high | component >> scale_low);
|
||||
component = av_bswap16(src[1][x]);
|
||||
*dest++ = av_bswap16(component << scale_high | component >> scale_low);
|
||||
component = av_bswap16(src[2][x]);
|
||||
*dest++ = av_bswap16(component << scale_high | component >> scale_low);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (alpha) {
|
||||
for (x = 0; x < width; x++) {
|
||||
*dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
|
||||
*dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
|
||||
*dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
|
||||
*dest++ = 0xffff;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < width; x++) {
|
||||
*dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
|
||||
*dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
|
||||
*dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (alpha) {
|
||||
for (x = 0; x < width; x++) {
|
||||
*dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
|
||||
*dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
|
||||
*dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
|
||||
*dest++ = 0xffff;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < width; x++) {
|
||||
*dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
|
||||
*dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
|
||||
*dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (alpha) {
|
||||
for (x = 0; x < width; x++) {
|
||||
*dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
|
||||
*dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
|
||||
*dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
|
||||
*dest++ = 0xffff;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < width; x++) {
|
||||
*dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
|
||||
*dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
|
||||
*dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
src[i] += srcStride[i] >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int planarRgb16ToRgb16Wrapper(SwsContext *c, const uint8_t *src[],
|
||||
int srcStride[], int srcSliceY, int srcSliceH,
|
||||
uint8_t *dst[], int dstStride[])
|
||||
{
|
||||
const uint16_t *src102[] = { (uint16_t *)src[1], (uint16_t *)src[0], (uint16_t *)src[2] };
|
||||
const uint16_t *src201[] = { (uint16_t *)src[2], (uint16_t *)src[0], (uint16_t *)src[1] };
|
||||
int stride102[] = { srcStride[1], srcStride[0], srcStride[2] };
|
||||
int stride201[] = { srcStride[2], srcStride[0], srcStride[1] };
|
||||
const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
|
||||
const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
|
||||
int bits_per_sample = src_format->comp[0].depth_minus1 + 1;
|
||||
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 (src_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) !=
|
||||
(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) {
|
||||
av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
|
||||
src_format->name, dst_format->name);
|
||||
return srcSliceH;
|
||||
}
|
||||
switch (c->dstFormat) {
|
||||
case AV_PIX_FMT_BGR48LE:
|
||||
case AV_PIX_FMT_BGR48BE:
|
||||
gbr16ptopacked16(src102, stride102,
|
||||
dst[0] + srcSliceY * dstStride[0], dstStride[0],
|
||||
srcSliceH, 0, swap, bits_per_sample, c->srcW);
|
||||
break;
|
||||
case AV_PIX_FMT_RGB48LE:
|
||||
case AV_PIX_FMT_RGB48BE:
|
||||
gbr16ptopacked16(src201, stride201,
|
||||
dst[0] + srcSliceY * dstStride[0], dstStride[0],
|
||||
srcSliceH, 0, swap, bits_per_sample, c->srcW);
|
||||
break;
|
||||
case AV_PIX_FMT_RGBA64LE:
|
||||
case AV_PIX_FMT_RGBA64BE:
|
||||
gbr16ptopacked16(src201, stride201,
|
||||
dst[0] + srcSliceY * dstStride[0], dstStride[0],
|
||||
srcSliceH, 1, swap, bits_per_sample, c->srcW);
|
||||
break;
|
||||
case AV_PIX_FMT_BGRA64LE:
|
||||
case AV_PIX_FMT_BGRA64BE:
|
||||
gbr16ptopacked16(src102, stride102,
|
||||
dst[0] + srcSliceY * dstStride[0], dstStride[0],
|
||||
srcSliceH, 1, swap, bits_per_sample, c->srcW);
|
||||
break;
|
||||
default:
|
||||
av_log(c, AV_LOG_ERROR,
|
||||
"unsupported planar RGB conversion %s -> %s\n",
|
||||
src_format->name, dst_format->name);
|
||||
}
|
||||
|
||||
return srcSliceH;
|
||||
}
|
||||
|
||||
static void gbr24ptopacked24(const uint8_t *src[], int srcStride[],
|
||||
uint8_t *dst, int dstStride, int srcSliceH,
|
||||
int width)
|
||||
@ -1070,6 +1215,17 @@ 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_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 ||
|
||||
srcFormat == AV_PIX_FMT_GBRP12LE || srcFormat == AV_PIX_FMT_GBRP12BE ||
|
||||
srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE) &&
|
||||
(dstFormat == AV_PIX_FMT_RGB48LE || dstFormat == AV_PIX_FMT_RGB48BE ||
|
||||
dstFormat == AV_PIX_FMT_BGR48LE || dstFormat == AV_PIX_FMT_BGR48BE ||
|
||||
dstFormat == AV_PIX_FMT_RGBA64LE || dstFormat == AV_PIX_FMT_RGBA64BE ||
|
||||
dstFormat == AV_PIX_FMT_BGRA64LE || dstFormat == AV_PIX_FMT_BGRA64BE))
|
||||
c->swScale = planarRgb16ToRgb16Wrapper;
|
||||
|
||||
if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth_minus1 == 7 &&
|
||||
isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
|
||||
c->swScale = rgbToPlanarRgbWrapper;
|
||||
|
@ -11,7 +11,7 @@
|
||||
./tests/data/images/dpx/%02d.dpx CRC=0xe5b9c023
|
||||
609920 ./tests/data/images/dpx/02.dpx
|
||||
b9f22728f8ff393bf30cf6cbd624fa95 *./tests/data/images/dpx/02.dpx
|
||||
./tests/data/images/dpx/%02d.dpx CRC=0xb6310a70
|
||||
./tests/data/images/dpx/%02d.dpx CRC=0xf38d5830
|
||||
407168 ./tests/data/images/dpx/02.dpx
|
||||
545603630f30dec2768c8ae8d12eb8ea *./tests/data/images/dpx/02.dpx
|
||||
./tests/data/images/dpx/%02d.dpx CRC=0xe72ce131
|
||||
|
Loading…
Reference in New Issue
Block a user