src/3rdparty/phonon/gstreamer/x11renderer.cpp
changeset 0 1918ee327afb
child 30 5dc02b23752f
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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 
       
    34 QT_BEGIN_NAMESPACE
       
    35 
       
    36 namespace Phonon
       
    37 {
       
    38 namespace Gstreamer
       
    39 {
       
    40 
       
    41 class OverlayWidget : public QWidget
       
    42 {
       
    43 public:
       
    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     }
       
    57 private:
       
    58     VideoWidget *m_videoWidget;
       
    59     X11Renderer *m_renderer;
       
    60 };
       
    61 
       
    62 X11Renderer::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 
       
    77 X11Renderer::~X11Renderer()
       
    78 {
       
    79     m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, false);
       
    80     m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, false);
       
    81     delete m_renderWidget;
       
    82 }
       
    83 
       
    84 GstElement* 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 neccessary 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 
       
   112 void 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 
       
   124 void X11Renderer::aspectRatioChanged(Phonon::VideoWidget::AspectRatio)
       
   125 {
       
   126     if (m_renderWidget) {
       
   127         m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
       
   128     }
       
   129 }
       
   130 
       
   131 void X11Renderer::scaleModeChanged(Phonon::VideoWidget::ScaleMode)
       
   132 {
       
   133     if (m_renderWidget) {
       
   134         m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
       
   135     }
       
   136 }
       
   137 
       
   138 void X11Renderer::movieSizeChanged(const QSize &movieSize)
       
   139 {
       
   140     Q_UNUSED(movieSize);
       
   141     if (m_renderWidget) {
       
   142         m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
       
   143     }
       
   144 }
       
   145 
       
   146 bool X11Renderer::eventFilter(QEvent *e)
       
   147 {
       
   148     if (e->type() == QEvent::Show) {
       
   149         // Setting these values ensures smooth resizing since it
       
   150         // will prevent the system from clearing the background
       
   151         m_renderWidget->setAttribute(Qt::WA_NoSystemBackground, true);
       
   152         m_renderWidget->setAttribute(Qt::WA_PaintOnScreen, true);
       
   153         setOverlay();
       
   154     } else if (e->type() == QEvent::Resize) {
       
   155         // This is a workaround for missing background repaints
       
   156         // when reducing window size
       
   157         m_renderWidget->setGeometry(m_videoWidget->calculateDrawFrameRect());
       
   158         windowExposed();
       
   159     }
       
   160     return false;
       
   161 }
       
   162 
       
   163 void X11Renderer::handlePaint(QPaintEvent *)
       
   164 {
       
   165     QPainter painter(m_videoWidget);
       
   166     painter.fillRect(m_videoWidget->rect(), m_videoWidget->palette().background());
       
   167 }
       
   168 
       
   169 void X11Renderer::setOverlay()
       
   170 {
       
   171     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
       
   172         WId windowId = m_renderWidget->winId();
       
   173         // Even if we have created a winId at this point, other X applications
       
   174         // need to be aware of it.
       
   175         QApplication::syncX();
       
   176         gst_x_overlay_set_xwindow_id ( GST_X_OVERLAY(m_videoSink) ,  windowId );
       
   177     }
       
   178     windowExposed();
       
   179     m_overlaySet = true;
       
   180 }
       
   181 
       
   182 void X11Renderer::windowExposed()
       
   183 {
       
   184     QApplication::syncX();
       
   185     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
       
   186         gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
       
   187 }
       
   188 
       
   189 }
       
   190 } //namespace Phonon::Gstreamer
       
   191 
       
   192 QT_END_NAMESPACE
       
   193 
       
   194 #endif // Q_WS_QWS