На дисплее видеокамеры мерцает изображение, хотя я (кажется, я) отключил стирание фона.Почему?
Даже текст, отображаемый над видеопрезентацией, мигает.
Полный код в Bitbucket .
Возможно, наиболее релевантный код, гизмо для отображения видео:
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 ) )
{}
};
Основной код из потока видео производителя:
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 );
}
}
Функция putResult
просто вызывает SendMessage
Windows, который синхронизируется с потоком отображения.
Я не вижу, как удается проникнуть мерцанию?
EDIT : я нашел исправление, а именнодобавив
WS_CLIPCHILDREN
к главному окну и используя
RedrawWindow
, чтобы вызвать немедленное перерисовывание элемента управления (дочернее окно).Большая загадка, почему это работает.Большая загадка: без применения
RedrawWindow
,
WS_CLIPCHILDREN
вызывает чрезвычайную медленность, например, 1 кадр каждые 20 секунд?
РЕДАКТИРОВАТЬ 2 : это не длилось долго.: - (
РЕДАКТИРОВАТЬ 3 : * РЕШЕНО *. И mea culpa . Все это мерцание было вызвано неправильным вызовом InvalidateRect
, в коде главного окна. Я, вероятно, положил его туда только для проверки, и забыл удалить его. Argh!