【发布时间】:2017-07-06 14:35:15
【问题描述】:
我正在尝试为以 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 毫秒调用以下两种方法的计时器,以实现 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。这没有帮助。如何防止这种闪烁?
【问题讨论】:
-
你的 WM_PAINT 处理程序是什么样的?
-
也许这就是问题所在,我目前没有处理 WM_PAINT。我需要双缓冲吗?如果是这样,在 MFC 中这样做的正确方法是什么?
-
您正在使 updateVideoScreen 中的主窗口无效,这将触发 WM_PAINT。我以为那是你真正将位图blit到屏幕上的时候。