aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_wmvdrm/BufferPool.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Input/in_wmvdrm/BufferPool.h')
-rw-r--r--Src/Plugins/Input/in_wmvdrm/BufferPool.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_wmvdrm/BufferPool.h b/Src/Plugins/Input/in_wmvdrm/BufferPool.h
new file mode 100644
index 00000000..b4c1ec2a
--- /dev/null
+++ b/Src/Plugins/Input/in_wmvdrm/BufferPool.h
@@ -0,0 +1,203 @@
+#ifndef NULLSOFT_BUFFERPOOLH
+#define NULLSOFT_BUFFERPOOLH
+
+#include <wmsdk.h>
+#include "../nu/AutoLock.h"
+#include <deque>
+#include <iostream>
+#include <cassert>
+using namespace Nullsoft::Utility;
+class Buffer;
+class Pool
+{
+public:
+ virtual void ReturnBuffer(Buffer *buffer) = 0;
+};
+
+class Buffer : public INSSBuffer
+{
+public:
+ Buffer(size_t _size, Pool *_pool)
+ : size(_size),
+ length(0),
+ pool(_pool),
+ refCount(1)
+ {
+ buffer = new unsigned char[size];
+ }
+
+ ~Buffer()
+ {
+ delete[] buffer;
+ }
+
+ ULONG STDMETHODCALLTYPE AddRef()
+ {
+ return ++refCount;
+ }
+
+ ULONG STDMETHODCALLTYPE Release()
+ {
+ assert(refCount > 0);
+
+ if (--refCount == 0)
+ {
+ length = 0;
+ pool->ReturnBuffer(this);
+ }
+ return refCount;
+ }
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
+ {
+ if (IID_INSSBuffer == iid)
+ {
+ *ppvObject = static_cast<INSSBuffer *>(this);
+ AddRef();
+ return S_OK;
+ }
+ else
+ {
+ *ppvObject = 0;
+ return E_NOINTERFACE;
+ }
+ }
+
+ HRESULT STDMETHODCALLTYPE GetBuffer(BYTE **ppdwBuffer)
+ {
+ *ppdwBuffer = (BYTE *)buffer;
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE GetBufferAndLength(BYTE **ppdwBuffer, DWORD *pdwLength)
+ {
+ *ppdwBuffer = (BYTE *)buffer;
+ *pdwLength = length;
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE GetLength(DWORD *pdwLength)
+ {
+ *pdwLength = length;
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE GetMaxLength(DWORD *pdwLength)
+ {
+ *pdwLength = size;
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE SetLength(DWORD dwLength)
+ {
+ length = dwLength;
+ return S_OK;
+ }
+
+ bool CanFit(size_t sizeCompare)
+ {
+ return (sizeCompare <= size);
+ }
+ size_t size, length;
+ Pool *pool;
+ int refCount;
+ unsigned char *buffer;
+};
+
+class BufferPool : public Pool
+{
+ typedef std::deque<Buffer *> PoolList;
+public:
+ long limit;
+ BufferPool() : allocSize(0),
+ poolSize(0),
+ limit(0)
+ {}
+
+ ~BufferPool()
+ {
+ FreeBuffers();
+ }
+ void FreeBuffers()
+ {
+
+ AutoLock lock (bufferGuard);
+ while (!pool.empty())
+ {
+ Buffer *buff = pool.front();
+ delete buff;
+ pool.pop_front();
+ poolSize = 0;
+ }
+ }
+ void ReturnBuffer(Buffer *buffer)
+ {
+ AutoLock lock (bufferGuard);
+ pool.push_back(buffer);
+ }
+ Buffer *SearchForBuffer(size_t size)
+ {
+ PoolList::iterator itr;
+ AutoLock lock (bufferGuard);
+ for (itr = pool.begin();itr != pool.end();itr++)
+ {
+ if ((*itr)->CanFit(size))
+ {
+ Buffer *buff = *itr;
+ pool.erase(itr);
+ buff->AddRef();
+ return buff;
+ }
+ }
+ return 0;
+ }
+
+ void PreAllocate(size_t count)
+ {
+ if (!allocSize)
+ return ;
+ for (size_t i = 0;i != count;i++)
+ {
+ AutoLock lock (bufferGuard);
+ pool.push_back( new Buffer(allocSize , this));
+ }
+ }
+ INSSBuffer *GetBuffer(size_t size)
+ {
+ Buffer *buff = SearchForBuffer(size);
+
+ /*
+ while (!buff && poolSize>=limit && limit)
+ {
+ Sleep(1);
+ buff = SearchForBuffer(size);
+ }*/
+
+ if (!buff)
+ {
+ poolSize++;
+ std::cerr << "poolsize = " << poolSize << std::endl;
+ buff = new Buffer(allocSize ? allocSize : size, this);
+ }
+ return buff;
+ }
+
+ void test()
+ {
+ std::cerr << "pool.size() == " << pool.size();
+ std::cerr << " and poolsize == " << poolSize << std::endl;
+ }
+
+ void SetAllocSize(long size)
+ {
+ allocSize = size;
+ }
+
+ PoolList pool;
+ LockGuard bufferGuard;
+ size_t allocSize;
+ size_t poolSize;
+
+};
+
+#endif