mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
refactor: Remove CameraSource singleton
Grossly expose it publicly from Nexus for the time being since Profile is sometimes constructed from main, while Nexus is also a singleton. So CameraSource can't be constructed in main and be passed in to Nexus on construction. This should be temporary, until Nexus's singleton is removed as well.
This commit is contained in:
parent
9bf17acca6
commit
61b3cb528a
|
@ -71,7 +71,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CoreAV::CoreAV(std::unique_ptr<ToxAV, ToxAVDeleter> toxav_, CompatibleRecursiveMutex& toxCoreLock,
|
CoreAV::CoreAV(std::unique_ptr<ToxAV, ToxAVDeleter> toxav_, CompatibleRecursiveMutex& toxCoreLock,
|
||||||
IAudioSettings& audioSettings_, IGroupSettings& groupSettings_)
|
IAudioSettings& audioSettings_, IGroupSettings& groupSettings_, CameraSource& cameraSource_)
|
||||||
: audio{nullptr}
|
: audio{nullptr}
|
||||||
, toxav{std::move(toxav_)}
|
, toxav{std::move(toxav_)}
|
||||||
, coreavThread{new QThread{this}}
|
, coreavThread{new QThread{this}}
|
||||||
|
@ -79,6 +79,7 @@ CoreAV::CoreAV(std::unique_ptr<ToxAV, ToxAVDeleter> toxav_, CompatibleRecursiveM
|
||||||
, coreLock{toxCoreLock}
|
, coreLock{toxCoreLock}
|
||||||
, audioSettings{audioSettings_}
|
, audioSettings{audioSettings_}
|
||||||
, groupSettings{groupSettings_}
|
, groupSettings{groupSettings_}
|
||||||
|
, cameraSource{cameraSource_}
|
||||||
{
|
{
|
||||||
assert(coreavThread);
|
assert(coreavThread);
|
||||||
assert(iterateTimer);
|
assert(iterateTimer);
|
||||||
|
@ -111,7 +112,8 @@ void CoreAV::connectCallbacks()
|
||||||
* @return CoreAV instance on success, {} on failure
|
* @return CoreAV instance on success, {} on failure
|
||||||
*/
|
*/
|
||||||
CoreAV::CoreAVPtr CoreAV::makeCoreAV(Tox* core, CompatibleRecursiveMutex& toxCoreLock,
|
CoreAV::CoreAVPtr CoreAV::makeCoreAV(Tox* core, CompatibleRecursiveMutex& toxCoreLock,
|
||||||
IAudioSettings& audioSettings, IGroupSettings& groupSettings)
|
IAudioSettings& audioSettings, IGroupSettings& groupSettings,
|
||||||
|
CameraSource& cameraSource)
|
||||||
{
|
{
|
||||||
Toxav_Err_New err;
|
Toxav_Err_New err;
|
||||||
std::unique_ptr<ToxAV, ToxAVDeleter> toxav{toxav_new(core, &err)};
|
std::unique_ptr<ToxAV, ToxAVDeleter> toxav{toxav_new(core, &err)};
|
||||||
|
@ -131,7 +133,8 @@ CoreAV::CoreAVPtr CoreAV::makeCoreAV(Tox* core, CompatibleRecursiveMutex& toxCor
|
||||||
|
|
||||||
assert(toxav != nullptr);
|
assert(toxav != nullptr);
|
||||||
|
|
||||||
return CoreAVPtr{new CoreAV{std::move(toxav), toxCoreLock, audioSettings, groupSettings}};
|
return CoreAVPtr{new CoreAV{std::move(toxav), toxCoreLock, audioSettings,
|
||||||
|
groupSettings, cameraSource}};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -288,7 +291,8 @@ bool CoreAV::startCall(uint32_t friendNum, bool video)
|
||||||
|
|
||||||
// Audio backend must be set before making a call
|
// Audio backend must be set before making a call
|
||||||
assert(audio != nullptr);
|
assert(audio != nullptr);
|
||||||
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall(friendNum, video, *this, *audio));
|
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall(friendNum, video,
|
||||||
|
*this, *audio, cameraSource));
|
||||||
// Call object must be owned by this thread or there will be locking problems with Audio
|
// Call object must be owned by this thread or there will be locking problems with Audio
|
||||||
call->moveToThread(thread());
|
call->moveToThread(thread());
|
||||||
assert(call != nullptr);
|
assert(call != nullptr);
|
||||||
|
@ -722,7 +726,8 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid
|
||||||
|
|
||||||
// Audio backend must be set before receiving a call
|
// Audio backend must be set before receiving a call
|
||||||
assert(self->audio != nullptr);
|
assert(self->audio != nullptr);
|
||||||
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall{friendNum, video, *self, *self->audio});
|
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall{friendNum, video,
|
||||||
|
*self, *self->audio, self->cameraSource});
|
||||||
// Call object must be owned by CoreAV thread or there will be locking problems with Audio
|
// Call object must be owned by CoreAV thread or there will be locking problems with Audio
|
||||||
call->moveToThread(self->thread());
|
call->moveToThread(self->thread());
|
||||||
assert(call != nullptr);
|
assert(call != nullptr);
|
||||||
|
|
|
@ -51,7 +51,8 @@ class CoreAV : public QObject
|
||||||
public:
|
public:
|
||||||
using CoreAVPtr = std::unique_ptr<CoreAV>;
|
using CoreAVPtr = std::unique_ptr<CoreAV>;
|
||||||
static CoreAVPtr makeCoreAV(Tox* core, CompatibleRecursiveMutex& toxCoreLock,
|
static CoreAVPtr makeCoreAV(Tox* core, CompatibleRecursiveMutex& toxCoreLock,
|
||||||
IAudioSettings& audioSettings, IGroupSettings& groupSettings);
|
IAudioSettings& audioSettings, IGroupSettings& groupSettings,
|
||||||
|
CameraSource&);
|
||||||
|
|
||||||
void setAudio(IAudioControl& newAudio);
|
void setAudio(IAudioControl& newAudio);
|
||||||
IAudioControl* getAudio();
|
IAudioControl* getAudio();
|
||||||
|
@ -118,7 +119,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
CoreAV(std::unique_ptr<ToxAV, ToxAVDeleter> tox_, CompatibleRecursiveMutex &toxCoreLock,
|
CoreAV(std::unique_ptr<ToxAV, ToxAVDeleter> tox_, CompatibleRecursiveMutex &toxCoreLock,
|
||||||
IAudioSettings& audioSettings_, IGroupSettings& groupSettings_);
|
IAudioSettings& audioSettings_, IGroupSettings& groupSettings_, CameraSource&);
|
||||||
void connectCallbacks();
|
void connectCallbacks();
|
||||||
|
|
||||||
void process();
|
void process();
|
||||||
|
@ -165,4 +166,5 @@ private:
|
||||||
|
|
||||||
IAudioSettings& audioSettings;
|
IAudioSettings& audioSettings;
|
||||||
IGroupSettings& groupSettings;
|
IGroupSettings& groupSettings;
|
||||||
|
CameraSource& cameraSource;
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,7 +59,6 @@ ToxCall::~ToxCall()
|
||||||
{
|
{
|
||||||
if (videoEnabled) {
|
if (videoEnabled) {
|
||||||
QObject::disconnect(videoInConn);
|
QObject::disconnect(videoInConn);
|
||||||
CameraSource::getInstance().unsubscribe();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,10 +117,12 @@ CoreVideoSource* ToxCall::getVideoSource() const
|
||||||
return videoSource;
|
return videoSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av_, IAudioControl& audio_)
|
ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av_,
|
||||||
|
IAudioControl& audio_, CameraSource& cameraSource_)
|
||||||
: ToxCall(VideoEnabled, av_, audio_)
|
: ToxCall(VideoEnabled, av_, audio_)
|
||||||
, sink(audio_.makeSink())
|
, sink(audio_.makeSink())
|
||||||
, friendId{FriendNum}
|
, friendId{FriendNum}
|
||||||
|
, cameraSource{cameraSource_}
|
||||||
{
|
{
|
||||||
connect(audioSource.get(), &IAudioSource::frameAvailable, this,
|
connect(audioSource.get(), &IAudioSource::frameAvailable, this,
|
||||||
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
|
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
|
||||||
|
@ -137,13 +138,12 @@ ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av_,
|
||||||
// register video
|
// register video
|
||||||
if (videoEnabled) {
|
if (videoEnabled) {
|
||||||
videoSource = new CoreVideoSource();
|
videoSource = new CoreVideoSource();
|
||||||
CameraSource& source = CameraSource::getInstance();
|
|
||||||
|
|
||||||
if (source.isNone()) {
|
if (cameraSource.isNone()) {
|
||||||
source.setupDefault();
|
cameraSource.setupDefault();
|
||||||
}
|
}
|
||||||
source.subscribe();
|
cameraSource.subscribe();
|
||||||
videoInConn = QObject::connect(&source, &VideoSource::frameAvailable,
|
videoInConn = QObject::connect(&cameraSource, &VideoSource::frameAvailable,
|
||||||
[&av_, FriendNum](std::shared_ptr<VideoFrame> frame) {
|
[&av_, FriendNum](std::shared_ptr<VideoFrame> frame) {
|
||||||
av_.sendCallVideo(FriendNum, frame);
|
av_.sendCallVideo(FriendNum, frame);
|
||||||
});
|
});
|
||||||
|
@ -155,6 +155,9 @@ ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av_,
|
||||||
|
|
||||||
ToxFriendCall::~ToxFriendCall()
|
ToxFriendCall::~ToxFriendCall()
|
||||||
{
|
{
|
||||||
|
if (videoEnabled) {
|
||||||
|
cameraSource.unsubscribe();
|
||||||
|
}
|
||||||
QObject::disconnect(audioSinkInvalid);
|
QObject::disconnect(audioSinkInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ class AudioFilterer;
|
||||||
class CoreVideoSource;
|
class CoreVideoSource;
|
||||||
class CoreAV;
|
class CoreAV;
|
||||||
class Group;
|
class Group;
|
||||||
|
class CameraSource;
|
||||||
|
|
||||||
class ToxCall : public QObject
|
class ToxCall : public QObject
|
||||||
{
|
{
|
||||||
|
@ -91,7 +92,7 @@ class ToxFriendCall : public ToxCall
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ToxFriendCall() = delete;
|
ToxFriendCall() = delete;
|
||||||
ToxFriendCall(uint32_t friendId, bool VideoEnabled, CoreAV& av_, IAudioControl& audio_);
|
ToxFriendCall(uint32_t friendId, bool VideoEnabled, CoreAV& av_, IAudioControl& audio_, CameraSource&);
|
||||||
ToxFriendCall(ToxFriendCall&& other) = delete;
|
ToxFriendCall(ToxFriendCall&& other) = delete;
|
||||||
ToxFriendCall& operator=(ToxFriendCall&& other) = delete;
|
ToxFriendCall& operator=(ToxFriendCall&& other) = delete;
|
||||||
~ToxFriendCall();
|
~ToxFriendCall();
|
||||||
|
@ -110,6 +111,7 @@ private:
|
||||||
TOXAV_FRIEND_CALL_STATE state{TOXAV_FRIEND_CALL_STATE_NONE};
|
TOXAV_FRIEND_CALL_STATE state{TOXAV_FRIEND_CALL_STATE_NONE};
|
||||||
std::unique_ptr<IAudioSink> sink;
|
std::unique_ptr<IAudioSink> sink;
|
||||||
uint32_t friendId;
|
uint32_t friendId;
|
||||||
|
CameraSource& cameraSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ToxGroupCall : public ToxCall
|
class ToxGroupCall : public ToxCall
|
||||||
|
|
|
@ -67,7 +67,6 @@ void cleanup()
|
||||||
s.sync();
|
s.sync();
|
||||||
|
|
||||||
Nexus::destroyInstance();
|
Nexus::destroyInstance();
|
||||||
CameraSource::destroyInstance();
|
|
||||||
Settings::destroyInstance();
|
Settings::destroyInstance();
|
||||||
qDebug() << "Cleanup success";
|
qDebug() << "Cleanup success";
|
||||||
|
|
||||||
|
@ -400,13 +399,13 @@ int main(int argc, char* argv[])
|
||||||
// note: Because Settings is shouldering global settings as well as model specific ones it
|
// note: Because Settings is shouldering global settings as well as model specific ones it
|
||||||
// cannot be integrated into a central model object yet
|
// cannot be integrated into a central model object yet
|
||||||
nexus.setSettings(&settings);
|
nexus.setSettings(&settings);
|
||||||
|
auto& cameraSource = Nexus::getCameraSource();
|
||||||
// Autologin
|
// Autologin
|
||||||
// TODO (kriby): Shift responsibility of linking views to model objects from nexus
|
// TODO (kriby): Shift responsibility of linking views to model objects from nexus
|
||||||
// Further: generate view instances separately (loginScreen, mainGUI, audio)
|
// Further: generate view instances separately (loginScreen, mainGUI, audio)
|
||||||
Profile* profile = nullptr;
|
Profile* profile = nullptr;
|
||||||
if (autoLogin && Profile::exists(profileName) && !Profile::isEncrypted(profileName)) {
|
if (autoLogin && Profile::exists(profileName) && !Profile::isEncrypted(profileName)) {
|
||||||
profile = Profile::loadProfile(profileName, QString(), settings, &parser);
|
profile = Profile::loadProfile(profileName, QString(), settings, &parser, cameraSource);
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
QMessageBox::information(nullptr, QObject::tr("Error"),
|
QMessageBox::information(nullptr, QObject::tr("Error"),
|
||||||
QObject::tr("Failed to load profile automatically."));
|
QObject::tr("Failed to load profile automatically."));
|
||||||
|
|
|
@ -63,7 +63,10 @@ Nexus::Nexus(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, profile{nullptr}
|
, profile{nullptr}
|
||||||
, widget{nullptr}
|
, widget{nullptr}
|
||||||
{}
|
, cameraSource(new CameraSource())
|
||||||
|
{
|
||||||
|
assert(cameraSource);
|
||||||
|
}
|
||||||
|
|
||||||
Nexus::~Nexus()
|
Nexus::~Nexus()
|
||||||
{
|
{
|
||||||
|
@ -228,7 +231,7 @@ void Nexus::showMainGUI()
|
||||||
assert(profile);
|
assert(profile);
|
||||||
|
|
||||||
// Create GUI
|
// Create GUI
|
||||||
widget = new Widget(*profile, *audioControl);
|
widget = new Widget(*profile, *audioControl, *cameraSource);
|
||||||
|
|
||||||
// Start GUI
|
// Start GUI
|
||||||
widget->init();
|
widget->init();
|
||||||
|
@ -301,7 +304,7 @@ Profile* Nexus::getProfile()
|
||||||
*/
|
*/
|
||||||
void Nexus::onCreateNewProfile(const QString& name, const QString& pass)
|
void Nexus::onCreateNewProfile(const QString& name, const QString& pass)
|
||||||
{
|
{
|
||||||
setProfile(Profile::createProfile(name, pass, *settings, parser));
|
setProfile(Profile::createProfile(name, pass, *settings, parser, *cameraSource));
|
||||||
parser = nullptr; // only apply cmdline proxy settings once
|
parser = nullptr; // only apply cmdline proxy settings once
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +313,7 @@ void Nexus::onCreateNewProfile(const QString& name, const QString& pass)
|
||||||
*/
|
*/
|
||||||
void Nexus::onLoadProfile(const QString& name, const QString& pass)
|
void Nexus::onLoadProfile(const QString& name, const QString& pass)
|
||||||
{
|
{
|
||||||
setProfile(Profile::loadProfile(name, pass, *settings, parser));
|
setProfile(Profile::loadProfile(name, pass, *settings, parser, *cameraSource));
|
||||||
parser = nullptr; // only apply cmdline proxy settings once
|
parser = nullptr; // only apply cmdline proxy settings once
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -344,6 +347,11 @@ Widget* Nexus::getDesktopGUI()
|
||||||
return getInstance().widget;
|
return getInstance().widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CameraSource& Nexus::getCameraSource()
|
||||||
|
{
|
||||||
|
return *getInstance().cameraSource;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
void Nexus::retranslateUi()
|
void Nexus::retranslateUi()
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "audio/iaudiocontrol.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "audio/iaudiocontrol.h"
|
#include <memory>
|
||||||
|
|
||||||
class Widget;
|
class Widget;
|
||||||
class Profile;
|
class Profile;
|
||||||
|
@ -30,6 +32,7 @@ class Settings;
|
||||||
class LoginScreen;
|
class LoginScreen;
|
||||||
class Core;
|
class Core;
|
||||||
class QCommandLineParser;
|
class QCommandLineParser;
|
||||||
|
class CameraSource;
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
class QMenuBar;
|
class QMenuBar;
|
||||||
|
@ -53,6 +56,7 @@ public:
|
||||||
static Core* getCore();
|
static Core* getCore();
|
||||||
static Profile* getProfile();
|
static Profile* getProfile();
|
||||||
static Widget* getDesktopGUI();
|
static Widget* getDesktopGUI();
|
||||||
|
static CameraSource& getCameraSource();
|
||||||
|
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
@ -104,4 +108,5 @@ private:
|
||||||
Widget* widget;
|
Widget* widget;
|
||||||
std::unique_ptr<IAudioControl> audioControl;
|
std::unique_ptr<IAudioControl> audioControl;
|
||||||
QCommandLineParser* parser = nullptr;
|
QCommandLineParser* parser = nullptr;
|
||||||
|
std::unique_ptr<CameraSource> cameraSource;
|
||||||
};
|
};
|
||||||
|
|
|
@ -232,7 +232,7 @@ bool logCreateToxDataError(const CreateToxDataError& error, const QString& userN
|
||||||
|
|
||||||
QStringList Profile::profiles;
|
QStringList Profile::profiles;
|
||||||
|
|
||||||
void Profile::initCore(const QByteArray& toxsave, Settings& s, bool isNewProfile)
|
void Profile::initCore(const QByteArray& toxsave, Settings& s, bool isNewProfile, CameraSource& cameraSource)
|
||||||
{
|
{
|
||||||
if (toxsave.isEmpty() && !isNewProfile) {
|
if (toxsave.isEmpty() && !isNewProfile) {
|
||||||
qCritical() << "Existing toxsave is empty";
|
qCritical() << "Existing toxsave is empty";
|
||||||
|
@ -265,7 +265,7 @@ void Profile::initCore(const QByteArray& toxsave, Settings& s, bool isNewProfile
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
coreAv = CoreAV::makeCoreAV(core->getTox(), core->getCoreLoopLock(), s, s);
|
coreAv = CoreAV::makeCoreAV(core->getTox(), core->getCoreLoopLock(), s, s, cameraSource);
|
||||||
if (!coreAv) {
|
if (!coreAv) {
|
||||||
qDebug() << "Failed to start ToxAV";
|
qDebug() << "Failed to start ToxAV";
|
||||||
emit failedToStart();
|
emit failedToStart();
|
||||||
|
@ -311,7 +311,7 @@ Profile::Profile(const QString& name_, std::unique_ptr<ToxEncrypt> passkey_, Pat
|
||||||
* @note If the profile is already in use return nullptr.
|
* @note If the profile is already in use return nullptr.
|
||||||
*/
|
*/
|
||||||
Profile* Profile::loadProfile(const QString& name, const QString& password, Settings& settings,
|
Profile* Profile::loadProfile(const QString& name, const QString& password, Settings& settings,
|
||||||
const QCommandLineParser* parser)
|
const QCommandLineParser* parser, CameraSource& cameraSource)
|
||||||
{
|
{
|
||||||
if (ProfileLocker::hasLock()) {
|
if (ProfileLocker::hasLock()) {
|
||||||
qCritical() << "Tried to load profile " << name << ", but another profile is already locked!";
|
qCritical() << "Tried to load profile " << name << ", but another profile is already locked!";
|
||||||
|
@ -339,7 +339,7 @@ Profile* Profile::loadProfile(const QString& name, const QString& password, Sett
|
||||||
constexpr bool isNewProfile = false;
|
constexpr bool isNewProfile = false;
|
||||||
settings.updateProfileData(p, parser, isNewProfile);
|
settings.updateProfileData(p, parser, isNewProfile);
|
||||||
|
|
||||||
p->initCore(toxsave, settings, isNewProfile);
|
p->initCore(toxsave, settings, isNewProfile, cameraSource);
|
||||||
p->loadDatabase(password);
|
p->loadDatabase(password);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
@ -354,7 +354,7 @@ Profile* Profile::loadProfile(const QString& name, const QString& password, Sett
|
||||||
* @note If the profile is already in use return nullptr.
|
* @note If the profile is already in use return nullptr.
|
||||||
*/
|
*/
|
||||||
Profile* Profile::createProfile(const QString& name, const QString& password, Settings& settings,
|
Profile* Profile::createProfile(const QString& name, const QString& password, Settings& settings,
|
||||||
const QCommandLineParser* parser)
|
const QCommandLineParser* parser, CameraSource& cameraSource)
|
||||||
{
|
{
|
||||||
CreateToxDataError error;
|
CreateToxDataError error;
|
||||||
Paths& paths = settings.getPaths();
|
Paths& paths = settings.getPaths();
|
||||||
|
@ -371,7 +371,7 @@ Profile* Profile::createProfile(const QString& name, const QString& password, Se
|
||||||
constexpr bool isNewProfile = true;
|
constexpr bool isNewProfile = true;
|
||||||
settings.updateProfileData(p, parser, isNewProfile);
|
settings.updateProfileData(p, parser, isNewProfile);
|
||||||
|
|
||||||
p->initCore(QByteArray(), settings, isNewProfile);
|
p->initCore(QByteArray(), settings, isNewProfile, cameraSource);
|
||||||
p->loadDatabase(password);
|
p->loadDatabase(password);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
class Settings;
|
class Settings;
|
||||||
class QCommandLineParser;
|
class QCommandLineParser;
|
||||||
class ToxPk;
|
class ToxPk;
|
||||||
|
class CameraSource;
|
||||||
|
|
||||||
class Profile : public QObject
|
class Profile : public QObject
|
||||||
{
|
{
|
||||||
|
@ -45,9 +46,9 @@ class Profile : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Profile* loadProfile(const QString& name, const QString& password, Settings& settings,
|
static Profile* loadProfile(const QString& name, const QString& password, Settings& settings,
|
||||||
const QCommandLineParser* parser);
|
const QCommandLineParser* parser, CameraSource&);
|
||||||
static Profile* createProfile(const QString& name, const QString& password, Settings& settings,
|
static Profile* createProfile(const QString& name, const QString& password, Settings& settings,
|
||||||
const QCommandLineParser* parser);
|
const QCommandLineParser* parser, CameraSource&);
|
||||||
~Profile();
|
~Profile();
|
||||||
|
|
||||||
Core& getCore() const;
|
Core& getCore() const;
|
||||||
|
@ -108,7 +109,7 @@ private:
|
||||||
static QStringList getFilesByExt(QString extension);
|
static QStringList getFilesByExt(QString extension);
|
||||||
QString avatarPath(const ToxPk& owner, bool forceUnencrypted = false);
|
QString avatarPath(const ToxPk& owner, bool forceUnencrypted = false);
|
||||||
bool saveToxSave(QByteArray data);
|
bool saveToxSave(QByteArray data);
|
||||||
void initCore(const QByteArray& toxsave, Settings &s, bool isNewProfile);
|
void initCore(const QByteArray& toxsave, Settings &s, bool isNewProfile, CameraSource&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<AvatarBroadcaster> avatarBroadcaster;
|
std::unique_ptr<AvatarBroadcaster> avatarBroadcaster;
|
||||||
|
|
|
@ -90,8 +90,6 @@ extern "C" {
|
||||||
* @brief Remember how many times we subscribed for RAII
|
* @brief Remember how many times we subscribed for RAII
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CameraSource* CameraSource::instance{nullptr};
|
|
||||||
|
|
||||||
CameraSource::CameraSource()
|
CameraSource::CameraSource()
|
||||||
: deviceThread{new QThread}
|
: deviceThread{new QThread}
|
||||||
, deviceName{"none"}
|
, deviceName{"none"}
|
||||||
|
@ -122,22 +120,6 @@ CameraSource::CameraSource()
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the singleton instance.
|
|
||||||
*/
|
|
||||||
CameraSource& CameraSource::getInstance()
|
|
||||||
{
|
|
||||||
if (!instance)
|
|
||||||
instance = new CameraSource();
|
|
||||||
return *instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraSource::destroyInstance()
|
|
||||||
{
|
|
||||||
delete instance;
|
|
||||||
instance = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup default device
|
* @brief Setup default device
|
||||||
* @note If a device is already open, the source will seamlessly switch to the new device.
|
* @note If a device is already open, the source will seamlessly switch to the new device.
|
||||||
|
|
|
@ -36,8 +36,8 @@ class CameraSource : public VideoSource
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CameraSource& getInstance();
|
CameraSource();
|
||||||
static void destroyInstance();
|
~CameraSource();
|
||||||
void setupDefault();
|
void setupDefault();
|
||||||
bool isNone() const;
|
bool isNone() const;
|
||||||
|
|
||||||
|
@ -53,8 +53,6 @@ signals:
|
||||||
void openFailed();
|
void openFailed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CameraSource();
|
|
||||||
~CameraSource();
|
|
||||||
void stream();
|
void stream();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -78,6 +76,4 @@ private:
|
||||||
|
|
||||||
std::atomic_bool isNone_;
|
std::atomic_bool isNone_;
|
||||||
std::atomic_int subscriptions;
|
std::atomic_int subscriptions;
|
||||||
|
|
||||||
static CameraSource* instance;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,11 +47,12 @@ const int BTN_PANEL_WIDTH = 250;
|
||||||
const auto BTN_STYLE_SHEET_PATH = QStringLiteral("chatForm/fullScreenButtons.css");
|
const auto BTN_STYLE_SHEET_PATH = QStringLiteral("chatForm/fullScreenButtons.css");
|
||||||
}
|
}
|
||||||
|
|
||||||
NetCamView::NetCamView(ToxPk friendPk_, QWidget* parent)
|
NetCamView::NetCamView(ToxPk friendPk_, CameraSource& cameraSource_, QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, selfFrame{nullptr}
|
, selfFrame{nullptr}
|
||||||
, friendPk{friendPk_}
|
, friendPk{friendPk_}
|
||||||
, e(false)
|
, e(false)
|
||||||
|
, cameraSource{cameraSource_}
|
||||||
{
|
{
|
||||||
verLayout = new QVBoxLayout(this);
|
verLayout = new QVBoxLayout(this);
|
||||||
setWindowTitle(tr("Tox video"));
|
setWindowTitle(tr("Tox video"));
|
||||||
|
@ -167,7 +168,7 @@ NetCamView::~NetCamView()
|
||||||
void NetCamView::show(VideoSource* source, const QString& title)
|
void NetCamView::show(VideoSource* source, const QString& title)
|
||||||
{
|
{
|
||||||
setSource(source);
|
setSource(source);
|
||||||
selfVideoSurface->setSource(&CameraSource::getInstance());
|
selfVideoSurface->setSource(&cameraSource);
|
||||||
|
|
||||||
setTitle(title);
|
setTitle(title);
|
||||||
QWidget::show();
|
QWidget::show();
|
||||||
|
|
|
@ -34,13 +34,14 @@ class QPushButton;
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
class QShowEvent;
|
class QShowEvent;
|
||||||
|
class CameraSource;
|
||||||
|
|
||||||
class NetCamView : public QWidget
|
class NetCamView : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetCamView(ToxPk friendPk_, QWidget* parent = nullptr);
|
NetCamView(ToxPk friendPk_, CameraSource&, QWidget* parent = nullptr);
|
||||||
~NetCamView();
|
~NetCamView();
|
||||||
|
|
||||||
virtual void show(VideoSource* source, const QString& title);
|
virtual void show(VideoSource* source, const QString& title);
|
||||||
|
@ -95,4 +96,5 @@ private:
|
||||||
QPushButton* microphoneButton = nullptr;
|
QPushButton* microphoneButton = nullptr;
|
||||||
QPushButton* endVideoButton = nullptr;
|
QPushButton* endVideoButton = nullptr;
|
||||||
QPushButton* exitFullScreenButton = nullptr;
|
QPushButton* exitFullScreenButton = nullptr;
|
||||||
|
CameraSource& cameraSource;
|
||||||
};
|
};
|
||||||
|
|
|
@ -107,13 +107,15 @@ QString secondsToDHMS(quint32 duration)
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ChatForm::ChatForm(Profile& profile, Friend* chatFriend, IChatLog& chatLog_,
|
ChatForm::ChatForm(Profile& profile, Friend* chatFriend, IChatLog& chatLog_,
|
||||||
IMessageDispatcher& messageDispatcher_, DocumentCache& documentCache_, SmileyPack& smileyPack_)
|
IMessageDispatcher& messageDispatcher_, DocumentCache& documentCache_,
|
||||||
|
SmileyPack& smileyPack_, CameraSource& cameraSource_)
|
||||||
: GenericChatForm(profile.getCore(), chatFriend, chatLog_, messageDispatcher_,
|
: GenericChatForm(profile.getCore(), chatFriend, chatLog_, messageDispatcher_,
|
||||||
documentCache_, smileyPack_)
|
documentCache_, smileyPack_)
|
||||||
, core{profile.getCore()}
|
, core{profile.getCore()}
|
||||||
, f(chatFriend)
|
, f(chatFriend)
|
||||||
, isTyping{false}
|
, isTyping{false}
|
||||||
, lastCallIsVideo{false}
|
, lastCallIsVideo{false}
|
||||||
|
, cameraSource{cameraSource_}
|
||||||
{
|
{
|
||||||
setName(f->getDisplayedName());
|
setName(f->getDisplayedName());
|
||||||
|
|
||||||
|
@ -509,7 +511,7 @@ std::unique_ptr<NetCamView> ChatForm::createNetcam()
|
||||||
{
|
{
|
||||||
qDebug() << "creating netcam";
|
qDebug() << "creating netcam";
|
||||||
uint32_t friendId = f->getId();
|
uint32_t friendId = f->getId();
|
||||||
std::unique_ptr<NetCamView> view = std::unique_ptr<NetCamView>(new NetCamView(f->getPublicKey(), this));
|
std::unique_ptr<NetCamView> view = std::unique_ptr<NetCamView>(new NetCamView(f->getPublicKey(), cameraSource, this));
|
||||||
CoreAV* av = core.getAv();
|
CoreAV* av = core.getAv();
|
||||||
VideoSource* source = av->getVideoSourceFromCall(friendId);
|
VideoSource* source = av->getVideoSourceFromCall(friendId);
|
||||||
view->show(source, f->getDisplayedName());
|
view->show(source, f->getDisplayedName());
|
||||||
|
|
|
@ -50,7 +50,8 @@ class ChatForm : public GenericChatForm
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ChatForm(Profile& profile, Friend* chatFriend, IChatLog& chatLog_,
|
ChatForm(Profile& profile, Friend* chatFriend, IChatLog& chatLog_,
|
||||||
IMessageDispatcher& messageDispatcher_, DocumentCache&, SmileyPack&);
|
IMessageDispatcher& messageDispatcher_, DocumentCache&, SmileyPack&,
|
||||||
|
CameraSource&);
|
||||||
~ChatForm() override;
|
~ChatForm() override;
|
||||||
void setStatusMessage(const QString& newMessage);
|
void setStatusMessage(const QString& newMessage);
|
||||||
|
|
||||||
|
@ -141,4 +142,5 @@ private:
|
||||||
bool isTyping;
|
bool isTyping;
|
||||||
bool lastCallIsVideo;
|
bool lastCallIsVideo;
|
||||||
std::unique_ptr<NetCamView> netcam;
|
std::unique_ptr<NetCamView> netcam;
|
||||||
|
CameraSource& cameraSource;
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,13 +42,12 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
SettingsWidget::SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio,
|
SettingsWidget::SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio,
|
||||||
Core* core, SmileyPack& smileyPack, Widget* parent)
|
Core* core, SmileyPack& smileyPack, CameraSource& cameraSource, Widget* parent)
|
||||||
: QWidget(parent, Qt::Window)
|
: QWidget(parent, Qt::Window)
|
||||||
{
|
{
|
||||||
CoreAV* coreAV = core->getAv();
|
CoreAV* coreAV = core->getAv();
|
||||||
IAudioSettings* audioSettings = &Settings::getInstance();
|
IAudioSettings* audioSettings = &Settings::getInstance();
|
||||||
IVideoSettings* videoSettings = &Settings::getInstance();
|
IVideoSettings* videoSettings = &Settings::getInstance();
|
||||||
CameraSource& camera = CameraSource::getInstance();
|
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
@ -65,7 +64,7 @@ SettingsWidget::SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio,
|
||||||
std::unique_ptr<PrivacyForm> pfrm(new PrivacyForm(core));
|
std::unique_ptr<PrivacyForm> pfrm(new PrivacyForm(core));
|
||||||
connect(pfrm.get(), &PrivacyForm::clearAllReceipts, parent, &Widget::clearAllReceipts);
|
connect(pfrm.get(), &PrivacyForm::clearAllReceipts, parent, &Widget::clearAllReceipts);
|
||||||
|
|
||||||
AVForm* rawAvfrm = new AVForm(audio, coreAV, camera, audioSettings, videoSettings);
|
AVForm* rawAvfrm = new AVForm(audio, coreAV, cameraSource, audioSettings, videoSettings);
|
||||||
std::unique_ptr<AVForm> avfrm(rawAvfrm);
|
std::unique_ptr<AVForm> avfrm(rawAvfrm);
|
||||||
std::unique_ptr<AdvancedForm> expfrm(new AdvancedForm());
|
std::unique_ptr<AdvancedForm> expfrm(new AdvancedForm());
|
||||||
std::unique_ptr<AboutForm> abtfrm(new AboutForm(updateCheck));
|
std::unique_ptr<AboutForm> abtfrm(new AboutForm(updateCheck));
|
||||||
|
|
|
@ -39,12 +39,13 @@ class ContentLayout;
|
||||||
class UpdateCheck;
|
class UpdateCheck;
|
||||||
class Widget;
|
class Widget;
|
||||||
class SmileyPack;
|
class SmileyPack;
|
||||||
|
class CameraSource;
|
||||||
|
|
||||||
class SettingsWidget : public QWidget
|
class SettingsWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio, Core *core, SmileyPack&, Widget* parent = nullptr);
|
SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio, Core *core, SmileyPack&, CameraSource&, Widget* parent = nullptr);
|
||||||
~SettingsWidget();
|
~SettingsWidget();
|
||||||
|
|
||||||
bool isShown() const;
|
bool isShown() const;
|
||||||
|
|
|
@ -139,7 +139,8 @@ void Widget::acceptFileTransfer(const ToxFile& file, const QString& path)
|
||||||
|
|
||||||
Widget* Widget::instance{nullptr};
|
Widget* Widget::instance{nullptr};
|
||||||
|
|
||||||
Widget::Widget(Profile &profile_, IAudioControl& audio_, QWidget* parent)
|
Widget::Widget(Profile &profile_, IAudioControl& audio_, CameraSource& cameraSource_,
|
||||||
|
QWidget* parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
, profile{profile_}
|
, profile{profile_}
|
||||||
, trayMenu{nullptr}
|
, trayMenu{nullptr}
|
||||||
|
@ -151,6 +152,7 @@ Widget::Widget(Profile &profile_, IAudioControl& audio_, QWidget* parent)
|
||||||
, settings(Settings::getInstance())
|
, settings(Settings::getInstance())
|
||||||
, smileyPack(new SmileyPack())
|
, smileyPack(new SmileyPack())
|
||||||
, documentCache(new DocumentCache(*smileyPack))
|
, documentCache(new DocumentCache(*smileyPack))
|
||||||
|
, cameraSource{cameraSource_}
|
||||||
{
|
{
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
QString locale = settings.getTranslation();
|
QString locale = settings.getTranslation();
|
||||||
|
@ -292,7 +294,8 @@ void Widget::init()
|
||||||
updateCheck = std::unique_ptr<UpdateCheck>(new UpdateCheck(settings));
|
updateCheck = std::unique_ptr<UpdateCheck>(new UpdateCheck(settings));
|
||||||
connect(updateCheck.get(), &UpdateCheck::updateAvailable, this, &Widget::onUpdateAvailable);
|
connect(updateCheck.get(), &UpdateCheck::updateAvailable, this, &Widget::onUpdateAvailable);
|
||||||
#endif
|
#endif
|
||||||
settingsWidget = new SettingsWidget(updateCheck.get(), audio, core, *smileyPack, this);
|
settingsWidget = new SettingsWidget(updateCheck.get(), audio, core, *smileyPack,
|
||||||
|
cameraSource, this);
|
||||||
#if UPDATE_CHECK_ENABLED
|
#if UPDATE_CHECK_ENABLED
|
||||||
updateCheck->checkForUpdate();
|
updateCheck->checkForUpdate();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1190,7 +1193,7 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk)
|
||||||
std::make_shared<ChatHistory>(*newfriend, history, *core, settings,
|
std::make_shared<ChatHistory>(*newfriend, history, *core, settings,
|
||||||
*friendMessageDispatcher);
|
*friendMessageDispatcher);
|
||||||
auto friendForm = new ChatForm(profile, newfriend, *chatHistory,
|
auto friendForm = new ChatForm(profile, newfriend, *chatHistory,
|
||||||
*friendMessageDispatcher, *documentCache, *smileyPack);
|
*friendMessageDispatcher, *documentCache, *smileyPack, cameraSource);
|
||||||
connect(friendForm, &ChatForm::updateFriendActivity, this, &Widget::updateFriendActivity);
|
connect(friendForm, &ChatForm::updateFriendActivity, this, &Widget::updateFriendActivity);
|
||||||
|
|
||||||
friendMessageDispatchers[friendPk] = friendMessageDispatcher;
|
friendMessageDispatchers[friendPk] = friendMessageDispatcher;
|
||||||
|
|
|
@ -84,6 +84,7 @@ class Settings;
|
||||||
class IChatLog;
|
class IChatLog;
|
||||||
class ChatHistory;
|
class ChatHistory;
|
||||||
class SmileyPack;
|
class SmileyPack;
|
||||||
|
class CameraSource;
|
||||||
class Widget final : public QMainWindow
|
class Widget final : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -117,7 +118,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Widget(Profile& profile_, IAudioControl& audio_, QWidget* parent = nullptr);
|
Widget(Profile& profile_, IAudioControl& audio_, CameraSource&,
|
||||||
|
QWidget* parent = nullptr);
|
||||||
~Widget() override;
|
~Widget() override;
|
||||||
void init();
|
void init();
|
||||||
void setCentralWidget(QWidget* widget, const QString& widgetName);
|
void setCentralWidget(QWidget* widget, const QString& widgetName);
|
||||||
|
@ -383,6 +385,7 @@ private:
|
||||||
#endif
|
#endif
|
||||||
std::unique_ptr<SmileyPack> smileyPack;
|
std::unique_ptr<SmileyPack> smileyPack;
|
||||||
std::unique_ptr<DocumentCache> documentCache;
|
std::unique_ptr<DocumentCache> documentCache;
|
||||||
|
CameraSource& cameraSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool toxActivateEventHandler(const QByteArray& data);
|
bool toxActivateEventHandler(const QByteArray& data);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user