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