Remove waiting for stream closure in multi-thread audio

This commit is contained in:
erorcun 2021-06-27 14:42:52 +03:00
parent 5458632c40
commit db4ae18e5d
3 changed files with 23 additions and 20 deletions

View File

@ -36,6 +36,7 @@ std::mutex gAudioThreadQueueMutex;
std::condition_variable gAudioThreadCv; std::condition_variable gAudioThreadCv;
bool gAudioThreadTerm = false; bool gAudioThreadTerm = false;
std::queue<CStream*> gStreamsToProcess; // values are not unique, we will handle that ourself std::queue<CStream*> gStreamsToProcess; // values are not unique, we will handle that ourself
std::queue<std::pair<IDecoder*, void*>> gStreamsToClose;
#else #else
#include "stream.h" #include "stream.h"
#endif #endif
@ -1012,7 +1013,11 @@ CStream::FlagAsToBeProcessed(bool close)
return; return;
gAudioThreadQueueMutex.lock(); gAudioThreadQueueMutex.lock();
gStreamsToProcess.push(this); if (close)
gStreamsToClose.push(std::pair<IDecoder*, void*>(m_pSoundFile ? m_pSoundFile : nil, m_pBuffer ? m_pBuffer : nil));
else
gStreamsToProcess.push(this);
gAudioThreadQueueMutex.unlock(); gAudioThreadQueueMutex.unlock();
gAudioThreadCv.notify_one(); gAudioThreadCv.notify_one();
@ -1026,10 +1031,22 @@ void audioFileOpsThread()
{ {
// Just a semaphore // Just a semaphore
std::unique_lock<std::mutex> queueMutex(gAudioThreadQueueMutex); std::unique_lock<std::mutex> queueMutex(gAudioThreadQueueMutex);
gAudioThreadCv.wait(queueMutex, [] { return gStreamsToProcess.size() > 0 || gAudioThreadTerm; }); gAudioThreadCv.wait(queueMutex, [] { return gStreamsToProcess.size() > 0 || gStreamsToClose.size() > 0 || gAudioThreadTerm; });
if (gAudioThreadTerm) if (gAudioThreadTerm)
return; return;
if (!gStreamsToClose.empty()) {
auto streamToClose = gStreamsToClose.front();
gStreamsToClose.pop();
if (streamToClose.first) { // pSoundFile
delete streamToClose.first;
}
if (streamToClose.second) { // pBuffer
free(streamToClose.second);
}
}
if (!gStreamsToProcess.empty()) { if (!gStreamsToProcess.empty()) {
stream = gStreamsToProcess.front(); stream = gStreamsToProcess.front();
gStreamsToProcess.pop(); gStreamsToProcess.pop();
@ -1044,18 +1061,6 @@ void audioFileOpsThread()
do { do {
if (!stream->IsOpened()) { if (!stream->IsOpened()) {
// We MUST do that here, because we release mutex for m_pSoundFile->Seek() and m_pSoundFile->Decode() since they're costly
if (stream->m_pSoundFile) {
delete stream->m_pSoundFile;
stream->m_pSoundFile = nil;
}
if (stream->m_pBuffer) {
free(stream->m_pBuffer);
stream->m_pBuffer = nil;
}
lock.unlock();
stream->m_closeCv.notify_one();
break; break;
} }
@ -1166,10 +1171,6 @@ bool CStream::Open(const char* filename, uint32 overrideSampleRate)
#ifdef MULTITHREADED_AUDIO #ifdef MULTITHREADED_AUDIO
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
CStream *stream = this;
// Wait for thread to close old one. We can't close it here, because the thread might be running Decode() or Seek(), while mutex is released
m_closeCv.wait(lock, [this] { return m_pSoundFile == nil && m_pBuffer == nil; });
m_bDoSeek = false; m_bDoSeek = false;
m_SeekPos = 0; m_SeekPos = 0;
#endif #endif
@ -1255,7 +1256,8 @@ void CStream::Close()
Stop(); Stop();
ClearBuffers(); ClearBuffers();
m_bIExist = false; m_bIExist = false;
// clearing buffer queues are not needed. after m_bIExist is cleared, this stream is ded std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // TSness not required, mutex is acquired
} }
FlagAsToBeProcessed(true); FlagAsToBeProcessed(true);

View File

@ -127,7 +127,7 @@ public:
std::mutex m_mutex; std::mutex m_mutex;
std::queue<std::pair<ALuint, ALuint>> m_fillBuffers; // left and right buffer std::queue<std::pair<ALuint, ALuint>> m_fillBuffers; // left and right buffer
tsQueue<std::pair<ALuint, ALuint>> m_queueBuffers; tsQueue<std::pair<ALuint, ALuint>> m_queueBuffers;
std::condition_variable m_closeCv; // std::condition_variable m_closeCv;
bool m_bDoSeek; bool m_bDoSeek;
uint32 m_SeekPos; uint32 m_SeekPos;
bool m_bIExist; bool m_bIExist;

View File

@ -526,6 +526,7 @@ _FindMP3s(void)
{ {
total_ms = aStream[0]->GetLengthMS(); total_ms = aStream[0]->GetLengthMS();
aStream[0]->Close(); aStream[0]->Close();
OutputDebugString(fd.cFileName); OutputDebugString(fd.cFileName);
_pMP3List = new tMP3Entry; _pMP3List = new tMP3Entry;