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
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,43 +106,24 @@ 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++)
{
RTPReceiver::~RTPReceiver() {
if (_cbRtpFeedback) {
for (int i = 0; i < _numCSRCs; i++) {
_cbRtpFeedback->OnIncomingCSRCChanged(_id,_currentRemoteCSRC[i], false);
}
}
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 (!_payloadTypeMap.empty()) {
std::map<WebRtc_Word8, Payload*>::iterator it = _payloadTypeMap.begin();
delete it->second;
_payloadTypeMap.erase(it);
}
} while (loop);
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__);
}
WebRtc_Word32
RTPReceiver::Init()
{
WebRtc_Word32 RTPReceiver::Init() {
CriticalSectionScoped lock(_criticalSectionRTPReceiver);
_lastReceiveTime = 0;
@ -184,22 +173,11 @@ RTPReceiver::Init()
_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 (!_payloadTypeMap.empty()) {
std::map<WebRtc_Word8, Payload*>::iterator it = _payloadTypeMap.begin();
delete it->second;
_payloadTypeMap.erase(it);
}
} while (loop);
Bitrate::Init();
RTPReceiverAudio::Init();
@ -369,24 +347,17 @@ RTPReceiver::RegisterIncomingDataCallback(RtpData* incomingDataCallback)
return 0;
}
WebRtc_Word32
RTPReceiver::RegisterReceivePayload( const WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE],
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;
}
const WebRtc_UWord32 rate) {
assert(payloadName);
CriticalSectionScoped lock(_criticalSectionRTPReceiver);
// sanity
switch(payloadType)
{
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
@ -397,301 +368,269 @@ RTPReceiver::RegisterReceivePayload( const WebRtc_Word8 payloadName[RTP_PAYLOAD_
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);
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"%s invalid payloadtype:%d",
__FUNCTION__, payloadType);
return -1;
default:
break;
}
WebRtc_Word32 payloadNameLength = (WebRtc_Word32)strlen(payloadName);
size_t payloadNameLength = strlen(payloadName);
MapItem* item = NULL;
item = _payloadTypeMap.Find(payloadType);
if( NULL != item)
{
std::map<WebRtc_Word8, Payload*>::iterator it =
_payloadTypeMap.find(payloadType);
if (it != _payloadTypeMap.end()) {
// we already use this payload type
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem();
Payload* payload = it->second;
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
// 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 &&
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
(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)
{
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);
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"%s invalid argument payloadType:%d already registered",
__FUNCTION__, payloadType);
return -1;
}
if(_audio)
{
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);
std::map<WebRtc_Word8, Payload*>::iterator audio_it =
_payloadTypeMap.begin();
while (audio_it != _payloadTypeMap.end()) {
Payload* payload = audio_it->second;
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
// if audio check frequency and rate
if( payload->audio)
{
if (payload->audio) {
if (payload->typeSpecific.Audio.frequency == frequency &&
(payload->typeSpecific.Audio.rate == rate || payload->typeSpecific.Audio.rate == 0 || rate == 0))
{
(payload->typeSpecific.Audio.rate == rate ||
payload->typeSpecific.Audio.rate == 0 || rate == 0)) {
// remove old setting
delete payload;
_payloadTypeMap.Erase(item);
_payloadTypeMap.erase(audio_it);
break;
}
} else if(ModuleRTPUtility::StringCompare(payloadName,"red",3))
{
} else if(StringCompare(payloadName,"red",3)) {
delete payload;
_payloadTypeMap.Erase(item);
_payloadTypeMap.erase(audio_it);
break;
}
}
item = _payloadTypeMap.Next(item);
audio_it++;
}
}
ModuleRTPUtility::Payload* payload = NULL;
Payload* payload = NULL;
// save the RED payload type
// used in both audio and video
if(ModuleRTPUtility::StringCompare(payloadName,"red",3))
{
if (StringCompare(payloadName,"red",3)) {
_redPayloadType = payloadType;
payload = new ModuleRTPUtility::Payload;
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
{
} 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__);
}
if (payload == NULL) {
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"%s filed to register payload",
__FUNCTION__);
return -1;
}
}
_payloadTypeMap.Insert(payloadType, payload);
_payloadTypeMap[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;
_lastReceivedMediaPayloadType = -1;
return 0;
}
WebRtc_Word32
RTPReceiver::DeRegisterReceivePayload(const WebRtc_Word8 payloadType)
{
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<WebRtc_Word8, Payload*>::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(
const WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE],
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__);
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);
size_t payloadNameLength = strlen(payloadName);
CriticalSectionScoped lock(_criticalSectionRTPReceiver);
MapItem* item = _payloadTypeMap.First();
while( NULL != item)
{
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem();
std::map<WebRtc_Word8, Payload*>::const_iterator it =
_payloadTypeMap.begin();
while (it != _payloadTypeMap.end()) {
Payload* payload = it->second;
assert(payload);
WebRtc_Word32 nameLength = (WebRtc_Word32)strlen(payload->name);
if(payloadNameLength == nameLength && ModuleRTPUtility::StringCompare(payload->name, payloadName, payloadNameLength))
{
size_t nameLength = strlen(payload->name);
if (payloadNameLength == nameLength &&
StringCompare(payload->name, payloadName, payloadNameLength)) {
// name match
if(payload->audio)
{
if (rate == 0)
{
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();
payload->typeSpecific.Audio.channels == channels) {
*payloadType = it->first;
return 0;
}
}
else
{
} 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();
payload->typeSpecific.Audio.rate == rate) {
// extra rate condition added
*payloadType = it->first;
return 0;
}
}
} else
{
} else {
// video
*payloadType = item->GetId();
*payloadType = it->first;
return 0;
}
}
item = _payloadTypeMap.Next(item);
it++;
}
return -1;
}
WebRtc_Word32
RTPReceiver::ReceivePayload(const WebRtc_Word8 payloadType,
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
{
WebRtc_UWord32* rate) const {
CriticalSectionScoped lock(_criticalSectionRTPReceiver);
MapItem* item = _payloadTypeMap.Find(payloadType);
if( NULL == item)
{
std::map<WebRtc_Word8, Payload*>::const_iterator it =
_payloadTypeMap.find(payloadType);
if (it == _payloadTypeMap.end()) {
return -1;
}
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem();
Payload* payload = it->second;
assert(payload);
if(frequency)
{
if(payload->audio)
{
if(frequency) {
if(payload->audio) {
*frequency = payload->typeSpecific.Audio.frequency;
} else
{
} else {
*frequency = 90000;
}
}
if(channels)
{
if(payload->audio)
{
if (channels) {
if(payload->audio) {
*channels = payload->typeSpecific.Audio.channels;
} else
{
} else {
*channels = 1;
}
}
if (rate)
{
if(payload->audio)
{
if (rate) {
if(payload->audio) {
*rate = payload->typeSpecific.Audio.rate;
} else
{
} else {
assert(false);
*rate = 0;
}
}
if(payloadName)
{
if (payloadName) {
memcpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE);
}
return 0;
}
WebRtc_Word32
RTPReceiver::RemotePayload(WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE],
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_UWord8* channels) const {
if(_lastReceivedPayloadType == -1) {
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__);
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( NULL != item)
{
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem();
if(payload)
{
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 )
{
if (payloadType) {
*payloadType = _lastReceivedPayloadType;
}
if(frequency)
{
if(payload->audio)
{
if (frequency) {
if (payload->audio) {
*frequency = payload->typeSpecific.Audio.frequency;
} else
{
} else {
*frequency = 90000;
}
}
if(channels)
{
if(payload->audio)
{
if (channels) {
if (payload->audio) {
*channels = payload->typeSpecific.Audio.channels;
} else
{
} else {
*channels = 1;
}
}
return 0;
}
}
return -1;
}
WebRtc_Word32
RTPReceiver::RegisterRtpHeaderExtension(const RTPExtensionType type,
@ -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 {
std::map<WebRtc_Word8, Payload*>::const_iterator it =
_payloadTypeMap.find(payloadType);
// check that this is a registered payload type
if(item == NULL)
{
if (it == _payloadTypeMap.end()) {
return -1;
}
payload = (ModuleRTPUtility::Payload*)item->GetItem();
if(payload == NULL)
{
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,9 +1119,7 @@ RTPReceiver::SetSSRCFilter(const bool enable, const WebRtc_UWord32 allowedSSRC)
}
// no criticalsection when called
void
RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader)
{
void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader) {
bool newSSRC = false;
bool reInitializeDecoder = false;
WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE];
@ -1201,8 +1131,9 @@ RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader)
{
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;
// reset last report
@ -1213,68 +1144,62 @@ RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader)
_lastReceivedSequenceNumber = 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 (rtpHeader->header.payloadType == _lastReceivedPayloadType)
{
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)
{
std::map<WebRtc_Word8, Payload*>::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)
{
if(payload->audio) {
frequency = payload->typeSpecific.Audio.frequency;
channels = payload->typeSpecific.Audio.channels;
rate = payload->typeSpecific.Audio.rate;
} else
{
} else {
frequency = 90000;
}
}
}
}
}
_SSRC = rtpHeader->header.ssrc;
}
}
if(newSSRC)
{
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)
{
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,
WebRtc_Word32 RTPReceiver::CheckPayloadChanged(
const WebRtcRTPHeader* rtpHeader,
const WebRtc_Word8 firstPayloadByte,
bool& isRED,
ModuleRTPUtility::AudioPayload& audioSpecificPayload,
ModuleRTPUtility::VideoPayload& videoSpecificPayload)
{
AudioPayload& audioSpecificPayload,
VideoPayload& videoSpecificPayload) {
bool reInitializeDecoder = false;
WebRtc_Word8 payloadName[RTP_PAYLOAD_NAME_SIZE];
@ -1283,123 +1208,112 @@ RTPReceiver::CheckPayloadChanged(const WebRtcRTPHeader* rtpHeader,
{
CriticalSectionScoped lock(_criticalSectionRTPReceiver);
if (payloadType != _lastReceivedPayloadType)
{
if (REDPayloadType(payloadType))
{
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 (payloadType == _lastReceivedPayloadType) {
if(_audio)
{
memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific, sizeof(_lastReceivedAudioSpecific));
} else
{
memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific, sizeof(_lastReceivedVideoSpecific));
memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific,
sizeof(_lastReceivedAudioSpecific));
} else {
memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific,
sizeof(_lastReceivedVideoSpecific));
}
return 0;
}
}
if(_audio)
{
if(TelephoneEventPayloadType(payloadType))
{
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))
{
if (CNGPayloadType(payloadType, audioSpecificPayload.frequency)) {
// don't do callbacks for DTMF packets
isRED = false;
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
if(item == NULL)
{
if (it == _payloadTypeMap.end()) {
return -1;
}
memset(payloadName, 0, sizeof(payloadName));
ModuleRTPUtility::Payload* payload = (ModuleRTPUtility::Payload*)item->GetItem();
if(payload == NULL)
{
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(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)
{
} else {
if (_lastReceivedMediaPayloadType == _lastReceivedPayloadType) {
// Only reset the decoder if the media codec type has changed.
reInitializeDecoder = false;
}
_lastReceivedMediaPayloadType = _lastReceivedPayloadType;
}
}
if(reInitializeDecoder)
{
if (reInitializeDecoder) {
// reset statistics
ResetStatistics();
}
}else
{
} else {
if(_audio)
{
memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific, sizeof(_lastReceivedAudioSpecific));
memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific,
sizeof(_lastReceivedAudioSpecific));
} else
{
memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific, sizeof(_lastReceivedVideoSpecific));
memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific,
sizeof(_lastReceivedVideoSpecific));
}
isRED = false;
}
} // end critsect
if(reInitializeDecoder)
{
if (reInitializeDecoder) {
CriticalSectionScoped lock(_criticalSectionCbs);
if(_cbRtpFeedback)
{
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);
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);
} 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
}
}

View File

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

View File

@ -24,7 +24,6 @@ RTPReceiverAudio::RTPReceiverAudio(const WebRtc_Word32 id):
_telephoneEventForwardToDecoder(false),
_telephoneEventDetectEndOfTone(false),
_telephoneEventPayloadType(-1),
_telephoneEventReported(),
_cngNBPayloadType(-1),
_cngWBPayloadType(-1),
_cngSWBPayloadType(-1),
@ -41,19 +40,15 @@ RTPReceiverAudio::~RTPReceiverAudio()
delete _criticalSectionFeedback;
}
WebRtc_Word32
RTPReceiverAudio::Init()
{
WebRtc_Word32 RTPReceiverAudio::Init() {
_lastReceivedFrequency = 8000;
_telephoneEvent = false;
_telephoneEventForwardToDecoder = false;
_telephoneEventDetectEndOfTone = false;
_telephoneEventPayloadType = -1;
while(_telephoneEventReported.Size() > 0)
{
_telephoneEventReported.Erase(_telephoneEventReported.First());
}
_telephoneEventReported.clear();
_cngNBPayloadType = -1;
_cngWBPayloadType = -1;
_cngSWBPayloadType = -1;
@ -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<WebRtc_UWord8>::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<WebRtc_UWord8>::iterator first =
_telephoneEventReported.begin();
if(first != _telephoneEventReported.end() && *first > 15)
{
// don't forward non DTMF events
return 0;

View File

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

View File

@ -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();