28091 Commits
Author SHA1 Message Date
yefei5 c69954c345 avformat/rmdec: reset audio deinterleave state on seek
rm_read_seek() clears rm->audio_pkt_cnt but leaves the per-stream
ast->sub_packet_cnt and ast->audiotimestamp untouched. For the
interleaved deinterleavers (GENR / INT4 / SIPR) a stale sub_packet_cnt
makes the next block complete after only (h - sub_packet_cnt) new rm
packets, so it keeps pre-seek payload in the remaining descramble slots
and loses its container timestamp.

519ebb5ee5 added rm_read_seek() for the same problem (ticket #1605) but
only reset the output counter, not the assembly progress.

Signed-off-by: yefei5 <yefei5@xiaomi.com>
2026-10-28 04:40:17 +00:00
Martin Mirchev 94110fbc39 avformat/oggparsevorbis: fix chained streams with headers over 64 KiB
When a chained Vorbis stream starts, its three header packets are
packed into new extradata with 16-bit size prefixes. A header larger
than 65535 bytes, typically a comment header with embedded cover art,
gets its size truncated, so the Vorbis parser cannot be reinitialized
and demuxing fails with "Failed to re-initialize Vorbis parser". The
audio of the new chained stream and everything after it is lost.

Use Xiph lacing instead, as vorbis_header() already does for the
initial extradata.

Signed-off-by: Martin Mirchev <mmirchev@comp.nus.edu.sg>
2026-10-28 01:57:05 +00:00
Michael Niedermayer 8b46bd6487 avformat/dashdec: clear pending segment restart when seeking
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
2026-10-26 18:57:05 +00:00
Zhao Zhili 246d0da2c1 avformat/img2enc: Split rawvideo planes only for fully planar formats
AV_PIX_FMT_FLAG_PLANAR does not exclude semi-planar formats such as
NV12, so they were split into .y/.U/.V files with corrupted chroma:

    ffmpeg -f lavfi -i testsrc -frames:v 1 -pix_fmt nv12 \
        -c:v rawvideo out.%03d.y

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2026-10-26 17:02:09 +00:00
Michael Niedermayer 46bd2205b9 avformat/r3d: seek through an index built from the RDVO offsets
Fixes: nLpmeA2sqSrC
Fixes: swarm-r3d_seek-uses-count-as-byte-offset-seeks-to-wrong-location-74db25

Found-by: zhang xingxing <2388969553@qq.com>
The report suggested seeking to the frame offsets of the RDVO atom.

Failing seek Replicated through UnModified FFmpeg with the R3D samples

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-10-24 20:19:14 +00:00
zhang xingxing 941598a1ef avformat/dashdec: do not seek before the first segment
Fixes: lyANsYWHaqPo
Fixes: swarm-Out-of-bounds-fragments-array-index-lacks-sign-check-38a148

Found-by: zhang xingxing <2388969553@qq.com>

Request of nonexistent segments Replicated through UnModified FFmpeg with the demuxer log

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-10-24 20:19:14 +00:00
James Almer 5f0a7701c1 Bump minor after branching release/9.1
Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-24 17:05:20 -03:00
James Almer aecf409c18 Bump minor version for release/9.1
Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-24 17:05:20 -03:00
Jun Zhao f5f31760f8 tests/fate: cover chapter subframe alignment and non-synchsafe v2.4 CHAP
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>
2026-10-24 15:15:50 +00:00
Jun Zhao 260d32d06d avformat/id3v2: tighten v2.4 non-synchsafe frame size boundary check
A valid synchsafe integer has the MSB cleared in every byte, and a
candidate next-frame boundary inside an ID3v2.4 tag must be followed by
the end of the tag, zero padding, or a plausible 10-byte frame header
whose size fits in the remaining tag bytes.

Previously, size_to_syncsafe(tlen) was probed even when tlen had bit 7
set in one of its bytes (such as 0x000000b6), and check_tag() accepted
any four uppercase ASCII characters (such as "LLLL" inside a chapter
title) as a valid next frame ID without checking the following frame
size. It could also read past the end of the ID3v2 tag when the last
frame had fewer than 4 bytes of padding.

Check tlen with is_syncsafe() before probing size_to_syncsafe(tlen), bound
the probe to the remaining tag bytes, and verify in check_tag() that a
candidate frame header fits in the remaining tag length (including empty
frames, which id3v2_parse() skips).

Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
2026-10-24 15:15:50 +00:00
Jun Zhao cb6e9efa88 avformat/id3v2: skip unread bytes after chapter text subframes
read_ttag() stops at the first NUL terminator or on decoding errors
without consuming the remainder of the declared frame payload. Subtracting
tlen in read_chapter() without advancing pb over the unread bytes leaves
the stream misaligned for any subsequent embedded subframe.

Track the number of bytes consumed by read_ttag() and skip the remainder
of tlen before reading the next subframe header.

Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
2026-10-24 15:15:50 +00:00
Dale Curtis 1d83e7145c lavf/oggparsevorbis: set stream start_time before applying ts_offset
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.
2026-10-24 13:15:32 +00:00
Jun Zhao 6b05263b44 tests/fate: add an AU G.726LE encoding tag round-trip test
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>
2026-10-24 15:42:12 +08:00
Jun Zhao 9b738770b4 avformat/au: select G.726LE encoding tag from sample bit width
au_write_header() looked up the AU encoding tag with ff_codec_get_tag(),
which always returned the first AV_CODEC_ID_ADPCM_G726LE entry (23, 4-bit
32 kbit/s) regardless of the stream bit width. Remuxing 16, 24 or
40 kbit/s G.726LE into AU wrote encoding 23, so reopening the file read
it back as 4-bit 32 kbit/s with the wrong duration.

Select the tag from bits_per_coded_sample, falling back to bit_rate,
sample_rate and channel count when bits_per_coded_sample is unset: 25 for
3-bit, 23 for 4-bit, 26 for 5-bit, and the existing '7262' tag (with a
warning, since Sun AU defines no standard 2-bit code) for 2-bit. Reject
other widths.

Use overflow-safe rescaling to derive the per-channel width from the total
bitrate, preserving nearest-integer rounding.

Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/25401
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
2026-10-24 15:42:12 +08:00
Ted Meyer d8990137ee libavformat/flacdec: error on overflow in metadata
if accumulating metadata_head_size would lead to an integer overflow,
return an error instead
2026-10-24 02:31:48 +00:00
Niklas Haas a5fac7bf5a avformat/jpegmpfdec: add -loop and -framerate options
Otherwise this demuxer would regress relative to image2 for basic JPEG
inputs that happen to contain an HDR gain map, which are often produced
by e.g. smartphones.

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-10-23 20:33:53 +00:00
Niklas Haas fd92307c40 avformat/jpegmpfdec: add JPEG Multi-Picture Format demuxer
This format is only auto-probed when we can be certain that the image is a
JPEG MPF file; as evidenced either by the extension (.mpo), or by the
presence of an MPF APP2 marker or an ISO21496 gain map stub.

This does require parsing possibly arbitrarily far into the file, since
the MPF header can be after a > 2 KB EXIF header; and this matches files
produced in the wild (by e.g. Apple's jpeg ultra hdr encoder).

The probe function returns AVERROR(EAGAIN) to request more data until it
reaches either the MPF marker or the start of the entropy coded data. If
the probe limit or EOF is hit first, the best scoring other format wins,
e.g. image2 for regular .jpg files.

A few additional notes:

- libultrahdr produces quite spec-incompliant files which we unfortunately
  have to work around

- since the MPF format table can be arbitrarily far from the header, we
  also need to store possibly a lot of data and re-return it to the caller;
  I have followed the convention established by e.g. fitsdec.c of just keeping
  a spare AVPacket for bytes already read during header parsing (cf. also
  jpegxl_anim_dec.c)

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-10-23 20:33:53 +00:00
Niklas HaasandClaude Opus 5.5 a84069e128 avformat/img2dec: only probe image demuxers for the codec
When the codec is not specified, image2 probes the first file with
av_probe_input_format3() and only uses the result if the winner is an
image demuxer. Any other format scoring higher for the same file thus
leaves the codec unset, even if an image demuxer would match.

Probe only the image demuxers instead. This is needed for the upcoming
jpeg_mpf demuxer, which outscores jpeg_pipe on MPF files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-10-23 20:33:53 +00:00
Niklas Haas 5d20365bb4 avformat/jpegmpfenc: skip marker padding bytes
JPEG segments may be preceded by an arbitrary number of 0xFF bytes.
We don't need a separate length check here because the bytestream2 API
already returns 0 when the end of the segment is reached prematurely, which
would fail the following length check.

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-10-23 20:33:53 +00:00
Niklas Haas b6fe3a94ba avformat/jpegmpf: split common definitions off from jpegmpfenc
Also replaces one instance of magic numbers by an enum.

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-10-23 20:33:53 +00:00
Niklas Haas ee4a4c4d72 avformat/demux: set up size for gain map stream groups
Mirroring the existing logic for LCEVC, except using the size of the base
layer rather than the size of the EL.

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-10-23 20:33:53 +00:00
Niklas Haas 851bdb6208 avformat/demux: allow returning AVERROR(EAGAIN) from read_probe()
This fills a gap in the probe scoring API; where it's not possible for
a demuxer to both express "I don't know yet" and "this file could definitely
be mine" at the same time.

This is needed for the example of JPEG Multi-Picture Format files, which
are uniquely distinguished from regular JPEG files by the presence of a
special marker that can live arbitrarily far into the file.

This is a bit analogous to the situation with ID3v2 tags, which can also
hide the true file format behind them. In this case, the probe logic already
has a special hack to detect and force more data (cf. `nodat`) - but letting
the demuxer itself decide this case is an IMHO more elegant solution.

Signed-off-by: Niklas Haas <git@haasn.dev>
2026-10-23 20:33:53 +00:00
Zhao Zhili c6f044e604 avformat/udp: wake the rx thread when the input is closed
Closing an input that receives no data took up to POLLING_TIME, as
udp_close() could only wait for the rx thread to come back from its
poll() slice before joining it. Have the thread wait on a wakeup
channel next to the socket and signal that channel from udp_close()
after setting close_req.

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2026-10-23 17:36:15 +00:00
Zhao Zhili 2f74158ddf avformat/network: add a wakeup channel for blocking waits
ff_network_wait_fd() can only return after its poll() slice, so a
thread blocked in it notices a request from another thread up to
POLLING_TIME late. Add a one-shot channel that a second thread can
signal to end the wait at once, together with a wait function that
polls it next to the socket.

The channel is an eventfd where available and a pipe otherwise. On
Windows neither can be waited on together with sockets, so it is a
loopback datagram socket connected to itself.

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2026-10-23 17:36:15 +00:00
Romain Beauxis d19f86ff4c avformat: discard the priming or the seek pre-roll after a seek
After avformat_seek_file(), the decoder is not told what to discard
from what it decodes: the frames over the pre-roll are not reliable,
and a seek that lands inside the priming at the start of the stream
outputs the rest of it. Only some demuxers, such as mov, set the skip
for the priming themselves.

Mark the streams after a successful seek, and on the first packet of
each audio stream, add to the samples to skip, which the decoder applies
through AV_PKT_DATA_SKIP_SAMPLES:
- on the first packet of the stream, the priming, as when decoding from
  the start: its exact count when it is known;
- on any other packet, the larger of the rest of the priming, which ends
  at the start time of the stream, and the seek pre-roll of the codec,
  as the decoder misses what came before. After the priming of a stream
  whose start the seek targets, no pre-roll is added, as which packet
  comes first then depends on the demuxer. Each stream compares the
  target with its own start.

The first packet is only recognised when the demuxer knows the first
timestamp of the stream, such as after avformat_find_stream_info();
otherwise, the packet gets the pre-roll as after any seek. The priming
needs the timestamp of the packet and the start time of the stream, the
pre-roll does not. The skip may span several packets, as the decoder
carries it over the frames it outputs. Side data the demuxer set on the
packet is kept: the larger skip is used, and its padding at the end of
the stream is not overwritten.

The skip supplies the pre-roll the stream declares, whatever the demuxer
landed on; recovery beyond it depends on the codec and the bitstream.
The caller keeps or trims what is decoded after it as it wishes.

The decoding of the tests without accurate seek now starts one frame
later for AAC in MP4, CAF and ADTS, and two 2048 samples frames later
for HE-AAC in ADTS and with implicit SBR. A seek that lands on the last
packet of the priming of AAC in CAF, with 64 samples of it left, now
skips the 1024 samples of pre-roll instead of outputting that priming.
For Opus in Matroska, 3840 samples are skipped instead of the 312 the
decoder drops from its first frame, and the decoding with accurate seek
is cut on frames 24 samples, half a millisecond, earlier, within the
precision of the Matroska timestamps. A seek past the end of AAC in CAF
and Opus in Matroska skips the pre-roll on the last packet and keeps its
padding. A seek on the later of two streams, close to its start, adds
the pre-roll to the other stream, which is already past its own start.
A seek back to the start of Matroska now skips the exact priming on the
first packet: 312 samples for Opus and 481 for MP2.
2026-10-23 15:38:04 +00:00
Romain Beauxis 843e83ed2d avformat/seek: leave the pre-roll before the target of avformat_seek_file()
Demuxers and decoders declare the pre-roll an audio stream needs in
AVCodecParameters.seek_preroll, but nothing used it, so a seek landed on
the frame that holds the target and the first frame decoded there was not
reliable.

Move the target back by the largest pre-roll of the audio streams that
are not discarded, whichever stream the seek is on, as they all land
near the target, without leaving the range the caller asked for or going
before the start of the stream. A finite end of the range moves back as
much as the target, and an open end stays open. The pre-roll is rounded up so that it is never shorter
than declared. The caller still discards what it decodes before the
target, as it already had to for a seek that does not land on it. Seeks
by byte or by frame number are left alone. When the start of the stream
is unknown, the earlier target may come before the first packet, so if
the seek fails, it is done again to the target the caller asked for.

The seeks of the tests now land one frame earlier for AAC, and about
80 ms earlier for Opus in Matroska. A forward seek still lands forward,
one frame earlier. A seek on the video stream just after a keyframe now
lands on the keyframe before, to leave room for the pre-roll of AAC. A
seek through concat lands earlier, as concat and the file it reads both
move the target back. A seek close to the start of ADTS, whose start is
unknown, lands at the start instead of failing.
2026-10-23 15:38:04 +00:00
Romain Beauxis e4b1a53fea avformat/seek: keep the target inside the range when rescaling it
ff_rescale_interval() rounds the bounds of the range inwards and the
target to the nearest, so a target close to a bound could fall outside
the range, which the seek then rejects. A seek through the concat
demuxer to 0.53 s in a file starting at -2112 samples fails this way:
the file it reads gets a target one tick after the end of the range.

Clamp the target to the range, and use ff_rescale_interval() for the
same conversion done for read_seek2() with a single stream.

The seek through concat now lands at the target instead of failing and
reading from the start. The rescaled targets of the interval test stay
within their range: 10 instead of 11, and 4 instead of 3.
2026-10-23 15:38:04 +00:00
Romain Beauxis 7adcef146d libavformat/tests/seek_utils: print the rescaled intervals
Print each interval before and after ff_rescale_interval() and compare
them against a reference, so that a change in the rounding shows there.

The reference records the current output, where the rescaled target can
fall outside the rescaled range: 11 after an end of 10, and 3 before a
start of 4.
2026-10-23 15:38:04 +00:00
Romain Beauxis 3d4caf8301 libavformat/tests/seek: print the samples to skip and discard
Print the AV_PKT_DATA_SKIP_SAMPLES side data of a packet when it has
one, so that the tests show what is discarded around a seek.
2026-10-23 15:38:04 +00:00
Romain Beauxis 33d1d97a19 libavformat/tests/seek: add an option to set the start of a forward seek
The first seek done with -seekforw asks for a range that starts at the
target, so it can never land before it. Add -seekmin to start the range
earlier, as ffplay does for its forward seeks, so that tests can show
how such a seek lands.
2026-10-23 15:38:04 +00:00
James Almer b938b5c8e4 avformat/mov: simplify setting Exif side data
Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-23 11:22:12 -03:00
James Almer 5c83e281e6 avformat/mov: export Alpha type Stream Groups
Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-23 11:22:12 -03:00
James Almer fd56ed17ca avformat/mov: fix parsing auxl derived layered video stream groups if they don't reference a tile grid
mov_parse_heif_layered_video() needs to be called even if nb_heif_group is 0,
otherwise auxl derived groups might be skipped.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-23 11:22:12 -03:00
James Almer e88ef42af1 avformat/dump: print Alpha channel Stream Group information
And merge all the Layered Video based group types into a single block.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-23 11:22:12 -03:00
James Almer e5605b4bb4 avformat: add an split Color and Alpha channel Stream Group
Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-23 11:22:05 -03:00
Niklas Haas 935f29eaae avformat/shared: rename -read_only to -cache_read_only
And add a deprecated alias for backwards compatibility.

Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
2026-10-23 10:26:32 +00:00
Michael Niedermayer abb54ce406 Bump minor after branching release/9.1
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-10-23 06:44:03 +02:00
Michael Niedermayer 66143d6aaa Bump minor version for release/9.1
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-10-23 06:44:03 +02:00
Jun Zhao 1a24bd6c7f tests/fate: add an ID3v2 chapter size round-trip
Cover ID3v2.3 and ID3v2.4 with a chapter title long enough that a plain
size and a synchsafe size differ. Print the CHAP size bytes, declared and
actual tag lengths, chapter counts, titles and timings for FATE to compare
against its reference output.

Also give the first embedded text frame an oversized length and verify
through the reference that both chapters and their timings survive.

Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
2026-10-23 09:25:28 +08:00
Jun Zhao e828b52165 avformat/id3v2: honor the tag version in CHAP frame sizes
ID3v2.3 stores a frame size as a plain 32-bit integer. ID3v2.4 stores it
as a synchsafe integer. write_chapter() always wrote the plain form, and
read_chapter() always read it that way. Once an embedded text frame
reached 128 bytes, the size no longer fitted and the chapter was dropped.

Write the CHAP header with the same version rule as other frames. Read an
embedded frame with that rule, and keep the chapter when a subframe size
does not fit.

Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/25357
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
2026-10-23 07:06:02 +08:00
Michael Niedermayer 2668cb6e31 avformat/asfdec_f: export stream-specific metadata in the stream
Store such entries in the metadata of the corresponding stream.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-10-22 16:39:53 +00:00
Michael Niedermayer dadf0b5b2e avformat/asfdec_f: pass the target dictionary to get_tag()
Allows storing tags in a dictionary other than the format metadata.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-10-22 16:39:53 +00:00
Romain Beauxis 8191fa0b8c avformat/hls: accept EXT-X-START in Master Playlists
EXT-X-START may appear in both Master and Media Playlists (RFC 8216
4.3.5.2). Parsing it allocated a Media Playlist, so a Master Playlist
carrying it before its EXT-X-STREAM-INF entries was rejected since
0e6eef3551.

Record the offset while parsing and apply it once the playlist type is
known. A value from a Master Playlist applies to all its Media
Playlists, which then ignore their own, as RFC 8216 4.3.5 recommends.

Defer EXT-X-ENDLIST the same way, so that it is not lost when it
precedes the first tag allocating the Media Playlist.
2026-10-22 02:51:14 +00:00
Romain Beauxis 1b552f55db libavformat/tests: add an HLS playlist parsing test program
Parse a playlist, then optionally a Media Playlist into the first
playlist it declared, as hls_read_header() does, and print the parsed
playlists with their finished state and EXT-X-START offset.
2026-10-22 02:51:14 +00:00
James Almer 9e6f96bac1 avformat/movenc: wrap AVIF specific functions with a preprocessor check
Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-21 18:35:41 -03:00
James Almer bcb0ac1d9d avformat/movenc: flag the alpha image in AVIF as hidden
Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-21 18:35:41 -03:00
James Almer 7461dbcb55 avformat/movenc: use bitstream information to write AVIF parameters if needed
If the pixel format is a hardware one, components will be unset, and we will
end up writing an invalid pixi box.

Signed-off-by: James Almer <jamrial@gmail.com>
2026-10-21 18:35:41 -03:00
Martin Mirchev 6dba2558c0 avformat/mov: check the stream group type when updating IAMF streams
The lookup of the stream group for each IAMF audio element compared only
the group id and kept the last match. Mix presentation groups are created
after the audio element groups and use the mix_presentation_id as their
id, so if a mix_presentation_id equals an audio_element_id the mix
presentation group was picked instead. Its entries are the streams of
every audio element, so the same output stream got its index entries
filled twice and the av_assert0(!out_sti->index_entries) aborted.

Such files are written by FFmpeg's own mp4 muxer, e.g. with two audio
elements with ids 1 and 2 and a mix presentation with id 1.

Also check the group type. Keep using the last match: audio element ids
are only unique within one IAMF track, and the groups of the current
track were just appended, so the last match is the audio element of the
current track even if an earlier track uses the same id.

Signed-off-by: Martin Mirchev <mmirchev@comp.nus.edu.sg>
2026-10-21 16:32:08 +00:00
StressTestorandClaude Opus 5.5 c50d6fca7a avformat/mpegts: stop the raw PCR readahead on a short read
mpegts_raw_read_packet() with compute_pcr looks ahead up to
MAX_PACKET_READAHEAD packets for the next PCR, reading 12 bytes of
each candidate into a stack buffer with avio_read() and ignoring the
return value. When the lookahead runs past the end of the file the
buffer keeps whatever it held, uninitialised on the first iteration,
and parse_pcr() is run on it. If those bytes happen to look like a
PCR, the garbage difference becomes pcr_incr and is published as the
duration of this packet and the pts of every later one. On a build
with -ftrivial-auto-var-init=pattern a file ending in a partial
packet yields duration=1716393918470 instead of 27000000.

Stop the readahead when the seek or the read fails. The packet itself
was already read successfully, and the "no next PCR found" fallback
to the previous increment is the designed behaviour for this case, so
failing the packet would be wrong.

Same class as c2394a0ff3 (binka), 29f513af78 (fsb), 4b47405e1c (genh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: StressTestor <212606152+StressTestor@users.noreply.github.com>
2026-10-21 09:27:17 +00:00
StressTestorandClaude Opus 5.5 47ed4708e2 avformat/wtvdec: fail on a short read of a legacy attribute GUID
get_tag() reads a 16-byte GUID attribute into a stack buffer with
avio_read() and ignores the return value. On a legacy_attrib entry
that is cut inside the GUID, the 16 bytes are never written and the
uninitialised stack contents are formatted with PRI_PRETTY_GUID and
published as a metadata string; ffprobe prints them as e.g.
"TAG:encoder=aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaaaaaa" on a build with
-ftrivial-auto-var-init=pattern.

Use ff_get_guid(), which reads with ffio_read_size() and fails on a
short read, and return without adding the tag, as get_tag() already
does when a string attribute is empty.

Same class as c2394a0ff3 (binka), 29f513af78 (fsb), 4b47405e1c (genh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: StressTestor <212606152+StressTestor@users.noreply.github.com>
2026-10-21 09:27:17 +00:00