1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-13 21:28:01 +02:00

swscale/range_convert: saturate output instead of limiting input

For bit depths <= 14, the result is saturated to 15 bits.
For bit depths > 14, the result is saturated to 19 bits.

x86_64:
chrRangeFromJpeg8_1920_c:    2126.5   2127.4  (1.00x)
chrRangeFromJpeg16_1920_c:   2331.4   2325.2  (1.00x)
chrRangeToJpeg8_1920_c:      3163.0   3166.9  (1.00x)
chrRangeToJpeg16_1920_c:     3163.7   2152.4  (1.47x)
lumRangeFromJpeg8_1920_c:    1262.2   1263.0  (1.00x)
lumRangeFromJpeg16_1920_c:   1079.5   1080.5  (1.00x)
lumRangeToJpeg8_1920_c:      1860.5   1886.8  (0.99x)
lumRangeToJpeg16_1920_c:     1910.2   1077.0  (1.77x)

aarch64 A55:
chrRangeFromJpeg8_1920_c:   28836.2  28835.2  (1.00x)
chrRangeFromJpeg16_1920_c:  28840.1  28839.8  (1.00x)
chrRangeToJpeg8_1920_c:     44196.2  23074.7  (1.92x)
chrRangeToJpeg16_1920_c:    36527.3  17318.9  (2.11x)
lumRangeFromJpeg8_1920_c:   15388.5  15389.7  (1.00x)
lumRangeFromJpeg16_1920_c:  15389.3  15388.2  (1.00x)
lumRangeToJpeg8_1920_c:     23069.7  19227.8  (1.20x)
lumRangeToJpeg16_1920_c:    19227.8  15387.0  (1.25x)

aarch64 A76:
chrRangeFromJpeg8_1920_c:    6334.7   6324.4  (1.00x)
chrRangeFromJpeg16_1920_c:   6336.0   6339.9  (1.00x)
chrRangeToJpeg8_1920_c:     11474.5   9656.0  (1.19x)
chrRangeToJpeg16_1920_c:     9640.5   6340.4  (1.52x)
lumRangeFromJpeg8_1920_c:    4453.2   4422.0  (1.01x)
lumRangeFromJpeg16_1920_c:   4414.2   4420.9  (1.00x)
lumRangeToJpeg8_1920_c:      6645.0   5949.1  (1.12x)
lumRangeToJpeg16_1920_c:     6005.2   4446.8  (1.35x)

NOTE: all simd optimizations for range_convert have been disabled
      except for x86, which already had the same behaviour.
      they will be re-enabled when they are fixed for each architecture.
This commit is contained in:
Ramiro Polla 2024-09-24 22:29:44 +02:00
parent 536a44e8dc
commit 2d1358a84d
5 changed files with 29 additions and 10 deletions

View File

@ -225,6 +225,10 @@ void ff_chrRangeToJpeg_neon(int16_t *dstU, int16_t *dstV, int width);
av_cold void ff_sws_init_range_convert_aarch64(SwsInternal *c)
{
/* This code is currently disabled because of changes in the base
* implementation of these functions. This code should be enabled
* again once those changes are ported to this architecture. */
#if 0
int cpu_flags = av_get_cpu_flags();
if (have_neon(cpu_flags)) {
@ -238,6 +242,7 @@ av_cold void ff_sws_init_range_convert_aarch64(SwsInternal *c)
}
}
}
#endif
}
av_cold void ff_sws_init_swscale_aarch64(SwsInternal *c)

View File

@ -26,6 +26,10 @@
av_cold void ff_sws_init_range_convert_loongarch(SwsInternal *c)
{
/* This code is currently disabled because of changes in the base
* implementation of these functions. This code should be enabled
* again once those changes are ported to this architecture. */
#if 0
int cpu_flags = av_get_cpu_flags();
if (have_lsx(cpu_flags)) {
@ -52,6 +56,7 @@ av_cold void ff_sws_init_range_convert_loongarch(SwsInternal *c)
}
}
#endif // #if HAVE_LASX
#endif
}
av_cold void ff_sws_init_swscale_loongarch(SwsInternal *c)

View File

@ -28,6 +28,10 @@ void ff_range_chr_from_jpeg_16_rvv(int16_t *, int16_t *, int);
av_cold void ff_sws_init_range_convert_riscv(SwsInternal *c)
{
/* This code is currently disabled because of changes in the base
* implementation of these functions. This code should be enabled
* again once those changes are ported to this architecture. */
#if 0
#if HAVE_RVV
int flags = av_get_cpu_flags();
@ -47,6 +51,7 @@ av_cold void ff_sws_init_range_convert_riscv(SwsInternal *c)
c->chrConvertRange = convs[from].chr;
}
#endif
#endif
}
#define RVV_INPUT(name) \

View File

@ -160,8 +160,10 @@ static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
{
int i;
for (i = 0; i < width; i++) {
dstU[i] = (FFMIN(dstU[i], 30775) * 4663 - 9289992) >> 12; // -264
dstV[i] = (FFMIN(dstV[i], 30775) * 4663 - 9289992) >> 12; // -264
int U = (dstU[i] * 4663 - 9289992) >> 12; // -264
int V = (dstV[i] * 4663 - 9289992) >> 12; // -264
dstU[i] = FFMIN(U, (1 << 15) - 1);
dstV[i] = FFMIN(V, (1 << 15) - 1);
}
}
@ -177,8 +179,10 @@ static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
static void lumRangeToJpeg_c(int16_t *dst, int width)
{
int i;
for (i = 0; i < width; i++)
dst[i] = (FFMIN(dst[i], 30189) * 19077 - 39057361) >> 14;
for (i = 0; i < width; i++) {
int Y = (dst[i] * 19077 - 39057361) >> 14;
dst[i] = FFMIN(Y, (1 << 15) - 1);
}
}
static void lumRangeFromJpeg_c(int16_t *dst, int width)
@ -194,8 +198,10 @@ static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
int32_t *dstU = (int32_t *) _dstU;
int32_t *dstV = (int32_t *) _dstV;
for (i = 0; i < width; i++) {
dstU[i] = ((int)(FFMIN(dstU[i], 30775 << 4) * 4663U - (9289992 << 4))) >> 12; // -264
dstV[i] = ((int)(FFMIN(dstV[i], 30775 << 4) * 4663U - (9289992 << 4))) >> 12; // -264
int U = ((int)(dstU[i] * 4663U - (9289992 << 4))) >> 12; // -264
int V = ((int)(dstV[i] * 4663U - (9289992 << 4))) >> 12; // -264
dstU[i] = FFMIN(U, (1 << 19) - 1);
dstV[i] = FFMIN(V, (1 << 19) - 1);
}
}
@ -215,7 +221,8 @@ static void lumRangeToJpeg16_c(int16_t *_dst, int width)
int i;
int32_t *dst = (int32_t *) _dst;
for (i = 0; i < width; i++) {
dst[i] = ((int)(FFMIN(dst[i], 30189 << 4) * 4769U - (39057361 << 2))) >> 12;
int Y = ((int)(dst[i] * 4769U - (39057361 << 2))) >> 12;
dst[i] = FFMIN(Y, (1 << 19) - 1);
}
}

View File

@ -40,9 +40,6 @@ lum_from_offset: times 4 dd 33561947
SECTION .text
; NOTE: there is no need to clamp the input when converting to jpeg range
; (like we do in the C code) because packssdw will saturate the output.
;-----------------------------------------------------------------------------
; lumConvertRange
;