aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_wmvdrm/MediaThread.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/MediaThread.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_wmvdrm/MediaThread.cpp')
-rw-r--r--Src/Plugins/Input/in_wmvdrm/MediaThread.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_wmvdrm/MediaThread.cpp b/Src/Plugins/Input/in_wmvdrm/MediaThread.cpp
new file mode 100644
index 00000000..1120c952
--- /dev/null
+++ b/Src/Plugins/Input/in_wmvdrm/MediaThread.cpp
@@ -0,0 +1,110 @@
+#include "main.h"
+#include "MediaThread.h"
+#include "config.h"
+
+MediaThread::MediaThread() : wait(INFINITE), thread(0)
+{
+ killEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ stopped = CreateEvent(NULL, TRUE, TRUE, NULL);
+ bufferFreed = CreateEvent(NULL, TRUE, TRUE, NULL);
+}
+
+MediaThread::~MediaThread()
+{
+ Kill();
+ if (thread)
+ CloseHandle(thread);
+}
+
+VOID CALLBACK MediaThread_StartAPC(ULONG_PTR param)
+{
+ reinterpret_cast<MediaThread *>(param)->StartAPC();
+}
+
+void MediaThread::StartAPC()
+{
+ wait=config_video_jitter;
+}
+
+void MediaThread::StopAPC()
+{
+ BufferList::iterator itr;
+ for (itr = buffers.begin();itr != buffers.end();itr++)
+ {
+ (*itr)->buffer->Release();
+ delete (*itr);
+ }
+
+ buffers.clear();
+ SetEvent(stopped);
+ SetEvent(bufferFreed);
+ wait=INFINITE;
+}
+
+static VOID CALLBACK MediaThread_StopAPC(ULONG_PTR param)
+{
+ reinterpret_cast<MediaThread *>(param)->StopAPC();
+}
+
+void MediaThread::Stop()
+{
+ ResetEvent(stopped);
+ QueueUserAPC(MediaThread_StopAPC, thread, reinterpret_cast<ULONG_PTR>(this));
+ WaitForSingleObject(stopped, INFINITE);
+}
+
+void MediaThread::WaitForStop()
+{
+ WaitForSingleObject(stopped, INFINITE);
+}
+
+void MediaThread::SignalStop()
+{
+ ResetEvent(stopped);
+ QueueUserAPC(MediaThread_StopAPC, thread, reinterpret_cast<ULONG_PTR>(this));
+}
+
+void MediaThread::Kill()
+{
+ SetEvent(killEvent);
+ WaitForSingleObject(stopped, INFINITE);
+}
+
+void MediaThread::OrderedInsert(MediaBuffer *buffer)
+{
+ BufferList::iterator itr;
+ for (itr = buffers.begin();itr != buffers.end(); itr++)
+ {
+ if ((*itr)->timestamp > buffer->timestamp)
+ {
+ buffers.insert(itr, buffer);
+ break;
+ }
+ }
+ if (itr == buffers.end())
+ buffers.push_back(buffer);
+
+}
+
+
+VOID CALLBACK MediaThread_AddAPC(ULONG_PTR param)
+{
+ MediaBufferAPC *apc = reinterpret_cast<MediaBufferAPC *>(param);
+ apc->thread->AddAPC(apc->buffer);
+ delete apc;
+}
+
+bool MediaThread::AddBuffer(INSSBuffer *buff, QWORD ts, unsigned long flags, bool drmProtected)
+{
+ if (WaitForSingleObject(bufferFreed, 0) == WAIT_TIMEOUT)
+ return false;
+
+ buff->AddRef();
+ MediaBuffer *buffer = new MediaBuffer(buff, ts, flags, drmProtected);
+ MediaBufferAPC *apc = new MediaBufferAPC;
+ apc->buffer = buffer;
+ apc->thread = this;
+ QueueUserAPC(MediaThread_AddAPC, thread, reinterpret_cast<ULONG_PTR>(apc));
+ Sleep(config_video_jitter); // sleep for a bit to keep the thread from going nuts
+ return true; // added
+}