This has the downside of requiring these tables to be recomputed on every
init, but saves ~270 kB of static data.
Signed-off-by: Niklas Haas <git@haasn.dev>
The current logic uses 12-bit linear light math, which is woefully insufficient
and leads to nasty postarization artifacts. This patch simply switches the
internal logic to 16-bit precision.
This raises the memory requirement of these tables from 32 kB to 272 kB.
All relevant FATE tests updated for improved accuracy.
Fixes: #4829
Signed-off-by: Niklas Haas <git@haasn.dev>
Sponsored-by: Sovereign Tech Fund
It makes no difference when the input has an alpha plane, and may end up in
crashes or undefined behavior if it doesn't.
Signed-off-by: James Almer <jamrial@gmail.com>
This patch corrects a C operator precedence issue in fftools/ffmpeg_opt.c
where the abs_start_seek calculation did not yield the expected result
due to incorrect placement of parentheses.
header is previously declared as an int argument then
shadowed in the scope of the loop as a AV1RawOBUHeader.
Signed-off-by: Marth64 <marth64@proxyid.net>
Fixes: signed integer overflow: 529008646 * 8 cannot be represented in type 'int'
Fixes: 383379145/clusterfuzz-testcase-minimized-ffmpeg_dem_CAF_fuzzer-6674045107503104
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: signed integer overflow: -3483479120376300096 - 7442323944145700864 cannot be represented in type 'long'
Fixes: 383187489/clusterfuzz-testcase-minimized-ffmpeg_dem_WEBM_DASH_MANIFEST_fuzzer-4561470580391936
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: NULL ptr use
Fixes: 378634700/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_RV60_fuzzer-5008344043028480
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: Peter Ross <pross@xvid.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: 378634700/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_RV60_fuzzer-5008344043028480
Fixes: assertion failure
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: Peter Ross <pross@xvid.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This way the (slow) allocation of an image is done after various additional checks
Fixes: Timeout
Fixes: 379418967/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_ESCAPE130_fuzzer-6507383574036480
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Switches to av_frame_side_data_remove_by_props(), covering a number of
cases that we previously ignored. Additionally, stop stripping metadata
when merely changing colorspace or color range, since these do not
affect the actual color volume of the image data, only the encoding.
As discussed in the previous commit, we often need a convenient way of
stripping all side data related to a certain aspect of the frame. This helper
accomplishes just that.
I considered also adding a way to match only side data matching *all*
properties, but I think this is sufficiently useless in practise to not warrant
inclusion in the API.
Many filters modify certain aspects of frame data, e.g. through resizing
(vf_*scale* family), color volume mapping (vf_lut*, vf_tonemap*), or
possibly others.
When this happens, we should strip all frame side data that will no
longer be correct/relevant after the operation. For example, changing
the image size should invalidate AV_FRAME_DATA_PANSCAN because the crop
window (given in pixels) no longer corresponds to the actual image size.
For another example, tone-mapping filters (e.g. from HDR to SDR) should
strip all of the dynamic HDR related metadata.
Since there are a lot of different side data types that are affected by such
operations, it makes sense to establish this information in a common, easily
accessible way. The existing side data properties enum is a perfect fit for
this.
While this one was technically supported on account of the generic options
code allowing "none" as a valid alias for 0, not having it listed here meant
it never showed up in e.g. the -h output, and is also inconsistent with other
places in the code that generally add an explicit alias with appropriate
documentation. Reduces user confusion at negligible cost.
Fixes: #9192
Signed-off-by: Niklas Haas <git@haasn.dev>
Sponsored-by: Sovereign Tech Fund
This leverages the previously introduced color management subsystem in order
to adapt between transfer functions and color spaces, as well as for HDR tone
mapping.
Take special care to handle grayscale formats without a colorspace
gracefully.
This is a lightweight wrapper around the underlying color management system,
whose job it is merely to manage the 3DLUT state and apply them to the frame
data. This is where we might add platform-specific optimizations in the future.
I also plan on adding support for more pixel formats in the future. In
particular, we could support YUV or XYZ input formats directly using only
negligible additional code in the 3DLUT setup functions. This would eliminate
the major source of slowdown, which is currently the roundtrip to RGBA64.
The underlying color mapping logic was ported as straightforwardly as possible
from libplacebo, although the API and glue code has been very heavily
refactored / rewritten. In particular, the generalization of gamut mapping
methods is replaced by a single ICC intent selection, and constants have been
hard-coded.
To minimize the amount of overall operations, this gamut mapping LUT now embeds
a direct end-to-end transformation to the output color space; something that
libplacebo does in shaders, but which is prohibitively expensive in software.
In order to preserve compatibility with dynamic tone mapping without severely
regressing performance, we add the ability to generate a pair of "split" LUTS,
one for encoding the input and output to the perceptual color space, and a
third to embed the tone mapping operation. Additionally, this intermediate
space could be used for additional subjective effect (e.g. changing
saturation or brightness).
The big downside of the new approach is that generating a static color mapping
LUT is now fairly slow, as the chromaticity lobe peaks have to be recomputed
for every single RGB value, since correlated RGB colors are not necessarily
aligned in ICh space. Generating a split 3DLUT significantly alleviates this
problem because the expensive step is done as part of the IPT input LUT, which
can share the same hue peak calculation at least for all input intensities.
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.
Swscale currently handles XYZ by embedding a forced conversion to
BT.709 RGB with a hardcoded matrix. This is not ideal, but to preserve the
status quo and avoid any unexpected changes in behavior, this patch merely
fixes the inferred primaries tag to match the reality.
In the future, I would like to handle XYZ properly, via direct conversion
to the target colorspace (or possibly simply by using a more fitting
RGB intermediate like SMPTE428), but for now just keep the status quo.
Logic is loosely on equivalent decisions in libplacebo. The basic idea is to try
and be a bit conservative by treating AVCOL_*_UNSPECIFIED as a no-op, unless the
other primaries set are non-standard / wide-gamut or HDR. This helps avoid
unintended or unexpected colorspace conversions, while forcing it in cases where
we are almost certain it is needed. The major departure from libplacebo semantics
is that we no default to a 1000:1 contrast ration for SDR displays, instead modelling
them as idealized devices with an infinite contrast ratio.
In either case, setting SWS_STRICT overrides this behavior in favor of always
requiring explicit colorspace metadata.
Logic ported from libplacebo's AVFrame helpers. The basic idea is to use the
provided MaxRGB/MaxSCL values to infer what the actual luminance would have
been, which HDR10+ metadata does not provide directly. It's worth pointing out
that this gives us an *upper* bound on the true maximum luminance, so any
error in the estimation cannot result in clipping.