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 #include "h223types.h"
     19 #include "h324utils.h"
     20 
     21 H223ChannelParam::H223ChannelParam(TPVChannelId id, PS_H223LogicalChannelParameters lcp, PS_DataType dt)
     22         : pH223Lcp(NULL), pDataType(NULL)
     23 {
     24     lcn = id;
     25     if (lcp)
     26     {
     27         pH223Lcp = Copy_H223LogicalChannelParameters(lcp);
     28     }
     29     if (dt)
     30     {
     31         pDataType = Copy_DataType(dt);
     32     }
     33     bitrate = GetMaxBitrate(pDataType);
     34     sample_interval = 0;
     35     unsigned fr = GetMaxFrameRate(pDataType);
     36     if (fr)
     37         sample_interval = (unsigned)((double)1000 / (double)fr);
     38 }
     39 
     40 H223ChannelParam::H223ChannelParam(TPVChannelId id,
     41                                    PS_H223LogicalChannelParameters lcp,
     42                                    unsigned aBitrate,
     43                                    unsigned aSampleInterval)
     44         : pH223Lcp(NULL), pDataType(NULL)
     45 {
     46     lcn = id;
     47     if (lcp)
     48     {
     49         pH223Lcp = Copy_H223LogicalChannelParameters(lcp);
     50     }
     51     bitrate = aBitrate;
     52     sample_interval = aSampleInterval;
     53 }
     54 
     55 H223ChannelParam::H223ChannelParam(const H223ChannelParam & that) : CPVChannelParam(),
     56         pH223Lcp(NULL), pDataType(NULL)
     57 {
     58     lcn = that.lcn;
     59     if (that.pH223Lcp)
     60     {
     61         pH223Lcp = Copy_H223LogicalChannelParameters(that.pH223Lcp);
     62     }
     63     if (that.pDataType)
     64     {
     65         pDataType = Copy_DataType(that.pDataType);
     66     }
     67     bitrate = that.bitrate;
     68     sample_interval = that.sample_interval;
     69 }
     70 
     71 H223ChannelParam::~H223ChannelParam()
     72 {
     73     if (pH223Lcp)
     74     {
     75         Delete_H223LogicalChannelParameters(pH223Lcp);
     76         OSCL_DEFAULT_FREE(pH223Lcp);
     77         pH223Lcp = NULL;
     78     }
     79     if (pDataType)
     80     {
     81         Delete_DataType(pDataType);
     82         OSCL_DEFAULT_FREE(pDataType);
     83         pDataType = NULL;
     84     }
     85 }
     86 
     87 H223ChannelParam& H223ChannelParam::operator =(const H223ChannelParam & that)
     88 {
     89     Clear();
     90     lcn = that.lcn;
     91     SetLcnParams(that.pH223Lcp);
     92     SetDataType(that.pDataType);
     93     bitrate = that.bitrate;
     94     sample_interval = that.sample_interval;
     95     return *this;
     96 }
     97 
     98 void H223ChannelParam::SetLcnParams(PS_H223LogicalChannelParameters lcp)
     99 {
    100     if (pH223Lcp)
    101     {
    102         Delete_H223LogicalChannelParameters(pH223Lcp);
    103         OSCL_DEFAULT_FREE(pH223Lcp);
    104         pH223Lcp = NULL;
    105     }
    106     if (lcp)
    107     {
    108         pH223Lcp = Copy_H223LogicalChannelParameters(lcp);
    109     }
    110 }
    111 
    112 void H223ChannelParam::SetDataType(PS_DataType dt)
    113 {
    114     if (pDataType)
    115     {
    116         Delete_DataType(pDataType);
    117         OSCL_DEFAULT_FREE(pDataType);
    118         pDataType = NULL;
    119     }
    120     if (dt)
    121     {
    122         pDataType = Copy_DataType(dt);
    123     }
    124 }
    125 
    126 void H223ChannelParam::Clear()
    127 {
    128     lcn = CHANNEL_ID_UNKNOWN;
    129     SetLcnParams(NULL);
    130     SetDataType(NULL);
    131 }
    132 
    133 PS_H223LogicalChannelParameters H223ChannelParam::GetLcnParams()
    134 {
    135     return pH223Lcp;
    136 }
    137 
    138 PS_DataType H223ChannelParam::GetDataType()
    139 {
    140     return pDataType;
    141 }
    142 
    143 void H223ChannelParam::SetChannelId(TPVChannelId id)
    144 {
    145     lcn = id;
    146 }
    147 
    148 TPVChannelId H223ChannelParam::GetChannelId()
    149 {
    150     return lcn;
    151 }
    152 unsigned H223ChannelParam::GetBitrate()
    153 {
    154     return bitrate;
    155 }
    156 
    157 unsigned H223ChannelParam::GetSampleInterval()
    158 {
    159     return sample_interval;
    160 }
    161 
    162 unsigned H223ChannelParam::GetFormatSpecificInfo(uint8*& fsi)
    163 {
    164     return ::GetFormatSpecificInfo(GetDataType(), fsi);
    165 }
    166 
    167 OlcParam* OlcParam::NewL(TPVDirection dir,
    168                          TPVChannelId id,
    169                          H223ChannelParam* forward_params,
    170                          H223ChannelParam* reverse_params)
    171 {
    172     OlcParam* ret = OSCL_NEW(OlcParam, ());
    173     ret->Set(dir, id, forward_params, reverse_params);
    174     return ret;
    175 }
    176 
    177 OlcParam::OlcParam()
    178         : iForwardParams(NULL),
    179         iReverseParams(NULL)
    180 {
    181     iState = OLC_IDLE;
    182     iDir = OUTGOING;
    183     iId = CHANNEL_ID_UNKNOWN;
    184     iMtState = MT_IDLE;
    185     iMtSn = H223_DEFAULT_MT_SN;
    186     iMtNum = H223_DEFAULT_MT_NUM;
    187     iReplacementForChannelId = CHANNEL_ID_UNKNOWN;
    188     iMyType = 0;
    189 }
    190 
    191 void OlcParam::Set(TPVDirection dir, TPVChannelId id, H223ChannelParam* forward_params, H223ChannelParam* reverse_params)
    192 {
    193     iDir = dir;
    194     iId = id;
    195     if (iForwardParams)
    196     {
    197         OSCL_DELETE(iForwardParams);
    198         iForwardParams = NULL;
    199     }
    200     if (iReverseParams)
    201     {
    202         OSCL_DELETE(iReverseParams);
    203         iReverseParams = NULL;
    204     }
    205 
    206     if (forward_params)
    207     {
    208         iForwardParams = OSCL_NEW(H223ChannelParam, (*forward_params));
    209     }
    210     if (reverse_params)
    211     {
    212         iReverseParams = OSCL_NEW(H223ChannelParam, (*reverse_params));
    213     }
    214 }
    215 
    216 void OlcParam::InitOlc(TPVDirection dir,
    217                        TPVChannelId id,
    218                        PS_DataType dt,
    219                        PS_H223LogicalChannelParameters lcp,
    220                        TPVChannelId idRvs,
    221                        PS_DataType dtRvs,
    222                        PS_H223LogicalChannelParameters lcpRvs)
    223 {
    224     H223ChannelParam* forward_params = new H223ChannelParam(id, lcp, dt);
    225     H223ChannelParam* reverse_params = NULL;
    226     if (lcpRvs)
    227     {
    228         reverse_params = new H223ChannelParam(idRvs, lcpRvs, dtRvs);
    229     }
    230     // insert into the list of olcs
    231     Set(dir, id, forward_params, reverse_params);
    232     SetState(OLC_PENDING);
    233     delete forward_params;
    234     if (reverse_params)
    235         delete reverse_params;
    236 }
    237 
    238 OlcParam::~OlcParam()
    239 {
    240     if (iForwardParams)
    241     {
    242         OSCL_DELETE(iForwardParams);
    243         iForwardParams = NULL;
    244     }
    245     if (iReverseParams)
    246     {
    247         OSCL_DELETE(iReverseParams);
    248         iReverseParams = NULL;
    249     }
    250 }
    251 
    252 TPVDirection OlcParam::GetDirection()
    253 {
    254     return iDir;
    255 }
    256 
    257 TPVChannelId OlcParam::GetChannelId()
    258 {
    259     return iId;
    260 }
    261 
    262 void OlcParam::SetState(OlcState state)
    263 {
    264     iState = state;
    265 }
    266 
    267 OlcState OlcParam::GetState()
    268 {
    269     return iState;
    270 }
    271 
    272 TPVDirectionality OlcParam::GetDirectionality()
    273 {
    274     return iReverseParams ? EPVT_BI_DIRECTIONAL : EPVT_UNI_DIRECTIONAL;
    275 }
    276 
    277 H223ChannelParam* OlcParam::GetForwardParams()
    278 {
    279     return iForwardParams;
    280 }
    281 
    282 H223ChannelParam* OlcParam::GetReverseParams()
    283 {
    284     return iReverseParams;
    285 }
    286 
    287 void OlcParam::SetMtState(MtState state)
    288 {
    289     iMtState = state;
    290 }
    291 
    292 MtState OlcParam::GetMtState()
    293 {
    294     return iMtState;
    295 }
    296 
    297 void OlcParam::SetMtSn(int32 sn)
    298 {
    299     iMtSn = sn;
    300 }
    301 
    302 int32 OlcParam::GetMtSn()const
    303 {
    304     return iMtSn;
    305 }
    306 
    307 void OlcParam::SetMtNum(uint32 num)
    308 {
    309     iMtNum = num;
    310 }
    311 
    312 uint32 OlcParam::GetMtNum()const
    313 {
    314     return iMtNum;
    315 }
    316 
    317 void OlcParam::SetReplacementFor(TPVChannelId id)
    318 {
    319     iReplacementForChannelId = id;
    320 }
    321 
    322 TPVChannelId OlcParam::GetReplacementFor()
    323 {
    324     return iReplacementForChannelId;
    325 }
    326 
    327 OlcList::OlcList()
    328 {
    329 }
    330 
    331 OlcList::~OlcList()
    332 {
    333     Clear();
    334 }
    335 
    336 void OlcList::Clear()
    337 {
    338     OlcParam* olc = NULL;
    339     OlcList::iterator it = begin();
    340     while (it != end())
    341     {
    342         olc = (*it++).second;
    343         OSCL_DELETE(olc);
    344     }
    345     clear();
    346 }
    347 
    348 bool OlcList::HasOlcs(TPVDirection dir,
    349                       PV2WayMediaType media_type,
    350                       unsigned states)
    351 {
    352     bool hasOlcs = false;
    353     OlcList::iterator it = begin();
    354     while (it != end())
    355     {
    356         value_type& val = (*it++);
    357         PV2WayMediaType mt_cur =::GetMediaType(val.second->GetForwardParams()->GetDataType());
    358         if (val.first.iDir == dir &&
    359                 (media_type == PV_MEDIA_NONE || mt_cur == media_type) &&
    360                 (states & val.second->GetState()))
    361         {
    362             hasOlcs = true;
    363             break;
    364         }
    365     }
    366     return hasOlcs;
    367 }
    368 
    369 unsigned OlcList::FindOutgoingOlcsByMtState(unsigned states,
    370         Oscl_Vector<OlcParam*, OsclMemAllocator>& list)
    371 {
    372     OlcList::iterator it = begin();
    373     list.clear();
    374     while (it != end())
    375     {
    376         value_type& val = (*it++);
    377         if ((val.first.iDir == OUTGOING || val.second->GetDirectionality() == EPVT_BI_DIRECTIONAL) &&
    378                 states & val.second->GetMtState())
    379         {
    380             list.push_back(val.second);
    381         }
    382     }
    383     return list.size();
    384 }
    385 
    386 unsigned OlcList::FindCodecs(TPVDirection dir,
    387                              PV2WayMediaType media_type,
    388                              unsigned states,
    389                              TPVDirection owner,
    390                              Oscl_Vector<OlcFormatInfo, OsclMemAllocator>& list)
    391 {
    392     OlcFormatInfo info;
    393     OlcList::iterator it = begin();
    394     list.clear();
    395     while (it != end())
    396     {
    397         value_type& val = (*it++);
    398         if ((owner == PV_DIRECTION_BOTH || owner == PV_DIRECTION_NONE || val.first.iDir == owner) &&
    399                 ((val.first.iDir == dir) || (val.second->GetDirectionality() == EPVT_BI_DIRECTIONAL)) &&
    400                 (val.second->GetState() & states))
    401         {
    402             H223ChannelParam* h223params = (dir == val.first.iDir) ? val.second->GetForwardParams() :
    403                                            val.second->GetReverseParams();
    404             PVCodecType_t codec =::GetCodecType(h223params->GetDataType());
    405             if (codec == PV_CODEC_TYPE_NONE)
    406                 continue;
    407             if ((media_type == PV_MEDIA_NONE) ||
    408                     (::GetMediaType(h223params->GetDataType()) == media_type))
    409             {
    410                 info.iId = h223params->GetChannelId();
    411                 info.iCodec = codec;
    412                 info.isSymmetric = true;
    413                 list.push_back(info);
    414             }
    415         }
    416     }
    417     return list.size();
    418 }
    419 
    420 bool OlcList::FindCodec(TPVDirection dir,
    421                         PV2WayMediaType media_type,
    422                         unsigned states,
    423                         TPVDirection owner,
    424                         OlcFormatInfo& info)
    425 {
    426     OlcList::iterator it = begin();
    427     while (it != end())
    428     {
    429         value_type& val = (*it++);
    430         if ((owner == PV_DIRECTION_BOTH || owner == PV_DIRECTION_NONE || val.first.iDir == owner) &&
    431                 ((val.first.iDir == dir) || (val.second->GetDirectionality() == EPVT_BI_DIRECTIONAL)) &&
    432                 (val.second->GetState() & states))
    433         {
    434             H223ChannelParam* h223params = (dir == val.first.iDir) ? val.second->GetForwardParams() :
    435                                            val.second->GetReverseParams();
    436             if ((media_type == PV_MEDIA_NONE) ||
    437                     (::GetMediaType(h223params->GetDataType()) == media_type))
    438             {
    439                 info.iId = h223params->GetChannelId();
    440                 info.iCodec = ::GetCodecType(h223params->GetDataType());
    441                 info.isSymmetric = true;
    442                 return true;
    443             }
    444         }
    445     }
    446     return false;
    447 }
    448 
    449 bool OlcList::IsSymmetric(PV2WayMediaType media_type,
    450                           TPVDirection out_owner,
    451                           unsigned outgoing_states,
    452                           TPVDirection in_owner,
    453                           unsigned incoming_states)
    454 {
    455     OlcFormatInfo outgoing_info, incoming_info;
    456     if (FindCodec(OUTGOING,  media_type, outgoing_states, out_owner, outgoing_info) &&
    457             FindCodec(INCOMING,  media_type, incoming_states, in_owner, incoming_info))
    458     {
    459         return (outgoing_info.iCodec == incoming_info.iCodec);
    460     }
    461     return true;
    462 }
    463 
    464 
    465 OlcParam* OlcList::AppendOlc(TPVDirection dir,
    466                              TPVChannelId id,
    467                              PS_DataType dt,
    468                              PS_H223LogicalChannelParameters lcp,
    469                              TPVChannelId idRvs,
    470                              PS_DataType dtRvs,
    471                              PS_H223LogicalChannelParameters lcpRvs)
    472 {
    473     OlcParam* olc = OSCL_NEW(OlcParam, ());
    474     olc->InitOlc(dir, id, dt, lcp, idRvs, dtRvs, lcpRvs);
    475     AppendOlc(olc, dir, id);
    476 
    477     return olc;
    478 }
    479 
    480 void OlcList::AppendOlc(OlcParam* param,
    481                         TPVDirection dir,
    482                         TPVChannelId id)
    483 {
    484     OlcKey key(dir, id);
    485     insert(OlcList::value_type(key, param));
    486 }
    487 
    488 
    489 unsigned OlcList::FindOlcs(TPVDirection dir,
    490                            PV2WayMediaType media_type,
    491                            unsigned states,
    492                            Oscl_Vector<OlcParam*, OsclMemAllocator>& list)
    493 {
    494     OlcList::iterator it = begin();
    495     list.clear();
    496     while (it != end())
    497     {
    498         value_type& val = (*it++);
    499         PV2WayMediaType mt_cur =::GetMediaType(val.second->GetForwardParams()->GetDataType());
    500         if (val.first.iDir == dir &&
    501                 (media_type == PV_MEDIA_NONE || (mt_cur == media_type)))
    502         {
    503             if (states & val.second->GetState())
    504             {
    505                 list.push_back(val.second);
    506             }
    507         }
    508     }
    509     return list.size();
    510 }
    511 
    512 
    513 OlcParam* OlcList::FindOlcByMtSn(uint32 sn)
    514 {
    515     OlcList::iterator it = begin();
    516     while (it != end())
    517     {
    518         OlcList::value_type& val = (*it++);
    519         OlcParam* olc = val.second;
    520         if (olc->GetDirection() == OUTGOING || olc->GetReverseParams())
    521         {
    522             if (olc->GetMtSn() >= 0 && sn == (uint32)olc->GetMtSn())
    523             {
    524                 return olc;
    525             }
    526         }
    527     }
    528     return NULL;
    529 }
    530 
    531 OlcParam* OlcList::FindOlcGivenChannel(TPVDirection dir, TPVChannelId lcn)
    532 {
    533     OlcKey key(dir, lcn);
    534     OlcList::iterator iter = find(key);
    535     if (iter == end() || ((*iter).second == NULL))
    536     {
    537         return NULL;
    538     }
    539     return (*iter).second;
    540 }
    541 
    542 
    543 OlcParam* OlcList::FindOlc(TPVDirection dir, PV2WayMediaType media_type, unsigned state)
    544 {
    545     OlcList::iterator it = begin();
    546     while (it != end())
    547     {
    548         value_type& val = (*it++);
    549         PV2WayMediaType mt_cur =::GetMediaType(val.second->GetForwardParams()->GetDataType());
    550         if (val.first.iDir == dir &&
    551                 (media_type == PV_MEDIA_NONE || (mt_cur == media_type)))
    552         {
    553             if (state & val.second->GetState())
    554             {
    555                 return val.second;
    556             }
    557         }
    558     }
    559     return NULL;
    560 }
    561 
    562 bool OlcList::HasOlc(TPVDirection dir, TPVChannelId lcn)
    563 {
    564     OlcKey key(dir, lcn);
    565     OlcList::iterator iter = find(key);
    566     if (iter == end() || ((*iter).second == NULL))
    567     {
    568         return false;
    569     }
    570     return true;
    571 }
    572 
    573 bool OlcList::HasOlc(TPVDirection dir, TPVChannelId lcn, unsigned state)
    574 {
    575     OlcKey key(dir, lcn);
    576     OlcList::iterator iter = find(key);
    577     if (iter == end() || ((*iter).second == NULL))
    578     {
    579         return false;
    580     }
    581     else
    582     {
    583         // loop through and find one with given state
    584         while (iter != end())
    585         {
    586             OlcParam* olcparam = (*iter++).second;
    587             int tempState = state;
    588             if (olcparam->GetState() == tempState)
    589             {
    590                 return true;
    591             }
    592         }
    593     }
    594     return false;
    595 }
    596 
    597 void OlcList::SetCurrLcn(TPVChannelId aCurLcn)
    598 {
    599     iCurLcn = aCurLcn;
    600 }
    601 
    602 TPVChannelId OlcList::GetNextAvailLcn()
    603 {
    604     TPVChannelId ret = iCurLcn++;
    605     bool duplicate = true;
    606     while (duplicate)
    607     {
    608         OlcParam* olc_param = FindOlcGivenChannel(OUTGOING, ret);
    609         if (ret && (olc_param == NULL))
    610             duplicate = false;
    611         else
    612             ret = iCurLcn++;
    613     }
    614     return ret;
    615 }
    616 
    617 
    618 int TPVMuxDescriptorSlot::is_fit(unsigned that_lcn, unsigned size)
    619 {
    620     int ret = (lcn == that_lcn);
    621     if (ret && size && max_size)
    622     {
    623         ret = (size >= min_size && size <= max_size);
    624     }
    625     return ret;
    626 }
    627 
    628 OSCL_EXPORT_REF CPVMultiplexEntryDescriptor* CPVMultiplexEntryDescriptor::NewL(PS_MultiplexEntryDescriptor descriptor,
    629         unsigned max_pdu_size)
    630 {
    631     CPVMultiplexEntryDescriptor* ret = OSCL_NEW(CPVMultiplexEntryDescriptor, ());
    632     ret->ConstructL(descriptor, max_pdu_size);
    633     return ret;
    634 }
    635 
    636 
    637 CPVMultiplexEntryDescriptor::CPVMultiplexEntryDescriptor():
    638         iDescriptor(NULL),
    639         iMaxPduSize(0)
    640 {
    641 }
    642 
    643 OSCL_EXPORT_REF CPVMultiplexEntryDescriptor::CPVMultiplexEntryDescriptor(const CPVMultiplexEntryDescriptor& that)
    644 {
    645     ConstructL(that.iDescriptor, that.iMaxPduSize);
    646 }
    647 
    648 OSCL_EXPORT_REF CPVMultiplexEntryDescriptor::~CPVMultiplexEntryDescriptor()
    649 {
    650     iLcns.clear();
    651 
    652     if (iDescriptor)
    653     {
    654         Delete_MultiplexEntryDescriptor(iDescriptor);
    655         OSCL_DEFAULT_FREE(iDescriptor);
    656         iDescriptor = NULL;
    657     }
    658 }
    659 
    660 void CPVMultiplexEntryDescriptor::ConstructL(PS_MultiplexEntryDescriptor descriptor, unsigned max_pdu_size)
    661 {
    662     OSCL_ASSERT(descriptor);
    663     bool control_descriptor = false;
    664     if (descriptor->multiplexTableEntryNumber == 0)
    665     {
    666         descriptor->multiplexTableEntryNumber = 1;
    667         control_descriptor = true;
    668     }
    669     iDescriptor = Copy_MultiplexEntryDescriptor(descriptor);
    670     if (control_descriptor)
    671     {
    672         iDescriptor->multiplexTableEntryNumber = 0;
    673         descriptor->multiplexTableEntryNumber = 0;
    674     }
    675     iMaxPduSize = max_pdu_size;
    676 
    677     if (descriptor->option_of_elementList)
    678     {
    679         int size = 0;
    680         FindLcns(descriptor->elementList, descriptor->size_of_elementList, iMaxPduSize, iLcns, &size);
    681     }
    682 }
    683 
    684 OSCL_EXPORT_REF int CPVMultiplexEntryDescriptor::FindLcn(uint16 channel_id, uint16 len, TPVMuxDescriptorSlot& slot_info)
    685 {
    686     TPVMuxDescriptorSlotList::iterator it = iLcns.find(channel_id);
    687     int ret = 0;
    688     if (it != iLcns.end())
    689     {
    690         TPVMuxDescriptorSlot& found_slot = (*it).second;
    691         if (found_slot.is_fit(channel_id, len))
    692         {
    693             slot_info = (*it).second;
    694             ret = 1;
    695         }
    696     }
    697     return ret;
    698 }
    699 
    700 unsigned CPVMultiplexEntryDescriptor::FindLcns(
    701     PS_MultiplexElement pElement,
    702     int ListSize,
    703     int max_pdu_size,
    704     TPVMuxDescriptorSlotList& lcns,
    705     int* subelement_size)
    706 {
    707     unsigned num_lcns = 0;
    708     *subelement_size = 0;
    709 
    710     for (int cnt = ListSize ; cnt != 0 ; cnt --)
    711     {
    712         /* SubElemnt Search */
    713         if (pElement->muxType.index)
    714         {
    715             int size = 0;
    716             TPVMuxDescriptorSlotList lcns_local;
    717             num_lcns += FindLcns(pElement->muxType.subElementList, pElement->muxType.size, max_pdu_size, lcns_local, &size);
    718             OSCL_ASSERT(size);
    719             unsigned rc_min = 0;
    720             unsigned rc_max = 0;
    721             if (pElement->repeatCount.index)
    722             {
    723                 // ucf
    724                 rc_max = max_pdu_size / size;
    725                 rc_min = 1;
    726             }
    727             else
    728             {
    729                 // finite
    730                 rc_max = rc_min = pElement->repeatCount.finite;
    731             }
    732             /* update the subelement size */
    733             *subelement_size += (rc_max * size);
    734 
    735             /* update the max size */
    736             max_pdu_size -= (*subelement_size);
    737 
    738             /* Multiply the max and min sizes in lcns_local by rc, and add to the lcns list */
    739             TPVMuxDescriptorSlotList::iterator it = lcns_local.begin();
    740 
    741             while (it != lcns_local.end())
    742             {
    743                 TPVMuxDescriptorSlot slot_info = {0, 0, 0};
    744                 TPVMuxDescriptorSlot& slot = (*it++).second;
    745 
    746                 slot.max_size *= rc_max;
    747                 slot.min_size *= rc_min;
    748                 /* is it present in the lcns list ? */
    749                 if (FindLcn((uint16)slot.lcn, 0, slot_info) <= 0)
    750                 {
    751                     lcns.insert(TPVMuxDescriptorSlotList::value_type(slot.lcn, slot_info));
    752                 }
    753                 slot_info.lcn = slot.lcn;
    754                 slot_info.min_size += slot.min_size;
    755                 slot_info.max_size += slot.max_size;
    756                 lcns[slot.lcn] = slot_info;
    757             }
    758         }
    759         else
    760         {
    761             TPVMuxDescriptorSlot slot_info = {0, 0, 0};
    762             unsigned min_size = 0;
    763             unsigned max_size = 0;
    764             if (pElement->repeatCount.index)
    765             {
    766                 // ucf
    767                 min_size = 1;
    768                 max_size = 0;
    769             }
    770             else
    771             {
    772                 // finite
    773                 min_size = max_size = pElement->repeatCount.finite;
    774             }
    775             slot_info.lcn = pElement->muxType.logicalChannelNumber;
    776             slot_info.min_size = min_size;
    777             slot_info.max_size = max_size;
    778             lcns.insert(TPVMuxDescriptorSlotList::value_type(slot_info.lcn, slot_info));
    779             num_lcns++;
    780             *subelement_size += max_size;
    781             max_pdu_size -= max_size;
    782         }
    783         pElement ++;
    784     }
    785     return num_lcns;
    786 }
    787 
    788 OSCL_EXPORT_REF unsigned CPVMultiplexEntryDescriptor::NumLcns()
    789 {
    790     return iLcns.size();
    791 }
    792 
    793 OSCL_EXPORT_REF PS_MultiplexEntryDescriptor CPVMultiplexEntryDescriptor::GetH245descriptor()
    794 {
    795     return iDescriptor;
    796 }
    797 
    798 OSCL_EXPORT_REF CPVMultiplexEntryDescriptorVector::CPVMultiplexEntryDescriptorVector()
    799 {
    800 
    801 }
    802 
    803 OSCL_EXPORT_REF CPVMultiplexEntryDescriptorVector::CPVMultiplexEntryDescriptorVector(const CPVMultiplexEntryDescriptorVector& that) :  Oscl_Vector<CPVMultiplexEntryDescriptor*, OsclMemAllocator>(that)
    804 
    805 {
    806     CPVMultiplexEntryDescriptor* desc = NULL;
    807     for (unsigned num = 0; num < that.size(); num++)
    808     {
    809         desc = OSCL_NEW(CPVMultiplexEntryDescriptor, (*that[num]));
    810         push_back(desc);
    811     }
    812 }
    813 
    814 OSCL_EXPORT_REF CPVMultiplexEntryDescriptorVector::~CPVMultiplexEntryDescriptorVector()
    815 {
    816     Clear();
    817 }
    818 
    819 OSCL_EXPORT_REF void CPVMultiplexEntryDescriptorVector::Clear()
    820 {
    821     CPVMultiplexEntryDescriptor* desc = NULL;
    822     while (size())
    823     {
    824         desc = back();
    825         OSCL_DELETE(desc);
    826         pop_back();
    827     }
    828 }
    829