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
|
||||
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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user