qtmobility/src/multimedia/qvideowidget.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "qvideowidget_p.h"
    42 #include "qvideowidget_p.h"
    43 
    43 
    44 #include "qmediaobject.h"
    44 #include <qmediaobject.h>
    45 #include "qmediaservice.h"
    45 #include <qmediaservice.h>
    46 #include "qvideooutputcontrol.h"
    46 #include <qvideowindowcontrol.h>
    47 #include "qvideowindowcontrol.h"
    47 #include <qvideowidgetcontrol.h>
    48 #include "qvideowidgetcontrol.h"
    48 
    49 
    49 #include <qpaintervideosurface_p.h>
    50 #include "qpaintervideosurface_p.h"
    50 #include <qvideorenderercontrol.h>
    51 #include "qvideorenderercontrol.h"
    51 #include <qvideosurfaceformat.h>
    52 #include <QtMultimedia/qvideosurfaceformat.h>
       
    53 #include <qpainter.h>
    52 #include <qpainter.h>
    54 
    53 
    55 #include <qapplication.h>
    54 #include <qapplication.h>
    56 #include <qevent.h>
    55 #include <qevent.h>
    57 #include <qdialog.h>
    56 #include <qdialog.h>
    61 using namespace Qt;
    60 using namespace Qt;
    62 
    61 
    63 QT_BEGIN_NAMESPACE
    62 QT_BEGIN_NAMESPACE
    64 
    63 
    65 QVideoWidgetControlBackend::QVideoWidgetControlBackend(
    64 QVideoWidgetControlBackend::QVideoWidgetControlBackend(
    66         QVideoWidgetControl *control, QWidget *widget)
    65         QMediaService *service, QVideoWidgetControl *control, QWidget *widget)
    67     : m_widgetControl(control)
    66     : m_service(service)
       
    67     , m_widgetControl(control)
    68 {
    68 {
    69     connect(control, SIGNAL(brightnessChanged(int)), widget, SLOT(_q_brightnessChanged(int)));
    69     connect(control, SIGNAL(brightnessChanged(int)), widget, SLOT(_q_brightnessChanged(int)));
    70     connect(control, SIGNAL(contrastChanged(int)), widget, SLOT(_q_contrastChanged(int)));
    70     connect(control, SIGNAL(contrastChanged(int)), widget, SLOT(_q_contrastChanged(int)));
    71     connect(control, SIGNAL(hueChanged(int)), widget, SLOT(_q_hueChanged(int)));
    71     connect(control, SIGNAL(hueChanged(int)), widget, SLOT(_q_hueChanged(int)));
    72     connect(control, SIGNAL(saturationChanged(int)), widget, SLOT(_q_saturationChanged(int)));
    72     connect(control, SIGNAL(saturationChanged(int)), widget, SLOT(_q_saturationChanged(int)));
    78     layout->addWidget(control->videoWidget());
    78     layout->addWidget(control->videoWidget());
    79 
    79 
    80     widget->setLayout(layout);
    80     widget->setLayout(layout);
    81 }
    81 }
    82 
    82 
       
    83 void QVideoWidgetControlBackend::releaseControl()
       
    84 {
       
    85     m_service->releaseControl(m_widgetControl);
       
    86 }
       
    87 
    83 void QVideoWidgetControlBackend::setBrightness(int brightness)
    88 void QVideoWidgetControlBackend::setBrightness(int brightness)
    84 {
    89 {
    85     m_widgetControl->setBrightness(brightness);
    90     m_widgetControl->setBrightness(brightness);
    86 }
    91 }
    87 
    92 
   115 {
   120 {
   116     m_widgetControl->setAspectRatioMode(mode);
   121     m_widgetControl->setAspectRatioMode(mode);
   117 }
   122 }
   118 
   123 
   119 QRendererVideoWidgetBackend::QRendererVideoWidgetBackend(
   124 QRendererVideoWidgetBackend::QRendererVideoWidgetBackend(
   120         QVideoRendererControl *control, QWidget *widget)
   125         QMediaService *service, QVideoRendererControl *control, QWidget *widget)
   121     : m_rendererControl(control)
   126     : m_service(service)
       
   127     , m_rendererControl(control)
   122     , m_widget(widget)
   128     , m_widget(widget)
   123     , m_surface(new QPainterVideoSurface)
   129     , m_surface(new QPainterVideoSurface)
   124     , m_aspectRatioMode(Qt::KeepAspectRatio)
   130     , m_aspectRatioMode(Qt::KeepAspectRatio)
   125     , m_updatePaintDevice(true)
   131     , m_updatePaintDevice(true)
   126 {
   132 {
   136 }
   142 }
   137 
   143 
   138 QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend()
   144 QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend()
   139 {
   145 {
   140     delete m_surface;
   146     delete m_surface;
       
   147 }
       
   148 
       
   149 void QRendererVideoWidgetBackend::releaseControl()
       
   150 {
       
   151     m_service->releaseControl(m_rendererControl);
   141 }
   152 }
   142 
   153 
   143 void QRendererVideoWidgetBackend::clearSurface()
   154 void QRendererVideoWidgetBackend::clearSurface()
   144 {
   155 {
   145     m_rendererControl->setSurface(0);
   156     m_rendererControl->setSurface(0);
   295                 0, 0, size.width() / m_nativeSize.width(), size.height() / m_nativeSize.height());
   306                 0, 0, size.width() / m_nativeSize.width(), size.height() / m_nativeSize.height());
   296         m_sourceRect.moveCenter(QPointF(0.5, 0.5));
   307         m_sourceRect.moveCenter(QPointF(0.5, 0.5));
   297     }
   308     }
   298 }
   309 }
   299 
   310 
   300 QWindowVideoWidgetBackend::QWindowVideoWidgetBackend(QVideoWindowControl *control, QWidget *widget)
   311 QWindowVideoWidgetBackend::QWindowVideoWidgetBackend(
   301     : m_windowControl(control)
   312         QMediaService *service, QVideoWindowControl *control, QWidget *widget)
       
   313     : m_service(service)
       
   314     , m_windowControl(control)
   302     , m_widget(widget)
   315     , m_widget(widget)
   303     , m_aspectRatioMode(Qt::KeepAspectRatio)
   316     , m_aspectRatioMode(Qt::KeepAspectRatio)
   304 {
   317 {
   305     connect(control, SIGNAL(brightnessChanged(int)), m_widget, SLOT(_q_brightnessChanged(int)));
   318     connect(control, SIGNAL(brightnessChanged(int)), m_widget, SLOT(_q_brightnessChanged(int)));
   306     connect(control, SIGNAL(contrastChanged(int)), m_widget, SLOT(_q_contrastChanged(int)));
   319     connect(control, SIGNAL(contrastChanged(int)), m_widget, SLOT(_q_contrastChanged(int)));
   312 
   325 
   313 QWindowVideoWidgetBackend::~QWindowVideoWidgetBackend()
   326 QWindowVideoWidgetBackend::~QWindowVideoWidgetBackend()
   314 {
   327 {
   315 }
   328 }
   316 
   329 
       
   330 void QWindowVideoWidgetBackend::releaseControl()
       
   331 {
       
   332     m_service->releaseControl(m_windowControl);
       
   333 }
       
   334 
   317 void QWindowVideoWidgetBackend::setBrightness(int brightness)
   335 void QWindowVideoWidgetBackend::setBrightness(int brightness)
   318 {
   336 {
   319     m_windowControl->setBrightness(brightness);
   337     m_windowControl->setBrightness(brightness);
   320 }
   338 }
   321 
   339 
   399         currentControl->setSaturation(saturation);
   417         currentControl->setSaturation(saturation);
   400         currentControl->setAspectRatioMode(aspectRatioMode);
   418         currentControl->setAspectRatioMode(aspectRatioMode);
   401     }
   419     }
   402 }
   420 }
   403 
   421 
   404 void QVideoWidgetPrivate::show()
       
   405 {
       
   406     if (outputControl) {
       
   407         if (widgetBackend != 0) {
       
   408             setCurrentControl(widgetBackend);
       
   409             outputControl->setOutput(QVideoOutputControl::WidgetOutput);
       
   410         } else if (windowBackend != 0 && (q_func()->window() == 0
       
   411                 || !q_func()->window()->testAttribute(Qt::WA_DontShowOnScreen))) {
       
   412             windowBackend->showEvent();
       
   413             currentBackend = windowBackend;
       
   414             setCurrentControl(windowBackend);
       
   415             outputControl->setOutput(QVideoOutputControl::WindowOutput);
       
   416         } else if (rendererBackend != 0) {
       
   417             rendererBackend->showEvent();
       
   418             currentBackend = rendererBackend;
       
   419             setCurrentControl(rendererBackend);
       
   420             outputControl->setOutput(QVideoOutputControl::RendererOutput);
       
   421         } else {
       
   422             outputControl->setOutput(QVideoOutputControl::NoOutput);
       
   423         }
       
   424     }
       
   425 }
       
   426 
       
   427 void QVideoWidgetPrivate::clearService()
   422 void QVideoWidgetPrivate::clearService()
   428 {
   423 {
   429     if (service) {
   424     if (service) {
   430         QObject::disconnect(service, SIGNAL(destroyed()), q_func(), SLOT(_q_serviceDestroyed()));
   425         QObject::disconnect(service, SIGNAL(destroyed()), q_func(), SLOT(_q_serviceDestroyed()));
   431 
       
   432         if (outputControl)
       
   433             outputControl->setOutput(QVideoOutputControl::NoOutput);
       
   434 
   426 
   435         if (widgetBackend) {
   427         if (widgetBackend) {
   436             QLayout *layout = q_func()->layout();
   428             QLayout *layout = q_func()->layout();
   437 
   429 
   438             for (QLayoutItem *item = layout->takeAt(0); item; item = layout->takeAt(0)) {
   430             for (QLayoutItem *item = layout->takeAt(0); item; item = layout->takeAt(0)) {
   439                 item->widget()->setParent(0);
   431                 item->widget()->setParent(0);
   440                 delete item;
   432                 delete item;
   441             }
   433             }
   442             delete layout;
   434             delete layout;
   443 
   435 
       
   436             widgetBackend->releaseControl();
       
   437 
   444             delete widgetBackend;
   438             delete widgetBackend;
   445             widgetBackend = 0;
   439             widgetBackend = 0;
   446         }
   440         } else if (rendererBackend) {
   447 
       
   448         delete windowBackend;
       
   449         windowBackend = 0;
       
   450 
       
   451         if (rendererBackend) {
       
   452             rendererBackend->clearSurface();
   441             rendererBackend->clearSurface();
       
   442             rendererBackend->releaseControl();
   453 
   443 
   454             delete rendererBackend;
   444             delete rendererBackend;
   455             rendererBackend = 0;
   445             rendererBackend = 0;
       
   446         } else {
       
   447             windowBackend->releaseControl();
       
   448 
       
   449             delete windowBackend;
       
   450             windowBackend = 0;
   456         }
   451         }
   457 
   452 
   458         currentBackend = 0;
   453         currentBackend = 0;
   459         currentControl = 0;
   454         currentControl = 0;
   460         outputControl = 0;
       
   461         service = 0;
   455         service = 0;
   462     }
   456     }
   463 }
   457 }
   464 
   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 
   465 void QVideoWidgetPrivate::_q_serviceDestroyed()
   506 void QVideoWidgetPrivate::_q_serviceDestroyed()
   466 {
   507 {
   467     if (widgetBackend) {
   508     if (widgetBackend)
   468         delete q_func()->layout();
   509         delete q_func()->layout();
   469 
   510 
   470         delete widgetBackend;
   511     delete widgetBackend;
   471         widgetBackend = 0;
       
   472     }
       
   473 
       
   474     delete windowBackend;
   512     delete windowBackend;
       
   513     delete rendererBackend;
       
   514 
       
   515     widgetBackend = 0;
   475     windowBackend = 0;
   516     windowBackend = 0;
   476 
       
   477     delete rendererBackend;
       
   478     rendererBackend = 0;
   517     rendererBackend = 0;
   479 
       
   480     currentControl = 0;
   518     currentControl = 0;
   481     currentBackend = 0;
   519     currentBackend = 0;
   482     outputControl = 0;
       
   483     service = 0;
   520     service = 0;
   484 }
       
   485 
       
   486 void QVideoWidgetPrivate::_q_mediaObjectDestroyed()
       
   487 {
       
   488     mediaObject = 0;
       
   489     clearService();
       
   490 }
   521 }
   491 
   522 
   492 void QVideoWidgetPrivate::_q_brightnessChanged(int b)
   523 void QVideoWidgetPrivate::_q_brightnessChanged(int b)
   493 {
   524 {
   494     if (b != brightness)
   525     if (b != brightness)
   540     constructor, and detached by destroying the QVideoWidget.
   571     constructor, and detached by destroying the QVideoWidget.
   541 
   572 
   542     \code
   573     \code
   543         player = new QMediaPlayer;
   574         player = new QMediaPlayer;
   544 
   575 
   545         widget = new QVideoWidget(player);
   576         widget = new QVideoWidget;
   546         widget->show();
   577         widget->show();
   547 
   578 
       
   579         player->setVideoOutput(widget);
   548         player->setMedia(QUrl("http://example.com/movie.mp4"));
   580         player->setMedia(QUrl("http://example.com/movie.mp4"));
   549         player->play();
   581         player->play();
   550     \endcode
   582     \endcode
   551 
   583 
   552     \bold {Note}: Only a single display output can be attached to a media
   584     \bold {Note}: Only a single display output can be attached to a media
   570 /*!
   602 /*!
   571     Destroys a video widget.
   603     Destroys a video widget.
   572 */
   604 */
   573 QVideoWidget::~QVideoWidget()
   605 QVideoWidget::~QVideoWidget()
   574 {
   606 {
   575     setMediaObject(0);
   607     d_ptr->clearService();
       
   608 
   576     delete d_ptr;
   609     delete d_ptr;
   577 }
   610 }
   578 
   611 
   579 /*!
   612 /*!
   580     \property QVideoWidget::mediaObject
   613     \property QVideoWidget::mediaObject
   584 QMediaObject *QVideoWidget::mediaObject() const
   617 QMediaObject *QVideoWidget::mediaObject() const
   585 {
   618 {
   586     return d_func()->mediaObject;
   619     return d_func()->mediaObject;
   587 }
   620 }
   588 
   621 
   589 void QVideoWidget::setMediaObject(QMediaObject *object)
   622 bool QVideoWidget::setMediaObject(QMediaObject *object)
   590 {
   623 {
   591     Q_D(QVideoWidget);
   624     Q_D(QVideoWidget);
   592 
   625 
   593     if (object == d->mediaObject)
   626     if (object == d->mediaObject)
   594         return;
   627         return true;
   595 
       
   596     if (d->mediaObject) {
       
   597         disconnect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed()));
       
   598         d->mediaObject->unbind(this);
       
   599     }
       
   600 
   628 
   601     d->clearService();
   629     d->clearService();
   602 
   630 
   603     d->mediaObject = object;
   631     d->mediaObject = object;
   604 
   632 
   605     if (d->mediaObject) {
   633     if (d->mediaObject)
   606         d->service = d->mediaObject->service();
   634         d->service = d->mediaObject->service();
   607 
   635 
   608         connect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed()));
       
   609         d->mediaObject->bind(this);
       
   610     }
       
   611 
       
   612     if (d->service) {
   636     if (d->service) {
       
   637         if (d->createWidgetBackend()) {
       
   638             // Nothing to do here.
       
   639         } else if ((!window() || !window()->testAttribute(Qt::WA_DontShowOnScreen))
       
   640                 && d->createWindowBackend()) {
       
   641             if (isVisible())
       
   642                 d->windowBackend->showEvent();
       
   643         } else if (d->createRendererBackend()) {
       
   644             if (isVisible())
       
   645                 d->rendererBackend->showEvent();
       
   646         } else {
       
   647             d->service = 0;
       
   648             d->mediaObject = 0;
       
   649 
       
   650             return false;
       
   651         }
       
   652 
   613         connect(d->service, SIGNAL(destroyed()), SLOT(_q_serviceDestroyed()));
   653         connect(d->service, SIGNAL(destroyed()), SLOT(_q_serviceDestroyed()));
   614 
   654     } else {
   615         d->outputControl = qobject_cast<QVideoOutputControl *>(
   655         d->mediaObject = 0;
   616                 d->service->control(QVideoOutputControl_iid));
   656 
   617 
   657         return false;
   618         QVideoWidgetControl *widgetControl = qobject_cast<QVideoWidgetControl *>(
   658     }
   619                 d->service->control(QVideoWidgetControl_iid));
   659 
   620 
   660     return true;
   621         if (widgetControl != 0) {
       
   622             d->widgetBackend = new QVideoWidgetControlBackend(widgetControl, this);
       
   623         } else {
       
   624             QVideoWindowControl *windowControl = qobject_cast<QVideoWindowControl *>(
       
   625                     d->service->control(QVideoWindowControl_iid));
       
   626 
       
   627             if (windowControl != 0)
       
   628                 d->windowBackend = new QWindowVideoWidgetBackend(windowControl, this);
       
   629 
       
   630             QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>(
       
   631                     d->service->control(QVideoRendererControl_iid));
       
   632 
       
   633             if (rendererControl != 0)
       
   634                 d->rendererBackend = new QRendererVideoWidgetBackend(rendererControl, this);
       
   635         }
       
   636 
       
   637         if (isVisible())
       
   638             d->show();
       
   639     }
       
   640 }
   661 }
   641 
   662 
   642 /*!
   663 /*!
   643     \property QVideoWidget::aspectRatioMode
   664     \property QVideoWidget::aspectRatioMode
   644     \brief how video is scaled with respect to its aspect ratio.
   665     \brief how video is scaled with respect to its aspect ratio.
   878 {
   899 {
   879     Q_D(QVideoWidget);
   900     Q_D(QVideoWidget);
   880 
   901 
   881     QWidget::showEvent(event);
   902     QWidget::showEvent(event);
   882 
   903 
   883     d->show();
   904     // The window backend won't work for re-directed windows so use the renderer backend instead.
   884 
   905     if (d->windowBackend && window()->testAttribute(Qt::WA_DontShowOnScreen)) {
       
   906         d->windowBackend->releaseControl();
       
   907 
       
   908         delete d->windowBackend;
       
   909         d->windowBackend = 0;
       
   910 
       
   911         d->createRendererBackend();
       
   912     }
       
   913 
       
   914     if (d->currentBackend)
       
   915         d->currentBackend->showEvent();
   885 }
   916 }
   886 
   917 
   887 /*!
   918 /*!
   888 
   919 
   889   Handles the hide \a event.
   920   Handles the hide \a event.