From af6f15c1bf11bdf3676e9017133c592a2b13593a Mon Sep 17 00:00:00 2001 From: "pwestin@webrtc.org" Date: Thu, 19 Jan 2012 15:53:59 +0000 Subject: [PATCH] Changed RTP reveivers to use stl map and list. Review URL: https://webrtc-codereview.appspot.com/349010 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1475 4adac7df-926f-26a2-2b94-8c16560cd09d --- src/modules/rtp_rtcp/source/rtp_receiver.cc | 1122 ++++++++--------- src/modules/rtp_rtcp/source/rtp_receiver.h | 5 +- .../rtp_rtcp/source/rtp_receiver_audio.cc | 49 +- .../rtp_rtcp/source/rtp_receiver_audio.h | 7 +- .../rtp_rtcp/source/rtp_receiver_video.h | 6 +- 5 files changed, 551 insertions(+), 638 deletions(-) diff --git a/src/modules/rtp_rtcp/source/rtp_receiver.cc b/src/modules/rtp_rtcp/source/rtp_receiver.cc index 159f0ccfc9..c5c7e9e6b4 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver.cc +++ b/src/modules/rtp_rtcp/source/rtp_receiver.cc @@ -21,6 +21,14 @@ #include // abs namespace webrtc { + +using ModuleRTPUtility::AudioPayload; +using ModuleRTPUtility::GetCurrentRTP; +using ModuleRTPUtility::Payload; +using ModuleRTPUtility::RTPPayloadParser; +using ModuleRTPUtility::StringCompare; +using ModuleRTPUtility::VideoPayload; + RTPReceiver::RTPReceiver(const WebRtc_Word32 id, const bool audio, RtpRtcpClock* clock, @@ -98,112 +106,82 @@ RTPReceiver::RTPReceiver(const WebRtc_Word32 id, WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__); } -RTPReceiver::~RTPReceiver() -{ - if(_cbRtpFeedback) - { - for(int i = 0; i < _numCSRCs; i++) - { - _cbRtpFeedback->OnIncomingCSRCChanged(_id,_currentRemoteCSRC[i], false); - } +RTPReceiver::~RTPReceiver() { + if (_cbRtpFeedback) { + for (int i = 0; i < _numCSRCs; i++) { + _cbRtpFeedback->OnIncomingCSRCChanged(_id,_currentRemoteCSRC[i], false); } - delete _criticalSectionCbs; - delete _criticalSectionRTPReceiver; + } + delete _criticalSectionCbs; + delete _criticalSectionRTPReceiver; - // empty map - bool loop = true; - do - { - MapItem* item = _payloadTypeMap.First(); - if(item) - { - // delete - ModuleRTPUtility::Payload* payload= ((ModuleRTPUtility::Payload*)item->GetItem()); - delete payload; - - // remove from map and delete Item - _payloadTypeMap.Erase(item); - } else - { - loop = false; - } - } while (loop); - - WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__); + while (!_payloadTypeMap.empty()) { + std::map::iterator it = _payloadTypeMap.begin(); + delete it->second; + _payloadTypeMap.erase(it); + } + WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__); } -WebRtc_Word32 -RTPReceiver::Init() -{ - CriticalSectionScoped lock(_criticalSectionRTPReceiver); +WebRtc_Word32 RTPReceiver::Init() { + CriticalSectionScoped lock(_criticalSectionRTPReceiver); - _lastReceiveTime = 0; - _lastReceivedPayloadLength = 0; - _packetTimeOutMS = 0; - _lastReceivedPayloadType = -1; - _lastReceivedMediaPayloadType = -1; - _redPayloadType = -1; + _lastReceiveTime = 0; + _lastReceivedPayloadLength = 0; + _packetTimeOutMS = 0; + _lastReceivedPayloadType = -1; + _lastReceivedMediaPayloadType = -1; + _redPayloadType = -1; - memset(&_lastReceivedAudioSpecific, 0, sizeof(_lastReceivedAudioSpecific)); - _lastReceivedAudioSpecific.channels = 1; + memset(&_lastReceivedAudioSpecific, 0, sizeof(_lastReceivedAudioSpecific)); + _lastReceivedAudioSpecific.channels = 1; - _lastReceivedVideoSpecific.videoCodecType = kRtpNoVideo; - _lastReceivedVideoSpecific.maxRate = 0; - _SSRC = 0; - _numCSRCs = 0; - _numEnergy = 0; - _jitterQ4 = 0; - _jitterMaxQ4 = 0; - _cumulativeLoss = 0; - _jitterQ4TransmissionTimeOffset = 0; - _useSSRCFilter = false; - _SSRCFilter = 0; + _lastReceivedVideoSpecific.videoCodecType = kRtpNoVideo; + _lastReceivedVideoSpecific.maxRate = 0; + _SSRC = 0; + _numCSRCs = 0; + _numEnergy = 0; + _jitterQ4 = 0; + _jitterMaxQ4 = 0; + _cumulativeLoss = 0; + _jitterQ4TransmissionTimeOffset = 0; + _useSSRCFilter = false; + _SSRCFilter = 0; - _localTimeLastReceivedTimestamp = 0; - _lastReceivedTimestamp = 0; - _lastReceivedSequenceNumber = 0; - _lastReceivedTransmissionTimeOffset = 0; + _localTimeLastReceivedTimestamp = 0; + _lastReceivedTimestamp = 0; + _lastReceivedSequenceNumber = 0; + _lastReceivedTransmissionTimeOffset = 0; - _receivedSeqFirst = 0; - _receivedSeqMax = 0; - _receivedSeqWraps = 0; + _receivedSeqFirst = 0; + _receivedSeqMax = 0; + _receivedSeqWraps = 0; - _receivedPacketOH = 12; // RTP header - _receivedByteCount = 0; - _receivedOldPacketCount = 0; - _receivedInorderPacketCount = 0; + _receivedPacketOH = 12; // RTP header + _receivedByteCount = 0; + _receivedOldPacketCount = 0; + _receivedInorderPacketCount = 0; - _lastReportInorderPackets = 0; - _lastReportOldPackets = 0; - _lastReportSeqMax = 0; - _lastReportFractionLost = 0; - _lastReportCumulativeLost = 0; - _lastReportExtendedHighSeqNum = 0; - _lastReportJitter = 0; - _lastReportJitterTransmissionTimeOffset = 0; + _lastReportInorderPackets = 0; + _lastReportOldPackets = 0; + _lastReportSeqMax = 0; + _lastReportFractionLost = 0; + _lastReportCumulativeLost = 0; + _lastReportExtendedHighSeqNum = 0; + _lastReportJitter = 0; + _lastReportJitterTransmissionTimeOffset = 0; - _rtpHeaderExtensionMap.Erase(); + _rtpHeaderExtensionMap.Erase(); - // clear db - bool loop = true; - do - { - MapItem* item = _payloadTypeMap.First(); - if(item) - { - ModuleRTPUtility::Payload* payload= ((ModuleRTPUtility::Payload*)item->GetItem()); - delete payload; - // remove from map - _payloadTypeMap.Erase(item); - } else - { - loop = false; - } - } while (loop); + while (!_payloadTypeMap.empty()) { + std::map::iterator it = _payloadTypeMap.begin(); + delete it->second; + _payloadTypeMap.erase(it); + } - Bitrate::Init(); - RTPReceiverAudio::Init(); - return RTPReceiverVideo::Init(); + Bitrate::Init(); + RTPReceiverAudio::Init(); + return RTPReceiverVideo::Init(); } void @@ -369,160 +347,149 @@ RTPReceiver::RegisterIncomingDataCallback(RtpData* incomingDataCallback) return 0; } -WebRtc_Word32 -RTPReceiver::RegisterReceivePayload( const WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], - const WebRtc_Word8 payloadType, - const WebRtc_UWord32 frequency, - const WebRtc_UWord8 channels, - const WebRtc_UWord32 rate) -{ - if(payloadName == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); - return -1; +WebRtc_Word32 RTPReceiver::RegisterReceivePayload( + const WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], + const WebRtc_Word8 payloadType, + const WebRtc_UWord32 frequency, + const WebRtc_UWord8 channels, + const WebRtc_UWord32 rate) { + assert(payloadName); + CriticalSectionScoped lock(_criticalSectionRTPReceiver); + + // sanity + switch (payloadType) { + // reserved payload types to avoid RTCP conflicts when marker bit is set + case 64: // 192 Full INTRA-frame request + case 72: // 200 Sender report + case 73: // 201 Receiver report + case 74: // 202 Source description + case 75: // 203 Goodbye + case 76: // 204 Application-defined + case 77: // 205 Transport layer FB message + case 78: // 206 Payload-specific FB message + case 79: // 207 Extended report + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "%s invalid payloadtype:%d", + __FUNCTION__, payloadType); + return -1; + default: + break; + } + size_t payloadNameLength = strlen(payloadName); + + std::map::iterator it = + _payloadTypeMap.find(payloadType); + if (it != _payloadTypeMap.end()) { + // we already use this payload type + Payload* payload = it->second; + assert(payload); + + size_t nameLength = strlen(payload->name); + + // check if it's the same as we already have + // if same ignore sending an error + if (payloadNameLength == nameLength && + StringCompare(payload->name, payloadName, payloadNameLength)) { + if (_audio && + payload->audio && + payload->typeSpecific.Audio.frequency == frequency && + payload->typeSpecific.Audio.channels == channels && + (payload->typeSpecific.Audio.rate == rate || + payload->typeSpecific.Audio.rate == 0 || rate == 0)) { + payload->typeSpecific.Audio.rate = rate; + // Ensure that we update the rate if new or old is zero + return 0; + } + if (!_audio && !payload->audio) { + // update maxBitrate for video + payload->typeSpecific.Video.maxRate = rate; + return 0; + } } + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "%s invalid argument payloadType:%d already registered", + __FUNCTION__, payloadType); + return -1; + } + if (_audio) { + // remove existing item, hence search for the name + // only for audio, for video we allow a codecs to use multiple pltypes + std::map::iterator audio_it = + _payloadTypeMap.begin(); + while (audio_it != _payloadTypeMap.end()) { + Payload* payload = audio_it->second; + size_t nameLength = strlen(payload->name); - CriticalSectionScoped lock(_criticalSectionRTPReceiver); - - // sanity - switch(payloadType) - { - // reserved payload types to avoid RTCP conflicts when marker bit is set - case 64: // 192 Full INTRA-frame request - case 72: // 200 Sender report - case 73: // 201 Receiver report - case 74: // 202 Source description - case 75: // 203 Goodbye - case 76: // 204 Application-defined - case 77: // 205 Transport layer FB message - case 78: // 206 Payload-specific FB message - case 79: // 207 Extended report - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid payloadtype:%d", __FUNCTION__, payloadType); - return -1; - default: + if (payloadNameLength == nameLength && + StringCompare(payload->name, payloadName, payloadNameLength)) { + // we found the payload name in the list + // if audio check frequency and rate + if (payload->audio) { + if (payload->typeSpecific.Audio.frequency == frequency && + (payload->typeSpecific.Audio.rate == rate || + payload->typeSpecific.Audio.rate == 0 || rate == 0)) { + // remove old setting + delete payload; + _payloadTypeMap.erase(audio_it); break; - } - WebRtc_Word32 payloadNameLength = (WebRtc_Word32)strlen(payloadName); - - MapItem* item = NULL; - item = _payloadTypeMap.Find(payloadType); - if( NULL != item) - { - // we already use this payload type - - ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); - assert(payload); - - WebRtc_Word32 nameLength = (WebRtc_Word32)strlen(payload->name); - - // check if it's the same as we already have - // if same ignore sending an error - if(payloadNameLength == nameLength && ModuleRTPUtility::StringCompare(payload->name, payloadName, payloadNameLength)) - { - if(_audio && - payload->audio && - payload->typeSpecific.Audio.frequency == frequency && - payload->typeSpecific.Audio.channels == channels && - (payload->typeSpecific.Audio.rate == rate || payload->typeSpecific.Audio.rate == 0 || rate == 0)) - { - payload->typeSpecific.Audio.rate = rate; // Ensure that we update the rate if new or old is zero - return 0; - } - if(!_audio && !payload->audio) - { - // update maxBitrate for video - payload->typeSpecific.Video.maxRate = rate; - return 0; - } + } + } else if(StringCompare(payloadName,"red",3)) { + delete payload; + _payloadTypeMap.erase(audio_it); + break; } - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument payloadType:%d already registered", __FUNCTION__, payloadType); - return -1; + } + audio_it++; } + } + Payload* payload = NULL; - if(_audio) - { - // remove existing item, hence search for the name - // only for audio, for video we allow a codecs to use multiple pltypes - item = _payloadTypeMap.First(); - while(item) - { - ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); - WebRtc_Word32 nameLength = (WebRtc_Word32)strlen(payload->name); - - if(payloadNameLength == nameLength && ModuleRTPUtility::StringCompare(payload->name, payloadName, payloadNameLength)) - { - // we found the payload name in the list - // if audio check frequency and rate - if( payload->audio) - { - if(payload->typeSpecific.Audio.frequency == frequency && - (payload->typeSpecific.Audio.rate == rate || payload->typeSpecific.Audio.rate == 0 || rate == 0)) - { - // remove old setting - delete payload; - _payloadTypeMap.Erase(item); - break; - } - } else if(ModuleRTPUtility::StringCompare(payloadName,"red",3)) - { - delete payload; - _payloadTypeMap.Erase(item); - break; - } - } - item = _payloadTypeMap.Next(item); - } + // save the RED payload type + // used in both audio and video + if (StringCompare(payloadName,"red",3)) { + _redPayloadType = payloadType; + payload = new Payload; + payload->audio = false; + memcpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE); + } else { + if (_audio) { + payload = RegisterReceiveAudioPayload(payloadName, payloadType, + frequency, channels, rate); + } else { + payload = RegisterReceiveVideoPayload(payloadName, payloadType, rate); } + } + if (payload == NULL) { + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "%s filed to register payload", + __FUNCTION__); + return -1; + } + _payloadTypeMap[payloadType] = payload; - ModuleRTPUtility::Payload* payload = NULL; - - // save the RED payload type - // used in both audio and video - if(ModuleRTPUtility::StringCompare(payloadName,"red",3)) - { - _redPayloadType = payloadType; - payload = new ModuleRTPUtility::Payload; - payload->audio = false; - memcpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE); - } else - { - if(_audio) - { - payload = RegisterReceiveAudioPayload(payloadName, payloadType, frequency, channels, rate); - } else - { - payload = RegisterReceiveVideoPayload(payloadName, payloadType, rate); - } - if(payload == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s filed to register payload", __FUNCTION__); - return -1; - } - } - _payloadTypeMap.Insert(payloadType, payload); - - // Successful set of payload type, clear the value of last receivedPT, since it might mean something else - _lastReceivedPayloadType = -1; - _lastReceivedMediaPayloadType = -1; - return 0; + // Successful set of payload type, clear the value of last receivedPT, + // since it might mean something else + _lastReceivedPayloadType = -1; + _lastReceivedMediaPayloadType = -1; + return 0; } -WebRtc_Word32 -RTPReceiver::DeRegisterReceivePayload(const WebRtc_Word8 payloadType) -{ - CriticalSectionScoped lock(_criticalSectionRTPReceiver); +WebRtc_Word32 RTPReceiver::DeRegisterReceivePayload( + const WebRtc_Word8 payloadType) { + CriticalSectionScoped lock(_criticalSectionRTPReceiver); - MapItem* item = _payloadTypeMap.Find(payloadType); - if( NULL != item) - { - ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); - delete payload; + std::map::iterator it = + _payloadTypeMap.find(payloadType); - _payloadTypeMap.Erase(item); - return 0; - } - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s failed to find payloadType:%d", __FUNCTION__, payloadType); + if (it == _payloadTypeMap.end()) { + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "%s failed to find payloadType:%d", + __FUNCTION__, payloadType); return -1; + } + delete it->second; + _payloadTypeMap.erase(it); + return 0; } WebRtc_Word32 RTPReceiver::ReceivePayloadType( @@ -530,167 +497,139 @@ WebRtc_Word32 RTPReceiver::ReceivePayloadType( const WebRtc_UWord32 frequency, const WebRtc_UWord8 channels, const WebRtc_UWord32 rate, - WebRtc_Word8* payloadType) const -{ - if(payloadType == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__); - return -1; - } - - WebRtc_Word32 payloadNameLength = (WebRtc_Word32)strlen(payloadName); - - CriticalSectionScoped lock(_criticalSectionRTPReceiver); - - MapItem* item = _payloadTypeMap.First(); - while( NULL != item) - { - ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); - assert(payload); - - WebRtc_Word32 nameLength = (WebRtc_Word32)strlen(payload->name); - if(payloadNameLength == nameLength && ModuleRTPUtility::StringCompare(payload->name, payloadName, payloadNameLength)) - { - // name match - if(payload->audio) - { - if (rate == 0) - { - // [default] audio, check freq and channels - if( payload->typeSpecific.Audio.frequency == frequency && - payload->typeSpecific.Audio.channels == channels) - { - *payloadType = item->GetId(); - return 0; - } - } - else - { - // audio, check freq, channels and rate - if( payload->typeSpecific.Audio.frequency == frequency && - payload->typeSpecific.Audio.channels == channels && - payload->typeSpecific.Audio.rate == rate) // extra rate condition added - { - *payloadType = item->GetId(); - return 0; - } - } - } else - { - // video - *payloadType = item->GetId(); - return 0; - } - } - item = _payloadTypeMap.Next(item); - } + WebRtc_Word8* payloadType) const { + if (payloadType == NULL) { + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "%s invalid argument", __FUNCTION__); return -1; -} + } + size_t payloadNameLength = strlen(payloadName); -WebRtc_Word32 -RTPReceiver::ReceivePayload(const WebRtc_Word8 payloadType, - WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], - WebRtc_UWord32* frequency, - WebRtc_UWord8* channels, - WebRtc_UWord32* rate) const -{ - CriticalSectionScoped lock(_criticalSectionRTPReceiver); + CriticalSectionScoped lock(_criticalSectionRTPReceiver); - MapItem* item = _payloadTypeMap.Find(payloadType); - if( NULL == item) - { - return -1; - } - ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); + std::map::const_iterator it = + _payloadTypeMap.begin(); + + while (it != _payloadTypeMap.end()) { + Payload* payload = it->second; assert(payload); - if(frequency) - { - if(payload->audio) - { - *frequency = payload->typeSpecific.Audio.frequency; - } else - { - *frequency = 90000; + size_t nameLength = strlen(payload->name); + if (payloadNameLength == nameLength && + StringCompare(payload->name, payloadName, payloadNameLength)) { + // name match + if( payload->audio) { + if (rate == 0) { + // [default] audio, check freq and channels + if (payload->typeSpecific.Audio.frequency == frequency && + payload->typeSpecific.Audio.channels == channels) { + *payloadType = it->first; + return 0; + } + } else { + // audio, check freq, channels and rate + if( payload->typeSpecific.Audio.frequency == frequency && + payload->typeSpecific.Audio.channels == channels && + payload->typeSpecific.Audio.rate == rate) { + // extra rate condition added + *payloadType = it->first; + return 0; + } } + } else { + // video + *payloadType = it->first; + return 0; + } } - if(channels) - { - if(payload->audio) - { - *channels = payload->typeSpecific.Audio.channels; - } else - { - *channels = 1; - } - } - if (rate) - { - if(payload->audio) - { - *rate = payload->typeSpecific.Audio.rate; - } else - { - assert(false); - *rate = 0; - } - } - if(payloadName) - { - memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE); - } - return 0; + it++; + } + return -1; } -WebRtc_Word32 -RTPReceiver::RemotePayload(WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], - WebRtc_Word8* payloadType, - WebRtc_UWord32* frequency, - WebRtc_UWord8* channels) const -{ - if(_lastReceivedPayloadType == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__); - return -1; - } - memset(payloadName, 0, RTP_PAYLOAD_NAME_SIZE); +WebRtc_Word32 RTPReceiver::ReceivePayload( + const WebRtc_Word8 payloadType, + WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], + WebRtc_UWord32* frequency, + WebRtc_UWord8* channels, + WebRtc_UWord32* rate) const { + CriticalSectionScoped lock(_criticalSectionRTPReceiver); - MapItem* item = _payloadTypeMap.Find(_lastReceivedPayloadType); - if( NULL != item) - { - ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); - if(payload) - { - memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); + std::map::const_iterator it = + _payloadTypeMap.find(payloadType); - if(payloadType ) - { - *payloadType = _lastReceivedPayloadType; - } - if(frequency) - { - if(payload->audio) - { - *frequency = payload->typeSpecific.Audio.frequency; - } else - { - *frequency = 90000; - } - } - if(channels) - { - if(payload->audio) - { - *channels = payload->typeSpecific.Audio.channels; - } else - { - *channels = 1; - } - } - return 0; - } - } + if (it == _payloadTypeMap.end()) { return -1; + } + Payload* payload = it->second; + assert(payload); + + if(frequency) { + if(payload->audio) { + *frequency = payload->typeSpecific.Audio.frequency; + } else { + *frequency = 90000; + } + } + if (channels) { + if(payload->audio) { + *channels = payload->typeSpecific.Audio.channels; + } else { + *channels = 1; + } + } + if (rate) { + if(payload->audio) { + *rate = payload->typeSpecific.Audio.rate; + } else { + assert(false); + *rate = 0; + } + } + if (payloadName) { + memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE); + } + return 0; +} + +WebRtc_Word32 RTPReceiver::RemotePayload( + WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], + WebRtc_Word8* payloadType, + WebRtc_UWord32* frequency, + WebRtc_UWord8* channels) const { + if(_lastReceivedPayloadType == -1) { + WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__); + return -1; + } + std::map::const_iterator it = + _payloadTypeMap.find(_lastReceivedPayloadType); + + if (it == _payloadTypeMap.end()) { + return -1; + } + Payload* payload = it->second; + assert(payload); + payloadName[RTP_PAYLOAD_NAME_SIZE - 1] = 0; + memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); + + if (payloadType) { + *payloadType = _lastReceivedPayloadType; + } + if (frequency) { + if (payload->audio) { + *frequency = payload->typeSpecific.Audio.frequency; + } else { + *frequency = 90000; + } + } + if (channels) { + if (payload->audio) { + *channels = payload->typeSpecific.Audio.channels; + } else { + *channels = 1; + } + } + return 0; } WebRtc_Word32 @@ -836,11 +775,11 @@ WebRtc_Word32 RTPReceiver::IncomingRTPPacket( CheckSSRCChanged(rtp_header); bool is_red = false; - ModuleRTPUtility::VideoPayload video_specific; + VideoPayload video_specific; video_specific.maxRate = 0; video_specific.videoCodecType = kRtpNoVideo; - ModuleRTPUtility::AudioPayload audio_specific; + AudioPayload audio_specific; audio_specific.bitsPerSample = 0; audio_specific.channels = 0; audio_specific.frequency = 0; @@ -955,7 +894,7 @@ RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtpHeader, _receivedSeqMax = rtpHeader->header.sequenceNumber; _receivedInorderPacketCount = 1; _localTimeLastReceivedTimestamp = - ModuleRTPUtility::GetCurrentRTP(&_clock, freq); //time in samples + GetCurrentRTP(&_clock, freq); //time in samples return; } @@ -963,7 +902,7 @@ RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtpHeader, if(InOrderPacket(rtpHeader->header.sequenceNumber)) { const WebRtc_UWord32 RTPtime = - ModuleRTPUtility::GetCurrentRTP(&_clock, freq); //time in samples + GetCurrentRTP(&_clock, freq); //time in samples _receivedInorderPacketCount++; // wrong if we use RetransmitOfOldPacket @@ -1110,28 +1049,21 @@ RTPReceiver::TimeStamp() const return _lastReceivedTimestamp; } -WebRtc_UWord32 -RTPReceiver::PayloadTypeToPayload(const WebRtc_UWord8 payloadType, - ModuleRTPUtility::Payload*& payload) const -{ - MapItem* item = _payloadTypeMap.Find(payloadType); +WebRtc_UWord32 RTPReceiver::PayloadTypeToPayload( + const WebRtc_UWord8 payloadType, + Payload*& payload) const { - // check that this is a registered payload type - if(item == NULL) - { - return -1; - } + std::map::const_iterator it = + _payloadTypeMap.find(payloadType); - payload = (ModuleRTPUtility::Payload*)item->GetItem(); - if(payload == NULL) - { - return -1; - } - - return 0; + // check that this is a registered payload type + if (it == _payloadTypeMap.end()) { + return -1; + } + payload = it->second; + return 0; } - // timeStamp of the last incoming packet that is the first packet of its frame WebRtc_Word32 RTPReceiver::EstimatedRemoteTimeStamp(WebRtc_UWord32& timestamp) const @@ -1148,7 +1080,7 @@ RTPReceiver::EstimatedRemoteTimeStamp(WebRtc_UWord32& timestamp) const return -1; } //time in samples - WebRtc_UWord32 diff = ModuleRTPUtility::GetCurrentRTP(&_clock, freq) + WebRtc_UWord32 diff = GetCurrentRTP(&_clock, freq) - _localTimeLastReceivedTimestamp; timestamp = _lastReceivedTimestamp + diff; @@ -1187,225 +1119,207 @@ RTPReceiver::SetSSRCFilter(const bool enable, const WebRtc_UWord32 allowedSSRC) } // no criticalsection when called -void -RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader) -{ - bool newSSRC = false; - bool reInitializeDecoder = false; - WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE]; - WebRtc_UWord32 frequency = 90000; // default video freq - WebRtc_UWord8 channels = 1; - WebRtc_UWord32 rate = 0; - memset(payloadName, 0, sizeof(payloadName)); +void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader) { + bool newSSRC = false; + bool reInitializeDecoder = false; + WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE]; + WebRtc_UWord32 frequency = 90000; // default video freq + WebRtc_UWord8 channels = 1; + WebRtc_UWord32 rate = 0; + memset(payloadName, 0, sizeof(payloadName)); - { - CriticalSectionScoped lock(_criticalSectionRTPReceiver); + { + CriticalSectionScoped lock(_criticalSectionRTPReceiver); - if (_SSRC != rtpHeader->header.ssrc || (_lastReceivedPayloadType == -1 && _SSRC == 0)) // we need the _payloadType to make the call if the remote SSRC is 0 - { - newSSRC = true; + if (_SSRC != rtpHeader->header.ssrc || + (_lastReceivedPayloadType == -1 && _SSRC == 0)) { + // we need the _payloadType to make the call if the remote SSRC is 0 + newSSRC = true; - // reset last report - ResetStatistics(); - RTPReceiverVideo::ResetOverUseDetector(); + // reset last report + ResetStatistics(); + RTPReceiverVideo::ResetOverUseDetector(); - _lastReceivedTimestamp = 0; - _lastReceivedSequenceNumber = 0; - _lastReceivedTransmissionTimeOffset = 0; + _lastReceivedTimestamp = 0; + _lastReceivedSequenceNumber = 0; + _lastReceivedTransmissionTimeOffset = 0; - if (_SSRC) // do we have a SSRC? then the stream is restarted - { - // if we have the same codec? reinit decoder - if (rtpHeader->header.payloadType == _lastReceivedPayloadType) - { - reInitializeDecoder = true; + if (_SSRC) { // do we have a SSRC? then the stream is restarted + // if we have the same codec? reinit decoder + if (rtpHeader->header.payloadType == _lastReceivedPayloadType) { + reInitializeDecoder = true; - MapItem* item = _payloadTypeMap.Find(rtpHeader->header.payloadType); - if( NULL != item) - { - ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); - if(payload) - { - memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); - if(payload->audio) - { - frequency = payload->typeSpecific.Audio.frequency; - channels = payload->typeSpecific.Audio.channels; - rate = payload->typeSpecific.Audio.rate; - } else - { - frequency = 90000; - } - } - } - } - } - _SSRC = rtpHeader->header.ssrc; + std::map::iterator it = + _payloadTypeMap.find(rtpHeader->header.payloadType); + + if (it == _payloadTypeMap.end()) { + return; + } + Payload* payload = it->second; + assert(payload); + payloadName[RTP_PAYLOAD_NAME_SIZE - 1] = 0; + memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); + if(payload->audio) { + frequency = payload->typeSpecific.Audio.frequency; + channels = payload->typeSpecific.Audio.channels; + rate = payload->typeSpecific.Audio.rate; + } else { + frequency = 90000; + } } + } + _SSRC = rtpHeader->header.ssrc; } - if(newSSRC) - { - // we need to get this to our RTCP sender and receiver - // need to do this outside critical section - _rtpRtcp.SetRemoteSSRC(rtpHeader->header.ssrc); + } + if(newSSRC) { + // we need to get this to our RTCP sender and receiver + // need to do this outside critical section + _rtpRtcp.SetRemoteSSRC(rtpHeader->header.ssrc); + } + CriticalSectionScoped lock(_criticalSectionCbs); + if(_cbRtpFeedback) { + if(newSSRC) { + _cbRtpFeedback->OnIncomingSSRCChanged(_id, rtpHeader->header.ssrc); } - - CriticalSectionScoped lock(_criticalSectionCbs); - if(_cbRtpFeedback) - { - if(newSSRC) - { - _cbRtpFeedback->OnIncomingSSRCChanged(_id, rtpHeader->header.ssrc); - } - if(reInitializeDecoder) - { - if(-1 == _cbRtpFeedback->OnInitializeDecoder(_id, rtpHeader->header.payloadType, payloadName, frequency, channels, rate)) // new stream same codec - { - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "Failed to create decoder for payload type:%d", rtpHeader->header.payloadType); - } - } + if(reInitializeDecoder) { + if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, + rtpHeader->header.payloadType, payloadName, frequency, channels, + rate)) { // new stream same codec + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "Failed to create decoder for payload type:%d", + rtpHeader->header.payloadType); + } } + } } // no criticalsection when called -WebRtc_Word32 -RTPReceiver::CheckPayloadChanged(const WebRtcRTPHeader* rtpHeader, - const WebRtc_Word8 firstPayloadByte, - bool& isRED, - ModuleRTPUtility::AudioPayload& audioSpecificPayload, - ModuleRTPUtility::VideoPayload& videoSpecificPayload) -{ - bool reInitializeDecoder = false; +WebRtc_Word32 RTPReceiver::CheckPayloadChanged( + const WebRtcRTPHeader* rtpHeader, + const WebRtc_Word8 firstPayloadByte, + bool& isRED, + AudioPayload& audioSpecificPayload, + VideoPayload& videoSpecificPayload) { + bool reInitializeDecoder = false; - WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE]; - WebRtc_Word8 payloadType = rtpHeader->header.payloadType; + WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE]; + WebRtc_Word8 payloadType = rtpHeader->header.payloadType; - { - CriticalSectionScoped lock(_criticalSectionRTPReceiver); + { + CriticalSectionScoped lock(_criticalSectionRTPReceiver); - if (payloadType != _lastReceivedPayloadType) - { - if (REDPayloadType(payloadType)) - { - // get the real codec payload type - payloadType = firstPayloadByte & 0x7f; - isRED = true; + if (payloadType != _lastReceivedPayloadType) { + if (REDPayloadType(payloadType)) { + // get the real codec payload type + payloadType = firstPayloadByte & 0x7f; + isRED = true; - //when we receive RED we need to check the real payload type - if (payloadType == _lastReceivedPayloadType) - { - if(_audio) - { - memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific, sizeof(_lastReceivedAudioSpecific)); - } else - { - memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific, sizeof(_lastReceivedVideoSpecific)); - } - return 0; - } - } - if(_audio) - { - if(TelephoneEventPayloadType(payloadType)) - { - // don't do callbacks for DTMF packets - isRED = false; - return 0; - } - - // frequency is updated for CNG - if(CNGPayloadType(payloadType, audioSpecificPayload.frequency)) - { - // don't do callbacks for DTMF packets - isRED = false; - return 0; - } - } - MapItem* item = _payloadTypeMap.Find(payloadType); - - // check that this is a registered payload type - if(item == NULL) - { - return -1; - } - memset(payloadName, 0, sizeof(payloadName)); - - ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); - if(payload == NULL) - { - return -1; - } - - memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); - _lastReceivedPayloadType = payloadType; - - reInitializeDecoder = true; - - if(payload->audio) - { - memcpy(&_lastReceivedAudioSpecific, &(payload->typeSpecific.Audio), sizeof(_lastReceivedAudioSpecific)); - memcpy(&audioSpecificPayload, &(payload->typeSpecific.Audio), sizeof(_lastReceivedAudioSpecific)); - }else - { - memcpy(&_lastReceivedVideoSpecific, &(payload->typeSpecific.Video), sizeof(_lastReceivedVideoSpecific)); - memcpy(&videoSpecificPayload, &(payload->typeSpecific.Video), sizeof(_lastReceivedVideoSpecific)); - - if (_lastReceivedVideoSpecific.videoCodecType == kRtpFecVideo) - { - // Only reset the decoder on media packets. - reInitializeDecoder = false; - } - else - { - if (_lastReceivedMediaPayloadType == _lastReceivedPayloadType) - { - // Only reset the decoder if the media codec type has changed. - reInitializeDecoder = false; - } - _lastReceivedMediaPayloadType = _lastReceivedPayloadType; - } - } - if(reInitializeDecoder) - { - // reset statistics - ResetStatistics(); - } - }else - { - if(_audio) - { - memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific, sizeof(_lastReceivedAudioSpecific)); - } else - { - memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific, sizeof(_lastReceivedVideoSpecific)); - } - isRED = false; + //when we receive RED we need to check the real payload type + if (payloadType == _lastReceivedPayloadType) { + if(_audio) + { + memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific, + sizeof(_lastReceivedAudioSpecific)); + } else { + memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific, + sizeof(_lastReceivedVideoSpecific)); + } + return 0; } - } // end critsect - if(reInitializeDecoder) - { - CriticalSectionScoped lock(_criticalSectionCbs); - if(_cbRtpFeedback) - { - // create new decoder instance - if(_audio) - { - if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType, payloadName, audioSpecificPayload.frequency, audioSpecificPayload.channels, audioSpecificPayload.rate)) - { - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "Failed to create audio decoder for payload type:%d", payloadType); - return -1; // Wrong payload type - } - } else - { - if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType, payloadName, 90000, 1, 0)) - { - WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "Failed to create video decoder for payload type:%d", payloadType); - return -1; // Wrong payload type - } - } + } + if (_audio) { + if (TelephoneEventPayloadType(payloadType)) { + // don't do callbacks for DTMF packets + isRED = false; + return 0; } + // frequency is updated for CNG + if (CNGPayloadType(payloadType, audioSpecificPayload.frequency)) { + // don't do callbacks for DTMF packets + isRED = false; + return 0; + } + } + std::map::iterator it = + _payloadTypeMap.find(payloadType); + + // check that this is a registered payload type + if (it == _payloadTypeMap.end()) { + return -1; + } + Payload* payload = it->second; + assert(payload); + payloadName[RTP_PAYLOAD_NAME_SIZE - 1] = 0; + memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); + _lastReceivedPayloadType = payloadType; + + reInitializeDecoder = true; + + if(payload->audio) { + memcpy(&_lastReceivedAudioSpecific, &(payload->typeSpecific.Audio), + sizeof(_lastReceivedAudioSpecific)); + memcpy(&audioSpecificPayload, &(payload->typeSpecific.Audio), + sizeof(_lastReceivedAudioSpecific)); + } else { + memcpy(&_lastReceivedVideoSpecific, &(payload->typeSpecific.Video), + sizeof(_lastReceivedVideoSpecific)); + memcpy(&videoSpecificPayload, &(payload->typeSpecific.Video), + sizeof(_lastReceivedVideoSpecific)); + + if (_lastReceivedVideoSpecific.videoCodecType == kRtpFecVideo) + { + // Only reset the decoder on media packets. + reInitializeDecoder = false; + } else { + if (_lastReceivedMediaPayloadType == _lastReceivedPayloadType) { + // Only reset the decoder if the media codec type has changed. + reInitializeDecoder = false; + } + _lastReceivedMediaPayloadType = _lastReceivedPayloadType; + } + } + if (reInitializeDecoder) { + // reset statistics + ResetStatistics(); + } + } else { + if(_audio) + { + memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific, + sizeof(_lastReceivedAudioSpecific)); + } else + { + memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific, + sizeof(_lastReceivedVideoSpecific)); + } + isRED = false; } - return 0; + } // end critsect + if (reInitializeDecoder) { + CriticalSectionScoped lock(_criticalSectionCbs); + if (_cbRtpFeedback) { + // create new decoder instance + if(_audio) { + if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType, + payloadName, audioSpecificPayload.frequency, + audioSpecificPayload.channels, audioSpecificPayload.rate)) { + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "Failed to create audio decoder for payload type:%d", + payloadType); + return -1; // Wrong payload type + } + } else { + if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType, + payloadName, 90000, 1, 0)) { + WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, + "Failed to create video decoder for payload type:%d", + payloadType); + return -1; // Wrong payload type + } + } + } + } + return 0; } // no criticalsection when called diff --git a/src/modules/rtp_rtcp/source/rtp_receiver.h b/src/modules/rtp_rtcp/source/rtp_receiver.h index 32916c7677..142c6cf4ca 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver.h +++ b/src/modules/rtp_rtcp/source/rtp_receiver.h @@ -11,6 +11,8 @@ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_ +#include + #include "typedefs.h" #include "rtp_utility.h" @@ -208,8 +210,7 @@ private: WebRtc_Word8 _redPayloadType; - // - MapWrapper _payloadTypeMap; + std::map _payloadTypeMap; RtpHeaderExtensionMap _rtpHeaderExtensionMap; // SSRCs diff --git a/src/modules/rtp_rtcp/source/rtp_receiver_audio.cc b/src/modules/rtp_rtcp/source/rtp_receiver_audio.cc index cb75c9e3ee..b7eda91d26 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver_audio.cc +++ b/src/modules/rtp_rtcp/source/rtp_receiver_audio.cc @@ -24,7 +24,6 @@ RTPReceiverAudio::RTPReceiverAudio(const WebRtc_Word32 id): _telephoneEventForwardToDecoder(false), _telephoneEventDetectEndOfTone(false), _telephoneEventPayloadType(-1), - _telephoneEventReported(), _cngNBPayloadType(-1), _cngWBPayloadType(-1), _cngSWBPayloadType(-1), @@ -41,26 +40,22 @@ RTPReceiverAudio::~RTPReceiverAudio() delete _criticalSectionFeedback; } -WebRtc_Word32 -RTPReceiverAudio::Init() -{ - _lastReceivedFrequency = 8000; - _telephoneEvent = false; - _telephoneEventForwardToDecoder = false; - _telephoneEventDetectEndOfTone = false; - _telephoneEventPayloadType = -1; +WebRtc_Word32 RTPReceiverAudio::Init() { + _lastReceivedFrequency = 8000; + _telephoneEvent = false; + _telephoneEventForwardToDecoder = false; + _telephoneEventDetectEndOfTone = false; + _telephoneEventPayloadType = -1; - while(_telephoneEventReported.Size() > 0) - { - _telephoneEventReported.Erase(_telephoneEventReported.First()); - } - _cngNBPayloadType = -1; - _cngWBPayloadType = -1; - _cngSWBPayloadType = -1; - _cngPayloadType = -1; - _G722PayloadType = -1; - _lastReceivedG722 = false; - return 0; + _telephoneEventReported.clear(); + + _cngNBPayloadType = -1; + _cngWBPayloadType = -1; + _cngSWBPayloadType = -1; + _cngPayloadType = -1; + _G722PayloadType = -1; + _lastReceivedG722 = false; + return 0; } void @@ -342,14 +337,17 @@ RTPReceiverAudio::ParseAudioCodecSpecific(WebRtcRTPHeader* rtpHeader, { bool end = (payloadData[(4*n)+1] & 0x80)? true:false; - if(_telephoneEventReported.Find(payloadData[4*n]) != NULL) + std::set::iterator event = + _telephoneEventReported.find(payloadData[4*n]); + + if(event != _telephoneEventReported.end()) { // we have already seen this event if(end) { removedEvents[numberOfRemovedEvents]= payloadData[4*n]; numberOfRemovedEvents++; - _telephoneEventReported.Erase(payloadData[4*n]); + _telephoneEventReported.erase(payloadData[4*n]); } }else { @@ -360,7 +358,7 @@ RTPReceiverAudio::ParseAudioCodecSpecific(WebRtcRTPHeader* rtpHeader, { newEvents[numberOfNewEvents] = payloadData[4*n]; numberOfNewEvents++; - _telephoneEventReported.Insert(payloadData[4*n],NULL); + _telephoneEventReported.insert(payloadData[4*n]); } } } @@ -411,8 +409,9 @@ RTPReceiverAudio::ParseAudioCodecSpecific(WebRtcRTPHeader* rtpHeader, // don't forward event to decoder return 0; } - MapItem* first = _telephoneEventReported.First(); - if(first && first->GetId() > 15) + std::set::iterator first = + _telephoneEventReported.begin(); + if(first != _telephoneEventReported.end() && *first > 15) { // don't forward non DTMF events return 0; diff --git a/src/modules/rtp_rtcp/source/rtp_receiver_audio.h b/src/modules/rtp_rtcp/source/rtp_receiver_audio.h index 8a7172af8b..e3a096a6e2 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver_audio.h +++ b/src/modules/rtp_rtcp/source/rtp_receiver_audio.h @@ -11,11 +11,12 @@ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_AUDIO_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_AUDIO_H_ +#include + #include "rtp_rtcp_defines.h" #include "rtp_utility.h" #include "typedefs.h" -#include "map_wrapper.h" namespace webrtc { class CriticalSectionWrapper; @@ -77,8 +78,8 @@ private: bool _telephoneEvent; bool _telephoneEventForwardToDecoder; bool _telephoneEventDetectEndOfTone; - WebRtc_Word8 _telephoneEventPayloadType; - MapWrapper _telephoneEventReported; + WebRtc_Word8 _telephoneEventPayloadType; + std::set _telephoneEventReported; WebRtc_Word8 _cngNBPayloadType; WebRtc_Word8 _cngWBPayloadType; diff --git a/src/modules/rtp_rtcp/source/rtp_receiver_video.h b/src/modules/rtp_rtcp/source/rtp_receiver_video.h index d2c7c5e014..bbfa8a822b 100644 --- a/src/modules/rtp_rtcp/source/rtp_receiver_video.h +++ b/src/modules/rtp_rtcp/source/rtp_receiver_video.h @@ -15,8 +15,6 @@ #include "rtp_utility.h" #include "typedefs.h" -#include "map_wrapper.h" -#include "list_wrapper.h" #include "overuse_detector.h" #include "remote_rate_control.h" @@ -25,12 +23,12 @@ namespace webrtc { class ReceiverFEC; class ModuleRtpRtcpImpl; +class CriticalSectionWrapper; class RTPReceiverVideo { public: - RTPReceiverVideo(const WebRtc_Word32 id, - ModuleRtpRtcpImpl* owner); + RTPReceiverVideo(const WebRtc_Word32 id, ModuleRtpRtcpImpl* owner); virtual ~RTPReceiverVideo();