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
This commit is contained in:
pwestin@webrtc.org 2012-01-19 15:53:59 +00:00
parent 38f4816737
commit af6f15c1bf
5 changed files with 551 additions and 638 deletions

View File

@ -21,6 +21,14 @@
#include <stdlib.h> // abs #include <stdlib.h> // abs
namespace webrtc { 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, RTPReceiver::RTPReceiver(const WebRtc_Word32 id,
const bool audio, const bool audio,
RtpRtcpClock* clock, RtpRtcpClock* clock,
@ -98,43 +106,24 @@ RTPReceiver::RTPReceiver(const WebRtc_Word32 id,
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__); WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
} }
RTPReceiver::~RTPReceiver() RTPReceiver::~RTPReceiver() {
{ if (_cbRtpFeedback) {
if(_cbRtpFeedback) for (int i = 0; i < _numCSRCs; i++) {
{
for(int i = 0; i < _numCSRCs; i++)
{
_cbRtpFeedback->OnIncomingCSRCChanged(_id,_currentRemoteCSRC[i], false); _cbRtpFeedback->OnIncomingCSRCChanged(_id,_currentRemoteCSRC[i], false);
} }
} }
delete _criticalSectionCbs; delete _criticalSectionCbs;
delete _criticalSectionRTPReceiver; delete _criticalSectionRTPReceiver;
// empty map while (!_payloadTypeMap.empty()) {
bool loop = true; std::map<WebRtc_Word8, Payload*>::iterator it = _payloadTypeMap.begin();
do delete it->second;
{ _payloadTypeMap.erase(it);
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__); WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__);
} }
WebRtc_Word32 WebRtc_Word32 RTPReceiver::Init() {
RTPReceiver::Init()
{
CriticalSectionScoped lock(_criticalSectionRTPReceiver); CriticalSectionScoped lock(_criticalSectionRTPReceiver);
_lastReceiveTime = 0; _lastReceiveTime = 0;
@ -184,22 +173,11 @@ RTPReceiver::Init()
_rtpHeaderExtensionMap.Erase(); _rtpHeaderExtensionMap.Erase();
// clear db while (!_payloadTypeMap.empty()) {
bool loop = true; std::map<WebRtc_Word8, Payload*>::iterator it = _payloadTypeMap.begin();
do delete it->second;
{ _payloadTypeMap.erase(it);
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);
Bitrate::Init(); Bitrate::Init();
RTPReceiverAudio::Init(); RTPReceiverAudio::Init();
@ -369,24 +347,17 @@ RTPReceiver::RegisterIncomingDataCallback(RtpData* incomingDataCallback)
return 0; return 0;
} }
WebRtc_Word32 WebRtc_Word32 RTPReceiver::RegisterReceivePayload(
RTPReceiver::RegisterReceivePayload( const WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], const WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE],
const WebRtc_Word8 payloadType, const WebRtc_Word8 payloadType,
const WebRtc_UWord32 frequency, const WebRtc_UWord32 frequency,
const WebRtc_UWord8 channels, const WebRtc_UWord8 channels,
const WebRtc_UWord32 rate) const WebRtc_UWord32 rate) {
{ assert(payloadName);
if(payloadName == NULL)
{
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
return -1;
}
CriticalSectionScoped lock(_criticalSectionRTPReceiver); CriticalSectionScoped lock(_criticalSectionRTPReceiver);
// sanity // sanity
switch(payloadType) switch (payloadType) {
{
// reserved payload types to avoid RTCP conflicts when marker bit is set // reserved payload types to avoid RTCP conflicts when marker bit is set
case 64: // 192 Full INTRA-frame request case 64: // 192 Full INTRA-frame request
case 72: // 200 Sender report case 72: // 200 Sender report
@ -397,132 +368,128 @@ RTPReceiver::RegisterReceivePayload( const WebRtc_Word8 payloadName[RTP_PAYLOAD_
case 77: // 205 Transport layer FB message case 77: // 205 Transport layer FB message
case 78: // 206 Payload-specific FB message case 78: // 206 Payload-specific FB message
case 79: // 207 Extended report case 79: // 207 Extended report
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid payloadtype:%d", __FUNCTION__, payloadType); WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"%s invalid payloadtype:%d",
__FUNCTION__, payloadType);
return -1; return -1;
default: default:
break; break;
} }
WebRtc_Word32 payloadNameLength = (WebRtc_Word32)strlen(payloadName); size_t payloadNameLength = strlen(payloadName);
MapItem* item = NULL; std::map<WebRtc_Word8, Payload*>::iterator it =
item = _payloadTypeMap.Find(payloadType); _payloadTypeMap.find(payloadType);
if( NULL != item) if (it != _payloadTypeMap.end()) {
{
// we already use this payload type // we already use this payload type
Payload* payload = it->second;
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem();
assert(payload); assert(payload);
WebRtc_Word32 nameLength = (WebRtc_Word32)strlen(payload->name); size_t nameLength = strlen(payload->name);
// check if it's the same as we already have // check if it's the same as we already have
// if same ignore sending an error // if same ignore sending an error
if(payloadNameLength == nameLength && ModuleRTPUtility::StringCompare(payload->name, payloadName, payloadNameLength)) if (payloadNameLength == nameLength &&
{ StringCompare(payload->name, payloadName, payloadNameLength)) {
if(_audio && if (_audio &&
payload->audio && payload->audio &&
payload->typeSpecific.Audio.frequency == frequency && payload->typeSpecific.Audio.frequency == frequency &&
payload->typeSpecific.Audio.channels == channels && payload->typeSpecific.Audio.channels == channels &&
(payload->typeSpecific.Audio.rate == rate || payload->typeSpecific.Audio.rate == 0 || rate == 0)) (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 payload->typeSpecific.Audio.rate = rate;
// Ensure that we update the rate if new or old is zero
return 0; return 0;
} }
if(!_audio && !payload->audio) if (!_audio && !payload->audio) {
{
// update maxBitrate for video // update maxBitrate for video
payload->typeSpecific.Video.maxRate = rate; payload->typeSpecific.Video.maxRate = rate;
return 0; return 0;
} }
} }
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument payloadType:%d already registered", __FUNCTION__, payloadType); WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"%s invalid argument payloadType:%d already registered",
__FUNCTION__, payloadType);
return -1; return -1;
} }
if (_audio) {
if(_audio)
{
// remove existing item, hence search for the name // remove existing item, hence search for the name
// only for audio, for video we allow a codecs to use multiple pltypes // only for audio, for video we allow a codecs to use multiple pltypes
item = _payloadTypeMap.First(); std::map<WebRtc_Word8, Payload*>::iterator audio_it =
while(item) _payloadTypeMap.begin();
{ while (audio_it != _payloadTypeMap.end()) {
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); Payload* payload = audio_it->second;
WebRtc_Word32 nameLength = (WebRtc_Word32)strlen(payload->name); size_t nameLength = strlen(payload->name);
if(payloadNameLength == nameLength && ModuleRTPUtility::StringCompare(payload->name, payloadName, payloadNameLength)) if (payloadNameLength == nameLength &&
{ StringCompare(payload->name, payloadName, payloadNameLength)) {
// we found the payload name in the list // we found the payload name in the list
// if audio check frequency and rate // if audio check frequency and rate
if( payload->audio) if (payload->audio) {
{ if (payload->typeSpecific.Audio.frequency == frequency &&
if(payload->typeSpecific.Audio.frequency == frequency && (payload->typeSpecific.Audio.rate == rate ||
(payload->typeSpecific.Audio.rate == rate || payload->typeSpecific.Audio.rate == 0 || rate == 0)) payload->typeSpecific.Audio.rate == 0 || rate == 0)) {
{
// remove old setting // remove old setting
delete payload; delete payload;
_payloadTypeMap.Erase(item); _payloadTypeMap.erase(audio_it);
break; break;
} }
} else if(ModuleRTPUtility::StringCompare(payloadName,"red",3)) } else if(StringCompare(payloadName,"red",3)) {
{
delete payload; delete payload;
_payloadTypeMap.Erase(item); _payloadTypeMap.erase(audio_it);
break; break;
} }
} }
item = _payloadTypeMap.Next(item); audio_it++;
} }
} }
Payload* payload = NULL;
ModuleRTPUtility::Payload* payload = NULL;
// save the RED payload type // save the RED payload type
// used in both audio and video // used in both audio and video
if(ModuleRTPUtility::StringCompare(payloadName,"red",3)) if (StringCompare(payloadName,"red",3)) {
{
_redPayloadType = payloadType; _redPayloadType = payloadType;
payload = new ModuleRTPUtility::Payload; payload = new Payload;
payload->audio = false; payload->audio = false;
memcpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE); memcpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE);
} else } else {
{ if (_audio) {
if(_audio) payload = RegisterReceiveAudioPayload(payloadName, payloadType,
{ frequency, channels, rate);
payload = RegisterReceiveAudioPayload(payloadName, payloadType, frequency, channels, rate); } else {
} else
{
payload = RegisterReceiveVideoPayload(payloadName, payloadType, rate); payload = RegisterReceiveVideoPayload(payloadName, payloadType, rate);
} }
if(payload == NULL) }
{ if (payload == NULL) {
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s filed to register payload", __FUNCTION__); WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"%s filed to register payload",
__FUNCTION__);
return -1; return -1;
} }
} _payloadTypeMap[payloadType] = payload;
_payloadTypeMap.Insert(payloadType, payload);
// Successful set of payload type, clear the value of last receivedPT, since it might mean something else // Successful set of payload type, clear the value of last receivedPT,
// since it might mean something else
_lastReceivedPayloadType = -1; _lastReceivedPayloadType = -1;
_lastReceivedMediaPayloadType = -1; _lastReceivedMediaPayloadType = -1;
return 0; return 0;
} }
WebRtc_Word32 WebRtc_Word32 RTPReceiver::DeRegisterReceivePayload(
RTPReceiver::DeRegisterReceivePayload(const WebRtc_Word8 payloadType) const WebRtc_Word8 payloadType) {
{
CriticalSectionScoped lock(_criticalSectionRTPReceiver); CriticalSectionScoped lock(_criticalSectionRTPReceiver);
MapItem* item = _payloadTypeMap.Find(payloadType); std::map<WebRtc_Word8, Payload*>::iterator it =
if( NULL != item) _payloadTypeMap.find(payloadType);
{
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem();
delete payload;
_payloadTypeMap.Erase(item); if (it == _payloadTypeMap.end()) {
return 0; WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
} "%s failed to find payloadType:%d",
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s failed to find payloadType:%d", __FUNCTION__, payloadType); __FUNCTION__, payloadType);
return -1; return -1;
}
delete it->second;
_payloadTypeMap.erase(it);
return 0;
} }
WebRtc_Word32 RTPReceiver::ReceivePayloadType( WebRtc_Word32 RTPReceiver::ReceivePayloadType(
@ -530,167 +497,139 @@ WebRtc_Word32 RTPReceiver::ReceivePayloadType(
const WebRtc_UWord32 frequency, const WebRtc_UWord32 frequency,
const WebRtc_UWord8 channels, const WebRtc_UWord8 channels,
const WebRtc_UWord32 rate, const WebRtc_UWord32 rate,
WebRtc_Word8* payloadType) const WebRtc_Word8* payloadType) const {
{ if (payloadType == NULL) {
if(payloadType == NULL) WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
{ "%s invalid argument", __FUNCTION__);
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
return -1; return -1;
} }
size_t payloadNameLength = strlen(payloadName);
WebRtc_Word32 payloadNameLength = (WebRtc_Word32)strlen(payloadName);
CriticalSectionScoped lock(_criticalSectionRTPReceiver); CriticalSectionScoped lock(_criticalSectionRTPReceiver);
MapItem* item = _payloadTypeMap.First(); std::map<WebRtc_Word8, Payload*>::const_iterator it =
while( NULL != item) _payloadTypeMap.begin();
{
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); while (it != _payloadTypeMap.end()) {
Payload* payload = it->second;
assert(payload); assert(payload);
WebRtc_Word32 nameLength = (WebRtc_Word32)strlen(payload->name); size_t nameLength = strlen(payload->name);
if(payloadNameLength == nameLength && ModuleRTPUtility::StringCompare(payload->name, payloadName, payloadNameLength)) if (payloadNameLength == nameLength &&
{ StringCompare(payload->name, payloadName, payloadNameLength)) {
// name match // name match
if(payload->audio) if( payload->audio) {
{ if (rate == 0) {
if (rate == 0)
{
// [default] audio, check freq and channels // [default] audio, check freq and channels
if( payload->typeSpecific.Audio.frequency == frequency && if (payload->typeSpecific.Audio.frequency == frequency &&
payload->typeSpecific.Audio.channels == channels) payload->typeSpecific.Audio.channels == channels) {
{ *payloadType = it->first;
*payloadType = item->GetId();
return 0; return 0;
} }
} } else {
else
{
// audio, check freq, channels and rate // audio, check freq, channels and rate
if( payload->typeSpecific.Audio.frequency == frequency && if( payload->typeSpecific.Audio.frequency == frequency &&
payload->typeSpecific.Audio.channels == channels && payload->typeSpecific.Audio.channels == channels &&
payload->typeSpecific.Audio.rate == rate) // extra rate condition added payload->typeSpecific.Audio.rate == rate) {
{ // extra rate condition added
*payloadType = item->GetId(); *payloadType = it->first;
return 0; return 0;
} }
} }
} else } else {
{
// video // video
*payloadType = item->GetId(); *payloadType = it->first;
return 0; return 0;
} }
} }
item = _payloadTypeMap.Next(item); it++;
} }
return -1; return -1;
} }
WebRtc_Word32 WebRtc_Word32 RTPReceiver::ReceivePayload(
RTPReceiver::ReceivePayload(const WebRtc_Word8 payloadType, const WebRtc_Word8 payloadType,
WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE],
WebRtc_UWord32* frequency, WebRtc_UWord32* frequency,
WebRtc_UWord8* channels, WebRtc_UWord8* channels,
WebRtc_UWord32* rate) const WebRtc_UWord32* rate) const {
{
CriticalSectionScoped lock(_criticalSectionRTPReceiver); CriticalSectionScoped lock(_criticalSectionRTPReceiver);
MapItem* item = _payloadTypeMap.Find(payloadType); std::map<WebRtc_Word8, Payload*>::const_iterator it =
if( NULL == item) _payloadTypeMap.find(payloadType);
{
if (it == _payloadTypeMap.end()) {
return -1; return -1;
} }
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); Payload* payload = it->second;
assert(payload); assert(payload);
if(frequency) if(frequency) {
{ if(payload->audio) {
if(payload->audio)
{
*frequency = payload->typeSpecific.Audio.frequency; *frequency = payload->typeSpecific.Audio.frequency;
} else } else {
{
*frequency = 90000; *frequency = 90000;
} }
} }
if(channels) if (channels) {
{ if(payload->audio) {
if(payload->audio)
{
*channels = payload->typeSpecific.Audio.channels; *channels = payload->typeSpecific.Audio.channels;
} else } else {
{
*channels = 1; *channels = 1;
} }
} }
if (rate) if (rate) {
{ if(payload->audio) {
if(payload->audio)
{
*rate = payload->typeSpecific.Audio.rate; *rate = payload->typeSpecific.Audio.rate;
} else } else {
{
assert(false); assert(false);
*rate = 0; *rate = 0;
} }
} }
if(payloadName) if (payloadName) {
{
memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE); memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE);
} }
return 0; return 0;
} }
WebRtc_Word32 WebRtc_Word32 RTPReceiver::RemotePayload(
RTPReceiver::RemotePayload(WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE], WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE],
WebRtc_Word8* payloadType, WebRtc_Word8* payloadType,
WebRtc_UWord32* frequency, WebRtc_UWord32* frequency,
WebRtc_UWord8* channels) const WebRtc_UWord8* channels) const {
{ if(_lastReceivedPayloadType == -1) {
if(_lastReceivedPayloadType == -1)
{
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__); WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__);
return -1; return -1;
} }
memset(payloadName, 0, RTP_PAYLOAD_NAME_SIZE); std::map<WebRtc_Word8, Payload*>::const_iterator it =
_payloadTypeMap.find(_lastReceivedPayloadType);
MapItem* item = _payloadTypeMap.Find(_lastReceivedPayloadType); if (it == _payloadTypeMap.end()) {
if( NULL != item) return -1;
{ }
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); Payload* payload = it->second;
if(payload) assert(payload);
{ payloadName[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
if(payloadType ) if (payloadType) {
{
*payloadType = _lastReceivedPayloadType; *payloadType = _lastReceivedPayloadType;
} }
if(frequency) if (frequency) {
{ if (payload->audio) {
if(payload->audio)
{
*frequency = payload->typeSpecific.Audio.frequency; *frequency = payload->typeSpecific.Audio.frequency;
} else } else {
{
*frequency = 90000; *frequency = 90000;
} }
} }
if(channels) if (channels) {
{ if (payload->audio) {
if(payload->audio)
{
*channels = payload->typeSpecific.Audio.channels; *channels = payload->typeSpecific.Audio.channels;
} else } else {
{
*channels = 1; *channels = 1;
} }
} }
return 0; return 0;
}
}
return -1;
} }
WebRtc_Word32 WebRtc_Word32
@ -836,11 +775,11 @@ WebRtc_Word32 RTPReceiver::IncomingRTPPacket(
CheckSSRCChanged(rtp_header); CheckSSRCChanged(rtp_header);
bool is_red = false; bool is_red = false;
ModuleRTPUtility::VideoPayload video_specific; VideoPayload video_specific;
video_specific.maxRate = 0; video_specific.maxRate = 0;
video_specific.videoCodecType = kRtpNoVideo; video_specific.videoCodecType = kRtpNoVideo;
ModuleRTPUtility::AudioPayload audio_specific; AudioPayload audio_specific;
audio_specific.bitsPerSample = 0; audio_specific.bitsPerSample = 0;
audio_specific.channels = 0; audio_specific.channels = 0;
audio_specific.frequency = 0; audio_specific.frequency = 0;
@ -955,7 +894,7 @@ RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtpHeader,
_receivedSeqMax = rtpHeader->header.sequenceNumber; _receivedSeqMax = rtpHeader->header.sequenceNumber;
_receivedInorderPacketCount = 1; _receivedInorderPacketCount = 1;
_localTimeLastReceivedTimestamp = _localTimeLastReceivedTimestamp =
ModuleRTPUtility::GetCurrentRTP(&_clock, freq); //time in samples GetCurrentRTP(&_clock, freq); //time in samples
return; return;
} }
@ -963,7 +902,7 @@ RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtpHeader,
if(InOrderPacket(rtpHeader->header.sequenceNumber)) if(InOrderPacket(rtpHeader->header.sequenceNumber))
{ {
const WebRtc_UWord32 RTPtime = const WebRtc_UWord32 RTPtime =
ModuleRTPUtility::GetCurrentRTP(&_clock, freq); //time in samples GetCurrentRTP(&_clock, freq); //time in samples
_receivedInorderPacketCount++; _receivedInorderPacketCount++;
// wrong if we use RetransmitOfOldPacket // wrong if we use RetransmitOfOldPacket
@ -1110,28 +1049,21 @@ RTPReceiver::TimeStamp() const
return _lastReceivedTimestamp; return _lastReceivedTimestamp;
} }
WebRtc_UWord32 WebRtc_UWord32 RTPReceiver::PayloadTypeToPayload(
RTPReceiver::PayloadTypeToPayload(const WebRtc_UWord8 payloadType, const WebRtc_UWord8 payloadType,
ModuleRTPUtility::Payload*& payload) const Payload*& payload) const {
{
MapItem* item = _payloadTypeMap.Find(payloadType); std::map<WebRtc_Word8, Payload*>::const_iterator it =
_payloadTypeMap.find(payloadType);
// check that this is a registered payload type // check that this is a registered payload type
if(item == NULL) if (it == _payloadTypeMap.end()) {
{
return -1; return -1;
} }
payload = it->second;
payload = (ModuleRTPUtility::Payload*)item->GetItem();
if(payload == NULL)
{
return -1;
}
return 0; return 0;
} }
// timeStamp of the last incoming packet that is the first packet of its frame // timeStamp of the last incoming packet that is the first packet of its frame
WebRtc_Word32 WebRtc_Word32
RTPReceiver::EstimatedRemoteTimeStamp(WebRtc_UWord32& timestamp) const RTPReceiver::EstimatedRemoteTimeStamp(WebRtc_UWord32& timestamp) const
@ -1148,7 +1080,7 @@ RTPReceiver::EstimatedRemoteTimeStamp(WebRtc_UWord32& timestamp) const
return -1; return -1;
} }
//time in samples //time in samples
WebRtc_UWord32 diff = ModuleRTPUtility::GetCurrentRTP(&_clock, freq) WebRtc_UWord32 diff = GetCurrentRTP(&_clock, freq)
- _localTimeLastReceivedTimestamp; - _localTimeLastReceivedTimestamp;
timestamp = _lastReceivedTimestamp + diff; timestamp = _lastReceivedTimestamp + diff;
@ -1187,9 +1119,7 @@ RTPReceiver::SetSSRCFilter(const bool enable, const WebRtc_UWord32 allowedSSRC)
} }
// no criticalsection when called // no criticalsection when called
void void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader) {
RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader)
{
bool newSSRC = false; bool newSSRC = false;
bool reInitializeDecoder = false; bool reInitializeDecoder = false;
WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE]; WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE];
@ -1201,8 +1131,9 @@ RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader)
{ {
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 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; newSSRC = true;
// reset last report // reset last report
@ -1213,68 +1144,62 @@ RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader)
_lastReceivedSequenceNumber = 0; _lastReceivedSequenceNumber = 0;
_lastReceivedTransmissionTimeOffset = 0; _lastReceivedTransmissionTimeOffset = 0;
if (_SSRC) // do we have a SSRC? then the stream is restarted if (_SSRC) { // do we have a SSRC? then the stream is restarted
{
// if we have the same codec? reinit decoder // if we have the same codec? reinit decoder
if (rtpHeader->header.payloadType == _lastReceivedPayloadType) if (rtpHeader->header.payloadType == _lastReceivedPayloadType) {
{
reInitializeDecoder = true; reInitializeDecoder = true;
MapItem* item = _payloadTypeMap.Find(rtpHeader->header.payloadType); std::map<WebRtc_Word8, Payload*>::iterator it =
if( NULL != item) _payloadTypeMap.find(rtpHeader->header.payloadType);
{
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); if (it == _payloadTypeMap.end()) {
if(payload) return;
{ }
Payload* payload = it->second;
assert(payload);
payloadName[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
if(payload->audio) if(payload->audio) {
{
frequency = payload->typeSpecific.Audio.frequency; frequency = payload->typeSpecific.Audio.frequency;
channels = payload->typeSpecific.Audio.channels; channels = payload->typeSpecific.Audio.channels;
rate = payload->typeSpecific.Audio.rate; rate = payload->typeSpecific.Audio.rate;
} else } else {
{
frequency = 90000; frequency = 90000;
} }
} }
} }
}
}
_SSRC = rtpHeader->header.ssrc; _SSRC = rtpHeader->header.ssrc;
} }
} }
if(newSSRC) if(newSSRC) {
{
// we need to get this to our RTCP sender and receiver // we need to get this to our RTCP sender and receiver
// need to do this outside critical section // need to do this outside critical section
_rtpRtcp.SetRemoteSSRC(rtpHeader->header.ssrc); _rtpRtcp.SetRemoteSSRC(rtpHeader->header.ssrc);
} }
CriticalSectionScoped lock(_criticalSectionCbs); CriticalSectionScoped lock(_criticalSectionCbs);
if(_cbRtpFeedback) if(_cbRtpFeedback) {
{ if(newSSRC) {
if(newSSRC)
{
_cbRtpFeedback->OnIncomingSSRCChanged(_id, rtpHeader->header.ssrc); _cbRtpFeedback->OnIncomingSSRCChanged(_id, rtpHeader->header.ssrc);
} }
if(reInitializeDecoder) if(reInitializeDecoder) {
{ if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id,
if(-1 == _cbRtpFeedback->OnInitializeDecoder(_id, rtpHeader->header.payloadType, payloadName, frequency, channels, rate)) // new stream same codec 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); WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"Failed to create decoder for payload type:%d",
rtpHeader->header.payloadType);
} }
} }
} }
} }
// no criticalsection when called // no criticalsection when called
WebRtc_Word32 WebRtc_Word32 RTPReceiver::CheckPayloadChanged(
RTPReceiver::CheckPayloadChanged(const WebRtcRTPHeader* rtpHeader, const WebRtcRTPHeader* rtpHeader,
const WebRtc_Word8 firstPayloadByte, const WebRtc_Word8 firstPayloadByte,
bool& isRED, bool& isRED,
ModuleRTPUtility::AudioPayload& audioSpecificPayload, AudioPayload& audioSpecificPayload,
ModuleRTPUtility::VideoPayload& videoSpecificPayload) VideoPayload& videoSpecificPayload) {
{
bool reInitializeDecoder = false; bool reInitializeDecoder = false;
WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE]; WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE];
@ -1283,123 +1208,112 @@ RTPReceiver::CheckPayloadChanged(const WebRtcRTPHeader* rtpHeader,
{ {
CriticalSectionScoped lock(_criticalSectionRTPReceiver); CriticalSectionScoped lock(_criticalSectionRTPReceiver);
if (payloadType != _lastReceivedPayloadType) if (payloadType != _lastReceivedPayloadType) {
{ if (REDPayloadType(payloadType)) {
if (REDPayloadType(payloadType))
{
// get the real codec payload type // get the real codec payload type
payloadType = firstPayloadByte & 0x7f; payloadType = firstPayloadByte & 0x7f;
isRED = true; isRED = true;
//when we receive RED we need to check the real payload type //when we receive RED we need to check the real payload type
if (payloadType == _lastReceivedPayloadType) if (payloadType == _lastReceivedPayloadType) {
{
if(_audio) if(_audio)
{ {
memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific, sizeof(_lastReceivedAudioSpecific)); memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific,
} else sizeof(_lastReceivedAudioSpecific));
{ } else {
memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific, sizeof(_lastReceivedVideoSpecific)); memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific,
sizeof(_lastReceivedVideoSpecific));
} }
return 0; return 0;
} }
} }
if(_audio) if (_audio) {
{ if (TelephoneEventPayloadType(payloadType)) {
if(TelephoneEventPayloadType(payloadType))
{
// don't do callbacks for DTMF packets // don't do callbacks for DTMF packets
isRED = false; isRED = false;
return 0; return 0;
} }
// frequency is updated for CNG // frequency is updated for CNG
if(CNGPayloadType(payloadType, audioSpecificPayload.frequency)) if (CNGPayloadType(payloadType, audioSpecificPayload.frequency)) {
{
// don't do callbacks for DTMF packets // don't do callbacks for DTMF packets
isRED = false; isRED = false;
return 0; return 0;
} }
} }
MapItem* item = _payloadTypeMap.Find(payloadType); std::map<WebRtc_Word8, ModuleRTPUtility::Payload*>::iterator it =
_payloadTypeMap.find(payloadType);
// check that this is a registered payload type // check that this is a registered payload type
if(item == NULL) if (it == _payloadTypeMap.end()) {
{
return -1; return -1;
} }
memset(payloadName, 0, sizeof(payloadName)); Payload* payload = it->second;
assert(payload);
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem(); payloadName[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
if(payload == NULL)
{
return -1;
}
memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1); memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
_lastReceivedPayloadType = payloadType; _lastReceivedPayloadType = payloadType;
reInitializeDecoder = true; reInitializeDecoder = true;
if(payload->audio) if(payload->audio) {
{ memcpy(&_lastReceivedAudioSpecific, &(payload->typeSpecific.Audio),
memcpy(&_lastReceivedAudioSpecific, &(payload->typeSpecific.Audio), sizeof(_lastReceivedAudioSpecific)); sizeof(_lastReceivedAudioSpecific));
memcpy(&audioSpecificPayload, &(payload->typeSpecific.Audio), sizeof(_lastReceivedAudioSpecific)); memcpy(&audioSpecificPayload, &(payload->typeSpecific.Audio),
}else sizeof(_lastReceivedAudioSpecific));
{ } else {
memcpy(&_lastReceivedVideoSpecific, &(payload->typeSpecific.Video), sizeof(_lastReceivedVideoSpecific)); memcpy(&_lastReceivedVideoSpecific, &(payload->typeSpecific.Video),
memcpy(&videoSpecificPayload, &(payload->typeSpecific.Video), sizeof(_lastReceivedVideoSpecific)); sizeof(_lastReceivedVideoSpecific));
memcpy(&videoSpecificPayload, &(payload->typeSpecific.Video),
sizeof(_lastReceivedVideoSpecific));
if (_lastReceivedVideoSpecific.videoCodecType == kRtpFecVideo) if (_lastReceivedVideoSpecific.videoCodecType == kRtpFecVideo)
{ {
// Only reset the decoder on media packets. // Only reset the decoder on media packets.
reInitializeDecoder = false; reInitializeDecoder = false;
} } else {
else if (_lastReceivedMediaPayloadType == _lastReceivedPayloadType) {
{
if (_lastReceivedMediaPayloadType == _lastReceivedPayloadType)
{
// Only reset the decoder if the media codec type has changed. // Only reset the decoder if the media codec type has changed.
reInitializeDecoder = false; reInitializeDecoder = false;
} }
_lastReceivedMediaPayloadType = _lastReceivedPayloadType; _lastReceivedMediaPayloadType = _lastReceivedPayloadType;
} }
} }
if(reInitializeDecoder) if (reInitializeDecoder) {
{
// reset statistics // reset statistics
ResetStatistics(); ResetStatistics();
} }
}else } else {
{
if(_audio) if(_audio)
{ {
memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific, sizeof(_lastReceivedAudioSpecific)); memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific,
sizeof(_lastReceivedAudioSpecific));
} else } else
{ {
memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific, sizeof(_lastReceivedVideoSpecific)); memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific,
sizeof(_lastReceivedVideoSpecific));
} }
isRED = false; isRED = false;
} }
} // end critsect } // end critsect
if(reInitializeDecoder) if (reInitializeDecoder) {
{
CriticalSectionScoped lock(_criticalSectionCbs); CriticalSectionScoped lock(_criticalSectionCbs);
if(_cbRtpFeedback) if (_cbRtpFeedback) {
{
// create new decoder instance // create new decoder instance
if(_audio) if(_audio) {
{ if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType,
if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType, payloadName, audioSpecificPayload.frequency, audioSpecificPayload.channels, audioSpecificPayload.rate)) payloadName, audioSpecificPayload.frequency,
{ audioSpecificPayload.channels, audioSpecificPayload.rate)) {
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "Failed to create audio decoder for payload type:%d", payloadType); WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"Failed to create audio decoder for payload type:%d",
payloadType);
return -1; // Wrong payload type return -1; // Wrong payload type
} }
} else } else {
{ if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType,
if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType, payloadName, 90000, 1, 0)) payloadName, 90000, 1, 0)) {
{ WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "Failed to create video decoder for payload type:%d", payloadType); "Failed to create video decoder for payload type:%d",
payloadType);
return -1; // Wrong payload type return -1; // Wrong payload type
} }
} }

View File

@ -11,6 +11,8 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_
#include <map>
#include "typedefs.h" #include "typedefs.h"
#include "rtp_utility.h" #include "rtp_utility.h"
@ -208,8 +210,7 @@ private:
WebRtc_Word8 _redPayloadType; WebRtc_Word8 _redPayloadType;
// std::map<WebRtc_Word8, ModuleRTPUtility::Payload*> _payloadTypeMap;
MapWrapper _payloadTypeMap;
RtpHeaderExtensionMap _rtpHeaderExtensionMap; RtpHeaderExtensionMap _rtpHeaderExtensionMap;
// SSRCs // SSRCs

View File

@ -24,7 +24,6 @@ RTPReceiverAudio::RTPReceiverAudio(const WebRtc_Word32 id):
_telephoneEventForwardToDecoder(false), _telephoneEventForwardToDecoder(false),
_telephoneEventDetectEndOfTone(false), _telephoneEventDetectEndOfTone(false),
_telephoneEventPayloadType(-1), _telephoneEventPayloadType(-1),
_telephoneEventReported(),
_cngNBPayloadType(-1), _cngNBPayloadType(-1),
_cngWBPayloadType(-1), _cngWBPayloadType(-1),
_cngSWBPayloadType(-1), _cngSWBPayloadType(-1),
@ -41,19 +40,15 @@ RTPReceiverAudio::~RTPReceiverAudio()
delete _criticalSectionFeedback; delete _criticalSectionFeedback;
} }
WebRtc_Word32 WebRtc_Word32 RTPReceiverAudio::Init() {
RTPReceiverAudio::Init()
{
_lastReceivedFrequency = 8000; _lastReceivedFrequency = 8000;
_telephoneEvent = false; _telephoneEvent = false;
_telephoneEventForwardToDecoder = false; _telephoneEventForwardToDecoder = false;
_telephoneEventDetectEndOfTone = false; _telephoneEventDetectEndOfTone = false;
_telephoneEventPayloadType = -1; _telephoneEventPayloadType = -1;
while(_telephoneEventReported.Size() > 0) _telephoneEventReported.clear();
{
_telephoneEventReported.Erase(_telephoneEventReported.First());
}
_cngNBPayloadType = -1; _cngNBPayloadType = -1;
_cngWBPayloadType = -1; _cngWBPayloadType = -1;
_cngSWBPayloadType = -1; _cngSWBPayloadType = -1;
@ -342,14 +337,17 @@ RTPReceiverAudio::ParseAudioCodecSpecific(WebRtcRTPHeader* rtpHeader,
{ {
bool end = (payloadData[(4*n)+1] & 0x80)? true:false; bool end = (payloadData[(4*n)+1] & 0x80)? true:false;
if(_telephoneEventReported.Find(payloadData[4*n]) != NULL) std::set<WebRtc_UWord8>::iterator event =
_telephoneEventReported.find(payloadData[4*n]);
if(event != _telephoneEventReported.end())
{ {
// we have already seen this event // we have already seen this event
if(end) if(end)
{ {
removedEvents[numberOfRemovedEvents]= payloadData[4*n]; removedEvents[numberOfRemovedEvents]= payloadData[4*n];
numberOfRemovedEvents++; numberOfRemovedEvents++;
_telephoneEventReported.Erase(payloadData[4*n]); _telephoneEventReported.erase(payloadData[4*n]);
} }
}else }else
{ {
@ -360,7 +358,7 @@ RTPReceiverAudio::ParseAudioCodecSpecific(WebRtcRTPHeader* rtpHeader,
{ {
newEvents[numberOfNewEvents] = payloadData[4*n]; newEvents[numberOfNewEvents] = payloadData[4*n];
numberOfNewEvents++; 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 // don't forward event to decoder
return 0; return 0;
} }
MapItem* first = _telephoneEventReported.First(); std::set<WebRtc_UWord8>::iterator first =
if(first && first->GetId() > 15) _telephoneEventReported.begin();
if(first != _telephoneEventReported.end() && *first > 15)
{ {
// don't forward non DTMF events // don't forward non DTMF events
return 0; return 0;

View File

@ -11,11 +11,12 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_AUDIO_H_ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_AUDIO_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_AUDIO_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_AUDIO_H_
#include <set>
#include "rtp_rtcp_defines.h" #include "rtp_rtcp_defines.h"
#include "rtp_utility.h" #include "rtp_utility.h"
#include "typedefs.h" #include "typedefs.h"
#include "map_wrapper.h"
namespace webrtc { namespace webrtc {
class CriticalSectionWrapper; class CriticalSectionWrapper;
@ -78,7 +79,7 @@ private:
bool _telephoneEventForwardToDecoder; bool _telephoneEventForwardToDecoder;
bool _telephoneEventDetectEndOfTone; bool _telephoneEventDetectEndOfTone;
WebRtc_Word8 _telephoneEventPayloadType; WebRtc_Word8 _telephoneEventPayloadType;
MapWrapper _telephoneEventReported; std::set<WebRtc_UWord8> _telephoneEventReported;
WebRtc_Word8 _cngNBPayloadType; WebRtc_Word8 _cngNBPayloadType;
WebRtc_Word8 _cngWBPayloadType; WebRtc_Word8 _cngWBPayloadType;

View File

@ -15,8 +15,6 @@
#include "rtp_utility.h" #include "rtp_utility.h"
#include "typedefs.h" #include "typedefs.h"
#include "map_wrapper.h"
#include "list_wrapper.h"
#include "overuse_detector.h" #include "overuse_detector.h"
#include "remote_rate_control.h" #include "remote_rate_control.h"
@ -25,12 +23,12 @@
namespace webrtc { namespace webrtc {
class ReceiverFEC; class ReceiverFEC;
class ModuleRtpRtcpImpl; class ModuleRtpRtcpImpl;
class CriticalSectionWrapper;
class RTPReceiverVideo class RTPReceiverVideo
{ {
public: public:
RTPReceiverVideo(const WebRtc_Word32 id, RTPReceiverVideo(const WebRtc_Word32 id, ModuleRtpRtcpImpl* owner);
ModuleRtpRtcpImpl* owner);
virtual ~RTPReceiverVideo(); virtual ~RTPReceiverVideo();