/* * Copyright 2014 Range Networks, Inc. * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing * information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #define LOG_GROUP LogGroup::SIP // Can set Log.Level.SIP for debugging #include #include #include "SIPRtp.h" #include "SIPBase.h" #include "SIP2Interface.h" #include #undef WARNING // The nimrods defined this to "warning" #undef CR // This too // Type is RtpCallback, but args determined by rtp_signal_table_emit2 extern "C" { void ourRtpTimestampJumpCallback(RtpSession *session, unsigned long timestamp,unsigned long dialogid) { SIP::SipDialogRef dialog = SIP::gSipInterface.dmFindDialogByRtp(session); if (dialog.self()) { LOG(NOTICE) << "RTP timestamp jump"<mRxTime) { rtp_session_resync(session); dialog->mRxTime = 0; dialog->mRxRealTime = 0; } } else { LOG(ALERT) << "RTP timestamp jump, but no dialog"<= 63200) { mDTMFEnding = 1; } //volume 10 for some magic reason, arg 3 is true to send an end packet. // (pat) The magic reason is that the spec says DTMF tones below a certain dB should be ignored by the receiver, which is dumber than snot. int code = rtp_session_add_telephone_event(mSession,m,get_rtp_tev_type(mDTMF),!!mDTMFEnding,10,mDTMFDuration); int bytes = rtp_session_sendm_with_ts(mSession,m,mDTMFStartTime); LOG(DEBUG) <= 3) { mDTMFEnding = 0; mDTMF = 0; } } return (!code && bytes > 0); } // Return true if ok, false on failure. bool SipRtp::startDTMF(char key) { LOG (DEBUG) << key <clock_rate in rtp_session_ts_to_time to yield 20ms. void SipRtp::txFrame(AudioFrame* frame, unsigned numFlushed) { if(vgetSipState()!=Active) return; ScopedLock lock(mRtpLock); // HACK -- Hardcoded for GSM/8000. // FIXME: Make this work for multiple vocoder types. (pat) fixed, but codec is still hard-coded in initRTP1. int nbytes = frame->sizeBytes(); // (pat 8-2013) Our send stream is discontinous. After a discontinuity, the sound degrades. // I think this is caused by bugs in the RTP library. mTxTime += (numFlushed+1)*160; int result = rtp_session_send_with_ts(mSession, frame->begin(), nbytes, mTxTime); LOG(DEBUG) << LOGVAR(mTxTime) <begin(), maxsize, mRxTime, &more); // (pat) You MUST increase rxTime even if rtp_session_recv... returns 0. // This looks like a bug in the RTP lib to me, specifically, here: // Excerpt from rtpsession.c: rtp_session_recvm_with_ts(): // // prevent reading from the sockets when two consecutives calls for a same timestamp*/ // if (user_ts==session->rtp.rcv_last_app_ts) // read_socket=FALSE; // The bug is the above should also check the qempty() flag. // It should only manifest when blocking mode is off but we had it on when I thought I saw troubles. // I tried incrementing by just 1 when ret is 0, but that resulted in no sound at all. if (!rtpUseRealTime) { mRxTime += 160; } //LOG(DEBUG) << "rtp_session_recv returns("<setSizeBits(ret * 8); // (pat) Added warning; you could get ALOT of these: // Update: It is not that the frame is over-sized, it is that there is another frame already in the queue. //if (more) { LOG(WARNING) << "Incoming RTP frame over-sized, extra ignored." <