Makes the next commit simpler. It's probably a bad idea to add more
fields to the global state, but on the other hand the client API state
is pretty much per-instance anyway. It also will help with things like
the proposed libmpv custom stream API.
This makes no sense, because the client is obligated to react to this
event.
This also happens to fix a deadlock with JSON IPC clients sending
"disable_event all", because MPV_EVENT_SHUTDOWN was used to stop the
thread driving the socket connection (fixes#2558).
Client API users can enable log output with mpv_request_log_messages().
But you can enable only a single log level. This is normally enough, but
the --msg-level option (which controls the terminal log level) provides
more flexibility. Due to internal complexity, it would be hard to
provide the same flexibility for each client API handle. But there's a
simple way to achieve basically the same thing: add an option that sends
log messages to the API handle, which would also be printed to the
terminal as by --msg-level.
The only change is that we don't disable this logic if the terminal is
disabled. Instead we check for this before the message is output, which
in theory can lower performance if messages are being spammed. It could
be handled with some more effort, but the gain would be negligible.
Adding an external audio track before loading the main file didn't work
right. For one, mp_switch_track() assumes it is called after the main
file is loaded. (The difference is that decoders are only initialized
once the main file is loaded, and we avoid doing this before that for
whatever reason.)
To avoid further messiness, just allow mp_switch_track() to be called at
any time. Also make it do what mp_mark_user_track_selection() did, since
the latter requires current_track to be set. (One could probably simply
allow current_track to be set at this point, but it'd interfere with
default track selection anyway and thus would be pointless.)
Fixes#1984.
There is not much of a reason to have these wrappers around. Use POSIX
standard functions directly, and use a separate utility function to take
care of the timespec calculations. (Course POSIX for using this weird
format for time values.)
The client API (libmpv) and encoding (--o) have slightly different
defaults from the command line player. Instead of doing a bunch of calls
to set the options explicitly, use profiles. This is simpler and has the
advantage that they can be listed on command line (instead of possibly
forcing the user to find and read the code to know all the details).
Unlike other VOs, this rendered OSD even while no VO was created
(because the renderer lives as long as the API user wants). Change this,
and refactor the code so that the OSD object is accessible only while
the VO is created.
(There is a short time where the OSD can still be accessed even after VO
destruction - this is not a race condition, though it's inelegant and
unfortunately unavoidable.)
Move the command line parsing and some other things to the common init
routine shared between command line player and client API. This means
they're using almost exactly the same code now.
The main intended side effect is that the client API will load mpv.conf;
though still only if config loading is enabled.
(The cplayer still avoids creating an extra thread, passes a command
line, and prints an exit status to the terminal. It also has some
different defaults.)
This does what it's documented to do.
The implementation reuses the code in mpv_detach_destroy(). Due to the
way async requests currently work, just sending a synchronous dummy
request (like a "ignore" command) would be enough to ensure
synchronization, but this code will continue to work even if this
changes.
The line "ctx->event_mask = 0;" is removed, but it shouldn't be needed.
(If a client is somehow very slow to terminate, this could silence an
annoying queue overflow message, but all in all it does nothing.)
Calling mpv_wait_async_requests() and mpv_wait_event() concurrently is
in theory allowed, so change pthread_cond_signal() to
pthread_cond_broadcast() to avoid missed wakeups.
As requested in issue #1542.
Sigh...
The C locale system is incredibly shitty, and if used, breaks basic
string functions. The locale can change the decimal mark from "." to
",", which affects conversion between floats and strings: snprintf() and
strtod() respect the locale decimal mark, and change behavior. (What's
even better, the behavior of these functions can change asynchronously,
if setlocale() is called after threads were started.)
So just check the locale in the client API, and refuse to work if it's
wrong. This also makes the lib print to stderr, which I consider the
lesser evil in this specific situation.
Before this, we merely printed a message to the terminal. Now the API
user can determine this properly. This might be important for API users
which somehow maintain complex state, which all has to be invalidated if
(state-changing) events are missing due to an overflow.
This also forces the client API user to empty the event queue, which is
good, because otherwise the event queue would reach the "filled up"
state immediately again due to further asynchronous events being added
to the queue.
Also add some minor improvements to mpv_wait_event() documentation, and
some other minor cosmetic changes.
mpv_opengl_cb_uninit_gl() can be called at any time; but then the
decoder must be destroyed due to complications with hardware decoding.
This is why kill_video() exists. To make things easier, there is the
invariant that while vo_opengl_cb is active, the OpenGL state must
exist. But kill_video() didn't actually destroy the VO; only the video
decoder. This could trigger an assertion (vo_opengl_cb.c:187).
Actually, the video output is always destroyed lazily at a later point
if the decoder is destroyed, but not early enough for out purposes.
This may or may not be useful for client API users.
Fold this API extension into the previous API bump. The previous bump
was only yesterday, so it's ok.
Until now, calling mpv_opengl_cb_uninit_gl() at a "bad moment" could
make the whole thing to explode. The API user was asked to avoid such
situations by calling it only in "good moments". But this was probably a
bit too subtle and could easily be overlooked.
Integrate the approach the qml example uses directly into the
implementation. If the OpenGL context is to be unitialized, forcefully
disable video, and block until this is done.
Before this commit, this was defined to trigger undefined behavior. This
was nice because it required less code; but on the other hand, Lua as
well as IPC support had to check these things manually. Do it directly
in the API to avoid code duplication, and to make the API more robust.
(The total code size still grows, though...)
Since all of the failure cases were originally meant to ruin things
forever, there is no way to return error codes. So just print the
errors.
This adds API to libmpv that lets host applications use the mpv opengl
renderer. This is a more flexible (and possibly more portable) option to
foreign window embedding (via --wid).
This assumes that methods like context sharing and multithreaded OpenGL
rendering are infeasible, and that a way is needed to integrate it with
an application that uses a single thread to render everything.
Add an example that does this with QtQuick/qml. The example is
relatively lazy, but still shows how relatively simple the integration
is. The FBO indirection could probably be avoided, but would require
more work (and would probably lead to worse QtQuick integration, because
it would have to ignore transformations like rotation).
Because this makes mpv directly use the host application's OpenGL
context, there is no platform specific code involved in mpv, except
for hw decoding interop.
main.qml is derived from some Qt example.
The following things are still missing:
- a way to do better video timing
- expose GL renderer options, allow changing them at runtime
- support for color equalizer controls
- support for screenshots
This is simply not allowed, and doing it triggered an assertion. It's
still not allowed, because the terminal and related functionality is a
global resource, and there doesn't seem to be a sane way to manage the
signal handlers.
But be a bit nicer, and just the terminal if it's already in use.
Note that terminal _output_ happens anyway. This becomes usable with
this commit. To facilitate logging-only usage further, also explicitly
disable terminal input, so that "terminal=yes" can be used for logging
without much interference with other things. (It'll still overwrite some
signal handlers, though.)
Currently, --ytdl is off by default, but even if this is changed, never
enable it by default for the client API. It would be inappropriate to
start an intrusive external subprocess behind the host application's
back.
Use a fixed size array for the client name, which also limits the client
name in size. Sanitize the client name string, and replace characters
that are not in [A-Za-z0-9] with '_'.
The values compared here happen to be of unsigned enum types - but the
test is not supposed to break if we somehow force the enum to signed, or
if the compiler happens to use a signed type (as far as I remember, the
exact integer type the compiler can use is implementation-defined).
Add a generic mechanism to the VO to relay "extra" events from VO to
player. Use it to notify the core of window resizes, which in turn will
be used to mark all affected properties ("window-scale" in this case) as
changed.
(I refrained from hacking this as internal command into input_ctx, or to
poll the state change, etc. - but in the end, maybe it would be best to
actually pass the client API context directly to the places where events
can happen.)
This is probably what libmpv users want; and it also improves error
reporting (or we'd have to add a way to communicate such mid-playback
failures as events).
Especially with other components (libavcodec, OSX stuff), the thread
list can get quite populated. Setting the thread name helps when
debugging.
Since this is not portable, we check the OS variants in waf configure.
old-configure just gets a special-case for glibc, since doing a full
check here would probably be a waste of effort.
A vague idea to get something similar what libquvi did.
Undocumented because it might change a lot, or even be removed. To give
an idea what it does, a Lua script could do the following:
-- type ID priority
mp.commandv("hook_add", "on_load", 0, 0)
mp.register_script_message("hook_run", function(param, param2)
-- param is "0", the user-chosen ID from the hook_add command
-- param2 is the magic value that has to be passed to finish
-- the hook
mp.resume_all()
-- do something, maybe set options that are reset on end:
mp.set_property("file-local-options/name", "value")
-- or change the URL that's being opened:
local url = mp.get_property("stream-open-filename")
mp.set_property("stream-open-filename", url .. ".png")
-- let the player (or the next script) continue
mp.commandv("hook_ack", param2)
end)
Allows passing native types as arguments.
Also some minor doc improvements, including giving some (natural)
improvements to mpv_free_node_contents().
Note: mpv_command_node_async() is completely untested.
The event monitor is used to get keyboard events when there is no window, but
since it is a global monitor to the current process, we don't want it in a
library setting.
After @frau's split of macosx_events from macosx_application, `is_cplayer' is
not needed anymore. At the moment only global events such as Media Keys and
Apple Remote work, because the VO-level ones were hardcoded to be disabled.
(that will be fix in a later commit ).