blob: b51efb5d0cb52870eac3365b2e4266959d26298a [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
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 "ssrc_database.h"
12
13#include "critical_section_wrapper.h"
14#include "trace.h"
15
16#include <stdlib.h>
17#include <cassert>
18
19#ifdef _WIN32
20 #include <windows.h>
21 #include <MMSystem.h> //timeGetTime
22
henrike@webrtc.org315282c2011-12-09 17:46:20 +000023// TODO(hellner): investigate if it is necessary to disable these warnings.
niklase@google.com470e71d2011-07-07 08:21:25 +000024 #pragma warning(disable:4311)
25 #pragma warning(disable:4312)
niklase@google.com470e71d2011-07-07 08:21:25 +000026#else
27 #include <stdio.h>
28 #include <string.h>
29 #include <time.h>
30 #include <sys/time.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000031#endif
32
33namespace webrtc {
henrike@webrtc.org315282c2011-12-09 17:46:20 +000034SSRCDatabase*
35SSRCDatabase::StaticInstance(CountOperation count_operation)
niklase@google.com470e71d2011-07-07 08:21:25 +000036{
henrike@webrtc.org315282c2011-12-09 17:46:20 +000037 SSRCDatabase* impl =
38 GetStaticInstance<SSRCDatabase>(count_operation);
39 return impl;
niklase@google.com470e71d2011-07-07 08:21:25 +000040}
41
42SSRCDatabase*
43SSRCDatabase::GetSSRCDatabase()
44{
henrike@webrtc.org315282c2011-12-09 17:46:20 +000045 return StaticInstance(kAddRef);
niklase@google.com470e71d2011-07-07 08:21:25 +000046}
47
48void
49SSRCDatabase::ReturnSSRCDatabase()
50{
henrike@webrtc.org315282c2011-12-09 17:46:20 +000051 StaticInstance(kRelease);
niklase@google.com470e71d2011-07-07 08:21:25 +000052}
53
pbos@webrtc.org2f446732013-04-08 11:08:41 +000054uint32_t
niklase@google.com470e71d2011-07-07 08:21:25 +000055SSRCDatabase::CreateSSRC()
56{
henrike@webrtc.org65573f22011-12-13 19:17:27 +000057 CriticalSectionScoped lock(_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +000058
pbos@webrtc.org2f446732013-04-08 11:08:41 +000059 uint32_t ssrc = GenerateRandom();
niklase@google.com470e71d2011-07-07 08:21:25 +000060
61#ifndef WEBRTC_NO_STL
62
63 while(_ssrcMap.find(ssrc) != _ssrcMap.end())
64 {
65 ssrc = GenerateRandom();
66 }
67 _ssrcMap[ssrc] = 0;
68
69#else
70 if(_sizeOfSSRC <= _numberOfSSRC)
71 {
72 // allocate more space
73 const int newSize = _sizeOfSSRC + 10;
pbos@webrtc.org2f446732013-04-08 11:08:41 +000074 uint32_t* tempSSRCVector = new uint32_t[newSize];
75 memcpy(tempSSRCVector, _ssrcVector, _sizeOfSSRC*sizeof(uint32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +000076 delete [] _ssrcVector;
77
78 _ssrcVector = tempSSRCVector;
79 _sizeOfSSRC = newSize;
80 }
81
82 // check if in DB
83 if(_ssrcVector)
84 {
85 for (int i=0; i<_numberOfSSRC; i++)
86 {
87 if (_ssrcVector[i] == ssrc)
88 {
89 // we have a match
90 i = 0; // start over with a new ssrc
91 ssrc = GenerateRandom();
92 }
93
94 }
95 // add to database
96 _ssrcVector[_numberOfSSRC] = ssrc;
97 _numberOfSSRC++;
98 }
99#endif
100 return ssrc;
101}
102
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000103int32_t
104SSRCDatabase::RegisterSSRC(const uint32_t ssrc)
niklase@google.com470e71d2011-07-07 08:21:25 +0000105{
henrike@webrtc.org65573f22011-12-13 19:17:27 +0000106 CriticalSectionScoped lock(_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000107
108#ifndef WEBRTC_NO_STL
109
110 _ssrcMap[ssrc] = 0;
111
112#else
113 if(_sizeOfSSRC <= _numberOfSSRC)
114 {
115 // allocate more space
116 const int newSize = _sizeOfSSRC + 10;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000117 uint32_t* tempSSRCVector = new uint32_t[newSize];
118 memcpy(tempSSRCVector, _ssrcVector, _sizeOfSSRC*sizeof(uint32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000119 delete [] _ssrcVector;
120
121 _ssrcVector = tempSSRCVector;
122 _sizeOfSSRC = newSize;
123 }
124 // check if in DB
125 if(_ssrcVector)
126 {
127 for (int i=0; i<_numberOfSSRC; i++)
128 {
129 if (_ssrcVector[i] == ssrc)
130 {
131 // we have a match
132 return -1;
133 }
134 }
135 // add to database
136 _ssrcVector[_numberOfSSRC] = ssrc;
137 _numberOfSSRC++;
138 }
139#endif
140 return 0;
141}
142
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000143int32_t
144SSRCDatabase::ReturnSSRC(const uint32_t ssrc)
niklase@google.com470e71d2011-07-07 08:21:25 +0000145{
henrike@webrtc.org65573f22011-12-13 19:17:27 +0000146 CriticalSectionScoped lock(_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +0000147
148#ifndef WEBRTC_NO_STL
149 _ssrcMap.erase(ssrc);
150
151#else
152 if(_ssrcVector)
153 {
154 for (int i=0; i<_numberOfSSRC; i++)
155 {
156 if (_ssrcVector[i] == ssrc)
157 {
158 // we have a match
159 // remove from database
160 _ssrcVector[i] = _ssrcVector[_numberOfSSRC-1];
161 _numberOfSSRC--;
162 break;
163 }
164 }
165 }
166#endif
167 return 0;
168}
169
170SSRCDatabase::SSRCDatabase()
171{
172 // we need to seed the random generator, otherwise we get 26500 each time, hardly a random value :)
173#ifdef _WIN32
174 srand(timeGetTime());
175#else
176 struct timeval tv;
177 struct timezone tz;
178 gettimeofday(&tv, &tz);
179 srand(tv.tv_usec);
180#endif
181
182#ifdef WEBRTC_NO_STL
183 _sizeOfSSRC = 10;
184 _numberOfSSRC = 0;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000185 _ssrcVector = new uint32_t[10];
niklase@google.com470e71d2011-07-07 08:21:25 +0000186#endif
187 _critSect = CriticalSectionWrapper::CreateCriticalSection();
188
189 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, -1, "%s created", __FUNCTION__);
190}
191
192SSRCDatabase::~SSRCDatabase()
193{
194#ifdef WEBRTC_NO_STL
195 delete [] _ssrcVector;
196#else
197 _ssrcMap.clear();
198#endif
199 delete _critSect;
200
201 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, -1, "%s deleted", __FUNCTION__);
202}
203
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000204uint32_t SSRCDatabase::GenerateRandom()
niklase@google.com470e71d2011-07-07 08:21:25 +0000205{
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000206 uint32_t ssrc = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000207 do
208 {
209 ssrc = rand();
210 ssrc = ssrc <<16;
211 ssrc += rand();
212
213 } while (ssrc == 0 || ssrc == 0xffffffff);
214
215 return ssrc;
216}
217} // namespace webrtc