qtmobility/src/multimedia/qvideowidget.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
--- a/qtmobility/src/multimedia/qvideowidget.cpp	Fri Jun 11 14:26:25 2010 +0300
+++ b/qtmobility/src/multimedia/qvideowidget.cpp	Wed Jun 23 19:08:38 2010 +0300
@@ -41,15 +41,14 @@
 
 #include "qvideowidget_p.h"
 
-#include "qmediaobject.h"
-#include "qmediaservice.h"
-#include "qvideooutputcontrol.h"
-#include "qvideowindowcontrol.h"
-#include "qvideowidgetcontrol.h"
+#include <qmediaobject.h>
+#include <qmediaservice.h>
+#include <qvideowindowcontrol.h>
+#include <qvideowidgetcontrol.h>
 
-#include "qpaintervideosurface_p.h"
-#include "qvideorenderercontrol.h"
-#include <QtMultimedia/qvideosurfaceformat.h>
+#include <qpaintervideosurface_p.h>
+#include <qvideorenderercontrol.h>
+#include <qvideosurfaceformat.h>
 #include <qpainter.h>
 
 #include <qapplication.h>
@@ -63,8 +62,9 @@
 QT_BEGIN_NAMESPACE
 
 QVideoWidgetControlBackend::QVideoWidgetControlBackend(
-        QVideoWidgetControl *control, QWidget *widget)
-    : m_widgetControl(control)
+        QMediaService *service, QVideoWidgetControl *control, QWidget *widget)
+    : m_service(service)
+    , m_widgetControl(control)
 {
     connect(control, SIGNAL(brightnessChanged(int)), widget, SLOT(_q_brightnessChanged(int)));
     connect(control, SIGNAL(contrastChanged(int)), widget, SLOT(_q_contrastChanged(int)));
@@ -80,6 +80,11 @@
     widget->setLayout(layout);
 }
 
+void QVideoWidgetControlBackend::releaseControl()
+{
+    m_service->releaseControl(m_widgetControl);
+}
+
 void QVideoWidgetControlBackend::setBrightness(int brightness)
 {
     m_widgetControl->setBrightness(brightness);
@@ -117,8 +122,9 @@
 }
 
 QRendererVideoWidgetBackend::QRendererVideoWidgetBackend(
-        QVideoRendererControl *control, QWidget *widget)
-    : m_rendererControl(control)
+        QMediaService *service, QVideoRendererControl *control, QWidget *widget)
+    : m_service(service)
+    , m_rendererControl(control)
     , m_widget(widget)
     , m_surface(new QPainterVideoSurface)
     , m_aspectRatioMode(Qt::KeepAspectRatio)
@@ -140,6 +146,11 @@
     delete m_surface;
 }
 
+void QRendererVideoWidgetBackend::releaseControl()
+{
+    m_service->releaseControl(m_rendererControl);
+}
+
 void QRendererVideoWidgetBackend::clearSurface()
 {
     m_rendererControl->setSurface(0);
@@ -297,8 +308,10 @@
     }
 }
 
-QWindowVideoWidgetBackend::QWindowVideoWidgetBackend(QVideoWindowControl *control, QWidget *widget)
-    : m_windowControl(control)
+QWindowVideoWidgetBackend::QWindowVideoWidgetBackend(
+        QMediaService *service, QVideoWindowControl *control, QWidget *widget)
+    : m_service(service)
+    , m_windowControl(control)
     , m_widget(widget)
     , m_aspectRatioMode(Qt::KeepAspectRatio)
 {
@@ -314,6 +327,11 @@
 {
 }
 
+void QWindowVideoWidgetBackend::releaseControl()
+{
+    m_service->releaseControl(m_windowControl);
+}
+
 void QWindowVideoWidgetBackend::setBrightness(int brightness)
 {
     m_windowControl->setBrightness(brightness);
@@ -401,37 +419,11 @@
     }
 }
 
-void QVideoWidgetPrivate::show()
-{
-    if (outputControl) {
-        if (widgetBackend != 0) {
-            setCurrentControl(widgetBackend);
-            outputControl->setOutput(QVideoOutputControl::WidgetOutput);
-        } else if (windowBackend != 0 && (q_func()->window() == 0
-                || !q_func()->window()->testAttribute(Qt::WA_DontShowOnScreen))) {
-            windowBackend->showEvent();
-            currentBackend = windowBackend;
-            setCurrentControl(windowBackend);
-            outputControl->setOutput(QVideoOutputControl::WindowOutput);
-        } else if (rendererBackend != 0) {
-            rendererBackend->showEvent();
-            currentBackend = rendererBackend;
-            setCurrentControl(rendererBackend);
-            outputControl->setOutput(QVideoOutputControl::RendererOutput);
-        } else {
-            outputControl->setOutput(QVideoOutputControl::NoOutput);
-        }
-    }
-}
-
 void QVideoWidgetPrivate::clearService()
 {
     if (service) {
         QObject::disconnect(service, SIGNAL(destroyed()), q_func(), SLOT(_q_serviceDestroyed()));
 
-        if (outputControl)
-            outputControl->setOutput(QVideoOutputControl::NoOutput);
-
         if (widgetBackend) {
             QLayout *layout = q_func()->layout();
 
@@ -441,54 +433,93 @@
             }
             delete layout;
 
+            widgetBackend->releaseControl();
+
             delete widgetBackend;
             widgetBackend = 0;
-        }
-
-        delete windowBackend;
-        windowBackend = 0;
-
-        if (rendererBackend) {
+        } else if (rendererBackend) {
             rendererBackend->clearSurface();
+            rendererBackend->releaseControl();
 
             delete rendererBackend;
             rendererBackend = 0;
+        } else {
+            windowBackend->releaseControl();
+
+            delete windowBackend;
+            windowBackend = 0;
         }
 
         currentBackend = 0;
         currentControl = 0;
-        outputControl = 0;
         service = 0;
     }
 }
 
+bool QVideoWidgetPrivate::createWidgetBackend()
+{
+    if (QMediaControl *control = service->requestControl(QVideoWidgetControl_iid)) {
+        if (QVideoWidgetControl *widgetControl = qobject_cast<QVideoWidgetControl *>(control)) {
+            widgetBackend = new QVideoWidgetControlBackend(service, widgetControl, q_func());
+
+            setCurrentControl(widgetBackend);
+
+            return true;
+        }
+        service->releaseControl(control);
+    }
+    return false;
+}
+
+bool QVideoWidgetPrivate::createWindowBackend()
+{
+    if (QMediaControl *control = service->requestControl(QVideoWindowControl_iid)) {
+        if (QVideoWindowControl *windowControl = qobject_cast<QVideoWindowControl *>(control)) {
+            windowBackend = new QWindowVideoWidgetBackend(service, windowControl, q_func());
+            currentBackend = windowBackend;
+
+            setCurrentControl(windowBackend);
+
+            return true;
+        }
+        service->releaseControl(control);
+    }
+    return false;
+}
+
+bool QVideoWidgetPrivate::createRendererBackend()
+{
+    if (QMediaControl *control = service->requestControl(QVideoRendererControl_iid)) {
+        if (QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>(control)) {
+            rendererBackend = new QRendererVideoWidgetBackend(service, rendererControl, q_func());
+            currentBackend = rendererBackend;
+
+            setCurrentControl(rendererBackend);
+
+            return true;
+        }
+        service->releaseControl(control);
+    }
+    return false;
+}
+
 void QVideoWidgetPrivate::_q_serviceDestroyed()
 {
-    if (widgetBackend) {
+    if (widgetBackend)
         delete q_func()->layout();
 
-        delete widgetBackend;
-        widgetBackend = 0;
-    }
-
+    delete widgetBackend;
     delete windowBackend;
-    windowBackend = 0;
+    delete rendererBackend;
 
-    delete rendererBackend;
+    widgetBackend = 0;
+    windowBackend = 0;
     rendererBackend = 0;
-
     currentControl = 0;
     currentBackend = 0;
-    outputControl = 0;
     service = 0;
 }
 
-void QVideoWidgetPrivate::_q_mediaObjectDestroyed()
-{
-    mediaObject = 0;
-    clearService();
-}
-
 void QVideoWidgetPrivate::_q_brightnessChanged(int b)
 {
     if (b != brightness)
@@ -542,9 +573,10 @@
     \code
         player = new QMediaPlayer;
 
-        widget = new QVideoWidget(player);
+        widget = new QVideoWidget;
         widget->show();
 
+        player->setVideoOutput(widget);
         player->setMedia(QUrl("http://example.com/movie.mp4"));
         player->play();
     \endcode
@@ -572,7 +604,8 @@
 */
 QVideoWidget::~QVideoWidget()
 {
-    setMediaObject(0);
+    d_ptr->clearService();
+
     delete d_ptr;
 }
 
@@ -586,57 +619,45 @@
     return d_func()->mediaObject;
 }
 
-void QVideoWidget::setMediaObject(QMediaObject *object)
+bool QVideoWidget::setMediaObject(QMediaObject *object)
 {
     Q_D(QVideoWidget);
 
     if (object == d->mediaObject)
-        return;
-
-    if (d->mediaObject) {
-        disconnect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed()));
-        d->mediaObject->unbind(this);
-    }
+        return true;
 
     d->clearService();
 
     d->mediaObject = object;
 
-    if (d->mediaObject) {
+    if (d->mediaObject)
         d->service = d->mediaObject->service();
 
-        connect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed()));
-        d->mediaObject->bind(this);
-    }
-
     if (d->service) {
-        connect(d->service, SIGNAL(destroyed()), SLOT(_q_serviceDestroyed()));
-
-        d->outputControl = qobject_cast<QVideoOutputControl *>(
-                d->service->control(QVideoOutputControl_iid));
-
-        QVideoWidgetControl *widgetControl = qobject_cast<QVideoWidgetControl *>(
-                d->service->control(QVideoWidgetControl_iid));
-
-        if (widgetControl != 0) {
-            d->widgetBackend = new QVideoWidgetControlBackend(widgetControl, this);
+        if (d->createWidgetBackend()) {
+            // Nothing to do here.
+        } else if ((!window() || !window()->testAttribute(Qt::WA_DontShowOnScreen))
+                && d->createWindowBackend()) {
+            if (isVisible())
+                d->windowBackend->showEvent();
+        } else if (d->createRendererBackend()) {
+            if (isVisible())
+                d->rendererBackend->showEvent();
         } else {
-            QVideoWindowControl *windowControl = qobject_cast<QVideoWindowControl *>(
-                    d->service->control(QVideoWindowControl_iid));
-
-            if (windowControl != 0)
-                d->windowBackend = new QWindowVideoWidgetBackend(windowControl, this);
+            d->service = 0;
+            d->mediaObject = 0;
 
-            QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>(
-                    d->service->control(QVideoRendererControl_iid));
-
-            if (rendererControl != 0)
-                d->rendererBackend = new QRendererVideoWidgetBackend(rendererControl, this);
+            return false;
         }
 
-        if (isVisible())
-            d->show();
+        connect(d->service, SIGNAL(destroyed()), SLOT(_q_serviceDestroyed()));
+    } else {
+        d->mediaObject = 0;
+
+        return false;
     }
+
+    return true;
 }
 
 /*!
@@ -880,8 +901,18 @@
 
     QWidget::showEvent(event);
 
-    d->show();
+    // The window backend won't work for re-directed windows so use the renderer backend instead.
+    if (d->windowBackend && window()->testAttribute(Qt::WA_DontShowOnScreen)) {
+        d->windowBackend->releaseControl();
 
+        delete d->windowBackend;
+        d->windowBackend = 0;
+
+        d->createRendererBackend();
+    }
+
+    if (d->currentBackend)
+        d->currentBackend->showEvent();
 }
 
 /*!