基于位图的视频播放器

时间:2017-07-06 14:35:15

标签: windows mfc

我试图为以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。这没有帮助。如何防止这种闪烁?

1 个答案:

答案 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控件可能会更清晰。无论如何,这会显示没有闪烁的视频。