src/multimedia/qvideowidget.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qvideowidget_p.h"
       
    43 
       
    44 #include <qmediaobject.h>
       
    45 #include <qmediaservice.h>
       
    46 #include <qvideowindowcontrol.h>
       
    47 #include <qvideowidgetcontrol.h>
       
    48 
       
    49 #include <qpaintervideosurface_p.h>
       
    50 #include <qvideorenderercontrol.h>
       
    51 #include <qvideosurfaceformat.h>
       
    52 #include <qpainter.h>
       
    53 
       
    54 #include <qapplication.h>
       
    55 #include <qevent.h>
       
    56 #include <qdialog.h>
       
    57 #include <qboxlayout.h>
       
    58 #include <qnamespace.h>
       
    59 
       
    60 using namespace Qt;
       
    61 
       
    62 QT_BEGIN_NAMESPACE
       
    63 
       
    64 QVideoWidgetControlBackend::QVideoWidgetControlBackend(
       
    65         QMediaService *service, QVideoWidgetControl *control, QWidget *widget)
       
    66     : m_service(service)
       
    67     , m_widgetControl(control)
       
    68 {
       
    69     connect(control, SIGNAL(brightnessChanged(int)), widget, SLOT(_q_brightnessChanged(int)));
       
    70     connect(control, SIGNAL(contrastChanged(int)), widget, SLOT(_q_contrastChanged(int)));
       
    71     connect(control, SIGNAL(hueChanged(int)), widget, SLOT(_q_hueChanged(int)));
       
    72     connect(control, SIGNAL(saturationChanged(int)), widget, SLOT(_q_saturationChanged(int)));
       
    73     connect(control, SIGNAL(fullScreenChanged(bool)), widget, SLOT(_q_fullScreenChanged(bool)));
       
    74 
       
    75     QBoxLayout *layout = new QVBoxLayout;
       
    76     layout->setMargin(0);
       
    77     layout->setSpacing(0);
       
    78     layout->addWidget(control->videoWidget());
       
    79 
       
    80     widget->setLayout(layout);
       
    81 }
       
    82 
       
    83 void QVideoWidgetControlBackend::releaseControl()
       
    84 {
       
    85     m_service->releaseControl(m_widgetControl);
       
    86 }
       
    87 
       
    88 void QVideoWidgetControlBackend::setBrightness(int brightness)
       
    89 {
       
    90     m_widgetControl->setBrightness(brightness);
       
    91 }
       
    92 
       
    93 void QVideoWidgetControlBackend::setContrast(int contrast)
       
    94 {
       
    95     m_widgetControl->setContrast(contrast);
       
    96 }
       
    97 
       
    98 void QVideoWidgetControlBackend::setHue(int hue)
       
    99 {
       
   100     m_widgetControl->setHue(hue);
       
   101 }
       
   102 
       
   103 void QVideoWidgetControlBackend::setSaturation(int saturation)
       
   104 {
       
   105     m_widgetControl->setSaturation(saturation);
       
   106 }
       
   107 
       
   108 void QVideoWidgetControlBackend::setFullScreen(bool fullScreen)
       
   109 {
       
   110     m_widgetControl->setFullScreen(fullScreen);
       
   111 }
       
   112 
       
   113 
       
   114 Qt::AspectRatioMode QVideoWidgetControlBackend::aspectRatioMode() const
       
   115 {
       
   116     return m_widgetControl->aspectRatioMode();
       
   117 }
       
   118 
       
   119 void QVideoWidgetControlBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
       
   120 {
       
   121     m_widgetControl->setAspectRatioMode(mode);
       
   122 }
       
   123 
       
   124 QRendererVideoWidgetBackend::QRendererVideoWidgetBackend(
       
   125         QMediaService *service, QVideoRendererControl *control, QWidget *widget)
       
   126     : m_service(service)
       
   127     , m_rendererControl(control)
       
   128     , m_widget(widget)
       
   129     , m_surface(new QPainterVideoSurface)
       
   130     , m_aspectRatioMode(Qt::KeepAspectRatio)
       
   131     , m_updatePaintDevice(true)
       
   132 {
       
   133     connect(this, SIGNAL(brightnessChanged(int)), m_widget, SLOT(_q_brightnessChanged(int)));
       
   134     connect(this, SIGNAL(contrastChanged(int)), m_widget, SLOT(_q_contrastChanged(int)));
       
   135     connect(this, SIGNAL(hueChanged(int)), m_widget, SLOT(_q_hueChanged(int)));
       
   136     connect(this, SIGNAL(saturationChanged(int)), m_widget, SLOT(_q_saturationChanged(int)));
       
   137     connect(m_surface, SIGNAL(frameChanged()), this, SLOT(frameChanged()));
       
   138     connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
       
   139             this, SLOT(formatChanged(QVideoSurfaceFormat)));
       
   140 
       
   141     m_rendererControl->setSurface(m_surface);
       
   142 }
       
   143 
       
   144 QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend()
       
   145 {
       
   146     delete m_surface;
       
   147 }
       
   148 
       
   149 void QRendererVideoWidgetBackend::releaseControl()
       
   150 {
       
   151     m_service->releaseControl(m_rendererControl);
       
   152 }
       
   153 
       
   154 void QRendererVideoWidgetBackend::clearSurface()
       
   155 {
       
   156     m_rendererControl->setSurface(0);
       
   157 }
       
   158 
       
   159 void QRendererVideoWidgetBackend::setBrightness(int brightness)
       
   160 {
       
   161     m_surface->setBrightness(brightness);
       
   162 
       
   163     emit brightnessChanged(brightness);
       
   164 }
       
   165 
       
   166 void QRendererVideoWidgetBackend::setContrast(int contrast)
       
   167 {
       
   168     m_surface->setContrast(contrast);
       
   169 
       
   170     emit contrastChanged(contrast);
       
   171 }
       
   172 
       
   173 void QRendererVideoWidgetBackend::setHue(int hue)
       
   174 {
       
   175     m_surface->setHue(hue);
       
   176 
       
   177     emit hueChanged(hue);
       
   178 }
       
   179 
       
   180 void QRendererVideoWidgetBackend::setSaturation(int saturation)
       
   181 {
       
   182     m_surface->setSaturation(saturation);
       
   183 
       
   184     emit saturationChanged(saturation);
       
   185 }
       
   186 
       
   187 Qt::AspectRatioMode QRendererVideoWidgetBackend::aspectRatioMode() const
       
   188 {
       
   189     return m_aspectRatioMode;
       
   190 }
       
   191 
       
   192 void QRendererVideoWidgetBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
       
   193 {
       
   194     m_aspectRatioMode = mode;
       
   195 
       
   196     m_widget->updateGeometry();
       
   197 }
       
   198 
       
   199 void QRendererVideoWidgetBackend::setFullScreen(bool)
       
   200 {
       
   201 }
       
   202 
       
   203 QSize QRendererVideoWidgetBackend::sizeHint() const
       
   204 {
       
   205     return m_surface->surfaceFormat().sizeHint();
       
   206 }
       
   207 
       
   208 void QRendererVideoWidgetBackend::showEvent()
       
   209 {
       
   210 }
       
   211 
       
   212 void QRendererVideoWidgetBackend::hideEvent(QHideEvent *)
       
   213 {
       
   214 #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
       
   215     m_updatePaintDevice = true;
       
   216     m_surface->setGLContext(0);
       
   217 #endif
       
   218 }
       
   219 
       
   220 void QRendererVideoWidgetBackend::resizeEvent(QResizeEvent *)
       
   221 {
       
   222     updateRects();
       
   223 }
       
   224 
       
   225 void QRendererVideoWidgetBackend::moveEvent(QMoveEvent *)
       
   226 {
       
   227 }
       
   228 
       
   229 void QRendererVideoWidgetBackend::paintEvent(QPaintEvent *event)
       
   230 {
       
   231     QPainter painter(m_widget);
       
   232 
       
   233     if (m_widget->testAttribute(Qt::WA_OpaquePaintEvent)) {
       
   234         QRegion borderRegion = event->region();
       
   235         borderRegion = borderRegion.subtracted(m_boundingRect);
       
   236 
       
   237         QBrush brush = m_widget->palette().window();
       
   238 
       
   239         QVector<QRect> rects = borderRegion.rects();
       
   240         for (QVector<QRect>::iterator it = rects.begin(), end = rects.end(); it != end; ++it) {
       
   241             painter.fillRect(*it, brush);
       
   242         }
       
   243     }
       
   244 
       
   245     if (m_surface->isActive() && m_boundingRect.intersects(event->rect())) {
       
   246         m_surface->paint(&painter, m_boundingRect, m_sourceRect);
       
   247 
       
   248         m_surface->setReady(true);
       
   249     } else {
       
   250  #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
       
   251         if (m_updatePaintDevice && (painter.paintEngine()->type() == QPaintEngine::OpenGL
       
   252                 || painter.paintEngine()->type() == QPaintEngine::OpenGL2)) {
       
   253             m_updatePaintDevice = false;
       
   254 
       
   255             m_surface->setGLContext(const_cast<QGLContext *>(QGLContext::currentContext()));
       
   256             if (m_surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) {
       
   257                 m_surface->setShaderType(QPainterVideoSurface::GlslShader);
       
   258             } else {
       
   259                 m_surface->setShaderType(QPainterVideoSurface::FragmentProgramShader);
       
   260             }
       
   261         }
       
   262 #endif
       
   263     }
       
   264 
       
   265 }
       
   266 
       
   267 void QRendererVideoWidgetBackend::formatChanged(const QVideoSurfaceFormat &format)
       
   268 {
       
   269     m_nativeSize = format.sizeHint();
       
   270 
       
   271     updateRects();
       
   272 
       
   273     m_widget->updateGeometry();
       
   274     m_widget->update();
       
   275 }
       
   276 
       
   277 void QRendererVideoWidgetBackend::frameChanged()
       
   278 {
       
   279     m_widget->update(m_boundingRect);
       
   280 }
       
   281 
       
   282 void QRendererVideoWidgetBackend::updateRects()
       
   283 {
       
   284     QRect rect = m_widget->rect();
       
   285 
       
   286     if (m_nativeSize.isEmpty()) {
       
   287         m_boundingRect = QRect();
       
   288     } else if (m_aspectRatioMode == Qt::IgnoreAspectRatio) {
       
   289         m_boundingRect = rect;
       
   290         m_sourceRect = QRectF(0, 0, 1, 1);
       
   291     } else if (m_aspectRatioMode == Qt::KeepAspectRatio) {
       
   292         QSize size = m_nativeSize;
       
   293         size.scale(rect.size(), Qt::KeepAspectRatio);
       
   294 
       
   295         m_boundingRect = QRect(0, 0, size.width(), size.height());
       
   296         m_boundingRect.moveCenter(rect.center());
       
   297 
       
   298         m_sourceRect = QRectF(0, 0, 1, 1);
       
   299     } else if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
       
   300         m_boundingRect = rect;
       
   301 
       
   302         QSizeF size = rect.size();
       
   303         size.scale(m_nativeSize, Qt::KeepAspectRatio);
       
   304 
       
   305         m_sourceRect = QRectF(
       
   306                 0, 0, size.width() / m_nativeSize.width(), size.height() / m_nativeSize.height());
       
   307         m_sourceRect.moveCenter(QPointF(0.5, 0.5));
       
   308     }
       
   309 }
       
   310 
       
   311 QWindowVideoWidgetBackend::QWindowVideoWidgetBackend(
       
   312         QMediaService *service, QVideoWindowControl *control, QWidget *widget)
       
   313     : m_service(service)
       
   314     , m_windowControl(control)
       
   315     , m_widget(widget)
       
   316     , m_aspectRatioMode(Qt::KeepAspectRatio)
       
   317 {
       
   318     connect(control, SIGNAL(brightnessChanged(int)), m_widget, SLOT(_q_brightnessChanged(int)));
       
   319     connect(control, SIGNAL(contrastChanged(int)), m_widget, SLOT(_q_contrastChanged(int)));
       
   320     connect(control, SIGNAL(hueChanged(int)), m_widget, SLOT(_q_hueChanged(int)));
       
   321     connect(control, SIGNAL(saturationChanged(int)), m_widget, SLOT(_q_saturationChanged(int)));
       
   322     connect(control, SIGNAL(fullScreenChanged(bool)), m_widget, SLOT(_q_fullScreenChanged(bool)));
       
   323     connect(control, SIGNAL(nativeSizeChanged()), m_widget, SLOT(_q_dimensionsChanged()));
       
   324 }
       
   325 
       
   326 QWindowVideoWidgetBackend::~QWindowVideoWidgetBackend()
       
   327 {
       
   328 }
       
   329 
       
   330 void QWindowVideoWidgetBackend::releaseControl()
       
   331 {
       
   332     m_service->releaseControl(m_windowControl);
       
   333 }
       
   334 
       
   335 void QWindowVideoWidgetBackend::setBrightness(int brightness)
       
   336 {
       
   337     m_windowControl->setBrightness(brightness);
       
   338 }
       
   339 
       
   340 void QWindowVideoWidgetBackend::setContrast(int contrast)
       
   341 {
       
   342     m_windowControl->setContrast(contrast);
       
   343 }
       
   344 
       
   345 void QWindowVideoWidgetBackend::setHue(int hue)
       
   346 {
       
   347     m_windowControl->setHue(hue);
       
   348 }
       
   349 
       
   350 void QWindowVideoWidgetBackend::setSaturation(int saturation)
       
   351 {
       
   352     m_windowControl->setSaturation(saturation);
       
   353 }
       
   354 
       
   355 void QWindowVideoWidgetBackend::setFullScreen(bool fullScreen)
       
   356 {
       
   357     m_windowControl->setFullScreen(fullScreen);
       
   358 }
       
   359 
       
   360 Qt::AspectRatioMode QWindowVideoWidgetBackend::aspectRatioMode() const
       
   361 {
       
   362     return m_windowControl->aspectRatioMode();
       
   363 }
       
   364 
       
   365 void QWindowVideoWidgetBackend::setAspectRatioMode(Qt::AspectRatioMode mode)
       
   366 {
       
   367     m_windowControl->setAspectRatioMode(mode);
       
   368 }
       
   369 
       
   370 QSize QWindowVideoWidgetBackend::sizeHint() const
       
   371 {
       
   372     return m_windowControl->nativeSize();
       
   373 }
       
   374 
       
   375 void QWindowVideoWidgetBackend::showEvent()
       
   376 {
       
   377     m_windowControl->setWinId(m_widget->winId());
       
   378 
       
   379     m_windowControl->setDisplayRect(m_widget->rect());
       
   380 }
       
   381 
       
   382 void QWindowVideoWidgetBackend::hideEvent(QHideEvent *)
       
   383 {
       
   384 }
       
   385 
       
   386 void QWindowVideoWidgetBackend::moveEvent(QMoveEvent *)
       
   387 {
       
   388     m_windowControl->setDisplayRect(m_widget->rect());
       
   389 }
       
   390 
       
   391 void QWindowVideoWidgetBackend::resizeEvent(QResizeEvent *)
       
   392 {
       
   393     m_windowControl->setDisplayRect(m_widget->rect());
       
   394 }
       
   395 
       
   396 void QWindowVideoWidgetBackend::paintEvent(QPaintEvent *event)
       
   397 {
       
   398     if (m_widget->testAttribute(Qt::WA_OpaquePaintEvent)) {
       
   399         QPainter painter(m_widget);
       
   400 
       
   401         painter.fillRect(event->rect(), m_widget->palette().window());
       
   402     }
       
   403 
       
   404     m_windowControl->repaint();
       
   405 
       
   406     event->accept();
       
   407 }
       
   408 
       
   409 void QVideoWidgetPrivate::setCurrentControl(QVideoWidgetControlInterface *control)
       
   410 {
       
   411     if (currentControl != control) {
       
   412         currentControl = control;
       
   413 
       
   414         currentControl->setBrightness(brightness);
       
   415         currentControl->setContrast(contrast);
       
   416         currentControl->setHue(hue);
       
   417         currentControl->setSaturation(saturation);
       
   418         currentControl->setAspectRatioMode(aspectRatioMode);
       
   419     }
       
   420 }
       
   421 
       
   422 void QVideoWidgetPrivate::clearService()
       
   423 {
       
   424     if (service) {
       
   425         QObject::disconnect(service, SIGNAL(destroyed()), q_func(), SLOT(_q_serviceDestroyed()));
       
   426 
       
   427         if (widgetBackend) {
       
   428             QLayout *layout = q_func()->layout();
       
   429 
       
   430             for (QLayoutItem *item = layout->takeAt(0); item; item = layout->takeAt(0)) {
       
   431                 item->widget()->setParent(0);
       
   432                 delete item;
       
   433             }
       
   434             delete layout;
       
   435 
       
   436             widgetBackend->releaseControl();
       
   437 
       
   438             delete widgetBackend;
       
   439             widgetBackend = 0;
       
   440         } else if (rendererBackend) {
       
   441             rendererBackend->clearSurface();
       
   442             rendererBackend->releaseControl();
       
   443 
       
   444             delete rendererBackend;
       
   445             rendererBackend = 0;
       
   446         } else {
       
   447             windowBackend->releaseControl();
       
   448 
       
   449             delete windowBackend;
       
   450             windowBackend = 0;
       
   451         }
       
   452 
       
   453         currentBackend = 0;
       
   454         currentControl = 0;
       
   455         service = 0;
       
   456     }
       
   457 }
       
   458 
       
   459 bool QVideoWidgetPrivate::createWidgetBackend()
       
   460 {
       
   461     if (QMediaControl *control = service->requestControl(QVideoWidgetControl_iid)) {
       
   462         if (QVideoWidgetControl *widgetControl = qobject_cast<QVideoWidgetControl *>(control)) {
       
   463             widgetBackend = new QVideoWidgetControlBackend(service, widgetControl, q_func());
       
   464 
       
   465             setCurrentControl(widgetBackend);
       
   466 
       
   467             return true;
       
   468         }
       
   469         service->releaseControl(control);
       
   470     }
       
   471     return false;
       
   472 }
       
   473 
       
   474 bool QVideoWidgetPrivate::createWindowBackend()
       
   475 {
       
   476     if (QMediaControl *control = service->requestControl(QVideoWindowControl_iid)) {
       
   477         if (QVideoWindowControl *windowControl = qobject_cast<QVideoWindowControl *>(control)) {
       
   478             windowBackend = new QWindowVideoWidgetBackend(service, windowControl, q_func());
       
   479             currentBackend = windowBackend;
       
   480 
       
   481             setCurrentControl(windowBackend);
       
   482 
       
   483             return true;
       
   484         }
       
   485         service->releaseControl(control);
       
   486     }
       
   487     return false;
       
   488 }
       
   489 
       
   490 bool QVideoWidgetPrivate::createRendererBackend()
       
   491 {
       
   492     if (QMediaControl *control = service->requestControl(QVideoRendererControl_iid)) {
       
   493         if (QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>(control)) {
       
   494             rendererBackend = new QRendererVideoWidgetBackend(service, rendererControl, q_func());
       
   495             currentBackend = rendererBackend;
       
   496 
       
   497             setCurrentControl(rendererBackend);
       
   498 
       
   499             return true;
       
   500         }
       
   501         service->releaseControl(control);
       
   502     }
       
   503     return false;
       
   504 }
       
   505 
       
   506 void QVideoWidgetPrivate::_q_serviceDestroyed()
       
   507 {
       
   508     if (widgetBackend)
       
   509         delete q_func()->layout();
       
   510 
       
   511     delete widgetBackend;
       
   512     delete windowBackend;
       
   513     delete rendererBackend;
       
   514 
       
   515     widgetBackend = 0;
       
   516     windowBackend = 0;
       
   517     rendererBackend = 0;
       
   518     currentControl = 0;
       
   519     currentBackend = 0;
       
   520     service = 0;
       
   521 }
       
   522 
       
   523 void QVideoWidgetPrivate::_q_brightnessChanged(int b)
       
   524 {
       
   525     if (b != brightness)
       
   526         emit q_func()->brightnessChanged(brightness = b);
       
   527 }
       
   528 
       
   529 void QVideoWidgetPrivate::_q_contrastChanged(int c)
       
   530 {
       
   531     if (c != contrast)
       
   532         emit q_func()->contrastChanged(contrast = c);
       
   533 }
       
   534 
       
   535 void QVideoWidgetPrivate::_q_hueChanged(int h)
       
   536 {
       
   537     if (h != hue)
       
   538         emit q_func()->hueChanged(hue = h);
       
   539 }
       
   540 
       
   541 void QVideoWidgetPrivate::_q_saturationChanged(int s)
       
   542 {
       
   543     if (s != saturation)
       
   544         emit q_func()->saturationChanged(saturation = s);
       
   545 }
       
   546 
       
   547 
       
   548 void QVideoWidgetPrivate::_q_fullScreenChanged(bool fullScreen)
       
   549 {
       
   550     if (!fullScreen && q_func()->isFullScreen())
       
   551         q_func()->showNormal();
       
   552 }
       
   553 
       
   554 void QVideoWidgetPrivate::_q_dimensionsChanged()
       
   555 {
       
   556     q_func()->updateGeometry();
       
   557     q_func()->update();
       
   558 }
       
   559 
       
   560 /*!
       
   561     \class QVideoWidget
       
   562     \preliminary
       
   563 
       
   564     \brief The QVideoWidget class provides a widget which presents video
       
   565     produced by a media object.
       
   566     \ingroup multimedia
       
   567 
       
   568     Attaching a QVideoWidget to a QMediaObject allows it to display the
       
   569     video or image output of that media object.  A QVideoWidget is attached
       
   570     to media object by passing a pointer to the QMediaObject in its
       
   571     constructor, and detached by destroying the QVideoWidget.
       
   572 
       
   573     \code
       
   574         player = new QMediaPlayer;
       
   575 
       
   576         widget = new QVideoWidget;
       
   577         widget->show();
       
   578 
       
   579         player->setVideoOutput(widget);
       
   580         player->setMedia(QUrl("http://example.com/movie.mp4"));
       
   581         player->play();
       
   582     \endcode
       
   583 
       
   584     \bold {Note}: Only a single display output can be attached to a media
       
   585     object at one time.
       
   586 
       
   587     \sa QMediaObject, QMediaPlayer, QGraphicsVideoItem
       
   588 */
       
   589 
       
   590 /*!
       
   591     Constructs a new video widget.
       
   592 
       
   593     The \a parent is passed to QWidget.
       
   594 */
       
   595 QVideoWidget::QVideoWidget(QWidget *parent)
       
   596     : QWidget(parent, 0)
       
   597     , d_ptr(new QVideoWidgetPrivate)
       
   598 {
       
   599     d_ptr->q_ptr = this;
       
   600 }
       
   601 
       
   602 /*!
       
   603     Destroys a video widget.
       
   604 */
       
   605 QVideoWidget::~QVideoWidget()
       
   606 {
       
   607     d_ptr->clearService();
       
   608 
       
   609     delete d_ptr;
       
   610 }
       
   611 
       
   612 /*!
       
   613     \property QVideoWidget::mediaObject
       
   614     \brief the media object which provides the video displayed by a widget.
       
   615 */
       
   616 
       
   617 QMediaObject *QVideoWidget::mediaObject() const
       
   618 {
       
   619     return d_func()->mediaObject;
       
   620 }
       
   621 
       
   622 /*!
       
   623     \internal
       
   624 */
       
   625 bool QVideoWidget::setMediaObject(QMediaObject *object)
       
   626 {
       
   627     Q_D(QVideoWidget);
       
   628 
       
   629     if (object == d->mediaObject)
       
   630         return true;
       
   631 
       
   632     d->clearService();
       
   633 
       
   634     d->mediaObject = object;
       
   635 
       
   636     if (d->mediaObject)
       
   637         d->service = d->mediaObject->service();
       
   638 
       
   639     if (d->service) {
       
   640         if (d->createWidgetBackend()) {
       
   641             // Nothing to do here.
       
   642         } else if ((!window() || !window()->testAttribute(Qt::WA_DontShowOnScreen))
       
   643                 && d->createWindowBackend()) {
       
   644             if (isVisible())
       
   645                 d->windowBackend->showEvent();
       
   646         } else if (d->createRendererBackend()) {
       
   647             if (isVisible())
       
   648                 d->rendererBackend->showEvent();
       
   649         } else {
       
   650             d->service = 0;
       
   651             d->mediaObject = 0;
       
   652 
       
   653             return false;
       
   654         }
       
   655 
       
   656         connect(d->service, SIGNAL(destroyed()), SLOT(_q_serviceDestroyed()));
       
   657     } else {
       
   658         d->mediaObject = 0;
       
   659 
       
   660         return false;
       
   661     }
       
   662 
       
   663     return true;
       
   664 }
       
   665 
       
   666 /*!
       
   667     \property QVideoWidget::aspectRatioMode
       
   668     \brief how video is scaled with respect to its aspect ratio.
       
   669 */
       
   670 
       
   671 Qt::AspectRatioMode QVideoWidget::aspectRatioMode() const
       
   672 {
       
   673     return d_func()->aspectRatioMode;
       
   674 }
       
   675 
       
   676 void QVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode)
       
   677 {
       
   678     Q_D(QVideoWidget);
       
   679 
       
   680     if (d->currentControl) {
       
   681         d->currentControl->setAspectRatioMode(mode);
       
   682         d->aspectRatioMode = d->currentControl->aspectRatioMode();
       
   683     } else {
       
   684         d->aspectRatioMode = mode;
       
   685     }
       
   686 }
       
   687 
       
   688 /*!
       
   689     \property QVideoWidget::fullScreen
       
   690     \brief whether video display is confined to a window or is fullScreen.
       
   691 */
       
   692 
       
   693 void QVideoWidget::setFullScreen(bool fullScreen)
       
   694 {
       
   695     Q_D(QVideoWidget);
       
   696 
       
   697     if (fullScreen) {
       
   698         Qt::WindowFlags flags = windowFlags();
       
   699 
       
   700         d->nonFullScreenFlags = flags & (Qt::Window | Qt::SubWindow);
       
   701         flags |= Qt::Window;
       
   702         flags &= ~Qt::SubWindow;
       
   703         setWindowFlags(flags);
       
   704         
       
   705         showFullScreen();
       
   706     } else {
       
   707         showNormal();
       
   708     }
       
   709 }
       
   710 
       
   711 /*!
       
   712     \fn QVideoWidget::fullScreenChanged(bool fullScreen)
       
   713 
       
   714     Signals that the \a fullScreen mode of a video widget has changed.
       
   715 
       
   716     \sa fullScreen
       
   717 */
       
   718 
       
   719 /*!
       
   720     \property QVideoWidget::brightness
       
   721     \brief an adjustment to the brightness of displayed video.
       
   722 
       
   723     Valid brightness values range between -100 and 100, the default is 0.
       
   724 */
       
   725 
       
   726 int QVideoWidget::brightness() const
       
   727 {
       
   728     return d_func()->brightness;
       
   729 }
       
   730 
       
   731 void QVideoWidget::setBrightness(int brightness)
       
   732 {
       
   733     Q_D(QVideoWidget);
       
   734 
       
   735     int boundedBrightness = qBound(-100, brightness, 100);
       
   736 
       
   737     if (d->currentControl)
       
   738         d->currentControl->setBrightness(boundedBrightness);
       
   739     else if (d->brightness != boundedBrightness)
       
   740         emit brightnessChanged(d->brightness = boundedBrightness);
       
   741 }
       
   742 
       
   743 /*!
       
   744     \fn QVideoWidget::brightnessChanged(int brightness)
       
   745 
       
   746     Signals that a video widgets's \a brightness adjustment has changed.
       
   747 
       
   748     \sa brightness
       
   749 */
       
   750 
       
   751 /*!
       
   752     \property QVideoWidget::contrast
       
   753     \brief an adjustment to the contrast of displayed video.
       
   754 
       
   755     Valid contrast values range between -100 and 100, the default is 0.
       
   756 
       
   757 */
       
   758 
       
   759 int QVideoWidget::contrast() const
       
   760 {
       
   761     return d_func()->contrast;
       
   762 }
       
   763 
       
   764 void QVideoWidget::setContrast(int contrast)
       
   765 {
       
   766     Q_D(QVideoWidget);
       
   767 
       
   768     int boundedContrast = qBound(-100, contrast, 100);
       
   769 
       
   770     if (d->currentControl)
       
   771         d->currentControl->setContrast(boundedContrast);
       
   772     else if (d->contrast != boundedContrast)
       
   773         emit contrastChanged(d->contrast = boundedContrast);
       
   774 }
       
   775 
       
   776 /*!
       
   777     \fn QVideoWidget::contrastChanged(int contrast)
       
   778 
       
   779     Signals that a video widgets's \a contrast adjustment has changed.
       
   780 
       
   781     \sa contrast
       
   782 */
       
   783 
       
   784 /*!
       
   785     \property QVideoWidget::hue
       
   786     \brief an adjustment to the hue of displayed video.
       
   787 
       
   788     Valid hue values range between -100 and 100, the default is 0.
       
   789 */
       
   790 
       
   791 int QVideoWidget::hue() const
       
   792 {
       
   793     return d_func()->hue;
       
   794 }
       
   795 
       
   796 void QVideoWidget::setHue(int hue)
       
   797 {
       
   798     Q_D(QVideoWidget);
       
   799 
       
   800     int boundedHue = qBound(-100, hue, 100);
       
   801 
       
   802     if (d->currentControl)
       
   803         d->currentControl->setHue(boundedHue);
       
   804     else if (d->hue != boundedHue)
       
   805         emit hueChanged(d->hue = boundedHue);
       
   806 }
       
   807 
       
   808 /*!
       
   809     \fn QVideoWidget::hueChanged(int hue)
       
   810 
       
   811     Signals that a video widgets's \a hue has changed.
       
   812 
       
   813     \sa hue
       
   814 */
       
   815 
       
   816 /*!
       
   817     \property QVideoWidget::saturation
       
   818     \brief an adjustment to the saturation of displayed video.
       
   819 
       
   820     Valid saturation values range between -100 and 100, the default is 0.
       
   821 */
       
   822 
       
   823 int QVideoWidget::saturation() const
       
   824 {
       
   825     return d_func()->saturation;
       
   826 }
       
   827 
       
   828 void QVideoWidget::setSaturation(int saturation)
       
   829 {
       
   830     Q_D(QVideoWidget);
       
   831 
       
   832     int boundedSaturation = qBound(-100, saturation, 100);
       
   833 
       
   834     if (d->currentControl)
       
   835         d->currentControl->setSaturation(boundedSaturation);
       
   836     else if (d->saturation != boundedSaturation)
       
   837         emit saturationChanged(d->saturation = boundedSaturation);
       
   838 
       
   839 }
       
   840 
       
   841 /*!
       
   842     \fn QVideoWidget::saturationChanged(int saturation)
       
   843 
       
   844     Signals that a video widgets's \a saturation has changed.
       
   845 
       
   846     \sa saturation
       
   847 */
       
   848 
       
   849 /*!
       
   850   Returns the size hint for the current back end,
       
   851   if there is one, or else the size hint from QWidget.
       
   852  */
       
   853 QSize QVideoWidget::sizeHint() const
       
   854 {
       
   855     Q_D(const QVideoWidget);
       
   856 
       
   857     if (d->currentBackend)
       
   858         return d->currentBackend->sizeHint();
       
   859     else
       
   860         return QWidget::sizeHint();
       
   861 
       
   862 
       
   863 }
       
   864 
       
   865 /*!
       
   866     \reimp
       
   867     \internal
       
   868  */
       
   869 bool QVideoWidget::event(QEvent *event)
       
   870 {
       
   871     Q_D(QVideoWidget);
       
   872 
       
   873     if (event->type() == QEvent::WindowStateChange) {
       
   874         Qt::WindowFlags flags = windowFlags();
       
   875 
       
   876         if (windowState() & Qt::WindowFullScreen) {
       
   877             if (d->currentControl)
       
   878                 d->currentControl->setFullScreen(true);
       
   879 
       
   880             if (!d->wasFullScreen)
       
   881                 emit fullScreenChanged(d->wasFullScreen = true);
       
   882         } else {
       
   883             if (d->currentControl)
       
   884                 d->currentControl->setFullScreen(false);
       
   885 
       
   886             if (d->wasFullScreen) {
       
   887                 flags &= ~(Qt::Window | Qt::SubWindow); //clear the flags...
       
   888                 flags |= d->nonFullScreenFlags; //then we reset the flags (window and subwindow)
       
   889                 setWindowFlags(flags);
       
   890 
       
   891                 emit fullScreenChanged(d->wasFullScreen = false);
       
   892             }
       
   893         }
       
   894     }
       
   895     return QWidget::event(event);
       
   896 }
       
   897 
       
   898 /*!
       
   899   Handles the show \a event.
       
   900  */
       
   901 void QVideoWidget::showEvent(QShowEvent *event)
       
   902 {
       
   903     Q_D(QVideoWidget);
       
   904 
       
   905     QWidget::showEvent(event);
       
   906 
       
   907     // The window backend won't work for re-directed windows so use the renderer backend instead.
       
   908     if (d->windowBackend && window()->testAttribute(Qt::WA_DontShowOnScreen)) {
       
   909         d->windowBackend->releaseControl();
       
   910 
       
   911         delete d->windowBackend;
       
   912         d->windowBackend = 0;
       
   913 
       
   914         d->createRendererBackend();
       
   915     }
       
   916 
       
   917     if (d->currentBackend)
       
   918         d->currentBackend->showEvent();
       
   919 }
       
   920 
       
   921 /*!
       
   922 
       
   923   Handles the hide \a event.
       
   924 */
       
   925 void QVideoWidget::hideEvent(QHideEvent *event)
       
   926 {
       
   927     Q_D(QVideoWidget);
       
   928 
       
   929     if (d->currentBackend)
       
   930         d->currentBackend->hideEvent(event);
       
   931 
       
   932     QWidget::hideEvent(event);
       
   933 }
       
   934 
       
   935 /*!
       
   936   Handles the resize \a event.
       
   937  */
       
   938 void QVideoWidget::resizeEvent(QResizeEvent *event)
       
   939 {
       
   940     Q_D(QVideoWidget);
       
   941 
       
   942     QWidget::resizeEvent(event);
       
   943 
       
   944     if (d->currentBackend)
       
   945         d->currentBackend->resizeEvent(event);
       
   946 }
       
   947 
       
   948 /*!
       
   949   Handles the move \a event.
       
   950  */
       
   951 void QVideoWidget::moveEvent(QMoveEvent *event)
       
   952 {
       
   953     Q_D(QVideoWidget);
       
   954 
       
   955     if (d->currentBackend)
       
   956         d->currentBackend->moveEvent(event);
       
   957 }
       
   958 
       
   959 /*!
       
   960   Handles the paint \a event.
       
   961  */
       
   962 void QVideoWidget::paintEvent(QPaintEvent *event)
       
   963 {
       
   964     Q_D(QVideoWidget);
       
   965 
       
   966     if (d->currentBackend) {
       
   967         d->currentBackend->paintEvent(event);
       
   968     } else if (testAttribute(Qt::WA_OpaquePaintEvent)) {
       
   969         QPainter painter(this);
       
   970 
       
   971         painter.fillRect(event->rect(), palette().window());
       
   972     }
       
   973 }
       
   974 
       
   975 #include "moc_qvideowidget.cpp"
       
   976 #include "moc_qvideowidget_p.cpp"
       
   977 QT_END_NAMESPACE
       
   978