diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_wmvdrm/SeekLayer.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_wmvdrm/SeekLayer.cpp')
-rw-r--r-- | Src/Plugins/Input/in_wmvdrm/SeekLayer.cpp | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_wmvdrm/SeekLayer.cpp b/Src/Plugins/Input/in_wmvdrm/SeekLayer.cpp new file mode 100644 index 00000000..2b7eabdd --- /dev/null +++ b/Src/Plugins/Input/in_wmvdrm/SeekLayer.cpp @@ -0,0 +1,376 @@ +#include "SeekLayer.h" +#include "Main.h" +#include "output/AudioOut.h" +#include "util.h" +#include <assert.h> +using namespace Nullsoft::Utility; + +struct OpenThreadData +{ + IWMReaderCallback *callback; + wchar_t *url; + IWMReader *reader; + + void open() + { + reader->Open(url, callback, 0); + } + + OpenThreadData(IWMReader *_reader, const wchar_t *_url, IWMReaderCallback *_callback) + { + reader = _reader; + reader->AddRef(); + callback = _callback; + callback->AddRef(); + + url = _wcsdup(_url); + } + + ~OpenThreadData() + { + free(url); + reader->Release(); + callback->Release(); + } +}; +DWORD WINAPI OpenThread(void *param) +{ + OpenThreadData *data = (OpenThreadData *)param; + data->open(); + delete data; + return 0; +} + +#define NEW_SEEK +SeekLayer::SeekLayer(IWMReader *_reader, ClockLayer *_clock) + : seekPos(0), reader(_reader), playState(PLAYSTATE_CLOSED), metadata(NULL), clock(_clock), + needPause(false), paused(false), needStop(false), + seekGuard(GUARDNAME("Seek Guard")), + oldState_buffer(PLAYSTATE_NONE) +{ + reader->AddRef(); + reader->QueryInterface(&reader2); +} + +void SeekLayer::DoStop() +{ + if (paused) + reader->Resume(); + + reader->Stop(); + First().Stopping(); + First().Kill(); + if (paused) + { + paused = false; + out->Pause(0); + } + needStop = false; +} + +void SeekLayer::SeekTo(long position) +{ + AutoLock lock (seekGuard LOCKNAME("SeekTo")); + if (paused) + { + reader->Resume(); + } + First().Stopping(); + First().Kill(); + seekPos = position; + clock->SetLastOutputTime(position); + clock->SetStartTimeMilliseconds(position); + out->Flush(position); + QWORD qSeekPos = position; + qSeekPos *= 10000; + reader->Start(qSeekPos, 0, 1.0f, NULL); + if (paused) + { + reader->Pause(); + } +} + +void SeekLayer::Pause() +{ + AutoLock lock (seekGuard LOCKNAME("Pause")); + if (playState == PLAYSTATE_STARTED) + { + paused = true; + reader->Pause(); + out->Pause(1); + } + else + { + needPause = true; + } +} + +int SeekLayer::Open(const wchar_t *filename, IWMReaderCallback *callback) +{ + AutoLock lock (seekGuard LOCKNAME("Open")); + assert(playState == PLAYSTATE_CLOSED); + needStop = false; + playState = PLAYSTATE_OPENING; + DWORD dummyId; + CreateThread(NULL, 0, OpenThread, new OpenThreadData(reader, filename, callback), 0, &dummyId); + return 0; +} + +void SeekLayer::Stop() +{ + AutoLock lock (seekGuard LOCKNAME("Stop")); + needStop = true; + + switch (playState) + { + case PLAYSTATE_BUFFERING: +// needStop=false; + reader2->StopBuffering(); +// reader->Stop(); + break; + + case PLAYSTATE_OPENING: + // wait for it to open (or connect) and then we'll kill it there + break; + + case PLAYSTATE_NONE: + case PLAYSTATE_STOPPED: + if (FAILED(reader->Close())) // reader->Close() is sometimes synchronous, and sometimes not valid here + { + playState = PLAYSTATE_CLOSED; + return ; + } + break; + + case PLAYSTATE_OPENED: + case PLAYSTATE_STARTED: + reader->Stop(); + First().Stopping(); + First().Kill(); + break; + + case PLAYSTATE_CLOSED: + needStop = false; + break; + /* + case PLAYSTATE_BUFFERING: + reader2->StopBuffering(); + reader->Stop(); + break;*/ + + case PLAYSTATE_SEEK: + break; + } + + while (playState != PLAYSTATE_CLOSED) + { + lock.ManualUnlock(); + Sleep(55); + lock.ManualLock(MANUALLOCKNAME("[Manual Lock]Stop")); + } + needStop = false; +} + +void SeekLayer::Unpause() +{ + AutoLock lock (seekGuard LOCKNAME("Unpause")); + if (playState == PLAYSTATE_STARTED) + { + paused = false; + out->Pause(0); + reader->Resume(); + clock->Clock(); + } + else + { + needPause = false; + } +} + +void SeekLayer::Opened() +{ + { + AutoLock lock (seekGuard LOCKNAME("SeekLayer::Opened")); + if (needStop) + { + playState = PLAYSTATE_OPENED; + lock.ManualUnlock(); + reader->Close(); + lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Opened")); + return ; + } + + playState = PLAYSTATE_OPENED; + } + WMHandler::Opened(); +} + +void SeekLayer::Stopped() +{ + { + AutoLock lock (seekGuard LOCKNAME("Stopped")); + if (needStop) + { + playState = PLAYSTATE_STOPPED; + lock.ManualUnlock(); + reader->Close(); + lock.ManualLock(MANUALLOCKNAME("Stopped")); + } + else + { + playState = PLAYSTATE_STOPPED; + } + + WMHandler::Stopped(); + } +} + +void SeekLayer::Started() +{ + { + AutoLock lock (seekGuard LOCKNAME("Started")); + playState = PLAYSTATE_STARTED; + + if (needStop) + { + reader->Stop(); + First().Stopping(); + First().Kill(); + return ; + } + else if (needPause) + { + Pause(); + needPause = false; + } + } + WMHandler::Started(); +} + +void SeekLayer::Closed() +{ + playState = PLAYSTATE_CLOSED; + paused = false; + needPause = false; + needStop = false; + seekPos = 0; + + WMHandler::Closed(); +} + +void SeekLayer::BufferingStarted() +{ + { + AutoLock lock (seekGuard LOCKNAME("BufferingStarted")); + if (playState == PLAYSTATE_OPENED) + oldState_buffer = PLAYSTATE_NONE; + else + oldState_buffer = playState; + if (playState != PLAYSTATE_STARTED) + playState = PLAYSTATE_BUFFERING; + if (needStop) + reader2->StopBuffering(); + + } + WMHandler::BufferingStarted(); +} + + +void SeekLayer::BufferingStopped() +{ + { + AutoLock lock (seekGuard LOCKNAME("BufferingStopped")); + if (needStop) + reader->Stop(); + playState = oldState_buffer; + } + WMHandler::BufferingStopped(); +} + + +void SeekLayer::EndOfFile() +{ + { + AutoLock lock (seekGuard LOCKNAME("EndOfFile")); + if (needStop) + return ; + } + WMHandler::EndOfFile(); + +} + +void SeekLayer::Connecting() +{ + { + AutoLock lock (seekGuard LOCKNAME("SeekLayer::Connecting")); + if (needStop) + { + playState = PLAYSTATE_NONE; + lock.ManualUnlock(); + reader->Close(); + lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Connecting")); + return ; + } + playState = PLAYSTATE_NONE; + } + WMHandler::Connecting(); +} + + +void SeekLayer::Locating() +{ + { + AutoLock lock (seekGuard LOCKNAME("SeekLayer::Locating")); + if (needStop) + { + playState = PLAYSTATE_NONE; + lock.ManualUnlock(); + reader->Close(); + lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::Locating")); + return ; + } + playState = PLAYSTATE_NONE; + } + WMHandler::Locating(); +} + + +void SeekLayer::OpenCalled() +{ + { + AutoLock lock (seekGuard LOCKNAME("SeekLayer::OpenCalled")); + if (needStop) + { + playState = PLAYSTATE_NONE; + lock.ManualUnlock(); + reader->Close(); + lock.ManualLock(MANUALLOCKNAME("[Manual Lock]SeekLayer::OpenCalled")); + return ; + } + + playState = PLAYSTATE_NONE; + } + WMHandler::OpenCalled(); +} + +void SeekLayer::OpenFailed() +{ + { + AutoLock lock (seekGuard LOCKNAME("SeekLayer::OpenFailed")); + if (playState == PLAYSTATE_OPENING) + playState = PLAYSTATE_NONE; + } + WMHandler::OpenFailed(); +} + +void SeekLayer::Error() +{ + { + AutoLock lock (seekGuard LOCKNAME("SeekLayer::Error")); + /*if (playState == PLAYSTATE_OPENING) + playState = PLAYSTATE_CLOSED; + else */if (playState != PLAYSTATE_CLOSED) + playState = PLAYSTATE_NONE; + } + WMHandler::Error(); +} |