Before this commit, the user could specify a printf format string
which wasn't verified, and could result in:
- Undefined behavior due to missing or non-matching arguments.
- Buffer overflow due to untested result length.
The offending code was added at commit 103a9609 (2002, mplayer svn):
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4566 b3059339-0415-0410-9bf9-f77b7e298cf2
It moved around but was not modified meaningfully until now.
Now we reject all conversion specifiers at the format except %%
and a simple subset of the valid specifiers. Also, we now use
snprintf to avoid buffer overflow.
The format string is provided by the user as part of mf:// URI.
Report and initial patch by Stefan Schiller.
Patch reviewed by @jeeb, @sfan5, Stefan Schiller.
Trigraphs such as "??=" (which are enabled by default with -std=c11)
can mess up strings, so avoid them entirely by escaping question marks.
This also drops Python 2 compatibility from file2string, making the
change to the waf rule necessary. The input file is now opened in
binary mode which is also more correct versus the old text mode
which just happened to work even on binary files.
This reverts commit 3d17e19c2c.
The effect of turning off this setting is that mpv doesn't tell libass what
the video stream's resolution is. This happens to result in some files having
their transforms scaled in ways that give higher performance (as described
in #7435) because libass happened to guess a video resolution that resulted
in transforms yielding smaller bitmaps, but it's just as easy for the opposite
to happen depending on the resolutions and effects involved.
The option's name is also somewhat misleading: setting the storage size affects
blur, but it also affects stroke (which is far more important for the vast
majority of scripts) and 3D transforms (which look very screwy when done wrong).
Upstream waf still ships with the default interpreter being "python",
though the script works with both Python 2 and Python 3 (they're not
changing the default choice during 2.0.x releases for compatibility
reasons apparently). Add code to bootstrap.py to change the
interpreter from "python" to "python3" when downloading the "waf"
file.
Running any mpv code under Python 2 should be considered unsupported
in the future (and any code added need not work under Python 2).
remove the hardcoded swift target version and move the version
restriction to configure. this was a bad idea anyway and could lead to
mismatched object files between obj-c and swift. fix travis 10.12 legacy
build.
also update the SDK version parser to handle the new macOS 11 scheme.
Fixes#8281
Currently in mpv functions sixel failures return the
value status which is of type SIXELSTATUS. So changing
it to -1 which is explicit and compatible with mpv.
Also log the errors using MP_ERR/MP_LOG with the
error string returned by libsixel to have more info.
fixedpalette seems to be slightly faster than dynamic
palette, and also in mlterm it avoids corruption of
too bright values overflowing to black. Hence setting
it to be default choice instead of dynamic palette.
Resize the image based on the dimensions reported by
vo_get_src_dst_rects to correctly handle aspect ratio
that might be set/ignored.
Added pad-x and pad-y options for padding.
These options will be used to remove the extra padding.
Some terminals report the padding of 2px in the ioctl
dimensions which can't be used for displaying sixel
output. These options can be used for fine tuning
the output video resolution.
Now all the terminal size detection and calculation logic
is done in a single function at resize. Also top and left
values are computed from the dst_rect parameters to simplify
the logic for the aspect ratio based centering.
Additionally vo-sixel-rows and vo-sixel-cols options
have been added to enable the user to override the values
in case of failures with get_terminal_size2.
This commit also adds ability to handle video zoom correctly.
Whenever video-zoom is triggered, the src and dst rects
will be updated. Scaling seems to work well now.
This has no changes to mpv sixel playback behaviour.
This is required because currently the offset values
and the resolutions are being overwritten and not
remembered.
Having them in the same line made it hard to read them in the man page
since they are formatted in the same way and they look as though they
are only one definition.
Recent versions of mpv have applied security checks to --playlist
that previously only existed if playlist files were played as an
input directly. This commit documents this change and how to work
around it, in the event that playlist files are trusted.
Previously the mouse command never ended up in enter/leave keypresses
for the default section even when logically required, because input.c
does not know the area of the default section and relies on something
feeding it ENTER/LEAVE presses - which the VO typically does but the
mouse command didn't.
Now the mouse command feeds it ENTER/LEAVE if required.
It's possible to handle it differently and more consistently by:
1. reverting this commit.
2. Updating the default section area whenever the osd dimensions change.
3. Always ignore MOUSE_ENTER keys because the position is not known yet
(but MOSE_MOVE typically follows right away).
4. On mouse move: first generate ENTER/LEAVE if required.
That would guarantee consistency between mouse position and enter/leave
events but could be more sensitive to manage (the default section has
"infinite" area which is used to capture any event outside of specific
section areas), while this commit keeps consistency same as before and
depending on correct external feeding - which we now do better, even if
still not optimally (like before, it's still technically possible that
a script recieves MOUSE_ENTER and then reads the position before it got
updated after the ENTER).
Add a third field: "hover", which is updated from input.c after input
keys MP_KEY_MOUSE_LEAVE and MP_KEY_MOUSE_ENTER - which are typically
sent by the VO.
It's part of mouse-pos and not a new property because it's highly tied
to mouse-pos - it makes x/y invalid while the cursor doesn't hover the
window.
Unike mouse-move, no dummy command was generated, so we add dummy
command in order for observer notification to work even while nothing
is bound.
Like mouse-pos, clients could not detect whether the mouse pointer
hovers the window because the OSC force-binds the MOUSE_LEAVE key, and
now they can using the hover field.
The lua mp.get_mouse_pos() wrapper still returns only x, y because
that's what osc.lua needs. Other clients can simply read the property.
mp.get_mouse_pos() is undocumented and is no longer required - the
property can be used officially by any client now, however, osc.lua
uses it, and also some user scripts learnt to rely on it, so we keep
it - as a trivial wrapper around the new mouse-pos property.
This is a read-only MPV_NODE value with integer fields: x, y.
The values are unmodified from mp_input_get_mouse_pos(...).
Observer notification of this property is tied to the INPUT_PROCESSED
event, which fires after mouse move even if no command is bound
(dummy commands are generated if nothing is bound to ensure that
mp_input_get_mouse_pos returns the latest values - see ac927e39 ).
This allows clients such as JSON IPC to observe mouse position even
while the OSC is enabled - the OSC force-binds mouse move for most
of the window area, making it impossible for other clients to bind
mouse move without breaking the OSC.
Apparently mpv supports loading config files from the same directory as
the mpv.exe. This is a fallback of some sort. It used the old_home
mechanism.
I want to add a warning if old_home exists, but that would always show
the warning on win32. Obviously we don't want that.
Add a separate exe_dir entry to deal with that.
Untested, but probably works.
Mistakenly reverted as part of the default configuration directory
location switch-back in aa18a8e1cd.
Separation of the mpv executable directory from old_path is a
good change now that we warn about the old_config directory also
existing.
Fixes#8232Fixes#8244Fixes#8262
This can be viewed at page 4 of the internal stats display (i or I).
CPU time report is the same as at lua.c, but untested - doesn't seem
to work on windows - also not for lua.
TL;DR: Set env MPV_LEAK_REPORT=1 to enable js memory reporting stats.
This also almost doubles the memory usage by js scripts.
For memory reporting, we don't have enough info by default, because
even when using a custom allocator, mujs doesn't report the old size
(on free or realloc) because it doesn't track this value, and as
a result we can't track the overall size.
Our option are either to track the size of each allocation on our own,
or use talloc which tracks this value.
However, using talloc for mujs allocations adds a considerable
overhead, and almost doubles(!) the overall memory used, because each
individual allocation includes a considerable talloc header, and mujs
does many small allocations.
So our solution is that by default we behave like previously - not
using a custom allocator with mujs, and stats does not display memory
usage for js scripts.
However, if the env var MPV_LEAK_REPORT is set to 1, then we use
a custom allocator with talloc and track/report memory usage.
We can't switch allocator at runtime, so an mpv instance either tracks
or doesn't track js scripts memory usage, according to the env var.
(we could use a property and apply it whenever a new script starts,
so that it could change for newly launched scripts, but we don't).
- Explain which properties are writeable.
- Mark edition-list/N/id as writable.
- Remove (R) from some read-only properties since none of the others
have it.
- Add osd-dimension/ to its subproperties.
- options/<name> isn't read-only.
- focused works on macOS because of 82eda2e. Though it shouldn't be
possible to observe it without raising VO_EVENT_FOCUS.
The picture type is explained in /usr/include/libavutil/avutil.h
Other subproperties in /usr/include/libavutil/frame.h
And there is a more detailed explanation for repeat_pict in
/usr/include/libavcodec/avcodec.h
When possible, refer to booleans with "Whether..." since it can refer to
both yes (using input.conf and mp.get_property) and true (using the JSON
IPC or mp.get_property_native/bool), else explicitly say yes/true.
Say "true" for subprocess and osd-overlay named arguments since you
can't use them in input.conf and you will typically use them with the
boolean true in the named arguments, like the subprocess example in the
manpage does (though the string "yes" also works).
Subproperties that can't be accessed with the / syntax like
demuxer-cache-state's bof-cached and eof-cached always return true,
never yes.
Set pcm state to SND_PCM_STATE_XRUN in case -EPIPE is received,
and handle this state as per the usual logic.
This way snd_pcm_prepare gets called, and the loop continued.
Inspired by a patch posted by malc_ on #mpv.
The pointer button event had no code to handle any modifier keys. So
this meant input combinations like Shift+MTBN_LEFT did not work. Fix
this by ripping out the modifier-checking code in keyboard key event to
a separate function and using it for both the keyboard and mouse events.
In the case of the mouse, it is possible that the keyboard may not exist
so be sure to check before trying to get any modifiers. Fixes#8239.
30dcfbc is a workaround for incorrect border sizes that could occur on
sway/wlroots in certain edge cases. This seemed harmless enough, but it
turns out that on mutter the extra wl_surface_commit somehow causes the
window always go to the top left of the screen after you leave
fullscreen. No idea why this occurs, but the original commit is a
workaround a sway bug and causing regressions for other users isn't
right despite the author being biased towards sway/wlroots.
This reverts commit 30dcfbc9cb.
Based on the implementation of ffmpeg's sixel backend output written
by Hayaki Saito
https://github.com/saitoha/FFmpeg-SIXEL/blob/sixel/libavdevice/sixel.c
Sixel is a protocol to display graphics in a terminal. This commit
adds support to play videos on a sixel enabled terminal using libsixel.
With --vo=sixel, the output will be in sixel format.
The input frame will be scaled to the user specified resolution
(--vo-sixel-width and --vo-sixel-height) using swscaler and then
encoded using libsixel and output to the terminal. This method
requires high cpu and there are high frame drops for 720p and
higher resolution videos and might require using lesser colors and
have drop in quality. Docs have all the supported options listed
to fine tune the output quality.
TODO: A few parameters of libsixel such as the sixel_encode_policy
and the SIXEL_XTERM16 variables are hardcoded, might want to
expose them as command line options. Also the initialization
resolution is not automatic and if the user doesn't specify the
dimensions, it picks 320x240 as the default resolution which is not
optimal. So need to automatically pick the best fit resolution for
the current open terminal window size.
This allows keybindings such as:
a script-message-to console type "seek :0 absolute" 6
% script-message-to console type "seek absolute-percent" 6
The cursor position 0 isn't allowed because it has the weird effect of
filling the console with the text twice, leaving the cursor in the
middle.
Negative positions would put the cursor n characters before the end, and
positions greater than the text's length at the end. They seem to work
at first, but the console breaks when you move the cursor, so they
aren't allowed.
It seems that float values don't cause issues, but I'm using the
argument's floor anyway to be safe. Using >= 1 instead of > 0 ignores
values like 0.5.
The wl_pointer interface defines button argument as “a button code as
defined in the Linux kernel's linux/input-event-codes.h header file,
e.g. BTN_LEFT.”
We could #define these few buttons ourselves, but there is no system to
test it on, so for now let’s disable Wayland support on them.
This is a call to non-Linux system maintainers, please help test this
backend on your system and report issues you find, or even working
state.
Wayland’s wl_pointer interface describes the button event’s argument as
being taken from linux/input-event-codes.h, so there is no need to
include the more generic linux/input.h.
This introduces the delete-watch-later-config command, to complement
write-watch-later-config. This is an alternative to #8141.
The general problem that this change is attempting to help solve has
been described in #336, #3169 and #6574. Though persistent playback
position of a single file is generally a solved problem, this is not
the case for playlists, as described in #8138.
The motivation is facilitating intermittent playback of very large
playlists, consisting of hundreds of entries each many hours
long. Though the current "watch later" mechanism works well - provided
that the files each occur only once in that playlist, and are played
only via that playlist - the biggest issue is that the position is
lost completely should mpv exit uncleanly (e.g. due to a power
failure). Existing workarounds (in the form of Lua scripts which call
write-watch-later-config periodically) fail in the playlist case, due
to the mechanism used by mpv to determine where within a playlist to
resume playback from.
The missing puzzle piece needed to allow scripts to implement a
complete solution to this problem is simply a way to clean up the
watch-later configuration that the script asked mpv to write using
write-watch-later-config. With that in place, scripts can then
register an end-file event listener, check the stop playback reason,
and in the "eof" and "stop" case, invoke delete-watch-later-config to
delete any saved positions written by write-watch-later-config. The
script can then proceed to immediately write a new one when the next
file is loaded, which altogether allows mpv to resume from the correct
playlist and file position upon next startup.
Because events are delivered and executed asynchronously,
delete-watch-later-config takes an optional filename argument, to
allow scripts to clear watch-later configuration for files after mpv
had already moved on from playing them and proceeded to another file.
A Lua script which makes use of this change can be found here:
https://gist.github.com/CyberShadow/2f71a97fb85ed42146f6d9f522bc34ef
(A modification of the one written by @Hakkin, in that this one takes
advantage of the new command, and also saves the state immediately
when a new file is loaded.)
Testing kwinft out (kwin fork), it was discovered that sometimes it
would return a ust value of 0 which subsequently resulted in incorrect
presentation statistics (i.e. large negative numbers which are obviously
impossible). Arguably, it shouldn't return 0s, but a workaround for mpv
in this case is harmless.
As we are now on 20.04, these packages are now available in the
repositories. Additionally, they don't need to be separately pulled
in, as gcc-mingw-w64 already does that.
The original documentation here is unclear, so let's describe the
behaviour we actually have. Inspired by wm4's updated docs but
obviously not identical because we're not changing any of the
behaviours.
There have been mentions that there are apparently some bugs with
regards to possible random build failures, so bumping after a few
years sounds like an OK thing to test/do.
VOCTRL_UPDATE_RENDER_OPTS is supposed to be optional so check if it
actually exists before executing the function. Fixes a segfault when
changing the alpha value at runtime on non-wayland platforms.
7fb972f fixed transparency on x11/EGL/Mesa but happened to also break it
for wayland and nvidia. Ideally on wayland, you should just be able to
pick the right EGLConfig that has alpha but this doesn't seem to work
because reasons. So just go back to setting the EGL_ALPHA_SIZE bit if
the user asks for alpha. Apparently this worked before for nvidia as
well. The hack is to just run an eglQueryString in the x11egl context.
If it picks up Mesa as the EGL_VENDOR, then force ctx->opts.want_alpha
to 0 and let pick_xrgba_config take care of the rest.
Made possible with 00b9c81. 34b8adc let the wayland surface set an
opaque region depending on if alpha was set by the user or not. However,
there was no attempted detection for runtime changes and it is possible
(at least in wayland vulkan) to toggle the alpha on and off. So this
meant, we could be incorrectly signalling an opaque region if the user
happened to change the alpha. Additionally, add a helper function for
this and use it everywhere we want to set the opaque region.
vo_gpu has a small set of options for ra_ctx that can be set. In
practice, runtime toggling doesn't matter for most of these as they have
no effect while a video is playing. However, changing the alpha option
during runtime can actually work depending on the backend used. mpv
already detected when one of these options changed, but it made no
attempt to update the options in the ra_ctx accordingly (likely because
nothing made any use of this information). Another related change is to
add an update_render_opts to the fns and allow invidiual backends to
(optionally) use it.
efb0c5c changed the rendering logic of mpv on wayland and made it skip
rendering when it did not receive frame callback in time. The idea was
to skip rendering when the surface was hidden and be less wasteful. This
unfortunately had issues in certain instances where a frame callback
could be missed (but the window was still in view) due to imprecise
rendering (like the default audio video-sync mode). This would lead to
the video appearing to stutter since mpv would skip rendering in those
cases.
To account for this case, simply re-add an old heuristic for detecting
if a window is hidden or not since the goal is to simply not render when
a window is hidden. If the wait on the frame callback times out enough
times in a row, then we consider the window hidden and thus begin to
skip rendering then. The actual threshold to consider a surface as
hidden is completely arbitrary (greater than your monitor's refresh
rate), but it's safe enough since realistically you're not going to miss
60+ frame callbacks in a row unless the surface actually is hidden.
Fixes#8169.
Fixes an issue with clang not using the -mconsole option if mwindows
is present resulting in mpv.com being a gui program instead of a
console program.
Does not interfere with gcc compilation.
result without this patch
```
file .\mpv.com .\mpv.exe
.\mpv.com: PE32+ executable (GUI) x86-64 (stripped to external PDB)
.\mpv.exe: PE32+ executable (GUI) x86-64 (stripped to external PDB)
```
both executables open the mpv gui with out console output.
result with this patch
```
file .\mpv.com .\mpv.exe
.\mpv.com: PE32+ executable (console) x86-64 (stripped to external PDB)
.\mpv.exe: PE32+ executable (GUI) x86-64 (stripped to external PDB)
```
mpv.com properly outputs text to console instead of instantly opening
a gui
`, for MS Windows` removed from the end of file outputs to reduce col
count
https://github.com/m-ab-s/media-autobuild_suite/issues/1794
Signed-off-by: Christopher Degawa <ccom@randomderp.com>
Pointless feature that can be done with environment variables. It was
also implemented incorrectly and broke autoprobing.
This reverts commit 015b676875.
As per the client API, a client can connect to any arbitrary wayland
socket. mpv has always just passed NULL which connected to the
compositor currently in use, but one could just as easily pass the name
of a different socket (i.e. the value of WAYLAND_DISPLAY). Here, we just
expose this argument as a user configurable option. If the user passes a
socket name that does not exist, then print a warning and fall back to
NULL.
Apparently a part of the wayland spec. A compositor may use a surface
that has set part of itself as opaque for various optimizations. For
mpv, we simply set the entire surface as opaque as long as the user has
not set alpha=yes (note: alpha is technically broken in the wayland EGL
backend at the time of this commit but oh well). wlshm is always opaque.
Fixes#8125.
Picks up files like "cover.jpg". It's made part of normal external file
loading, so I'm adding 3 new options that are direct equivalents for the
options that control loading of external subtitle and audio files. Even
though I bet nobody wants them and they just increase confusion... I
guess the world is actually hell, so this outcome should be fine.
It prefers non-specific external files like "cover.jpg" over embedded
cover art. Not sure if that's wanted or unwanted.
There's some pain over explicitly marking such files as external
pictures. This is basically an optimization: in most cases, a heuristic
would treat an image file loaded with --external-file the same (it's a
heuristic because ffmpeg can't tell us whether something is an image or
a video). However, even with this heuristic, it would decode the cover
art picture again on each seek, which would essentially slow down
seeking in audio files. This bothered me greatly, which is why I'm
adding these additional options at all, and bothered with the previous
commit.
Fixes: #3056
Essentially, this lets video.c decide whether to consider a video track
cover art, instead of having the decoder wrapper use the lower level
sh_stream flag.
Some pain because of the dumb threading shit. Moving the code further
down to make some of it part of the lock should not change behavior,
although it could (framedrop nonsense).
This commit should not change actual behavior, and is only preparation
for the following commit.
on macOS 10.15 setting the activation policy behaves quite weirdly. the
call changes the current active App to a nameless process, which
probably also the reason that prevents the not focusing to work.
a workaround for that, is to refocus the previous active app.
Fixes#7725
brew update tries to update the java cask, which it tries to build from
source. this takes too long and leads to a timeout of the job. we can't
manually remove the java cask because of a bug in the too old brew cask
version and the old formula. we just remove the whole cask tap and call
it a day, since we don't need it anyway.
Back in the olden days, mpv's wayland backend was driven by the frame
callback. This had several issues and was removed in favor of the
current approach which allowed some advanced features (like
display-resample and presentation time) to actually work properly.
However as a consequence, it meant that mpv always rendered, even if the
surface was hidden. Wayland people consider this "wasteful" (and well
they aren't wrong). This commit aims to avoid wasteful rendering by
doing some additional checks in the swapchain. There's three main parts
to this.
1. Wayland EGL now uses an external swapchain (like the drm context).
Before we start a new frame, we check to see if we are waiting on a
callback from the compositor. If there is no wait, then go ahead and
proceed to render the frame, swap buffers, and then initiate
vo_wayland_wait_frame to poll (with a timeout) for the next potential
callback. If we are still waiting on callback from the compositor when
starting a new frame, then we simple skip rendering it entirely until
the surface comes back into view.
2. Wayland on vulkan has essentially the same approach although the
details are a little different. The ra_vk_ctx does not have support for
an external swapchain and although such a mechanism could theoretically
be added, it doesn't make much sense with libplacebo. Instead,
start_frame was added as a param and used to check for callback.
3. For wlshm, it's simply a matter of adding frame callback to it,
leveraging vo_wayland_wait_frame, and using the frame callback value to
whether or not to draw the image.
In the recent terminal commit, I "compressed" the read() error handling,
and messed it up. The return value could be -1 for other non-fatal
errors (such as EIO when trying to read while backgrounded), which
resulted in buf.len getting messed up.
Fixes: 602384348e
Nobody needs this anymore. If not too many people complain, we'll remove
this completely. Many already consider X11 and OpenGL legacy, so we
don't need TWO X11/OpenGL backends.
Due to Unix being legacy garbage, it's not possible to safely detect the
ESC key on terminal. The key sequences are ambiguous. The code for the
ESC key also starts the sequences for other special keys.
Until now, you needed to hit ESC twice for it to be recognized.
Attempt to handle this better by using a timeout to detect the key. If
ESC is in the input buffer, but nothing else arrived after a timeout,
assume it's the ESC key. I think this is the method vim uses. Currently,
the timeout is set at 100ms. This is hardcoded and cannot be changed.
It's possible that this causes problems on slow ssh connections or so.
I'm not sure what exactly happens if you manage to get ESC + another
normal key into the input buffer. If it's a known sequence, it will be
matched and interpreted as such. If not, it'll probably be discarded.
Previous commit fixes it for libswscale. The libzimg path has extra code
to copy by slice, but it still may access pixel groups using normal
memory accesses (for example, reading rgba pixel data via uint32_t), so
document a minimum alignment requirement per pixel format.
If the alignment is less than 16, certain libswscale code paths will
silently corrupt memory outside of the target buffer. This actually
affected the libmpv software rendering API (that was fun to debug).
Rather than passing this problem to the next API user, try to avoid it
within libmpv.
It's unclear which alignment libswscale requires for safe operation. I'm
picking 32 (one more than the observed safe value in the case I
experienced), because libavfilter mostly uses this value.
The way to work this around is slow: just make a full copy of the entire
input or output image. Possibly this could be optimized by using the
slice API, but that would be more effort, and would likely expose
further libswscale bugs. Hope that this is a rarely needed path.
The next commit will update the alignment requirement documentation
bits.
Pause can be changed during a file change, such as with for example
--reset-on-next-file=pause, or in hooks, or by being quick, and in this
case the AO's pause state was not updated correctly. mpctx->ao_chain is
only set if playback is fully initialized, while the AO itself in
mpctx->ao can be reused across files.
Fix this by always running set_pause_state() if the pause option is
changed. Could cause new bugs since running this used to be explicitly
avoided outside of the loaded state. The handling of time_frame is
potentially worrisome.
Regression due to recent audio refactor; before that, the AO didn't have
a separate/persistent pause state.
Fixes: #8079
Since b74c09efbf, audio-only files let you seek to arbitrary points
beyond the end of the file (but still displayed the time clamped to the
nominal file duration). This was confusing and just not wanted. The
reason is probably that the commit removed setting the audio PTS for
data before the seek target, so if you seek past the end of the file,
the audio PTS is never set. This in turn means the logic to determine
the current playback time has no PTS at all, and thus falls back to the
seek PTS.
This happened in the past for other reasons (like efe43d768f). I have
enough of this, so I'm just changing the code to clamp the seek
timestamp to a "known" range. Do this when seeking ends, because in the
fallback case, the playback time shouldn't be stuck at e.g. "end +
seek_argument". Also do it when initiating a new seek (mp_seek), because
if the previous seek hasn't finished yet, it shouldn't add them up and
allow it to go "out of range" either. The latter is especially relevant
for hr-seeks.
Doing this clamping is problematic because the duration is a possibly
invalid value from the demuxer, or just missing. Especially with
timestamp resets, fun sometimes happens, and in these situations it
might be better not to clamp.
One could argue you should just use the last audio timestamp returned by
the decoder or demuxer (even if that directly conflicts with --end), but
that sounds even more hairy.
In summary: what a dumb waste of time, what the fuck.
Add a property that returns whether the window is focused, currently
only for X11 and Wayland.
My use cause for this is having an equivalent of pause-when-minimize.lua
for tiling window managers: make mpv play only while it's in the current
workspace or is focused (I'm fine with either one but prefer focus).
On X I do this by observing display-names, which is empty when the
rectangles of the display and mpv don't intersect, but on Wayland its
value doesn't change when mpv leaves the current workspace (and the same
check doesn't work since the geometries still intersect).
This could later be made writable as requested in #6252.
Note that on Wayland se shouldn't consider an unactivated window with
keyboard input focused.
The wlroots compositors I tested set activated after changing the
keyboard focus, so if you set wl->focused only in
keyboard_handle_enter() and keyboard_handle_leave() to avoid adding the
"has_keyboard_input" member, focused isn't set to true when first
opening mpv until you focus another window and focus mpv again.
Conversely, if that order can't be assumed for all compositors, we
should toggle wl->focused when necessary in keyboard_handle_enter() and
keyboard_handle_leave() as well as in handle_toplevel_config().
--audio-stream-silence is a shitty feature compensating for awful
consumer garbage, that mutes PCM at first to check whether it's
compressed audio, using formats advocated and owned by malicious patent
troll companies (who spend more money on their lawyers than paying any
technicians), wrapped in a wasteful way to make it constant bitrate
using a standard whose text is not freely available, and only rude users
want it. This feature has been carelessly broken, because it's
complicated and stupid. What would Jesus do? If not getting an aneurysm,
or pushing over tables with expensive A/V receivers on top of them, he'd
probably fix the feature. So let's take inspiration from Jesus Christ
himself, and do something as dumb as wasting some of our limited
lifetime on this incredibly stupid fucking shit.
This is tricky, because state changes like end-of-audio are supposed to
be driven by the AO driver, while playing silence precludes this. But it
seems code paths for "untimed" AOs can be reused.
But there are still problems. For example, underruns will just happen
normally (and stop audio streaming), because we don't have a separate
heuristic to check whether the buffer is "low enough" (as a consequence
of a network stall, but before the audio output itself underruns).
Create a central function which pumps data through the filter. This also
might fix bogus use of the filter API on flushing. (The filter is just
used for convenience, but I guess the overall result is still simpler.)
The render API replaced the opengl_cb API over 2 years ago. Since then,
the opengl_cb API was emulated on top of the render API. While it would
probably be reasonable to emulate these APIs until they're removed in an
eventual libmpv 2.0 bump, I have some non-technical reasons to disable
the API now.
The API stubs remain; they're needed for formal ABI compatibility.
If you encode to e.g. an audio-only format, then video is disabled
automatically. This also takes care of the very cryptic error message.
It says "[vo/lavc] codec for video not found". Sort of true, but
obscures the real problem if it's e.g. an audio-only format.
I don't see the point of this. Not doing it may defer an error to later.
That's OK? For now, it seems better to reduce the encoding internal API.
If someone can demonstrate that this is needed, I might reimplement it
in a different way.
Since this is a messy and fragile mechanism, I want it logged (even if
it's somewhat in conflict with the verbose logging policy). On the other
hand, it's unconditionally logged on every playloop iteration. So add
some nonsense to log it only on progress.
Just for the redundant message. The function which is called here,
ao_drain(), does not care in which state it is called, and already
handled this gracefully.
AVFrame doesn't have public code for pool allocation, so mpv does it
manually. AVFrame allocation is very tricky, so we added a bug.
This crashed with libopus encoding, but not some other audio codecs,
because the libopus libavcodec wrapper accesses AVFrame.data. Most code
tries to avoid accessing AVFrame.data and uses AVFrame.extended_data,
because using the former would subtly corrupt memory on more than 8
channels. The fact that this problem manifested only now shows that most
AVFrame consuming FFmpeg code indeed uses extended_data for audio.
It is now the AO's responsibility to handle period size alignment. The
ao->period_size alignment field is unused as of the recent audio
refactor commit. Remove it.
It turns out that ao_alsa shows extremely inefficient behavior as a
consequence of the removal of period size aligned writes in the
mentioned refactor commit. This is because it could get into a state
where it repeatedly wrote single samples (as small as 1 sample), and
starved the rest of the player as a consequence. Too bad. Explicitly
align the size in ao_alsa. Other AOs, which need this, should do the
same.
One reason why it broke so badly with ao_alsa was that it retried the
write() even if all reported space could be written. So stop doing that
too. Retry the write only if we somehow wrote less.
I'm not sure about ao_pulse.
Unused, was terrible garbage. It was (or at least its implementation
was) always a make-shift solution, and just gross bullshit. It is unused
now, so delete it.
This replaces the two buffers (ao_chain.ao_buffer in the core, and
buffer_state.buffers in the AO) with a single queue. Instead of having a
byte based buffer, the queue is simply a list of audio frames, as output
by the decoder. This should make dataflow simpler and reduce copying.
It also attempts to simplify fill_audio_out_buffers(), the function I
always hated most, because it's full of subtle and buggy logic.
Unfortunately, I got assaulted by corner cases, dumb features (attempt
at seamless looping, really?), and other crap, so it got pretty
complicated again. fill_audio_out_buffers() is still full of subtle and
buggy logic. Maybe it got worse. On the other hand, maybe there really
is some progress. Who knows.
Originally, the data flow parts was meant to be in f_output_chain, but
due to tricky interactions with the playloop code, it's now in the dummy
filter in audio.c.
At least this improves the way the audio PTS is passed to the encoder in
encoding mode. Now it attempts to pass frames directly, along with the
pts, which should minimize timestamp problems. But to be honest, encoder
mode is one big kludge that shouldn't exist in this way.
This commit should be considered pre-alpha code. There are lots of bugs
still hiding.
Do not make resetting the "access" filters reset the queue itself. This
is more flexible, and will be used in a later commit.
Also, if the queue is not in the reset state while the input access
filter is reset, make it immediately request data again. This is more
consistent, because it'll enter the state it "should" be, rather when
the filter's process function is called at an (essentially) random point
in the future. This means the filter graph will resume work on its own
if the queue was not reset before filter reset.
This could affect the only current user of f_async_queue, the code for
the --vd-queue-enable/--ad-queue-enable feature in f_decoder_wrapper.
But it looks like this already uses it in a compatible way.
This is a kind of bad hack (with bad implementation) to paint over other
problems of the filter system. The main problem is that some filters
might be left with pending frames if the filter runner is "paused",
which we don't want. To be used in a later commit.
It's relevant in some obscure corner cases (EDL file that has a segment
without audio). Didn't test what's actually going on (is ad_lavc.c
behaving wrong? is libavcodec behaving wrong or in an unexpected way? is
lavc_process wrong?) and just patched it over with some bullshit, so the
fix might be too complicated, and could be reworked at some later point.
This sure is a real data flow fuckmess.
Allow mp_aframe_clip_timestamps() to discard a spdif frame if it's
entirely out of the timestamp range. Just a minor thing that might make
handling these dumb formats easier.
Transparent windows on X11/EGL/native Mesa GL didn't work for various
reasons. From what I remember, the current code did work with nvidia at
least. Mesa has made attempts to fix this, but they never really made it
in.
But it turns out you can make EGL/Mesa list the EGLConfigs that use X11
RGBA visuals, and context_x11egl.c contains code that explicitly selects
them if alpha is requested (see pick_xrgba_config()).
The reason EGL/Mesa did not list them (and thus breaking transparency)
is because we requested a EGL_ALPHA_SIZE != 0 if alpha is requested. But
the transparent EGLConfigs use EGL_ALPHA_SIZE == 0. That's because EGL
doesn't actually support the concept of transparent windows; the alpha
size parameter is something else (memory rendering without FBOs or
something, I don't care enough to look up the real reasons).
This still won't work on Wayland. Every EGL backend needs platform
specific code. (Good job, EGL, such an awesome platform independent
standard.)
Fixes: #6590
Previously get_state() would keep setting the cork status
while paused, but it only does for that after underflows now.
Correct this oversight by creating the stream corked for start()
to uncork it at a later time.
fixes#8026
Oversight in b0f0be7. The user_sbc value would update but not last_sbc
if no presentation events were received. This would result in an
incorrect sbc_passed value (in practice, this should always be 1 since,
as far I know, all wayland compositors are currently only capable of
double buffering). When bring the window back into view, it would result
in a single frame of very high vsync jitter. Although in most cases it
was imperceptible, rarely I was able to completely break playback (i.e.
constant mistimed/dropped frames). Fix this by simply incrementing
last_sbc by 1 if the window is hidden. The buffer swap call did still
occur. The user just didn't see it.
This reverts commit 41243e7c4f.
This fixes image format detection. FFmpeg has an utter called "image2",
which is designed to read patterns in filenames (so you can play
something like "%*.jpg" for all jpg files in the current directory).
"image2" is not what we want; it's just broken with custom I/O like
mpv uses it, and we don't want to "accidentally" interpret filenames
as pattern. That's why mpv blacklists it.
Unfortunately, "image2" is sometimes the format that FFmpeg's probe API
returns as best match. Thus demux_lavf fails to detect the file type,
and after some more futile attempts, we end up at demux_mf, which uses
detection by file extension. (Not sure why. I guess MPlayer did that,
and foudn that sufficient.) If the file extension is wrong (which
happens a lot because apparently the world is full of idiots who don't
manage to get the most simple things right), the image "loads", but
decoding obviously fails.
There's no easy way around this. The FFmpeg API has no mechanism to
exclude a specific format from probing (like image2, which breaks stuff
for us). Out of the 5 probe functions the API provides, none can probe
a specific format or include or exclude specific formats. The main
problem is that AVInputFormat.read_probe is a private symbol.
FFmpeg itself has no problem opening such files. It turns out that it
works, because even though image2 by itself uses detection by file
extension, it uses private API to further probe the exact format. It
explicitly excludes itself to prevent recursion.
But fortunately, that also means that it's impossible to get the image2
format if no filename is passed to the prober. (No filename, no file
extension.) Apparently we pass it in because it helps in corner cases.
Until almost 3 years ago, we passed the filename only when normal
probing already failed. Restore this by this revert. It makes
incorrectly named files work. The revert also makes the (apparently
forgotten) comment above the touched line of code true again.
Yes, quite possible that this breaks some mp3s again. You can't win
with FFmpeg. Thanks FFmpeg for making us fail at opening simple image
files and/or the most widely used file format for audio.
Why on earth did I ever bother with this dumb crap? If we do not have
any presentation statistics, just set the relevant vo_sync_info values
to -1 to disable it. It's much simpler than using mp deltas and trying
to keep up with mpv's clock. This also appears to fix audio/video
desynchronization if you start a video with the pause flag, move it out
of view, and then unpause it. Technically harmless since the video
wasn't even in view and putting back in view recovered it, but a quieter
terminal is better.
Well, whatever. Only results in an error message being printed, because
there is no other error reporting mechanism, and the general policy is
to keep trying with the rest of the data (i.e. not report EOF).
This can happen if a file contains headers only, or if decoding of all
data failed, and such. Interestingly, it also happened when doing "mpv
--loop emptyfile.png", because demux_mf still detects file formats by
file extension.
In this situation, the player burned a lot of CPU by restarting playback
after doing nothing. Although such "degenerate" behavior can't be
avoided in all situations (what if you loop a file with 1 audio
sample?), detecting this seems to make sense.
For now, this actually decrements the loop count by 1, and then errors
out with a warning. Works for --loop and --ab-loop, while
--loop-playlist already avoids this situation with an existing
mechanism.
Accepting ":" in addition to "," seems confusing and dumb. It only
causing problems when you want to pass a value that contains ":". Remove
support for ":", it is now treated like any other normal character. This
affects all options that are listed as "Key/value list" in the option
list.
It's possible that this breaks for someone who happened to use ":" as
separator. But this was undocumented, and never recommended. Originally,
the option treated many other characters in a special way, but this was
changed in commit a3d561f950. I'm, not sure why ":" was explicitly
included. Maybe because -the absurd -vf/--af syntax uses ":" as list
separator. But "," was always recommended and used in examples for
key/value options.
Fixes: #8021 (if you consider it a bug)
this fixes some race condition where the content of the layer wasn't
updated because the size didn't changed and the layer was already marked
as updated. just force an update on reconfig.
Fixes#7989
this is preparation for new backends. currently this is done via the
libmpv API but for future new new VOs not based on libmpv we need these
VOCTRL events.
remove the libmpv observer for the macOS specific options and use a
config cache + change callback for runtime changes. this is also a
preparation for new backends and generalises even more, since libmpv
functions can't and shouldn't be used in usual vo backends. for feature
parity the config cache is used.
move all backend independent code parts in their own folder and files,
to simplify adding new backends. the goal is to only extend one class
and add the backend dependent parts there. usually only the (un)init,
config and related parts need to be implemented per backend. furthermore
all needed windowing and related events are propagated and can be
overwritten. the other backend dependent part is usually the surface for
rendering, for example the opengl oder metal layer.
in the best case a new backend can be added with only a few hundred
lines.
The software rendering API makes libswscale directly write into supplied
user memory. As such, weird memory corruption bugs on non-optimal buffer
configurations are exposed to the user.
It was possible for sway to get incorrectly sized borders if you resized
the mpv window in a creative manner (e.g. open a video in a non-floating
mode, set window scale to 2, then float it and witness wrong border
sizes). This is possibly a sway bug (Plasma doesn't have these border
issues at least), but there's a reasonable workaround for this.
The reason for the incorrect border size is because it is possible for
mpv to ignore the width/height from the toplevel listener and set its
own size. This new size can differ from what sway/wlroots believes the
size is which is what causes the sever side decorations to be drawn on
incorrect dimensions.
A simple trick is to just explicitly commit the surface after a resize
is performed. This is only done if mpv is not fullscreened or maximized
since we always obey the compositor widths/heights in those cases.
Sending the commit signals the compositor of the new change in the
surface and thus sway/wlroots updates its internal coordinates
appropriately and borders are no longer broken.
This allows users to control whether full dialogue subtitles are displayed
with an audio track already in their preferred subtitle language.
Additionally, this improves handling for the forced flag, automatically
selecting between forced and unforced subtitle streams based on the user's
settings and the selected audio.
The original goal was to simplify all this logic to make it less fragile
and breaky. Unfortunately, that didn't exactly happen and things might
actually be more complicated in some ways (well in other ways it's
simplier). There's a lot of negotiation back and forth between the
client and the compositor regarding sizes. The client (aka mpv) can do a
resize on its own. But also the compositor can request its own resize
(which we should be nice and listen to of course). The older method had
a lot of breakfalls/edgecases that were gradually patched up as time
went on, but that approach is really fragile. This refactor should,
hopefully, be on a more solid foundation.
Don't call any of the xdg toplevel state changing functions
(fullscreen, maximized, etc.) directly. Use the toggle wrapper
functions. These signal that the state was changed which is later
handled in the toplevel listener.
Introduce a new vdparams variable that stores the actual dimensions of
the video. This does create some new (but neccesary) complexity.
wl->vdparams stores what the actual dimensions of the video are
(according to mpv). wl->window_size stores the last size of the window
(so it includes any manual resizes for instance). wl->geometry is the
actual size of the output that gets displayed on the screen.
Add support for reading a byte range from a stream via
the `slice://` protocol.
Syntax is `slice://start[-end]@URL` where end is a maximum
(read until end or eof).
Size suffixes support in `m_option` is reused so they can
be used with start/end.
This can be very useful with e.g. large MPEGTS streams with
corruption or time-stamp jumps or other issues in them.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
We've had some serious issues with GNOME in the past, but since then
their compositor has undergone some major internal improvements. The
most severe one [1], random vsync spikes and mistimed frames, can no
longer be reproduced by the original author of the issue. There are some
minor UI-related things (lack of window decorations for instance since
there is no xdg-decoration support), but users don't seem to complain
about that too much and they aren't revelant to playback.
3.38 isn't out quite yet, but that should also fix playback issues when
on a multimonitor setup (the fix is in the master branch at the moment).
In terms of playback, the only real concerning issue is the lack of idle
inhibit so a warning is still displayed. But GNOME has their own
workaround that users can use for that so if anyone happens to complain,
we can just point them to that.
[1] https://gitlab.gnome.org/GNOME/mutter/-/issues/957
When using presentation time, we have to be sure to update the ust when
no presentation events are received to make sure playback is still
smooth and in sync. Part of the recent presentation time refactor was to
use the presentation discarded event to signal that the window is
hidden. Evidently, this doesn't work the same everywhere for whatever
reason (drivers?? hardware??) and at least one user experienced issues
with playback getting out of sync since (presumably) the discarded event
didn't occur when hiding the window. Instead, let's just go back to the
old way of checking if the last_ust is equal to the ust value of the
last member in the wayland sync queue. Fixes#8010.
The motivation for this change was a segfault caused by e107342 which
has complicated reasons for occuring (i.e. I'm not 100% sure but I think
it is a really weird race). The major part of this commit is moving the
initialization of presentation listener to the frame_callback function.
Calling it in swap_buffers worked fine but in practice it meant a lot of
meaningless function calls if a window was hidden (the presentation
would just be immediately discarded). By calling it in frame_callback,
we ensure the listener is only created when it is possible to receive a
presentation event.
Of course calling the presentation listener in feedback_presented or
feedback_discarded was considered, but ultimately these events are too
slow. Receiving the ust/msc/sbc triplet here and then passing it to mpv
results in higher vsync judder since there is (likely) not enough time
before the next pageflip. By design, the frame callback is meant to give
us as much time as possible before the next repaint so calling it here
is probably optimal.
Additionally, we can make better use of the feedback_discarded event.
The wp_presentation_feedback should not be destroyed here. It will be
taken care of either when we get feedback again or when the player
quits. Instead what we can do is set a bool that tells wayland_sync_swap
to update itself based on mp_time delta. In practice, the result is not
any different than before, but it should be more understandable what is
going on now.
Of course, the segfault mentioned at the beginning is fixed with this as
well.
lua/js utils.get_env_list() uses `environ' which was ANSI, thus
it broke any unicode names/values.
mpv already has an internal utf8_environ for win32, but it's used
only at the getenv(..) wrapper and not exposed in itself, and also it
has lazy initialization - on first getenv() call.
Now `environ' maps to a function which ensures initialization while
keeping it an l-value (like posix expects).
The cost of this fuglyness is that files should include osdep/io.h
(which now declares environ as extern) rather than declaring it
themselves, or else the build will break on mingw.
This was a vague idea how to handle passing byte arrays from Lua to the
mpv command interface in a somewhat reasonable way. The idea was
cancelled, but leave the Lua part of it, since it might get useful
later, and prevents passing (and silently cutting off) such byte
strings.
Barely tested, let's say not tested at all.
Make it possible to feed a string to stdin of a subprocess. Out of
laziness, it can't be an arbitrary byte string. (Would require adding an
option type that takes in a Lua byte string.)
Do not set stdin of a subprocess to fd 0 (i.e. mpv's stdin) anymore,
because it makes things more consistent. Enabling stdin didn't make too
much sense in the first place, so this behavior change seems
justifiable.
win32 support missing.
Fixes: #8003
Such files violate the specification. Unfortunately, I could not test
whether it really works correctly, since I don't have a sample at hand
that is not broken in this regard.
Nothing major but it's technically possible for the
wp_presentation_feedback struct to still be allocated when quitting the
player. Just destroy it if it exists like all of the other wayland
objects.
In a playlist of videos with different sizes, going to the next video
would not properly resize the window. This actually broke way back in
7170910 (oops), but somehow nobody ever complained. The fix is simple.
If a window isn't maximized, be sure to set the window geometry again.
Just some small changes when creating the xdg_surface. Don't set the
toplevel title (or app id) in create_xdg_surface anymore because it's
entirely pointless. Also make it possible for create_xdg_surface to
return something other than 0 so the error checking is somewhat
meaningful. It's not really clear if these xdg functions can even fail
in the first place (perhaps some weird proxy marshalling crap could
possibly go wrong somehow), but it can't hurt. Note that all app id
stuff has been removed (temporarily) in this commit. See the next commit
which adds it back in.
The subtitle list is returned in randomized order, because a table (i.e.
JSON object) is used. To make the order stable across repeated
invocations, sort it by language.
This was incorrect, and grossly misleading. It created the impression
that the buffer is passed to mpv_render_context_create(), instead of
mpv_render_context__render().
(The recommendation is to add the document to the project git root, but
I'm against dumping such things into git. I'd rather replace the
Copyright full text files with links and move contribute.md to the wiki
than add the CCoC text as a file.)
Seems like this is requested all the time.
It seems libass allows out of range values, but does allows the subtitle
to go out of the screen at the bottom (only when moving it to the top
it's "clamped"). Too bad, don't do that then. The bitmap sub rendering
code on the other hand is under our control, and will not move a
subtitle out of the screen.
Fixes: #7986
Options like --sub-ass-force-style and others could not be changed at
runtime (the changes didn't take any effect). Fix this by using the
brutal approach, and completely reinit the subtitle state when this
happens. Maybe a bit clunky, but for now I'd rather not put more effort
into this.
Fixes: #7689
Requested. Should be good for simple use cases. "sub2" is technically
inconsistent (since the option is called --secondary-sid), but fuck the
consistent name.
The same was done to matroska.py before, so at least it's consistent.
Doesn't matter for waf, because it imports this script (rather than
executing it).
This sets the activeCodePage property in the manifest, which forces the
ANSI code page to be UTF-8 in Windows 10 1903 and up. It shouldn't make
a difference for mpv itself, since mpv already uses the wide-char APIs
for most functions, however some of mpv's dependencies, such as Lua,
rely on the ANSI codepage. Hence this change enables support for Unicode
file names in Lua's I/O library.
Thanks @avih for finding this property.
See:
https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page
FFmpeg expects those fields to be set on the AVFrame when
encoding audio, not doing so will cause the avcodec_send_frame
call to return EINVAL (at least in recent builds).
Uses the mechanism introduced in the previous commit. The hope was to
make auto-profiles easier to use, and to get rid of the need for
manually created inverse profiles. Not sure if the end result is useful.
Make it possible to restore from profiles by backing up the option
values before profile application. This is sort of like unapplying a
profile. Since there might be multiple ways to do this, a profile needs
to explicitly provide the "profile-restore" option, which specifies how
exactly this should be done.
This is a big mess. There is not natural way to do this. Profile
application is "destructive" and simply changes the values of the
options. Maybe one could argue that the option system should have
hierarchical "overlays" of profiles instead, where unset options will
use the value of the lower profiles. Options set interactively by the
user would be the top profile. Default values would be in the lowest
profile. You could unapply a profile by simply removing it from this
overlay stack.
But uh, let's not, so here's something stupid. It reuses some code used
for file local options to reduce code size. At least the overlay idea
would still be possible in theory, and could be added as another
profile-restore mode.
This is used by the following commit.
The callback now gets an object argument with defer/cont functions.
Like the lua code, the behavior is that each hook event allows at
most one continue, but nothing enforces the order of continuations
if more hook events arrive before prior ones were continued - which
is possible now with the defer option, but wasn't possible before
(continuation was synchronous from the hook event handler).
The property observation mechanism is fairly asynchronous to the player
core, and Lua scripts also are (they run in a separate thread). This may
sometimes lead to profiles being applied when it's too load.
For example, you may want to change network options depending on the
input URL - but most of these options would have to be set before the
HTTP access is made. But it could happen that the profile, and thus the
option, was applied at an slightly but arbitrary later time.
This is generally not fixable. But for the most important use-cases,
such as applying changes before media opening or playback
initialization, we can use some of the defined hooks.
Hooks make it synchronous again, by allowing API users (such as scripts)
to block the core because it continues with loading.
For this we simply don't continue a given hook, until we receive an idle
event, and have applied all changes. The idle event is in general used
to wait for property change notifications to settle down. Some of this
relies on the subtle ways guarantees are (maybe) given. See commit
ba70b150fb for the messy details. I'm not quite sure whether it
actually works, because I can't be bothered to read and understand my
bullshit from half a year ago. Should provide at least some improvement,
though.
This can now opt to not continue a hook after the hook callback returns.
This makes it easier for scripts, and may make it unnecessary to run
reentrant event loops etc. for scripts that want to wait before
continuing while still running the event loop.
This is taken from a somewhat older proof-of-concept script. The basic
idea, and most of the implementation, is still the same. The way the
profiles are actually defined changed.
I still feel bad about this being a Lua script, and running user
expressions as Lua code in a vaguely defined environment, but I guess as
far as balance of effort/maintenance/results goes, this is fine.
It's a bit bloated (the Lua scripting state is at least 150KB or so in
total), so in order to enable this by default, I decided it should
unload itself by default if no auto-profiles are used. (And currently,
it does not actually rescan the profile list if a new config file is
loaded some time later, so the script would do nothing anyway if no auto
profiles were defined.)
This still requires defining inverse profiles for "unapplying" a
profile. Also this is still somewhat racy. Both will probably be
alleviated to some degree in the future.
Sway 1.5 started sending more pointer motion events to mpv which broke
the autohiding behavior. The cursor would appear again if you
fullscreened. Sway had a good reason to do this because certain
applications had inconsistencies between hardware cursor and software
cursor without rebasing on state changes[1]. So mpv needs to take this
special case into consideration.
Initially, simply checking mouse coordinates for changes was considered,
but this doesn't work. All coordinates are surface-local in wayland so
something can appear to move in the local coordinate space but not
globally. You're not allowed to know global mouse coordinates in
wayland, and we don't care about local coordinate changes in mpv so this
approach isn't viable.
Instead, let's just keep track of a local state change. If the toplevel
surface changes in some way (fullscreen, maximized, etc.), then just set
a bool that lets us ignore the mp_input_set_mouse_pos function. This
keeps the cursor from appearing simply because the state was changed
(i.e. fullscreening). For compositors that don't send pointer motion
events on a state change, this does technically mean that the initial
mp_input_set_mouse_pos is never set. In practice, this isn't a
noticeable difference though because moving a mouse generates a ton of
motion events so you'll immediately see it on the second motion event.
[1] https://github.com/swaywm/sway/issues/5594
wl_display_dispatch is dangerous because it will block forever if the
event queue is empty. Any direct calls to this function should just be
replaced with wl_display_dispatch_pending which accomplishes the same
thing for mpv's purposes without any chance of blocking.
The other potential trap is wl_display_roundtrip. It can internally call
wl_display_dispatch which in certain circumstances could potentially
block. There are cases where we need the server to finish processing
client requests before doing anything else so this can not be cleanly
avoided. The dangerous call is the usage of wl_display_roundtrip in
vo_wayland_wait_frame. In the majority of cases, this shouldn't be a
problem because the previous wl_display_read_events should always queue
up some events on the fd for wl_display_roundtrip to send. However, the
compositor could potentially send us an error in the display queue that
could lead to bad behavior when wl_display_roundtrip is called.
The wl_display_roundtrip can't be removed because we are relying on its
semi-blocking capabilities, but the logic can be slightly adjusted to be
safer. The obvious thing to do is to make sure we check the pollfd for
any errors. If one is returned, then we call wl_display_cancel_read and
try again. The less obvious trick is to call wl_display_dispatch_pending
and move wl_display_roundtrip outside of the blocking + timeout loop.
This change has some subtle but important differences. Previously,
vo_wayland_wait_frame would read an event and wait on the server to
process it one-by-one. With this change, the events are dispatched as
soon as possible to the server and then we wait on all of those
(potentially multiple) events to be processed after we have either
received frame callback or the loop times out.
After that is done, we can then check for if there are any errors on the
display. If it's all clear, we can run wl_display_roundtrip without any
worries. If some error happens, then don't execute the function at all.
the problem here is that with time, and because the macOS VMs don't get
updated, the homebrew update is getting longer since more and more
changes have to be pulled. to prevent that, we cache the homebrew
installation folder after the update. that way we don't have to update
several months worth of updates every build. for the legacy build we
have to check put master again to actually cache the newest homebrew
version.
additionally to that, we also do the same as on the legacy build, with
the addition of not removing all installed formulas but only the ones
we don't need. so we don't need to reinstall those.
just remove all pre installed formulas, since we don't need the majority
of it. after that install what we need. this also fixes the brew update
of those formulas where the source links were broken like popt.
this also helps when the build times out due to building some formulas
from source that are not dependencies we need.
Previously, the compositor was signaled that a drag-and-drop ended with
wl_data_offer_finish in check_dnd_fd. This is, however, erroneous
because it is outside of the data_device_listener and in some cases
caused errors with certain compositors. check_dnd_fd itself does not
need to know or care about anything that happens in wayland. It just
needs to read data from an fd. The simple fix is to just always signal
the end of a drag-and-drop in data_device_handle_drop. check_dnd_fd can
free memory and close the fd later, but it should not talk to the
compositor. Fixes#7954.
The read of the wayland display fd in vo_wayland_wait_events was
incorrect and technically vulnerable to race conditions. The correct
usage as per the client api is to use wl_display_prepare_read as well as
wl_display_read_events.
scaletempo2 is a new audio filter for playing back
audio at modified speed and is based on chromium
commit 51ed77e3f37a9a9b80d6d0a8259e84a8ca635259.
It sounds subjectively better than the existing
implementions scaletempo and rubberband.
This fixes the "run" and "subprocess" commands on Windows, including
youtube-dl support.
Unix-like FD inheritance is emulated on Windows by using an undocumented
data structure[1] that gets passed to the newly created process in
STARTUPINFO.lpReserved2. It consists of two sparse arrays listing the
HANDLE and internal CRT flags corresponding to each FD. This structure
is used and understood primarily by MSVCRT, but there are other runtimes
and frameworks that can write it, like libuv.
The code for creating asynchronous "anonymous" pipes in Windows has been
enhanced and moved into windows_utils.c. This is mainly an artifact of
an unfinished future change to support anonymous IPC clients in Windows.
Right now, it's still only used in subprocess-win.c
[1]: https://www.catch22.net/tuts/undocumented-createprocess
Sharing a process sure is hard in POSIX.
The rationale is that you'd have to handle EINTR on every single
blocking syscall. stream_file.c does not seem to handle it on read()
calls.
It appears that on most modern systems, this can happen only if you call
sigaction(), and incompetently forget to add SA_RESTART. signal()
usually adds it.
Add env and detach arguments. This means the command.c code must use the
"new" mp_subprocess2(). So also take this as an opportunity to clean up.
win32 support gets broken by it, because it never made the switch to the
newer function.
The new detach parameter makes the "run" command fully redundant, but I
guess we'll keep it for simplicity. But change its implementation to use
mp_subprocess2() (couldn't do this earlier, because win32).
Privately, I'm going to use the "env" argument to add a key binding that
starts a shell with a FILE environment variable set to the currently
playing file, so this is very useful to me.
Note: breaks windows, so for example youtube-dl on windows will not work
anymore. mp_subprocess2() has to be implemented. The old functions are
gone, and subprocess-win.c is not built anymore. It will probably work
on Cygwin.
Rather than after tone-mapping. This prevents overflow when the
pre-tonemapped signal contains inputs exceeding sig_peak. I also
realized that with this clipping in place, post-clipping no longer needs
to be done, so this isn't even particularly slower.
The only two exceptions to the rule are "clip" and "linear", which
relied on the post-clipping to do their tone mapping properly.
Fixes#7929
This normally gets printed by libplacebo itself when initializing the
context, but due to the way our code is structured (for convenience) we
don't have the log hook enabled by the time this function call is
relevant. So instead just print it manually as an easier work-around
than restructuring the code.
This probably makes it much faster (I wouldn't know, I didn't run any
benchmarks ). Seems to work as well (although I'm not sure, it's not
like I'd perform rigorous tests).
The scale_zimg test seems to mysteriously treat color in fully
transparent alpha differently, which makes no sense, and isn't visible
(but makes the test fail). I can't be bothered with investigating this
more. What do you do with failing tests? Correct, you disable them. Or
rather, you disable whatever appears to cause them to fail, which is the
threading in this case.
This change follows mostly the tile_example.cpp. The slice size uses a
minimum of 64, which was suggested by the zimg author. Some of this
commit is a bit inelegant and weird, such as recomputing the scale
factor for every slice, or the way slice_h is managed. Too lazy to make
this more elegant.
zimg git had a regressio around active_region (which is needed by the
slicing), which was fixed in commit 83071706b2e6bc634. Apparently, the
bug was never released, so just add a warning to the manpage.
The intention is to add slice-threading to the wrapper. For that
purpose, move all zimg related state to a new struct mp_zimg_state.
There is now an array of instances of this struct. The intention is to
have one instance for each thread. As of this commit, this is hardcoded
to 1 thread; the following commit extends this.
libass recently switched the default from 1 to 0 for compatibility
with ASS scripts that rely on the historical/VSFilter default of 0.
libass does attempt to detect and avoid breaking scripts that rely
on the historic libass-only default of 1, but it doesn't cover tracks
created directly through the API, so set the header explicitly.
Fixes https://github.com/mpv-player/mpv/issues/7900.
It turns out that the AMD driver doesn't bother to set the size
field in the descriptor for an exported VA surface. I guess they
assume the caller can always use lseek() and don't bother. So, we
need to use lseek() in these situations.
Modified-by: Niklas Haas <git@haasn.xyz>
Guarded this behind PL_API_VER >= 88 to prevent it from exploding on
older libplacebo versions, where vaapi support does not yet work
properly on AMD due to lack of DRM modifiers.
When get_state() corks the stream after an underrun happens
priv->playing is incorrectly reset to true, which can cause the
player to miss the underrun entirely. Stop resetting priv->playing
during corking (but not uncorking) to fix this.
The underflow callback introduced in d27ad96 can be called
when the buffer is still full, causing playback to never
resume afterwards since get_state() reports free_samples == 0.
Fix this by fully resetting on underrun, which flushes
the stream and ensures free buffer space.
fixes#7874
we properly set the unfs window size on live resize end. due to a race
condition in the fullscreen events, which is also a live resize, the
unfs window size is incorrectly set to a fullscreen size. this happens
when the end fs screen event triggers before the end of live resize one.
this just adds a second condition to not be un fullscreen when updating
the unfs window size.
Mess this into the --geometry option, because I like to be
irresponsible. I considered adding a separate option, but at least this
allows me to defer the question how the hell this should work as
property (geometry simply and inherently does not).
Tested on IceWM only. Option equality test and string output not tested.
Probably did not cause any practical problems, but it sure seems
unclean. sws_utils users might also rely on these fields being exactly
the same as the actual input/output. It's better to avoid this.
I'm tired of dealing with this frequent spawning of xdg-screensaver when
debugging and what not. xdg-screensaver was never a serious tool anyway,
it's more like some self-deprecating joke by FDO folks.
This will affect X11 on GNOME and other DEs. I'm singling out GNOME
though, because they are the ones actively sabotaging any sane
technical solutions and community cooperation.
I have been accused of taking it out on innocent GNOME users, while none
of this will reach GNOME developers. Of course that is not the
intention.
This can be used to make vo_libmpv render video to a memory buffer. It
only adds a new backend API that takes memory surfaces. All the render
API (such as frame rendering control and so on) is reused.
I'm not quite convinced of the usefulness of this, and until now I
always resisted providing something like this. It only seems to
facilitate inefficient implementation. But whatever.
Unfortunately, this duplicates the software rendering glue code yet
again (like it exists in vo_x11, vo_wlshm, vo_drm, and probably more).
But in theory, these could reuse this backend in the future, just like
vo_gpu could reuse the render_gl API.
Fixes: #7852
libplacebo exposes this feature already, because this particular type of
bug is unusually common in practice. Simply make use of it, by exposing
it as an option.
Could probably also bump the libplacebo minimum version to get rid of
the #if, but that would break debian oldoldstable or something.
Fixes#7867.
Apparently mpv supports loading config files from the same directory as
the mpv.exe. This is a fallback of some sort. It used the old_home
mechanism.
I want to add a warning if old_home exists, but that would always show
the warning on win32. Obviously we don't want that.
Add a separate exe_dir entry to deal with that.
Untested, but probably works.
XDG is stupid, so change back to the standard behavior. Unfortunately,
most users will now have the XDG one, so we will still need to load
this. (This is exactly the same problem as when XDG support was
introduced, just the other way around).
This should not affect any normal users. Hopefully I tested this well
enough; my intention is not to torment miserable XDG fans; they can keep
using their config dir if they want it.
This changes behavior in two cases:
- new users (now creates ~/.mpv/ instead of ~/.config/mpv/)
- users which have both directories
The latter case will behave subtly or obviously different, not sure.
Just fix your shit.
Extend the manpage with all the messy details, as far as I could reverse
engineer them from the code.
De-emphasize it, since a user should usually not use it. This _could_ be
used to make the cache seekable with --cache=no, but it's better and
more intuitive to use --cache=yes. As such, the only use of this is for
debugging. I'm not quite sure if this should be removed entirely, but I
still see some value in it (for example if you want the cache lookahead,
but you're using a stream where cache seeking is somehow broken).
Using mediump float on GLES causes problems with kernel resampling,
PQ HDR, and possibly others. The issues are fixed by using highp,
which is available when GL_FRAGMENT_PRECISION_HIGH is defined.
--dscale= and --*scale-window= (i.e. an empty string) are respectively
valid settings for their options (and, in fact, the defaults).
This fixes the bug that it was impossible to reset e.g. tscale-window
back to the default "unset" setting after setting it once.
Credit goes to @CounterPillow for locating the cause of this bug.
For testing in VMs I guess?
This features a very broken hack that probably works. Though I didn't
test the packed format case. Again, the mismatch is essentially due to
big endian byte addresses decreasing as bit addresses increase, so you
can't represent a bit position in a byte stream with a single address,
which the mpv metadata does.
OSD is broken because repack.c doesn't support big endian. You'll have
to live with it.
The recent changes to the image format metadata broke big endian, and
that was intentional. Some things are inherent to little endian (like
the idea to coalesce bit and byte offsets into a single bit offset), and
they don't be fixed. But some obvious things can be fixed, such as
marking LE vs. BE formats the right way around on BE hosts.
The metadata is formally still in LE, except that if the LE/BE flag
matches the host endian, the host endian can be used when accessing
packed formats with bit shifts, or when computing byte aligned component
byte offsets. The former may work because formats with LE/BE variants
use the same bit offsets after byte swapping, the latter may work
because little endian is the natural concept for addressing memory. But
it will "subtly" fail to do the right thing in some cases, and code
using this can't know, so have fun.
Many things are broken, but this makes e.g. vo_gpu mostly work.
My general opinion about BE computers is that you should get a better
computer, you can get one for free from any garbage dump.
IMGFMT_RGB30 was added first; FFmpeg added AV_PIX_FMT_X2RGB10 later.
This is exactly the same, so treat them as such. For some reason,
libswscale still seems to output incompatible data - not sure what this
is about, but I'm not going to debug it.
Instead of applying this only to "regular" formats, do it with all
formats.
For some reason, some repackers still have their own endian code. These
could probably be removed, but whatever.
This change attempts to fix detection of how endian swapping is to be
performed. Details can be found in the code comments.
It should not change anything, other than fixing handling of the
X2RGB10BE ffmpeg pixel format. This format was detected incorrectly, and
the component location metadata was discarded due to an internal
consistency check. With this commit, it is handled correctly. At first I
thought the X2RGB10BE ffmpeg pixdesc metadata was wrong, but it appears
to be correct. The problem with this format is that it's the first
packed RGB format that requires bit shift to access, and where the
endian word size is larger than the (rounded up) component size, all
while pixdesc would "require" you to perform 3 memory accesses (instead
of 1), and the code tries to reverse this.
It appears that trying to use the pixdesc metadata is much, much more
work than just duplicating it in a saner form. To be fair, most problems
are with big endian, and the mpv internal format does not care much
about endian _hosts_.
The pull mode APIs were previously required to have thread-safe
ao_controls. However, locks were added in b83bdd1 for parity with push
mode. This introduced deadlocks in ao_wasapi.
Instead, only lock ao_control for the push mode APIs.
fixes#7787
See also #7832, #7811. We'll wait for feedback to see if those should
also be closed.
For cases in which the requirements of the GPU API prevent directly
uploading a texture with a given stride, we need to fix the stride
manually in host memory. This incurs an extra memcpy, but there's not
much we can do about it. (Even in `ra_gl` land, the driver will just
hide this memcpy from the user)
Note: This code could be done better. It could only copy as many texels
as needed, and it could pick a stride that's a multiple of
`gpu->limits.align_tex_xfer_stride` for better performance. Patches
welcome (tm)
Fixes#7759
Implementation copy/pasted from:
https://code.videolan.org/videolan/libplacebo/-/commit/f793fc0480f
This brings mpv's tone mapping more in line with industry standard
practices, for a hopefully more consistent result across the board.
Note that we ignore the black point adjustment of the tone mapping
entirely. In theory we could revisit this, if we ever make black point
compensation part of the mpv rendering pipeline.
This standard says we should use a value of 203 nits instead of 100 for
mapping between SDR and HDR.
Code copied from https://code.videolan.org/videolan/libplacebo/-/commit/9d9164773
In particular, that commit also includes a test case to make sure the
implementation doesn't break roundtrips.
Relevant to #4248 and #7357.
glslang accepted this, perhaps erronneously, but mesa does not. It seems
to be incorrect. A caveat is that this means *all* SSBOs are now
coherent, but since we only use SSBOs for peak detection, that's a
non-issue. (And besides, marking something as coherent when we don't
perform any synchronization commands on it should be a no-op anyway)
Fixes#7823
Commit fcf0b80dc9 fixed this the first time. Commit 85576f31a9
"accidentally" removed this code again. The commit message justifying
the removal is correct, except it doesn't take other side-effects of the
state machine into account. I obviously didn't remember what exactly
this was about. So add a comment explaining it this time.
Just apply it again; the thing the latter commit fixed still works.
Fixes: #7819
AOs which use the "push" API must set this field now. Actually, this was
sort of always required, but happened to work anyway. The future
intention is to use device_buffer as the pre-buffer amount, which has to
be available right before audio playback is started. "Pull" AOs really
need this too conceptually, just that the API is underspecified.
From what I can see, only ao_null did not do this yet.
Previously, device_buffer defaulted to 0 on pulse. This meant that
commit baa7b5c would always wait with a timeout of 0, leading to
high CPU usage for PulseAudio users.
By setting device_buffer to the number of samples per channel that
PulseAudio sets as its target, this commit fixes this behaviour.
since the title bar catches the mouse up and down events, the underlying
events view doesn't reset the isMoving state and no mouse movements are
signalled to the core. now we also reset the state in mouse up events
on the title bar.
Fixes#7807
The "screenshot window" command (ctrl+s by default) somehow broke video
colors with --gpu-api=vulkan --profile=gpu-hq when playback was paused.
I don't know the cause, but the rest of the code seems to imply
gl_video_reset_surfaces() needs to be called manually to flush some
caches, and it fixes the issue, so I assume there's no great mystery
here.
Commit 07b0c18 introduced some build breakages. Some breakages
were fixed on c1fc535 and a1adafe. This one is still remaining.
This commit fixes the following build error:
[153/521] Compiling video/out/vulkan/context_wayland.c
../video/out/vulkan/context_wayland.c:26:10: fatal error: video/out/wayland/presentation-time.h: No such file or directory
26 | #include "video/out/wayland/presentation-time.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
Relevant to: #7802
The playback thread may obviously still fill the AO'S entire audio
buffer, which means it unset p->draining, which makes no sense and broke
ao_drain(). So just don't unset it here.
Not sure if this really fixes this, it was hard to reproduce. Regression
due to the recent changes. There are probably many more bugs like this.
Stupid asynchronous nightmare state machine. Give me a language that
supports formal verification (in presence of concurrency) or something.
I feel like this makes slightly more sense. At least it doesn't include
the potentially arbitrary constant latency that is generally included in
the delay value. Also, the buffer status doesn't matter - either we've
filled the entire buffer (then we can wait this long), or there's not
enough data anyway (then the core will wake up the thread if new data is
available).
But ultimately, we have to guess, unless the AO does notify us with
ao_wakeup_playthread().
Draining may now wait for no reason up to 1/4th of the total buffer
time. Shouldn't be a disimprovement in practice.
It's conceivable that ao->driver->reset() will make the audio API wait
for ao_read_data() (i.e. its audio callback) to return. Since we
recently moved the reset() call inside the same lock that ao_read_data()
acquires, this could deadlock. Whether this really happens depends on
how exactly the AO behaves. For example, ao_wasapi does not have this
problem. "Push" AOs are not affected either.
Fix by moving it outside of the lock. Assume ao->driver->start() will
not have this problem.
Could affect ao_sdl, ao_coreaudio (and similar rotten fruit AOs). I'm
unsure whether anyone experienced the problem in practice.
Instead of the relatively subtle underflow handling, simply signal
whether the stream is in a playing state. Should make it more robust.
Should affect ao_alsa and ao_pulse only (and ao_openal, but it's
broken).
For ao_pulse, I'm just guessing. How the hell do you query whether a
stream is playing? Who knows. Seems to work, judging from very
superficial testing.
Just a detail. If wrong (not unlikely because I'm just guessing my own
messy state machine), this will make the player freeze due to waiting
for something that never happens. Enjoy.
The feeder thread basically woke up the core and itself too often, and
caused some CPU overhead. This was caused by the recent buffer.c
changes.
For one, do not let ao_read_data() wake up the core, and instead rely on
the feeder thread's own buffer management. This is a bit strange, since
the change intended to unify the buffer management, but being more
consequent about it is better deferred to later, when the buffer
management changes again anyway. And also, the "more" condition in the
feeder thread seems outdated, or at least what made it make sense has
been destroyed, so do something that may or may not be better. In any
case, I'm still not getting underruns with ao_alsa, but the wakeup
hammering is gone.
Commit 6a13954d67 lowered the frequency of wakeups with this
condition. But it seems it sometimes the audio sync mode really should
get the wakeup before the frame is rendered. Normally, vo_thread is
supposed to perform this wakeup. Now the wakeup frequency is twice of
what should be needed - whatever, maybe it can be fixed properly once or
if timing is moved to the VO entirely in the future.
Fixes: #7777 (probably, untested)
This affects "pull" AOs only: ao_alsa, ao_pulse, ao_openal, ao_pcm,
ao_lavc. There are changes to the other AOs too, but that's only about
renaming ao_driver.resume to ao_driver.start.
ao_openal is broken because I didn't manage to fix it, so it exits with
an error message. If you want it, why don't _you_ put effort into it? I
see no reason to waste my own precious lifetime over this (I realize the
irony).
ao_alsa loses the poll() mechanism, but it was mostly broken and didn't
really do what it was supposed to. There doesn't seem to be anything in
the ALSA API to watch the playback status without polling (unless you
want to use raw UNIX signals).
No idea if ao_pulse is correct, or whether it's subtly broken now. There
is no documentation, so I can't tell what is correct, without reverse
engineering the whole project. I recommend using ALSA.
This was supposed to be just a simple fix, but somehow it expanded scope
like a train wreck. Very high chance of regressions, but probably only
for the AOs listed above. The rest you can figure out from reading the
diff.
wasapi/coreaudio/sdl were affected, alsa/pusle were not.
The confusion here was that resume() has different meaning with pull and
push AOs.
Fixes: #7772
This should make --term-title work in Windows 8.1 and below.
OSC sequences are defined in ECMA-48. The 'Change Window Title' command,
as far as I can tell, is a de-facto standard defined by xterm[1]. In
either case, this code is probably still not standards-compliant.
This also changes mp_write_console_ansi to convert to UTF-16 before
parsing control sequences, because that made it easier to pass the OSC
param to SetConsoleTitleW. I think it's also more correct to do it this
way, even though it doesn't really matter much for our limited terminal
parsing. As a side-effect of this, mp_write_console_ansi no longer
mutates its argument.
[1]: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
Regression since the recent refactor. How did nobody notice?
This happened because the push code now calls the function for the pull
code. Both the former and latter apply the volume, so oops.
The recent change to the common code removed all calls to ->drain. It's
currently emulated via a timed sleep and polling ao_eof_reached(). That
is actually fallback code for AOs which lacked draining. I could just
readd the drain call, but it was a bad idea anyway. My plan to handle
this better is to require the AO to signal a underrun, even if
AOPLAY_FINAL_CHUNK is not set. Also reinstate not possibly waiting for
ao_lavc.c. ao_pcm.c did not have anything to handle this; whatever.
This simply printf()s a concatenation of the provided string and the
relevant escape sequences. No idea what exactly defines this escape
sequence (is it just a xterm thing that is now supported relatively
widely?), and this simply uses information provided on the linked github
issue.
Not much of an advantage over --term-status-msg, though at least this
can have a lower update frequency. Also I may consider setting a default
value, and then it shouldn't conflict with the status message.
Fixes: #1725
This is preparation to further cleanups (and eventually actual
improvements) of the audio output code.
AOs are split into two classes: pull and push. Pull AOs let an audio
callback of the native audio API read from a ring buffer. Push AOs
expose a function that works similar to write(), and for which we start
a "feeder" thread. It seems making this split was beneficial, because of
the different data flow, and emulating the one or other in the AOs
directly would have created code duplication (all the "pull" AOs had
their own ring buffer implementation before it was cleaned up).
Unfortunately, both types had completely separate implementations (in
pull.c and push.c). The idea was that little can be shared anyway. But
that's very annoying now, because I want to change the API between AO
and player.
This commit attempts to merge them. I've moved everything from push.c to
pull.c, the trivial entrypoints from ao.c to pull.c, and attempted to
reconcile the differences. It's a mess, but at least there's only one
ring buffer within the AO code now. Everything should work mostly the
same. Pull AOs now always copy the audio data under a lock; before this
commit, all ring buffer access was lock-free (except for the decoder
wakeup callback, which acquired a mutex). In theory, this is "bad", and
people obsessed with lock-free stuff will hate me, but in practice
probably won't matter. The planned change will probably remove this
copying-under-lock again, but who knows when this will happen.
One change for the push AOs now makes it drop audio, where before only a
warning was logged. This is only in case of AOs or drivers which exhibit
unexpected (and now unsupported) behavior.
This is a risky change. Although it's completely trivial conceptually,
there are too many special cases. In addition, I barely tested it, and
I've messed with it in a half-motivated state over a longer time, barely
making any progress, and finishing it under a rush when I already should
have been asleep. Most things seem to work, and I made superficial tests
with alsa, sdl, and encode mode. This should cover most things, but
there are a lot of tricky things that received no coverage. All this
text means you should be prepared to roll back to an older commit and
report your problem.
When the window is mapped, some ICCCM WM_HINTS are set.
The input field is set to true and state is set to NormalState.
To quote the spec, "The input field is used to communicate to the window
manager the input focus model used by the client" and "[c]lients with
the Passive and Locally Active models should set the input flag to True".
mpv falls under the Passive Input model, since it expects keyboard input,
but only listens for key events on its single, top-level window instead
of subordinate windows (Locally Active) or the root window (Globally
Active).
From the end users prospective, all EWMH/ICCCM compliant WMs (especially
the minimalistic ones) will allow the user to focus mpv, which will allow
mpv to receive key events. If the input field is not set, WMs are
allowed to assume that mpv doesn't require focus.
Commit 9d32d62b61 broke this when it changed OPT_TIME. I simply forgot
to adjust the command definition. The effect was that "no" was not
accepted as value.
I guess this qualifies as trolling. It's becoming increasingly clear
that Microsoft will not be able to deliver on this promise, at least not
in the way they made it seem at first. I'm not sure if Microsoft was the
one who did the trolling, or me. I actually expected that we'd get full
GUI integration of Linux applications including accelerated graphics,
but it was always clear that it wasn't going to work as well as
natively.
In any case, there is no need to frighten any users. The time when you
can run only "Windows Store Apps" on Windows (== the end for mpv and
many other applications on Windows) will come soon enough.
The "faster than native" statement is based on other people's real
experience of software running faster in Linux VMs than native windows
ports, by the way.
This mode drops or repeats audio data to adapt to video speed, instead
of resampling it or such. It was added to deal with SPDIF. The
implementation was part of fill_audio_out_buffers() - the entire
function is something whose complexity exploded in my face, and which I
want to clean up, and this is hopefully a first step.
Put it in a filter, and mess with the shitty glue code. It's all sort of
roundabout and illogical, but that can be rectified later. The important
part is that it works much like the resample or scaletempo filters.
For PCM audio, this does not work on samples anymore. This makes it much
worse. But for PCM you can use saner mechanisms that sound better. Also,
something about PTS tracking is wrong. But not wasting more time on
this.
Can be useful to force it to adapt to extreme speed changes, while a
higher limit would just use a fraction closer to the original video
speed.
Probably useful for testing only.
I'm not sure why it only rendered OSD inside the video. Since OSD
rendering was always done on the X image (after software scaling and
color conversion), there was no technical reason for this. Maybe it was
because the code started out this way, and it was annoying to change it.
Possibly, one reason was that it didn't normally have to clear the black
bars in every frame (if video didn't cover the entire window).
Anyway, simply render OSD to the full window. This gets rid of some
rather weird stuff. It seems to look mostly like vo_wlshm now. The
uncovered regions are cleared every frame, which could probably be
avoided by being clever with the OSD renderer code, but this is where
I'm decidedly losing interest.
There was some mysterious code for aligning the image width to 8 pixels.
Replace that by attempting to align it to SIMD alignment (might matter
for libswscale, or if repack.c gets SIMD). Why are there apparently 4
different ways representing a pixel format (depth, VisualID, Visual,
XVisualInfo), but none of them seem to provide the XImage.bits_per_pixel
value (the actual size of a pixel, including padding)? Even after 33
years, X11 still seems overengineered, confusing, and inconvenient. So
just call X11 a heap of shit, and assume the worst case for alignment.
It may be completely useless, and I can't verify it as no known samples
or other known/accessible software using it, but why not?
Putting this together with he 422 code requires making it slightly more
generic. I'm still staying with a "huge" if tree instead of a table to
select the scanline worker callback, because it's actually small and not
huge (although it not being generic still feels slightly painful).
Now everything is super generic and super undebuggable. Some awkwardness
because the new metadata is basically a transposed version of the
mp_regular_imgfmt metadata, which was used for component info before.
The old code ignored many corner cases, and even wrote "blacker than
black" to YUV images. Use the new pixel format metadata and other
recently added gimmicky crap, which should make this more correct. Even
the almighty fuckup of a format AV_PIX_FMT_UYYVYY411 should work,
although that couldn't be tested for obvious reasons.
This doesn't work for "monow", but this is so extremely fringe while at
the same time painful that I just won't care. In theory, it could be
modeled as some sort of inverted gray colorspace or something.
Make sure to accept only native endian mpv formats. Previously, it
didn't check, and simply matched LE, because these are usually defined
before the BE formats.
red_mask etc. are defined as unsigned long, so use that instead of
hardcoding a 32 bit limit.
A repeat of the previous useless commits.
Pondered whether to use separate fields or just a flags integer for
color and component types; the latter won for now.
Functions like mp_imgfmt_get_component_type() are now discouraged, and
mp_imgfmt_desc.flags is back for defining all information. Some days ago
I felt like the opposite would be the better design. Fortunately, it
doesn't matter.
With this, I think all image format properties that mpv needs are
exhaustively defined all in one place.
Execution of "stop" command in the case when idle mode was not enabled
resulted in player termination scenario not honoring user setting
"save-position-on-quit" from config file. This patch addresses the
issue by checking for "save-position-on-quit" in cmd_stop and saving
state when idle mode is not enabled.
Useless, but super generic! Actually may add support for other fringe
formats, however vo_x11 in itself is useless, so nothing won here. Also
I didn't bother with big endian support.
I guess I decided to stuff it all into mp_imgfmt_desc (the "old"
struct). This is probably a mistake. At first I was afraid that this
struct would get too fat (probably justified, and hereby happened), but
on the other hand mp_imgfmt_get_desc() (which builds the struct) calls
the former mp_imgfmt_get_layout(), and the separation doesn't make too
much sense anyway. Just merge them.
Still, try to keep out the extra info for packed YUV bullshit. I think
the result is OK, and there's as much information as there was before.
The test output changes a little. There's no independent bits[] array
anymore, so formats which did not previously have set this now show it.
(These formats are mpv-only and are still missing the metadata. To be
added later). Also, the output for the cursed packed formats changes.
Use the new pixfmt metadata to replace the format tables with weird
generic code.
As you can see, this removes the tables that essentially duplicate
information (which is baaaaaaaaaad), in exchange for code which is
probably more fragile and has less of a chance of being understood by
someone new to the code (which is probably even worse from a maintenance
and robustness point of view, but LALALA I CAN'T HEAR YOU).
There are some more formats which can be handled like this (RGB30 and
packed YUV I guess), maybe later.
My previous commit added support for this format, but it was still
broken, and prevented the allocation code from working. It's unknown
whether it's correct now (because this pixfmt is so obscure and useless,
there are no known samples around), but who cares.
Trying to use anything other than CLOCK_MONOTONIC here would be a
disaster. No idea if it's even possible for the clockid here to be
something other than CLOCK_MONOTONIC in this function but it's better
safe than sorry. Closes#7740.
I thought I'd probably want something like this, so the hardcoded stuff
in repack.c can be removed eventually. Of course this has no purpose at
all, and will not have any. (For now, this provides only metadata, and
nothing uses it, apart from the "test" that dumps it as text.)
This adds full support for AV_PIX_FMT_UYYVYY411 (probably out of spite,
because the format is 100% useless). Support for some mpv-only formats
is missing, ironically.
The code goes through _lengths_ to try to make sense out of the FFmpeg
AVPixFmtDescriptor data. Which is even more amazing that the new
metadata basically mirrors pixdesc, and just adds to it. Considering
code complexity and speed issues (it takes time to crunch through all
this shit all the time), and especially the fact that pixdesc is very
_incomplete_, it would probably better to have our own table to all
formats. But then we'd not scramble every time FFmpeg adds a new format,
which would be annoying. On the other hand, by using pixdesc, we get the
excitement to see whether this code will work, or break everything in
catastrophic ways.
The data structure still sucks a lot. Maybe I'll redo it again. The text
dump is weirdly differently formatted than the C struct - because I'm
not happy with the representation. Maybe I'll redo it all over again.
In summary: this commit does nothing.
Remove the vaguely defined plane_bits and component_bits fields from
struct mp_imgfmt_desc. Add weird replacements for existing uses. Remove
the bytes[] field, replace uses with bpp[].
Fix some potential alignment issues in existing code. As a compromise,
split mp_image_pixel_ptr() into 2 functions, because I think it's a bad
idea to implicitly round, but for some callers being slightly less
strict is convenient.
This shouldn't really change anything. In fact, it's a 100% useless
change. I'm just cleaning up what I started almost 8 years ago (see
commit 00653a3eb0). With this I've decided to keep mp_imgfmt_desc,
just removing the weird parts, and keeping the saner parts.
The image w and h members must match params.w and params.h, so
should not be changed directly. The helper function mp_image_set_size
is designed for this purpose, so just use that instead.
This prevents an assertion error with the rewritten draw_bmp.
Fixes#7721.
The generate_xxx() helpers, once defined, would appear as
user-visible functions; this would lead to unexpected and
confusing completion suggestions for gene<tab> after having
once run mpv in that shell.
This PR adds the prefix '_mpv_' to all completion functions
as a convention to make them less user-visible and less likely
to collide with other packages.
The OSC calls this "tooltip" (and although a general mechanism, there's
only one instance using it). One particular problem was that with the
default OSC layout, moving the mouse down and out of the window, the
tooltip stuck around, because the returned mouse position was the last
pixel row in the window, which still overlaps with the seek bar.
Instead of introducing mouse_in_window, you could check last_mouse_X for
nil, but I think this is clearer.
This returns (-1, -1) to the caller if the mouse is outside. Kind of
random, but works.
Added in libplacebo v60, unfortunately with some changes in design that
make it a bit of an awkward fit for the way timers are used in mpv.
Timer queries in libplacebo don't support "start" and "stop"-style
operations, and instead are attached directly to operations. The only
sane way of implementing this in the ra API is to have a single 'active
timer' that gets attached to every pass, taking care to sort distinct
operations into distinct pl_timer queries within that ra_timer.
This design unfortunately doesn't let us have multiple 'active timers'
concurrently, similar to the current such limitation in ra_gl. But it's
also not a big deal.
Before this, we pretty much guaranteed that --mpv-ipc-fd=3 would be
passed. The FD was hardcoded, so scripts started by this mechanism
didn't need to actually parse the argument. Change this to using a
mostly random FD number instead.
I decided to do this because posix_spawnp() and the current replacement
cannot "guarantee" a FD layout. posix_spawn_file_actions_adddup2() just
runs dup2() calls, so it may be hard to set FD 3/4 if they are already
used by something else. For example imagine trying to map:
{.fd = 3, .src_fd = 4},
{.fd = 4, .src_fd = 3},
Then it'd do dup2(4, 3), dup2(3, 4) (reminder: dup2(src, dst)), and the
end result is that FD 4 really maps to the original FD 4.
While this was not a problem in the present code, it's too messy that I
don't want to pretend it can always done this way without an unholy
mess. So my assumption is that FDs 0-2 can be freely assigned because
they're never closed (probably...), while for all other FDs only
pass-through is reasonable.
This code runs posix_spawnp() within a fork() in some cases, in order to
"disown" processes which are meant as being started detached. But
posix_spawnp() is not marked as async-signal-safe, so what we do is not
allowed. It could for example cause deadlocks, depending on
implementation and luck at runtime. Turns out posix_spawnp() is useless
crap.
Replace it with "classic" fork() to ensure correctness.
We could probably use another mechanism to start a process "disowned"
than doing a double-fork(). The only problem with "disowning" a process
is calling setsid() (which posix_spawnp() didn't support, but maybe will
in newer revisions), and removing as as parent from the child process
(the double-fork() will make PID 1 the parent). But there is no good way
to either remove us as parent, or to "reap" the PID in a way that is
safe and less of a mess than the current code. This is because
POSIX/UNIX is a miserable heap of shit. (Less shit than "alternatives"
like win32, no doubt.)
Because POSIX/UNIX is a miserable heap of shit, execvp() is also not
specified as async-signal-safe. It's funny how you can run a full
fledged HTTP server in an async-signal-safe context, but not start a
shitty damn process. Unix is really, really, really extremely bad at
this process management stuff. So we reimplement execvp() in an
async-signal-safe way.
The new code assumes that CLOEXEC is a thing. Since POSIX/UNIX is such a
heap of shit, O_CLOEXEC and FD_CLOEXEC were (probably) added at
different times, but both must be present. io.h defines them to 0 if
they don't exist, and in this case the code will error out at runtime.
Surely we could do without CLOEXEC via fallback, but I'll do that only
if at least 1 bug is reported wrt. this issue.
The idea how to report exec() failure or success is from musl. The way
as_execvpe() is also inspired by musl (for example, the list of error
codes that should make it fail is the same as in musl's code).
See manpage additions. This was requested, sort of. Although what has
been requested might be something completely different. So this is
speculative.
This also changes sub_get_text() to return an allocated copy, because
the buffer shit was too damn messy.
This does not normally happen. But since the --input-ipc-client option
can pass in raw FDs, it's probably a good thing in the interest of
making mistakes obvious. Without this, it just burned a core on invalid
FDs (poll() always returned immediately).
As discussed in the referenced issue. This is quite a behavior change,
bit since this option is new, and not included in any releases yet, I
think it's OK.
Fixes: #7648
Render most of the OSD on the CPU, then draw it using a relatively
simple method. Do this for minimum code maintenance overhead. (While it
doesn't matter for vo_direct3d, and the effort spent here is probably
more than this would ever hope, I do hope to simplify the internal OSD
API for all these fringe VOs. Only vo_gpu should be allowed to do more
sophisticated things.)
If your GPU is shit (which it will be if you "want" to use vo_direct3d),
this might actually improve performance... is what I'd say, but out of
laziness a full screen sized texture gets uploaded on every OSD/subtitle
change, so maybe not.
This isn't useful anymore. We have a much better d3d11 renderer in
vo_gpu. D3D11 is available in all supported Windows versions. The
StretchRect path might still be useful for someone (???), and leaving it
at least evades conflict about users who want to keep using this VO for
inexplicable reasons. (Low power usage might be a justified reason, but
still, no.)
Also fuck the win32 platform, it's a heap of stinky shit. Microsoft is
some sort of psycho clown software company. Granted, maybe still better
than much of the rest of Silly Con Valley.
The original solution for #7017 was sort of a hack, but this hack is no
longer needed because c05e5d9d fixed the underlying issue causing this
error to be spammed in the first place. So just remove the "fix" that
apparently introduced about as many issueas it fixed.
Fixes#7719, hopefully.
Whatever it's worth. Instead of doing a pretty stupid conversion to
float, just blend it directly. This works for most RGB formats that are
8 bits per component or below (the latter because we expand packed
fringe RGB formats for simplicity). For higher bit depth RGB this would
need extra code.
This checked params->color.space for being RGB. If the colorspace is
unset, this did dumb things because even if the imgfmt was a RGB one,
the colorspace was not set to RGB. This actually also happened to the
tests.
(Short-cutting RGB like this is actually wrong, since RGB could still
have strange gamma or primaries, which would warrant a full conversion.
So you'd need to check for these other parameters as well. To be fixed
later.)
This will probably make it slower. But since I don't care about
vo_vaapi, that's perfectly OK. It serves mostly as a test for the
previous commit. In addition, this code was pretty bad (custom broken
scaling and not-blending that probably broke in some situation). If that
wasn't enough, some vaapi drivers also provide only a single overlay at
a time, while this code required a bunch.
There also seems to be a Mesa bug: the overlay gets stretched when
src_x/y was not 0. Or maybe I misunderstood how this is supposed to
work. A bug is probably more likely? Nobody cares about this API.
Maybe this is useful for some of the lesser VOs. It's preferable over
bad ad-hoc solutions based on the more complex sub_bitmap data
structures (as observed e.g. in vo_vaapi.c), and does not use that much
more code since draw_bmp already created such an overlay internally.
But I still wanted something that avoids having to upload/render a full
screen-sized overlay if for example there's only a tiny subtitle line on
the bottom of the screen. So the new API can return a list of modified
pixels (for upload) and non-transparent pixels (for display). The way
these pixel rectangles are computed is a bit dumb and returns dumb
results, but it should be usable, and the implementation can change.
They are sort of confusing, and they hide the fact that they have an
alpha component. Using the actual formats directly is no problem, sicne
these were useful only for big endian systems, something we can't test
anyway.
This was not intended to be committed in 0e3f893606. It disables
the extra wakeup if working==true. I've convinced myself that the wakeup
was really needed at the time, so no idea how I didn't notice this until
someone pointed it out on the commit diff on github (lol).
Bill Gates did not only create COVID, he's also responsible for the
world's worst OS, where you have to literally jump through hoops of fire
to open files with Unicode file names. Lua did not care to implement any
jumping, so it's our turn to jump.
Untested (on win32).
Fixes: #7701
Change it to strictly accept local paths only. No more http://, no more
$HOME expansion with "~/" or mpv config path expansion with "~~/". This
should behave as if passing a path directly to open().
Reduce annoying log noise to further facilitate it using as open()
replacement.
Sometimes it's helpful to override this for specific mp_log instances,
because in some specific circumstances you just want to suppress log
file noise you never want to see.
-1 is an allowed value (for suppressing MSGL_FATAL==0). It looks like
the libplacebo wrapper still does this wrong, so it will probably
trigger UB in some cases. I guess I don't care, though.
This resolves prefixes such as "~/" and "~~/" at the caller, instead of
relying on stream_read_file() to do it. One of the following commits
will remove this from stream_read_file() itself.
Untested.
By default --sub-auto uses "exact". This was far from an "exact" match,
because it added anything that started with the video filename (without
extension), and seemed to end in something that looked like a language
code.
Make this stricter. "exact" still tolerate a language code, but the
video's filename must come before it without any unknown extra
characters. This may not load subtitles in some situations where it
previously did, and where the user might think that the naming
convention is such that it should be considered an exact match.
The subtitle priority sorting seems a bit worthless. I suppose it may
have some value in higher "fuzz" modes (like --sub-auto=fuzzy).
Also remove the mysterious "prio += prio;" line. I probably shouldn't
have checked, but it goes back to commit f16fa9d31 (2003), where someone
wanted to "refine" the priority without changing the rest of the code or
something.
Mostly untested, so have fun.
Fixes: #7702
The caller of render_frame() re-iterates without waiting if this
function returns true. That's normally meant for DS, where we draw
frames as fast as possible to let the driver perform waiting.
draw_bmp.c is the software blender for subtitles and OSD. It's used by
encoding mode (burning subtitles), and some VOs, like vo_drm, vo_x11,
vo_xv, and possibly more.
This changes the algorithm from upsampling the video to 4:4:4 and then
blending to downsampling the OSD and then blending directly to video.
This has far-reaching consequences for its internals, and results in an
effective rewrite.
Since I wanted to avoid un-premultiplying, all blending is done with
premultiplied alpha. That's actually the sane thing to do. The old code
just didn't do it, because it's very weird in YUV fixed point.
Essentially, you'd have to compensate for the chroma centering constant
by subtracting src_alpha/255*128. This seemed so hairy (especially with
correct rounding and high bit depths involved) that I went for using
float.
I think it turned out mostly OK, although it's more complex and less
maintainable than before. reinit() is certainly a bit too long. While it
should be possible to optimize the RGB path more (for example by
blending directly instead of doing the stupid float conversion), this is
probably slower. vo_xv users probably lose in this, because it takes the
slowest path (due to subsampling requirements and using YUV).
Why this rewrite? Nobody knows. I simply forgot the reason. But you'll
have it anyway. Whether or not this would have required a full rewrite,
at least it supports target alpha now (you can for example hard sub
transparent PNGs, if you ever wanted to use mpv for this).
Remove the check in vf_sub. The new draw_bmp.c is not as reliant on
libswscale anymore (mostly uses repack.c now), and osd.c shows an
error message on missing support instead now.
Formats with chroma subsampling of 4 are not supported, because FFmpeg
doesn't provide pixfmt definitions for alpha variants. We could provide
those ourselves (relatively trivial), but why bother.
This provides a way to convert YUV in fixed point (or pseudo-fixed
point; probably best to say "uint") to float, or rather coefficients
to perform such a conversion. Things like colorspace conversion is out
of scope, so this is simple and strictly per-component.
This is somewhat similar to mp_get_csp_mul(), but includes proper color
range expansion and correct chroma centering. The old function even
seems to have a bug, and assumes something about shifted range for full
range YCbCr, which is wrong.
vo_gpu should probably use the new function eventually.
Adding all these so I can use them for obscure processing purposes (see
later draw_bmp commit).
There isn't really a reason why they should exist. On the other hand,
they're just labels for formats that can be handled in a generic way,
and this commit adds support for them in the zimg wrapper and vo_gpu
just by making the formats exist. (Well, vo_gpu had to be fixed in the
previous commit.)
This was incorrect at least because the colorspace matrix attempted to
center chroma at (conceptually) 0.5, instead of 0. Also, it tried to
apply the fixed point shift logic for component sizes > 8 bit.
There is no float yuv format in mpv/ffmpeg yet, but see next commit,
which enables zimg to output it. I'm assuming zimg defines this format
such that luma is in range [0,1] and chroma in range [-0.5,0.5], with
the levels flag being ignored. This is consistent with H264/5 Annex E (I
think...), and it sort of seems to look right, so that's it.
Was broken with a zimg wrapper refucktor before the previous commit. In
addition, it seems this didn't match the vo_drm format, or the format
naming convention. So the order actually changes, and the format is
redefined. (The img_format.h comment was probably wrong.)
Change vo_gpu to the new format as well, so we can still test it.
For whatever purpose. If anything, this makes the zimg wrapper cleaner.
The added tests are not particular exhaustive, but nice to have. This
also makes the scale_zimg.c test pretty useless, because it only tests
repacking (going through the zimg wrapper). In theory, the repack_tests
things could also be used on scalers, but I guess it doesn't matter.
Some things are added over the previous zimg wrapper code. For example,
some fringe formats can now be expanded to 8 bit per component for
convenience.
The OSD is passed to VOs via struct sub_bitmaps, which has a change_id
field. This field is incremented whenever there is a (potential) change
to the other struct contents. If not, the VO can rely on it not having
changed. This must include for example sub_bitmap.x and sub_bitmap.dw.
If these two fields (and y equivalents) change, change_id must change,
even if the subtitle bitmap data might still be the same.
sd_lavc.c stopped respecting this at some unknown point. It could
sometimes cause problems, though usually only with bad and old VOs which
somehow relied on this more than vo_gpu. (I've actually encountered this
before with sd_lavc subtitle scaling, as indicated by a nasty comment,
though probably didn't track this down, since said old VOs can die in a
fire.)
Fix this by maintaining the change_id explicitly. Unfortunately adds
even more code. Instead of comparing the result we could track property
changes, but I think this is better. The number of parts is always very
low with this subtitle decoder, so there's no actual performance issue
to worry about.
This could be triggered by scaling changes (video-zoom etc.), but
probably also changing bitmap subtitle position or scaling.
Should be somewhat helpful. (All VOs are full of code trying to
compensate for this, more or less, and this will allow simplifying
some code later. Maybe.)
The screen size is mostly for robustness checks.
glibc/gcc make certain math functions set errno by default. This is not
required by the standard, and makes everything complexer and slower
(well done glibc). It typically prevents inlining certain math functions
too, where the compiler can turn a function call to a single
instruction, such as observed with lrint().
So this has possibly some minor performance advantages, and no
disadvantages.
Fallback to drmModeAddFB2 if drmModeAddFB2WithModifiers fails. I've
observed it failing on a pinebook pro running manjaro. We also got "0"
as modifiers from FFmpeg anyway, which might or might not have
something to do with this.
Instead of trying to find the source of the problem, just add this
fallback.
Untested (I don't have a platform that requires modifiers to work
here). Might break something, or might fix something. At least this
looks more intuitive to me.
The current implementation of presentation feedback was designed to be
used with flip model presentation. With the bitblt model,
GetFrameStatistics returns totally different values and it's not clear
if we can use them at all. Previously, this wasn't a problem because
with the bitblt model, GetFrameStatistics only worked in exclusive
fullscreen. Now that mpv supports exclusive fullscreen, we should
explicitly check for a flip model swapchain before using presentation
feedback.
This is really basic for planar image data access; not sure why there
weren't such helpers before.
They also handle trickier formats that use bit-packing, or they would be
mich simpler. (This affects only BGR4/BGR4/MONOW/MONOH, I hope whoever
invented them is proud of triggering so many special cases for so little
gain.)
These were still mapped to MP errors during probing, but they also get
triggered when instance creation fails due to lack of support for e.g.
wayland. Since waylandvk is probed above x11vk, we should probably
suppress these by default.
Closes#7626
This brings the displayed percentage closer to the exact number and
allows mpv to more frequently display 100% when it finishes playing a
typical video or audio file.
I have to say this in PR reviews all the time, so maybe I should make i
explicit. In too many words of course, many, many, too many words which
nobody will read, I get it, now shut up. Sneak in some subtle or not so
subtle comments about how I think that github is ruining code quality.
mp.set_osd_ass() (which was undocumented, or in other words, was not
supposed to be used by external scripts) used to do change detection in
the mpv C code. If the resolution or payload did not change, it was not
re-rendered on the lower levels.
Apparently this made some people sad, so fix it. (But only after I told
them to fuck off.) (Well I didn't put it this way, but still.)
For some reason this was never done? Looking through the code, it was
never the case that the frame cache was hit for still frames. I have no
idea why not. It makes a lot of sense to do so.
Notably, this massively improves the performance of updating the OSC
when viewing e.g. large still images, or while paused. (Tested on a
4000x8000 image, the OSC now responds smoothly to user input)
The header probing hacks were previously all broken. They only worked
the first time the archive file was open. Since subsequent opens (on
seek) occured in the middle of the source stream rather than at the
beginning, the stream_read_peek calls meant to retrieve the headers were
instead returning random bytes in the middle of the file.
Perhaps the worst manifestation of this was when seeking within a
multi-volume .rar archive with the "legacy" file naming pattern. If the
seek required a reopen, the fact that the archive was multi-volume would
be forgotten and the file would appear truncated terminating playback.
To solve this, only perform the header probling the first time the
archive is opened. Save the results and reuse them on subsequent
reopens. Put this in a wrapper so this is transparent to
demux_libarchive.
I couldn't find any reason for this message to be so far dispalced from
where it's necessity was determined. That necessity is not however in
question.
Also improve the wording and line breaking.
Making OSD/subtitle bitmaps refcounted was planend a longer time ago,
e.g. the sub_bitmaps.packed field (which refcounts the subtitle bitmap
data) was added in 2016. But nothing benefited much from it, because
struct sub_bitmaps was usually stack allocated, and there was this weird
callback stuff through osd_draw().
Make it possible to get actually refcounted subtitle bitmaps on the OSD
API level. For this, we just copy all subtitle data other than the
bitmaps with sub_bitmaps_copy(). At first, I had planned some fancy
refcount shit, but when that was a big mess and hard to debug and just
boiled to emulating malloc(), I made it a full allocation+copy. This
affects mostly the parts array. With crazy ASS subtitles, this parts
array can get pretty big (thousands of elements or more), in which case
the extra alloc/copy could become performance relevant. But then again
this is just pure bullshit, and I see no need to care. In practice, this
extra work most likely gets drowned out by libass murdering a single
core (while mpv is waiting for it) anyway. So fuck it.
I just wanted this so draw_bmp.c requires only a single call to render
everything. VOs also can benefit from this, because the weird callback
shit isn't necessary anymore (simpler code), but I haven't done anything
about it yet. In general I'd hope this will work towards simplifying the
OSD layer, which is prerequisite for making actual further improvements.
I haven't tested some cases such as the "overlay-add" command. Maybe it
crashes now? Who knows, who cares.
In addition, it might be worthwhile to reduce the code duplication
between all the things that output subtitle bitmaps (with repacking,
image allocation, etc.), but that's orthogonal.
Only _writes_ are aligned, so the assumption doesn't work for reads. But
it's easy to fix by rounding down x0 to the next byte boundary. Writing
pixels outside of the read area is allowed, and we don't go out of
buffer bounds.
Patch by anon32, permission to do anything with it.
This is mostly for testing. It adds passing through the metadata through
the video chain. The metadata can be manipulated with vf_format. Support
for zimg alpha conversion (if built with zimg after it gained alpha
support) is implemented. Support premultiplied input in vo_gpu.
Some things still seem to be buggy.
Used to be used by vo_x11, and some other situations where software
conversion was employed. Haven't seen anyone complain about how software
brightness controls went away (originating from mplayer), so whatever,
it won't be needed again.
This fixes two issues with invalid value after 38/48:
- It was not detected correctly and ended up skipping 4 instead of 0.
- The intent was to skip 0, but it's better to skip the rest.
Behavior with valid 2/5 after 38/48 was correct and is unaffected.
In the wayland code, the left mouse click is treated a bit differently.
Dragging the left click allows mpv to request a window move to the
compositor. In some cases, this can also request a window resize if the
osc-windowcontrols are enabled. These functions had the strange side
effect of messing up mpv's deadzone (it seemed to disappear completely).
A harmless enough workaround is to just explictly send an UP event for
left click after the move/resize functions are finished executing. The
xdg_toplevel move and resize functions both finish after the button
press is let go, so we are guarenteed to have the left click in the UP
state here. Sending this event probably unconfuses some calculation
somewhere thus fixing the deadzone bug. It feels a little silly, but
it's safe and works. Fixes#7651.
When stats.lua is used without a video window then it uses the terminal.
On Windows, however, so far it disabled ansi escape sequences and used
plaintext unless ANSICON env is set.
It's unclear why it's disabled on windows, because at the time it was
added it only used bold by default and mpv ansi emulation on windows
already supported bold at that time.
We can guess that it was disabled because if the same config is used on
both linux and Windows, and it had complex escape sequences for
stats.lue, then it would be emulated incorrectly on Windows.
This shouldn't be an issue anymore, as the last two commits both enhance
the emulation to be quite complete (and graceful where it's not), and
also enable the much-more complete native VT terminal when possible
(Windows 10).
Just remove this windows exception at stats.lua.
This enables native and more complete escape-sequence handling instead
of our emulation. E.g. it supports 256/true colors, and more.
This should get enabled automatically on Windows 10 build 16257
(August 2017) or later.
Previously an SGR sequence was emulated correctly only if:
- It had exactly 1 or 2 numeric values (not 0).
- Only reset, bold, and foreground colors were supported.
- 256/true colors were not skipped correctly with their sub-values.
Now it supports the same as before, plus:
- 0-16 (inclusive) numeric values, e.g. \e[m now resets correctly.
- Supports also codes for background color, reverse, underline* .
- Supports also codes for default intensity/fg/bg/reverse/underline.
- 256/true colors are recognized and skipped gracefully.
* Reverse/underline seem to work only on windows 10.
On FreeBSD non-POSIX threading functions are in a separate header.
DragonFly and OpenBSD adopted FreeBSD header and extensions.
../test.c:3:3: error: implicit declaration of function 'pthread_set_name_np' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
{ pthread_set_name_np(pthread_self(), "ducks"); return 0; }
^
../osdep/threads.c:47:5: error: implicit declaration of function 'pthread_set_name_np' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
pthread_set_name_np(pthread_self(), tname);
^
Signed-off-by: Jan Beich <jbeich@FreeBSD.org>
Move lookup GBRP or planar gray/alpha formats to separate functions in
some cases.
Make setup_regular_rgb_packer() not use a 4:4:4 YUV format to "pass"
RGB. This was used as a "trick" to avoid the stupid GBRP plane
permutation, but it confused severely, so get rid of it. Just do the
reordering, even if the zimg wrapper itself will reorder it back (which
is so stupid that I used the other approach at first). The comment
saying IMGFMT_420P was bogus of course; typically it was IMGFMT_444P.
This was inconsistent for unknown reason. monob was the way we wanted
it, and handling of monow was missing.
See the previous "img_format: add some mpv-only helper formats" commit.
Matters for the zimg wrapper.
mp_imgfmt_get_forced_csp() should be consistent with the MP_CSP_RGB/YUV
flags.
At least the different handling of the XYZ exception was a mess, even if
the result was the same.
Utterly useless, but the intention is to make dealing with corner case
pixel formats (forced upon us by FFmpeg, very rarely) less of a pain.
The zimg wrapper will use them. (It already supports these formats
automatically, but it will help with its internals.)
Y1 is considered RGB, even though gray formats are generally treated as
YUV for various reasons. mpv will default all YUV formats to limited
range internally, which makes no sense for a 1 bit format, so this is a
problem. I wanted to avoid that mp_image_params_guess_csp() (which
applies the default) explicitly checks for an image format, so although
a bit janky, this seems to be a good solution, especially because I
really don't give a shit about these formats, other than having to
handle them. It's notable that AV_PIX_FMT_MONOBLACK (also 1 bit gray,
just packed) already explicitly marked itself as RGB.
When I added mp_regular_imgfmt, I made the chroma subsampling use the
actual chroma division factor, instead of a shift (log2 of the actual
value). I had some ideas about how this was (probably?) more intuitive
and general. But nothing ever uses non-power of 2 subsampling (except
jpeg in rare cases apparently, because the world is a bad place).
Change the fields back to use shifts and rename them to avoid mistakes.
Make this slightly less ad-hoc. Also correct the missing alpha flag for
yap8/yap16.
Despite reduced redundancy, the LOC is going up anyway... whatever.
On FreeBSD and DragonFly kernel checks if `frsig` is valid and aborts
with `EINVAL` if not. However, `frsig` was never implemented.
$ build/mpv --gpu-context=drm /path/to/video.mkv
[...]
[vo/gpu] VT_SETMODE failed: Invalid argument
[vo/gpu/opengl] Failed to set up VT switcher. Terminal switching will be unavailable.
[...]
$ ./waf configure
Checking for vt.h : no
Checking for DRM : vt.h not found
[...]
../test.c:1:10: fatal error: 'sys/vt.h' file not found
#include <sys/vt.h>
^~~~~~~~~~
$ build/mpv --gpu-context=drm /path/to/video.mkv
Error parsing option gpu-context (option parameter could not be parsed)
Setting commandline option --gpu-context=drm failed.
Exiting... (Fatal error)
One not-so-nice hack in the wayland code is the assumption of when a
window is hidden (out of view from the compositor) and an arbitrary
delay for enabling/disabling the usage of presentation time. Since you
do not receive any presentation feedback when a window is hidden on
wayland (a feature or misfeature depending on who you ask), the ust is
updated based on the refresh_nsec statistic gathered from the previous
feedback event.
The flaw with this is that refresh_nsec basically just reports back the
display's refresh rate (1 / refresh_rate * 10^9). It doesn't tell you
how long the vsync interval really was. So as a video is left playing
out of view, the wl->last_queue_display_time becomes increasingly
inaccurate. This led to a vsync spike when bringing the mpv window back
into sight after it was hidden for a period of time. The hack for
working around this is to just wait a while before enabling presentation
time again. The discrepancy between the "bogus"
wl->last_queue_display_time and the actual value you get from the
feedback only happens initially after a switch. If you just discard
those values, you avoid the dramatic vsync spike.
It turns out that there's a smarter way to do this. Just use mp_time_us
deltas. The whole reason for these hacks is because
wl->last_queue_display_time wasn't close enough to how long it would
take for a frame to actually display if it wasn't hidden. Instead, mpv's
internal timer can be used, and the difference between wayland_sync_swap
calls is a close enough proxy for the vsync interval (certainly better
than using the monitor's refresh rate). This avoids the entire conundrum
of massive vsync spikes when bringing the player back into view, and it
means we can get rid of extra crap like wl->hidden.
UB sanitizer complains that aval<<24 (if >=128) cannot be represented as
int. Indeed, we would shift a bit into the sign of an int, which is
probably UB or implementation defined (I can't even remember, but the
stupidity of it burns). So technically, ubsan might be right.
Change aval to uint32_t, which I don't think has a chance of getting
promoted to int. Change the other *val to uint32_t too for cosmetic
symmetry.
So we have to obscure the intention of the code (*val can take only 8
bits) out of language stupidity. How nice. (What a shitty language.)
A mkv sample file was provided to me, which contained a moving PGS
subtitle track, with the same track rendered into the video as
reference. The subtitle track appeared to stutter (while the video one
was smooth). It turns out this was a timestamp rounding issue in mpv.
The subtitle timestamps in the file match the video ones exactly.
They're the same within the mpv demuxer too. Unfortunately, the
conversion from and to libavcodec timestamps is lossy, because mpv uses
a non-integer timebase, while libavcodec supports integers only. See
mp_pts_to_av() and mp_pts_from_av(). The recovered timestamp is almost
the same, but is off by a very minor part. As a result, the timestamps
won't compare equal, and if that happens, display of the subtitle frame
is skipped. Subtitle timestamps don't go through this conversion
because... libavcodec is special? The libavcodec subtitle API is
special.
Fix this by giving it a microsecond of slack. This is basically as if we
used an internal microseconds integer timebase, but only for the purpose
of image subtitle display.
The same could happen to sd_ass, except in practice it doesn't. ASS
subtitles (well, .ass files) inherently use a timebase incompatible to
video, so to ensure frame exactness, ASS timestamps are usually set to
slightly before the video frame's.
Discussion of better solutions:
One could rewrite mpv not to use float timestamps. You'd probably pick
some integer timebase instead (like microseconds), which would avoid the
libavcodec interop issue. At the very least this would be a lot of work.
It would be interesting to know whether the rounding in ther mpv<->lavc
timestamp conversion could be fixed to round-trip in this case. The
conversion tries to avoid problems by using the source timebase (e.g.
milliseconds with mkv). But in general some rounding is unavoidable,
because something between decoder and lowest demuxer layer could
transform the timestamps.
One could extend libavcodec to attach arbitrary information to avpacket
and return it in the resulting avframe. To some degree, such a mechanism
already exists (side data). But there are certain problems that make
this unfeasible and broken.
One could pass through exact mpv float timestamps by reinterpret-casting
them to int64_t, the FFmpeg timestamp type. Actually mpv used to do
this. But there were problems, such as FFmpeg (or things used by FFmpeg)
wanting to interpret the timestamps. Awful shit that make mpv change to
the current approach.
There's probably more but I'm getting bored. With some luck I wasted
precious seconds of your life with my nonsense.
It is more consistent for editions/chapters to go below either
the title or filename. They are all descriptive strings about
the media itself and not file metadata like filesize.
Suggested by Argon-
Edition information is conditional based on there being more than
one edition present. It is printed on the same line as Chapters to
save vertical space.
Apparently, this was a bit of a mess, which caused the bug fixed by
commit ec7f2388af. Try to improve this, and only use track selection
entries that exist.
zsh often sets DECCKM (i.e. Cursor Key Mode) meaning the arrow keys
send `SS3 A/B/C/D` instead of `CSI A/B/C/D`.
Add `key_entry` definitions for this alongside the existing DECCKM Reset
definitions.
e1e714ccc introduced a regression here when unloading a track (e.g. on
VO/AO initilization error), due to no corresponding option existing for
video/audio tracks with orders above 0, but the loop in
`mp_deselect_track` being hard-coded to clear tracks up to NUM_PTRACKS.
Introduce the simplest possible hackaround.
In theory this mostly happens automatically, especially after the 5
vsync limit disables this already. But if we uninit before 5 vsyncs are
rendered, this can get left in a dangling 'enabled' state, which leaks a
debug report callback.
Always explicitly disable it just to be on the safe side.
I must have messed this up when I actually added the Y210 format
(because that one is correct). So my comment in the commit adding this
about the FFmpeg pixfmt doxygen being wrong was wrong.
I'd like to use this opportunity to complain once more about the
existence of these terrible pixel formats.
Again worthless, slow, and only for libswscale parity.
With this, we support all formats libswscale supports, except bayer
input, and rgb4/bgr4 output. We even support some formats libswscale
doesn't.
It's possible that the zimg wrapper isn't always as fast as libswscale.
But there is optimization potential: the inner repack loops are
self-contained enough that they could be reasonably be implemented in
assembler (probably), and doing everything slice-wise should reduce the
overhead of the separate pack/unpack stages.
Just lazily tested.
The comment on AV_PIX_FMT_Y210LE seems to be wrong. It claims it's "like
YUYV422", bit it seems more like YVYU422, at last the way libswscale
input treats it. Maybe Intel pays its developers too much?
The repacker inner lop is probably rather inefficient. In theory we
could optimize it by reading the packed pixels as words, doing the
component reshuffling using compile time values etc., but I'd rather
keep the code size small. It's already bad enough that we have to
support 16 bit per component variants, just because this one Intel guy
couldn't keep it in his pants. In general, I can't be bothered to spend
time on optimizing it; I'm only doing this for fun (i.e. masochistic
obligation).
Instead of just picking the last tag that was encountered. The order of
the tags still depends on the file order.
This is probably wrong, and we should respect TargetTypeValue. But
despite staring at the spec, I have no idea what the hell this should
do, so fuck that.
Fixes: #7604
Generic statement about how this is not really appropriate, etc., and
only useful for temporary debugging things, and how I commit it anyway
despite violating my own principles (and how I'd reject this change if
it came from you).
Consider e.g. --aid=2 with a file that has only 1 track. Then it would
fall back to selecting track 1. Stop doing this. If no matching track is
found, this will not select any track now.
Note that the fingerprint stuff (track_layout_hash in the source)
prevents softens the impact of this change. Without the fingerprint,
playing a dual-audio file with the second track selected, and then a
single-audio file, would play the second file without audio. But the
fingerprint resets it due to differences in the track list.
Try to exhaustively document this and tricky interactions between the
other features. What a damn mess, I think it's simply cursed. Of course
it's still my fault.
See: #7608
Some time ago, properties and options were mostly unified. However, the
track selection properties/options semantics are incompatible to this
change. I'm still trying to handle the fallout.
There are two things that are in the way:
1. Track properties somehow return the runtime selection, not the option
value (all while properties are supposed to be aliases to options
with the same name).
2. The user's track options are not supposed to be changed without
interaction. If a track is auto-selected, the property should return
its ID, but the option value should remain at "auto". Only if the
user actually writes to the property the option should change. E.g.
playing e.g. an audio-only file and then a normal video file not play
the video file with --vid=no just because the audio file had no video
track.
In addition to each of them being in conflict with the property/option
unification, attempt to fix one of them breaks the other one.
Today, we're trying to fix parts of this and avoiding an unfortunate
case where you can get a conflicting option/property value, and where
trying to select a track does nothing if the track to select has the
same ID as the option value.
This breaks 2. from above in certain situations. See manpage additions.
See: #7608
Unfortunately, attached pictures (from tags etc.) are treated as video
tracks. That meant --sub-create-cc-track added a CC track for them as
well. Stop doing that.
See: #7608
This covers 8 and 16 bit packed RGB formats. It doesn't really help with
any actual use-cases, other than giving the finger to libswscale.
One problem is with different color depths. For example, rgb565 provides
1 bit more resolution to the green channel. zimg can only dither to a
uniform depth. I tried dithering to the highest depth and shifting away
1 bit for the lower channels, but that looked ugly (or I messed up
somewhere), so instead it dithers to the lowest depth, and adjusts the
value range if needed. Testing with bgr4_byte (extreme case with 1/2/1
depths), it looks more "grainy" (ordered dithering artifacts) than
libswscale, but it also looks cleaner and smoother. It doesn't have
libswscale's weird red-shift. So I call it a success.
Big endian formats need to be handled explicitly; the generic big endian
swapper code assumes byte-aligned components.
Unpacking is done with shifts and 3 LUTs. This is symmetric to the
packer. Using a generated palette might be better, but I preferred to
keep the symmetry, and not having to mess with a generated palette and
the pal8 code.
This uses FFmepg pixfmts constants directly. I would have preferred
keeping zimg completely separate. But neither do I want to add an IMGFMT
alias for every of these formats, nor do I want to extend our imgfmt
code such that it can provide a complete description of each packed RGB
format (similar to FFmpeg pixdesc).
It also appears that FFmpeg pixdesc as well as the FFmpeg pixfmt doxygen
have an error regarding RGB8: the R/B bit depths are swapped. libswscale
appears to be handling them differently. Not completely sure, as this is
the only packed format case with R/B havuing different depths (instead
of G, the middle component, where things are symmetric).
One of the extremely annoying dumb things in ffmpeg is that most pixel
formats are available as little endian and big endian variants. (The
sane way would be having native endian formats only.) Usually, most of
the real codecs use native formats only, while non-native formats are
used by fringe raw codecs only. But the PNG encoders and decoders
unfortunately use big endian formats, and since PNG it such a popular
format, this causes problems for us. In particular, the current zimg
wrapper will refuse to work (and mpv will fall back to sws) when writing
non-8 bit PNGs.
So add non-native endian support to zimg. This is done in a fairly
"generic" way (which means lots of potential for bugs). If input is a
"regular" format (and just byte-swapped), the rest happens
automatically, which happens to cover all interesting formats.
Some things could be more efficient; for example, unpacking is done on
the data before it's passed to the unpacker. You could make endian
swapping part of the actual unpacking process, which might be slightly
faster. You could avoid copying twice in some cases (such as when
there's no actual repacker, or if alignment needs to be corrected). But
I don't really care. It's reasonably fast for the normal case.
Not entirely sure whether this is correct. Some (but not many) formats
are covered by the tests, some I tested manually. Some I can't even
test, because libswscale doesn't support them (like nv20*).
This sucks, but is helpful for testing.
Obviously, it would be much nicer if there were a way to specify _all_
scaler options per filter (if the user wanted), instead of always using
the global options. But this is "too hard" for now. For testing, it is
extremely convenient to select the scaler backend, so add this option,
but make clear that it could go away. We'd delete it once there is a
better mechanism for this.
Edition title is already exposed in demux_edition, it was just never
added to the display. If no edition title exists it will fall back
to the edition number.
Keys and lines-to-scroll are configurabe, and the scroll keys are only
bound on pages which support scrolling (currently only page 4) - also
during oneshot (like the page-switching keys).
Scroll offset is reset for all pages on any key - except scroll keys, so
that entering or switching to a page resets the scroll, as well as when
"re-entering" the same page or "re-activating" the stats oneshot view.
TODO: print_page(..) is highly associated with extending the oneshot
timer if required. The timer handling can probably move into print_page
and removed from all the places which boilerplate its management.
The call was hidden very well, via
dvb_streaming_read -> dvb_update_config
-> dvb_streaming_start -> dvb_set_channel,
and broke the stream buffering logic.
Dropping that call does not noticeably slow down channel switches.
This used 1 MB due to building the complete command and property list
when starting the script. These are needed only for auto-completion, so
build them only on demand. Since building them is fast enough, rebuild
them every time.
The key bindings table is not that much, but saves some KBs. Oddly, the
code to build it uses less memory than the table at runtime (???), so
build it at runtime as well.
Add 2 tactic collectgarbage() calls as well. This frees unused heap when
it is known that the script is going to be completely inactive until
re-enabled by the user.
The buffer can be larger than the normal size when "peeking" is used
(such as done with some file formats, where a large number of bytes masy
need to be "peeked" at the beginning, because FFmpeg). Once normal
operation resumes, it's supposed to free this buffer again. Apparently
this didn't happen as intended, because normal reading did have no way
to discard back buffer before/while resizing the buffer. There's only a
path for discarding the back buffer when actually reading.
It seems like this unfortunately needs 2 code paths for discarding old
data. Just put it into stream_resize_buffer(), where it's rather
non-tricky (discarding can be done by adjusting the copy offset when
moving data to the new allocation). The function now drops old data if
it doesn't fit into the allocation. The caller must ensure that the new
size is sufficient; the function signature changes only so the size of
the implicitly guaranteed kept part can be checked with assert().
In display-sync mode, the core doesn't need to woken up every vsync, but
only every time a new actual video frame needs to be queued. So don't
wake up if there are still frames to repeat.
In audio-sync mode, the wakeup is simply redundant, since there's a
separate timer (in->wakeup_pts) to control when to queue a new frame. I
think.
This finally brings the required playloop iterations down to almost the
number of video frames. (As originally intended, really.)
Also a fairly risky change.
The wakeup at the end of VO frame rendering seems redundant, because
after rendering almost no state changes. The player core can queue a new
frame once frame rendering begins, and there's a separate wakeup for
this. The only thing that actually changes is in->rendering. The only
thing that seems to depend on it and can trigger a wakeup is the
vo_still_displaying() function. Change it so that it needs an explicit
call to a new API function, so we can avoid wakeups in the common case.
The vo_still_displaying() code is mostly just moved around due to
locking and for avoiding forward declarations.
Also a somewhat risky change (tasty new bugs).
This should be unnecessary, since the VO itself performs wakeups once a
new frame can be queued. The only situation I can think of where this
might be required are EOF situations (which are always strange).
If I'm wrong, there'll be fun new bugs, probably causing frame drops or
temporary stalls.
When the player core requests new frames from the filter, this is called
external/recursive filtering, which acts slightly differently from when
filters request new data internally. Mainly this is so the external user
doesn't have to call mp_filter_graph_run() just to get a frame. This
causes a number of complications, and the short version is that until
now, mp_filter_graph_run() has unnecessarily returned true in the
current common case, which made the playloop run too often for no
reason.
The problem is that when a mp_pin is read externally, updating the same
mp_pin during recursive filtering flagged external_pending when the
result was written, which made mp_filter_graph_run() return true, which
made the playloop call mp_filter_graph_run() again. This is redundant
because the caller is obviously checking the new state of the mp_pin
immediately.
The only situation in which external_pending really must be set is if
_another_ pin is changed. In theory, we could also unset it if the set
of "external" pins that are not in a signaled state becomes empty, but
we don't track that in a convenient way.
This commit removes the redundant signaling, and avoids running the
playloop an additional time for each video and audio frame (as it
actually was planned from the beginning, but duh).
If a filter receives an asynchronous wakeup during filtering, then
process newly pending filters resulting from that as well, before
returning to the user. Might possibly skip some redundant playloop
cycles.
There is an explicit comment in the code about how this shouldn't be
done, but I think it makes no sense. Filters have no business trying to
interrupt the mainloop, and mp_filter_graph_interrupt() provides a
proper mechanism to do this (though intended to be used by the filter
user, not filters).
In this case, init_buffers() was not called, and the unrelated cache
sample buffers were not initialized. It appears they are indeed
completely unrelated, so move their initialization away. Not sure what
exactly the purpose of calling init_buffers() is, maybe clearing old
data when displaying stats again. The new place for initializing the
cache sample buffers should achieve the same anyway.
Fixes: #7597
This should make it behave roughly like when switching from a file to
the next (clearing audio buffers, keeping AO, but closing AO if the
audio format seems to have changed and gapless mode is "weak").
Not necessarily useful, but harmless and may help with #7579 (untested).
Replace use of .min==1 with a proper flag. This is a good idea, because
it has nothing to do with numeric limits (also see commit 9d32d62b61
for how this can go wrong).
With this, m_option.min/max are strictly used for numeric limits.
This was optional, with the intention that normally such options require
a valid format. But there is no reason for this (at least not anymore),
and it's actually more logical to accept "no" in all situations this
option type is used. This also gets rid of the weird min field special
use.
These used ".min = MP_NOPTS_VALUE" to indicate certain exceptions. This
broke with the recent change to how min/max are handled, which made
setting min or max mean that a value range is used, thus setting max=0.
Fix this by not using magic a value in .min; replace it with a proper
flag.
Fixes: #7596
This is the proper fix for 1e7802. Turns out the solution is dead
simple: we can still set the allocator with lua_getallocf /
lua_setalloc.
This commit makes memory accounting work on luajit as well.
This is a stopgap measure. In theory we could maybe poll the memory
usage on luajit, but for now, simply reverting this part of fd3caa26
makes Lua work again. (And we can still collect cpu usage metrics)
Proper solution pending (tm)
While --input-file was removed for justified reasons, wanting to pass
down socket FDs this way is legitimate, useful, and easy to implement.
One odd thing is that
Fixes: #7592
Add an infrastructure for collecting performance-related data, use it in
some places. Add rendering of them to stats.lua.
There were two main goals: minimal impact on the normal code and normal
playback. So all these stats_* function calls either happen only during
initialization, or return immediately if no stats collection is going
on. That's why it does this lazily adding of stats entries etc. (a first
iteration made each stats entry an API thing, instead of just a single
stats_ctx, but I thought that was getting too intrusive in the "normal"
code, even if everything gets worse inside of stats.c).
You could get most of this information from various profilers (including
the extremely primitive --dump-stats thing in mpv), but this makes it
easier to see the most important information at once (at least in
theory), partially because we know best about the context of various
things.
Not very happy with this. It's all pretty primitive and dumb. At this
point I just wanted to get over with it, without necessarily having to
revisit it later, but with having my stupid statistics.
Somehow the code feels terrible. There are a lot of meh decisions in
there that could be better or worse (but mostly could be better), and it
just sucks but it's also trivial and uninteresting and does the job. I
guess I hate programming. It's so tedious and the result is always shit.
Anyway, enjoy.
I think that makes more sense.
And also remove the graph from the total cache usage, since that wasn't
very interesting. So there's still a total of 2 graphs.
That's where it comes from after all. The other property does not have
much of a reason to exist anymore, but there's no real reason to remove
it either.
Previously, EGL as provided by a pkg-config was checked for independently
in several places. The effect this had is that --disable-egl would not
actually disable EGL from the build, as this only affected the "egl" option
relied upon by egl-x11. wayland-gl and egl-drm did their own EGL checks.
By making wayland-gl and drm-egl depend on egl instead, we fix this
behaviour and can simplify egl-helpers a bit, as we can now simply
check whether egl or one of the other features providing some non-pc egl
is enabled, instead of checking every single thing that might be pulling
in egl.
Future work could make the "egl" option just be a catchall for any
EGL implementation, so that brcmegl and angle and Android can piggyback
on the egl option as well.
Ancient Linux audio output. Apparently it survived until now, because
some BSDs (but not all) had use of this. But these should work with
ao_sdl or ao_openal too (that's why these AOs exist after all). ao_oss
itself has the problem that it's virtually unmaintainable from my point
of view due to all the subtle (or non-subtle) difference. Look at the
ifdef mess and the multiple code paths (that shouldn't exist) in the
removed source code.
I wonder what this even is. I've never heard of anyone using it, and
can't find a corresponding library that actually builds with it. Good
enough to remove.
It was always marked as "experimental", and had inherent problems that
were never fixed. It was disabled by default, and I don't think anyone
is using it.
May or may not help when dealing with playlist loading in scripts. It's
supposed to help with the mean fact that loading a recursive playlist
will essentially edit the playlist behind the API user's back.
Scripts such as the OSC can be loaded and unloaded at runtime by
toggling the option that enables them. (It even works, although normally
it's only used to control initial loading.)
Unloading was racy because it used the client name; fix this.
The load-script change is an accidental feature. And probably useless.
I mostly intend this for internal purposes. Probably pretty useless for
external API users, but on the other hand trivial to expose. While it
makes a lot of sense internally, I'll probably regret exposing it.
This time is set on every seek (but when initiating it). A new seek
longer than 2 seconds after this is counted as separate seek for the
sake of the revert seek command. If a seek takes a bit longer, this
removes time from these 2 seconds. This commits resets it on the end of
the seek. (Doing anything special for seeks that take longer than 2
seconds is out of scope of this commit.)
Until now, it used only coordinates clipped to the screen for this,
which meant no negative margins were ever reported to libass. This broke
proper rendering of explicitly positioned ASS events (libass simply
could not know the real video size in this case.)
Fix this by reporting margins even if they're negative. This makes it
apparently work correctly with vo_gpu at least.
Note that I'm not really sure if anything in the rendering chain
required non-negative margins. If so, and that code implicitly assumed
it, I suppose crashes and such are possible.
The "rule" is that a fallback warning message should be shown only shown
if software decoding was used before, or in other words when either
hwdec was enabled before, but the stream suddenly falls back, or it was
attempted to enable it at runtime, and it didn't work.
The message wasn't printed the first time in the latter case, because
hwdec_notified was not set in forced software decoding mode. Fix it with
this commit. Fortunately, the logic becomes simpler.
There's no more need to call mp_lua_PITA to get the ctx, and the
autofree prototype is now enforced at the C level at compile time.
Also remove the redundant talloc_free_children at these functions
since it's now freed right after the function completes.
Also, rename auto_free_node to steal_node_allocations to be more
explicit and to avoid confusion with the autofree terminology.
Advantages of this approach:
- All the resources are released right after the function ends
regardless if it threw an error or not, without having to wait
for GC.
- Simpler code.
- Simpler lua setup which most likely uses less memory allocation and
as a result should be quicker, though it wasn't measured.
This commit adds the autofree wrapper and uses it where mp_lua_PITA
was used. It's not yet enforced at the C level, there are still
redundant talloc_free_children leftovers, and there are few more
places which could also use autofree. The next commits will address
those.
Looks like the recent change to this actually made it crash whenever
audio happened to be initialized first, due to not setting the
mux_stream field before the on_ready callback. Mess a way around this.
Also remove a stray unused variable from ao_lavc.c.
Lua changed behavior for this specific event. I considered the change
minor enough that it would not need to go through deprecation, but
someone hit it immediately and ask on the -dev channel.
It's probably better to restore the behavior. But mark it as deprecated,
since it's problematic (mismatch with the C API). Unfortunately, no
automatic warning is possible. (Or maybe it is, by playing sophisticated
Lua tricks such as setting a metatable and overriding indexing, but
let's not.)
Travis is currently having "problems" and is spamming IRC all the time
with pointless failure notifications. Make it so that it hopefully sends
a message only when it goes from success to failure, which should
exclude these cases.
While I'm at it, I'd like to complain how idiotic it is to store CI
configuration in a project's source repository. Such a repository should
only contain things that are inherently part of the code's function, not
part of the organization. You don't store bug reports, build results,
the website, developer access controls, etc. in this repository either.
But for CI it's supposed to be OK? I'm all for this "configuration as
code" thing, but what it should mean is that you store configuration
files in some git managed repository, NOT necessarily that you dump them
into the main source code repo. There are many arguments why it should
not be there, such as this very commit. I have a feeling this is mostly
just because all these idiotic web services just want to advertise their
shit and bind customers by not giving easy ways to treat source code and
CI service configuration orthogonal. And so, the source code repo gets
clobbered with stupid shit (both in the set of files and the commit
history). It's fairly idiotic and my tolerance for it is waning. (Oh, of
course you could probably jump through hoops to make it a separate repo,
but I bet that is complicated and has all kinds of downsides because it
won't be the way "it's meant to be used".)
The VM could throw at pushnode and before mpv_free_node_contents, which
would have resulted in leaked content.
Now this case is handled without leaks.
Note: the lua code still leaks on such case, but mp_lua_PITA doesn't
have destructors like the JS autofree has, which, specifically here,
can do mpv_free_node_contents. So TODO: enhance the lua PITA code to
behave more similar to the JS autofree.
Move some parts that can be generic to the client API code. It turns out
lua.c doesn't need anything special.
This adds the "id" field. I think this was actually missing from the
JSON IPC code (i.e. it's a very recent regression that is fixed with
this commit).
Both Lua and the JSON IPC code need to convert the mpv_event struct (and
everything it points to) to Lua tables or JSON.
I was getting sick of having to make the same changes to Lua and IPC. Do
what has been done everywhere else, and let the core handle this by
going through mpv_node (which is supposed to serve both Lua tables and
JSON, and potentially other scripting language backends). Expose it as
new libmpv API function.
The new API is still a bit "rough" and support for other event types
might be added in the future.
This silently adds support for the playlist_entry_id fields to both Lua
and JSON IPC.
There is a small API change for Lua; I don't think this matters, so I
didn't care about compatibility. The new code in client.c is mashed up
from the Lua and the IPC code. The manpage additions are moved from the
Lua docs, and made slightly more "general".
Some danger for unintended regressions both in Lua and IPC. Also damn
these node functions suck, expect crashes due to UB.
Not sure why this became more code instead of less compared to before
(according to the diff stat), even though some code duplication across
Lua and IPC was removed. Software development sucks.
Unfortunately, merely changing the playlist current position affects the
flags returned by the "playlist" property, so the entirely thing needs
to be marked as changed. Seems to be a design mistake.
Should give a good deal more explicit control and insight over the
player state.
Some feel a bit pointless, and/or expose internal weirdness. However,
it's not like the existing weirdness didn't exist before, or can be made
go away. (In part, the weirdness is because certain in-between states
are visible. Hiding them would make things simpler, but less flexible.)
Maybe this actually gives users a better idea how the API _should_ look
like, too.
On a side note, this tries to really guarantee that mpctx->playing is
set between playback start/end. For that, the loadfile.c changes assume
that mpctx->playing is set (guaranteed by code above the change), and
that playing->filename is set (probably could never be false; was broken
before and actually would have crashed if that could ever happen; in any
case, also add an assert to playlist.c for this).
playlist_entry_to_index() now tolerates playlist_entrys that are not
part of the playlist. This is also needed for mpctx->playing.
It's odd that this state is observable, but is made implicit by making
the property unavailable. It's also odd that an API user cannot directly
put the player into such a state.
Just allow reading/writing -1 (or in fact, any out of bounds index) for
this case.
I'm also refraining from using OPT_CHOICE for the "no selection" case,
because although that would be cleaner in theory, it would cause only
problems to API users due to the more complex property type (worse is
better).
One reason for not restricting the integer range on the input property
anymore is that if there are no playlist elements, the range would
contain only 1 integer, which cannot be represented anymore since the
recent m_option change. This was actually broken with 1 element
playlists before (and still is, with the constricted type for OSD and
the add/cycle commands). Doesn't matter too much.
If the user manages to run a "loadfile x append" command before the loop
in mp_play_files() is entered, then the player could start playing
these. This isn't expected, because appending files to the playlist in
idle mode does not normally start playback. It could happen because
there is a short time window where commands are processed before the
loop is entered (such as running the command when a script is loaded).
The idle mode semantics are pretty weird: if files were provided in
advance (on the command line), then these should be played immediately.
But if idle mode was already entered, and something is appended to the
playlist using "append", i.e. without explicitly triggering playback,
then it should remain in idle mode.
Try to follow this by redefining PT_STOP to strictly mean idle mode.
Remove the playlist->current check from idle_loop(), since only the
stop_play field counts now (cf. what mp_set_playlist_entry() does).
This actually introduces the possibility that playlist->current, and
with it playlist-pos, are set to something, even though playback is not
active or being started. Previously, this was only possible during state
transitions, such as when changing playlist entries.
Very annoyingly, this means the current way MPV_EVENT_IDLE was sent
doesn't work anymore. Logically, idle mode can be "active" even if
idle_loop() was not entered yet (between the time after mp_initialize()
and before the loop in mp_play_files()). Instead of worrying about this,
redo the "idle-active" property, and deprecate the event.
See: #7543
What was this even for? Also, most times, the cleared status line will
show up as an empty new line anyway, so this commit reduces the empty
new lines from 2 to 1.
The code that determines the process exit code ignores all stop_play
values other than PT_QUIT. Generally, PT_ERROR is meaningless outside of
play_current_file(), and is mostly equivalent to PT_NEXT_ENTRY.
Do something that makes it report a non-0 exit code, and indicates in
the terminal exit message that something went wrong.
Untested.
In shared mode, we previously tried to feed the full native format to
IsFormatSupported in the hopes that the "closest match" returned was
actually that.
Turns out, IsFormatSupported will always return the mix format if we
don't use the mix format's sample rate. This will also clobber our
choice of channel map with the mix format channel map even if our
desired channel map is supported due to surround emulation.
The solution is to not bother trying to use anything other than the mix
format sample rate. While we're at it, we might as well use the mix
format PCM sample format (always float32) since this conversion will
happen anyway and may avoid unecessary dithering to intermediate
integer formats if we are already resampling or channel mixing.
Using mpv without libass isn't really supported, since it's not only
used to display ASS subtitles, but all text subtitles, and even OSD.
At least 1 user complained that the player printed a warning if built
without libass. Avoid trying to create the impression that using this
software without libass is in any way supported or desirable, and make
it fully mandatory.
(As far as making dependencies optional goes, I'd rather make ffmpeg
optional, which is an oversized and bloated library, rather than
something tiny like libass.)
Because pthread failures are virtually undebuggable (which sure is
pretty strange, given all these heavy instrumentation tools these days).
Of course it affects only files which include osdep/threads.h.
I'm departing from the usual way to add symbols with config.h and using
"#if", and defining it on the compiler command line + "#ifdef" because I
don't want to include config.h from a header (which would be necessary
in this case) to keep things slightly cleaner. Maybe this is misguided,
but still.
This would have been easier if mpv defined its own wrappers for all
thread functions. But we don't (which to be honest is probably better
than e.g. going crazy like VLC and essentially reimplementing
everything). This seems to be a good compromise. Since it's off by
default and basically a developer tool, the minor undefined behavior
(redefining reserved symbols) isn't much of an issue.
After calling the main filter's destroy callback, all child filters are
destroyed. But one of them still tried to access the cache_lock mutex
(which is destroyed in said destroy callback). This actually caused a
crash on Android with _FORTIFY_SOURCE.
Fix this by destroying the child filters first.
As an unfortunate disaster, min/max values use the type double, which
causes tons of issues with int64_t types. Anyway, OPT_BYTE_SIZE is often
used as maximum for size_t quantities, which can have a size different
from (u)int64_t.
OPT_BYTE_SIZE still uses in64_t, because in theory, you could use it for
file sizes. (demux.c would for example be capable of caching more than
2GB on 32 bit platforms if a file cache is used. Though for some reason
the accounting code still uses size_t, so that use case is broken. But
still insist that it _could_ be used this way.)
There were various inconsistent attempts to set m_option.max to a value
such that the size_t/int64_t upper limit is not exceeded. Due to the
double max field, this didn't really work correctly. Try to fix this
with the M_MAX_MEM_BYTES constant. It's a good approximation, because on
32 bit it should allow 2GB (untested, also would probably exhaust
address space in practice but whatever), and something "high enough" in
64 bit.
For some reason, clang 11 still warns. But I think this might be a clang
bug, or I'm crazy. The result is correct anyway.
Since double has a mantissa too small to hold INT64_MAX in full
precision, converting INT64_MAX to double rounds up. Insert some casts
to silence corresponding warnings (as shown by clang 11).
Also, the comparison in multiply_int64() was incorrect (I think...),
because if v==(double)INT64_MAX, then v==(1<<64), which cannot be
represented as int64_t.
There are probably better ways to solve this.
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with
{"name", ...
followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.
I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.
Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.
Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.
In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
Previously, the vo wasn't always informed if something about the output
changed during playback. For instance, changing a display's refresh rate
during playback would not update mpv's display fps. Fix this by simply
using VO_EVENT_WIN_STATE in output_handle_done which executes whenever
something about the output is changed.
Forgot to remove this. Here you see my confusion and realization how
casting INT64_MAX to double becomes INT64_MAX+1 (due to mantissa
precision and rounding), so some things seemed not to make sense at
first.
The message_timeout field was basically polled. But ever since the OSC
was changed to work more event based, this didn't quite work. It was
quite visible when switching subtitle or audio tracks while paused (and
with caching disabled, since the cache update triggered some extra
redrawing).
Fix by using a proper timer.
I noticed that changing tracks with the message call commented didn't
redraw properly either, but, uh, I guess the message is always triggered
anyway, and happens to take care of this.
This seems to be an older bug. It set priv->outputfilename to a new
talloc-allocated string, but the field is also managed as string option,
so talloc will free it first, then m_option_free() is called on the
dangling pointer. Possibly this is caused by the earlier ta destruction
order change.
Allow the --window-maximized and --window-minimized flags to actually
work when the player is started. since macOS doesn't like using both at
the same time the minimized state takes precedence over the maximized
state.
The option code is very old and was added to MPlayer in the early 2000s,
when C99 was still new. MPlayer did not use the "bool" type anywhere,l
and the logical option equivalent to bool, the "flag" option type, used
int, with the convention that only the values 0 and 1 are allowed.
mpv may have hammered many, many additional tentacles to the option
code, but some of the basics never changed, and m_option_type_flag still
uses int. This seems a bit weird, since mpv uses bool for booleans. So
finally introduce an m_option_type_bool. To avoid duplicating too much
code, change the flag code to bool, and "reimplement" m_option_type_flag
on top of m_option_type_bool.
As a "demonstration", change the --fullscreen option to this new type.
Ideally, all options would be changed too bool, and m_option_type_flag
would be removed. But that is a lot of monotonous thankless work, so I'm
not doing it, and making it a painful years long transition.
At the same time, I'm introducing a new concept for option declarations.
Instead of OPT_BOOL(), which define the full m_option struct contents,
there's OPTF_BOOL(), which only takes the option field name itself. The
name is provided via a normal struct field initializer. Other fields
(such as flags) can be provided via designated initializers.
The advantage of this is that we don't need tons of nested vararg
macros. We also don't need to deal with 0-sized varargs being a pain
(and in fact they are not a thing in standard C99 and probably C11).
There is no need to provide a mandatory flags argument either, which is
the reason why so many OPT_ macros are used with a "0" argument. (The
flag argument seems to confuse other developers; they either don't
immediately recognize what it is, and sometimes it's supposed to be the
option's default value.)
Not having to mess with the flag argument in such option macros is also
a reason for the removal of M_OPT_RANGE etc., for the better or worse.
The only place that special-cased the _flag option type was in
command.c; change it to use something effectively very similar that
automatically includes the new _bool option type. Everything else should
be transparent to the change. The fullscreen option change should be
transparent too, as C99 bool is basically an integer type that is
clamped to 0/1 (except in Swift, Swift sucks).
Commits ba70b150fb and 8a4f812b76 should have mentioned this. These
things should be quite useful for client API users, and thus should be
mentioned in a prominent place.
Although I'm not sure if anyone will understand from this gibberish what
this really means.
Commit 8d965a1bfb changed option/property min/max handling. As a
consequence, ranges that contain only 1 or 0 elements are not possible
anymore. Normally that's fine, because it makes no sense to have an
option that has only one or none allowed value (statically).
But edition switching used some sort of mechanism where the property can
return a different, dynamically decided range at runtime. That meant
that if there were <2 editions, edition switching with the "cycle"
command would always pick the same value. But with the recent commit,
this changed to having "no range set" and would cycle through all
integer values.
Work this around with a simple change. Now, edition switching on a file
without editions shows "edition: auto" instead of "edition: 0", which
may appear odd. But the former is the --edition default value, and
previous mpv versions rendered the edition property like this when not
using switching.
(Who the fuck uses editions?)
Before this commit, option declarations used M_OPT_MIN/M_OPT_MAX (and
some other identifiers based on these) to signal whether an option had
min/max values. Remove these flags, and make it use a range implicitly
on the condition if min<max is true.
This requires care in all cases when only M_OPT_MIN or M_OPT_MAX were
set (instead of both). Generally, the commit replaces all these
instances with using DBL_MAX/DBL_MIN for the "unset" part of the range.
This also happens to fix some cases where you could pass over-large
values to integer options, which were silently truncated, but now cause
an error.
This commit has some higher potential for regressions.
Try to remove m_config implementation details from m_config_frontend.
Not sure if I like it. Seems to be ~100 lines of awkward code more, and
not much is gained from it. Also it took way too long to do it, and
there might be bugs.
Move the "old" mostly command line parsing and option management related
code to m_config_frontend.c/h. Move the the code that enables other part
of the player to access options to m_config_core.c/h. "frontend" is out
of lack of creativity for a better name.
Unfortunately, the separation isn't quite clean yet. m_config_frontend.c
still references some m_config_core.c implementation details, and
m_config_new() is even left in m_config_core.c for now. There some odd
functions that should be removed as well (marked as "Bad functions").
Fixing these things requires more changes and will be done separately.
struct m_config is left with the current name to reduce diff noise.
Also, since there are a _lot_ source files that include m_config.h, add
a replacement m_config.h that "redirects" to m_config_core.h.
This was mostly unused, and has certain problems. Just get rid of it.
It was still used in CDDA (--cdda-span) and a debug option for OpenGL
(--opengl-check-pattern). Replace both of these with 2 options, where
each sets the start/end values of the former span. Both were
undocumented somehow (normally we require all options to be documented),
so I'm not caring about compatibility, and not bothering to add it to
the API changelog.
The emulation is pretty bad, and C11 compilers are everywhere now. It's
time to retire the emulation, which was always meant as temporary hack
for transition.
In theory, a user can still use --disable-stdatomic to enable the
emulation code, but that's sort of hidden. Actual support will be
removed after the next release or so.
We have this cap now thanks to e2976e662, but we don't actually make
sure our FBOs are storable before we blindly attempt using them with
compute shaders.
There's no more need to unconditionally set `storage_dst = true` as long
as we make sure to include an extra condition on the `fbo_format`
selection to prevent users from accidentally enabling
compute-shader-only features with non-storable FBOs, alongside some
other miscellaneous adjustments to eliminate instances of "assumed
storability" from vo_gpu.
This simply makes the "is the destination FBO format bad?" check a tiny
bit less awful, by making sure we prefer storable FBO formats over
non-storable FBO formats. I'd love to make this also conditional on
whether or not we actually *need* a storable FBO format, but that logic
is decided later, in `pass_draw_to_screen`, and I don't want to
replicate the logic.
Fixes#7017.
Previously if the --fs-screen option was set, it would only use the
screen if mpv was launched with --fs and only on startup. During
runtime, the toggle would ignore it. Rework the logic here so that mpv's
fullscreen always uses --fs-screen if it is set. Additionally, cleanup
some unneeded cruft in vo_wayland_reconfig and make find_output more
useful.
Really minor detail that doesn't really matter. If frame stepping pauses
playback on end (why does this special case even exist), it should
probably be done after on_unload, because all works is supposed to be
finished at that point.
This was not reset in the num_properties==0 case. This didn't really
matter, but for debugging it's slightly nicer to see new_property_events
reset once the client thread is done with it.
Change to it 1000 hours, which is "infinite" enough. (Hesitant to use
INFINITY, as that is not in the option's range. The option parser
rejects it because it causes only problems in API users and so on.)
Until now the 'update' method used mp.command_native with a hardcoded
list of key names.
Change it to use whatever keys the user set to this object, so that
we can remain oblivious to new keys which 'osd-overlay' may support.
This is how the lua code did it from the begining. We didn't, and now
we pay the price.
Note: could be implemented either as we have now (clone `this`
excluding the methods) or by moving the methods up the prototype chain
(i.e. class methods) so they don't get enumerated and use `this` as
the command object itself.
However, in the latter approach we'll have to save the values which we
change (name, res_x, res_y) and restore them after the command, so it's
simpler to just clone `this`.
When the current file changes (or rather, when starting/finishing
playback of a playlist entry), clients tend to have the problem that
it's hard to tell whether a property change notification (via
mpv_observe_property() and mechanisms layered on top of it) is from the
previous or new playlist entry. The previous commit probably helps, but
all the asynchronity is still a bit unhelpful.
Try to make this better by adding new hooks, that are run before/after
playback init/deinit. This is similar to the existing hooks, except
they're outside of "initialized" playback, which excludes that you might
accidentally get an overlap between the current and the previous/next
playlist entry.
That still doesn't seem quite enough, since normally, property change
notifications come after the hook event. So basically a client would
have to explicitly "drain" the event queue within the hook, and make the
hook continue only after that is done. Knowing when property
notifications are done is another asynchronous nightmare (how exactly it
works keeps changing within client.c, and an API user probably can't
tell anymore when all pending properties are truly done). So introduce
another guarantee: properties that were changed before the hook happens
will be returned before the hook event is returned. That means the
client will have received all pending property notifications from the
previous playlist entry (or whatever) before the hook is entered.
As another minor complication, we shouldn't just keep the hook pending
until _all_ property notifications are done, since the client's hook
could produce new ones. (Or just consider things like the demuxer thread
hammering the client with cache update events, while the "on_preloaded"
hook is run.) So there is some extra untested, fragile logic in client.c
to handle this (the waiting_for_hook flag).
This probably works, but was barely tested. Not sure if this helps
anyone, but I think it's fine for my own purposes. (I really hated this
aspect of the API whenever I used it myself.)
This could happen if a property was flagged as changed, then updated,
then flagged again, but gen_property_change_event() was called before
the value was updated a second time. Then the function simply returned
the old value, and would later trigger a new change event again.
This was considered acceptable before, since property notifications are
asynchronous anyway (so they may always be "outdated", it just mattered
whether the most recent value was eventually delivered).
But consider ordering with events. It seems desirable that specific
important events (e.g. MPV_EVENT_START_FILE) should not be followed by
property updates that happened before it, because that would make
application logic really a mess, and property notification near-useless
in certain cases.
Avoid this by never returning a value if it was marked changed, but not
updated yet.
Unfortunately, this could lead to clients never receiving a value (or
receiving it with a high random delay), if they're too slow to read it
(or the property simply updates too often). Note that this is done for
_all_ property notifications, not just returned events. Hopefully not a
problem in practice. If it turns out to be one, this mechanism could be
restricted to actually returned events, for which this really matters.
No replacement. Qt or C++ code has no business in this repository, and
new code (even if it uses Qt) should not use it. Get rid of it.
We consider the libmpv API itself as stable. Symbols can be deprecated,
but not be removed. However, qthelper.hpp was never considered part of
the libmpv API. There no ABI implications either, since it's a header-
only implementation that uses C API symbols only. It's just a header
provided for convenience for Qt/C++ programs (i.e. extremely limited
usefulness).
This is more or less a minimal hack to make _some_ text measurement
functionality available to scripts. Since libass does not support such a
thing, this simply uses the bounding box of the rendered text.
This is far from ideal. Problems include:
- using a bitmap bounding box
- additional memory waste and/or flushing caches
- dependency on window size
- odd small deviations with different window sizes (run osd-test.lua and
resize the window after each timer update; the bounding boxes aren't
adjusted in an overly useful way)
- inability to query the size _after_ actual rendering
But I guess it's a start. Since I'm aware that it's crap, add a threat
to the manpage that this may be changed/removed again. For now, I'm
interested whether anyone will have use for it in its current form, as
it's an often requested feature.
When the demuxer cache read until the end of the stream, and was
finished and completely inactive, the cache properties were not updated
anymore via MP_EVENT_CACHE_UPDATE.
Unfortunately, many cache properties depend on the current playback
position, such as cache-duration or fw-bytes. This is especially visible
on the OSC. If everything was cached, seeking around didn't update the
displayed forward cache duration.
That means checking demuxer_reader_state.idle is not enough. You also
need to check whether the current playback position changed.
Fix this by explicitly using the current playback position, and update
the properties if it changed "enough". "Enough" is 1 second of media
time in this example, which may or may not be appropriate.
In general, this could probably be done better. There are many other
triggers that change the cache state and that are not covered. For now
I'm content with getting rid of the obvious problems.
I think the OSC problem in particular was caused by changing it from
polling to using property change notifications.
Apparently this bit-rotted a lot, and now causes more problems that it
helps. In particular picking up broadcom EGL instead of Mesa EGL will
break things. With RPI getting proper Mesa/DRM/V4L support, this problem
should solve itself as well.
Some filters may block the playloop for a longer time. For example, if a
decoder fails to decode anything and somehow just discards packets, the
filter graph would run (in a blocking manner) until all packets are
read, which could take a longer time if the demuxer thread is fast
enough.
Make it exit every 100ms. That should at least give the user a chance to
stop playback.
Filtering could run on a different thread, but I don't see much value in
doing that in the general case. It would just waste a thread. Although
being able to use mp_filter_graph_interrupt() would be slightly nicer
than such a timeout mechanism. Decoding in particular can actually use a
separate thread (--vd-queue-enable), but again, this is not enabled by
default, because it just wastes a thread.
Like the previous f_decoder_wrapper commit, this is probably a sin.
The mp_filter_run() invocation blocks as long as the demuxer provides
packets and the queue can be filled. That means it may block quite a
long time of the decoder queue size is large (since we use libavcodec in
a blocking manner; it regrettably does not have an async. API).
This made the main thread freeze in certain situations, because it has
to wait on the decoder thread.
Other than I suspected (I wrote that code, but that doesn't mean I know
how the hell it works), this did not freeze during seeking: seek resets
flushed the queue, which also prevented the decoder thread from adding
more frames to it, thus stopping decoding and responding to the main
thread in time. But it does fix the issue that exiting the player waited
for the decoder to finish filling the queue when stopping playback.
(This happened because it called mp_decoder_wrapper_set_play_dir()
before any resets. Related to the somewhat messy way play_dir is
generally set. But it affects all "synchronous" decoder wrapper API
calls.)
This uses pretty weird mechanisms in filter.h and dispatch.h. The
resulting durr hurr interactions are probably hard to follow, and this
whole thing is a sin. On the other hand, this is a _very_ user visible
issue, and I'm happy that it can be fixed in such an unintrusive way.
p->log has a prefix set that gives some context and distinguishes audio
and video decoders. The "public" wrapper filter didn't use it, which is
a regression since commit a3823ce0e0.
Filtering is integrated into an event loop, which is something the
filter API user provides. To make interacting with the event loop
easier, and in particular to avoid filtering to block event handling,
add functions the event loop code can suspend filtering.
While we cannot actually suspend a single filter, it's pretty easy to
suspend the filter graph run loop itself, which is responsible for
selecting which filter to run next.
This commit shouldn't change behavior at all, but the functions will be
used in later commits.
This was forgotten.
Hardware decoding typically breaks immediately, because many hw decoding
APIs require allocating all surfaces in advance (and/or libavcodec was
not made flexible enough to add new surfaces later). If the queue is
large enough, it will run out of surfaces, fail decoding, and fall back
to software decoding. We consider this the user's fault.
--hwdec-extra-frames can be used to avoid this, if you have enough GPU
memory, and the needed number of frames is lower than the arbitrary
mpv-set maximum limit of that option.
I don't know what should happen when the same value is written to the
property. It seems that it would be more natural if it were ignored
(since that's also what is done with options now), but you could argue
the other way around as well. In any case, changing it silently could
leads to user scripts etc. breaking, so don't change it now.
Instead, add blabla to the manpage to put the responsibility on the
user, so when we suddenly change it one day, we can blame any breakages
on someone else.
See: #7501
This required libsmbclient, which is a heavy dependency, and as a
library, has all kinds of problems. For one, the API requires completely
unacceptable global state (in particular, leaks auth state), and is not
thread-safe (meaning concurrent reads to multiple files block each
other).
There are better replacements: you can use the Linux kernel's builtin
CIFS support, fusesmb, or contribute supoport for libdsm.
This commit fixes a bug where handle for a framebuffer gets double
freed.
It seems to happen that the same prime fd gets two framebuffers.
As the prime fd is the same the resulting prime handle is also the
same.
This means one handle but 2 framebuffers and can lead to the following
chain:
1. The first framebuffer gets deleted the handle gets also freed via
the ioctl.
2. In startup phase not all 4 dumb buffers for overlay drawing
are set up. It can happen that the last dumb buffer gets the
handle we freed above.
3. The second framebuffer gets freed and the handle will be
freed again resulting that the 4's dumb buffer handle is not
backed by a buffer.
4. Drm prime continues to assign handles to its prime fds an
will lead to have this handle which was just freed to
reassign again but to an prime buffer.
5.Now the overlay should be drawn into dumb buffer 4 which
still has the same handle but is backed by the wrong buffer.
This leads to two different behaviors:
- MPV crashes as the drm prime buffers size als calculated
by the decoder output format. The overlay output format
differs and it takes more space. SO the size check
in kernel fails.
- MPV is continuing play. This happens when the decoders
allocates a bigger buffer than needed for the overlay.
For example overlay is Full HD and decoder output is 4k.
This leads to the behavior das the overlay wil be drawn
into the wrong buffer as its a drm prime buffer and results
in a flicker every fourth step.
Instead of having f_decoder_wrapper create its own copy of the entire
mpv option tree, create a struct local to that file and move all used
options to there.
movie_aspect is used by the "video-aspect" deprecated property code. I
think it's probably better not to remove the property yet, but
fortunately it's easy to work around without needing special handling
for this option or so.
correct_pts is used to prevent use of hr-seek in playloop.c. Ignore
that, if you use --no-correct-pts you're asking for trouble anyway. This
is the only behavior change.
The demuxer cache employs a strange method to make track switching
instant with caching enabled. Normally this would mean you have to wait
until the cache has played out (and you get new packets, including
packets from the newly selected track), or you have to perform a slow
high level seek (decoding video again etc.). The strange method is that
it performs a demuxer-level seek without a high level seek so it looks
like a continuous stream to the decoder, and the newly select stream
gets packets at the current playback position. This is called a refresh
seek.
This works only if some weird heuristics work. It needs a packet "unique
ID", for which it uses either dts or pts. The value must be strictly
monotonic increasing. If this doesn't work, the referesh seek can't be
executed, and the user has to wait until the end of the cache. Sometimes
there are files that simply do not work.
In the present case, there's actually a hack that we can extend. Packets
with unset position are likely generated by the parser, and the hack
which this commit touches simply attempts to make up a new (hopefully
unique) position value, even if the value itself makes no sense. It only
ha to be deterministic.
It turns out libavcodec sometimes output packets with repeating position
values. This commit tries to handle this case too with the same hack.
Fixes: #7498
Let's see how much everyone hates this. Leaving it enabled seems
problematic, because libavcodec returns an unspecific error if it
doesn't like it.
Fixes: #6300
See manpage additions. This has been a topic in MPlayer/mplayer2/mpv
since forever. But since libavcodec multi-threaded decoding was added,
I've always considered this pointless. libavcodec requires you to
"preload" it with packets, and then you can pretty much avoid blocking
on it, if decoding is fast enough.
But in some cases, a decoupled decoder thread _might_ help. Users have
for example come up with cases where decoding video in a separate
process and piping it as raw video to mpv helped. (Or my memory is
false, and it was about vapoursynth filtering, who knows.) So let's just
see whether this helps with anything.
Note that this would have been _much_ easier if libavcodec had an
asynchronous (or rather, non-blocking) API. It could probably have
easily gained that with a small change to its multi-threading code and a
small extension to its API, but I guess not.
Unfortunately, this uglifies f_decoder_wrapper quite a lot. Part of this
is due to annoying corner cases like legacy frame dropping and hardware
decoder state. These could probably be prettified later on.
There is also a change in playloop.c: this is because there is a need to
coordinate playback resets between demuxer thread, decoder thread, and
playback logic. I think this SEEK_BLOCK idea worked out reasonably well.
There are still a number of problems. For example, if the demuxer cache
is full, the decoder thread will simply block hard until the output
queue is full, which interferes with seeking. Could also be improved
later. Hardware decoding will probably die in a fire, because it will
run out of surfaces quickly. We could reduce the queue to size 1...
maybe later. We could update the queue options at runtime easily, but
currently I'm not going to bother.
I could only have put the lavc wrapper itself on a separate thread. But
there is some annoying interaction with EDL and backward playback shit,
and also you would have had to loop demuxer packets through the
playloop, so this sounded less annoying.
The food my mother made for us today was delicious.
Because audio uses the same code, also for audio (even if completely
pointless).
Fixes: #6926
This is supposed to enable communication between filter graphs on
separate threads. Having multiple threads makes only sense if they can
run concurrently with each other, which requires such an asynchronous
queue as a building block. (Probably.)
The basic idea is that you have two independent filters, which can be
each part of separate filter graphs, but which communicate into one
direction with an explicit queue. This is rather similar to unix pipes.
Just like unix pipes, the queue is limited in size, so that still some
data flow control enforced, and runaway memory usage is avoided.
This implementation is pretty dumb. In theory, you could avoid avoid
waking up the filter graphs in quite a lot of situations. For example,
you don't need to wake up the consumer filter if there are already
frames queued. Also, you could add "watermarks" that set a threshold at
which producer or consumer should be woken up to produce/consume more
frames (this would generally serve to "batch" multiple frames at once,
instead of performing high-frequency wakeups). But this is hard, so the
code is dumb. (I just deleted all related code when I still got
situations where wakeups were lost.)
This is actually salvaged and modified from a much older branch I had
lying around. It will be used in the next commit.
Instead of vague ideas about making different filter graphs on different
threads interact directly, this have no direct support. Instead, helpers
are required (such as added with the next commit).
Document it. Different root filters (i.e. separate filter graphs) are
now considered to be part of separate threads, so assert() if they're
found to accidentally interact.
Previously: 5.1 > 5.2 > luajit
Now: 5.2 > luajit > 5.1
I randomly decided that this should be done, since I suspect most
environments will prefer the highest Lua version anyway. There is not
much of a point picking the older one by default.
Maybe 5.1 should be dropped fully, but considering we need to stay
compatible with luajit, there is no particular incentive for this.
Preparation for a future commit. The demuxer queues might be read from
other threads than the one to issue the seek, and passing SEEK_BLOCK
with such a seek will provide a convenient way to synchronize this.
mp_filter_mark_async_progress() can asynchronously mark a filter for
processing, without waking up the filter thread. (It's some sort of
idiotic micro-optimization I guess?) But since it sets async_pending
without doing the wakeup, a mp_filter_wakeup() after this will do
nothing, and the wakeup is lost. Fix it by checking for the needed
wakeup separately.
Fortunately, nothing used this function yet, so there is no impact.
I may (optionally) move decoding to a separate thread in a future
change. It's a bit attractive to move the entire decoder wrapper to
there, so if the demuxer has a new packet, it doesn't have to wake up
the main thread, and can directly wake up the decoder. (Although that's
bullshit, since there's a queue in between, and libavcodec's
multi-threaded decoding plays cross-threads ping pong with packets
anyway. On the other hand, the main thread would still have to shuffle
the packets around, so whatever, just seems like better design.)
As preparation, there shouldn't be any mutable state exposed by the
wrapper. But there's still a large number of corner-caseish crap, so
just use setters/getters for them. This recorder thing will inherently
not work, so it'll have to be disabled if threads are used.
This is a bit painful, but probably still the right thing. Like
speculatively pulling teeth.
This explicitly depends on the pixfmt list from FFmpeg (done so to
easily spot regression, incompatible changes, and other unexpected
things).
Some local changes in mpv change some of the output. For pal8 an alias
was added back, and the [GENERIC] markers are removed because the mpv
aliases are not dependent on the mpv config anymore (which was
unnecessary).
The other changes are due to ffmpeg adding some new formats.
This was a hack that attempted to line up external audio tracks with
video. The problem is that if you do a keyframe seek backwards, video
will usually seek much farther back than audio (due to much higher
keyframe aka seek point distances). The hack somehow made seeking a 2
step process.
This existed in 4 different forms in the history of this code base, and
it was always very cumbersome. We mostly needed this for ytdl_hook (I
think?), which uses the 4th form, which is nicely confined to
demux_timeline and is unrelated to the "external" audio tracks in the
high level player.
Since this is (probably) not really widely needed anymore, get rid of
it. Better do this now, than when somehow rewriting all the seeking code
(which might happen in this decade or the next or so) and when it
wouldn't be easily revertable anymore in case we find we "really" need
it unlike expected.
There is no issue if hr-seeks are used. Also, you can still use edl
files to "bundle" multiple streams as if it was a single stream (this is
what ytdl_hook does now).
It seems sporadic errors are possible, such as connection timeouts.
Before the recent demuxer change, the demuxer thread retried many times
even on EOF, so an error was only interpreted as EOF once the decoder
queues ran out.
Change it to use EOF only. Since this may actually lead to the demuxer
thread being "stuck" and retrying forever (depending on libavformat API
behavior), I'm also adding a heuristic to prevent this, using a random
retry counter. This should not be necessary, but libavformat cannot be
trusted. (This retrying forever could be stopped by the user, but
obviously it would still heat the CPU for a longer time if the user is
not present.)
The "seekbarkeyframes" option is now interpreted such if it's true, the
player default is used. Too lazy to make this a choice option or
whatever; the Lua option parser doesn't have support for that anyway.
Someone who cares can adjust this.
Try to deal with various corner cases. But when I fix one thing, another
thing breaks. (And it's 50/50 whether I find the breakage immediately or
a few months later.) So results may vary.
The default for--hr-seek is changed to "default" (not creative enough to
find a better name). In this mode, audio seeking is exact if there is no
video, or if the video has only a single frame. This change is actually
pretty dumb, since audio frames are usually small enough that exact
seeking does not really add much. But it gets rid of some weird special
cases.
Internally, the most important change is that is_coverart and is_sparse
handling is merged. is_sparse was originally just a special case for
weird .ts streams that have the corresponding low-level flag set. The
idea is that they're pretty similar anyway, so this would reduce the
number of corner cases. But I'm not sure if this doesn't break the
original intended use case for it (I don't have a sample anyway).
This changes last-frame handling, and respects the duration of the last
frame only if audio is disabled. This is mostly "coincidental" due to
the need to make seeking past EOF trigger player exit, and is caused by
setting STATUS_EOF early. On the other hand, this might have been this
way before (see removed chunk close to it).
This tries to fix#7206 (hr-seeking past EOF does not stop playback)
again. Commit 57fbc9cd76 should have fixed this, but trying it again
(using that git revision), it often did not work. Whatever the fuck.
So add another dumb special case that will break within weeks. Note that
the check in handle_eof() had no effect, since execute_queued_seek() is
called later, which cancels EOF in the same case.
Hr-seek past the last frame instantly enters EOF, which means
handle_playback_time() will not set playback_pts to the video PTS (as
all video frames are skipped), which leads to the playback time being
taken from the last seek target. This results in confusing behavior,
especially since the seek time will be clipped to the file duration for
display, but not for further relative seeks.
Obviously, the time should be set to the last video frame, so use the
last video frame as fallback if both audio and video have ended. Also,
since the same problem exists with audio-only playback, add a fallback
for audio PTS too. We don't know which was the "last" fragment of media
played (to decide whether to use the audio or video PTS as the
fallback), but it doesn't matter since the maximum works.
This could lead to some undesired effects. In particular the audio PTS
is basically a bad guess, and is for example not clipped against --end.
(But the ridiculous way audio syncing and clamping currently works, I'm
not going to touch that shit unless I rewrite it completely.) The cover
art case is slightly broken: using --keep-open with keyframe seeks will
result in 0 as playback PTS (the video PTS). OK, who cares, it got late.
Also casually get rid of last_vo_pts, since that barely made any sense
at all.
Fixes: #7487
The seeking logic saves the last video frame it has seen (for example
for being able to seek to the last frame, or backstepping).
Unfortunately, the frame was fed back to the filtering pipeline in
situations when it shouldn't have. Then it's an out of order frame,
because it really saves the last _discarded_ frame.
For example, seeking to the end of a file with --keep-open, shift+up,
shift+down => invalid video pts warning due to saved_frame being fed
back.
Explicitly discard saved_frame when it's obviously not needed anymore.
The removed accesses to "r" are strictly speaking unrelated (just
const-propagating them).
In this case the video track has seek_start == seek_end, and due to the
"seek_start >= seek_end" condition, this was considered broken, and no
seek range was created, breaking cached seeking.
Fix this by allowing the case if they're equal, and a valid timestamp.
(NB: seeking backward in this will still jump to position 0, because it
is the video timestamp. This is unfortunately how it's supposed to work.
HR-seeks will also do this, but decode and skip the entire audio until
the seek target, so it will mostly appear to work.)
Exposed by commit b56e2efd5f. demux_timeline reported a bogus EOF if
"parallel" streams were used. If a virtual source reported EOF, it was
propagated as global EOF, without serving packets of other virtual
sources that have not ended yet.
Fix this by not reporting global EOF just because a source has not
returned a packet. Instead make the reader retry by returning no packet
and no EOF state, which will call d_read_packet() again with a different
source. Rely on the eof_reached flags to signal global EOF.
Since eof_reached is now more important, set it in a certain other case
when it apparently should have been set. do_read_next_packet()'s return
value is now ignored, so get rid of it.
This is useful with live streams, and it's not much worse than the h264
first packet hack, which reads some data anyway.
For some reason, the option wasn't even documented, so do that.
In addition, print the start time even if it's negative. That should not
be possible, but for some reason, the field is an int64_t copied from an
uint64_t so... whatever. Keeping the logging slightly more straight
forward is better anyway.
Remove some redundant fields that controlled or indicated whether the
demuxer was/could/should prefetch. Redefine how the eof/reading fields
work.
The in->eof field is now always valid, instead of weirdly being reset to
false in random situations. The in->reading field now corresponds to
whether the demuxer thread is working at all, and is reset if it stops
doing anything.
Also, I always found it stupid that dequeue_packet() forced the demuxer
thread to retry reading if it was EOF. This makes little sense, but was
probably added for files that are being appended to (running downloads).
It makes no sense, because if the cache really tried to read until file
EOF, it would encounter partial packets and throw errors, so all is lost
anyway. Plus stream_file now handles this better. So stop this behavior,
but add a temporary option that enables the old behavior.
I think checking for ds->eager when enabling prefetching never really
made sense (could be debated, but no, not really). On the other hand,
the change above exposed a missing wakeup in the backward demuxing code.
Some chances of regressions that could make it stuck in certain states
or so, or incorrect demuxer cache state reporting to the player
frontend.
Setting demux_set_stream_wakeup_cb() will make all sh_stream (i.e.
track) specific wakeups go to this callback. But the callback takes care
of only the sub_preload() case (where it tries to pre-load subtitles
from already parsed and memory-present subtitles in a blocking way).
The old code assumed that the normal demuxer wakeup callback is called.
This was disregarded when the newer code was added. (And actually, the
original plan was to make _all_ per-sh_stream wakeups go to specialized
callbacks to avoid wasted work. dec_sub really should set the callback
always, and propagate wakeups to the playloop code. But it's too far
into the night to write coherent code.)
I couldn't actually observe any manifestation of this bug. Normally, the
playloop wakes up for other reasons (such as driving audio and video
decoding), so the lost wakeups rarely matter.
A negative subtitle delay means that subtitles from the future should be
shown earlier. With muxed subtitles, subtitle packets are demuxed along
with audio and video packets. But since they are demuxed "lazily",
nothing guarantees that subtitle packets from the future are available
in time.
Typically, the user-observed effect is that subtitles do not appear at
all (or too late) with large negative --sub-delay values, but that using
--cache might fix this.
Make this behave better. Automatically extend read-ahead to as much as
needed by the subtitles. It seems it's the easiest to pass the subtitle
render timestamp to the demuxer in order to guarantee that everything is
read. This timestamp based approach might be fragile, so disable it if
no negative sub-delay is used.
As far as the player frontend part is concerned, this makes use of the
code path for external subtitles, which are not lazily demuxed, and may
already trigger waiting.
Fixes: #7484
Subtitle tracks are usually "lazy" (ds->eager=false), There are a number
of weird special cases associated with it. One of them is that they have
some sort of "temporary" EOF (to signal that there isn't a packet right
now, and the decoder should not block playback by waiting for more
packets). In a the next commit, I want to call mark_stream_eof() in case
of (some) of these temporary EOFs.
The problem is that mark_stream_eof() also calls the functions touched
by this commit. Basically they shouldn't do any complex work due to
these temporary EOFs (because they might happen very often). It turns
out that lazy tracks barely matter here: they do not extend the seek
range of a packet/EOF happens on them, they do not trigger seek range
joining, and they do not support backward demuxing.
This change should enable the following commit, while not causing any
behavior changes (i.e. bugs) with the current state.
args->client was deallocated if the FDs were closed and nothing
referenced it (IPC socket codes detected the closed sockets and
asynchronously killed the mpv_handle in args->client). The problem was
that args->log depended on it, and was also destroyed.
Fix this by duplicating the mp_log.
This has been part of the libmpv for a while, so the implementation in
the IPC code is quite simple: just pass the mpv_node representing the
value of the "command" field without further checks to
mpv_command_node().
The only problem are the IPC-specific commands, which essentially have
their own dispatch mechanism. They expect an array. I'm not going to
rewrite the dispatch mechanism, so these still work only with an array.
I decided make the other case explicit with cmd==NULL. (I could also
have set cmd=="", which would have avoided changing each if condition
since "" matches no existing command, but that felt dirty.)
I decided to make this explicit. The alternative would have been making
all commands asynchronous always, like a small note in the manpage
threatened. I think that could have caused compatibility issues.
As a design decision, this does not send a reply if an async command
started. This could be a good or bad idea, but in any case, it will make
async command look almost like synchronous ones, except they don't block
the IPC protocol.
The relatively recently added property update code has a race condition
when clients exit. It still tried to access mpv_handle during and after
it was destroyed.
The reason is that it unlocks the lock for the mpv_handle list (while
mpv_handle is locked), but nothing in mp_destroy_client() cares about
this case. The latter function locks mpv_handle only before/while it
makes sure all of its activity is coming to an end, such as asynchronous
requests, and property updates that are in progress. It did not include
the case when mp_client_send_property_changes() was still calling
send_client_property_changes() with mpv_handle locked.
Fix this by checking the mpv_handle.destroying field. This field can be
set only when mpv_handle is locked. While we're checking the lock, the
mpv_handle list is still locked, so at worst we might be at the point
before mp_destroy_client() locks the list again and finally destroys the
mpv_handle.
This is a hard to reproduce race condition which I spotted only once in
valgrind by chance, so the fix is unconfirmed.
The previous change ensured that these cannot fail anymore (much like in
original talloc). Change the APIs to not return a success value anymore,
to "cement" this.
The ta_ext_header was allocated on demand for allocations which have
child-allocations or destructors. In theory, it saved 2 words for every
TA leaf allocation. It had the very API-visible problem that setting a
parent or destructor could fail. (Although in most cases, the failure
was part of an allocation call anyway. Also, mpv code generally used the
early-failure variants, so it didn't matter.)
I think this was a bit too complex. These 2 words don't really matter;
if you have memory allocations where you are worried about overhead,
then these simply shouldn't use TA. Also, we never added new features to
TA that would have needed more "optional" header fields, which would
have justified the use of such a separately allocated header struct.
This uses quite straight-forward data structures. The only strange thing
is that ta_header.parent is NULL for most child allocations. That is
because we don't want to iterate over all children when the parent is
reallocated (yes, that is allowed, yes mpv makes use of it).
The new code has a few more special cases, because the list sentinel
concept isn't used anymore. Using it would have made the code more
unnatural/complex, because ta_ext_header doesn't exist anymore.
the actual character that made mpv crash is IDEOGRAPHIC COMMA
(U+3001, UTF-8: E3 80 81, 、) and that only in some specific
circumstances that could be reliably reproduced on my end.
using an NSString instead of the Swift String actually fixes that issues
even though they should technically do the exact same thing. i tested
all the other String initialisers, but they all had had the same issue.
this is kinda only a workaround till i can find a different way of
handling it.
this basically moves the remote command center to our mac events instead
of keeping it our Application, which is only available when started from
mpv itself. also make it independent of the NSApplication.
this also prevents a runtime crash
This was changed 6 years ago (444e583b6) and seemed to work fine. But it
does seem to cause issues with IceWM sometimes, while with StaticGravity
the problem is gone. Comparing both gravity values, reading the confused
source code comment, and reading the referenced commit message, I can't
determine what it even does, I just remove it.
Reproduction:
- start mpv in windowed mode, with 2 videos of different size
- switch to second video
- switch window with alt+tab
- switch back to mpv with alt+tab
- window moves to X=0
There's probably a better way to fix this. Please send a patch.
This was obviously nonsense. In Lua 5.1 this appeared to work correctly,
but it really turned "\." into "." (making the pattern accept any
character). The proper way is using "%" for escaping.
In all_formats mode, we've ignored what --ytdl-format did so far, since
we've converted the full format list, instead of just the formats
selected by youtube-dl.
But we can easily restore --ytdl-format behavior: just mark the selected
tracks as default tracks.
A parameter that is actually used is removed from the param_names[]
array, so we can report unused parameters. This also happened on
duplicate parameters, so adjust the warning to make it less confusing.
(In any case, you're not supposed to provide duplicate parameters.)
vbr and abr are the video and audio bitrates. Sometimes there is a weird
mix of any of them available, but in these cases, it's not good to fall
back to tbr if a specific track has no vbr/abr.
For example, the alphabetic site provides tbr only for the muxed
fallback stream, but using tbr would make the primitive mpv hls_bitrate
selection pick the compatibility stream for audio, because it appears to
have a higher bitrate than the other audio-only streams (because the
bitrate includes video). So we must not use tbr in this case.
On the other hand, formats coming from youtube-dl HLS master playlist
use will only have tbr set.
So as a heuristic, use the tbr only if it's the only bitrate available
in any track entry.
I don't think the skip_muxed option was overlay useful. While it was
nice to filter out the low quality muxed versions (as it happens on the
alphabetic site, I suspect it's compatibility stuff), it's not really
necessary, and just makes for another tricky and rarely used
configuration option. (This was different before muxed tracks were also
delay-loaded, and including the muxed versions slowed down loading.)
Add the force_all_formats option instead, which handles the HLS case.
Set it to true because they are also delay-loaded now, and don't slow
down startup as much.
Until now, delay-loading was for files with single tracks only
(basically what DASH and HLS like to expose, so adaptive streaming and
codec selection becomes easier - for sites, not for us). But they also
provide some interleaved versions, probably for compatibility. Until
now, we were forced to eagerly load it (making startup slightly slower).
But there is not much missing. We just need a way to provide multiple
metadata entries, and use them to represent each track.
A side effect is now that the "track_meta" header can be used for normal
EDL files too.
RTSP supports seeking, but at least the libavformat implementation makes
this dependent on runtime behavior. So you have to perform a seek, and
check if it fails. But even if you do this, the stream is interrupted
and restarted, and there seem to be other issues.
Assume that RTSP with unknown duration means it's a live stream, and
disable seeking in this case, as suggested by the issue reporter.
Fixes: #7472
Now this was stupid. To seek a source, it obviously has to be opened...
so just don't try to seek any unused source. If the track is actually
selected during playback, a seek to the correct position is performed
anyway.
These have ->segmented set (so the codec can be initialized properly),
but have no segment start or end times. This code was (probably) the
only thing which didn't handle this case.
If all streams were delay loaded, there was actually no duration present
at all in the EDL metadata. So the length was considered unknown by the
player frontend.
See manpage additions. We would have to extend delay_open to support
multiple sub-tracks (for audio and video), and we'd still don't know (?)
whether it might contain more than one stream each (thinking of HLS
master streams). And if it's a true interleaved file (such as a "normal"
mp4 file provided as fallback for more primitive players), we'd either
have to signal such "bundled" tracks, or waste bandwidth.
This restructures a lot. The if/else tree in add_single_video for format
selection was a bit annoying, so it's split into separate if blocks,
where it checks each time whether a URL was determined yet.
If a "format" has both audio and video codec set, it might contain both
audio and video. all_format assumes that each format is just a quality
variant containing a single track.
This seems to happen with sites that provide a HLS master URL.
youtube-dl tends to "butcher" it, and the result isn't very ideal. I
guess HLS "renditions" simply don't map well to youtube-dl's output
format and what mpv expects. Playing master HLS directly is also less
than ideal, because of libavformat's stupid probing.
Fix this by not using the delay-opening mechanism if it appears like we
detected such a case. Add a metadata override to set the track titles to
"muxed-N", to indicate that they form a single unit. (Mostly helpful for
testing.)
ytdl_hook.lua can do this with all_formats and when delay_open is used,
and if the source stream actually contains both audio and video. In this
case, it might accidentally hide a media type completely, or waste
bandwidth (if the stream has true interleaved audio/video). So it's
important to warn.
This is just a more convenient way to start IPC client scripts per mpv
instance.
Does not work on Windows, although it could if the subprocess and IPC
parts are implemented (and I guess .exe/.bat suffixes are required).
Also untested whether it builds on Windows. A lot of other things are
untested too, so don't complain.
Pretty worthless I guess. I only tested one site (and 2 videos), it's
somewhat likely that it will break with other sites. Even if you leave
the option disabled (the default).
Slightly related to #3548. This will allows you to use the bitrate
stream selection mechanism, that was added for HLS, with normal videos.
While paused, the decoders typically stop reading data from the demuxer.
But for some reason, the file size is returned as a public field in
struct demuxer (wat...), and updated only when the packet reading
function is called. This caused the file size property to always return
the same value when paused, even though the demuxer thread was reading
new data, and the internal file size was updated.
Fix with a simple hack.
Instead of every packet. Doing it every packet led to the performance
regression mentioned in the fstat() commit. This should now be over, but
out of being careful, don't query the file size that often. This is only
used for user interface things, so this should not cause any problems.
For the sake of leaving the code compact, abuse another thing that is
updated only every second (speed statistics).
It appears using lseek() to seek to the end and back to determine file
size is inefficient in some cases.
With CIFS, this restores the performance regression that happened when
the stream cache was removed (which called read() from a thread). This
is probably faster than the old code too, because it's the seeking that
was slowing down CIFS.
According to the user who tested this, the size caching does not help
with fstat() (although it did with the old method).
Fixes: #7408, #7152
The previous method for this sucked: for every launched detached
process, it started a thread, which then would leak if the launched
process didn't end before the player uninitialized. This was very racy
(although I bet the race condition wouldn't trigger in a 100 years), and
wasteful (threads aren't a cheap resource).
Implement it for POSIX directly. posix_spawn() has no direct support for
this, so we need to do it ourselves with fork(). We could probably do it
without fork(), and attempt to collect the PID in another thread. But
then we'd either have a waiting thread again, or we'd need to do an
unsafe waitpid(-1, ...) call. (POSIX process management sucks so badly,
how did they even manage this. Hopefully I'm just missing something, but
I'm not.) So now we depend on both posix_spawn() _and_ fork(), isn't it
fun?
Also call setsid(), to essentially detach the child process from the
terminal. (Otherwise it can receive various signals from the terminal,
which is probably not what you want.) posix_spawn() adds
POSIX_SPAWN_SETSID in newer POSIX releases, but we don't want to rely on
this yet.
The posix_spawnp() call is duplicated, but this is better than somehow
trying to unify the code paths.
Only somewhat tested, so enjoy the bugs.
Introduce mp_subprocess() and related definitions. This is a bit more
flexible than the old stuff. This may or may not be used for a more
complicated feature that involves starting processes, and which would
require more control.
Only port subprocess-posix.c to this API. The player still uses the
"old" API, so for win32 and dummy implementations, the new API is simply
not available, while for POSIX, the old APIs are emulated on top of the
new one. I'm hoping the win32 code can be ported as well, so the ifdefs
in subprocess.c can be dropped, and the player can (if convenient or
needed) use the new API.
Filters that fail to create are not supposed to do this. Generally it
should happen in process() only.
This fixes the previous commit. If a filter could not be created, it
"trashed" the wrapper filter with the failure. (Even if the wrapper were
to handle were to handle failures of sub-filter, it couldn't handle init
failure because it cannot call mp_filter_set_error_handler() before the
newly created filter is actually returned.)
Fixes: #7465 (attempt 2)
If hw decoding is used, but no hw deinterlacer is available, even though
we expect that it is present, fall back to using hw-download and yadif
anyway. Until now, it was over if the hw filter was somehow missing; for
example, yadif_cuda apparently requires a full Cuda SDK, so it can be
missing, even if nvdec is available. (Whether this particular case works
was not tested with this commit.)
Fixes: #7465
Libav seems rather dead: no release for 2 years, no new git commits in
master for almost a year (with one exception ~6 months ago). From what I
can tell, some developers resigned themselves to the horrifying idea to
post patches to ffmpeg-devel instead, while the rest of the developers
went on to greener pastures.
Libav was a better project than FFmpeg. Unfortunately, FFmpeg won,
because it managed to keep the name and website. Libav was pushed more
and more into obscurity: while there was initially a big push for Libav,
FFmpeg just remained "in place" and visible for most people. FFmpeg was
slowly draining all manpower and energy from Libav. A big part of this
was that FFmpeg stole code from Libav (regular merges of the entire
Libav git tree), making it some sort of Frankenstein mirror of Libav,
think decaying zombie with additional legs ("features") nailed to it.
"Stealing" surely is the wrong word; I'm just aping the language that
some of the FFmpeg members used to use. All that is in the past now, I'm
probably the only person left who is annoyed by this, and with this
commit I'm putting this decade long problem finally to an end. I just
thought I'd express my annoyance about this fucking shitshow one last
time.
The most intrusive change in this commit is the resample filter, which
originally used libavresample. Since the FFmpeg developer refused to
enable libavresample by default for drama reasons, and the API was
slightly different, so the filter used some big preprocessor mess to
make it compatible to libswresample. All that falls away now. The
simplification to the build system is also significant.
Works as ad-filter. I had some more plans, for example replacing
matching text with different text, but for now it's dropping matches
only. There's a big warning in the manpage that I might change
semantics. For example, I might turn it into a primitive sed.
In a sane world, you'd probably write a simple script that processes
downloaded subtitles before giving them to mpv, and avoid all this
complexity. But we don't live in a sane world, and the sooner you learn
this, the happier you will be. (But I also want to run this on muxed
subtitles.)
This is pretty straightforward. We use POSIX regexes, which are readily
available without additional pain or dependencies. This also means it's
(apparently) not available on win32 (MinGW). The regex list is because I
hate big monolithic regexes, and this makes it slightly better.
Very superficially tested.
Until now, filter_sdh was simply a function that was called by sd_ass
directly (if enabled).
I want to add another filter, so it's time to turn this into a somewhat
more general subtitle filtering infrastructure.
I pondered whether to reuse the audio/video filtering stuff - but better
not. Also, since subtitles are horrible and tend to refuse proper
abstraction, it's still messed into sd_ass, instead of working on the
dec_sub.c level. Actually mpv used to have subtitle "filters" and even
made subtitle converters part of it, but it was fairly horrible, so
don't do that again.
In addition, make runtime changes possible. Since this was supposed to
be a quick hack, I just decided to put all subtitle filter options into
a separate option group (=> simpler change notification), to manually
push the change through the playloop (like it was sort of before for OSD
options), and to recreate the sub filter chain completely in every
change. Should be good enough.
One strangeness is that due to prefetching and such, most subtitle
packets (or those some time ahead) are actually done filtering when we
change, so the user still needs to manually seek to actually refresh
everything. And since subtitle data is usually cached in ASS_Track (for
other terrible but user-friendly reasons), we also must clear the
subtitle data, but of course only on seek, since otherwise all subtitles
would just disappear. What a fucking mess, but such is life. We could
trigger a "refresh seek" to make this more automatic, but I don't feel
like it currently.
This is slightly inefficient (lots of allocations and copying), but I
decided that it doesn't matter. Could matter slightly for crazy ASS
subtitles that render with thousands of events.
Not very well tested. Still seems to work, but I didn't have many test
cases.
The example configuration uses values of true/false for the script
options. As per DOCS/man/lua.rst boolean values should be represented
with yes/no and using true/false will result in an error.
This updates the comments and changes the true/false values under the
example configuration to yes/no.
This renders incorrectly in the html output. I suspect you need one more
level here. Increase the indentation level. No other changes, other than
re-breaking some lines.
Uses the infrastructure added in the previous commits. This is
admittedly a bit weird (constructing EDL URLs and such). But on the
other hand, adding this as "first class" mechanism directly to the
sub-add command or so would increase weirdness and unexpected behavior
in other places, or at least that's what I think.
To reduce confusion, this goes through the effort of mapping the webvtt
codec, so it's shown "properly" in the codec list. Without this it would
show "null", but still work. In particular, any non-webvtt codecs should
still work if libavcodec supports it.
Not sure if I should remove the --all-subs hack from the code. But I
guess it does no harm.
This is for easier use with the "delay_open" feature added in the
previous commit. The "null" codec is reported if the codec is unknown
(because the stream was not opened yet at time the tracks were added).
The rest of the timeline mechanism will set the correct codec at
runtime. But this means every time a delay-loaded track is selected, it
wants to initialize a decoder for the "null" codec.
Accept a "null" decoder. But since FFmpeg has no such codec, and out of
my own laziness, just let it fall back to "common" codecs that need no
other initialization data.
Add something that will access an URL embedded in EDL only when the
track it corresponds to is actually selected. This is meant to help with
ytdl_hook.lua and to improve loading speeds.
In theory, all this stuff is available to any mpv user, but discourage
using it, as it's so specialized towards ytdl_hook.lua, that there's
danger we'll just break this once ytdl_hook.lua stops using it, or
similar.
Mostly untested.
Normally, the first sub-stream is implicitly created. This change lets
the user use more orthogonal syntax, and use a new_stream header for
every sub-stream, instead of having to skip the header for the first
one.
Accidentally broken by commit 99700bc52c. mp_path_join() does not
check for this, because it's supposed to work on filesystem strings (and
e.g. "http://fubar" is a valid relative path in UNIX).
Add a mp_log context to the parse_edl() function, and report some
errors. Previously, this just told you that something was wrong. Add
some error reporting to make it slightly less evil.
Put all parameters in a list before processing them. This makes adding
parameters for special headers easier, and we can report parameters that
were not understood. (For "compatibility", which probably doesn't matter
at all, still don't count them as errors; as before.)
The timeline stuff has messed up memory management because there are no
clear ownership rules between a some demuxer instances (master or
demux_timeline) and the timeline object itself.
This is another subtle problem that happened: apparently,
demux_timeline.open is supposed to take over ownership of timeline, but
only on success. If it fails, it's not supposed to free it. It didn't
follow this, which lead to a double-free if demux_timeline.open failed.
The failure path in demux.c calls both timeline_destroy() and
demux_timeline.close on failure.
Move them around in the source code to get rid of the forward
declarations. Other than rearranging the lines and removing the 2
forward declarations, there are no other changes at all.
stream_seek() might somewhat show up in the profiler, even if it's a
no-OP, because of the MP_TRACE() call. I find this annoying. Otherwise,
this should be of no consequence, and should not break or improve
anything.
Some cache logic in demux.c queries the raw byte stream size on every
packet read. This is because it reports the value to the user. (It has
to be polled like this because there is no change notification in most
underlying I/O APIs, and also the user can't just block on the demuxer
thread to update it explicitly.)
This causes a very high number of get_size calls with low packet sizes,
so cache the size, and update it on every read. Reads only happen
approximately all 64KB read with default settings, which is way less
frequent than every packet in such extreme cases.
In theory, this could in theory cause problems in some cases. Actually
this is whole commit complete non-sense, because why micro-optimize for
broken cases like patent troll codecs. I don't need to justify it
anyway.
As a minor detail, off_t is actually specified as signed, so the off_t
cast is never needed.
Resizing the window while preserving the aspect ratio actually kind of
sucked. The window size could make big dramatic changes which was pretty
unintuitive with respect to where the mouse was actually located.
Instead, let's just do some math to ensure that the window size is
always contained inside the width/height reported by
handle_toplevel_config while preserving the aspect ratio. Fixes#7426.
A previous commit moved the underrun reporting to report_underruns(),
and called it from get_space(). One reason was that I worried about
printing a log message from a "realtime" callback, so I tried to move it
out of the way. (Though there's little justification other than a bad
feeling. While an older version of the pull code tried to avoid any
mutexes at all in the callback to accommodate "requirements" from APIs
like jackaudio, we gave up on that. Nobody has complained yet.)
Simplify this and move underrun reporting back to the callback. But
instead of printing the message from there, move the message into the
playloop. Change the message slightly, because ao->log is inaccessible,
and without the log prefix (e.g. "[ao/alsa]"), some context is missing.
Fixes#7441. Just set screenrc to be equal to current_output's geometry.
Also remove some pointless/extra variables and print a warning/fallback
to screen 0 if a bad id is passed to --fs-screen.
AOs can report audio underruns, but only ao_alsa and ao_sdl (???)
currently do so. If the AO was marked as not reporting it, the cache
state was used to determine whether playback was interrupted due to slow
input.
This caused problems in some cases, such as video with very low video
frame rate: when a new frame is displayed, a new frame has to be
decoded, and since there it's so much further into the file (long frame
durations), the cache gets into an underrun state for a short moment,
even though both audio and video are playing fine. Enlarging the audio
buffer didn't help.
Fix this by making all AOs report underruns. If the AO driver does not
report underruns, fall back to using the buffer state.
pull.c behavior is slightly changed. Pull AOs are normally intended to
be used by pseudo-realtime audio APIs that fetch an audio buffer from
the API user via callback. I think it makes no sense to consider a
buffer underflow not an underrun in any situation, since we return
silence to the reader. (OK, maybe the reader could check the return
value? But let's not go there as long as there's no implementation.)
Remove the flag from ao_sdl.c, since it just worked via the generic
mechanism. Make the redundant underrun message verbose only.
push.c seems to log a redundant underflow message when resuming (because
somehow ao_play_data() is called when there's still no new data in the
buffer). But since ao_alsa does its own underrun reporting, and I only
use ao_alsa, I don't really care.
Also in all my tests, there seemed to be a rather high delay until the
underflow was logged (with audio only). I have no idea why this happened
and didn't try to debug this, but there's probably something wrong
somewhere.
This commit may cause random regressions.
See: #7440
If ao_add_events() is used, but all events flags are already set, then
we don't need to wakeup the core again.
Also, make the underrun message "exact" by avoiding the race condition
mentioned in the comment.
Avoiding redundant wakeups is not really worth the trouble, and it's
actually just a bonus in the change making the ao_underrun_event()
function return whether a new underrun was set, which is needed by the
following commit.
Obviously, we don't want to lose fractions, and the zimg active_region
fields in fact have the type double. The integer division was wrong.
Also, always set active_region.width/height. It appears zimg behavior
does not change if they're set to the normal integer values, so the
extra check to not set them in this case was worthless.
As suggested by the zimg author: active_region is not supported on
outputs (and the API returns an error), so instead scale to the "full"
surface, but adjust the source rectangle such that the cropped output
image happens to cover the correct region.
Does this even work? Since Balmer Peak doesn't work, I can't really say,
but it seems to look correct.
X11 is in fact beautiful and superior to Wayland. Instead, just state
what the problem is in most cases: software scaling. (We have
accelerated X11 rendering in vo_gpu and others.)
This was a confusing name, because 1. there's also a z_planes[] field,
and 2. it was not specific to zimg indexes.
Possibly there used to be an idea involved about supporting alpha to
non-alpha formats by discarding the alpha plane, but zimg does this now
(and zimg will correctly blend the alpha component too).
The special thing about this format is
1. mpv assigns the component ID 4 to alpha, and component IDs 2 and 3
are not present, which causes some messy details.
2. zimg always wants the alpha plane as plane 3, and plane 1 and 2 are
not present, while FFmpeg/mpv put the alpha plane as plane 1.
In theory, 2. could be avoided, since FFmpeg actually doesn't have a any
2 plane formats (alpha is either packed, or plane 3). But having to skip
"empty" planes would break expectations.
zplanes is not equivalent to the mpv plane count (actually it was always
used this way), while zimg does not really have a plane count, but does,
in this case, only use plane 0 and 3, while 2 and 3 are unused and
unset. z_planes[] (not zplanes) is now always valid for all 4 array
entries (because it uses zimg indexes), but a -1 entry means it's an
unused plane.
I wonder if these conventions taken by mpv/zimg are not just causing
extra work. Maybe component IDs should just be indexes by the "natural"
order (e.g. R-G-B-A, Y-U-V-A, Y-A), and alpha should be represented as a
field that specifies the component ID for it, or just strictly assume
that 2/4 component formats always use the last component for alpha.
We reorder the planes between mpv and zimg conventions. It turns out the
code still confused when which convention was used.
So the way it actually works is that the _only_ place where zimg order
is used is the zimg_image_buffer.plane[] array. plane_aligned[] and
zmask[] were accessed incorrectly, although I guess it rarely had a
reason to fail (plane reordering is mostly for RGB, which has planes of
all the same size).
Adjust some comments accordingly too.
The zimg wrapper "needs" these formats as intermediary when repacking
the normal gray/alpha packed format. The packed format is used by the
png decoder and encoder, and is thus interesting.
Unfortunately, mpv-only formats are a mess right now, because all the
existing code is focused around using the FFmpeg metadata for pixel
formats. This should be improved, but not now, so make the mess worse.
This commit doesn't add support for it to the zimg wrapper yet.
libzimg recently added direct alpha support and new API for it. (The API
change is rather minimal, and it turns out we can easily support old and
new zimg versions.)
This does not support _all_ alpha formats. For example, gray + alpha is
not supported yet, because my stupid design in the zimg wrapper would
require a planar gray + alpha format, while ffmpeg provides only a
packed one.
the macOS config was only used in cocoa-cb before and only included when
it was available. since this config is meant for general macOS options
and backend independent options we include it when cocoa is available.
one of the options is already used in the old cocoa backend, which broke
using it when build without swift or cocoa-cb support.
Fixes#7449
The bash completion seems to be working decently at this point, so I
feel comfortable caching the options output to improve the performance
of the completion.
The change, in an earlier commit, in format for ass to handle results
in a different number of fields to skip. Correct that so SDH filtering
works.
Should fix issue #7188
As requested I guess. It behaves quite similar to the --loop* options.
Not quite happy with the idea that 1) the option is mutated on each
operation (but at least it's consistent with --loop* and doesn't require
more properties), and 2) the ab-loop command will do nothing once all
loop iterations are done. As a concession, the OSD shows something about
"disabled".
Fixes: #7360
This is not really a changelog, but rather a list of potentially
breaking changes API- and normal users should be aware of, and to help
with migration from older mpv releases.
for reasons unknown to me the NSCursor (un)hide functions can be
completely unreliable and the cursor can have an unknown state. this
only happens on some system and wasn't able to reproduce this. it's
probably some dumb race condition that might be possible to work around,
though because of the lack of reproducibility on my end it's hard to
test.
i decided to rework the cursor hiding code yet again and make it a lot
less greedy. the cursor will now always unhide when moved and there
will never be a situation again the cursor can't be unhidden again.
on the other hand there might be edge cases now where the cursor won't
hide immediately and you have to move it slightly to make it disappear
again. this should be an acceptable tradeoff.
Fixes#6886
this creates a default log for the last mpv run when started from the
bundle. that way one can get a log of what happened even after an issue
occurred. also add a menu entry under Help to show the current log, but
only when the bundle is used.
Fixes#7396Fixes#2547
Wayland uses vo_wayland_wait_frame plus some polling with a timeout for
blocking on vsync. Here are a couple of changes that seem to be
improvements. First, the poll time is always rounded up instead of
truncated. When rendering frames longer than the standard 16.666 ms
timeout, it seems that truncating the poll time slightly early may cause
some vsync jitter spikes. Waiting longer, even if it's too long, appears
to behave better.
The second change is to use wl_display_roundtrip instead of
wl_display_dispatch_pending. wl_display_dispatch_pending dispatches all
events immediately. This is good to avoid blocking, but it's not
guaranteed to wait long enough for all events to be processed on the
display fd. The preceding wl_display_read_events routine ensures that
all events on the display fd are queued. We just need a semi-blocking
routine to dispatch them for the most reliable vsync.
wl_display_roundtrip will dispatch any events for us, but also wait for
a reply from the display server. This makes it ideal for this role. If
the compositor doesn't reply to the client something else is probably
horribly broken and wrong anyway. It's also not a permanently blocking
call like wl_display_dispatch. If there's no frame callback (i.e. the
window is hidden), then it does not dispatch any events and returns
immediately.
Directories inside ~~/scripts/ are now loaded as scripts, so don't use
it also for modules. Now there are no default module paths.
To compensate, we now try to run ~~/.init.js right after defaults.js,
so the user may extend the js init procedure via this script, e.g. for
adding default paths to mp.module_paths .
While mpv normally uses the text a key produces (as opposed to physical
key mappings), this is different with the keypad. This is for the sake
of making it possible to distinguish between these keys and the normal
number keys on the left side of a full size keyboard.
There were complaints that the keypad doesn't interact with console.lua,
so manually map them. This ignores numlock (behaves as if it's always
on), and maps KP_DEC to "." (even though it's mapped to "," on some
keyboards). The /*-+ keys produce ASCII on mpv (at least with X11) as an
inexplicable inconsistency, so there are no mappings for these.
Fixes: #7431
Due to asynchronicity, we generally can't guarantee that a video frame
matches up with other events such as playback time change exactly (since
decoding, presentation, and property update all happen at different
times). This is a complaint in the referenced bug report, where
screenshot filenames in each-frame screenshot did not use the correct
timestamp, and instead was lagging behind by 1 frame.
But in this case, synchronicity was already pretty much forced with wait
calls. The only problem was that the playback time was updated at a
later time, which results in the observed 1 frame lag. Fix this by
moving the place where the screenshot is triggered in this mode.
Normal screenshots may still have the old problem. There is no effort
made to guarantee the timestamps absolutely line up, same as with the
OSD. (If you want a guarantee, you need to use a video filter, such as
libavfilter's drawtext. These will obviously use the proper timestamp,
instead of going through the somewhat asynchronous property etc. system
in the player frontend.)
Fixes: #7433
See #7435 and related for context.
Basically, it seems that while the original vsfilter processed subtitles
like with this option set to "yes", many current players (mpc-hc
default, vlc, probably most libass users) treat them like with "no". In
the linked issue, this makes rendering severely slower, and can consume
a lot of memory (or just overflow libass memory calculations). It seems
that changing this to "no" will lead to more good than bad, especially
because newer subtitles may be authored for the "no" behavior.
Most libass users seem to use "no" exactly because they do not call
ass_set_storage_size() at all. This API was needed because the scaling
of the subtitles depends on the video size (vsfilter bugs, or
something). In addition, it's my personal opinion that rendering should
not depend on the video at all, so I like setting the default of this to
"no".
The script was set up to only call on_update when the changelist
was non-empty. However, since the size operator does not operate
on dicts, it always returned 0 (which is truthy), thus on_update
would always be called when the script-opts property changed.
When switching between having a video visible or not,
stats.lua now picks up the required formatting changes
for the cache stats page to display correctly.
The recently added feature to load scripts from a sub-directory. A
problem was that the script name was still derived from the actual
script source file that was loaded, which was always "main.lua" (or
similar), resulting in "main" as name.
Fix this by using the directory name.
One odd corner case is that you can do "--script=/path/foo////". As by
POSIX semantics, the extra "/" are ignored. However, the newly added
code strips only one separator, so mp_basename() returns "" (as it
should), and the empty name makes mp_new_client() fail in turn. I don't
really care about this, just don't do it. But mp_new_client() failure
was silent (since it normally never happens), so add at least an error
message for that, instead of being entirely silent.
There were a couple of erroneous things in the handle_toplevel_config
function. Firstly, looping through the different states was not handled
correctly. Launching a window as maximized (can happen in sway for
example) was always stuck on true and would never be set to false. Fix
this by always checking if XDG_TOPLEVEL_STATE_MAXIMIZED is found or not.
Also do a similar thing for the fullscreen state.
Additionally, there were some issues with resizing windows and
window-scale going back to old sizes. The root of this problem is that
the width and height arguments of handle_toplevel_config aren't actually
guarenteed to be the actual width and height of the surface. There are
times when mpv will set the surface size on its own (like with
window-scale) which will be unknown to the toplevel listener. To
complicate matters, there are times when we do want to use the width and
height arguments (like when resizing with the mouse).
Fix this by checking if the width and height arguments reported by
handle_toplevel_config changed from the previous call of the function.
If the value is different, then we go ahead and use them when setting
mpv's geometry. If not, then we just ignore it.
win32 is a cursed abomination which has "drive letters" at the root of
the filesystem namespace for no reason. This requires special handling
beyond tolerating the idiotic "\" path separator.
Even more cursed is the fact that a path starting with a drive letter
can be a relative path. For example, "c:billsucks" is actually a
relative path to the current working directory of the C drive. So for
example if the current working directory is "c:/windowsphone", then
"c:billsucks" would reference "c:/windowsphone/billsucks".
You should realize that win32 is a ridiculous satanic trash fire by the
point you realize that win32 has at least 26 current working
directories, one for each drive letter.
Anyway, the actual problem is that mpv's mp_path_join() function would
return a relative path if an absolute relative path is joined with a
drive-relative path. This should never happen; I bet it breaks a lot of
assumptions (maybe even some security or safety relevant ones, but
probably not).
Since relative drive paths are such a fucked up shit idea, don't try to
support them "properly", and just solve the problem at hand. The
solution produces a path that should be invalid on win32.
Joining two relative paths still behaves the same; this is probably OK
(maybe).
The change isn't very minimal due to me rewriting parts of it without
strict need, but I don't care.
Note that the Python os.path.join() function (after which the mpv
function was apparently modeled) has the same problem.
It appears Lua's package paths try to load .lua files from the current
working directory. Not only that, but also shared libraries.
WHAT THE FUCK IS WHOEVER IS RESPONSIBLE FOR THIS FUCKING DOING?
mpv isn't setting this package path; currently it's only extending it.
In any sane world, this wouldn't be a default. Most programs use
essentially random working directories and don't change it.
I cannot comprehend what bullshit about "convenience" or whatever made
them do something this broken and dangerous. Thousands of programs using
Lua out there will try to randomly load random code from random
directories.
In mpv's case, this is so security relevant, because mpv is normally
used from the command line, and you will most likely actually change
into your media directory or whatever with the shell, and play a file
from there. No, you don't want to load a (probably downloaded) shared
library from this directory if a script try to load a system lib with
the same name or so.
I'm not sure why LUA_PATH_DEFAULT in luaconf.h (both upstream and the
Debian version) put "./?.lua" at the end, but in any case, trying to
load a module that doesn't exist nicely lists all package paths in
order, and confirms it tries to load files from the working directory
first (anyone can try this). Even if it didn't, this would be
problematic at best.
Note that scripts are _not_ sandboxed. They're allowed to load system
libraries, which is also why we want to keep the non-idiotic parts of
the package paths.
Attempt to fix this by filtering out relative paths. This is a bit
fragile and not very great for something security related, but probably
the best we can do without having to make assumptions about the target
system file system layout. Also, someone else can fix this for Windows.
Also replace ":" with ";" (for the extra path). On a side note, this
extra path addition is just in this function out of laziness, since
I'd rather not have 2 functions with edit the package path.
mpv in default configuration (i.e. no external scripts) is probably not
affected. All builtin scripts only "require" preloaded modules, which,
in a stroke of genius by the Lua developers, are highest priority in the
load order. Otherwise, enjoy your semi-remote code execution bug.
Completely unrelated this, I'm open for scripting languages and
especially implementations which are all around better than Lua, and are
suited for low footprint embedding.
This simply didn't set the direction flag in most situations, which
meant the timestamps used in the subtitle renderer were nonsense,
leading to invisible subtitles.
This works only for text subtitles that are cached in the ASS_Track
state. Reading new subtitles is broken because the demuxer layer has
trouble returning subtitle packets backwards, and I think for rendering
bitmap subtitles, the pruning direction would have to be adjusted. (Not
sure if reversing the timestamps before the subtitle renderer backend is
even the right thing to do. At least for sd_ass.c, it seems to make
sense, because it caches subtitles with "normal" timestamps.)
Apparently such .cue files exist. They fail both probing and parsing. To
make it worse, the sample at hand was encoded as Latin1.
One part of this is replacing bstr_lstrip() with a version that supports
NBSP. One could argue that bstr_lstrip() should always do this, but I
don't want to overdo it. There are many more unicode abomination which
it could be said it's supposed to handle, so it will stay ASCII instead
of going down this rabbit hole. I'm just assuming this cue sheet was
generated by some stupid software that inexplicably liked NBSPs (which
is how we justify a one-off fix). The new lstrip_whitespace() doesn't
look particularly efficient, but it doesn't have to be.
The second part is dealing with the fact that the charset is not
necessarily UTF-8. We don't want to do conversion before probing thinks
it knows it's a cue sheet (would probably make it more fragile all
around), so just make it work with Latin1 by assuming invalid code
points are Latin1. This fallback is part of why lstrip_whitespace() is
sort of roundabout.
(You could still rewrite it as much more efficient state machine,
instead of using a slow and validating UTF-8 parser that is called per
codepoint. Starting to overthink this.)
Multimedia is terrible. Legacy charsets are terrible. Everything is
terrible.
Fixes: #7429
Unfortunately, libarchive detects a stream of 0s as tar, as demonstrated
by "mpv /dev/zero". This is inconvenient in some cases.
One example is the .cue demuxer trying to open a raw audio .bin file,
which it allows only if probing fails (as .bin is raw and normally will
not look like any real file format). Although this use-case is
worthless.
On some platforms the ZPOS property might exist, but be immutable.
This is at least the case on Intel Sandy Bridge since Linux kernel
5.5.0. Trying to set an immutable property will cause.
drmModeAtomicCommit to fail with -EINVAL.
On other platforms we might want to set ZPOS to tweak the layering of
planes.
To reconcile these two, simply have drm_object_set_property check if a
property is immutable before attempting to add it to the atomic
commit, instead returning an error code (which is, as previously,
ignored in the case of ZPOS as we don't strictly need it)
The cdio API always reads in sectors (fixed CDIO_CD_FRAMESIZE_RAW
blocks). In the past, mpv/MPlayer streams had a way for a stream to
signal a sector size, so the stream's fill_buffer implementation could
ignore the length argument. Later, that was removed, but stream_cdda.c
was left with assuming that the read size was always larger than the
sector size (rightfully at the time). Even later, this assumption was
broken with commit f37f4de, when it was suddenly possibly that smaller
reads were performed (at ring buffer boundaries). It returned EOF if the
buffer size was too small, so playback stopped very early.
Fix this by explicitly handling arbitrary sizes.
Tested with a .cue/.bin file only.
Fixes: #7384
The intention is to provide a slightly nicer way to distribute scripts.
For example, you could put multiple source files into the directory, and
then import them from the actual script file (this is still
unimplemented).
At first I wanted to require a config file (because you need to know at
least which scripting backend it should use). This wouldn't have been
too hard (could have reused/abused the mpv config file parsing
mechanism, and I already had working code that was just 2 function
calls). But probably better to do this without new config files, because
it might become a pain in the distant future.
So this just probes for "main.lua", "main.js", etc., until an existing
file is found.
Another important change is that this skips all directory entries whose
name starts with ".". This automatically excludes the "." and ".."
special directories, and is probably useful to exclude random crap that
might be lying around in the directory (such as editor temporary files,
or OSX, in its usual hrmful, annoying, and idiotic modus operandi,
sharting all over any directories opened by "Finder").
Although the changelog mentions the docs, they're added only in a later
commit.
This originally existed as a hack for weston. In certain scenarios, a
frame taking too long to render would cause vo_wayland_wait_frame to
timeout which would result in a ton of dropped frames. The naive
solution was to just to add a slight delay to the time value. If a
frame took too long, it would likely to fall under the timeout value and
all was well. This was exposed to the user since the default delay
(1000) was completely arbitrary.
However with presentation time, this doesn't appear to be neccesary.
Fresh frames that take longer than the display's refresh rate (16.666 ms
in most cases) behave well in Weston. In the other two main compositors
without presentation time (GNOME and Plasma), they also do not
experience any ill effects. It's better not to overcomplicate things, so
this "feature" can be removed now.
This is a central lock (that is to stay and has no reason to go away),
and it was simply made global. This reduces complexity when the original
MPlayer code was changed from single thread + global state to a context
handle.
Having the global lock was still a bit silly if there were multiple mpv
instances in the process, because it would make the instances wait for
each other for no reason. So move it to the per-instance context, which
is trivial enough.
The wakeup_log_file callback was still assuming that mp_msg_lock was
used to control the log file thread, but this changed while I was
writing this code, and forgot to update it. (It doesn't change any
state, which is untypical for condition variable usage. The state that
is changed is protected by another lock instead. But log_file_lock still
needs to be acquired to ensure the signal isn't sent while the thread is
right before the pthread_cond_wait() call, when the lock is held, but
the signal would still be lost.)
Because the buffer's wakeup callback now acquires the lock, the wakeup
callback must be called outside of the buffer lock, to keep the lock
order (log_file_lock > mp_log_buffer.lock). Fortunately, the wakeup
callback is immutable, or we would have needed another dumb leaf lock.
mp_msg_has_log_file() made a similar outdated assumption. But now access
to the log_file field is much trickier; just define that it's only to be
called from the thread that manages the msg state. (The calling code
could also just check whether the log-file option changed instead, but
currently that would be slightly more messy.)
Until now --log-file performed a blocking write to the log file, which
made any calling thread block for I/O. It even explicitly flushed after
every line (to make it tail-able, or to ensure a hard crash wouldn't
lose any of the output). This wasn't so good, because it could cause
real playback problems, which made it infeasible to enable it by
default.
Try to buffer it through a ring buffer and a thread. There's no other
choice but to use a thread, since async I/O on files is generally a big
and unportable pain. (We very much prefer portable pain.) Fortunately,
there's already a ring buffer (mp_log_buffer, normally for the client
API logging hook). This still involves some pretty messy locking. Give
each mp_log_buffer its own lock to make this easier.
This still makes calling threads block if the log buffer is full (unlike
with client API log buffers, which just drop messages). I don't want log
messages to get lost for this purpose. This also made locking pretty
complicated (without it, mp_log_buffer wouldn't have needed its own
lock). Maybe I'll remove this blocking again when it turns out to be
nonsense.
(We could avoid wasting an entire thread by "reusing" some other thread.
E.g. pick some otherwise not real time thread, and make it react to the
log buffer's wakeup callback. But let's not. It's complicated to abuse
random threads for this. It'd also raise locking complexity, because we
still want it to block on a full buffer.)
There wasn't really much of a reason to keep split_opt and
splot_opt_silent apart. It made sense before the latter also had a log
call (which was silenced by using mp_null_log if necessary).
Just merge them back into one, and always rely on mp_null_log to silence
unwanted output.
Shouldn't have any functional changes.
Add support for setting window-minimized and window-maximized in
Windows. The minimized and maximized state can be set independently.
When the window is minimized, the value of window-maximized will
determine whether the window is restored to the maximized state or not.
Changing state is done with ShowWindow(), which has commands that change
the window state and activate it (eg. SW_RESTORE) and commands that
change the window state without activating it (eg. SW_SHOWNOACTIVATE.)
It would be nice if we could use commands that don't activate the
window, so scripts could change the window state in the backrgound
without bringing it to the foreground, but there are some problems with
that. There is no command to maximize a window without activating it, so
SW_MAXIMIZE is used instead. Also, restoring a window from minimize
without activating it seems buggy. On my Windows 10 1909 PC, it always
moves the window to the back of the z-order. SW_RESTORE is used instead
of SW_SHOWNOACTIVATE because of this.
This also changes the way the window is initially shown. Previously, the
window was made visible as a consequence of the SWP_SHOWWINDOW flag in
the first call to SetWindowPos. In order to set the initial minimized or
maximized state of the window, the window is shown with the ShowWindow
function instead, where the ShowWindow command is determined by whether
the window should be initially maximized or minimized.
Even when showing the window normally, we should still call ShowWindow
with the SW_SHOW command instead of using SetWindowPos, since the first
call a process makes to ShowWindow(SW_SHOW) has special behaviour
where it uses the show command in the process' STARTUPINFO instead of
the command passed to the function, which should fix#5724.
Note: While changes to window-minimized while in fullscreen mode should
work as expected, changing window-maximized while in fullscreen does not
work and won't result in the window changing state, even after leaving
fullscreen. For this to work correctly, the fullscreen logic needs to be
changed to apply the new maximized state on leaving fullscreen.
Fixes: #5724Fixes: #7351
I noticed an oversight when using ytdl-hook -- if the path is a URL, we
try to `stat()` it, which obviously doesn't work. To mitigate that,
don't check or update mtimes for URLs.
it was possible for mouse events to be triggered when the core was
already being shut down. to prevent this properly close and remove the
window and additional remove the reference to MPVHelper object.
this deprecates the old cocoa backend only option and moves it to the
general macos ones. add support for the new option in the cocoa-cb
layer creation and use the new option in the olde cocoa backend.
Fixes#7272
due to the bundle config the icon is set automatically via the bundle
system mechanisms. this also makes it possible to set the icon to a
custom one with the standard macOS copy paste method via the file info
dialogue.
Fixes#6874
This reverts commit 1b0129c414.
It turns out most of the files affected by the idiotic use-case actually
use this old naming pattern, which I hoped was unused.
This means for now we'll always assume .rar files are multi-part (until
proven otherwise), but the following commit tries to fix this.
It's ridiculous that --script=something.dumb does not cause an error.
Make it error, and extend this behavior to the scripts/ sub-dir in the
mpv config dir.
I think there was a user complaint that this does not restore the
playlist position.
There's no reason not to save the "state" for unseekable streams; what
we probably don't want is to make restoring trying to issue a seek. So
just don't save the position. (Although we probably could anyway, since
seek requests on unseekable streams are ignored now.)
Fixes: issue number forgotten, if it even exists.
This was used to convert e.g. P010 to NV12 within the filter chain,
which hopefully a thing that is not needed anymore. (And has been dead
code since the ANGLE "RGB" interop code was removed.)
Notably, BGR0, which is the only additional format listed as supported
by the texture mapper, results in broken colors. This is most likely not
a mpv issue, so the whitelist fulfils its purpose.
As documented on struct mp_hwdec_ctx, hw_imgfmt specifies the hardware
surface wrapper format for which supported_formats is valid. If this was
not set, f_hwtransfer ignored supported_formats, and assumed all formats
were supported.
Cache display updates, especially when it's bigger than few minute,
could have been be very infrequent to the point that one is not sure
if it updates at all.
Reduce the 10% change-threshold to 5% and add another threshold of 5s.
Right now we are generating the fully option list before doing
anything else. That makes filename completion significantly slower
than it was before, for no gain. It's easy to only generate the
option list when it's actually needed.
I also know I could additionally cache the option list across
invocations, but I'm not doing that yet to make testing easier.
There are two improvements here:
1) Correct the right-side padding on the title box. This was messed
up previously because I was passing the title box width when I
should be passing the x coordinate. I've also increased the
spacing to separate the title from the window controls more
clearly.
2) I'ved added a mouse tracking area over the title bar so that the
osc doesn't disappear if you hover over the title box. This didn't
work previously because the input area only covers the actual
window controls. The implementation here is simplified in that
it's only a mouse area and not an input area. This is enough to
keep the osc visible, but it won't stop the mouse pointer
disappearing. Fixing that requires a full input area which, for
now, I will say isn't worth the effort.
It's a bit unintuitive today when you use the un-maximise control
while fullscreened. Depending on the VO in use, this might silently
change the maximise state without any visible effect, or it might
do nothing. It's less surprising if the control exits the fullscreen
state.
Note that the exact behaviour is still VO dependent. If the window
was maximised before being fullscreened, it might exit fullscreen
back to maximised or back to regular window mode.
I thought about trying to explicitly control that behaviour but
it makes the osc code weird and probably wouldn't work all the time.
Allow the --window-maximized and --window-minimized flags to actually
work when the player is started on wayland. If the compositor doesn't
support maximization or minimization, then these options just do
nothing.
Fixes#7345
There was a multitude of issues with cursor handling in wayland and
behavior seemed to vary for strange reasons across compositors and also
bad things were being done in wayland_common. The problem is complicated
and involved fullscreen states being set incorrectly under certain
instances and so on. The best solution is to just remove most of the
extra cruft. In handle_toplevel_config, instead of automatically
assuming is_fullscreen and is_maximized are false, we should use
whatever value is currently set vo_opts which matters when we initially
launch the window.
I think the previous code didn't consider the situation if the input
format was not any of the upload formats. It then could have possibly
tried to upload the wrong format (and not sure what the underlying APIs
do with it).
Take care of this, also improve logging, and change it such that
mp_hwupload_find_upload_format() does not unnecessarily change the state
(although it doesn't really matter).
With the recent change how f_hwtransfer could select formats, it's
possible that the upload_fmts list contains formats that are never
selected, and the filter would have failed.
The way it works now is that f_hwtransfer gets to select the format
(which honestly doesn't make sense, but whatever), and f_autoconvert
gets only a single format.
It would be more ideal if f_hwtransfer provided a list of possible input
formats, but that's absurdly too complex for now. Maybe I'll change it
back at some later point, but I expect this shit to be in a perpetual
state of complexity and brokenness.
Some complex commands (like commands generated by scripts to define key
bindings or the OSD overlay command) contain new lines, which "corrupts"
logging.
Fix this by escaping the parameters C-style. Abuse the JSON writer for
this, which already has code to vaguely produce C-style escapes.
At first I considered stripping the quotes, but then I thought it's
actually a good idea to leave them in, as it makes things clearer.
Follows an idea by avih.
(Oh yes, we could have skipped all the complexity, and hardcoded the
cases that work in the first place. This wouldn't be an issue if FFmpeg
or libva exported correct information. Also possible that FFmpeg's
filter chain does not allow to do this correctly in the first place,
since filters expose next to no meta information about what hw formats
etc. they need.)
Note that uploading yuv420p to a nv12 vaapi surface actually works, but
the blacklist excludes it. So this might get a bit slower. I'm not
bothering with this case because it's rarely needed, and the blacklist
specification would become a bit more complex if you had to specify
sw/upload format pairs.
Fixes: #7350
Basically, instead of trusting the upload format, and picking the first
sw format that has a desired upload format, trust the sw format. So now
we pick the sw format first, and then select from the set of upload
formats supported by it.
This is probably more straightforward, and works around a crash with
vaapi:
mpv 8bit.mkv --vf=format=vaapi --gpu-hwdec-interop=all
(Forces vaapi upload if hw decoding is not enabled.)
Unfortunately, this still does not work, because vaapi, FFmpeg, the VO
interop code, or all of them are doing something stupid. In particular,
this picks the yuv420p sw format, which doesn't really exist despiter
advertised (???????????????????????????????????????), and simply breaks.
See: #7350
hwdec_vaapi tries to probe all available surface formats in advance. For
that, we iterate over _all_ profiles in an attempt to collect possible
surface formats. This means we try profiles we normally wouldn't use for
decoding or filtering, and which could be "unrelated" services.
It seems some drivers report at least one profile, for which
vaQueryConfigEntrypoints() fails (because the profile is not supported;
not sure why it lists it, then). So turn the error message into a
verbose message to avoid confusing output.
Fixes: #7347
This shouldn't really matter, but it's probably best to avoid.
vo_wayland_control would execute set_cursor_visibility while wl->pointer
existed but it didn't check if wl->pointer_id existed. So
wl_pointer_set_cursor would be set to a null surface with an id of 0.
Instead, just wait until we have an actual, non-zero pointer id so that
the cursor is set with the correct, actual id and not a fictious 0 id.
This ensures that the pointer isn't set until it enters the wl_surface
which is what we want.
While we've had a zsh completion script for a while, we haven't had
one for bash. This one is reasonably comprehensive, although there are
improvements one could imagine for certain options.
at the time of the initial dpi query the window is not instantiated yet.
we use a proper fallback in that case, eg the target configured screen
or the main screen if none is set.
also change some weird oversight and a small optimisation.
don't build our own ffmpeg anymore and instead use the bottled version
from homebrew. update the newest macOS image. also handle macOS 10.12
as a legacy OS since homebrew and Apple stopped supporting it.
nevertheless it's helpful to build on that version since it's the last
version we support building on. it's a bit special since we have to pin
the homebrew-core version to a previous one where all the bottles for
macOS 10.12 are still available, otherwise it would build nearly
everything from source and that would take ages. also start caching the
homebrew cache folder for downloads.
This code assumed that the function is only called from the playloop
itself (and since property notification is done at the end of it, i.e.
before sleeping, it obviously would not have needed to wake up the
core).
But this function is actually called from some comments (such as
playlist-move), so this assumption was incorrect. Use the same method as
the other function.
Untested.
Fixes: #7339 (probably)
Seems like I'm still not done with rar playback stuff...
It turns out the reason for archive_read_open1() opening all volumes had
nothing to do with libarchive's rar code, but was a consequence of how
multi volume support is implemented in libarchive, and due to the fact
that we enabled archive_read_support_format_zip_seekable() (through
archive_read_support_format_zip()).
The seekable zip format will seek to the end of the file and search for
a zip "header" there. It could possibly be considered a libarchive bug
that it does that even if it's fairly sure that it's a RAR file.
We already do probing on a small buffer read from the start of the file
(i.e. not giving libarchive a way to seek the stream before we think
it's an archive), but that does not help, since libarchive needs to
probe _again_. libarchive does not seem to provide a function to query
the format (no archive_read_get_format()). Which seems quite strange,
but at least I didn't find one.
This commit works this around by doing some manual rar/zip probing. We
could have gone only with rar probing. But detecting zip separately
allows us to avoid that stream_libarchive seeks to the end during early
probing. This is an additional bonus on top of "fixing" multi volume
rar.
The zip probing is from archive_read_format_zip_streamable_bid(). The
rar signature is the common prefix of the rar and rar5 formats in
libarchive (presumably the RAR fixed header parts without version).
If the demuxer seeks to the end of the rar entry, this will still open
all volumes; I'm not sure whether the old/removed rar code in mpv could
handle this better.
See: #7182
This matches lua's 11b9315b but with the lagacy field names which the
js code used previously.
Currently the property always returns an object (with dummy/last/null
field values if there are no dimensions), but the code is ready for
a future case where it might return null if there are no dimensions - at
which case it will forward the null, breaking backward compatibility for
a better API.
Theoretically possible (and quite unlikely due to the small texture
size). The code was originally written with the assumption that texture
allocations can't fail, and it was never updated out of laziness.
Untested.
The idea is that if the player is resized, we do not delay redrawing
(which is normally done to limit the redraw rate to something
reasonable).
Not sure if this even does anything. For one, reacting to osd-dimensions
changes is cleaner than just polling the screen size with the next tick
event, and hoping that resizes generate tick events for whatever
logically unrelated reasons.
check_obj_resize() in sub/osd.c calls mp_client_broadcast_event(), which
calls notify_property_events(). This is pretty unexpected, because
check_obj_resize() may be called from the VO thread. While that's sort
of awful, it seems to be OK locking-wise. But it breaks an assumption in
notify_property_events() that the core doesn't need to be woken up,
which could possibly lead to a missed/delayed property update (although
rather unlikely).
Fix this by explicitly waking up the core when it's called from the OSD
code.
This is a gross hack for the shitty design of how VO properties are
handled (which was fine with MPlayer, but became increasingly a shit tub
with mpv's VO thread).
The problem here is that console.lua reads display-hidpi-scale on every
render, but which may take a long time for video timing and vsync
blocking. It will also block the core, making osc.lua unable to react to
window resizing quickly enough.
This should be solved by not using the "classic" blocking VOCTRL
mechanism, and instead side-stepping it with something that doesn't
require any waiting (like for example the "fullscreen" property does).
But this require more thinking and work my "brain" can handle at the
moment. So for now add a shitty hack that will cause a lot of problems,
and which will have to be replaced later. Most importantly, it'll break
theoretic support for multiple screens with different DPI, or runtime
DPI changes. Possibly could affect the Cocoa backend; the X11 isn't
dynamic enough by nature, and other backends do not implement this.
See previous commit.
A nice side-effect is that mp.get_osd_margins() is not a special
Lua-only thing anymore. I didn't test whether this function still works
as expected, though.
This "bundles" all OSD properties. It also makes some previously
Lua-only values available (Lua has mp.get_osd_margins(), unsure if
anything uses it).
The main intention is actually to allow retrieving all fields in an
"atomic" way. (Could introduce a mechanism on the level of the mpv
client API to do this, but doing ti ad-hoc all the time like this commit
is easier.)
Addresses dumb things like accidentally overwriting a media file with
e.g. "mpv --log-file test.mkv" (when the user thought that --log-file
was a flag option, when it actually takes a filename). This example will
now print an error. It still works with "-log-file overwritten.mkv", but
prints a warning.
Not sure if I'm being too careful or not "radical" enough. In any case,
both the syntax that stops working and the syntax that produces a
warning now have been discouraged and were called legacy for almost a
decade.
Well that was too much misery when trying to deal with an idiotic
feature, so it had to be compensated for.
Replace insults with proper explanation, libarchive sort of isn't guilty
in the first place, and their format support is pretty good all things
considered.
The change was not propagated to the OSD/subtitle code, since that still
uses an "old" method. Change it so that the propagation is actually
performed.
(One could argue the OSD/subtitle code should use other ways to update
the options, but that would probably be more effort for now.)
This turned every "normal" .rar filename into a multi-volume one
accidentally. Since the detection is purely by filename (due to lack of
support by libarchive I guess), it causes the nasty message added in the
previous commit to appear for every .rar file. Just drop it.
See manpage additions. The libarchive behavior mentioned in the last
paragraph there is technically unrelated, but makes this new option
mostly pointless.
See: #7182
Until now, they were all just added to options.c (e.g. demux_mkv_conf).
This adds a mechanism which can be used to add future options in a
(very) slightly more elegant way.
There are a lot of ad-hoc component lists in mpv: for example the stream
and demuxer lists. It doesn't seem to make sense to add any abstractions
around it since they are completely trivial and have very specific
probing mechanisms and so on, so they will remain ad-hoc.
This commits add a way to let these add arbitrary per-component options,
without giving up the ad-hoc way, and without having to dump them into
options.c with lots of ifdeffery (like it was done until now).
Also see next commit.
Instead of opening every volume on start just to see if it's there, all
all volumes that could possibly exist, and "handle" it on opening. This
requires working around some of libarchive's amazing stupidity and using
some empirically determined behavior. Will possibly break if libarchive
changes some of this behavior.
See: #7182
We whitelist formats (and not all of them). RAR v5 is a separated format
entry for inexplicable reasons. (It's a separate implementation, but who
really wants to support only either of the rar formats?)
I'm not sure if it was libarchive 3.3.3. Their git history is absolutely
chaotic. These people do not know how to use git. I couldn't be bothered
to dig deeper.
Currently, the activation and deactivation of input handling is done
inside the render() loop, but this does not run when the osc mode is
`never` - which does make sense.
That means that if you are cycling the visibility mode, the input
state will be whatever it was at the time of the mode change. And,
as our modes are ordered `auto` -> `always` -> `never`, the input
state will be enabled when you cycle to `never`.
There are various ways you can imagine fixing this, and in this
change I propose we reset the input state to disabled on a mode
change, and then let render() re-enable input if that's appropriate.
Fixes#7298.
It turns out that gnome wayland still has very serious issues that make
it unusable for playback with mpv. Other compositors mostly behave fine
(Plasma is just missing feature but it's not seriously broken), so GNOME
gets the special honor of having a warning printed out. The only
solution for GNOME users at this time of writing is to either use the
Xorg session or use another wayland compositor.
When switching tracks, the data for the new track is missing by the
amount of data prefetched. This is because all demuxers return
interleaved data, and you can't just seek the switched track alone.
Normally, this would mean that the new track simply gets no data for a
while (e.g. silence if it's an audio track). To avoid this, mpv performs
a special "refresh seek" in the demuxer, which tries to resume demuxing
from an earlier position, in a way that does not disrupt decoding for
the non-changed tracks. (Could write a lot about the reasons for doing
something so relatively complex, and the alternatives and their
weaknesses, but let's not.)
This requires that the demuxer can tell whether a packet after a seek
was before or after a previously demuxed packet, sort of like an unique
ID. The code can use the byte position (pos) and the DTS for this. The
DTS is normally strictly monotonically increasing, the position in most
sane file formats too (notably not mp4, in theory).
The file at hand had DTS==NOPTS packets (which is fine, usually this
happens when PTS can be used instead, but the demux.c code structure
doesn't make it easy to use this), and pos==-1 at the same time. The
latter is what libavformat likes to return when the packet was produced
by a "parser" (or in other words, packets were split or reassembled),
and the packet has no real file position. That means the refresh seek
mechanism has no packet position and can't work.
Fix this by making up a pseudo-position if it's missing. This needs to
set the same value every time, which is why it does not work for
keyframe packets (which, by definition, could be a seek target).
Fixes: #7306 (sort of)
When using --keep-open, and the end of the file is reached, the player's
"pause" property is set to true. Attempting to set it to false reverts
it back to true immediately. That's how it's designed, for better or
worse.
Running "seek -10 ; set pause no" did not work, because the seek is
first queued and pause is unset, but then the decoding functions
determine that EOF is still a thing, and "mpctx->stop_play =
AT_END_OF_FILE;" is set again. handle_keep_open() then sets pause again.
Only then the seek is actually run.
Fix this by not setting stop_play if a seek is queued.
In the distant past, the cuviddec backed copy hwaccel could be
configured directly using lavc options. However, since that time,
we gained support for automatic hw ctx creation which ended up
bypassing the lavc options.
Rather than trying to find a way to pass those options again, a
better idea is to make the 'cuda-decode-device' option, used by
the interop hwaccels, work for the copy hwaccels too.
And that's pretty simple: we have to add a create function that
checks the option and passes it on to ffmpeg.
Note that this does require a slight re-jig to the configuration
flags, as we now have a scenario where we want to build with support
for the cuda copy hwaccels but not the interop ones. So we need
a distinct configuration flag for that combination.
Fixes#7295.
In vaapi 1.1.0 (which confusingly is libva release 2.1.0), they
introduced a new surface export API that is more efficient, and
we've been supporting that and the old API ever since (Feb 2018).
If we drop support for the old API, we can do some fairly nice cleanup
of the code.
Note that the pkgconfig entries are explicitly versioned by the API
version and not the library version. I confirmed the upstream pkgconfig
files.
As we are less and less interested in vpdpau, with nvdec and vaapi
being better choices in general on nvidia and AMD respectively, we
might consider removing direct_mode, where we bypass the vdpau
mixer and work directly with yuv textures. Normally, working with
yuv textures would be great, but vdpau built in an assumption that
all frames are delivered as separate fields, causing us to have
to re-interleave them.
nvidia then introduces a new OpenGL extension that can return the
yuv frames as frames, but we can't just unconditionally switch to
that as we'd want to keep supporting older hardware where the drivers
are no longer getting new features. The end result is that we
wouldn't be able to get rid of the old code paths.
Removing direct_mode means we always use the mixer, and work with
rgba frame textures. There are some theoretical limitations to
this, but in practice they probably don't matter much - unsupported
colourspaces don't matter because without 10bit decoding support,
we can't use them anyway, and apparently we're not doing separate
chroma scaling these days, so scaling the rbga doesn't really lose
anything (and the vdpau hq scaling option remains available).
Although a linked list was ideal at first, there are cases where it
sucks, and became increasingly awkward (with the mpv command API
preferring integer indexes to access the list). In future, we probably
want to add more playlist-related functionality, so better change it to
an array now.
An array isn't always ideal either. Since playlist entries are still
separate objects (because in some cases you need a stable "iterator" to
it), but you still need to efficiently get the next/previous playlist
entry, there's a pl_index field, that needs to be maintained. E.g.
adding an entry at the start of the playlist => update the pl_index
field for all other entries. Well, it's not really worth to do something
more complicated to avoid these things.
This commit is probably buggy as shit. It's not like I bothered to test
everything. That's _your_ role.
GCC 9.2 warns about this. It was always a bit sketchy, so get rid of it.
VK_F10 generates WM_SYSKEYDOWN, so it only needs to be handled in the
WM_SYSKEYDOWN case.
Before this commit, runtime changes were only applied if something else
caused audio to be reinitialized. Now setting them reinitializes audio
explicitly.
This option type, used by --audio-channels, had a completely broken
m_option_type.equal implementation, and thus reacted incorrectly to
runtime option changes.
Broken since commit b16cea750f.
Thought it might be useful to document some of these things, instead of
explaining them over and over again. But I can guarantee that nobody
will ever read all this. (Independent of its quality and completeness.)
in certain circumstances the video was not redrawn even when the size
or the backing scale factor changed. this could lead to a lower
resolution output than intended.
now it redraws the video when screen properties or the window size
changes.
It's not really great. But I think it's good enough to save someone
who's lost. Most importantly, it should become obvious _what_ the
console expects (input commands), and how to exit it.
Would be nice if we could show some documentation, or give a link to
documentation, but that's out of scope and/or not easy.
I considered implementing the "help" command as builtin command in
command.c. On the other hand, this could not show console.lua specific
help, so I implemented it in console.lua. The ad-hoc command parsing
(that sort-of mirrors mpv input command syntax) for the "help" command
is probably the worst part of this.
It's deprecated. The new solution works almost exactly the same way
(since the still existing internal tick event triggers vsync-jitter
change command), though as far as API usage goes, it's somewhat
questionable. (The comment is meant to discourage anyone trying to copy
the idea for external scripts.)
This affects behavior when using the "del" default key binding.
Sometimes, setting visibility to always did not draw it correctly. This
probably fixes it.
Add an "auto-safe" mode, mostly triggered by Ubuntu's nonsense to force
hwdec=vaapi in the global config file in their mpv package. But to be
honest it's probably something more people want.
This is implemented as explicit whitelist. On Windows, HEVC/Intel is
sometimes broken, but it's still whitelisted, and in theory we'd need a
detailed whitelist of device names etc. (like for example browsers tend
to do). On OSX, videotoolbox is a pretty bad choice, but unfortunately
the only one, so it's whitelisted too. There may be a larger number of
hwdec wrappers that work anyway, and I'm for example ignoring Android.
when swift is disabled some headers are not included. one of them is the
options/options.h header that is needed for the vo_sub_opts struct. we
include it to fix the build without swift.
the second problem is the build time check for the macOS 10.12.2
features or more specific the Media Player support. since it is a swift
feature we can not use it when swift is disabled. add a separate
Media Player check that also depends on swift and use that new
preprocessor variable as a build time check instead.
Fixes#7282
Implemented using one-time idle observer (i.e. setTimeout), to avoid
additional function call(back) every time the event loop enters idle.
The lua mp.flush_key_bindings() is also available, also undocumented.
A minority of users have expressed a dislike of hats, calling them
"cancer [that] don't belong in software" describing the people who add
them as "shitty circlejerks" and "chucklefuck."
While I personally disagree with those opinions, it's probably easier
to let them have it their way. For that reason this adds the option
`greenandgrumpy` to the osc, which allows users to disable the hat.
libass uses integers for PlayResX/Y, so the osd-overlay command also
does. Lua (pre-5.3) does not have an integer type, but the command
interface makes a difference anyway. If you pass a Lua number with a
fractional part to an integer parameter (using mp.command_native()), it
will result in an error and complain about incompatible types.
I think that's fine, but since this behavior extends to
mp.set_osd_ass(), this is a compatibility problem.
Fix this by explicitly coercing the resolution parameters to integer
numbers.
The main reason for this is just to make show the OSC always above
console.lua, instead of a random order.
(And this is also the only reason osc.lua was changed to the new API.
The old API could have been extended, but lets not.)
This tries to avoid the update() call if nothing changed. This brings it
more into line with the old code (the osd-overlay command simply does
not skip the update if nothing changed). I don't know whether this
matters; most likely not. Normally, code should try to avoid redundant
updates on its own, so it's not the job of the command. However, for the
OSC we simply want to reduce the differences.
Lua scripting has an undocumented mp.set_osd_ass() function, which is
used by osc.lua and console.lua. Apparently, 3rd party scripts also use
this. It's probably time to make this a public API.
The Lua implementation just bypassed the libmpv API. To make it usable
by any type of client, turn it into a command, "osd-overlay".
There's already a "overlay-add". Ignore it (although the manpage admits
guiltiness). I don't really want to deal with that old command. Its main
problem is that it uses global IDs, while I'd like to avoid that scripts
mess with each others overlays (whether that is accidentally or
intentionally). Maybe "overlay-add" can eventually be merged into
"osd-overlay", but I'm too lazy to do that now.
Scripting now uses the commands. There is a helper to manage OSD
overlays. The helper is very "thin"; I only want to force script authors
to use the ID allocation, which may help with putting multiple scripts
into a single .lua file without causing conflicts (basically, avoiding
singletons within a script's environment). The old set_osd_ass() is
emulated with the new API.
The JS scripting wrapper also provides a set_osd_ass() function, which
calls internal mpv API. Comment that part (to keep it compiling), but
I'm leaving it to @avih to finish the change.
Lua scripting implements key bindings by defining an input section with
all the bindings in it. Every add_key_binding() call ran a mpv command
to update this section. This caused a lot of spam at debug log levels.
Reduce the spam and more it efficient by batching updates into a single
mpv command when the script becomes inactive. This is pretty simple,
because there's already the concept of idle handlers.
This requires that the script actually goes to sleep, which might not
happen in various extremely bogus corner cases, such as polling the mpv
message queue with active waiting. Just don't do that.
Demuxers can call demux_close_stream() to close the underlying stream if
it's not needed anymore. (Useful to release "heavy" resources like FDs
and sockets. Plus merely keeping a file open can have visible side
effects such as inability to unmount a filesystem or, on Windows, to do
anything with the file.)
Until now, this set demuxer->stream to a dummy stream, because most code
used to assume that the stream field is non-NULL. But this requirement
disappeared (in some cases, the stream field is already NULL), so stop
doing that. demux_lavf.c, one of the demuxers which calls this function,
still had some of this, though.
Make concat streams use the "worst" origin of its parts, which may or
may not be what makes sense. stream_memory has no natural way to do
this, so just add a vague comment.
mf:// has an obscure feature that lets you pass a list of filenames
separated by newlines. Who knows whether anyone is using that. It opened
these listfiles with fopen(), so the recent stream origin bullshit
doesn't operate on it. Fix this by using the mpv internal stream API
instead. Unfortunately there is no fgets(), so write an ad-hoc one. (An
implementation of line reading via "stream" is still in demux_playlist,
but it's better to keep it quarantined there.)
During the 12th month (checked during script initialization), draw a Santa hat
on top of the idle message's logo.
Slightly refactors and optimizes the drawing process as well: reorder original
logo layers and remove redundant holes in them, use a shared line prefix
to clear the style and set start position.
Signed-off-by: wm4 <wm4@nowhere>
Now that 00af718a made the lua read_options behavior much more similar
to the js behavior, the main difference was that lua does not re-read
the config file at on_update (but it does re-apply its stored content)
while js did re-read it.
Now the js on_update also does not re-read the config file and instead
applies its stored original content.
This is slightly hacky by adding an undocumented optional 4th argument
to read_options which allows overriding the config file content.
Make sure it gets properly reinitialized when needed. This is especially
useful now that the OSC reacts to runtime option changes, which can
change the layout too.
This may call set_property_number() on the margin properties more often
now, but since redundant option changes are ignored now, this shouldn't
have any too bad effects.
Fuck it, just let's just reinit everything.
On a side note, the changelist parameter provided by read_options()
(here "list") is now unused. But it's not hard to provide and might be
useful for other stuff. So don't remove it from the generic
read_options() code.
As described in the manpage changes. This makes more sense than the
previous approach, where options could "unexpectedly" stick. Although
this is still a somewhat arbitrary policy (ask many people and you'd get
a number of different expectations on what should happen), I think that
it reflects what mpv's builtin stuff does.
All the copying is annoying, but let's just hope nobody is stupid enough
to change these properties per video frame or something equally
ridiculous.
Apparently there are two different options for controlling which
screen an mpv window goes onto: --fs-screen and --screen. The former
explicitly only controls which screen a fullscreened window goes onto,
but does not appear to actually care about this option at runtime for
X11, so pressing f will always fullscreen to the screen mpv is currently
on. This means the option is of questionable usefulness for starters.
Making it worse, if you use --screen=1 --fs, mpv will actually fullscreen
on screen 0, because --fs-screen isn't set. Instead of doing that, fall
back to whatever --screen is set to.
This is a bit different than the lua code: on script-opts change it
simply re-applies the conf-file and script-opts to the options object,
and if this results in any changed value at options then on_update is
called with the changelist as argument.
This allows a value to revert back to the conf-file value if the
matching script-opts key had a different value and then got deleted.
It also guarantees to call back whenever the options object is
modified, which the lua code doesn't do (e.g. if the caller changed
a value and the observer changed it back - it won't detect a change).
With special attention to changing osc-visibility. Untested, although
osc-visibility works (it's pretty much equivalent to the key binding, so
there is not much interesting going on).
Somewhat inspired by code posted by github user CogentRedTester.
Fixes: #4513
The way how this modifies and backups/restores user option values is a
bit of a problem for runtime option changing.
Clean this up a little. Now cycling the visibility updates the user
option value, but always to "valid" values (unlike hidetimeout used to
be used). If the user option value is changed externally (enabled by a
later commit), it'll be cleanly overwritten.
Although they were not undocumented, they were hidden away in the
respective manpage sections. It's a good idea to add them to the main
keyboard bindings overview too. stats.lua also did this.
I decided to factor this into the user's scale option (instead of
somehow using it as default if the user has not specified it), because
it makes the option handling simpler, and won't break things like
per-screen DPI if the user only wants to scale the console font by a
factor.
(X11 does not support different per-screen DPI (or only via hacks), so
this is pretty simple. If other backends are going to implement this,
then they should send VO_EVENT_WIN_STATE if the DPI for the mpv window
changes by moving it to another screen or such.)
Until now, .edl files accepted only "simple" filenames, i.e. no relative
or absolute paths, no URLs. Now that the origin bullshit is a bit
cleaned up and enforced in the EDL code, there's absolutely no reason to
keep this.
The new code behaves somewhat similar to playlists. (Although playlists
are special because they're not truly recursively opened.)
mpv has a very weak and very annoying policy that determines whether a
playlist should be used or not. For example, if you play a remote
playlist, you usually don't want it to be able to read local filesystem
entries. (Although for a media player the impact is small I guess.)
It's weak and annoying as in that it does not prevent certain cases
which could be interpreted as bad in some cases, such as allowing
playlists on the local filesystem to reference remote URLs. It probably
barely makes sense, but we just want to exclude some other "definitely
not a good idea" things, all while playlists generally just work, so
whatever.
The policy is:
- from the command line anything is played
- local playlists can reference anything except "unsafe" streams
("unsafe" means special stream inputs like libavfilter graphs)
- remote playlists can reference only remote URLs
- things like "memory://" and archives are "transparent" to this
This commit does... something. It replaces the weird stream flags with a
slightly clearer "origin" value, which is now consequently passed down
and used everywhere. It fixes some deviations from the described policy.
I wanted to force archives to reference only content within them, but
this would probably have been more complicated (or required different
abstractions), and I'm too lazy to figure it out, so archives are now
"transparent" (playlists within archives behave the same outside).
There may be a lot of bugs in this.
This is unfortunately a very noisy commit because:
- every stream open call now needs to pass the origin
- so does every demuxer open call (=> params param. gets mandatory)
- most stream were changed to provide the "origin" value
- the origin value needed to be passed along in a lot of places
- I was too lazy to split the commit
Fixes: #7274
This has the advantage that playlists within the archive will work as
expected, because demux_playlist will correctly join the archive base
URL and entry name. Before this change, it could skip before the "|",
resulting in a broken URL.
For some inexplicable reason, the OSC runs the expand-text command a
_lot_. This command is logged at the log file default log level, so the
log file can quickly fill up with these messages. It directly violates
the mpv logging policy: per-frame (or similarly common) log messages
should not be enabled by default for the log file.
stats.lua uses the show-text command for some reason (instead of
creating its own OSD layer).
Explicitly reduce the log level for expand-text and some other commands.
Also reduce the log level for commands triggered by mouse movement.
The previous commit also contributed some to reduce log spam.
Fixes: #4771
Traditionally, the OSC used mpv's "tick" event, which was approximately
sent once per video frame. It didn't try to track any other state, and
just updated everything.
This is sort of a problem in many corner cases and non-corner cases. For
example, it would eat CPU in the paused state (probably to some degree
also the mpv core's fault), or would waste power or even throw errors
("event queue overflows") on high FPS video.
Change this to not using the tick event. Instead, react to a number of
property change events. Rate-limit actual redrawing with a timer; the
next update cannot happen sooner than the hardcoded 30ms OSC frame
duration. This has also the effect that multiple successive updates are
(mostly) coalesced.
This means the OSC won't eat your CPU when the player is fucking paused.
(It'll still update if e.g. the cache is growing, though.) There is some
potential for bugs whenever it uses properties that are not explicitly
observed. (In theory we could easily change this to a reactive concept
to avoid such things, but whatever.)
mpv_event_property (for property observation) actually never sets an
error status. You cannot distinguish between unavailable properties and
properties which returned an error. Not sure if it ever did.
I intend to rewrite this code approximately every 2 months.
Last time, I did this in commit d66eb93e5d (and 065c307e8e and
b2006eeb74). It was intended to remove the roundabout synchronous
thread "ping pong" when observing properties. At first, the original
async. code was replaced with some nice mostly synchronous code. But
then an async. code path had to be added for vo_libmpv, and finally the
sync. code was dropped because it broke in other obscure cases (like the
Objective-C Cocoa backend).
Try again. This time, update properties entirely on the main thread.
Updates get batched out on every playloop iteration. (At first I wanted
it to make it every time the player goes to sleep, but that might starve
API clients if the playloop get saturated.) One nice thing is that
clients only get woken up once all changed events have been sent, which
might reduce overhead.
While this sounds simple, it's not. The main problem is that reading
properties must not block the client API, i.e. no client API locks can
be held while reading the property. Maybe eventually we can avoid this
requirement, but currently it's just a fact. This means we have to
iterate over all clients and then over all properties (of each client),
all while releasing all locks when updating a property. Solve this by
rechecking on each iteration whether the list changed, and if so,
aborting the iteration and redo it "next time".
High risk change, expect bugs such as crashes and missing property
updates.
keyvalue_list_find_key() was called on a "partially" constructed list,
because the terminating NULL was added only later. Didn't I say this
code is cursed?
Fixes: #7273
This is for console.lua (see next commit). The idea is that console.lua
can adjust its offset to the bottom of the window by the height of the
OSC.
If the OSC is not set to permanently visible, export no margins, because
it would look weird to move the console depending on the mouse movement.
Very primitive and dumb, but fulfils its purpose for the next commits.
I chose this specific implementation because it has the lowest footprint
in command.c, without resorting to crazy hacks such as sending messages
between scripts (which would be hard to coordinate especially on
startup).
The size overflow check was inverted: instead of allowing reading only
the first dst_size bytes of the property, it allowed copying past the
property buffer (as returned by xlib). xlib doesn't return the size of
the buffer in bytes, so it has to be computed and checked manually.
Wouldn't it be great if C allowed me to write the overflow check in a
readable way, so it doesn't trick me into writing dumb security bugs?
Relying on X security is even dumber than creating a X security bug,
though, so this was not a real problem. But I found that one specific
call tried to read more than what the property provided, so reduce that.
Also, len*ib obviously can't overflow, so there's an additional layer of
dumb to this whole thing.
While we're at dumb things, why the hell does xlib use "long" for 32 bit
types. It's a god damn pain.
This was completely broken: it compared the first item of the filter
list only. Apparently I forgot that this is a list. This probably broke
aspects of runtime filter changing probably since commit b16cea750f.
Fix this, and remove some redundant code from obj_settings_equals().
Which is not the same as m_obj_settings_equal(), so rename it to make
confusing them harder. (obj_setting_match() has these very weird label
semantics that should probably just be killed. Or not.)
I don't even know anymore whether this was intended or not. Certain use
cases for the "-o" options might require this. These options are for
passing general FFmpeg options. These are translated to av_opt_set()
calls, which may or may not accumulate the option values on multiple
calls with the same option name (how should I know?).
Anyway, it seems crazy to allow non-unique keys, so make them unique.
The ad-hoc nature of the option code makes this wonderfully complicated
(when I wrote that this code is cursed, I meant it). In combination with
lazy testing, it probably means there are lots of bugs here.
Whenever I deal with this, I have to look at the code to make sense of
this. And beyond that, there are some strange inconsistencies. (I think
this code is cursed. It always was, and maybe always will be.)
Although the manpage claimed that using multiple items for -add etc. is
deprecated, string list options didn't warn against it. So add the
warning, and add something in the changelog (even though nobody will
ever read this).
The manpage mentioned --vf-append, but this didn't even exist. So add
it, I guess. We encourage using -append for the other option types, so
for consistency, it should work on filter options. (And I already
tricked me into believing it existed when I mentioned it in the
manpage.)
Make the "operations" table separate for all option types, and mention
the option type on every single of the top-level list options.
libavcodec's nvdec wrapper can return invalid frames, that do not have
any data fields set. This is not allowed by the API, but why would they
follow their own API?
Add a workaround to specifically detect this situation. In practice,
this should fall back to software decoding if it happens too often in a
row. (But single errors are still tolerated, because I don't know why.)
Untested due to lack of hardware from the regrettable graphics company.
Better do this here than deal with the moronic project we unfortunately
depend on.
See: #7185
Better do this here than deal with the moronic project we unfortunately
depend on.
The workaround is generic; unknown whether it works correctly with
multi-input/output filters or filter graphs. It assumes that if all
inputs are EOF, and all outputs are EAGAIN, the bug happened.
This is pretty tricky, because anything could happen. Any time some form
of progress is made, the got_eagain state needs to be reset, because the
filter pad's state could have changed.
These all have been replaced recently.
There was a leftover in window.swift. It couldn't have done anything
useful in the current state of the code, so drop these lines.
The generic change detection now handles this just as well.
The way how this function is manually called at init is slightly gross.
Make that part slightly more explicit to hopefully avoid confusion.
* Instead of following VOCTRL_FULLSCREEN, check for option changes.
* Instead of signaling VO_EVENT_FULLSCREEN_STATE, update the cached
option structure and have it propagated to the origin.
Additionally, gets rid of all the straight usage of the VO options
structure.
Done in a similar style to the Wayland common file, where in case
of reading the value, the "payload" from cache is utilized.
EDL files can have multiple segments taken from the same source file. In
this case, the source file is supposed to be opened only once. This
stopped working, and it created a new demuxer instance for every single
segment entry. This made it slow and made it use much more memory than
needed.
This was because it tried to iterate over the array of source files, but
the array count (num_parts) was only set to a non-0 value later. Fix
this by maintaining the count correctly.
In addition, the actual code for checking whether a source can be reused
(in open_source()) regressed and stopped working correctly. d->stream
could be NULL. Use demuxer.filename instead; I'm not entirely sure
whether this is always correct, but fortunately we have a distributed
almost-AI driven test suite (called "users") which will probably find
and report such cases.
Probably broke with commit a09396ee60 or something close, but didn't
check closer.
Fixes: #7267
In this combination, the [current-]window-scale properties still
incorrectly applied scaling.
For some reason, vo_calc_window_geometry2() handled this option
(basically ignored the dpi_scale parameter passed to it), but since the
DPI compensation for window-scale is implemented in x11_common.c, we
need to check and honor this option here too. (What a mess.)
console.lua uses "terminal-default" logging, which is supposed to return
all messages logged to the terminal to the API. Internally, this is
translated to MP_LOG_BUFFER_MSGL_TERM, which is MSGL_MAX+1, because it's
not an actual log level (blame C for not having proper sum types or
something).
Unfortunately, this unintentionally raised the internal log level to
MSGL_MAX+1. It still functioned as intended, because log messages were
simply filtered at a "later" point. But it led to every message being
formatted even if not needed. More importantly, it made mp_msg_test()
pointless (code calls this to avoid logging in "expensive" cases and if
the messages would just get discarded). Also, this broke libplacebo
logging, because the code to map the log messages did not expect a level
higher than MSGL_MAX (mp_msg_level() returned MSGL_MAX+1 too).
Fix this by not letting the dummy level value be used as log level.
Messages at terminal log level will always make it to the inner log
message dispatcher function (i.e. mp_msg_va() will call
write_msg_to_buffers()), so log buffers which use the dummy log level
don't need to adjust the actual log level at all.
This is similar to the "edition" change.
I considered making this go through deprecation, but didn't have a good
idea how to do that. Maybe it's fine, because this is pretty obscure.
But it might break some API users/scripts (it certainly broke
stats.lua), and all I have to say is sorry for that.
"window-scale" is 1.0 by default; however, x11 implicitly set that to
2.0 on hidpi screens. This made the default 2.0, which was inconsistent
with the option. The "window-scale" property jumped from 1.0 to 2.0 when
a window was created.
Avoid this by factoring the DPI into the window-scale. This makes the
UNFS_WINDOW_SIZE return a virtual size; since this value is used for the
window-scale property only, this is fine and has no further
consequences. (Originally, this was possibly meant to be used for other
purposes, but I'm perfectly fine with redoing this again should that
ever happen.)
This changes user-visible behavior, and it's as if setting window-scale
multiplies its argument by 2 suddenly. Hopefully no user will get angry.
This is for the previous commit, and should affect behavior with the
special M_PROPERTY_GET_CONSTRICTED_TYPE mechanism only. The effect is
that cycling the "edition" property, if the option is set to "auto",
will change to the second edition instead of the first.
Normally, option values must always be within their range, so this
should not affect anything else. M_PROPERTY_GET_CONSTRICTED_TYPE is
sort-of fine with this kind of behavior.
If this affects any other M_PROPERTY_GET_CONSTRICTED_TYPE users
neqatively, I will revert the change.
See manpage/changelog changes.
The purpose of this change is to removes another case of inconsistent
property behavior. At first I wanted to make this go through deprecation
before making a technically incompatible change, but then I considered
this feature too obscure as that anyone would care.
The VO underrun detection (just a weak heuristic) added in commit f26dfb
flagged the underrun state every time it was checked, and since the
check happened in every playloop iteration, this caused the playloop to
wake up itself on every iteration. It burned an entire core while in
this state.
Fix this by flagging this condition only once (as it should be), and
requiring that a frame is displayed to trigger it again. This makes it
work similar as the audio underrun check.
The bug report referenced below says --demuxer-thread=no avoided this.
This is because the demuxer layer doesn't do proper underrun reporting
if the reader thread is disabled.
Fixes: #7259
With the previous commit, there's no need for 1.5 anymore. And in fact,
it's just too dangerous to rely on 1.5 because of all the EGL craziness.
For example, you might get a 1.5 EGL system library, but a driver might
still give you 1.4 at runtime. If you assume that you can call 1.5
functions, you will probably get random crashes in this case. What a
cursed API. (The same problem exists with EGL 1.3, but fortunately
nothing seems to use that anymore. We can just ignore that problem.)
This tries to deal with the crazy EGL situation. The summary is:
- using eglGetDisplay() with multiple windowing platforms doesn't really
work, but Mesa had an awful hack for it
- this hack can be disabled at build time, and some distros sometimes
accidentally or intentionally do so
- Mesa will probably eventually disable it by default
- we switched to eglGetPlatformDisplay(), but this requires EGL 1.5
- the very regrettable graphics company (also known as Nvidia) ships
drivers (for old hardware I think) that are EGL 1.4 only
- that means even though we "require" EGL 1.5 and link against it, the
runtime EGL may be 1.4
- trying to run mpv there crashes in the dynamic linker
- so we have to go through some more awful compatibility hacks
This commit tries to do it "properly", but using EGL 1.4 as base. The
plaform selection mechanism is a messy extension there, which got
elevated to core API in 1.5 (but OF COURSE in incompatible ways).
I'm not sure whether the EGL 1.5 code path (by parsing the EGL_VERSION)
is really needed, but if you ask me, it feels slightly saner not to rely
on an EGL 1.4 kludge forever. But maybe this is just an instance of
self-harm, since they will most likely never drop or not provide this
API.
Also, unlike before, we actually check the extension string for the
individual platform extensions, because who knows, some EGL
implementations might curse us if we pass unknown platform parameters.
(But actually, the more I think about this, the more bullshit it is.)
X11 and Wayland were the only ones trying to call eglGetPlatformDisplay,
so they're the only ones which are adjusted in this commit.
Unfortunately, correct function of this commit is unconfirmed. It's
possible that it crashes with the old drivers mentioned above.
Why didn't they solve it like this:
struct native_display {
int platform_type;
void *native_display;
};
Could have kept eglGetDisplay() without all the obnoxious extension BS.
This assert() sometimes triggered (and still triggers) with lavc API
bugs. It tries to check that at least 1 plane is set to a non-NULL
value. Obviously, a valid frame returned by successful decoding should
never have it.
The problem is that some hwdecs use integer surface IDs cast to a
pointer. Recently, it happened that newer Intel drivers started using
surface ID 0 under certain circumstances (for unknown reasons), which
triggers this assert.
Just get rid of it.
For the sake of #7185, add an assert() specifically for nvdec. That
failure needs to be further analyzed, is probably a FFmpeg bug, and
without this assert() would just crash somewhere further down the video
chain.
Fixes: #7261
This code checked AVFrame.buf[0] instead of the decode return code to
see whether a frame was decoded. This is sort of suspicious; while I
think that the lavc API actually guarantees it, it's not intuitive
anyway. In addition, the code was unnecessarily roundabout.
Replace it with a proper error code check. Remove the other error return
(that was, or should have been, redundant before). The no-frame path is
now cleanly separated. Add an assert on the frame-returned path; if this
fails, lavc violated its own API.
the old event tap has several problems, like no proper priority support
or having to set accessibility permissions for mpv or the terminal.
it is now replaced by the new MediaPlayer which has proper priority
support and isn't as greedy as previously. this only includes Media Key
support and not any of the other features included in the MediaPlayer
framework, like proper Now Playing data (only set dummy data for now).
this is only available on macOS 10.12.2 and higher.
also removes some unnecessary redefines.
Fixes#6389
the Apple Remote has long been deprecated and abandoned by Apple.
current macs don't come with support for it anymore. support might be
re-added with the next commit.
using the MPContext as ta parent was a bad idea and shouldn't be done in
any circumstances there because it only supposed to be for internal
usage. this had the undesired effect that the options group was freed
but still used since the MPContext is freed afterwards.
instead manually free options group.
this removes the direct access of the mp_vo_opts stuct via the vo struct
and replaces it with the m_config_cache usage. this updates the
fullscreen and window-minimized property via m_config_cache_write_opt
instead of the old mechanism via VOCTRL and event flagging. also use the
new VOCTRL_VO_OPTS_CHANGED event for fullscreen and border changes.
People somehow think "should" makes things optional, even though the
wording was merely trying to account for the exception of the rule. I
guess this means programming documents should sound like we're running a
police state (which is also the ultimate outcome of all technological
development, if you weren't aware).
See: #7248
\s and \S aren't actually part of the spec, but it seems glibc supports
them anyway so I didn't notice when originally testing. This fixes the
script on Apple's libc and probably others that adhere more closely to
the spec.
The most direct replacement for \s would have been [[:space:]], but we
only expect to see spaces and tabs, so might as well just do that. Also
could have used [[:blank:]], which is basically a locale-aware version
of [ \t], but mpv isn't going to output anything but ASCII spaces and
tabs, so let's avoid unnecessary complexity and stick with the ASCII
literals.
It was supposed to be optional already, but I misunderstood how the
re_match_pcre option worked. If it's set, it will try to use PCRE
matching whether it's available or not (and blow up if it's not). So,
first try to load the module it'll use, and only set the option if that
works.
Fixes#7240.
Instead of traversing across leafs() which can lead to an infinite
loop issue with cross-linked libraries, use the dictionary
(libs_dict) created by libraries() to create a set (libs_set) of
every unique library. Every value in libs_dict is also a key in
libs_dict, so every unique library linked to mpv will be a key in
libs_dict. Use set() on libs_dict to return a set of the keys from
libs_dict, and remove binary from the set so that a duplicate of
the binary is not added to the libs directory.
Iterate over libs_set to bundle dylibs while using the libs_dict
to determine which install_names to change.
And troll Microsoft slightly while we're at it. But is it trolling if
it's the truth?
The level of C99 support in MSVC is probably a bit better than most
people think, but it's by far not adequate. We need a bit of either C11
or GNU extensions too, and rely on some MinGW helpers (that look like
they're provided by MS, except they're not).
Do it after decoding etc., but before waiting for input. This seems to
make more sense, because whether a queued seek can be applied depends on
the playback state. So it sounds like a good idea to apply the seek
first thing, but it's a bad idea to go to sleep if there's still a
queued seek pending (that couldn't be processed earlier).
Also add an empty line before mp_wait_events(); it doesn't really have
to do with the filter bullshit.
If you have a normal file with audio and video, and keep "spamming"
forward hr-seeks, the player just kept showing the last video frame
instead of exiting or playing the next file. This started happening
since commit 6bcda94cb. Although not a bug per se, it was odd, and very
user-noticable.
The main problem was that the pending seek command was processed before
the EOF was "noticed". Processing the command reset everything, so the
player did not terminate playback, but repeated the seek.
This commit restores the old behavior.
For one, it makes video return the correct status (video.c). The
parameter is a bit ugly, but better than duplicating the logic or having
another MPContext field. (As a minor detail, setting r=VD_EOF makes sure
have_new_frame() returns true, rather than going through another
iteration or whatever the hell will happen instead, which would clobber
logical_eof.)
Another thing is making the seek logic actually wait until the seek
outcome has been determined if audio is also active. Audio needs to wait
for video in order to get the video seek target position. (Which in turn
is because hr-seek still "snaps" to video frames. You can't seek in
between two frames, so audio can't just use the seek target, but always
has to wait on the timestamp of the video frame. This has other
disadvantages and is a misdesign, but not something I'll fix today.)
In theory, this might make hr-seeks less responsive, because it needs to
fully decode/filter the audio too, but in practice most time is spent on
video, which had to be fully decoded before this change. (In general,
hr-seek could probably just show a random frame when a queued hr-seek
overrides the current hr-seek, which would probably lead to a better
user experience, but that's out of scope.)
Fixes: #7206
I missed adding this when defining the style used for the video
title in the window control bar. The default behaviour is to wrap,
but we want to cut the title off when we run out of space.
See commit 4e4252f916 and the following as an example how this would
have to be done if done properly.
Since I'm unable to test on OSX, and nobody is interested in fixing this
code (including myself, actually), just remove the deprecated
definitions to make sure the code still builds. This will break runtime
switching of fullscreen, ontop, border. (The way the minimized state is
reported was also deprecated, but commit 40c2f2eeb0 already broke it
anyway.)
Seems like this was silently changed to enabled by default on the change
to libplacebo, without adjusting the manpage. Fix the documented
default.
Also add a comment about Nvidia; see referenced issue.
Fixes: #7245
...probably.
The EGL backend had a strange problem: when recreating the window, EGL
surface creation sometimes mysteriously failed. For example, keeping the
"_" key down (cycles video by default) destroys and recreates the window
in rapid succession, which will often enough show the "Could not create
EGL surface!" message.
This was puzzling because due to mpv's architecture, the X11 Window and
even the X11 Display were fully destroyed, the thread on which they ran
was destroyed, and then everything was recreated. There shouldn't have
been any state that could make subsequent EGL initialization fail.
It turns out mpv forgot to free EGLSurfaces in the x11 code. EGL is a
pretty crazy API (full of thread local and global state with weird
lifetime requirements), and for example it seems EGLDisplay cannot be
explicitly released, but apparently implicitly dies when the native
display is closed (at least EGL 1.5 claims eglTerminate() does _not_
invalidate the display, only certain objects linked to it). It appears
that Mesa still referenced at least EGLSurface in some form, and either
some pointer or some X11 ID was dangling, and when it randomly matched
when eglCreateWindowSurface() was called, it failed.
Fix this by calling eglTerminate(), which supposedly destroys (or rather
unreferences) contexts and surfaces created from the display (but
absurdly not the display itself).
Now why can't you just destroy the display? If it's implicitly
invalidated, why can't it just call eglTerminate() implicitly when this
happens? Did Mesa do something wrong when they somehow didn't
automatically remove the dangling object (so I could claim not to be
responsible for the bug)? Who the fuck knows, and I'm too tired to
figure this out (both because it's late, and because I'm tired of this
EGL crap API).
Still not sure if the code is correct now. I think EGL was designed to
maximize implementation and API-use complications. How else could you
possibly come up with something like the EGLDisplay life cycle? Or am I
just making a fuss? Anyway, fuck EGL, fuck computers, fuck technology.
Fixes: #7129
I was recently informed that unicode has official symbols for
window controls, and I put together a change to use them, which
worked, as long as a suitable font was installed. However, it's
not that hard to get a normal system that lacks an appropriate
font, and libass wants to print warnings if the symbols aren't
in the default font, which will almost always be true.
So, I gave up and added the symbols to the custom osd font that
we already have. This ensures they are always available, and
that they are aligned consistently on all platforms.
I took the symbols from the `symbola` font, as this has a suitable
licence and the symbols look nice enough.
Symbola Licence:
Fonts are free for any use; they may be opened, edited,
modified, regenerated, packaged and redistributed.
Finally, as we now have access to an un-maximize symbol, I added
logic to use it when the window is maximized.
Get rid of the legacy VOCTRL (which will be removed later). I'm not sure
what exactly fullscreen was supposed to do (toggling between using the
entire display, and what --geometry forced?), but I don't care, just get
rid of the VOCTRL. PRs to fix regressions caused by this will be
accepted, but personally I don't care since this is excessively fringe
and obscure.
This warning seems to be designed well. It doesn't seem to warn on
fallthrough-only case statements, so it's compatible to well written
code.
stream_dvdnav.c had an obscure bug in inactive code, fix it.
stream_dvb.c is the only place where it intentionally falls through, I
guess I'll just leave it alone.
The wayland backend needs to keep track of whether or not a window is
hidden for presentation time. There is no presentation feedback when a
window is hidden which means we shouldn't be sending information to the
vo_sync_info structure (i.e. just leave it all at -1). This seemed to
work fine, but recent changes to presentation time in one notable
compositor (Sway; it was probably always broken in Weston actually)
changed the presentation time behavior.
For reasons that aren't clear, there is a greater than 16.666ms delay
between the first presentation time event and the second presentation
time event (compositor latency?) when you switch back to an mpv window
after it is hidden for long enough (a few seconds). When using
presentation time, this causes mpv to feed in some bad values in its
vsync timing mechanism thus causing the A/V desync spike as described in
issue #7223.
This solution is not really ideal. It would be better if the
presentation time events received by the compositors did not have the
aforementioned inconsistency. However since this occurs in both Sway and
Weston and clients can't really fight compositors in wayland-world,
here's a reasonable enough workaround. Basically, just add a slight
delay before we start feeding information into the vo_sync_info again.
We already do this when the window is hidden, so it's not a huge leap.
The delay chosen here is arbitrary, and it basically just recycles the
same parameters used to detect if a window is hidden. If
vo_wayland_wait_frame times out 60 times in a row (or whatever your
monitor's refresh rate is), then we assume the window is hidden. This is
a pretty safe assumption; something has to be terribly wrong for you to
miss 60 vblanks in a row while a window is on the screen.
In this case, we basically just do the reverse of that. If mpv receives
60 frame callbacks in a row (or whatever your monitor's refresh rate
is), then it assumes the window is not hidden. Previously, as soon as it
received 1 frame callback it was declared not hidden. Essentially,
there's just 1 second of delay after reshowing a window before the
presentation time statistics are used again. This should be more than
enough time to skip over the weird inconsistent behavior presentation
time behavior and avoid the A/V desync spike.
Fixes#7223
I had previously wondered whether to do this, but in my testing
with x11 and wayland, the osc was being re-inited on a border
toggle already so I didn't add it.
However, on win32, things are different and there is no re-init
when toggling borders. I belive this is because the active window
size doesn't change in anyway, while on x11/wayland, toggling the
border actually changes the window size - and that trigger a re-init.
So, let's just be explicit and request a re-init when the border
is toggled.
Merged from mpv-repl git repo commit 5ea2bf64f9c239f0326b02. Some
changes were made on top of it:
- Tabs were converted to 4 spaces indentation (plus some manual
indentation fixes in some places).
- All user-visible mentions of "repl" were renamed to "console".
- The README was converted to a manpage (with heavy changes, some
additions taken from stats.rst; rossy converted the key bindings
table to RST).
- The method to change the default key binding was changed.
- Change minor detail about "font" default value setting (not a
functional change).
- Integrate into the player as builtin script, including an option to
prevent loading it.
Above changes and commit message done by wm4.
Signed-off-by: wm4 <wm4@nowhere>
drmModeAddFB is legacy, and might not pick the pixel format you
expect, depending on your driver. Use drmModeAddFB2 which specifies
this explicitly using a fourcc.
Seems like some drivers only increment msc every other page flip when
running in interlaced mode (I'm looking at you nouveau). I.e. it seems
to be incremented at the frame rate, rather than the field rate.
Obviously we can't work with this, so shame the driver and bail.
On intel this isn't an issue, as msc is incremented at field rate
there.
This means presentation feedback won't work correctly in interlaced
modes with those drivers, but who in their right mind uses an
interlaced mode these days, anyway?
Later calls to mp.add_key_binding() should take priority over previous
calls with the same key. Until now, the order was random (due to using
table pairs() iteration order).
Do this by simply sorting by a counter that is never reset. Since
input.c also gives later bindings priority, this works out.
Calling mp.remove_key_binding() on a newer binding makes an older still
existing binding with the same key active again. New bindings override
older ones, but do not overwrite them. I think these are good semantics
for most use cases.
(Note that the Lua code cannot determine whether two bindings use the
same key. Keys are strings, and two different strings could refer to the
same key. The code does not have access to input.c's key name
normalization, so it cannot compare them.)
It's user_filters.c which allows the "lavfi-" prefix to distinguish
libavfilter filters from mpv builtin filters. f_lavfi.c is a layer
below, and strictly passes anything it gets to libavfilter. So the
correct place for this is in user_filters.c, which also has the code for
stripping the prefix in the normal filter instantiation code.
In theory, using strstr() to search for extensions is a bad idea,
because some extension names might be prefixes for other names, so you
could get false positives. gl_check_extension() avoids this case.
It's not clear whether this is really needed; maybe not. Surely the EGL
committee is aware of these practices (many GL clients do this, which is
why it's widely considered bad practice), and would avoid defining new
extension names which contain existing names as sub-strings, but
whatever.
Adding an ifdef mess to deal with insufficient system headers is kind of
a mess. It's easier to just provide the definitions manually. This sucks
a bit too, but it's the approach we've been using with OpenGL headers in
general, and I think that worked pretty well.
On systems whose EGL headers do not define these extensions, the build
still failed due to missing ..._PLANE3_... defines. Although we supplied
missing EGL_LINUX_DMA_BUF_EXT defines manually, the PLANE3 ones are
actually from a separate extension, which explains why they were not
added to the fallback defines in the first place.
Add them, now it builds without the eglext.h include.
See #6838.
Since the recent option changes (probably b16cea750f), using the "vf"
or "af" commands to change the filter chain did not write the option
value correctly. This led to the option value being reset the next time
an option changed.
This happened because the new option value was not copied to the
m_config_cache's internal storage. So on the next option update, it
looked like the option value changed, because the user-side value was
different from the internal value. It was copied back, which meant the
original option value was reinstated, and the previous "vf"/"af" command
was undone.
Fix this by using the correct way to store the option value. This also
takes care of property change notification (because the function is
specifically separate from m_config_cache_write_opt() to do that), so
remove the old call.
Fixes: #7220
Both the "stop" and "loadfile" commands are asynchronous. "stop" starts
terminating playback, which used to be done in the same playloop
iteration, but now it may take longer, so a "loadfile" command can be
received while this is going on. (Possible that it used to work if the
second command was issued at least in the next playloop iteration.)
Make the "loadfile" override the "stop" mode, so the next file will be
played, instead of quitting or going into idle mode.
Unlike the referenced bug report claims, this has nothing to do with
IPC.
Fixes: #7225
When frame-stepping with display-sync mode enabled in high framerate
video, the frame was sometimes not redrawn correctly. Only the first OSD
interaction (or something similar) made it visible.
In this case, the core schedules many frames as dropped (because it's
ignorant of pausing/frame-stepping, as in theory the player is _not_
paused during frame-stepping, only at the end of it). There's a race
between the VO rendering the queued frame, and the core calling
vo_set_paused() after it has queued the frame. If the latter happens
first, the existing logic to redraw the previous dropped frame does
things correctly. If the former happens, the frame is not redrawn
automatically, but will be redrawn on the next user input (or if OSD is
enabled, and the pause state change updates it, which leads to an
immediate redraw).
Fix this by never actually dropping a frame in paused mode. The request
by the core to drop it is simply ignored.
Maybe this could be done slightly nicer by updating the pause state with
the VO atomically. Then we wouldn't have the frame drop counter going up
either (it's actually dropped, but then redrawn; but I doubt any user,
or me in a few weeks, would understand this). But I'm not really
interested in polishing this by increasing the complexity of the
frame-step code.
To aid in discoverability, and to address the most common case
directly, I'm adding an 'auto' mode for the window controls. In
this case, we will show the controls if there is no window border
and hide them if there are borders. This also respects the option
being toggled at runtime.
To ensure that it works in the wayland case, I've also made sure
that the wayland code explicitly forces the option to false if
decoration support is missing.
Based on feedback, I've split the config in two, with one option
for whether controls are active, and one for alignment. These are
new enough that we can get away with ignoring compatibility.
As preparation for adding the auto mode for window controls, we need
to make sure that the controls can be successfully toggled at runtime,
rather than only being able to configure them once at startup. Right
now, there is a problem with the handling of the show/hide zone for
the window controls.
The previous fix for #7212 was to avoid registering the input mapping
for the window control show/hide zone. If there is no input mapping,
then there is no input, and the zone is a no-op, even if it exists.
But this only happens at startup. After that point, the input mapping
doesn't exist and cannot be turned on.
In this change, I'm switching the approach; we now go back to always
registering the input mapping, and instead, we zero out the show/hide
zone if window controls are disabled, and set its size appropriately
if they are enabled.
This small regression was introduced by #7216. Previously, the wayland
backend used a trick which kept track of the previous fullscreen state
and used that logic for showing the cursor. Since vo_opts now keeps
track of the current fullscreen state, most of this stopped being
neccessary.
However, there was one edge case where the cursor didn't
behave the same: passing a fullscreen flag for the inital window. The
cursor would initially be visible here which is not desirable. This can
be remedied pretty easily by just setting the cursor visiblity to false
if the pointer entry event occurs on fullscreen. The only thing we need
to do is to make sure that the autohide delay isn't completely disabled
(i.e. the cursor is always visible). Hence the need for the previous
commit.
Certain backends (i.e. wayland) will need to do special things with the
mouse. It makes sense to expose the values of these options to them, so
they can behave correctly.
Do what we do best in multimedia: add conflicting hacks on top of other
hacks, that fix a single sample, and may break other ones.
In this case, it only happens if the file is most likely already broken
(subtitle bounding boxes go outside of the subtitle "canvas"), so it's
OK. The file still looks broken (and, in fact, the file is completely
fucking broken), but you can see the subtitles.
But in summary, this is not actually something I should have bothered
about.
I noticed that MPlayer shows the subtitles "correctly", but this is only
because they have a hack that extends subtitles with small resolution to
a larger hardcoded resolution. This hack was removed from mpv, because
it broke some completely legitimate files. As another really funny fact,
MPlayer's default video output (vdpau) appears to display this file
correctly, but only because it handles narrow aspect ratios (that extend
the height instead of the width) incorrectly. It extends the height, but
leaves the video with 1:1 aspect ratio at the top. It seems to repeat
the last video line. (-vo xv and -vo gl show it correctly, i.e.
stretched like mpv, by the way.) For some reason, the sample file at
hand is extended with black, so the subtitles are rendered into a black
area below the video, which is almost reasonable. So, MPlayer may
display this file "correctly", but in fact it only happens to do so
because of 1 hack that breaks legitimate files, and 1 bug. What the
fuck.
Fixes: #7218 (sort of)
Hr-seek has some sort of tolerance against timestamps, where it allows
for up to 5ms deviation. This means it can work only for videos with up
to 200 FPS framerate. There were complains about how it doesn't work
with videos beyond some high fps. (1000 was mentioned, although that
sounds more like it's about the limit that .mkv has.)
I suspect this is because otherwise, it might be hard to hit a timestamp
with --start, which specifies timestamps as integer, and thus will most
likely never represent a timestamp exactly. Another part of the problem
is that mpv uses 64 bit floats for timestamps, so fractional parts are
never represented exactly. (Both the "tolerance" and using floats for
timestamps were things introduced before my time.)
Anyway, in the backstep case, we can be relatively sure that the
timestamp will be exact (as in, the same unmodified value that was
returned by the filter chain), so we can make an exception for that, in
order to fix backstep.
Untested. (For that you have users.)
May help with #7208.
See previous commit. libavformat exports this information as AVStream.id
field.
The big problem is that the libavformat field is simply 0 if it's
unknown (i.e. the demuxer never sets it). So it needs to remain a
whitelist. Just add more formats which are known to have a meaningful
ID.
I considered exporting IDs for all formats, and then either leaving the
values as they are, or filtering duplicate values (and choosing
arbitrary but unique different IDs). But then again, I think it's sort
of mpv's job to filter FFmpeg's absurd bullshit API, and it should make
an effort to hide it rather than to reflect it.
See: #7211
The demuxer_id (exported in as "src-id" property) is supposed to be the
native stream ID, as it exists in the file, or -1 if that does not exist
(actually any negative value), or if it is unknown.
Until now, an ID was made up if it was missing. That seems like strange
non-sense, and I can't find the reason why it was done. But it was
probably for convenience by the EDL stuff or so.
Stop doing this. Fortunately, the src-id property was documented as
being unavailable if the ID is not known. Even the code for this was
present, it was just inactive until now. Extend input.rst with some
explanations.
Also fixing 3 other places where negative demuxer_id was ignored or
avoided.
The remaining legacy VOCTRLs are for the fullscreen and border
properties. For fullscreen this largely just replacing the private
state field with the vo option but there are small semantic
differences that we need to be careful of.
For the border setting, it's trivial as we don't have external
mechanisms for changing the state, but I also can't test it as
I'm not using a compositor that supports it.
I always intended for this to be accepted and mean "right" but I
made it show an error for any value that's not explicitly
recognised (while considering all unrecognised values to mean "right").
So let's explicitly recognise "yes".
I wanted to get this done quickly as I introduced the new VOCTRL
behaviour for minimize and maximize and it was immediately made
legacy, so best to purge it before anyone gets confused.
I did not sort out fullscreen as that's more involved and not something
I've educated myself about yet. But I did replace the VOCTRL_FULLSCREEN
usage with the new option change mechanism as that seemed simple
enough.
Pretty annoying affair. The vo_gpu code could of course not trigger
rendering from filters yet, so it needed to be extended. Also, this uses
some icky stuff made for vf_sub (and this was the reason I marked vf_sub
as deprecated), so everything is terrible.
The previous hack for fixing #7201 requires this, but it wasn't checked.
It's easy to check, so do it. (Yes, we could just have required OpenGL
3.2 headers and skipped the earlier fix.)
For #7201.
We don't want m_config uninitialization to call random change callbacks.
This happens at the end of mp_destroy(), when almost everything else is
already destroyed, and the change callbacks would probably trigger UB
all over the place.
The change callbacks could be trigger by m_config_restore_backups(),
which is just used as a cheap way to free the remaining state. The worst
is that this depends on which options may still have been part of this
"backup" state, which depends on user input.
Probably never a practical problem, since the backup state is most
likely guaranteed to be empty before uninit is performed, but still.
glx.h recursively includes gl.h, and there is no way to prevent this.
Old Mesa defines some GL symbols, but not all which mpv needs. In
particular, one user who was too lazy to update his ancient Ubuntu and
preferred to bother us with obscure bug reports, had Mesa headers which
did not define GL 3.2, so GLsync was not defined.
All in all I still think the idea of providing the GL API definitions
ourselves was a good idea; just GLX should have been isolated better.
But isolating GLX now is too much effort.
Not sure why I'm bothering with this at all.
Fixes: #7201 (unconfirmed)
This is necessary to avoid breaking input behaviour in the 'idle'
state when not playing a video. Otherwise, the mouse area starts off
covering the whole window and blocks normal input.
Commit 311cc5b6 added the ability use flags while omitting name, but
broke the case where both name and flags are omitted.
Now omitting either name or flags or both works as documented.
It seems logical to account for the window controls if `boxvideo`
is in use (which has the effect of reducing the size of the video
so that the osc is not covering the video).
This didn't match what is in wscript_build.py. Also, it should work on
non-X11 platforms... probably. (The condition is convoluted and almost
nonsensical, but the offscreen context creation needs to be cleaned up
anyway as soon as other backends, e.g. for win32, are added.)
Properties should handle this themselves. This basically sent redundant
notifications. I found only two places where the "proper" notification
was missing.
Now that the option-to-property bridge is gone, this is not needed
anymore. It always took the "silent" path.
Also, at least as of before this commit, this didn't correctly print a
warning when accessing a deprecated option as property. This was because
m_config_get_co_raw() was used, which intentionally does not print any
warnings, so switch to the non-raw one. (Affects only options that have
.deprecation_message set.)
Probably pretty useless in this form (see: the wall of warnings), but
someone wanted this.
I think this should be useful to perform some automated tests, maybe.
Fixes: #7194
This function always expects the GL struct pointer to be a talloc
allocation. So far so bad. But the terrible thing is that _lots_ of code
in mpv didn't quite get this (including the code which introduced the
way it is used this way). For example, in context_glx.c you see this:
struct priv {
GL gl;
...
GL is not a talloc allocation, but since it's at the start of a talloc
allocation, it works anyway. So far so bad. But the really terrible
thing is that mpgl_load_functions2() calls talloc_free_children() on the
GL pointer, which means that all of priv's. This would be unintentional
and could create dangling pointers. And this happens at the about 1
dozen of callers. I'm amazed it didn't broke yet anywhere.
Removing this anti-pattern with making GL "implicitly" a talloc
allocation would be too much effort at this point. So just manually free
the only allocation that the function attached to GL.
I missed these due to only testing with my personal osc config.
The deadzone needs to be correctly handled for the window controls,
or they will fail to appear when the mouse is close to or over them.
In the process of doing that, I realised that the controls should
respect the barmargin, if set. This is because the controls should
remain aligned when layout=topbar and as the control bar is top
aligned, it should be equally affected if the user needs to set
the barmargin.
I also fixed a mistake in trying to the use the mpv-osd-symbols font
for the window controls.
Should restore full functionality.
The initial state setting is a bit shoddy (instead of setting the
properties before map, we use the WM commands to change it after, so you
will see the normal window state for a moment; the WM commands do not
work on unmapped windows, so fixing this would require more code).
- remove VOCTRL_FULLSCREEN and VOCTRL_GET_FULLSCREEN
- have your own m_config_cache for the fullscreen option
(vo->opts_cache cannot be used because you lose per-option change
notifications, and it'd be a mess anyway)
- use VOCTRL_VO_OPTS_CHANGED to update it
(it's used for convenience)
- when updating it, check for the fullscreen option
(wasn't sure how to do it best; currently, it compares the raw
option pointers, but this could be changed)
- do not send VO_EVENT_FULLSCREEN_STATE on FS change
- instead write the option on FS change
(assign in opt. struct + m_config_cache_write_opt)
Instead of making m_config a special-case, it more or less uses the
underlying m_config_cache/m_config_shadow APIs properly. This makes the
player core a (relatively) equivalent user of the core option API. In
particular, this means that other threads can change core options with
m_config_cache_write_opt() calls (before this commit, this merely led to
diverging option values).
An important change is that before this commit, mpctx->opts contained
the "master copy" of all option data. Now it's just another copy of the
option data, and the shadow copy is considered the master. This is why
whenever mpctx->opts is written, the change needs to be copied to the
master (thus why this commits add a bunch of m_config_notify... calls).
If another thread (e.g. a VO) changes an option, async_change_cb is now
invoked, which funnels the change notification through the player's
layers.
The new self_notification parameter on mp_option_change_callback is so
that m_config_notify... doesn't trigger recursion, and it's used in
cases where the change was already "processed". It's still needed to
trigger libmpv property updates. (I considered using an extra
m_config_cache for that, but it'd only cause problems with no
advantages.)
I think the recent changes actually forgot to send libmpv property
updates in some cases. This should fix this anyway. In some cases,
property updates are reworked, and the potential for bugs should be
lower (probably).
The primary point of this change is to allow external updates, for
example by a VO writing the fullscreen option if the window state is
changed by the window manager (rather than mpv changing it). This is not
used yet, but the following commits will.
Goes in line with the recent changes to always checking for option value
changes. The player core will use this to determine whether it should
send additional change events.
Just an implementation detail that can be cleaned up now. Internally,
m_config maintains a tree of m_sub_options structs, except for the root
it was not defined explicitly. GLOBAL_CONFIG was a hack to get access to
it anyway. Define it explicitly instead.
The original MPlayer m_config was essentially only responsible for
handling some command line parsing details, handling profiles, and
file-local options. And then there's the new mpv stuff (that stuff was
regretfully written by me), which is mostly associated with making
things thread-safe (includes things like making it all library-safe,
instead of stuffing all option data into global variables).
This commit tries to separate them some more. For example,
m_config_shadow (the thread-safe thing) now does not need access to
m_config anymore. m_config can hopefully be reduced to handling only the
"old" mplayer-derived mechanisms.
This will allow any other threads to write to the global option data in
a safe way.
The typical example for this is the fullscreen option, which needs to be
written by VO (or even some other thing running completely separate from
the main thread). We have a complicated and annoying contraption which
gets the value updated on the main thread, and this function will help
get rid of it.
As of this commit, this doesn't really work yet, because he main thread
uses its own weird copy of the option data.
This adds m_config_cache_get_next_changed() and the change_flags field
in m_config_cache. Both can be used to determine whether specific
options changed (rather than the entire sub-group).
Not sure if I'm very happy with that. The former rather compact
update_options() is now a bit of a mess, because it needs to be
incremental. m_config_cache_get_next_changed() will not be too nice to
use, and change_flags still relies on global "allocation" of change
flags (see UPDATE_* defines in m_option.h). If C weren't such a
primitive language that smells like grandpa, it would be nice to define
per-option change callbacks or so.
This compares options by value to determine whether they have changed.
This makes it slower in theory, but in practice it probably doesn't
matter (options are rarely changed after initialization). The
alternative would have been per-option change counters (wastes too much
memory; not a practical problem but too ugly), or keep all
m_config_caches in a global list and have bitmaps with per-option change
bits (sounds complicated). I guess the current way is OK.
Technically, this changes semantics slightly by ignoring setting an
option to the same value. Technically this wasn't a no-op, although the
effect was almost almost no-op. Some code would actually become cleaner
by ignoring such redundant change events, and them being no-op is
probably also what the user would normally assume.
Create a separate struct for internal fields of m_config_cache, so API
users can't just mess with stuff they shouldn't access.
Move the ts field out of m_config_data, so we don't need unnecessary
atomics in one case.
This is just preparation, and shouldn't change any behavior.
The exact type name (m_obj_list_t) was removed in 2013. I don't think
this stub comment helps much with understanding this complicated thing
anyway (this code is for the --vf/--af options, and makes up almost half
of m_option.c).
This is used to detect whether any filters were changed. This code was
essentially ported to m_option.c.
One possible difference is how the old code did name comparison. It did
not actually compare the name (!?!?), so this might change behavior,
hopefully to the better.
Today, if window decorations are not present, either because they were
disabled, or because the platform doesn't support them
(eg: gnome-shell on wayland), there are no window controls, meaning it
is not possible to minimize/maximize/close a window without knowing
keyboard shortcuts.
While you can imagine various ways of offering client side decorations,
it is attractive to consider using OSC because that is functionality
that we already have.
The main work here is defining a separate input area from the main
OSC box with its own buttons, etc.
While we could probably handle auto-detection based on whether
decorations are present or not, it's manually controlled for now.
The window control logic is mostly disconnected from the OSC itself,
except in the case of the `topbar` layout, where there has to be
coordination so that the controls don't get drawn on top of each other.
I had to do fine-positioning of the buttons based on the font on
my system, so don't be surprised if it looks wrong elsewhere.
You could also argue that window controls should be unscaled, even
if the main OSC box is scaled, but I've not tried to do this.
We primarily care about pseudo-decorations for wayland, where
the compositor may not support server-side decorations. So let's
implement the minimize and maximize commands and return the
maximized window state.
If we want to implement window pseudo-decorations via OSC, we need a
way to tell the vo to minimize and maximize the window. Today, we have
minimized as a read-only property, and no property for maximized.
Let's made minimized settable and add a maximized property to go with
it. In turn, that requires us to add VOCTRLs for minimizing or
maximizing a window, and an additional WIN_STATE to indicate a
maximized window.
At least with gnome-shell (I know, I know), the compositor does
not provide the old window size when leaving the maximized state.
Instead, we get a toplevel_config event with a 0x0 size and no
additional states.
Today, we already save the window geometry to restore it when leaving
the fullscreen state, so we just need a small change for it to
kick in for leaving the maximized state. If I read this correctly,
we'll still respect the size passed by a compositor that actually
provides the old size.
Rather than hard-coding the edge grab zone width, we can make it
user configurable. It seems worthwhile to have separate configs
for pointer and touch usage as the defaults should be different,
and a user might have both input methods in use.
Today, we support resizing wayland windows when we detect a touch
event in a defined grab zone. As part of implementing
pseudo-decorations, we should have equivalent functionality for
mouse input. And if we detect support for actual decorations we
will not activate the grab zone as the decorations will provide this.
Use x11->opts instead of vo->opts. This doesn't matter currently, and
x11->opts is actually set to vo->opts. However, there's a chance that
either option access changes, or that the way backends integrate with
struct vo changes. This is just a preemptive change to make this less of
a mess, and it's generally a good idea to reduce accesses to struct vo
anyway.
The previous bunch of commits made this unnecessary, so this should be
a purely internal change with no user impact.
This may or may not open the way to future improvements. Even if not,
at least the property/option interaction should now be much less buggy.
Convert some remaining properties to work without the option-to-property
bridge. Behavior shouldn't change (except for the corner case that it
tries to reapply the new state when setting a property, while it used to
ignore redundant sets).
As it is the case with many of these changes, much of the code is not in
its final proper state yet, but is rather a temporary workaround. For
example, these "VO flag" properties should just be fully handled in the
VO backend. (Currently, the config or VO layers don't provide enough
mechanism yet as that all the backends like x11, win32, etc. could be
changed yet, but that's another refactoring mess for another time.)
Now nothing relies on this option-to-property bridge anymore, which
opens the way to even more refactoring, which eventually may result in
tiny improvements for the end user.
Until now, using a filter not in mpv's builtin filter list would assume
it's a libavfilter filter. If it wasn't, the option value was still
accepted, but creating the filter simply failed. But since this happens
after option parsing, so the result is confusing.
Improve this slightly by checking filter names. This will reject truly
unknown filters at option parsing time. Unfortunately, this still does
not check filter arguments. This would be much more complex, because
you'd have to create a dummy filter graph and allocate the filter. Maybe
another time.
The behavior is slightly different in a messy way. The change is in line
with the option-to-property bridge removal mentioned some commits ago
and thus is deemed necessary.
This attempted to restore the old filter chain if setting a new one at
runtime failed. This is not needed anymore, because changing the filter
chain is done in a "transactional" way now.
When changing filters at runtime (vf/af commands/properties), this could
crash due to a NULL pointer access. The code for comparing the old and
new option values (to detect changes) was simply buggy.
This function is dangerous, because it disables the already basic/week
type checking the option system has at all. I'm tend towards thinking
that all of its uses should be replaced.
This is preparation to get rid of the option-to-property bridge
(mp_on_set_option). This is a pretty insane thing that redirects
accesses to options to properties. It was needed in the ever ongoing
transition from something to... something else.
A good example for the need of this bridge is applying profiles at
runtime. This obviously goes through the config parser, but should also
make all changes effective, for which traditionally the property layer
is used.
There isn't much left that needs this bridge. This commit changes a
bunch of options (which also have a property implementation) to use
option change notifications instead. Many of the properties are still
left, but perform unrelated functions like OSD formatting.
This should be mostly compatible. There may be some subtle behavior
changes. For example, "hwdec" and "record-file" do not check for changes
anymore before applying them, so writing the current value to them
suddenly does something, while it was ignored before.
DVB changes untested, but should work.
These properties actually were removed/replaced, so there is no conflict
with the options of the same name anymore. For example, there is no
"audio-file" property anymore, but you still can set "audio-files" (and
--audio-file simply maps to --audio-files-append).
add_key_binding() makes the name argument optional (in weird Lua
fashion), which did not work if there were additional arguments. So
there is no way to avoid specifying a name while passing a rp argument.
Fix this, declare this way of skipping the argument as deprecated, and
allow passing name=nil as the preferred way to skip the name argument.
Handling the window with this function makes no sense, since windows
and kernels are not the same thing and don't share the same option list.
The only reason it's done is to make sure the char* points at the static
string rather than the dynamically allocated one, which we can do
manually in this function. Rewrite a bit for clarity/quality.
This is supposed to turn input.conf comments into inline documentation.
Whether this will be useful depends on whether there'll be a script
using this field.
This changes a small aspect of input.conf parsing fundamentally: this
attempts to strip comments/whitespace from the command string, which
will later be used to generate the command when a key binding is
executed. This should not have any negative effects, but there could be
unknown bugs. (For some reason, every command is parsed when input.conf
is parsed, but it still only stores the string for the command. I guess
that saves some minor amount of memory.)
Read-only information about all bindings. Somewhat hoping someone can
make a nice GUI-like overlay thing for it, which provides information
about mapped keys.
No reason to have this as bstr, just makes everything more complex.
Also clear mp_cmd.sender when it's copied. Otherwise it would be a
dangling pointer. Apparently it's never set to non-NULL in this
situation, but this is cleaner anyway.
Should be without consequences. I think this is less trouble, because
code frequently wants to add/remove bits for modifiers and key state
from key codes, and with this change you can't accidentally break it by
testing or removing bits from the old -1 value.
It did that because there was no other way. It used a lock-free ring
buffer, which does not support this. Use a "manual" ring buffer with
explicit locks instead, and drop messages from the start.
(We could have continued to use mp_ring, but it was already too late,
and although mp_ring is fine, using it for types other than bytes looked
awkward, and writing a ring buffer yet again seemed nicer. At least it's
not C++, where mp_ring would have been a template, and everything would
have looked like shit soup no matter what.)
In the referenced commit, I forgot about this part, and a client which
tried to use this was actually not woken up when needed.
(Also why the hell does the subject line of that commit say "removed"?)
Fixes: 8c2d73f112
Particularly for "any_unicode" mappings, so they don't have to
special-case keys like '#' and ' ', which are normally mapped to
symbolic names for input.conf reasons. (Though admittedly, this is a
pretty minor thing, since API users could map these manually.)
The key is never nil if it's invoked through the normal input path. The
key name could be "" if mp_cmd.key_name==NULL. This should not happen,
but there's no strong guarantee in input.c that it cannot happen, so
whatever.
The intended target for this is the mpv.repl script, which manually
added every single ASCII key as a separate key binding. This provides a
simpler mechanism, that will catch any kind of text input.
Due to its special nature, explicitly do not give a guarantee for
compatibility; thus the warning in input.rst.
I often watch sporting events. On many occasions I get files with the
same filename for each session. For example, for F1 I might have the
following directory structure:
F1/
FP1.mkv
FP2.mkv
FP3.mkv
Qualification.mkv
Race.mkv
Since usually one simply watches one race after the other, I usually
just rsync the new event's files over the old ones, so, for example,
Race.mkv will be replaced from the file for the last event with the file
from the new event.
One problem with this is that I like to use --resume-playback for other
kinds of media, so I have it on by default. That works great for, say, a
movie, but doesn't work so well with this scheme, because you can
trivially forget to pass --no-resume-playback on the command line and
end up 2 hours in, watching spoilers as the race results scroll down the
screen :-)
This patch adds a new option, --resume-playback-check-mtime, which
validates that the file's mtime hasn't changed since the watch_later
configuration was saved. It does this by setting the watch_later
configuration to have the same mtime as the file after it is saved.
Switching back and forth between checking mtime and not checking mtime
works fine, as we only choose whether to compare based on it, but we
update the watch_later configuration mtime regardless of its value.
These were a bad idea and are obscure. Scripting key mapping support
still uses them, but this is not relevant to scripting authors, because
the mpv provided helper code (defaults.lua) takes care of this. In
addition, the OSC uses a legacy form of this.
Hopefully, this input section stuff can be removed, and replaced by a
simpler mechanism.
As preparation for making repl.lua part of the core (maybe), add some
mechanisms which are supposed to improve its behavior.
Add a silent mode. Calling mpv_request_log_messages() with the log level
name prefixed with "silent:" will disable logging from the API user's
perspective. But it will keep the log buffer, and record new messages,
without returning them to the user. If logging is enabled again by
requesting the same log level without "silent:" prefix, the buffered log
messages are returned to the user at once. This is not documented,
because it's far too messy and special as that I'd want anyone to rely
on this behavior, but it will be perfectly fine for an internal script.
Another thing is that we record early startup messages. The goal is to
make the repl.lua script show option and config parsing file errors.
This works only with the special "terminal-default" log level.
In addition, reduce the "terminal-default" capacity to only 100 log
messages. If this is going to be enabled by default, it shouldn't use
too much resources.
This will just make it not work if mpv_request_log_messages() gets
extended to accept more names. Pass the argument without checking.
To keep the behavior the same (for whatever reasons, probably not
important), still raise an error if the libmpv API function returns an
error that the argument was bad.
(The check_loglevel() function is still used when the script _emits_ log
messages, which is different, and for which there is no API anyway.)
We should only be printing errors that occur when not probing, to
avoid creating the impression that something is wrong - and errors
during probing isn't a problem.
Until now, this didn't work, since the external image had pts 0; so
enabling video at a later time did nothing, because the image was
discarded. Since hrseek now ends on the last frame (instead of nothing),
reusing the hrseek mechanism solves this, and we don't even need to
treat the cursed coverart case separately.
If SEEK_FORWARD is set, a demuxer should skip to the next frame if the
timestamp does not fall on the start of a frame. If that flag is not
set, it should always seek to the first frame before the target
timestamp (or the first frame in the file).
See what the added code comment says. Normally when this is needed, it's
the cover art case. But this flag is not set when using an external
image. This gives weird seek behavior, because the frame will be
"normally" displayed for its determined duration, and during normal
video playback, the video pts will be used - which is always 0 here.
This should happen only if audio is active. Otherwise, we're more or
less in image viewer mode, where the image should be displayed for a
configured duration.
This gives much better behavior in general, and is what we want if video
somehow ends earlier than audio.
A common special is using an audio file with an external image file.
This commit makes things like switching aspect ratio work (provided the
demuxer for the image behaves correctly, which currently isn't the case
with demux_mf.c). Since the image file had timestamp 0, it was usually
skipped by hr-seek, and changed properties weren't applied to it at the
start of the filter chain.
This wasn't done, probably regression from one of the last dozen of
times this special code path was touched. This meant coverart images
ignored the user-set aspect ratio completely, and some other things.
Surprisingly, we've managed to get this far without context_glx ever
adding the X11 display as a native resource. But with the recent change
to attempt to enable vdpau when using EGL, the hwdec now requires the
display to be added. So let's add it.
eglGetPlatform() is a broken API, since it takes a windowing specific
argument, yet is supposed to work for multiple APIs at the same time. On
Linux, it can take both a X11 "Display" and a "wl_display". Obviously
there is no way to specify what kind of display the argument is (it's
just a void*).
Mesa has _eglNativePlatformDetectNativeDisplay, which does funny stuff
to try to guess the display type, including trying to call mincore() to
determine whether the pointer can be accessed at all. I guess this
recently accidentally broke (as a bug), but on the other hand, maybe
it's time to do this properly.
The fix is using eglGetPlaformDisplay(). This requires EGL 1.5, plus
Mesa needs to support the associated platform extension
(EGL_KHR_platform_x11).
Since I see no reasonable way to do this in a compatible way, just
require that EGL 1.5 is available. The problem is that EGL 1.4 seems to
require you to create a display to query EGL version and extension, and
you have a chicken-and-egg problem. It's very stupid. Maybe you could
jump through some more hoops to get something compatible, but fuck that.
Users on "too old" Mesa will fall back to GLX (which we keep around for
a regrettable company known by the name of Nvidia).
I think Wayland and GBM should do the same. They're sufficiently
bleeding-edge that you can expect them to have EGL 1.5. On the other
hand, the cursed RPI code will have to stay with a eglGetDisplay().
Speculative fix for #7154.
(Rant about EGL follows. Actually I deleted it.)
pass_color_map() (in video_shaders.c) and pass_colormanage() (video.c)
both duplicate the condition on whether to do peak computation. Peak
computation requires a compute shader, so if the duplicated conditions
don't match, video_shaders.c will generate a compute shader, but video.c
will try to run it as fragment shader. This leads to a "blue screen".
This can be reproduced by playing a HDTV video with --target-peak=99.
It's not clear how to fix this. Should pass_tone_map() be only invoked
if mp_trc_is_hdr() == true (what pass_colormanage() uses to decide
whether to enable peak computation), or should pass_colormanage() just
tell pass_color_map() to skip peak computation? Decide for the latter,
as it's more robust.
Even if not correct, at least it gets rid of the blue shit.
Fixes: #7149
It's too easy to introduce unintended circular lock dependencies. Just
now we found that the (old) cocoa vo_gpu backend is also affected by
this, because it waits on the Cocoa main thread, which in turn uses
libmpv API for OSX... stuff.
Also fix a missing initial property update after observe.
This leaves me unhappy, because it just leads to a stupid thread ping
pong. Will probably rewrite this later.
Give an overview over the various methods. I feel like I've written text
like this over and over again (compatibility.rst and
interface-changes.rst for example duplicate the list of mpv API
abstractions), but such is life in hell.
Use this in particular to strongly suggest not to parse terminal output.
This suggestion got lost or de-emphasized at some point (maybe when
removing MPlayer and "slave mode" references). Some of this text is
still there, but it can be considered "fine print" at best, that nobody
will see. Now we have it in a more prominent place. This is especially
important since MPlayer-style use of mpv still seems to be prevalent,
see for example #7153.
I have no idea why this still exists, since we have --input-ipc-server.
I think there was something about Windows, but the latter option is
implemented even on Windows.
It appears commit 4ad68d9452 broke handling the first video
frame duration through roundabout ways (I think because the duration of
the first frame was now available at all in the normal case). The first
frame was cut short, which showed up especially with looping, or if the
file had a low FPS.
This questionable change seems to fix it without breaking any other
known cases => push and call it a day.
The display-sync mode did not have this problem.
Fixes: #7150
It sometimes happens that HLS streams freeze because the HTTP server is
not responding for a fragment (or something similar, the exact
circumstances are unknown). The --timeout option didn't affect this,
because it's never set on HLS recursive connections (these download the
fragments, while the main connection likely nothing and just wastes a
TCP socket).
Apply an elaborate hack on top of an existing elaborate hack to somehow
get these options set. Of course this could still break easily, but hey,
it's ffmpeg, it can't not try to fuck you over. I'm so fucking sick of
ffmpeg's API bullshit, especially wrt. HLS.
Of course the change is sort of pointless. For HLS, GET requests should
just aggressively retried (because they're not "streamed", they're just
actual files on a CDN), while normal HTTP connections should probably
not be made this fragile (they could be streamed, i.e. they are backed
by some sort of real time encoder, and block if there is no data yet).
The 1 minute default timeout is too high to save playback if this
happens with HLS.
Vaguely related to #5793.
There isn't really a need to disable this for local playback. I think
originally I did this because I was afraid the code could mess up or be
annoying on local mode, but that's not really a good argument. I'd
rather test this code in local mode too. In this case, it shouldn't
really happen that it runs out of cache in the first place.
Until now, we've made FFmpeg use the default network timeout - which is
apparently infinite. I don't know if this was changed at some point,
although it seems likely, as I was sure there was a more useful default.
For most use cases, a smaller timeout is more useful (for example
recording something in the background), so force a timeout of 1 minute.
See: #5793
stream_skip() semantics were kind of bad, especially after the recent
change to the stream code. Forward stream_skip() calls could still
trigger a seek and fail, even if it was supposed to actually skip data.
(Maybe the idea that stream_skip() should try to seek is worthless in
the first place.)
Rename it to stream_seek_skip() (takes absolute position now because I
think that's better), and make it always skip if the stream is marked as
forward.
While we're at it, make EOF detection more robust. I guess s->eof
shouldn't exist at all, since it's valid only "sometimes". It should be
removed... but not today. A 1-byte stream_read_peek() call is good to
get the s->eof flag set to a correct value.
This makes the condition for including each init match the condition for
compiling the file that defines it.
It's possible to e.g. HAVE_GL and HAVE_VAAPI without HAVE_VAAPI_EGL,
which resulted in "undefined reference to `vaapi_gl_init'" with the old
code.
Used to contain flags for "save" setting of options at runtime. Now
there is nothing special needed anymore and it's 0. So drop it
completely, and remove anything that distinguishes between runtime and
initialization time.
Options marked with this flag were changed to strictly read-only after
initialization (mpv_initialize() in the client API, after option parsing
and config file loading with the CLI player).
This used to be necessary, because there was a single option struct that
could be accessed by multiple threads. For example, --config-dir sets
MPOpts.force_configdir, which was read whenever anything accessed the
mpv config dir (which could be on different threads, e.g. font
initialization tries to lookup fonts.conf from an arbitrary thread).
This isn't needed anymore, because threads now access these in a thread
safe way. In the case of --config-dir, the path is actually just copied
on init.
This M_OPT_FIXED mechanism is thus not strictly needed anymore. It still
prevents writing to some options that cannot take effect at runtime, but
even that can be dropped. In general, all mpv options can be changed any
time at runtime, even if they never take effect, and there's no need to
make an exception for a very low number of options. So just get rid of
it.
It's hard to see what FFmpeg does or what its API requires. It looks
like the alignment in our own allocation code might be slightly too
lenient, but who knows. Even if this is not needed, upping the alignment
only wastes memory and doesn't do anything bad.
(Note that the only reason why we have our own code is because FFmpeg
doesn't even provide it as API. API users are forced to recreate this,
even if they have no need for custom allocation!)
The "amultiply" filter crashes in AVX mode on unaligned access if an
audio pointer is unaligned (on 32 or 64 bytes I assume).
A requirement that audio data needs to be aligned isn't documented
anywhere. In our case, the data is still sample- and channel-aligned,
which is completely sane. Sure, you can imagine optimizations which make
some algorithms even faster by requiring higher alignment. But, and this
is a big but, you shouldn't crash api users because you just invented a
new undocumented requirement. And even more importantly, your
user-crashing optimization won't matter because it's just a trivial
algorithm working on audio. You don't need to pretend to be an
optimization devil, and nobody will give you a prize for this. But no,
lets random make API users crash (and then probably blame them for it!)
for something that wouldn't matter at all.
Not to mention that they do "document" some requirements on _video_
data, yet their vf_crop probably can still produce unaligned video
pointers. Oh how hilarious that the same documentation also talks about
libswscale alignment requirements. (This is weird because libswscale is
just one of many, many things which consume video data. Also did you
know that zimg, written in C++ and using intrinsics, i.e. the antithesis
to FFmpeg development, is much faster than libswscale, easier to use,
and produces more correct results, even if you ignore that libswscale
flat out doesn't support some very important features?)
Fucking tired of this bullshit. Can't wait until someone comes up with a
better framework than this... (well let's not write this out).
Fix this by copying instead of adjusting the start pointer when skipping
samples. This makes general operations slower just to fix interoperating
with a single filter. Thank you for your "optimization", FFmpeg. Go die
in a fire.
Didn't check whether this is correct. It probably is? If the frame needs
to be copied (due to COW), and memory allocation fails, it just silently
(or audibly lol) doesn't skip samples, because a never-fail function can
suddenly fail. Well, who cares.
Fixes: #7141
Probably. It's not like these pixel formats are formally specified -
FFmpeg added them because _some_ file format or decoder supports it, and
while that format/codec may define it precisely, the pixel format is
sort of disconnected and just a FFmpeg thing.
In any case, the yuva sample I had at hand uses the full range the
component data type can provide. The old code used the same "shifted"
range as for Y/U/V components, which must have been wrong.
This will not work correctly for packed YUVA formats, but fortunately
they matter even less.
It's not that we _want_ the log to be on an external site. We just want
the log, somehow. Probably not pasted inline into the issue text.
Also reword the "we are assholes who really want logs" part of the text.
It's a subtle balance between trying to be nice and being a complete
asshole, but no matter what you do, it will always sound like the
latter, so be direct.
This tests the RGB repacker code in zimg, which deserves to be tested
because it's tricky and there will be more formats.
scale_test.c contains some code that can be used to test any scaler. Or
at least that would be great; currently it can only test repacking of
some byte-aligned-component RGB formats. It should be called
repack_test.c, but I'm too lazy to change the filename now.
The idea is that libswscale is used to cross-check the conversions
performed by the zimg wrapper. This is why it's "OK" that scale_test.c
does libswscale calls.
scale_sws.c is the equivalent to scale_zimg.c, and is of course
worthless (because it tests libswscale by comparing the results with
libswscale), but still might help with finding bugs in scale_test.c.
This borrows a sorted list of image formats from test/img_format.c, for
the same reason that file sorts them.
There's a slight possibility that this can be used to test vo_gpu.c too
some times in the future.
This is fragile enough that it warrants getting "monitored".
This takes the commented test program code from img_format.c, makes it
output to a text file, and then compares it to a "ref" file stored in
git.
Originally, I wanted to do the comparison etc. in a shell or Python
script. But why not do it in C. So mpv calls /usr/bin/diff as a
sub-process now.
This test will start producing different output if FFmpeg adds new pixel
formats or pixel format flags, or if mpv adds new IMGFMT (either aliases
to FFmpeg formats or own formats). That is unavoidable, and requires
manual inspection of the results, and then updating the ref file.
The changes in the non-test code are to guarantee that the format ID
conversion functions only translate between valid IDs.
Defining NDEBUG via CFLAGS is the canonical way to disable assertions in
C. mpv respects this (and ta.c actually disables some debugging
machinery if it's defined).
But for tests, this is not useful at all. So if --enable-tests is passed
to configure, the user must not define NDEBUG, even if the rest of the
player does not care.
(We could just #undef NDEBUG, but let's not. Tests calling into the rest
of the player might depend on asserts there, or so.)
This stopped doing anything since how many years?
The only actual effect was that af_rubberband was made GPL only. Now it
is available in LGPL builds too.
Until now, each .c file in test/ was built as separate, self-contained
binary. Each binary could be run to execute the tests it contained.
Change this and make them part of the normal mpv binary. Now the tests
have to be invoked via the --unittest option. Do this for two reasons:
- Tests now run within a "properly" initialized mpv instance, so all
services are available.
- Possibly simplifying the situation for future build systems.
The first point is the main motivation. The mpv code is entangled with
mp_log and the option system. It feels like a bad idea to duplicate some
of the initialization of this just so you can call code using them.
I'm also getting rid of cmocka. There wouldn't be any problem to keep it
(it's a perfectly sane set of helpers), but NIH calls. I would have had
to aggregate all tests into a CMUnitTest list, and I don't see how I'd
get different types of entry points easily. Probably easily solvable,
but since we made only pretty basic use of this library, NIH-ing this is
actually easier (I needed a list of tests with custom metadata anyway,
so all what was left was reimplement the assert_* helpers).
Unit tests now don't output anything, and if they fail, they'll simply
crash and leave a message that typically requires inspecting the test
code to figure out what went wrong (and probably editing the test code
to get more information). I even merged the various test functions into
single ones. Sucks, but here you go.
chmap_sel.c is merged into chmap.c, because I didn't see the point of
this being separate. json.c drops the print_message() to go along with
the new silent-by-default idea, also there's a memory leak fix unrelated
to the rest of this commit.
The new code is enabled with --enable-tests (--enable-test goes away).
Due to waf's option parser, --enable-test still works, because it's a
unique prefix to --enable-tests.
The use of glXGetCurrentDisplay() restricted this to the GLX backend.
But actually it works under EGL as well. Removing the GLX-specific call
and using the general mpv-internal method to get the X "Display" makes
it work in mpv.
I didn't know this. Nvidia didn't list this as extension in the EGL
context when I still used their GPUs.
Note that this might in theory break use of vdpau in some libmpv clients
using the render API. But only if MPV_RENDER_PARAM_X11_DISPLAY is not
used, and they relied on mpv using glXGetCurrentDisplay(). EGL does not
provide such an API, and hwdec_vaapi.c also uses what hwdec_vdpau.c uses
now. Considering that vaapi is preferable these days, it's not bad at
all if these clients get "broken". They can be easily fixed by passing
the display to mpv correctly.
Some stream inputs may have higher latency with higher buffer sizes, for
example network filesystems via normal OS filesystem interface (these
have to wait until the full buffer is read, which means higher latency).
Probably doesn't matter in practice, but why take chances.
It was set, but its value was never used. The stream cache used to use
it, but it was removed. It controlled how much data it tried to read
from the underlying stream at once.
The user can now control the buffer size with --stream-buffer-size,
which achieves a similar effect, because the stream will in the common
case read half of the buffer size at once. In fact, the new default size
is 128KB, i.e. 64KB read size, which is as much as stream_file and
stream_cb requested by default. stream_memory requested more, but it
doesn't matter anyway. Only stream_smb set a larger size with 128KB.
The dvdnav API reads in 2K blocks (dvdnav_get_next_block()). The mpv
wrapper (fill_buffer() in this file) expects that the read size done by
the mpv core is at least 2K for this reason. If not, it returns an
error.
This used to be OK, because there was a thing called section alignment
in the core code. This was removed because the core shouldn't suffer
from optical disc idiosyncrasies. Which means that ever since, it has
been working only by coincidence, or maybe not at all.
Fixing this would require keeping a buffer in the priv struct, and
returning it piece by piece if the core makes smaller reads. I have no
intention of writing such code, so add an error message asking for a
patch. If anyone actually cares about DVD, maybe it'll get fixed.
This isn't really needed, since it doesn't support byte seeking (only
for avoiding that demux_disc fucks up even more if the nested demux_lavf
tries to seek in the TS).
stream_read_peek() duplicated what stream_read_more() checks for anyway
(whether the forward buffer is large enough). This can be skipped by
making the stream_read_more() return value more consistent.
demux_mkv was the only thing using this, and everything else accessed it
directly. No need to keep the indirection wrapper around.
(Funny how this getter was in the initial commit of MPlayer.)
For some reason, the first frame displayed on X11 with amdgpu and OpenGL
will be garbled. This is especially visible if the player starts,
displays a frame, but then still takes a while to properly start
playback.
With --interpolation, the behavior somehow changes (usually gets worse).
I'm not sure what exactly is going on, and the code in video.c is way
too abstruse. Maybe there is some slight possibility that a frame with
uncleared contents gets displayed, which somehow also corrupts another
frame that is displayed immediately after that.
If clear is unconditionally run, this somehow doesn't happen, and you
see a video frame. By any logic this shouldn't happen: a video frame
should always overwrite the background. So I can't exclude that this
isn't some sort of driver bug, or at least very obscure interaction.
Clearing should be practically free anyway, so always do it.
Fixes: #7105
(Only half of the buffer is actually used in a useful way, see manpage
or commit which added the option.)
Might have some advantages with broken network filesystem drivers.
See: #6802
Was probably worthless, and I can't measure a difference anymore (I used
to be able and it still seemed worth doing so back then).
When the default buffer size is enlarged in the next commit, the inline
buffer probably won't even be useful in theory, because the data will
rarely be on the same page as the other stream fields. It surely makes
the inline buffer seem like a ridiculous micro-optimization. Farewell...
In some corner cases (see #6802), it can be beneficial to use a larger
stream buffer size. Use this as argument to rewrite everything for no
reason.
Turn stream.c itself into a ring buffer, with configurable size. The
latter would have been easily achievable with minimal changes, and the
ring buffer is the hard part. There is no reason to have a ring buffer
at all, except possibly if ffmpeg don't fix their awful mp4 demuxer, and
some subtle issues with demux_mkv.c wanting to seek back by small
offsets (the latter was handled with small stream_peek() calls, which
are unneeded now).
In addition, this turns small forward seeks into reads (where data is
simply skipped). Before this commit, only stream_skip() did this (which
also mean that stream_skip() simply calls stream_seek() now).
Replace all stream_peek() calls with something else (usually
stream_read_peek()). The function was a problem, because it returned a
pointer to the internal buffer, which is now a ring buffer with
wrapping. The new function just copies the data into a buffer, and in
some cases requires callers to dynamically allocate memory. (The most
common case, demux_lavf.c, required a separate buffer allocation anyway
due to FFmpeg "idiosyncrasies".) This is the bulk of the demuxer_*
changes.
I'm not happy with this. There still isn't a good reason why there
should be a ring buffer, that is complex, and most of the time just
wastes half of the available memory. Maybe another rewrite soon.
It also contains bugs; you're an alpha tester now.
This is something relatively frequently needed, and there must be half a
dozen ad-hoc implementations in mpv. The next commit uses this, the
suspected duplicate implementations are hiding.
The old code made it depend on ->seekable. If it isn't seekable, and
something discarded the data, then it'll just show an error message,
which will at least be somewhat informative. If no data was discarded,
the seek call is always a no-op.
There's a weird "timeline" condition in the old code; this doesn't
matter anymore, because timeline stuff does not pass streams down to
nested demuxers anymore.
tv:// and pvr:// are gone, DVD almost. The former didn't really have any
uses left, except webcams. Provide a replacement example for that.
We don't need a separate section for DVD. If you use DVD, you're on your
own. There's still enough documentation left to puzzle things together
even if you don't read the source code.
Not like anyone reads it. Although putting all this text before listing
the allowed option values sort of has the intention to discourage users
from using the option at all. Advertise Ctrl+h, which is a decent way of
enabling hardware decoding temporarily.
They were used at some point, but then fell into disuse. In general,
these old flags are all a bit fuzzy, so it's a good idea to remove them
as much as possible.
The comment about MP_IMGFLAG_PAL isn't true anymore. The old meaning was
deprecated at some point, and the flag was removed from "pseudo
paletted" formats. I think mpv at one point changed its own flag from
AV_PIX_FMT_FLAG_PSEUDOPAL to AV_PIX_FMT_FLAG_PAL, when the former was
deprecated, and it became unnecessary to allocate a palette for
non-paletted formats. (The one who deprecated in FFmpeg was me, if you
wonder.)
MP_IMGFLAG_PLANAR was used in command.c, use a relatively similar flag
as replacement.
This is slightly helpful for testing, and otherwise useless and without
consequence.
I'm not using the correct output format and using IMGFMT_RGB0 as
placeholder. This doesn't matter currently, as both sws and zimg support
this as output (and support any input for it). I'm doing this because
it's surprisingly tricky to get the correct output format at this point,
without digging deeper into x11 shit or refactoring parts of the VO. I
don't care enough about this.
The user can raise the number of tolerated hardware decoding errors. On
the other hand, we have a static limit on packets that are "saved" for
fallback handling (and that's a good idea to avoid unbounded memory
usage). In this case, it could happen that the start of a file was fine
after a fallback, but after that buffered amount of data, it would
suddenly skip.
It's more useful to skip buffering entirely if the number of tolerated
decoding errors exceeds the fixed buffer.
(And also, I'm sure nobody gives a shit about this feature.)
prepare_decoding() returned a bool that was supposed to tell whether
decoding could work, or if something was fucked. After recent changes to
the decoder loop, this did not work anymore, and caused an endless loop.
Redo it, so it makes more sense. avctx being NULL (software fallback
initialization failed) now signals EOF. hwdec_failed needs to be handled
on send_packet() only, where it probably never happens anyway.
(Who was the idiot who made libavcodec have two entrypoints for
decoding? Oh right, it was me. PEBKAC.)
Shovel the code around to make the data flow slightly simpler (?). At
least there's only one send_packet function now. The old code had the
problem that send_packet() could be called even if there were queued
packets; due to sending the queued packets in the receive_frame
function, this should not happen anymore (the code checking for this
case in send_packet should normally never be called).
Untested with actual full stream hw decoders (none available here); I
created a test case by making hwaccel decoding fail.
Forgotten in commit 5d5fdb7. This failed to return the error code
properly. In particular, if the decoder rejected the packet, this was
not properly detected. Normally, this mattered only in specific cases.
Fixes: #7115
MPlayer isn't all too well-known anymore. It does not make sense to
"advertise" with it (and it actually never did).
The GPU comment needed clarification. I think originally, it was just to
signal that you'll have a bad time with Intel. Make that broader.
Instead, use a YUV planar format. It doesn't matter, since we use the
format only internally and for "management" purposes. We're only
interested in the physical layout, not what colorspace FFmpeg "forcibly"
associates with it.
Also get rid of using the old and slightly sketchy mp_imgfmt_find()
function. Yep, the IMGFMT_RGB30 now "constructs" the planar format,
instead of using a pixfmt constant. Slightly inconvenient, tricky, and
fragile, but I like it, so bugger off.
This whole thing gets rid of some of the strange plane permutations that
were needed earlier.
According to the definition of the GL format, and the definition in
img_format.h, and the actual output by vo_gpu, the order of components
was probably wrong. It's exceedingly likely that the vo_drm format (for
which this was originally written) has the same layout, so this was
probably a bug from when the zimg wrapper code was refactored.
This was too hardcoded to libswscale. In particular, IMGFMT_RGB30 output
is only possible with the zimg wrapper, so the context needs to be taken
into account (since this depends on the --sws-allow-zimg option
dynamically). This is still slightly risky, because zimg currently will
still fall back to swscale in some cases, such as when it refuses to
initialize the particular color conversion that is requested.
f_autoconvert.c could actually handle this better, but I'm tool fucking
lazy right now, and nobody cares anyway, so go away, OK?
This integrates it as "special" format, with no alpha component, as the
equivalent IMGFMT_RGB30 isn't meant to contain any.
Nothing can produce this format in the video chain yet, so the next
commits are needed to make this actually work.
Sometimes the atlas can get so large that it exceeds the maximum allowed
size for an mp_image. Since the atlas will never shrink naturally, this
breaks subtitles entirely until mpv is restarted. Reset the packer so
that subtitles can rendered properly once the atlas fits again.
This is a partial workaround for #6286.
The statement about the display FPS is outdated by several years.
"audio"-sync mode does not use the display FPS anymore, and that it's
X11 only also isn't true anymore.
These modes have separate implementations for audio and display video
sync. modes, so the explanations are separate.
Why the hell are users playing around with this anyway? The explanations
are probably too special to make sense for anyone who doesn't know the
code (and who knows the code doesn't need them anyway), but whatever.
This is mostly just because of the odd RGB default gamma issue, which
shouldn't have any real impact. This also sets allow_approximate_gamma,
which I hope is fine for normal use cases.
Normally, the Y plane can just be passed directly to zimg, and only the
chroma plane needs to be (de)interleaved. It still needs a copy if the Y
pointer is not aligned, though. (Whether this is actually a problem
depends on the CPU and probably zimg's compiler.)
This requires deciding per plane whether the plane should go through the
repack buffer or not. This logic is active in non-nv12 cases, because
not doing so would require extra code (maybe 2 lines or so).
repack_align is now always called, even if it's planar->planar with all
input aligned, but it won't actually do anything in that case. The
assumption is that zimg won't change behavior if you pass a callback
that does nothing versus passing NULL as callback.
This is for formats like nv12 (including p010, nv24, etc.). Might be
important for hardware decoding. Previously, this would have forced a
libswscale fallback.
The genericism makes this only slightly more complicated. The main
complication is due to the fact that mixing planar and packed stuff is
insane (thanks, Nvidia).
P010 output will actually happily set any of the 6 bit "padding" LSB,
that are normally supposed to be 0 (for unpadded data there is P016).
Scaling happens with 16 bit precision. Not going to bother adding an
extra packer which zeros them out, or with shifting them in
packing/unpacking. Lets just hope nobody notices.
This is similar to mp_imgfmt_find(), but probably a bit saner. Used by
the next commit. The previous commit is required to map this
unambiguously between all formats.
As the code comment says, this is needed to disambiguate FFmpeg formats.
This struct only describes the "physical" layout of a format, while
FFmpeg also attaches part of the colorspace information to the format.
We've set all planes to the same zmask. But for subsampled chroma, the
zmask obviously needs to be smaller. This could lead to out of bounds
memory read and write accesses.
Move the align repacker to a single function, since this is now more
convenient.
Make the existing "not found" messages debug only, and add a new verbose
message if a config file was opened. The idea is that logging should
make it apparent whether or not config files are loaded, and it's more
common to use scripts without config files, leading to fewer log
messages in verbose mode.
demux_mkv has lots of logging that shows information about the file. It
sort of reminds of mkvinfo output. While this is sometimes interesting,
it's too much for verbose mode, and should be in debug log level.
In 2017, we lowered this to debug level. But I think setting options is
important enough that it should be logged even in verbose, at least
compared to all the other dumb noise.
This might be reduced again if verbose logging becomes much cleaner.
This probably covers all packed formats which have byte-aligned
component, no alpha, and no subsampling. Everything else needs more
imgfmt metadata, or something even more complicated. Alpha is primarily
not supported, because zimg requires a second scaler instance for it,
and handling packing/unpacking with it is an unacceptable mess.
Raise swscale and zimg default parameters. This restores screenshot
quality settings (maybe) unset in the commit before. Also expose some
more libswscale and zimg options.
Since these options are also used for VOs like x11 and drm, this will
make x11/drm/etc. much slower. For compensation, provide a profile that
sets the old option values: sw-fast. I'm also enabling zimg here, just
as an experiment.
The core problem is that we have a single set of command line options
which control the settings used for most swscale/zimg uses. This was
done in the previous commit. It cannot differentiate between the VOs,
which need to be realtime and may accept/require lower quality options,
and things like screenshots or vo_image, which can be slower, but should
not sacrifice quality by default.
Should this have two sets of options or something similar to do the
right thing depending on the code which calls libswscale? Maybe. Or
should I just ignore the problem, make it someone else's problem (users
who want to use software conversion VOs), provide a sub-optimal
solution, and call it a day? Definitely, sounds good, pushing to master,
goodbye.
Lots of dumb crap to do... something. Instead of adding yet another dumb
helper, just use the main" sws_utils API in both callers. (Which,
unfortunately, has been duplicated for glorious webp screenshots,
despite the fact that webp is crap.)
Good part: can enable zimg for screenshots (as far as needed).
Bad part: uses "default" swscale parameters instead of HQ now.
Purpose uncertain. I guess it's slightly better, maybe.
The move of the sws/zimg options from VO opts (vo_opt_list) to the
top-level option list is tricky. VO opts have some helper code in vo.c,
that sends VOCTRL_SET_PANSCAN to the VO on every VO opts change. That's
because updating certain VO options used to be this way (and not just
the panscan option). This isn't needed anymore for sws/zimg options, so
explicitly move them away.
To be used in the next commit.
According to compiler explorer, __builtin_clz is very widely available,
and it barely makes sense to provide a fallback. clang also eats this
(and identifies at least as GCC 4). Actually, there's doubt that a fast
log2 implementation is needed at all (I guess UTF-8 parsing needs it,
but something UTF-8-specific would probably make it faster than using
log2). So the fallback is just something naive.
By default utilizes the color space of the desktop on which the
swap chain is located. If a specific value is defined, it will be
instead be utilized.
Enables configuration of the PQ color space (BT.2020 primaries,
PQ transfer function) for HDR.
Additionally, signals the swap chain color space to the renderer,
so that the render looks correct without having to specify
target-trc or target-prim manually.
Due to all of the APIs being Win10+ only, will only work starting
with Windows 10.
This lets us set primaries, transfer function and the target peak
based on what the presenting layer would want us to have.
Now that this mechanism is available, warn if the user has
overridden values such as primaries or transfer function.
This seems to have been missed when the storable flag was added, since
all the other flags were logged here. It can be useful to know if an RA
format is storable, so log it as well.
Using e.g. --vf=format=0bgr showed obviously wrong colors with --vo=gpu.
The reason is that leading padding wasn't handled correctly.
Try to hack fix it. While the code in copy_image() is somewhat
reasonable, I can't tell what the fuck is going on with that HOOKED
shit. For some reason this HOOKED shit doesn't use copy_image() (???),
or uses it incorrectly. It affects debanding. --deband=no works
correctly. If it's enabled, the crap in hook_prelude() is needed.
I bet there are many more bugs with this. For example, the deband shader
will try to deband the alpha channel if the format abgr is used (because
the correct component order is only established later). This can be
tested by inserting a "color.x = 0;" at the end of the deband shader,
and using --vf=format=rgba vs. abgr.
I cannot comprehend why it doesn't just store explicitly which
components a texture contains, and why it doesn't just read the
components always in an uniform way.
There's a big chance this fix works only by coincidence. This shouldn't
have been so hard either. Time for a complete rewrite?
With hwdec copy modes, mp_image_copy_attributes() is used to transfer
metadata other than the image data when copying the image from the
hardware surface. It didn't copy the closed caption data.
Fix this. This makes closed captions in copy mode work.
Fixes: #6376
sdl_gamepad.c and vo_sdl.c both have their own event loops and run in
separate threads. They don't know of each other (and shouldn't). Since
SDL only has one global event loop (why didn't they fix this in SDL2?),
these obviously clash. The actual behavior is relatively subtle, which
event being randomly dispatched to either of the threads.
This is very regrettable. Very.
Work this around. "Fortunately" SDL exposes its global state to some
degree. SDL_WasInit() returns whether a "subsystem" was initialized, and
you could say the one who initialized it owns it. Both SDL_INIT_VIDEO
and SDL_INIT_GAMECONTROLLER implicitly enable SDL_INIT_EVENTS, and the
event loop is indeed the resource that cannot be shared.
Unfortunately, this is still racy, since SDL_InitSubSystem is a second
call, and succeeds if the subsystem is already initialized (increases a
refcount I think). But good enough. Blame SDL for everything.
(I think I made this commit message too long. Nobody cares even.)
Fixes: #7085
These are inherently incompatible. As far as I'm aware, SDL must be used
from the main thread on OSX.
(Technically, this condition is wrong: the problem happens on OSX in
general, or more precisely, when SDL uses Cocoa. I didn't find the waf
OSX dependency name after 5 second of searching, so I'm just using
cocoa, without which mpv is useless on OSX anyway.)
It seems some users try to use it (!). This VO was always an experiment,
and intended for low power devices. Whether this experiment succeeded or
not, it's a rather obscure VO. Recently I've seen a regrettable user,
who seemed to use this only because mpv was built without x11 support
(!). Add this warning, like other fallback VOs have it. (The message was
copied from vo_x11.)
Enabling this by default probably causes a number of issues, such as
breaking vo_sdl, or reacting to various input devices while the window
is not focused. It's also pretty obscure, or at least new. Disable it by
default.
lavc_process() calls the receive/send callbacks, which mirror
libavcodec's send/receive API. The receive API in particular can return
both a status code and a frame. Normally, libavcodec is pretty explicit
that it can't return both a frame and an error. But the receive callback
does more stuff in addition (vd_lavc does hardware decoding fallbacks
etc.). The previous commit shows an instance where this happened, and
where it leaked a frame in this case.
For robustness, check whether the frame is set first, i.e. trust it over
the status code. Before this, it checked for an EOF status first.
Hopefully is of no consequence otherwise. I made this change after
testing everything (can someone implement a test suite which tests this
exhaustively).
Commit 5d5fdb77e9 changed details of the decoding control flow, and
called it a "high-risk" change. It turns out that this broke with with
hwdec copy mode, where there is some sort of delay queue (supposedly
increases efficiency, but more likely worthless cargo-cult).
It simply used the wrong (basically inverted) condition for the draining
case.
This was the only case that did not work properly. Other tests,
including video/audio decoding errors, software decoding fallbacks,
etc., seemed to work well. Might still not be exhaustive, as there are
so many corner cases.
Also change two error code returns. This don't/shouldn't really matter,
though the second error code led it to return both a frame and
AVERROR_EOF, which is unexpected, and makes lavc_process() leak a frame.
But also see next commit.
Fixes: 5d5fdb77e9
If expected_sync_pc is greater than submit_count, the unsigned
subtraction will wraparound, which breaks playback. This bug was found
while experimenting with bit-blt model present, but it might be possible
to trigger it with the flip model as well, if there was a dropped frame.
In theory, it's better to keep the old value, because that's more
consistent with the logic of using change timestamps. With the current
code, the old value will probably never be used (instead it will fetch a
new value on every change), so this shouldn't make a difference in
practice.
This doesn't take a ',' separated list. --script is just an alias for
--scripts--append. --scripts accepts a list, but uses the
mplayer-inherited platform-dependent path separator.
Fixes: #5996
In commit 065c307e8e, I broke everything. It seemed like a nice idea,
but it explicitly broke an assumption vo_libmpv were explicitly allowed
to make: that observing properties does not lock the core. The commit
did just that and locked the core for property updates. This made for
example mpv's own OSX backend freeze (it uses vo_libmpv for convenience
to make up for Apple's incredibly broken OpenGL shit).
I don't want to revert that commit just because vo_libmpv's design is
horrible. So instead add an optional asynchronous path, that is only
used if vo_libmpv is in use (best idea ever?).
Interestingly, this isn't so hard. It adds about 90 lines of code, which
are only run on OSX and libmpv users, so I don't have to care about the
crashes and weird behavior this might cause. It even worked on the first
try except for a quickly fixed memory leak. The code path can be tested
anywhere by just turning the uses_vo_libmpv condition into always true.
The atomic is out of laziness. Saves some thinking how to get around the
locking order.
JSON doesn't support these for some god-awful reason. (JSON would have
been so much better if it weren't based on JavaScript, the plague of
this world.)
We don't really care whether these specific values "round trip", so we
might as well write them in a standard-compliant way.
Untested. I was too lazy to even run this, but it probably works.
See #6691.
Internally, vo_gpu uses NaN for some options to indicate a default value
that is different depending on the context (e.g. different scalers).
There are 2 problems with this:
1. you couldn't reset the options to their defaults
2. NaN is a damn mess and shouldn't be part of the API
The option parser already rejected NaN explicitly, which is why 1.
didn't work. Regarding 2., JSON might be a good example, and actually
caused a bug report.
Fix this by mapping NaN to the special value "default". I think I'd
prefer other mechanisms (maybe just having every scaler expose separate
options?), but for now this will do. See you in a future commit, which
painfully deprecates this and replaces it with something else.
I refrained from using "no" (my favorite magic value for "unset" etc.)
because then I'd have e.g. make --no-scale-param1 work, which in
addition to a lot of effort looks dumb and nobody will use it.
Here's also an apology for the shitty added test script.
Fixes: #6691
The commit linked below added temporary unlocking to update_prop(),
which is indirectly called by mpv_wait_event(). If an unlock happens,
and no property change event is returned, we must re-poll the event
queue. Rechecking the state on unlocks is basically a standard
requirement for code using condition variables.
Untested beyond a simple test.
Fixes: 065c307e8e
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
Property change notification works by having the mpv core wake up all
clients observing a property when the property potentially changes. The
clients then read the property's value, and determine if there was an
actual change. (The latter part depends what the property returned for
the previous change notification, so it depends on the client, and
cannot be generated by the core itself.)
Until now, reading the property value was done in a pseudo-async way by
queuing a callback back to the core, running it there, and then waking
up the client thread again. I cannot comprehend why this was done in
such a complicated, fragile way. Maybe it's a leftover from times when
client.c had to do this (in short, because properties could access
vo_opengl, which has thread-local state).
One past idea was to make the implementation of true async properties
easier (for which you would need such a state machine anyway). But they
don't exist yet, and I doubt the current mess would be really helpful
when actually implementing them.
Simplify this, and run the update in the client's thread directly. In
addition to the fundamental change, many roundabout things can be
removed as a consequence.
Unfortunately, I noticed that lock order issues force you to release
ctx->lock before doing so, which makes things more complex due to
possible concurrent mpv_unobserve_property() calls. Solve this by
removing properties lazily, which means you may have to do multiple
mpv_wait_event() calls before the property entry is actually destroyed.
This should not matter in practice, and does not affect the semantics.
It could also cause "leaks" by observing/unobserving properties in a
loop, without ever calling mpv_wait_event(). Just don't do this, duh.
(I considered making this dependent on whether the previous
mpv_wait_event() call returned the property being removed, but a
separate code path seemed too complicated. I also considered copying the
name and property data when returning a MPV_EVENT_PROPERTY_CHANGE, but
actually this doesn't solve the problem of update_prop() being
interrupted by mpv_unobserve_property(); there are ways around it, but I
just said no.)
This was made using the cowboy coding software engineering methodology.
If you find any bugs, keep them yourself.
2019-10-24 17:51:36 +02:00
468 changed files with 40587 additions and 21882 deletions
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then docker run --env CC --env TARGET -v $TRAVIS_BUILD_DIR:/build $CONTAINER /bin/sh -c "cd /build && $CI_SCRIPT"; fi
- |
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ -n "$CONTAINER" ]; then
docker run --env CC --env TARGET -v $TRAVIS_BUILD_DIR:/build $CONTAINER /bin/sh -c "cd /build && $CI_SCRIPT"
else
$CI_SCRIPT
fi
fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./ci/build-macos.sh; fi
- if [ "$TRAVIS_OS_NAME" = "freebsd" ]; then ./ci/build-freebsd.sh; fi
$(pkg info -q libcdio-paranoia &&echo --enable-cdda)\
$NULL
python3 ./waf build
Loaded 100 of 468 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.