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

fix(toxcall): move ToxCall ownership to correct Thread

Makes the CoreAV thread own all ToxCalls in order to prevent signals
from being emitted via a Direct connection from Audio to CoreAV.
This commit is contained in:
sudden6 2020-03-16 12:40:17 +01:00
parent 58ee2feea8
commit 6b468e41fa
No known key found for this signature in database
GPG Key ID: 279509B499E032B9
3 changed files with 30 additions and 39 deletions

View File

@ -283,6 +283,8 @@ bool CoreAV::startCall(uint32_t friendNum, bool video)
// Audio backend must be set before making a call
assert(audio != nullptr);
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall(friendNum, video, *this, *audio));
// Call object must be owned by this thread or there will be locking problems with Audio
call->moveToThread(this->thread());
assert(call != nullptr);
calls.emplace(friendNum, std::move(call));
return true;
@ -543,7 +545,10 @@ void CoreAV::joinGroupCall(const Group& group)
// Audio backend must be set before starting a call
assert(audio != nullptr);
ToxGroupCallPtr groupcall = ToxGroupCallPtr(new ToxGroupCall{group, *this, *audio});
// Call Objects must be owned by CoreAV or there will be locking problems with Audio
groupcall->moveToThread(this->thread());
assert(groupcall != nullptr);
auto ret = groupCalls.emplace(group.getId(), std::move(groupcall));
if (ret.second == false) {
@ -713,6 +718,8 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid
// Audio backend must be set before receiving a call
assert(self->audio != nullptr);
ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall{friendNum, video, *self, *self->audio});
// Call object must be owned by CoreAV thread or there will be locking problems with Audio
call->moveToThread(self->thread());
assert(call != nullptr);
auto it = self->calls.emplace(friendNum, std::move(call));

View File

@ -57,9 +57,6 @@ ToxCall::ToxCall(bool VideoEnabled, CoreAV& av, IAudioControl& audio)
ToxCall::~ToxCall()
{
QObject::disconnect(audioInConn);
QObject::disconnect(audioSrcInvalid);
if (videoEnabled) {
QObject::disconnect(videoInConn);
CameraSource::getInstance().unsubscribe();
@ -126,19 +123,13 @@ ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av,
, sink(audio.makeSink())
, friendId{FriendNum}
{
// TODO(sudden6): move this to audio source
audioInConn =
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
connect(audioSource.get(), &IAudioSource::frameAvailable, this,
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
this->av->sendCallAudio(this->friendId, pcm, samples, chans, rate);
});
connect(audioSource.get(), &IAudioSource::invalidated, this, &ToxFriendCall::onAudioSourceInvalidated);
if (!audioInConn) {
qDebug() << "Audio input connection not working";
}
if (sink) {
audioSinkInvalid = sink->connectTo_invalidated(this, [this]() { this->onAudioSinkInvalidated(); });
}
@ -170,8 +161,7 @@ ToxFriendCall::~ToxFriendCall()
void ToxFriendCall::onAudioSourceInvalidated()
{
auto newSrc = audio.makeSource();
audioInConn =
QObject::connect(newSrc.get(), &IAudioSource::frameAvailable,
connect(newSrc.get(), &IAudioSource::frameAvailable, this,
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
this->av->sendCallAudio(this->friendId, pcm, samples, chans, rate);
});
@ -214,21 +204,16 @@ ToxGroupCall::ToxGroupCall(const Group& group, CoreAV& av, IAudioControl& audio)
, group{group}
{
// register audio
audioInConn =
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
if (this->group.getPeersCount() <= 1)
return;
connect(audioSource.get(), &IAudioSource::frameAvailable, this,
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
if (this->group.getPeersCount() <= 1) {
return;
}
this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate);
});
this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate);
});
if (!audioInConn) {
qDebug() << "Audio input connection not working";
}
audioSrcInvalid = QObject::connect(audioSource.get(), &IAudioSource::invalidated,
[this]() { this->onAudioSourceInvalidated(); });
connect(audioSource.get(), &IAudioSource::invalidated, this, &ToxGroupCall::onAudioSourceInvalidated);
}
ToxGroupCall::~ToxGroupCall()
@ -240,20 +225,18 @@ ToxGroupCall::~ToxGroupCall()
void ToxGroupCall::onAudioSourceInvalidated()
{
auto newSrc = audio.makeSource();
// TODO(sudden6): move this to audio source
audioInConn =
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
if (this->group.getPeersCount() <= 1)
return;
connect(audioSource.get(), &IAudioSource::frameAvailable,
[this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) {
if (this->group.getPeersCount() <= 1) {
return;
}
this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate);
});
this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate);
});
audioSource = std::move(newSrc);
audioSrcInvalid = QObject::connect(audioSource.get(), &IAudioSource::invalidated,
[this]() { this->onAudioSourceInvalidated(); });
connect(audioSource.get(), &IAudioSource::invalidated, this, &ToxGroupCall::onAudioSourceInvalidated);
}

View File

@ -77,7 +77,6 @@ protected:
CoreAV* av{nullptr};
// audio
IAudioControl& audio;
QMetaObject::Connection audioInConn;
bool muteMic{false};
bool muteVol{false};
// video
@ -86,11 +85,11 @@ protected:
bool videoEnabled{false};
bool nullVideoBitrate{false};
std::unique_ptr<IAudioSource> audioSource = nullptr;
QMetaObject::Connection audioSrcInvalid;
};
class ToxFriendCall : public ToxCall
{
Q_OBJECT
public:
ToxFriendCall() = delete;
ToxFriendCall(uint32_t friendId, bool VideoEnabled, CoreAV& av, IAudioControl& audio);
@ -103,12 +102,12 @@ public:
void playAudioBuffer(const int16_t* data, int samples, unsigned channels, int sampleRate) const;
private:
QMetaObject::Connection audioSinkInvalid;
private slots:
void onAudioSourceInvalidated();
void onAudioSinkInvalidated();
private:
QMetaObject::Connection audioSinkInvalid;
TOXAV_FRIEND_CALL_STATE state{TOXAV_FRIEND_CALL_STATE_NONE};
std::unique_ptr<IAudioSink> sink = nullptr;
uint32_t friendId;
@ -116,6 +115,7 @@ private:
class ToxGroupCall : public ToxCall
{
Q_OBJECT
public:
ToxGroupCall() = delete;
ToxGroupCall(const Group& group, CoreAV& av, IAudioControl& audio);
@ -137,6 +137,7 @@ private:
std::map<ToxPk, QMetaObject::Connection> sinkInvalid;
const Group& group;
private slots:
void onAudioSourceInvalidated();
void onAudioSinkInvalidated(ToxPk peerId);
};