📄 callaudio.cpp
字号:
QString codec = settings.readEntry( "/kphone/audio/Codec", "PCMU" ); if( codec == "PCMU" ) { setCodec( codecPCMU ); } else if( codec == "GSM" ) { setCodec( codecGSM ); } else if( codec == "PCMA" ) { setCodec( codecPCMA ); } else if( codec == "ILBC_20" ) { setCodec( codecILBC_20 ); } else if( codec == "ILBC" ) { setCodec( codecILBC_30 ); }}void CallAudio::readVideoSettings( void ){ QSettings settings; setVideoSW( settings.readEntry( "/kphone/video/videoSW", "/usr/local/bin/vic" ) ); QString videoCodec = settings.readEntry( "/kphone/video/codec", "h261" ); if( videoCodec == "h261" ) { setVideoCodec( codecH261 ); } else if( videoCodec == "h263" ) { setVideoCodec( codecH263 ); }}void CallAudio::setCurrentCall( SipCall *newcall ){ curcall = newcall; statusUpdated();}void CallAudio::attachToCallMember( SipCallMember *newmember ){ if( curmember ) { detachAndHold(); } curmember = newmember; connect( curmember, SIGNAL( statusUpdated(SipCallMember *) ), this, SLOT( memberStatusUpdated(SipCallMember *) ) ); statusUpdated();}void CallAudio::detachAndHold( void ){ if( local.isOnHold() ) { printf( "CallAudio: Call already on hold\n" ); } else { toggleOnHold(); }}void CallAudio::toggleOnHold( void ){ if( local.isOnHold() ) { printf( "CallAudio: Resuming call\n" ); curmember->requestInvite( audioOut().message( getRtpCodec(), getVideoRtpCodec(), getBodyMask() ), MimeContentType( "application/sdp" ) ); } else { printf( "CallAudio: Putting call on hold\n" ); local.setIpAddress( "0.0.0.0" ); local.setName( "Whoa there dewd" ); local.setPort( 0 ); local.setVideoPort( 0 ); curmember->requestInvite( local.message( getRtpCodec(), getVideoRtpCodec(), getBodyMask() ), MimeContentType( "application/sdp" ) ); detachFromCall(); }}bool CallAudio::checkCodec( SipCallMember *member ){ bool status = true; QString mstr = member->getSessionDescription(); rtpCodec = codecUnknown; videoRtpCodec = codecUnknown; if( mstr.contains( "m=audio" ) ) { QString ilbc = ""; QString m = mstr.mid( mstr.find( "m=audio" ) ); m = m.left( m.find( "\n" ) ); m = m.mid( m.find( "RTP/AVP" ) + 7 ); m += ' '; // dynamic port 96-127 if( mstr.lower().contains( "ilbc/8000" ) ) { ilbc = mstr.mid( mstr.lower().find( "ilbc/8000" ) - 7, 6 ); if( ilbc.contains( ":" ) ) { ilbc = ilbc.mid( ilbc.find( ":" ) + 1 ); } ilbc = ilbc.simplifyWhiteSpace(); } int posPCMU = m.find( " 0 " ); int posGSM = m.find( " 3 " ); int posPCMA = m.find( " 8 " ); int posILBC = m.lower().find( " " + ilbc + " " ); if( posPCMU < 0 ) posPCMU = 101; if( posGSM < 0 ) posGSM = 101; if( posPCMA < 0 ) posPCMA = 101; if( posILBC < 0 ) posILBC = 101;#define MIN(a,b) (a)<(b)?(a):(b) int winner = MIN ( posPCMU , posGSM ); winner = MIN ( winner , posPCMA ); winner = MIN ( winner , posILBC ); if ( winner == posPCMU ) { rtpCodec = codecPCMU; rtpCodecNum = 0; } else if ( winner == posGSM ) { rtpCodec = codecGSM; rtpCodecNum = 3; } if ( winner == posPCMA ) { rtpCodec = codecPCMA; rtpCodecNum = 8; } else if( winner == posILBC ) { rtpCodec = codecILBC_30; rtpCodecNum = ilbc.toInt(); if( mstr.contains( "a=fmtp:" ) ) { QString m = mstr.mid( mstr.find( "a=fmtp:" ) ); m = m.left( m.find( "\n" ) ); if( m.lower().contains( "mode=20" ) ) { rtpCodec = codecILBC_20; } } } } if( mstr.contains( "m=video" ) ) { QString ilbc = ""; QString m = mstr.mid( mstr.find( "m=video" ) ); m = m.left( m.find( "\n" ) ); m = m.mid( m.find( "RTP/AVP" ) + 7 ); m += ' '; int posH261 = m.find( " 31 " ); int posH263 = m.find( " 34 " ); if( posH261 < 0 ) posH261 = 101; if( posH263 < 0 ) posH263 = 101;#ifdef MESSENGER if( videoCodec == codecH261 ) { videoRtpCodec = codecH261; videoRtpCodecNum = 31; } else { videoRtpCodec = codecH263; videoRtpCodecNum = 34; }#else if( posH261 < posH263 ) { videoRtpCodec = codecH261; videoRtpCodecNum = 31; } else if( posH263 < posH261 ) { videoRtpCodec = codecH263; videoRtpCodecNum = 34; }#endif } if( rtpCodec == codecILBC_20 ) { printf( "CallAudio: Using iLBC 20ms for output\n" ); } else if( rtpCodec == codecILBC_30 ) { printf( "CallAudio: Using iLBC 30ms for output\n" ); } else if( rtpCodec == codecPCMA ) { printf( "CallAudio: Using G711a for output\n" ); } else if( rtpCodec == codecGSM ) { printf( "CallAudio: Using GSM for output\n" ); } else if( rtpCodec == codecPCMU ) { printf( "CallAudio: Using G711u for output\n" ); } else if( rtpCodec == codecUnknown ) { status = false; } if( rtpCodec != codecUnknown ) { if( videoRtpCodec == codecH261 ) { printf( "CallAudio: Using H261 for video output\n" ); } else if( videoRtpCodec == codecH263 ) { printf( "CallAudio: Using H263 for video output\n" ); } else { if( curcall ) { curcall->setCallType( SipCall::StandardCall ); } } } return status;}void CallAudio::memberStatusUpdated(SipCallMember *member){ SdpMessage sdpm; SdpMessage rsdp; curmember = member; sdpm.parseInput( curmember->getSessionDescription() ); if( checkCodec( curmember ) ) { if( curmember->getState() == SipCallMember::state_RequestingReInvite ) { if( sdpm.isOnHold() ) { rsdp.setName( "Accepting on hold" ); rsdp.setIpAddress( "0.0.0.0" ); rsdp.setPort( 0 ); rsdp.setVideoPort( 0 ); curmember->acceptInvite( rsdp.message( getRtpCodec(), getVideoRtpCodec(), getBodyMask() ), MimeContentType( "application/sdp" ) ); stopSendingAudio(); stopListeningAudio(); } else { curmember->acceptInvite( audioOut().message( getRtpCodec(), getVideoRtpCodec(), getBodyMask() ), MimeContentType( "application/sdp" ) ); } } if( sdpm != remote ) { remote = sdpm; if( !sdpm.isOnHold() ) { if( output ) { output->setCodec( getRtpCodec(), getRtpCodecNum() ); audioIn(); output->start(); input->start(); } else if( jack_audioout ) {// jack_audioout->setCodec( getRtpCodec(), getRtpCodecNum() ); audioIn();/* jack_audioout->start(); jack_audioin->start();*/ } } statusUpdated(); } }}void CallAudio::detachFromCall( void ){ if( curmember ) { disconnect( curmember, 0, this, 0 ); } curmember = 0; stopSendingAudio(); stopListeningAudio(); setCurrentCall( 0 ); if( pidVideo ) { kill( pidVideo, SIGKILL ); pidVideo = 0; }}bool CallAudio::isRemoteHold( void ){ return remote.isOnHold();}void CallAudio::renegotiateCall( void ){ if( !curcall ) return; stopSendingAudio(); stopListeningAudio(); curmember->requestInvite( audioOut().message( getRtpCodec(), getVideoRtpCodec(), getBodyMask() ), MimeContentType( "application/sdp" ) );}bool CallAudio::isAudioOn( void ){ return (output || input );}codecType CallAudio::getRtpCodec( void ){ if( rtpCodec != codecUnknown ) { return rtpCodec; } else { return codec; }}int CallAudio::getRtpCodecNum( void ){ int c; if( rtpCodec != codecUnknown ) { c = rtpCodecNum; } else { switch( codec ) { case codecGSM: c = 3; break; case codecPCMA: c = 8; break; case codecILBC_20: case codecILBC_30: c = 97; break; case codecPCMU: default: c = 0; break; } } return c;}codecType CallAudio::getVideoRtpCodec( void ){ if( videoRtpCodec != codecUnknown ) { return videoRtpCodec; } else { if( curcall ) { if( curcall->getCallType() == SipCall::videoCall ) { return videoCodec; } else { return codecUnknown; } } else { return codecUnknown; } }}int CallAudio::getVideoRtpCodecNum( void ){ int c; if( curcall ) { if( curcall->getCallType() != SipCall::videoCall ) { return -1; } } if( videoRtpCodec != codecUnknown ) { c = videoRtpCodecNum; } else { switch( videoCodec ) { case codecH261: c = 31; break; case codecH263: c = 34; break; default: c = -1; break; } } return c;}QString CallAudio::getVideoRtpCodecName( void ){ QString c; if( curcall->getCallType() != SipCall::videoCall ) { return ""; } if( videoRtpCodec != codecUnknown ) { switch( videoRtpCodec ) { case codecH263: c = "h263"; break; default: case codecH261: c = "h261"; break; } } else { switch( videoCodec ) { case codecH263: c = "h263"; break; default: case codecH261: c = "h261"; break; } } return c;}void CallAudio::setStunSrv( QString newStunSrv ){ useStun = true; stunSrv = newStunSrv;}void CallAudio::startDTMF(char code){ if (output) { output->startTone(code); } if (input) { input->startTone(code); }}void CallAudio::stopDTMF(void){ if (output) { output->stopTone(); } if (input) { input->stopTone(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -