1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Video: Initial video when call starts

This commit is contained in:
TheSpiritXIII 2015-08-18 17:44:34 -04:00
parent 814bd922ca
commit 50041a3140
12 changed files with 89 additions and 310 deletions

View File

@ -383,6 +383,7 @@ contains(ENABLE_SYSTRAY_GTK_BACKEND, NO) {
src/widget/form/setpassworddialog.cpp \
src/widget/form/tabcompleter.cpp \
src/ipc.cpp \
src/widget/flowlayout.cpp \
src/net/autoupdate.cpp \
src/widget/tool/callconfirmwidget.cpp \
src/widget/systemtrayicon.cpp \
@ -493,7 +494,6 @@ SOURCES += \
src/widget/genericchatitemlayout.cpp \
src/widget/categorywidget.cpp \
src/widget/tool/movablewidget.cpp \
src/widget/tool/flowlayout.cpp \
src/video/genericnetcamview.cpp \
src/video/groupnetcamview.cpp
@ -540,6 +540,5 @@ HEADERS += \
src/widget/genericchatitemlayout.h \
src/widget/categorywidget.h \
src/widget/tool/movablewidget.h \
src/widget/tool/flowlayout.h \
src/video/genericnetcamview.h \
src/video/groupnetcamview.h

View File

@ -227,6 +227,7 @@ void Settings::loadGlobal()
s.beginGroup("Video");
videoDev = s.value("videoDev", "").toString();
camVideoRes = s.value("camVideoRes",QSize()).toSize();
camVideoFPS = s.value("camVideoFPS", 0).toUInt();
s.endGroup();
// Read the embedded DHT bootsrap nodes list if needed
@ -422,6 +423,7 @@ void Settings::saveGlobal()
s.beginGroup("Video");
s.setValue("videoDev", videoDev);
s.setValue("camVideoRes",camVideoRes);
s.setValue("camVideoFPS",camVideoFPS);
s.endGroup();
}
@ -1175,6 +1177,19 @@ void Settings::setCamVideoRes(QSize newValue)
camVideoRes = newValue;
}
unsigned short Settings::getCamVideoFPS() const
{
QMutexLocker locker{&bigLock};
return camVideoFPS;
}
void Settings::setCamVideoFPS(unsigned short newValue)
{
QMutexLocker locker{&bigLock};
camVideoFPS = newValue;
}
QString Settings::getFriendAdress(const QString &publicKey) const
{
QMutexLocker locker{&bigLock};

View File

@ -163,6 +163,9 @@ public:
QSize getCamVideoRes() const;
void setCamVideoRes(QSize newValue);
unsigned short getCamVideoFPS() const;
void setCamVideoFPS(unsigned short newValue);
bool isAnimationEnabled() const;
void setAnimationEnabled(bool newValue);
@ -356,6 +359,7 @@ private:
// Video
QString videoDev;
QSize camVideoRes;
unsigned short camVideoFPS;
struct friendProp
{

View File

@ -24,8 +24,8 @@
#include <QTimer>
#include <QMap>
#include "src/audio/audio.h"
#include "src/widget/tool/flowlayout.h"
#include "src/core/core.h"
#include <QBoxLayout>
class LabeledVideo : public QFrame
{
@ -34,7 +34,7 @@ public:
: QFrame(parent)
{
//setFrameStyle(QFrame::Box);
videoSurface = new VideoSurface(-1, 0, expanding);
videoSurface = new VideoSurface(QPixmap(), 0, expanding);
videoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
videoSurface->setMinimumHeight(96);
//videoSurface->setMaximumHeight(96);
@ -133,13 +133,13 @@ GroupNetCamView::GroupNetCamView(int group, QWidget *parent)
//FlowLayout* horLayout = new FlowLayout(widget);
horLayout->addStretch();
LabeledVideo* labeledVideo = new LabeledVideo(this);
horLayout->addWidget(labeledVideo);
horLayout->setAlignment(labeledVideo, Qt::AlignCenter | Qt::AlignHCenter);
selfVideoSurface = new LabeledVideo(this);
horLayout->addWidget(selfVideoSurface);
horLayout->setAlignment(selfVideoSurface, Qt::AlignCenter | Qt::AlignHCenter);
horLayout->addStretch();
verLayout->insertWidget(1, scrollArea);
scrollArea->setMinimumHeight(labeledVideo->height());
scrollArea->setMinimumHeight(selfVideoSurface->height());
connect(&Audio::getInstance(), &Audio::groupAudioPlayed, this, &GroupNetCamView::groupAudioPlayed);
@ -147,6 +147,18 @@ GroupNetCamView::GroupNetCamView(int group, QWidget *parent)
timer->setInterval(1000);
connect(timer, &QTimer::timeout, this, &GroupNetCamView::findActivePeer);
timer->start();
connect(Core::getInstance(), &Core::selfAvatarChanged, [this]()
{
selfVideoSurface->update();
findActivePeer();
});
connect(Core::getInstance(), &Core::usernameSet, [this](const QString& username)
{
selfVideoSurface->setText(username);
findActivePeer();
});
selfVideoSurface->setText(Core::getInstance()->getUsername());
}
void GroupNetCamView::clearPeers()
@ -184,18 +196,16 @@ void GroupNetCamView::removePeer(int peer)
findActivePeer();
}
}
#include <QDebug>
void GroupNetCamView::setActive(int peer)
{
qDebug() << "HI: " << peer;
if (peer == -1)
{
// Show self.
videoLabelSurface->setText(selfVideoSurface->getText());
return;
}
auto peerVideo = videoList.find(peer);
qDebug() << "BTW" << (peerVideo == videoList.end());
if (peerVideo != videoList.end())
{

View File

@ -52,6 +52,7 @@ private:
QHBoxLayout* horLayout;
QMap<int, PeerVideo> videoList;
LabeledVideo* videoLabelSurface;
LabeledVideo* selfVideoSurface;
int activePeer;
int group;
};

View File

@ -19,9 +19,12 @@
#include "netcamview.h"
#include "camerasource.h"
#include "src/friend.h"
#include "src/friendlist.h"
#include "src/core/core.h"
#include "src/video/videosurface.h"
#include "src/widget/tool/movablewidget.h"
#include "src/persistence/settings.h"
#include <QLabel>
#include <QBoxLayout>
#include <QFrame>
@ -30,13 +33,14 @@ NetCamView::NetCamView(int friendId, QWidget* parent)
: GenericNetCamView(parent)
, selfFrame{nullptr}
{
videoSurface = new VideoSurface(friendId, this);
QString id = FriendList::findFriend(friendId)->getToxId().toString();
videoSurface = new VideoSurface(Settings::getInstance().getSavedAvatar(id), this);
videoSurface->setMinimumHeight(256);
videoSurface->setContentsMargins(6, 6, 6, 6);
verLayout->insertWidget(0, videoSurface, 1);
selfVideoSurface = new VideoSurface(-1, this, true);
selfVideoSurface = new VideoSurface(Settings::getInstance().getSavedAvatar(Core::getInstance()->getSelfId().toString()), this, true);
selfVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
selfVideoSurface->setMouseTracking(true);
selfVideoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
@ -65,6 +69,13 @@ NetCamView::NetCamView(int friendId, QWidget* parent)
updateFrameSize(boundingRect.size());
selfFrame->resetBoundary(boundingRect);
});
VideoMode videoMode;
QSize videoSize = Settings::getInstance().getCamVideoRes();
videoMode.width = videoSize.width();
videoMode.height = videoSize.height();
videoMode.FPS = Settings::getInstance().getCamVideoFPS();
CameraSource::getInstance().open(Settings::getInstance().getVideoDev(), videoMode);
}
void NetCamView::show(VideoSource *source, const QString &title)

View File

@ -32,20 +32,20 @@ float getSizeRatio(const QSize size)
return size.width() / static_cast<float>(size.height());
}
VideoSurface::VideoSurface(int friendId, QWidget* parent, bool expanding)
VideoSurface::VideoSurface(const QPixmap& avatar, QWidget* parent, bool expanding)
: QWidget{parent}
, source{nullptr}
, frameLock{false}
, hasSubscribed{0}
, friendId{friendId}
, avatar{avatar}
, ratio{1.0f}
, expanding{expanding}
{
recalulateBounds();
}
VideoSurface::VideoSurface(int friendId, VideoSource *source, QWidget* parent)
: VideoSurface(friendId, parent)
VideoSurface::VideoSurface(const QPixmap& avatar, VideoSource *source, QWidget* parent)
: VideoSurface(avatar, parent)
{
setSource(source);
}
@ -82,6 +82,16 @@ float VideoSurface::getRatio() const
return ratio;
}
void VideoSurface::setAvatar(const QPixmap &pixmap)
{
avatar = pixmap;
}
QPixmap VideoSurface::getAvatar() const
{
return avatar;
}
void VideoSurface::subscribe()
{
assert(hasSubscribed >= 0);
@ -154,21 +164,12 @@ void VideoSurface::paintEvent(QPaintEvent*)
else
{
painter.fillRect(boundingRect, Qt::white);
QPixmap avatar;
QPixmap drawnAvatar = avatar;
QString userId;
if (drawnAvatar.isNull())
drawnAvatar = Style::scaleSvgImage(":/img/contact_dark.svg", boundingRect.width(), boundingRect.height());
if (friendId != -1)
userId = FriendList::findFriend(friendId)->getToxId().toString();
else
userId = Core::getInstance()->getSelfId().toString();
avatar = Settings::getInstance().getSavedAvatar(userId);
if (avatar.isNull())
avatar = Style::scaleSvgImage(":/img/contact_dark.svg", boundingRect.width(), boundingRect.height());
painter.drawPixmap(boundingRect, avatar, avatar.rect());
painter.drawPixmap(boundingRect, drawnAvatar, drawnAvatar.rect());
}
unlock();
@ -185,7 +186,7 @@ void VideoSurface::showEvent(QShowEvent*)
{
//emit ratioChanged();
}
#include <QDebug>
void VideoSurface::recalulateBounds()
{
if (expanding)
@ -209,8 +210,6 @@ void VideoSurface::recalulateBounds()
boundingRect.setRect(pos.x(), pos.y(), size.width(), size.height());
}
qDebug() << contentsRect();
update();
}

View File

@ -30,14 +30,16 @@ class VideoSurface : public QWidget
Q_OBJECT
public:
VideoSurface(int friendId, QWidget* parent = 0, bool expanding = false);
VideoSurface(int friendId, VideoSource* source, QWidget* parent = 0);
VideoSurface(const QPixmap& avatar, QWidget* parent = 0, bool expanding = false);
VideoSurface(const QPixmap& avatar, VideoSource* source, QWidget* parent = 0);
~VideoSurface();
bool isExpanding() const;
void setSource(VideoSource* src); //NULL is a valid option
QRect getBoundingRect() const;
float getRatio() const;
void setAvatar(const QPixmap& pixmap);
QPixmap getAvatar() const;
signals:
void ratioChanged();
@ -64,7 +66,7 @@ private:
std::shared_ptr<VideoFrame> lastFrame;
std::atomic_bool frameLock; ///< Fast lock for lastFrame
uint8_t hasSubscribed;
int friendId;
QPixmap avatar;
float ratio;
bool expanding;
};

View File

@ -102,6 +102,7 @@ void AVForm::on_videoModescomboBox_currentIndexChanged(int index)
QString devName = videoDeviceList[devIndex].first;
VideoMode mode = videoModes[index];
Settings::getInstance().setCamVideoRes(QSize(mode.width, mode.height));
Settings::getInstance().setCamVideoFPS(mode.FPS);
camera.open(devName, mode);
}
@ -123,10 +124,11 @@ void AVForm::updateVideoModes(int curIndex)
bodyUI->videoModescomboBox->clear();
int prefResIndex = -1;
QSize prefRes = Settings::getInstance().getCamVideoRes();
unsigned short prefFPS = Settings::getInstance().getCamVideoFPS();
for (int i=0; i<videoModes.size(); ++i)
{
VideoMode mode = videoModes[i];
if (mode.width==prefRes.width() && mode.height==prefRes.height() && prefResIndex==-1)
if (mode.width==prefRes.width() && mode.height==prefRes.height() && mode.FPS == prefFPS && prefResIndex==-1)
prefResIndex = i;
QString str;
if (mode.height && mode.width)
@ -192,9 +194,11 @@ void AVForm::onVideoDevChanged(int index)
updateVideoModes(index);
bodyUI->videoModescomboBox->blockSignals(previouslyBlocked);
camera.open(dev);
killVideoSurface();
createVideoSurface();
}
void AVForm::onResProbingFinished(QList<QSize> res)
/*void AVForm::onResProbingFinished(QList<QSize> res)
{
QSize savedRes = Settings::getInstance().getCamVideoRes();
int savedResIndex = -1;
@ -215,7 +219,7 @@ void AVForm::onResProbingFinished(QList<QSize> res)
bodyUI->videoModescomboBox->setCurrentIndex(savedResIndex);
else
bodyUI->videoModescomboBox->setCurrentIndex(bodyUI->videoModescomboBox->count()-1);
}
}*/
void AVForm::hideEvent(QHideEvent *)
{
@ -242,7 +246,7 @@ void AVForm::getVideoDevices()
videoDevIndex = bodyUI->videoDevCombobox->count()-1;
}
//addItem changes currentIndex -> reset
bodyUI->videoDevCombobox->setCurrentIndex(-1);
//bodyUI->videoDevCombobox->setCurrentIndex(-1);
bodyUI->videoDevCombobox->setCurrentIndex(videoDevIndex);
bodyUI->videoDevCombobox->blockSignals(false);
updateVideoModes(videoDevIndex);
@ -361,7 +365,7 @@ void AVForm::createVideoSurface()
{
if (camVideoSurface)
return;
camVideoSurface = new VideoSurface(-1, bodyUI->CamFrame);
camVideoSurface = new VideoSurface(QPixmap(), bodyUI->CamFrame);
camVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
camVideoSurface->setMinimumSize(QSize(160, 120));
camVideoSurface->setSource(&camera);

View File

@ -63,7 +63,7 @@ private slots:
// camera
void onVideoDevChanged(int index);
void onResProbingFinished(QList<QSize> res);
//void onResProbingFinished(QList<QSize> res);
virtual void hideEvent(QHideEvent*) final override;
virtual void showEvent(QShowEvent*) final override;

View File

@ -1,190 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtWidgets>
#include "flowlayout.h"
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
: m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
FlowLayout::~FlowLayout()
{
QLayoutItem *item;
while ((item = takeAt(0)))
delete item;
}
void FlowLayout::addItem(QLayoutItem *item)
{
itemList.append(item);
}
int FlowLayout::horizontalSpacing() const
{
if (m_hSpace >= 0) {
return m_hSpace;
} else {
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
}
}
int FlowLayout::verticalSpacing() const
{
if (m_vSpace >= 0) {
return m_vSpace;
} else {
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}
}
int FlowLayout::count() const
{
return itemList.size();
}
QLayoutItem *FlowLayout::itemAt(int index) const
{
return itemList.value(index);
}
QLayoutItem *FlowLayout::takeAt(int index)
{
if (index >= 0 && index < itemList.size())
return itemList.takeAt(index);
else
return 0;
}
Qt::Orientations FlowLayout::expandingDirections() const
{
return 0;
}
bool FlowLayout::hasHeightForWidth() const
{
return true;
}
int FlowLayout::heightForWidth(int width) const
{
int height = doLayout(QRect(0, 0, width, 0), true);
return height;
}
void FlowLayout::setGeometry(const QRect &rect)
{
QLayout::setGeometry(rect);
doLayout(rect, false);
}
QSize FlowLayout::sizeHint() const
{
return minimumSize();
}
QSize FlowLayout::minimumSize() const
{
QSize size;
QLayoutItem *item;
foreach (item, itemList)
size = size.expandedTo(item->minimumSize());
size += QSize(2*margin(), 2*margin());
return size;
}
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
{
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;
QLayoutItem *item;
foreach (item, itemList) {
QWidget *wid = item->widget();
int spaceX = horizontalSpacing();
if (spaceX == -1)
spaceX = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
int spaceY = verticalSpacing();
if (spaceY == -1)
spaceY = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
int nextX = x + item->sizeHint().width() + spaceX;
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}
if (!testOnly)
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}
return y + lineHeight - rect.y() + bottom;
}
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
{
QObject *parent = this->parent();
if (!parent) {
return -1;
} else if (parent->isWidgetType()) {
QWidget *pw = static_cast<QWidget *>(parent);
return pw->style()->pixelMetric(pm, 0, pw);
} else {
return static_cast<QLayout *>(parent)->spacing();
}
}

View File

@ -1,76 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef FLOWLAYOUT_H
#define FLOWLAYOUT_H
#include <QLayout>
#include <QRect>
#include <QStyle>
class FlowLayout : public QLayout
{
public:
explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
~FlowLayout();
void addItem(QLayoutItem *item) Q_DECL_OVERRIDE;
int horizontalSpacing() const;
int verticalSpacing() const;
Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE;
bool hasHeightForWidth() const Q_DECL_OVERRIDE;
int heightForWidth(int) const Q_DECL_OVERRIDE;
int count() const Q_DECL_OVERRIDE;
QLayoutItem *itemAt(int index) const Q_DECL_OVERRIDE;
QSize minimumSize() const Q_DECL_OVERRIDE;
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
QSize sizeHint() const Q_DECL_OVERRIDE;
QLayoutItem *takeAt(int index) Q_DECL_OVERRIDE;
private:
int doLayout(const QRect &rect, bool testOnly) const;
int smartSpacing(QStyle::PixelMetric pm) const;
QList<QLayoutItem *> itemList;
int m_hSpace;
int m_vSpace;
};
#endif // FLOWLAYOUT_H