|
|
@ -204,7 +204,11 @@ bool CoreAV::isCallStarted(const Group* g) const |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool CoreAV::isCallActive(const Friend* f) const |
|
|
|
bool CoreAV::isCallActive(const Friend* f) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return isCallStarted(f) && calls[f->getId()].isActive(); |
|
|
|
auto it = calls.find(f->getId()); |
|
|
|
|
|
|
|
if (it == calls.end()) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return isCallStarted(f) && it->second.isActive(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -214,12 +218,17 @@ bool CoreAV::isCallActive(const Friend* f) const |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool CoreAV::isCallActive(const Group* g) const |
|
|
|
bool CoreAV::isCallActive(const Group* g) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return isCallStarted(g) && groupCalls[g->getId()].isActive(); |
|
|
|
auto it = groupCalls.find(g->getId()); |
|
|
|
|
|
|
|
if (it == groupCalls.end()) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return isCallStarted(g) && it->second.isActive(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CoreAV::isCallVideoEnabled(const Friend* f) const |
|
|
|
bool CoreAV::isCallVideoEnabled(const Friend* f) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return isCallStarted(f) && calls[f->getId()].getVideoEnabled(); |
|
|
|
auto it = calls.find(f->getId()); |
|
|
|
|
|
|
|
return isCallStarted(f) && it->second.getVideoEnabled(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CoreAV::answerCall(uint32_t friendNum, bool video) |
|
|
|
bool CoreAV::answerCall(uint32_t friendNum, bool video) |
|
|
@ -240,17 +249,18 @@ bool CoreAV::answerCall(uint32_t friendNum, bool video) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
qDebug() << QString("answering call %1").arg(friendNum); |
|
|
|
qDebug() << QString("answering call %1").arg(friendNum); |
|
|
|
assert(calls.find(friendNum) != calls.end()); |
|
|
|
auto it = calls.find(friendNum); |
|
|
|
|
|
|
|
assert(it != calls.end()); |
|
|
|
TOXAV_ERR_ANSWER err; |
|
|
|
TOXAV_ERR_ANSWER err; |
|
|
|
|
|
|
|
|
|
|
|
const uint32_t videoBitrate = video ? VIDEO_DEFAULT_BITRATE : 0; |
|
|
|
const uint32_t videoBitrate = video ? VIDEO_DEFAULT_BITRATE : 0; |
|
|
|
if (toxav_answer(toxav, friendNum, Settings::getInstance().getAudioBitrate(), videoBitrate, &err)) { |
|
|
|
if (toxav_answer(toxav, friendNum, Settings::getInstance().getAudioBitrate(), videoBitrate, &err)) { |
|
|
|
calls[friendNum].setActive(true); |
|
|
|
it->second.setActive(true); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
qWarning() << "Failed to answer call with error" << err; |
|
|
|
qWarning() << "Failed to answer call with error" << err; |
|
|
|
toxav_call_control(toxav, friendNum, TOXAV_CALL_CONTROL_CANCEL, nullptr); |
|
|
|
toxav_call_control(toxav, friendNum, TOXAV_CALL_CONTROL_CANCEL, nullptr); |
|
|
|
calls.erase(friendNum); |
|
|
|
calls.erase(it); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -273,7 +283,8 @@ bool CoreAV::startCall(uint32_t friendNum, bool video) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
qDebug() << QString("Starting call with %1").arg(friendNum); |
|
|
|
qDebug() << QString("Starting call with %1").arg(friendNum); |
|
|
|
if (calls.find(friendNum) != calls.end()) { |
|
|
|
auto it = calls.find(friendNum); |
|
|
|
|
|
|
|
if (it != calls.end()) { |
|
|
|
qWarning() << QString("Can't start call with %1, we're already in this call!").arg(friendNum); |
|
|
|
qWarning() << QString("Can't start call with %1, we're already in this call!").arg(friendNum); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
@ -282,8 +293,8 @@ bool CoreAV::startCall(uint32_t friendNum, bool video) |
|
|
|
if (!toxav_call(toxav, friendNum, Settings::getInstance().getAudioBitrate(), videoBitrate, nullptr)) |
|
|
|
if (!toxav_call(toxav, friendNum, Settings::getInstance().getAudioBitrate(), videoBitrate, nullptr)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
calls.insert(std::make_pair(friendNum, ToxFriendCall(friendNum, video, *this))); |
|
|
|
auto ret = calls.insert(std::make_pair(friendNum, ToxFriendCall(friendNum, video, *this))); |
|
|
|
calls[friendNum].startTimeout(friendNum); |
|
|
|
ret.first->second.startTimeout(friendNum); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -341,13 +352,14 @@ void CoreAV::timeoutCall(uint32_t friendNum) |
|
|
|
* @return False only on error, but not if there's nothing to send. |
|
|
|
* @return False only on error, but not if there's nothing to send. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool CoreAV::sendCallAudio(uint32_t callId, const int16_t* pcm, size_t samples, uint8_t chans, |
|
|
|
bool CoreAV::sendCallAudio(uint32_t callId, const int16_t* pcm, size_t samples, uint8_t chans, |
|
|
|
uint32_t rate) |
|
|
|
uint32_t rate) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (calls.find(callId) == calls.end()) { |
|
|
|
auto it = calls.find(callId); |
|
|
|
|
|
|
|
if (it == calls.end()) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ToxFriendCall& call = calls[callId]; |
|
|
|
ToxFriendCall const& call = it->second; |
|
|
|
|
|
|
|
|
|
|
|
if (call.getMuteMic() || !call.isActive() |
|
|
|
if (call.getMuteMic() || !call.isActive() |
|
|
|
|| !(call.getState() & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A)) { |
|
|
|
|| !(call.getState() & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A)) { |
|
|
@ -378,11 +390,12 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// We might be running in the FFmpeg thread and holding the CameraSource lock
|
|
|
|
// We might be running in the FFmpeg thread and holding the CameraSource lock
|
|
|
|
// So be careful not to deadlock with anything while toxav locks in toxav_video_send_frame
|
|
|
|
// So be careful not to deadlock with anything while toxav locks in toxav_video_send_frame
|
|
|
|
if (calls.find(callId) == calls.end()) { |
|
|
|
auto it = calls.find(callId); |
|
|
|
|
|
|
|
if (it == calls.end()) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ToxFriendCall& call = calls[callId]; |
|
|
|
ToxFriendCall& call = it->second; |
|
|
|
|
|
|
|
|
|
|
|
if (!call.getVideoEnabled() || !call.isActive() |
|
|
|
if (!call.getVideoEnabled() || !call.isActive() |
|
|
|
|| !(call.getState() & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V)) { |
|
|
|
|| !(call.getState() & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V)) { |
|
|
@ -431,8 +444,9 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void CoreAV::toggleMuteCallInput(const Friend* f) |
|
|
|
void CoreAV::toggleMuteCallInput(const Friend* f) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (f && (calls.find(f->getId()) != calls.end())) { |
|
|
|
auto it = calls.find(f->getId()); |
|
|
|
ToxCall& call = calls[f->getId()]; |
|
|
|
if (f && (it != calls.end())) { |
|
|
|
|
|
|
|
ToxCall& call = it->second; |
|
|
|
call.setMuteMic(!call.getMuteMic()); |
|
|
|
call.setMuteMic(!call.getMuteMic()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -443,8 +457,9 @@ void CoreAV::toggleMuteCallInput(const Friend* f) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void CoreAV::toggleMuteCallOutput(const Friend* f) |
|
|
|
void CoreAV::toggleMuteCallOutput(const Friend* f) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (f && (calls.find(f->getId()) != calls.end())) { |
|
|
|
auto it = calls.find(f->getId()); |
|
|
|
ToxCall& call = calls[f->getId()]; |
|
|
|
if (f && (it != calls.end())) { |
|
|
|
|
|
|
|
ToxCall& call = it->second; |
|
|
|
call.setMuteVol(!call.getMuteVol()); |
|
|
|
call.setMuteVol(!call.getMuteVol()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -470,11 +485,12 @@ void CoreAV::groupCallCallback(void* tox, uint32_t group, uint32_t peer, const i |
|
|
|
Core* c = static_cast<Core*>(core); |
|
|
|
Core* c = static_cast<Core*>(core); |
|
|
|
CoreAV* cav = c->getAv(); |
|
|
|
CoreAV* cav = c->getAv(); |
|
|
|
|
|
|
|
|
|
|
|
if (cav->groupCalls.find(group) == cav->groupCalls.end()) { |
|
|
|
auto it = cav->groupCalls.find(group); |
|
|
|
|
|
|
|
if (it == cav->groupCalls.end()) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ToxGroupCall& call = cav->groupCalls[group]; |
|
|
|
ToxGroupCall& call = it->second; |
|
|
|
|
|
|
|
|
|
|
|
emit c->groupPeerAudioPlaying(group, peer); |
|
|
|
emit c->groupPeerAudioPlaying(group, peer); |
|
|
|
|
|
|
|
|
|
|
@ -499,11 +515,12 @@ void CoreAV::groupCallCallback(void* tox, int group, int peer, const int16_t* da |
|
|
|
Core* c = static_cast<Core*>(core); |
|
|
|
Core* c = static_cast<Core*>(core); |
|
|
|
CoreAV* cav = c->getAv(); |
|
|
|
CoreAV* cav = c->getAv(); |
|
|
|
|
|
|
|
|
|
|
|
if (cav->groupCalls.find(group) == cav->groupCalls.end()) { |
|
|
|
auto it = cav->groupCalls.find(group); |
|
|
|
|
|
|
|
if (it == cav->groupCalls.end()) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ToxGroupCall& call = cav->groupCalls[group]; |
|
|
|
ToxGroupCall& call = it->second; |
|
|
|
|
|
|
|
|
|
|
|
emit c->groupPeerAudioPlaying(group, peer); |
|
|
|
emit c->groupPeerAudioPlaying(group, peer); |
|
|
|
|
|
|
|
|
|
|
@ -528,9 +545,13 @@ void CoreAV::groupCallCallback(void* tox, int group, int peer, const int16_t* da |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void CoreAV::invalidateGroupCallPeerSource(int group, int peer) |
|
|
|
void CoreAV::invalidateGroupCallPeerSource(int group, int peer) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
auto it = groupCalls.find(group); |
|
|
|
|
|
|
|
if (it == groupCalls.end()) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
Audio& audio = Audio::getInstance(); |
|
|
|
Audio& audio = Audio::getInstance(); |
|
|
|
audio.unsubscribeOutput(groupCalls[group].getPeers()[peer]); |
|
|
|
audio.unsubscribeOutput(it->second.getPeers()[peer]); |
|
|
|
groupCalls[group].getPeers()[peer] = 0; |
|
|
|
it->second.getPeers()[peer] = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -548,15 +569,16 @@ void CoreAV::invalidateGroupCallSources(int group) |
|
|
|
* @param friendNum Id of friend in call list. |
|
|
|
* @param friendNum Id of friend in call list. |
|
|
|
* @return Video surface to show |
|
|
|
* @return Video surface to show |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
VideoSource* CoreAV::getVideoSourceFromCall(int friendNum) |
|
|
|
VideoSource* CoreAV::getVideoSourceFromCall(int friendNum) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (calls.find(friendNum) == calls.end()) { |
|
|
|
auto it = calls.find(friendNum); |
|
|
|
|
|
|
|
if (it == calls.end()) { |
|
|
|
qWarning() << "CoreAV::getVideoSourceFromCall: No such call, did it die before we finished " |
|
|
|
qWarning() << "CoreAV::getVideoSourceFromCall: No such call, did it die before we finished " |
|
|
|
"answering?"; |
|
|
|
"answering?"; |
|
|
|
return nullptr; |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return calls[friendNum].getVideoSource(); |
|
|
|
return it->second.getVideoSource(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -568,8 +590,12 @@ void CoreAV::joinGroupCall(int groupId) |
|
|
|
{ |
|
|
|
{ |
|
|
|
qDebug() << QString("Joining group call %1").arg(groupId); |
|
|
|
qDebug() << QString("Joining group call %1").arg(groupId); |
|
|
|
|
|
|
|
|
|
|
|
groupCalls[groupId] = ToxGroupCall{groupId, *this}; |
|
|
|
auto ret = groupCalls.insert(std::pair<int, ToxGroupCall>(groupId, ToxGroupCall{groupId, *this})); |
|
|
|
groupCalls[groupId].setActive(true); |
|
|
|
if (ret.second == false) { |
|
|
|
|
|
|
|
qWarning() << "This group call already exists, not joining!"; |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ret.first->second.setActive(true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -585,15 +611,14 @@ void CoreAV::leaveGroupCall(int groupId) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CoreAV::sendGroupCallAudio(int groupId, const int16_t* pcm, size_t samples, uint8_t chans, |
|
|
|
bool CoreAV::sendGroupCallAudio(int groupId, const int16_t* pcm, size_t samples, uint8_t chans, |
|
|
|
uint32_t rate) |
|
|
|
uint32_t rate) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (groupCalls.find(groupId) == groupCalls.end()) { |
|
|
|
std::map<int, ToxGroupCall>::const_iterator it = groupCalls.find(groupId); |
|
|
|
|
|
|
|
if (it == groupCalls.end()) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ToxGroupCall& call = groupCalls[groupId]; |
|
|
|
if (!it->second.isActive() || it->second.getMuteMic()) { |
|
|
|
|
|
|
|
|
|
|
|
if (!call.isActive() || call.getMuteMic()) { |
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -610,8 +635,9 @@ bool CoreAV::sendGroupCallAudio(int groupId, const int16_t* pcm, size_t samples, |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void CoreAV::muteCallInput(const Group* g, bool mute) |
|
|
|
void CoreAV::muteCallInput(const Group* g, bool mute) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (g && (groupCalls.find(g->getId()) != groupCalls.end())) { |
|
|
|
auto it = groupCalls.find(g->getId()); |
|
|
|
groupCalls[g->getId()].setMuteMic(mute); |
|
|
|
if (g && (it != groupCalls.end())) { |
|
|
|
|
|
|
|
it->second.setMuteMic(mute); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -622,8 +648,9 @@ void CoreAV::muteCallInput(const Group* g, bool mute) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void CoreAV::muteCallOutput(const Group* g, bool mute) |
|
|
|
void CoreAV::muteCallOutput(const Group* g, bool mute) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (g && (groupCalls.find(g->getId()) != groupCalls.end())) { |
|
|
|
auto it = groupCalls.find(g->getId()); |
|
|
|
groupCalls[g->getId()].setMuteVol(mute); |
|
|
|
if (g && (it != groupCalls.end())) { |
|
|
|
|
|
|
|
it->second.setMuteVol(mute); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -639,7 +666,8 @@ bool CoreAV::isGroupCallInputMuted(const Group* g) const |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const uint32_t groupId = g->getId(); |
|
|
|
const uint32_t groupId = g->getId(); |
|
|
|
return (groupCalls.find(groupId) != groupCalls.end()) && groupCalls[groupId].getMuteMic(); |
|
|
|
auto it = groupCalls.find(groupId); |
|
|
|
|
|
|
|
return (it != groupCalls.end()) && it->second.getMuteMic(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -654,7 +682,8 @@ bool CoreAV::isGroupCallOutputMuted(const Group* g) const |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const uint32_t groupId = g->getId(); |
|
|
|
const uint32_t groupId = g->getId(); |
|
|
|
return (groupCalls.find(groupId) != groupCalls.end()) && groupCalls[groupId].getMuteVol(); |
|
|
|
auto it = groupCalls.find(groupId); |
|
|
|
|
|
|
|
return (it != groupCalls.end()) && it->second.getMuteVol(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -691,7 +720,8 @@ bool CoreAV::isCallInputMuted(const Friend* f) const |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
const uint32_t friendId = f->getId(); |
|
|
|
const uint32_t friendId = f->getId(); |
|
|
|
return (calls.find(friendId) != calls.end()) && calls[friendId].getMuteMic(); |
|
|
|
auto it = calls.find(friendId); |
|
|
|
|
|
|
|
return (it != calls.end()) && it->second.getMuteMic(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -705,7 +735,8 @@ bool CoreAV::isCallOutputMuted(const Friend* f) const |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
const uint32_t friendId = f->getId(); |
|
|
|
const uint32_t friendId = f->getId(); |
|
|
|
return (calls.find(friendId) != calls.end()) && calls[f->getId()].getMuteVol(); |
|
|
|
auto it = calls.find(friendId); |
|
|
|
|
|
|
|
return (it != calls.end()) && it->second.getMuteVol(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -763,7 +794,8 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (self->calls.find(friendNum) != self->calls.end()) { |
|
|
|
auto it = self->calls.insert(std::pair<uint32_t, ToxFriendCall>(friendNum, ToxFriendCall{friendNum, video, *self})); |
|
|
|
|
|
|
|
if (it.second == false) { |
|
|
|
/// Hanging up from a callback is supposed to be UB,
|
|
|
|
/// Hanging up from a callback is supposed to be UB,
|
|
|
|
/// but since currently the toxav callbacks are fired from the toxcore thread,
|
|
|
|
/// but since currently the toxav callbacks are fired from the toxcore thread,
|
|
|
|
/// we'll always reach this point through a non-blocking queud connection, so not in the
|
|
|
|
/// we'll always reach this point through a non-blocking queud connection, so not in the
|
|
|
@ -773,7 +805,6 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
qDebug() << QString("Received call invite from %1").arg(friendNum); |
|
|
|
qDebug() << QString("Received call invite from %1").arg(friendNum); |
|
|
|
self->calls[friendNum] = ToxFriendCall{friendNum, video, *self}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// We don't get a state callback when answering, so fill the state ourselves in advance
|
|
|
|
// We don't get a state callback when answering, so fill the state ourselves in advance
|
|
|
|
int state = 0; |
|
|
|
int state = 0; |
|
|
@ -781,7 +812,8 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid |
|
|
|
state |= TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_ACCEPTING_A; |
|
|
|
state |= TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_ACCEPTING_A; |
|
|
|
if (video) |
|
|
|
if (video) |
|
|
|
state |= TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V; |
|
|
|
state |= TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V; |
|
|
|
calls[friendNum].setState(static_cast<TOXAV_FRIEND_CALL_STATE>(state)); |
|
|
|
it.first->second.setState(static_cast<TOXAV_FRIEND_CALL_STATE>(state)); |
|
|
|
|
|
|
|
// note: changed to self->
|
|
|
|
|
|
|
|
|
|
|
|
emit reinterpret_cast<CoreAV*>(self)->avInvite(friendNum, video); |
|
|
|
emit reinterpret_cast<CoreAV*>(self)->avInvite(friendNum, video); |
|
|
|
self->threadSwitchLock.clear(std::memory_order_release); |
|
|
|
self->threadSwitchLock.clear(std::memory_order_release); |
|
|
@ -808,21 +840,24 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (self->calls.find(friendNum) == self->calls.end()) { |
|
|
|
auto it = self->calls.find(friendNum); |
|
|
|
|
|
|
|
if (it == self->calls.end()) { |
|
|
|
qWarning() << QString("stateCallback called, but call %1 is already dead").arg(friendNum); |
|
|
|
qWarning() << QString("stateCallback called, but call %1 is already dead").arg(friendNum); |
|
|
|
self->threadSwitchLock.clear(std::memory_order_release); |
|
|
|
self->threadSwitchLock.clear(std::memory_order_release); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ToxFriendCall& call = self->calls[friendNum]; |
|
|
|
ToxFriendCall& call = it->second; |
|
|
|
|
|
|
|
|
|
|
|
if (state & TOXAV_FRIEND_CALL_STATE_ERROR) { |
|
|
|
if (state & TOXAV_FRIEND_CALL_STATE_ERROR) { |
|
|
|
qWarning() << "Call with friend" << friendNum << "died of unnatural causes!"; |
|
|
|
qWarning() << "Call with friend" << friendNum << "died of unnatural causes!"; |
|
|
|
calls.erase(friendNum); |
|
|
|
calls.erase(friendNum); |
|
|
|
|
|
|
|
// why not self->
|
|
|
|
emit self->avEnd(friendNum, true); |
|
|
|
emit self->avEnd(friendNum, true); |
|
|
|
} else if (state & TOXAV_FRIEND_CALL_STATE_FINISHED) { |
|
|
|
} else if (state & TOXAV_FRIEND_CALL_STATE_FINISHED) { |
|
|
|
qDebug() << "Call with friend" << friendNum << "finished quietly"; |
|
|
|
qDebug() << "Call with friend" << friendNum << "finished quietly"; |
|
|
|
calls.erase(friendNum); |
|
|
|
calls.erase(friendNum); |
|
|
|
|
|
|
|
// why not self->
|
|
|
|
emit self->avEnd(friendNum); |
|
|
|
emit self->avEnd(friendNum); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// If our state was null, we started the call and were still ringing
|
|
|
|
// If our state was null, we started the call and were still ringing
|
|
|
@ -904,11 +939,12 @@ void CoreAV::audioFrameCallback(ToxAV*, uint32_t friendNum, const int16_t* pcm, |
|
|
|
uint8_t channels, uint32_t samplingRate, void* vSelf) |
|
|
|
uint8_t channels, uint32_t samplingRate, void* vSelf) |
|
|
|
{ |
|
|
|
{ |
|
|
|
CoreAV* self = static_cast<CoreAV*>(vSelf); |
|
|
|
CoreAV* self = static_cast<CoreAV*>(vSelf); |
|
|
|
if (self->calls.find(friendNum) == self->calls.end()) { |
|
|
|
auto it = calls.find(friendNum); |
|
|
|
|
|
|
|
if (it == self->calls.end()) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ToxFriendCall& call = self->calls[friendNum]; |
|
|
|
ToxFriendCall& call = it->second; |
|
|
|
|
|
|
|
|
|
|
|
if (call.getMuteVol()) { |
|
|
|
if (call.getMuteVol()) { |
|
|
|
return; |
|
|
|
return; |
|
|
@ -928,11 +964,12 @@ void CoreAV::videoFrameCallback(ToxAV*, uint32_t friendNum, uint16_t w, uint16_t |
|
|
|
const uint8_t* y, const uint8_t* u, const uint8_t* v, |
|
|
|
const uint8_t* y, const uint8_t* u, const uint8_t* v, |
|
|
|
int32_t ystride, int32_t ustride, int32_t vstride, void*) |
|
|
|
int32_t ystride, int32_t ustride, int32_t vstride, void*) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (calls.find(friendNum) == calls.end()) { |
|
|
|
auto it = calls.find(friendNum); |
|
|
|
|
|
|
|
if (it == calls.end()) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
CoreVideoSource* videoSource = calls[friendNum].getVideoSource(); |
|
|
|
CoreVideoSource* videoSource = it->second.getVideoSource(); |
|
|
|
if (!videoSource) { |
|
|
|
if (!videoSource) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|