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.