From 49d1b42f7088c0d41df346437b64fe20bbaac22f Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 5 Apr 2014 23:54:21 +0200 Subject: 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. --- player/command.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'player/command.c') diff --git a/player/command.c b/player/command.c index 14654af14b..127ef1e42d 100644 --- a/player/command.c +++ b/player/command.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -2272,6 +2273,29 @@ static const m_option_t mp_properties[] = { {0}, }; +// Each entry describes which properties an event (possibly) changes. +#define E(x, ...) [x] = (const char*[]){__VA_ARGS__, NULL} +const char **mp_event_property_change[] = { + E(MPV_EVENT_START_FILE, "*"), + E(MPV_EVENT_END_FILE, "*"), + E(MPV_EVENT_FILE_LOADED, "*"), + E(MPV_EVENT_TRACKS_CHANGED, "track-list"), + E(MPV_EVENT_TRACK_SWITCHED, "vid", "video", "aid", "audio", "sid", "sub", + "secondary-sid"), + E(MPV_EVENT_IDLE, "*"), + E(MPV_EVENT_PAUSE, "pause"), + E(MPV_EVENT_UNPAUSE, "pause"), + E(MPV_EVENT_TICK, "time-pos", "stream-pos", "stream-time-pos", "avsync", + "percent-pos", "time-remaining", "playtime-remaining"), + E(MPV_EVENT_VIDEO_RECONFIG, "video-out-params", "video-params", + "video-format", "video-codec", "video-bitrate", "dwidth", "dheight", + "width", "height", "fps", "aspect"), + E(MPV_EVENT_AUDIO_RECONFIG, "audio-format", "audio-codec", "audio-bitrate", + "samplerate", "channels", "audio"), + E(MPV_EVENT_METADATA_UPDATE, "metadata"), +}; +#undef E + const struct m_option *mp_get_property_list(void) { return mp_properties; @@ -3468,4 +3492,11 @@ void mp_notify(struct MPContext *mpctx, int event, void *arg) ctx->last_seek_pts = MP_NOPTS_VALUE; mp_client_broadcast_event(mpctx, event, arg); + if (event >= 0 && event < MP_ARRAY_SIZE(mp_event_property_change)) + mp_client_property_change(mpctx, mp_event_property_change[event]); +} + +void mp_notify_property(struct MPContext *mpctx, char *property) +{ + mp_client_property_change(mpctx, (const char*[]){property, NULL}); } -- cgit v1.2.3