1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /* */
19 /*********************************************************************************/
20
21 /*
22 ** File: rtcp.cpp
23 **
24 ** Description:
25 ** This module implements the RTCP class. This class is used to encode and
26 ** decode RTCP packets. Please refer to the RTCP design document for
27 ** details.
28 */
29
30 /*
31 ** Includes
32 */
33
34 //#include <stdlib.h>
35 //#include <math.h>
36 #include "rtcp.h"
37
38 #ifndef OSCL_DLL_H_INCLUDED
39 #include "oscl_dll.h"
40 #endif
41
42 // Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()43 OSCL_DLL_ENTRY_POINT_DEFAULT()
44
45
46 /*
47 ** Constants
48 */
49
50
51 /*
52 ** Methods
53 */
54 RTCP_Base::RTCP_Base(const uint8 version)
55 : rtcpVersion(version)
56 {}
57
~RTCP_Base()58 OSCL_EXPORT_REF RTCP_Base::~RTCP_Base()
59 {}
60
61
get_report_block(uint index)62 OSCL_EXPORT_REF RTCP_ReportBlock* RTCP_RR::get_report_block(uint index)
63 {
64
65
66 if (index >= max_report_blocks)
67 {
68 return NULL;
69 }
70
71 if (index >= num_report_blocks)
72 {
73 num_report_blocks = index + 1;
74 }
75
76 if (index < NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS)
77 {
78 return preallocated_reports + index;
79 }
80
81 if (!additional_reports)
82 {
83
84 additional_reports = OSCL_ARRAY_NEW(RTCP_ReportBlock, max_report_blocks - NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS);
85 }
86
87 return additional_reports + (index - NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS);
88
89 }
90
91
read_report_block(uint index) const92 const RTCP_ReportBlock* RTCP_RR::read_report_block(uint index) const
93 {
94
95
96 if (index >= num_report_blocks)
97 {
98 return NULL;
99 }
100
101 if (index < NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS)
102 {
103 return preallocated_reports + index;
104 }
105
106 if (!additional_reports)
107 {
108 return NULL;
109 }
110
111 return additional_reports + (index - NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS);
112
113 }
114
115
set_max_report_blocks(uint new_max_report_blocks)116 bool RTCP_RR::set_max_report_blocks(uint new_max_report_blocks)
117 {
118
119 if (additional_reports)
120 {
121 // reports array already exists
122 if (new_max_report_blocks > max_report_blocks)
123 {
124 // only update max if greater than old max
125 max_report_blocks = new_max_report_blocks;
126 if (new_max_report_blocks > NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS)
127 {
128 // free current additional reports and allocate new array
129 delete[] additional_reports;
130 additional_reports = OSCL_ARRAY_NEW(RTCP_ReportBlock, new_max_report_blocks - NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS);
131 }
132 }
133 }
134 else if (new_max_report_blocks > NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS)
135 {
136 // allocate additional_reports array
137 additional_reports = OSCL_ARRAY_NEW(RTCP_ReportBlock, new_max_report_blocks - NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS);
138 max_report_blocks = new_max_report_blocks;
139 }
140
141 return true;
142
143 }
144
145
set_report_block(uint index,const RTCP_ReportBlock & report_block)146 bool RTCP_RR::set_report_block(uint index, const RTCP_ReportBlock& report_block)
147 {
148 if (index >= max_report_blocks)
149 {
150 return false;
151 }
152
153 if (index < NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS)
154 {
155
156 preallocated_reports[index] = report_block;
157
158 }
159 else if (!additional_reports)
160 {
161 // allocate the additional reports array
162 additional_reports = OSCL_ARRAY_NEW(RTCP_ReportBlock, max_report_blocks - NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS);
163 additional_reports[index - NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS] =
164 report_block;
165 }
166 else
167 {
168
169 additional_reports[index - NUM_PREALLOCATED_RTCP_RR_REPORT_BLOCKS] =
170 report_block;
171
172 }
173
174 num_report_blocks = index + 1;
175 return true;
176 }
177
178
get_report_block(uint index)179 RTCP_ReportBlock* RTCP_SR::get_report_block(uint index)
180 {
181
182
183 if (index >= max_report_blocks)
184 {
185 return NULL;
186 }
187
188 if (index >= num_report_blocks)
189 {
190 num_report_blocks = index + 1;
191 }
192
193 if (index < NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS)
194 {
195 return preallocated_reports + index;
196 }
197
198 if (!additional_reports)
199 {
200 additional_reports = OSCL_ARRAY_NEW(RTCP_ReportBlock, max_report_blocks - NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS);
201
202 }
203
204 return additional_reports + (index - NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS);
205
206 }
207
208
read_report_block(uint index) const209 const RTCP_ReportBlock* RTCP_SR::read_report_block(uint index) const
210 {
211
212 if (index >= num_report_blocks)
213 {
214 return NULL;
215 }
216
217 if (index < NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS)
218 {
219 return preallocated_reports + index;
220 }
221
222 if (!additional_reports)
223 {
224 return NULL;
225 }
226
227 return additional_reports + (index - NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS);
228
229 }
230
231
set_max_report_blocks(uint new_max_report_blocks)232 bool RTCP_SR::set_max_report_blocks(uint new_max_report_blocks)
233 {
234
235 if (additional_reports)
236 {
237 // reports array already exists
238 if (new_max_report_blocks > max_report_blocks)
239 {
240 // only update max if greater than old max
241 max_report_blocks = new_max_report_blocks;
242 if (new_max_report_blocks > NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS)
243 {
244 // free current additional reports and allocate new array
245 delete[] additional_reports;
246 additional_reports = OSCL_ARRAY_NEW(RTCP_ReportBlock, new_max_report_blocks - NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS);
247 }
248 }
249 }
250 else if (new_max_report_blocks > NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS)
251 {
252 // allocate additional_reports array
253 additional_reports = OSCL_ARRAY_NEW(RTCP_ReportBlock, new_max_report_blocks - NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS);
254 max_report_blocks = new_max_report_blocks;
255 }
256
257 return true;
258
259 }
260
261
set_report_block(uint index,const RTCP_ReportBlock & report_block)262 bool RTCP_SR::set_report_block(uint index, const RTCP_ReportBlock& report_block)
263 {
264 if (index >= max_report_blocks)
265 {
266 return false;
267 }
268
269 if (index < NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS)
270 {
271
272 preallocated_reports[index] = report_block;
273
274 }
275 else if (!additional_reports)
276 {
277 // allocate the additional reports array
278 additional_reports = OSCL_ARRAY_NEW(RTCP_ReportBlock, max_report_blocks - NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS);
279 additional_reports[index - NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS] =
280 report_block;
281 }
282 else
283 {
284
285 additional_reports[index - NUM_PREALLOCATED_RTCP_SR_REPORT_BLOCKS] =
286 report_block;
287
288 }
289
290 num_report_blocks = index + 1;
291 return true;
292 }
293
294
set_max_items(uint new_max_items)295 void SDES_chunk::set_max_items(uint new_max_items)
296 {
297
298 if (new_max_items > max_sdes_items)
299 {
300 // update sdes items
301 max_sdes_items = new_max_items;
302
303 if (new_max_items > NUM_PREALLOCATED_RTCP_CHUNK_ITEMS)
304 {
305 int32 extra_items = new_max_items - NUM_PREALLOCATED_RTCP_CHUNK_ITEMS;
306
307 // now allocate the extra array
308 SDES_item* new_additional = OSCL_ARRAY_NEW(SDES_item, extra_items);
309
310 if (additional_items)
311 {
312 if (num_sdes_items > NUM_PREALLOCATED_RTCP_CHUNK_ITEMS)
313 {
314 // copy old additional to the new array
315 for (uint ii = 0; ii < num_sdes_items -
316 NUM_PREALLOCATED_RTCP_CHUNK_ITEMS; ++ii)
317 {
318 new_additional[ii] = additional_items[ii];
319 }
320 }
321 delete[] additional_items;
322 }
323
324 additional_items = new_additional;
325
326 }
327
328 }
329
330 }
331
332
get_item(uint item_index)333 SDES_item* SDES_chunk::get_item(uint item_index)
334 {
335 if (item_index >= max_sdes_items)
336 {
337 return NULL;
338 }
339
340 if (item_index >= num_sdes_items)
341 {
342 num_sdes_items = item_index + 1;
343 }
344
345 if (item_index >= NUM_PREALLOCATED_RTCP_CHUNK_ITEMS)
346 {
347 if (!additional_items)
348 {
349 additional_items = OSCL_ARRAY_NEW(SDES_item, max_sdes_items - NUM_PREALLOCATED_RTCP_CHUNK_ITEMS);
350 }
351
352 return additional_items + (item_index - NUM_PREALLOCATED_RTCP_CHUNK_ITEMS);
353 }
354
355 return chunk_items + item_index;
356 }
357
358
read_item(uint item_index) const359 const SDES_item* SDES_chunk::read_item(uint item_index) const
360 {
361 if (item_index >= num_sdes_items)
362 {
363 return NULL;
364 }
365
366 if (item_index >= NUM_PREALLOCATED_RTCP_CHUNK_ITEMS)
367 {
368 if (!additional_items)
369 {
370 return NULL;
371 }
372
373 return additional_items + (item_index - NUM_PREALLOCATED_RTCP_CHUNK_ITEMS);
374 }
375
376 return chunk_items + item_index;
377 }
378
379
add_item(const SDES_item & item)380 bool SDES_chunk::add_item(const SDES_item& item)
381 {
382
383 const uint SDES_ARRAY_INCREMENT = 10;
384
385 if (num_sdes_items > max_sdes_items)
386 {
387 // allocate more
388 set_max_items(max_sdes_items + SDES_ARRAY_INCREMENT);
389 }
390
391 if (num_sdes_items >= NUM_PREALLOCATED_RTCP_CHUNK_ITEMS)
392 {
393 if (!additional_items)
394 {
395 additional_items = OSCL_ARRAY_NEW(SDES_item, max_sdes_items - NUM_PREALLOCATED_RTCP_CHUNK_ITEMS);
396 }
397 additional_items[num_sdes_items - NUM_PREALLOCATED_RTCP_CHUNK_ITEMS] = item;
398 chunk_size += item.content.len + 2;
399 }
400 else
401 {
402
403 chunk_items[num_sdes_items] = item;
404 chunk_size += item.content.len + 2;
405 }
406
407 ++num_sdes_items;
408 return true;
409
410 }
411
412
413
set_max_chunks(uint new_max_chunks)414 void RTCP_SDES::set_max_chunks(uint new_max_chunks)
415 {
416
417 if (new_max_chunks > max_chunks)
418 {
419 // update sdes items
420 max_chunks = new_max_chunks;
421
422 if (new_max_chunks > NUM_PREALLOCATED_RTCP_CHUNKS)
423 {
424 int32 extra_chunks = new_max_chunks - NUM_PREALLOCATED_RTCP_CHUNKS;
425
426 // now allocate the extra array
427 SDES_chunk* new_additional = OSCL_ARRAY_NEW(SDES_chunk, extra_chunks);
428
429 if (additional_chunks)
430 {
431 if (chunk_count > NUM_PREALLOCATED_RTCP_CHUNKS)
432 {
433 // copy old additional to the new array
434 for (uint ii = 0; ii < chunk_count -
435 NUM_PREALLOCATED_RTCP_CHUNKS; ++ii)
436 {
437 new_additional[ii] = additional_chunks[ii];
438 }
439 }
440 delete[] additional_chunks;
441 }
442
443 additional_chunks = new_additional;
444
445 }
446
447 }
448
449 }
450
451
get_chunk(uint chunk_index)452 SDES_chunk* RTCP_SDES::get_chunk(uint chunk_index)
453 {
454 if (chunk_index >= max_chunks)
455 {
456 return NULL;
457 }
458
459 if (chunk_index >= chunk_count)
460 {
461 chunk_count = chunk_index + 1;
462 }
463
464 if (chunk_index >= NUM_PREALLOCATED_RTCP_CHUNKS)
465 {
466 if (!additional_chunks)
467 {
468 additional_chunks = OSCL_ARRAY_NEW(SDES_chunk, max_chunks - NUM_PREALLOCATED_RTCP_CHUNKS);
469 }
470
471 return additional_chunks + (chunk_index - NUM_PREALLOCATED_RTCP_CHUNKS);
472 }
473
474 return chunk_array + chunk_index;
475 }
476
read_chunk(uint chunk_index) const477 const SDES_chunk* RTCP_SDES::read_chunk(uint chunk_index) const
478 {
479 if (chunk_index >= chunk_count)
480 {
481 return NULL;
482 }
483
484 if (chunk_index >= NUM_PREALLOCATED_RTCP_CHUNKS)
485 {
486 if (!additional_chunks)
487 {
488 return NULL;
489 }
490
491 return additional_chunks + (chunk_index - NUM_PREALLOCATED_RTCP_CHUNKS);
492 }
493
494 return chunk_array + chunk_index;
495 }
496
497
add_chunk(const SDES_chunk & chunk)498 bool RTCP_SDES::add_chunk(const SDES_chunk& chunk)
499 {
500
501 const uint SDES_ARRAY_INCREMENT = 10;
502
503 if (chunk_count > max_chunks)
504 {
505 // allocate more
506 set_max_chunks(max_chunks + SDES_ARRAY_INCREMENT);
507 }
508
509 if (chunk_count >= NUM_PREALLOCATED_RTCP_CHUNKS)
510 {
511 if (!additional_chunks)
512 {
513 additional_chunks = OSCL_ARRAY_NEW(SDES_chunk, max_chunks - NUM_PREALLOCATED_RTCP_CHUNKS);
514 }
515 additional_chunks[chunk_count - NUM_PREALLOCATED_RTCP_CHUNKS] = chunk;
516 }
517 else
518 {
519 chunk_array[chunk_count] = chunk;
520 }
521
522 ++chunk_count;
523 return true;
524
525 }
526
527
528
529
530