Cocoa Port:
- Video filters are now multithreaded! This significantly improves video filter performance on multiprocessor machines.
This commit is contained in:
parent
2b82193674
commit
9f1a392803
|
@ -465,7 +465,7 @@ GPU3DInterface *core3DList[] = {
|
|||
spinlockRender3DLineHack = OS_SPINLOCK_INIT;
|
||||
|
||||
displayType = DS_DISPLAY_TYPE_COMBO;
|
||||
vf = [[CocoaVideoFilter alloc] initWithSize:NSMakeSize(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT * 2)];
|
||||
vf = [[CocoaVideoFilter alloc] initWithSize:NSMakeSize(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT * 2) typeID:VideoFilterTypeID_None numberThreads:2];
|
||||
|
||||
gpuStateFlags = GPUSTATE_MAIN_GPU_MASK |
|
||||
GPUSTATE_MAIN_BG0_MASK |
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
- (id) initWithSize:(NSSize)theSize;
|
||||
- (id) initWithSize:(NSSize)theSize typeID:(VideoFilterTypeID)typeID;
|
||||
- (id) initWithSize:(NSSize)theSize typeID:(VideoFilterTypeID)typeID numberThreads:(NSUInteger)numThreads;
|
||||
- (BOOL) setSourceSize:(NSSize)theSize;
|
||||
- (BOOL) changeFilter:(VideoFilterTypeID)typeID;
|
||||
- (UInt32 *) runFilter;
|
||||
|
|
|
@ -24,15 +24,20 @@
|
|||
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithSize:NSMakeSize(1, 1) typeID:VideoFilterTypeID_None];
|
||||
return [self initWithSize:NSMakeSize(1, 1) typeID:VideoFilterTypeID_None numberThreads:1];
|
||||
}
|
||||
|
||||
- (id) initWithSize:(NSSize)theSize
|
||||
{
|
||||
return [self initWithSize:theSize typeID:VideoFilterTypeID_None];
|
||||
return [self initWithSize:theSize typeID:VideoFilterTypeID_None numberThreads:1];
|
||||
}
|
||||
|
||||
- (id) initWithSize:(NSSize)theSize typeID:(VideoFilterTypeID)typeID
|
||||
{
|
||||
return [self initWithSize:theSize typeID:typeID numberThreads:1];
|
||||
}
|
||||
|
||||
- (id) initWithSize:(NSSize)theSize typeID:(VideoFilterTypeID)typeID numberThreads:(NSUInteger)numThreads
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil)
|
||||
|
@ -40,7 +45,7 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
vf = new VideoFilter((unsigned int)theSize.width, (unsigned int)theSize.height, typeID);
|
||||
vf = new VideoFilter((unsigned int)theSize.width, (unsigned int)theSize.height, typeID, numThreads);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ int scanline_filter_d = 4;
|
|||
********************************************************************************************/
|
||||
VideoFilter::VideoFilter()
|
||||
{
|
||||
_threadCount = 1;
|
||||
|
||||
SSurface *newSrcSurface = (SSurface *)malloc(sizeof(SSurface));
|
||||
if (newSrcSurface == NULL)
|
||||
{
|
||||
|
@ -43,26 +45,101 @@ VideoFilter::VideoFilter()
|
|||
throw;
|
||||
}
|
||||
|
||||
_srcSurfaceMaster = newSrcSurface;
|
||||
_destSurfaceMaster = newDestSurface;
|
||||
_srcSurfaceThread = _srcSurfaceMaster;
|
||||
_destSurfaceThread = _destSurfaceMaster;
|
||||
|
||||
_isFilterRunning = false;
|
||||
_srcSurfaceBufferMaster = NULL;
|
||||
_typeID = VideoFilterTypeID_None;
|
||||
|
||||
pthread_mutex_init(&_mutexSrc, NULL);
|
||||
pthread_mutex_init(&_mutexDest, NULL);
|
||||
pthread_mutex_init(&_mutexTypeID, NULL);
|
||||
pthread_mutex_init(&_mutexTypeString, NULL);
|
||||
pthread_cond_init(&_condRunning, NULL);
|
||||
|
||||
_isFilterRunning = false;
|
||||
_srcSurfaceBufferMaster = NULL;
|
||||
newSrcSurface->Surface = NULL;
|
||||
newDestSurface->Surface = NULL;
|
||||
_vfThread = (pthread_t *)malloc(sizeof(pthread_t));
|
||||
if (_vfThread == NULL)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
_srcSurface = newSrcSurface;
|
||||
_destSurface = newDestSurface;
|
||||
_typeID = VideoFilterTypeID_None;
|
||||
_vfThreadParam = (VideoFilterThreadParam *)malloc(sizeof(VideoFilterThreadParam));
|
||||
if (_vfThreadParam == NULL)
|
||||
{
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_condVFThreadFinish = (pthread_cond_t *)malloc(sizeof(pthread_cond_t));
|
||||
if (_condVFThreadFinish == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_mutexVFThreadFinish = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
if (_mutexVFThreadFinish == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_isFilterRunningThread = (bool *)malloc(sizeof(bool));
|
||||
if (_isFilterRunningThread == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
|
||||
free(_mutexVFThreadFinish);
|
||||
_mutexVFThreadFinish = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_vfThreadParam->exitThread = false;
|
||||
pthread_mutex_init(&_vfThreadParam->mutexThreadExecute, NULL);
|
||||
pthread_cond_init(&_vfThreadParam->condThreadExecute, NULL);
|
||||
|
||||
pthread_cond_init(_condVFThreadFinish, NULL);
|
||||
_vfThreadParam->condThreadFinish = _condVFThreadFinish;
|
||||
|
||||
pthread_mutex_init(_mutexVFThreadFinish, NULL);
|
||||
_vfThreadParam->mutexThreadFinish = _mutexVFThreadFinish;
|
||||
|
||||
*_isFilterRunningThread = false;
|
||||
_vfThreadParam->isFilterRunning = _isFilterRunningThread;
|
||||
|
||||
pthread_create(_vfThread, NULL, &RunVideoFilterThread, _vfThreadParam);
|
||||
|
||||
_srcSurfaceMaster->Surface = NULL;
|
||||
_destSurfaceMaster->Surface = NULL;
|
||||
SetSourceSize(1, 1);
|
||||
}
|
||||
|
||||
VideoFilter::VideoFilter(unsigned int srcWidth, unsigned int srcHeight)
|
||||
{
|
||||
_threadCount = 1;
|
||||
|
||||
SSurface *newSrcSurface = (SSurface *)malloc(sizeof(SSurface));
|
||||
if (newSrcSurface == NULL)
|
||||
{
|
||||
|
@ -77,26 +154,101 @@ VideoFilter::VideoFilter(unsigned int srcWidth, unsigned int srcHeight)
|
|||
throw;
|
||||
}
|
||||
|
||||
_srcSurfaceMaster = newSrcSurface;
|
||||
_destSurfaceMaster = newDestSurface;
|
||||
_srcSurfaceThread = _srcSurfaceMaster;
|
||||
_destSurfaceThread = _destSurfaceMaster;
|
||||
|
||||
_isFilterRunning = false;
|
||||
_srcSurfaceBufferMaster = NULL;
|
||||
_typeID = VideoFilterTypeID_None;
|
||||
|
||||
pthread_mutex_init(&_mutexSrc, NULL);
|
||||
pthread_mutex_init(&_mutexDest, NULL);
|
||||
pthread_mutex_init(&_mutexTypeID, NULL);
|
||||
pthread_mutex_init(&_mutexTypeString, NULL);
|
||||
pthread_cond_init(&_condRunning, NULL);
|
||||
|
||||
_isFilterRunning = false;
|
||||
_srcSurfaceBufferMaster = NULL;
|
||||
newSrcSurface->Surface = NULL;
|
||||
newDestSurface->Surface = NULL;
|
||||
_vfThread = (pthread_t *)malloc(sizeof(pthread_t));
|
||||
if (_vfThread == NULL)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
_srcSurface = newSrcSurface;
|
||||
_destSurface = newDestSurface;
|
||||
_typeID = VideoFilterTypeID_None;
|
||||
_vfThreadParam = (VideoFilterThreadParam *)malloc(sizeof(VideoFilterThreadParam));
|
||||
if (_vfThreadParam == NULL)
|
||||
{
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_condVFThreadFinish = (pthread_cond_t *)malloc(sizeof(pthread_cond_t));
|
||||
if (_condVFThreadFinish == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_mutexVFThreadFinish = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
if (_mutexVFThreadFinish == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_isFilterRunningThread = (bool *)malloc(sizeof(bool));
|
||||
if (_isFilterRunningThread == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
|
||||
free(_mutexVFThreadFinish);
|
||||
_mutexVFThreadFinish = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_vfThreadParam->exitThread = false;
|
||||
pthread_mutex_init(&_vfThreadParam->mutexThreadExecute, NULL);
|
||||
pthread_cond_init(&_vfThreadParam->condThreadExecute, NULL);
|
||||
|
||||
pthread_cond_init(_condVFThreadFinish, NULL);
|
||||
_vfThreadParam->condThreadFinish = _condVFThreadFinish;
|
||||
|
||||
pthread_mutex_init(_mutexVFThreadFinish, NULL);
|
||||
_vfThreadParam->mutexThreadFinish = _mutexVFThreadFinish;
|
||||
|
||||
*_isFilterRunningThread = false;
|
||||
_vfThreadParam->isFilterRunning = _isFilterRunningThread;
|
||||
|
||||
pthread_create(_vfThread, NULL, &RunVideoFilterThread, _vfThreadParam);
|
||||
|
||||
_srcSurfaceMaster->Surface = NULL;
|
||||
_destSurfaceMaster->Surface = NULL;
|
||||
SetSourceSize(srcWidth, srcHeight);
|
||||
}
|
||||
|
||||
VideoFilter::VideoFilter(unsigned int srcWidth, unsigned int srcHeight, VideoFilterTypeID typeID)
|
||||
{
|
||||
_threadCount = 1;
|
||||
|
||||
SSurface *newSrcSurface = (SSurface *)malloc(sizeof(SSurface));
|
||||
if (newSrcSurface == NULL)
|
||||
{
|
||||
|
@ -111,21 +263,234 @@ VideoFilter::VideoFilter(unsigned int srcWidth, unsigned int srcHeight, VideoFil
|
|||
throw;
|
||||
}
|
||||
|
||||
_srcSurfaceMaster = newSrcSurface;
|
||||
_destSurfaceMaster = newDestSurface;
|
||||
_srcSurfaceThread = _srcSurfaceMaster;
|
||||
_destSurfaceThread = _destSurfaceMaster;
|
||||
|
||||
_isFilterRunning = false;
|
||||
_srcSurfaceBufferMaster = NULL;
|
||||
_typeID = typeID;
|
||||
|
||||
pthread_mutex_init(&_mutexSrc, NULL);
|
||||
pthread_mutex_init(&_mutexDest, NULL);
|
||||
pthread_mutex_init(&_mutexTypeID, NULL);
|
||||
pthread_mutex_init(&_mutexTypeString, NULL);
|
||||
pthread_cond_init(&_condRunning, NULL);
|
||||
|
||||
_vfThread = (pthread_t *)malloc(sizeof(pthread_t));
|
||||
if (_vfThread == NULL)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
_vfThreadParam = (VideoFilterThreadParam *)malloc(sizeof(VideoFilterThreadParam));
|
||||
if (_vfThreadParam == NULL)
|
||||
{
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_condVFThreadFinish = (pthread_cond_t *)malloc(sizeof(pthread_cond_t));
|
||||
if (_condVFThreadFinish == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_mutexVFThreadFinish = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
if (_mutexVFThreadFinish == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_isFilterRunningThread = (bool *)malloc(sizeof(bool));
|
||||
if (_isFilterRunningThread == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
|
||||
free(_mutexVFThreadFinish);
|
||||
_mutexVFThreadFinish = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_vfThreadParam->exitThread = false;
|
||||
pthread_mutex_init(&_vfThreadParam->mutexThreadExecute, NULL);
|
||||
pthread_cond_init(&_vfThreadParam->condThreadExecute, NULL);
|
||||
|
||||
pthread_cond_init(_condVFThreadFinish, NULL);
|
||||
_vfThreadParam->condThreadFinish = _condVFThreadFinish;
|
||||
|
||||
pthread_mutex_init(_mutexVFThreadFinish, NULL);
|
||||
_vfThreadParam->mutexThreadFinish = _mutexVFThreadFinish;
|
||||
|
||||
*_isFilterRunningThread = false;
|
||||
_vfThreadParam->isFilterRunning = _isFilterRunningThread;
|
||||
|
||||
pthread_create(_vfThread, NULL, &RunVideoFilterThread, _vfThreadParam);
|
||||
|
||||
_srcSurfaceMaster->Surface = NULL;
|
||||
_destSurfaceMaster->Surface = NULL;
|
||||
SetSourceSize(srcWidth, srcHeight);
|
||||
}
|
||||
|
||||
VideoFilter::VideoFilter(unsigned int srcWidth, unsigned int srcHeight, VideoFilterTypeID typeID, unsigned int numberThreads)
|
||||
{
|
||||
// Bounds check
|
||||
if (numberThreads <= 1)
|
||||
{
|
||||
numberThreads = 1;
|
||||
}
|
||||
|
||||
_threadCount = numberThreads;
|
||||
|
||||
// We maintain a master surface with our master settings, plus additional surfaces
|
||||
// specific to each thread that work off the master surface.
|
||||
size_t threadAlloc = numberThreads + 1;
|
||||
if (numberThreads == 1)
|
||||
{
|
||||
threadAlloc = 1;
|
||||
}
|
||||
|
||||
SSurface *newSrcSurface = (SSurface *)malloc(sizeof(SSurface) * threadAlloc);
|
||||
if (newSrcSurface == NULL)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
SSurface *newDestSurface = (SSurface *)malloc(sizeof(SSurface) * threadAlloc);
|
||||
if (newDestSurface == NULL)
|
||||
{
|
||||
free(newSrcSurface);
|
||||
newSrcSurface = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
// Index the master surface at 0. When freeing, always free the master surface.
|
||||
_srcSurfaceMaster = newSrcSurface;
|
||||
_destSurfaceMaster = newDestSurface;
|
||||
|
||||
// If we're only using one thread, we can make the master surface and the thread
|
||||
// surface the same. Otherwise, index the thread surfaces starting at 1. Since
|
||||
// thread surfaces are pointers relative to the master surface, do not free any
|
||||
// thread surface directly!
|
||||
if (_threadCount <= 1)
|
||||
{
|
||||
_srcSurfaceThread = _srcSurfaceMaster;
|
||||
_destSurfaceThread = _destSurfaceMaster;
|
||||
}
|
||||
else
|
||||
{
|
||||
_srcSurfaceThread = _srcSurfaceMaster + 1;
|
||||
_destSurfaceThread = _destSurfaceMaster + 1;
|
||||
}
|
||||
|
||||
_isFilterRunning = false;
|
||||
_srcSurfaceBufferMaster = NULL;
|
||||
newSrcSurface->Surface = NULL;
|
||||
newDestSurface->Surface = NULL;
|
||||
|
||||
_srcSurface = newSrcSurface;
|
||||
_destSurface = newDestSurface;
|
||||
_typeID = typeID;
|
||||
|
||||
pthread_mutex_init(&_mutexSrc, NULL);
|
||||
pthread_mutex_init(&_mutexDest, NULL);
|
||||
pthread_mutex_init(&_mutexTypeID, NULL);
|
||||
pthread_mutex_init(&_mutexTypeString, NULL);
|
||||
pthread_cond_init(&_condRunning, NULL);
|
||||
|
||||
_vfThread = (pthread_t *)malloc(sizeof(pthread_t) * _threadCount);
|
||||
if (_vfThread == NULL)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
_vfThreadParam = (VideoFilterThreadParam *)malloc(sizeof(VideoFilterThreadParam) * _threadCount);
|
||||
if (_vfThreadParam == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_condVFThreadFinish = (pthread_cond_t *)malloc(sizeof(pthread_cond_t) * _threadCount);
|
||||
if (_condVFThreadFinish == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_mutexVFThreadFinish = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t) * _threadCount);
|
||||
if (_mutexVFThreadFinish == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
_isFilterRunningThread = (bool *)malloc(sizeof(bool) * _threadCount);
|
||||
if (_isFilterRunningThread == NULL)
|
||||
{
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
|
||||
free(_mutexVFThreadFinish);
|
||||
_mutexVFThreadFinish = NULL;
|
||||
throw;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_vfThreadParam[i].exitThread = false;
|
||||
pthread_mutex_init(&_vfThreadParam[i].mutexThreadExecute, NULL);
|
||||
pthread_cond_init(&_vfThreadParam[i].condThreadExecute, NULL);
|
||||
|
||||
pthread_cond_init(&_condVFThreadFinish[i], NULL);
|
||||
_vfThreadParam[i].condThreadFinish = &_condVFThreadFinish[i];
|
||||
|
||||
pthread_mutex_init(&_mutexVFThreadFinish[i], NULL);
|
||||
_vfThreadParam[i].mutexThreadFinish = &_mutexVFThreadFinish[i];
|
||||
|
||||
_isFilterRunningThread[i] = false;
|
||||
_vfThreadParam[i].isFilterRunning = &_isFilterRunningThread[i];
|
||||
|
||||
pthread_create(&_vfThread[i], NULL, &RunVideoFilterThread, &_vfThreadParam[i]);
|
||||
}
|
||||
|
||||
_srcSurfaceMaster->Surface = NULL;
|
||||
_destSurfaceMaster->Surface = NULL;
|
||||
SetSourceSize(srcWidth, srcHeight);
|
||||
}
|
||||
|
||||
|
@ -141,10 +506,10 @@ VideoFilter::~VideoFilter()
|
|||
pthread_cond_wait(&this->_condRunning, &this->_mutexDest);
|
||||
}
|
||||
|
||||
free(_destSurface->Surface);
|
||||
_destSurface->Surface = NULL;
|
||||
free(_destSurface);
|
||||
_destSurface = NULL;
|
||||
free(_destSurfaceMaster->Surface);
|
||||
_destSurfaceMaster->Surface = NULL;
|
||||
free(_destSurfaceMaster);
|
||||
_destSurfaceMaster = NULL;
|
||||
|
||||
pthread_mutex_unlock(&_mutexDest);
|
||||
|
||||
|
@ -152,12 +517,39 @@ VideoFilter::~VideoFilter()
|
|||
|
||||
free(_srcSurfaceBufferMaster);
|
||||
_srcSurfaceBufferMaster = NULL;
|
||||
_srcSurface->Surface = NULL;
|
||||
free(_srcSurface);
|
||||
_srcSurface = NULL;
|
||||
_srcSurfaceMaster->Surface = NULL;
|
||||
free(_srcSurfaceMaster);
|
||||
_srcSurfaceMaster = NULL;
|
||||
|
||||
pthread_mutex_unlock(&_mutexSrc);
|
||||
|
||||
for (unsigned int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
pthread_mutex_lock(&_vfThreadParam[i].mutexThreadExecute);
|
||||
_vfThreadParam[i].exitThread = true;
|
||||
pthread_cond_signal(&_vfThreadParam[i].condThreadExecute);
|
||||
pthread_mutex_unlock(&_vfThreadParam[i].mutexThreadExecute);
|
||||
|
||||
pthread_join(_vfThread[i], NULL);
|
||||
_vfThread[i] = NULL;
|
||||
pthread_mutex_destroy(&_vfThreadParam[i].mutexThreadExecute);
|
||||
pthread_cond_destroy(&_vfThreadParam[i].condThreadExecute);
|
||||
|
||||
pthread_cond_destroy(&_condVFThreadFinish[i]);
|
||||
pthread_mutex_destroy(&_mutexVFThreadFinish[i]);
|
||||
}
|
||||
|
||||
free(_vfThread);
|
||||
_vfThread = NULL;
|
||||
free(_vfThreadParam);
|
||||
_vfThreadParam = NULL;
|
||||
free(_condVFThreadFinish);
|
||||
_condVFThreadFinish = NULL;
|
||||
free(_mutexVFThreadFinish);
|
||||
_mutexVFThreadFinish = NULL;
|
||||
free(_isFilterRunningThread);
|
||||
_isFilterRunningThread = NULL;
|
||||
|
||||
pthread_mutex_destroy(&_mutexSrc);
|
||||
pthread_mutex_destroy(&_mutexDest);
|
||||
pthread_mutex_destroy(&_mutexTypeID);
|
||||
|
@ -194,16 +586,30 @@ bool VideoFilter::SetSourceSize(unsigned int width, unsigned int height)
|
|||
return result;
|
||||
}
|
||||
|
||||
this->_srcSurface->Width = width;
|
||||
this->_srcSurface->Height = height;
|
||||
this->_srcSurface->Pitch = width * 2;
|
||||
this->_srcSurfaceMaster->Width = width;
|
||||
this->_srcSurfaceMaster->Height = height;
|
||||
this->_srcSurfaceMaster->Pitch = width * 2;
|
||||
// Set the working source buffer pointer so that the working memory block is padded
|
||||
// with 4 pixel rows worth of memory on both sides.
|
||||
this->_srcSurface->Surface = (unsigned char *)(newSurfaceBuffer + (width * 4));
|
||||
this->_srcSurfaceMaster->Surface = (unsigned char *)(newSurfaceBuffer + (width * 4));
|
||||
|
||||
free(this->_srcSurfaceBufferMaster);
|
||||
this->_srcSurfaceBufferMaster = newSurfaceBuffer;
|
||||
|
||||
// Update the surfaces on threads.
|
||||
for (unsigned int i = 0; i < this->_threadCount; i++)
|
||||
{
|
||||
this->_srcSurfaceThread[i] = *this->_srcSurfaceMaster;
|
||||
this->_srcSurfaceThread[i].Height /= this->_threadCount;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
this->_srcSurfaceThread[i].Surface = (unsigned char *)((uint32_t *)this->_srcSurfaceThread[i - 1].Surface + (this->_srcSurfaceThread[i - 1].Width * this->_srcSurfaceThread[i - 1].Height));
|
||||
}
|
||||
|
||||
this->_vfThreadParam[i].srcSurface = this->_srcSurfaceThread[i];
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&this->_mutexSrc);
|
||||
|
||||
result = this->ChangeFilter(this->GetTypeID());
|
||||
|
@ -229,8 +635,8 @@ bool VideoFilter::ChangeFilter(VideoFilterTypeID typeID)
|
|||
bool result = false;
|
||||
|
||||
pthread_mutex_lock(&this->_mutexSrc);
|
||||
const unsigned int srcWidth = this->_srcSurface->Width;
|
||||
const unsigned int srcHeight = this->_srcSurface->Height;
|
||||
const unsigned int srcWidth = this->_srcSurfaceMaster->Width;
|
||||
const unsigned int srcHeight = this->_srcSurfaceMaster->Height;
|
||||
pthread_mutex_unlock(&this->_mutexSrc);
|
||||
|
||||
unsigned int destWidth = srcWidth;
|
||||
|
@ -358,12 +764,27 @@ bool VideoFilter::ChangeFilter(VideoFilterTypeID typeID)
|
|||
}
|
||||
|
||||
this->_filterCallback = filterCallback;
|
||||
this->_destSurface->Width = destWidth;
|
||||
this->_destSurface->Height = destHeight;
|
||||
this->_destSurface->Pitch = destWidth * 2;
|
||||
this->_destSurfaceMaster->Width = destWidth;
|
||||
this->_destSurfaceMaster->Height = destHeight;
|
||||
this->_destSurfaceMaster->Pitch = destWidth * 2;
|
||||
|
||||
free(this->_destSurface->Surface);
|
||||
this->_destSurface->Surface = (unsigned char*)newSurfaceBuffer;
|
||||
free(this->_destSurfaceMaster->Surface);
|
||||
this->_destSurfaceMaster->Surface = (unsigned char*)newSurfaceBuffer;
|
||||
|
||||
// Update the surfaces on threads.
|
||||
for (unsigned int i = 0; i < this->_threadCount; i++)
|
||||
{
|
||||
this->_destSurfaceThread[i] = *this->_destSurfaceMaster;
|
||||
this->_destSurfaceThread[i].Height /= this->_threadCount;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
this->_destSurfaceThread[i].Surface = (unsigned char *)((uint32_t *)this->_destSurfaceThread[i - 1].Surface + (this->_destSurfaceThread[i - 1].Width * this->_destSurfaceThread[i - 1].Height));
|
||||
}
|
||||
|
||||
this->_vfThreadParam[i].destSurface = this->_destSurfaceThread[i];
|
||||
this->_vfThreadParam[i].filterCallback = this->_filterCallback;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&this->_mutexDest);
|
||||
|
||||
|
@ -392,17 +813,35 @@ uint32_t* VideoFilter::RunFilter()
|
|||
pthread_mutex_lock(&this->_mutexDest);
|
||||
|
||||
this->_isFilterRunning = true;
|
||||
uint32_t *destBufPtr = (uint32_t *)this->_destSurface->Surface;
|
||||
uint32_t *destBufPtr = (uint32_t *)this->_destSurfaceMaster->Surface;
|
||||
|
||||
pthread_mutex_lock(&this->_mutexSrc);
|
||||
|
||||
if (this->_filterCallback == NULL)
|
||||
{
|
||||
memcpy(this->_destSurface->Surface, this->_srcSurface->Surface, this->_destSurface->Width * this->_destSurface->Height * sizeof(uint32_t));
|
||||
memcpy(this->_destSurfaceMaster->Surface, this->_srcSurfaceMaster->Surface, this->_destSurfaceMaster->Width * this->_destSurfaceMaster->Height * sizeof(uint32_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_filterCallback(*this->_srcSurface, *this->_destSurface);
|
||||
for (unsigned int i = 0; i < this->_threadCount; i++)
|
||||
{
|
||||
pthread_mutex_lock(&this->_vfThreadParam[i].mutexThreadExecute);
|
||||
*this->_vfThreadParam[i].isFilterRunning = true;
|
||||
pthread_cond_signal(&this->_vfThreadParam[i].condThreadExecute);
|
||||
pthread_mutex_unlock(&this->_vfThreadParam[i].mutexThreadExecute);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < this->_threadCount; i++)
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexVFThreadFinish[i]);
|
||||
|
||||
while (this->_isFilterRunningThread[i])
|
||||
{
|
||||
pthread_cond_wait(&this->_condVFThreadFinish[i], &this->_mutexVFThreadFinish[i]);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&this->_mutexVFThreadFinish[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&this->_mutexSrc);
|
||||
|
@ -557,7 +996,7 @@ void VideoFilter::SetTypeString(std::string typeString)
|
|||
uint32_t* VideoFilter::GetSrcBufferPtr()
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexSrc);
|
||||
uint32_t *ptr = (uint32_t *)this->_srcSurface->Surface;
|
||||
uint32_t *ptr = (uint32_t *)this->_srcSurfaceMaster->Surface;
|
||||
pthread_mutex_unlock(&this->_mutexSrc);
|
||||
|
||||
return ptr;
|
||||
|
@ -566,7 +1005,7 @@ uint32_t* VideoFilter::GetSrcBufferPtr()
|
|||
uint32_t* VideoFilter::GetDestBufferPtr()
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexDest);
|
||||
uint32_t *ptr = (uint32_t *)this->_destSurface->Surface;
|
||||
uint32_t *ptr = (uint32_t *)this->_destSurfaceMaster->Surface;
|
||||
pthread_mutex_unlock(&this->_mutexDest);
|
||||
|
||||
return ptr;
|
||||
|
@ -575,7 +1014,7 @@ uint32_t* VideoFilter::GetDestBufferPtr()
|
|||
unsigned int VideoFilter::GetSrcWidth()
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexSrc);
|
||||
unsigned int width = this->_srcSurface->Width;
|
||||
unsigned int width = this->_srcSurfaceMaster->Width;
|
||||
pthread_mutex_unlock(&this->_mutexSrc);
|
||||
|
||||
return width;
|
||||
|
@ -584,7 +1023,7 @@ unsigned int VideoFilter::GetSrcWidth()
|
|||
unsigned int VideoFilter::GetSrcHeight()
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexSrc);
|
||||
unsigned int height = this->_srcSurface->Height;
|
||||
unsigned int height = this->_srcSurfaceMaster->Height;
|
||||
pthread_mutex_unlock(&this->_mutexSrc);
|
||||
|
||||
return height;
|
||||
|
@ -593,7 +1032,7 @@ unsigned int VideoFilter::GetSrcHeight()
|
|||
unsigned int VideoFilter::GetDestWidth()
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexDest);
|
||||
unsigned int width = this->_destSurface->Width;
|
||||
unsigned int width = this->_destSurfaceMaster->Width;
|
||||
pthread_mutex_unlock(&this->_mutexDest);
|
||||
|
||||
return width;
|
||||
|
@ -602,8 +1041,41 @@ unsigned int VideoFilter::GetDestWidth()
|
|||
unsigned int VideoFilter::GetDestHeight()
|
||||
{
|
||||
pthread_mutex_lock(&this->_mutexDest);
|
||||
unsigned int height = this->_destSurface->Height;
|
||||
unsigned int height = this->_destSurfaceMaster->Height;
|
||||
pthread_mutex_unlock(&this->_mutexDest);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
static void* RunVideoFilterThread(void *arg)
|
||||
{
|
||||
VideoFilterThreadParam *param = (VideoFilterThreadParam *)arg;
|
||||
|
||||
do
|
||||
{
|
||||
pthread_mutex_lock(¶m->mutexThreadExecute);
|
||||
|
||||
while (!*param->isFilterRunning && !param->exitThread)
|
||||
{
|
||||
pthread_cond_wait(¶m->condThreadExecute, ¶m->mutexThreadExecute);
|
||||
}
|
||||
|
||||
if (param->exitThread)
|
||||
{
|
||||
pthread_mutex_unlock(¶m->mutexThreadExecute);
|
||||
break;
|
||||
}
|
||||
|
||||
param->filterCallback(param->srcSurface, param->destSurface);
|
||||
|
||||
pthread_mutex_lock(param->mutexThreadFinish);
|
||||
*param->isFilterRunning = false;
|
||||
pthread_cond_signal(param->condThreadFinish);
|
||||
pthread_mutex_unlock(param->mutexThreadFinish);
|
||||
|
||||
pthread_mutex_unlock(¶m->mutexThreadExecute);
|
||||
|
||||
} while (!param->exitThread);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,21 @@ enum VideoFilterTypeID
|
|||
|
||||
typedef void (*VideoFilterCallback)(SSurface Src, SSurface Dst);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SSurface srcSurface;
|
||||
SSurface destSurface;
|
||||
VideoFilterCallback filterCallback;
|
||||
|
||||
bool exitThread;
|
||||
pthread_mutex_t mutexThreadExecute;
|
||||
pthread_cond_t condThreadExecute;
|
||||
pthread_cond_t *condThreadFinish;
|
||||
pthread_mutex_t *mutexThreadFinish;
|
||||
bool *isFilterRunning;
|
||||
|
||||
} VideoFilterThreadParam;
|
||||
|
||||
/********************************************************************************************
|
||||
VideoFilter - C++ CLASS
|
||||
|
||||
|
@ -99,12 +114,21 @@ class VideoFilter
|
|||
private:
|
||||
VideoFilterTypeID _typeID;
|
||||
std::string _typeString;
|
||||
SSurface *_srcSurface;
|
||||
SSurface *_destSurface;
|
||||
SSurface *_srcSurfaceMaster;
|
||||
SSurface *_destSurfaceMaster;
|
||||
SSurface *_srcSurfaceThread;
|
||||
SSurface *_destSurfaceThread;
|
||||
uint32_t *_srcSurfaceBufferMaster;
|
||||
VideoFilterCallback _filterCallback;
|
||||
bool _isFilterRunning;
|
||||
|
||||
unsigned int _threadCount;
|
||||
pthread_t *_vfThread;
|
||||
VideoFilterThreadParam *_vfThreadParam;
|
||||
pthread_cond_t *_condVFThreadFinish;
|
||||
pthread_mutex_t *_mutexVFThreadFinish;
|
||||
bool *_isFilterRunningThread;
|
||||
|
||||
pthread_mutex_t _mutexSrc;
|
||||
pthread_mutex_t _mutexDest;
|
||||
pthread_mutex_t _mutexTypeID;
|
||||
|
@ -119,6 +143,7 @@ public:
|
|||
VideoFilter();
|
||||
VideoFilter(unsigned int srcWidth, unsigned int srcHeight);
|
||||
VideoFilter(unsigned int srcWidth, unsigned int srcHeight, VideoFilterTypeID typeID);
|
||||
VideoFilter(unsigned int srcWidth, unsigned int srcHeight, VideoFilterTypeID typeID, unsigned int numberThreads);
|
||||
~VideoFilter();
|
||||
|
||||
bool SetSourceSize(unsigned int width, unsigned int height);
|
||||
|
@ -136,4 +161,6 @@ public:
|
|||
unsigned int GetDestHeight();
|
||||
};
|
||||
|
||||
static void* RunVideoFilterThread(void *arg);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue