aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_wmvdrm/SeekLayer.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_wmvdrm/SeekLayer.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-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.cpp376
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();
+}