J'essaie de mettre en place un simple lecteur vidéo pour les vidéos stockées au format RAW. Ces vidéos sont éventuellement transmises via un filtre de convolution. Ma classe CWinApp a trois méthodes pertinentes. Tout d'abord, lorsqu'une vidéo est sélectionnée et placée dans le pointeur viewingVideo
, j'allouer deux bitmaps:Scintillement sur lecteur vidéo bitmap
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);
}
Puis, lors de la lecture l'utilisateur appuie, j'initialiser minuteries qui appellent les deux méthodes suivantes jamais 33 ms, 30 images par seconde lecture:
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);
}
À un moment donné, les méthodes devraient utiliser différentes bitmaps. Il y a pas mal de scintillement sur l'écran lorsque je démarre ces minuteries. Lorsque je décommente l'appel DeflateRect
, ce qui rend update
un rectangle de 2x2 pixels, il devient clair qu'il existe deux sources de scintillement: parfois l'image entière scintille, et parfois seulement le rectangle 2x2 au centre.
J'ai essayé les correctifs courants suggérés par ailleurs, comme la transmission de WM_ERASEBKGND
dans CMyView
. Cela n'a pas aidé. Comment puis-je empêcher ce scintillement?
Et à quoi ressemble votre gestionnaire WM_PAINT? –
Peut-être que c'est le problème, je ne gère pas actuellement WM_PAINT. Ai-je besoin d'un double tampon? Si oui, quelle est la bonne façon de le faire dans MFC? – srossd
Vous invalidez la fenêtre principale dans updateVideoScreen, qui va déclencher un WM_PAINT. J'ai supposé que c'est à ce moment-là que l'on écrirait le bitmap à l'écran. –