[Qt-interest] Intercepting Phonon VideoWidget frames as they are pushed

Trenton Tuggle Trent at tuggle.org
Tue Mar 24 22:38:21 CET 2009


On Mar 24, 2009, at 4:02 PM, Kaleb Pederson wrote:

> On Tuesday 24 March 2009 11:50:56 am Trenton Tuggle wrote:
>> Interesting update...
>>
>> I've been unable to "capture" VideoWidget paint events at all -- it
>> appears as if it somehow gets drawn outside of a PaintEvent -- but  
>> how
>> could it then be captured and redirected onto a
>> QGraphicsViewProxyWidget?
>
> Wouldn't you really need a proxy QPaintDevice?  The QPaintDevice  
> could then render onto whatever it wanted.
>
> Please let us know how it goes.


Kaleb, thanks for the thoughts!  I'm trying to use a QImage as my proxy.

What I've tried to create is a QWidget subclass which draws to a  
QImage, then emits a signal signifying the update.

The primary methods I'm trying are capturing PaintEvents, and  
overloading the paintEngine().  Neither technique seems to be working  
-- I know this because my image never gets updated and PaintEvents  
never get seen.

Note that my only test case is trying to capture a  
Phonon::VideoWidget, so I suppose a possibility is that I'm doing the  
right things, but VideoWidget somehow bypasses normal stuff for  
performance purposes.  I've been looking through the Phonon backend  
(Quicktime) code, but it's not apparent how drawing is performed.

Here's my code:

class WidgetImager
     : public QWidget
{
     Q_OBJECT

public:
     WidgetImager(QWidget *parent = 0, Qt::WindowFlags f = 0);
     virtual ~WidgetImager();

     QImage *image();

signals:
     void updated();

protected:
     virtual QPaintEngine * paintEngine () const;
     virtual bool event(QEvent *event);
     virtual void paintEvent(QPaintEvent *event);
     virtual void resizeEvent(QResizeEvent *event);

private:
     QImage* image_;
};


WidgetImager::WidgetImager(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
     setAttribute(Qt::WA_PaintOnScreen);
     setAttribute(Qt::WA_NoSystemBackground);
     setAttribute(Qt::WA_OpaquePaintEvent, true);

     image_ = new QImage(size(), QImage::Format_RGB32);
}

WidgetImager::~WidgetImager()
{
     delete image_;
}

QImage *WidgetImager::image()
{
     return image_;
}

bool WidgetImager::event(QEvent *event)
{
     if (event->type() == QEvent::Paint)
     {
         //Make sure all paint operations redirect here
         QPainter::setRedirected(this, image_);
         bool accept = QWidget::event(event);

         // Notify clients of the update
         emit updated();

         return accept;
     }

     return QWidget::event(event);
}

void WidgetImager::paintEvent(QPaintEvent *event)
{
     Q_UNUSED(event);
}

void WidgetImager::resizeEvent(QResizeEvent *event)
{
     QWidget::resizeEvent(event);

     delete image_;
     image_ = new QImage(event->size(), QImage::Format_RGB32);
}

QPaintEngine * WidgetImager::paintEngine () const
{
     // Try using the image's painter to capture updates
     return image_->paintEngine();
}


> --Kaleb
>
>> What's the mechanism that QGraphicsViewProxyWidget uses to "capture"
>> the paint events of its children and "redirect" them to be drawn on
>> the appropriate Graphics View/Scene?
>>
>> Thanks in advance for any pointers...
>>
>> -Trent Tuggle <Trent at Tuggle.Org>
>>
>>
>> On Mar 21, 2009, at 11:39 AM, Trenton Tuggle wrote:
>>
>>> I have an interesting challenge I've been working on:
>>>
>>> I'm working on video processing, and am investigating using Phonon  
>>> for
>>> platform-independent back-ends.
>>>
>>> My interest is not the usual, though -- I have little interest in
>>> showing the video on-screen (although that would be nice, also) but
>>> primarily, I'm interested in obtaining the video frames.
>>>
>>> Now I know it's easy to render() a widget (such as VideoWidget)  
>>> onto a
>>> pixmap or other, but I'm really interested in obtaining the frames  
>>> in
>>> a more automated way -- such as getting a signal when the next frame
>>> is ready, etc.  My thought is that since VideoWidget can be embedded
>>> in a graphics scene, it must be possible to intercept its painting
>>> events and redirect it to a qimage or something: but so far I've
>>> failed.
>>>
>>> So that's my question: how can I embed a VideoWidget in something  
>>> that
>>> can intercept paint events, redirect them to a QImage, then signal a
>>> processor that a frame is ready for processing?
>>>
>>> I've tried stuff along these lines:
>>>
>>> http://www.kdedevelopers.org/node/3644
>>>
>>> The thought was that I'll create a Phonon path to play on a
>>> VideoWidget embedded in something like that which would capture the
>>> frame, then signal my processor....
>>>
>>> But so far, I've been unable to get the widget I create to receive  
>>> any
>>> paint events, or intercept anything at all -- it doesn't even get
>>> resized properly when a video is loaded!
>>>
>>> If anyone has any advice or input on this, I'd really appreciate it!
>>>
>>> Thanks in advance!
>>>
>>> Trent Tuggle <Trent at Tuggle.Org>
>>> _______________________________________________
>>> Qt-interest mailing list
>>> Qt-interest at trolltech.com
>>> http://lists.trolltech.com/mailman/listinfo/qt-interest
>>
>> _______________________________________________
>> Qt-interest mailing list
>> Qt-interest at trolltech.com
>> http://lists.trolltech.com/mailman/listinfo/qt-interest
>>




More information about the Qt-interest-old mailing list