forked from FFmpeg/FFmpeg
swscale: add ICC intent enum and option
This setting can be used to infuence the type of tone and gamut mapping used internally when color space conversions are required. As discussed at VDD'24, the default was set to relative colorimetric clipping, which is approximately associative, surjective and idempotent. As such, it roundtrips well, although it is strictly speaking not associative on out-of-gamut colors.
This commit is contained in:
parent
7b7c32322d
commit
45f0a7ad33
8 changed files with 62 additions and 8 deletions
|
@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
|
|||
|
||||
API changes, most recent first:
|
||||
|
||||
2024-12-xx - xxxxxxxxxx - lsws 8.13.100 - swscale.h
|
||||
Add enum SwsIntent and SwsContext.intent.
|
||||
|
||||
2024-12-15 - xxxxxxxxxx - lavc 61.27.100 packet.h
|
||||
Add av_container_fifo_alloc_avpacket().
|
||||
|
||||
|
|
|
@ -21071,7 +21071,38 @@ Set libswscale input parameters for scaling algorithms that need them. See
|
|||
complete documentation. If not explicitly specified the filter applies
|
||||
empty parameters.
|
||||
|
||||
@item intent
|
||||
Set the ICC rendering intent to use when transforming between different color
|
||||
spaces. It accepts the following values:
|
||||
|
||||
@table @samp
|
||||
@item perceptual
|
||||
Use a perceptually guided tone and gamut mapping curve. The exact details of
|
||||
the mapping used may change at any time and should not be relied on as stable.
|
||||
This intent is recommended for final viewing of image/video content in typical
|
||||
viewing settings.
|
||||
|
||||
@item relative_colorimetric
|
||||
Statically clip out-of-gamut colors using a colorimetric clipping curve which
|
||||
attempts to find the colorimetrically least dissimilar in-gamut color. This
|
||||
intent performs white point adaptation and black point adaptation. This is
|
||||
the default. This intent is recommended wherever faithful color reproduction
|
||||
is of the utmost importance, even at the cost of clipping.
|
||||
|
||||
@item absolute_colorimetric
|
||||
Hard clip out-of-gamut colors with no attempt at white or black point
|
||||
reproduction. This intent will reproduce in-gamut colors 1:1 on the output
|
||||
display as they would appear on the reference display, assuming the output
|
||||
display is appropriately calibrated.
|
||||
|
||||
@item saturation
|
||||
Performs saturation mapping - that is, stretches the input color volume
|
||||
directly onto the output color volume, in non-linear fashion that preserves the
|
||||
original signal appearance as much as possible. This intent is recommended for
|
||||
signal content evaluation, as it will not lead to any clipping. It is roughly
|
||||
analogous to not performing any color mapping, although it still takes into
|
||||
account the mastering display primaries and any differences in encoding TRC.
|
||||
@end table
|
||||
|
||||
@item size, s
|
||||
Set the video size. For the syntax of this option, check the
|
||||
|
|
|
@ -579,6 +579,7 @@ static int opts_equal(const SwsContext *c1, const SwsContext *c2)
|
|||
c1->src_v_chr_pos == c2->src_v_chr_pos &&
|
||||
c1->dst_h_chr_pos == c2->dst_h_chr_pos &&
|
||||
c1->dst_v_chr_pos == c2->dst_v_chr_pos &&
|
||||
c1->intent == c2->intent &&
|
||||
!memcmp(c1->scaler_params, c2->scaler_params, sizeof(c1->scaler_params));
|
||||
|
||||
}
|
||||
|
|
|
@ -84,6 +84,12 @@ static const AVOption swscale_options[] = {
|
|||
{ "threads", "number of threads", OFFSET(threads), AV_OPT_TYPE_INT, {.i64 = 1 }, .flags = VE, .unit = "threads", .max = INT_MAX },
|
||||
{ "auto", "automatic selection", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = VE, .unit = "threads" },
|
||||
|
||||
{ "intent", "color mapping intent", OFFSET(intent), AV_OPT_TYPE_INT, { .i64 = SWS_INTENT_RELATIVE_COLORIMETRIC }, .flags = VE, .unit = "intent", .max = SWS_INTENT_NB - 1 },
|
||||
{ "perceptual", "perceptual tone mapping", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_INTENT_PERCEPTUAL }, .flags = VE, .unit = "intent" },
|
||||
{ "relative_colorimetric", "relative colorimetric clipping", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_INTENT_RELATIVE_COLORIMETRIC }, .flags = VE, .unit = "intent" },
|
||||
{ "saturation", "saturation mapping", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_INTENT_SATURATION }, .flags = VE, .unit = "intent" },
|
||||
{ "absolute_colorimetric", "absolute colorimetric clipping", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_INTENT_ABSOLUTE_COLORIMETRIC }, .flags = VE, .unit = "intent" },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -162,6 +162,14 @@ typedef enum SwsFlags {
|
|||
SWS_ERROR_DIFFUSION = 1 << 23, ///< Set `SwsContext.dither` instead
|
||||
} SwsFlags;
|
||||
|
||||
typedef enum SwsIntent {
|
||||
SWS_INTENT_PERCEPTUAL = 0, ///< Perceptual tone mapping
|
||||
SWS_INTENT_RELATIVE_COLORIMETRIC = 1, ///< Relative colorimetric clipping
|
||||
SWS_INTENT_SATURATION = 2, ///< Saturation mapping
|
||||
SWS_INTENT_ABSOLUTE_COLORIMETRIC = 3, ///< Absolute colorimetric clipping
|
||||
SWS_INTENT_NB, ///< not part of the ABI
|
||||
} SwsIntent;
|
||||
|
||||
/***********************************
|
||||
* Context creation and management *
|
||||
***********************************/
|
||||
|
@ -226,6 +234,11 @@ typedef struct SwsContext {
|
|||
int dst_v_chr_pos; ///< Destination vertical chroma position
|
||||
int dst_h_chr_pos; ///< Destination horizontal chroma position
|
||||
|
||||
/**
|
||||
* Desired ICC intent for color space conversions.
|
||||
*/
|
||||
int intent;
|
||||
|
||||
/* Remember to add new fields to graph.c:opts_equal() */
|
||||
} SwsContext;
|
||||
|
||||
|
|
|
@ -699,7 +699,7 @@ static_assert(offsetof(SwsInternal, redDither) + DITHER32_INT == offsetof(SwsInt
|
|||
#if ARCH_X86_64
|
||||
/* x86 yuv2gbrp uses the SwsInternal for yuv coefficients
|
||||
if struct offsets change the asm needs to be updated too */
|
||||
static_assert(offsetof(SwsInternal, yuv2rgb_y_offset) == 40332,
|
||||
static_assert(offsetof(SwsInternal, yuv2rgb_y_offset) == 40348,
|
||||
"yuv2rgb_y_offset must be updated in x86 asm");
|
||||
#endif
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "version_major.h"
|
||||
|
||||
#define LIBSWSCALE_VERSION_MINOR 12
|
||||
#define LIBSWSCALE_VERSION_MINOR 13
|
||||
#define LIBSWSCALE_VERSION_MICRO 100
|
||||
|
||||
#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
|
||||
|
|
|
@ -582,7 +582,7 @@ yuv2nv12cX_fn yuv2nv21
|
|||
|
||||
%if ARCH_X86_64
|
||||
struc SwsInternal
|
||||
.padding: resb 40332 ; offsetof(SwsInternal, yuv2rgb_y_offset)
|
||||
.padding: resb 40348 ; offsetof(SwsInternal, yuv2rgb_y_offset)
|
||||
.yuv2rgb_y_offset: resd 1
|
||||
.yuv2rgb_y_coeff: resd 1
|
||||
.yuv2rgb_v2r_coeff: resd 1
|
||||
|
|
Loading…
Add table
Reference in a new issue