From: o.danchenko Date: Thu, 7 Jul 2016 17:05:54 +0000 (+0300) Subject: Updated priority concept has been implemented. X-Git-Tag: accepted/tizen/common/20160824.154818~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32402b9cbb09ddde3e97bce5ba415c3db9f77fa6;p=platform%2Fcore%2Fapi%2Fsound-pool.git Updated priority concept has been implemented. Change-Id: Ib93d525ca176788af8d1f015b3c419637be92e89 Signed-off-by: o.danchenko --- diff --git a/src/priority.c b/src/priority.c index 0f5a7f2..834f83a 100644 --- a/src/priority.c +++ b/src/priority.c @@ -116,6 +116,12 @@ sound_pool_error_e _sound_stream_priority_remove_stream( return SOUND_POOL_ERROR_NONE; } +/* + * Checks selected stream for availability of playing. It depends + * on its position in priority queue and current state of other streams. + * The queue is analyzed downwards to lower priorities skipping all paused + * streams until first suspended stream is found. +*/ sound_pool_error_e _sound_stream_priority_check(stream_priority_manager_t *mgr, sound_stream_t *stream, gboolean *out) { @@ -128,13 +134,41 @@ sound_pool_error_e _sound_stream_priority_check(stream_priority_manager_t *mgr, SP_INST_CHECK(mgr->pool->sources, SOUND_POOL_ERROR_INVALID_PARAMETER); SP_INST_CHECK(g_hash_table_lookup(mgr->pool->sources, stream->parent_source->tag_name), SOUND_POOL_ERROR_KEY_NOT_AVAILABLE); + SP_RETVM_IF(NULL == mgr->priority_queue, SOUND_POOL_ERROR_INVALID_PARAMETER, + "Can't perform checking stream [%s] due to priority queue is NULL.", + stream->parent_source->tag_name); *out = FALSE; - int position = g_list_index(mgr->priority_queue, (gconstpointer)stream); - SP_RETVM_IF(-1 == position, SOUND_POOL_ERROR_INVALID_PARAMETER, - "Can't find stream in priority queue[%s]", stream->parent_source->tag_name); + sound_stream_t *ref_stream = (sound_stream_t*)(mgr->priority_queue->data); + gboolean flag_target_priority = FALSE; + gboolean flag_terminator = FALSE; + unsigned rank = ref_stream->priority; + + if (rank == stream->priority) { + *out = TRUE; + } else { + GList *iter = mgr->priority_queue; + for (; iter != NULL && !flag_terminator; iter = iter->next) { + sound_stream_t *str = (sound_stream_t *)iter->data; + if ((ref_stream->priority > str->priority)) { + if (flag_target_priority) { + flag_terminator = TRUE; + continue; + } + rank = ref_stream->priority; + ref_stream = str; + } + + if (SOUND_POOL_STREAM_STATE_PLAYING == str->state || + SOUND_POOL_STREAM_STATE_SUSPENDED == str->state) { + rank = str->priority; + flag_target_priority = TRUE; + } + } - *out = TRUE; + if (rank == stream->priority) + *out = TRUE; + } SP_DEBUG_FLEAVE(); return SOUND_POOL_ERROR_NONE; @@ -149,7 +183,8 @@ void _sound_stream_priority_update_playback(stream_priority_manager_t *mgr) gboolean can_run = FALSE; if (mgr->pool->state == SOUND_POOL_STATE_INACTIVE) { - SP_INFO("No need to update priority, Sound pool is INACTIVE."); + SP_INFO("No need to update streams state based on priority, " + "because of Sound pool is INACTIVE."); return; } @@ -159,15 +194,16 @@ void _sound_stream_priority_update_playback(stream_priority_manager_t *mgr) GList *iter = mgr->priority_queue; for (; iter != NULL; iter = iter->next) { sound_stream_t *stream = (sound_stream_t *)iter->data; + if (SOUND_POOL_ERROR_NONE != _sound_stream_priority_check(mgr, stream, &can_run)) continue; if (TRUE == can_run) { - if (SOUND_POOL_STREAM_STATE_PLAYING != stream->state) + if (SOUND_POOL_STREAM_STATE_PLAYING != stream->state && + SOUND_POOL_STREAM_STATE_PAUSED != stream->state) _sound_stream_play(stream); - } else { - if (SOUND_POOL_STREAM_STATE_PLAYING == stream->state) - _sound_stream_pause(stream); + } else if (SOUND_POOL_STREAM_STATE_PLAYING == stream->state) { + _sound_stream_pause(stream); stream->state_previous = stream->state; stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED; if (_stream_cb_manager_register_event(mgr->pool->cbmgr, stream) != diff --git a/src/sound_pool.c b/src/sound_pool.c index 54c802e..66d51fd 100644 --- a/src/sound_pool.c +++ b/src/sound_pool.c @@ -119,6 +119,7 @@ sound_pool_error_e sound_pool_stream_play(sound_pool_h pool, const char *tag, sound_pool_t *_pool = (sound_pool_t *)pool; sound_source_t *_source = NULL; + sound_pool_error_e ret_destroy = SOUND_POOL_ERROR_NONE; sound_pool_error_e ret = _sound_pool_get_source_by_tag(_pool, tag, &_source); SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when " "getting sound source [%s] from the sound pool", tag); @@ -130,27 +131,36 @@ sound_pool_error_e sound_pool_stream_play(sound_pool_h pool, const char *tag, "Error while creating sound source instance."); ret = _sound_stream_set_loop(_stream, loop); - SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when " - "setting sound stream loop parameter", tag); + if (ret != SOUND_POOL_ERROR_NONE) + GOTO_FAIL("Error occurred when setting sound stream loop parameter", cfail); ret = _sound_stream_set_volume(_stream, volume); - SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when " - "setting sound stream volume parameter", tag); + if (ret != SOUND_POOL_ERROR_NONE) + GOTO_FAIL("Error occurred when setting sound stream volume " "parameter", + cfail); if (callback) { ret = _sound_stream_set_callback(_stream, callback, data); - SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when " - "setting sound stream callback", tag); + if (ret != SOUND_POOL_ERROR_NONE) + GOTO_FAIL("Error occurred when setting sound stream callback", cfail); } ret = _sound_stream_set_priority(_stream, priority); - SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when " - "setting sound stream priority parameter", tag); + if (ret != SOUND_POOL_ERROR_NONE) + GOTO_FAIL("Error occurred when setting sound stream priority " + "parameter", cfail); *id = _stream->id; SP_DEBUG_FLEAVE(); return ret; + +cfail: + ret_destroy = _sound_stream_destroy(_stream); + SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret_destroy, ret_destroy, + "Error occurred during removal of uncompleted sound stream."); + SP_DEBUG_FLEAVE(); + return ret; } sound_pool_error_e sound_pool_stream_pause(sound_pool_h pool, unsigned id) @@ -168,6 +178,8 @@ sound_pool_error_e sound_pool_stream_pause(sound_pool_h pool, unsigned id) SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when " "pausing sound stream [%u]", id); + _sound_stream_priority_update_playback(_pool->mgr_priority); + SP_DEBUG_FLEAVE(); return ret; } @@ -186,6 +198,8 @@ sound_pool_error_e sound_pool_stream_resume(sound_pool_h pool, unsigned id) SP_RETVM_IF(ret != SOUND_POOL_ERROR_NONE, ret, "Error occurred when " "resuming sound stream [%u]", id); + _sound_stream_priority_update_playback(_pool->mgr_priority); + SP_DEBUG_FLEAVE(); return ret; } diff --git a/src/soundpool.c b/src/soundpool.c index e62ae59..2c8707d 100644 --- a/src/soundpool.c +++ b/src/soundpool.c @@ -201,6 +201,8 @@ sound_pool_error_e _sound_pool_activate(sound_pool_t *pool) sound_pool_state_e old_state = pool->state; pool->state = SOUND_POOL_STATE_ACTIVE; + _sound_stream_priority_update_playback(pool->mgr_priority); + /* Generate array of all AlSources in pool */ GPtrArray *streams = NULL; if (g_hash_table_size(pool->streams) > 0) { diff --git a/src/source.c b/src/source.c index 09631b3..09f6906 100644 --- a/src/source.c +++ b/src/source.c @@ -118,6 +118,7 @@ sound_pool_error_e _sound_source_create(sound_pool_t *pool, const char *tag, SOUND_POOL_ERROR_OUT_OF_MEMORY, "Memory alloc failure. Can't create sound _src"); + sound_pool_error_e ret_destroy = SOUND_POOL_ERROR_NONE; sound_pool_error_e ret = SOUND_POOL_ERROR_NONE; alGenBuffers(1, &_src->al_buffer); if (alGetError() != AL_NO_ERROR) { @@ -138,9 +139,9 @@ sound_pool_error_e _sound_source_create(sound_pool_t *pool, const char *tag, return ret; cfail: - ret = _sound_source_destroy(_src); - SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "Error occurred during removal " - "of sound source[%s].", tag); + ret_destroy = _sound_source_destroy(_src); + SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret_destroy, ret_destroy, + "Error occurred during removal of sound source[%s].", tag); SP_DEBUG_FLEAVE(); return ret; } diff --git a/src/stream.c b/src/stream.c index aace90f..eefe07f 100644 --- a/src/stream.c +++ b/src/stream.c @@ -247,6 +247,8 @@ sound_pool_error_e _sound_stream_destroy(sound_stream_t *stream) alSourcei(stream->al_source, AL_BUFFER, 0); alDeleteSources(1, &stream->al_source); SP_DEBUG("Deleting OpenAL source with id [%u]", stream->al_source); + if (alGetError() != AL_NO_ERROR) + SP_ERROR("OpenAL error while stream[%d] destroying.", stream->id); } else { SP_DEBUG("Can't set current context for deleting OpenAL source with id [%u]", stream->al_source); @@ -265,6 +267,7 @@ sound_pool_error_e _sound_stream_play(sound_stream_t *stream) SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER); SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER); sound_pool_t *pool = stream->parent_source->parent_pool; + sound_pool_error_e ret = SOUND_POOL_ERROR_NONE; SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER); SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED && stream->state != SOUND_POOL_STREAM_STATE_PAUSED && @@ -283,17 +286,16 @@ sound_pool_error_e _sound_stream_play(sound_stream_t *stream) stream->state == SOUND_POOL_STREAM_STATE_NONE) { stream->state_previous = stream->state; stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED; - if (_stream_cb_manager_register_event(pool->cbmgr, stream) != - SOUND_POOL_ERROR_NONE) - SP_DEBUG("State changing event wasn't registered." - "Callbacks will be not called"); - SP_DEBUG("Don't play due to SoundPool is in inactive state."); + ret = _stream_cb_manager_register_event(pool->cbmgr, stream); + SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event " + "wasn't registered. Callbacks will be not called"); + SP_INFO("Don't play due to SoundPool is in inactive state."); } else { alSourcePlay(stream->al_source); } SP_DEBUG_FLEAVE(); - return SOUND_POOL_ERROR_NONE; + return ret; } sound_pool_error_e _sound_stream_pause(sound_stream_t *stream) @@ -302,6 +304,7 @@ sound_pool_error_e _sound_stream_pause(sound_stream_t *stream) SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER); SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER); sound_pool_t *pool = stream->parent_source->parent_pool; + sound_pool_error_e ret = SOUND_POOL_ERROR_NONE; SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER); SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_SUSPENDED && stream->state != SOUND_POOL_STREAM_STATE_PLAYING, @@ -315,17 +318,16 @@ sound_pool_error_e _sound_stream_pause(sound_stream_t *stream) stream->state == SOUND_POOL_STREAM_STATE_SUSPENDED) { stream->state_previous = stream->state; stream->state = SOUND_POOL_STREAM_STATE_PAUSED; - if (_stream_cb_manager_register_event(pool->cbmgr, stream) != - SOUND_POOL_ERROR_NONE) - SP_DEBUG("State changing event wasn't registered." - "Callbacks will be not called"); - SP_DEBUG("Don't paused due to SoundPool is in inactive state."); + ret = _stream_cb_manager_register_event(pool->cbmgr, stream); + SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event " + "wasn't registered. Callbacks will be not called"); + SP_INFO("Don't paused due to SoundPool is in inactive state."); } else { alSourcePause(stream->al_source); } SP_DEBUG_FLEAVE(); - return SOUND_POOL_ERROR_NONE; + return ret; } sound_pool_error_e _sound_stream_resume(sound_stream_t *stream) @@ -334,6 +336,7 @@ sound_pool_error_e _sound_stream_resume(sound_stream_t *stream) SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER); SP_INST_CHECK(stream->parent_source, SOUND_POOL_ERROR_INVALID_PARAMETER); sound_pool_t *pool = stream->parent_source->parent_pool; + sound_pool_error_e ret = SOUND_POOL_ERROR_NONE; SP_INST_CHECK(pool, SOUND_POOL_ERROR_INVALID_PARAMETER); SP_RETVM_IF(stream->state != SOUND_POOL_STREAM_STATE_PAUSED, SOUND_POOL_ERROR_INVALID_OPERATION, "Can't resume stream in [%s] " @@ -347,17 +350,16 @@ sound_pool_error_e _sound_stream_resume(sound_stream_t *stream) { stream->state_previous = stream->state; stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED; - if (_stream_cb_manager_register_event(pool->cbmgr, stream) != - SOUND_POOL_ERROR_NONE) - SP_DEBUG("State changing event wasn't registered." - "Callbacks will be not called"); - SP_DEBUG("Don't resumed due to SoundPool is in inactive state."); + ret = _stream_cb_manager_register_event(pool->cbmgr, stream); + SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event " + "wasn't registered. Callbacks will be not called"); + SP_INFO("Don't resumed due to SoundPool is in inactive state."); } else { alSourcePlay(stream->al_source); } SP_DEBUG_FLEAVE(); - return SOUND_POOL_ERROR_NONE; + return ret; } sound_pool_error_e _sound_stream_stop(sound_stream_t *stream) @@ -462,19 +464,19 @@ sound_pool_error_e _sound_stream_set_priority(sound_stream_t *stream, SP_DEBUG_FENTER(); SP_INST_CHECK(stream, SOUND_POOL_ERROR_INVALID_PARAMETER); SP_INST_CHECK(stream->parent_source->parent_pool, SOUND_POOL_ERROR_INVALID_PARAMETER); - SP_INST_CHECK(stream->parent_source->parent_pool->mgr_priority, SOUND_POOL_ERROR_INVALID_PARAMETER); + SP_INST_CHECK(stream->parent_source->parent_pool->mgr_priority, + SOUND_POOL_ERROR_INVALID_PARAMETER); + sound_pool_error_e ret = SOUND_POOL_ERROR_NONE; stream->priority = rank; if (stream->parent_source->parent_pool->state == SOUND_POOL_STATE_INACTIVE) { if (stream->state == SOUND_POOL_STREAM_STATE_NONE) { stream->state_previous = stream->state; stream->state = SOUND_POOL_STREAM_STATE_SUSPENDED; - if (_stream_cb_manager_register_event( - stream->parent_source->parent_pool->cbmgr, stream) - != SOUND_POOL_ERROR_NONE) - SP_DEBUG( - "State changing event wasn't registered." "Callbacks" - " will be not called"); + ret = _stream_cb_manager_register_event( stream->parent_source->parent_pool->cbmgr, + stream); + SP_RETVM_IF(SOUND_POOL_ERROR_NONE != ret, ret, "State changing event " + "wasn't registered. Callbacks will be not called"); } SP_DEBUG("No need to update priority, Sound pool is INACTIVE."); return SOUND_POOL_ERROR_NONE;