blob: 7c45e55af81cb4703d8f99f10d60d16a6e1b7e57 [file] [log] [blame]
Edric Milaret627500d2015-03-27 16:41:40 -04001/***************************************************************************
Edric Milaret5f316da2015-09-28 11:57:42 -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)
Edric Milaret627500d2015-03-27 16:41:40 -040025{
26 connect(Video::PreviewManager::instance(),
27 SIGNAL(previewStarted(Video::Renderer*)),
Edric Milaret72c406d2015-04-28 13:23:54 -040028 this, SLOT(previewStarted(Video::Renderer*)));
Edric Milaret627500d2015-03-27 16:41:40 -040029 connect(CallModel::instance(),
30 SIGNAL(rendererAdded(Call*,Video::Renderer*)),
31 this, SLOT(callInitiated(Call*, Video::Renderer*)),
32 Qt::ConnectionType::DirectConnection);
Edric Milareta9f937f2015-06-01 17:10:34 -040033
34 QPalette pal(palette());
35 pal.setColor(QPalette::Background, Qt::black);
36 this->setAutoFillBackground(true);
37 this->setPalette(pal);
Edric Milaret627500d2015-03-27 16:41:40 -040038}
39
40VideoWidget::~VideoWidget()
41{}
42
43void
44VideoWidget::previewStarted(Video::Renderer *renderer) {
Eloi BAILd94e0662015-09-21 13:58:31 -040045 //Enforce that only one videowidget we'll be used at the same time
46 if (not isVisible())
47 return;
Edric Milaret53971612015-07-15 10:00:04 -040048 previewRenderer_ = renderer;
49 connect(previewRenderer_, SIGNAL(frameUpdated()),
50 this, SLOT(frameFromPreview()));
51 connect(previewRenderer_, SIGNAL(stopped()),
52 this, SLOT(previewStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -040053}
54
55void
Edric Milaret72c406d2015-04-28 13:23:54 -040056VideoWidget::previewStopped() {
Edric Milaret72c406d2015-04-28 13:23:54 -040057 disconnect(previewRenderer_, SIGNAL(frameUpdated()),
Edric Milaret1eca0292015-06-29 12:03:36 -040058 this, SLOT(frameFromPreview()));
Edric Milaret72c406d2015-04-28 13:23:54 -040059 disconnect(previewRenderer_, SIGNAL(stopped()),
Edric Milaret1eca0292015-06-29 12:03:36 -040060 this, SLOT(renderingStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -040061 previewRenderer_ = nullptr;
62}
63
64void
65VideoWidget::frameFromPreview() {
Eloi BAILd94e0662015-09-21 13:58:31 -040066 if (previewRenderer_ && previewRenderer_->isRendering()) {
Edric Milaret37157b32015-10-13 18:00:03 -040067 {
68 QMutexLocker lock(&mutex_);
69 auto tmp = previewRenderer_->currentFrame();
70 if (tmp.storage.size())
71 currentPreviewFrame_ = tmp;
Eloi BAILd94e0662015-09-21 13:58:31 -040072 }
Edric Milaret37157b32015-10-13 18:00:03 -040073 update();
Edric Milaret627500d2015-03-27 16:41:40 -040074 }
Edric Milaret627500d2015-03-27 16:41:40 -040075}
76
77void
Edric Milaret1eca0292015-06-29 12:03:36 -040078VideoWidget::paintEvent(QPaintEvent *evt) {
Edric Milaret627500d2015-03-27 16:41:40 -040079 Q_UNUSED(evt)
Edric Milaret627500d2015-03-27 16:41:40 -040080 QPainter painter(this);
Edric Milaret37157b32015-10-13 18:00:03 -040081
82 if (renderer_) {
83 {
84 QMutexLocker lock(&mutex_);
85 if (currentDistantFrame_.storage.size() != 0) {
86 frameDistant_ = std::move(currentDistantFrame_.storage);
87 distantImage_.reset(new QImage((uchar*)frameDistant_.data(),
88 renderer_->size().width(),
89 renderer_->size().height(),
90 QImage::Format_ARGB32_Premultiplied));
91 }
92 }
93 if (distantImage_) {
94 auto scaledDistant = distantImage_->scaled(size(), Qt::KeepAspectRatio);
95 auto xDiff = (width() - scaledDistant.width()) / 2;
96 auto yDiff = (height() - scaledDistant.height()) /2;
97 painter.drawImage(QRect(xDiff,yDiff,scaledDistant.width(),scaledDistant.height()), scaledDistant);
98 }
Edric Milareta9f937f2015-06-01 17:10:34 -040099 }
Edric Milaret37157b32015-10-13 18:00:03 -0400100 if (previewRenderer_) {
101 {
102 QMutexLocker lock(&mutex_);
103 if (currentPreviewFrame_.storage.size() != 0) {
104 framePreview_ = std::move(currentPreviewFrame_.storage);
105 previewImage_.reset(new QImage((uchar*)framePreview_.data(),
106 previewRenderer_->size().width(),
107 previewRenderer_->size().height(),
108 QImage::Format_ARGB32_Premultiplied));
109
110 }
111 }
112 if (previewImage_) {
113 auto previewHeight = !renderer_ ? height() : height()/4;
114 auto previewWidth = !renderer_ ? width() : width()/4;
115 auto scaledPreview = previewImage_->scaled(previewWidth, previewHeight, Qt::KeepAspectRatio);
116 auto xDiff = (previewWidth - scaledPreview.width()) / 2;
117 auto yDiff = (previewHeight - scaledPreview.height()) / 2;
118 auto yPos = !renderer_ ? yDiff : height() - previewHeight - previewMargin_;
119 auto xPos = !renderer_ ? xDiff : width() - scaledPreview.width() - previewMargin_;
120 painter.drawImage(QRect(xPos,yPos,scaledPreview.width(),scaledPreview.height()),
121 scaledPreview);
122 }
Edric Milaret627500d2015-03-27 16:41:40 -0400123 }
124 painter.end();
125}
126
127void
128VideoWidget::callInitiated(Call* call, Video::Renderer *renderer) {
129 Q_UNUSED(call)
Eloi BAILd94e0662015-09-21 13:58:31 -0400130 //Enforce that only one videowidget we'll be used at the same time
131 if (not isVisible())
132 return;
Edric Milaret53971612015-07-15 10:00:04 -0400133 renderer_ = renderer;
134 connect(renderer_, SIGNAL(frameUpdated()), this, SLOT(frameFromDistant()));
135 connect(renderer_, SIGNAL(stopped()),this, SLOT(renderingStopped()),
136 Qt::ConnectionType::DirectConnection);
Edric Milaret627500d2015-03-27 16:41:40 -0400137}
138
139void
140VideoWidget::frameFromDistant() {
Eloi BAILd94e0662015-09-21 13:58:31 -0400141 if (renderer_ && renderer_->isRendering()) {
Edric Milaret37157b32015-10-13 18:00:03 -0400142 {
143 QMutexLocker lock(&mutex_);
144 auto tmp = renderer_->currentFrame();
145 if (tmp.storage.size())
146 currentDistantFrame_ = tmp;
147
Eloi BAILd94e0662015-09-21 13:58:31 -0400148 }
Edric Milaret37157b32015-10-13 18:00:03 -0400149 update();
Edric Milaret627500d2015-03-27 16:41:40 -0400150 }
Edric Milaret627500d2015-03-27 16:41:40 -0400151}
152
153void
154VideoWidget::renderingStopped() {
Edric Milaret72c406d2015-04-28 13:23:54 -0400155 disconnect(renderer_, SIGNAL(frameUpdated()), this, SLOT(frameFromDistant()));
156 disconnect(renderer_, SIGNAL(stopped()),this, SLOT(renderingStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -0400157 renderer_ = nullptr;
158}