1 /*  This file is part of the KDE project.
2 
3     Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 
5     This library is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Lesser General Public License as published by
7     the Free Software Foundation, either version 2.1 or 3 of the License.
8 
9     This library is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU Lesser General Public License for more details.
13 
14     You should have received a copy of the GNU Lesser General Public License
15     along with this library.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include <QtGui/QPainter>
19 #include <gst/gst.h>
20 #include "common.h"
21 #include "message.h"
22 #include "mediaobject.h"
23 #include "qwidgetvideosink.h"
24 #include "widgetrenderer.h"
25 #include "qrgb.h"
26 
27 // support old OpenGL installations (1.2)
28 // assume that if TEXTURE0 isn't defined, none are
29 #ifndef GL_TEXTURE0
30 # define GL_TEXTURE0    0x84C0
31 # define GL_TEXTURE1    0x84C1
32 # define GL_TEXTURE2    0x84C2
33 #endif
34 
35 #ifndef QT_NO_PHONON_VIDEO
36 QT_BEGIN_NAMESPACE
37 
frameRendered()38 static void frameRendered()
39 {
40     static QString displayFps = qgetenv("PHONON_GST_FPS");
41     if (displayFps.isEmpty())
42         return;
43 
44     static int frames = 0;
45     static QTime lastTime = QTime::currentTime();
46     QTime time = QTime::currentTime();
47 
48     int delta = lastTime.msecsTo(time);
49     if (delta > 2000) {
50         printf("FPS: %f\n", 1000.0 * frames / qreal(delta));
51         lastTime = time;
52         frames = 0;
53     }
54 
55     ++frames;
56 }
57 
58 namespace Phonon
59 {
60 namespace Gstreamer
61 {
62 
WidgetRenderer(VideoWidget * videoWidget)63 WidgetRenderer::WidgetRenderer(VideoWidget *videoWidget)
64         : AbstractRenderer(videoWidget)
65         , m_width(0)
66         , m_height(0)
67 {
68     videoWidget->backend()->logMessage("Creating QWidget renderer");
69     if ((m_videoSink = GST_ELEMENT(g_object_new(get_type_RGB(), NULL)))) {
70         gst_object_ref (GST_OBJECT (m_videoSink)); //Take ownership
71         gst_object_sink (GST_OBJECT (m_videoSink));
72 
73         QWidgetVideoSinkBase*  sink = reinterpret_cast<QWidgetVideoSinkBase*>(m_videoSink);
74         // Let the videosink know which widget to direct frame updates to
75         sink->renderWidget = videoWidget;
76     }
77 
78     // Clear the background with black by default
79     QPalette palette;
80     palette.setColor(QPalette::Background, Qt::black);
81     m_videoWidget->setPalette(palette);
82     m_videoWidget->setAutoFillBackground(true);
83     m_videoWidget->setAttribute(Qt::WA_NoSystemBackground, false);
84     m_videoWidget->setAttribute(Qt::WA_PaintOnScreen, false);
85 }
86 
setNextFrame(const QByteArray & array,int w,int h)87 void WidgetRenderer::setNextFrame(const QByteArray &array, int w, int h)
88 {
89     if (m_videoWidget->root()->state() == Phonon::LoadingState)
90         return;
91 
92     m_frame = QImage();
93     {
94         m_frame = QImage((uchar *)array.constData(), w, h, QImage::Format_RGB32);
95     }
96 
97     m_array = array;
98     m_width = w;
99     m_height = h;
100 
101     m_videoWidget->update();
102 }
103 
handleMediaNodeEvent(const MediaNodeEvent * event)104 void WidgetRenderer::handleMediaNodeEvent(const MediaNodeEvent *event)
105 {
106     switch (event->type()) {
107     case MediaNodeEvent::SourceChanged:
108     {
109         clearFrame();
110         break;
111     }
112     default:
113         break;
114     }
115 }
116 
clearFrame()117 void WidgetRenderer::clearFrame()
118 {
119     m_frame = QImage();
120     m_array = QByteArray();
121     m_videoWidget->update();
122 }
123 
currentFrame() const124 const QImage &WidgetRenderer::currentFrame() const
125 {
126     return m_frame;
127 }
128 
handlePaint(QPaintEvent * event)129 void WidgetRenderer::handlePaint(QPaintEvent *event)
130 {
131     Q_UNUSED(event);
132     QPainter painter(m_videoWidget);
133     m_drawFrameRect = m_videoWidget->calculateDrawFrameRect();
134     painter.drawImage(drawFrameRect(), currentFrame());
135     frameRendered();
136 }
137 
eventFilter(QEvent * event)138 bool WidgetRenderer::eventFilter(QEvent * event)
139 {
140     if (event->type() == QEvent::User) {
141         NewFrameEvent *frameEvent= static_cast <NewFrameEvent *>(event);
142         setNextFrame(frameEvent->frame, frameEvent->width, frameEvent->height);
143         return true;
144     }
145     return false;
146 }
147 
148 }
149 } //namespace Phonon::Gstreamer
150 
151 QT_END_NAMESPACE
152 #endif //QT_NO_PHONON_VIDEO
153