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:
Code:
mpOverlay->fill( Qt::red ); mpOverlayLabel->hide( ); mpOverlayLabel->setPixmap( *mpOverlay );
Then whenever I click on the screen I do this:
Code:
{ AzElPoint point; 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:
Code:
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!
