MultiThreading in DirectShow Transform filter

Hi! I've got a problem about using threads to do my image processing in the transform function of my transform filter. My main problem is that when I'm processing big images of large samples, the video renderer seems to drop frames. So I thought of instead of processing a single sample line by line, I will use multiple threads to do the work, each thread starting at starting at different offsets in the sample. However, It seems that the video renderer has dropped more frames after I changed the code.

Here's my code with the threads ( called from transform function ):
/*Code*/

BOOL LibRGB2YCC(unsigned char *pSrcBuf, unsigned char *pDstBuf,int nThreadCnt, long lComImgHt, long lLastImgHt,
long lStride, long lWidth, long lHeight,BOOL bGrayScale)
{
TRACE( "ENTERED LIBRGB2YCC:\n" );
TRACE( " THREAD NUM: %d ", nThreadCnt );
ThreadStruct* pTransParam = new ThreadStruct[nThreadCnt];
TRACE( "AFTER THREAD STRUCT ALLOCATION:\n" );
for( int i = 0; i < nThreadCnt; i++ )
{
pTransParam[i].BmpWidth = lWidth;
pTransParam[i].SrcStride = lStride;
pTransParam[i].bGrayScale = bGrayScale;

if(( i == ( nThreadCnt -1 )) && (lLastImgHt!=0) )
pTransParam[i].BmpHeight = lLastImgHt;
else
pTransParam[i].BmpHeight = lComImgHt;

pTransParam[i].pSrcBuff = pSrcBuf + ( lStride * (lComImgHt * i ));
pTransParam[i].pDstBuff = pDstBuf + ( lWidth * 3 * (lComImgHt * i ));
}

HANDLE *pThreadHandles = new HANDLE[nThreadCnt];
CWinThread *ParseThread;
for( i = 0; i < nThreadCnt; i++ )
{
ParseThread = AfxBeginThread( ThreadFuncRGB24toYCC, &pTransParam[i], THREAD_PRIORITY_TIME_CRITICAL, 0, CREATE_SUSPENDED );
ParseThread->m_bAutoDelete = TRUE;
pThreadHandles[i] = ParseThread->m_hThread;
ParseThread->ResumeThread();
}

WaitForMultipleObjects(nThreadCnt,pThreadHandles,TRUE,3000);

return TRUE;

}

UINT ThreadFuncRGB24toYCC(LPVOID pParam)
{

ThreadStruct* pThreadParam = (ThreadStruct*)pParam;

BYTE *pDst, *pSrc;

float Y, Cr, Cb;
long r,g,b;
long y,x;
float ycbcrCoeffs[3] = { 0.2989F, 0.5866F, 0.1145F };
float D1, D2;

D1 = 1.F/(2.F - 2.F*ycbcrCoeffs[2]);
D2 = 1.F/(2.F - 2.F*ycbcrCoeffs[0]);

pDst = pThreadParam->pDstBuff;

for( y = 0; y < pThreadParam->BmpHeight ; y++ )
{
pSrc = (BYTE*) pThreadParam->pSrcBuff;
for( x = 0; x < pThreadParam->BmpWidth; x++ )
{
b = (long)*pSrc ++;
g = (long)*pSrc ++;
r = (long)*pSrc ++;

Y = ycbcrCoeffs[0]*r + ycbcrCoeffs[1]*g + ycbcrCoeffs[2]*b;
Cb = (b - Y) * D1;
Cr = (r - Y) * D2;

if( pThreadParam->bGrayScale )
{
*pDst++ = V2Code(Y,0, 255, 255);
*pDst++ = V2Code(Y,0, 255, 255);
*pDst++ = V2Code(Y,0, 255, 255);
}
else
{

*pDst++ = V2Code(Y,0, 255, 255); //Y
*pDst++ = V2Code(Cb,128, 255, 127);//Cb
*pDst++ = V2Code(Cr,128, 255, 127);//Cr
}

}

pThreadParam->pSrcBuff += pThreadParam->SrcStride;
}

return 0;
}

/* Code */

Is there a problem with using AfxBeginThread() inside a transform function? Why is it slowing down instead of speeding up since more threads are simultaneously processing my sample?

Please Help. ASAp
Thanks!
[3564 byte] By [HotChick] at [2007-11-19 10:50:59]
# 1 Re: MultiThreading in DirectShow Transform filter
By adding more threads you won't speed up the processing, but you would slow it down by introducing context switching and other overhead (at least on single non-hyperthreading CPUs).

You should rather try to optimize your code, for instance:

if( pThreadParam->bGrayScale )
is evaluated BmpHeight*BmpWidth times for each frame, and it probably evaluates to the same result every time.

- petter
wildfrog at 2007-11-10 3:50:37 >