Updated priority concept has been implemented. 18/79018/6
authoro.danchenko <o.danchenko@samsung.com>
Thu, 7 Jul 2016 17:05:54 +0000 (20:05 +0300)
committero.danchenko <o.danchenko@samsung.com>
Thu, 14 Jul 2016 13:49:36 +0000 (16:49 +0300)
Change-Id: Ib93d525ca176788af8d1f015b3c419637be92e89
Signed-off-by: o.danchenko <o.danchenko@samsung.com>
src/priority.c
src/sound_pool.c
src/soundpool.c
src/source.c
src/stream.c

index 0f5a7f2..834f83a 100644 (file)
@@ -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) !=
index 54c802e..66d51fd 100644 (file)
@@ -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;
 }
index e62ae59..2c8707d 100644 (file)
@@ -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) {
index 09631b3..09f6906 100644 (file)
@@ -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;
 }
index aace90f..eefe07f 100644 (file)
@@ -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;