videofilter:

- Add one layer of abstraction to the thread synchronization code.
- By doing this abstraction, this code has been made compatible with Windows.
This commit is contained in:
rogerman 2013-09-04 05:11:49 +00:00
parent 5d26046bc6
commit d9d41b5a96
2 changed files with 171 additions and 68 deletions

View File

@ -25,7 +25,7 @@ int scanline_filter_b = 2;
int scanline_filter_c = 2; int scanline_filter_c = 2;
int scanline_filter_d = 4; int scanline_filter_d = 4;
// // Parameters passed to the RunVideoFilterTask() thread task function
typedef struct typedef struct
{ {
void *index; void *index;
@ -68,10 +68,10 @@ VideoFilter::VideoFilter(size_t srcWidth,
_vfAttributes = VideoFilterAttributesList[VideoFilterTypeID_None]; _vfAttributes = VideoFilterAttributesList[VideoFilterTypeID_None];
} }
pthread_mutex_init(&_mutexSrc, NULL); ThreadLockInit(&_lockSrc);
pthread_mutex_init(&_mutexDst, NULL); ThreadLockInit(&_lockDst);
pthread_mutex_init(&_mutexAttributes, NULL); ThreadLockInit(&_lockAttributes);
pthread_cond_init(&_condRunning, NULL); ThreadCondInit(&_condRunning);
// Create all threads // Create all threads
_vfThread.resize(threadCount); _vfThread.resize(threadCount);
@ -106,29 +106,29 @@ VideoFilter::~VideoFilter()
_vfThread.clear(); _vfThread.clear();
// Destroy everything else // Destroy everything else
pthread_mutex_lock(&_mutexSrc); ThreadLockLock(&_lockSrc);
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&_lockDst);
while (this->_isFilterRunning) while (_isFilterRunning)
{ {
pthread_cond_wait(&this->_condRunning, &this->_mutexDst); ThreadCondWait(&_condRunning, &_lockDst);
} }
free(_vfDstSurface.Surface); free(_vfDstSurface.Surface);
_vfDstSurface.Surface = NULL; _vfDstSurface.Surface = NULL;
pthread_mutex_unlock(&_mutexDst); ThreadLockUnlock(&_lockDst);
free(_vfSrcSurfacePixBuffer); free(_vfSrcSurfacePixBuffer);
_vfSrcSurfacePixBuffer = NULL; _vfSrcSurfacePixBuffer = NULL;
_vfSrcSurface.Surface = NULL; _vfSrcSurface.Surface = NULL;
pthread_mutex_unlock(&_mutexSrc); ThreadLockUnlock(&_lockSrc);
pthread_mutex_destroy(&_mutexSrc); ThreadLockDestroy(&_lockSrc);
pthread_mutex_destroy(&_mutexDst); ThreadLockDestroy(&_lockDst);
pthread_mutex_destroy(&_mutexAttributes); ThreadLockDestroy(&_lockAttributes);
pthread_cond_destroy(&_condRunning); ThreadCondDestroy(&_condRunning);
} }
/******************************************************************************************** /********************************************************************************************
@ -150,7 +150,7 @@ bool VideoFilter::SetSourceSize(const size_t width, const size_t height)
{ {
bool result = false; bool result = false;
pthread_mutex_lock(&this->_mutexSrc); ThreadLockLock(&this->_lockSrc);
// Overallocate the source buffer by 8 rows of pixels to account for out-of-bounds // Overallocate the source buffer by 8 rows of pixels to account for out-of-bounds
// memory reads done by some filters. // memory reads done by some filters.
@ -186,7 +186,7 @@ bool VideoFilter::SetSourceSize(const size_t width, const size_t height)
} }
} }
pthread_mutex_unlock(&this->_mutexSrc); ThreadLockUnlock(&this->_lockSrc);
const VideoFilterAttributes vfAttr = this->GetAttributes(); const VideoFilterAttributes vfAttr = this->GetAttributes();
result = this->ChangeFilterByAttributes(&vfAttr); result = this->ChangeFilterByAttributes(&vfAttr);
@ -250,16 +250,16 @@ bool VideoFilter::ChangeFilterByAttributes(const VideoFilterAttributes *vfAttr)
this->SetAttributes(*vfAttr); this->SetAttributes(*vfAttr);
VideoFilterAttributes &workingAttributes = this->_vfAttributes; VideoFilterAttributes &workingAttributes = this->_vfAttributes;
pthread_mutex_lock(&this->_mutexSrc); ThreadLockLock(&this->_lockSrc);
const size_t srcWidth = this->_vfSrcSurface.Width; const size_t srcWidth = this->_vfSrcSurface.Width;
const size_t srcHeight = this->_vfSrcSurface.Height; const size_t srcHeight = this->_vfSrcSurface.Height;
pthread_mutex_unlock(&this->_mutexSrc); ThreadLockUnlock(&this->_lockSrc);
const size_t dstWidth = srcWidth * workingAttributes.scaleMultiply / workingAttributes.scaleDivide; const size_t dstWidth = srcWidth * workingAttributes.scaleMultiply / workingAttributes.scaleDivide;
const size_t dstHeight = srcHeight * workingAttributes.scaleMultiply / workingAttributes.scaleDivide; const size_t dstHeight = srcHeight * workingAttributes.scaleMultiply / workingAttributes.scaleDivide;
const VideoFilterFunc filterFunction = workingAttributes.filterFunction; const VideoFilterFunc filterFunction = workingAttributes.filterFunction;
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
uint32_t *newSurfaceBuffer = (uint32_t *)calloc(dstWidth * dstHeight, sizeof(uint32_t)); uint32_t *newSurfaceBuffer = (uint32_t *)calloc(dstWidth * dstHeight, sizeof(uint32_t));
if (newSurfaceBuffer == NULL) if (newSurfaceBuffer == NULL)
@ -293,7 +293,7 @@ bool VideoFilter::ChangeFilterByAttributes(const VideoFilterAttributes *vfAttr)
this->_vfThread[i].param.filterFunction = this->_vfFunc; this->_vfThread[i].param.filterFunction = this->_vfFunc;
} }
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
result = true; result = true;
@ -314,8 +314,8 @@ bool VideoFilter::ChangeFilterByAttributes(const VideoFilterAttributes *vfAttr)
********************************************************************************************/ ********************************************************************************************/
uint32_t* VideoFilter::RunFilter() uint32_t* VideoFilter::RunFilter()
{ {
pthread_mutex_lock(&this->_mutexSrc); ThreadLockLock(&this->_lockSrc);
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
this->_isFilterRunning = true; this->_isFilterRunning = true;
@ -345,10 +345,10 @@ uint32_t* VideoFilter::RunFilter()
} }
this->_isFilterRunning = false; this->_isFilterRunning = false;
pthread_cond_signal(&this->_condRunning); ThreadCondSignal(&this->_condRunning);
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
pthread_mutex_unlock(&this->_mutexSrc); ThreadLockUnlock(&this->_lockSrc);
return (uint32_t *)this->_vfDstSurface.Surface; return (uint32_t *)this->_vfDstSurface.Surface;
} }
@ -381,7 +381,7 @@ uint32_t* VideoFilter::RunFilter()
Returns: Returns:
Nothing. Nothing.
********************************************************************************************/ ********************************************************************************************/
void VideoFilter::RunFilterCustomByID(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ dstBuffer, void VideoFilter::RunFilterCustomByID(const uint32_t *__restrict srcBuffer, uint32_t *__restrict dstBuffer,
const size_t srcWidth, const size_t srcHeight, const size_t srcWidth, const size_t srcHeight,
const VideoFilterTypeID typeID) const VideoFilterTypeID typeID)
{ {
@ -420,7 +420,7 @@ void VideoFilter::RunFilterCustomByID(const uint32_t *__restrict__ srcBuffer, ui
Returns: Returns:
Nothing. Nothing.
********************************************************************************************/ ********************************************************************************************/
void VideoFilter::RunFilterCustomByAttributes(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ dstBuffer, void VideoFilter::RunFilterCustomByAttributes(const uint32_t *__restrict srcBuffer, uint32_t *__restrict dstBuffer,
const size_t srcWidth, const size_t srcHeight, const size_t srcWidth, const size_t srcHeight,
const VideoFilterAttributes *vfAttr) const VideoFilterAttributes *vfAttr)
{ {
@ -492,88 +492,88 @@ const char* VideoFilter::GetTypeStringByID(const VideoFilterTypeID typeID)
********************************************************************************************/ ********************************************************************************************/
VideoFilterAttributes VideoFilter::GetAttributes() VideoFilterAttributes VideoFilter::GetAttributes()
{ {
pthread_mutex_lock(&this->_mutexAttributes); ThreadLockLock(&this->_lockAttributes);
VideoFilterAttributes vfAttr = this->_vfAttributes; VideoFilterAttributes vfAttr = this->_vfAttributes;
pthread_mutex_unlock(&this->_mutexAttributes); ThreadLockUnlock(&this->_lockAttributes);
return vfAttr; return vfAttr;
} }
void VideoFilter::SetAttributes(const VideoFilterAttributes vfAttr) void VideoFilter::SetAttributes(const VideoFilterAttributes vfAttr)
{ {
pthread_mutex_lock(&this->_mutexAttributes); ThreadLockLock(&this->_lockAttributes);
this->_vfAttributes = vfAttr; this->_vfAttributes = vfAttr;
pthread_mutex_unlock(&this->_mutexAttributes); ThreadLockUnlock(&this->_lockAttributes);
} }
VideoFilterTypeID VideoFilter::GetTypeID() VideoFilterTypeID VideoFilter::GetTypeID()
{ {
pthread_mutex_lock(&this->_mutexAttributes); ThreadLockLock(&this->_lockAttributes);
VideoFilterTypeID typeID = this->_vfAttributes.typeID; VideoFilterTypeID typeID = this->_vfAttributes.typeID;
pthread_mutex_unlock(&this->_mutexAttributes); ThreadLockUnlock(&this->_lockAttributes);
return typeID; return typeID;
} }
const char* VideoFilter::GetTypeString() const char* VideoFilter::GetTypeString()
{ {
pthread_mutex_lock(&this->_mutexAttributes); ThreadLockLock(&this->_lockAttributes);
const char *typeString = this->_vfAttributes.typeString; const char *typeString = this->_vfAttributes.typeString;
pthread_mutex_unlock(&this->_mutexAttributes); ThreadLockUnlock(&this->_lockAttributes);
return typeString; return typeString;
} }
uint32_t* VideoFilter::GetSrcBufferPtr() uint32_t* VideoFilter::GetSrcBufferPtr()
{ {
pthread_mutex_lock(&this->_mutexSrc); ThreadLockLock(&this->_lockSrc);
uint32_t *ptr = (uint32_t *)this->_vfSrcSurface.Surface; uint32_t *ptr = (uint32_t *)this->_vfSrcSurface.Surface;
pthread_mutex_unlock(&this->_mutexSrc); ThreadLockUnlock(&this->_lockSrc);
return ptr; return ptr;
} }
uint32_t* VideoFilter::GetDstBufferPtr() uint32_t* VideoFilter::GetDstBufferPtr()
{ {
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
uint32_t *ptr = (uint32_t *)this->_vfDstSurface.Surface; uint32_t *ptr = (uint32_t *)this->_vfDstSurface.Surface;
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
return ptr; return ptr;
} }
size_t VideoFilter::GetSrcWidth() size_t VideoFilter::GetSrcWidth()
{ {
pthread_mutex_lock(&this->_mutexSrc); ThreadLockLock(&this->_lockSrc);
size_t width = this->_vfSrcSurface.Width; size_t width = this->_vfSrcSurface.Width;
pthread_mutex_unlock(&this->_mutexSrc); ThreadLockUnlock(&this->_lockSrc);
return width; return width;
} }
size_t VideoFilter::GetSrcHeight() size_t VideoFilter::GetSrcHeight()
{ {
pthread_mutex_lock(&this->_mutexSrc); ThreadLockLock(&this->_lockSrc);
size_t height = this->_vfSrcSurface.Height; size_t height = this->_vfSrcSurface.Height;
pthread_mutex_unlock(&this->_mutexSrc); ThreadLockUnlock(&this->_lockSrc);
return height; return height;
} }
size_t VideoFilter::GetDstWidth() size_t VideoFilter::GetDstWidth()
{ {
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
size_t width = this->_vfDstSurface.Width; size_t width = this->_vfDstSurface.Width;
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
return width; return width;
} }
size_t VideoFilter::GetDstHeight() size_t VideoFilter::GetDstHeight()
{ {
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
size_t height = this->_vfDstSurface.Height; size_t height = this->_vfDstSurface.Height;
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
return height; return height;
} }
@ -587,7 +587,7 @@ int VideoFilter::GetFilterParameteri(VideoFilterParamID paramID)
{ {
int value = 0; int value = 0;
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
switch (_VideoFilterParamAttributesList[paramID].type) switch (_VideoFilterParamAttributesList[paramID].type)
{ {
@ -607,7 +607,7 @@ int VideoFilter::GetFilterParameteri(VideoFilterParamID paramID)
break; break;
} }
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
return value; return value;
} }
@ -616,7 +616,7 @@ unsigned int VideoFilter::GetFilterParameterui(VideoFilterParamID paramID)
{ {
unsigned int value = 0; unsigned int value = 0;
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
switch (_VideoFilterParamAttributesList[paramID].type) switch (_VideoFilterParamAttributesList[paramID].type)
{ {
@ -636,7 +636,7 @@ unsigned int VideoFilter::GetFilterParameterui(VideoFilterParamID paramID)
break; break;
} }
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
return value; return value;
} }
@ -645,7 +645,7 @@ float VideoFilter::GetFilterParameterf(VideoFilterParamID paramID)
{ {
float value = 0.0f; float value = 0.0f;
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
switch (_VideoFilterParamAttributesList[paramID].type) switch (_VideoFilterParamAttributesList[paramID].type)
{ {
@ -665,7 +665,7 @@ float VideoFilter::GetFilterParameterf(VideoFilterParamID paramID)
break; break;
} }
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
return value; return value;
} }
@ -677,7 +677,7 @@ void VideoFilter::SetFilterParameteri(VideoFilterParamID paramID, int value)
return; return;
} }
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
switch (_VideoFilterParamAttributesList[paramID].type) switch (_VideoFilterParamAttributesList[paramID].type)
{ {
@ -697,7 +697,7 @@ void VideoFilter::SetFilterParameteri(VideoFilterParamID paramID, int value)
break; break;
} }
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
} }
void VideoFilter::SetFilterParameterui(VideoFilterParamID paramID, unsigned int value) void VideoFilter::SetFilterParameterui(VideoFilterParamID paramID, unsigned int value)
@ -707,7 +707,7 @@ void VideoFilter::SetFilterParameterui(VideoFilterParamID paramID, unsigned int
return; return;
} }
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
switch (_VideoFilterParamAttributesList[paramID].type) switch (_VideoFilterParamAttributesList[paramID].type)
{ {
@ -727,7 +727,7 @@ void VideoFilter::SetFilterParameterui(VideoFilterParamID paramID, unsigned int
break; break;
} }
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
} }
void VideoFilter::SetFilterParameterf(VideoFilterParamID paramID, float value) void VideoFilter::SetFilterParameterf(VideoFilterParamID paramID, float value)
@ -737,7 +737,7 @@ void VideoFilter::SetFilterParameterf(VideoFilterParamID paramID, float value)
return; return;
} }
pthread_mutex_lock(&this->_mutexDst); ThreadLockLock(&this->_lockDst);
switch (_VideoFilterParamAttributesList[paramID].type) switch (_VideoFilterParamAttributesList[paramID].type)
{ {
@ -757,7 +757,7 @@ void VideoFilter::SetFilterParameterf(VideoFilterParamID paramID, float value)
break; break;
} }
pthread_mutex_unlock(&this->_mutexDst); ThreadLockUnlock(&this->_lockDst);
} }
// Task function for multithreaded filtering // Task function for multithreaded filtering
@ -769,3 +769,86 @@ static void* RunVideoFilterTask(void *arg)
return NULL; return NULL;
} }
#ifdef _MSC_VER
void ThreadLockInit(ThreadLock *theLock)
{
InitializeCriticalSection(theLock);
}
void ThreadLockDestroy(ThreadLock *theLock)
{
DeleteCriticalSection(theLock);
}
void ThreadLockLock(ThreadLock *theLock)
{
EnterCriticalSection(theLock);
}
void ThreadLockUnlock(ThreadLock *theLock)
{
LeaveCriticalSection(theLock);
}
void ThreadCondInit(ThreadCond *theCondition)
{
*theCondition = CreateEvent(NULL, FALSE, FALSE, NULL);
}
void ThreadCondDestroy(ThreadCond *theCondition)
{
CloseHandle(*theCondition);
}
void ThreadCondWait(ThreadCond *theCondition, ThreadLock *conditionLock)
{
WaitForSingleObject(*theCondition, INFINITE);
}
void ThreadCondSignal(ThreadCond *theCondition)
{
SetEvent(*theCondition);
}
#else
void ThreadLockInit(ThreadLock *theLock)
{
pthread_mutex_init(theLock, NULL);
}
void ThreadLockDestroy(ThreadLock *theLock)
{
pthread_mutex_destroy(theLock);
}
void ThreadLockLock(ThreadLock *theLock)
{
pthread_mutex_lock(theLock);
}
void ThreadLockUnlock(ThreadLock *theLock)
{
pthread_mutex_unlock(theLock);
}
void ThreadCondInit(ThreadCond *theCondition)
{
pthread_cond_init(theCondition, NULL);
}
void ThreadCondDestroy(ThreadCond *theCondition)
{
pthread_cond_destroy(theCondition);
}
void ThreadCondWait(ThreadCond *theCondition, ThreadLock *conditionLock)
{
pthread_cond_wait(theCondition, conditionLock);
}
void ThreadCondSignal(ThreadCond *theCondition)
{
pthread_cond_signal(theCondition);
}
#endif

View File

@ -19,11 +19,21 @@
#ifndef _VIDEOFILTER_ #ifndef _VIDEOFILTER_
#define _VIDEOFILTER_ #define _VIDEOFILTER_
#include <stdint.h> #if defined(_MSC_VER)
typedef unsigned __int32 uint32_t;
#include <windows.h>
typedef CRITICAL_SECTION ThreadLock;
typedef HANDLE ThreadCond;
#else
#include <stdint.h>
#include <pthread.h>
typedef pthread_mutex_t ThreadLock;
typedef pthread_cond_t ThreadCond;
#endif
#include <stdlib.h> #include <stdlib.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <pthread.h>
#include "filter.h" #include "filter.h"
#include "../utils/task.h" #include "../utils/task.h"
@ -157,10 +167,10 @@ private:
std::vector<VideoFilterThread> _vfThread; std::vector<VideoFilterThread> _vfThread;
bool _isFilterRunning; bool _isFilterRunning;
pthread_mutex_t _mutexSrc; ThreadLock _lockSrc;
pthread_mutex_t _mutexDst; ThreadLock _lockDst;
pthread_mutex_t _mutexAttributes; ThreadLock _lockAttributes;
pthread_cond_t _condRunning; ThreadCond _condRunning;
void SetAttributes(const VideoFilterAttributes vfAttr); void SetAttributes(const VideoFilterAttributes vfAttr);
@ -173,8 +183,8 @@ public:
bool ChangeFilterByAttributes(const VideoFilterAttributes *vfAttr); bool ChangeFilterByAttributes(const VideoFilterAttributes *vfAttr);
uint32_t* RunFilter(); uint32_t* RunFilter();
static void RunFilterCustomByID(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ dstBuffer, const size_t srcWidth, const size_t srcHeight, const VideoFilterTypeID typeID); static void RunFilterCustomByID(const uint32_t *__restrict srcBuffer, uint32_t *__restrict dstBuffer, const size_t srcWidth, const size_t srcHeight, const VideoFilterTypeID typeID);
static void RunFilterCustomByAttributes(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ dstBuffer, const size_t srcWidth, const size_t srcHeight, const VideoFilterAttributes *vfAttr); static void RunFilterCustomByAttributes(const uint32_t *__restrict srcBuffer, uint32_t *__restrict dstBuffer, const size_t srcWidth, const size_t srcHeight, const VideoFilterAttributes *vfAttr);
static const char* GetTypeStringByID(const VideoFilterTypeID typeID); static const char* GetTypeStringByID(const VideoFilterTypeID typeID);
VideoFilterAttributes GetAttributes(); VideoFilterAttributes GetAttributes();
@ -197,4 +207,14 @@ public:
static void* RunVideoFilterTask(void *arg); static void* RunVideoFilterTask(void *arg);
void ThreadLockInit(ThreadLock *theLock);
void ThreadLockDestroy(ThreadLock *theLock);
void ThreadLockLock(ThreadLock *theLock);
void ThreadLockUnlock(ThreadLock *theLock);
void ThreadCondInit(ThreadCond *theCondition);
void ThreadCondDestroy(ThreadCond *theCondition);
void ThreadCondWait(ThreadCond *theCondition, ThreadLock *conditionLock);
void ThreadCondSignal(ThreadCond *theCondition);
#endif #endif