@ -105,8 +105,9 @@ CoreAV::CoreAV(Tox* tox)
@@ -105,8 +105,9 @@ CoreAV::CoreAV(Tox* tox)
CoreAV : : ~ CoreAV ( )
{
for ( const auto & call : calls )
for ( const auto & call : calls ) {
cancelCall ( call . first ) ;
}
killTimerFromThread ( ) ;
toxav_kill ( toxav ) ;
coreavThread - > exit ( 0 ) ;
@ -198,7 +199,7 @@ bool CoreAV::isCallStarted(const Group* g) const
@@ -198,7 +199,7 @@ bool CoreAV::isCallStarted(const Group* g) const
*/
bool CoreAV : : isCallActive ( const Friend * f ) const
{
return isCallStarted ( f ) ? ! ( calls [ f - > getId ( ) ] . inactive ) : false ;
return isCallStarted ( f ) & & calls [ f - > getId ( ) ] . isActive ( ) ;
}
/**
@ -208,12 +209,12 @@ bool CoreAV::isCallActive(const Friend* f) const
@@ -208,12 +209,12 @@ bool CoreAV::isCallActive(const Friend* f) const
*/
bool CoreAV : : isCallActive ( const Group * g ) const
{
return isCallStarted ( g ) ? ! ( groupCalls [ g - > getId ( ) ] . inactive ) : false ;
return isCallStarted ( g ) & & groupCalls [ g - > getId ( ) ] . isActive ( ) ;
}
bool CoreAV : : isCallVideoEnabled ( const Friend * f ) const
{
return isCallStarted ( f ) ? calls [ f - > getId ( ) ] . videoEnabled : false ;
return isCallStarted ( f ) & & calls [ f - > getId ( ) ] . getVideoEnabled ( ) ;
}
bool CoreAV : : answerCall ( uint32_t friendNum , bool video )
@ -238,7 +239,7 @@ bool CoreAV::answerCall(uint32_t friendNum, bool video)
@@ -238,7 +239,7 @@ bool CoreAV::answerCall(uint32_t friendNum, bool video)
const uint32_t videoBitrate = video ? VIDEO_DEFAULT_BITRATE : 0 ;
if ( toxav_answer ( toxav , friendNum , Settings : : getInstance ( ) . getAudioBitrate ( ) , videoBitrate , & err ) ) {
calls [ friendNum ] . inactive = false ;
calls [ friendNum ] . setActive ( false ) ;
return true ;
} else {
qWarning ( ) < < " Failed to answer call with error " < < err ;
@ -275,7 +276,7 @@ bool CoreAV::startCall(uint32_t friendNum, bool video)
@@ -275,7 +276,7 @@ bool CoreAV::startCall(uint32_t friendNum, bool video)
if ( ! toxav_call ( toxav , friendNum , Settings : : getInstance ( ) . getAudioBitrate ( ) , videoBitrate , nullptr ) )
return false ;
calls [ friendNum ] = ToxFriendCall { friendNum , video , * this } ;
calls . insert ( std : : make_pair ( friendNum , ToxFriendCall ( friendNum , video , * this ) ) ) ;
calls [ friendNum ] . startTimeout ( friendNum ) ;
return true ;
}
@ -336,12 +337,13 @@ void CoreAV::timeoutCall(uint32_t friendNum)
@@ -336,12 +337,13 @@ void CoreAV::timeoutCall(uint32_t friendNum)
bool CoreAV : : sendCallAudio ( uint32_t callId , const int16_t * pcm , size_t samples , uint8_t chans ,
uint32_t rate )
{
if ( calls . find ( callId ) = = calls . end ( ) )
if ( calls . find ( callId ) = = calls . end ( ) ) {
return false ;
}
ToxFriendCall & call = calls [ callId ] ;
if ( call . muteMic | | call . inactive | | ! ( call . state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A ) ) {
if ( call . getMuteMic ( ) | | call . isActive ( ) | | ! ( call . getState ( ) & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A ) ) {
return true ;
}
@ -358,8 +360,9 @@ bool CoreAV::sendCallAudio(uint32_t callId, const int16_t* pcm, size_t samples,
@@ -358,8 +360,9 @@ bool CoreAV::sendCallAudio(uint32_t callId, const int16_t* pcm, size_t samples,
}
}
} while ( err = = TOXAV_ERR_SEND_FRAME_SYNC & & retries < 5 ) ;
if ( err = = TOXAV_ERR_SEND_FRAME_SYNC )
if ( err = = TOXAV_ERR_SEND_FRAME_SYNC ) {
qDebug ( ) < < " toxav_audio_send_frame error: Lock busy, dropping frame " ;
}
return true ;
}
@ -368,18 +371,20 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe)
@@ -368,18 +371,20 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe)
{
// 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
if ( calls . find ( callId ) = = calls . end ( ) )
if ( calls . find ( callId ) = = calls . end ( ) ) {
return ;
}
ToxFriendCall & call = calls [ callId ] ;
if ( ! call . videoEnabled | | call . inactive | | ! ( call . state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V ) )
if ( ! call . getVideoEnabled ( ) | | call . isActive ( ) | | ! ( call . getState ( ) & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V ) ) {
return ;
}
if ( call . nullVideoBitrate ) {
if ( call . getVideoEnabled ( ) ) {
qDebug ( ) < < " Restarting video stream to friend " < < callId ;
toxav_bit_rate_set ( toxav , callId , - 1 , VIDEO_DEFAULT_BITRATE , nullptr ) ;
call . nullVideoBitrate = false ;
call . setVideoEnabled ( false ) ;
}
ToxYUVFrame frame = vframe - > toToxYUVFrame ( ) ;
@ -403,8 +408,9 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe)
@@ -403,8 +408,9 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe)
}
}
} while ( err = = TOXAV_ERR_SEND_FRAME_SYNC & & retries < 5 ) ;
if ( err = = TOXAV_ERR_SEND_FRAME_SYNC )
if ( err = = TOXAV_ERR_SEND_FRAME_SYNC ) {
qDebug ( ) < < " toxav_video_send_frame error: Lock busy, dropping frame " ;
}
}
/**
@ -415,7 +421,7 @@ void CoreAV::toggleMuteCallInput(const Friend* f)
@@ -415,7 +421,7 @@ void CoreAV::toggleMuteCallInput(const Friend* f)
{
if ( f & & ( calls . find ( f - > getId ( ) ) ! = calls . end ( ) ) ) {
ToxCall & call = calls [ f - > getId ( ) ] ;
call . muteMic = ! call . muteMic ;
call . setMuteMic ( ! call . getMuteMic ( ) ) ;
}
}
@ -427,7 +433,7 @@ void CoreAV::toggleMuteCallOutput(const Friend* f)
@@ -427,7 +433,7 @@ void CoreAV::toggleMuteCallOutput(const Friend* f)
{
if ( f & & ( calls . find ( f - > getId ( ) ) ! = calls . end ( ) ) ) {
ToxCall & call = calls [ f - > getId ( ) ] ;
call . muteVol = ! call . muteVol ;
call . setMuteVol ( call . getMuteVol ( ) ) ;
}
}
@ -459,14 +465,16 @@ void CoreAV::groupCallCallback(void* tox, int group, int peer, const int16_t* da
@@ -459,14 +465,16 @@ void CoreAV::groupCallCallback(void* tox, int group, int peer, const int16_t* da
emit c - > groupPeerAudioPlaying ( group , peer ) ;
if ( call . muteVol | | call . inactive )
if ( call . getMuteVol ( ) | | ! call . isActive ( ) )
{
return ;
}
Audio & audio = Audio : : getInstance ( ) ;
if ( ! call . peers [ peer ] )
audio . subscribeOutput ( call . peers [ peer ] ) ;
if ( ! call . getPeers ( ) [ peer ] )
audio . subscribeOutput ( call . getPeers ( ) [ peer ] ) ;
audio . playAudioBuffer ( call . peers [ peer ] , data , samples , channels , sample_rate ) ;
audio . playAudioBuffer ( call . getPeers ( ) [ peer ] , data , samples , channels , sample_rate ) ;
}
/**
@ -477,8 +485,8 @@ void CoreAV::groupCallCallback(void* tox, int group, int peer, const int16_t* da
@@ -477,8 +485,8 @@ void CoreAV::groupCallCallback(void* tox, int group, int peer, const int16_t* da
void CoreAV : : invalidateGroupCallPeerSource ( int group , int peer )
{
Audio & audio = Audio : : getInstance ( ) ;
audio . unsubscribeOutput ( groupCalls [ group ] . peers [ peer ] ) ;
groupCalls [ group ] . peers [ peer ] = 0 ;
audio . unsubscribeOutput ( groupCalls [ group ] . getPeers ( ) [ peer ] ) ;
groupCalls [ group ] . getPeers ( ) [ peer ] = 0 ;
}
/**
@ -494,7 +502,7 @@ VideoSource* CoreAV::getVideoSourceFromCall(int friendNum)
@@ -494,7 +502,7 @@ VideoSource* CoreAV::getVideoSourceFromCall(int friendNum)
return nullptr ;
}
return calls [ friendNum ] . videoSource ;
return calls [ friendNum ] . getVideoSource ( ) ;
}
/**
@ -507,7 +515,7 @@ void CoreAV::joinGroupCall(int groupId)
@@ -507,7 +515,7 @@ void CoreAV::joinGroupCall(int groupId)
qDebug ( ) < < QString ( " Joining group call %1 " ) . arg ( groupId ) ;
groupCalls [ groupId ] = ToxGroupCall { groupId , * this } ;
groupCalls [ groupId ] . inactive = false ;
groupCalls [ groupId ] . setActive ( false ) ;
}
/**
@ -531,8 +539,9 @@ bool CoreAV::sendGroupCallAudio(int groupId, const int16_t* pcm, size_t samples,
@@ -531,8 +539,9 @@ bool CoreAV::sendGroupCallAudio(int groupId, const int16_t* pcm, size_t samples,
ToxGroupCall & call = groupCalls [ groupId ] ;
if ( call . inactive | | call . muteMic )
if ( call . isActive ( ) | | call . getMuteMic ( ) ) {
return true ;
}
if ( toxav_group_send_audio ( toxav_get_tox ( toxav ) , groupId , pcm , samples , chans , rate ) ! = 0 )
qDebug ( ) < < " toxav_group_send_audio error " ;
@ -547,8 +556,9 @@ bool CoreAV::sendGroupCallAudio(int groupId, const int16_t* pcm, size_t samples,
@@ -547,8 +556,9 @@ bool CoreAV::sendGroupCallAudio(int groupId, const int16_t* pcm, size_t samples,
*/
void CoreAV : : muteCallInput ( const Group * g , bool mute )
{
if ( g & & ( groupCalls . find ( g - > getId ( ) ) ! = groupCalls . end ( ) ) )
groupCalls [ g - > getId ( ) ] . muteMic = mute ;
if ( g & & ( groupCalls . find ( g - > getId ( ) ) ! = groupCalls . end ( ) ) ) {
groupCalls [ g - > getId ( ) ] . setMuteMic ( mute ) ;
}
}
/**
@ -558,8 +568,9 @@ void CoreAV::muteCallInput(const Group* g, bool mute)
@@ -558,8 +568,9 @@ void CoreAV::muteCallInput(const Group* g, bool mute)
*/
void CoreAV : : muteCallOutput ( const Group * g , bool mute )
{
if ( g & & ( groupCalls . find ( g - > getId ( ) ) ! = groupCalls . end ( ) ) )
groupCalls [ g - > getId ( ) ] . muteVol = mute ;
if ( g & & ( groupCalls . find ( g - > getId ( ) ) ! = groupCalls . end ( ) ) ) {
groupCalls [ g - > getId ( ) ] . setMuteVol ( mute ) ;
}
}
/**
@ -569,7 +580,12 @@ void CoreAV::muteCallOutput(const Group* g, bool mute)
@@ -569,7 +580,12 @@ void CoreAV::muteCallOutput(const Group* g, bool mute)
*/
bool CoreAV : : isGroupCallInputMuted ( const Group * g ) const
{
return g & & ( groupCalls . find ( g - > getId ( ) ) ! = groupCalls . end ( ) ) ? groupCalls [ g - > getId ( ) ] . muteMic : false ;
if ( ! g ) {
return false ;
}
const uint32_t groupId = g - > getId ( ) ;
return ( groupCalls . find ( groupId ) ! = groupCalls . end ( ) ) & & groupCalls [ groupId ] . getMuteMic ( ) ;
}
/**
@ -579,7 +595,12 @@ bool CoreAV::isGroupCallInputMuted(const Group* g) const
@@ -579,7 +595,12 @@ bool CoreAV::isGroupCallInputMuted(const Group* g) const
*/
bool CoreAV : : isGroupCallOutputMuted ( const Group * g ) const
{
return g & & ( groupCalls . find ( g - > getId ( ) ) ! = groupCalls . end ( ) ) ? groupCalls [ g - > getId ( ) ] . muteVol : false ;
if ( ! g ) {
return false ;
}
const uint32_t groupId = g - > getId ( ) ;
return ( groupCalls . find ( groupId ) ! = groupCalls . end ( ) ) & & groupCalls [ groupId ] . getMuteVol ( ) ;
}
/**
@ -612,7 +633,11 @@ bool CoreAV::isGroupAvEnabled(int groupId) const
@@ -612,7 +633,11 @@ bool CoreAV::isGroupAvEnabled(int groupId) const
*/
bool CoreAV : : isCallInputMuted ( const Friend * f ) const
{
return f & & ( calls . find ( f - > getId ( ) ) ! = calls . end ( ) ) ? calls [ f - > getId ( ) ] . muteMic : false ;
if ( ! f ) {
return false ;
}
const uint32_t friendId = f - > getId ( ) ;
return ( calls . find ( friendId ) ! = calls . end ( ) ) & & calls [ friendId ] . getMuteMic ( ) ;
}
/**
@ -622,7 +647,11 @@ bool CoreAV::isCallInputMuted(const Friend* f) const
@@ -622,7 +647,11 @@ bool CoreAV::isCallInputMuted(const Friend* f) const
*/
bool CoreAV : : isCallOutputMuted ( const Friend * f ) const
{
return f & & ( calls . find ( f - > getId ( ) ) ! = calls . end ( ) ) ? calls [ f - > getId ( ) ] . muteVol : false ;
if ( ! f ) {
return false ;
}
const uint32_t friendId = f - > getId ( ) ;
return ( calls . find ( friendId ) ! = calls . end ( ) ) & & calls [ f - > getId ( ) ] . getMuteVol ( ) ;
}
/**
@ -631,11 +660,12 @@ bool CoreAV::isCallOutputMuted(const Friend* f) const
@@ -631,11 +660,12 @@ bool CoreAV::isCallOutputMuted(const Friend* f) const
void CoreAV : : invalidateCallSources ( )
{
for ( auto & kv : groupCalls ) {
kv . second . peers . clear ( ) ;
kv . second . getPeers ( ) . clear ( ) ;
}
for ( auto & kv : calls ) {
kv . second . alSource = 0 ;
// TODO: this is wrong, "0" is a valid source id
kv . second . setAlSource ( 0 ) ;
}
}
@ -650,7 +680,7 @@ void CoreAV::sendNoVideo()
@@ -650,7 +680,7 @@ void CoreAV::sendNoVideo()
for ( auto & kv : calls ) {
ToxFriendCall & call = kv . second ;
toxav_bit_rate_set ( toxav , kv . first , - 1 , 0 , nullptr ) ;
call . nullVideoBitrate = true ;
call . setNullVideoBitrate ( true ) ;
}
}
@ -693,7 +723,7 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid
@@ -693,7 +723,7 @@ 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 ;
if ( video )
state | = TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V ;
calls [ friendNum ] . state = static_cast < TOXAV_FRIEND_CALL_STATE > ( state ) ;
calls [ friendNum ] . setState ( static_cast < TOXAV_FRIEND_CALL_STATE > ( state ) ) ;
emit reinterpret_cast < CoreAV * > ( self ) - > avInvite ( friendNum , video ) ;
self - > threadSwitchLock . clear ( std : : memory_order_release ) ;
@ -738,27 +768,29 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
@@ -738,27 +768,29 @@ void CoreAV::stateCallback(ToxAV* toxav, uint32_t friendNum, uint32_t state, voi
emit self - > avEnd ( friendNum ) ;
} else {
// If our state was null, we started the call and were still ringing
if ( ! call . state & & state ) {
if ( ! call . getState ( ) & & state ) {
call . stopTimeout ( ) ;
call . inactive = false ;
emit self - > avStart ( friendNum , call . videoEnabled ) ;
} else if ( ( call . state & TOXAV_FRIEND_CALL_STATE_SENDING_V )
call . setActive ( false ) ;
emit self - > avStart ( friendNum , call . getVideoEnabled ( ) ) ;
} else if ( ( call . getState ( ) & TOXAV_FRIEND_CALL_STATE_SENDING_V )
& & ! ( state & TOXAV_FRIEND_CALL_STATE_SENDING_V ) ) {
qDebug ( ) < < " Friend " < < friendNum < < " stopped sending video " ;
if ( call . videoSource )
call . videoSource - > stopSource ( ) ;
} else if ( ! ( call . state & TOXAV_FRIEND_CALL_STATE_SENDING_V )
if ( call . getVideoSource ( ) ) {
call . getVideoSource ( ) - > stopSource ( ) ;
}
} else if ( ! ( call . getState ( ) & TOXAV_FRIEND_CALL_STATE_SENDING_V )
& & ( state & TOXAV_FRIEND_CALL_STATE_SENDING_V ) ) {
// Workaround toxav sometimes firing callbacks for "send last frame" -> "stop sending
// video"
// out of orders (even though they were sent in order by the other end).
// We simply stop the videoSource from emitting anything while the other end says it's
// not sending
if ( call . videoSource )
call . videoSource - > restartSource ( ) ;
if ( call . getVideoSource ( ) ) {
call . getVideoSource ( ) - > restartSource ( ) ;
}
}
call . state = static_cast < TOXAV_FRIEND_CALL_STATE > ( state ) ;
call . setState ( static_cast < TOXAV_FRIEND_CALL_STATE > ( state ) ) ;
}
self - > threadSwitchLock . clear ( std : : memory_order_release ) ;
}
@ -784,31 +816,38 @@ void CoreAV::audioFrameCallback(ToxAV*, uint32_t friendNum, const int16_t* pcm,
@@ -784,31 +816,38 @@ void CoreAV::audioFrameCallback(ToxAV*, uint32_t friendNum, const int16_t* pcm,
uint8_t channels , uint32_t samplingRate , void * vSelf )
{
CoreAV * self = static_cast < CoreAV * > ( vSelf ) ;
if ( self - > calls . find ( friendNum ) = = self - > calls . end ( ) )
if ( self - > calls . find ( friendNum ) = = self - > calls . end ( ) ) {
return ;
}
ToxCall & call = self - > calls [ friendNum ] ;
ToxFriend Call & call = self - > calls [ friendNum ] ;
if ( call . muteVol )
if ( call . getMuteVol ( ) ) {
return ;
}
Audio & audio = Audio : : getInstance ( ) ;
if ( ! call . alSource )
audio . subscribeOutput ( call . alSource ) ;
if ( ! call . getAlSource ( ) ) {
quint32 sourceId ;
audio . subscribeOutput ( sourceId ) ;
call . setAlSource ( sourceId ) ;
}
audio . playAudioBuffer ( call . alSource , pcm , sampleCount , channels , samplingRate ) ;
audio . playAudioBuffer ( call . getAlSource ( ) , pcm , sampleCount , channels , samplingRate ) ;
}
void CoreAV : : videoFrameCallback ( ToxAV * , uint32_t friendNum , uint16_t w , uint16_t h ,
const uint8_t * y , const uint8_t * u , const uint8_t * v ,
int32_t ystride , int32_t ustride , int32_t vstride , void * )
{
if ( calls . find ( friendNum ) = = calls . end ( ) )
if ( calls . find ( friendNum ) = = calls . end ( ) ) {
return ;
}
ToxFriendCall & call = calls [ friendNum ] ;
if ( ! call . videoSource )
CoreVideoSource * videoSource = calls [ friendNum ] . getVideoSource ( ) ;
if ( ! videoSource ) {
return ;
}
vpx_image frame ;
frame . d_h = h ;
@ -820,5 +859,5 @@ void CoreAV::videoFrameCallback(ToxAV*, uint32_t friendNum, uint16_t w, uint16_t
@@ -820,5 +859,5 @@ void CoreAV::videoFrameCallback(ToxAV*, uint32_t friendNum, uint16_t w, uint16_t
frame . stride [ 1 ] = ustride ;
frame . stride [ 2 ] = vstride ;
call . videoSource - > pushFrame ( & frame ) ;
videoSource - > pushFrame ( & frame ) ;
}