|
|
|
@ -19,6 +19,7 @@
@@ -19,6 +19,7 @@
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include "core.h" |
|
|
|
|
#include "coreav.h" |
|
|
|
|
#include "src/video/camerasource.h" |
|
|
|
|
#include "src/video/corevideosource.h" |
|
|
|
|
#include "src/video/videoframe.h" |
|
|
|
@ -31,14 +32,23 @@
@@ -31,14 +32,23 @@
|
|
|
|
|
#include <QDebug> |
|
|
|
|
#include <QTimer> |
|
|
|
|
|
|
|
|
|
ToxCall Core::calls[TOXAV_MAX_CALLS]; |
|
|
|
|
QVector<ToxCall> CoreAV::calls; |
|
|
|
|
QHash<int, ToxGroupCall> CoreAV::groupCalls; |
|
|
|
|
#ifdef QTOX_FILTER_AUDIO |
|
|
|
|
AudioFilterer * Core::filterer[TOXAV_MAX_CALLS] {nullptr}; |
|
|
|
|
QVector<AudioFilterer*> CoreAV::filterer; |
|
|
|
|
#endif |
|
|
|
|
const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4}; |
|
|
|
|
uint8_t* Core::videobuf; |
|
|
|
|
|
|
|
|
|
bool Core::anyActiveCalls() |
|
|
|
|
CoreAV::~CoreAV() |
|
|
|
|
{ |
|
|
|
|
for (ToxCall call : calls) |
|
|
|
|
{ |
|
|
|
|
if (!call.active) |
|
|
|
|
continue; |
|
|
|
|
hangupCall(call.callId); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool CoreAV::anyActiveCalls() |
|
|
|
|
{ |
|
|
|
|
for (auto& call : calls) |
|
|
|
|
{ |
|
|
|
@ -48,26 +58,17 @@ bool Core::anyActiveCalls()
@@ -48,26 +58,17 @@ bool Core::anyActiveCalls()
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::prepareCall(uint32_t friendId, int32_t callId, ToxAv* toxav, bool videoEnabled) |
|
|
|
|
void CoreAV::prepareCall(uint32_t friendId, int32_t callId, ToxAV* toxav, bool videoEnabled) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("preparing call %1").arg(callId); |
|
|
|
|
|
|
|
|
|
if (!videobuf) |
|
|
|
|
videobuf = new uint8_t[videobufsize]; |
|
|
|
|
|
|
|
|
|
calls[callId].callId = callId; |
|
|
|
|
calls[callId].friendId = friendId; |
|
|
|
|
calls[callId].muteMic = false; |
|
|
|
|
calls[callId].muteVol = false; |
|
|
|
|
// the following three lines are also now redundant from startCall, but are
|
|
|
|
|
// necessary there for outbound and here for inbound
|
|
|
|
|
calls[callId].codecSettings = av_DefaultSettings; |
|
|
|
|
calls[callId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; |
|
|
|
|
calls[callId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; |
|
|
|
|
calls[callId].videoEnabled = videoEnabled; |
|
|
|
|
int r = toxav_prepare_transmission(toxav, callId, videoEnabled); |
|
|
|
|
if (r < 0) |
|
|
|
|
qWarning() << QString("Error starting call %1: toxav_prepare_transmission failed with %2").arg(callId).arg(r); |
|
|
|
|
|
|
|
|
|
// Audio
|
|
|
|
|
Audio::getInstance().subscribeInput(); |
|
|
|
@ -102,135 +103,35 @@ void Core::prepareCall(uint32_t friendId, int32_t callId, ToxAv* toxav, bool vid
@@ -102,135 +103,35 @@ void Core::prepareCall(uint32_t friendId, int32_t callId, ToxAv* toxav, bool vid
|
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::onAvMediaChange(void* toxav, int32_t callId, void* core) |
|
|
|
|
{ |
|
|
|
|
int friendId; |
|
|
|
|
int cap = toxav_capability_supported((ToxAv*)toxav, callId, |
|
|
|
|
(ToxAvCapabilities)(av_VideoEncoding|av_VideoDecoding)); |
|
|
|
|
if (!cap) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
friendId = toxav_get_peer_id((ToxAv*)toxav, callId, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
qDebug() << "Received media change from friend "<<friendId; |
|
|
|
|
|
|
|
|
|
if (cap == (av_VideoEncoding|av_VideoDecoding)) // Video call
|
|
|
|
|
{ |
|
|
|
|
emit static_cast<Core*>(core)->avMediaChange(friendId, callId, true); |
|
|
|
|
calls[callId].videoSource = new CoreVideoSource; |
|
|
|
|
CameraSource& source = CameraSource::getInstance(); |
|
|
|
|
source.subscribe(); |
|
|
|
|
calls[callId].videoEnabled = true; |
|
|
|
|
} |
|
|
|
|
else // Audio call
|
|
|
|
|
{ |
|
|
|
|
emit static_cast<Core*>(core)->avMediaChange(friendId, callId, false); |
|
|
|
|
calls[callId].videoEnabled = false; |
|
|
|
|
CameraSource::getInstance().unsubscribe(); |
|
|
|
|
calls[callId].videoSource->setDeleteOnClose(true); |
|
|
|
|
calls[callId].videoSource = nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
fail: // Centralized error handling
|
|
|
|
|
qWarning() << "Toxcore error while receiving media change on call "<<callId; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::answerCall(int32_t callId) |
|
|
|
|
void CoreAV::answerCall(int32_t callId) |
|
|
|
|
{ |
|
|
|
|
int friendId = toxav_get_peer_id(toxav, callId, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV answer peer ID"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ToxAvCSettings* transSettings = new ToxAvCSettings; |
|
|
|
|
int err = toxav_get_peer_csettings(toxav, callId, 0, transSettings); |
|
|
|
|
if (err != av_ErrorNone) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "answerCall: error getting call settings"; |
|
|
|
|
delete transSettings; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (transSettings->call_type == av_TypeVideo) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("answering call %1 with video").arg(callId); |
|
|
|
|
toxav_answer(toxav, callId, transSettings); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("answering call %1 without video").arg(callId); |
|
|
|
|
toxav_answer(toxav, callId, transSettings); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
delete transSettings; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::hangupCall(int32_t callId) |
|
|
|
|
void CoreAV::hangupCall(int32_t callId) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("hanging up call %1").arg(callId); |
|
|
|
|
toxav_hangup(toxav, callId); |
|
|
|
|
calls[callId].active = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::rejectCall(int32_t callId) |
|
|
|
|
void CoreAV::rejectCall(int32_t callId) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("rejecting call %1").arg(callId); |
|
|
|
|
calls[callId].active = false; |
|
|
|
|
toxav_reject(toxav, callId, nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::startCall(uint32_t friendId, bool video) |
|
|
|
|
void CoreAV::startCall(uint32_t friendId, bool video) |
|
|
|
|
{ |
|
|
|
|
int32_t callId; |
|
|
|
|
ToxAvCSettings cSettings = av_DefaultSettings; |
|
|
|
|
cSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; |
|
|
|
|
cSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; |
|
|
|
|
if (video) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("Starting new call with %1 with video").arg(friendId); |
|
|
|
|
cSettings.call_type = av_TypeVideo; |
|
|
|
|
if (toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME) == 0) |
|
|
|
|
{ |
|
|
|
|
calls[callId].videoEnabled=true; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
qWarning() << QString("Failed to start new video call with %1").arg(friendId); |
|
|
|
|
emit avCallFailed(friendId); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("Starting new call with %1 without video").arg(friendId); |
|
|
|
|
cSettings.call_type = av_TypeAudio; |
|
|
|
|
if (toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME) == 0) |
|
|
|
|
{ |
|
|
|
|
calls[callId].videoEnabled=false; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
qWarning() << QString("Failed to start new audio call with %1").arg(friendId); |
|
|
|
|
emit avCallFailed(friendId); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::cancelCall(int32_t callId, uint32_t friendId) |
|
|
|
|
void CoreAV::cancelCall(int32_t callId, uint32_t friendId) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("Cancelling call with %1").arg(friendId); |
|
|
|
|
calls[callId].active = false; |
|
|
|
|
toxav_cancel(toxav, callId, friendId, nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::cleanupCall(int32_t callId) |
|
|
|
|
void CoreAV::cleanupCall(int32_t callId) |
|
|
|
|
{ |
|
|
|
|
assert(calls[callId].active); |
|
|
|
|
qDebug() << QString("cleaning up call %1").arg(callId); |
|
|
|
@ -249,16 +150,10 @@ void Core::cleanupCall(int32_t callId)
@@ -249,16 +150,10 @@ void Core::cleanupCall(int32_t callId)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Audio::getInstance().unsubscribeInput(); |
|
|
|
|
toxav_kill_transmission(Core::getInstance()->toxav, callId); |
|
|
|
|
|
|
|
|
|
if (!anyActiveCalls()) |
|
|
|
|
{ |
|
|
|
|
delete[] videobuf; |
|
|
|
|
videobuf = nullptr; |
|
|
|
|
} |
|
|
|
|
//toxav_kill_transmission(Core::getInstance()->toxav, callId);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::playCallAudio(void* toxav, int32_t callId, const int16_t *data, uint16_t samples, void *user_data) |
|
|
|
|
void CoreAV::playCallAudio(void* toxav, int32_t callId, const int16_t *data, uint16_t samples, void *user_data) |
|
|
|
|
{ |
|
|
|
|
Q_UNUSED(user_data); |
|
|
|
|
|
|
|
|
@ -268,12 +163,12 @@ void Core::playCallAudio(void* toxav, int32_t callId, const int16_t *data, uint1
@@ -268,12 +163,12 @@ void Core::playCallAudio(void* toxav, int32_t callId, const int16_t *data, uint1
|
|
|
|
|
if (!calls[callId].alSource) |
|
|
|
|
alGenSources(1, &calls[callId].alSource); |
|
|
|
|
|
|
|
|
|
ToxAvCSettings dest; |
|
|
|
|
if (toxav_get_peer_csettings((ToxAv*)toxav, callId, 0, &dest) == 0) |
|
|
|
|
playAudioBuffer(calls[callId].alSource, data, samples, dest.audio_channels, dest.audio_sample_rate); |
|
|
|
|
//ToxAvCSettings dest;
|
|
|
|
|
//if (toxav_get_peer_csettings((ToxAV*)toxav, callId, 0, &dest) == 0)
|
|
|
|
|
// playAudioBuffer(calls[callId].alSource, data, samples, dest.audio_channels, dest.audio_sample_rate);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::sendCallAudio(int32_t callId, ToxAv* toxav) |
|
|
|
|
void CoreAV::sendCallAudio(int32_t callId, ToxAV* toxav) |
|
|
|
|
{ |
|
|
|
|
if (!calls[callId].active) |
|
|
|
|
return; |
|
|
|
@ -284,6 +179,7 @@ void Core::sendCallAudio(int32_t callId, ToxAv* toxav)
@@ -284,6 +179,7 @@ void Core::sendCallAudio(int32_t callId, ToxAv* toxav)
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
const int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000 * av_DefaultSettings.audio_channels; |
|
|
|
|
const int bufsize = framesize * 2 * av_DefaultSettings.audio_channels; |
|
|
|
|
uint8_t buf[bufsize]; |
|
|
|
@ -322,10 +218,11 @@ void Core::sendCallAudio(int32_t callId, ToxAv* toxav)
@@ -322,10 +218,11 @@ void Core::sendCallAudio(int32_t callId, ToxAv* toxav)
|
|
|
|
|
if ((r = toxav_send_audio(toxav, callId, dest, r)) < 0) |
|
|
|
|
qDebug() << "toxav_send_audio error"; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
calls[callId].sendAudioTimer->start(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::playCallVideo(void*, int32_t callId, const vpx_image_t* img, void *user_data) |
|
|
|
|
void CoreAV::playCallVideo(void*, int32_t callId, const vpx_image *img, void *user_data) |
|
|
|
|
{ |
|
|
|
|
Q_UNUSED(user_data); |
|
|
|
|
|
|
|
|
@ -335,7 +232,7 @@ void Core::playCallVideo(void*, int32_t callId, const vpx_image_t* img, void *us
@@ -335,7 +232,7 @@ void Core::playCallVideo(void*, int32_t callId, const vpx_image_t* img, void *us
|
|
|
|
|
calls[callId].videoSource->pushFrame(img); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::sendCallVideo(int32_t callId, ToxAv* toxav, std::shared_ptr<VideoFrame> vframe) |
|
|
|
|
void CoreAV::sendCallVideo(int32_t callId, ToxAV* toxav, std::shared_ptr<VideoFrame> vframe) |
|
|
|
|
{ |
|
|
|
|
if (!calls[callId].active || !calls[callId].videoEnabled) |
|
|
|
|
return; |
|
|
|
@ -349,6 +246,7 @@ void Core::sendCallVideo(int32_t callId, ToxAv* toxav, std::shared_ptr<VideoFram
@@ -349,6 +246,7 @@ void Core::sendCallVideo(int32_t callId, ToxAv* toxav, std::shared_ptr<VideoFram
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
int result; |
|
|
|
|
if ((result = toxav_prepare_video_frame(toxav, callId, videobuf, videobufsize, frame)) < 0) |
|
|
|
|
{ |
|
|
|
@ -359,213 +257,25 @@ void Core::sendCallVideo(int32_t callId, ToxAv* toxav, std::shared_ptr<VideoFram
@@ -359,213 +257,25 @@ void Core::sendCallVideo(int32_t callId, ToxAv* toxav, std::shared_ptr<VideoFram
|
|
|
|
|
|
|
|
|
|
if ((result = toxav_send_video(toxav, callId, (uint8_t*)videobuf, result)) < 0) |
|
|
|
|
qDebug() << QString("toxav_send_video error: %1").arg(result); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
delete frame; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::micMuteToggle(int32_t callId) |
|
|
|
|
void CoreAV::micMuteToggle(int32_t callId) |
|
|
|
|
{ |
|
|
|
|
if (calls[callId].active) |
|
|
|
|
calls[callId].muteMic = !calls[callId].muteMic; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::volMuteToggle(int32_t callId) |
|
|
|
|
void CoreAV::volMuteToggle(int32_t callId) |
|
|
|
|
{ |
|
|
|
|
if (calls[callId].active) |
|
|
|
|
calls[callId].muteVol = !calls[callId].muteVol; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::onAvCancel(void* _toxav, int32_t callId, void* core) |
|
|
|
|
{ |
|
|
|
|
ToxAv* toxav = static_cast<ToxAv*>(_toxav); |
|
|
|
|
|
|
|
|
|
int friendId = toxav_get_peer_id(toxav, callId, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV cancel"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
qDebug() << QString("AV cancel from %1").arg(friendId); |
|
|
|
|
|
|
|
|
|
calls[callId].active = false; |
|
|
|
|
|
|
|
|
|
#ifdef QTOX_FILTER_AUDIO |
|
|
|
|
if (filterer[callId]) |
|
|
|
|
{ |
|
|
|
|
filterer[callId]->closeFilter(); |
|
|
|
|
delete filterer[callId]; |
|
|
|
|
filterer[callId] = nullptr; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
emit static_cast<Core*>(core)->avCancel(friendId, callId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::onAvReject(void* _toxav, int32_t callId, void* core) |
|
|
|
|
{ |
|
|
|
|
ToxAv* toxav = static_cast<ToxAv*>(_toxav); |
|
|
|
|
int friendId = toxav_get_peer_id(toxav, callId, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV reject"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
qDebug() << QString("AV reject from %1").arg(friendId); |
|
|
|
|
|
|
|
|
|
emit static_cast<Core*>(core)->avRejected(friendId, callId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::onAvEnd(void* _toxav, int32_t call_index, void* core) |
|
|
|
|
{ |
|
|
|
|
ToxAv* toxav = static_cast<ToxAv*>(_toxav); |
|
|
|
|
|
|
|
|
|
int friendId = toxav_get_peer_id(toxav, call_index, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV end"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
qDebug() << QString("AV end from %1").arg(friendId); |
|
|
|
|
|
|
|
|
|
emit static_cast<Core*>(core)->avEnd(friendId, call_index); |
|
|
|
|
|
|
|
|
|
if (calls[call_index].active) |
|
|
|
|
cleanupCall(call_index); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::onAvRinging(void* _toxav, int32_t call_index, void* core) |
|
|
|
|
{ |
|
|
|
|
ToxAv* toxav = static_cast<ToxAv*>(_toxav); |
|
|
|
|
|
|
|
|
|
int friendId = toxav_get_peer_id(toxav, call_index, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV ringing"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (calls[call_index].videoEnabled) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("AV ringing with %1 with video").arg(friendId); |
|
|
|
|
emit static_cast<Core*>(core)->avRinging(friendId, call_index, true); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("AV ringing with %1 without video").arg(friendId); |
|
|
|
|
emit static_cast<Core*>(core)->avRinging(friendId, call_index, false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::onAvRequestTimeout(void* _toxav, int32_t call_index, void* core) |
|
|
|
|
{ |
|
|
|
|
ToxAv* toxav = static_cast<ToxAv*>(_toxav); |
|
|
|
|
|
|
|
|
|
int friendId = toxav_get_peer_id(toxav, call_index, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV request timeout"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
qDebug() << QString("AV request timeout with %1").arg(friendId); |
|
|
|
|
|
|
|
|
|
emit static_cast<Core*>(core)->avRequestTimeout(friendId, call_index); |
|
|
|
|
|
|
|
|
|
if (calls[call_index].active) |
|
|
|
|
cleanupCall(call_index); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::onAvPeerTimeout(void* _toxav, int32_t call_index, void* core) |
|
|
|
|
{ |
|
|
|
|
ToxAv* toxav = static_cast<ToxAv*>(_toxav); |
|
|
|
|
|
|
|
|
|
int friendId = toxav_get_peer_id(toxav, call_index, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV peer timeout"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
qDebug() << QString("AV peer timeout with %1").arg(friendId); |
|
|
|
|
|
|
|
|
|
emit static_cast<Core*>(core)->avPeerTimeout(friendId, call_index); |
|
|
|
|
|
|
|
|
|
if (calls[call_index].active) |
|
|
|
|
cleanupCall(call_index); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) |
|
|
|
|
{ |
|
|
|
|
ToxAv* toxav = static_cast<ToxAv*>(_toxav); |
|
|
|
|
|
|
|
|
|
int friendId = toxav_get_peer_id(toxav, call_index, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV invite"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ToxAvCSettings* transSettings = new ToxAvCSettings; |
|
|
|
|
int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); |
|
|
|
|
if (err != av_ErrorNone) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "onAvInvite: error getting call type"; |
|
|
|
|
delete transSettings; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (transSettings->call_type == av_TypeVideo) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("AV invite from %1 with video").arg(friendId); |
|
|
|
|
emit static_cast<Core*>(core)->avInvite(friendId, call_index, true); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("AV invite from %1 without video").arg(friendId); |
|
|
|
|
emit static_cast<Core*>(core)->avInvite(friendId, call_index, false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
delete transSettings; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::onAvStart(void* _toxav, int32_t call_index, void* core) |
|
|
|
|
{ |
|
|
|
|
ToxAv* toxav = static_cast<ToxAv*>(_toxav); |
|
|
|
|
|
|
|
|
|
int friendId = toxav_get_peer_id(toxav, call_index, 0); |
|
|
|
|
if (friendId < 0) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Received invalid AV start"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ToxAvCSettings* transSettings = new ToxAvCSettings; |
|
|
|
|
int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); |
|
|
|
|
if (err != av_ErrorNone) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "onAvStart: error getting call type"; |
|
|
|
|
delete transSettings; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (transSettings->call_type == av_TypeVideo) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("AV start from %1 with video").arg(friendId); |
|
|
|
|
prepareCall(friendId, call_index, toxav, true); |
|
|
|
|
emit static_cast<Core*>(core)->avStart(friendId, call_index, true); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("AV start from %1 without video").arg(friendId); |
|
|
|
|
prepareCall(friendId, call_index, toxav, false); |
|
|
|
|
emit static_cast<Core*>(core)->avStart(friendId, call_index, false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
delete transSettings; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This function's logic was shamelessly stolen from uTox
|
|
|
|
|
void Core::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, unsigned channels, int sampleRate) |
|
|
|
|
void CoreAV::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, unsigned channels, int sampleRate) |
|
|
|
|
{ |
|
|
|
|
if (!channels || channels > 2) |
|
|
|
|
{ |
|
|
|
@ -610,12 +320,12 @@ void Core::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, un
@@ -610,12 +320,12 @@ void Core::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, un
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VideoSource *Core::getVideoSourceFromCall(int callNumber) |
|
|
|
|
VideoSource *CoreAV::getVideoSourceFromCall(int callNumber) |
|
|
|
|
{ |
|
|
|
|
return calls[callNumber].videoSource; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::joinGroupCall(int groupId) |
|
|
|
|
void CoreAV::joinGroupCall(int groupId) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("Joining group call %1").arg(groupId); |
|
|
|
|
groupCalls[groupId].groupId = groupId; |
|
|
|
@ -623,16 +333,13 @@ void Core::joinGroupCall(int groupId)
@@ -623,16 +333,13 @@ void Core::joinGroupCall(int groupId)
|
|
|
|
|
groupCalls[groupId].muteVol = false; |
|
|
|
|
// the following three lines are also now redundant from startCall, but are
|
|
|
|
|
// necessary there for outbound and here for inbound
|
|
|
|
|
groupCalls[groupId].codecSettings = av_DefaultSettings; |
|
|
|
|
groupCalls[groupId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; |
|
|
|
|
groupCalls[groupId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; |
|
|
|
|
|
|
|
|
|
// Audio
|
|
|
|
|
Audio::getInstance().subscribeInput(); |
|
|
|
|
|
|
|
|
|
// Go
|
|
|
|
|
Core* core = Core::getInstance(); |
|
|
|
|
ToxAv* toxav = core->toxav; |
|
|
|
|
ToxAV* toxav = core->toxav; |
|
|
|
|
|
|
|
|
|
groupCalls[groupId].sendAudioTimer = new QTimer(); |
|
|
|
|
groupCalls[groupId].active = true; |
|
|
|
@ -642,7 +349,7 @@ void Core::joinGroupCall(int groupId)
@@ -642,7 +349,7 @@ void Core::joinGroupCall(int groupId)
|
|
|
|
|
groupCalls[groupId].sendAudioTimer->start(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::leaveGroupCall(int groupId) |
|
|
|
|
void CoreAV::leaveGroupCall(int groupId) |
|
|
|
|
{ |
|
|
|
|
qDebug() << QString("Leaving group call %1").arg(groupId); |
|
|
|
|
groupCalls[groupId].active = false; |
|
|
|
@ -655,7 +362,7 @@ void Core::leaveGroupCall(int groupId)
@@ -655,7 +362,7 @@ void Core::leaveGroupCall(int groupId)
|
|
|
|
|
delete groupCalls[groupId].sendAudioTimer; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::sendGroupCallAudio(int groupId, ToxAv* toxav) |
|
|
|
|
void CoreAV::sendGroupCallAudio(int groupId, ToxAV *toxav) |
|
|
|
|
{ |
|
|
|
|
if (!groupCalls[groupId].active) |
|
|
|
|
return; |
|
|
|
@ -666,6 +373,7 @@ void Core::sendGroupCallAudio(int groupId, ToxAv* toxav)
@@ -666,6 +373,7 @@ void Core::sendGroupCallAudio(int groupId, ToxAv* toxav)
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
const int framesize = (groupCalls[groupId].codecSettings.audio_frame_duration * groupCalls[groupId].codecSettings.audio_sample_rate) / 1000 * av_DefaultSettings.audio_channels; |
|
|
|
|
const int bufsize = framesize * 2 * av_DefaultSettings.audio_channels; |
|
|
|
|
uint8_t buf[bufsize]; |
|
|
|
@ -680,35 +388,63 @@ void Core::sendGroupCallAudio(int groupId, ToxAv* toxav)
@@ -680,35 +388,63 @@ void Core::sendGroupCallAudio(int groupId, ToxAv* toxav)
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
groupCalls[groupId].sendAudioTimer->start(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::disableGroupCallMic(int groupId) |
|
|
|
|
void CoreAV::disableGroupCallMic(int groupId) |
|
|
|
|
{ |
|
|
|
|
groupCalls[groupId].muteMic = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::disableGroupCallVol(int groupId) |
|
|
|
|
void CoreAV::disableGroupCallVol(int groupId) |
|
|
|
|
{ |
|
|
|
|
groupCalls[groupId].muteVol = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::enableGroupCallMic(int groupId) |
|
|
|
|
void CoreAV::enableGroupCallMic(int groupId) |
|
|
|
|
{ |
|
|
|
|
groupCalls[groupId].muteMic = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Core::enableGroupCallVol(int groupId) |
|
|
|
|
void CoreAV::enableGroupCallVol(int groupId) |
|
|
|
|
{ |
|
|
|
|
groupCalls[groupId].muteVol = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Core::isGroupCallMicEnabled(int groupId) |
|
|
|
|
bool CoreAV::isGroupCallMicEnabled(int groupId) |
|
|
|
|
{ |
|
|
|
|
return !groupCalls[groupId].muteMic; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Core::isGroupCallVolEnabled(int groupId) |
|
|
|
|
bool CoreAV::isGroupCallVolEnabled(int groupId) |
|
|
|
|
{ |
|
|
|
|
return !groupCalls[groupId].muteVol; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool CoreAV::isGroupAvEnabled(int groupId) |
|
|
|
|
{ |
|
|
|
|
return tox_group_get_type(Core::getInstance()->tox, groupId) == TOX_GROUPCHAT_TYPE_AV; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CoreAV::resetCallSources() |
|
|
|
|
{ |
|
|
|
|
for (ToxGroupCall& call : groupCalls) |
|
|
|
|
{ |
|
|
|
|
for (ALuint source : call.alSources) |
|
|
|
|
alDeleteSources(1, &source); |
|
|
|
|
call.alSources.clear(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (ToxCall& call : calls) |
|
|
|
|
{ |
|
|
|
|
if (call.active && call.alSource) |
|
|
|
|
{ |
|
|
|
|
ALuint tmp = call.alSource; |
|
|
|
|
call.alSource = 0; |
|
|
|
|
alDeleteSources(1, &tmp); |
|
|
|
|
|
|
|
|
|
alGenSources(1, &call.alSource); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|