Fixes use of uninitialized value and dumping it into AVERAGE-BANDWIDTH
in playlist. Note this will be correctly set when we are at final
segment, otherwise it's optional.
Fixes: fate-hls-seek test on MSAN build
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Sometimes the duration itself reflects the remainder samples by being set to a
value lower than the frame size, but in other cases it's done only through
a discard padding value in side data.
Take the latter into account when calculating durations.
Fixes issue #23532.
Signed-off-by: James Almer <jamrial@gmail.com>
Anchor c->first_timestamp to the playlist that established it and only let
that playlist's expiring segments advance it, so it slides exactly once
per window slide.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
After a seek, hls_read_packet drops packets until each playlist reaches
seek_timestamp. That threshold lives on c->first_timestamp's baseline,
i.e. the DTS of whichever stream produced the very first packet. Streams
can have different DTS baselines though. So comparing one stream's
threshold against another stream's DTS is wrong. A stream whose first
keyframe precedes the global baseline gets its segment keyframe dropped
and resumes a segment (or more) late.
Track the first DTS per playlist and rebase the threshold onto each
playlist's own baseline. Since HLS segments are presentation-aligned
across renditions, every stream then resumes at the same presentation
time. seek_timestamp keeps its meaning on the global timeline, only the
per-playlist comparison value is translated.
This fixes playlists that would be unable to play from the start, and
instead skip one or more segments, before data is output.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
find_timestamp_in_playlist() already selects the first segment when the
target is below the playlist's first timestamp, but returns 0.
hls_read_seek() treats that as a failure, and all seek operation is
failed.
This breaks seeking to the very start whenever the requested timestamp
is slightly below the first one. Clamp such targets to the first segment
and report success instead.
Fixes: https://github.com/mpv-player/mpv/issues/14840#issuecomment-4703186169
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
CMAF and other EXT-X-BYTERANGE playlists address consecutive segments as
contiguous byte ranges of a single resource. Each segment was fetched with
a separate bounded request, paying a request/response round-trip per
segment even though the connection was kept alive.
Keep the AVIOContext open across segments of the same resource and seek to
the next segment instead of reopening, for contiguous ranges the seek
targets the current position and issues no request in practice.
Non-contiguous, encrypted and non-seekable cases fall back to the
previous reopen behaviour.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Master playlists can reference the same media playlist URI from several
rendition group. new_playlist() allocated a separate playlist struct for
each reference, this is unndeded work and we can fold duplicates into
single probe.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
If the HTTP server still has stale bytes in the TCP receive buffer, but
the underlying conection was already closed, then the http_open_cnx()
call might fail even though we successfully drained the previous request.
In this case, there is no proper fallback to a new connection, leading to
sudden truncation.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
Otherwise, this might leak stale bytes that were already drained by the
HTTP soft-seek attempt.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
This avoids an underflow if short_seek is negative (which can happen if e.g.
ffurl_get_short_seek() returns AVERROR(ENOSYS)), as well as a possible
underflow if the read position is somehow past `range_end` (e.g. if the HTTP
server malicously lied about the content range but gave us more bytes anyway)
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
The avpriv_packet_list_put/get/free() functions and the PacketList type
were implemented in libavcodec and exported via the avpriv_ mechanism
solely so that libavformat (and decklink in libavdevice) could use them;
libavcodec itself has no users of them. Exporting them across the library
boundary has the usual drawbacks for shared builds (export/import overhead
and having to keep them around for ABI stability even once unneeded).
Move the implementation and the PacketList/PacketListEntry types to
libavformat and rename the functions to ff_packet_list_*(). libavformat is
the primary user and compiles the new packet_list.c directly; decklink,
the only libavdevice user, gets a private copy for shared builds via the
SHLIBOBJS scheme already used for reverse.o and ccfifo.o (static builds
resolve the symbols from libavformat).
AVPACKET_IS_EMPTY() and ff_side_data_set_prft() remain in
libavcodec/packet_internal.h as they are libavcodec-internal.
The decision to switch to checking peer certificates by default
at the next major version bump was announced on 2025-08-09
in commit 5621eee672.
Thanks to Michael Niedermayer for pointing out that the documentation
needs to be updated, too.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Removing the dtls_start() and create a simple dtls_open()
wrapper that just set s->is_dtls and call tls_open() to
use common code.
Signed-off-by: Jack Lau <jacklau1222gm@gmail.com>
This is first step for moving dtls related code
into tls_open() to make sure they can use common
code in one function.
Next patch should be removing dtls_start() and create
a simple dtls_open() wrapper (set is_dtls and then call
tls_open()) just like GnuTLS.
Signed-off-by: Jack Lau <jacklau1222gm@gmail.com>
fix ticket: 8636
video_keyframe_size and video_keyframe_pos tracked the end of the
previous P/B frame. In the case of I-frame only videos, this would
result in byteoffsets always being 0@0 in the case of fmp4. For
mpegts, the size would be correct but the pos still always be @0.
Since size and pos already correctly track the start of a segment,
we can re-use them even in I-frame only mode.
Both the seek index and the stream duration are constantly being updated as
trun boxes are read.
Fixes mpv issue 18149.
Signed-off-by: James Almer <jamrial@gmail.com>
Fixes: NULL pointer dereference
As a sideeffect this also sets the timescale correctly if an
intermediate matches MOV_TIMESCALE_Q, the previous code stoped
in that case as it could not distinguish it from the overflow detection
Regression since: 51f5f60443
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Some muxers, like Matroska, use it to write priming samples.
fate-segment-adts-to-mkv no longer uses the ref file from
fate-segment-adts-to-mkv-header-all as it's demuxed through the hls demuxer
and this commit exposed a bug where initial padding is not being propagated.
Signed-off-by: James Almer <jamrial@gmail.com>
The default of 1000 may result in off by 1 errors when rescaling certain
durations, as is the case of fate-gaplessenc-itunes-to-ipod-aac, so lets
try to prevent that by using a global timescale every track can agree
with whenever possible.
Signed-off-by: James Almer <jamrial@gmail.com>
When a demuxer reports the last packet with a duration smaller than the real coded duration,
this information is not relayed to the decoder, which will happily output all the trimming
samples anyway.
Fix that by ensuring we export a discard padding information as side data.
Signed-off-by: James Almer <jamrial@gmail.com>
fix issue: issues/23238
Several time-related fields in DASHContext were declared as uint64_t,
causing the arithmetic in calc_cur_seg_no(), calc_min_seg_no(), and
calc_max_seg_no() to be performed with unsigned semantics.
The expression:
(get_current_time_in_sec() - availability_start_time) * fragment_timescale
is uint64_t throughout. When presentationTimeOffset is large (e.g. an
absolute epoch-based timestamp common in DVB-DASH live streams), the
subsequent subtraction:
uint64_t_result - presentation_timeoffset
wraps around to a value near 2^64, because the elapsed wall-clock time
in timescale ticks is far smaller than the absolute presentation time
offset. The enormous quotient ends up truncated to int32_t when passed
to ff_dash_fill_tmpl_params(), producing a negative $Number$ value in
the segment URL and causing repeated HTTP 403 errors.
Fix this by changing the affected fields and the two helper functions
(get_current_time_in_sec, get_utc_date_time_insec) from uint64_t to
int64_t. All values involved are well within the int64_t range (Unix
timestamps in seconds and ISO 8601 durations), and the arithmetic
naturally needs signed semantics because intermediate sub-expressions
like (elapsed - time_shift_buffer_depth) can be negative at stream
start.
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
At check_count == CHECK_COUNT the existing branch caps the score at
SCORE_MAX/2 even when every analyzed packet is sync-aligned and when
analyze() already has full confidence. This loses probe to
signature-only image demuxers (e.g. png_pipe at SCORE_MAX - 1) for
streams with a small leading non-TS prefix. Some CDNs prepend a 1x1 PNG
to MPEG-TS payloads to bypass image-only Content-Type filtering, and the
PNG signature otherwise wins the first probe iteration.
Fixes: https://github.com/mpv-player/mpv/issues/11365
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
If the filesize is known as a result of AVERROR_EOF on a block that ends
before the current seek position, this might end up negative. Error
out cleanly instead of aborting.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
flock() also locks against accesses by other threads of the same
process, unlike fcntl().
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
Instead, read to the output/temporary buffer (write_back path). This is to
lessen the impact of racing the write against other clients trying to race
the same pending block.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
Needed for the upcoming commit, but also more robust in general. The memory
waste is negligible.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
This value is matched to the typical seek latency in a reasonably capable
7200 rpm disk device, as well as the typical latency of an on-premise HTTP
request.
Note that this change should rarely have a significant effect, because
it only matters when using multiple concurrent processes, and one process
is somehow stuck in I/O (or died). Since we sleep in a loop for 1/16th of
the requested timeout value, this should only increase the effective read
latency by up to ~500 us on top of the actual underlying latency.
The alternative is hammering the same underlying resource with the exact
same requests at the exact same time (e.g. during init).
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>