Decrypts a stream that was encrypted as a whole with AES in CTR mode,
with a key of 128, 192 or 256 bits. The counter block is the IV plus
the index of the block as a 128 bit big endian number, so the stream
seeks wherever the inner stream does.
A failed curl_global_init(), curl_multi_init() or curl_multi_perform()
sets a flag on the curl context. When unusable state is detected, all
requests are rejected.
Limit a read to what is left of the slice. The limit was the distance
from the position inside the slice to the absolute end, so a slice with
a start above zero returned up to a buffer of data past its end.
Fixes: ffa9aaa2e4
Parse the end of every reply's Content-Range and keep requesting from
where the reply stopped until the known size is reached. With an unknown
size ("bytes S-E/*") only a 416 tells where the file ends, so treat it
as EOF and take the size it reports. Validate the status and offset of
follow-up replies and drop the body of anything else.
get_size() takes the size from fstat(). The size only means something
for regular files. For pipes and sockets macOS and the BSDs put the
number of bytes currently buffered in st_size, so mpv reported a small
value that changed with every read as the stream size. Since 20eead1813
switched from lseek(), which fails on pipes, to fstat(), the guard only
handled the case where st_size is 0, which is what Linux reports.
FFmpeg 9.0.1 started[1] to bound the trun sample count by avio_size()
and rejects fragments once the pipe holds fewer bytes than the sample
index has entries.
Don't report a size for non regular files that are not seekable. Windows
is unaffected because mp_fstat() already reports 0 for pipes, same as
Linux.
[1] https://github.com/FFmpeg/FFmpeg/commit/ae0e0ba3c3df840191e7a4c9b76494372ec53202Fixes: #18405
BD-J applets seek their player and restart playlists without any event
reaching the read loop, menu loop points do this constantly. Compare
bd_tell against the end of the previous read and treat a mismatch as a
jump. Checking before the read keeps the new position's head out of
the old slave demuxer, the forward-only stream cannot re-read it. A
read delivered together with a jump event can already carry data of
the new position, the same check drops it.
The release of a still can already sit in the event queue behind the
event that announced it. Holding at first sight would miss it and
freeze the menu until user input. STILL_TIME is re-emitted on every
read while the still holds and does not count as progress.
Menu-domain seeks: menu PGCs sequence intro/transition segments and
the looping button segment as programs of one PGC, and the menu
subpicture is a one-shot packet at a cell start. dvdnav's time search
lands mid-cell (erratically so in menu VOBs, which often lack usable
time maps), skipping the subpicture and leaving the menu without
visible buttons until its next loop. Map menu seeks to program skips.
Title seeks: dvdnav_time_search() interpolates the target from cell
durations. On VBR content the landing can fall further short than the
seek step, so repeated relative seeks converge to a fixed point and
never advance. Use dvdnav_jump_to_sector_by_time(), which resolves
through the VTS time maps, with dvdnav_time_search() as the fallback for
titles without one. Accurate landings also let the hr-seek margin
shrink.
A menu change keeps the VM's selected-button register unless the link
command carried a button number or the new button set forces one via
fosl_btnn. Select the first button in that case.
The resync seek that follows a disc-initiated jump must not reposition
the VM. On BD the jump is handled out-of-band by reopening the slave
demuxer on the packet-read path, and the VM already sits at the jump
destination. Repositioning it with the (stale) seek target time would
hop to the wrong place. Adopting the discontinuity counter here would
leave the old slave demuxer parsing the new playlist's data with the
wrong codec context. Flush our side only, and keep the counter stale so
the read path still performs the reopen.
Passing a disc image directly (e.g. `mpv disc.iso`) previously fell
through to FFmpeg. Route it to the matching disc backend instead,
like the VIDEO_TS.IFO/AUDIO_TS.IFO/BDMV redirectors already do.
When the disc VM jumps (menu activation, end of title), the demuxer
and player have to flush and reinitialize exactly at the boundary.
Hold an EOF at the boundary until the demuxer acks it, and resync
the player with a regular seek, which already orders flush, decoder
reset and restart. d_seek recognizes the held boundary and releases
it instead of repositioning the VM.
Also log the VM domain in nav event messages.
DVD-Audio discs carry an Audio Still Video Set (ASVS). An MPEG-2 still
images (cover art, booklet/lyric pages) that the disc associates with
tracks.
A new STREAM_CTRL_GET_STILL returns the still for a given playback time.
demux_disc exposes it as a selectable mpeg2video track and injects the
still as a keyframe at the track's playback time. It changes as playback
crosses track boundaries (and follows onset times when a disc encodes
them).
--dvda-page (with the new STREAM_CTRL_SET_STILL_PAGE) forces a specific
still page instead of the scheduled one. The still state is guarded by
a mutex, runtime page changes arrive from the player thread while the
demuxer thread extracts stills.
Add a dvda:// protocol backed by libdvdread. Audio title sets are
enumerated from the ATS IFOs. Each ATS title is exposed as an mpv
title/edition and its tracks as chapters.
Menus are not supported, they would need full VM implementation, and
libdvdnav currently doesn't support DVD-Audio.
Still images (ASVS) may be supported in the future.
The menu/highlight state is filled by event processing on the demuxer
thread and read by nav commands and controls on the player thread. Add
a mutex around it.
BD_EVENT_POPUP was tracked into has_popup, which never grew a
consumer. BD_EVENT_MENU's menu_event_active only fed the menu_active
condition, where it was subsumed by the visible-overlay check. Remove
all three.
The highlight rectangle and palette were passed around as loose fields
in three places. Bundle them into a struct, pass the whole nav state to
the sd_lavc control.
This is awkward, because libbluray has a single global log callback.
libmpv can spawn multiple players in a single process, and the
instance created last takes over the callback (the previous instance's
log stays alive until its stream closes, so a racing callback never
sees a dangling pointer). This mirrors how ffmpeg logging works.
The callback delivers only a string without severity, so everything is
printed as MSGL_DEBUG, with the libbluray debug mask derived from our
log level.
Use dvdnav_open2() with a logger callback instead of letting libdvdnav
print to stderr. This bumps the libdvdnav requirement to 6.1.0. 6.1.0 is
from 2019, it's resonable to request it by now.
Store the duration in 90 kHz ticks instead of converting back and
forth. This also fixes STREAM_CTRL_GET_CURRENT_TIME's failure check,
which previously compared the already-converted value against -1 and
could never trigger.
Menu activations, HOP_CHANNEL and VTS changes jump the source position.
On this strictly forward stream the demuxer cannot tell where the old
content ends, so buffered pre-jump data would mix with post-jump data.
Return a single EOF at the boundary so the demuxer drains and resets
before any new content flows.
Menu support added bd_read_ext for events but kept the old bd_read
path, leaving two read loops. Use bd_read_ext everywhere and handle
all events in one place.
Track BD_EVENT_STILL/STILL_TIME. Hold playback on indefinite stills and
skip timed stills only. Activations on a held still bump the
discontinuity counter, the disc VM will jump.
DVDNAV_STILL_FRAME means the VM is holding a frame indefinitely (menu
pages, some logos) or for a timed duration. Report the indefinite case
via nav state so the player holds playback at EOF instead of ending
the file, and skip timed stills, which would otherwise stall playback.
We cache some state like title properties, in some cases during deinit
player thread may actually try to read it during demuxer thead read.
Just add a lock, it shouldn't be called frequently to cause too much
synchronization.
Internally the angle stays 0-based (matching the libbluray API), only
the user-visible option/property values are 1-based. BD_EVENT_ANGLE
delivers a 1-based value and is converted on arrival.
The disc VM advances when the stream is read, so in nav mode the cache
must not run ahead of what the user is seeing. Never read ahead (a
looping menu is endless). Never satisfy seeks from the cache either.
This applies to the whole disc session, not only while a menu is on
screen. The VM can jump at any time (BD-J timers, end of title), so
the cache must never run ahead of playback.
Activations still must be able to drive the VM while nothing is
consumed. demux_drive_nav() forces a single read for them.
Adds support for the ARGB overlay callback from libbluray. libbluray
does not convert between its overlay formats, BD-J planes arrive as
ARGB while HDMV planes arrive RLE-encoded, so both callbacks have to
be supported.
When the Java VM is not available, fall back to non-menu playback.
Also bump libbluray requirement to 1.0.2, it was released in 2017.
The disc VM selects audio and subpicture streams itself (menu SPU
highlights, title-authored stream changes on jumps). Follow the VM's
selection on every hop, and turn subtitles on/off with the disc's
sub_visible flag.
The sync only applies while the corresponding track selection is on
auto. An explicitly chosen track (--aid/--sid or runtime cycling) is
never overridden.
Playing a disc through the menu means crossing playlist boundaries at
runtime: menu -> title (and back), sub-menu -> sub-menu, title -> title.
Each new playlist can have a different stream count and/or a different
codec mix. The previous slave demuxer was probed once at open and never
refreshed, so after a hop the player either kept decoding stale streams
or saw nothing at all. Tear down and re-open the slave on every nav
discontinuity.
Add HDMV menu support to stream_bluray, activated by opening with
"bd://menu/..." or the global --disc-menu option.
The IG overlay plane arrives through the libbluray YUV overlay
callback. Decode the palettized RLE into a BGRA plane (premultiplied
alpha) and hand it to the player via STREAM_CTRL_GET_NAV_OVERLAY.
STREAM_CTRL_NAV_CMD maps arrow/select/menu/popup/mouse actions onto
bd_user_input() and bd_mouse_select(). Events relevant to the menu
state (title, playlist, menu on/off) are tracked so
STREAM_CTRL_GET_NAV_STATE can report an active menu, and playlist
changes bump discontinuity_id so the player flushes stale packets.
Drive libdvdnav's menu state through the new disc-nav protocol so the
player can show and interact with VMGM and VTSM menus.
STREAM_CTRL_NAV_CMD maps the nav actions onto libdvdnav.
STREAM_CTRL_GET_NAV_STATE reports whether a menu with buttons is on
screen, the highlight rectangle and palette of the focused button, and
the ids of the disc-selected audio/SPU streams.
Menu mode is entered by opening with dvd://menu or --disc-menu, which
starts at the disc's root menu instead of a title.
Define three new stream controls so disc backends (libdvdnav, libbluray)
can expose their in-disc menu/highlight state to the player.
Not used yet, the next commits add the backends and the player side.
While here, drop the message to MP_VERBOSE and fix its wording.
"switched to title" is misleading because this is a VTS-change event,
not a title change.
request_start is producer state, a fast transfer can complete and roll it
forward before curl_open gets to read it, mislabeling all stream offsets.
Store the requested offset separately and use it for the initial pos.
Fixes: 289723b41a