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