Commit Graph

60 Commits

Author SHA1 Message Date
wm4 b799bf0dbf client API: use playback abort mechanism
If you send the "quit" or "stop" command with the client API, it will
now attempt to kill network I/O immediately (same as normal input in the
previous commits).
2014-09-13 16:52:42 +02:00
wm4 017b3fa9db lua: synchronously wait until scripts are loaded
This makes the player wait until each script is loaded. Do this to give
the script a chance to setup all its event handlers. It might also be
useful to allow a script to change options that matter for playback.

While waiting for a script to be loaded, the player actually accepts
input. This is needed because the scripts can execute player commands
anyway while they are being "loaded". The player won't react to most
commands though: it can't quit or navigate the playlist in this state.

For deciding whether a script is finally loaded, we use a cheap hack: if
mpv_wait_event() is called, it's considered loaded. Let's hope this is
good enough. I think it's better than introducing explicit API for this.
Although I'm sure this will turn out as too simplistic some time in the
future, the same would probably happen with a more explicit API.
2014-09-06 17:02:47 +02:00
wm4 f59f1e532e client API: fix memory leak with rejected events
The event was copied early, and wasn't released if it was rejected
instead of being added to the event queue. Fix by copying the event at a
point when it's certainly added to the event queue.

The dup_event_data() function is merely moved.
2014-08-31 19:51:41 +02:00
wm4 fb1266c98b player: update cache state only if requested
Add a mechanism to the client API code, which allows the player core to
query whether a client API event is needed at all. Use it for the cache
update.

In this case, this is probably a pure microoptimization; but the
mechanism will be useful for other things too.
2014-08-28 17:49:09 +02:00
wm4 a7107686d7 client API: directly lock playloop
Until recently, vo_opengl could be accessed from a single thread only,
due to the OpenGL API context being thread-specific. This issue doesn't
exist anymore, because VOs run on their own thread. This means we can
simply lock/unlock the playloop instead of doing something complicated
to get the playloop thread to execute our code.
2014-08-14 19:40:43 +02:00
wm4 733bdebcb9 client API: minor optimizations for property notification
Internally, there are two mechanisms which can trigger property
notification as used with "observed" properties in the client API.

The first mechanism associates events with a group of properties that
are potentially changed by a certain event. mp_event_property_change[]
declares these associations, and maps each event to a set of strings.
When an event happens, the set of strings is matched against the list of
observed properties of each client. Make this more efficient by
comparing bitsets of events instead. This way, only a bit-wise "and" is
needed for each observed property. Even better, we can completely skip
clients which have no observed properties that match.

The second mechanism just updates individual properties explicitly by
name. Optimize this by using the property index instead. It would be
nice if we could reuse the first mechanism for the second one, but
there are too many properties to fit into a 64 bit mask.

(Though the limit on 64 events might get us into trouble later...)
2014-08-02 01:53:22 +02:00
wm4 aaa90e1a33 client API: fix deadlock when calling mpv_terminate_destroy before init
This is perfectly allowed, but was ignored, because it's a corner case.

It doesn't actually wait for other clients to be destroyed, but on the
other hand I think there's no way to have other clients before
initialization.

CC: @mpv-player/stable
2014-07-31 03:12:18 +02:00
wm4 ef600041ba audio, client API: check mp_make_wakeup_pipe() return value
Could fail e.g. due to FD exhaustion.
2014-07-25 14:32:45 +02:00
wm4 4fedf86b8a client API: allow calling mpv_terminate_destroy(NULL)
This is an oversight and a bug.

CC: @mpv-player/stable
2014-07-04 02:24:49 +02:00
wm4 99f5fef0ea Add more const
While I'm not very fond of "const", it's important for declarations
(it decides whether a symbol is emitted in a read-only or read/write
section). Fix all these cases, so we have writeable global data only
when we really need.
2014-06-11 00:39:14 +02:00
wm4 adea4386bc client API: disable LIRC input by default
Not only should using libmpv hog such global resources; it's also very
unlikely an application embedding mpv will ever want to make use of
this.
2014-06-09 01:20:55 +02:00
wm4 09dd1ed47c client API: minor documentation fixes/enhancements 2014-06-08 16:11:39 +02:00
wm4 51834592fc client API: trigger wakeup when creating wakeup pipe/callback
Since redundant wakeups are avoided now, it's easy to miss a wakeup when
creating/setting the pipe/callback after the client API was signalled.
If the client API is signalled, need_wakeup is set to true, and
wakeup_client skips writing to the pipe or calling the client API. That
this can happen is not very obvious to the client API, so trigger a
wakeup right on start in order to remove this special case.
2014-06-08 16:11:11 +02:00
wm4 5cc68c792b client API: restructure waiting, do log msg wakeup properly
Until now, availability of new log messages (through the mechanism
associated with mpv_request_log_messages()) did not wakeup the client
API properly. Commit 3b7402b5 was basically a hack to improve that
somewhat, but it wasn't a solution.

The main problem is that the client API itself is producing messages, so
the message callback would attempt to lock the client API lock,
resulting in a deadlock. Even if the lock was recursive, we'd run into
lock-order issues.

Solve this by using a separate lock for waiting and wakeup. Also, since
it's a natural addition, avoid redundant wakeups. This means the wakeup
callback as well as the wakeup pipe will be triggered only once until
the next mpv_wait_event() call happens.

This might make the wakeup callback be invoked in a reentrant way for
the first time, for example if a mpv_* function prints to a log. Adjust
the docs accordingly. (Note that non-reentrant beheavior was never
guaranteed - basically the wakeup callback is somewhat dangerous and
inconvenient.)

Also remove some traces of unneeded code. ctx->shutdown for one was
never set, and probably a leftover of an abandoned idea.
2014-06-07 23:16:46 +02:00
wm4 fca608ccb9 client API: rename mpv_destroy() to mpv_detach_destroy()
A bit verbose, but less misleading. In most cases, the API user probably
actually wants mpv_terminate_destroy() instead, so the less-useful
function shouldn't have a simnpler name anyway.
2014-06-07 20:25:48 +02:00
wm4 500ce69a06 client API: add API function that ensures total destruction
mpv_destroy() should perhaps better be called mpv_detach(), because it
destroys only the handle, not necessarily the player. The player is only
terminated if a quit command is sent.

This function quits automatically, and additionally waits until the
player is completely destroyed. It removes the possibility that the
player core is still uninitializing, while all client handles are
already destroyed. (Although in practice, the difference is usually not
important.)
2014-06-07 15:57:54 +02:00
wm4 a1000962e3 client API: change mpv_wait_event() timeout semantics
Now a negative timeout mean an infinite timeout. This is similar to the
poll() system call. Apparently this is more intuitive and less confusing
than specifying a "very high" value as timeout if you want to wait
forever.

For callers that never pass negative timeouts, nothing changes.
2014-06-07 15:57:47 +02:00
wm4 43d46a28fe client API: enlarge the message buffer if log level is high 2014-06-06 19:25:52 +02:00
wm4 3b7402b51c client API: call wakeup callback if there are new messages
Listening on messages currently uses polling (every time
mpv_wait_event() has no new events, the message buffer is polled and a
message event is possibly created). Improve this situation a bit, and
call the user-supplied wakeup callback.

This will increase the frequency with which the wakeup callback is
called, but the client is already supposed to be able to deal with this
situation. Also, as before, calling mpv_wait_event() from the wakeup
callback is forbidden, so the client can't read new messages from the
callback directly.

The wakeup pipe is written either. Since the wakeup pipe is created
lazily, we can't access the pipe handle without creating a race
condition or a deadlock. (This is actually very silly, since in practice
the race condition won't matter, but for now let's keep it clean.)
2014-06-06 19:24:30 +02:00
wm4 ecbb12923f client API: don't update properties in uninitialized state
If an API user calls mpv_wait_event() and mpv_observe_property() before
mpv_initialize(), it could happen that a property was accessed before
initialization, which is not ok.
2014-06-06 17:27:05 +02:00
wm4 4279712d1e client API: don't use the mpv config files by default
This was always intended this way, and even documented in client.h. Due
to an oversight it was never actually implemented.

The intention is that mpv embedded in applications and "real mpv" don't
conflict. An API user can undo this by setting the "config" option to
"yes", if using the user's mpv config is desired.
2014-06-06 17:26:01 +02:00
wm4 7716424d48 client API: use shared code for creating the wakeup pipe
Should be equivalent, reduces code duplication.
2014-06-06 17:22:53 +02:00
wm4 662592c860 client API: fix swapped pipe ends used with mpv_set_wakeup_callback
This was extremely wrong. It was never tested because nobody ever used
it (the feature was added for someone who never tried it in the end).
2014-06-06 17:21:30 +02:00
wm4 5a5a3c53f7 client API: report success status when running commands
Until now, an error was reported only if the command couldn't be parsed.
Attempt to do more fine-grained reporting. This is not necessarily
perfect, but it's an improvement.
2014-06-01 03:41:46 +02:00
wm4 01c3847b80 client API: fix mpv_observe_property with MP_FORMAT_NONE
It returned only 1 change event (after registration), and then went
silent. This was accidentally broken some time ago.
2014-05-24 16:17:52 +02:00
wm4 537ac1a15f client API: add mpv_load_config_file()
This is probably a good idea, because it would make it easier for
software embedding mpv to configure the mpv parts, without requiring the
host program to provide explicit mechanisms for this (other than calling
mpv_load_config_file()).
2014-05-18 19:21:39 +02:00
wm4 caa939aa91 options: unify code for setting string and "raw" options
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.
2014-05-18 19:21:39 +02:00
wm4 f47a4fc3d9 threads: use mpv time for mpthread_cond_timedwait wrapper
Use the time as returned by mp_time_us() for mpthread_cond_timedwait(),
instead of calculating the struct timespec value based on a timeout.
This (probably) makes it easier to wait for a specific deadline.
2014-05-18 19:20:32 +02:00
wm4 1ef1e8e509 client API: fix "missed" property notifications
If a property is notified as changed, and then again (before the change
notification is returned to the client), and the second change is a
sporadic change (i.e. nothing actually changed) and the change
notification was associated with with a data type, it could happen that
a change was "overlooked", because it would detect no change on the
second notification.

This is actually a pretty annoying corner case, due to the annoying way
we do things, so just store both the previously returned _and_ the newly
obtained property value. then we always compare with the user value to
check for a change, excluding any possibility of a missed change.

Note that we don't (can't/shouldn't) care if a value changes, and then
changes back; it's fine if that doesn't generate a notification. This is
due to how property notifications are supposed to be coalesced.
2014-05-18 00:02:55 +02:00
wm4 2279f718de player: reorganize how lua scripts are loaded
Make loading of scripts independent of Lua. Move some of the loading
code from lua.c to scripting.c, and make it easier to add new scripting
backends.
2014-05-13 02:39:37 +02:00
wm4 1279ebf5c5 client API: fix inverted condition
Oops. Sigh.
2014-05-02 17:23:25 +02:00
wm4 e8a996cede client API: add chapter change event
Also works for mpv_observe_property() on the "chapter" property.
2014-04-27 22:28:07 +02:00
wm4 2b26517ef7 dispatch: move into its own source file
This was part of osdep/threads.c out of laziness. But it doesn't contain
anything OS dependent. Note that the rest of threads.c actually isn't
all that OS dependent either (just some minor ifdeffery to work around
the lack of clock_gettime() on OSX).
2014-04-23 21:16:51 +02:00
wm4 b430c886aa client API: make mpv_set_option set options natively
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.
2014-04-22 01:42:57 +02:00
wm4 196619671d client API: remove mpv_event_pause_reason
And slightly adjust the semantics of MPV_EVENT_PAUSE/MPV_EVENT_UNPAUSE.

The real pause state can now be queried with the "core-idle" property,
the user pause state with the "pause" property, whether the player is
paused due to cache with "paused-for-cache", and the keep open event can
be guessed with the "eof-reached" property.
2014-04-14 22:33:41 +02:00
wm4 4e5cea86c2 client API: add mpv_get_wakeup_pipe convenience function
Should make integreating with some event loops easier. Untested.
2014-04-12 20:13:07 +02:00
wm4 86094c2c5a client API: include the reason in MPV_EVENT_END_FILE
Otherwise, the client API user could not know why playback was stopped.

Regarding the fact that 0 is used both for normal EOF and EOF on error:
this is because mplayer traditionally did not distinguish these, and in
general it's hard to tell the real reason. (There are various weird
corner cases which make it hard.)
2014-04-11 01:23:32 +02:00
wm4 217008be4a client: change equality rules for MPV_FORMAT_NONE 2014-04-09 20:27:26 +02:00
wm4 b23a1edf55 client: add a comment 2014-04-09 19:27:28 +02:00
wm4 89d400dc21 client API: avoid redundant property change events if possible
This is done simply by comparing the previous and current values. Do
this only if the requested format is not MPV_FORMAT_NONE.
2014-04-08 22:06:39 +02:00
wm4 49d1b42f70 client API: add a way to notify clients of property changes
This turned out ridiculously complex. I think it will have to be
simplified some day. Main reason for the complexity are:
- filtering properties by forcing clients to observe individual
  properties explicitly
  (to avoid spamming clients with changes they don't want)
- optional retrieval of property value with the notification
  (the basic idea was that this is more user friendly)
- allowing to the client to specify a format in which the value
  should be retrieved
  (because if a property changes its type, the client API couldn't
  convert it properly, and compatibility would break)

I don't know yet which of these are important, and everything could
change. In particular, the interface and semantics should be adjusted
to reduce the implementation complexity.

While I consider the API complete, there could (and probably will) be
bugs left. Also while the implementation is complete, it's inefficient.
The complexity of the property matching is O(a*b*c) with a clients,
b observed properties, and c properties changing at once. I threw away
an earlier implementation using bitmasks, because it was too unwieldy.
2014-04-06 03:22:49 +02:00
wm4 14eb233da9 client API: use a manual ringbuffer
Remove the use of mp_ring and use a simple array and a bunch of
variables instead. This is way less awkwad.

The change in reserve_reply fixes incorrect tracking of free events.
2014-04-06 03:22:49 +02:00
wm4 637664d95a command, lua: change script_message semantics
Change script_message to broadcast the message to all clients. Add a new
script_message_to command, which does what the old script_message
command did.

This is intended as simplification, although it might lead to chaos too.
2014-03-17 18:26:56 +01:00
wm4 93065af3ed client API: fix timeout handling
(Again.)

Fixed Lua timers as well.
2014-03-01 00:38:17 +01:00
wm4 c30bf22d8d client API: rename MPV_EVENT_PLAYBACK_START, add MPV_EVENT_SEEK
Rename MPV_EVENT_PLAYBACK_START to MPV_EVENT_FILE_LOADED.

Add MPV_EVENT_SEEK and MPV_EVENT_PLAYBACK_RESTART.
2014-02-28 01:31:38 +01:00
wm4 1852555ca1 client API: wait for remaining asynchronous requests before terminating
Sending an asynchronous request and then calling mpv_destroy() would
crash the player when trying to send the reply to the removed client.
Fix this by waiting until all remaining replies have been sent.
2014-02-28 01:03:37 +01:00
wm4 412bb336ab client API: don't explode when destroying uninitialized mpv_handle 2014-02-26 21:03:35 +01:00
wm4 bd75766ef0 client API: accept NULL as mpv_destroy() argument 2014-02-26 21:03:35 +01:00
wm4 eca9210399 client API: treat MPV_FORMAT_STRING differently in mpv_set_property
Always map MPV_FORMAT_STRING to setting property value directly through
M_PROPERTY_SET_STRING, instead of trying to go through
M_PROPERTY_SET_NODE.

This treats a direct MPV_FORMAT_STRING query differently from a
MPV_FORMAT_STRING wrapped in a mpv_node. This was already the case in
mpv_get_property(). The reason for all this is that mpv_node is supposed
to be the exact type, while a direct MPV_FORMAT_STRING goes through all
possible conversions.

Not sure if these semantics are good.
2014-02-26 21:03:35 +01:00
xylosper c176f2be39 client API: fix broken property/option functions
1. Cannot set option after initialized: it seems that this bug has
   existed since libmpv was introduced first. Maybe just a typo.
2. Crash when setting property with native format: mpv_set_property
   just causes a crash when using a native format. I found an invalid
   casting and fixed it.
3. Wrong error value for mpv_get_property: when an error occurred,
   mpv_get_property always returns wrong format error because every
   error for property except M_PROPERTY_NOT_IMPLEMENTED is just ignored.

Signed-off-by: wm4 <wm4@nowhere>

Closes pull request #593. Does not incldue the first fix, which was not
correct. The underlying bug will be fixed by a later commit.

Commit message extracted from pull request and slightly edited.
2014-02-26 21:01:54 +01:00