summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon/gstreamer/x11renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/phonon/gstreamer/x11renderer.cpp')
-rw-r--r--src/3rdparty/phonon/gstreamer/x11renderer.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/3rdparty/phonon/gstreamer/x11renderer.cpp b/src/3rdparty/phonon/gstreamer/x11renderer.cpp
new file mode 100644
index 0000000..73877a8
--- /dev/null
+++ b/src/3rdparty/phonon/gstreamer/x11renderer.cpp
@@ -0,0 +1,194 @@
+/* This file is part of the KDE project.
+
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+ This library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 or 3 of the License.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "videowidget.h"
+#include "x11renderer.h"
+
+#ifndef Q_WS_QWS
+
+#include <QtGui/QPalette>
+#include <QtGui/QApplication>
+#include <QtGui/QPainter>
+#include <X11/Xlib.h>
+#include <gst/gst.h>
+#include <gst/interfaces/xoverlay.h>
+#include <gst/interfaces/propertyprobe.h>
+#include "common.h"
+#include "mediaobject.h"
+#include "message.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace Gstreamer
+{
+
+class OverlayWidget : public QWidget
+{
+public:
+ OverlayWidget(VideoWidget *videoWidget, X11Renderer *renderer) :
+ QWidget(videoWidget),
+ m_videoWidget(videoWidget),
+ m_renderer(renderer) { }
+ void paintEvent(QPaintEvent *) {
+ Phonon::State state = m_videoWidget->root() ? m_videoWidget->root()->state() : Phonon::LoadingState;
+ if (state == Phonon::PlayingState || state == Phonon::PausedState) {
+ m_renderer->windowExposed();
+ } else {
+ QPainter painter(this);
+ painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
+ }
+ }
+private:
+ VideoWidget *m_videoWidget;
+ X11Renderer *m_renderer;
+};
+
+X11Renderer::X11Renderer(VideoWidget *videoWidget)
+ : AbstractRenderer(videoWidget)
+{
+ m_renderWidget = new OverlayWidget(videoWidget, this);
+ videoWidget->backend()->logMessage("Creating X11 overlay renderer");
+ QPalette palette;
+ palette.setColor(QPalette::Background, Qt::black);
+ m_videoWidget->setPalette(palette);
+ m_videoWidget->setAutoFillBackground(true);
+ m_renderWidget->setMouseTracking(true);
+ m_videoSink = createVideoSink();
+ aspectRatioChanged(videoWidget->aspectRatio());
+ setOverlay();
+}
+
+X11Renderer::~X11Renderer()
+{
+ m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, false);
+ m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, false);
+ delete m_renderWidget;
+}
+
+GstElement* X11Renderer::createVideoSink()
+{
+ GstElement *videoSink = gst_element_factory_make ("xvimagesink", NULL);
+ if (videoSink) {
+ // Check if the xv sink is usable
+ if (gst_element_set_state(videoSink, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
+ gst_object_unref(GST_OBJECT(videoSink));
+ videoSink = 0;
+ } else {
+ // Note that this should not really be neccessary as these are
+ // default values, though under certain conditions values are retained
+ // even between application instances. (reproducible on 0.10.16/Gutsy)
+ g_object_set(G_OBJECT(videoSink), "brightness", 0, (const char*)NULL);
+ g_object_set(G_OBJECT(videoSink), "contrast", 0, (const char*)NULL);
+ g_object_set(G_OBJECT(videoSink), "hue", 0, (const char*)NULL);
+ g_object_set(G_OBJECT(videoSink), "saturation", 0, (const char*)NULL);
+ }
+ }
+
+ if (!videoSink)
+ videoSink = gst_element_factory_make ("ximagesink", NULL);
+
+ gst_object_ref (GST_OBJECT (videoSink)); //Take ownership
+ gst_object_sink (GST_OBJECT (videoSink));
+
+ return videoSink;
+}
+
+void X11Renderer::handleMediaNodeEvent(const MediaNodeEvent *event)
+{
+ switch (event->type()) {
+ case MediaNodeEvent::SourceChanged:
+ setOverlay(); // We need to do this whenever the pipeline is reset
+ break; // otherwise the videosink will open in its own window
+ default:
+ break;
+ }
+}
+
+
+void X11Renderer::aspectRatioChanged(Phonon::VideoWidget::AspectRatio)
+{
+ if (m_renderWidget) {
+ m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
+ }
+}
+
+void X11Renderer::scaleModeChanged(Phonon::VideoWidget::ScaleMode)
+{
+ if (m_renderWidget) {
+ m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
+ }
+}
+
+void X11Renderer::movieSizeChanged(const QSize &movieSize)
+{
+ Q_UNUSED(movieSize);
+ if (m_renderWidget) {
+ m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
+ }
+}
+
+bool X11Renderer::eventFilter(QEvent *e)
+{
+ if (e->type() == QEvent::Show) {
+ // Setting these values ensures smooth resizing since it
+ // will prevent the system from clearing the background
+ m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, true);
+ m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, true);
+ setOverlay();
+ } else if (e->type() == QEvent::Resize) {
+ // This is a workaround for missing background repaints
+ // when reducing window size
+ m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
+ windowExposed();
+ }
+ return false;
+}
+
+void X11Renderer::handlePaint(QPaintEvent *)
+{
+ QPainter painter(m_videoWidget);
+ painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
+}
+
+void X11Renderer::setOverlay()
+{
+ if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+ WId windowId = m_renderWidget->winId();
+ // Even if we have created a winId at this point, other X applications
+ // need to be aware of it.
+ QApplication::syncX();
+ gst_x_overlay_set_xwindow_id ( GST_X_OVERLAY(m_videoSink) , windowId );
+ }
+ windowExposed();
+ m_overlaySet = true;
+}
+
+void X11Renderer::windowExposed()
+{
+ QApplication::syncX();
+ if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
+ gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
+}
+
+}
+} //namespace Phonon::Gstreamer
+
+QT_END_NAMESPACE
+
+#endif // Q_WS_QWS