From: Suyeon Hwang Date: Wed, 21 Apr 2021 10:40:41 +0000 (+0900) Subject: Use single play thread to play PCM data X-Git-Tag: submit/tizen/20220218.073949~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F10%2F266210%2F9;p=platform%2Fcore%2Fuifw%2Ftts.git Use single play thread to play PCM data To simplify the management of player thread, this patch makes only one sub thread to play PCM data. Change-Id: I9f0a050f59411bb692e038488e474dce0716cb46 Signed-off-by: Suyeon Hwang --- diff --git a/server/ttsd_player.c b/server/ttsd_player.c index cb51e1ad..cd379580 100644 --- a/server/ttsd_player.c +++ b/server/ttsd_player.c @@ -112,6 +112,7 @@ static double g_bg_volume_ratio; static pthread_mutex_t g_play_thread_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_player_control_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t g_play_thread_cond = PTHREAD_COND_INITIALIZER; /* * Internal Interfaces */ @@ -580,7 +581,7 @@ bool ttsd_player_does_interrupt_have_playback_focus() return result; } -static void __play_thread(void *data, Ecore_Thread *thread) +static void __play_thread_old(void *data, Ecore_Thread *thread) { SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread"); @@ -599,7 +600,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* set volume policy as 40% */ __set_policy_for_playing(); while (1) { // 1st while(1) - pthread_mutex_lock(&g_play_thread_mutex); /* check g_playing_info one more time */ if (false == __is_player_valid(player)) { SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player is not valid"); @@ -609,7 +609,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); } __unset_policy_for_playing(); - pthread_mutex_unlock(&g_play_thread_mutex); return; } @@ -662,7 +661,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - pthread_mutex_unlock(&g_play_thread_mutex); return; } __set_playing_status(true); @@ -694,7 +692,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) } /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - pthread_mutex_unlock(&g_play_thread_mutex); return; } else if (0 < ttsd_data_get_sound_data_size(player->uid)) { /* new audio data come */ @@ -719,8 +716,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); } - } else { // TTSD_SYNTHESIS_CONTROL_DOING - SLOG(LOG_ERROR, tts_tag(), "[Player] Sound data is NULL, while engine is on processing to synthesize"); } } // end of 2nd while(1). waiting for new audio data come @@ -733,7 +728,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* resume play thread */ player->state = APP_STATE_PLAYING; - pthread_mutex_unlock(&g_play_thread_mutex); continue; } // NULL == sound_data @@ -750,7 +744,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - pthread_mutex_unlock(&g_play_thread_mutex); return; } @@ -781,7 +774,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - pthread_mutex_unlock(&g_play_thread_mutex); return; } @@ -801,7 +793,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) } // 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_clear_sound_data(&sound_data); - pthread_mutex_unlock(&g_play_thread_mutex); continue; } // (NULL == sound_data->data || 0 >= sound_data->data_size) } // NO player->is_paused_data @@ -819,8 +810,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - - pthread_mutex_unlock(&g_play_thread_mutex); return; } @@ -853,11 +842,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - - pthread_mutex_unlock(&g_play_thread_mutex); - pthread_mutex_lock(&g_player_control_mutex); - g_playing_info = NULL; - pthread_mutex_unlock(&g_player_control_mutex); return; } SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio"); @@ -889,8 +873,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - - pthread_mutex_unlock(&g_play_thread_mutex); return; } // (NULL == g_playing_info && APP_STATE_PAUSED != player->state) @@ -917,7 +899,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) } /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - pthread_mutex_unlock(&g_play_thread_mutex); return; } // (APP_STATE_PAUSED == player->state) } // while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) @@ -938,7 +919,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - pthread_mutex_unlock(&g_play_thread_mutex); return; } // (NULL == g_playing_info && APP_STATE_READY == player->state) @@ -952,7 +932,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - pthread_mutex_unlock(&g_play_thread_mutex); return; } @@ -966,7 +945,6 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - pthread_mutex_unlock(&g_play_thread_mutex); return; } @@ -985,12 +963,30 @@ static void __play_thread(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); ttsd_data_clear_sound_data(&sound_data); - pthread_mutex_unlock(&g_play_thread_mutex); return; } + } // end of 1st while(1) +} + +static void __play_thread(void *data, Ecore_Thread *thread) +{ + SLOG(LOG_INFO, tts_tag(), "[Player] play thread is on"); + + while (g_player_init) { + SLOG(LOG_INFO, tts_tag(), "[Player] Wait play request..."); + pthread_cond_wait(&g_play_thread_cond, &g_play_thread_mutex); + if (false == g_player_init) { + SLOG(LOG_INFO, tts_tag(), "[Player] Player is released"); + pthread_mutex_unlock(&g_play_thread_mutex); + break; + } + __play_thread_old(data, thread); pthread_mutex_unlock(&g_play_thread_mutex); - } // end of 1st while(1) + pthread_mutex_lock(&g_player_control_mutex); + g_playing_info = NULL; + pthread_mutex_unlock(&g_player_control_mutex); + } } int __create_ducking_handle(void) @@ -1084,6 +1080,8 @@ int ttsd_player_init() return -1; } + ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL); + g_player_init = true; pthread_mutex_unlock(&g_player_control_mutex); @@ -1181,6 +1179,7 @@ int ttsd_player_release(void) /* clear g_player_list */ g_playing_info = NULL; g_player_init = false; + pthread_cond_broadcast(&g_play_thread_cond); g_stream_info_h = NULL; @@ -1312,12 +1311,10 @@ int ttsd_player_play(unsigned int uid) } current->state = APP_STATE_PLAYING; - g_playing_info = current; - SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get()); SLOG(LOG_INFO, tts_tag(), "[Player] Run thread"); - ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL); + pthread_cond_broadcast(&g_play_thread_cond); pthread_mutex_unlock(&g_player_control_mutex); return 0; @@ -1471,7 +1468,7 @@ int ttsd_player_resume(unsigned int uid) g_playing_info = current; SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread"); - ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL); + pthread_cond_broadcast(&g_play_thread_cond); pthread_mutex_unlock(&g_player_control_mutex); return 0; diff --git a/server/ttsd_server.c b/server/ttsd_server.c index 8820e746..29b55b5b 100644 --- a/server/ttsd_server.c +++ b/server/ttsd_server.c @@ -985,6 +985,23 @@ int ttsd_server_add_queue(unsigned int uid, const char* text, const char* lang, return TTSD_ERROR_NONE; } +static int __pause_client(unsigned int uid) +{ + int ret = ttsd_data_set_client_state(uid, APP_STATE_PAUSED); + if (TTSD_ERROR_NONE != ret) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail set pause state() : ret(%d)", ret); + return TTSD_ERROR_OPERATION_FAILED; + } + + ret = ttsd_player_pause(uid); + if (TTSD_ERROR_NONE != ret) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail player_pause() : ret(%d)", ret); + return TTSD_ERROR_OPERATION_FAILED; + } + + return TTSD_ERROR_NONE; +} + void __send_interrupt_client(unsigned int uid) { SLOG(LOG_INFO, tts_tag(), "[Server] Send new state by policy. uid(%u)", uid); @@ -994,14 +1011,14 @@ void __send_interrupt_client(unsigned int uid) return; } - ttsd_mode_e mode = ttsd_data_get_mode(uid); - if (TTSD_MODE_DEFAULT != mode) { - /* send message to client about changing state */ - ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_READY); - } else { - ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_PAUSED); + app_tts_state_e state = APP_STATE_CREATED; + + if (0 != ttsd_data_get_client_state(uid, &state)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to get state. uid(%u), pid(%d)", uid, pid); + return; } + ttsdc_ipc_send_set_state_message(pid, uid, state); SLOG(LOG_INFO, tts_tag(), "[Server] Finish to send new state by policy. uid(%u)", uid); return; } @@ -1037,17 +1054,15 @@ int ttsd_server_play(unsigned int uid, const char* credential) unsigned int current_uid = ttsd_data_get_current_playing(); SLOG(LOG_INFO, tts_tag(), "[Server] playing uid (%u)", current_uid); - if (uid != current_uid && -1 != current_uid) { + if (uid != current_uid && 0 <= ttsd_data_is_client(current_uid)) { if (TTSD_MODE_DEFAULT != ttsd_data_get_mode(current_uid)) { /* Send interrupt message */ SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%u) will be interrupted into 'Stop' state ", current_uid); - /* pause player */ + /* stop player */ if (0 != ttsd_server_stop(current_uid)) { SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to stop server and player : uid (%u)", current_uid); } - - __send_interrupt_client(current_uid); } else { /* Default mode policy of interrupt is "Pause" */ @@ -1055,15 +1070,12 @@ int ttsd_server_play(unsigned int uid, const char* credential) SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%u) will be interrupted into 'Pause' state ", current_uid); /* pause player */ - if (0 != ttsd_player_pause(current_uid)) { - SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to ttsd_player_pause() : uid (%u)", current_uid); + if (0 != __pause_client(current_uid)) { + SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to ttsd_server_pause() : uid (%u)", current_uid); } - - /* change state */ - ttsd_data_set_client_state(current_uid, APP_STATE_PAUSED); - - __send_interrupt_client(current_uid); } + + __send_interrupt_client(current_uid); } /* Change current play */ @@ -1076,21 +1088,20 @@ int ttsd_server_play(unsigned int uid, const char* credential) return TTSD_ERROR_OPERATION_FAILED; } + int ret = TTSD_ERROR_NONE; if (APP_STATE_PAUSED == state) { SLOG(LOG_DEBUG, tts_tag(), "[Server] uid(%u) is 'Pause' state : resume player", uid); - g_is_paused = false; - - /* Resume player */ - if (0 != ttsd_player_resume(uid)) { - SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to ttsd_player_resume()"); - } + ret = ttsd_player_resume(uid); } else { SLOG(LOG_DEBUG, tts_tag(), "[Server] Play player. uid(%u)", uid); + ret = ttsd_player_play(uid); + } - if (0 != ttsd_player_play(uid)) { - SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to ttsd_player_play()"); - } + if (TTSD_ERROR_NONE != ret) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play sound : uid(%u)", uid); + ttsd_data_set_client_state(uid, state); + return TTSD_ERROR_OPERATION_FAILED; } ttsd_data_set_credential(uid, credential); @@ -1124,19 +1135,17 @@ int ttsd_server_stop(unsigned int uid) if (TTSD_SYNTHESIS_CONTROL_DOING == synth_control && uid == ttsd_data_get_current_playing()) { SLOG(LOG_DEBUG, tts_tag(), "[Server] TTS-engine is running"); - int ret = 0; - ret = ttsd_engine_cancel_synthesis(); - if (0 != ret) + int ret = ttsd_engine_cancel_synthesis(); + if (TTSD_ERROR_NONE != ret) SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to cancel synthesis : ret(%d)", ret); } ttsd_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED); /* stop player */ - if (0 != ttsd_player_stop(uid)) { + ttsd_data_set_client_state(uid, APP_STATE_READY); + if (TTSD_ERROR_NONE != ttsd_player_stop(uid)) { SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsd_player_stop()"); } - - ttsd_data_set_client_state(uid, APP_STATE_READY); } /* Reset all data */ @@ -1164,15 +1173,12 @@ int ttsd_server_pause(unsigned int uid, int* utt_id) *utt_id = g_utt.uttid; SLOG(LOG_INFO, tts_tag(), "[Server] server pause, uid(%u), g_uid(%u), utt_id(%d)", uid, g_utt.uid, *utt_id); - int ret = 0; - ret = ttsd_player_pause(uid); - if (0 != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail player_pause() : ret(%d)", ret); + int ret = __pause_client(uid); + if (TTSD_ERROR_NONE != ret) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to pause player : ret(%d)", ret); return TTSD_ERROR_OPERATION_FAILED; } - ttsd_data_set_client_state(uid, APP_STATE_PAUSED); - return TTSD_ERROR_NONE; } @@ -1304,17 +1310,15 @@ int ttsd_server_play_pcm(unsigned int uid) unsigned int current_uid = ttsd_data_get_current_playing(); SLOG(LOG_INFO, tts_tag(), "[Server] playing uid (%u)", current_uid); - if (uid != current_uid && -1 != current_uid) { + if (uid != current_uid && 0 <= ttsd_data_is_client(current_uid)) { if (TTSD_MODE_DEFAULT != ttsd_data_get_mode(current_uid)) { /* Send interrupt message */ SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%u) will be interrupted into 'Stop' state ", current_uid); - /* pause player */ + /* stop player */ if (0 != ttsd_server_stop(current_uid)) { SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to stop server and player : uid (%u)", current_uid); } - - __send_interrupt_client(current_uid); } else { /* Default mode policy of interrupt is "Pause" */ @@ -1322,15 +1326,12 @@ int ttsd_server_play_pcm(unsigned int uid) SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%u) will be interrupted into 'Pause' state ", current_uid); /* pause player */ - if (0 != ttsd_player_pause(current_uid)) { - SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to ttsd_player_pause() : uid (%u)", current_uid); + if (0 != __pause_client(current_uid)) { + SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to ttsd_server_pause() : uid (%u)", current_uid); } - - /* change state */ - ttsd_data_set_client_state(current_uid, APP_STATE_PAUSED); - - __send_interrupt_client(current_uid); } + + __send_interrupt_client(current_uid); } /* Change current play */ @@ -1339,27 +1340,20 @@ int ttsd_server_play_pcm(unsigned int uid) return TTSD_ERROR_OPERATION_FAILED; } + int ret = TTSD_ERROR_NONE; if (APP_STATE_PAUSED == state) { SLOG(LOG_DEBUG, tts_tag(), "[Server] uid(%u) is 'Pause' state : resume player", uid); - - /* Resume player */ - if (0 != ttsd_player_resume(uid)) { - SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to ttsd_player_resume()"); - } + g_is_paused = false; + ret = ttsd_player_resume(uid); } else { - if (0 != ttsd_player_play(uid)) { - SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play pcm sound : uid(%u)", uid); - - // Change ready state - ttsd_server_stop_pcm(uid); + SLOG(LOG_DEBUG, tts_tag(), "[Server] Play player. uid(%u)", uid); + ret = ttsd_player_play(uid); + } - int tmp_pid = ttsd_data_get_pid(uid); - if (tmp_pid <= 0) { - SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to send set_state_message. uid(%u)", uid); - } else { - ttsdc_ipc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); - } - } + if (TTSD_ERROR_NONE != ret) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play sound : uid(%u)", uid); + ttsd_data_set_client_state(uid, state); + return TTSD_ERROR_OPERATION_FAILED; } return TTSD_ERROR_NONE; @@ -1456,18 +1450,6 @@ int ttsd_server_add_pcm(unsigned int uid, int event, void* data, int data_size, free(temp_sound_data); temp_sound_data = NULL; } - -/* if (0 != ttsd_player_play(uid)) { - SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play sound : uid(%u)", uid); - - // Change ready state - ttsd_server_stop(uid); - - int tmp_pid; - tmp_pid = ttsd_data_get_pid(uid); - ttsdc_ipc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); - } -*/ } else { SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_ERROR"); }