- fixes
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "helper/HL_VariantMap.h"
|
||||
#include "helper/HL_CsvReader.h"
|
||||
#include "helper/HL_Base64.h"
|
||||
#include "media/MT_CodecList.h"
|
||||
#include <fstream>
|
||||
|
||||
|
||||
@@ -210,7 +211,8 @@ void AgentImpl::processStart(JsonCpp::Value& request, JsonCpp::Value &answer)
|
||||
SocketHeap::instance().start();
|
||||
|
||||
// Initialize terminal
|
||||
MT::CodecList::Settings settings;
|
||||
auto settings = MT::CodecList::Settings::getClientSettings();
|
||||
|
||||
mTerminal = std::make_shared<MT::Terminal>(settings);
|
||||
|
||||
// Enable/disable codecs
|
||||
@@ -220,10 +222,10 @@ void AgentImpl::processStart(JsonCpp::Value& request, JsonCpp::Value &answer)
|
||||
priorityConfig->at(i) = i;
|
||||
|
||||
// Disable dynamic payload codec types - commented for now
|
||||
/*if (cl.codecAt(i).payloadType() < 96)
|
||||
priorityConfig->at(i) = i;
|
||||
else
|
||||
priorityConfig->at(i) = -1;*/
|
||||
// if (cl.codecAt(i).payloadType() < 96)
|
||||
// priorityConfig->at(i) = i;
|
||||
// else
|
||||
// priorityConfig->at(i) = -1;
|
||||
|
||||
config()[CONFIG_CODEC_PRIORITY] = priorityConfig;
|
||||
|
||||
|
||||
@@ -423,13 +423,13 @@ bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** de
|
||||
payloadLength = p->GetPayloadLength(),
|
||||
ptype = p->GetPayloadType();
|
||||
|
||||
// ICELogInfo(<< "Adding packet No " << p->GetSequenceNumber());
|
||||
ICELogInfo(<< "Adding packet No " << p->GetSequenceNumber());
|
||||
// Increase codec counter
|
||||
mStat.mCodecCount[ptype]++;
|
||||
|
||||
// Check if codec can be handled
|
||||
Codec* codec = nullptr;
|
||||
CodecMap::iterator codecIter = mCodecMap.find(ptype);
|
||||
auto codecIter = mCodecMap.find(ptype);
|
||||
if (codecIter == mCodecMap.end())
|
||||
{
|
||||
time_length = 10;
|
||||
@@ -618,7 +618,17 @@ AudioReceiver::DecodeResult AudioReceiver::decodePacket(const RtpBuffer::ResultL
|
||||
|
||||
// Find codec by payload type
|
||||
int ptype = p->rtp()->GetPayloadType();
|
||||
mCodec = mCodecMap[ptype];
|
||||
|
||||
// Look into mCodecMap if exists
|
||||
auto codecIter = mCodecMap.find(ptype);
|
||||
if (codecIter == mCodecMap.end())
|
||||
return {};
|
||||
|
||||
|
||||
if (!codecIter->second)
|
||||
codecIter->second = mCodecList.createCodecByPayloadType(ptype);
|
||||
|
||||
mCodec = codecIter->second;
|
||||
if (mCodec)
|
||||
{
|
||||
if (rate)
|
||||
@@ -695,7 +705,7 @@ AudioReceiver::DecodeResult AudioReceiver::decodePacket(const RtpBuffer::ResultL
|
||||
|
||||
AudioReceiver::DecodeResult AudioReceiver::decodeNone(Audio::DataWindow& output, DecodeOptions options)
|
||||
{
|
||||
ICELogDebug(<< "No packet available in jitter buffer");
|
||||
// ICELogDebug(<< "No packet available in jitter buffer");
|
||||
mFailedCount++;
|
||||
return DecodeResult_Skip;
|
||||
}
|
||||
|
||||
@@ -225,9 +225,9 @@ void AudioStream::addData(const void* buffer, int bytes)
|
||||
if (packetTime <= encodedTime)
|
||||
{
|
||||
// Time to send packet
|
||||
ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType << ", plength = " << (int)mEncodedAudio.size());
|
||||
ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType << ", plength = " << (int)mEncodedAudio.size() << " to ");
|
||||
mRtpSession.SendPacketEx(mEncodedAudio.data(), mEncodedAudio.size(), mTransmittingPayloadType, false,
|
||||
packetTime * codec->samplerate()/1000, 0, NULL, 0);
|
||||
packetTime * codec->samplerate()/1000, 0, nullptr, 0);
|
||||
mEncodedAudio.clear();
|
||||
encodedTime = 0;
|
||||
}
|
||||
@@ -365,9 +365,11 @@ void AudioStream::dataArrived(PDatagramSocket s, const void* buffer, int length,
|
||||
|
||||
// Find right handler for rtp stream
|
||||
SingleAudioStream* rtpStream = nullptr;
|
||||
AudioStreamMap::iterator streamIter = mStreamMap.find(packet->GetSSRC());
|
||||
if (streamIter == mStreamMap.end())
|
||||
mStreamMap[packet->GetSSRC()] = rtpStream = new SingleAudioStream(mCodecSettings, mStat);
|
||||
auto streamIter = mStreamMap.find(packet->GetSSRC());
|
||||
if (streamIter == mStreamMap.end()) {
|
||||
rtpStream = new SingleAudioStream(mCodecSettings, mStat);
|
||||
mStreamMap.insert({packet->GetSSRC(), rtpStream});
|
||||
}
|
||||
else
|
||||
rtpStream = streamIter->second;
|
||||
|
||||
|
||||
@@ -62,16 +62,16 @@ public:
|
||||
protected:
|
||||
Audio::DataWindow mCapturedAudio; // Data from microphone
|
||||
Audio::DataWindow mStereoCapturedAudio;
|
||||
char mIncomingPcmBuffer[AUDIO_MIC_BUFFER_SIZE]; // Temporary buffer to allow reading from file
|
||||
char mResampleBuffer[AUDIO_MIC_BUFFER_SIZE*8]; // Temporary buffer to hold data
|
||||
char mStereoBuffer[AUDIO_MIC_BUFFER_SIZE*16]; // Temporary buffer to hold data converted to stereo
|
||||
char mIncomingPcmBuffer[AUDIO_MIC_BUFFER_SIZE] = {0}; // Temporary buffer to allow reading from file
|
||||
char mResampleBuffer[AUDIO_MIC_BUFFER_SIZE*8] = {0}; // Temporary buffer to hold data
|
||||
char mStereoBuffer[AUDIO_MIC_BUFFER_SIZE*16] = {0}; // Temporary buffer to hold data converted to stereo
|
||||
PCodec mTransmittingCodec; // Current encoding codec
|
||||
int mTransmittingPayloadType; // Payload type to mark outgoing packets
|
||||
int mPacketTime; // Required packet time
|
||||
int mTransmittingPayloadType = -1; // Payload type to mark outgoing packets
|
||||
int mPacketTime = 0; // Required packet time
|
||||
char mFrameBuffer[MT_MAXAUDIOFRAME]; // Temporary buffer to hold results of encoder
|
||||
ByteBuffer mEncodedAudio; // Encoded frame(s)
|
||||
int mEncodedTime; // Time length of encoded audio
|
||||
const CodecList::Settings& mCodecSettings; // Configuration for stream
|
||||
int mEncodedTime = 0; // Time length of encoded audio
|
||||
CodecList::Settings mCodecSettings; // Configuration for stream
|
||||
Mutex mMutex; // Mutex
|
||||
int mRemoteTelephoneCodec; // Payload for remote telephone codec
|
||||
jrtplib::RTPSession mRtpSession; // Rtp session
|
||||
@@ -83,12 +83,12 @@ protected:
|
||||
RtpDump* mRtpDump = nullptr;
|
||||
#endif
|
||||
Audio::Resampler mCaptureResampler8,
|
||||
mCaptureResampler16,
|
||||
mCaptureResampler32,
|
||||
mCaptureResampler48;
|
||||
mCaptureResampler16,
|
||||
mCaptureResampler32,
|
||||
mCaptureResampler48;
|
||||
DtmfContext mDtmfContext;
|
||||
char mReceiveBuffer[MAX_VALID_UDPPACKET_SIZE],
|
||||
mSrtpDecodeBuffer[MAX_VALID_UDPPACKET_SIZE];
|
||||
char mReceiveBuffer[MAX_VALID_UDPPACKET_SIZE] = {0},
|
||||
mSrtpDecodeBuffer[MAX_VALID_UDPPACKET_SIZE] = {0};
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -106,7 +106,7 @@ protected:
|
||||
|
||||
Statistics* mFinalStatistics = nullptr;
|
||||
|
||||
bool decryptSrtp(void* data, int* len);
|
||||
// bool decryptSrtp(void* data, int* len);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ PStream Terminal::createStream(int type, VariantMap& /*config*/)
|
||||
switch (type)
|
||||
{
|
||||
case Stream::Audio:
|
||||
result = std::make_shared<AudioStream>(MT::CodecList::Settings::DefaultSettings);
|
||||
result = std::make_shared<AudioStream>(MT::CodecList::Settings::getClientSettings());
|
||||
mAudioList.add(result);
|
||||
break;
|
||||
|
||||
|
||||
@@ -25,6 +25,17 @@ using namespace MT;
|
||||
|
||||
using strx = strx;
|
||||
|
||||
CodecList::Settings CodecList::Settings::getAnalyzerSettings()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
CodecList::Settings CodecList::Settings::getClientSettings()
|
||||
{
|
||||
Settings r;
|
||||
r.mOpusSpec.push_back(Settings::OpusSpec(MT_OPUS_CODEC_PT, 48000, 2));
|
||||
return r;
|
||||
}
|
||||
|
||||
bool CodecList::Settings::contains(int ptype) const
|
||||
{
|
||||
@@ -223,7 +234,7 @@ static int findOctetMode(const char* line)
|
||||
|
||||
CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>& codeclist)
|
||||
{
|
||||
CodecList::Settings r{DefaultSettings};
|
||||
CodecList::Settings r;
|
||||
|
||||
for (auto& c: codeclist)
|
||||
{
|
||||
@@ -235,41 +246,27 @@ CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>&
|
||||
auto params = c.parameters();
|
||||
|
||||
// Dynamic payload type codecs only - ISAC / iLBC / Speex / etc.
|
||||
if (codec_name == "OPUS")
|
||||
{
|
||||
if (codec_name == "OPUS") {
|
||||
// Check the parameters
|
||||
int channels = strx::toInt(enc_params.c_str(), 1);
|
||||
r.mOpusSpec.push_back({ptype, samplerate, channels});
|
||||
}
|
||||
else
|
||||
if (codec_name == "AMR-WB")
|
||||
{
|
||||
} else if (codec_name == "AMR-WB") {
|
||||
int octet_mode = findOctetMode(params.c_str());
|
||||
if (octet_mode != -1)
|
||||
{
|
||||
if (octet_mode != -1) {
|
||||
if (octet_mode == 0)
|
||||
r.mAmrWbPayloadType.insert(ptype);
|
||||
else
|
||||
if (octet_mode == 1)
|
||||
else if (octet_mode == 1)
|
||||
r.mAmrWbOctetPayloadType.insert(ptype);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (codec_name == "AMR" || codec_name == "AMR-NB")
|
||||
{
|
||||
} else if (codec_name == "AMR" || codec_name == "AMR-NB") {
|
||||
int octet_mode = findOctetMode(params.c_str());
|
||||
if (octet_mode != -1)
|
||||
{
|
||||
if (octet_mode != -1) {
|
||||
if (octet_mode == 0)
|
||||
r.mAmrNbPayloadType.insert(ptype);
|
||||
else
|
||||
if (octet_mode == 1)
|
||||
else if (octet_mode == 1)
|
||||
r.mAmrNbOctetPayloadType.insert(ptype);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (codec_name == "EVS")
|
||||
{
|
||||
} else if (codec_name == "EVS") {
|
||||
r.mEvsSpec.push_back({ptype});
|
||||
}
|
||||
}
|
||||
@@ -314,7 +311,6 @@ bool CodecList::Settings::operator == (const Settings& rhs) const
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
CodecList::Settings CodecList::Settings::DefaultSettings;
|
||||
|
||||
CodecList::CodecList(const Settings& settings)
|
||||
:mSettings(settings)
|
||||
@@ -405,8 +401,8 @@ void CodecList::fillCodecMap(CodecMap& cm)
|
||||
for (auto& factory: mFactoryList)
|
||||
{
|
||||
// Create codec here. Although they are not needed right now - they can be needed to find codec's info.
|
||||
// PCodec c = factory->create();
|
||||
cm.insert({factory->payloadType(), PCodec()});
|
||||
PCodec c = factory->create();
|
||||
cm.insert({factory->payloadType(), c});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,7 +434,7 @@ bool CodecListPriority::compare(const Item& item1, const Item& item2)
|
||||
|
||||
void CodecListPriority::setupFrom(PVariantMap vmap)
|
||||
{
|
||||
CodecList::Settings settings;
|
||||
auto settings = CodecList::Settings::getClientSettings();
|
||||
CodecList cl(settings);
|
||||
//mPriorityList.resize(cl.count());
|
||||
bool emptyVmap = vmap ? vmap->empty() : true;
|
||||
|
||||
@@ -101,11 +101,12 @@ public:
|
||||
std::string toString() const;
|
||||
void clear();
|
||||
|
||||
static Settings DefaultSettings;
|
||||
|
||||
static Settings parseSdp(const std::list<resip::Codec>& codeclist);
|
||||
|
||||
bool operator == (const Settings& rhs) const;
|
||||
|
||||
static Settings getClientSettings();
|
||||
static Settings getAnalyzerSettings();
|
||||
};
|
||||
|
||||
CodecList(const Settings& settings);
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
/* Copyright(C) 2007-2019 VoIP objects (voipobjects.com)
|
||||
/* Copyright(C) 2007-2026 VoIP objects (voipobjects.com)
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MT_NativeRtpSender.h"
|
||||
#include "ICELog.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define LOG_SUBSYSTEM "MT"
|
||||
using namespace MT;
|
||||
|
||||
NativeRtpSender::NativeRtpSender(Statistics& stat)
|
||||
:mStat(stat), mSrtpSession(nullptr)
|
||||
:mStat(stat), mSrtpSession(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -19,107 +21,108 @@ NativeRtpSender::~NativeRtpSender()
|
||||
|
||||
bool NativeRtpSender::SendRTP(const void *data, size_t len)
|
||||
{
|
||||
if (mTarget.mRtp.isEmpty() || !mSocket.mRtp)
|
||||
return false;
|
||||
|
||||
if (mTarget.mRtp.isEmpty() || !mSocket.mRtp)
|
||||
return false;
|
||||
|
||||
#if defined(USE_RTPDUMP)
|
||||
if (mDumpWriter)
|
||||
mDumpWriter->add(data, len);
|
||||
if (mDumpWriter)
|
||||
mDumpWriter->add(data, len);
|
||||
#endif
|
||||
|
||||
// Copy data to intermediary buffer bigger that original
|
||||
int sendLength = len;
|
||||
memcpy(mSendBuffer, data, len);
|
||||
// Copy data to intermediary buffer bigger that original
|
||||
int sendLength = len;
|
||||
memcpy(mSendBuffer, data, len);
|
||||
|
||||
// Encrypt SRTP if needed
|
||||
if (mSrtpSession)
|
||||
{
|
||||
if (mSrtpSession->active())
|
||||
// Encrypt SRTP if needed
|
||||
if (mSrtpSession)
|
||||
{
|
||||
if (!mSrtpSession->protectRtp(mSendBuffer, &sendLength))
|
||||
return false;
|
||||
if (mSrtpSession->active())
|
||||
{
|
||||
if (!mSrtpSession->protectRtp(mSendBuffer, &sendLength))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mSocket.mRtp->sendDatagram(mTarget.mRtp, mSendBuffer, sendLength);
|
||||
mStat.mSentRtp++;
|
||||
mStat.mSent += len;
|
||||
ICELogInfo(<< "Sending " << sendLength <<" bytes to " << mTarget.mRtp.toBriefStdString());
|
||||
mSocket.mRtp->sendDatagram(mTarget.mRtp, mSendBuffer, sendLength);
|
||||
mStat.mSentRtp++;
|
||||
mStat.mSent += len;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** This member function will be called when an RTCP packet needs to be transmitted. */
|
||||
bool NativeRtpSender::SendRTCP(const void *data, size_t len)
|
||||
{
|
||||
if (mTarget.mRtp.isEmpty() || !mSocket.mRtcp)
|
||||
return false;
|
||||
// Copy data to intermediary buffer bigger that original
|
||||
int sendLength = len;
|
||||
memcpy(mSendBuffer, data, len);
|
||||
|
||||
// Encrypt SRTP if needed
|
||||
if (mSrtpSession)
|
||||
{
|
||||
if (mSrtpSession->active())
|
||||
{
|
||||
if (!mSrtpSession->protectRtcp(mSendBuffer, &sendLength))
|
||||
if (mTarget.mRtp.isEmpty() || !mSocket.mRtcp)
|
||||
return false;
|
||||
// Copy data to intermediary buffer bigger that original
|
||||
int sendLength = len;
|
||||
memcpy(mSendBuffer, data, len);
|
||||
|
||||
// Encrypt SRTP if needed
|
||||
if (mSrtpSession)
|
||||
{
|
||||
if (mSrtpSession->active())
|
||||
{
|
||||
if (!mSrtpSession->protectRtcp(mSendBuffer, &sendLength))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mSocket.mRtcp->sendDatagram(mTarget.mRtcp, mSendBuffer, sendLength);
|
||||
mStat.mSentRtcp++;
|
||||
mStat.mSent += len;
|
||||
mSocket.mRtcp->sendDatagram(mTarget.mRtcp, mSendBuffer, sendLength);
|
||||
mStat.mSentRtcp++;
|
||||
mStat.mSent += len;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** Used to identify if an RTPAddress instance originated from this sender (to be able to detect own packets). */
|
||||
bool NativeRtpSender::ComesFromThisSender(const jrtplib::RTPAddress *a)
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void NativeRtpSender::setDestination(RtpPair<InternetAddress> target)
|
||||
{
|
||||
mTarget = target;
|
||||
mTarget = target;
|
||||
}
|
||||
|
||||
RtpPair<InternetAddress> NativeRtpSender::destination()
|
||||
{
|
||||
return mTarget;
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
void NativeRtpSender::setSocket(const RtpPair<PDatagramSocket>& socket)
|
||||
{
|
||||
mSocket = socket;
|
||||
mSocket = socket;
|
||||
}
|
||||
|
||||
RtpPair<PDatagramSocket>& NativeRtpSender::socket()
|
||||
{
|
||||
return mSocket;
|
||||
return mSocket;
|
||||
}
|
||||
|
||||
#if defined(USE_RTPDUMP)
|
||||
void NativeRtpSender::setDumpWriter(RtpDump *dump)
|
||||
{
|
||||
mDumpWriter = dump;
|
||||
mDumpWriter = dump;
|
||||
}
|
||||
|
||||
RtpDump* NativeRtpSender::dumpWriter()
|
||||
{
|
||||
return mDumpWriter;
|
||||
return mDumpWriter;
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeRtpSender::setSrtpSession(SrtpSession* srtp)
|
||||
{
|
||||
mSrtpSession = srtp;
|
||||
mSrtpSession = srtp;
|
||||
}
|
||||
|
||||
SrtpSession* NativeRtpSender::srtpSession()
|
||||
{
|
||||
return mSrtpSession;
|
||||
return mSrtpSession;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,19 +18,19 @@
|
||||
|
||||
namespace MT
|
||||
{
|
||||
class NativeRtpSender: public jrtplib::RTPExternalSender
|
||||
{
|
||||
public:
|
||||
class NativeRtpSender: public jrtplib::RTPExternalSender
|
||||
{
|
||||
public:
|
||||
NativeRtpSender(Statistics& stat);
|
||||
~NativeRtpSender();
|
||||
|
||||
/** This member function will be called when RTP data needs to be transmitted. */
|
||||
bool SendRTP(const void *data, size_t len);
|
||||
/** This member function will be called when RTP data needs to be transmitted. */
|
||||
bool SendRTP(const void *data, size_t len);
|
||||
|
||||
/** This member function will be called when an RTCP packet needs to be transmitted. */
|
||||
bool SendRTCP(const void *data, size_t len);
|
||||
/** This member function will be called when an RTCP packet needs to be transmitted. */
|
||||
bool SendRTCP(const void *data, size_t len);
|
||||
|
||||
/** Used to identify if an RTPAddress instance originated from this sender (to be able to detect own packets). */
|
||||
/** Used to identify if an RTPAddress instance originated from this sender (to be able to detect own packets). */
|
||||
bool ComesFromThisSender(const jrtplib::RTPAddress *a);
|
||||
|
||||
void setDestination(RtpPair<InternetAddress> destination);
|
||||
@@ -46,7 +46,7 @@ namespace MT
|
||||
void setSrtpSession(SrtpSession* srtp);
|
||||
SrtpSession* srtpSession();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
RtpPair<PDatagramSocket> mSocket;
|
||||
RtpPair<InternetAddress> mTarget;
|
||||
Statistics& mStat;
|
||||
@@ -55,7 +55,7 @@ namespace MT
|
||||
#endif
|
||||
SrtpSession* mSrtpSession;
|
||||
char mSendBuffer[MAX_VALID_UDPPACKET_SIZE];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ void SingleAudioStream::copyPcmTo(Audio::DataWindow& output, int needed)
|
||||
break;
|
||||
}
|
||||
|
||||
if (output.filled() < needed)
|
||||
ICELogError(<< "Not enough data for speaker's mixer");
|
||||
// if (output.filled() < needed)
|
||||
// ICELogError(<< "Not enough data for speaker's mixer");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user