blob: aad2a0ee9526a50a32610bf02e0dea0d47bf3686 [file] [log] [blame]
Edric Milaret627500d2015-03-27 16:41:40 -04001/***************************************************************************
Edric Milaret4bba46d2015-04-29 16:33:38 -04002 * Copyright (C) 2015 by Savoir-Faire Linux *
Edric Milaret627500d2015-03-27 16:41:40 -04003 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
19#include "videowidget.h"
20
Edric Milaret627500d2015-03-27 16:41:40 -040021VideoWidget::VideoWidget(QWidget *parent) :
22 QWidget(parent)
23 , previewRenderer_(nullptr)
24 , renderer_(nullptr)
Eloi BAILd94e0662015-09-21 13:58:31 -040025 , currentDistantFrame_(nullptr)
26 , currentPreviewFrame_(nullptr)
Edric Milaret627500d2015-03-27 16:41:40 -040027{
28 connect(Video::PreviewManager::instance(),
29 SIGNAL(previewStarted(Video::Renderer*)),
Edric Milaret72c406d2015-04-28 13:23:54 -040030 this, SLOT(previewStarted(Video::Renderer*)));
Edric Milaret627500d2015-03-27 16:41:40 -040031 connect(CallModel::instance(),
32 SIGNAL(rendererAdded(Call*,Video::Renderer*)),
33 this, SLOT(callInitiated(Call*, Video::Renderer*)),
34 Qt::ConnectionType::DirectConnection);
Edric Milareta9f937f2015-06-01 17:10:34 -040035
36 QPalette pal(palette());
37 pal.setColor(QPalette::Background, Qt::black);
38 this->setAutoFillBackground(true);
39 this->setPalette(pal);
Edric Milaret627500d2015-03-27 16:41:40 -040040}
41
42VideoWidget::~VideoWidget()
43{}
44
45void
46VideoWidget::previewStarted(Video::Renderer *renderer) {
Eloi BAILd94e0662015-09-21 13:58:31 -040047 //Enforce that only one videowidget we'll be used at the same time
48 if (not isVisible())
49 return;
Edric Milaret53971612015-07-15 10:00:04 -040050 previewRenderer_ = renderer;
51 connect(previewRenderer_, SIGNAL(frameUpdated()),
52 this, SLOT(frameFromPreview()));
53 connect(previewRenderer_, SIGNAL(stopped()),
54 this, SLOT(previewStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -040055}
56
57void
Edric Milaret72c406d2015-04-28 13:23:54 -040058VideoWidget::previewStopped() {
Edric Milaret72c406d2015-04-28 13:23:54 -040059 disconnect(previewRenderer_, SIGNAL(frameUpdated()),
Edric Milaret1eca0292015-06-29 12:03:36 -040060 this, SLOT(frameFromPreview()));
Edric Milaret72c406d2015-04-28 13:23:54 -040061 disconnect(previewRenderer_, SIGNAL(stopped()),
Edric Milaret1eca0292015-06-29 12:03:36 -040062 this, SLOT(renderingStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -040063 previewRenderer_ = nullptr;
Eloi BAILd94e0662015-09-21 13:58:31 -040064 if (currentPreviewFrame_) {
65 delete currentPreviewFrame_;
66 currentPreviewFrame_ = nullptr;
67 }
Edric Milaret627500d2015-03-27 16:41:40 -040068}
69
70void
71VideoWidget::frameFromPreview() {
Eloi BAILd94e0662015-09-21 13:58:31 -040072 if (previewRenderer_ && previewRenderer_->isRendering()) {
73 if (currentPreviewFrame_) {
74 delete currentPreviewFrame_;
75 currentPreviewFrame_ = nullptr;
76 }
77 const QSize size(previewRenderer_->size());
78 currentPreviewFrame_ = new QImage(
79 (const uchar*)previewRenderer_->currentFrame().constData(),
80 size.width(), size.height(), QImage::Format_ARGB32_Premultiplied);
81 repaint();
Edric Milaret627500d2015-03-27 16:41:40 -040082 }
Edric Milaret627500d2015-03-27 16:41:40 -040083}
84
85void
Edric Milaret1eca0292015-06-29 12:03:36 -040086VideoWidget::paintEvent(QPaintEvent *evt) {
Edric Milaret627500d2015-03-27 16:41:40 -040087 Q_UNUSED(evt)
Edric Milaret627500d2015-03-27 16:41:40 -040088 QPainter painter(this);
Edric Milaret1eca0292015-06-29 12:03:36 -040089 if (renderer_ && currentDistantFrame_) {
Eloi BAILd94e0662015-09-21 13:58:31 -040090 auto scaledDistant = currentDistantFrame_->scaled(size(), Qt::KeepAspectRatio);
Edric Milareta9f937f2015-06-01 17:10:34 -040091 auto xDiff = (width() - scaledDistant.width()) / 2;
92 auto yDiff = (height() - scaledDistant.height()) /2;
93 painter.drawImage(QRect(xDiff,yDiff,scaledDistant.width(),scaledDistant.height()), scaledDistant);
94 }
Edric Milaret1eca0292015-06-29 12:03:36 -040095 if (previewRenderer_ && currentPreviewFrame_) {
Edric Milareta9f937f2015-06-01 17:10:34 -040096 auto previewHeight = !renderer_ ? height() : height()/4;
97 auto previewWidth = !renderer_ ? width() : width()/4;
Eloi BAILd94e0662015-09-21 13:58:31 -040098 auto scaledPreview = currentPreviewFrame_->scaled(previewWidth, previewHeight, Qt::KeepAspectRatio);
Edric Milareta9f937f2015-06-01 17:10:34 -040099 auto xDiff = (previewWidth - scaledPreview.width()) / 2;
100 auto yDiff = (previewHeight - scaledPreview.height()) / 2;
101 auto yPos = !renderer_ ? yDiff : height() - previewHeight - previewMargin_;
102 auto xPos = !renderer_ ? xDiff : width() - scaledPreview.width() - previewMargin_;
103 painter.drawImage(QRect(xPos,yPos,scaledPreview.width(),scaledPreview.height()),
104 scaledPreview);
Edric Milaret627500d2015-03-27 16:41:40 -0400105 }
106 painter.end();
107}
108
109void
110VideoWidget::callInitiated(Call* call, Video::Renderer *renderer) {
111 Q_UNUSED(call)
Eloi BAILd94e0662015-09-21 13:58:31 -0400112 //Enforce that only one videowidget we'll be used at the same time
113 if (not isVisible())
114 return;
Edric Milaret53971612015-07-15 10:00:04 -0400115 renderer_ = renderer;
116 connect(renderer_, SIGNAL(frameUpdated()), this, SLOT(frameFromDistant()));
117 connect(renderer_, SIGNAL(stopped()),this, SLOT(renderingStopped()),
118 Qt::ConnectionType::DirectConnection);
Edric Milaret627500d2015-03-27 16:41:40 -0400119}
120
121void
122VideoWidget::frameFromDistant() {
Eloi BAILd94e0662015-09-21 13:58:31 -0400123 if (renderer_ && renderer_->isRendering()) {
124 if (currentDistantFrame_) {
125 delete currentDistantFrame_;
126 currentDistantFrame_ = nullptr;
127 }
128 const QSize size(renderer_->size());
129 currentDistantFrame_ = new QImage(
130 (const uchar*)renderer_->currentFrame().constData(),
131 size.width(), size.height(), QImage::Format_ARGB32_Premultiplied);
132 repaint();
Edric Milaret627500d2015-03-27 16:41:40 -0400133 }
Edric Milaret627500d2015-03-27 16:41:40 -0400134}
135
136void
137VideoWidget::renderingStopped() {
Edric Milaret72c406d2015-04-28 13:23:54 -0400138 disconnect(renderer_, SIGNAL(frameUpdated()), this, SLOT(frameFromDistant()));
139 disconnect(renderer_, SIGNAL(stopped()),this, SLOT(renderingStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -0400140 renderer_ = nullptr;
Eloi BAILd94e0662015-09-21 13:58:31 -0400141 if (currentDistantFrame_) {
142 delete currentDistantFrame_;
143 currentDistantFrame_ = nullptr;
144 }
Edric Milaret627500d2015-03-27 16:41:40 -0400145}