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

Kaleb Pederson kaleb.pederson at gmail.com
Wed Mar 25 23:37:00 CET 2009


On Wed, Mar 25, 2009 at 1:54 PM, Trenton Tuggle <Trent at tuggle.org> wrote:
> Ok...
>
> So in my continuing saga to snag video frames, I'm now simply trying
> to render() a VideoWidget to a QImage and it's not working...  I can't
> seem to trace into the call, but it's certainly not drawing anything
> into the image!

That seems pretty straightforward.  And I'd presume you tested it with
a more simple widget?

> Does anyone know whether or not this *should* succeed?

Not offhand.  If you do an OS-level screen capture using the print
screen button (or Alt-PrintScrn, or Ctrl-PrintScrn) does it capture
the videowidget output when embedded in QGraphicsView, or does it
leave that section of the screen blank?

In looking briefly at the source, an event filter is installed on the
proxy widget, but I didn't see it picking up the paint event, unless I
missed something.

Also, what do you mean you can't seem to trace into the call? As in,
you set a breakpoint in the paint event of something and it doesn't
enter it?  Does it work if you use a standard widget?

Good luck.

--Kaleb

> Thanks in advance!
>
> Trent Tuggle <Trent at Tuggle.Org>
>
> On Mar 24, 2009, at 5:38 PM, Trenton Tuggle wrote:
>
>> 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
>>>>
>>
>> _______________________________________________
>> 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