123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- #include "Main.h"
- #include "AudioThread.h"
- #include "AudioLayer.h"
- #include <assert.h>
- extern unsigned long endTime;
- DWORD WINAPI AudThread_stub(void *ptr)
- {
- ((AudioThread *)ptr)->AudThread();
- return 0;
- }
- void AudioThread::Start(WMHandler *_output)
- {
- assert(_output);
- output = _output;
- eof=0;
- ResetEvent(stopped);
- QueueUserAPC(MediaThread_StartAPC, thread, reinterpret_cast<ULONG_PTR>(static_cast<MediaThread *>(this)));
- }
- AudioThread::AudioThread(AudioLayer *audio) : output(0), audioLayer(audio)
- {
- DWORD id;
- thread = CreateThread(NULL, 256*1024, AudThread_stub, (void *)this, NULL, &id);
- SetThreadPriority(thread, AGAVE_API_CONFIG->GetInt(playbackConfigGroupGUID, L"priority", THREAD_PRIORITY_HIGHEST));
- }
- void AudioThread::AudThread()
- {
- int endbreak=0;
- while (true)
- {
- switch (WaitForSingleObjectEx(killEvent, wait, TRUE))
- {
- case WAIT_OBJECT_0:
- //StopAPC();
- return;
- case WAIT_TIMEOUT:
- {
- if (buffers.empty() || endbreak)
- {
- SetEvent(bufferFreed);
- if (eof==1)
- {
- eof=2;
- output->EndOfFile();
- }
- endbreak = 0;
- continue;
- }
- MediaBuffer *buffer = buffers.front();
- DWORD length;
- void *data;
- buffer->buffer->GetBufferAndLength((BYTE **)&data, &length);
- //if (out->CanWrite() >= length)
- {
- QWORD timestamptemp = buffer->timestamp/10000LL;
- DWORD timestamp = static_cast<DWORD>(timestamptemp);
- if (buffer->flags & WM_SF_DISCONTINUITY)
- {
- // fill with silence!
- int msToFill = timestamp - out->GetWrittenTime(); // TODO: maybe use microsoft's time resolution?
- if (msToFill > 0 && msToFill < 2000)
- {
- int bytes = audioLayer->AudioMillisecondsToBytes(msToFill);
- __int8 *zeroes = (__int8 *)calloc(bytes, 1);
- if (zeroes)
- {
- output->AudioDataReceived(zeroes, bytes, timestamp);
- free(zeroes);
- }
- else
- {
- out->Flush(timestamp);
- }
- }
- else if (msToFill > 0)
- {
- out->Flush(timestamp);
- }
- }
- output->AudioDataReceived(data, length, timestamp);
- // TODO seen a few crash reports failing around here
- // might be the cause of the random wma fails
- // but crash dump doesn't help too much afaict
- try {
- buffer->buffer->Release();
- delete buffer;
- } catch (...) {}
-
- //buffers.pop_front();
- if (buffers.size())
- {
- buffers.erase(buffers.begin());
- }
- unsigned long x = endTime;
- if (x && timestamp > x)
- {
- eof = 1; // reached the end baby....
- endbreak = 1;
- }
- }
- if (buffers.size() < config_audio_cache_frames)
- SetEvent(bufferFreed);
- }
- continue;
- default:
- continue;
- }
- }
- }
- void AudioThread::AddAPC(MediaBuffer *buffer)
- {
- OrderedInsert(buffer);
- if (buffers.size() >= config_audio_cache_frames)
- ResetEvent(bufferFreed);
- }
|