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))); |
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 { |
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))); |
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) |
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. |