Reputation: 145269
I get flickering in my cam video display, even though I (think I) turned off background erasure. Why?
Even the text display above the video presentation flickers.
Full code at Bitbucket.
Perhaps most relevant code, the gizmo that display the video:
class ImageDisplay:
public gizmo::SubGizmo
{
typedef gizmo::SubGizmo Base;
private:
winapi::graphics::ColorDib dib_;
protected:
void onPaint( raw::DcHandle const dc ) CPP_IS_OVERRIDE
{
dib_.renderOn( dc );
}
bool onWmEraseBkgnd( raw::DcHandle const dc )
{
CPP_DECLARE_UNUSED( dc );
return true; // Just say it's done, so it won't be done again.
}
void onWmPaint() CPP_IS_OVERRIDE
{
callOnPaint();
}
virtual raw::LResult dispatchWm(
raw::UInt const messageId,
raw::WParam const wParam,
raw::LParam const lParam
)
{
CPP_DUMMY_USE_OF( wParam ); CPP_DUMMY_USE_OF( lParam );
typedef ImageDisplay W;
switch( messageId )
{
case WM_ERASEBKGND:
return FORWARD_WM_TO( this, W::onWmEraseBkgnd, WM_ERASEBKGND, wParam, lParam );
}
return Base::dispatchWm( messageId, wParam, lParam );
}
public:
void setImage( cvapi::ImageRef const newImage )
{
dib_ = win_cv::dibFrom( newImage );
setExtent( newImage.extent() );
}
ImageDisplay(
Gizmo& parent,
int const x,
int const y,
cvapi::ImageRef const& pic
)
: Base( parent, x, y, pic.width(), pic.height() )
, dib_( win_cv::dibFrom( pic ) )
{}
};
The main code from the video producer thread:
void imageProducer(
wstring const& namePattern,
PutFunction const putResult,
Thread::Control const& threadControl
)
{
assert( !!putResult );
cv::VideoCapture cap( 0 ); // Open the default camera.
hopefully( cap.isOpened() )
|| throwX( "cam::imageProducer: VideoCapture::<init> failed" );
for(;;)
{
cv::Mat frame;
if( threadControl.exitIsRequested() ) { return; }
cap >> frame; // Get a new frame from camera.
if( threadControl.exitIsRequested() ) { return; }
putResult( frame );
}
}
The putResult
function just calls Windows’s SendMessage
, which synchronizes with the display thread.
I can't see how the flicker manages to sneak in?
WS_CLIPCHILDREN
to the main window, and using RedrawWindow
to force immediate redrawing of the control (child window). Big mystery why it works. Bigger mystery: without RedrawWindow
applied, WS_CLIPCHILDREN
causes extreme slowness, like 1 frame every 20 secs?
EDIT 2: it didn't last. :-(
EDIT 3: * S O L V E D *. And mea culpa. All that flicker was caused by an inappropriate call to InvalidateRect
, in the main window code. I had probably put it there just to test things, and forgotten to remove it. Argh!
Upvotes: 1
Views: 1397
Reputation: 145269
Mea culpa. All that flicker was caused by an inappropriate call to Windows’ InvalidateRect
, in the main window code. I had probably put that call there just to test things, and forgotten to remove it. Argh!
Learning point:
Do not blame the “system” (here the Windows API, but also compiler etc.) before you have checked absolutely everything in your own code. It is like dirty fingerprints on your glasses. You never put your fingers on your glasses, and yet these fingerprints appear; same with mysterious undesirable statements in the code.
Upvotes: 2