diff --git a/webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.h b/webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.h index 352537d6ef..2969ecebe6 100644 --- a/webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.h +++ b/webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.h @@ -57,7 +57,7 @@ public: // Add/remove participants as candidates for mixing. virtual int32_t SetMixabilityStatus(MixerParticipant& participant, - const bool mixable) = 0; + bool mixable) = 0; // mixable is set to true if a participant is a candidate for mixing. virtual int32_t MixabilityStatus(MixerParticipant& participant, bool& mixable) = 0; diff --git a/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc b/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc index a8fbe07a14..214068433d 100644 --- a/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc +++ b/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc @@ -19,6 +19,13 @@ namespace webrtc { namespace { +struct ParticipantFramePair { + MixerParticipant* participant; + AudioFrame* audioFrame; +}; + +typedef std::list ParticipantFramePairList; + // Mix |frame| into |mixed_frame|, with saturation protection and upmixing. // These effects are applied to |frame| itself prior to mixing. Assumes that // |mixed_frame| always has at least as many channels as |frame|. Supports @@ -40,20 +47,18 @@ void MixFrames(AudioFrame* mixed_frame, AudioFrame* frame) { } // Return the max number of channels from a |list| composed of AudioFrames. -int MaxNumChannels(const ListWrapper& list) { - ListItem* item = list.First(); +int MaxNumChannels(const AudioFrameList* list) { int max_num_channels = 1; - while (item) { - AudioFrame* frame = static_cast(item->GetItem()); - max_num_channels = std::max(max_num_channels, frame->num_channels_); - item = list.Next(item); + for (AudioFrameList::const_iterator iter = list->begin(); + iter != list->end(); + ++iter) { + max_num_channels = std::max(max_num_channels, (*iter)->num_channels_); } return max_num_channels; } void SetParticipantStatistics(ParticipantStatistics* stats, - const AudioFrame& frame) -{ + const AudioFrame& frame) { stats->participant = frame.id_; stats->level = 0; // TODO(andrew): to what should this be set? } @@ -61,58 +66,47 @@ void SetParticipantStatistics(ParticipantStatistics* stats, } // namespace MixerParticipant::MixerParticipant() - : _mixHistory(new MixHistory()) -{ + : _mixHistory(new MixHistory()) { } -MixerParticipant::~MixerParticipant() -{ +MixerParticipant::~MixerParticipant() { delete _mixHistory; } -int32_t MixerParticipant::IsMixed(bool& mixed) const -{ +int32_t MixerParticipant::IsMixed(bool& mixed) const { return _mixHistory->IsMixed(mixed); } MixHistory::MixHistory() - : _isMixed(0) -{ + : _isMixed(0) { } -MixHistory::~MixHistory() -{ +MixHistory::~MixHistory() { } -int32_t MixHistory::IsMixed(bool& mixed) const -{ +int32_t MixHistory::IsMixed(bool& mixed) const { mixed = _isMixed; return 0; } -int32_t MixHistory::WasMixed(bool& wasMixed) const -{ +int32_t MixHistory::WasMixed(bool& wasMixed) const { // Was mixed is the same as is mixed depending on perspective. This function // is for the perspective of AudioConferenceMixerImpl. return IsMixed(wasMixed); } -int32_t MixHistory::SetIsMixed(const bool mixed) -{ +int32_t MixHistory::SetIsMixed(const bool mixed) { _isMixed = mixed; return 0; } -void MixHistory::ResetMixedStatus() -{ +void MixHistory::ResetMixedStatus() { _isMixed = false; } -AudioConferenceMixer* AudioConferenceMixer::Create(int id) -{ +AudioConferenceMixer* AudioConferenceMixer::Create(int id) { AudioConferenceMixerImpl* mixer = new AudioConferenceMixerImpl(id); - if(!mixer->Init()) - { + if(!mixer->Init()) { delete mixer; return NULL; } @@ -140,11 +134,9 @@ AudioConferenceMixerImpl::AudioConferenceMixerImpl(int id) _timeStamp(0), _timeScheduler(kProcessPeriodicityInMs), _mixedAudioLevel(), - _processCalls(0) -{} + _processCalls(0) {} -bool AudioConferenceMixerImpl::Init() -{ +bool AudioConferenceMixerImpl::Init() { _crit.reset(CriticalSectionWrapper::CreateCriticalSection()); if (_crit.get() == NULL) return false; @@ -188,25 +180,21 @@ bool AudioConferenceMixerImpl::Init() return true; } -AudioConferenceMixerImpl::~AudioConferenceMixerImpl() -{ +AudioConferenceMixerImpl::~AudioConferenceMixerImpl() { MemoryPool::DeleteMemoryPool(_audioFramePool); assert(_audioFramePool == NULL); } -int32_t AudioConferenceMixerImpl::ChangeUniqueId(const int32_t id) -{ +int32_t AudioConferenceMixerImpl::ChangeUniqueId(const int32_t id) { _id = id; return 0; } // Process should be called every kProcessPeriodicityInMs ms -int32_t AudioConferenceMixerImpl::TimeUntilNextProcess() -{ +int32_t AudioConferenceMixerImpl::TimeUntilNextProcess() { int32_t timeUntilNextProcess = 0; CriticalSectionScoped cs(_crit.get()); - if(_timeScheduler.TimeToNextUpdate(timeUntilNextProcess) != 0) - { + if(_timeScheduler.TimeToNextUpdate(timeUntilNextProcess) != 0) { WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, _id, "failed in TimeToNextUpdate() call"); // Sanity check @@ -216,9 +204,8 @@ int32_t AudioConferenceMixerImpl::TimeUntilNextProcess() return timeUntilNextProcess; } -int32_t AudioConferenceMixerImpl::Process() -{ - uint32_t remainingParticipantsAllowedToMix = +int32_t AudioConferenceMixerImpl::Process() { + size_t remainingParticipantsAllowedToMix = kMaximumAmountOfMixedParticipants; { CriticalSectionScoped cs(_crit.get()); @@ -229,9 +216,9 @@ int32_t AudioConferenceMixerImpl::Process() _timeScheduler.UpdateScheduler(); } - ListWrapper mixList; - ListWrapper rampOutList; - ListWrapper additionalFramesList; + AudioFrameList mixList; + AudioFrameList rampOutList; + AudioFrameList additionalFramesList; std::map mixedParticipantsMap; { CriticalSectionScoped cs(_cbCrit.get()); @@ -242,41 +229,34 @@ int32_t AudioConferenceMixerImpl::Process() // information. // TODO(henrike): this is probably more appropriate to do in // GetLowestMixingFrequency(). - if (lowFreq == 12000) - { + if (lowFreq == 12000) { lowFreq = 16000; } else if (lowFreq == 24000) { lowFreq = 32000; } - if(lowFreq <= 0) - { + if(lowFreq <= 0) { CriticalSectionScoped cs(_crit.get()); _processCalls--; return 0; - } else { - switch(lowFreq) - { + } else { + switch(lowFreq) { case 8000: - if(OutputFrequency() != kNbInHz) - { + if(OutputFrequency() != kNbInHz) { SetOutputFrequency(kNbInHz); } break; case 16000: - if(OutputFrequency() != kWbInHz) - { + if(OutputFrequency() != kWbInHz) { SetOutputFrequency(kWbInHz); } break; case 32000: - if(OutputFrequency() != kSwbInHz) - { + if(OutputFrequency() != kSwbInHz) { SetOutputFrequency(kSwbInHz); } break; case 48000: - if(OutputFrequency() != kFbInHz) - { + if(OutputFrequency() != kFbInHz) { SetOutputFrequency(kFbInHz); } break; @@ -289,19 +269,17 @@ int32_t AudioConferenceMixerImpl::Process() } } - UpdateToMix(mixList, rampOutList, &mixedParticipantsMap, + UpdateToMix(&mixList, &rampOutList, &mixedParticipantsMap, remainingParticipantsAllowedToMix); - GetAdditionalAudio(additionalFramesList); + GetAdditionalAudio(&additionalFramesList); UpdateMixedStatus(mixedParticipantsMap); - _scratchParticipantsToMixAmount = - static_cast(mixedParticipantsMap.size()); + _scratchParticipantsToMixAmount = mixedParticipantsMap.size(); } // Get an AudioFrame for mixing from the memory pool. AudioFrame* mixedAudio = NULL; - if(_audioFramePool->PopMemory(mixedAudio) == -1) - { + if(_audioFramePool->PopMemory(mixedAudio) == -1) { WEBRTC_TRACE(kTraceMemory, kTraceAudioMixerServer, _id, "failed PopMemory() call"); assert(false); @@ -318,9 +296,9 @@ int32_t AudioConferenceMixerImpl::Process() // with an API instead of dynamically. // Find the max channels over all mixing lists. - const int num_mixed_channels = std::max(MaxNumChannels(mixList), - std::max(MaxNumChannels(additionalFramesList), - MaxNumChannels(rampOutList))); + const int num_mixed_channels = std::max(MaxNumChannels(&mixList), + std::max(MaxNumChannels(&additionalFramesList), + MaxNumChannels(&rampOutList))); mixedAudio->UpdateFrame(-1, _timeStamp, NULL, 0, _outputFrequency, AudioFrame::kNormalSpeech, @@ -328,18 +306,15 @@ int32_t AudioConferenceMixerImpl::Process() _timeStamp += _sampleSize; - MixFromList(*mixedAudio, mixList); - MixAnonomouslyFromList(*mixedAudio, additionalFramesList); - MixAnonomouslyFromList(*mixedAudio, rampOutList); + MixFromList(*mixedAudio, &mixList); + MixAnonomouslyFromList(*mixedAudio, &additionalFramesList); + MixAnonomouslyFromList(*mixedAudio, &rampOutList); - if(mixedAudio->samples_per_channel_ == 0) - { + if(mixedAudio->samples_per_channel_ == 0) { // Nothing was mixed, set the audio samples to silence. mixedAudio->samples_per_channel_ = _sampleSize; mixedAudio->Mute(); - } - else - { + } else { // Only call the limiter if we have something to mix. if(!LimitMixedAudio(*mixedAudio)) retval = -1; @@ -348,12 +323,10 @@ int32_t AudioConferenceMixerImpl::Process() _mixedAudioLevel.ComputeLevel(mixedAudio->data_,_sampleSize); audioLevel = _mixedAudioLevel.GetLevel(); - if(_mixerStatusCb) - { + if(_mixerStatusCb) { _scratchVadPositiveParticipantsAmount = 0; - UpdateVADPositiveParticipants(mixList); - if(_amountOf10MsUntilNextCallback-- == 0) - { + UpdateVADPositiveParticipants(&mixList); + if(_amountOf10MsUntilNextCallback-- == 0) { _amountOf10MsUntilNextCallback = _amountOf10MsBetweenCallbacks; timeForMixerCallback = true; } @@ -362,8 +335,7 @@ int32_t AudioConferenceMixerImpl::Process() { CriticalSectionScoped cs(_cbCrit.get()); - if(_mixReceiver != NULL) - { + if(_mixReceiver != NULL) { const AudioFrame** dummy = NULL; _mixReceiver->NewMixedAudio( _id, @@ -373,12 +345,11 @@ int32_t AudioConferenceMixerImpl::Process() } if((_mixerStatusCallback != NULL) && - timeForMixerCallback) - { + timeForMixerCallback) { _mixerStatusCallback->MixedParticipants( _id, _scratchMixedParticipants, - _scratchParticipantsToMixAmount); + static_cast(_scratchParticipantsToMixAmount)); _mixerStatusCallback->VADPositiveParticipants( _id, @@ -390,9 +361,9 @@ int32_t AudioConferenceMixerImpl::Process() // Reclaim all outstanding memory. _audioFramePool->PushMemory(mixedAudio); - ClearAudioFrameList(mixList); - ClearAudioFrameList(rampOutList); - ClearAudioFrameList(additionalFramesList); + ClearAudioFrameList(&mixList); + ClearAudioFrameList(&rampOutList); + ClearAudioFrameList(&additionalFramesList); { CriticalSectionScoped cs(_crit.get()); _processCalls--; @@ -401,22 +372,18 @@ int32_t AudioConferenceMixerImpl::Process() } int32_t AudioConferenceMixerImpl::RegisterMixedStreamCallback( - AudioMixerOutputReceiver& mixReceiver) -{ + AudioMixerOutputReceiver& mixReceiver) { CriticalSectionScoped cs(_cbCrit.get()); - if(_mixReceiver != NULL) - { + if(_mixReceiver != NULL) { return -1; } _mixReceiver = &mixReceiver; return 0; } -int32_t AudioConferenceMixerImpl::UnRegisterMixedStreamCallback() -{ +int32_t AudioConferenceMixerImpl::UnRegisterMixedStreamCallback() { CriticalSectionScoped cs(_cbCrit.get()); - if(_mixReceiver == NULL) - { + if(_mixReceiver == NULL) { return -1; } _mixReceiver = NULL; @@ -424,8 +391,7 @@ int32_t AudioConferenceMixerImpl::UnRegisterMixedStreamCallback() } int32_t AudioConferenceMixerImpl::SetOutputFrequency( - const Frequency frequency) -{ + const Frequency frequency) { CriticalSectionScoped cs(_crit.get()); _outputFrequency = frequency; @@ -435,18 +401,15 @@ int32_t AudioConferenceMixerImpl::SetOutputFrequency( } AudioConferenceMixer::Frequency -AudioConferenceMixerImpl::OutputFrequency() const -{ +AudioConferenceMixerImpl::OutputFrequency() const { CriticalSectionScoped cs(_crit.get()); return _outputFrequency; } int32_t AudioConferenceMixerImpl::RegisterMixerStatusCallback( AudioMixerStatusReceiver& mixerStatusCallback, - const uint32_t amountOf10MsBetweenCallbacks) -{ - if(amountOf10MsBetweenCallbacks == 0) - { + const uint32_t amountOf10MsBetweenCallbacks) { + if(amountOf10MsBetweenCallbacks == 0) { WEBRTC_TRACE( kTraceWarning, kTraceAudioMixerServer, @@ -456,8 +419,7 @@ int32_t AudioConferenceMixerImpl::RegisterMixerStatusCallback( } { CriticalSectionScoped cs(_cbCrit.get()); - if(_mixerStatusCallback != NULL) - { + if(_mixerStatusCallback != NULL) { WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, _id, "Mixer status callback already registered"); return -1; @@ -473,8 +435,7 @@ int32_t AudioConferenceMixerImpl::RegisterMixerStatusCallback( return 0; } -int32_t AudioConferenceMixerImpl::UnRegisterMixerStatusCallback() -{ +int32_t AudioConferenceMixerImpl::UnRegisterMixerStatusCallback() { { CriticalSectionScoped cs(_crit.get()); if(!_mixerStatusCb) @@ -494,38 +455,31 @@ int32_t AudioConferenceMixerImpl::UnRegisterMixerStatusCallback() int32_t AudioConferenceMixerImpl::SetMixabilityStatus( MixerParticipant& participant, - const bool mixable) -{ - if (!mixable) - { + bool mixable) { + if (!mixable) { // Anonymous participants are in a separate list. Make sure that the // participant is in the _participantList if it is being mixed. SetAnonymousMixabilityStatus(participant, false); } - uint32_t numMixedParticipants; + size_t numMixedParticipants; { CriticalSectionScoped cs(_cbCrit.get()); const bool isMixed = - IsParticipantInList(participant,_participantList); + IsParticipantInList(participant, &_participantList); // API must be called with a new state. - if(!(mixable ^ isMixed)) - { + if(!(mixable ^ isMixed)) { WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, _id, "Mixable is aready %s", isMixed ? "ON" : "off"); return -1; } bool success = false; - if(mixable) - { - success = AddParticipantToList(participant,_participantList); + if(mixable) { + success = AddParticipantToList(participant, &_participantList); + } else { + success = RemoveParticipantFromList(participant, &_participantList); } - else - { - success = RemoveParticipantFromList(participant,_participantList); - } - if(!success) - { + if(!success) { WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, _id, "failed to %s participant", mixable ? "add" : "remove"); @@ -533,13 +487,12 @@ int32_t AudioConferenceMixerImpl::SetMixabilityStatus( return -1; } - int numMixedNonAnonymous = _participantList.GetSize(); - if (numMixedNonAnonymous > kMaximumAmountOfMixedParticipants) - { + size_t numMixedNonAnonymous = _participantList.size(); + if (numMixedNonAnonymous > kMaximumAmountOfMixedParticipants) { numMixedNonAnonymous = kMaximumAmountOfMixedParticipants; } - numMixedParticipants = numMixedNonAnonymous + - _additionalParticipantList.GetSize(); + numMixedParticipants = + numMixedNonAnonymous + _additionalParticipantList.size(); } // A MixerParticipant was added or removed. Make sure the scratch // buffer is updated if necessary. @@ -551,40 +504,34 @@ int32_t AudioConferenceMixerImpl::SetMixabilityStatus( int32_t AudioConferenceMixerImpl::MixabilityStatus( MixerParticipant& participant, - bool& mixable) -{ + bool& mixable) { CriticalSectionScoped cs(_cbCrit.get()); - mixable = IsParticipantInList(participant, _participantList); + mixable = IsParticipantInList(participant, &_participantList); return 0; } int32_t AudioConferenceMixerImpl::SetAnonymousMixabilityStatus( - MixerParticipant& participant, const bool anonymous) -{ + MixerParticipant& participant, const bool anonymous) { CriticalSectionScoped cs(_cbCrit.get()); - if(IsParticipantInList(participant, _additionalParticipantList)) - { - if(anonymous) - { + if(IsParticipantInList(participant, &_additionalParticipantList)) { + if(anonymous) { return 0; } - if(!RemoveParticipantFromList(participant, _additionalParticipantList)) - { + if(!RemoveParticipantFromList(participant, + &_additionalParticipantList)) { WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, _id, "unable to remove participant from anonymous list"); assert(false); return -1; } - return AddParticipantToList(participant, _participantList) ? 0 : -1; + return AddParticipantToList(participant, &_participantList) ? 0 : -1; } - if(!anonymous) - { + if(!anonymous) { return 0; } const bool mixable = RemoveParticipantFromList(participant, - _participantList); - if(!mixable) - { + &_participantList); + if(!mixable) { WEBRTC_TRACE( kTraceWarning, kTraceAudioMixerServer, @@ -594,39 +541,33 @@ int32_t AudioConferenceMixerImpl::SetAnonymousMixabilityStatus( // already registered. return -1; } - return AddParticipantToList(participant, _additionalParticipantList) ? + return AddParticipantToList(participant, &_additionalParticipantList) ? 0 : -1; } int32_t AudioConferenceMixerImpl::AnonymousMixabilityStatus( - MixerParticipant& participant, bool& mixable) -{ + MixerParticipant& participant, bool& mixable) { CriticalSectionScoped cs(_cbCrit.get()); mixable = IsParticipantInList(participant, - _additionalParticipantList); + &_additionalParticipantList); return 0; } int32_t AudioConferenceMixerImpl::SetMinimumMixingFrequency( - Frequency freq) -{ + Frequency freq) { // Make sure that only allowed sampling frequencies are used. Use closest // higher sampling frequency to avoid losing information. - if (static_cast(freq) == 12000) - { + if (static_cast(freq) == 12000) { freq = kWbInHz; } else if (static_cast(freq) == 24000) { freq = kSwbInHz; } if((freq == kNbInHz) || (freq == kWbInHz) || (freq == kSwbInHz) || - (freq == kLowestPossible)) - { + (freq == kLowestPossible)) { _minimumMixingFreq=freq; return 0; - } - else - { + } else { WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, _id, "SetMinimumMixingFrequency incorrect frequency: %i",freq); assert(false); @@ -636,20 +577,17 @@ int32_t AudioConferenceMixerImpl::SetMinimumMixingFrequency( // Check all AudioFrames that are to be mixed. The highest sampling frequency // found is the lowest that can be used without losing information. -int32_t AudioConferenceMixerImpl::GetLowestMixingFrequency() -{ +int32_t AudioConferenceMixerImpl::GetLowestMixingFrequency() { const int participantListFrequency = - GetLowestMixingFrequencyFromList(_participantList); + GetLowestMixingFrequencyFromList(&_participantList); const int anonymousListFrequency = - GetLowestMixingFrequencyFromList(_additionalParticipantList); + GetLowestMixingFrequencyFromList(&_additionalParticipantList); const int highestFreq = (participantListFrequency > anonymousListFrequency) ? participantListFrequency : anonymousListFrequency; // Check if the user specified a lowest mixing frequency. - if(_minimumMixingFreq != kLowestPossible) - { - if(_minimumMixingFreq > highestFreq) - { + if(_minimumMixingFreq != kLowestPossible) { + if(_minimumMixingFreq > highestFreq) { return _minimumMixingFreq; } } @@ -657,60 +595,47 @@ int32_t AudioConferenceMixerImpl::GetLowestMixingFrequency() } int32_t AudioConferenceMixerImpl::GetLowestMixingFrequencyFromList( - ListWrapper& mixList) -{ + MixerParticipantList* mixList) { int32_t highestFreq = 8000; - ListItem* item = mixList.First(); - while(item) - { - MixerParticipant* participant = - static_cast(item->GetItem()); - const int32_t neededFrequency = participant->NeededFrequency(_id); - if(neededFrequency > highestFreq) - { + for (MixerParticipantList::iterator iter = mixList->begin(); + iter != mixList->end(); + ++iter) { + const int32_t neededFrequency = (*iter)->NeededFrequency(_id); + if(neededFrequency > highestFreq) { highestFreq = neededFrequency; } - item = mixList.Next(item); } return highestFreq; } void AudioConferenceMixerImpl::UpdateToMix( - ListWrapper& mixList, - ListWrapper& rampOutList, + AudioFrameList* mixList, + AudioFrameList* rampOutList, std::map* mixParticipantList, - uint32_t& maxAudioFrameCounter) { + size_t& maxAudioFrameCounter) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "UpdateToMix(mixList,rampOutList,mixParticipantList,%d)", maxAudioFrameCounter); - const uint32_t mixListStartSize = mixList.GetSize(); - ListWrapper activeList; // Elements are AudioFrames + const size_t mixListStartSize = mixList->size(); + AudioFrameList activeList; // Struct needed by the passive lists to keep track of which AudioFrame // belongs to which MixerParticipant. - struct ParticipantFramePair - { - MixerParticipant* participant; - AudioFrame* audioFrame; - }; - ListWrapper passiveWasNotMixedList; // Elements are MixerParticipant - ListWrapper passiveWasMixedList; // Elements are MixerParticipant - ListItem* item = _participantList.First(); - while(item) - { + ParticipantFramePairList passiveWasNotMixedList; + ParticipantFramePairList passiveWasMixedList; + for (MixerParticipantList::iterator participant = _participantList.begin(); + participant != _participantList.end(); + ++participant) { // Stop keeping track of passive participants if there are already // enough participants available (they wont be mixed anyway). bool mustAddToPassiveList = (maxAudioFrameCounter > - (activeList.GetSize() + - passiveWasMixedList.GetSize() + - passiveWasNotMixedList.GetSize())); + (activeList.size() + + passiveWasMixedList.size() + + passiveWasNotMixedList.size())); - MixerParticipant* participant = static_cast( - item->GetItem()); bool wasMixed = false; - participant->_mixHistory->WasMixed(wasMixed); + (*participant)->_mixHistory->WasMixed(wasMixed); AudioFrame* audioFrame = NULL; - if(_audioFramePool->PopMemory(audioFrame) == -1) - { + if(_audioFramePool->PopMemory(audioFrame) == -1) { WEBRTC_TRACE(kTraceMemory, kTraceAudioMixerServer, _id, "failed PopMemory() call"); assert(false); @@ -718,56 +643,46 @@ void AudioConferenceMixerImpl::UpdateToMix( } audioFrame->sample_rate_hz_ = _outputFrequency; - if(participant->GetAudioFrame(_id,*audioFrame) != 0) - { + if((*participant)->GetAudioFrame(_id,*audioFrame) != 0) { WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, _id, "failed to GetAudioFrame() from participant"); _audioFramePool->PushMemory(audioFrame); - item = _participantList.Next(item); continue; } // TODO(henrike): this assert triggers in some test cases where SRTP is // used which prevents NetEQ from making a VAD. Temporarily disable this // assert until the problem is fixed on a higher level. // assert(audioFrame->vad_activity_ != AudioFrame::kVadUnknown); - if (audioFrame->vad_activity_ == AudioFrame::kVadUnknown) - { + if (audioFrame->vad_activity_ == AudioFrame::kVadUnknown) { WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, _id, "invalid VAD state from participant"); } - if(audioFrame->vad_activity_ == AudioFrame::kVadActive) - { - if(!wasMixed) - { + if(audioFrame->vad_activity_ == AudioFrame::kVadActive) { + if(!wasMixed) { RampIn(*audioFrame); } - if(activeList.GetSize() >= maxAudioFrameCounter) - { + if(activeList.size() >= maxAudioFrameCounter) { // There are already more active participants than should be // mixed. Only keep the ones with the highest energy. - ListItem* replaceItem = NULL; + AudioFrameList::iterator replaceItem; CalculateEnergy(*audioFrame); uint32_t lowestEnergy = audioFrame->energy_; - ListItem* activeItem = activeList.First(); - while(activeItem) - { - AudioFrame* replaceFrame = static_cast( - activeItem->GetItem()); - CalculateEnergy(*replaceFrame); - if(replaceFrame->energy_ < lowestEnergy) - { - replaceItem = activeItem; - lowestEnergy = replaceFrame->energy_; + bool found_replace_item = false; + for (AudioFrameList::iterator iter = activeList.begin(); + iter != activeList.end(); + ++iter) { + CalculateEnergy(**iter); + if((*iter)->energy_ < lowestEnergy) { + replaceItem = iter; + lowestEnergy = (*iter)->energy_; + found_replace_item = true; } - activeItem = activeList.Next(activeItem); } - if(replaceItem != NULL) - { - AudioFrame* replaceFrame = static_cast( - replaceItem->GetItem()); + if(found_replace_item) { + AudioFrame* replaceFrame = *replaceItem; bool replaceWasMixed = false; std::map::iterator it = @@ -780,255 +695,219 @@ void AudioConferenceMixerImpl::UpdateToMix( it->second->_mixHistory->WasMixed(replaceWasMixed); mixParticipantList->erase(replaceFrame->id_); - activeList.Erase(replaceItem); + activeList.erase(replaceItem); - activeList.PushFront(static_cast(audioFrame)); - (*mixParticipantList)[audioFrame->id_] = participant; + activeList.push_front(*replaceItem); + (*mixParticipantList)[audioFrame->id_] = *participant; assert(mixParticipantList->size() <= kMaximumAmountOfMixedParticipants); if (replaceWasMixed) { RampOut(*replaceFrame); - rampOutList.PushBack(static_cast(replaceFrame)); - assert(rampOutList.GetSize() <= + rampOutList->push_back(replaceFrame); + assert(rampOutList->size() <= kMaximumAmountOfMixedParticipants); } else { _audioFramePool->PushMemory(replaceFrame); } } else { - if(wasMixed) - { + if(wasMixed) { RampOut(*audioFrame); - rampOutList.PushBack(static_cast(audioFrame)); - assert(rampOutList.GetSize() <= + rampOutList->push_back(audioFrame); + assert(rampOutList->size() <= kMaximumAmountOfMixedParticipants); } else { _audioFramePool->PushMemory(audioFrame); } } } else { - activeList.PushFront(static_cast(audioFrame)); - (*mixParticipantList)[audioFrame->id_] = participant; + activeList.push_front(audioFrame); + (*mixParticipantList)[audioFrame->id_] = *participant; assert(mixParticipantList->size() <= kMaximumAmountOfMixedParticipants); } } else { - if(wasMixed) - { + if(wasMixed) { ParticipantFramePair* pair = new ParticipantFramePair; pair->audioFrame = audioFrame; - pair->participant = participant; - passiveWasMixedList.PushBack(static_cast(pair)); + pair->participant = *participant; + passiveWasMixedList.push_back(pair); } else if(mustAddToPassiveList) { RampIn(*audioFrame); ParticipantFramePair* pair = new ParticipantFramePair; pair->audioFrame = audioFrame; - pair->participant = participant; - passiveWasNotMixedList.PushBack(static_cast(pair)); + pair->participant = *participant; + passiveWasNotMixedList.push_back(pair); } else { _audioFramePool->PushMemory(audioFrame); } } - item = _participantList.Next(item); } - assert(activeList.GetSize() <= maxAudioFrameCounter); + assert(activeList.size() <= maxAudioFrameCounter); // At this point it is known which participants should be mixed. Transfer // this information to this functions output parameters. - while(!activeList.Empty()) - { - ListItem* mixItem = activeList.First(); - mixList.PushBack(mixItem->GetItem()); - activeList.Erase(mixItem); + for (AudioFrameList::iterator iter = activeList.begin(); + iter != activeList.end(); + ++iter) { + mixList->push_back(*iter); } + activeList.clear(); // Always mix a constant number of AudioFrames. If there aren't enough // active participants mix passive ones. Starting with those that was mixed // last iteration. - while(!passiveWasMixedList.Empty()) - { - ListItem* mixItem = passiveWasMixedList.First(); - ParticipantFramePair* pair = static_cast( - mixItem->GetItem()); - if(mixList.GetSize() < maxAudioFrameCounter + mixListStartSize) - { - mixList.PushBack(pair->audioFrame); - (*mixParticipantList)[pair->audioFrame->id_] = - pair->participant; + for (ParticipantFramePairList::iterator iter = passiveWasMixedList.begin(); + iter != passiveWasMixedList.end(); + ++iter) { + if(mixList->size() < maxAudioFrameCounter + mixListStartSize) { + mixList->push_back((*iter)->audioFrame); + (*mixParticipantList)[(*iter)->audioFrame->id_] = + (*iter)->participant; assert(mixParticipantList->size() <= kMaximumAmountOfMixedParticipants); + } else { + _audioFramePool->PushMemory((*iter)->audioFrame); } - else - { - _audioFramePool->PushMemory(pair->audioFrame); - } - delete pair; - passiveWasMixedList.Erase(mixItem); + delete *iter; } // And finally the ones that have not been mixed for a while. - while(!passiveWasNotMixedList.Empty()) - { - ListItem* mixItem = passiveWasNotMixedList.First(); - ParticipantFramePair* pair = static_cast( - mixItem->GetItem()); - if(mixList.GetSize() < maxAudioFrameCounter + mixListStartSize) - { - mixList.PushBack(pair->audioFrame); - (*mixParticipantList)[pair->audioFrame->id_] = pair->participant; + for (ParticipantFramePairList::iterator iter = + passiveWasNotMixedList.begin(); + iter != passiveWasNotMixedList.end(); + ++iter) { + if(mixList->size() < maxAudioFrameCounter + mixListStartSize) { + mixList->push_back((*iter)->audioFrame); + (*mixParticipantList)[(*iter)->audioFrame->id_] = + (*iter)->participant; assert(mixParticipantList->size() <= kMaximumAmountOfMixedParticipants); + } else { + _audioFramePool->PushMemory((*iter)->audioFrame); } - else - { - _audioFramePool->PushMemory(pair->audioFrame); - } - delete pair; - passiveWasNotMixedList.Erase(mixItem); + delete *iter; } - assert(maxAudioFrameCounter + mixListStartSize >= mixList.GetSize()); - maxAudioFrameCounter += mixListStartSize - mixList.GetSize(); + assert(maxAudioFrameCounter + mixListStartSize >= mixList->size()); + maxAudioFrameCounter += mixListStartSize - mixList->size(); } void AudioConferenceMixerImpl::GetAdditionalAudio( - ListWrapper& additionalFramesList) -{ + AudioFrameList* additionalFramesList) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "GetAdditionalAudio(additionalFramesList)"); - ListItem* item = _additionalParticipantList.First(); - while(item) - { - // The GetAudioFrame() callback may remove the current item. Store the - // next item just in case that happens. - ListItem* nextItem = _additionalParticipantList.Next(item); + // The GetAudioFrame() callback may result in the participant being removed + // from additionalParticipantList_. If that happens it will invalidate any + // iterators. Create a copy of the participants list such that the list of + // participants can be traversed safely. + MixerParticipantList additionalParticipantList; + additionalParticipantList.insert(additionalParticipantList.begin(), + _additionalParticipantList.begin(), + _additionalParticipantList.end()); - MixerParticipant* participant = static_cast( - item->GetItem()); + for (MixerParticipantList::iterator participant = + additionalParticipantList.begin(); + participant != additionalParticipantList.end(); + ++participant) { AudioFrame* audioFrame = NULL; - if(_audioFramePool->PopMemory(audioFrame) == -1) - { + if(_audioFramePool->PopMemory(audioFrame) == -1) { WEBRTC_TRACE(kTraceMemory, kTraceAudioMixerServer, _id, "failed PopMemory() call"); assert(false); return; } audioFrame->sample_rate_hz_ = _outputFrequency; - if(participant->GetAudioFrame(_id, *audioFrame) != 0) - { + if((*participant)->GetAudioFrame(_id, *audioFrame) != 0) { WEBRTC_TRACE(kTraceWarning, kTraceAudioMixerServer, _id, "failed to GetAudioFrame() from participant"); _audioFramePool->PushMemory(audioFrame); - item = nextItem; continue; } - if(audioFrame->samples_per_channel_ == 0) - { + if(audioFrame->samples_per_channel_ == 0) { // Empty frame. Don't use it. _audioFramePool->PushMemory(audioFrame); - item = nextItem; continue; } - additionalFramesList.PushBack(static_cast(audioFrame)); - item = nextItem; + additionalFramesList->push_back(audioFrame); } } void AudioConferenceMixerImpl::UpdateMixedStatus( - std::map& mixedParticipantsMap) -{ + std::map& mixedParticipantsMap) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "UpdateMixedStatus(mixedParticipantsMap)"); assert(mixedParticipantsMap.size() <= kMaximumAmountOfMixedParticipants); // Loop through all participants. If they are in the mix map they // were mixed. - ListItem* participantItem = _participantList.First(); - while(participantItem != NULL) - { + for (MixerParticipantList::iterator participant = _participantList.begin(); + participant != _participantList.end(); + ++participant) { bool isMixed = false; - MixerParticipant* participant = - static_cast(participantItem->GetItem()); - for (std::map::iterator it = mixedParticipantsMap.begin(); it != mixedParticipantsMap.end(); ++it) { - if (it->second == participant) { + if (it->second == *participant) { isMixed = true; break; } } - participant->_mixHistory->SetIsMixed(isMixed); - participantItem = _participantList.Next(participantItem); + (*participant)->_mixHistory->SetIsMixed(isMixed); } } -void AudioConferenceMixerImpl::ClearAudioFrameList(ListWrapper& audioFrameList) -{ +void AudioConferenceMixerImpl::ClearAudioFrameList( + AudioFrameList* audioFrameList) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "ClearAudioFrameList(audioFrameList)"); - ListItem* item = audioFrameList.First(); - while(item) - { - AudioFrame* audioFrame = static_cast(item->GetItem()); - _audioFramePool->PushMemory(audioFrame); - audioFrameList.Erase(item); - item = audioFrameList.First(); + for (AudioFrameList::iterator iter = audioFrameList->begin(); + iter != audioFrameList->end(); + ++iter) { + _audioFramePool->PushMemory(*iter); } + audioFrameList->clear(); } void AudioConferenceMixerImpl::UpdateVADPositiveParticipants( - ListWrapper& mixList) -{ + AudioFrameList* mixList) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "UpdateVADPositiveParticipants(mixList)"); - ListItem* item = mixList.First(); - while(item != NULL) - { - AudioFrame* audioFrame = static_cast(item->GetItem()); - CalculateEnergy(*audioFrame); - if(audioFrame->vad_activity_ == AudioFrame::kVadActive) - { + for (AudioFrameList::iterator iter = mixList->begin(); + iter != mixList->end(); + ++iter) { + CalculateEnergy(**iter); + if((*iter)->vad_activity_ == AudioFrame::kVadActive) { _scratchVadPositiveParticipants[ _scratchVadPositiveParticipantsAmount].participant = - audioFrame->id_; + (*iter)->id_; // TODO(andrew): to what should this be set? _scratchVadPositiveParticipants[ _scratchVadPositiveParticipantsAmount].level = 0; _scratchVadPositiveParticipantsAmount++; } - item = mixList.Next(item); } } bool AudioConferenceMixerImpl::IsParticipantInList( MixerParticipant& participant, - ListWrapper& participantList) -{ + MixerParticipantList* participantList) const { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "IsParticipantInList(participant,participantList)"); - ListItem* item = participantList.First(); - while(item != NULL) - { - MixerParticipant* rhsParticipant = - static_cast(item->GetItem()); - if(&participant == rhsParticipant) - { + for (MixerParticipantList::const_iterator iter = participantList->begin(); + iter != participantList->end(); + ++iter) { + if(&participant == *iter) { return true; } - item = participantList.Next(item); } return false; } bool AudioConferenceMixerImpl::AddParticipantToList( MixerParticipant& participant, - ListWrapper& participantList) -{ + MixerParticipantList* participantList) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "AddParticipantToList(participant, participantList)"); - if(participantList.PushBack(static_cast(&participant)) == -1) - { - return false; - } + participantList->push_back(&participant); // Make sure that the mixed status is correct for new MixerParticipant. participant._mixHistory->ResetMixedStatus(); return true; @@ -1036,52 +915,43 @@ bool AudioConferenceMixerImpl::AddParticipantToList( bool AudioConferenceMixerImpl::RemoveParticipantFromList( MixerParticipant& participant, - ListWrapper& participantList) -{ + MixerParticipantList* participantList) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "RemoveParticipantFromList(participant, participantList)"); - ListItem* item = participantList.First(); - while(item) - { - if(item->GetItem() == &participant) - { - participantList.Erase(item); + for (MixerParticipantList::iterator iter = participantList->begin(); + iter != participantList->end(); + ++iter) { + if(*iter == &participant) { + participantList->erase(iter); // Participant is no longer mixed, reset to default. participant._mixHistory->ResetMixedStatus(); return true; } - item = participantList.Next(item); } return false; } int32_t AudioConferenceMixerImpl::MixFromList( AudioFrame& mixedAudio, - const ListWrapper& audioFrameList) -{ + const AudioFrameList* audioFrameList) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "MixFromList(mixedAudio, audioFrameList)"); - uint32_t position = 0; - ListItem* item = audioFrameList.First(); - if(item == NULL) - { - return 0; - } + if(audioFrameList->empty()) return 0; - if(_numMixedParticipants == 1) - { + uint32_t position = 0; + if(_numMixedParticipants == 1) { // No mixing required here; skip the saturation protection. - AudioFrame* audioFrame = static_cast(item->GetItem()); + AudioFrame* audioFrame = audioFrameList->front(); mixedAudio.CopyFrom(*audioFrame); SetParticipantStatistics(&_scratchMixedParticipants[position], *audioFrame); return 0; } - while(item != NULL) - { - if(position >= kMaximumAmountOfMixedParticipants) - { + for (AudioFrameList::const_iterator iter = audioFrameList->begin(); + iter != audioFrameList->end(); + ++iter) { + if(position >= kMaximumAmountOfMixedParticipants) { WEBRTC_TRACE( kTraceMemory, kTraceAudioMixerServer, @@ -1092,14 +962,12 @@ int32_t AudioConferenceMixerImpl::MixFromList( assert(false); position = 0; } - AudioFrame* audioFrame = static_cast(item->GetItem()); - MixFrames(&mixedAudio, audioFrame); + MixFrames(&mixedAudio, (*iter)); SetParticipantStatistics(&_scratchMixedParticipants[position], - *audioFrame); + **iter); position++; - item = audioFrameList.Next(item); } return 0; @@ -1108,35 +976,29 @@ int32_t AudioConferenceMixerImpl::MixFromList( // TODO(andrew): consolidate this function with MixFromList. int32_t AudioConferenceMixerImpl::MixAnonomouslyFromList( AudioFrame& mixedAudio, - const ListWrapper& audioFrameList) -{ + const AudioFrameList* audioFrameList) { WEBRTC_TRACE(kTraceStream, kTraceAudioMixerServer, _id, "MixAnonomouslyFromList(mixedAudio, audioFrameList)"); - ListItem* item = audioFrameList.First(); - if(item == NULL) - return 0; - if(_numMixedParticipants == 1) - { + if(audioFrameList->empty()) return 0; + + if(_numMixedParticipants == 1) { // No mixing required here; skip the saturation protection. - AudioFrame* audioFrame = static_cast(item->GetItem()); + AudioFrame* audioFrame = audioFrameList->front(); mixedAudio.CopyFrom(*audioFrame); return 0; } - while(item != NULL) - { - AudioFrame* audioFrame = static_cast(item->GetItem()); - MixFrames(&mixedAudio, audioFrame); - item = audioFrameList.Next(item); + for (AudioFrameList::const_iterator iter = audioFrameList->begin(); + iter != audioFrameList->end(); + ++iter) { + MixFrames(&mixedAudio, *iter); } return 0; } -bool AudioConferenceMixerImpl::LimitMixedAudio(AudioFrame& mixedAudio) -{ - if(_numMixedParticipants == 1) - { +bool AudioConferenceMixerImpl::LimitMixedAudio(AudioFrame& mixedAudio) { + if(_numMixedParticipants == 1) { return true; } @@ -1155,8 +1017,7 @@ bool AudioConferenceMixerImpl::LimitMixedAudio(AudioFrame& mixedAudio) // negative value is undefined). mixedAudio += mixedAudio; - if(error != _limiter->kNoError) - { + if(error != _limiter->kNoError) { WEBRTC_TRACE(kTraceError, kTraceAudioMixerServer, _id, "Error from AudioProcessing: %d", error); assert(false); diff --git a/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.h b/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.h index a0123f9819..31dc71e5dc 100644 --- a/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.h +++ b/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.h @@ -11,6 +11,7 @@ #ifndef WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_ #define WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_ +#include #include #include "webrtc/engine_configurations.h" @@ -19,13 +20,15 @@ #include "webrtc/modules/audio_conference_mixer/source/memory_pool.h" #include "webrtc/modules/audio_conference_mixer/source/time_scheduler.h" #include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/system_wrappers/interface/list_wrapper.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" namespace webrtc { class AudioProcessing; class CriticalSectionWrapper; +typedef std::list AudioFrameList; +typedef std::list MixerParticipantList; + // Cheshire cat implementation of MixerParticipant's non virtual functions. class MixHistory { @@ -74,7 +77,7 @@ public: const uint32_t amountOf10MsBetweenCallbacks); virtual int32_t UnRegisterMixerStatusCallback(); virtual int32_t SetMixabilityStatus(MixerParticipant& participant, - const bool mixable); + bool mixable); virtual int32_t MixabilityStatus(MixerParticipant& participant, bool& mixable); virtual int32_t SetMinimumMixingFrequency(Frequency freq); @@ -98,18 +101,18 @@ private: // used to be mixed but shouldn't be mixed any longer. These AudioFrames // should be ramped out over this AudioFrame to avoid audio discontinuities. void UpdateToMix( - ListWrapper& mixList, - ListWrapper& rampOutList, + AudioFrameList* mixList, + AudioFrameList* rampOutList, std::map* mixParticipantList, - uint32_t& maxAudioFrameCounter); + size_t& maxAudioFrameCounter); // Return the lowest mixing frequency that can be used without having to // downsample any audio. int32_t GetLowestMixingFrequency(); - int32_t GetLowestMixingFrequencyFromList(ListWrapper& mixList); + int32_t GetLowestMixingFrequencyFromList(MixerParticipantList* mixList); // Return the AudioFrames that should be mixed anonymously. - void GetAdditionalAudio(ListWrapper& additionalFramesList); + void GetAdditionalAudio(AudioFrameList* additionalFramesList); // Update the MixHistory of all MixerParticipants. mixedParticipantsList // should contain a map of MixerParticipants that have been mixed. @@ -117,44 +120,44 @@ private: std::map& mixedParticipantsList); // Clears audioFrameList and reclaims all memory associated with it. - void ClearAudioFrameList(ListWrapper& audioFrameList); + void ClearAudioFrameList(AudioFrameList* audioFrameList); // Update the list of MixerParticipants who have a positive VAD. mixList // should be a list of AudioFrames void UpdateVADPositiveParticipants( - ListWrapper& mixList); + AudioFrameList* mixList); // This function returns true if it finds the MixerParticipant in the // specified list of MixerParticipants. bool IsParticipantInList( MixerParticipant& participant, - ListWrapper& participantList); + MixerParticipantList* participantList) const; // Add/remove the MixerParticipant to the specified // MixerParticipant list. bool AddParticipantToList( MixerParticipant& participant, - ListWrapper& participantList); + MixerParticipantList* participantList); bool RemoveParticipantFromList( MixerParticipant& removeParticipant, - ListWrapper& participantList); + MixerParticipantList* participantList); // Mix the AudioFrames stored in audioFrameList into mixedAudio. int32_t MixFromList( AudioFrame& mixedAudio, - const ListWrapper& audioFrameList); + const AudioFrameList* audioFrameList); // Mix the AudioFrames stored in audioFrameList into mixedAudio. No // record will be kept of this mix (e.g. the corresponding MixerParticipants // will not be marked as IsMixed() int32_t MixAnonomouslyFromList(AudioFrame& mixedAudio, - const ListWrapper& audioFrameList); + const AudioFrameList* audioFrameList); bool LimitMixedAudio(AudioFrame& mixedAudio); // Scratch memory // Note that the scratch memory may only be touched in the scope of // Process(). - uint32_t _scratchParticipantsToMixAmount; + size_t _scratchParticipantsToMixAmount; ParticipantStatistics _scratchMixedParticipants[ kMaximumAmountOfMixedParticipants]; uint32_t _scratchVadPositiveParticipantsAmount; @@ -172,9 +175,9 @@ private: AudioMixerOutputReceiver* _mixReceiver; AudioMixerStatusReceiver* _mixerStatusCallback; - uint32_t _amountOf10MsBetweenCallbacks; - uint32_t _amountOf10MsUntilNextCallback; - bool _mixerStatusCb; + uint32_t _amountOf10MsBetweenCallbacks; + uint32_t _amountOf10MsUntilNextCallback; + bool _mixerStatusCb; // The current sample frequency and sample size when mixing. Frequency _outputFrequency; @@ -184,10 +187,11 @@ private: MemoryPool* _audioFramePool; // List of all participants. Note all lists are disjunct - ListWrapper _participantList; // May be mixed. - ListWrapper _additionalParticipantList; // Always mixed, anonomously. + MixerParticipantList _participantList; // May be mixed. + // Always mixed, anonomously. + MixerParticipantList _additionalParticipantList; - uint32_t _numMixedParticipants; + size_t _numMixedParticipants; uint32_t _timeStamp; diff --git a/webrtc/system_wrappers/interface/list_wrapper.h b/webrtc/system_wrappers/interface/list_wrapper.h deleted file mode 100644 index fe6607195a..0000000000 --- a/webrtc/system_wrappers/interface/list_wrapper.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_ -#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_ - -#include "webrtc/system_wrappers/interface/constructor_magic.h" - -namespace webrtc { - -class CriticalSectionWrapper; - -class ListItem { - friend class ListWrapper; - - public: - ListItem(const void* ptr); - ListItem(const unsigned int item); - virtual ~ListItem(); - void* GetItem() const; - unsigned int GetUnsignedItem() const; - - protected: - ListItem* next_; - ListItem* prev_; - - private: - const void* item_ptr_; - const unsigned int item_; -}; - -class ListWrapper { - public: - ListWrapper(); - virtual ~ListWrapper(); - - // Returns the number of elements stored in the list. - unsigned int GetSize() const; - - // Puts a pointer to anything last in the list. - int PushBack(const void* ptr); - // Puts a pointer to anything first in the list. - int PushFront(const void* ptr); - - // Puts a copy of the specified integer last in the list. - int PushBack(const unsigned int item_id); - // Puts a copy of the specified integer first in the list. - int PushFront(const unsigned int item_id); - - // Pops the first ListItem from the list - int PopFront(); - - // Pops the last ListItem from the list - int PopBack(); - - // Returns true if the list is empty - bool Empty() const; - - // Returns a pointer to the first ListItem in the list. - ListItem* First() const; - - // Returns a pointer to the last ListItem in the list. - ListItem* Last() const; - - // Returns a pointer to the ListItem stored after item in the list. - ListItem* Next(ListItem* item) const; - - // Returns a pointer to the ListItem stored before item in the list. - ListItem* Previous(ListItem* item) const; - - // Removes item from the list. - int Erase(ListItem* item); - - // Insert list item after existing_previous_item. Please note that new_item - // must be created using new ListItem(). The map will take ownership of - // new_item following a successfull insert. If insert fails new_item will - // not be released by the List - int Insert(ListItem* existing_previous_item, - ListItem* new_item); - - // Insert list item before existing_next_item. Please note that new_item - // must be created using new ListItem(). The map will take ownership of - // new_item following a successfull insert. If insert fails new_item will - // not be released by the List - int InsertBefore(ListItem* existing_next_item, - ListItem* new_item); - - private: - void PushBackImpl(ListItem* item); - void PushFrontImpl(ListItem* item); - - CriticalSectionWrapper* critical_section_; - ListItem* first_; - ListItem* last_; - unsigned int size_; -}; - -} // namespace webrtc - -#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_ diff --git a/webrtc/system_wrappers/source/list_no_stl.cc b/webrtc/system_wrappers/source/list_no_stl.cc deleted file mode 100644 index 5c9f5af01c..0000000000 --- a/webrtc/system_wrappers/source/list_no_stl.cc +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/system_wrappers/interface/list_wrapper.h" - -#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" -#include "webrtc/system_wrappers/interface/trace.h" - -namespace webrtc { - -ListItem::ListItem(const void* item) - : next_(0), - prev_(0), - item_ptr_(item), - item_(0) { -} - -ListItem::ListItem(const unsigned int item) - : next_(0), - prev_(0), - item_ptr_(0), - item_(item) { -} - -ListItem::~ListItem() { -} - -void* ListItem::GetItem() const { - return const_cast(item_ptr_); -} - -unsigned int ListItem::GetUnsignedItem() const { - return item_; -} - -ListWrapper::ListWrapper() - : critical_section_(CriticalSectionWrapper::CreateCriticalSection()), - first_(0), - last_(0), - size_(0) { -} - -ListWrapper::~ListWrapper() { - if (!Empty()) { - // TODO(hellner) I'm not sure this loggin is useful. - WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, - "Potential memory leak in ListWrapper"); - // Remove all remaining list items. - while (Erase(First()) == 0) - {} - } - delete critical_section_; -} - -bool ListWrapper::Empty() const { - return !first_ && !last_; -} - -unsigned int ListWrapper::GetSize() const { - return size_; -} - -int ListWrapper::PushBack(const void* ptr) { - ListItem* item = new ListItem(ptr); - CriticalSectionScoped lock(critical_section_); - PushBackImpl(item); - return 0; -} - -int ListWrapper::PushBack(const unsigned int item_id) { - ListItem* item = new ListItem(item_id); - CriticalSectionScoped lock(critical_section_); - PushBackImpl(item); - return 0; -} - -int ListWrapper::PushFront(const unsigned int item_id) { - ListItem* item = new ListItem(item_id); - CriticalSectionScoped lock(critical_section_); - PushFrontImpl(item); - return 0; -} - -int ListWrapper::PushFront(const void* ptr) { - ListItem* item = new ListItem(ptr); - CriticalSectionScoped lock(critical_section_); - PushFrontImpl(item); - return 0; -} - -int ListWrapper::PopFront() { - return Erase(first_); -} - -int ListWrapper::PopBack() { - return Erase(last_); -} - -ListItem* ListWrapper::First() const { - return first_; -} - -ListItem* ListWrapper::Last() const { - return last_; -} - -ListItem* ListWrapper::Next(ListItem* item) const { - if (!item) { - return 0; - } - return item->next_; -} - -ListItem* ListWrapper::Previous(ListItem* item) const { - if (!item) { - return 0; - } - return item->prev_; -} - -int ListWrapper::Insert(ListItem* existing_previous_item, ListItem* new_item) { - if (!new_item) { - return -1; - } - // Allow existing_previous_item to be NULL if the list is empty. - // TODO(hellner) why allow this? Keep it as is for now to avoid - // breaking API contract. - if (!existing_previous_item && !Empty()) { - return -1; - } - CriticalSectionScoped lock(critical_section_); - if (!existing_previous_item) { - PushBackImpl(new_item); - return 0; - } - ListItem* next_item = existing_previous_item->next_; - new_item->next_ = existing_previous_item->next_; - new_item->prev_ = existing_previous_item; - existing_previous_item->next_ = new_item; - if (next_item) { - next_item->prev_ = new_item; - } else { - last_ = new_item; - } - size_++; - return 0; -} - -int ListWrapper::InsertBefore(ListItem* existing_next_item, - ListItem* new_item) { - if (!new_item) { - return -1; - } - // Allow existing_next_item to be NULL if the list is empty. - // Todo: why allow this? Keep it as is for now to avoid breaking API - // contract. - if (!existing_next_item && !Empty()) { - return -1; - } - CriticalSectionScoped lock(critical_section_); - if (!existing_next_item) { - PushBackImpl(new_item); - return 0; - } - - ListItem* previous_item = existing_next_item->prev_; - new_item->next_ = existing_next_item; - new_item->prev_ = previous_item; - existing_next_item->prev_ = new_item; - if (previous_item) { - previous_item->next_ = new_item; - } else { - first_ = new_item; - } - size_++; - return 0; -} - -int ListWrapper::Erase(ListItem* item) { - if (!item) { - return -1; - } - size_--; - ListItem* previous_item = item->prev_; - ListItem* next_item = item->next_; - if (!previous_item) { - if (next_item) { - next_item->prev_ = 0; - } - first_ = next_item; - } else { - previous_item->next_ = next_item; - } - if (!next_item) { - if (previous_item) { - previous_item->next_ = 0; - } - last_ = previous_item; - } else { - next_item->prev_ = previous_item; - } - delete item; - return 0; -} - -void ListWrapper::PushBackImpl(ListItem* item) { - if (Empty()) { - first_ = item; - last_ = item; - size_++; - return; - } - - item->prev_ = last_; - last_->next_ = item; - last_ = item; - size_++; -} - -void ListWrapper::PushFrontImpl(ListItem* item) { - if (Empty()) { - first_ = item; - last_ = item; - size_++; - return; - } - - item->next_ = first_; - first_->prev_ = item; - first_ = item; - size_++; -} - -} // namespace webrtc diff --git a/webrtc/system_wrappers/source/list_no_stl.h b/webrtc/system_wrappers/source/list_no_stl.h deleted file mode 100644 index dcc9209e25..0000000000 --- a/webrtc/system_wrappers/source/list_no_stl.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_ -#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_ - -#include "webrtc/system_wrappers/interface/constructor_magic.h" - -namespace webrtc { - -class CriticalSectionWrapper; - -class ListNoStlItem { - public: - ListNoStlItem(const void* ptr); - ListNoStlItem(const unsigned int item); - virtual ~ListNoStlItem(); - void* GetItem() const; - unsigned int GetUnsignedItem() const; - - protected: - ListNoStlItem* next_; - ListNoStlItem* prev_; - - private: - friend class ListNoStl; - - const void* item_ptr_; - const unsigned int item_; - DISALLOW_COPY_AND_ASSIGN(ListNoStlItem); -}; - -class ListNoStl { - public: - ListNoStl(); - virtual ~ListNoStl(); - - // ListWrapper functions - unsigned int GetSize() const; - int PushBack(const void* ptr); - int PushBack(const unsigned int item_id); - int PushFront(const void* ptr); - int PushFront(const unsigned int item_id); - int PopFront(); - int PopBack(); - bool Empty() const; - ListNoStlItem* First() const; - ListNoStlItem* Last() const; - ListNoStlItem* Next(ListNoStlItem* item) const; - ListNoStlItem* Previous(ListNoStlItem* item) const; - int Erase(ListNoStlItem* item); - int Insert(ListNoStlItem* existing_previous_item, - ListNoStlItem* new_item); - - int InsertBefore(ListNoStlItem* existing_next_item, - ListNoStlItem* new_item); - - private: - void PushBack(ListNoStlItem* item); - void PushFront(ListNoStlItem* item); - - CriticalSectionWrapper* critical_section_; - ListNoStlItem* first_; - ListNoStlItem* last_; - unsigned int size_; - DISALLOW_COPY_AND_ASSIGN(ListNoStl); -}; - -} // namespace webrtc - -#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_ diff --git a/webrtc/system_wrappers/source/list_stl.cc b/webrtc/system_wrappers/source/list_stl.cc deleted file mode 100644 index 81b6f0cc8a..0000000000 --- a/webrtc/system_wrappers/source/list_stl.cc +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/system_wrappers/interface/list_wrapper.h" - -#include "webrtc/system_wrappers/interface/trace.h" - -namespace webrtc { - -ListItem::ListItem(const void* item) - : this_iter_(), - item_ptr_(item), - item_(0) { -} - -ListItem::ListItem(const unsigned int item) - : this_iter_(), - item_ptr_(0), - item_(item) { -} - -ListItem::~ListItem() { -} - -void* ListItem::GetItem() const { - return const_cast(item_ptr_); -} - -unsigned int ListItem::GetUnsignedItem() const { - return item_; -} - -ListWrapper::ListWrapper() - : list_() { -} - -ListWrapper::~ListWrapper() { - if (!Empty()) { - // TODO(hellner) I'm not sure this loggin is useful. - WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, - "Potential memory leak in ListWrapper"); - // Remove all remaining list items. - while (Erase(First()) == 0) {} - } -} - -bool ListWrapper::Empty() const { - return list_.empty(); -} - -unsigned int ListWrapper::GetSize() const { - return list_.size(); -} - -int ListWrapper::PushBack(const void* ptr) { - ListItem* item = new ListItem(ptr); - list_.push_back(item); - return 0; -} - -int ListWrapper::PushBack(const unsigned int item_id) { - ListItem* item = new ListItem(item_id); - list_.push_back(item); - return 0; -} - -int ListWrapper::PushFront(const unsigned int item_id) { - ListItem* item = new ListItem(item_id); - list_.push_front(item); - return 0; -} - -int ListWrapper::PushFront(const void* ptr) { - ListItem* item = new ListItem(ptr); - list_.push_front(item); - return 0; -} - -int ListWrapper::PopFront() { - if (list_.empty()) { - return -1; - } - list_.pop_front(); - return 0; -} - -int ListWrapper::PopBack() { - if (list_.empty()) { - return -1; - } - list_.pop_back(); - return 0; -} - -ListItem* ListWrapper::First() const { - if (list_.empty()) { - return NULL; - } - std::list::iterator item_iter = list_.begin(); - ListItem* return_item = (*item_iter); - return_item->this_iter_ = item_iter; - return return_item; -} - -ListItem* ListWrapper::Last() const { - if (list_.empty()) { - return NULL; - } - // std::list::end() addresses the last item + 1. Decrement so that the - // actual last is accessed. - std::list::iterator item_iter = list_.end(); - --item_iter; - ListItem* return_item = (*item_iter); - return_item->this_iter_ = item_iter; - return return_item; -} - -ListItem* ListWrapper::Next(ListItem* item) const { - if (item == NULL) { - return NULL; - } - std::list::iterator item_iter = item->this_iter_; - ++item_iter; - if (item_iter == list_.end()) { - return NULL; - } - ListItem* return_item = (*item_iter); - return_item->this_iter_ = item_iter; - return return_item; -} - -ListItem* ListWrapper::Previous(ListItem* item) const { - if (item == NULL) { - return NULL; - } - std::list::iterator item_iter = item->this_iter_; - if (item_iter == list_.begin()) { - return NULL; - } - --item_iter; - ListItem* return_item = (*item_iter); - return_item->this_iter_ = item_iter; - return return_item; -} - -int ListWrapper::Insert(ListItem* existing_previous_item, - ListItem* new_item) { - // Allow existing_previous_item to be NULL if the list is empty. - // TODO(hellner) why allow this? Keep it as is for now to avoid - // breaking API contract. - if (!existing_previous_item && !Empty()) { - return -1; - } - - if (!new_item) { - return -1; - } - - std::list::iterator insert_location = list_.begin(); - if (!Empty()) { - insert_location = existing_previous_item->this_iter_; - if (insert_location != list_.end()) { - ++insert_location; - } - } - - list_.insert(insert_location, new_item); - return 0; -} - -int ListWrapper::InsertBefore(ListItem* existing_next_item, - ListItem* new_item) { - // Allow existing_next_item to be NULL if the list is empty. - // Todo: why allow this? Keep it as is for now to avoid breaking API - // contract. - if (!existing_next_item && !Empty()) { - return -1; - } - if (!new_item) { - return -1; - } - - std::list::iterator insert_location = list_.begin(); - if (!Empty()) { - insert_location = existing_next_item->this_iter_; - } - - list_.insert(insert_location, new_item); - return 0; -} - -int ListWrapper::Erase(ListItem* item) { - if (item == NULL) { - return -1; - } - list_.erase(item->this_iter_); - return 0; -} - -} // namespace webrtc diff --git a/webrtc/system_wrappers/source/list_stl.h b/webrtc/system_wrappers/source/list_stl.h deleted file mode 100644 index 29945304f3..0000000000 --- a/webrtc/system_wrappers/source/list_stl.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_ -#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_ - -#include - -#include "webrtc/system_wrappers/interface/constructor_magic.h" - -namespace webrtc { - -class ListItem { - public: - ListItem(const void* ptr); - ListItem(const unsigned int item); - virtual ~ListItem(); - void* GetItem() const; - unsigned int GetUnsignedItem() const; - - private: - friend class ListWrapper; - mutable std::list::iterator this_iter_; - const void* item_ptr_; - const unsigned int item_; - DISALLOW_COPY_AND_ASSIGN(ListItem); -}; - -class ListWrapper { - public: - ListWrapper(); - ~ListWrapper(); - - // ListWrapper functions - unsigned int GetSize() const; - int PushBack(const void* ptr); - int PushBack(const unsigned int item_id); - int PushFront(const void* ptr); - int PushFront(const unsigned int item_id); - int PopFront(); - int PopBack(); - bool Empty() const; - ListItem* First() const; - ListItem* Last() const; - ListItem* Next(ListItem* item) const; - ListItem* Previous(ListItem* item) const; - int Erase(ListItem* item); - int Insert(ListItem* existing_previous_item, ListItem* new_item); - int InsertBefore(ListItem* existing_next_item, ListItem* new_item); - - private: - mutable std::list list_; - DISALLOW_COPY_AND_ASSIGN(ListWrapper); -}; - -} // namespace webrtc - -#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_ diff --git a/webrtc/system_wrappers/source/list_unittest.cc b/webrtc/system_wrappers/source/list_unittest.cc deleted file mode 100644 index 1e4f922a6b..0000000000 --- a/webrtc/system_wrappers/source/list_unittest.cc +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/system_wrappers/interface/list_wrapper.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/system_wrappers/interface/scoped_ptr.h" - -using ::webrtc::ListWrapper; -using ::webrtc::ListItem; -using ::webrtc::scoped_ptr; - -// Note: kNumberOfElements needs to be even. -const unsigned int kNumberOfElements = 10; - -// An opaque implementation of dynamic or statically allocated unsigned ints. -// This class makes it possible to use the exact same code for testing of both -// the dynamic and static implementation of ListWrapper. -// Clarification: ListWrapper has two versions of PushBack(..). It takes an -// unsigned integer or a void pointer. The integer implementation takes care -// of memory management. The void pointer version expect the caller to manage -// the memory associated with the void pointer. -// This class works like the integer version but can be implemented on top of -// either the integer version or void pointer version of ListWrapper. -// Note: the non-virtual fuctions behave the same for both versions. -class ListWrapperSimple { -public: - static ListWrapperSimple* Create(bool static_allocation); - virtual ~ListWrapperSimple() {} - - // These three functions should be used for manipulating ListItems so that - // they are the type corresponding to the underlying implementation. - virtual unsigned int GetUnsignedItem( - const ListItem* item) const = 0; - virtual ListItem* CreateListItem(unsigned int item_id) = 0; - unsigned int GetSize() const { - return list_.GetSize(); - } - virtual int PushBack(const unsigned int item_id) = 0; - virtual int PushFront(const unsigned int item_id) = 0; - virtual int PopFront() = 0; - virtual int PopBack() = 0; - bool Empty() const { - return list_.Empty(); - } - ListItem* First() const { - return list_.First(); - } - ListItem* Last() const { - return list_.Last(); - } - ListItem* Next(ListItem* item) const { - return list_.Next(item); - } - ListItem* Previous(ListItem* item) const { - return list_.Previous(item); - } - virtual int Erase(ListItem* item) = 0; - int Insert(ListItem* existing_previous_item, - ListItem* new_item) { - const int retval = list_.Insert(existing_previous_item, new_item); - if (retval != 0) { - EXPECT_TRUE(DestroyListItem(new_item)); - } - return retval; - } - - int InsertBefore(ListItem* existing_next_item, - ListItem* new_item) { - const int retval = list_.InsertBefore(existing_next_item, new_item); - if (retval != 0) { - EXPECT_TRUE(DestroyListItem(new_item)); - } - return retval; - } -protected: - ListWrapperSimple() {} - - virtual bool DestroyListItemContent(ListItem* item) = 0; - bool DestroyListItem(ListItem* item) { - const bool retval = DestroyListItemContent(item); - delete item; - return retval; - } - - ListWrapper list_; -}; - -void ClearList(ListWrapperSimple* list_wrapper) { - if (list_wrapper == NULL) { - return; - } - ListItem* list_item = list_wrapper->First(); - while (list_item != NULL) { - EXPECT_EQ(list_wrapper->Erase(list_item), 0); - list_item = list_wrapper->First(); - } -} - -class ListWrapperStatic : public ListWrapperSimple { -public: - ListWrapperStatic() {} - virtual ~ListWrapperStatic() { - ClearList(this); - } - - virtual unsigned int GetUnsignedItem(const ListItem* item) const { - return item->GetUnsignedItem(); - } - virtual ListItem* CreateListItem(unsigned int item_id) { - return new ListItem(item_id); - } - virtual bool DestroyListItemContent(ListItem* item) { - return true; - } - virtual int PushBack(const unsigned int item_id) { - return list_.PushBack(item_id); - } - virtual int PushFront(const unsigned int item_id) { - return list_.PushFront(item_id); - } - virtual int PopFront() { - return list_.PopFront(); - } - virtual int PopBack() { - return list_.PopBack(); - } - virtual int Erase(ListItem* item) { - return list_.Erase(item); - } -}; - -class ListWrapperDynamic : public ListWrapperSimple { -public: - ListWrapperDynamic() {} - virtual ~ListWrapperDynamic() { - ClearList(this); - } - - virtual unsigned int GetUnsignedItem(const ListItem* item) const { - const unsigned int* return_value_pointer = - reinterpret_cast(item->GetItem()); - if (return_value_pointer == NULL) { - return -1; - } - return *return_value_pointer; - } - virtual ListItem* CreateListItem(unsigned int item_id) { - unsigned int* item_id_pointer = new unsigned int; - if (item_id_pointer == NULL) { - return NULL; - } - *item_id_pointer = item_id; - ListItem* return_value = new ListItem( - reinterpret_cast(item_id_pointer)); - if (return_value == NULL) { - delete item_id_pointer; - return NULL; - } - return return_value; - } - virtual bool DestroyListItemContent(ListItem* item) { - if (item == NULL) { - return false; - } - bool return_value = false; - unsigned int* item_id_ptr = reinterpret_cast( - item->GetItem()); - if (item_id_ptr != NULL) { - return_value = true; - delete item_id_ptr; - } - return return_value; - } - virtual int PushBack(const unsigned int item_id) { - unsigned int* item_id_ptr = new unsigned int; - if (item_id_ptr == NULL) { - return -1; - } - *item_id_ptr = item_id; - const int return_value = list_.PushBack( - reinterpret_cast(item_id_ptr)); - if (return_value != 0) { - delete item_id_ptr; - } - return return_value; - } - virtual int PushFront(const unsigned int item_id) { - unsigned int* item_id_ptr = new unsigned int; - if (item_id_ptr == NULL) { - return -1; - } - *item_id_ptr = item_id; - const int return_value = list_.PushFront( - reinterpret_cast(item_id_ptr)); - if (return_value != 0) { - delete item_id_ptr; - } - return return_value; - } - virtual int PopFront() { - return Erase(list_.First()); - } - virtual int PopBack() { - return Erase(list_.Last()); - } - virtual int Erase(ListItem* item) { - if (item == NULL) { - return -1; - } - int retval = 0; - if (!DestroyListItemContent(item)) { - retval = -1; - ADD_FAILURE(); - } - if (list_.Erase(item) != 0) { - retval = -1; - } - return retval; - } -}; - -ListWrapperSimple* ListWrapperSimple::Create(bool static_allocation) { - if (static_allocation) { - return new ListWrapperStatic(); - } - return new ListWrapperDynamic(); -} - -ListWrapperSimple* CreateAscendingList(bool static_allocation) { - ListWrapperSimple* return_value = ListWrapperSimple::Create( - static_allocation); - if (return_value == NULL) { - return NULL; - } - for (unsigned int i = 0; i < kNumberOfElements; ++i) { - if (return_value->PushBack(i) == -1) { - ClearList(return_value); - delete return_value; - return NULL; - } - } - return return_value; -} - -ListWrapperSimple* CreateDescendingList(bool static_allocation) { - ListWrapperSimple* return_value = ListWrapperSimple::Create( - static_allocation); - if (return_value == NULL) { - return NULL; - } - for (unsigned int i = 0; i < kNumberOfElements; ++i) { - if (return_value->PushBack(kNumberOfElements - i - 1) == -1) { - ClearList(return_value); - delete return_value; - return NULL; - } - } - return return_value; -} - -// [0,kNumberOfElements - 1,1,kNumberOfElements - 2,...] (this is why -// kNumberOfElements need to be even) -ListWrapperSimple* CreateInterleavedList(bool static_allocation) { - ListWrapperSimple* return_value = ListWrapperSimple::Create( - static_allocation); - if (return_value == NULL) { - return NULL; - } - unsigned int uneven_count = 0; - unsigned int even_count = 0; - for (unsigned int i = 0; i < kNumberOfElements; i++) { - unsigned int push_value = 0; - if ((i % 2) == 0) { - push_value = even_count; - even_count++; - } else { - push_value = kNumberOfElements - uneven_count - 1; - uneven_count++; - } - if (return_value->PushBack(push_value) == -1) { - ClearList(return_value); - delete return_value; - return NULL; - } - } - return return_value; -} - -void PrintList(const ListWrapperSimple* list) { - ListItem* list_item = list->First(); - printf("["); - while (list_item != NULL) { - printf("%3u", list->GetUnsignedItem(list_item)); - list_item = list->Next(list_item); - } - printf("]\n"); -} - -bool CompareLists(const ListWrapperSimple* lhs, const ListWrapperSimple* rhs) { - const unsigned int list_size = lhs->GetSize(); - if (lhs->GetSize() != rhs->GetSize()) { - return false; - } - if (lhs->Empty()) { - return rhs->Empty(); - } - unsigned int i = 0; - ListItem* lhs_item = lhs->First(); - ListItem* rhs_item = rhs->First(); - while (i < list_size) { - if (lhs_item == NULL) { - return false; - } - if (rhs_item == NULL) { - return false; - } - if (lhs->GetUnsignedItem(lhs_item) != rhs->GetUnsignedItem(rhs_item)) { - return false; - } - i++; - lhs_item = lhs->Next(lhs_item); - rhs_item = rhs->Next(rhs_item); - } - return true; -} - -TEST(ListWrapperTest, ReverseNewIntList) { - // Create a new temporary list with elements reversed those of - // new_int_list_ - const scoped_ptr descending_list( - CreateDescendingList(rand() % 2)); - ASSERT_FALSE(descending_list.get() == NULL); - ASSERT_FALSE(descending_list->Empty()); - ASSERT_EQ(kNumberOfElements, descending_list->GetSize()); - - const scoped_ptr ascending_list( - CreateAscendingList(rand() % 2)); - ASSERT_FALSE(ascending_list.get() == NULL); - ASSERT_FALSE(ascending_list->Empty()); - ASSERT_EQ(kNumberOfElements, ascending_list->GetSize()); - - scoped_ptr list_to_reverse( - ListWrapperSimple::Create(rand() % 2)); - - // Reverse the list using PushBack and Previous. - for (ListItem* item = ascending_list->Last(); item != NULL; - item = ascending_list->Previous(item)) { - list_to_reverse->PushBack(ascending_list->GetUnsignedItem(item)); - } - - ASSERT_TRUE(CompareLists(descending_list.get(), list_to_reverse.get())); - - scoped_ptr list_to_un_reverse( - ListWrapperSimple::Create(rand() % 2)); - ASSERT_FALSE(list_to_un_reverse.get() == NULL); - // Reverse the reversed list using PushFront and Next. - for (ListItem* item = list_to_reverse->First(); item != NULL; - item = list_to_reverse->Next(item)) { - list_to_un_reverse->PushFront(list_to_reverse->GetUnsignedItem(item)); - } - ASSERT_TRUE(CompareLists(ascending_list.get(), list_to_un_reverse.get())); -} - -TEST(ListWrapperTest, PopTest) { - scoped_ptr ascending_list(CreateAscendingList(rand() % 2)); - ASSERT_FALSE(ascending_list.get() == NULL); - ASSERT_FALSE(ascending_list->Empty()); - EXPECT_EQ(0, ascending_list->PopFront()); - EXPECT_EQ(1U, ascending_list->GetUnsignedItem(ascending_list->First())); - - EXPECT_EQ(0, ascending_list->PopBack()); - EXPECT_EQ(kNumberOfElements - 2, ascending_list->GetUnsignedItem( - ascending_list->Last())); - EXPECT_EQ(kNumberOfElements - 2, ascending_list->GetSize()); -} - -// Use Insert to interleave two lists. -TEST(ListWrapperTest, InterLeaveTest) { - scoped_ptr interleave_list( - CreateAscendingList(rand() % 2)); - ASSERT_FALSE(interleave_list.get() == NULL); - ASSERT_FALSE(interleave_list->Empty()); - - scoped_ptr descending_list( - CreateDescendingList(rand() % 2)); - ASSERT_FALSE(descending_list.get() == NULL); - - for (unsigned int i = 0; i < kNumberOfElements / 2; ++i) { - ASSERT_EQ(0, interleave_list->PopBack()); - ASSERT_EQ(0, descending_list->PopBack()); - } - ASSERT_EQ(kNumberOfElements / 2, interleave_list->GetSize()); - ASSERT_EQ(kNumberOfElements / 2, descending_list->GetSize()); - - unsigned int insert_position = kNumberOfElements / 2; - ASSERT_EQ(insert_position * 2, kNumberOfElements); - while (!descending_list->Empty()) { - ListItem* item = descending_list->Last(); - ASSERT_FALSE(item == NULL); - - const unsigned int item_id = descending_list->GetUnsignedItem(item); - ASSERT_EQ(0, descending_list->Erase(item)); - - ListItem* insert_item = interleave_list->CreateListItem(item_id); - ASSERT_FALSE(insert_item == NULL); - item = interleave_list->First(); - ASSERT_FALSE(item == NULL); - for (unsigned int j = 0; j < insert_position - 1; ++j) { - item = interleave_list->Next(item); - ASSERT_FALSE(item == NULL); - } - EXPECT_EQ(0, interleave_list->Insert(item, insert_item)); - --insert_position; - } - - scoped_ptr interleaved_list( - CreateInterleavedList(rand() % 2)); - ASSERT_FALSE(interleaved_list.get() == NULL); - ASSERT_FALSE(interleaved_list->Empty()); - ASSERT_TRUE(CompareLists(interleaved_list.get(), interleave_list.get())); -} - -// Use InsertBefore to interleave two lists. -TEST(ListWrapperTest, InterLeaveTestII) { - scoped_ptr interleave_list( - CreateDescendingList(rand() % 2)); - ASSERT_FALSE(interleave_list.get() == NULL); - ASSERT_FALSE(interleave_list->Empty()); - - scoped_ptr ascending_list(CreateAscendingList(rand() % 2)); - ASSERT_FALSE(ascending_list.get() == NULL); - - for (unsigned int i = 0; i < kNumberOfElements / 2; ++i) { - ASSERT_EQ(0, interleave_list->PopBack()); - ASSERT_EQ(0, ascending_list->PopBack()); - } - ASSERT_EQ(kNumberOfElements / 2, interleave_list->GetSize()); - ASSERT_EQ(kNumberOfElements / 2, ascending_list->GetSize()); - - unsigned int insert_position = kNumberOfElements / 2; - ASSERT_EQ(insert_position * 2, kNumberOfElements); - while (!ascending_list->Empty()) { - ListItem* item = ascending_list->Last(); - ASSERT_FALSE(item == NULL); - - const unsigned int item_id = ascending_list->GetUnsignedItem(item); - ASSERT_EQ(0, ascending_list->Erase(item)); - - ListItem* insert_item = interleave_list->CreateListItem(item_id); - ASSERT_FALSE(insert_item == NULL); - item = interleave_list->First(); - ASSERT_FALSE(item == NULL); - for (unsigned int j = 0; j < insert_position - 1; ++j) { - item = interleave_list->Next(item); - ASSERT_FALSE(item == NULL); - } - EXPECT_EQ(interleave_list->InsertBefore(item, insert_item), 0); - --insert_position; - } - - scoped_ptr interleaved_list( - CreateInterleavedList(rand() % 2)); - ASSERT_FALSE(interleaved_list.get() == NULL); - ASSERT_FALSE(interleaved_list->Empty()); - - ASSERT_TRUE(CompareLists(interleaved_list.get(), interleave_list.get())); -} diff --git a/webrtc/system_wrappers/source/system_wrappers.gyp b/webrtc/system_wrappers/source/system_wrappers.gyp index 07806d1ec2..8d6df30447 100644 --- a/webrtc/system_wrappers/source/system_wrappers.gyp +++ b/webrtc/system_wrappers/source/system_wrappers.gyp @@ -37,7 +37,6 @@ '../interface/event_wrapper.h', '../interface/file_wrapper.h', '../interface/fix_interlocked_exchange_pointer_win.h', - '../interface/list_wrapper.h', '../interface/logcat_trace_context.h', '../interface/logging.h', '../interface/ref_count.h', @@ -83,7 +82,6 @@ 'event_win.h', 'file_impl.cc', 'file_impl.h', - 'list_no_stl.cc', 'logcat_trace_context.cc', 'logging.cc', 'rw_lock.cc', diff --git a/webrtc/system_wrappers/source/system_wrappers_tests.gyp b/webrtc/system_wrappers/source/system_wrappers_tests.gyp index 5686105e46..06737d23c2 100644 --- a/webrtc/system_wrappers/source/system_wrappers_tests.gyp +++ b/webrtc/system_wrappers/source/system_wrappers_tests.gyp @@ -23,7 +23,6 @@ 'condition_variable_unittest.cc', 'critical_section_unittest.cc', 'event_tracer_unittest.cc', - 'list_unittest.cc', 'logging_unittest.cc', 'data_log_unittest.cc', 'data_log_unittest_disabled.cc', diff --git a/webrtc/system_wrappers/test/list/list.cc b/webrtc/system_wrappers/test/list/list.cc deleted file mode 100644 index 35ddf33585..0000000000 --- a/webrtc/system_wrappers/test/list/list.cc +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "webrtc/system_wrappers/interface/list_wrapper.h" - -const int kNumberOfElements = 10; - -void FailTest(bool failed) -{ - if (failed) - { - printf("Test failed!\n"); - printf("Press enter to continue:"); - getchar(); - exit(0); - } -} - -int GetStoredIntegerValue(ListItem* list_item) -{ - void* list_item_pointer = list_item->GetItem(); - if (list_item_pointer != NULL) - { - return *(reinterpret_cast(list_item_pointer)); - } - return static_cast(list_item->GetUnsignedItem()); -} - -void PrintList(ListWrapper& list) -{ - ListItem* list_item = list.First(); - printf("List: "); - while (list_item != NULL) - { - int item_value = GetStoredIntegerValue(list_item); - FailTest(item_value < 0); - printf(" %d",item_value); - list_item = list.Next(list_item); - } - printf("\n"); -} - -// The list should always be in ascending order -void ListSanity(ListWrapper& list) -{ - if(list.Empty()) - { - return; - } - ListItem* item_iter = list.First(); - // Fake a previous value for the first iteration - int previous_value = GetStoredIntegerValue(item_iter) - 1; - while (item_iter != NULL) - { - const int value = GetStoredIntegerValue(item_iter); - FailTest(value != previous_value + 1); - previous_value = value; - item_iter = list.Next(item_iter); - } -} - -int main(int /*argc*/, char* /*argv*/[]) -{ - printf("List Test:\n"); - int element_array[kNumberOfElements]; - for (int i = 0; i < kNumberOfElements; i++) - { - element_array[i] = i; - } - // Test PushBack 1 - ListWrapper test_list; - for (int i = 2; i < kNumberOfElements - 2; i++) - { - FailTest(test_list.PushBack((void*)&element_array[i]) != 0); - } - // Test PushBack 2 - FailTest(test_list.PushBack(element_array[kNumberOfElements - 2]) != 0); - FailTest(test_list.PushBack(element_array[kNumberOfElements - 1]) != 0); - // Test PushFront 2 - FailTest(test_list.PushFront(element_array[1]) != 0); - // Test PushFront 1 - FailTest(test_list.PushFront((void*)&element_array[0]) != 0); - // Test GetSize - FailTest(test_list.GetSize() != kNumberOfElements); - PrintList(test_list); - //Test PopFront - FailTest(test_list.PopFront() != 0); - //Test PopBack - FailTest(test_list.PopBack() != 0); - // Test GetSize - FailTest(test_list.GetSize() != kNumberOfElements - 2); - // Test Empty - FailTest(test_list.Empty()); - // Test First - ListItem* first_item = test_list.First(); - FailTest(first_item == NULL); - // Test Last - ListItem* last_item = test_list.Last(); - FailTest(last_item == NULL); - // Test Next - ListItem* second_item = test_list.Next(first_item); - FailTest(second_item == NULL); - FailTest(test_list.Next(last_item) != NULL); - FailTest(test_list.Next(NULL) != NULL); - // Test Previous - ListItem* second_to_last_item = test_list.Previous(last_item); - FailTest(second_to_last_item == NULL); - FailTest(test_list.Previous(first_item) != NULL); - FailTest(test_list.Previous(NULL) != NULL); - // Test GetUnsignedItem - FailTest(last_item->GetUnsignedItem() != - kNumberOfElements - 2); - FailTest(last_item->GetItem() != - NULL); - // Test GetItem - FailTest(GetStoredIntegerValue(second_to_last_item) != - kNumberOfElements - 3); - FailTest(second_to_last_item->GetUnsignedItem() != 0); - // Pop last and first since they are pushed as unsigned items. - FailTest(test_list.PopFront() != 0); - FailTest(test_list.PopBack() != 0); - // Test Insert. Please note that old iterators are no longer valid at - // this point. - ListItem* insert_item_last = new ListItem(reinterpret_cast(&element_array[kNumberOfElements - 2])); - FailTest(test_list.Insert(test_list.Last(),insert_item_last) != 0); - FailTest(test_list.Insert(NULL,insert_item_last) == 0); - ListItem* insert_item_last2 = new ListItem(reinterpret_cast(&element_array[kNumberOfElements - 2])); - FailTest(test_list.Insert(insert_item_last2,NULL) == 0); - // test InsertBefore - ListItem* insert_item_first = new ListItem(reinterpret_cast(&element_array[1])); - FailTest(test_list.InsertBefore(test_list.First(),insert_item_first) != 0); - FailTest(test_list.InsertBefore(NULL,insert_item_first) == 0); - ListItem* insert_item_first2 = new ListItem(reinterpret_cast(&element_array[1])); - FailTest(test_list.InsertBefore(insert_item_first2,NULL) == 0); - PrintList(test_list); - ListSanity(test_list); - // Erase the whole list - int counter = 0; - while (test_list.PopFront() == 0) - { - FailTest(counter++ > kNumberOfElements); - } - PrintList(test_list); - // Test APIs when list is empty - FailTest(test_list.GetSize() != 0); - FailTest(test_list.PopFront() != -1); - FailTest(test_list.PopBack() != -1); - FailTest(!test_list.Empty()); - FailTest(test_list.First() != NULL); - FailTest(test_list.Last() != NULL); - FailTest(test_list.Next(NULL) != NULL); - FailTest(test_list.Previous(NULL) != NULL); - FailTest(test_list.Erase(NULL) != -1); - // Test Insert APIs when list is empty - ListItem* new_item = new ListItem(reinterpret_cast(&element_array[0])); - FailTest(test_list.Insert(NULL,new_item) != 0); - FailTest(test_list.Empty()); - FailTest(test_list.PopFront() != 0); - ListItem* new_item2 = new ListItem(reinterpret_cast(&element_array[0])); - FailTest(test_list.InsertBefore(NULL,new_item2) != 0); - FailTest(test_list.Empty()); - - printf("Tests passed successfully!\n"); -}