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:
parent
58ee2feea8
commit
6b468e41fa
|
@ -283,6 +283,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));
|
||||||
|
// Call object must be owned by this thread or there will be locking problems with Audio
|
||||||
|
call->moveToThread(this->thread());
|
||||||
assert(call != nullptr);
|
assert(call != nullptr);
|
||||||
calls.emplace(friendNum, std::move(call));
|
calls.emplace(friendNum, std::move(call));
|
||||||
return true;
|
return true;
|
||||||
|
@ -543,7 +545,10 @@ void CoreAV::joinGroupCall(const Group& group)
|
||||||
|
|
||||||
// Audio backend must be set before starting a call
|
// Audio backend must be set before starting a call
|
||||||
assert(audio != nullptr);
|
assert(audio != nullptr);
|
||||||
|
|
||||||
ToxGroupCallPtr groupcall = ToxGroupCallPtr(new ToxGroupCall{group, *this, *audio});
|
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);
|
assert(groupcall != nullptr);
|
||||||
auto ret = groupCalls.emplace(group.getId(), std::move(groupcall));
|
auto ret = groupCalls.emplace(group.getId(), std::move(groupcall));
|
||||||
if (ret.second == false) {
|
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
|
// 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});
|
||||||
|
// Call object must be owned by CoreAV thread or there will be locking problems with Audio
|
||||||
|
call->moveToThread(self->thread());
|
||||||
assert(call != nullptr);
|
assert(call != nullptr);
|
||||||
|
|
||||||
auto it = self->calls.emplace(friendNum, std::move(call));
|
auto it = self->calls.emplace(friendNum, std::move(call));
|
||||||
|
|
|
@ -57,9 +57,6 @@ ToxCall::ToxCall(bool VideoEnabled, CoreAV& av, IAudioControl& audio)
|
||||||
|
|
||||||
ToxCall::~ToxCall()
|
ToxCall::~ToxCall()
|
||||||
{
|
{
|
||||||
QObject::disconnect(audioInConn);
|
|
||||||
QObject::disconnect(audioSrcInvalid);
|
|
||||||
|
|
||||||
if (videoEnabled) {
|
if (videoEnabled) {
|
||||||
QObject::disconnect(videoInConn);
|
QObject::disconnect(videoInConn);
|
||||||
CameraSource::getInstance().unsubscribe();
|
CameraSource::getInstance().unsubscribe();
|
||||||
|
@ -126,19 +123,13 @@ ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av,
|
||||||
, sink(audio.makeSink())
|
, sink(audio.makeSink())
|
||||||
, friendId{FriendNum}
|
, friendId{FriendNum}
|
||||||
{
|
{
|
||||||
// TODO(sudden6): move this to audio source
|
connect(audioSource.get(), &IAudioSource::frameAvailable, this,
|
||||||
audioInConn =
|
|
||||||
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
|
|
||||||
[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) {
|
||||||
this->av->sendCallAudio(this->friendId, pcm, samples, chans, rate);
|
this->av->sendCallAudio(this->friendId, pcm, samples, chans, rate);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(audioSource.get(), &IAudioSource::invalidated, this, &ToxFriendCall::onAudioSourceInvalidated);
|
connect(audioSource.get(), &IAudioSource::invalidated, this, &ToxFriendCall::onAudioSourceInvalidated);
|
||||||
|
|
||||||
if (!audioInConn) {
|
|
||||||
qDebug() << "Audio input connection not working";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sink) {
|
if (sink) {
|
||||||
audioSinkInvalid = sink->connectTo_invalidated(this, [this]() { this->onAudioSinkInvalidated(); });
|
audioSinkInvalid = sink->connectTo_invalidated(this, [this]() { this->onAudioSinkInvalidated(); });
|
||||||
}
|
}
|
||||||
|
@ -170,8 +161,7 @@ ToxFriendCall::~ToxFriendCall()
|
||||||
void ToxFriendCall::onAudioSourceInvalidated()
|
void ToxFriendCall::onAudioSourceInvalidated()
|
||||||
{
|
{
|
||||||
auto newSrc = audio.makeSource();
|
auto newSrc = audio.makeSource();
|
||||||
audioInConn =
|
connect(newSrc.get(), &IAudioSource::frameAvailable, this,
|
||||||
QObject::connect(newSrc.get(), &IAudioSource::frameAvailable,
|
|
||||||
[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) {
|
||||||
this->av->sendCallAudio(this->friendId, pcm, samples, chans, 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}
|
, group{group}
|
||||||
{
|
{
|
||||||
// register audio
|
// register audio
|
||||||
audioInConn =
|
connect(audioSource.get(), &IAudioSource::frameAvailable, this,
|
||||||
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
|
|
||||||
[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) {
|
||||||
if (this->group.getPeersCount() <= 1)
|
if (this->group.getPeersCount() <= 1) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate);
|
this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!audioInConn) {
|
connect(audioSource.get(), &IAudioSource::invalidated, this, &ToxGroupCall::onAudioSourceInvalidated);
|
||||||
qDebug() << "Audio input connection not working";
|
|
||||||
}
|
|
||||||
|
|
||||||
audioSrcInvalid = QObject::connect(audioSource.get(), &IAudioSource::invalidated,
|
|
||||||
[this]() { this->onAudioSourceInvalidated(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ToxGroupCall::~ToxGroupCall()
|
ToxGroupCall::~ToxGroupCall()
|
||||||
|
@ -240,20 +225,18 @@ ToxGroupCall::~ToxGroupCall()
|
||||||
void ToxGroupCall::onAudioSourceInvalidated()
|
void ToxGroupCall::onAudioSourceInvalidated()
|
||||||
{
|
{
|
||||||
auto newSrc = audio.makeSource();
|
auto newSrc = audio.makeSource();
|
||||||
// TODO(sudden6): move this to audio source
|
connect(audioSource.get(), &IAudioSource::frameAvailable,
|
||||||
audioInConn =
|
|
||||||
QObject::connect(audioSource.get(), &IAudioSource::frameAvailable,
|
|
||||||
[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) {
|
||||||
if (this->group.getPeersCount() <= 1)
|
if (this->group.getPeersCount() <= 1) {
|
||||||
return;
|
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);
|
audioSource = std::move(newSrc);
|
||||||
|
|
||||||
audioSrcInvalid = QObject::connect(audioSource.get(), &IAudioSource::invalidated,
|
connect(audioSource.get(), &IAudioSource::invalidated, this, &ToxGroupCall::onAudioSourceInvalidated);
|
||||||
[this]() { this->onAudioSourceInvalidated(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,6 @@ protected:
|
||||||
CoreAV* av{nullptr};
|
CoreAV* av{nullptr};
|
||||||
// audio
|
// audio
|
||||||
IAudioControl& audio;
|
IAudioControl& audio;
|
||||||
QMetaObject::Connection audioInConn;
|
|
||||||
bool muteMic{false};
|
bool muteMic{false};
|
||||||
bool muteVol{false};
|
bool muteVol{false};
|
||||||
// video
|
// video
|
||||||
|
@ -86,11 +85,11 @@ protected:
|
||||||
bool videoEnabled{false};
|
bool videoEnabled{false};
|
||||||
bool nullVideoBitrate{false};
|
bool nullVideoBitrate{false};
|
||||||
std::unique_ptr<IAudioSource> audioSource = nullptr;
|
std::unique_ptr<IAudioSource> audioSource = nullptr;
|
||||||
QMetaObject::Connection audioSrcInvalid;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ToxFriendCall : public ToxCall
|
class ToxFriendCall : public ToxCall
|
||||||
{
|
{
|
||||||
|
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);
|
||||||
|
@ -103,12 +102,12 @@ public:
|
||||||
|
|
||||||
void playAudioBuffer(const int16_t* data, int samples, unsigned channels, int sampleRate) const;
|
void playAudioBuffer(const int16_t* data, int samples, unsigned channels, int sampleRate) const;
|
||||||
|
|
||||||
private:
|
private slots:
|
||||||
QMetaObject::Connection audioSinkInvalid;
|
|
||||||
void onAudioSourceInvalidated();
|
void onAudioSourceInvalidated();
|
||||||
void onAudioSinkInvalidated();
|
void onAudioSinkInvalidated();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QMetaObject::Connection audioSinkInvalid;
|
||||||
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 = nullptr;
|
std::unique_ptr<IAudioSink> sink = nullptr;
|
||||||
uint32_t friendId;
|
uint32_t friendId;
|
||||||
|
@ -116,6 +115,7 @@ private:
|
||||||
|
|
||||||
class ToxGroupCall : public ToxCall
|
class ToxGroupCall : public ToxCall
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ToxGroupCall() = delete;
|
ToxGroupCall() = delete;
|
||||||
ToxGroupCall(const Group& group, CoreAV& av, IAudioControl& audio);
|
ToxGroupCall(const Group& group, CoreAV& av, IAudioControl& audio);
|
||||||
|
@ -137,6 +137,7 @@ private:
|
||||||
std::map<ToxPk, QMetaObject::Connection> sinkInvalid;
|
std::map<ToxPk, QMetaObject::Connection> sinkInvalid;
|
||||||
const Group& group;
|
const Group& group;
|
||||||
|
|
||||||
|
private slots:
|
||||||
void onAudioSourceInvalidated();
|
void onAudioSourceInvalidated();
|
||||||
void onAudioSinkInvalidated(ToxPk peerId);
|
void onAudioSinkInvalidated(ToxPk peerId);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user