1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/rtp_rtcp/source/ssrc_database.h" 12 13 #include <assert.h> 14 #include <stdlib.h> 15 16 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 17 18 #ifdef _WIN32 19 #include <windows.h> 20 #include <MMSystem.h> //timeGetTime 21 22 // TODO(hellner): investigate if it is necessary to disable these warnings. 23 #pragma warning(disable:4311) 24 #pragma warning(disable:4312) 25 #else 26 #include <stdio.h> 27 #include <string.h> 28 #include <time.h> 29 #include <sys/time.h> 30 #endif 31 32 namespace webrtc { 33 SSRCDatabase* StaticInstance(CountOperation count_operation)34SSRCDatabase::StaticInstance(CountOperation count_operation) 35 { 36 SSRCDatabase* impl = 37 GetStaticInstance<SSRCDatabase>(count_operation); 38 return impl; 39 } 40 41 SSRCDatabase* GetSSRCDatabase()42SSRCDatabase::GetSSRCDatabase() 43 { 44 return StaticInstance(kAddRef); 45 } 46 47 void ReturnSSRCDatabase()48SSRCDatabase::ReturnSSRCDatabase() 49 { 50 StaticInstance(kRelease); 51 } 52 53 uint32_t CreateSSRC()54SSRCDatabase::CreateSSRC() 55 { 56 CriticalSectionScoped lock(_critSect); 57 58 uint32_t ssrc = GenerateRandom(); 59 60 #ifndef WEBRTC_NO_STL 61 62 while(_ssrcMap.find(ssrc) != _ssrcMap.end()) 63 { 64 ssrc = GenerateRandom(); 65 } 66 _ssrcMap[ssrc] = 0; 67 68 #else 69 if(_sizeOfSSRC <= _numberOfSSRC) 70 { 71 // allocate more space 72 const int newSize = _sizeOfSSRC + 10; 73 uint32_t* tempSSRCVector = new uint32_t[newSize]; 74 memcpy(tempSSRCVector, _ssrcVector, _sizeOfSSRC*sizeof(uint32_t)); 75 delete [] _ssrcVector; 76 77 _ssrcVector = tempSSRCVector; 78 _sizeOfSSRC = newSize; 79 } 80 81 // check if in DB 82 if(_ssrcVector) 83 { 84 for (int i=0; i<_numberOfSSRC; i++) 85 { 86 if (_ssrcVector[i] == ssrc) 87 { 88 // we have a match 89 i = 0; // start over with a new ssrc 90 ssrc = GenerateRandom(); 91 } 92 93 } 94 // add to database 95 _ssrcVector[_numberOfSSRC] = ssrc; 96 _numberOfSSRC++; 97 } 98 #endif 99 return ssrc; 100 } 101 102 int32_t RegisterSSRC(const uint32_t ssrc)103SSRCDatabase::RegisterSSRC(const uint32_t ssrc) 104 { 105 CriticalSectionScoped lock(_critSect); 106 107 #ifndef WEBRTC_NO_STL 108 109 _ssrcMap[ssrc] = 0; 110 111 #else 112 if(_sizeOfSSRC <= _numberOfSSRC) 113 { 114 // allocate more space 115 const int newSize = _sizeOfSSRC + 10; 116 uint32_t* tempSSRCVector = new uint32_t[newSize]; 117 memcpy(tempSSRCVector, _ssrcVector, _sizeOfSSRC*sizeof(uint32_t)); 118 delete [] _ssrcVector; 119 120 _ssrcVector = tempSSRCVector; 121 _sizeOfSSRC = newSize; 122 } 123 // check if in DB 124 if(_ssrcVector) 125 { 126 for (int i=0; i<_numberOfSSRC; i++) 127 { 128 if (_ssrcVector[i] == ssrc) 129 { 130 // we have a match 131 return -1; 132 } 133 } 134 // add to database 135 _ssrcVector[_numberOfSSRC] = ssrc; 136 _numberOfSSRC++; 137 } 138 #endif 139 return 0; 140 } 141 142 int32_t ReturnSSRC(const uint32_t ssrc)143SSRCDatabase::ReturnSSRC(const uint32_t ssrc) 144 { 145 CriticalSectionScoped lock(_critSect); 146 147 #ifndef WEBRTC_NO_STL 148 _ssrcMap.erase(ssrc); 149 150 #else 151 if(_ssrcVector) 152 { 153 for (int i=0; i<_numberOfSSRC; i++) 154 { 155 if (_ssrcVector[i] == ssrc) 156 { 157 // we have a match 158 // remove from database 159 _ssrcVector[i] = _ssrcVector[_numberOfSSRC-1]; 160 _numberOfSSRC--; 161 break; 162 } 163 } 164 } 165 #endif 166 return 0; 167 } 168 SSRCDatabase()169SSRCDatabase::SSRCDatabase() 170 { 171 // we need to seed the random generator, otherwise we get 26500 each time, hardly a random value :) 172 #ifdef _WIN32 173 srand(timeGetTime()); 174 #else 175 struct timeval tv; 176 struct timezone tz; 177 gettimeofday(&tv, &tz); 178 srand(tv.tv_usec); 179 #endif 180 181 #ifdef WEBRTC_NO_STL 182 _sizeOfSSRC = 10; 183 _numberOfSSRC = 0; 184 _ssrcVector = new uint32_t[10]; 185 #endif 186 _critSect = CriticalSectionWrapper::CreateCriticalSection(); 187 } 188 ~SSRCDatabase()189SSRCDatabase::~SSRCDatabase() 190 { 191 #ifdef WEBRTC_NO_STL 192 delete [] _ssrcVector; 193 #else 194 _ssrcMap.clear(); 195 #endif 196 delete _critSect; 197 } 198 GenerateRandom()199uint32_t SSRCDatabase::GenerateRandom() 200 { 201 uint32_t ssrc = 0; 202 do 203 { 204 ssrc = rand(); 205 ssrc = ssrc <<16; 206 ssrc += rand(); 207 208 } while (ssrc == 0 || ssrc == 0xffffffff); 209 210 return ssrc; 211 } 212 } // namespace webrtc 213