blob: df09b01bdf298f92d2cd4ef8a8b4446d8bdfdb41 [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
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000011#include "webrtc/modules/rtp_rtcp/source/ssrc_database.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000013#include <assert.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000014#include <stdlib.h>
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000015
16#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000017
18#ifdef _WIN32
19 #include <windows.h>
20 #include <MMSystem.h> //timeGetTime
21
henrike@webrtc.org315282c2011-12-09 17:46:20 +000022// TODO(hellner): investigate if it is necessary to disable these warnings.
niklase@google.com470e71d2011-07-07 08:21:25 +000023 #pragma warning(disable:4311)
24 #pragma warning(disable:4312)
niklase@google.com470e71d2011-07-07 08:21:25 +000025#else
26 #include <stdio.h>
27 #include <string.h>
28 #include <time.h>
29 #include <sys/time.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000030#endif
31
32namespace webrtc {
henrike@webrtc.org315282c2011-12-09 17:46:20 +000033SSRCDatabase*
34SSRCDatabase::StaticInstance(CountOperation count_operation)
niklase@google.com470e71d2011-07-07 08:21:25 +000035{
henrike@webrtc.org315282c2011-12-09 17:46:20 +000036 SSRCDatabase* impl =
37 GetStaticInstance<SSRCDatabase>(count_operation);
38 return impl;
niklase@google.com470e71d2011-07-07 08:21:25 +000039}
40
41SSRCDatabase*
42SSRCDatabase::GetSSRCDatabase()
43{
henrike@webrtc.org315282c2011-12-09 17:46:20 +000044 return StaticInstance(kAddRef);
niklase@google.com470e71d2011-07-07 08:21:25 +000045}
46
47void
48SSRCDatabase::ReturnSSRCDatabase()
49{
henrike@webrtc.org315282c2011-12-09 17:46:20 +000050 StaticInstance(kRelease);
niklase@google.com470e71d2011-07-07 08:21:25 +000051}
52
pbos@webrtc.org2f446732013-04-08 11:08:41 +000053uint32_t
niklase@google.com470e71d2011-07-07 08:21:25 +000054SSRCDatabase::CreateSSRC()
55{
henrike@webrtc.org65573f22011-12-13 19:17:27 +000056 CriticalSectionScoped lock(_critSect);
niklase@google.com470e71d2011-07-07 08:21:25 +000057
pbos@webrtc.org2f446732013-04-08 11:08:41 +000058 uint32_t ssrc = GenerateRandom();
niklase@google.com470e71d2011-07-07 08:21:25 +000059
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +000060#ifndef WEBRTC_NO_STL
61
niklase@google.com470e71d2011-07-07 08:21:25 +000062 while(_ssrcMap.find(ssrc) != _ssrcMap.end())
63 {
64 ssrc = GenerateRandom();
65 }
66 _ssrcMap[ssrc] = 0;
67
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +000068#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
niklase@google.com470e71d2011-07-07 08:21:25 +000099 return ssrc;
100}
101
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000102int32_t
103SSRCDatabase::RegisterSSRC(const uint32_t ssrc)
niklase@google.com470e71d2011-07-07 08:21:25 +0000104{
henrike@webrtc.org65573f22011-12-13 19:17:27 +0000105 CriticalSectionScoped lock(_critSect);
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +0000106
107#ifndef WEBRTC_NO_STL
108
niklase@google.com470e71d2011-07-07 08:21:25 +0000109 _ssrcMap[ssrc] = 0;
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +0000110
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
niklase@google.com470e71d2011-07-07 08:21:25 +0000139 return 0;
140}
141
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000142int32_t
143SSRCDatabase::ReturnSSRC(const uint32_t ssrc)
niklase@google.com470e71d2011-07-07 08:21:25 +0000144{
henrike@webrtc.org65573f22011-12-13 19:17:27 +0000145 CriticalSectionScoped lock(_critSect);
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +0000146
147#ifndef WEBRTC_NO_STL
niklase@google.com470e71d2011-07-07 08:21:25 +0000148 _ssrcMap.erase(ssrc);
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +0000149
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
niklase@google.com470e71d2011-07-07 08:21:25 +0000166 return 0;
167}
168
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
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +0000181#ifdef WEBRTC_NO_STL
182 _sizeOfSSRC = 10;
183 _numberOfSSRC = 0;
184 _ssrcVector = new uint32_t[10];
185#endif
niklase@google.com470e71d2011-07-07 08:21:25 +0000186 _critSect = CriticalSectionWrapper::CreateCriticalSection();
niklase@google.com470e71d2011-07-07 08:21:25 +0000187}
188
189SSRCDatabase::~SSRCDatabase()
190{
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +0000191#ifdef WEBRTC_NO_STL
192 delete [] _ssrcVector;
193#else
niklase@google.com470e71d2011-07-07 08:21:25 +0000194 _ssrcMap.clear();
andresp@webrtc.org5ac876b2014-07-10 07:41:59 +0000195#endif
196 delete _critSect;
niklase@google.com470e71d2011-07-07 08:21:25 +0000197}
198
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000199uint32_t SSRCDatabase::GenerateRandom()
niklase@google.com470e71d2011-07-07 08:21:25 +0000200{
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000201 uint32_t ssrc = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000202 do
203 {
204 ssrc = rand();
205 ssrc = ssrc <<16;
206 ssrc += rand();
207
208 } while (ssrc == 0 || ssrc == 0xffffffff);
209
210 return ssrc;
211}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000212} // namespace webrtc