A previous commit changed m_config so that it always creates the shadow
thing, and the function's only remaining purpose was to initialize
mpv_global. It makes much more sense to do that at the caller, and it's
only 1 line of code too.
This is good because a private thing is not so public anymore, and it's
also preparation for further changes.
Some tricky memory management issues: m_config_data (i.e. config->data)
now depends on m_config_shadow, instead of m_config. In particular,
free_option_data() accesses the m_config_shadow.groups array. Obviously
it must be freed before m_config_shadow.
Move the comments documenting exported functions to the header. It looks
like the header is the preferred place for that (although I don't really
appreciate headers where you lose the overview because of all the
documentation comments). Add comments to some undocumented prototypes.
This was one of those "shouldn't exist" type of functions that could
access internals that were supposed to be isolated away, but some code
needed to access it anyway.
It looks like the last use of it went away in 2016, shortly after it was
introduced.
Passing NULL to mp_get_config_group() returns the main option struct.
This is just a dumb hack to deal with inconsistencies caused by legacy
things (as I'll claim), and will probably be changed in the future. So
before littering the whole code base with hard to find NULL parameters,
require using callers an easy to find separate define.
Actually rewrite most of the option management code. This affects how
options are allocated, and how thread-safe access to them is done.
One thing that is nicer is that creating m_config_cache does not need to
ridiculously recreate and store the entire option list again. Instead,
option metadata and option storage are now separated. m_config contains
the metadata, and m_config_data all or parts of the actual option
values. (m_config_cache simply uses the metadata part of m_config, which
is immutable after creation.)
The mentioned hack was introduced in commit 1a2319f3e4, and is the
global state around g_group_mutex. Although it was "benign" global
state, it's good that it's finally removed.
There is some craziness here: the function allocates m_config_cache,
which in turn allocates the actual option struct, which is what the
function returns. The user would expect to be able to use talloc_free()
to deallocate everything. Of course this didn't work, because the
returned pointer is not the root parent in the talloc tree.
But with some additional talloc craziness, this can be fixed. We
rearrange the parent pointers such that freeing the option struct will
free m_config_cache first, which uninits the contents in the option
struct, but fortunately not the option struct itself.
This change should simplify API use on the caller side, and reduce
surprises.
This is part of trying to get rid of --af-defaults, and the af
resample filter.
It requires a complicated mechanism to set the defaults on the resample
filter for backwards compatibility.
Remove them from the big MPOpts struct and move them to their sub
structs. In the places where their fields are used, create a private
copy of the structs, instead of accessing the semi-deprecated global
option struct instance (mpv_global.opts) directly.
This actually makes accessing these options finally thread-safe. They
weren't even if they should have for years. (Including some potential
for undefined behavior when e.g. the OSD font was changed at runtime.)
This is mostly transparent. All options get moved around, but most users
of the options just need to access a different struct (changing sd.opts
to a different type changes a lot of uses, for example).
One thing which has to be considered and could cause potential
regressions is that the new option copies must be explicitly updated.
sub_update_opts() takes care of this for example.
Another thing is that writing to the option structs manually won't work,
because the changes won't be propagated to other copies. Apparently the
only affected case is the implementation of the sub-step command, which
tries to change sub_delay. Handle this one explicitly (osd_changed()
doesn't need to be called anymore, because changing the option triggers
UPDATE_OSD, and updates the OSD as a consequence). The way the option
value is propagated is rather hacky, but for now this will do.
So far, we had a thread-safe way to read options, but no option update
notification mechanism. Everything was funneled though the main thread's
central mp_option_change_callback() function. For example, if the
panscan options were changed, the function called vo_control() with
VOCTRL_SET_PANSCAN to manually notify the VO thread of updates. This
worked, but's pretty inconvenient. Most of these problems come from the
fact that MPlayer was written as a single-threaded program.
This commit works towards a more flexible mechanism. It adds an update
callback to m_config_cache (the thing that is already used for
thread-safe access of global options).
This alone would still be rather inconvenient, at least in context of
VOs. Add another mechanism on top of it that uses mp_dispatch_queue, and
takes care of some annoying synchronization issues. We extend
mp_dispatch_queue itself to make this easier and slightly more
efficient.
As a first application, use this to reimplement certain VO scaling and
renderer options. The update_opts() function translates these to the
"old" VOCTRLs, though.
An annoyingly subtle issue is that m_config_cache's destructor now
releases pending notifications, and must be released before the
associated dispatch queue. Otherwise, it could happen that option
updates during e.g. VO destruction queue or run stale entries, which is
not expected.
Rather untested. The singly-linked list code in dispatch.c is probably
buggy, and I bet some aspects about synchronization are not entirely
sane.
Remove the various redundant m_config_set_option* calls, rename the
remaining one to m_config_set_option_cli(), and merge the
m_config_parse_option() function.
All authors of the current code have agreed (as far as this commit
requires).
options.c/options.h will take more effort, because it contains all the
option declarations, and thus is touched extremely often.
m_option.c is technically still GPL, because of commit 2c82d5a1d8
(michael has agreed to LGPL, but only once the core of mpv is LGPL).
The geometry parsing code in m_option.c was originally by someone who
could not be reached. However, it was heavily rewritten anyway, and only
the syntax remains (i.e. not copyright-relevant).
parse_commandline.c contains a change by "adland" (commit 1d0ac71ae8),
who could not be reached - this this specific part is GPL only.
Fortunately, it matters only for DVD (and even then is more like a hack,
but whatever).
There are some other relevant changes, but they have all been reverted,
moved somewhere else, deleted, or replaced.
Long planned. Leads to some sanity.
There still are some rather gross things. Especially g_groups is ugly,
and a hack that can hopefully be removed. (There is a plan for it, but
whether it's implemented depends on how much energy is left.)
Seems like this confused users quite often.
Instead of --profile=pseudo-gui, --player-operation-mode=pseudo-gui now
has to be used to invoke pseudo GUI mode. The old way still works, and
still behaves in the old way.
I would have been fine with this, but now I want to add another flag,
and the duplication would become more messy than having a strange
function for deduplication.
Extend the flag-based notification mechanism that was used via
M_OPT_TERM. Make the vo_opengl update mechanism use this (which, btw.,
also fixes compilation with OpenGL renderers forcibly disabled).
While this adds a 3rd mechanism and just seems to further the chaos, I'd
rather have a very simple mechanism now, than actually furthering the
mess by mixing old and new update mechanisms. In particular, we'll be
able to remove quite some property implementations, and replace them
with much simpler update handling. The new update mechanism can also
more easily refactored once we have a final mechanism that handles
everything in an uniform way.
Some properties had a different type from their equivalent options (such
as mute, volume, deinterlace, edition). This wasn't really sane, as raw
option values should be always within their bounds. On the other hand,
these properties use a different type to reflect runtime limits (such as
range of available editions), or simply to improve the "UI" (you don't
want to cycle throuhg the completely useless "auto" value when cycling
the "mute" property).
Handle this by making them always return the option type, but also
allowing them to provide a "constricted" type, which is used for UI
purposes. All M_PROPERTY_GET_CONSTRICTED_TYPE changes are related to
this.
One consequence is that you can set the volume property to arbitrary
high values just like with the --volume option, but using the "add"
command it still restricts it to the --volume-max range.
Also deprecate --chapter, as it is grossly incompatible to the chapter
property. We pondered renaming it to --chapters, or introducing a more
powerful --range option, but concluded that --start --end is actually
enough.
These changes appear to take care of the last gross property/option
incompatibilities, although there might still be a few lurking.
All option write accesses are now put through the property interface,
which means runtime option value verification and runtime updates are
applied. This is done even for command line arguments and config files.
This has many subtle and not-so-subtle consequences. The potential for
unintended and intended subtle or not-subtle behavior changes is very
large.
Architecturally, this is us literally jumping through hoops. It really
should work the other way around, with options being able to have
callbacks for value verification and applying runtime updates. But this
would require rewriting the entirety of command.c. This change is more
practical, and if anything will at least allow incremental changes.
Some options are too incompatible for this to work - these are excluded
with an explicit blacklist.
This change fixes many issues caused by the mismatch between properties
and options. For example, this fixes#3281.
This has all been made unnecessary recently. The change not to copy the
global option struct in particular can be made because now nothing
accesses the global options anymore in the demux and stream layers.
Some code that was accidentally added/changed in commit 5e30e7a0 is also
removed, because it was simply committed accidentally, and was never
used.
This works by first parsing a config file into the default profile, and
applying it once parsing the whole file is finished.
This won't work across config files (not even if you include other
config files via "include=file.conf").
vo_opengl sub-option were always rather annoying to handle. It seems
better to make them global options instead. This is simpler and easier
to use. The only disadvantage we are aware of is that it's not clear
that many/all of these new global options work with vo_opengl only.
--vo=opengl-hq is also deprecated.
There is extensive compatibility with the old behavior. One exception is
that --vo-defaults will not apply to opengl-hq (though with opengl it
still works). vo-cmdline is also dysfunctional and will be removed in a
following commit.
These changes also affect opengl-cb.
The update mechanism is still rather inefficient: it requires syncing
with the VO after each option change, rather than batching updates.
There's also no granularity (video.c just updates "everything", and if
auto-ICC profiles are enabled, vo_opengl.c will fetch them on each
update).
Most of the manpage changes were done by Niklas Haas <git@haasn.xyz>.
The way option runtime changes are handled is pretty bad in the current
codebase. There's a big option struct (MPOpts), which contains almost
everything, and for which no synchronization mechanism exists. This was
handled by either making some options read-only after initialization,
duplicating the option struct, using sub-options (in the VO), and so on.
Introduce a mechanism that creates a copy of the global options (or
parts of it), and provides a well-defined way to update them in a
thread-safe way.
Most code can remain the same, just that all the component glue code has
to explicitly make use of it first.
There is still lots of room for improvement. For example, the update
mechanism could be better.
Normally I'd prefer a bunch of smaller functions with fewer parameters
over a single function with a lot of parameters. But future changes will
require messing with the parameters in a slightly more complex way, so a
combined function will be needed anyway. The now-unused "global"
parameter is required for later as well.
Now options are accessible through the property list as well, which
unifies them to a degree.
Not all options support runtime changes (meaning affected components
need to be restarted for the options to take effects). Remove from the
manpage those properties which are cleanly mapped to options anyway.
From the user-perspective they're just options available through the
property interface.
This is a really old weird MPlayer feature. While the MPlayer requires
you to use the sub-option syntax in these cases, mpv "flattens" them to
normal options. The still-supported alternate sub-option syntax remains
a weird artifact that hopefully nobody uses.
For example you can do "-sub-text font=Foo:color=0.5" instead of using
"--sub-text-font=Foo --sub-text-color=0.5". For --sub-text this is an
accidental feature, but it used to be documented for
--demuxer-rawaudio and some others.
This should just be removed, but for now only print a warning to preempt
complaints from weird users wanting this feature back.
More appropriate. Originally it really was for automatically added
options, but now it even needed some stupid comments to indicate that
it was used for simply hiding options.
Update msg.c state immediately if a terminal or logging setting is set.
Until now, this was delayed until mp[v]_initialize() was called. When
using the client API, you could easily miss logged error messages, even
when logging was initialized early on by calling
mpv_request_log_messages().
(Properties can't be used for this either, because properties do not
work before mpv_initialize().)
bstr.c doesn't really deserve its own directory, and compat had just
a few files, most of which may as well be in osdep. There isn't really
any justification for these extra directories, so get rid of them.
The compat/libav.h was empty - just delete it. We changed our approach
to API compatibility, and will likely not need it anymore.
The code paths for setting options by string and by direct "raw" value
were too different, which resulted in some weird code. Make the code
paths closer to each other.
Also, use this to remove the weirdness in the mpv_set_option()
implementation.
This should fix some issues, such as not being able to set the
"no-video" option with MPV_FORMAT_FLAG.
Note that this changes semantics a bit. Now setting an option strictly
overwrite it, even if the corresponding command line option does not.
For example, if we change --sub to append by default, then setting the
"sub" option via the client API would still never append. (Oddly, this
also applies to --vf-add, which will overwrite the old value when using
the client API.)
I'm doing this because there's no proper separation between the command
line parser and setting an option using the MPV_FORMAT_STRING format.
Maybe the solution to this mess would be adding format aware code (i.e.
m_option_set_node) to every option type, and falling back to strings
only if needed - but this would mean that you couldn't set e.g. an
integer option using MPV_FORMAT_STRING, which doesn't seem to be ideal
either.
In conclusion, the current approach seems to be most robust, but I'm
open to suggestions should someone find that these semantics are a
problem.
This is only half-implemented: actually the option will first be
converted from mpv_node to its native type, then it's converted to a
string, and then back to its native type. This is because the option
API was made for strings and not anything else.
Other than being grossly inelegant, the only downside is probably with
string lists and key/value lists, which don't escape strings containing
syntax elements correctly.
Always pass around mp_log contexts in the option parser code. This of
course affects all users of this API as well.
In stream.c, pass a mp_null_log, because we can't do it properly yet.
This will be fixed later.