There are no syncronization between audio_in_read() and audio_in_unprepare().
Therefore, assert crash occurs possibly while use multiple reader thread.
Changes:
* Add locking method at audio_in_read() and null check of mpPulseAudioClient.
* Fixed syncronous-method of audio_out_write() too.
* Miscellaneous typos are fixed.
[Version] 0.3.45
[Profile] Common
[Issue Type] Bug Fix
Signed-off-by: KimJeongYeon <jeongyeon.kim@samsung.com>
Change-Id: I18147b9e1e7bb5c16816250d65d2ff066f6383b7
(cherry picked from commit
b465e5b8b0898e2b639ac899426faace320a36cb)
Name: capi-media-audio-io
Summary: An Audio Input & Audio Output library in Tizen Native API
-Version: 0.3.44
+Version: 0.3.45
Release: 0
Group: Multimedia/API
License: Apache-2.0
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The audioType is invalid [type:%d]", static_cast<int>(audioType));
}
- if (mpAudioSessionHandler->getId() < 0) { //Did not registerSound()
+ if (mpAudioSessionHandler->getId() < 0) { // Did not registerSound()
// Check session to skip registration
if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSessionEvent() == false) {
// Register ASM Listener
int ret = 0;
try {
+ internalLock();
+
+ // If another thread did call unprepare, do not read
+ if (mpPulseAudioClient == NULL)
+ THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+
// Block until read done
ret = mpPulseAudioClient->read(buffer, length);
+
+ internalUnlock();
} catch (CAudioError e) {
+ internalUnlock();
throw e;
}
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "The audioType is invalid [type:%d]", static_cast<int>(audioType));
}
- if (mpAudioSessionHandler->getId() < 0) { //Did not registerSound()
+ if (mpAudioSessionHandler->getId() < 0) { // Did not registerSound()
if (isForceIgnore() == false) {
// Register ASM Listener
AUDIO_IO_LOGD("Register ASM Listener");
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameters are invalid - buffer:%p, length:%zu", buffer, length);
}
- /* When write() is called in PulseAudio callback, bypass a pcm data to PulseAudioClient (For Asynchronous) */
+ /* When write() is called in PulseAudio callback, bypass a pcm data to CPulseAudioClient (For Asynchronous) */
if (mpPulseAudioClient->isInThread() == true) {
int ret = mpPulseAudioClient->write(buffer, length);
if (ret < 0) {
/* For synchronization */
internalLock();
+ // If another thread did call unprepare, do not write
+ if (mpPulseAudioClient == NULL)
+ THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+
// Sets synchronous flag
__mIsUsedSyncWrite = true;
}
#ifdef _AUDIO_IO_DEBUG_TIMING_
- AUDIO_IO_LOGD("PulseAudioClient->write(buffer:%p, length:%d)", buffer, l);
+ AUDIO_IO_LOGD("CPulseAudioClient->write(buffer:%p, length:%d)", buffer, l);
#endif
int ret = mpPulseAudioClient->write(buffer, l);
// Copy partial pcm data on out parameter
#ifdef _AUDIO_IO_DEBUG_TIMING_
- AUDIO_IO_LOGD("memcpy() that a peeked buffer[%], index[%d], length[%d] on out buffer", (const uint8_t*)(__mpSyncReadDataPtr) + __mSyncReadIndex, __mSyncReadIndex, l);
+ AUDIO_IO_LOGD("memcpy() that a peeked buffer[0x%x], index[%d], length[%d] on out buffer", (const uint8_t*)(__mpSyncReadDataPtr) + __mSyncReadIndex, __mSyncReadIndex, l);
#endif
memcpy(buffer, (const uint8_t*)__mpSyncReadDataPtr + __mSyncReadIndex, l);
if (outputHandle == NULL) {
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
}
- size_t writen = outputHandle->write(buffer, static_cast<size_t>(length));
- ret = static_cast<int>(writen);
+ size_t written = outputHandle->write(buffer, static_cast<size_t>(length));
+ ret = static_cast<int>(written);
#ifdef _AUDIO_IO_DEBUG_TIMING_
- AUDIO_IO_LOGD("writen:%d", writen);
+ AUDIO_IO_LOGD("written:%d", written);
#endif
} catch (CAudioError e) {
AUDIO_IO_LOGE("%s", e.getErrorMsg());
fclose(fp);
+ audio_in_unprepare(input);
audio_in_destroy(input);
}