When a fragment's samples are inserted into the index exactly at a stream's current sample, current_sample is left on the first inserted entry, and tts_index is never moved with the shifted timing entries, so after a seek a stream moves back to the start of the loaded fragment or gets the composition offset of another sample.
Advance current_sample and tts_index past the inserted entries, and roll tts_index back with current_sample when a truncated trun is trimmed.
The seek in fate-mov-mp4-frag-chapters-seek now returns the same packets and timestamps as a read without the fragment index.
With seek_individually, the last stream seeked sets next_root_atom, so a chapter track whose samples all sit in the first fragment makes mov_read_packet() read every fragment from the start of the file before it reaches the seeked sample.
Resume reading from the earliest fragment any stream that is read landed in, which keeps the fragments that a lagging audio track still needs and ignores the chapter track.
The seek in fate-mov-mp4-frag-chapters-seek no longer restarts from the beginning of the file.
Mux the chapters of vorbis_chapter_extension_demo.ogg with generated audio and B-frame video into a fragmented MP4, then seek to 8 s with use_mfra_for=pts and read 40 packets across one fragment boundary.
The reference records the current behaviour, where the read starts at 2 s without audio because the chapter track's seek leaves the fragment index on the first fragment.
A WebVTT segment contains every cue shown during its period (RFC 8216,
3.5), so a cue that reaches into the next segment appears in both. Keep
the cues of the previous segment and drop the ones the current segment
repeats, so each cue is delivered once. The kept cues read before the
media position was known move onto it once it is, so the comparison is on
one timeline. Nothing is repeated across a discontinuity, so the kept cues
are dropped when the opened segment has another discontinuity sequence
number (RFC 8216, 4.3.3.3), which also covers a boundary that already left
a live playlist.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Discard the cues of a subtitle playlist by their end time when seeking
or when the playlist is enabled during playback, so a cue that is on
screen at the target is delivered instead of the next one starting after
it.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Set the timestamp_map option of the webvtt demuxer for the subtitle
segments in place of prefer_hls_mpegts_pts, which no demuxer has, so the
cue times land on the MPEG-TS timeline of the audio and video. That time
is on the 33 bit PES clock, so each cue is put on the period of that clock
nearest to the position of the media, which is read first when both are
enabled. A cue read without any media does not become that position, and
a cue still buffered when the media is enabled is placed relative to it
before it is returned.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
HLS WebVTT segments carry an X-TIMESTAMP-MAP header that maps a cue time
to an MPEG-TS time of the other renditions (RFC 8216, 3.5). With
timestamp_map set, add the offset it gives to the cue timestamps, and use
the 90 kHz MPEG-TS time base for the stream so that the mapping stays
exact. Skip the header when it comes in a block of its own instead of
ending the parsing there.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Audio from 10 s with WebVTT segments mapping cue time 0 to 10 s, a cue
that spans three segments and a seek into the second segment.
Note tests are ugly with printf generation, but this is the only way to
get full HLS test to work, it's not a single file that we could upload
to fate samples server.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Exercise empty input and short streams around the decode delay without requiring hardware. Print results for FATE comparison, including the EOF state and timestamp difference.
Assisted-by: Fairy
Encode a 16-bit gray image with the jpegls encoder, set the ILV byte of
the SOS header to 1 and check that it decodes to the source picture.
Signed-off-by: Martin Mirchev <mmirchev@comp.nus.edu.sg>
cavs/avsplus-1080i-testcard.ts is five pictures (I P B P B) of a 1080i
broadcast test card, captured off air from a Beijing DTMB multiplex on
2021-09-23. It carries no program content, only a zone plate, frequency
bursts and channel idents.
The five pictures cover AEC intra and inter decoding, field coded
pictures, two enhanced field coded B pictures and 15 annex A pseudo
start codes. No existing FATE sample reaches any of these paths:
fate-cavs and fate-cavs-bunny are both JiZhun and progressive.
Signed-off-by: Rainbaby <r@bgr.jp>
The horizontal pass of the two dimensional quarter sample interpolation
reaches (96 + 42) * 255 = 35190 in the ii and kk positions and overflows
the int16_t intermediate. The other four positions use the half sample
filter, stay within -510..2550 and keep int16_t. Only the C path is
affected; the x86 SIMD covers just the one dimensional positions.
Signed-off-by: Rainbaby <r@bgr.jp>
cavs/bunny.mp4 is already in the FATE suite for fate-cavs-demux, and it
reaches decoding paths the existing fate-cavs sample does not.
Signed-off-by: Rainbaby <r@bgr.jp>
The header test wrote two KTX files only to read a few header fields,
the reject test wrote a file it expects to fail. Pipe the header test's
output into od, which dumps the fields from glInternalFormat to the
mipmap level count, and send the reject test's output to stdout.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
set_string_number() parses the operand of a "+x" or "-x" flags update as
a double and casts it to int64_t to OR it into, or mask it out of, the
current flags. Only the combined value then reaches the range check in
write_number(), so the operand itself was never validated:
- A value outside the int64_t range, or inf, makes the conversion
undefined behaviour (C17 6.3.1.4). UBSan reports it for
av_opt_set(ctx, "flags", "+77777777777777777777", 0), and what the
cast produces depends on the target: measured on AArch64, where it
saturates, "+1e20" happened to be rejected downstream while "-1e20"
was accepted.
- A fractional operand is silently truncated, so "+1.5" and "-1.5" are
accepted although "1.5" is refused as not being a valid set of flags.
Run the existing flags range check on the operand before the cast, so an
invalid operand returns AVERROR(ERANGE) exactly like an invalid absolute
value, as av_opt_set() documents, and add the four cases to fate-opt.
Reported by FuzzAnything-ORG with a UBSan trace.
Fixes#22389
The DVB subtitles written by this encoder always use page 1 as
composition and ancillary page id, but the encoder never told the muxers
about it: it never set any extradata.
Muxers need it. The Matroska CodecPrivate of an S_DVBSUB track is
mandatory and holds the composition page id, the ancillary page id and
the subtitling type, five bytes in that order; MPEG-TS reorders these
fields into its subtitling descriptor, which carries the language and
the type before the page ids, and the decoder only reads the page ids.
A file without them is invalid, and players that require them (VLC
refuses to create such a track and then filters the segments by page id)
show no subtitles at all, while players that do not, like mpv, are
unaffected.
Set the five bytes in the encoder so that every container gets them,
including MPEG-TS, which previously filled in the page ids with the same
hardcoded default. The encoded packets are unchanged; only the
fate-sub-dvb reference gains the extradata line of the output stream.
Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/25610
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
The subtitling type written into the subtitling descriptor is taken from
the stream extradata whenever it holds a full record, five bytes per
service: composition page id, ancillary page id and subtitling type.
That record can come from an encoder, which cannot know dispositions, so
a stream for the hard of hearing would be written as a normal subtitle.
Replace a normal subtitling type (0x1x) with the matching one for the
hard of hearing (0x2x, same monitor aspect ratio criticality) when the
stream disposition says so. Only single-service records are adjusted:
the demuxer flags the whole stream as soon as one of several services is
for the hard of hearing, so rewriting a multi-service record would also
change the type of the other services.
Covered by fate-mpegts-dvbsub-hearing-impaired (single service) and
fate-mpegts-dvbsub-multi-service (several services).
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
Header packets of a chained stream are only buffered in identification,
comment, setup order. A misplaced packet discards the buffered set with
a warning, so a missing or misordered header no longer mixes headers
from different chains into the new extradata. A misplaced comment
header is skipped without applying its metadata.
Reserved packet types are ignored, as required by Vorbis I section
1.3.2, and leave a buffered header set intact.
255302da70 and 5a633ec2dd applied the metadata of mid-stream comment
headers for MPD streams. No MPD release sends them: since v0.15, its
encoder starts a new chain with a full header set on tag changes.
A lone comment header is invalid. It is skipped to avoid failing the
stream, but its metadata is not honoured.
Splice pages of moog_small.ogg into a stream with comment and setup
headers without identification header, then an identification header
followed by audio.
The reference records the current output: the metadata of misplaced
comment headers is applied, and headers from different places are
packed into new extradata.
Patch the first quantizer of the first frame of a remuxed existing
sample that uses three quantizers per frame, and decode it with four
frame threads.
Signed-off-by: Martin Mirchev <mmirchev@comp.nus.edu.sg>
Print intermediate chroma results for both range directions at
8/9/10/12/14/16 bits, including neutral and nearby values. Test both
planes with the C and available native implementations, and keep
expected values in tests/ref/fate/sws-range-convert.
Based on the test implementation from Forgejo_Fairy in PR #25549.
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
solve_range_convert() anchored the range conversion offset at the upper
endpoint (src_max -> dst_max). For chroma, mapping the limited-range
interval [16, 240] to the full-range interval [0, 255] via the upper
endpoint shifts the neutral chroma center (128 << (bit_depth - 8)) to
127.5 in 8-bit units.
After 4bee010844 added the fixed-point rounding bias, that -0.5 LSB
shift canceled out the final output rounding bias for colored chroma,
leaving a systematic -0.5 LSB truncation bias in full-range chroma and
causing neutral gray to still round down to 127 on the x86 4:2:0 vertical
filter path.
Per ITU-T H.273 Section 8.3, the achromatic chroma center is
128 << (bit_depth - 8) in both limited and full range. Anchor the chroma
range conversion offset at the neutral chroma center while keeping the
luma offset anchored at the upper endpoint.
Based on the root-cause analysis and patch from Forgejo_Fairy and alec
in issues #24005 and #25521.
Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/24005
Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/25521
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
TIME-OFFSET was only read as the first attribute of EXT-X-START, so a
tag with PRECISE first was ignored. RFC 8216 4.2 does not order the
pairs of an attribute-list. Parse it with ff_parse_key_value() as the
other attribute lists are.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
The hls-start demux tests cover the cases of the hls-parse tests
through the demuxer. There is no need for hls.c API test code.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
hls-start-master.m3u8 has an EXT-X-START before its EXT-X-MEDIA and
EXT-X-STREAM-INF tags. Its variant hls-start-media.m3u8 has one of its
own and its audio rendition none. Both are live playlists of four
0.144 s segments. hls-start-variant.m3u8 is the same Master Playlist
without EXT-X-START. hls-start-endlist.m3u8 has an EXT-X-ENDLIST
between its EXT-X-START and its first segment.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
The graph closes its three looped inputs by letting trim return EOF
while the main input is still active. On the unfixed code this
deadlocks the CLI with a significant probability, so the test then
only finishes by timeout; with the fix it passes deterministically.
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
A scaled conversion between two XYZ formats decoded the codes into
gamma 2.2 RGB, scaled that and encoded it back, which quantizes twice
and clips every color outside the BT.709 gamut. Scale the codes like
those of an RGB format instead, as the unscaled conversion already did,
and round the result to 12 bits, which keeps the 4 padding bits zero.
The slice contexts of the graph take the XYZ flags of their parent for
that.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
The EOTF scaled X and Z by the X/Y and Z/Y of the DCI white, the
reference projector of RP 431-2, which ST 428-1 does not define: it
fixes the transfer alone, 52.37/48 above the 48 cd/m2 white. Treat the
three channels alike, L = (Lw - Lb) * 52.37/48 * V^2.6 + Lb, through the
wrappers of the other SDR curves. Equal in each channel, the black is
neutral in RGB only. The black of X'Y'Z' has the white of its content,
which only the RGB it is decoded into knows, so the documentation asks
for Lb = 0 on X'Y'Z' samples and their black after that conversion. A
gray of the reference projector came out at the chromaticity (0.298,
0.366) instead of its own. Broken since 06f084468e.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
The gamma tables put the top code of X'Y'Z' at linear 1.0, so the
48 cd/m2 reference white of a DCDM, code 3960, came out at 0.918, about
8 percent dark. ST 428-1 (H.273 transfer 17) puts 52.37 cd/m2 at the top
code, L = 52.37/48 * V^2.6, so that the white lands on 1.0 and the codes
above it are headroom. Fold the factor into the matrices, since the X and
Z of a white exceed 1.0 and a 16-bit table cannot hold them: the headroom
clips in RGB after the matrix, and RGB white encodes to code 3960.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
The matrices were rounded by hand from constants that do not quite
match the BT.709 chromaticities, the largest coefficient is off by 5
in Q12.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
H.273 value 10, SMPTE ST 428-1 (CIE 1931 XYZ), lists red (X) at (1, 0),
green (Y) at (0, 1), blue (Z) at (0, 0) and the centre white at
(1/3, 1/3).
The table had the monochromatic primaries of the CIE 1931 RGB space
instead.
Note that ST 428-1 only defines the encoding of the XYZ tristimulus
values and the transfer function. XYZ is absolute, so nothing in it
names the white the content was mastered to, and real DCDM content does
not have an equal-energy white. The standard reserves its headroom for
white points such as D55, D61 and D65, and the reference projector of RP
431-2 has DCI white. However, H.273 describes both the primaries (10)
(they shouldn't have) and the transfer (17) of such content, so follow
it here. For decoding, the mastering primaries can be given in place of
value 10 (e.g. AVCOL_PRI_SMPTE431 for a DCDM) with the ST 428-1 transfer
kept.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Regressed by the introduction of planar XYZ formats, which unintentionally
exposed XYZ formats as "supported" in libswscale's unstable path, despite XYZ
formats not yet being supported by the new ops code.
This incomplete partial support was then poorly and incorrectly worked
around by 2ed5830108, a20ae16999 and 60c8273b35. The test framework still
spams errors as a result of these three incomplete work-arounds.
Rather than pile on a third work-around (e.g. skipping XYZ in the test
framework), just do the sensible thing and properly disable support for
formats that are not yet handled correctly by the ops path.
Correct handling will require the introduction of 1D LUTs / TRCs, which
is a larger change on the roadmap.
Fixes: 2983c23762
Signed-off-by: Niklas Haas <git@haasn.dev>
Two concatenated container images: the first ends with an empty
"free" box, the "jxlc" box of the second has size 0. The parser must
output them as two packets, and must not treat size 0 as an invalid
box size.
Signed-off-by: Martin Mirchev <mmirchev@comp.nus.edu.sg>
Remux two short streams from an existing sample, the second one with a
70000-byte comment header, and demux their concatenation.
Signed-off-by: Martin Mirchev <mmirchev@comp.nus.edu.sg>
Use angle 0, so the gain is exactly 1 inside dmax, and move the center
to the top left corner so that part of the frame lies beyond dmax and
must saturate. Cover the planar (yuv444p) and packed (rgb24) paths.
Signed-off-by: Martin Mirchev <mmirchev@comp.nus.edu.sg>
Probing a small fragment can reach EOF and set is_restart_needed before a
seek. dash_seek selects a new segment but leaves this flag set, so
read_data does not advance cur_seq_no at the next EOF. The selected
segment is then opened a second time.
Clear the pending restart along with the other segment read state before
reopening the component. Do this before probing the new segment, which
may legitimately set the flag again.
Add generated MP2 DASH tests comparing seek-to-zero and sequential packet
checksums and timestamps. The seek test emits 14 duplicate packets without
the reset; both tests produce the same 42 packets with it.
Fixes#25247
Assisted-by: Fairy
Previously, the uop macros were generated from the union of uops over all
backends, so each backend would also instantiate uops that only the other
one can ever use. Split off a separate "x86" backend, and generate a separate
C header for it, together with its NASM macros in a single pass.
The x86 backend only enables SWS_UOP_FLAG_FMA on CPUs with FMA3, so generate
its uops both with and without FMA.
This does not reduce the checkasm coverage: the uops removed from
uops_macros.h are all LINEAR_FMA, READ_PLANAR_FV_FMA or RW_SHUFFLE, which
checkasm does not test, since the C reference backend cannot run them. The
only tests that disappear are the SSE4 and AVX2 variants of two U8 PERMUTE
kernels, which the x86 backend no longer builds because it never uses them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Niklas Haas <git@haasn.dev>
Replaces the hack of running the C preprocessor over the C macros to produce
NASM syntax at build time. The generated file is now committed and checked by
FATE, as with uops_macros.h.
As a side effect, the DECL_* macros are now proper multi-line NASM macros,
so drop the parentheses around their arguments.
The FATE test is split up per generated file, with fate-sws-uops-macros
running all of them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Niklas Haas <git@haasn.dev>
Extend fate-id3v2chap to verify that:
- unread trailing bytes after a NUL-terminated text subframe (TPE1) are
skipped so both TPE1 ("artist") and the following embedded subframe
(TIT2) are parsed;
- a non-conforming v2.4 CHAP frame with a plain 32-bit size whose high
bit is set (0x000000b6) is not truncated even when the stripped offset
contains a fitting empty frame header;
- a valid synchsafe v2.4 CHAP frame followed by an empty TPE1 frame and
a TALB frame preserves the subsequent frames;
- an ambiguous plain 256-byte v2.4 CHAP size (0x00000100, all high bits
clear) rejects the 128-byte synchsafe candidate whose fake header
exceeds the remaining tag length.
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
Commit 63b7e4cefa stopped setting st->start_time on the BOS page while
shifting the priming packet's timestamp by -ts_offset. Because the priming
packet produces no PCM output, actual audio begins at the unshifted
timestamp (0). Leaving start_time unset caused ogg_get_length() to subtract
the negative pts from st->duration (inflating duration by ts_offset) and
update_initial_timestamps() to set a negative start_time.
Set st->start_time to os->lastpts on the BOS page before subtracting
priv->ts_offset.
Cover 2-, 3-, 4- and 5-bit G.726LE, bit-rate fallback when
bits_per_coded_sample is unset, and rejection of unsupported bit widths.
Compare explicit widths with bitrate fallback for two-channel streams too.
Use an initialized payload and the existing memory-backed AVIO helper for
deterministic readback without custom read/seek callbacks.
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>