Commit Graph
3509 Commits
Author SHA1 Message Date
Bogdan Lisman f7bbcb91b7 avcodec/snowenc: fix SIGFPE in get_dc() when a block lies outside the plane
get_dc() divides the accumulated, OBMC-weighted DC by aa, the sum of the
squared OBMC weights taken over the in-plane pixels.  When an OBMC block
falls entirely outside the plane - e.g. a tiny chroma plane after mcdeint
splits a frame into fields - no pixel contributes, aa stays 0 and the
ROUNDED_DIV() divides by zero (SIGFPE).  ab is 0 in exactly the same case,
so the result degenerates to 0; return it directly.

Reproducible with the GPL mcdeint filter in slow/extra_slow mode, e.g.

    ffmpeg -f lavfi -i testsrc=s=128x2 -vf mcdeint=mode=slow -f null -

Add a self-contained lavfi-based FATE regression test for the slow mode,
which previously crashed and is therefore not covered by the existing
sample-based fast/medium tests.

Fixes trac ticket #7779.

Signed-off-by: Bogdan Lisman <bogdan@pydevsolutions.com>
(cherry picked from commit a62d996927)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-06-17 04:08:30 +02:00
Bogdan Lisman 223764a43e avcodec/snowenc: fix out-of-bounds memcpy in get_block_rd() for narrow planes
For an edge block, get_block_rd() copies the full-OBMC-weight central
region directly from cur[] into the reconstruction.  It moved one
boundary to block_w/block_h but overwrote the in-plane clip (x0/x1/y0/y1
computed earlier from the plane size) instead of intersecting with it.
When a plane is narrower than block_w - e.g. a tiny field/chroma plane
produced by the mcdeint filter - the right-edge case left x0 = block_w
while x1 stayed clipped to w - sx < block_w, so x1 - x0 became negative
and was passed to memcpy() as a huge size_t, crashing with SIGSEGV.

Intersect the moved boundaries with the existing clip so the copy region
stays inside the plane and the memcpy length can never be negative.

Reproducible with the GPL mcdeint filter in slow/extra_slow mode, e.g.

    ffmpeg -f lavfi -i testsrc=s=5x32 -vf mcdeint=mode=slow -f null -

This is a separate crash from the get_dc() SIGFPE (ticket #7779) reached
through the same iterative_me() path.  Add a lavfi-based FATE regression
test.

Signed-off-by: Bogdan Lisman <bogdan@pydevsolutions.com>
(cherry picked from commit 1168447626)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-06-15 23:57:25 +02:00
Bogdan Lisman 213b6561ba avutil/eval: apply unary sign to print, squish, gauss and lerp
The leading sign of a (sub)expression is stored as +-1 in each node's
value field (parse_factor) and every other function multiplies its
result by it. print, squish, gauss and lerp ignored it, so e.g.
-print(1) evaluated to 1 instead of -1 and -gauss(0) to 0.398942
instead of -0.398942, while -1*print(1) was correct.

Fixes: ticket #9833
Reported-by: Player701
Signed-off-by: Bogdan Lisman <bogdan@pydevsolutions.com>
(cherry picked from commit 3d1d546f70)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-06-15 23:57:24 +02:00
Jun Zhao 5bc4a9898c lavfi/bwdif: fix heap-buffer-overflow with small height videos
Reproduce:
  ffmpeg -i /tmp/bwdif_test_input_160x4_gray16.jpg -vf "bwdif" -f null -

filter_intra accesses rows 3 lines away via cur[mrefs3] and cur[prefs3].
For small height videos (h <= 4), this causes heap-buffer-overflow.

Add boundary check for filter_intra when YADIF_FIELD_END is set.
The boundary condition (y < 3) or (y + 3 >= td->h) precisely matches
filter_intra's 3-line context requirement.

Test file: 160x4 gray16 JPEG
https://code.ffmpeg.org/attachments/db2ace24-bc00-4af6-a53a-5df6b0d51b15

fix #21570

Reviewed-by: Thomas Mundt <tmundt75@gmail.com>
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
(cherry picked from commit 795bccdaf5)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-03-15 00:49:57 +01:00
Andreas Rheinhardt ee72731722 tests/fate/vcodec: Test intra_dc_precision
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-03-07 20:14:36 +01:00
Nicolas Gaullier fe86fd07d3 fftools/ffprobe: do not show refs when not processing frames
refs does not belong to AVCodecParameters, so require a decoder:
it should only be showed when frames are actually processed by ffprobe.

Signed-off-by: Nicolas Gaullier <nicolas.gaullier@cji.paris>
2026-03-05 13:49:59 +00:00
James Almer 40e60a7db0 tests/fate/mov: add tests to demux specific streams within a IAMF Track
Signed-off-by: James Almer <jamrial@gmail.com>
2026-03-02 09:28:36 -03:00
Steven Liu 2559f263ea tests/fate/flvenc: add vvc in enhanced flv test case 2026-03-01 04:21:45 +00:00
Adrien Guinet da9a6d51f5 avformat/mov: add support for multiple decryption keys
This commit introduces new options to support more than one decryption
keys:
* add a decryption_keys option to MOV, that supports a dictionary of
  KID=>key (in hex), using AV_OPT_TYPE_DICT
* add the corresponding cenc_decryption_keys option to DASH

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2026-02-28 04:01:08 +01:00
Niklas Haas 43f1189af7 swscale/ops_optimizer: eliminate unnecessary dither indices
Generates a lot of incremental diffs due to things like ignored alpha
planes or chroma planes that are not actually modified.

e.g.

 bgr24 -> gbrap10be:
   [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
   [ u8 ...X -> +++X] SWS_OP_CONVERT      : u8 -> f32
   [f32 ...X -> ...X] SWS_OP_SCALE        : * 341/85
-  [f32 ...X -> ...X] SWS_OP_DITHER       : 16x16 matrix + {2 3 0 5}
+  [f32 ...X -> ...X] SWS_OP_DITHER       : 16x16 matrix + {2 3 0 -1}
   [f32 ...X -> ...X] SWS_OP_MIN          : x <= {1023 1023 1023 1023}
   [f32 ...X -> +++X] SWS_OP_CONVERT      : f32 -> u16
   [u16 ...X -> zzzX] SWS_OP_SWAP_BYTES
   [u16 ...X -> zzzX] SWS_OP_SWIZZLE      : 1023
   [u16 ...X -> zzz+] SWS_OP_CLEAR        : {_ _ _ 65283}
   [u16 .... -> zzz+] SWS_OP_WRITE        : 4 elem(s) planar >> 0
     (X = unused, z = byteswapped, + = exact, 0 = zero)

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-02-26 13:09:14 +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 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
Niklas Haas 46d721a69a swscale/optimizer: compress planar reads with unused planes
After plane splitting, we can end up with a situation where a subpass wants
to read only, say, the alpha plane. In this case, we should compress the
planar read by instead swizzling the alpha plane into the correct place
in the src plane order, and then reading only a single plane.

Results in a bunch of benign diffs like:

 yuva444p -> ya8:
-  [ u8 XXXX -> ++++] SWS_OP_READ         : 4 elem(s) planar >> 0
-  [ u8 .XX. -> ++++] SWS_OP_CONVERT      : u8 -> f32
-  [f32 .XX. -> .+++] SWS_OP_LINEAR       : luma [...]
-  [f32 .XX. -> .+++] SWS_OP_DITHER       : 16x16 matrix + {0 3 2 5}
-  [f32 .XX. -> .+++] SWS_OP_MAX          : {0 0 0 0} <= x
-  [f32 .XX. -> .+++] SWS_OP_MIN          : x <= {255 _ _ 255}
-  [f32 .XX. -> ++++] SWS_OP_CONVERT      : f32 -> u8
-  [ u8 .XX. -> ++++] SWS_OP_SWIZZLE      : 0312
-  [ u8 ..XX -> ++++] SWS_OP_WRITE        : 2 elem(s) packed >> 0
+  [ u8 XXXX -> ++XX] SWS_OP_READ         : 2 elem(s) planar >> 0, via {0, 3}
+  [ u8 ..XX -> ++XX] SWS_OP_CONVERT      : u8 -> f32
+  [f32 ..XX -> +XX+] SWS_OP_SWIZZLE      : 0321
+  [f32 .XX. -> .XX+] SWS_OP_LINEAR       : luma [...]
+  [f32 .XX. -> .XX+] SWS_OP_DITHER       : 16x16 matrix + {0 3 2 5}
+  [f32 .XX. -> .XX+] SWS_OP_MAX          : {0 0 0 0} <= x
+  [f32 .XX. -> .XX+] SWS_OP_MIN          : x <= {255 _ _ 255}
+  [f32 .XX. -> +XX+] SWS_OP_CONVERT      : f32 -> u8
+  [ u8 .XX. -> ++XX] SWS_OP_SWIZZLE      : 0312
+  [ u8 ..XX -> ++XX] SWS_OP_WRITE        : 2 elem(s) packed >> 0

This may seem noisy, but really is mostly a result of the fact that the unused
middle components are now marked as garbage instead of as valid data.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-02-19 19:44:46 +00:00
Niklas Haas b01236d5fb swscale/optimizer: try pushing all swizzles towards the output
Now that we can directly promote these to plane swizzles, we generally want
to try pushing them in one direction - ideally towards the output, as in the
case of split subpasses, the output is guaranteed to be planar. (And there
may not even be a read)

Results in a lot of diffs, ranging from the benign, e.g.:

 rgb24 -> bgr48be:
   [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
   [ u8 ...X -> +++X] SWS_OP_CONVERT      : u8 -> u16 (expand)
-  [u16 ...X -> +++X] SWS_OP_SWIZZLE      : 2103
   [u16 ...X -> zzzX] SWS_OP_SWAP_BYTES
+  [u16 ...X -> zzzX] SWS_OP_SWIZZLE      : 2103
   [u16 ...X -> zzzX] SWS_OP_WRITE        : 3 elem(s) packed >> 0

 rgb24 -> gbrp9be:
   [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
   [ u8 ...X -> +++X] SWS_OP_CONVERT      : u8 -> f32
   [f32 ...X -> ...X] SWS_OP_SCALE        : * 511/255
   [f32 ...X -> ...X] SWS_OP_DITHER       : 16x16 matrix + {0 3 2 5}
   [f32 ...X -> ...X] SWS_OP_MIN          : x <= {511 511 511 _}
   [f32 ...X -> +++X] SWS_OP_CONVERT      : f32 -> u16
-  [u16 ...X -> +++X] SWS_OP_SWIZZLE      : 1203
   [u16 ...X -> zzzX] SWS_OP_SWAP_BYTES
-  [u16 ...X -> zzzX] SWS_OP_WRITE        : 3 elem(s) planar >> 0
+  [u16 ...X -> zzzX] SWS_OP_WRITE        : 3 elem(s) planar >> 0, via {2, 0, 1}

To the clear improvements, e.g.:

 bgr24 -> gbrp16be:
   [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
-  [ u8 ...X -> +++X] SWS_OP_SWIZZLE      : 2103
   [ u8 ...X -> +++X] SWS_OP_CONVERT      : u8 -> u16 (expand)
-  [u16 ...X -> +++X] SWS_OP_SWIZZLE      : 1203
   [u16 ...X -> zzzX] SWS_OP_SWAP_BYTES
-  [u16 ...X -> zzzX] SWS_OP_WRITE        : 3 elem(s) planar >> 0
+  [u16 ...X -> zzzX] SWS_OP_WRITE        : 3 elem(s) planar >> 0, via {1, 0, 2}

The only case worth careful consideration is when there are swizzled inputs
that result in unusual plane patterns, e.g.:

 argb -> gbrp9be:
   [ u8 XXXX -> ++++] SWS_OP_READ         : 4 elem(s) packed >> 0
-  [ u8 X... -> ++++] SWS_OP_SWIZZLE      : 1230
-  [ u8 ...X -> ++++] SWS_OP_CONVERT      : u8 -> f32
-  [f32 ...X -> ....] SWS_OP_SCALE        : * 511/255
-  [f32 ...X -> ....] SWS_OP_DITHER       : 16x16 matrix + {0 3 2 5}
-  [f32 ...X -> ....] SWS_OP_MIN          : x <= {511 511 511 _}
-  [f32 ...X -> ++++] SWS_OP_CONVERT      : f32 -> u16
-  [u16 ...X -> ++++] SWS_OP_SWIZZLE      : 1203
-  [u16 ...X -> zzzz] SWS_OP_SWAP_BYTES
-  [u16 ...X -> zzzz] SWS_OP_WRITE        : 3 elem(s) planar >> 0
+  [ u8 X... -> ++++] SWS_OP_CONVERT      : u8 -> f32
+  [f32 X... -> ....] SWS_OP_SCALE        : * 511/255
+  [f32 X... -> ....] SWS_OP_DITHER       : 16x16 matrix + {0 0 3 2}
+  [f32 X... -> ....] SWS_OP_MIN          : x <= {511 511 511 511}
+  [f32 X... -> ++++] SWS_OP_CONVERT      : f32 -> u16
+  [u16 X... -> zzzz] SWS_OP_SWAP_BYTES
+  [u16 X... -> zzzz] SWS_OP_SWIZZLE      : 3120
+  [u16 ...X -> zzzz] SWS_OP_WRITE        : 3 elem(s) planar >> 0, via {1, 2, 0}
     (X = unused, z = byteswapped, + = exact, 0 = zero)

Observe the change from ...X to X..., which is a pattern that doesn't
necessarily have a fast path and would usually end up falling back to the
generic 4-component implementations (rather than the 3-component ones).

That said, this is not a big deal, since we can ultimately re-align the
set of implementations with what's actually needed; once we're done with
plane splitting and so forth.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-02-19 19:44:46 +00:00
Niklas Haas aaa898a2d1 swscale/optimizer: promote component swizzles to plane swizzles
In some cases, we can just directly swizzle the order of input/output
planes, rather than applying a swizzle operation on the data itself.

This can eliminate some such swizzle operations entirely, for example
yuv444p -> vuya is now just a read, clear and write.

Results in a lot of simplifications like this:

 rgb24 -> gbrp:
   [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
-  [ u8 ...X -> +++X] SWS_OP_SWIZZLE      : 1203
-  [ u8 ...X -> +++X] SWS_OP_WRITE        : 3 elem(s) planar >> 0
+  [ u8 ...X -> +++X] SWS_OP_WRITE        : 3 elem(s) planar >> 0, via {2, 0, 1}

 rgb24 -> gbrap16le:
   [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
   [ u8 ...X -> +++X] SWS_OP_CONVERT      : u8 -> u16 (expand)
-  [u16 ...X -> +++X] SWS_OP_SWIZZLE      : 1203
   [u16 ...X -> ++++] SWS_OP_CLEAR        : {_ _ _ 65535}
-  [u16 .... -> ++++] SWS_OP_WRITE        : 4 elem(s) planar >> 0
+  [u16 .... -> ++++] SWS_OP_WRITE        : 4 elem(s) planar >> 0, via {2, 0, 1, 3}

 yuv444p -> vuya:
-  [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) planar >> 0
-  [ u8 ...X -> +++X] SWS_OP_SWIZZLE      : 2103
+  [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) planar >> 0, via {2, 1, 0}
   [ u8 ...X -> ++++] SWS_OP_CLEAR        : {_ _ _ 255}
   [ u8 .... -> ++++] SWS_OP_WRITE        : 4 elem(s) packed >> 0

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-02-19 19:44:46 +00:00
Niklas Haas 4b8790f107 swscale/optimizer: allow commuting CLEAR past SWAP_BYTES
This requires a bit of a manual check in the 32-bit integer case to
make sure we don't exceed the value range of AVRational; but it still allows
quite a number of optimizations despite that restriction.

e.g.

rgb24 -> yuva444p9be:
-  [u16 ...X -> ++++] SWS_OP_CLEAR        : {_ _ _ 511}
-  [u16 .... -> zzzz] SWS_OP_SWAP_BYTES
-  [u16 .... -> zzzz] SWS_OP_WRITE        : 4 elem(s) planar >> 0
+  [u16 ...X -> zzzX] SWS_OP_SWAP_BYTES
+  [u16 ...X -> zzz+] SWS_OP_CLEAR        : {_ _ _ 65281}
+  [u16 .... -> zzz+] SWS_OP_WRITE        : 4 elem(s) planar >> 0

gray -> yuv444p12be:
-  [u16 .XXX -> +++X] SWS_OP_CLEAR        : {_ 2048 2048 _}
-  [u16 ...X -> zzzX] SWS_OP_SWAP_BYTES
-  [u16 ...X -> zzzX] SWS_OP_WRITE        : 3 elem(s) planar >> 0
+  [u16 .XXX -> zzXX] SWS_OP_SWAP_BYTES
+  [u16 .XXX -> z++X] SWS_OP_CLEAR        : {_ 8 8 _}
+  [u16 ...X -> z++X] SWS_OP_WRITE        : 3 elem(s) planar >> 0

Ultimately, the benefit of this will only become relevant once we start
splitting apart planes, since then we can have planes with only CLEAR
operations.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-02-19 19:44:46 +00:00
Niklas Haas c17a9ba0b8 tests/sws_ops: explicitly skip no-op operation lists
These are not necessarily empty, as a result of the previous changes.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-02-19 19:44:46 +00:00
James Almer e1484a30e5 avformat/dtshddec: properly support priming and padding samples
Don't just export initial_padding, but also take it into account for timestamps
by adjusting the stream's start_time. Also, export the padding samples in a way
that's actually supported, as currently trailing_padding is unused so no user
will look at it.

For the sake of not reducing coverage and because the lossy tests have reference
files that contain the priming samples, add the skip_manual flags2 to the tests
so we still output them. A new ffprobe call will ensure the demuxer behavior is
tested too.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-02-12 09:59:54 -03:00
James Almer 70f0ddd2ca tests/fate/dca: use stream_demux for lossless tests
Unlike md5, the adler32 hash shows the frames with priming samples, which will
be useful in the following commits.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-02-12 09:59:54 -03:00
John Chadwick 8b9b71494b tests/fate/image: Add psd-rgbxx
This is an rgb test image with two auxilliary channels and no alpha
channels.
2026-02-11 20:35:20 +00:00
James Almer 2e79453549 tests/fate/id3v2: don't use a reference file for fate-id3v2-invalid-tags
This fixes running the test under Valgrind, where more, unrelated lines are
printed, making the comparison fail.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-02-09 14:04:22 +00:00
James Almer 3ab8b976c1 avformat/matroskaenc: parse Opus packets to write proper durations
Before this patch, the last packet in the affected fate test would be written
without a BlockDuration element despite the packet's duration being shorter
than the Opus frame size.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-02-05 23:21:49 -03:00
James Almer 0880458e4c avformat/matroskadec: take into account priming samples in audio tracks
Signed-off-by: James Almer <jamrial@gmail.com>
2026-02-05 23:21:49 -03:00
James Almer 1dd8547193 avformat/demux: don't overwrite already set packet durations with parser ones
Following up on b613eebe78, if a demuxer that exports complete frames sets a
duration, don't overwrite it from the output of the parser.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-02-05 23:21:49 -03:00
James Almer 7581abdcb1 avformat/cafenc: support writing Packet Table Chunk Header if there are priming or remainder frames
If a codec has fixed block_align and frame_size but a given sample has either
priming or remainder frames, a pakt chunk can be written declaring zero packets
and no table, reporting only the samples to be discarded.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-01-29 21:09:02 -03:00
James Almer 8d1f247ec1 avformat/cafenc: fix setting frame count fields in Packet Table Description
st->duration is not guaranteed to be set, so store the sum of packet durations instead.
Also, set mPrimingFrames and mRemainderFrames to correct values.

Based on a patch by Jun Zhao.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-01-29 21:09:02 -03:00
James Almer c52b287ba9 avformat/cafdec: fix setting stream and packet durations
Take into account priming frames, exported as start time, and remainder frames,
substracted from the stream duration as well as exported as discard padding
side data in the last packet.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-01-29 21:09:02 -03:00
Jun Zhao b326b3a08d lavc/av1_parser: Extract SAR from render_size
Extract the Sample Aspect Ratio (SAR) from render_width_minus_1 and
render_height_minus_1 in the sequence header.

The AV1 specification defines the render dimensions, which can be used
in conjunction with the coded dimensions to determine the pixel aspect
ratio. This ensures consistent aspect ratio handling for AV1 streams
encapsulated in containers like MP4 or MKV, as observed in the updated
FATE tests where SAR changes from 0/1 to 1/1.

Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
2026-01-14 23:56:39 +00:00
Nicolas Gaullier af6a1dd0b2 avformat/demux: duplicate side_data in parse_packet()
If an input packet results in several output packets, the side data will be
exported only by the first output packet, and be missing from the rest.

Signed-off-by: Nicolas Gaullier <nicolas.gaullier@cji.paris>
Signed-off-by: James Almer <jamrial@gmail.com>
2026-01-07 20:25:18 -03:00
James Almer 0cca125a94 avformat/demux: prevent the loss of packet side data when using an parser
Many parsers will request data until they find what will be the start of the
next assembled packet in order to decide where to cut the current one. If this
happens, the loop in demux.c will, in case the demuxer exports already fully
assembled packets as is sometimes the case for MPEG-TS, discard the already
handled first input packet before it tries to move its side data to the output.

The affected FATE tests reflect this change by no longer dropping the side data
from the first input packet, nor exporting every other side data in the wrong
output packet.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-01-07 20:25:18 -03:00
wangwenchao10 2892815c45 avformat/pcmdec: Mark raw PCM stream as having no timestamps
Signed-off-by: wangwenchao10 <wangwenchao10@xiaomi.com>
2026-01-05 01:23:17 +00:00
Ayose c7a2646bc7 avfilter/vf_drawvg: values from the p() function can be used as colors.
To be able to reuse colors from the original frame, the last value returned by
`p()` is tracked in the eval state, and if it is assigned to a variable, the
original color components are copied to `color_vars`. Thus, commands like
`setcolor` and `colorstop` can use those variables:

    setvar pixel (p(0, 0))
    ...
    setcolor pixel

`fate-filter-drawvg-video` now also verifies the `p()` function.

Signed-off-by: Ayose <ayosec@gmail.com>
2026-01-04 13:42:20 +00:00
Ayose 46c9584dc5 avfilter/vf_drawvg: support color expressions as setvar/call arguments.
The arguments for `setvar` and `call` commands can be colors (like `#rrggbb`).
This replaces the previous trick of using `0xRRGGBBAA` values to use colors as
procedure arguments.

The parser stores colors as the value expected by Cairo (a `double[4]`). This
array is allocated on the heap so the size of the union in `VGSArgument` is
not increased (i.e. it is still 8 bytes, instead of 32).

Signed-off-by: Ayose <ayosec@gmail.com>
2026-01-04 13:42:20 +00:00
James Almer c6e7243f11 avutil/opt: fix av_opt_is_set_to_default() for array options with no default value
If AVOptionArrayDef.def is NULL, av_opt_is_set_to_default() should return true
when the field in the object is NULL.

Signed-off-by: James Almer <jamrial@gmail.com>
2025-12-30 20:14:56 -03:00
James Almer 6223b7fa0b tests/fate/iamf: add tests for Projection mode ambisonic Audio Elements
Signed-off-by: James Almer <jamrial@gmail.com>
2025-12-29 12:02:53 -03:00
Niklas Haas c0f49db53d swscale/ops: remove broken value range assumption hack
This information is now pre-filled automatically for SWS_OP_READ when
relevant.

yuv444p10msbbe -> rgb24:
   [u16 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) planar >> 0
   [u16 ...X -> +++X] SWS_OP_SWAP_BYTES
   [u16 ...X -> +++X] SWS_OP_RSHIFT       : >> 6
   [u16 ...X -> +++X] SWS_OP_CONVERT      : u16 -> f32
   [f32 ...X -> ...X] SWS_OP_LINEAR       : matrix3+off3 [...]
   [f32 ...X -> ...X] SWS_OP_DITHER       : 16x16 matrix + {0 3 2 5}
   [f32 ...X -> ...X] SWS_OP_MAX          : {0 0 0 0} <= x
+  [f32 ...X -> ...X] SWS_OP_MIN          : x <= {255 255 255 _}
   [f32 ...X -> +++X] SWS_OP_CONVERT      : f32 -> u8
   [ u8 ...X -> +++X] SWS_OP_WRITE        : 3 elem(s) packed >> 0
    (X = unused, + = exact, 0 = zero)

(This clamp is needed and was incorrectly optimized away before, because the
`SWS_OP_RSHIFT` incorrectly distorted the value range assertion)
2025-12-24 16:37:22 +00:00
Niklas Haas 5f1be98f62 swscale/ops: add SWS_COMP_SWAPPED
This flag keeps track of whether a pixel is currently byte-swapped or
not. Not needed by current backends, but informative and useful for
catching potential endianness errors.

Updates a lot of FATE tests with a cosmetic diff like this:

 rgb24 -> gray16be:
   [ u8 XXXX -> +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
   [ u8 ...X -> +++X] SWS_OP_CONVERT      : u8 -> f32
   [f32 ...X -> .++X] SWS_OP_LINEAR       : dot3 [...]
   [f32 .XXX -> +++X] SWS_OP_CONVERT      : f32 -> u16
-  [u16 .XXX -> +++X] SWS_OP_SWAP_BYTES
-  [u16 .XXX -> +++X] SWS_OP_WRITE        : 1 elem(s) planar >> 0
-    (X = unused, + = exact, 0 = zero)
+  [u16 .XXX -> zzzX] SWS_OP_SWAP_BYTES
+  [u16 .XXX -> zzzX] SWS_OP_WRITE        : 1 elem(s) planar >> 0
+    (X = unused, z = byteswapped, + = exact, 0 = zero)

(The choice of `z` to represent swapped integers is arbitrary, but I think
it's visually evocative and distinct from the other symbols)
2025-12-24 16:37:22 +00:00
Damitha Gunawardena bb769d9d90 avcodec/gifenc: avoid redundant local color table when global palette is used
Addressing the fact that first frame has a LCT when global pallette is used for pal8.
issue: #20896
2025-12-23 14:34:13 +00:00
Zhao Zhili 260f5a47a5 avformat/rawvideodec: add stride option to skip line padding
Some tools like v4l2-ctl dump data without skip padding. If the
padding size is not an integer multiple of the number of pixel
bytes, we cannot handle it by using a larger width, e.g.,, for
RGB24 image with 32 bytes padding in each line.
2025-12-23 03:20:34 +00:00
Niklas Haas fafd72ef04 swscale/ops_internal: fix ff_sws_pack_op_decode()
This function was assuming that the bits are MSB-aligned, but they are
LSB-aligned in both practice (and in the actual backend).

Also update the documentation of SwsPackOp to make this clearer.

Fixes an incorrect omission of a clamp after decoding e.g. rgb4, since
the max value range was incorrectly determined as 0 as a result of unpacking
the MSB bits instead of the LSB bits:

 bgr4 -> gray:
   [ u8 XXXX -> +XXX] SWS_OP_READ         : 1 elem(s) packed >> 1
   [ u8 .XXX -> +++X] SWS_OP_UNPACK       : {1 2 1 0}
   [ u8 ...X -> +++X] SWS_OP_SWIZZLE      : 2103
   [ u8 ...X -> +++X] SWS_OP_CONVERT      : u8 -> f32
   [f32 ...X -> .++X] SWS_OP_LINEAR       : dot3 [...]
   [f32 .XXX -> .++X] SWS_OP_DITHER       : 16x16 matrix + {0 3 2 5}
+  [f32 .XXX -> .++X] SWS_OP_MIN          : x <= {255 _ _ _}
   [f32 .XXX -> +++X] SWS_OP_CONVERT      : f32 -> u8
   [ u8 .XXX -> +++X] SWS_OP_WRITE        : 1 elem(s) planar >> 0
     (X = unused, + = exact, 0 = zero)
2025-12-22 20:14:31 +00:00
Romain Beauxis b43645b2ef libavformat/id3v2.c: return valid string in decode_str for empty strings
with no bom. Fixes: #YWH-PGM40646-12
2025-12-22 13:44:42 +00:00
Leo Izen 784aa09fa8 avcodec/exif: parse additional EXIF IFDs
Most EXIF metadata is in IFD0 and most EXIF payloads only contain
one IFD, but it is possible for there to be more IFDs after the
existing trailing one. exiftool and similar software report these IFDs
as IFD1, IFD2, etc. This commit reads those additional IFDs and attaches
them as dummy entries in the top-level IFD ranging from 0xFFFC down to
0xFFED, which are unused by the EXIF spec. The EXIF API is only able to
return and work with a single IFD, so by attaching it as a subdirectory
this metadata can be preserved.

This is done transparently through the read/write process. Upon parsing
an additional IFD1, it will be attached, but it will be written with
av_exif_write after IFD0 rather than as a subdirectory, as intended.

Existing files without more than one IFD, i.e. most files, will be unaffected
by this change, as well as API clients looking to parse specific fields, but
now more metadata is parsed and written, rather than simply being discarded
as trailing data.

Signed-off-by: Leo Izen <leo.izen@gmail.com>
2025-12-20 11:53:23 -05:00
Niklas Haas 75ba2bf457 swscale/ops: correctly truncate on ff_sws_apply_op_q(SWS_OP_RSHIFT)
Instead of using a "precise" division, simulate the actual truncation.

Note that the division by `den` is unneeded in principle because the
denominator *should* always be 1 for an integer, but this way we don't
explode if the user should happen to pass `4/2` or something.

Fixes a lot of unnecessary clamps w.r.t. xv36, e.g.:

 xv36be -> yuv444p12be:
   [u16 XXXX -> ++++] SWS_OP_READ         : 4 elem(s) packed >> 0
   [u16 ...X -> ++++] SWS_OP_SWAP_BYTES
   [u16 ...X -> ++++] SWS_OP_SWIZZLE      : 1023
   [u16 ...X -> ++++] SWS_OP_RSHIFT       : >> 4
-  [u16 ...X -> ++++] SWS_OP_CONVERT      : u16 -> f32
-  [f32 ...X -> ++++] SWS_OP_MIN          : x <= {4095 4095 4095 _}
-  [f32 ...X -> ++++] SWS_OP_CONVERT      : f32 -> u16
   [u16 ...X -> ++++] SWS_OP_SWAP_BYTES
   [u16 ...X -> ++++] SWS_OP_WRITE        : 3 elem(s) planar >> 0
     (X = unused, + = exact, 0 = zero)
2025-12-20 13:52:45 +00:00
James Almer 1d662641c5 tests/fate/demux: add a raw JPEG-XS demux test
Use the concat protocol, to test the parser's capabilities to differentiate between
EOC maker before SOC marker, on top of false EOC marker positives and EOC maker on EOF.

Signed-off-by: James Almer <jamrial@gmail.com>
2025-12-16 10:38:56 -03:00
Niklas Haas 18edb246c8 swscale/ops_optimizer: correctly commute swizzles with dither ops
This requires updating the order of the dither matrix offsets as well. In
particular, this can only be done cleanly if the dither matrix offsets are
compatible between duplicated channels; but this should be guaranteed after
the previous commits.

As a side note, this also fixes a bug where we pushed SWS_OP_SWIZZLE past
SWS_OP_DITHER even for very low bit depth output (e.g. rgb4), which led to
a big loss in accuracy due to loss of per-channel dither noise.

Improves loss of e.g. gray -> rgb444 from 0.00358659 to 0.00261414,
now beating legacy swscale in these cases as well.
2025-12-15 14:31:58 +00:00
Niklas Haas 6184924892 swscale/format: don't add chroma noise when dithering grayscale content
On the surface, this trades a tiny bit of PSNR for not introducing chroma
noise into grayscale images. However, the main reason for this change is
actually motivated by a desire to avoid regressing the status quo of
duplicating swizzles being able to be commuted past dither ops.
2025-12-15 14:31:58 +00:00
Niklas Haas 960cf3015e swscale/ops: add explicit row offset to SwsDitherOp
To improve decorrelation between components, we offset the dither matrix
slightly for each component. This is currently done by adding a hard-coded
offset of {0, 3, 2, 5} to each of the four components, respectively.

However, this represents a serious challenge when re-ordering SwsDitherOp
past a swizzle, or when splitting an SwsOpList into multiple sub-operations
(e.g. for decoupling luma from subsampled chroma when they are independent).

To fix this on a fundamental level, we have to keep track of the offset per
channel as part of the SwsDitherOp metadata, and respect those values at
runtime.

This commit merely adds the metadata; the update to the underlying backends
will come in a follow-up commit. The FATE change is merely due to the
added offsets in the op list print-out.
2025-12-15 14:31:58 +00:00