Fix paused data handling logic 80/271380/1
authorSuyeon Hwang <stom.hwang@samsung.com>
Fri, 14 May 2021 05:37:55 +0000 (14:37 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Fri, 18 Feb 2022 10:33:29 +0000 (19:33 +0900)
By current pause logic, player_s stores pointer of paused sound_data_s and its data index for
resuming, and these are stored sperately by member variable of player_s.
However, the index and sound_data_s can be managed together if sound_data_s has the member for
data index, although current logic has no problem.
And also, managing together is easy and safe to handle paused data.
If we combine paseud index and data with sound_data_s, player_s should not store the data, because
the first data of the list from ttsd_data is the last played data and it should be paused data
itself.

By this patch, new functions are defined on ttsd_data. These functions provides interface to access
sound data. And also this patch creates new functions for checking whether client has pasued data
or not.

Change-Id: I9ca41a08bafdff97ae7b4ba3981897cd9485bbe4
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
server/ttsd_data.cpp
server/ttsd_data.h
server/ttsd_player.cpp

index 71baa77..c779083 100644 (file)
@@ -37,6 +37,7 @@ typedef struct
 
        std::list<speak_data_s*> m_speak_data;
        std::list<sound_data_s*> m_wav_data;
+       bool paused_data_existing;
 
        std::list<used_voice_s> m_used_voice;
        tts_ipc_method_e ipc_method;
@@ -166,6 +167,7 @@ int ttsd_data_new_client(int pid, unsigned int uid)
        app.mode = TTSD_MODE_DEFAULT;
        app.ipc_method = TTS_IPC_METHOD_UNDEFINED;
        app.credential = nullptr;
+       app.paused_data_existing = false;
 
        g_app_list.push_back(app);
 
@@ -600,6 +602,7 @@ sound_data_s* ttsd_data_create_sound_data(int utt_id, const void* data, unsigned
        sound_data->audio_type = audio_type;
        sound_data->rate = rate;
        sound_data->channels = channels;
+       sound_data->played_data_size = 0;
 
        return sound_data;
 }
@@ -664,10 +667,20 @@ static sound_data_s* __get_sound_data(app_data_s* app_data)
        return app_data->m_wav_data.front();
 }
 
-int ttsd_data_get_sound_data(unsigned int uid, sound_data_s** data)
+sound_data_s* ttsd_data_get_first_sound_data(unsigned int uid)
 {
-       SLOG(LOG_DEBUG, tts_tag(), "[DATA] sound_data_s: %p", *data);
+       lock_guard<mutex> lock(g_app_data_mutex);
+       app_data_s* app_data = __get_client_app_data(uid);
+       if (nullptr == app_data) {
+               SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
+               return nullptr;
+       }
+
+       return __get_sound_data(app_data);
+}
 
+int ttsd_data_pop_sound_data(unsigned int uid)
+{
        lock_guard<mutex> lock(g_app_data_mutex);
        app_data_s* app_data = __get_client_app_data(uid);
        if (nullptr == app_data) {
@@ -675,15 +688,12 @@ int ttsd_data_get_sound_data(unsigned int uid, sound_data_s** data)
                return TTSD_ERROR_INVALID_PARAMETER;
        }
 
-       sound_data_s* soundData = __get_sound_data(app_data);
-       if (nullptr == soundData) {
-               SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
+       if (app_data->m_wav_data.empty()) {
+               SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Sound data is empty (%u)", uid);
                return TTSD_ERROR_OPERATION_FAILED;
        }
 
        app_data->m_wav_data.pop_front();
-       *data = soundData;
-
        return TTSD_ERROR_NONE;
 }
 
@@ -764,6 +774,31 @@ int ttsd_data_set_client_state(unsigned int uid, app_tts_state_e state)
        return TTSD_ERROR_NONE;
 }
 
+int ttsd_data_set_paused_data_existing(unsigned int uid, bool is_paused_data_existing)
+{
+       lock_guard<mutex> lock(g_app_data_mutex);
+       app_data_s* app_data = __get_client_app_data(uid);
+       if (nullptr == app_data) {
+               SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
+               return TTSD_ERROR_INVALID_PARAMETER;
+       }
+
+       app_data->paused_data_existing = is_paused_data_existing;
+       return TTSD_ERROR_NONE;
+}
+
+bool ttsd_data_is_paused_data_existing(unsigned int uid)
+{
+       lock_guard<mutex> lock(g_app_data_mutex);
+       app_data_s* app_data = __get_client_app_data(uid);
+       if (nullptr == app_data) {
+               SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
+               return false;
+       }
+
+       return app_data->paused_data_existing;
+}
+
 unsigned int ttsd_data_get_current_playing()
 {
        lock_guard<mutex> lock(g_app_data_mutex);
index f0df92f..8c9a1b6 100644 (file)
@@ -50,6 +50,7 @@ typedef struct {
        int utt_id;
        char* data;
        unsigned int data_size;
+       unsigned int played_data_size;
 
        ttse_result_event_e event;
        ttse_audio_type_e audio_type;
@@ -104,7 +105,9 @@ void ttsd_data_destroy_sound_data(sound_data_s* sound_data);
 
 int ttsd_data_add_sound_data(unsigned int uid, sound_data_s* data);
 
-int ttsd_data_get_sound_data(unsigned int uid, sound_data_s** data);
+sound_data_s* ttsd_data_get_first_sound_data(unsigned int uid);
+
+int ttsd_data_pop_sound_data(unsigned int uid);
 
 int ttsd_data_get_sound_data_size(unsigned int uid);
 
@@ -119,6 +122,10 @@ int ttsd_data_get_client_state(unsigned int uid, app_tts_state_e* state);
 
 int ttsd_data_set_client_state(unsigned int uid, app_tts_state_e state);
 
+int ttsd_data_set_paused_data_existing(unsigned int uid, bool is_paused_data_existing);
+
+bool ttsd_data_is_paused_data_existing(unsigned int uid);
+
 
 unsigned int ttsd_data_get_current_playing();
 
index e268fbe..09292c5 100644 (file)
@@ -36,10 +36,6 @@ typedef struct {
 
        /* Current utterance information */
        ttse_result_event_e     event;  /** event of last utterance */
-
-       bool                    is_paused_data;
-       int                     idx;
-       sound_data_s*           paused_data;
 } player_s;
 
 #define SOUND_BUFFER_LENGTH    2048
@@ -344,26 +340,10 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                        return;
                }
 
-               if (true == player->is_paused_data && NULL != player->paused_data) {
+               if (ttsd_data_is_paused_data_existing(player->uid)) {
                        /* Resume player */
-                       sound_data_s* paused_data = player->paused_data;
-                       player->paused_data = NULL;
-
-                       ttsd_data_destroy_sound_data(sound_data);
-                       sound_data = ttsd_data_create_sound_data(paused_data->utt_id, paused_data->data, paused_data->data_size,
-                                       paused_data->event, paused_data->audio_type, paused_data->rate, paused_data->channels);
-                       if (NULL == sound_data || paused_data->data_size <= 0) {
-                               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Out of memory OR paused_data is empty");
-                               ttsd_data_destroy_sound_data(sound_data);
-                               sound_data = paused_data;
-                       } else { // NULL != sound_data && NULL != temp && player->paused_data->data_size > 0
-                               ttsd_data_destroy_sound_data(paused_data);
-                       }
-
-                       idx = player->idx;
-
-                       player->is_paused_data = false;
-                       player->idx = 0;
+                       sound_data = ttsd_data_get_first_sound_data(player->uid);
+                       ttsd_data_set_paused_data_existing(player->uid, false);
 
                        if (NULL == sound_data) {
                                /* Request unprepare */
@@ -378,9 +358,8 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                        SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)",
                                sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
                } else { // NO player->is_paused_data
-                       sound_data = NULL;
-                       ret = ttsd_data_get_sound_data(player->uid, &sound_data);
-                       if (0 != ret || NULL == sound_data) {
+                       sound_data = ttsd_data_get_first_sound_data(player->uid);
+                       if (nullptr == sound_data) {
                                /* empty queue */
                                SLOG(LOG_ERROR, tts_tag(), "[Player] No sound data. Waiting mode");
 
@@ -441,8 +420,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                                        SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
                                        /* unset volume policy, volume will be 100% */
                                        __unset_policy_for_playing();
-                                       ttsd_data_destroy_sound_data(sound_data);
-                                       sound_data = NULL;
                                        return;
                                }
 
@@ -463,7 +440,15 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                        idx = 0;
 
                        if (NULL == sound_data->data || 0 >= sound_data->data_size) {
-                               if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
+                               ttse_result_event_e event = sound_data->event;
+                               int utt_id = sound_data->utt_id;
+
+                               if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(player->uid)) {
+                                       ttsd_data_destroy_sound_data(sound_data);
+                               }
+                               sound_data = nullptr;
+
+                               if (TTSE_RESULT_EVENT_FINISH == event) {
                                        SLOG(LOG_DEBUG, tts_tag(), "No sound data");
                                        /* send utterence finish signal */
                                        int pid = ttsd_data_get_pid(player->uid);
@@ -472,8 +457,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                                                SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
                                                /* unset volume policy, volume will be 100% */
                                                __unset_policy_for_playing();
-                                               ttsd_data_destroy_sound_data(sound_data);
-                                               sound_data = NULL;
                                                return;
                                        }
 
@@ -484,16 +467,16 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
 #endif
 
                                        __set_playing_status(false);
-                                       if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
+
+
+                                       if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, utt_id)) {
                                                SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)",
-                                                       pid, player->uid, sound_data->utt_id);
+                                                       pid, player->uid, utt_id);
                                        } else {
-                                               SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
+                                               SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, utt_id);
                                        }
-                               } // TTSE_RESULT_EVENT_FINISH == sound_data->event
-                               SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", sound_data->event, player->uid, sound_data->utt_id);
-                               ttsd_data_destroy_sound_data(sound_data);
-                               sound_data = NULL;
+                               } // TTSE_RESULT_EVENT_FINISH == event
+                               SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", event, player->uid, utt_id);
                                continue;
                        } // (NULL == sound_data->data || 0 >= sound_data->data_size)
                } // NO player->is_paused_data
@@ -503,9 +486,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                        SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
                        /* unset volume policy, volume will be 100% */
                        __unset_policy_for_playing();
-
-                       ttsd_data_destroy_sound_data(sound_data);
-                       sound_data = NULL;
                        return;
                }
 
@@ -533,8 +513,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
 
                                        /* unset volume policy, volume will be 100% */
                                        __unset_policy_for_playing();
-                                       ttsd_data_destroy_sound_data(sound_data);
-                                       sound_data = NULL;
                                        return;
                                }
 
@@ -552,6 +530,7 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                                SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
                        } else {
                                idx += len;
+                               sound_data->played_data_size = idx;
                                SLOG(LOG_INFO, tts_tag(), "[Player INFO] After audio_out_write");
                        }
 
@@ -560,24 +539,15 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                                g_audio_stream->unprepareAudioOut();
                                /* unset volume policy, volume will be 100% */
                                __unset_policy_for_playing();
-
-                               ttsd_data_destroy_sound_data(sound_data);
-                               sound_data = NULL;
                                return;
                        } // (NULL == g_playing_info && APP_STATE_PAUSED != player->state)
 
                        if (APP_STATE_PAUSED == player->state) {
                                /* Save data */
                                SLOG(LOG_DEBUG, tts_tag(), "[Player] player(%p)", player);
-                               ttsd_data_destroy_sound_data(player->paused_data);
-                               player->paused_data = sound_data;
-
-                               player->is_paused_data = true;
-                               player->idx = idx;
-
+                               ttsd_data_set_paused_data_existing(player->uid, true);
 
                                SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause");
-
                                /* Request prepare */
                                g_audio_stream->unprepareAudioOut();
                                /* unset volume policy, volume will be 100% */
@@ -586,21 +556,16 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                        } // (APP_STATE_PAUSED == player->state)
                } // while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state)
 
-               if (NULL == g_playing_info && APP_STATE_READY == player->state) {
-                       /* player_stop */
-                       SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
+               ttse_result_event_e event = sound_data->event;
+               int utt_id = sound_data->utt_id;
 
-                       /* Request prepare */
-                       g_audio_stream->unprepareAudioOut();
-                       /* unset volume policy, volume will be 100% */
-                       __unset_policy_for_playing();
+               if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(player->uid)) {
                        ttsd_data_destroy_sound_data(sound_data);
-                       sound_data = NULL;
-                       return;
-               } // (NULL == g_playing_info && APP_STATE_READY == player->state)
+               }
+               sound_data = nullptr;
 
                if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
-                       (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
+                       (TTSE_RESULT_EVENT_FINISH == event)) {
                        /* send utterence finish signal */
                        int pid = ttsd_data_get_pid(player->uid);
 
@@ -608,8 +573,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                                SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
                                /* unset volume policy, volume will be 100% */
                                __unset_policy_for_playing();
-                               ttsd_data_destroy_sound_data(sound_data);
-                               sound_data = NULL;
                                return;
                        }
 
@@ -617,29 +580,34 @@ static void __play_thread_old(void *data, Ecore_Thread *thread)
                        __close_buffer_dump_file();
 #endif
                        __set_playing_status(false);
-                       if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
+
+                       if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, utt_id)) {
                                SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)",
-                                       pid, player->uid, sound_data->utt_id);
+                                       pid, player->uid, utt_id);
                                /* unset volume policy, volume will be 100% */
                                __unset_policy_for_playing();
-                               ttsd_data_destroy_sound_data(sound_data);
-                               sound_data = NULL;
                                return;
                        }
 
-                       SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
-               } // ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) && (TTSE_RESULT_EVENT_FINISH == sound_data->event))
+                       SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, utt_id);
+               } // ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) && (TTSE_RESULT_EVENT_FINISH == event))
 
-               ttsd_data_destroy_sound_data(sound_data);
-               sound_data = NULL;
+               if (NULL == g_playing_info && APP_STATE_READY == player->state) {
+                       /* player_stop */
+                       SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
+
+                       /* Request prepare */
+                       g_audio_stream->unprepareAudioOut();
+                       /* unset volume policy, volume will be 100% */
+                       __unset_policy_for_playing();
+                       return;
+               } // (NULL == g_playing_info && APP_STATE_READY == player->state)
 
                if (NULL == g_playing_info) {
                        SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
                        g_audio_stream->unprepareAudioOut();
                        /* unset volume policy, volume will be 100% */
                        __unset_policy_for_playing();
-                       ttsd_data_destroy_sound_data(sound_data);
-                       sound_data = NULL;
                        return;
                }
        } // end of 1st while(1)
@@ -764,9 +732,7 @@ int ttsd_player_create_instance(unsigned int uid)
        new_client->uid = uid;
        new_client->event = TTSE_RESULT_EVENT_FINISH;
        new_client->state = APP_STATE_READY;
-       new_client->is_paused_data = false;
-       new_client->idx = 0;
-       new_client->paused_data = NULL;
+       ttsd_data_set_paused_data_existing(uid, false);
 
        SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%u)", uid);
 
@@ -932,16 +898,9 @@ int ttsd_player_clear(unsigned int uid)
                return -1;
        }
 
-       if (true == current->is_paused_data) {
-               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data");
-               ttsd_data_destroy_sound_data(current->paused_data);
-               current->paused_data = NULL;
-       }
-
        current->event = TTSE_RESULT_EVENT_FINISH;
        current->state = APP_STATE_READY;
-       current->is_paused_data = false;
-       current->idx = 0;
+       ttsd_data_set_paused_data_existing(uid, false);
 
        SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%u)", uid);
 
@@ -1070,15 +1029,7 @@ int ttsd_player_all_stop()
                        if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
                                data->event = TTSE_RESULT_EVENT_FINISH;
                                data->state = APP_STATE_READY;
-
-                               if (true == data->is_paused_data) {
-                                       SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data");
-                                       ttsd_data_destroy_sound_data(data->paused_data);
-                                       data->paused_data = NULL;
-                               }
-
-                               data->is_paused_data = false;
-                               data->idx = 0;
+                               ttsd_data_set_paused_data_existing(data->uid, false);
                        }
 
                        /* Get next item */