3681 Commits
Author SHA1 Message Date
Niklas Haas 770a1ef28d swscale/ops_optimizer: eliminate unneeded SWS_OP_MIN/MAX components
The current code only checks to see if the entire operation is a no-op,
but doesn't allow removing unneeded components from the operation.

Results in a large number of minor improvements, e.g.

 rgba 16x16 -> ya8 16x16:
   u8_read_packed_xyzw
   u8_to_f32_xyzw
   f32_linear_x_xxx00
   f32_dither_x_0_16x16
-  f32_min_xw
+  f32_min_x
   f32_to_u8_xw
   u8_permute_xyz_y_w
   u8_write_packed_xy

or:

 rgba 16x16 -> yuva444p10le 16x16:
   u8_read_packed_xyzw
   u8_to_f32_xyzw
   f32_linear_xyzw_xxx0x_xxx0x_xxx0x_000x0
   f32_dither_xyzw_0_3_2_5_16x16
-  f32_min_xyzw
+  f32_min_w
   f32_to_u16_xyzw
   u16_write_planar_xyzw

And some major ones, e.g.

 yuva444p 16x16 -> gbrap 16x16:
-  u8_read_planar_xyzw
-  u8_to_f32_xyzw
+  u8_read_planar_x
+  u8_write_planar_x
+ Sub-pass #1:
+  u8_read_planar_xyz
+  u8_to_f32_xyz
   f32_linear_xyz_x0x0x_xxx0x_xx00x
   f32_dither_xyz_0_3_2_16x16
-  f32_max_xyzw
-  f32_min_xyzw
-  f32_to_u8_xyzw
-  u8_write_planar_xyzw
+  f32_max_xyz
+  f32_min_xyz
+  f32_to_u8_xyz
+  u8_write_planar_xyz

Which is now split between two subpasses, one for the no-op alpha
copy and one for the yuv444 -> gbrp conversion. This has been
previously blocked by the SWS_OP_MIN/MAX clamp on the RGB channels
marking the alpha channel as dirty, even though it should be a no-op
on the alpha channel.

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-08-09 21:03:33 +02:00
Niklas Haas 49dd7666d1 swscale/ops: use unzwizzled component index for SwsComps.dep_in[]
This is more true to the name; these dependencies track *components*,
not planes - in both directions.

Generates a bunch of benign diffs.

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-08-09 21:03:33 +02:00
James Almer afd6b8451f libswresample/tests/rematrix: rewrite into a matrix printing tool
Signed-off-by: James Almer <jamrial@gmail.com>
2026-08-09 13:55:37 -03:00
Kacper Michajłow 2a20737f66 Revert "lavfi/bwdif: fix heap-buffer-overflow with small height videos"
This reverts commit 795bccdaf5.

The heap-buffer-overflow was a symptom of the >8 bit boundary
conditions bug fixed in the previous commit. This workaround is no
longer needed.

This restores spatial-only interpolation of the whole frame for the
first and last fields, instead of running the temporal edge filter
against cloned reference frames on the outermost lines. Because of that
first frame references are updated to pre-fix values.

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2026-08-08 21:46:08 +00:00
Kacper Michajłow 5e6d663c94 avfilter/vf_bwdif: fix line boundary checks for >8 bits content
The mrefs/prefs boundary conditions scaled the y limits by the number of
bytes per sample, even though the ref offsets are already expressed in
elements. For content deeper than 8 bits this clamped perfectly valid
in-bounds line taps.

Found by validating the libplacebo GPU port against this filter, which
matches exactly on 16-bit content everywhere except these lines.

This changes the output for >8 bit content on the affected lines.

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2026-08-08 21:46:08 +00:00
Romain Beauxis 23fccd657c avformat/mp3enc: keep trailing padding spanning several packets
The trailing padding is read from the AV_PKT_DATA_SKIP_SAMPLES side data of
every packet, overwriting the previous value, so only the last packet was
ever accounted for. A single packet holds at most one frame, which caps the
padding that can be written at 1152 + 528 + 1 samples.

LAME regularly reports more than that: gapless/gapless.mp3 carries 1984 and
comes out of a stream copy with 1681, decoding to 303 samples more than the
file it was copied from.

Accumulate instead, and add the decoder delay once the total is known.

Fixes: https://trac.ffmpeg.org/ticket/9755
2026-08-07 21:18:03 +00:00
Ayoub Nabil fc02470c62 avfilter/f_ebur128: fix top-back channel weighting
ITU-R BS.1770 assigns a weight of 1.0 to height channels, but the
filter included the top-back channels in the 1.41 surround mask.

remove the top-back channels from that mask and add a FATE test for
the resulting loudness measurement.

fixes #23968.

Signed-off-by: Ayoub Nabil <237098474+ayoubnabil@users.noreply.github.com>
2026-08-06 00:30:00 +00:00
iSold Leo ec2a4105e2 swscale: avoid overflow in fast bilinear edge handling
The final edge clamp computes the source position using int
multiplication before shifting. With sufficiently wide inputs this
overflows, which may suppress the clamp and leave the last output
pixels interpolated with the padding byte.

Promote the multiplication to int64_t in the C, MMXEXT and VSX
implementations.

Add a regression test covering the rightmost pixel of a wide upscale,
which is wrong before this change on both the C and the MMXEXT path.

Fixes: signed integer overflow: 15 * 255918080 cannot be represented in type 'int'
Fixes: #21591
Signed-off-by: iSold Leo <s@qwqlog.com>
2026-08-05 19:34:30 +00:00
Niklas Haas 6321b53809 swscale/ops: solve for component dependencies
Needed to determine reverse dependencies of different input planes, for
appropriately splitting op lists involving subsampled planes.

Generates benign diffs that just reflect the new addition, e.g.:

 yuva444p 16x16 -> rgb24 16x16:
   [ u8 ===X] SWS_OP_READ         : 3 elem(s) planar >> 0
     min: {0 0 0 _}, max: {255 255 255 _}
+    inputs: {x y z _}, outputs: {xyz yz xy _}
   [ u8 ===X] SWS_OP_CONVERT      : u8 -> f32
     min: {0 0 0 _}, max: {255 255 255 _}
+    inputs: {x y z _}, outputs: {xyz yz xy _}
   [f32 ...X] SWS_OP_LINEAR       : matrix3+off3 [[85/73 0 1.596027 0 -222.921566] [85/73 -0.391762 -0.812968 0 135.575295] [85/73 2.017232 0 0 -276.835851] [0 0 0 1 0]]
     min: {-222.921566 -171.630839 -276.835851 _}, max: {480.983073 432.493103 534.476153 _}
+    inputs: {xz xyz xy _}, outputs: {x y z _}
   [f32 ...X] SWS_OP_DITHER       : 16x16 matrix + {0 3 2 -1}
     min: {-222.919612 -171.628886 -276.833898 _}, max: {481.981120 433.491150 535.474200 _}
+    inputs: {xz xyz xy _}, outputs: {x y z _}
   [f32 ...X] SWS_OP_MAX          : {0 0 0 _} <= x
     min: {0 0 0 _}, max: {481.981120 433.491150 535.474200 _}
+    inputs: {xz xyz xy _}, outputs: {x y z _}
   [f32 ...X] SWS_OP_MIN          : x <= {255 255 255 _}
     min: {0 0 0 _}, max: {255 255 255 _}
+    inputs: {xz xyz xy _}, outputs: {x y z _}
   [f32 +++X] SWS_OP_CONVERT      : f32 -> u8
     min: {0 0 0 _}, max: {255 255 255 _}
+    inputs: {xz xyz xy _}, outputs: {x y z _}
   [ u8 XXXX] SWS_OP_WRITE        : 3 elem(s) packed >> 0
     ('X' unused, 'z' byteswapped, '=' copied, '$' const, '+' integer, '0' zero)

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-08-03 09:32:30 +00:00
panboxiaosa b57a3d028d avformat/mov: set video packet durations in presentation order
STTS sample deltas follow decode order, while AVPacket.duration is
defined as the interval to the next PTS in presentation order. Assigning
the deltas directly therefore produces incorrect packet durations for
VFR video with reordered frames.

After index construction and edit-list processing, sort samples by PTS
and set every duration with a following PTS from adjacent presentation
timestamps. This reorders STTS durations where possible and derives
intervals produced by the STTS/CTTS combination when necessary. Keep the
original timing table if allocation fails or timestamps are invalid.

Add FATE coverage for the official VFR H.264 sample and for a generated
MPEG-4 case whose presentation intervals are not a permutation of its
STTS deltas. Update the HEVC dts2pts CRA reference for the corrected
presentation-order durations.

Signed-off-by: panboxiaosa <panboxiaosa@gmail.com>
2026-07-29 23:49:33 +00:00
Kacper Michajłow 848fb754dd avformat/hls: don't discard target segment's first keyframe when seeking
Segment starts on the seek timeline are derived from EXTINF durations,
so the first keyframe of the target segment can have a slightly lower
DTS than the snapped seek position, in which case the packet discard
loop would skip it and resume playback one segment late. Make sure we
start at the very beginning of the stream in this case.

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2026-07-28 18:01:18 +02:00
Kacper Michajłow 84bc576371 avformat/hls: set stream start_time for all playlist types
Rebase the first packet's timestamp onto the start of the segment list
regardless of playlist type, and report it as start_time. Previously
only EVENT playlists did this and live streams took start_time from the
first loaded segment at the live edge. Which is not correct as some
servers provide very deep (hours even) time shift in live playlist. The
evicted segments are already tracked by EXT-X-MEDIA-SEQUENCE. This
allows us to use all available segments, not only the future ones on
live playlist.

Also prefer PTS over DTS, as EXTINF durations and start_time are
presentation time.

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2026-07-28 18:01:18 +02:00
Kacper Michajłow b449f86287 tests/fate/pcm: add fate-pcm_dvda test
Input is cut down version of https://samples.mplayerhq.hu/DVD-Audio/ats.AOB

Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
2026-07-28 17:55:33 +02:00
Timo Rothenpieler 7e1f4dc318 Reapply "avfilter/avfiltergraph: always retry format negotiation after auto-filters"
This reverts commit cd9d265344.
2026-07-27 20:13:00 +02:00
Nicolas George cd9d265344 Revert "avfilter/avfiltergraph: always retry format negotiation after auto-filters"
This reverts commit 978a0821ee.

The stability of the negotiation process has never been studied
with multiple rounds.

It has always been documented to users that scale was the filter
to insert to manage format conversions. A second filter for
a specific type of conversion should never have been added:
the proper fix for the issue that this commit tried to fix is
to give scale the ability to handle premultiplication too.
2026-07-27 10:27:27 +02:00
Nathan Lucas 7002e01c19 tests/fate/spdif: add TrueHD branch padding test
Add a small synthetic TrueHD sample that exercises large MAT padding in
spdifenc. The sample covers both the input_timing path with padding above
MAT_FRAME_SIZE / 2 and the output_timing discontinuity path.

It also verifies queued MAT frame emission when one input packet completes
more than one MAT frame.

Signed-off-by: Nathan Lucas <nlucasgit@gmail.com>
2026-07-25 20:12:16 -06:00
James Almer afb74faff6 tests/ref: update references
Missed in 642ae726ff after a faulty rebase.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-22 21:14:07 -03:00
James Almer 9c8fc66ce1 tests/fate/matroska: add a test for Track Timescale handling
Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-22 20:50:14 -03:00
StachowiakDawid c182b1c09c Add new mode to mpdecimate video filter 2026-07-20 17:49:47 +00:00
Lynne 9d0a4132ff avcodec/aacenc: rework NMR stereo decisions, retune coded bandwidth
Stereo decisions are made per band before quantization, from the psy
model's spectra, and carry cross-frame memory (EMA-smoothed statistics,
per-grid mode banks, leave-hysteresis) so the image holds instead of
churning:

  * M/S adopts content-driven and rate-free (side under half the mid);
    for mid-dominant bands M/S is simply the better coding at every
    rate, and a wandering L/R fraction reads as image instability.
  * I/S competes with M/S above 6.1 kHz instead of only seeing M/S
    rejects (which are exactly the wide bands it cannot render), and
    engages under SUSTAINED strain only: the pressure ramp gated by the
    lambda floor, so pressure spikes at a comfortable operating point
    cannot flood it onto content where coding the side is affordable
    and strictly better. Unengaged candidates fall back to M/S.
  * Pairs whose joint-tool candidacy fraction stays low decouple:
    block switching goes per-channel and M/S stops, matching how
    independent coding wins on diffuse decorrelated content.
  * PNS in a pair is reserved for clearly-wide bands (it renders
    uncorrelated noise per channel).

Block switching for a pair is decided through the psy window_pair()
hook so common_window survives transients.

The NMR rate-to-bandwidth table is retuned upward at >= 48 kbps/ch to
track the bandwidth strong encoders deliver; both quality metrics
improve on a 16-clip battery and wider regresses. Lower rates are
unchanged.
2026-07-19 20:41:53 +08:00
Lynne 646f2796c8 avcodec/aacenc: rework NMR rate control, pool CPE budgets, add decision memory
Rate control: replace the integral servo with a stateless pressure
offset (exp2(-K*fill/R)) so a drained reservoir cannot wind up and
crater quality after loud stretches; slew-limit the final operating
lambda per frame (bits deviate instead, the reservoir absorbs); seed
the reservoir full at stream start; and track rate strain explicitly:
a long-frame lambda EMA against anchors that scale up when the achieved
distortion/mask ratio flags noise-class content (whose psy masks are
wholesale violated and lambda reads inflated), plus a lambda min-tracker
separating sustained starvation from transient spikes at a comfortable
operating point. The resulting pressure ramp gates every
pressure-adaptive tool from one place.

CPE budget pooling: solve both channels of a pair jointly under one
shared lambda against a pooled budget (NMRSlot defer/solve/commit)
instead of an equal per-channel split, which starved the mid/carrier
while the side gold-plated. Mono and VBR output are unchanged.

Transients: isolated onsets are coded uniformly finer across the short
run and repaid from steady stretches; dense-beat runs get a
starvation-scaled boost; a transition premask clamps START-frame
thresholds toward the previous long frame (an attack cannot mask
backwards).

Decision memory: marginal per-frame re-decisions oscillate audibly, so
every stateful choice now carries hysteresis - band zeroing, PNS
enter/leave with debounce (and near-masked bands staying noise until a
loudness guard), per-grid stereo mode banks that survive window
switches, and the short-TNS accept state.

TNS-covered bands price distortion by the synthesis filter's
re-amplification gain, so the trellis spends where noise will actually
be heard.
2026-07-19 20:41:52 +08:00
Romain Beauxis 63b7e4cefa lavf/oggparsevorbis: rework timestamp offset and end trimming
Replace the first-page packet scan with a direct use of the first
packet's duration as the timestamp offset (the Vorbis I spec
guarantees it produces no PCM output).

Track last_page_granule to correctly anchor EOS trimming regardless
of any initial granule offset. Track bos_pos to reinitialize parser
state at stream boundaries without resetting at page boundaries.

Restore the granule=0 workaround from ticket #3710 and handle
chained streams by clearing bos_pos when new headers are collected.

Vorbis I spec: https://xiph.org/vorbis/doc/Vorbis_I_spec.html
2026-07-18 15:48:34 +00:00
Romain Beauxis de038122a3 tests/fate/ogg-vorbis.mak: add test to show packets initial padding and
side data.
2026-07-18 15:48:34 +00:00
Romain Beauxis b79eae1af4 libavformat/id3v2enc.c: add write support for COMM/USLT descriptor+lang keys 2026-07-18 09:59:57 -05:00
Romain Beauxis b0c702aec2 libavformat/id3v2: deprecate legacy COMM descriptor-as-key behavior 2026-07-18 09:59:57 -05:00
Romain Beauxis eb107d8772 libavformat/id3v2.c: Factor out support for reading lyrics and comment
tags.
2026-07-18 09:59:57 -05:00
Romain Beauxis 9dcb14d982 tests/fate/id3v2.mak: add test for XXX lang in COMM and USLT frames, fix
comment for -sort test.
2026-07-18 09:59:57 -05:00
Ramiro Polla 1dae8f89b2 swscale/uops: generate more specific masks for unpack when translating
Unused components weren't being taken into consideration.
2026-07-16 08:46:11 +00:00
Vignesh Venkat 5002b55ce7 fate/mov: Add fate test for t35 cdsc track
Signed-off-by: Vignesh Venkat <vigneshv@google.com>
2026-07-14 15:50:30 -03:00
Niklas Haas 44e1b60c6a swscale/uops: consolidate SWS_UOP_{PERMUTE,COPY,MOVE}
Rather than having two uops for the C reference code and a separate
uop for the x86 backend, we can just implement the C reference
using the same register-register assignment logic.

This results in only slightly worse codegen, since the compiler is
smart enough to eliminate the unnecessary copies.

The main downside is the fact that we need to allocate extra stack space
to back-fill the remaining (unused) pointers. In theory, we could do this
more efficiently by re-using unused *input* registers directly, but that
would require a lot of reliance on compile-time constant folding teasing
apart the entire register index tracking loop and duplicate check, so this
is a useful middle ground.

On platforms like x86, we still don't care about the PERMUTE vs
COPY distinction, but it's also harmless (2-3 extra lines to
instantiate the underlying MOVE macro on both uop variants).

Finally, we need to add a mask to the move uops to keep track of which
outputs are actually needed (especially for checkasm). Though it does result
in the rather unfortunate downside that it bloats the names of the uop
names.

The op lists change to reflect the new representation, e.g.:

 rgb24 16x16 -> bgr24 16x16:
   [ u8 +++X] SWS_OP_READ         : 3 elem(s) packed >> 0
     min: {0 0 0 _}, max: {255 255 255 _}
   [ u8 +++X] SWS_OP_SWIZZLE      : 2103
     min: {0 0 0 _}, max: {255 255 255 _}
   [ u8 XXXX] SWS_OP_WRITE        : 3 elem(s) packed >> 0
     ('X' unused, 'z' byteswapped, '=' copied, '$' const, '+' integer, '0' zero)
  translated micro-ops:
     u8_read_packed_xyz
-    u8_permute_zyxw
+    u8_permute_xyzw_txz_xzt
     u8_write_packed_xyz

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-07-14 12:24:01 +00:00
Michael NiedermayerandFable-5 cff4a69294 avfilter: add latticepal filter
Convert packed 24/32-bit RGB/BGR/RGBA/BGRA input to PAL8 using a per-frame palette
whose colors are placed on a face-centered cubic lattice (realized as the
scaled D3/D4 checkerboard lattice), with a user-supplied density controlling
the number of lattice steps spanning one color axis.

Only lattice points actually used by a frame enter its palette; if a frame
needs more than 256 of them, the filter will itearatively drop palettte
entries and reassign affected pixels until 256 color remain

lookup uses the Conway-Sloane rounding algorithm. Supported dithering
modes: none, ordered 8x8 bayer (swscale), Cluster & Void blue noise and
Floyd-Steinberg error diffusion.

Co-Authored-by: Fable-5
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-07-13 18:16:18 +00:00
James Almer c16840b826 avcodec/dca_xll: export downmix matrix coefficients
Only for primary channel sets if they embeed coefficients for now.

$ ./ffmpeg -downmix stereo -i $fate-suite/dts/dcadec-suite/xll_51_24_48_768.dtshd -y native.wav

Before:
$ ./ffmpeg -i $fate-suite/dts/dcadec-suite/xll_51_24_48_768.dtshd -af aresample,aformat=channel_layouts=stereo -y swr.wav
[...]
[Parsed_aresample_0] [SWR] Using fltp internally between filters
[Parsed_aresample_0] [SWR] Matrix coefficients:
[Parsed_aresample_0] [SWR] FL: FL:0.414214 FR:0.000000 FC:0.292893 LFE:0.000000 SL:0.292893 SR:0.000000
[Parsed_aresample_0] [SWR] FR: FL:0.000000 FR:0.414214 FC:0.292893 LFE:0.000000 SL:0.000000 SR:0.292893
[Parsed_aresample_0] ch:6 chl:5.1(side) fmt:s32p r:48000Hz -> ch:2 chl:stereo fmt:s16 r:48000Hz
[...]

$ tests/tiny_psnr.exe native.wav swr.wav
stddev:21178.05 PSNR:  9.81 MAXDIFF:49613 bytes:     8192/     8192

After:
$ ./ffmpeg -i $fate-suite/dts/dcadec-suite/xll_51_24_48_768.dtshd -af aresample,aformat=channel_layouts=stereo -y swr.wav
[...]
[Parsed_aresample_0] [SWR] Using fltp internally between filters
[Parsed_aresample_0] [SWR] Custom matrix coefficients:
[Parsed_aresample_0] [SWR] FL: FL:-0.100006 FR:0.000000 FC:0.000000 LFE:0.000000 SL:-0.707092 SR:0.000000
[Parsed_aresample_0] [SWR] FR: FL:0.000000 FR:-0.100006 FC:0.000000 LFE:0.000000 SL:0.000000 SR:-0.707092
[Parsed_aresample_0] ch:6 chl:5.1(side) fmt:s32p r:48000Hz -> ch:2 chl:stereo fmt:s16 r:48000Hz
[...]

$ tests/tiny_psnr.exe native.wav swr.wav
stddev:    0.71 PSNR: 99.22 MAXDIFF:    1 bytes:     8192/     8192

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-11 19:32:17 -03:00
Romain Beauxis 4641be96e5 fftools/ffmpeg_mux_init.c: delete encoder-specific metadata when re-encoding. 2026-07-11 17:14:43 +00:00
Romain Beauxis c1be9b4a81 Add FATE tests for stale metadata during re-encoding. 2026-07-11 17:14:43 +00:00
James Almer c31a781412 avcodec/audio_frame_queue: add skip samples side data to output packets
Instead of reimplementing the same code on every afq user, just do it here.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-11 11:10:12 -03:00
James Almer 4eb56054c2 fftools/ffmpeg_demux: merge LCEVC enhancement payloads into the base stream
This is a temporary implementation until support for bitstream filter graphs is
generically added to the scheduler.

The dual track tests are as such changed so their output is not affected by builds
with liblcevc-dec enabled.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-06 13:27:29 -03:00
Vladimir Panteleev e058e8c0c5 vf_photosensitivity: fix metadata when duplicating frames
When the blending factor was calculated to be 0, the hot path skipped
updating variables later emitted in metadata.

Fix the flow to ensure they are populated consistently.

Extend the FATE test suite to check metadata output.
2026-07-05 00:41:30 +00:00
Vladimir PanteleevandCodex CLI dd057bd856 fate/filter-video: add photosensitivity blend test
Add a small self-contained lavfi test for the photosensitivity filter's
blend path. The graph produces one black RGB frame followed by two white
RGB frames, then runs:

    photosensitivity=frames=2:threshold=95:blend=0.5

The threshold is chosen so that the first black-to-white transition
barely exceeds the detector limit. A full 8x8 RGB grid transition has
badness 64 * 3 * 255 = 48960, while threshold=95 gives 48640 for the
first checked history window. That forces the filter into the blend
branch without needing any external sample.

With blend=0.5, the runtime factor is 48640 / 48960 * 0.5, or about
0.4967. The fixed-point blender truncates this to an input-frame weight
of 127/256, so blending black toward white produces an RGB component
value of 126. The reference therefore records black, the blended gray
frame, and then the following accepted white frame.

This makes the otherwise cryptic CRCs tie directly to the blend
calculation and history update behavior.

Co-authored-by: Codex CLI <noreply@openai.com>
2026-07-05 00:41:30 +00:00
marcos ashton 2f779272e0 libavformat/img2enc: add update_filemtime option
Add a new boolean option -update_filemtime to the image2 muxer that
sets each output file's modification time based on the creation_time
metadata plus the frame's PTS offset.

This is useful when extracting frames from dashcam or action camera
footage where wall-clock timestamps should be preserved on the output
files, allowing photo management tools to sort frames by capture time
without post-processing.

The option requires creation_time metadata to be set (via -metadata
creation_time=...). If not present, a warning is logged and the
option is silently disabled. When PTS is unavailable, the creation
time is used as-is without frame offset.

Uses utimes() on POSIX and _utime() on Windows to set file timestamps
with microsecond and second precision respectively.

Includes a FATE roundtrip test that writes frames with a known
creation_time, reads them back using the demuxer's -ts_from_file
option, and verifies the PTS values match the expected timestamps.

Closes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/22537
Signed-off-by: marcos ashton <marcosashiglesias@gmail.com>
2026-07-03 19:47:10 +00:00
James Almer 9011e7083e tests/fate/ffmpeg: remove audio stream from fate-autorotate
It's not relevant to the test, and it's often affected by unrelated changes to the
ac3 encoder.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-03 09:53:23 -03:00
James Almer d8c1dd4233 tests/fate/ac3: add a test to check correct encoder sample output
Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-02 17:53:21 -03:00
James Almer b5bfb7716c avcodec/ac3enc: drain the buffered samples at the end of encoding
When encoding a stream with an amount of samples multiple of a block, the last
the last 256 samples would be lost as the encoders were not marked as
AV_CODEC_CAP_DELAY.

This can be easily reproduced with:

ffmpeg -f lavfi -i sine -ac 2 -af atrim=start_sample=0:end_sample=4608 -c:a eac3 -f framecrc -

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-02 17:53:20 -03:00
marcos ashton 784ab15589 tests/fate/libavutil: add FATE test for video_hint
Test av_video_hint_alloc with 0, 1, and 4 rects, and
av_video_hint_create_side_data. Verifies that av_video_hint_rects
and av_video_hint_get_rect return pointers consistent with
rect_offset and rect_size, write/read-back of rect coordinates,
both hint type values, and OOM paths via av_max_alloc.

Coverage for libavutil/video_hint.c: 0.00% -> 82.05%

The remaining uncovered lines are the nb_rects overflow guard and
the av_buffer_create / av_frame_new_side_data_from_buf failure
cleanup paths, which av_max_alloc() cannot reach since it forces
the first allocation to fail.
2026-07-02 13:48:58 +00:00
marcos ashton 7ea44ca6a6 tests/fate/libavutil: add FATE test for mastering_display_metadata
Test all 5 public functions: av_mastering_display_metadata_alloc,
av_mastering_display_metadata_alloc_size, the create_side_data
variant, av_content_light_metadata_alloc, and its create_side_data
variant. Verifies the {0,1} rational defaults set by get_defaults(),
write/read-back of HDR metadata fields, frame side data attachment
for both mastering display and content light metadata, and OOM
paths via av_max_alloc.

Coverage for libavutil/mastering_display_metadata.c: 86.49% -> 100.00%
2026-07-02 13:48:58 +00:00
marcos ashton 324617b26f tests/fate/libavutil: add FATE test for dovi_meta
Test av_dovi_alloc, av_dovi_metadata_alloc, and av_dovi_find_level.
Verifies that the four inline offset-based accessors (get_header,
get_mapping, get_color, get_ext) return pointers consistent with
the offset fields, that find_level returns the first matching ext
block or NULL for a missing level, and OOM paths via av_max_alloc.

Coverage for libavutil/dovi_meta.c: 63.16% -> 100.00%
2026-07-02 13:48:58 +00:00
James Almer 053b2d18fa avcodec/aacenc: export discard padding side data when needed
This is in line with other encoders, and is needed by the matroska muxer
to properly signal end trimming samples.

gaplessenc-pcm-to-mov-aac changes as the mov muxer now uses this information
when writing the edit list, so the shorter frame duration is not needed.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-02 02:57:29 +00:00
James Almer a693a4cd80 tests/fate/generic-tags: use codec copy instead of encoding
Using ac3_fixed output was not enough as there's float to int conversion due to
the fact the mp3float decoder is used.
Instead of playing with codec combinations, just remove encoding from the test
altogheter. Mov supports muxing mp3 just fine.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-01 14:35:14 -03:00
James Almer d7d2d9d539 tests/fate/generic-tags: use ac3_fixed encoder instead of float aac
There's no guarantee the aac encoder will be bitexact in its output across platforms.
Use ac3_fixed instead of aac_fixed while at it, so the aac encoder can get improvements
without affecting this test.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-07-01 13:52:48 -03:00
Lynne 38161819e7 fate: update AAC encoder tests 2026-07-01 21:05:27 +09:00
James Almer b1327568b6 avformat/movenc: unify remainder samples signaling
When writing edit lists and the last packet has skip samples side data to
report discard padding, for codecs that have a fixed frame size it's best to
always use the full packet duration to calculate track duration (and thus
bitrate in some cases) and let the edit list be the sole source of triming
information.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-06-30 22:19:24 -03:00