我试图为以RAW格式存储的视频组合一个简单的视频播放器。这些视频可选地通过卷积滤镜。我的CWinApp类有三个相关的方法。首先,当选择视频并将其放在指针viewingVideo
中时,我会分配两个位图:
void CMyApp::setBitmaps() {
if (viewingVideo == NULL)
return;
bmp1 = CreateDIBSection(dc, viewingVideo->bmi, DIB_RGB_COLORS, NULL, NULL, 0);
bmp2 = CreateDIBSection(dc, viewingVideo->bmi, DIB_RGB_COLORS, NULL, NULL, 0);
}
然后,当用户按下播放时,我初始化调用以下两种方法的定时器33 ms,播放30 fps:
void CMyApp::updateVideoFrame() {
if (viewingVideo == NULL)
return;
if (viewingKernel != NULL) {
applyKernelFFT(viewingKernel, viewingVideo, currentFrame);
}
if (viewingKernel == NULL)
SetDIBits(dc, bmpToggle ? bmp2 : bmp1, 0, viewingVideo->height, (char*)(viewingVideo->data) + currentFrame*viewingVideo->bpp*viewingVideo->width*viewingVideo->height, viewingVideo->bmi, DIB_RGB_COLORS);
else
SetDIBits(dc, bmpToggle ? bmp2 : bmp1, 0, viewingVideo->height, (char*)(viewingVideo->filtered_data), viewingVideo->bmi, DIB_RGB_COLORS);
bmpToggle = !bmpToggle;
}
void CMyApp::updateVideoScreen() {
CMyView* view = CMyView::GetView(); //returns the active view
view->m_Video.SetBitmap(bmpToggle ? bmp1 : bmp2);
CRect update;
view->m_Video.GetWindowRect(&update);
view->ScreenToClient(&update);
//update.DeflateRect(update.Width()/2-1, update.Height()/2 - 1);
InvalidateRect(*AfxGetMainWnd(), update, FALSE);
}
在任何给定时间,方法应使用不同的位图。当我启动这些计时器时,屏幕上有相当多的闪烁。当我取消注释DeflateRect
调用,使update
为2x2像素矩形时,很明显实际上存在两个闪烁源:有时整个图像闪烁,有时只有2x2矩形在中心。
我已尝试过其他地方建议的常见修补方法,例如在WM_ERASEBKGND
中处理CMyView
。这没有帮助。如何防止这种闪烁?
答案 0 :(得分:0)
对于任何想要从他们的软件中删除癫痫警告的人来说,这是修复闪烁所需要的。阿德里安麦卡锡的建议是完全正确的。在updateVideoScreen
中,我将view->m_Video.SetBitmap(bmpToggle ? bmp1 : bmp2);
替换为SelectObject(dc, bmpToggle ? bmp1 : bmp2);
,因此位图数据将发送到我的内存DC而不是控件。然后我覆盖OnPaint()
以调用BitBlt
将位图写入视频控件所在的屏幕:
void CMTFBoostView::OnPaint()
{
CRect rect;
m_Video.GetWindowRect(&rect);
ScreenToClient(&rect);
video* v = ((CMTFBoostApp*)AfxGetApp())->viewingVideo;
CDC* src = ((CMTFBoostApp*)AfxGetApp())->cdc;
CDC* dc = GetDC();
if (v != NULL && dc->RectVisible(rect)) {
dc->BitBlt(rect.left, rect.top, v->width, v->height, src, 0, 0, SRCCOPY);
}
ReleaseDC(dc);
CFormView::OnPaint();
}
前面的几行是将视频放在我之前的地方 - 从视图中完全删除CStatic控件可能会更清晰。无论如何,这会显示没有闪烁的视频。