source: trunk/src/3rdparty/phonon/gstreamer/x11renderer.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 6.1 KB
Line 
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 "videowidget.h"
19#include "x11renderer.h"
20
21#ifndef Q_WS_QWS
22
23#include <QtGui/QPalette>
24#include <QtGui/QApplication>
25#include <QtGui/QPainter>
26#include <X11/Xlib.h>
27#include <gst/gst.h>
28#include <gst/interfaces/xoverlay.h>
29#include <gst/interfaces/propertyprobe.h>
30#include "common.h"
31#include "mediaobject.h"
32#include "message.h"
33
34QT_BEGIN_NAMESPACE
35
36namespace Phonon
37{
38namespace Gstreamer
39{
40
41class OverlayWidget : public QWidget
42{
43public:
44 OverlayWidget(VideoWidget *videoWidget, X11Renderer *renderer) :
45 QWidget(videoWidget),
46 m_videoWidget(videoWidget),
47 m_renderer(renderer) { }
48 void paintEvent(QPaintEvent *) {
49 Phonon::State state = m_videoWidget->root() ? m_videoWidget->root()->state() : Phonon::LoadingState;
50 if (state == Phonon::PlayingState || state == Phonon::PausedState) {
51 m_renderer->windowExposed();
52 } else {
53 QPainter painter(this);
54 painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
55 }
56 }
57private:
58 VideoWidget *m_videoWidget;
59 X11Renderer *m_renderer;
60};
61
62X11Renderer::X11Renderer(VideoWidget *videoWidget)
63 : AbstractRenderer(videoWidget)
64{
65 m_renderWidget = new OverlayWidget(videoWidget, this);
66 videoWidget->backend()->logMessage("Creating X11 overlay renderer");
67 QPalette palette;
68 palette.setColor(QPalette::Background, Qt::black);
69 m_videoWidget->setPalette(palette);
70 m_videoWidget->setAutoFillBackground(true);
71 m_renderWidget->setMouseTracking(true);
72 m_videoSink = createVideoSink();
73 aspectRatioChanged(videoWidget->aspectRatio());
74 setOverlay();
75}
76
77X11Renderer::~X11Renderer()
78{
79 m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, false);
80 m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, false);
81 delete m_renderWidget;
82}
83
84GstElement* X11Renderer::createVideoSink()
85{
86 GstElement *videoSink = gst_element_factory_make ("xvimagesink", NULL);
87 if (videoSink) {
88 // Check if the xv sink is usable
89 if (gst_element_set_state(videoSink, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
90 gst_object_unref(GST_OBJECT(videoSink));
91 videoSink = 0;
92 } else {
93 // Note that this should not really be necessary as these are
94 // default values, though under certain conditions values are retained
95 // even between application instances. (reproducible on 0.10.16/Gutsy)
96 g_object_set(G_OBJECT(videoSink), "brightness", 0, (const char*)NULL);
97 g_object_set(G_OBJECT(videoSink), "contrast", 0, (const char*)NULL);
98 g_object_set(G_OBJECT(videoSink), "hue", 0, (const char*)NULL);
99 g_object_set(G_OBJECT(videoSink), "saturation", 0, (const char*)NULL);
100 }
101 }
102
103 if (!videoSink)
104 videoSink = gst_element_factory_make ("ximagesink", NULL);
105
106 gst_object_ref (GST_OBJECT (videoSink)); //Take ownership
107 gst_object_sink (GST_OBJECT (videoSink));
108
109 return videoSink;
110}
111
112void X11Renderer::handleMediaNodeEvent(const MediaNodeEvent *event)
113{
114 switch (event->type()) {
115 case MediaNodeEvent::SourceChanged:
116 setOverlay(); // We need to do this whenever the pipeline is reset
117 break; // otherwise the videosink will open in its own window
118 default:
119 break;
120 }
121}
122
123
124void X11Renderer::aspectRatioChanged(Phonon::VideoWidget::AspectRatio)
125{
126 if (m_renderWidget) {
127 m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
128 }
129}
130
131void X11Renderer::scaleModeChanged(Phonon::VideoWidget::ScaleMode)
132{
133 if (m_renderWidget) {
134 m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
135 }
136}
137
138void X11Renderer::movieSizeChanged(const QSize &movieSize)
139{
140 Q_UNUSED(movieSize);
141
142 if (m_renderWidget) {
143 m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
144 }
145}
146
147bool X11Renderer::eventFilter(QEvent *e)
148{
149 if (e->type() == QEvent::Show) {
150 // Setting these values ensures smooth resizing since it
151 // will prevent the system from clearing the background
152 m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, true);
153 m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, true);
154 setOverlay();
155 } else if (e->type() == QEvent::Resize) {
156 // This is a workaround for missing background repaints
157 // when reducing window size
158 m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
159 windowExposed();
160 }
161 return false;
162}
163
164void X11Renderer::handlePaint(QPaintEvent *)
165{
166 QPainter painter(m_videoWidget);
167 painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
168}
169
170void X11Renderer::setOverlay()
171{
172 if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
173 WId windowId = m_renderWidget->winId();
174 // Even if we have created a winId at this point, other X applications
175 // need to be aware of it.
176 QApplication::syncX();
177 gst_x_overlay_set_xwindow_id ( GST_X_OVERLAY(m_videoSink) , windowId );
178 }
179 windowExposed();
180 m_overlaySet = true;
181}
182
183void X11Renderer::windowExposed()
184{
185 QApplication::syncX();
186 if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
187 gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
188}
189
190}
191} //namespace Phonon::Gstreamer
192
193QT_END_NAMESPACE
194
195#endif // Q_WS_QWS
Note: See TracBrowser for help on using the repository browser.