100 Commits
Author SHA1 Message Date
Ramiro Polla 2576e09434 swscale/aarch64/ops: simplify process function generation
There was no good reason to have it as an SwsAArch64OpType.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-10 01:47:11 +02:00
Ramiro Polla 19250a1846 swscale/aarch64/ops: use plain ret instruction
Use a call/ret pair instead of awkwardly exporting and then jumping
back to the return label.

This is similar to c29465bcb6, but for aarch64.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-10 01:47:10 +02:00
Ramiro Polla 061dc9ab6d swscale/aarch64/rasm: add blr instruction
And a64op_lr() helper for LR register.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-10 01:46:29 +02:00
Ramiro Polla ecba7e1d42 swscale/aarch64/rasm: split conditional and unconditional branch instructions
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-10 01:46:29 +02:00
Ramiro Polla 692951d1c2 swscale/tests/sws_ops_aarch64: fix skipping of scaling ops
Scaling ops were add to ff_sws_enum_op_lists() in 1d841635. But the
code that skipped scaling ops in convert_to_aarch64_impl() wasn't
taking into consideration that, in sws_ops_aarch64, the scaling ops
aren't folded into read ops.

Also updates libswscale/aarch64/ops_entries.c with the new entries.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-10 01:46:29 +02:00
Ramiro Polla f8af47b640 build: remove checkasm_header_config_generated.h on distclean
Forgotten in 4569ab7eaa.
2026-06-06 23:58:13 +02:00
Ramiro Polla 025d6330a5 swscale/aarch64/ops_asmgen: fold impl pointer increment into loading of continuation address
This commit reduces every kernel by one instruction, for example:
 function ff_sws_clear_8_u16_0001_neon, export=1, jumpable=1
-        ldr             x0, [x1]                        // SwsFuncPtr cont = impl->cont;
         ldr             q16, [x1, #16]                  // v128 clear_vec = impl->priv.v128;
+        ldr             x0, [x1], #32                   // SwsFuncPtr cont = (impl++)->cont;
         dup             v0.8h, v16.h[0]                 // vl[0] = broadcast(clear_vec[0])
-        add             x1, x1, #32                     // impl += 1;
         br              x0                              // jump to cont
 endfunc

A55: Overall speedup=1.066x faster, min=0.881x max=1.288x
A76: Overall speedup=1.012x faster, min=0.570x max=1.546x

The large min/max differences are due to pathological branch miss cases
that happen either before of after this commit.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-06 11:54:14 +00:00
Ramiro Polla 20b0a4faaa tests/fate: add fate-sws-unstable test
The fate test for unscaled conversions (fate-sws-unscaled) does not
test the filtering (scaling) paths.

This commit adds a test for all the scaling paths for the new swscale
code, but only runs 2% of the tests (otherwise this test alone would
take about two and a half minutes on a modern x86_64 machine).

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-05 22:37:18 +02:00
Ramiro PollaandNiklas Haas 016cee7a02 tests/fate/sws-unscaled: constrain to -backends unstable
This is more explicit than -flags unstable, because it also excludes
any pixel formats that are only handled by the legacy code.

Sponsored-by: Sovereign Tech Fund
Co-authored-by: Niklas Haas <git@haasn.dev>
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-05 22:35:55 +02:00
Ramiro Polla 59166b4131 swscale/input: fix rgbf32 input (add half input functions)
The rgbf32 input code was missing the subsampled input functions.

This fixes:
$ ./libswscale/tests/swscale -scaler none -src rgbf32be -dst rgb565be
rgbf32be 96x96 -> rgb565be 96x96, flags=0x0 dither=1 scaler=0/0, SSIM={Y=0.999820 U=0.932819 V=0.924956 A=1.000000} loss=1.436615e-02
rgbf32be 96x96 -> rgb565be 96x96, flags=0x0 dither=1 scaler=0/0
  loss 1.436615e-02 is WORSE by 1.413935e-02, expected loss 2.267957e-04

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-05 22:33:58 +02:00
Ramiro Polla 6b7fd40e25 swscale/swscale_unscaled: disable unscaled copy from yaf32be to grayf32be
yaf32be input wasn't being properly filtered out of the simple copy
condition when converting to grayf32be, which caused half the luma
plane to be interleaved with half the alpha plane, instead of just
copying the luma plane.

This fixes:
$ ./libswscale/tests/swscale -scaler none -src yaf32be -dst grayf32be
yaf32be 96x96 -> grayf32be 96x96, flags=0x0 dither=1 scaler=0/0, SSIM={Y=0.866842 U=1.000000 V=1.000000 A=1.000000} loss=1.065262e-01
yaf32be 96x96 -> grayf32be 96x96, flags=0x0 dither=1 scaler=0/0
  loss 1.065262e-01 is WORSE by 1.065202e-01, expected loss 6.020069e-06

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-05 22:33:37 +02:00
Ramiro Polla 3977bca9f4 swscale/utils: improve check for float formats that will be converted to uint16_t
This was triggering an assertion in x86:
$ ./libswscale/tests/swscale -scaler none -backends unstable -src rgb24 -dst yaf32be
Assertion c->srcBpc == 16 failed at src/libswscale/x86/swscale.c:637
Aborted

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-05 22:31:09 +02:00
Ramiro Polla c7046f0ab3 swscale/ops_backend: add missing float clear pattern
This fixes:
$ ./libswscale/tests/swscale -scaler none -backends unstable -src rgb24 -dst yaf32be

... and exposes another bug in x86 when -cpuflags 0 is not passed,
which will be fixed in next commit.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-05 22:29:24 +02:00
Ramiro Polla fcaafd2c11 swscale/tests/swscale: add -scaler/-scaler_sub parameters to set scaler algorithm
The -unscaled parameter has been removed in favour of "-scaler none".

Some legacy scalers cannot be selected with these options (i.e.: SWS_X
and SWS_FAST_BILINEAR). To test these, the -flags parameter shoule be
used instead.

This option sets the scaler/scaler_sub fields in SwsContext. There is a
comment about these fields in struct SwsContext:

  Note: Does not affect the legacy (stateful) API.

This comment is not entirely correct, since scaler/scaler_sub are taken
into consideration to select the algorithm, but that doesn't update the
flags field, which is still used to select implementations:

libswscale/x86/swscale.c:574:            if (c->opts.flags & SWS_FAST_BILINEAR && c->canMMXEXTBeUsed) {
libswscale/ppc/swscale_vsx.c:2033:            if (c->opts.flags & SWS_FAST_BILINEAR && c->opts.dst_w >= c->opts.src_w && c->chrDstW >= c->chrSrcW) {
libswscale/swscale_unscaled.c:2465:        && (!needsDither || (c->opts.flags&(SWS_FAST_BILINEAR|SWS_POINT))))
libswscale/swscale_unscaled.c:2650:    if (c->opts.flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
libswscale/utils.c:1279:            && !(sws->flags & SWS_FAST_BILINEAR)
libswscale/utils.c:1388:         (flags & SWS_FAST_BILINEAR)))
libswscale/utils.c:1417:            && (flags & SWS_FAST_BILINEAR)) {
libswscale/utils.c:1437:    if (flags & SWS_FAST_BILINEAR) {
libswscale/utils.c:1648:        if (c->canMMXEXTBeUsed && (flags & SWS_FAST_BILINEAR)) {
libswscale/swscale.c:678:            if (c->opts.flags & SWS_FAST_BILINEAR) {

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-05 03:00:31 +02:00
Ramiro Polla a16e674f7f swscale/tests/swscale: add -api parameter (supersedes -legacy parameter)
The "-legacy 1" option was added in 101a2f6fc6 to run the main
conversion with the legacy scaler. This was done by forcing the use of
the legacy API. This way, it was possible to pass "-flags unstable" and
still ensure the legacy scaler path was being taken.

New legacy-related parameters will be added to the test tool, so it
makes sense to rename the -legacy option to reflect what it was
actually doing.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-04 22:55:30 +02:00
Ramiro Polla c458346de2 swscale/tests/swscale: reuse init_frame() for src
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-04 22:54:33 +02:00
Ramiro Polla b9968758ab swscale/tests/swscale: add optional destination size to -s option
This lets us test specific scaling operations, for example:
$ ./libswscale/tests/swscale -s 96x96:128x128 -src yuva444p -dst rgb24 -flags unstable+neighbor
yuva444p 96x96 -> rgb24 128x128, flags=0x100010 dither=1, SSIM={Y=0.999932 U=0.999957 V=0.999937 A=1.000000} loss=6.514788e-05

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-04 22:54:30 +02:00
Ramiro Polla 2e50831755 swscale/tests/swscale: propagate ret out of parse_options()
This will make it easier to keep function-scoped variables.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-06-04 22:54:27 +02:00
Ramiro Polla cc0d904795 Revert "swscale/tests/swscale: check if formats require the legacy path with -hw"
This reverts commit ac611d3120.
2026-06-04 22:54:23 +02:00
Ramiro Polla 0ac3b00a18 avcodec/mjpegdec: simplify bayer width handling
Double s->avctx->width directly, simplifying width-related code in
ljpeg_decode_rgb_scan().
2026-05-26 11:19:14 +02:00
Ramiro Polla 2065ead16e avcodec/mjpegdec: remove redundant vpred variable for bayer
The vpred variable in ljpeg_decode_rgb_scan() is redundant with
buffer[0][i], which is used by the generic codepath.
2026-05-26 11:19:14 +02:00
Ramiro Polla 3040962167 swscale/swscale_unscaled: fix packed30togbra10() and gbr16ptopacked30() for GBRP 10 and 12 bit MSB formats
The formats added in e93de9948d keep the values in the most significant
bits of the uint16_t, and packed30togbra10() and gbr16ptopacked30()
weren't taking into consideration the shift field from AVComponentDescriptor.

Reproducible with:
$ ./libswscale/tests/swscale -unscaled 1 -src gbrp10msbbe -dst x2rgb10le
$ ./libswscale/tests/swscale -unscaled 1 -src x2rgb10le -dst gbrp10msbbe
2026-05-25 22:44:21 +00:00
Ramiro Polla 20b009e301 avformat/webp: add Animated WebP demuxer
Original work by Josef Zlomek <josef@pex.com>

Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-05-19 11:36:10 +02:00
Ramiro Polla a3d8ba6613 avcodec/webp: add support for Animated WebP decoding
Fixes: 4907

Adds Animated WebP feature according to spec:
https://developers.google.com/speed/webp/docs/riff_container#animation

Original work by Josef Zlomek <josef@pex.com>
and Thilo Borgmann <thilo.borgmann@mail.de>

Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-05-19 11:36:10 +02:00
Ramiro Polla 2ca634f5db avcodec/codec_id: add Animated WebP codec ID and descriptor
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-05-19 11:36:10 +02:00
Ramiro Polla d0a84c660a swscale/unscaled: fix rgbToRgbWrapper for non-native-endian formats
The fix from 5fa2a65c11 introduced a regression for non-native-endian
formats (such as rgb565be on a little-endian system).

Reproducible with:
$ ./libswscale/tests/swscale -unscaled 1 -src rgb565be -dst rgb24

Also:
$ ./ffmpeg_g -i /opt/samples/jpegls/128.jls -vf "scale=size=512x512,format=rgb24,scale=flags=neighbor,format=rgb565be" -f rawvideo -vframes 1 -y rgb565be.raw
$ magick -size 512x512 -endian MSB RGB565:rgb565be.raw output.png
$ ./ffplay_g output.png

(note: don't use ffmpeg to convert from rgb565be.raw to output for the
test above since it will perform the same bug and cancel out the error)
2026-05-15 14:21:50 +00:00
Ramiro Polla d812c8b0eb swscale/tests/swscale: log test parameters on loss error
When running with "-v 0", the test parameters were not being printed,
which made it hard to track down which conversion the error referred
to.

Now the test parameters are logged with av_log() when a loss error
happens.
2026-05-15 14:12:48 +00:00
Ramiro Polla 1cc9b15bab swscale/tests/swscale: fix -p option when -flags and/or -unscaled are used
The -p, -flags, and -unscaled options all affected the decision to
select a subsample of the tests to run. When specifying -p 0.1, about
57% of the tests would run instead of the expect 10%.

This commit fixes this by separating -p from -flags and -unscaled.
2026-05-15 14:12:48 +00:00
Ramiro Polla 24d432e227 swscale/tests/swscale: improve help text for -p option 2026-05-15 14:12:48 +00:00
Ramiro PollaandMartin Storsjö 8d9c1db95d arm/simple_idct_arm: Reindent previously unindented code 2026-04-29 13:53:07 +03:00
Ramiro Polla 08f56d4898 avcodec/webp: remove write-only lossless field from WebPContext 2026-04-23 16:46:42 +00:00
Ramiro Polla 9e8e82308b avcodec/webp: use av_fourcc2str() to print fourccs 2026-04-23 16:46:42 +00:00
Ramiro Polla 0cd2bbe4f4 avformat/apngdec: fix playback of piped apng files
The check for avio_size() made apng_read_header() return an error
instead of just disabling looping.
2026-04-23 16:46:21 +00:00
Ramiro Polla 2e92764b86 avformat/apngdec: remove unused function argument 2026-04-23 16:46:21 +00:00
Ramiro Polla 49a2d426e9 configure: collapse else + if into elif 2026-04-13 12:46:49 +00:00
Ramiro Polla 31f280e1e6 configure: add missing quotes around user-specified tool paths
Found-by: Luke Jolliffe <luke.jolliffe@bbc.co.uk>
2026-04-13 12:46:49 +00:00
Ramiro Polla c1d4fe8b44 configure: fix html docs generation when makeinfo is disabled
The makeinfo_html variable wasn't being disabled when the makeinfo test
failed, which prevented texi2html from being probed.

Fixes 589da160b2.

Found-by: Luke Jolliffe <luke.jolliffe@bbc.co.uk>
2026-04-13 12:46:49 +00:00
Ramiro Polla 1f6699ef26 ffbuild/common: remove DBG=1 to preprocess external asm
It had been added in bc8e044d (2015), and broken in 3ddae9ee (2017).

Nobody has complained since, so it's safe to assume that it is not
being used.
2026-04-03 16:15:33 +02:00
Ramiro Polla 53537f6cf5 swscale/aarch64: mark CPS kernel functions as indirect branch targets
Only the process functions are entered via an indirect _call_ from C.
The kernel functions and process_return are dispatched to by indirect
_branches_ instead (continuation-passing style design).

Make use of the recently added "jumpable" parameter to the function
macro in libavutil/aarch64/asm.S to fix these functions when BTI is
enabled.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-31 11:48:52 +00:00
Ramiro Polla af443abe99 aarch64: Add support for indirect branch targets in the function macro
The function macro emits AARCH64_VALID_CALL_TARGET for exported symbols,
marking them as valid destinations for indirect _calls_. Functions that
are reached by indirect _branches_ (i.e. tail-call dispatch chains
where the link register is not set) require AARCH64_VALID_JUMP_TARGET
instead.

This commit adds a "jumpable" parameter to the function macro that, when
set, emits AARCH64_VALID_JUMP_TARGET instead of AARCH64_VALID_CALL_TARGET.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-31 11:48:52 +00:00
Ramiro Polla 2517c328fc swscale/aarch64: add NEON sws_ops backend
This commit pieces together the previous few commits to implement the
NEON backend for sws_ops.

In essence, a tool which runs on the target (sws_ops_aarch64) is used
to enumerate all the functions that the backend needs to implement. The
list it generates is stored in the repository (ops_entries.c).

The list from above is used at build time by a code generator tool
(ops_asmgen) to implement all the sws_ops functions the NEON backend
supports, and generate a lookup function in C to retrieve the assembly
function pointers.

At runtime, the NEON backend fetches the function pointers to the
assembly functions and chains them together in a continuation-passing
style design, similar to the x86 backend.

The following speedup is observed from legacy swscale to NEON:
A520: Overall speedup=3.780x faster, min=0.137x max=91.928x
A720: Overall speedup=4.129x faster, min=0.234x max=92.424x

And the following from the C sws_ops implementation to NEON:
A520: Overall speedup=5.513x faster, min=0.927x max=14.169x
A720: Overall speedup=4.786x faster, min=0.585x max=20.157x

The slowdowns from legacy to NEON are the same for C/x86. Mostly low
bit-depth conversions that did not perform dithering in legacy.

The 0.585x outlier from C to NEON is gbrpf32le -> gbrapf32le, which is
mostly memcpy with the C implementation. All other conversions are
better.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-30 11:38:35 +00:00
Ramiro Polla 534757926f swscale/aarch64: introduce ops_asmgen for NEON backend
The NEON sws_ops backend follows the same continuation-passing style
design as the x86 backend.

Unlike the C and x86 backends, which implement the various operation
functions through the use of templates and preprocessor macros, the
NEON backend uses a build-time code generator, which is introduced by
this commit.

This code generator has two modes of operation:
 -ops:
  Generates an assembly file in GNU assembler syntax targeting AArch64,
  which implements all the sws_ops functions the NEON backend supports.
 -lookup:
  Generates a C function with a hierarchical condition chain that
  returns the pointer to one of the functions generated above, based on
  a given set of parameters derived from SwsOp.

This is the core of the NEON sws_ops backend.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-30 11:38:35 +00:00
Ramiro Polla 991611536c swscale/aarch64: introduce a runtime aarch64 assembler interface
The runtime assembler interface provides an instruction-level IR and
builder API tailored to the needs of the swscale dynamic pipeline.
It is not meant to be a general purpose assembler interface.

Currently only a static file backend, which emits GNU assembler text,
has been implemented. In the future, this interface will be used to
write functions dynamically at runtime.

This code will be compiled both for runtime usage to generate optimized
functions and for build-time usage to generate static assembly files.
Therefore, it must not depend on internal FFmpeg libraries.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-30 11:38:35 +00:00
Ramiro Polla a1bfaa0e78 swscale/aarch64: introduce tool to enumerate sws_ops for NEON backend
The NEON sws_ops backend will use a build-time code generator for the
various operation functions it needs to implement. This build time code
generator (ops_asmgen) will need a list of the operations that must be
implemented. This commit adds a tool (sws_ops_aarch64) that generates
such a list (ops_entries.c).

The list is generated by iterating over all possible conversion
combinations and collecting the parameters for each NEON assembly
function that has to be implemented, defined by an unique set of
parameters derived from SwsOp. Whenever swscale evolves, with improved
optimization passes, new pixel formats, or improvements to the backend
itself, this file (ops_entries.c) should be regenerated by running:
    $ make sws_ops_entries_aarch64

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-30 11:38:35 +00:00
Ramiro PollaandNiklas Haas b6e470467e swscale/tests/sws_ops: add -v option to set log verbosity
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-28 16:48:13 +00:00
Ramiro Polla 5640bd3a4f swscale/tests/swscale: require reference file to perform comparisons
The legacy scaler is no longer implicitly used to generate a reference
to perform comparisons for every conversion. It is now up to the user
to generate a reference file and use it as input for a separate run to
perform comparisons.

It is now possible to compare against previous runs of the graph-based
scaler, for example to test for newer optimizations.

This reduces the overall time necessary to obtain speedup numbers from
the legacy scaler to the graph-based scaler (or any other comparison,
for that matter) since the reference must only be run once.

For example, to check the speedup between the legacy scaler and the
graph-based scaler:
  ./libswscale/tests/swscale [...] -bench 50 -legacy 1 > legacy_ref.txt
  ./libswscale/tests/swscale [...] -bench 50 -ref legacy_ref.txt

If no -ref file is specified, we are assuming that we are generating a
reference file, and therefore all information is printed (including
ssim/loss, and benchmarks if -bench is used).

If a -ref file is specified, the output printed depends on whether we
are testing for correctness (ssim/loss only) or benchmarking (time/
speedup only, along with overall speedup).

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 5146519131 swscale/tests/swscale: add -pretty option to align fields in output
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla d1779ece67 swscale/tests/swscale: print number of iterations in benchmark output
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 1568cae66f swscale/tests/swscale: some tweaks to the output format
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 6ed173f238 swscale/tests/swscale: always print loss in output
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 822d592575 swscale/tests/swscale: make loss printing code more consistent
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 1980d8ba8a swscale/tests/swscale: remove duplicate printing of parameters on error
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla b03ff92567 swscale/tests/swscale: print losses using scientific notation
This emphasizes the order of magnitude of the loss, which is what is
important for us.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 739d9eca59 swscale/tests/swscale: be more strict with reference file format
The format of the reference file is the output which is printed to
stdout from this tool itself.

Malformed reference files cause an error, with a more descriptive error
message. Running a subset of the reference conversions is still
supported through -src and/or -dst.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 041b6f330f swscale/tests/swscale: indent after previous commit
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 6780353460 swscale/tests/swscale: restore reference file functionality
The test results (along with SSIM) are printed to stdout again so that
the output can be parsed by -ref.

Benchmark results have also been added to the output.

We still need to re-run the reference tests to perform benchmarks, but
this will be simplified in the next few commits.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 0b427ea47e swscale/tests/swscale: reorder test results output
The conversion parameters, ssim/loss, and benchmark results will
eventually be merged into the same output line.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 58cdd89789 swscale/tests/swscale: allow passing -bench 0 to disable benchmarks
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 101a2f6fc6 swscale/tests/swscale: add option to run main conversion with legacy scaler
The low bit depth workaround code is duplicated in this commit, but the
other occurrence will be removed in a few commits, so I see no reason
to factor it out.

The legacy scaler still has some conversions that give results much
worse than the expected loss, but we still want them as reference, so
we don't trigger expected loss errors on conversions with the legacy
scaler.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 3eb178a197 swscale/tests/swscale: split scale_new() out of run_test()
We will eventually be able to select between running the new graph-based
scaler or the legacy scaler.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla c27df6ccc9 swscale/tests/swscale: add helper function to log sws_scale_frame() failures
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla c6d78efa9b swscale/tests/swscale: split init_frame() out of run_test()
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 7e635337cf swscale/tests/swscale: introduce struct test_results to collect results
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 8d35328e54 swscale/tests/swscale: split print_results() out of run_test()
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 2b0e1920e5 swscale/tests/swscale: propagate error out of run_test()
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 2222b523f2 swscale/tests/swscale: cosmetics (avoid assignments in conditions) 2026-03-14 06:13:19 +00:00
Ramiro Polla 713979919d Revert "tests/swscale: check supported inputs for legacy swscale separately"
Support for input and output formats are already checked in run_self_tests().

This reverts commit a22faeb992.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-14 06:13:19 +00:00
Ramiro Polla 72167e5150 avcodec/mjpegdec: deprecate extern_huff option 2026-03-12 14:47:01 +01:00
Ramiro Polla e3ee346749 swscale/tests/swscale: add -s option to set frame size
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-11 08:05:08 +00:00
Ramiro Polla 5c5444db59 swscale/tests/swscale: avoid redundant ref->src conversions
The ref->src conversion only needs to be performed once per source
pixel format.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-11 08:05:08 +00:00
Ramiro Polla a09cddc803 swscale/tests/swscale: make auxiliary conversions bitexact and accurate_rnd
This prevents the propagation of dither_error across frames, and should
also improve reproducibility across platforms.

Also remove setting of flags for sws_src_dst early on, since it will
inevitably be overwritten during the tests.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-11 08:05:08 +00:00
Ramiro Polla d935000f09 swscale/tests/swscale: give names to SwsContext variables 2026-03-11 08:05:08 +00:00
Ramiro Polla 49b1e214cf swscale/tests/swscale: pass opts and mode arguments as const pointers 2026-03-11 08:05:08 +00:00
Ramiro Polla e34071e7d5 swscale/tests/swscale: split init_ref() out of main()
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-11 08:05:08 +00:00
Ramiro Polla f83c9718ec swscale/tests/swscale: split parse_options() out of main()
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-11 08:05:08 +00:00
Ramiro Polla 953efc9f56 swscale/tests/swscale: remove hardcoded dimension checks
Remove dimension checks originally added to please static analysis
tools. There is little reason to have arbitrary limits in this
developer test tool. The reference files are under control by the user.

This reverts f70a651b3f and c0f0bec2f2.
2026-03-11 08:05:08 +00:00
Ramiro Polla 955cf563c8 swscale/tests/swscale: always allocate frame in scale_legacy()
Legacy swscale may overwrite the pixel formats in the context (see
handle_formats() in libswscale/utils.c). This may lead to an issue
where, when sws_frame_start() allocates a new frame, it uses the wrong
pixel format.

Instead of fixing the issue in swscale, just make sure dst is always
allocated prior to calling the legacy scaler.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-03-11 08:05:08 +00:00
Ramiro Polla 4792440ab8 swscale/unscaled: fix planarCopyWrapper for float formats with same endianness 2026-03-09 08:22:58 +00:00
Ramiro Polla 252ab61726 avutil/frame: fix typos 2026-03-07 00:54:49 +00:00
Ramiro Polla 493dfc356f swscale/swscale_internal: fix typos in flag names 2026-03-05 20:38:55 +01:00
Ramiro Polla 23bb7c3907 swscale/ops_backend: mark unreachable branch
The pixel format for the process loops have already been checked at
this point to be valid.

The switch added in e4abfb8e51 returns AVERROR(EINVAL) in the default
case without calling ff_sws_op_chain_free(chain), but there's no need
to free it since we mark this branch as unreachable.
2026-02-27 16:44:19 +00:00
Ramiro Polla f436d885fc swscale/swscale: fix typos 2026-02-26 18:36:46 +00:00
Ramiro Polla c9977acbc6 swscale/ops: clear range values SWS_OP_{MIN,MAX}
This gives partial range values on conversions with floats, after the
values have been clamped.

 gbrpf32be -> rgb8:
   [f32 XXXX -> zzzX] SWS_OP_READ         : 3 elem(s) planar >> 0
   [f32 ...X -> ...X] SWS_OP_SWAP_BYTES
   [f32 ...X -> ...X] SWS_OP_SWIZZLE      : 2013
   [f32 ...X -> ...X] SWS_OP_LINEAR       : diag3 [[7 0 0 0 0] [0 7 0 0 0] [0 0 3 0 0] [0 0 0 1 0]]
   [f32 ...X -> ...X] SWS_OP_DITHER       : 16x16 matrix + {0 3 2 5}
   [f32 ...X -> ...X] SWS_OP_MAX          : {0 0 0 0} <= x
+    min: {0, 0, 0, _}, max: {nan, nan, nan, _}
   [f32 ...X -> ...X] SWS_OP_MIN          : x <= {7 7 3 _}
+    min: {0, 0, 0, _}, max: {7, 7, 3, _}
   [f32 ...X -> +++X] SWS_OP_CONVERT      : f32 -> u8
+    min: {0, 0, 0, _}, max: {7, 7, 3, _}
   [ u8 ...X -> +XXX] SWS_OP_PACK         : {3 3 2 0}
-    min: {0, _, _, _}, max: {0, _, _, _}
+    min: {0, _, _, _}, max: {255, _, _, _}
   [ u8 .XXX -> +XXX] SWS_OP_WRITE        : 1 elem(s) packed >> 0
-    min: {0, _, _, _}, max: {0, _, _, _}
+    min: {0, _, _, _}, max: {255, _, _, _}
     (X = unused, z = byteswapped, + = exact, 0 = zero)

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-02-24 20:25:59 +01:00
Ramiro Polla 9fbb03f428 swscale/tests/sws_ops: don't print unused components in the output
Clean up the output by not printing the flags and range values of
unused components in ff_sws_op_list_print().

 rgb24 -> gray16le:
   [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
-    min: {0, 0, 0, nan}, max: {255, 255, 255, nan}
+    min: {0, 0, 0, _}, max: {255, 255, 255, _}
   [ u8 ...X -> +++X] SWS_OP_CONVERT      : u8 -> f32
-    min: {0, 0, 0, nan}, max: {255, 255, 255, nan}
-  [f32 ...X -> .++X] SWS_OP_LINEAR       : dot3 [[76.843000 150.859000 29.298000 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0]]
-    min: {0, 0, 0, nan}, max: {65535, 255, 255, nan}
-  [f32 .XXX -> +++X] SWS_OP_CONVERT      : f32 -> u16
-    min: {0, 0, 0, nan}, max: {65535, 255, 255, nan}
-  [u16 .XXX -> +++X] SWS_OP_WRITE        : 1 elem(s) planar >> 0
-    min: {0, 0, 0, nan}, max: {65535, 255, 255, nan}
+    min: {0, 0, 0, _}, max: {255, 255, 255, _}
+  [f32 ...X -> .XXX] SWS_OP_LINEAR       : dot3 [[76.843000 150.859000 29.298000 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0]]
+    min: {0, _, _, _}, max: {65535, _, _, _}
+  [f32 .XXX -> +XXX] SWS_OP_CONVERT      : f32 -> u16
+    min: {0, _, _, _}, max: {65535, _, _, _}
+  [u16 .XXX -> +XXX] SWS_OP_WRITE        : 1 elem(s) planar >> 0
+    min: {0, _, _, _}, max: {65535, _, _, _}
     (X = unused, z = byteswapped, + = exact, 0 = zero)

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-02-24 20:22:12 +01:00
Ramiro Polla c7c8c31302 swscale/tests/sws_ops: print range values in the output
This gives more information about each operation and helps catch issues
earlier on.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <ramiro.polla@gmail.com>
2026-02-24 19:27:51 +01:00
Ramiro Polla a0b55a0491 avcodec/mjpegdec: fix indentation and some white spaces 2026-02-20 16:32:10 +01:00
Ramiro Polla 0accfde281 avcodec/jpeglsdec: fix decoding of jpegls files with restart markers 2026-02-20 16:32:10 +01:00
Ramiro Polla 80edf78e58 tests/fate/image: add jpegls tests with restart markers
The samples have been generated with:
jpeg -c -ls 0 -z 1 great_wave_128.ppm jpegls/ilv0_rst.jls
jpeg -c -ls 1 -z 1 great_wave_128.ppm jpegls/ilv1_rst.jls

Note: ilv2 is still unsupported
2026-02-20 16:32:10 +01:00
Ramiro Polla 5672c410a6 avcodec/mjpegdec: unescape data for each restart marker individually
Instead of unescaping the entire image data buffer in advance, and then
having to perform heuristics to skip over where the restart markers
would have been, unescape the image data for each restart marker
individually.
2026-02-20 16:32:10 +01:00
Ramiro Polla 22771117a0 avcodec/mjpegdec: move get_bits_left() checks after handling of restart count
This commit doesn't really change much on its own, but it's helpful in
preparation for the following commit.
2026-02-20 16:32:10 +01:00
Ramiro Polla 3783b8f5e1 avcodec/mjpegdec: move vpred initialization out of loop in ljpeg_decode_rgb_scan()
The initialization code was only being run when mb_y was 0, so it could
just as well be moved out of the loop.

I haven't been able to find a bayer sample that has restart markers to
check whether vpred should be reinitialized at every restart. It would
seem logical that it should, but I have left this out until we find a
sample that does have restart markers.
2026-02-20 16:32:10 +01:00
Ramiro Polla 851cb118da avcodec/jpegls: clear more JLSState fields inside ff_jpegls_init_state() 2026-02-20 16:32:10 +01:00
Ramiro Polla 3f2d4b49e6 avcodec/mjpegdec: split mjpeg_find_raw_scan_data() out of mjpeg_unescape_sos() 2026-02-20 16:32:10 +01:00
Ramiro Polla bb48d2dba2 avcodec/mjpegdec: simplify decode_scan codepaths in ff_mjpeg_decode_sos()
This will be helpful for the next commit.
2026-02-20 16:32:10 +01:00
Ramiro Polla 179db32777 avcodec/mjpegdec: move MxPEG parameters from mjpeg_decode_scan() to MJpegDecodeContext 2026-02-20 16:32:10 +01:00
Ramiro Polla 14602cd999 avcodec/mjpegdec: move SOS header fields to MJpegDecodeContext
Use naming for SOS header fields from ISO/IEC 10918-1's non-lossless
mode of operation in ff_mjpeg_decode_sos() instead of mixing JPEG-LS
and lossless names. Each decode function still keeps its correct name
for each field.
2026-02-20 16:32:10 +01:00
Ramiro Polla c1cd31320d avcodec/mjpegdec: find correct sizes for SOS fields
For hwaccel, find_marker() was being used to skip over the image data,
which could include multiple restart markers.

For MJPEG-B and THP, the field size was already correct since the image
data was already unescaped.

For the rest (mjpeg and jpegls), the buffer was being incremented by
the unescaped_buf_size, which could be smaller than the actual buffer
size.

Now the buffer is correctly incremented in all cases.
2026-02-20 16:32:10 +01:00
Ramiro Polla cad555d0a4 avcodec/mjpegdec: improve unescaping of SOS fields
For non-jpegls:

Changes the behaviour to be more in line with IJG's reference implementation:
- optional 0xFF fill bytes in a stuffed zero byte sequence (which is an
  invalid pattern according to the standard) are now discarded:
    "FF (FF)? 00" => "FF" instead of "FF 00"
- sequences with optional 0xFF fill bytes and a marker are no longer copied:
    "FF (FF)? XX" => "" instead of "FF XX"
- a trailing 0xFF byte is no longer issued when a valid "0xFF 0xXX" marker
  is found:
    "FF XX" => "" instead of "FF"

For jpegls:

Changes the behaviour to be more in line with IJG's (non-jpegls) reference
implementation, similar to the changes above:
- optional 0xFF fill bytes in a stuffed zero bit sequence (which is an
  invalid pattern according to the standard) are now discarded:
  "FF (FF)? 0b0xxxxxxx" => "FF 0bxxxxxxx" instead of "FF 7F XX"
- sequences with optional 0xFF fill bytes and a marker are no longer copied:
  "FF (FF)? 0b1xxxxxxx" => "" instead of "FF 7F"

Unescaping for jpegls is now done in one pass instead of two. The first
pass used to detect the length of the buffer, while the second pass would
copy up to the detected length.

Note that jpegls restart markers are still not supported.

There is also a speed up with the new implementations, mostly due to the
usage of memchr() as suggested by Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-02-20 16:32:10 +01:00
Ramiro Polla 8abb40a8d8 avcodec/mjpegdec: simplify away mjpeg_unescape_sos()'s parameters
The input is always obtained from s->gB and the output is always used
to initialize s->gb, so we can move that inside the function itself.
2026-02-20 16:32:10 +01:00
Ramiro Polla 3d90949d1e avcodec/mjpegdec: split mjpeg_unescape_sos() out of ff_mjpeg_find_marker()
Now only the image data is unescaped (and not the SOS header). As a
side-effect, this also provides a proper fix for decoding CJPG files
(issue #133).
2026-02-20 16:32:10 +01:00