From 54d8b7b31e3fbcbe80e20d0aef2bc344d44db81e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Aug 2009 03:55:47 +0200 Subject: implement ca_context_playing() call --- gtkdoc/libcanberra-sections.txt | 1 + src/alsa.c | 29 +++++++++++++++++++++++++++++ src/canberra.h.in | 1 + src/common.c | 29 +++++++++++++++++++++++++++++ src/driver.h | 2 ++ src/dso.c | 17 ++++++++++++++++- src/gstreamer.c | 28 ++++++++++++++++++++++++++++ src/multi.c | 29 +++++++++++++++++++++++++++++ src/oss.c | 29 +++++++++++++++++++++++++++++ src/pulse.c | 30 ++++++++++++++++++++++++++++++ 10 files changed, 194 insertions(+), 1 deletion(-) diff --git a/gtkdoc/libcanberra-sections.txt b/gtkdoc/libcanberra-sections.txt index 326faa1..60094a0 100644 --- a/gtkdoc/libcanberra-sections.txt +++ b/gtkdoc/libcanberra-sections.txt @@ -63,6 +63,7 @@ ca_context_play_full ca_context_cancel ca_context_cache ca_context_cache_full +ca_context_playing ca_strerror diff --git a/src/alsa.c b/src/alsa.c index 5f35e8b..e9647c5 100644 --- a/src/alsa.c +++ b/src/alsa.c @@ -521,3 +521,32 @@ int driver_cancel(ca_context *c, uint32_t id) { return CA_SUCCESS; } + +int driver_playing(ca_context *c, uint32_t id, int *playing) { + struct private *p; + struct outstanding *out; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(playing, CA_ERROR_INVALID); + + p = PRIVATE(c); + + *playing = 0; + + ca_mutex_lock(p->outstanding_mutex); + + for (out = p->outstanding; out; out = out->next) { + + if (out->dead || + out->id != id) + continue; + + *playing = 1; + break; + } + + ca_mutex_unlock(p->outstanding_mutex); + + return CA_SUCCESS; +} diff --git a/src/canberra.h.in b/src/canberra.h.in index 5bf76b2..5bf198a 100644 --- a/src/canberra.h.in +++ b/src/canberra.h.in @@ -485,6 +485,7 @@ int ca_context_play(ca_context *c, uint32_t id, ...) __attribute__((sentinel)); int ca_context_cache_full(ca_context *c, ca_proplist *p); int ca_context_cache(ca_context *c, ...) __attribute__((sentinel)); int ca_context_cancel(ca_context *c, uint32_t id); +int ca_context_playing(ca_context *c, uint32_t id, int *playing); const char *ca_strerror(int code); diff --git a/src/common.c b/src/common.c index e2548ec..db60aa0 100644 --- a/src/common.c +++ b/src/common.c @@ -689,3 +689,32 @@ int ca_parse_cache_control(ca_cache_control_t *control, const char *c) { return CA_SUCCESS; } + +/** + * ca_context_playing: + * @c: the context to check if sound is still playing + * @id: the id that identify the sounds to check + * @playing: a pointer to a boolean that will be updated with the play status + * + * Check if at least one sound with the specified id is still + * playing. Returns 0 in *playing if no sound with this id is playing + * anymore or non-zero if there is at least one playing. + * + * Returns: 0 on success, negative error code on error. + * Since: 0.16 + */ +int ca_context_playing(ca_context *c, uint32_t id, int *playing) { + int ret; + + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(playing, CA_ERROR_INVALID); + ca_mutex_lock(c->mutex); + ca_return_val_if_fail_unlock(c->opened, CA_ERROR_STATE, c->mutex); + + ret = driver_playing(c, id, playing); + + ca_mutex_unlock(c->mutex); + + return ret; +} diff --git a/src/driver.h b/src/driver.h index 98b40d7..c843b8d 100644 --- a/src/driver.h +++ b/src/driver.h @@ -33,4 +33,6 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_callback_t int driver_cancel(ca_context *c, uint32_t id); int driver_cache(ca_context *c, ca_proplist *p); +int driver_playing(ca_context *c, uint32_t id, int *playing); + #endif diff --git a/src/dso.c b/src/dso.c index c9c2a15..97c04d4 100644 --- a/src/dso.c +++ b/src/dso.c @@ -42,6 +42,7 @@ struct private_dso { int (*driver_play)(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_callback_t cb, void *userdata); int (*driver_cancel)(ca_context *c, uint32_t id); int (*driver_cache)(ca_context *c, ca_proplist *p); + int (*driver_playing)(ca_context *c, uint32_t id, int *playing); }; #define PRIVATE_DSO(c) ((struct private_dso *) ((c)->private_dso)) @@ -257,7 +258,8 @@ int driver_open(ca_context *c) { !(p->driver_change_props = GET_FUNC_PTR(p->module, driver, "driver_change_props", int, (ca_context *, ca_proplist *, ca_proplist *))) || !(p->driver_play = GET_FUNC_PTR(p->module, driver, "driver_play", int, (ca_context*, uint32_t, ca_proplist *, ca_finish_callback_t, void *))) || !(p->driver_cancel = GET_FUNC_PTR(p->module, driver, "driver_cancel", int, (ca_context*, uint32_t))) || - !(p->driver_cache = GET_FUNC_PTR(p->module, driver, "driver_cache", int, (ca_context*, ca_proplist *)))) { + !(p->driver_cache = GET_FUNC_PTR(p->module, driver, "driver_cache", int, (ca_context*, ca_proplist *))) || + !(p->driver_playing = GET_FUNC_PTR(p->module, driver, "driver_playing", int, (ca_context*, uint32_t, int*)))) { ca_free(driver); driver_destroy(c); @@ -361,3 +363,16 @@ int driver_cache(ca_context *c, ca_proplist *pl) { return p->driver_cache(c, pl); } + +int driver_playing(ca_context *c, uint32_t id, int *playing) { + struct private_dso *p; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE); + ca_return_val_if_fail(playing, CA_ERROR_INVALID); + + p = PRIVATE_DSO(c); + ca_return_val_if_fail(p->driver_playing, CA_ERROR_STATE); + + return p->driver_playing(c, id, playing); +} diff --git a/src/gstreamer.c b/src/gstreamer.c index 4173479..5ff835c 100644 --- a/src/gstreamer.c +++ b/src/gstreamer.c @@ -552,3 +552,31 @@ int driver_cache(ca_context *c, ca_proplist *proplist) { return CA_ERROR_NOTSUPPORTED; } + +int driver_playing(ca_context *c, uint32_t id, int *playing) { + struct private *p; + struct outstanding *out; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(playing, CA_ERROR_INVALID); + + p = PRIVATE(c); + + *playing = 0; + + ca_mutex_lock(p->outstanding_mutex); + + for (out = p->outstanding; out; out = out->next) { + + if (out->id != id || out->pipeline == NULL || out->dead == TRUE) + continue; + + *playing = 1; + break; + } + + ca_mutex_unlock(p->outstanding_mutex); + + return CA_SUCCESS; +} diff --git a/src/multi.c b/src/multi.c index 598b1f2..233e635 100644 --- a/src/multi.c +++ b/src/multi.c @@ -330,3 +330,32 @@ int driver_cache(ca_context *c, ca_proplist *proplist) { return ret; } + +int driver_playing(ca_context *c, uint32_t id, int *playing) { + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(playing, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + p = PRIVATE(c); + + *playing = 0; + + for (b = p->backends; b; b = b->next) { + int r, _playing = 0; + + r = ca_context_playing(b->context, id, &_playing); + + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + + if (_playing) + *playing = 1; + } + + return ret; +} diff --git a/src/oss.c b/src/oss.c index 6135780..eebc2f8 100644 --- a/src/oss.c +++ b/src/oss.c @@ -499,3 +499,32 @@ int driver_cancel(ca_context *c, uint32_t id) { return CA_SUCCESS; } + +int driver_playing(ca_context *c, uint32_t id, int *playing) { + struct private *p; + struct outstanding *out; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(playing, CA_ERROR_INVALID); + + p = PRIVATE(c); + + *playing = 0; + + ca_mutex_lock(p->outstanding_mutex); + + for (out = p->outstanding; out; out = out->next) { + + if (out->dead || + out->id != id) + continue; + + *playing = 1; + break; + } + + ca_mutex_unlock(p->outstanding_mutex); + + return CA_SUCCESS; +} diff --git a/src/pulse.c b/src/pulse.c index 2a61c8f..2283b68 100644 --- a/src/pulse.c +++ b/src/pulse.c @@ -1271,3 +1271,33 @@ finish_unlocked: return ret; } + +int driver_playing(ca_context *c, uint32_t id, int *playing) { + struct private *p; + struct outstanding *out; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(playing, CA_ERROR_INVALID); + + p = PRIVATE(c); + + *playing = 0; + + ca_mutex_lock(p->outstanding_mutex); + + for (out = p->outstanding; out; out = out->next) { + + if (out->type == OUTSTANDING_UPLOAD || + out->id != id || + out->sink_input == PA_INVALID_INDEX) + continue; + + *playing = 1; + break; + } + + ca_mutex_unlock(p->outstanding_mutex); + + return CA_SUCCESS; +} -- cgit