Results 1 to 4 of 4

Thread: DirectShow VMR9 Drawing on QWidget Subclass Resulting in Repaint Flicker

  1. #1
    Join Date
    Sep 2012
    Posts
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Question DirectShow VMR9 Drawing on QWidget Subclass Resulting in Repaint Flicker

    I apologize in advance if there's a thread lurking somewhere that contains the information I'm looking for. I searched. Honestly, I did.

    I have a QWidget subclass which is meant to be the area where a DirectShow VMR9 draws its video output. The application is working perfectly--all of the DirectShow stuff is wired up happily and the VMR9 is drawing on my QWidget subclass. The problem is that when resizing the window, I'm getting a lot of flicker in the redraw. It looks to me like Qt and DirectShow are having a race during repainting. It looks like Qt is clearing the widget, and then DirectShow is repainting afterward. In my QWidget subclass I have a paintEvent() method something like this:

    Qt Code:
    1. void VideoWidget::paintEvent(QPaintEvent*) {
    2. RECT pos;
    3. pos.top = 0;
    4. pos.left = 0;
    5. pos.bottom = height() - 1;
    6. pos.right = width() - 1;
    7. _impl->vmrWc->SetVideoPosition(NULL, &pos);
    8. HWND hWnd = (HWND) winId();
    9. HDC hDC = GetDC(hWnd);
    10. _impl->vmrWc->RepaintVideo(hWnd, hDC);
    11. }
    To copy to clipboard, switch view to plain text mode 

    "_impl->vmrWc" refers to the IVMRWindowlessControl9 for my VMR9 renderer.

    Is there something I should be doing differently with my QWidget subclass to provoke it to not try to redraw the widget's contents?

    Thanks in advance...
    Michael

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: DirectShow VMR9 Drawing on QWidget Subclass Resulting in Repaint Flicker

    I am not sure if this will help but you could look at the Qt::WA_NoSystemBackground and Qt::WA_OpaquePaintEvent QWidget attribute

    See Transparency and Double Buffering and QWidget::setAttribute())

  3. #3
    Join Date
    Sep 2012
    Posts
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: DirectShow VMR9 Drawing on QWidget Subclass Resulting in Repaint Flicker

    From reading the docs, that really sounds like it should have done the trick. I'm now setting Qt::WA_OpaquePaintEvent in the constructor of my QWidget subclass. That makes the flicker happen in black, instead of in the default widget background color. It looks a tiny bit better, but it's still not right.

    I've also split the work I was doing up into two methods now:

    Qt Code:
    1. void VideoViewer::paintEvent(QPaintEvent*) {
    2. HWND hWnd = (HWND) winId();
    3. HDC hDC = GetDC(hWnd);
    4. _impl->vmrWc->RepaintVideo(hWnd, hDC);
    5. }
    6.  
    7. void VideoViewer::resizeEvent(QResizeEvent*) {
    8. RECT pos;
    9. pos.top = 0;
    10. pos.left = 0;
    11. pos.bottom = height() - 1;
    12. pos.right = width() - 1;
    13. _impl->vmrWc->SetVideoPosition(NULL, &pos);
    14. }
    To copy to clipboard, switch view to plain text mode 

    From reading the DirectShow docs, it seems like something is going on with the windows messages, and possibly causing DirectShow to think it needs to repaint more than it should?

    This code is being ported from wxWidgets--things worked well there. I have a feeling it's got to be something minor and silly.

  4. #4
    Join Date
    Sep 2012
    Posts
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: DirectShow VMR9 Drawing on QWidget Subclass Resulting in Repaint Flicker

    Ok... I managed to get this sorted out.

    in my QWidget subclass, I had to override the QWidget::paintEngine method to return NULL. I also had to set the following widget properties:

    Qt Code:
    1. setAttribute(Qt::WA_OpaquePaintEvent, true);
    2. setAttribute(Qt::WA_NoSystemBackground, true);
    3. setAttribute(Qt::WA_PaintOnScreen, true);
    4. setAutoFillBackground(false);
    To copy to clipboard, switch view to plain text mode 

    I also adjusted my calls to the IVMRWindowlessControl9 like the following:

    Qt Code:
    1. void WindowsVideoViewer::paintEvent(QPaintEvent*) {
    2. HWND hWnd = (HWND) winId();
    3. HDC hDC = GetDC(hWnd);
    4. _impl->vmrWc->RepaintVideo(hWnd, hDC);
    5. }
    6.  
    7. void WindowsVideoViewer::resizeEvent(QResizeEvent*) {
    8. RECT pos;
    9. pos.top = 0;
    10. pos.left = 0;
    11. pos.bottom = height();
    12. pos.right = width();
    13. _impl->vmrWc->SetVideoPosition(NULL, &pos);
    14. }
    To copy to clipboard, switch view to plain text mode 

    Everything seems happy now.

    Ok... I managed to get this sorted out.

    in my QWidget subclass, I had to override the QWidget::paintEngine method to return NULL. I also had to set the following widget properties:

    Qt Code:
    1. setAttribute(Qt::WA_OpaquePaintEvent, true);
    2. setAttribute(Qt::WA_NoSystemBackground, true);
    3. setAttribute(Qt::WA_PaintOnScreen, true);
    4. setAutoFillBackground(false);
    To copy to clipboard, switch view to plain text mode 

    I also adjusted my calls to the IVMRWindowlessControl9 like the following:

    Qt Code:
    1. void WindowsVideoViewer::paintEvent(QPaintEvent*) {
    2. HWND hWnd = (HWND) winId();
    3. HDC hDC = GetDC(hWnd);
    4. _impl->vmrWc->RepaintVideo(hWnd, hDC);
    5. }
    6.  
    7. void WindowsVideoViewer::resizeEvent(QResizeEvent*) {
    8. RECT pos;
    9. pos.top = 0;
    10. pos.left = 0;
    11. pos.bottom = height();
    12. pos.right = width();
    13. _impl->vmrWc->SetVideoPosition(NULL, &pos);
    14. }
    To copy to clipboard, switch view to plain text mode 

    Everything seems happy now.


    Added after 5 minutes:


    ChrisW67's tips pointed me in the right direction, but the chunk of code that pushed it over the edge was in the Qt 4.8 source distribution at the location:

    Qt Code:
    1. qt-everywhere-opensource-src-4.8.3/src/3rdparty/phonon/ds9
    To copy to clipboard, switch view to plain text mode 

    Specifically, the VideoWidget class.
    Last edited by MichaelQuigley; 25th September 2012 at 20:11.

Similar Threads

  1. VMR9 (DirectShow) Windowless and QAxWidget
    By Tabgok in forum Qt Programming
    Replies: 2
    Last Post: 20th July 2011, 15:25
  2. When is the geometry of a QWidget subclass set?
    By Luc4 in forum Qt Programming
    Replies: 3
    Last Post: 3rd May 2011, 21:14
  3. Replies: 4
    Last Post: 17th January 2011, 13:05
  4. Replies: 4
    Last Post: 17th October 2010, 22:30
  5. x11,about qwidget::repaint()
    By calmspeaker in forum Qt Programming
    Replies: 7
    Last Post: 9th December 2009, 06:50

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.