- clang format + naming improved
This commit is contained in:
@@ -18,13 +18,12 @@
|
||||
|
||||
#define LOG_SUBSYSTEM "media"
|
||||
|
||||
//#define DUMP_SENDING_AUDIO
|
||||
// #define DUMP_SENDING_AUDIO
|
||||
|
||||
using namespace MT;
|
||||
AudioStream::AudioStream(const CodecList::Settings& settings)
|
||||
:mPacketTime(0), mEncodedTime(0), mCodecSettings(settings),
|
||||
mRemoteTelephoneCodec(0), mRtpSession(), mTransmittingPayloadType(-1),
|
||||
mRtpSender(mStat)
|
||||
: mPacketTime(0), mEncodedTime(0), mCodecSettings(settings), mRemoteTelephoneCodec(0), mRtpSession(),
|
||||
mTransmittingPayloadType(-1), mRtpSender(mStat)
|
||||
{
|
||||
mOutputBuffer.setCapacity(16384);
|
||||
mCapturedAudio.setCapacity(16384);
|
||||
@@ -36,19 +35,19 @@ AudioStream::AudioStream(const CodecList::Settings& settings)
|
||||
// Configure transmitter
|
||||
jrtplib::RTPExternalTransmissionParams params(&mRtpSender, 0);
|
||||
|
||||
jrtplib::RTPSessionParams sessionParams;
|
||||
jrtplib::RTPSessionParams sessionParams;
|
||||
sessionParams.SetAcceptOwnPackets(true);
|
||||
sessionParams.SetMaximumPacketSize(MT_MAXRTPPACKET);
|
||||
sessionParams.SetResolveLocalHostname(false);
|
||||
sessionParams.SetUsePollThread(false);
|
||||
sessionParams.SetOwnTimestampUnit(1/8000.0);
|
||||
sessionParams.SetOwnTimestampUnit(1 / 8000.0);
|
||||
mRtpSession.Create(sessionParams, ¶ms, jrtplib::RTPTransmitter::ExternalProto);
|
||||
mRtpDtmfSession.Create(sessionParams, ¶ms, jrtplib::RTPTransmitter::ExternalProto);
|
||||
|
||||
// Attach srtp session to sender
|
||||
mRtpSender.setSrtpSession(&mSrtpSession);
|
||||
//mRtpDump = new RtpDump("d:\\outgoing.rtp");
|
||||
//mRtpSender.setDumpWriter(mRtpDump);
|
||||
// mRtpDump = new RtpDump("d:\\outgoing.rtp");
|
||||
// mRtpSender.setDumpWriter(mRtpDump);
|
||||
|
||||
#if defined(DUMP_SENDING_AUDIO)
|
||||
mSendingDump = std::make_shared<WavFileWriter>();
|
||||
@@ -107,7 +106,7 @@ void AudioStream::setDestination(const RtpPair<InternetAddress>& dest)
|
||||
mRtpSender.setDestination(dest);
|
||||
}
|
||||
|
||||
void AudioStream::setTransmittingCodec(Codec::Factory& factory, int payloadType)
|
||||
void AudioStream::setTransmittingCodec(Codec::Factory& factory, int payloadType)
|
||||
{
|
||||
ICELogInfo(<< "Selected codec " << factory.name() << "/" << factory.samplerate() << " for transmitting");
|
||||
|
||||
@@ -146,28 +145,38 @@ void AudioStream::addData(const void* buffer, int bytes)
|
||||
{
|
||||
Lock l(mMutex);
|
||||
codec = mTransmittingCodec.get();
|
||||
if (nullptr == codec) {
|
||||
if (nullptr == codec)
|
||||
{
|
||||
// ICELogDebug(<< "No transmitting codec selected.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Resample
|
||||
unsigned dstlen = unsigned(float(codec->samplerate() / float(AUDIO_SAMPLERATE)) * bytes);
|
||||
unsigned dstlen = unsigned(float(codec->samplerate() / float(AUDIO_SAMPLERATE)) * bytes);
|
||||
Audio::Resampler* r = nullptr;
|
||||
switch (codec->samplerate())
|
||||
{
|
||||
case 8000: r = &mCaptureResampler8; break;
|
||||
case 16000: r = &mCaptureResampler16; break;
|
||||
case 32000: r = &mCaptureResampler32; break;
|
||||
case 48000: r = &mCaptureResampler48; break;
|
||||
case 8000:
|
||||
r = &mCaptureResampler8;
|
||||
break;
|
||||
case 16000:
|
||||
r = &mCaptureResampler16;
|
||||
break;
|
||||
case 32000:
|
||||
r = &mCaptureResampler32;
|
||||
break;
|
||||
case 48000:
|
||||
r = &mCaptureResampler48;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
size_t processedInput = 0;
|
||||
dstlen = r->processBuffer(buffer, bytes, processedInput, mResampleBuffer, dstlen);
|
||||
// ProcessedInput output value is ignored - because sample rate of input is always 8/16/32/48K - so all buffer is processed
|
||||
// ProcessedInput output value is ignored - because sample rate of input is always 8/16/32/48K - so all buffer is
|
||||
// processed
|
||||
|
||||
// See if we need stereo <-> mono conversions
|
||||
unsigned stereolen = 0;
|
||||
@@ -181,22 +190,26 @@ void AudioStream::addData(const void* buffer, int bytes)
|
||||
|
||||
// See if inband dtmf audio should be sent instead
|
||||
ByteBuffer dtmf;
|
||||
if (mDtmfContext.type() == DtmfContext::Dtmf_Inband && mDtmfContext.getInband(AUDIO_MIC_BUFFER_LENGTH, codec->samplerate(), dtmf))
|
||||
if (mDtmfContext.type() == DtmfContext::Dtmf_Inband &&
|
||||
mDtmfContext.getInband(AUDIO_MIC_BUFFER_LENGTH, codec->samplerate(), dtmf))
|
||||
mCapturedAudio.add(dtmf.data(), dtmf.size());
|
||||
else
|
||||
mCapturedAudio.add(stereolen ? mStereoBuffer : mResampleBuffer, stereolen ? stereolen : dstlen);
|
||||
|
||||
// See if it is time to send RFC2833 tone
|
||||
ByteBuffer rfc2833, stopPacket;
|
||||
if (mDtmfContext.type() == DtmfContext::Dtmf_Rfc2833 && mDtmfContext.getRfc2833(AUDIO_MIC_BUFFER_LENGTH, rfc2833, stopPacket))
|
||||
if (mDtmfContext.type() == DtmfContext::Dtmf_Rfc2833 &&
|
||||
mDtmfContext.getRfc2833(AUDIO_MIC_BUFFER_LENGTH, rfc2833, stopPacket))
|
||||
{
|
||||
if (rfc2833.size())
|
||||
mRtpDtmfSession.SendPacket(rfc2833.data(), rfc2833.size(), mRemoteTelephoneCodec, true, AUDIO_MIC_BUFFER_LENGTH * 8);
|
||||
mRtpDtmfSession.SendPacket(rfc2833.data(), rfc2833.size(), mRemoteTelephoneCodec, true,
|
||||
AUDIO_MIC_BUFFER_LENGTH * 8);
|
||||
|
||||
if (stopPacket.size())
|
||||
{
|
||||
for (int i=0; i<3; i++)
|
||||
mRtpDtmfSession.SendPacket(stopPacket.data(), stopPacket.size(), mRemoteTelephoneCodec, true, AUDIO_MIC_BUFFER_LENGTH * 8);
|
||||
for (int i = 0; i < 3; i++)
|
||||
mRtpDtmfSession.SendPacket(stopPacket.data(), stopPacket.size(), mRemoteTelephoneCodec, true,
|
||||
AUDIO_MIC_BUFFER_LENGTH * 8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,14 +218,15 @@ void AudioStream::addData(const void* buffer, int bytes)
|
||||
int packetTime = mPacketTime ? mPacketTime : codec->frameTime();
|
||||
|
||||
// Make stereo version if required
|
||||
for (int i=0; i<mCapturedAudio.filled() / codec->pcmLength(); i++)
|
||||
for (int i = 0; i < mCapturedAudio.filled() / codec->pcmLength(); i++)
|
||||
{
|
||||
if (mSendingDump)
|
||||
mSendingDump->write((const char*)mCapturedAudio.data() + codec->pcmLength() * i, codec->pcmLength());
|
||||
|
||||
auto r = codec->encode({(const uint8_t*)mCapturedAudio.data() + codec->pcmLength()*i, (size_t)codec->pcmLength()},
|
||||
{(uint8_t*)mFrameBuffer, MT_MAXAUDIOFRAME});
|
||||
|
||||
auto r =
|
||||
codec->encode({(const uint8_t*)mCapturedAudio.data() + codec->pcmLength() * i, (size_t)codec->pcmLength()},
|
||||
{(uint8_t*)mFrameBuffer, MT_MAXAUDIOFRAME});
|
||||
|
||||
// Counter of processed input bytes of raw pcm data from microphone
|
||||
processed += codec->pcmLength();
|
||||
encodedTime += codec->frameTime();
|
||||
@@ -224,9 +238,10 @@ 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() << " to ");
|
||||
ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType
|
||||
<< ", plength = " << (int)mEncodedAudio.size() << " to ");
|
||||
mRtpSession.SendPacketEx(mEncodedAudio.data(), mEncodedAudio.size(), mTransmittingPayloadType, false,
|
||||
packetTime * codec->samplerate()/1000, 0, nullptr, 0);
|
||||
packetTime * codec->samplerate() / 1000, 0, nullptr, 0);
|
||||
mEncodedAudio.clear();
|
||||
encodedTime = 0;
|
||||
}
|
||||
@@ -239,14 +254,14 @@ void AudioStream::addData(const void* buffer, int bytes)
|
||||
void AudioStream::copyDataTo(Audio::Mixer& mixer, int needed)
|
||||
{
|
||||
// mStreamMap is also mutated from the network thread (dataArrived)
|
||||
Lock l(mMutex);
|
||||
Lock l(mMutex);
|
||||
|
||||
// Local audio mixer - used to send audio to media observer
|
||||
Audio::Mixer localMixer;
|
||||
Audio::Mixer localMixer;
|
||||
Audio::DataWindow forObserver;
|
||||
|
||||
// Iterate
|
||||
for (auto& streamIter: mStreamMap)
|
||||
for (auto& streamIter : mStreamMap)
|
||||
{
|
||||
Audio::DataWindow w;
|
||||
w.setCapacity(32768);
|
||||
@@ -287,7 +302,8 @@ void AudioStream::copyDataTo(Audio::Mixer& mixer, int needed)
|
||||
{
|
||||
int mixedBytes = localMixer.mixAndGetPcm(forObserver);
|
||||
if (mixedBytes > 0)
|
||||
mMediaObserver->onMedia(forObserver.data(), mixedBytes, MT::Stream::MediaDirection::Incoming, this, mMediaObserverTag);
|
||||
mMediaObserver->onMedia(forObserver.data(), mixedBytes, MT::Stream::MediaDirection::Incoming, this,
|
||||
mMediaObserverTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,11 +311,12 @@ void AudioStream::dataArrived(PDatagramSocket s, const void* buffer, int length,
|
||||
{
|
||||
// Protects mStreamMap (also iterated by copyDataTo on the audio thread)
|
||||
// and the receive/decrypt buffers.
|
||||
Lock l(mMutex);
|
||||
Lock l(mMutex);
|
||||
|
||||
jrtplib::RTPIPv6Address addr6;
|
||||
jrtplib::RTPIPv4Address addr4;
|
||||
jrtplib::RTPExternalTransmissionInfo* info = dynamic_cast<jrtplib::RTPExternalTransmissionInfo*>(mRtpSession.GetTransmissionInfo());
|
||||
jrtplib::RTPIPv6Address addr6;
|
||||
jrtplib::RTPIPv4Address addr4;
|
||||
jrtplib::RTPExternalTransmissionInfo* info =
|
||||
dynamic_cast<jrtplib::RTPExternalTransmissionInfo*>(mRtpSession.GetTransmissionInfo());
|
||||
assert(info);
|
||||
|
||||
// Drop RTP packets if stream is not receiving now; let RTCP go
|
||||
@@ -315,15 +332,16 @@ void AudioStream::dataArrived(PDatagramSocket s, const void* buffer, int length,
|
||||
|
||||
if (mSrtpSession.active())
|
||||
{
|
||||
bool srtpResult;
|
||||
size_t srcLength = length; size_t dstLength = sizeof mSrtpDecodeBuffer;
|
||||
bool srtpResult;
|
||||
size_t srcLength = length;
|
||||
size_t dstLength = sizeof mSrtpDecodeBuffer;
|
||||
if (RtpHelper::isRtp(mReceiveBuffer, receiveLength))
|
||||
srtpResult = mSrtpSession.unprotectRtp(mReceiveBuffer, srcLength, mSrtpDecodeBuffer, &dstLength);
|
||||
else
|
||||
srtpResult = mSrtpSession.unprotectRtcp(mReceiveBuffer, srcLength, mSrtpDecodeBuffer, &dstLength);
|
||||
if (!srtpResult)
|
||||
{
|
||||
ICELogError(<<"Cannot decrypt SRTP packet.");
|
||||
ICELogError(<< "Cannot decrypt SRTP packet.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -379,8 +397,9 @@ void AudioStream::dataArrived(PDatagramSocket s, const void* buffer, int length,
|
||||
|
||||
// Find right handler for rtp stream
|
||||
SingleAudioStream* rtpStream = nullptr;
|
||||
auto streamIter = mStreamMap.find(packet->GetSSRC());
|
||||
if (streamIter == mStreamMap.end()) {
|
||||
auto streamIter = mStreamMap.find(packet->GetSSRC());
|
||||
if (streamIter == mStreamMap.end())
|
||||
{
|
||||
rtpStream = new SingleAudioStream(mCodecSettings, mStat);
|
||||
mStreamMap.insert({packet->GetSSRC(), rtpStream});
|
||||
}
|
||||
@@ -395,14 +414,13 @@ void AudioStream::dataArrived(PDatagramSocket s, const void* buffer, int length,
|
||||
// without these, a skewed or buggy peer can poison mRttDelay
|
||||
// (and therefore the Id term in MOS).
|
||||
double rtt = mRtpSession.GetCurrentSourceInfo()->INF_GetRoundtripTime().GetDouble();
|
||||
if (rtt > 0 && rtt < 30.0) // reject "RTT not making any sense" (>30s)
|
||||
if (rtt > 0 && rtt < 30.0) // reject "RTT not making any sense" (>30s)
|
||||
{
|
||||
// Once an average is established, cap a new sample at 3x mean
|
||||
// so a single outlier can't skew the running RTT.
|
||||
constexpr double kRttNormalizeFactor = 3.0;
|
||||
const double meanRtt = mStat.mRttDelay.average();
|
||||
if (mStat.mRttDelay.is_initialized() && meanRtt > 0.0 &&
|
||||
rtt > meanRtt * kRttNormalizeFactor)
|
||||
const double meanRtt = mStat.mRttDelay.average();
|
||||
if (mStat.mRttDelay.is_initialized() && meanRtt > 0.0 && rtt > meanRtt * kRttNormalizeFactor)
|
||||
{
|
||||
rtt = meanRtt * kRttNormalizeFactor;
|
||||
}
|
||||
@@ -438,8 +456,12 @@ void AudioStream::readFile(const Audio::PWavFileReader& stream, MediaDirection d
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case MediaDirection::Outgoing: mDumpStreams.mStreamForReadingOutgoing = stream; break;
|
||||
case MediaDirection::Incoming: mDumpStreams.mStreamForReadingIncoming = stream; break;
|
||||
case MediaDirection::Outgoing:
|
||||
mDumpStreams.mStreamForReadingOutgoing = stream;
|
||||
break;
|
||||
case MediaDirection::Incoming:
|
||||
mDumpStreams.mStreamForReadingIncoming = stream;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,8 +469,12 @@ void AudioStream::writeFile(const Audio::PWavFileWriter& writer, MediaDirection
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case MediaDirection::Outgoing: mDumpStreams.mStreamForRecordingOutgoing = writer; break;
|
||||
case MediaDirection::Incoming: mDumpStreams.mStreamForRecordingIncoming = writer; break;
|
||||
case MediaDirection::Outgoing:
|
||||
mDumpStreams.mStreamForRecordingOutgoing = writer;
|
||||
break;
|
||||
case MediaDirection::Incoming:
|
||||
mDumpStreams.mStreamForRecordingIncoming = writer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user