Video Filter:
- When changing filters, skip the costly construction of a new destination buffer if the new surface size will be the same.
This commit is contained in:
parent
d1c6c6e3ac
commit
9a642be896
|
@ -247,56 +247,74 @@ bool VideoFilter::ChangeFilterByAttributes(const VideoFilterAttributes *vfAttr)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetAttributes(*vfAttr);
|
if (this->_vfDstSurface.Surface != NULL && this->_vfAttributes.scaleMultiply == vfAttr->scaleMultiply && this->_vfAttributes.scaleDivide == vfAttr->scaleDivide)
|
||||||
VideoFilterAttributes &workingAttributes = this->_vfAttributes;
|
|
||||||
|
|
||||||
ThreadLockLock(&this->_lockSrc);
|
|
||||||
const size_t srcWidth = this->_vfSrcSurface.Width;
|
|
||||||
const size_t srcHeight = this->_vfSrcSurface.Height;
|
|
||||||
ThreadLockUnlock(&this->_lockSrc);
|
|
||||||
|
|
||||||
const size_t dstWidth = srcWidth * workingAttributes.scaleMultiply / workingAttributes.scaleDivide;
|
|
||||||
const size_t dstHeight = srcHeight * workingAttributes.scaleMultiply / workingAttributes.scaleDivide;
|
|
||||||
const VideoFilterFunc filterFunction = workingAttributes.filterFunction;
|
|
||||||
|
|
||||||
ThreadLockLock(&this->_lockDst);
|
|
||||||
|
|
||||||
uint32_t *newSurfaceBuffer = (uint32_t *)calloc(dstWidth * dstHeight, sizeof(uint32_t));
|
|
||||||
if (newSurfaceBuffer == NULL)
|
|
||||||
{
|
{
|
||||||
return result;
|
// If we have an existing buffer and the new size is identical to the old size,
|
||||||
}
|
// we can skip the costly construction of the buffer and simply clear it instead.
|
||||||
|
ThreadLockLock(&this->_lockDst);
|
||||||
this->_vfFunc = filterFunction;
|
|
||||||
this->_vfDstSurface.Width = dstWidth;
|
|
||||||
this->_vfDstSurface.Height = dstHeight;
|
|
||||||
this->_vfDstSurface.Pitch = dstWidth * 2;
|
|
||||||
|
|
||||||
free(this->_vfDstSurface.Surface);
|
|
||||||
this->_vfDstSurface.Surface = (unsigned char *)newSurfaceBuffer;
|
|
||||||
|
|
||||||
// Update the surfaces on threads.
|
|
||||||
const size_t threadCount = this->_vfThread.size();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < threadCount; i++)
|
|
||||||
{
|
|
||||||
SSurface &threadDstSurface = this->_vfThread[i].param.dstSurface;
|
|
||||||
threadDstSurface = this->_vfDstSurface;
|
|
||||||
threadDstSurface.Height /= threadCount;
|
|
||||||
|
|
||||||
if (i > 0)
|
memset(this->_vfDstSurface.Surface, 0, this->_vfDstSurface.Width * _vfDstSurface.Height * sizeof(uint32_t));
|
||||||
|
this->_vfFunc = vfAttr->filterFunction;
|
||||||
|
|
||||||
|
const size_t threadCount = this->_vfThread.size();
|
||||||
|
for (size_t i = 0; i < threadCount; i++)
|
||||||
{
|
{
|
||||||
SSurface &prevThreadDstSurface = this->_vfThread[i - 1].param.dstSurface;
|
this->_vfThread[i].param.filterFunction = this->_vfFunc;
|
||||||
threadDstSurface.Surface = (unsigned char *)((uint32_t *)prevThreadDstSurface.Surface + (prevThreadDstSurface.Width * prevThreadDstSurface.Height));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_vfThread[i].param.filterFunction = this->_vfFunc;
|
ThreadLockUnlock(&this->_lockDst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Construct a new destination buffer per filter attributes.
|
||||||
|
ThreadLockLock(&this->_lockSrc);
|
||||||
|
const size_t srcWidth = this->_vfSrcSurface.Width;
|
||||||
|
const size_t srcHeight = this->_vfSrcSurface.Height;
|
||||||
|
ThreadLockUnlock(&this->_lockSrc);
|
||||||
|
|
||||||
|
const size_t dstWidth = srcWidth * vfAttr->scaleMultiply / vfAttr->scaleDivide;
|
||||||
|
const size_t dstHeight = srcHeight * vfAttr->scaleMultiply / vfAttr->scaleDivide;
|
||||||
|
const VideoFilterFunc filterFunction = vfAttr->filterFunction;
|
||||||
|
|
||||||
|
ThreadLockLock(&this->_lockDst);
|
||||||
|
|
||||||
|
uint32_t *newSurfaceBuffer = (uint32_t *)calloc(dstWidth * dstHeight, sizeof(uint32_t));
|
||||||
|
if (newSurfaceBuffer == NULL)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_vfFunc = filterFunction;
|
||||||
|
this->_vfDstSurface.Width = dstWidth;
|
||||||
|
this->_vfDstSurface.Height = dstHeight;
|
||||||
|
this->_vfDstSurface.Pitch = dstWidth * 2;
|
||||||
|
|
||||||
|
free(this->_vfDstSurface.Surface);
|
||||||
|
this->_vfDstSurface.Surface = (unsigned char *)newSurfaceBuffer;
|
||||||
|
|
||||||
|
// Update the surfaces on threads.
|
||||||
|
const size_t threadCount = this->_vfThread.size();
|
||||||
|
for (size_t i = 0; i < threadCount; i++)
|
||||||
|
{
|
||||||
|
SSurface &threadDstSurface = this->_vfThread[i].param.dstSurface;
|
||||||
|
threadDstSurface = this->_vfDstSurface;
|
||||||
|
threadDstSurface.Height /= threadCount;
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
SSurface &prevThreadDstSurface = this->_vfThread[i - 1].param.dstSurface;
|
||||||
|
threadDstSurface.Surface = (unsigned char *)((uint32_t *)prevThreadDstSurface.Surface + (prevThreadDstSurface.Width * prevThreadDstSurface.Height));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_vfThread[i].param.filterFunction = this->_vfFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadLockUnlock(&this->_lockDst);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadLockUnlock(&this->_lockDst);
|
this->SetAttributes(*vfAttr);
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue