• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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