blob: 16e764008056f4426193c4dfb75559d6b13b1424 [file] [log] [blame]
Edric Milaret627500d2015-03-27 16:41:40 -04001/***************************************************************************
Anthony LĂ©onard2fde81d2017-04-17 10:06:55 -04002 * Copyright (C) 2015-2017 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 Milaret25236d92016-03-28 09:40:58 -040021#include "utils.h"
22
Edric Milaret80e0b212015-10-16 10:07:43 -040023VideoWidget::VideoWidget(QWidget* parent) :
Edric Milaret627500d2015-03-27 16:41:40 -040024 QWidget(parent)
25 , previewRenderer_(nullptr)
26 , renderer_(nullptr)
Edric Milaret80e0b212015-10-16 10:07:43 -040027 , isPreviewDisplayed_(true)
Edric Milaret0b7fe5d2016-01-27 11:12:43 -050028 , fullPreview_(false)
Edric Milaret627500d2015-03-27 16:41:40 -040029{
Edric Milareta3e47282015-10-23 15:20:30 -040030 connect(&Video::PreviewManager::instance(),
Edric Milaret627500d2015-03-27 16:41:40 -040031 SIGNAL(previewStarted(Video::Renderer*)),
Edric Milaret72c406d2015-04-28 13:23:54 -040032 this, SLOT(previewStarted(Video::Renderer*)));
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
Edric Milaret80e0b212015-10-16 10:07:43 -040044VideoWidget::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;
Nicolas Jagerc7b8e4b2016-02-29 09:20:40 -050048
49 resetPreview_ = true;
50
Edric Milaret80e0b212015-10-16 10:07:43 -040051 if (previewRenderer_ == renderer)
52 return;
Edric Milaret53971612015-07-15 10:00:04 -040053 previewRenderer_ = renderer;
54 connect(previewRenderer_, SIGNAL(frameUpdated()),
55 this, SLOT(frameFromPreview()));
56 connect(previewRenderer_, SIGNAL(stopped()),
57 this, SLOT(previewStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -040058}
59
60void
Edric Milaret72c406d2015-04-28 13:23:54 -040061VideoWidget::previewStopped() {
Edric Milaret72c406d2015-04-28 13:23:54 -040062 disconnect(previewRenderer_, SIGNAL(frameUpdated()),
Edric Milaret1eca0292015-06-29 12:03:36 -040063 this, SLOT(frameFromPreview()));
Edric Milaret72c406d2015-04-28 13:23:54 -040064 disconnect(previewRenderer_, SIGNAL(stopped()),
Edric Milaret80e0b212015-10-16 10:07:43 -040065 this, SLOT(previewStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -040066 previewRenderer_ = nullptr;
Edric Milaret8f0a9ba2016-02-02 14:40:40 -050067 repaint();
Edric Milaret627500d2015-03-27 16:41:40 -040068}
69
70void
71VideoWidget::frameFromPreview() {
Eloi BAILd94e0662015-09-21 13:58:31 -040072 if (previewRenderer_ && previewRenderer_->isRendering()) {
Edric Milaret37157b32015-10-13 18:00:03 -040073 {
74 QMutexLocker lock(&mutex_);
75 auto tmp = previewRenderer_->currentFrame();
76 if (tmp.storage.size())
77 currentPreviewFrame_ = tmp;
Eloi BAILd94e0662015-09-21 13:58:31 -040078 }
Edric Milaret37157b32015-10-13 18:00:03 -040079 update();
Edric Milaret627500d2015-03-27 16:41:40 -040080 }
Edric Milaret627500d2015-03-27 16:41:40 -040081}
82
83void
Edric Milaret80e0b212015-10-16 10:07:43 -040084VideoWidget::paintEvent(QPaintEvent* evt) {
Edric Milaret627500d2015-03-27 16:41:40 -040085 Q_UNUSED(evt)
Edric Milaret627500d2015-03-27 16:41:40 -040086 QPainter painter(this);
Edric Milaret37157b32015-10-13 18:00:03 -040087
88 if (renderer_) {
89 {
90 QMutexLocker lock(&mutex_);
Edric Milaret571af072015-11-12 16:26:49 -050091 if (currentDistantFrame_.storage.size() != 0
92 && currentDistantFrame_.storage.size() ==
Edric Milaretbf674312016-01-25 10:59:11 -050093 (unsigned int)(renderer_->size().height()*renderer_->size().width()*4)) {
Edric Milaret37157b32015-10-13 18:00:03 -040094 frameDistant_ = std::move(currentDistantFrame_.storage);
95 distantImage_.reset(new QImage((uchar*)frameDistant_.data(),
96 renderer_->size().width(),
97 renderer_->size().height(),
98 QImage::Format_ARGB32_Premultiplied));
99 }
100 }
101 if (distantImage_) {
102 auto scaledDistant = distantImage_->scaled(size(), Qt::KeepAspectRatio);
103 auto xDiff = (width() - scaledDistant.width()) / 2;
Nicolas Jagerc7b8e4b2016-02-29 09:20:40 -0500104 auto yDiff = (height() - scaledDistant.height()) / 2;
Edric Milaret37157b32015-10-13 18:00:03 -0400105 painter.drawImage(QRect(xDiff,yDiff,scaledDistant.width(),scaledDistant.height()), scaledDistant);
106 }
Edric Milareta9f937f2015-06-01 17:10:34 -0400107 }
Andreas Traczyk6c323c62018-12-26 13:04:22 -0500108 if ((previewRenderer_ && isPreviewDisplayed_) || (photoMode_ && hasFrame_)) {
109 if (previewRenderer_) {
Edric Milaret37157b32015-10-13 18:00:03 -0400110 QMutexLocker lock(&mutex_);
Edric Milaret571af072015-11-12 16:26:49 -0500111 if (currentPreviewFrame_.storage.size() != 0
112 && currentPreviewFrame_.storage.size() ==
Edric Milaretbf674312016-01-25 10:59:11 -0500113 (unsigned int)(previewRenderer_->size().height()*previewRenderer_->size().width()*4)) {
Edric Milaret37157b32015-10-13 18:00:03 -0400114 framePreview_ = std::move(currentPreviewFrame_.storage);
115 previewImage_.reset(new QImage((uchar*)framePreview_.data(),
116 previewRenderer_->size().width(),
117 previewRenderer_->size().height(),
118 QImage::Format_ARGB32_Premultiplied));
Andreas Traczyk6c323c62018-12-26 13:04:22 -0500119 hasFrame_ = true;
Edric Milaret37157b32015-10-13 18:00:03 -0400120
121 }
122 }
123 if (previewImage_) {
Nicolas Jagerc7b8e4b2016-02-29 09:20:40 -0500124 if(resetPreview_) {
125 auto previewHeight = fullPreview_ ? height() : height() / 4;
126 auto previewWidth = fullPreview_ ? width() : width() / 4;
Edric Milaret25236d92016-03-28 09:40:58 -0400127 QImage scaledPreview;
128 if (photoMode_)
129 scaledPreview = Utils::getCirclePhoto(*previewImage_, previewHeight);
130 else
131 scaledPreview = previewImage_->scaled(previewWidth, previewHeight, Qt::KeepAspectRatio);
Nicolas Jagerc7b8e4b2016-02-29 09:20:40 -0500132 auto xDiff = (previewWidth - scaledPreview.width()) / 2;
133 auto yDiff = (previewHeight - scaledPreview.height()) / 2;
134 auto yPos = fullPreview_ ? yDiff : height() - previewHeight - previewMargin_;
135 auto xPos = fullPreview_ ? xDiff : width() - scaledPreview.width() - previewMargin_;
136 previewGeometry_.setRect(xPos, yPos, scaledPreview.width(), scaledPreview.height());
137 painter.drawImage(previewGeometry_, scaledPreview);
138 resetPreview_ = false;
139 }
140
Edric Milaret25236d92016-03-28 09:40:58 -0400141 QImage scaledPreview;
142 if (photoMode_)
143 scaledPreview = Utils::getCirclePhoto(*previewImage_, previewGeometry_.height());
144 else
145 scaledPreview = previewImage_->scaled(previewGeometry_.width(),
146 previewGeometry_.height(),
147 Qt::KeepAspectRatio);
Nicolas Jagerc7b8e4b2016-02-29 09:20:40 -0500148 previewGeometry_.setWidth(scaledPreview.width());
149 previewGeometry_.setHeight(scaledPreview.height());
Edric Milaret25236d92016-03-28 09:40:58 -0400150
Nicolas Jagerc7b8e4b2016-02-29 09:20:40 -0500151 painter.drawImage(previewGeometry_, scaledPreview);
Edric Milaret37157b32015-10-13 18:00:03 -0400152 }
Andreas Traczyk6c323c62018-12-26 13:04:22 -0500153 } else if (photoMode_) {
154 paintBackgroundColor(&painter, Qt::black);
Edric Milaret627500d2015-03-27 16:41:40 -0400155 }
156 painter.end();
157}
158
159void
Andreas Traczyk6c323c62018-12-26 13:04:22 -0500160VideoWidget::paintBackgroundColor(QPainter* painter, QColor color)
161{
162 QImage black(1, 1, QImage::Format_ARGB32);
163 black.fill(color);
164 QImage scaledPreview = Utils::getCirclePhoto(black, height());
165 previewGeometry_.setWidth(scaledPreview.width());
166 previewGeometry_.setHeight(scaledPreview.height());
167 painter->drawImage(previewGeometry_, scaledPreview);
168}
169
170void
Edric Milaret80e0b212015-10-16 10:07:43 -0400171VideoWidget::setDistantRenderer(Video::Renderer* renderer) {
172 if (not renderer)
Eloi BAILd94e0662015-09-21 13:58:31 -0400173 return;
Edric Milaret80e0b212015-10-16 10:07:43 -0400174 if (renderer_ != renderer) {
175 renderingStopped();
176 renderer_ = renderer;
177 connect(renderer_, SIGNAL(frameUpdated()), this, SLOT(frameFromDistant()));
178 connect(renderer_, SIGNAL(stopped()),this, SLOT(renderingStopped()));
179 }
Edric Milaret627500d2015-03-27 16:41:40 -0400180}
181
182void
183VideoWidget::frameFromDistant() {
Eloi BAILd94e0662015-09-21 13:58:31 -0400184 if (renderer_ && renderer_->isRendering()) {
Edric Milaret37157b32015-10-13 18:00:03 -0400185 {
186 QMutexLocker lock(&mutex_);
187 auto tmp = renderer_->currentFrame();
188 if (tmp.storage.size())
189 currentDistantFrame_ = tmp;
Eloi BAILd94e0662015-09-21 13:58:31 -0400190 }
Edric Milaret37157b32015-10-13 18:00:03 -0400191 update();
Edric Milaret627500d2015-03-27 16:41:40 -0400192 }
Edric Milaret627500d2015-03-27 16:41:40 -0400193}
194
195void
196VideoWidget::renderingStopped() {
Edric Milaret80e0b212015-10-16 10:07:43 -0400197 if (not renderer_)
198 return;
Edric Milaret72c406d2015-04-28 13:23:54 -0400199 disconnect(renderer_, SIGNAL(frameUpdated()), this, SLOT(frameFromDistant()));
200 disconnect(renderer_, SIGNAL(stopped()),this, SLOT(renderingStopped()));
Edric Milaret627500d2015-03-27 16:41:40 -0400201 renderer_ = nullptr;
Edric Milaret8f0a9ba2016-02-02 14:40:40 -0500202 repaint();
Edric Milaret627500d2015-03-27 16:41:40 -0400203}
Edric Milaret80e0b212015-10-16 10:07:43 -0400204
205void
206VideoWidget::setPreviewDisplay(bool display) {
207 isPreviewDisplayed_ = display;
208}
Edric Milaret0b7fe5d2016-01-27 11:12:43 -0500209
210void
211VideoWidget::setIsFullPreview(bool full) {
212 fullPreview_ = full;
213}
Edric Milaret25236d92016-03-28 09:40:58 -0400214
215QImage
216VideoWidget::takePhoto() {
217 if (previewImage_)
218 return previewImage_.get()->copy();
219 return QImage();
220}
221
222void
223VideoWidget::setPhotoMode(bool isPhotoMode) {
224
225 photoMode_ = isPhotoMode;
226 auto color = isPhotoMode ? Qt::transparent : Qt::black;
227
228 QPalette pal(palette());
229 pal.setColor(QPalette::Background, color);
230 setAutoFillBackground(true);
231 setPalette(pal);
232}