aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_wmvdrm/VideoThread.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/VideoThread.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_wmvdrm/VideoThread.cpp')
-rw-r--r--Src/Plugins/Input/in_wmvdrm/VideoThread.cpp166
1 files changed, 166 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_wmvdrm/VideoThread.cpp b/Src/Plugins/Input/in_wmvdrm/VideoThread.cpp
new file mode 100644
index 00000000..fd6f1f09
--- /dev/null
+++ b/Src/Plugins/Input/in_wmvdrm/VideoThread.cpp
@@ -0,0 +1,166 @@
+#include "Main.h"
+#include "VideoThread.h"
+#include "VideoLayer.h"
+#include "config.h"
+#include <windows.h>
+
+DWORD WINAPI VidThread_stub(void *ptr)
+{
+ ((VideoThread *)ptr)->VidThread();
+ return 0;
+}
+
+VideoThread::VideoThread() : converter(0), clock(0)
+{
+ drm = false;
+
+ DWORD id;
+ thread = CreateThread(NULL, 256*1024, VidThread_stub, (void *)this, NULL, &id);
+ SetThreadPriority(thread, AGAVE_API_CONFIG->GetInt(playbackConfigGroupGUID, L"priority", THREAD_PRIORITY_HIGHEST));
+}
+
+void VideoThread::Start(VideoDataConverter *_converter, WMHandler *_clock)
+{
+ clock = _clock;
+ if (converter != _converter)
+ {
+ if (converter)
+ delete converter;
+ converter = _converter;
+ }
+ ResetEvent(stopped);
+ QueueUserAPC(MediaThread_StartAPC, thread, reinterpret_cast<ULONG_PTR>(this));
+}
+
+void VideoThread::VidThread()
+{
+ while (true)
+ {
+ switch (WaitForSingleObjectEx(killEvent, wait, TRUE))
+ {
+ case WAIT_OBJECT_0:
+ //StopAPC();
+ return;
+
+ case WAIT_TIMEOUT:
+ {
+ if (buffers.empty())
+ {
+ SetEvent(bufferFreed);
+ continue;
+ }
+
+ MediaBuffer *buffer = buffers.front();
+
+ __int64 diff;
+ clock->TimeToSync(buffer->timestamp, diff);
+ if (diff < VIDEO_ACCEPTABLE_JITTER)
+ {
+ void *data;
+ DWORD size;
+
+ buffer->buffer->GetBufferAndLength((BYTE **)&data, &size);
+ if (buffer->drmProtected)
+ winamp.EncryptedDrawFrame(converter->Convert(data));
+ else
+ winamp.DrawFrame(converter->Convert(data));
+
+ try {
+ buffer->buffer->Release();
+ delete buffer;
+ } catch (...) {}
+
+ //buffers.pop_front();
+ if (buffers.size())
+ {
+ buffers.erase(buffers.begin());
+ }
+ }
+ if (buffers.size() < config_video_cache_frames)
+ SetEvent(bufferFreed);
+ }
+ continue;
+
+ default:
+ continue;
+ }
+ }
+}
+
+void VideoThread::AddAPC(MediaBuffer *buffer)
+{
+ if (buffers.empty())
+ {
+ __int64 diff;
+ clock->TimeToSync(buffer->timestamp, diff);
+ if (diff < VIDEO_ACCEPTABLE_JITTER)
+ {
+ void *data;
+ DWORD size;
+ buffer->buffer->GetBufferAndLength((BYTE **)&data, &size);
+ if (buffer->drmProtected)
+ winamp.EncryptedDrawFrame(converter->Convert(data));
+ else
+ winamp.DrawFrame(converter->Convert(data));
+
+ buffer->buffer->Release();
+ if (buffers.size() >= config_video_cache_frames)
+ ResetEvent(bufferFreed);
+ return;
+ }
+ }
+
+ OrderedInsert(buffer);
+
+ if (buffers.size() >= config_video_cache_frames)
+ ResetEvent(bufferFreed);
+}
+
+struct VideoOpenParameters
+{
+ int width;
+ int height;
+ int color_format;
+ double aspect;
+ int flip;
+ bool drm;
+};
+
+VOID CALLBACK VideoThread::VideoThread_VideoOpenAPC(ULONG_PTR params)
+{
+ VideoOpenParameters *p = (VideoOpenParameters *)params;
+ if (p->drm)
+ {
+ winamp.OpenEncryptedVideo(p->width, p->height, !!p->flip, p->aspect, p->color_format);
+ }
+ else
+ {
+ winamp.OpenVideo(p->width, p->height, !!p->flip, p->aspect, p->color_format);
+ }
+}
+
+void VideoThread::OpenVideo(bool drm, int width, int height, bool flip, double aspect, int fourcc)
+{
+ VideoOpenParameters *p = new VideoOpenParameters;
+ p->width = width;
+ p->height = height;
+ p->color_format = fourcc;
+ p->aspect = aspect;
+ p->flip = flip;
+ p->drm = drm;
+ this->drm = drm;
+ QueueUserAPC(VideoThread_VideoOpenAPC, thread, reinterpret_cast<ULONG_PTR>(p));
+}
+
+VOID CALLBACK VideoThread::VideoThread_VideoCloseAPC(ULONG_PTR params)
+{
+ if (params)
+ winamp.CloseEncryptedVideo();
+ else
+ winamp.CloseVideo();
+}
+
+void VideoThread::CloseVideo(bool drm)
+{
+ QueueUserAPC(VideoThread_VideoCloseAPC, thread, static_cast<ULONG_PTR>(drm));
+} \ No newline at end of file