• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)34 SSRCDatabase::StaticInstance(CountOperation count_operation)
35 {
36   SSRCDatabase* impl =
37       GetStaticInstance<SSRCDatabase>(count_operation);
38   return impl;
39 }
40 
41 SSRCDatabase*
GetSSRCDatabase()42 SSRCDatabase::GetSSRCDatabase()
43 {
44     return StaticInstance(kAddRef);
45 }
46 
47 void
ReturnSSRCDatabase()48 SSRCDatabase::ReturnSSRCDatabase()
49 {
50     StaticInstance(kRelease);
51 }
52 
53 uint32_t
CreateSSRC()54 SSRCDatabase::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)103 SSRCDatabase::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)143 SSRCDatabase::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()169 SSRCDatabase::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()189 SSRCDatabase::~SSRCDatabase()
190 {
191 #ifdef WEBRTC_NO_STL
192     delete [] _ssrcVector;
193 #else
194     _ssrcMap.clear();
195 #endif
196     delete _critSect;
197 }
198 
GenerateRandom()199 uint32_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