From 0607bd1c4748f8713ab8c163c856cd556f8c982a Mon Sep 17 00:00:00 2001 From: Dmytro Bogovych Date: Tue, 11 Apr 2023 13:43:38 +0300 Subject: [PATCH] - ongoing work to ease jitter & RTT calculation --- src/engine/helper/HL_StreamState.h | 14 +- src/engine/media/MT_AudioStream.cpp | 609 +++++++------- src/engine/media/MT_AudioStream.h | 32 +- src/engine/media/MT_Box.cpp | 2 +- src/libs/jrtplib/src/rtcpscheduler.cpp | 1 + .../jrtplib/src/rtpexternaltransmitter.cpp | 19 +- src/libs/jrtplib/src/rtpexternaltransmitter.h | 9 + src/libs/jrtplib/src/rtpkeyhashtable.h | 4 +- src/libs/jrtplib/src/rtppacket.h | 2 +- src/libs/jrtplib/src/rtpsession.cpp | 4 +- src/libs/jrtplib/src/rtpsession.h | 8 +- src/libs/jrtplib/src/rtpsourcedata.cpp | 780 +++++++++--------- src/libs/jrtplib/src/rtpsourcedata.h | 620 +++++++------- src/libs/jrtplib/src/rtpsources.cpp | 4 +- 14 files changed, 1071 insertions(+), 1037 deletions(-) diff --git a/src/engine/helper/HL_StreamState.h b/src/engine/helper/HL_StreamState.h index 542f7398..906c7c09 100644 --- a/src/engine/helper/HL_StreamState.h +++ b/src/engine/helper/HL_StreamState.h @@ -1,4 +1,4 @@ -/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com) +/* Copyright(C) 2007-2023 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/. */ @@ -10,13 +10,13 @@ enum class StreamState { - Sending = 1, // Transmitting RTP. Set this flag to allow outgoing media stream. + Sending = 1, // Transmitting RTP. Set this flag to allow outgoing media stream. Receiving = 2, // Receiving RTP. Set this flag to allow receiving media stream. - Playing = 4, // Play to audio. Unmutes the audio from specified stream. - Grabbing = 8, // Capture audio. Unmutes the audio to specified stream. - Srtp = 16, // Use SRTP. Make attempt - SipSend = 32, // Declare send capability in SDP - SipRecv = 64 // Declare recv capability in SDP + Playing = 4, // Play to audio. Unmutes the audio from specified stream. + Grabbing = 8, // Capture audio. Unmutes the audio to specified stream. + Srtp = 16, // Use SRTP. Make attempt + SipSend = 32, // Declare send capability in SDP + SipRecv = 64 // Declare recv capability in SDP }; diff --git a/src/engine/media/MT_AudioStream.cpp b/src/engine/media/MT_AudioStream.cpp index 32fa0d9d..8f5a2cda 100644 --- a/src/engine/media/MT_AudioStream.cpp +++ b/src/engine/media/MT_AudioStream.cpp @@ -22,413 +22,412 @@ 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); - mCaptureResampler8.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 8000); - mCaptureResampler16.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 16000); - mCaptureResampler32.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 32000); - mCaptureResampler48.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 48000); + mOutputBuffer.setCapacity(16384); + mCapturedAudio.setCapacity(16384); + mCaptureResampler8.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 8000); + mCaptureResampler16.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 16000); + mCaptureResampler32.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 32000); + mCaptureResampler48.start(AUDIO_CHANNELS, AUDIO_SAMPLERATE, 48000); - // Configure transmitter - jrtplib::RTPExternalTransmissionParams params(&mRtpSender, 0); - - jrtplib::RTPSessionParams sessionParams; - sessionParams.SetAcceptOwnPackets(true); - sessionParams.SetMaximumPacketSize(MT_MAXRTPPACKET); - sessionParams.SetResolveLocalHostname(false); - sessionParams.SetUsePollThread(false); - 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); + // Configure transmitter + jrtplib::RTPExternalTransmissionParams params(&mRtpSender, 0); + + jrtplib::RTPSessionParams sessionParams; + sessionParams.SetAcceptOwnPackets(true); + sessionParams.SetMaximumPacketSize(MT_MAXRTPPACKET); + sessionParams.SetResolveLocalHostname(false); + sessionParams.SetUsePollThread(false); + 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); #if defined(DUMP_SENDING_AUDIO) - mSendingDump = std::make_shared(); - mSendingDump->open("sending_audio.wav", 8000, 1); + mSendingDump = std::make_shared(); + mSendingDump->open("sending_audio.wav", 8000, 1); #endif } AudioStream::~AudioStream() { - ICELogInfo(<< "Delete AudioStream instance"); - if (mSendingDump) - { - mSendingDump->close(); - mSendingDump.reset(); - } + ICELogInfo(<< "Delete AudioStream instance"); + if (mSendingDump) + { + mSendingDump->close(); + mSendingDump.reset(); + } - // Delete used rtp streams - for (AudioStreamMap::iterator streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) - delete streamIter->second; - mStreamMap.clear(); + // Delete used rtp streams + for (AudioStreamMap::iterator streamIter = mStreamMap.begin(); streamIter != mStreamMap.end(); ++streamIter) + delete streamIter->second; + mStreamMap.clear(); - if (mRtpDtmfSession.IsActive()) - mRtpDtmfSession.Destroy(); - if (mRtpSession.IsActive()) - mRtpSession.Destroy(); + if (mRtpDtmfSession.IsActive()) + mRtpDtmfSession.Destroy(); + if (mRtpSession.IsActive()) + mRtpSession.Destroy(); #if defined(USE_RTPDUMP) - if (mRtpDump) - { - mRtpDump->flush(); - delete mRtpDump; - } + if (mRtpDump) + { + mRtpDump->flush(); + delete mRtpDump; + } #endif - mCaptureResampler8.stop(); - mCaptureResampler16.stop(); - mCaptureResampler32.stop(); - mCaptureResampler48.stop(); - ICELogInfo(<< "Encoded " << mEncodedTime << " milliseconds of audio"); + mCaptureResampler8.stop(); + mCaptureResampler16.stop(); + mCaptureResampler32.stop(); + mCaptureResampler48.stop(); + ICELogInfo(<< "Encoded " << mEncodedTime << " milliseconds of audio"); - if (mDumpStreams.mStreamForRecordingIncoming) - mDumpStreams.mStreamForRecordingIncoming->close(); - if (mDumpStreams.mStreamForReadingOutgoing) - mDumpStreams.mStreamForReadingOutgoing->close(); + if (mDumpStreams.mStreamForRecordingIncoming) + mDumpStreams.mStreamForRecordingIncoming->close(); + if (mDumpStreams.mStreamForReadingOutgoing) + mDumpStreams.mStreamForReadingOutgoing->close(); - if (mFinalStatistics) - *mFinalStatistics = mStat; + if (mFinalStatistics) + *mFinalStatistics = mStat; - ICELogInfo(<< mStat.toString()); + ICELogInfo(<< mStat.toString()); } void AudioStream::setDestination(const RtpPair& dest) { - Lock l(mMutex); - Stream::setDestination(dest); - mRtpSender.setDestination(dest); + Lock l(mMutex); + Stream::setDestination(dest); + mRtpSender.setDestination(dest); } void AudioStream::setTransmittingCodec(Codec::Factory& factory, int payloadType) { - ICELogInfo(<< "Selected codec " << factory.name() << "/" << factory.samplerate() << " for transmitting"); + ICELogInfo(<< "Selected codec " << factory.name() << "/" << factory.samplerate() << " for transmitting"); - Lock l(mMutex); - mTransmittingCodec = factory.create(); - mTransmittingPayloadType = payloadType; - if (mRtpSession.IsActive()) - mRtpSession.SetTimestampUnit(1.0 / mTransmittingCodec->samplerate()); + Lock l(mMutex); + mTransmittingCodec = factory.create(); + mTransmittingPayloadType = payloadType; + if (mRtpSession.IsActive()) + mRtpSession.SetTimestampUnit(1.0 / mTransmittingCodec->samplerate()); } PCodec AudioStream::transmittingCodec() { - Lock l(mMutex); - return mTransmittingCodec; + Lock l(mMutex); + return mTransmittingCodec; } void AudioStream::addData(const void* buffer, int bytes) { - assert(bytes == AUDIO_MIC_BUFFER_SIZE); + assert(bytes == AUDIO_MIC_BUFFER_SIZE); - // Read predefined audio if configured - if (mDumpStreams.mStreamForReadingOutgoing) - { - if (mDumpStreams.mStreamForReadingOutgoing->isOpened()) - mDumpStreams.mStreamForReadingOutgoing->read(const_cast(buffer), bytes); - } - - // Read mirrored audio if needed - if (mMirror && mMirrorPrebuffered) - mMirrorBuffer.read(const_cast(buffer), bytes); - - if (mMediaObserver) - mMediaObserver->onMedia(buffer, bytes, MT::Stream::MediaDirection::Outgoing, this, mMediaObserverTag); - - Codec* codec = nullptr; - { - Lock l(mMutex); - codec = mTransmittingCodec.get(); - if (nullptr == codec) { - // ICELogDebug(<< "No transmitting codec selected."); - return; + // Read predefined audio if configured + if (mDumpStreams.mStreamForReadingOutgoing) + { + if (mDumpStreams.mStreamForReadingOutgoing->isOpened()) + mDumpStreams.mStreamForReadingOutgoing->read(const_cast(buffer), bytes); } - } - // Resample - 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; - default: - assert(0); - } + // Read mirrored audio if needed + if (mMirror && mMirrorPrebuffered) + mMirrorBuffer.read(const_cast(buffer), bytes); - 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 + if (mMediaObserver) + mMediaObserver->onMedia(buffer, bytes, MT::Stream::MediaDirection::Outgoing, this, mMediaObserverTag); - // See if we need stereo <-> mono conversions - unsigned stereolen = 0; - if (codec->channels() != AUDIO_CHANNELS) - { - if (codec->channels() == 2) - stereolen = Audio::ChannelConverter::monoToStereo(mResampleBuffer, dstlen, mStereoBuffer, dstlen * 2); + Codec* codec = nullptr; + { + Lock l(mMutex); + codec = mTransmittingCodec.get(); + if (nullptr == codec) { + // ICELogDebug(<< "No transmitting codec selected."); + return; + } + } + + // Resample + 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; + 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 + + // See if we need stereo <-> mono conversions + unsigned stereolen = 0; + if (codec->channels() != AUDIO_CHANNELS) + { + if (codec->channels() == 2) + stereolen = Audio::ChannelConverter::monoToStereo(mResampleBuffer, dstlen, mStereoBuffer, dstlen * 2); + else + dstlen = Audio::ChannelConverter::stereoToMono(mResampleBuffer, dstlen, mResampleBuffer, dstlen / 2); + } + + // 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)) + mCapturedAudio.add(dtmf.data(), dtmf.size()); else - dstlen = Audio::ChannelConverter::stereoToMono(mResampleBuffer, dstlen, mResampleBuffer, dstlen / 2); - } + mCapturedAudio.add(stereolen ? mStereoBuffer : mResampleBuffer, stereolen ? stereolen : dstlen); - // 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)) - 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 (rfc2833.size()) - mRtpDtmfSession.SendPacket(rfc2833.data(), rfc2833.size(), mRemoteTelephoneCodec, true, AUDIO_MIC_BUFFER_LENGTH * 8); - - if (stopPacket.size()) + // 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)) { - for (int i=0; i<3; i++) - mRtpDtmfSession.SendPacket(stopPacket.data(), stopPacket.size(), mRemoteTelephoneCodec, true, AUDIO_MIC_BUFFER_LENGTH * 8); + if (rfc2833.size()) + 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); + } } - } - - int processed = 0; - int encodedTime = 0; - int packetTime = mPacketTime ? mPacketTime : codec->frameTime(); - // Make stereo version if required - for (int i=0; ipcmLength(); i++) - { - if (mSendingDump) - mSendingDump->write((const char*)mCapturedAudio.data() + codec->pcmLength() * i, codec->pcmLength()); + int processed = 0; + int encodedTime = 0; + int packetTime = mPacketTime ? mPacketTime : codec->frameTime(); - int produced; - produced = codec->encode((const char*)mCapturedAudio.data() + codec->pcmLength()*i, - codec->pcmLength(), mFrameBuffer, MT_MAXAUDIOFRAME); + // Make stereo version if required + for (int i=0; ipcmLength(); i++) + { + if (mSendingDump) + mSendingDump->write((const char*)mCapturedAudio.data() + codec->pcmLength() * i, codec->pcmLength()); + + int produced; + produced = codec->encode((const char*)mCapturedAudio.data() + codec->pcmLength()*i, + codec->pcmLength(), mFrameBuffer, MT_MAXAUDIOFRAME); - // Counter of processed input bytes of raw pcm data from microphone - processed += codec->pcmLength(); - encodedTime += codec->frameTime(); - mEncodedTime += codec->frameTime(); + // Counter of processed input bytes of raw pcm data from microphone + processed += codec->pcmLength(); + encodedTime += codec->frameTime(); + mEncodedTime += codec->frameTime(); - if (produced) - { - mEncodedAudio.appendBuffer(mFrameBuffer, produced); - if (packetTime <= encodedTime) - { - // Time to send packet - ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType << ", plength = " << (int)mEncodedAudio.size()); - mRtpSession.SendPacketEx(mEncodedAudio.data(), mEncodedAudio.size(), mTransmittingPayloadType, false, - packetTime * codec->samplerate()/1000, 0, NULL, 0); - mEncodedAudio.clear(); - encodedTime = 0; - } + if (produced) + { + mEncodedAudio.appendBuffer(mFrameBuffer, produced); + if (packetTime <= encodedTime) + { + // Time to send packet + ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType << ", plength = " << (int)mEncodedAudio.size()); + mRtpSession.SendPacketEx(mEncodedAudio.data(), mEncodedAudio.size(), mTransmittingPayloadType, false, + packetTime * codec->samplerate()/1000, 0, NULL, 0); + mEncodedAudio.clear(); + encodedTime = 0; + } + } } - } - if (processed > 0) - mCapturedAudio.erase(processed); + if (processed > 0) + mCapturedAudio.erase(processed); } void AudioStream::copyDataTo(Audio::Mixer& mixer, int needed) { - // Local audio mixer - used to send audio to media observer - Audio::Mixer localMixer; - Audio::DataWindow forObserver; + // Local audio mixer - used to send audio to media observer + Audio::Mixer localMixer; + Audio::DataWindow forObserver; - // Iterate - for (auto& streamIter: mStreamMap) - { - Audio::DataWindow w; - w.setCapacity(32768); - - SingleAudioStream* sas = streamIter.second; - if (sas) + // Iterate + for (auto& streamIter: mStreamMap) { - sas->copyPcmTo(w, needed); + Audio::DataWindow w; + w.setCapacity(32768); - // Provide mirroring if needed - if (mMirror) - { - mMirrorBuffer.add(w.data(), w.filled()); - if (!mMirrorPrebuffered) - mMirrorPrebuffered = mMirrorBuffer.filled() >= MT_MIRROR_PREBUFFER; - } - - if (!(state() & (int)StreamState::Receiving)) - w.zero(needed); - - // Check if we do not need input from this stream - if (w.filled()) - { - if (mDumpStreams.mStreamForRecordingIncoming) + SingleAudioStream* sas = streamIter.second; + if (sas) { - if (mDumpStreams.mStreamForRecordingIncoming->isOpened()) - mDumpStreams.mStreamForRecordingIncoming->write(w.data(), w.filled()); + sas->copyPcmTo(w, needed); + + // Provide mirroring if needed + if (mMirror) + { + mMirrorBuffer.add(w.data(), w.filled()); + if (!mMirrorPrebuffered) + mMirrorPrebuffered = mMirrorBuffer.filled() >= MT_MIRROR_PREBUFFER; + } + + if (!(state() & (int)StreamState::Receiving)) + w.zero(needed); + + // Check if we do not need input from this stream + if (w.filled()) + { + if (mDumpStreams.mStreamForRecordingIncoming) + { + if (mDumpStreams.mStreamForRecordingIncoming->isOpened()) + mDumpStreams.mStreamForRecordingIncoming->write(w.data(), w.filled()); + } + mixer.addPcm(this, streamIter.first, w, AUDIO_SAMPLERATE, false); + + if (mMediaObserver) + localMixer.addPcm(this, streamIter.first, w, AUDIO_SAMPLERATE, false); + } } - mixer.addPcm(this, streamIter.first, w, AUDIO_SAMPLERATE, false); - - if (mMediaObserver) - localMixer.addPcm(this, streamIter.first, w, AUDIO_SAMPLERATE, false); - } } - } - if (mMediaObserver) - { - localMixer.mixAndGetPcm(forObserver); - mMediaObserver->onMedia(forObserver.data(), forObserver.capacity(), MT::Stream::MediaDirection::Incoming, this, mMediaObserverTag); - } + if (mMediaObserver) + { + localMixer.mixAndGetPcm(forObserver); + mMediaObserver->onMedia(forObserver.data(), forObserver.capacity(), MT::Stream::MediaDirection::Incoming, this, mMediaObserverTag); + } } void AudioStream::dataArrived(PDatagramSocket s, const void* buffer, int length, InternetAddress& source) { - jrtplib::RTPIPv6Address addr6; - jrtplib::RTPIPv4Address addr4; - jrtplib::RTPExternalTransmissionInfo* info = dynamic_cast(mRtpSession.GetTransmissionInfo()); - assert(info); - - // Drop RTP packets if stream is not receiving now; let RTCP go - if (!(state() & (int)StreamState::Receiving) && RtpHelper::isRtp(buffer, length)) - { - ICELogMedia(<< "Stream is not allowed to receive RTP stream. Ignore the packet"); - return; - } + jrtplib::RTPIPv6Address addr6; + jrtplib::RTPIPv4Address addr4; + jrtplib::RTPExternalTransmissionInfo* info = dynamic_cast(mRtpSession.GetTransmissionInfo()); + assert(info); - // Copy incoming data to temp buffer to perform possible srtp unprotect - int receiveLength = length; - memcpy(mReceiveBuffer, buffer, length); - - bool srtpResult; - if (mSrtpSession.active()) - { - if (RtpHelper::isRtp(mReceiveBuffer, receiveLength)) - srtpResult = mSrtpSession.unprotectRtp(mReceiveBuffer, &receiveLength); - else - srtpResult = mSrtpSession.unprotectRtcp(mReceiveBuffer, &receiveLength); - if (!srtpResult) + // Drop RTP packets if stream is not receiving now; let RTCP go + if (!(state() & (int)StreamState::Receiving) && RtpHelper::isRtpOrRtcp(buffer, length)) { - ICELogError(<<"Cannot decrypt SRTP packet."); - return; + ICELogMedia(<< "Stream is not allowed to receive RTP stream. Ignore the RT(C)P packet"); + return; } - } - //ICELogDebug(<< "Packet no: " << RtpHelper::findPacketNo(mReceiveBuffer, receiveLength)); + // Copy incoming data to temp buffer to perform possible srtp unprotect + int receiveLength = length; + memcpy(mReceiveBuffer, buffer, length); - switch (source.family()) - { - case AF_INET: - addr4.SetIP(source.sockaddr4()->sin_addr.s_addr); - addr4.SetPort(source.port()); - ICELogMedia(<< "Injecting RTP/RTCP packet into jrtplib"); - info->GetPacketInjector()->InjectRTPorRTCP(mReceiveBuffer, receiveLength, addr4); - break; - - case AF_INET6: - addr6.SetIP(source.sockaddr6()->sin6_addr); - addr6.SetPort(source.port()); - ICELogMedia(<< "Injecting RTP/RTCP packet into jrtplib"); - info->GetPacketInjector()->InjectRTPorRTCP(mReceiveBuffer, receiveLength, addr6); - break; - - default: - assert(0); - } - - mStat.mReceived += length; - if (RtpHelper::isRtp(mReceiveBuffer, receiveLength)) - { - if (!mStat.mFirstRtpTime.is_initialized()) - mStat.mFirstRtpTime = std::chrono::system_clock::now(); - mStat.mReceivedRtp++; - } - else - mStat.mReceivedRtcp++; - - mRtpSession.Poll(); // maybe it is extra with external transmitter - bool hasData = mRtpSession.GotoFirstSourceWithData(); - while (hasData) - { - std::shared_ptr packet(mRtpSession.GetNextPacket()); - if (packet) + bool srtpResult; + if (mSrtpSession.active()) { - ICELogMedia(<< "jrtplib returned packet"); - // 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); + if (RtpHelper::isRtp(mReceiveBuffer, receiveLength)) + srtpResult = mSrtpSession.unprotectRtp(mReceiveBuffer, &receiveLength); else - rtpStream = streamIter->second; - - // Process incoming data packet - rtpStream->process(packet); - - double rtt = mRtpSession.GetCurrentSourceInfo()->INF_GetRoundtripTime().GetDouble(); - if (rtt > 0) - mStat.mRttDelay.process(rtt); + srtpResult = mSrtpSession.unprotectRtcp(mReceiveBuffer, &receiveLength); + if (!srtpResult) + { + ICELogError(<<"Cannot decrypt SRTP packet."); + return; + } + } + + switch (source.family()) + { + case AF_INET: + addr4.SetIP(source.sockaddr4()->sin_addr.s_addr); + addr4.SetPort(source.port()); + ICELogMedia(<< "Injecting RTP/RTCP packet into jrtplib"); + info->GetPacketInjector()->InjectRTPorRTCP(mReceiveBuffer, receiveLength, addr4); + break; + + case AF_INET6: + addr6.SetIP(source.sockaddr6()->sin6_addr); + addr6.SetPort(source.port()); + ICELogMedia(<< "Injecting RTP/RTCP packet into jrtplib"); + info->GetPacketInjector()->InjectRTPorRTCP(mReceiveBuffer, receiveLength, addr6); + break; + + default: + assert(0); + } + + mStat.mReceived += length; + if (RtpHelper::isRtp(mReceiveBuffer, receiveLength)) + { + if (!mStat.mFirstRtpTime.is_initialized()) + mStat.mFirstRtpTime = std::chrono::system_clock::now(); + mStat.mReceivedRtp++; + } + else + mStat.mReceivedRtcp++; + + mRtpSession.Poll(); // maybe it is extra with external transmitter + bool hasData = mRtpSession.GotoFirstSourceWithData(); + while (hasData) + { + std::shared_ptr packet(mRtpSession.GetNextPacket()); + if (packet) + { + ICELogMedia(<< "jrtplib returned packet"); + + // 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); + else + rtpStream = streamIter->second; + + // Process incoming data packet + rtpStream->process(packet); + + double rtt = mRtpSession.GetCurrentSourceInfo()->INF_GetRoundtripTime().GetDouble(); + if (rtt > 0) + mStat.mRttDelay.process(rtt); + } + hasData = mRtpSession.GotoNextSourceWithData(); } - hasData = mRtpSession.GotoNextSourceWithData(); - } } void AudioStream::setState(unsigned state) { - Stream::setState(state); + Stream::setState(state); } void AudioStream::setTelephoneCodec(int payloadType) { - mRemoteTelephoneCodec = payloadType; + mRemoteTelephoneCodec = payloadType; } void AudioStream::setSocket(const RtpPair& socket) { - Stream::setSocket(socket); - mRtpSender.setSocket(socket); + Stream::setSocket(socket); + mRtpSender.setSocket(socket); } DtmfContext& AudioStream::queueOfDtmf() { - return mDtmfContext; + return mDtmfContext; } void AudioStream::readFile(const Audio::PWavFileReader& stream, MediaDirection direction) { - switch (direction) - { - case MediaDirection::Outgoing: mDumpStreams.mStreamForReadingOutgoing = stream; break; - case MediaDirection::Incoming: mDumpStreams.mStreamForReadingIncoming = stream; break; - } + switch (direction) + { + case MediaDirection::Outgoing: mDumpStreams.mStreamForReadingOutgoing = stream; break; + case MediaDirection::Incoming: mDumpStreams.mStreamForReadingIncoming = stream; break; + } } void AudioStream::writeFile(const Audio::PWavFileWriter& writer, MediaDirection direction) { - switch (direction) - { - case MediaDirection::Outgoing: mDumpStreams.mStreamForRecordingOutgoing = writer; break; - case MediaDirection::Incoming: mDumpStreams.mStreamForRecordingIncoming = writer; break; - } + switch (direction) + { + case MediaDirection::Outgoing: mDumpStreams.mStreamForRecordingOutgoing = writer; break; + case MediaDirection::Incoming: mDumpStreams.mStreamForRecordingIncoming = writer; break; + } } void AudioStream::setupMirror(bool enable) { - if (!mMirror && enable) - { - mMirrorBuffer.setCapacity(MT_MIRROR_CAPACITY); - mMirrorPrebuffered = false; - } - mMirror = enable; + if (!mMirror && enable) + { + mMirrorBuffer.setCapacity(MT_MIRROR_CAPACITY); + mMirrorPrebuffered = false; + } + mMirror = enable; } void AudioStream::setFinalStatisticsOutput(Statistics* stats) { - mFinalStatistics = stats; + mFinalStatistics = stats; } diff --git a/src/engine/media/MT_AudioStream.h b/src/engine/media/MT_AudioStream.h index bb6a7eea..cb44278b 100644 --- a/src/engine/media/MT_AudioStream.h +++ b/src/engine/media/MT_AudioStream.h @@ -25,10 +25,10 @@ namespace MT { - - class AudioStream: public Stream - { - public: + +class AudioStream: public Stream +{ +public: AudioStream(const CodecList::Settings& codecSettings); ~AudioStream(); @@ -38,7 +38,7 @@ namespace MT void setTransmittingCodec(Codec::Factory& factory, int payloadType) override; PCodec transmittingCodec(); - // Called to queue data captured from microphone. + // Called to queue data captured from microphone. // Buffer holds 16bits PCM data with AUDIO_SAMPLERATE rate and AUDIO_CHANNELS channels. void addData(const void* buffer, int length); @@ -51,7 +51,7 @@ namespace MT void setState(unsigned state) override; void setTelephoneCodec(int payloadType); - DtmfContext& queueOfDtmf(); + DtmfContext& queueOfDtmf(); void readFile(const Audio::PWavFileReader& stream, MediaDirection direction) override; void writeFile(const Audio::PWavFileWriter& writer, MediaDirection direction) override; @@ -59,7 +59,7 @@ namespace MT void setFinalStatisticsOutput(Statistics* stats); - protected: +protected: Audio::DataWindow mCapturedAudio; // Data from microphone Audio::DataWindow mStereoCapturedAudio; char mIncomingPcmBuffer[AUDIO_MIC_BUFFER_SIZE]; // Temporary buffer to allow reading from file @@ -83,18 +83,18 @@ namespace MT RtpDump* mRtpDump = nullptr; #endif Audio::Resampler mCaptureResampler8, - mCaptureResampler16, - mCaptureResampler32, - mCaptureResampler48; - DtmfContext mDtmfContext; + mCaptureResampler16, + mCaptureResampler32, + mCaptureResampler48; + DtmfContext mDtmfContext; char mReceiveBuffer[MAX_VALID_UDPPACKET_SIZE]; struct { - Audio::PWavFileWriter mStreamForRecordingIncoming, - mStreamForRecordingOutgoing; - Audio::PWavFileReader mStreamForReadingIncoming, - mStreamForReadingOutgoing; + Audio::PWavFileWriter mStreamForRecordingIncoming, + mStreamForRecordingOutgoing; + Audio::PWavFileReader mStreamForReadingIncoming, + mStreamForReadingOutgoing; } mDumpStreams; Audio::PWavFileWriter mSendingDump; @@ -106,7 +106,7 @@ namespace MT Statistics* mFinalStatistics = nullptr; bool decryptSrtp(void* data, int* len); - }; +}; }; #endif diff --git a/src/engine/media/MT_Box.cpp b/src/engine/media/MT_Box.cpp index 39609402..1ae8c8ca 100644 --- a/src/engine/media/MT_Box.cpp +++ b/src/engine/media/MT_Box.cpp @@ -40,7 +40,7 @@ PStream Terminal::createStream(int type, VariantMap& /*config*/) switch (type) { case Stream::Audio: - result = PStream(new AudioStream(MT::CodecList::Settings::DefaultSettings)); + result = std::make_shared(MT::CodecList::Settings::DefaultSettings); mAudioList.add(result); break; diff --git a/src/libs/jrtplib/src/rtcpscheduler.cpp b/src/libs/jrtplib/src/rtcpscheduler.cpp index a4c4073a..05f5af30 100644 --- a/src/libs/jrtplib/src/rtcpscheduler.cpp +++ b/src/libs/jrtplib/src/rtcpscheduler.cpp @@ -100,6 +100,7 @@ RTCPScheduler::~RTCPScheduler() void RTCPScheduler::Reset() { + pmembers = 0; headeroverhead = 0; // user has to set this to an appropriate value hassentrtcp = false; firstcall = true; diff --git a/src/libs/jrtplib/src/rtpexternaltransmitter.cpp b/src/libs/jrtplib/src/rtpexternaltransmitter.cpp index 7ad42a09..ce50c191 100644 --- a/src/libs/jrtplib/src/rtpexternaltransmitter.cpp +++ b/src/libs/jrtplib/src/rtpexternaltransmitter.cpp @@ -900,9 +900,26 @@ void RTPExternalTransmitter::InjectRTPorRTCP(const void *data, size_t len, const AbortWaitInternal(); MAINMUTEX_UNLOCK - } +void RTPExternalTransmitter::InjectRaw(RTPRawPacket* packet) +{ + if (!init) + return; + + MAINMUTEX_LOCK + if (!created) + { + MAINMUTEX_UNLOCK + return; + } + rawpacketlist.push_back(packet); + AbortWaitInternal(); + + MAINMUTEX_UNLOCK +} + + #ifdef RTPDEBUG void RTPExternalTransmitter::Dump() { diff --git a/src/libs/jrtplib/src/rtpexternaltransmitter.h b/src/libs/jrtplib/src/rtpexternaltransmitter.h index 8db73a84..80b9272c 100644 --- a/src/libs/jrtplib/src/rtpexternaltransmitter.h +++ b/src/libs/jrtplib/src/rtpexternaltransmitter.h @@ -96,6 +96,8 @@ public: /** Use this function to inject an RTP or RTCP packet and the transmitter will try to figure out which type of packet it is. */ void InjectRTPorRTCP(const void *data, size_t len, const RTPAddress &a); + + void InjectRaw(RTPRawPacket* packet); private: RTPExternalTransmitter *transmitter; }; @@ -186,6 +188,8 @@ public: void InjectRTP(const void *data, size_t len, const RTPAddress &a); void InjectRTCP(const void *data, size_t len, const RTPAddress &a); void InjectRTPorRTCP(const void *data, size_t len, const RTPAddress &a); + void InjectRaw(RTPRawPacket* packet); + private: void FlushPackets(); @@ -233,6 +237,11 @@ inline void RTPExternalPacketInjecter::InjectRTPorRTCP(const void *data, size_t transmitter->InjectRTPorRTCP(data, len, a); } +inline void RTPExternalPacketInjecter::InjectRaw(RTPRawPacket* packet) +{ + transmitter->InjectRaw(packet); +} + } // end namespace #endif // RTPTCPSOCKETTRANSMITTER_H diff --git a/src/libs/jrtplib/src/rtpkeyhashtable.h b/src/libs/jrtplib/src/rtpkeyhashtable.h index 1d334a9f..5f1b2048 100644 --- a/src/libs/jrtplib/src/rtpkeyhashtable.h +++ b/src/libs/jrtplib/src/rtpkeyhashtable.h @@ -54,13 +54,13 @@ class RTPKeyHashTable : public RTPMemoryObject { public: RTPKeyHashTable(RTPMemoryManager *mgr = 0,int memtype = RTPMEM_TYPE_OTHER); - ~RTPKeyHashTable() { Clear(); } + ~RTPKeyHashTable() { Clear(); } void GotoFirstElement() { curhashelem = firsthashelem; } void GotoLastElement() { curhashelem = lasthashelem; } bool HasCurrentElement() { return (curhashelem == 0)?false:true; } int DeleteCurrentElement(); - Element &GetCurrentElement() { return curhashelem->GetElement(); } + Element &GetCurrentElement() { return curhashelem->GetElement(); } Key &GetCurrentKey() { return curhashelem->GetKey(); } int GotoElement(const Key &k); bool HasElement(const Key &k); diff --git a/src/libs/jrtplib/src/rtppacket.h b/src/libs/jrtplib/src/rtppacket.h index db52ebda..64d79765 100644 --- a/src/libs/jrtplib/src/rtppacket.h +++ b/src/libs/jrtplib/src/rtppacket.h @@ -80,7 +80,7 @@ public: bool gotextension,uint16_t extensionid,uint16_t extensionlen_numwords,const void *extensiondata, void *buffer,size_t buffersize,RTPMemoryManager *mgr = 0); - virtual ~RTPPacket(); + virtual ~RTPPacket(); /** If an error occurred in one of the constructors, this function returns the error code. */ int GetCreationError() const { return error; } diff --git a/src/libs/jrtplib/src/rtpsession.cpp b/src/libs/jrtplib/src/rtpsession.cpp index c0296b28..155323d2 100644 --- a/src/libs/jrtplib/src/rtpsession.cpp +++ b/src/libs/jrtplib/src/rtpsession.cpp @@ -1444,8 +1444,8 @@ int RTPSession::ProcessPolledData() RTPTime colltimeout = RTPTime(Td*collisionmultiplier); RTPTime notetimeout = RTPTime(Td*notemultiplier); - sources.MultipleTimeouts(t,sendertimeout,byetimeout,generaltimeout,notetimeout); - collisionlist.Timeout(t,colltimeout); + // sources.MultipleTimeouts(t,sendertimeout,byetimeout,generaltimeout,notetimeout); + // collisionlist.Timeout(t,colltimeout); // We'll check if it's time for RTCP stuff diff --git a/src/libs/jrtplib/src/rtpsession.h b/src/libs/jrtplib/src/rtpsession.h index df846098..4b4a610b 100644 --- a/src/libs/jrtplib/src/rtpsession.h +++ b/src/libs/jrtplib/src/rtpsession.h @@ -55,6 +55,8 @@ #include #endif // RTP_SUPPORT_THREAD +#include + namespace jrtplib { @@ -474,7 +476,11 @@ protected: const uint8_t *cname,size_t cnamelength) { } /** Is called when a new entry \c srcdat is added to the source table. */ - virtual void OnNewSource(RTPSourceData *srcdat) { } + virtual void OnNewSource(RTPSourceData *srcdat) + { + // Sync timestamp unit + srcdat->SetTimestampUnit(timestampunit); + } /** Is called when the entry \c srcdat is about to be deleted from the source table. */ virtual void OnRemoveSource(RTPSourceData *srcdat) { } diff --git a/src/libs/jrtplib/src/rtpsourcedata.cpp b/src/libs/jrtplib/src/rtpsourcedata.cpp index bdf59f60..78d9685a 100644 --- a/src/libs/jrtplib/src/rtpsourcedata.cpp +++ b/src/libs/jrtplib/src/rtpsourcedata.cpp @@ -7,7 +7,7 @@ This library was developed at the Expertise Centre for Digital Media (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for + (http://www.uhasselt.be). The library is based upon work done for my thesis at the School for Knowledge Technology (Belgium/The Netherlands). Permission is hereby granted, free of charge, to any person obtaining a @@ -35,462 +35,462 @@ #include "rtpaddress.h" #include "rtpmemorymanager.h" #if ! (defined(WIN32) || defined(_WIN32_WCE)) - #include +#include #endif // WIN32 #ifdef RTPDEBUG - #include - #include +#include +#include #endif // RTPDEBUG #include "rtpdebug.h" #define ACCEPTPACKETCODE \ - *accept = true; \ - \ - sentdata = true; \ - packetsreceived++; \ - numnewpackets++; \ - \ - if (pack->GetExtendedSequenceNumber() == 0) \ - { \ - baseseqnr = 0x0000FFFF; \ - numcycles = 0x00010000; \ - } \ - else \ - baseseqnr = pack->GetExtendedSequenceNumber() - 1; \ - \ - exthighseqnr = baseseqnr + 1; \ - prevpacktime = receivetime; \ - prevexthighseqnr = baseseqnr; \ - savedextseqnr = baseseqnr; \ - \ - pack->SetExtendedSequenceNumber(exthighseqnr); \ - \ - prevtimestamp = pack->GetTimestamp(); \ - lastmsgtime = prevpacktime; \ - if (!ownpacket) /* for own packet, this value is set on an outgoing packet */ \ - lastrtptime = prevpacktime; + *accept = true; \ + \ + sentdata = true; \ + packetsreceived++; \ + numnewpackets++; \ + \ + if (pack->GetExtendedSequenceNumber() == 0) \ +{ \ + baseseqnr = 0x0000FFFF; \ + numcycles = 0x00010000; \ + } \ + else \ + baseseqnr = pack->GetExtendedSequenceNumber() - 1; \ + \ + exthighseqnr = baseseqnr + 1; \ + prevpacktime = receivetime; \ + prevexthighseqnr = baseseqnr; \ + savedextseqnr = baseseqnr; \ + \ + pack->SetExtendedSequenceNumber(exthighseqnr); \ + \ + prevtimestamp = pack->GetTimestamp(); \ + lastmsgtime = prevpacktime; \ + if (!ownpacket) /* for own packet, this value is set on an outgoing packet */ \ + lastrtptime = prevpacktime; namespace jrtplib { void RTPSourceStats::ProcessPacket(RTPPacket *pack,const RTPTime &receivetime,double tsunit, - bool ownpacket,bool *accept,bool applyprobation,bool *onprobation) + bool ownpacket, bool *accept, bool applyprobation, bool *onprobation) { - // Note that the sequence number in the RTP packet is still just the - // 16 bit number contained in the RTP header + // Note that the sequence number in the RTP packet is still just the + // 16 bit number contained in the RTP header - *onprobation = false; - - if (!sentdata) // no valid packets received yet - { + *onprobation = false; + + if (!sentdata) // no valid packets received yet + { #ifdef RTP_SUPPORT_PROBATION - if (applyprobation) - { - bool acceptpack = false; + if (applyprobation) + { + bool acceptpack = false; - if (probation) - { - uint16_t pseq; - uint32_t pseq2; - - pseq = prevseqnr; - pseq++; - pseq2 = (uint32_t)pseq; - if (pseq2 == pack->GetExtendedSequenceNumber()) // ok, its the next expected packet - { - prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); - probation--; - if (probation == 0) // probation over - acceptpack = true; - else - *onprobation = true; - } - else // not next packet - { - probation = RTP_PROBATIONCOUNT; - prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); - *onprobation = true; - } - } - else // first packet received with this SSRC ID, start probation - { - probation = RTP_PROBATIONCOUNT; - prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); - *onprobation = true; - } - - if (acceptpack) - { - ACCEPTPACKETCODE - } - else - { - *accept = false; - lastmsgtime = receivetime; - } - } - else // No probation - { - ACCEPTPACKETCODE - } + if (probation) + { + uint16_t pseq; + uint32_t pseq2; + + pseq = prevseqnr; + pseq++; + pseq2 = (uint32_t)pseq; + if (pseq2 == pack->GetExtendedSequenceNumber()) // ok, its the next expected packet + { + prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); + probation--; + if (probation == 0) // probation over + acceptpack = true; + else + *onprobation = true; + } + else // not next packet + { + probation = RTP_PROBATIONCOUNT; + prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); + *onprobation = true; + } + } + else // first packet received with this SSRC ID, start probation + { + probation = RTP_PROBATIONCOUNT; + prevseqnr = (uint16_t)pack->GetExtendedSequenceNumber(); + *onprobation = true; + } + + if (acceptpack) + { + ACCEPTPACKETCODE + } + else + { + *accept = false; + lastmsgtime = receivetime; + } + } + else // No probation + { + ACCEPTPACKETCODE + } #else // No compiled-in probation support - ACCEPTPACKETCODE + ACCEPTPACKETCODE -#endif // RTP_SUPPORT_PROBATION - } - else // already got packets - { - uint16_t maxseq16; - uint32_t extseqnr; + #endif // RTP_SUPPORT_PROBATION + } + else // already got packets + { + uint16_t maxseq16; + uint32_t extseqnr; - // Adjust max extended sequence number and set extende seq nr of packet + // Adjust max extended sequence number and set extende seq nr of packet - *accept = true; - packetsreceived++; - numnewpackets++; + *accept = true; + packetsreceived++; + numnewpackets++; - maxseq16 = (uint16_t)(exthighseqnr&0x0000FFFF); - if (pack->GetExtendedSequenceNumber() >= maxseq16) - { - extseqnr = numcycles+pack->GetExtendedSequenceNumber(); - exthighseqnr = extseqnr; - } - else - { - uint16_t dif1,dif2; + maxseq16 = (uint16_t)(exthighseqnr&0x0000FFFF); + if (pack->GetExtendedSequenceNumber() >= maxseq16) + { + extseqnr = numcycles+pack->GetExtendedSequenceNumber(); + exthighseqnr = extseqnr; + } + else + { + uint16_t dif1,dif2; - dif1 = ((uint16_t)pack->GetExtendedSequenceNumber()); - dif1 -= maxseq16; - dif2 = maxseq16; - dif2 -= ((uint16_t)pack->GetExtendedSequenceNumber()); - if (dif1 < dif2) - { - numcycles += 0x00010000; - extseqnr = numcycles+pack->GetExtendedSequenceNumber(); - exthighseqnr = extseqnr; - } - else - extseqnr = numcycles+pack->GetExtendedSequenceNumber(); - } + dif1 = ((uint16_t)pack->GetExtendedSequenceNumber()); + dif1 -= maxseq16; + dif2 = maxseq16; + dif2 -= ((uint16_t)pack->GetExtendedSequenceNumber()); + if (dif1 < dif2) + { + numcycles += 0x00010000; + extseqnr = numcycles+pack->GetExtendedSequenceNumber(); + exthighseqnr = extseqnr; + } + else + extseqnr = numcycles+pack->GetExtendedSequenceNumber(); + } - pack->SetExtendedSequenceNumber(extseqnr); + pack->SetExtendedSequenceNumber(extseqnr); - // Calculate jitter + // Calculate jitter - if (tsunit > 0) - { + if (tsunit > 0) + { #if 0 - RTPTime curtime = receivetime; - double diffts1,diffts2,diff; + RTPTime curtime = receivetime; + double diffts1,diffts2,diff; - curtime -= prevpacktime; - diffts1 = curtime.GetDouble()/tsunit; - diffts2 = (double)pack->GetTimestamp() - (double)prevtimestamp; - diff = diffts1 - diffts2; - if (diff < 0) - diff = -diff; - diff -= djitter; - diff /= 16.0; - djitter += diff; - jitter = (uint32_t)djitter; + curtime -= prevpacktime; + diffts1 = curtime.GetDouble()/tsunit; + diffts2 = (double)pack->GetTimestamp() - (double)prevtimestamp; + diff = diffts1 - diffts2; + if (diff < 0) + diff = -diff; + diff -= djitter; + diff /= 16.0; + djitter += diff; + jitter = (uint32_t)djitter; #else -RTPTime curtime = receivetime; -double diffts1,diffts2,diff; -uint32_t curts = pack->GetTimestamp(); + RTPTime curtime = receivetime; + double diffts1,diffts2,diff; + uint32_t curts = pack->GetTimestamp(); -curtime -= prevpacktime; -diffts1 = curtime.GetDouble()/tsunit; + curtime -= prevpacktime; + diffts1 = curtime.GetDouble() / tsunit; -if (curts > prevtimestamp) -{ - uint32_t unsigneddiff = curts - prevtimestamp; + if (curts > prevtimestamp) + { + uint32_t unsigneddiff = curts - prevtimestamp; - if (unsigneddiff < 0x10000000) // okay, curts realy is larger than prevtimestamp - diffts2 = (double)unsigneddiff; - else - { - // wraparound occurred and curts is actually smaller than prevtimestamp + if (unsigneddiff < 0x10000000) // okay, curts realy is larger than prevtimestamp + diffts2 = (double)unsigneddiff; + else + { + // wraparound occurred and curts is actually smaller than prevtimestamp - unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value) - diffts2 = -((double)unsigneddiff); - } -} -else if (curts < prevtimestamp) -{ - uint32_t unsigneddiff = prevtimestamp - curts; + unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value) + diffts2 = -((double)unsigneddiff); + } + } + else if (curts < prevtimestamp) + { + uint32_t unsigneddiff = prevtimestamp - curts; - if (unsigneddiff < 0x10000000) // okay, curts really is smaller than prevtimestamp - diffts2 = -((double)unsigneddiff); // negative since we actually need curts-prevtimestamp - else - { - // wraparound occurred and curts is actually larger than prevtimestamp + if (unsigneddiff < 0x10000000) // okay, curts really is smaller than prevtimestamp + diffts2 = -((double)unsigneddiff); // negative since we actually need curts-prevtimestamp + else + { + // wraparound occurred and curts is actually larger than prevtimestamp - unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value) - diffts2 = (double)unsigneddiff; - } -} -else - diffts2 = 0; + unsigneddiff = -unsigneddiff; // to get the actual difference (in absolute value) + diffts2 = (double)unsigneddiff; + } + } + else + diffts2 = 0; -diff = diffts1 - diffts2; -if (diff < 0) - diff = -diff; -diff -= djitter; -diff /= 16.0; -djitter += diff; -jitter = (uint32_t)djitter; + diff = diffts1 - diffts2; + if (diff < 0) + diff = -diff; + diff -= djitter; + diff /= 16.0; + djitter += diff; + jitter = (uint32_t)djitter; #endif - } - else - { - djitter = 0; - jitter = 0; - } + } + else + { + djitter = 0; + jitter = 0; + } - prevpacktime = receivetime; - prevtimestamp = pack->GetTimestamp(); - lastmsgtime = prevpacktime; - if (!ownpacket) // for own packet, this value is set on an outgoing packet - lastrtptime = prevpacktime; - } + prevpacktime = receivetime; + prevtimestamp = pack->GetTimestamp(); + lastmsgtime = prevpacktime; + if (!ownpacket) // for own packet, this value is set on an outgoing packet + lastrtptime = prevpacktime; + } } RTPSourceData::RTPSourceData(uint32_t s, RTPMemoryManager *mgr) : RTPMemoryObject(mgr),SDESinf(mgr),byetime(0,0) { - ssrc = s; - issender = false; - iscsrc = false; - timestampunit = -1; - receivedbye = false; - byereason = 0; - byereasonlen = 0; - rtpaddr = 0; - rtcpaddr = 0; - ownssrc = false; - validated = false; - processedinrtcp = false; - isrtpaddrset = false; - isrtcpaddrset = false; + ssrc = s; + issender = false; + iscsrc = false; + timestampunit = -1; + receivedbye = false; + byereason = 0; + byereasonlen = 0; + rtpaddr = 0; + rtcpaddr = 0; + ownssrc = false; + validated = false; + processedinrtcp = false; + isrtpaddrset = false; + isrtcpaddrset = false; } RTPSourceData::~RTPSourceData() { - FlushPackets(); - if (byereason) - RTPDeleteByteArray(byereason,GetMemoryManager()); - if (rtpaddr) - RTPDelete(rtpaddr,GetMemoryManager()); - if (rtcpaddr) - RTPDelete(rtcpaddr,GetMemoryManager()); + FlushPackets(); + if (byereason) + RTPDeleteByteArray(byereason,GetMemoryManager()); + if (rtpaddr) + RTPDelete(rtpaddr,GetMemoryManager()); + if (rtcpaddr) + RTPDelete(rtcpaddr,GetMemoryManager()); } double RTPSourceData::INF_GetEstimatedTimestampUnit() const { - if (!SRprevinf.HasInfo()) - return -1.0; - - RTPTime t1 = RTPTime(SRinf.GetNTPTimestamp()); - RTPTime t2 = RTPTime(SRprevinf.GetNTPTimestamp()); - if ((t1.GetSeconds() == 0 && t1.GetMicroSeconds() == 0) || - (t2.GetSeconds() == 0 && t2.GetMicroSeconds() == 0)) // one of the times couldn't be calculated - return -1.0; + if (!SRprevinf.HasInfo()) + return -1.0; - if (t1 <= t2) - return -1.0; + RTPTime t1 = RTPTime(SRinf.GetNTPTimestamp()); + RTPTime t2 = RTPTime(SRprevinf.GetNTPTimestamp()); + if ((t1.GetSeconds() == 0 && t1.GetMicroSeconds() == 0) || + (t2.GetSeconds() == 0 && t2.GetMicroSeconds() == 0)) // one of the times couldn't be calculated + return -1.0; - t1 -= t2; // get the time difference - - uint32_t tsdiff = SRinf.GetRTPTimestamp()-SRprevinf.GetRTPTimestamp(); - - return (t1.GetDouble()/((double)tsdiff)); + if (t1 <= t2) + return -1.0; + + t1 -= t2; // get the time difference + + uint32_t tsdiff = SRinf.GetRTPTimestamp()-SRprevinf.GetRTPTimestamp(); + + return (t1.GetDouble()/((double)tsdiff)); } RTPTime RTPSourceData::INF_GetRoundtripTime() const { - if (!RRinf.HasInfo()) - return RTPTime(0,0); - if (RRinf.GetDelaySinceLastSR() == 0 && RRinf.GetLastSRTimestamp() == 0) - return RTPTime(0,0); + if (!RRinf.HasInfo()) + return RTPTime(0,0); + if (RRinf.GetDelaySinceLastSR() == 0 && RRinf.GetLastSRTimestamp() == 0) + return RTPTime(0,0); - RTPNTPTime recvtime = RRinf.GetReceiveTime().GetNTPTime(); - uint32_t rtt = ((recvtime.GetMSW()&0xFFFF)<<16)|((recvtime.GetLSW()>>16)&0xFFFF); - rtt -= RRinf.GetLastSRTimestamp(); - rtt -= RRinf.GetDelaySinceLastSR(); + RTPNTPTime recvtime = RRinf.GetReceiveTime().GetNTPTime(); + uint32_t rtt = ((recvtime.GetMSW()&0xFFFF)<<16)|((recvtime.GetLSW()>>16)&0xFFFF); + rtt -= RRinf.GetLastSRTimestamp(); + rtt -= RRinf.GetDelaySinceLastSR(); - double drtt = (((double)rtt)/65536.0); - return RTPTime(drtt); + double drtt = (((double)rtt)/65536.0); + return RTPTime(drtt); } #ifdef RTPDEBUG void RTPSourceData::Dump() { - std::cout << "Source data for SSRC: " << ssrc << std::endl; - std::cout << " Active: " << ((IsActive())?"Yes":"No") << std::endl; - std::cout << " Sender: " << ((issender)?"Yes":"No") << std::endl; - std::cout << " CSRC: " << ((iscsrc)?"Yes":"No") << std::endl; - std::cout << " Received bye: " << ((receivedbye)?"Yes":"No") << std::endl; - std::cout << " ProcessedInRTCP: " << ((processedinrtcp)?"Yes":"No") << std::endl; - std::cout << " Timestamp unit: " << timestampunit << std::endl; - std::cout << " RTP address: "; - if (!isrtpaddrset) - std::cout << "Not set" << std::endl; - else - { - if (rtpaddr == 0) - std::cout << "Own session" << std::endl; - else - std::cout << rtpaddr->GetAddressString() << std::endl; - } - std::cout << " RTCP address: "; - if (!isrtcpaddrset) - std::cout << "Not set" << std::endl; - else - { - if (rtcpaddr == 0) - std::cout << "Own session" << std::endl; - else - std::cout << rtcpaddr->GetAddressString() << std::endl; - } - if (SRinf.HasInfo()) - { - if (!SRprevinf.HasInfo()) - { - std::cout << " SR Info:" << std::endl; - std::cout << " NTP timestamp: " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW() << std::endl; - std::cout << " RTP timestamp: " << SRinf.GetRTPTimestamp() << std::endl; - std::cout << " Packet count: " << SRinf.GetPacketCount() << std::endl; - std::cout << " Octet count: " << SRinf.GetByteCount() << std::endl; - std::cout << " Receive time: " << SRinf.GetReceiveTime().GetSeconds() << std::endl; - } - else - { - std::cout << " SR Info:" << std::endl; - std::cout << " NTP timestamp: " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW() - << " (" << SRprevinf.GetNTPTimestamp().GetMSW() << ":" << SRprevinf.GetNTPTimestamp().GetLSW() << ")" << std::endl; - std::cout << " RTP timestamp: " << SRinf.GetRTPTimestamp() - << " (" << SRprevinf.GetRTPTimestamp() << ")" << std::endl; - std::cout << " Packet count: " << SRinf.GetPacketCount() - << " (" << SRprevinf.GetPacketCount() << ")" << std::endl; - std::cout << " Octet count: " << SRinf.GetByteCount() - << " (" << SRprevinf.GetByteCount() <<")" << std::endl; - std::cout << " Receive time: " << SRinf.GetReceiveTime().GetSeconds() - << " (" << SRprevinf.GetReceiveTime().GetSeconds() << ")" << std::endl; - } - } - if (RRinf.HasInfo()) - { - if (!RRprevinf.HasInfo()) - { - std::cout << " RR Info:" << std::endl; - std::cout << " Fraction lost: " << RRinf.GetFractionLost() << std::endl; - std::cout << " Packets lost: " << RRinf.GetPacketsLost() << std::endl; - std::cout << " Ext.High.Seq: " << RRinf.GetExtendedHighestSequenceNumber() << std::endl; - std::cout << " Jitter: " << RRinf.GetJitter() << std::endl; - std::cout << " LSR: " << RRinf.GetLastSRTimestamp() << std::endl; - std::cout << " DLSR: " << RRinf.GetDelaySinceLastSR() << std::endl; - std::cout << " Receive time: " << RRinf.GetReceiveTime().GetSeconds() << std::endl; - } - else - { - std::cout << " RR Info:" << std::endl; - std::cout << " Fraction lost: " << RRinf.GetFractionLost() - << " (" << RRprevinf.GetFractionLost() << ")" << std::endl; - std::cout << " Packets lost: " << RRinf.GetPacketsLost() - << " (" << RRprevinf.GetPacketsLost() << ")" << std::endl; - std::cout << " Ext.High.Seq: " << RRinf.GetExtendedHighestSequenceNumber() - << " (" << RRprevinf.GetExtendedHighestSequenceNumber() << ")" << std::endl; - std::cout << " Jitter: " << RRinf.GetJitter() - << " (" << RRprevinf.GetJitter() << ")" << std::endl; - std::cout << " LSR: " << RRinf.GetLastSRTimestamp() - << " (" << RRprevinf.GetLastSRTimestamp() << ")" << std::endl; - std::cout << " DLSR: " << RRinf.GetDelaySinceLastSR() - << " (" << RRprevinf.GetDelaySinceLastSR() << ")" << std::endl; - std::cout << " Receive time: " << RRinf.GetReceiveTime().GetSeconds() - << " (" << RRprevinf.GetReceiveTime().GetSeconds() <<")" << std::endl; - } - } - std::cout << " Stats:" << std::endl; - std::cout << " Sent data: " << ((stats.HasSentData())?"Yes":"No") << std::endl; - std::cout << " Packets received: " << stats.GetNumPacketsReceived() << std::endl; - std::cout << " Seq. base: " << stats.GetBaseSequenceNumber() << std::endl; - std::cout << " Ext.High.Seq: " << stats.GetExtendedHighestSequenceNumber() << std::endl; - std::cout << " Jitter: " << stats.GetJitter() << std::endl; - std::cout << " New packets: " << stats.GetNumPacketsReceivedInInterval() << std::endl; - std::cout << " Saved seq. nr.: " << stats.GetSavedExtendedSequenceNumber() << std::endl; - std::cout << " RTT: " << INF_GetRoundtripTime().GetDouble() << " seconds" << std::endl; - if (INF_GetEstimatedTimestampUnit() > 0) - std::cout << " Estimated: " << (1.0/INF_GetEstimatedTimestampUnit()) << " samples per second" << std::endl; - std::cout << " SDES Info:" << std::endl; + std::cout << "Source data for SSRC: " << ssrc << std::endl; + std::cout << " Active: " << ((IsActive())?"Yes":"No") << std::endl; + std::cout << " Sender: " << ((issender)?"Yes":"No") << std::endl; + std::cout << " CSRC: " << ((iscsrc)?"Yes":"No") << std::endl; + std::cout << " Received bye: " << ((receivedbye)?"Yes":"No") << std::endl; + std::cout << " ProcessedInRTCP: " << ((processedinrtcp)?"Yes":"No") << std::endl; + std::cout << " Timestamp unit: " << timestampunit << std::endl; + std::cout << " RTP address: "; + if (!isrtpaddrset) + std::cout << "Not set" << std::endl; + else + { + if (rtpaddr == 0) + std::cout << "Own session" << std::endl; + else + std::cout << rtpaddr->GetAddressString() << std::endl; + } + std::cout << " RTCP address: "; + if (!isrtcpaddrset) + std::cout << "Not set" << std::endl; + else + { + if (rtcpaddr == 0) + std::cout << "Own session" << std::endl; + else + std::cout << rtcpaddr->GetAddressString() << std::endl; + } + if (SRinf.HasInfo()) + { + if (!SRprevinf.HasInfo()) + { + std::cout << " SR Info:" << std::endl; + std::cout << " NTP timestamp: " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW() << std::endl; + std::cout << " RTP timestamp: " << SRinf.GetRTPTimestamp() << std::endl; + std::cout << " Packet count: " << SRinf.GetPacketCount() << std::endl; + std::cout << " Octet count: " << SRinf.GetByteCount() << std::endl; + std::cout << " Receive time: " << SRinf.GetReceiveTime().GetSeconds() << std::endl; + } + else + { + std::cout << " SR Info:" << std::endl; + std::cout << " NTP timestamp: " << SRinf.GetNTPTimestamp().GetMSW() << ":" << SRinf.GetNTPTimestamp().GetLSW() + << " (" << SRprevinf.GetNTPTimestamp().GetMSW() << ":" << SRprevinf.GetNTPTimestamp().GetLSW() << ")" << std::endl; + std::cout << " RTP timestamp: " << SRinf.GetRTPTimestamp() + << " (" << SRprevinf.GetRTPTimestamp() << ")" << std::endl; + std::cout << " Packet count: " << SRinf.GetPacketCount() + << " (" << SRprevinf.GetPacketCount() << ")" << std::endl; + std::cout << " Octet count: " << SRinf.GetByteCount() + << " (" << SRprevinf.GetByteCount() <<")" << std::endl; + std::cout << " Receive time: " << SRinf.GetReceiveTime().GetSeconds() + << " (" << SRprevinf.GetReceiveTime().GetSeconds() << ")" << std::endl; + } + } + if (RRinf.HasInfo()) + { + if (!RRprevinf.HasInfo()) + { + std::cout << " RR Info:" << std::endl; + std::cout << " Fraction lost: " << RRinf.GetFractionLost() << std::endl; + std::cout << " Packets lost: " << RRinf.GetPacketsLost() << std::endl; + std::cout << " Ext.High.Seq: " << RRinf.GetExtendedHighestSequenceNumber() << std::endl; + std::cout << " Jitter: " << RRinf.GetJitter() << std::endl; + std::cout << " LSR: " << RRinf.GetLastSRTimestamp() << std::endl; + std::cout << " DLSR: " << RRinf.GetDelaySinceLastSR() << std::endl; + std::cout << " Receive time: " << RRinf.GetReceiveTime().GetSeconds() << std::endl; + } + else + { + std::cout << " RR Info:" << std::endl; + std::cout << " Fraction lost: " << RRinf.GetFractionLost() + << " (" << RRprevinf.GetFractionLost() << ")" << std::endl; + std::cout << " Packets lost: " << RRinf.GetPacketsLost() + << " (" << RRprevinf.GetPacketsLost() << ")" << std::endl; + std::cout << " Ext.High.Seq: " << RRinf.GetExtendedHighestSequenceNumber() + << " (" << RRprevinf.GetExtendedHighestSequenceNumber() << ")" << std::endl; + std::cout << " Jitter: " << RRinf.GetJitter() + << " (" << RRprevinf.GetJitter() << ")" << std::endl; + std::cout << " LSR: " << RRinf.GetLastSRTimestamp() + << " (" << RRprevinf.GetLastSRTimestamp() << ")" << std::endl; + std::cout << " DLSR: " << RRinf.GetDelaySinceLastSR() + << " (" << RRprevinf.GetDelaySinceLastSR() << ")" << std::endl; + std::cout << " Receive time: " << RRinf.GetReceiveTime().GetSeconds() + << " (" << RRprevinf.GetReceiveTime().GetSeconds() <<")" << std::endl; + } + } + std::cout << " Stats:" << std::endl; + std::cout << " Sent data: " << ((stats.HasSentData())?"Yes":"No") << std::endl; + std::cout << " Packets received: " << stats.GetNumPacketsReceived() << std::endl; + std::cout << " Seq. base: " << stats.GetBaseSequenceNumber() << std::endl; + std::cout << " Ext.High.Seq: " << stats.GetExtendedHighestSequenceNumber() << std::endl; + std::cout << " Jitter: " << stats.GetJitter() << std::endl; + std::cout << " New packets: " << stats.GetNumPacketsReceivedInInterval() << std::endl; + std::cout << " Saved seq. nr.: " << stats.GetSavedExtendedSequenceNumber() << std::endl; + std::cout << " RTT: " << INF_GetRoundtripTime().GetDouble() << " seconds" << std::endl; + if (INF_GetEstimatedTimestampUnit() > 0) + std::cout << " Estimated: " << (1.0/INF_GetEstimatedTimestampUnit()) << " samples per second" << std::endl; + std::cout << " SDES Info:" << std::endl; - size_t len; - char str[1024]; - uint8_t *val; - - if ((val = SDESinf.GetCNAME(&len)) != 0) - { - memcpy(str,val,len); - str[len] = 0; - std::cout << " CNAME: " << std::string(str) << std::endl; - } - if ((val = SDESinf.GetName(&len)) != 0) - { - memcpy(str,val,len); - str[len] = 0; - std::cout << " Name: " << std::string(str) << std::endl; - } - if ((val = SDESinf.GetEMail(&len)) != 0) - { - memcpy(str,val,len); - str[len] = 0; - std::cout << " EMail: " << std::string(str) << std::endl; - } - if ((val = SDESinf.GetPhone(&len)) != 0) - { - memcpy(str,val,len); - str[len] = 0; - std::cout << " phone: " << std::string(str) << std::endl; - } - if ((val = SDESinf.GetLocation(&len)) != 0) - { - memcpy(str,val,len); - str[len] = 0; - std::cout << " Location: " << std::string(str) << std::endl; - } - if ((val = SDESinf.GetTool(&len)) != 0) - { - memcpy(str,val,len); - str[len] = 0; - std::cout << " Tool: " << std::string(str) << std::endl; - } - if ((val = SDESinf.GetNote(&len)) != 0) - { - memcpy(str,val,len); - str[len] = 0; - std::cout << " Note: " << std::string(str) << std::endl; - } + size_t len; + char str[1024]; + uint8_t *val; + + if ((val = SDESinf.GetCNAME(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " CNAME: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetName(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " Name: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetEMail(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " EMail: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetPhone(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " phone: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetLocation(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " Location: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetTool(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " Tool: " << std::string(str) << std::endl; + } + if ((val = SDESinf.GetNote(&len)) != 0) + { + memcpy(str,val,len); + str[len] = 0; + std::cout << " Note: " << std::string(str) << std::endl; + } #ifdef RTP_SUPPORT_SDESPRIV - SDESinf.GotoFirstPrivateValue(); - uint8_t *pref; - size_t preflen; - while (SDESinf.GetNextPrivateValue(&pref,&preflen,&val,&len)) - { - char prefstr[1024]; - memcpy(prefstr,pref,preflen); - memcpy(str,val,len); - prefstr[preflen] = 0; - str[len] = 0; - std::cout << " Private: " << std::string(prefstr) << ":" << std::string(str) << std::endl; - } + SDESinf.GotoFirstPrivateValue(); + uint8_t *pref; + size_t preflen; + while (SDESinf.GetNextPrivateValue(&pref,&preflen,&val,&len)) + { + char prefstr[1024]; + memcpy(prefstr,pref,preflen); + memcpy(str,val,len); + prefstr[preflen] = 0; + str[len] = 0; + std::cout << " Private: " << std::string(prefstr) << ":" << std::string(str) << std::endl; + } #endif // RTP_SUPPORT_SDESPRIV - if (byereason) - { - memcpy(str,byereason,byereasonlen); - str[byereasonlen] = 0; - std::cout << " BYE Reason: " << std::string(str) << std::endl; - } + if (byereason) + { + memcpy(str,byereason,byereasonlen); + str[byereasonlen] = 0; + std::cout << " BYE Reason: " << std::string(str) << std::endl; + } } #endif // RTPDEBUG diff --git a/src/libs/jrtplib/src/rtpsourcedata.h b/src/libs/jrtplib/src/rtpsourcedata.h index b12c5f76..934afe4e 100644 --- a/src/libs/jrtplib/src/rtpsourcedata.h +++ b/src/libs/jrtplib/src/rtpsourcedata.h @@ -7,7 +7,7 @@ This library was developed at the Expertise Centre for Digital Media (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for + (http://www.uhasselt.be). The library is based upon work done for my thesis at the School for Knowledge Technology (Belgium/The Netherlands). Permission is hereby granted, free of charge, to any person obtaining a @@ -55,111 +55,111 @@ class RTPAddress; class JRTPLIB_IMPORTEXPORT RTCPSenderReportInfo { public: - RTCPSenderReportInfo():ntptimestamp(0,0),receivetime(0,0) { hasinfo = false; rtptimestamp = 0; packetcount = 0; bytecount = 0; } - void Set(const RTPNTPTime &ntptime,uint32_t rtptime,uint32_t pcount, - uint32_t bcount,const RTPTime &rcvtime) { ntptimestamp = ntptime; rtptimestamp = rtptime; packetcount = pcount; bytecount = bcount; receivetime = rcvtime; hasinfo = true; } - - bool HasInfo() const { return hasinfo; } - RTPNTPTime GetNTPTimestamp() const { return ntptimestamp; } - uint32_t GetRTPTimestamp() const { return rtptimestamp; } - uint32_t GetPacketCount() const { return packetcount; } - uint32_t GetByteCount() const { return bytecount; } - RTPTime GetReceiveTime() const { return receivetime; } + RTCPSenderReportInfo():ntptimestamp(0,0),receivetime(0,0) { hasinfo = false; rtptimestamp = 0; packetcount = 0; bytecount = 0; } + void Set(const RTPNTPTime &ntptime,uint32_t rtptime,uint32_t pcount, + uint32_t bcount,const RTPTime &rcvtime) { ntptimestamp = ntptime; rtptimestamp = rtptime; packetcount = pcount; bytecount = bcount; receivetime = rcvtime; hasinfo = true; } + + bool HasInfo() const { return hasinfo; } + RTPNTPTime GetNTPTimestamp() const { return ntptimestamp; } + uint32_t GetRTPTimestamp() const { return rtptimestamp; } + uint32_t GetPacketCount() const { return packetcount; } + uint32_t GetByteCount() const { return bytecount; } + RTPTime GetReceiveTime() const { return receivetime; } private: - bool hasinfo; - RTPNTPTime ntptimestamp; - uint32_t rtptimestamp; - uint32_t packetcount; - uint32_t bytecount; - RTPTime receivetime; + bool hasinfo; + RTPNTPTime ntptimestamp; + uint32_t rtptimestamp; + uint32_t packetcount; + uint32_t bytecount; + RTPTime receivetime; }; class JRTPLIB_IMPORTEXPORT RTCPReceiverReportInfo { public: - RTCPReceiverReportInfo():receivetime(0,0) { hasinfo = false; fractionlost = 0; packetslost = 0; exthighseqnr = 0; jitter = 0; lsr = 0; dlsr = 0; } - void Set(uint8_t fraclost,int32_t plost,uint32_t exthigh, - uint32_t jit,uint32_t l,uint32_t dl,const RTPTime &rcvtime) { fractionlost = ((double)fraclost)/256.0; packetslost = plost; exthighseqnr = exthigh; jitter = jit; lsr = l; dlsr = dl; receivetime = rcvtime; hasinfo = true; } - - bool HasInfo() const { return hasinfo; } - double GetFractionLost() const { return fractionlost; } - int32_t GetPacketsLost() const { return packetslost; } - uint32_t GetExtendedHighestSequenceNumber() const { return exthighseqnr; } - uint32_t GetJitter() const { return jitter; } - uint32_t GetLastSRTimestamp() const { return lsr; } - uint32_t GetDelaySinceLastSR() const { return dlsr; } - RTPTime GetReceiveTime() const { return receivetime; } + RTCPReceiverReportInfo():receivetime(0,0) { hasinfo = false; fractionlost = 0; packetslost = 0; exthighseqnr = 0; jitter = 0; lsr = 0; dlsr = 0; } + void Set(uint8_t fraclost,int32_t plost,uint32_t exthigh, + uint32_t jit,uint32_t l,uint32_t dl,const RTPTime &rcvtime) { fractionlost = ((double)fraclost)/256.0; packetslost = plost; exthighseqnr = exthigh; jitter = jit; lsr = l; dlsr = dl; receivetime = rcvtime; hasinfo = true; } + + bool HasInfo() const { return hasinfo; } + double GetFractionLost() const { return fractionlost; } + int32_t GetPacketsLost() const { return packetslost; } + uint32_t GetExtendedHighestSequenceNumber() const { return exthighseqnr; } + uint32_t GetJitter() const { return jitter; } + uint32_t GetLastSRTimestamp() const { return lsr; } + uint32_t GetDelaySinceLastSR() const { return dlsr; } + RTPTime GetReceiveTime() const { return receivetime; } private: - bool hasinfo; - double fractionlost; - int32_t packetslost; - uint32_t exthighseqnr; - uint32_t jitter; - uint32_t lsr; - uint32_t dlsr; - RTPTime receivetime; + bool hasinfo; + double fractionlost; + int32_t packetslost; + uint32_t exthighseqnr; + uint32_t jitter; + uint32_t lsr; + uint32_t dlsr; + RTPTime receivetime; }; class JRTPLIB_IMPORTEXPORT RTPSourceStats { public: - RTPSourceStats(); - void ProcessPacket(RTPPacket *pack,const RTPTime &receivetime,double tsunit,bool ownpacket,bool *accept,bool applyprobation,bool *onprobation); + RTPSourceStats(); + void ProcessPacket(RTPPacket *pack,const RTPTime &receivetime,double tsunit,bool ownpacket,bool *accept,bool applyprobation,bool *onprobation); - bool HasSentData() const { return sentdata; } - uint32_t GetNumPacketsReceived() const { return packetsreceived; } - uint32_t GetBaseSequenceNumber() const { return baseseqnr; } - uint32_t GetExtendedHighestSequenceNumber() const { return exthighseqnr; } - uint32_t GetJitter() const { return jitter; } - void ResetJitter() { jitter = 0; } - int32_t GetNumPacketsReceivedInInterval() const { return numnewpackets; } - uint32_t GetSavedExtendedSequenceNumber() const { return savedextseqnr; } - void StartNewInterval() { numnewpackets = 0; savedextseqnr = exthighseqnr; } - - void SetLastMessageTime(const RTPTime &t) { lastmsgtime = t; } - RTPTime GetLastMessageTime() const { return lastmsgtime; } - void SetLastRTPPacketTime(const RTPTime &t) { lastrtptime = t; } - RTPTime GetLastRTPPacketTime() const { return lastrtptime; } + bool HasSentData() const { return sentdata; } + uint32_t GetNumPacketsReceived() const { return packetsreceived; } + uint32_t GetBaseSequenceNumber() const { return baseseqnr; } + uint32_t GetExtendedHighestSequenceNumber() const { return exthighseqnr; } + uint32_t GetJitter() const { return jitter; } + void ResetJitter() { jitter = 0; } + int32_t GetNumPacketsReceivedInInterval() const { return numnewpackets; } + uint32_t GetSavedExtendedSequenceNumber() const { return savedextseqnr; } + void StartNewInterval() { numnewpackets = 0; savedextseqnr = exthighseqnr; } - void SetLastNoteTime(const RTPTime &t) { lastnotetime = t; } - RTPTime GetLastNoteTime() const { return lastnotetime; } + void SetLastMessageTime(const RTPTime &t) { lastmsgtime = t; } + RTPTime GetLastMessageTime() const { return lastmsgtime; } + void SetLastRTPPacketTime(const RTPTime &t) { lastrtptime = t; } + RTPTime GetLastRTPPacketTime() const { return lastrtptime; } + + void SetLastNoteTime(const RTPTime &t) { lastnotetime = t; } + RTPTime GetLastNoteTime() const { return lastnotetime; } private: - bool sentdata; - uint32_t packetsreceived; - uint32_t numcycles; // shifted left 16 bits - uint32_t baseseqnr; - uint32_t exthighseqnr,prevexthighseqnr; - uint32_t jitter,prevtimestamp; - double djitter; - RTPTime prevpacktime; - RTPTime lastmsgtime; - RTPTime lastrtptime; - RTPTime lastnotetime; - uint32_t numnewpackets; - uint32_t savedextseqnr; + bool sentdata; + uint32_t packetsreceived; + uint32_t numcycles; // shifted left 16 bits + uint32_t baseseqnr; + uint32_t exthighseqnr,prevexthighseqnr; + uint32_t jitter,prevtimestamp; + double djitter; + RTPTime prevpacktime; + RTPTime lastmsgtime; + RTPTime lastrtptime; + RTPTime lastnotetime; + uint32_t numnewpackets; + uint32_t savedextseqnr; #ifdef RTP_SUPPORT_PROBATION - uint16_t prevseqnr; - int probation; - RTPSources::ProbationType probationtype; + uint16_t prevseqnr; + int probation; + RTPSources::ProbationType probationtype; #endif // RTP_SUPPORT_PROBATION }; - + inline RTPSourceStats::RTPSourceStats():prevpacktime(0,0),lastmsgtime(0,0),lastrtptime(0,0),lastnotetime(0,0) { - sentdata = false; - packetsreceived = 0; - baseseqnr = 0; - exthighseqnr = 0; - prevexthighseqnr = 0; - jitter = 0; - numcycles = 0; - numnewpackets = 0; - prevtimestamp = 0; - djitter = 0; - savedextseqnr = 0; + sentdata = false; + packetsreceived = 0; + baseseqnr = 0; + exthighseqnr = 0; + prevexthighseqnr = 0; + jitter = 0; + numcycles = 0; + numnewpackets = 0; + prevtimestamp = 0; + djitter = 0; + savedextseqnr = 0; #ifdef RTP_SUPPORT_PROBATION - probation = 0; - prevseqnr = 0; + probation = 0; + prevseqnr = 0; #endif // RTP_SUPPORT_PROBATION } @@ -167,311 +167,311 @@ inline RTPSourceStats::RTPSourceStats():prevpacktime(0,0),lastmsgtime(0,0),lastr class JRTPLIB_IMPORTEXPORT RTPSourceData : public RTPMemoryObject { protected: - RTPSourceData(uint32_t ssrc, RTPMemoryManager *mgr = 0); - virtual ~RTPSourceData(); + RTPSourceData(uint32_t ssrc, RTPMemoryManager *mgr = 0); + virtual ~RTPSourceData(); public: - /** Extracts the first packet of this participants RTP packet queue. */ - RTPPacket *GetNextPacket(); + /** Extracts the first packet of this participants RTP packet queue. */ + RTPPacket *GetNextPacket(); - /** Clears the participant's RTP packet list. */ - void FlushPackets(); + /** Clears the participant's RTP packet list. */ + void FlushPackets(); - /** Returns \c true if there are RTP packets which can be extracted. */ - bool HasData() const { if (!validated) return false; return packetlist.empty()?false:true; } + /** Returns \c true if there are RTP packets which can be extracted. */ + bool HasData() const { if (!validated) return false; return packetlist.empty()?false:true; } - /** Returns the SSRC identifier for this member. */ - uint32_t GetSSRC() const { return ssrc; } + /** Returns the SSRC identifier for this member. */ + uint32_t GetSSRC() const { return ssrc; } - /** Returns \c true if the participant was added using the RTPSources member function CreateOwnSSRC and - * returns \c false otherwise. - */ - bool IsOwnSSRC() const { return ownssrc; } + /** Returns \c true if the participant was added using the RTPSources member function CreateOwnSSRC and + * returns \c false otherwise. + */ + bool IsOwnSSRC() const { return ownssrc; } - /** Returns \c true if the source identifier is actually a CSRC from an RTP packet. */ - bool IsCSRC() const { return iscsrc; } + /** Returns \c true if the source identifier is actually a CSRC from an RTP packet. */ + bool IsCSRC() const { return iscsrc; } - /** Returns \c true if this member is marked as a sender and \c false if not. */ - bool IsSender() const { return issender; } + /** Returns \c true if this member is marked as a sender and \c false if not. */ + bool IsSender() const { return issender; } - /** Returns \c true if the participant is validated, which is the case if a number of - * consecutive RTP packets have been received or if a CNAME item has been received for - * this participant. - */ - bool IsValidated() const { return validated; } + /** Returns \c true if the participant is validated, which is the case if a number of + * consecutive RTP packets have been received or if a CNAME item has been received for + * this participant. + */ + bool IsValidated() const { return validated; } - /** Returns \c true if the source was validated and had not yet sent a BYE packet. */ - bool IsActive() const { if (!validated) return false; if (receivedbye) return false; return true; } + /** Returns \c true if the source was validated and had not yet sent a BYE packet. */ + bool IsActive() const { if (!validated) return false; if (receivedbye) return false; return true; } - /** This function is used by the RTCPPacketBuilder class to mark whether this participant's - * information has been processed in a report block or not. - */ - void SetProcessedInRTCP(bool v) { processedinrtcp = v; } - - /** This function is used by the RTCPPacketBuilder class and returns whether this participant - * has been processed in a report block or not. - */ - bool IsProcessedInRTCP() const { return processedinrtcp; } - - /** Returns \c true if the address from which this participant's RTP packets originate has - * already been set. - */ - bool IsRTPAddressSet() const { return isrtpaddrset; } + /** This function is used by the RTCPPacketBuilder class to mark whether this participant's + * information has been processed in a report block or not. + */ + void SetProcessedInRTCP(bool v) { processedinrtcp = v; } - /** Returns \c true if the address from which this participant's RTCP packets originate has - * already been set. - */ - bool IsRTCPAddressSet() const { return isrtcpaddrset; } + /** This function is used by the RTCPPacketBuilder class and returns whether this participant + * has been processed in a report block or not. + */ + bool IsProcessedInRTCP() const { return processedinrtcp; } - /** Returns the address from which this participant's RTP packets originate. - * Returns the address from which this participant's RTP packets originate. If the address has - * been set and the returned value is NULL, this indicates that it originated from the local - * participant. - */ - const RTPAddress *GetRTPDataAddress() const { return rtpaddr; } + /** Returns \c true if the address from which this participant's RTP packets originate has + * already been set. + */ + bool IsRTPAddressSet() const { return isrtpaddrset; } - /** Returns the address from which this participant's RTCP packets originate. - * Returns the address from which this participant's RTCP packets originate. If the address has - * been set and the returned value is NULL, this indicates that it originated from the local - * participant. - */ - const RTPAddress *GetRTCPDataAddress() const { return rtcpaddr; } + /** Returns \c true if the address from which this participant's RTCP packets originate has + * already been set. + */ + bool IsRTCPAddressSet() const { return isrtcpaddrset; } - /** Returns \c true if we received a BYE message for this participant and \c false otherwise. */ - bool ReceivedBYE() const { return receivedbye; } + /** Returns the address from which this participant's RTP packets originate. + * Returns the address from which this participant's RTP packets originate. If the address has + * been set and the returned value is NULL, this indicates that it originated from the local + * participant. + */ + const RTPAddress *GetRTPDataAddress() const { return rtpaddr; } - /** Returns the reason for leaving contained in the BYE packet of this participant. - * Returns the reason for leaving contained in the BYE packet of this participant. The length of - * the reason is stored in \c len. - */ - uint8_t *GetBYEReason(size_t *len) const { *len = byereasonlen; return byereason; } + /** Returns the address from which this participant's RTCP packets originate. + * Returns the address from which this participant's RTCP packets originate. If the address has + * been set and the returned value is NULL, this indicates that it originated from the local + * participant. + */ + const RTPAddress *GetRTCPDataAddress() const { return rtcpaddr; } - /** Returns the time at which the BYE packet was received. */ - RTPTime GetBYETime() const { return byetime; } - - /** Sets the value for the timestamp unit to be used in jitter calculations for data received from this participant. - * Sets the value for the timestamp unit to be used in jitter calculations for data received from this participant. - * If not set, the library uses an approximation for the timestamp unit which is calculated from two consecutive - * RTCP sender reports. The timestamp unit is defined as a time interval divided by the corresponding timestamp - * interval. For 8000 Hz audio this would be 1/8000. For video, often a timestamp unit of 1/90000 is used. - */ - void SetTimestampUnit(double tsu) { timestampunit = tsu; } + /** Returns \c true if we received a BYE message for this participant and \c false otherwise. */ + bool ReceivedBYE() const { return receivedbye; } - /** Returns the timestamp unit used for this participant. */ - double GetTimestampUnit() const { return timestampunit; } + /** Returns the reason for leaving contained in the BYE packet of this participant. + * Returns the reason for leaving contained in the BYE packet of this participant. The length of + * the reason is stored in \c len. + */ + uint8_t *GetBYEReason(size_t *len) const { *len = byereasonlen; return byereason; } - /** Returns \c true if an RTCP sender report has been received from this participant. */ - bool SR_HasInfo() const { return SRinf.HasInfo(); } + /** Returns the time at which the BYE packet was received. */ + RTPTime GetBYETime() const { return byetime; } - /** Returns the NTP timestamp contained in the last sender report. */ - RTPNTPTime SR_GetNTPTimestamp() const { return SRinf.GetNTPTimestamp(); } + /** Sets the value for the timestamp unit to be used in jitter calculations for data received from this participant. + * Sets the value for the timestamp unit to be used in jitter calculations for data received from this participant. + * If not set, the library uses an approximation for the timestamp unit which is calculated from two consecutive + * RTCP sender reports. The timestamp unit is defined as a time interval divided by the corresponding timestamp + * interval. For 8000 Hz audio this would be 1/8000. For video, often a timestamp unit of 1/90000 is used. + */ + void SetTimestampUnit(double tsu) { timestampunit = tsu; } - /** Returns the RTP timestamp contained in the last sender report. */ - uint32_t SR_GetRTPTimestamp() const { return SRinf.GetRTPTimestamp(); } + /** Returns the timestamp unit used for this participant. */ + double GetTimestampUnit() const { return timestampunit; } - /** Returns the packet count contained in the last sender report. */ - uint32_t SR_GetPacketCount() const { return SRinf.GetPacketCount(); } + /** Returns \c true if an RTCP sender report has been received from this participant. */ + bool SR_HasInfo() const { return SRinf.HasInfo(); } - /** Returns the octet count contained in the last sender report. */ - uint32_t SR_GetByteCount() const { return SRinf.GetByteCount(); } + /** Returns the NTP timestamp contained in the last sender report. */ + RTPNTPTime SR_GetNTPTimestamp() const { return SRinf.GetNTPTimestamp(); } - /** Returns the time at which the last sender report was received. */ - RTPTime SR_GetReceiveTime() const { return SRinf.GetReceiveTime(); } - - /** Returns \c true if more than one RTCP sender report has been received. */ - bool SR_Prev_HasInfo() const { return SRprevinf.HasInfo(); } + /** Returns the RTP timestamp contained in the last sender report. */ + uint32_t SR_GetRTPTimestamp() const { return SRinf.GetRTPTimestamp(); } - /** Returns the NTP timestamp contained in the second to last sender report. */ - RTPNTPTime SR_Prev_GetNTPTimestamp() const { return SRprevinf.GetNTPTimestamp(); } + /** Returns the packet count contained in the last sender report. */ + uint32_t SR_GetPacketCount() const { return SRinf.GetPacketCount(); } - /** Returns the RTP timestamp contained in the second to last sender report. */ - uint32_t SR_Prev_GetRTPTimestamp() const { return SRprevinf.GetRTPTimestamp(); } + /** Returns the octet count contained in the last sender report. */ + uint32_t SR_GetByteCount() const { return SRinf.GetByteCount(); } - /** Returns the packet count contained in the second to last sender report. */ - uint32_t SR_Prev_GetPacketCount() const { return SRprevinf.GetPacketCount(); } + /** Returns the time at which the last sender report was received. */ + RTPTime SR_GetReceiveTime() const { return SRinf.GetReceiveTime(); } - /** Returns the octet count contained in the second to last sender report. */ - uint32_t SR_Prev_GetByteCount() const { return SRprevinf.GetByteCount(); } + /** Returns \c true if more than one RTCP sender report has been received. */ + bool SR_Prev_HasInfo() const { return SRprevinf.HasInfo(); } - /** Returns the time at which the second to last sender report was received. */ - RTPTime SR_Prev_GetReceiveTime() const { return SRprevinf.GetReceiveTime(); } + /** Returns the NTP timestamp contained in the second to last sender report. */ + RTPNTPTime SR_Prev_GetNTPTimestamp() const { return SRprevinf.GetNTPTimestamp(); } - /** Returns \c true if this participant sent a receiver report with information about the reception of our data. */ - bool RR_HasInfo() const { return RRinf.HasInfo(); } + /** Returns the RTP timestamp contained in the second to last sender report. */ + uint32_t SR_Prev_GetRTPTimestamp() const { return SRprevinf.GetRTPTimestamp(); } - /** Returns the fraction lost value from the last report. */ - double RR_GetFractionLost() const { return RRinf.GetFractionLost(); } + /** Returns the packet count contained in the second to last sender report. */ + uint32_t SR_Prev_GetPacketCount() const { return SRprevinf.GetPacketCount(); } - /** Returns the number of lost packets contained in the last report. */ - int32_t RR_GetPacketsLost() const { return RRinf.GetPacketsLost(); } + /** Returns the octet count contained in the second to last sender report. */ + uint32_t SR_Prev_GetByteCount() const { return SRprevinf.GetByteCount(); } - /** Returns the extended highest sequence number contained in the last report. */ - uint32_t RR_GetExtendedHighestSequenceNumber() const { return RRinf.GetExtendedHighestSequenceNumber(); } + /** Returns the time at which the second to last sender report was received. */ + RTPTime SR_Prev_GetReceiveTime() const { return SRprevinf.GetReceiveTime(); } - /** Returns the jitter value from the last report. */ - uint32_t RR_GetJitter() const { return RRinf.GetJitter(); } + /** Returns \c true if this participant sent a receiver report with information about the reception of our data. */ + bool RR_HasInfo() const { return RRinf.HasInfo(); } - /** Returns the LSR value from the last report. */ - uint32_t RR_GetLastSRTimestamp() const { return RRinf.GetLastSRTimestamp(); } + /** Returns the fraction lost value from the last report. */ + double RR_GetFractionLost() const { return RRinf.GetFractionLost(); } - /** Returns the DLSR value from the last report. */ - uint32_t RR_GetDelaySinceLastSR() const { return RRinf.GetDelaySinceLastSR(); } + /** Returns the number of lost packets contained in the last report. */ + int32_t RR_GetPacketsLost() const { return RRinf.GetPacketsLost(); } - /** Returns the time at which the last report was received. */ - RTPTime RR_GetReceiveTime() const { return RRinf.GetReceiveTime(); } - - /** Returns \c true if this participant sent more than one receiver report with information - * about the reception of our data. - */ - bool RR_Prev_HasInfo() const { return RRprevinf.HasInfo(); } + /** Returns the extended highest sequence number contained in the last report. */ + uint32_t RR_GetExtendedHighestSequenceNumber() const { return RRinf.GetExtendedHighestSequenceNumber(); } - /** Returns the fraction lost value from the second to last report. */ - double RR_Prev_GetFractionLost() const { return RRprevinf.GetFractionLost(); } + /** Returns the jitter value from the last report. */ + uint32_t RR_GetJitter() const { return RRinf.GetJitter(); } - /** Returns the number of lost packets contained in the second to last report. */ - int32_t RR_Prev_GetPacketsLost() const { return RRprevinf.GetPacketsLost(); } + /** Returns the LSR value from the last report. */ + uint32_t RR_GetLastSRTimestamp() const { return RRinf.GetLastSRTimestamp(); } - /** Returns the extended highest sequence number contained in the second to last report. */ - uint32_t RR_Prev_GetExtendedHighestSequenceNumber() const { return RRprevinf.GetExtendedHighestSequenceNumber(); } + /** Returns the DLSR value from the last report. */ + uint32_t RR_GetDelaySinceLastSR() const { return RRinf.GetDelaySinceLastSR(); } - /** Returns the jitter value from the second to last report. */ - uint32_t RR_Prev_GetJitter() const { return RRprevinf.GetJitter(); } - - /** Returns the LSR value from the second to last report. */ - uint32_t RR_Prev_GetLastSRTimestamp() const { return RRprevinf.GetLastSRTimestamp(); } + /** Returns the time at which the last report was received. */ + RTPTime RR_GetReceiveTime() const { return RRinf.GetReceiveTime(); } - /** Returns the DLSR value from the second to last report. */ - uint32_t RR_Prev_GetDelaySinceLastSR() const { return RRprevinf.GetDelaySinceLastSR(); } + /** Returns \c true if this participant sent more than one receiver report with information + * about the reception of our data. + */ + bool RR_Prev_HasInfo() const { return RRprevinf.HasInfo(); } - /** Returns the time at which the second to last report was received. */ - RTPTime RR_Prev_GetReceiveTime() const { return RRprevinf.GetReceiveTime(); } + /** Returns the fraction lost value from the second to last report. */ + double RR_Prev_GetFractionLost() const { return RRprevinf.GetFractionLost(); } - /** Returns \c true if validated RTP packets have been received from this participant. */ - bool INF_HasSentData() const { return stats.HasSentData(); } + /** Returns the number of lost packets contained in the second to last report. */ + int32_t RR_Prev_GetPacketsLost() const { return RRprevinf.GetPacketsLost(); } - /** Returns the total number of received packets from this participant. */ - int32_t INF_GetNumPacketsReceived() const { return stats.GetNumPacketsReceived(); } + /** Returns the extended highest sequence number contained in the second to last report. */ + uint32_t RR_Prev_GetExtendedHighestSequenceNumber() const { return RRprevinf.GetExtendedHighestSequenceNumber(); } - /** Returns the base sequence number of this participant. */ - uint32_t INF_GetBaseSequenceNumber() const { return stats.GetBaseSequenceNumber(); } + /** Returns the jitter value from the second to last report. */ + uint32_t RR_Prev_GetJitter() const { return RRprevinf.GetJitter(); } - /** Returns the extended highest sequence number received from this participant. */ - uint32_t INF_GetExtendedHighestSequenceNumber() const { return stats.GetExtendedHighestSequenceNumber(); } + /** Returns the LSR value from the second to last report. */ + uint32_t RR_Prev_GetLastSRTimestamp() const { return RRprevinf.GetLastSRTimestamp(); } - /** Returns the current jitter value for this participant. */ - uint32_t INF_GetJitter() const { return stats.GetJitter(); } + /** Returns the DLSR value from the second to last report. */ + uint32_t RR_Prev_GetDelaySinceLastSR() const { return RRprevinf.GetDelaySinceLastSR(); } - /** Returns the time at which something was last heard from this member. */ - RTPTime INF_GetLastMessageTime() const { return stats.GetLastMessageTime(); } + /** Returns the time at which the second to last report was received. */ + RTPTime RR_Prev_GetReceiveTime() const { return RRprevinf.GetReceiveTime(); } - /** Returns the time at which the last RTP packet was received. */ - RTPTime INF_GetLastRTPPacketTime() const { return stats.GetLastRTPPacketTime(); } + /** Returns \c true if validated RTP packets have been received from this participant. */ + bool INF_HasSentData() const { return stats.HasSentData(); } - /** Returns the estimated timestamp unit, calculated from two consecutive sender reports. */ - double INF_GetEstimatedTimestampUnit() const; + /** Returns the total number of received packets from this participant. */ + int32_t INF_GetNumPacketsReceived() const { return stats.GetNumPacketsReceived(); } - /** Returns the number of packets received since a new interval was started with INF_StartNewInterval. */ - uint32_t INF_GetNumPacketsReceivedInInterval() const { return stats.GetNumPacketsReceivedInInterval(); } + /** Returns the base sequence number of this participant. */ + uint32_t INF_GetBaseSequenceNumber() const { return stats.GetBaseSequenceNumber(); } - /** Returns the extended sequence number which was stored by the INF_StartNewInterval call. */ - uint32_t INF_GetSavedExtendedSequenceNumber() const { return stats.GetSavedExtendedSequenceNumber(); } + /** Returns the extended highest sequence number received from this participant. */ + uint32_t INF_GetExtendedHighestSequenceNumber() const { return stats.GetExtendedHighestSequenceNumber(); } - /** Starts a new interval to count received packets in; this also stores the current extended highest sequence - * number to be able to calculate the packet loss during the interval. - */ - void INF_StartNewInterval() { stats.StartNewInterval(); } + /** Returns the current jitter value for this participant. */ + uint32_t INF_GetJitter() const { return stats.GetJitter(); } - /** Estimates the round trip time by using the LSR and DLSR info from the last receiver report. */ - RTPTime INF_GetRoundtripTime() const; + /** Returns the time at which something was last heard from this member. */ + RTPTime INF_GetLastMessageTime() const { return stats.GetLastMessageTime(); } - /** Returns the time at which the last SDES NOTE item was received. */ - RTPTime INF_GetLastSDESNoteTime() const { return stats.GetLastNoteTime(); } - - /** Returns a pointer to the SDES CNAME item of this participant and stores its length in \c len. */ - uint8_t *SDES_GetCNAME(size_t *len) const { return SDESinf.GetCNAME(len); } + /** Returns the time at which the last RTP packet was received. */ + RTPTime INF_GetLastRTPPacketTime() const { return stats.GetLastRTPPacketTime(); } - /** Returns a pointer to the SDES name item of this participant and stores its length in \c len. */ - uint8_t *SDES_GetName(size_t *len) const { return SDESinf.GetName(len); } + /** Returns the estimated timestamp unit, calculated from two consecutive sender reports. */ + double INF_GetEstimatedTimestampUnit() const; - /** Returns a pointer to the SDES e-mail item of this participant and stores its length in \c len. */ - uint8_t *SDES_GetEMail(size_t *len) const { return SDESinf.GetEMail(len); } + /** Returns the number of packets received since a new interval was started with INF_StartNewInterval. */ + uint32_t INF_GetNumPacketsReceivedInInterval() const { return stats.GetNumPacketsReceivedInInterval(); } - /** Returns a pointer to the SDES phone item of this participant and stores its length in \c len. */ - uint8_t *SDES_GetPhone(size_t *len) const { return SDESinf.GetPhone(len); } + /** Returns the extended sequence number which was stored by the INF_StartNewInterval call. */ + uint32_t INF_GetSavedExtendedSequenceNumber() const { return stats.GetSavedExtendedSequenceNumber(); } - /** Returns a pointer to the SDES location item of this participant and stores its length in \c len. */ - uint8_t *SDES_GetLocation(size_t *len) const { return SDESinf.GetLocation(len); } + /** Starts a new interval to count received packets in; this also stores the current extended highest sequence + * number to be able to calculate the packet loss during the interval. + */ + void INF_StartNewInterval() { stats.StartNewInterval(); } - /** Returns a pointer to the SDES tool item of this participant and stores its length in \c len. */ - uint8_t *SDES_GetTool(size_t *len) const { return SDESinf.GetTool(len); } + /** Estimates the round trip time by using the LSR and DLSR info from the last receiver report. */ + RTPTime INF_GetRoundtripTime() const; + + /** Returns the time at which the last SDES NOTE item was received. */ + RTPTime INF_GetLastSDESNoteTime() const { return stats.GetLastNoteTime(); } + + /** Returns a pointer to the SDES CNAME item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetCNAME(size_t *len) const { return SDESinf.GetCNAME(len); } + + /** Returns a pointer to the SDES name item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetName(size_t *len) const { return SDESinf.GetName(len); } + + /** Returns a pointer to the SDES e-mail item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetEMail(size_t *len) const { return SDESinf.GetEMail(len); } + + /** Returns a pointer to the SDES phone item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetPhone(size_t *len) const { return SDESinf.GetPhone(len); } + + /** Returns a pointer to the SDES location item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetLocation(size_t *len) const { return SDESinf.GetLocation(len); } + + /** Returns a pointer to the SDES tool item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetTool(size_t *len) const { return SDESinf.GetTool(len); } + + /** Returns a pointer to the SDES note item of this participant and stores its length in \c len. */ + uint8_t *SDES_GetNote(size_t *len) const { return SDESinf.GetNote(len); } - /** Returns a pointer to the SDES note item of this participant and stores its length in \c len. */ - uint8_t *SDES_GetNote(size_t *len) const { return SDESinf.GetNote(len); } - #ifdef RTP_SUPPORT_SDESPRIV - /** Starts the iteration over the stored SDES private item prefixes and their associated values. */ - void SDES_GotoFirstPrivateValue() { SDESinf.GotoFirstPrivateValue(); } - - /** If available, returns \c true and stores the next SDES private item prefix in \c prefix and its length in - * \c prefixlen; the associated value and its length are then stored in \c value and \c valuelen. - */ - bool SDES_GetNextPrivateValue(uint8_t **prefix,size_t *prefixlen,uint8_t **value,size_t *valuelen) { return SDESinf.GetNextPrivateValue(prefix,prefixlen,value,valuelen); } + /** Starts the iteration over the stored SDES private item prefixes and their associated values. */ + void SDES_GotoFirstPrivateValue() { SDESinf.GotoFirstPrivateValue(); } - /** Looks for the entry which corresponds to the SDES private item prefix \c prefix with length - * \c prefixlen; if found, the function returns \c true and stores the associated value and - * its length in \c value and \c valuelen respectively. - */ - bool SDES_GetPrivateValue(uint8_t *prefix,size_t prefixlen,uint8_t **value,size_t *valuelen) const { return SDESinf.GetPrivateValue(prefix,prefixlen,value,valuelen); } + /** If available, returns \c true and stores the next SDES private item prefix in \c prefix and its length in + * \c prefixlen; the associated value and its length are then stored in \c value and \c valuelen. + */ + bool SDES_GetNextPrivateValue(uint8_t **prefix,size_t *prefixlen,uint8_t **value,size_t *valuelen) { return SDESinf.GetNextPrivateValue(prefix,prefixlen,value,valuelen); } + + /** Looks for the entry which corresponds to the SDES private item prefix \c prefix with length + * \c prefixlen; if found, the function returns \c true and stores the associated value and + * its length in \c value and \c valuelen respectively. + */ + bool SDES_GetPrivateValue(uint8_t *prefix,size_t prefixlen,uint8_t **value,size_t *valuelen) const { return SDESinf.GetPrivateValue(prefix,prefixlen,value,valuelen); } #endif // RTP_SUPPORT_SDESPRIV #ifdef RTPDEBUG - virtual void Dump(); + virtual void Dump(); #endif // RTPDEBUG protected: - std::list packetlist; + std::list packetlist; - uint32_t ssrc; - bool ownssrc; - bool iscsrc; - double timestampunit; - bool receivedbye; - bool validated; - bool processedinrtcp; - bool issender; - - RTCPSenderReportInfo SRinf,SRprevinf; - RTCPReceiverReportInfo RRinf,RRprevinf; - RTPSourceStats stats; - RTCPSDESInfo SDESinf; - - bool isrtpaddrset,isrtcpaddrset; - RTPAddress *rtpaddr,*rtcpaddr; - - RTPTime byetime; - uint8_t *byereason; - size_t byereasonlen; + uint32_t ssrc; + bool ownssrc; + bool iscsrc; + double timestampunit; + bool receivedbye; + bool validated; + bool processedinrtcp; + bool issender; + + RTCPSenderReportInfo SRinf,SRprevinf; + RTCPReceiverReportInfo RRinf,RRprevinf; + RTPSourceStats stats; + RTCPSDESInfo SDESinf; + + bool isrtpaddrset,isrtcpaddrset; + RTPAddress *rtpaddr,*rtcpaddr; + + RTPTime byetime; + uint8_t *byereason; + size_t byereasonlen; }; inline RTPPacket *RTPSourceData::GetNextPacket() { - if (!validated) - return 0; + if (!validated) + return 0; - RTPPacket *p; + RTPPacket *p; - if (packetlist.empty()) - return 0; - p = *(packetlist.begin()); - packetlist.pop_front(); - return p; + if (packetlist.empty()) + return 0; + p = *(packetlist.begin()); + packetlist.pop_front(); + return p; } inline void RTPSourceData::FlushPackets() { - std::list::const_iterator it; + std::list::const_iterator it; - for (it = packetlist.begin() ; it != packetlist.end() ; ++it) - RTPDelete(*it,GetMemoryManager()); - packetlist.clear(); + for (it = packetlist.begin() ; it != packetlist.end() ; ++it) + RTPDelete(*it,GetMemoryManager()); + packetlist.clear(); } } // end namespace diff --git a/src/libs/jrtplib/src/rtpsources.cpp b/src/libs/jrtplib/src/rtpsources.cpp index d8e7bbd7..5e1bcd09 100644 --- a/src/libs/jrtplib/src/rtpsources.cpp +++ b/src/libs/jrtplib/src/rtpsources.cpp @@ -809,7 +809,9 @@ int RTPSources::ObtainSourceDataInstance(uint32_t ssrc,RTPInternalSourceData **s #endif // RTP_SUPPORT_PROBATION if (srcdat2 == 0) return ERR_RTP_OUTOFMEM; - if ((status = sourcelist.AddElement(ssrc,srcdat2)) < 0) + + // Add new source item + if ((status = sourcelist.AddElement(ssrc,srcdat2)) < 0) { RTPDelete(srcdat2,GetMemoryManager()); return status;