-
Notifications
You must be signed in to change notification settings - Fork 411
llama-17925 : TextToSpeech crash, followed by black screen #6454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: sprint/26Q1
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -538,7 +538,7 @@ bool TTSSpeaker::pause(uint32_t id) { | |
| if(m_pipeline) { | ||
| if(!m_isPaused) { | ||
| m_isPaused = true; | ||
| gst_element_set_state(m_pipeline, GST_STATE_PAUSED); | ||
| setPipelineState(GST_STATE_PAUSED); | ||
| TTSLOG_INFO("Set state to PAUSED"); | ||
| return true; | ||
| } | ||
|
|
@@ -552,7 +552,7 @@ bool TTSSpeaker::resume(uint32_t id) { | |
|
|
||
| if(m_pipeline) { | ||
| if(m_isPaused) { | ||
| gst_element_set_state(m_pipeline, GST_STATE_PLAYING); | ||
| setPipelineState(GST_STATE_PLAYING); | ||
| TTSLOG_INFO("Set state to PLAYING"); | ||
| return true; | ||
| } | ||
|
|
@@ -923,6 +923,18 @@ void TTSSpeaker::createPipeline(PipelineType type) { | |
| resetPipeline(); | ||
| } | ||
|
|
||
| void TTSSpeaker::setPipelineState(GstState state) { | ||
| if(m_pipeline) | ||
| { | ||
| std::lock_guard<std::mutex> lock(m_pipelineMutex); | ||
| gst_element_set_state(m_pipeline, state); | ||
| } | ||
| else | ||
| { | ||
| TTSLOG_ERROR("Pipeline error occured"); | ||
|
||
| } | ||
| } | ||
|
|
||
| void TTSSpeaker::resetPipeline() { | ||
| TTSLOG_WARNING("Resetting Pipeline..."); | ||
|
|
||
|
|
@@ -944,7 +956,7 @@ void TTSSpeaker::resetPipeline() { | |
| createPipeline(m_pipelinetype); | ||
| } else { | ||
| // If pipeline is present, bring it to NULL state | ||
| gst_element_set_state(m_pipeline, GST_STATE_NULL); | ||
| setPipelineState(GST_STATE_NULL); | ||
| while(!waitForStatus(GST_STATE_NULL, 60*1000)); | ||
| } | ||
| } | ||
|
|
@@ -953,7 +965,7 @@ void TTSSpeaker::destroyPipeline() { | |
| TTSLOG_WARNING("Destroying Pipeline..."); | ||
|
|
||
| if(m_pipeline) { | ||
| gst_element_set_state(m_pipeline, GST_STATE_NULL); | ||
| setPipelineState(GST_STATE_NULL); | ||
| waitForStatus(GST_STATE_NULL, 1*1000); | ||
| g_source_remove(m_busWatch); | ||
| gst_object_unref(m_pipeline); | ||
|
Comment on lines
967
to
971
|
||
|
|
@@ -1015,8 +1027,7 @@ void TTSSpeaker::waitForAudioToFinishTimeout(float timeout_s) { | |
| m_isEOS, m_pipeline, m_pipelineError, m_flushed); | ||
|
|
||
| // Irrespective of EOS / Timeout reset pipeline | ||
| if(m_pipeline) | ||
| gst_element_set_state(m_pipeline, GST_STATE_NULL); | ||
| setPipelineState(GST_STATE_NULL); | ||
|
|
||
| if(!m_isEOS) | ||
| TTSLOG_ERROR("Stopped waiting for audio to finish without hitting EOS!"); | ||
|
|
@@ -1068,7 +1079,7 @@ void TTSSpeaker::play(string url, SpeechData &data, bool authrequired, string to | |
| // PCM Sink seems to be accepting volume change before PLAYING state | ||
| g_object_set(G_OBJECT(m_audioVolume), "volume", (double) (data.client->configuration()->volume() / MAX_VOLUME), NULL); | ||
|
|
||
| gst_element_set_state(m_pipeline, GST_STATE_PLAYING); | ||
| setPipelineState(GST_STATE_PLAYING); | ||
|
|
||
| #if defined(PLATFORM_AMLOGIC) || defined(PLATFORM_REALTEK) || defined(PLATFORM_BROADCOM) | ||
| setMixGain(MIXGAIN_PRIM,data.primVolDuck); | ||
|
|
@@ -1148,7 +1159,7 @@ void TTSSpeaker::GStreamerThreadFunc(void *ctx) { | |
| // Stop thread on Speaker's cue | ||
| if(!speaker->m_runThread) { | ||
| if(speaker->m_pipeline) { | ||
| gst_element_set_state(speaker->m_pipeline, GST_STATE_NULL); | ||
| speaker->setPipelineState(GST_STATE_NULL); | ||
| speaker->waitForStatus(GST_STATE_NULL, 1*1000); | ||
| } | ||
| TTSLOG_INFO("Stopping GStreamerThread"); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setPipelineState function has a time-of-check-time-of-use (TOCTOU) race condition. The m_pipeline pointer is checked for NULL before acquiring the mutex lock, but m_pipeline could be set to NULL by another thread (e.g., in destroyPipeline at line 975 or createPipeline at line 910) between the check and the lock acquisition. The NULL check should be performed after acquiring the mutex lock to ensure thread safety.