diff --git a/webrtc/modules/rtp_rtcp/source/ssrc_database.cc b/webrtc/modules/rtp_rtcp/source/ssrc_database.cc index c9572cd1b7..fb02b7ef12 100644 --- a/webrtc/modules/rtp_rtcp/source/ssrc_database.cc +++ b/webrtc/modules/rtp_rtcp/source/ssrc_database.cc @@ -10,92 +10,51 @@ #include "webrtc/modules/rtp_rtcp/source/ssrc_database.h" -#include -#include - +#include "webrtc/base/checks.h" +#include "webrtc/system_wrappers/include/clock.h" #include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#ifdef _WIN32 -#include -#include // timeGetTime - -// TODO(hellner): investigate if it is necessary to disable these warnings. -#pragma warning(disable : 4311) -#pragma warning(disable : 4312) -#else -#include -#include -#include -#include -#endif - namespace webrtc { -SSRCDatabase* SSRCDatabase::StaticInstance(CountOperation count_operation) { - SSRCDatabase* impl = GetStaticInstance(count_operation); - return impl; +namespace { +uint64_t Seed() { + return Clock::GetRealTimeClock()->TimeInMicroseconds(); } +} // namespace SSRCDatabase* SSRCDatabase::GetSSRCDatabase() { - return StaticInstance(kAddRef); + return GetStaticInstance(kAddRef); } void SSRCDatabase::ReturnSSRCDatabase() { - StaticInstance(kRelease); + GetStaticInstance(kRelease); } uint32_t SSRCDatabase::CreateSSRC() { - CriticalSectionScoped lock(_critSect); + CriticalSectionScoped lock(crit_.get()); - uint32_t ssrc = GenerateRandom(); - - while (_ssrcMap.find(ssrc) != _ssrcMap.end()) { - ssrc = GenerateRandom(); + while (true) { // Try until get a new ssrc. + // 0 and 0xffffffff are invalid values for SSRC. + uint32_t ssrc = random_.Rand(1u, 0xfffffffe); + if (ssrcs_.insert(ssrc).second) { + return ssrc; + } } - _ssrcMap[ssrc] = 0; - - return ssrc; } -int32_t SSRCDatabase::RegisterSSRC(const uint32_t ssrc) { - CriticalSectionScoped lock(_critSect); - _ssrcMap[ssrc] = 0; - return 0; +void SSRCDatabase::RegisterSSRC(uint32_t ssrc) { + CriticalSectionScoped lock(crit_.get()); + ssrcs_.insert(ssrc); } -int32_t SSRCDatabase::ReturnSSRC(const uint32_t ssrc) { - CriticalSectionScoped lock(_critSect); - _ssrcMap.erase(ssrc); - return 0; +void SSRCDatabase::ReturnSSRC(uint32_t ssrc) { + CriticalSectionScoped lock(crit_.get()); + ssrcs_.erase(ssrc); } -SSRCDatabase::SSRCDatabase() { -// we need to seed the random generator, otherwise we get 26500 each time, -// hardly a random value :) -#ifdef _WIN32 - srand(timeGetTime()); -#else - struct timeval tv; - struct timezone tz; - gettimeofday(&tv, &tz); - srand(tv.tv_usec); -#endif - - _critSect = CriticalSectionWrapper::CreateCriticalSection(); -} +SSRCDatabase::SSRCDatabase() + : crit_(CriticalSectionWrapper::CreateCriticalSection()), random_(Seed()) {} SSRCDatabase::~SSRCDatabase() { - _ssrcMap.clear(); - delete _critSect; } -uint32_t SSRCDatabase::GenerateRandom() { - uint32_t ssrc = 0; - do { - ssrc = rand(); - ssrc = ssrc << 16; - ssrc += rand(); - } while (ssrc == 0 || ssrc == 0xffffffff); - - return ssrc; -} } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/ssrc_database.h b/webrtc/modules/rtp_rtcp/source/ssrc_database.h index 5e52f07528..7a3133638d 100644 --- a/webrtc/modules/rtp_rtcp/source/ssrc_database.h +++ b/webrtc/modules/rtp_rtcp/source/ssrc_database.h @@ -11,8 +11,10 @@ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_SSRC_DATABASE_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_SSRC_DATABASE_H_ -#include +#include +#include "webrtc/base/random.h" +#include "webrtc/base/scoped_ptr.h" #include "webrtc/system_wrappers/include/static_instance.h" #include "webrtc/typedefs.h" @@ -25,8 +27,8 @@ class SSRCDatabase { static void ReturnSSRCDatabase(); uint32_t CreateSSRC(); - int32_t RegisterSSRC(const uint32_t ssrc); - int32_t ReturnSSRC(const uint32_t ssrc); + void RegisterSSRC(uint32_t ssrc); + void ReturnSSRC(uint32_t ssrc); protected: SSRCDatabase(); @@ -39,13 +41,10 @@ class SSRCDatabase { // template class. friend SSRCDatabase* GetStaticInstance( CountOperation count_operation); - static SSRCDatabase* StaticInstance(CountOperation count_operation); - uint32_t GenerateRandom(); - - std::map _ssrcMap; - - CriticalSectionWrapper* _critSect; + rtc::scoped_ptr crit_; + Random random_ GUARDED_BY(crit_); + std::set ssrcs_ GUARDED_BY(crit_); }; } // namespace webrtc