diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-11-18 13:10:21 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-11-29 13:34:08 +0100 |
commit | e24e3835503cf2cc2b7a6d8d31c5ec3cee3be6bc (patch) | |
tree | ba5856250a4a9c2a7f7dc759878ae0f4a7c8d81d | |
parent | f2ce69c4bd8ad9ef11ee3981e6c381508112f872 (diff) |
media-session: add callback based sync method
Call the callback when the sync completes. Implement roundtrip
with this.
-rw-r--r-- | src/examples/media-session/media-session.c | 58 | ||||
-rw-r--r-- | src/examples/media-session/media-session.h | 3 |
2 files changed, 53 insertions, 8 deletions
diff --git a/src/examples/media-session/media-session.c b/src/examples/media-session/media-session.c index 70d7e978..7a14f4d0 100644 --- a/src/examples/media-session/media-session.c +++ b/src/examples/media-session/media-session.c @@ -63,6 +63,13 @@ struct data { size_t size; }; +struct sync { + struct spa_list link; + int seq; + void (*callback) (void *data); + void *data; +}; + struct impl { struct sm_media_session this; @@ -87,6 +94,7 @@ struct impl { struct spa_list endpoint_link_list; /** list of struct endpoint_link */ struct pw_map endpoint_links; /** map of endpoint_link */ + struct spa_list sync_list; /** list of struct sync */ int rescan_seq; int last_seq; }; @@ -623,20 +631,46 @@ int sm_media_session_schedule_rescan(struct sm_media_session *sess) return impl->rescan_seq; } +int sm_media_session_sync(struct sm_media_session *sess, + void (*callback) (void *data), void *data) +{ + struct impl *impl = SPA_CONTAINER_OF(sess, struct impl, this); + struct sync *sync; + + sync = calloc(1, sizeof(struct sync)); + if (sync == NULL) + return -errno; + + spa_list_append(&impl->sync_list, &sync->link); + sync->callback = callback; + sync->data = data; + sync->seq = pw_core_proxy_sync(impl->core_proxy, 0, impl->last_seq); + return sync->seq; +} + +static void roundtrip_callback(void *data) +{ + int *done = data; + *done = 1; +} + int sm_media_session_roundtrip(struct sm_media_session *sess) { struct impl *impl = SPA_CONTAINER_OF(sess, struct impl, this); struct pw_main_loop *loop = sess->loop; - int seq, res; + int done, res; if (impl->core_proxy == NULL) return -EIO; - seq = pw_core_proxy_sync(impl->core_proxy, 0, impl->last_seq); - pw_log_debug(NAME" %p: roundtrip %d", impl, seq); + done = 0; + if ((res = sm_media_session_sync(sess, roundtrip_callback, &done)) < 0) + return res; + + pw_log_debug(NAME" %p: roundtrip %d", impl, res); pw_loop_enter(loop->loop); - while (impl->last_seq <= seq) { + while (!done) { if ((res = pw_loop_iterate(loop->loop, -1)) < 0) { pw_log_warn(NAME" %p: iterate error %d (%s)", loop, res, spa_strerror(res)); @@ -644,12 +678,10 @@ int sm_media_session_roundtrip(struct sm_media_session *sess) } } pw_loop_leave(loop->loop); - if (res >= 0) - res = seq; - pw_log_debug(NAME" %p: roundtrip done %d", impl, res); + pw_log_debug(NAME" %p: roundtrip done", impl); - return res; + return 0; } static void @@ -955,7 +987,16 @@ static int start_policy(struct impl *impl) static void core_done(void *data, uint32_t id, int seq) { struct impl *impl = data; + struct sync *s, *t; impl->last_seq = seq; + + spa_list_for_each_safe(s, t, &impl->sync_list, link) { + if (s->seq == seq) { + spa_list_remove(&s->link); + s->callback(s->data); + free(s); + } + } if (impl->rescan_seq == seq) { pw_log_trace(NAME" %p: rescan %u %d", impl, id, seq); sm_media_session_emit_rescan(impl, seq); @@ -1070,6 +1111,7 @@ int main(int argc, char *argv[]) pw_map_init(&impl.globals, 64, 64); pw_map_init(&impl.endpoint_links, 64, 64); spa_list_init(&impl.endpoint_link_list); + spa_list_init(&impl.sync_list); spa_hook_list_init(&impl.hooks); if ((res = pw_remote_connect(impl.monitor_remote)) < 0) diff --git a/src/examples/media-session/media-session.h b/src/examples/media-session/media-session.h index e1fc4acf..5bb21b1d 100644 --- a/src/examples/media-session/media-session.h +++ b/src/examples/media-session/media-session.h @@ -164,6 +164,9 @@ int sm_media_session_add_listener(struct sm_media_session *sess, struct spa_hook int sm_media_session_roundtrip(struct sm_media_session *sess); +int sm_media_session_sync(struct sm_media_session *sess, + void (*callback) (void *data), void *data); + struct sm_object *sm_media_session_find_object(struct sm_media_session *sess, uint32_t id); int sm_media_session_schedule_rescan(struct sm_media_session *sess); |