📄 audiortp.cpp
字号:
/* * Copyright (C) 2004-2005 Savoir-Faire Linux inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <cstdio>#include <cstdlib>#include <ccrtp/rtp.h>#include <assert.h>#include <string>#include <cstring>#include "../global.h"#include "../manager.h"#include "codecDescriptor.h"#include "audiortp.h"#include "audiolayer.h"#include "ringbuffer.h"#include "../user_cfg.h"#include "../sipcall.h"#include <samplerate.h>////////////////////////////////////////////////////////////////////////////////// AudioRtp ////////////////////////////////////////////////////////////////////////////////AudioRtp::AudioRtp (){ _RTXThread = 0;}AudioRtp::~AudioRtp (void) { delete _RTXThread; _RTXThread = 0;}int AudioRtp::createNewSession (SIPCall *ca) { ost::MutexLock m(_threadMutex); // something should stop the thread before... if ( _RTXThread != 0 ) { _debug("! ARTP Failure: Thread already exists..., stopping it\n"); delete _RTXThread; _RTXThread = 0; //return -1; } // Start RTP Send/Receive threads _symmetric = Manager::instance().getConfigInt(SIGNALISATION,SYMMETRIC) ? true : false; _RTXThread = new AudioRtpRTX (ca, _symmetric); try { if (_RTXThread->start() != 0) { _debug("! ARTP Failure: unable to start RTX Thread\n"); return -1; } } catch(...) { _debugException("! ARTP Failure: when trying to start a thread"); throw; } return 0;} voidAudioRtp::closeRtpSession () { ost::MutexLock m(_threadMutex); // This will make RTP threads finish. // _debug("Stopping AudioRTP\n"); try { delete _RTXThread; _RTXThread = 0; } catch(...) { _debugException("! ARTP Exception: when stopping audiortp\n"); throw; }}////////////////////////////////////////////////////////////////////////////////// AudioRtpRTX Class //////////////////////////////////////////////////////////////////////////////////AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym) { setCancel(cancelDeferred); time = new ost::Time(); _ca = sipcall; _sym = sym; // AudioRtpRTX should be close if we change sample rate _receiveDataDecoded = new int16[RTP_20S_48KHZ_MAX]; _sendDataEncoded = new unsigned char[RTP_20S_8KHZ_MAX]; // we estimate that the number of format after a conversion 8000->48000 is expanded to 6 times _dataAudioLayer = new SFLDataFormat[RTP_20S_48KHZ_MAX]; _floatBuffer8000 = new float32[RTP_20S_8KHZ_MAX]; _floatBuffer48000 = new float32[RTP_20S_48KHZ_MAX]; _intBuffer8000 = new int16[RTP_20S_8KHZ_MAX]; // TODO: Change bind address according to user settings. // TODO: this should be the local ip not the external (router) IP std::string localipConfig = _ca->getLocalIp(); // _ca->getLocalIp(); ost::InetHostAddress local_ip(localipConfig.c_str()); if (!_sym) { _sessionRecv = new ost::RTPSession(local_ip, _ca->getLocalAudioPort()); _sessionSend = new ost::RTPSession(local_ip, _ca->getLocalAudioPort()); _session = NULL; } else { _session = new ost::SymmetricRTPSession (local_ip, _ca->getLocalAudioPort()); _sessionRecv = NULL; _sessionSend = NULL; }}AudioRtpRTX::~AudioRtpRTX () { _start.wait(); try { this->terminate(); } catch(...) { _debugException("! ARTP: Thread destructor didn't terminate correctly"); throw; } //_debug("terminate audiortprtx ended...\n"); _ca = 0; if (!_sym) { delete _sessionRecv; _sessionRecv = 0; delete _sessionSend; _sessionSend = 0; } else { delete _session; _session = 0; } delete [] _intBuffer8000; _intBuffer8000 = 0; delete [] _floatBuffer48000; _floatBuffer48000 = 0; delete [] _floatBuffer8000; _floatBuffer8000 = 0; delete [] _dataAudioLayer; _dataAudioLayer = 0; delete [] _sendDataEncoded; _sendDataEncoded = 0; delete [] _receiveDataDecoded; _receiveDataDecoded = 0; delete time; time = NULL;}voidAudioRtpRTX::initAudioRtpSession (void) { try { if (_ca == 0) { return; } //_debug("Init audio RTP session\n"); ost::InetHostAddress remote_ip(_ca->getRemoteIp().c_str()); if (!remote_ip) { _debug("! ARTP Thread Error: Target IP address [%s] is not correct!\n", _ca->getRemoteIp().data()); return; } // Initialization if (!_sym) { _sessionRecv->setSchedulingTimeout (10000); _sessionRecv->setExpireTimeout(1000000); _sessionSend->setSchedulingTimeout(10000); _sessionSend->setExpireTimeout(1000000); } else { _session->setSchedulingTimeout(10000); _session->setExpireTimeout(1000000); } if (!_sym) { if ( !_sessionRecv->addDestination(remote_ip, (unsigned short) _ca->getRemoteAudioPort()) ) { _debug("AudioRTP Thread Error: could not connect to port %d\n", _ca->getRemoteAudioPort()); return; } if (!_sessionSend->addDestination (remote_ip, (unsigned short) _ca->getRemoteAudioPort())) { _debug("! ARTP Thread Error: could not connect to port %d\n", _ca->getRemoteAudioPort()); return; } AudioCodec* audiocodec = _ca->getAudioCodec(); bool payloadIsSet = false; if (audiocodec) { if (audiocodec->hasDynamicPayload()) { payloadIsSet = _sessionRecv->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate())); } else { payloadIsSet= _sessionRecv->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload())); payloadIsSet = _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload())); } } _sessionSend->setMark(true); } else { //_debug("AudioRTP Thread: Added session destination %s:%d\n", remote_ip.getHostname(), (unsigned short) _ca->getRemoteSdpAudioPort()); if (!_session->addDestination (remote_ip, (unsigned short) _ca->getRemoteAudioPort())) { return; } AudioCodec* audiocodec = _ca->getAudioCodec(); bool payloadIsSet = false; if (audiocodec) { if (audiocodec->hasDynamicPayload()) { payloadIsSet = _session->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate())); } else { payloadIsSet = _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload())); } } } } catch(...) { _debugException("! ARTP Failure: initialisation failed"); throw; }}voidAudioRtpRTX::sendSessionFromMic(int timestamp){ // STEP: // 1. get data from mic // 2. convert it to int16 - good sample, good rate // 3. encode it // 4. send it try { timestamp += time->getSecond(); if (_ca==0) { _debug(" !ARTP: No call associated (mic)\n"); return; } // no call, so we do nothing AudioLayer* audiolayer = Manager::instance().getAudioDriver(); if (!audiolayer) { _debug(" !ARTP: No audiolayer available for mic\n"); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -