PDA

View Full Version : Flicker Problem



ToddAtWSU
26th June 2006, 14:08
I figured out how to get my overlay to work on my DirectShow video. I just made a QPixmap of size 5x5 and put this on a QLabel of size 5x5 which I draw on top of the QAxWidget displaying my video. This works great instead of trying to create a transparent pixmap/label but I get a lot of flicker when I click on the video to draw the point. In my GUI building function I set these variables up like this:


mpOverlay = new QPixmap( 5, 5 );
mpOverlay->fill( Qt::red );

mpOverlayLabel = new QLabel( mpVideoPlayer );
mpOverlayLabel->setGeometry( QRect( 0, 0, 5, 5 ) );
mpOverlayLabel->hide( );
mpOverlayLabel->setPixmap( *mpOverlay );

Then whenever I click on the screen I do this:


if( event->type() == QEvent::MouseButtonRelease )
{
AzElPoint point;
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);

point.frameNumber = getCurrentFrame( );
point.xPos = mouseEvent->x( );
point.yPos = mouseEvent->y( );

if( mouseEvent->button() == Qt::LeftButton )
{
// If left button, place mark on overlay to indicate position
// and store position in array at the current frame index
for( int i = 0 ; i < azElPoints.size( ) ; i++ )
{
if( azElPoints[i].frameNumber == getCurrentFrame( ) )
{
azElPoints.removeAt( i );
erasePoint = true;
}
}
azElPoints.push_back( point );
printf( "x=%d, y=%d\n", point.xPos, point.yPos );
update( );
return true;
}
}

And my paint event handler just calls repaintWindow( ) which looks like this:


void VideoViewerWindow::repaintWindow( )
{
long lWidth, lHeight;
HRESULT hr = pWindowlessControl->GetNativeVideoSize( &lWidth, &lHeight, NULL, NULL );
RECT rcSrc, rcDest;
// Set the source rectangle.
SetRect( &rcSrc, 0, 0, lWidth, lHeight );

// Get the window client area.
GetClientRect( (HWND) mpVideoPlayer->winId( ), &rcDest );
// Set the destination rectangle.
SetRect(&rcDest, 1, 1, 558, 349);

// Set the video position.
hr = pWindowlessControl->SetVideoPosition( &rcSrc, &rcDest );

PAINTSTRUCT ps;
HDC hdc;
RECT rcClient;
GetClientRect( (HWND) mpVideoPlayer->winId( ), &rcClient );
hdc = BeginPaint( (HWND) mpVideoPlayer->winId( ), &ps );
if( pWindowlessControl != NULL )
{
// Find the region where the application can paint by subtracting
// the video destination rectangle from the client area.
// (Assume that g_rcDest was calculated previously.)
HRGN rgnClient = CreateRectRgnIndirect( &rcClient );
HRGN rgnVideo = CreateRectRgnIndirect( &rcDest );
CombineRgn( rgnClient, rgnClient, rgnVideo, RGN_DIFF );

// Paint on window.
HBRUSH hbr = GetSysColorBrush( COLOR_BTNFACE );
FillRgn( hdc, rgnClient, hbr );

// Clean up.
DeleteObject( hbr );
DeleteObject( rgnClient );
DeleteObject( rgnVideo );

// Request the VMR to paint the video and draw the point chosen by the user.
int i;
for( i = 0 ; i < azElPoints.size( ) ; i++ )
{
if( azElPoints[i].frameNumber == getCurrentFrame( ) )
{
mpOverlayLabel->move( azElPoints[i].xPos - 2, azElPoints[i].yPos - 2 );
mpOverlayLabel->show( );
break;
}
}
if( i == azElPoints.size( ) )
{
mpOverlayLabel->hide( );
}
HRESULT hr = pWindowlessControl->RepaintVideo( (HWND) mpVideoPlayer->winId( ), hdc );
}
}

You can see what I am doing is just showing/hiding the QLabel and then redrawing the video (ie. the QAxWidget) which in turns redraws the QLabel since it is a child of the QAxWidget. But when I click the screen, I want the dot (QPixmap/QLabel) to appear without causing the entire screen to flicker. Sometimes the screen flickers and sometimes it does not. And when it does flicker, sometimes the flicker lasts almost a half of a second - which is very noticeable. So any ideas on how to improve my function(s) to prevent this from flickering would be great! Thanks!

ToddAtWSU
26th June 2006, 16:50
I got the flickering disappearing because I was noticing that I was calling update() and there seemes to be another update() being called so I was redrawing the same thing twice. By taking out my update() call it took out the flicker. The only problem now is there is considerable lag between clicking on the screen and the small QLabel/QPixmap actually appearing. Is there just a big lag between catching the mouseButtonRelease and Paint event? The image clicking occurs fast and if I play the movie straight through after rewinding it after clicking on it, it plays through fast and shows all the points. So it seems the individual events work fast but when you combine them they are slow. Is this normal? Thanks!