Home | History | Annotate | Download | only in src
      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
     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 
     58 OSCL_EXPORT_REF RTCP_Base::~RTCP_Base()
     59 {}
     60 
     61 
     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 
     92 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 
    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 
    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 
    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 
    209 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 
    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 
    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 
    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 
    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 
    359 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 
    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 
    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 
    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 
    477 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 
    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