summaryrefslogtreecommitdiffstats
path: root/libmpv
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-03-23 16:24:49 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-03-26 23:02:23 -0700
commitf60826c3a14ba3b49077f17e5364b7347f9b468a (patch)
tree285f39963a9f978939743b12527539e1ec8a3f54 /libmpv
parent6d7cfdfae582353e1f10797bb2c587e6ada0aed7 (diff)
downloadmpv-f60826c3a14ba3b49077f17e5364b7347f9b468a.tar.bz2
mpv-f60826c3a14ba3b49077f17e5364b7347f9b468a.tar.xz
client API: add a first class hook API, and deprecate old API
As it turns out, there are multiple libmpv users who saw a need to use the hook API. The API is kind of shitty and was never meant to be actually public (it was mostly a hack for the ytdl script). Introduce a proper API and deprecate the old one. The old one will probably continue to work for a few releases, but will be removed eventually. There are some slight changes to the old API, but if a user followed the manual properly, it won't break. Mostly untested. Appears to work with ytdl_hook.
Diffstat (limited to 'libmpv')
-rw-r--r--libmpv/client.h79
-rw-r--r--libmpv/mpv.def2
2 files changed, 80 insertions, 1 deletions
diff --git a/libmpv/client.h b/libmpv/client.h
index cd646eb218..77c149e405 100644
--- a/libmpv/client.h
+++ b/libmpv/client.h
@@ -1133,6 +1133,9 @@ int mpv_get_property_async(mpv_handle *ctx, uint64_t reply_userdata,
* property yourself. Try to avoid endless feedback loops, which could happen
* if you react to the change notifications triggered by your own change.
*
+ * Only the mpv_handle on which this was called will receive the property
+ * change events, or can unobserve them.
+ *
* @param reply_userdata This will be used for the mpv_event.reply_userdata
* field for the received MPV_EVENT_PROPERTY_CHANGE
* events. (Also see section about asynchronous calls,
@@ -1350,7 +1353,14 @@ typedef enum mpv_event_id {
* Event delivery will continue normally once this event was returned
* (this forces the client to empty the queue completely).
*/
- MPV_EVENT_QUEUE_OVERFLOW = 24
+ MPV_EVENT_QUEUE_OVERFLOW = 24,
+ /**
+ * Triggered if a hook handler was registered with mpv_hook_add(), and the
+ * hook is invoked. If you receive this, you must handle it, and continue
+ * the hook with mpv_hook_continue().
+ * See also mpv_event and mpv_event_hook.
+ */
+ MPV_EVENT_HOOK = 25,
// Internal note: adjust INTERNAL_EVENT_BASE when adding new events.
} mpv_event_id;
@@ -1514,6 +1524,17 @@ typedef struct mpv_event_client_message {
const char **args;
} mpv_event_client_message;
+typedef struct mpv_event_hook {
+ /**
+ * The hook name as passed to mpv_hook_add().
+ */
+ const char *name;
+ /**
+ * Internal ID that must be passed to mpv_hook_continue().
+ */
+ uint64_t id;
+} mpv_event_hook;
+
typedef struct mpv_event {
/**
* One of mpv_event. Keep in mind that later ABI compatible releases might
@@ -1682,6 +1703,62 @@ void mpv_set_wakeup_callback(mpv_handle *ctx, void (*cb)(void *d), void *d);
*/
void mpv_wait_async_requests(mpv_handle *ctx);
+/**
+ * A hook is like a synchronous event that blocks the player. You register
+ * a hook handler with this function. You will get an event, which you need
+ * to handle, and once things are ready, you can let the player continue with
+ * mpv_hook_continue().
+ *
+ * Currently, hooks can't be removed explicitly. But they will be implicitly
+ * removed if the mpv_handle it was registered with is destroyed. This also
+ * continues the hook if it was being handled by the destroyed mpv_handle (but
+ * this should be avoided, as it might mess up order of hook execution).
+ *
+ * Hook handlers are ordered globally by priority and order of registration.
+ * Handlers for the same hook with same priority are invoked in order of
+ * registration (the handler registered first is run first). Handlers with
+ * lower priority are run first (which seems backward).
+ *
+ * See the "Hooks" section in the manpage to see which hooks are currently
+ * defined.
+ *
+ * Some hooks might be reentrant (so you get multiple MPV_EVENT_HOOK for the
+ * same hook). If this can happen for a specific hook type, it will be
+ * explicitly documented in the manpage.
+ *
+ * Only the mpv_handle on which this was called will receive the hook events,
+ * or can "continue" them.
+ *
+ * @param reply_userdata This will be used for the mpv_event.reply_userdata
+ * field for the received MPV_EVENT_HOOK events.
+ * If you have no use for this, pass 0.
+ * @param name The hook name. This should be one of the documented names. But
+ * if the name is unknown, the hook event will simply be never
+ * raised.
+ * @param priority See remarks above. Use 0 as a neutral default.
+ * @return error code (usually fails only on OOM)
+ */
+int mpv_hook_add(mpv_handle *ctx, uint64_t reply_userdata,
+ const char *name, int priority);
+
+/**
+ * Respond to a MPV_EVENT_HOOK event. You must call this after you have handled
+ * the event. There is no way to "cancel" or "stop" the hook.
+ *
+ * Calling this will will typically unblock the player for whatever the hook
+ * is responsible for (e.g. for the "on_load" hook it lets it continue
+ * playback).
+ *
+ * It is explicitly undefined behavior to call this more than once for each
+ * MPV_EVENT_HOOK, to pass an incorrect ID, or to call this on a mpv_handle
+ * different from the one that registered the handler and received the event.
+ *
+ * @param id This must be the value of the mpv_event_hook.id field for the
+ * corresponding MPV_EVENT_HOOK.
+ * @return error code
+ */
+int mpv_hook_continue(mpv_handle *ctx, uint64_t id);
+
#if MPV_ENABLE_DEPRECATED
/**
diff --git a/libmpv/mpv.def b/libmpv/mpv.def
index ccd98422a7..1d828f4b2b 100644
--- a/libmpv/mpv.def
+++ b/libmpv/mpv.def
@@ -21,6 +21,8 @@ mpv_get_property_string
mpv_get_sub_api
mpv_get_time_us
mpv_get_wakeup_pipe
+mpv_hook_add
+mpv_hook_continue
mpv_initialize
mpv_load_config_file
mpv_observe_property