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 "oscl_rand.h"
     19 #include "logicalchannel.h"
     20 #include "pvmf_simple_media_buffer.h"
     21 #include "pvmf_media_data.h"
     22 #include "pvmf_media_cmd.h"
     23 #include "pvmf_media_msg_format_ids.h"
     24 
     25 #ifndef OSCL_MIME_STRING_UTILS_H
     26 #include "pv_mime_string_utils.h"
     27 #endif
     28 
     29 #ifndef PER_COPIER
     30 #include "h245_copier.h"
     31 #endif
     32 
     33 #ifndef PER_DELETER
     34 #include "h245_deleter.h"
     35 #endif
     36 // decreasing DEF_CHANNEL_BUFFER_SIZE_MS can result out of memory errors,
     37 // please change also PV_MAX_VIDEO_FRAME_SIZE to lower value.
     38 #define DEF_CHANNEL_BITRATE 64000
     39 #define DEF_INCOMING_CHANNEL_BUFFER_SIZE_MS 2800
     40 #define DEF_OUTGOING_CHANNEL_BUFFER_SIZE_MS 2800
     41 #define TIMESTAMP_MAX INT_MAX
     42 #define DEF_SEGMENTABLE_CHANNEL_OH_BPS 2000
     43 #define H223_INCOMING_CHANNEL_NUM_MEDIA_MSG 300
     44 #define H223_OUTGOING_CHANNEL_NUM_MEDIA_MSG 300
     45 #define H223_INCOMING_CHANNEL_FRAGMENT_SIZE 128
     46 #define H223_INCOMING_CHANNEL_NUM_MEDIA_DATA 300
     47 #define H223_INCOMING_CHANNEL_NUM_FRAGS_IN_MEDIA_DATA (3*1024/128)
     48 #define PV2WAY_BPS_TO_BYTES_PER_MSEC_RIGHT_SHIFT 13
     49 
     50 
     51 #define H223_LCN_IN_TIMESTAMP_BASE 40
     52 
     53 
     54 H223LogicalChannel::H223LogicalChannel(TPVChannelId num,
     55                                        bool segmentable,
     56                                        OsclSharedPtr<AdaptationLayer>& al,
     57                                        PS_DataType data_type,
     58                                        LogicalChannelObserver* observer,
     59                                        uint32 bitrate,
     60                                        uint32 sample_interval,
     61                                        uint32 num_media_data)
     62         : PvmfPortBaseImpl(num, this),
     63         lcn(num),
     64         next(NULL),
     65         iAl(al),
     66         iBitrate(0),
     67         iSampleInterval(0),
     68         iObserver(observer),
     69         iFormatSpecificInfo(NULL),
     70         iFormatSpecificInfoLen(0),
     71         iLogger(NULL),
     72         iDataType(NULL),
     73         iAudioLatency(0),
     74         iVideoLatency(0)
     75 {
     76     iSegmentable = segmentable;
     77     iIncomingSkew = 0;
     78     iLastSduTimestamp = 0;
     79     iSampleInterval = sample_interval;
     80     uint32 bitrate_overhead = IsSegmentable() ? DEF_SEGMENTABLE_CHANNEL_OH_BPS :
     81                               (uint32)((2000 / sample_interval + 1) >> 1) * (al->GetHdrSz() + al->GetTrlrSz());
     82     iBitrate = bitrate + bitrate_overhead;
     83     iNumMediaData = num_media_data;
     84     iMaxSduSize = (uint16)(iAl->GetSduSize() - iAl->GetHdrSz() - iAl->GetTrlrSz());
     85     if (data_type)
     86     {
     87         iDataType = Copy_DataType(data_type);
     88     }
     89     iMediaType = GetFormatType();
     90     iPaused = false;
     91     iClock = NULL;
     92 }
     93 
     94 H223LogicalChannel::~H223LogicalChannel()
     95 {
     96     if (iDataType)
     97     {
     98         Delete_DataType(iDataType);
     99         OSCL_DEFAULT_FREE(iDataType);
    100         iDataType = NULL;
    101     }
    102     if (iFormatSpecificInfo)
    103     {
    104         oscl_free(iFormatSpecificInfo);
    105         iFormatSpecificInfo = NULL;
    106         iFormatSpecificInfoLen = 0;
    107     }
    108 
    109 }
    110 
    111 void H223LogicalChannel::Init()
    112 {
    113     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LogicalChannel::Init"));
    114     iSendFormatSpecificInfo = false;
    115 }
    116 
    117 PVMFStatus H223LogicalChannel::SetFormatSpecificInfo(uint8* info, uint16 info_len)
    118 {
    119     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LogicalChannel::SetFormatSpecificInfo lcn=%d, info_len=%d, info=%x", lcn, info_len, info));
    120     iSendFormatSpecificInfo = false;
    121     if (iFormatSpecificInfo)
    122     {
    123         oscl_free(iFormatSpecificInfo);
    124         iFormatSpecificInfo = NULL;
    125         iFormatSpecificInfoLen = 0;
    126     }
    127 
    128     if (info == NULL || info_len == 0)
    129         return PVMFSuccess;
    130 
    131     iFormatSpecificInfo = (uint8*)oscl_malloc(info_len);
    132     oscl_memcpy(iFormatSpecificInfo, info, info_len);
    133     iFormatSpecificInfoLen = info_len;
    134     iSendFormatSpecificInfo = true;
    135     return PVMFSuccess;
    136 }
    137 
    138 const uint8* H223LogicalChannel::GetFormatSpecificInfo(uint32* info_len)
    139 {
    140     if (info_len == NULL)
    141     {
    142         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LogicalChannel::GetFormatSpecificInfo ERROR info_len==NULL"));
    143         return NULL;
    144     }
    145     *info_len = iFormatSpecificInfoLen;
    146     return iFormatSpecificInfo;
    147 }
    148 
    149 
    150 OSCL_EXPORT_REF void H223LogicalChannel::QueryInterface(const PVUuid& aUuid, OsclAny*& aPtr)
    151 {
    152     aPtr = NULL;
    153     if (aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
    154     {
    155         aPtr = (PvmiCapabilityAndConfig*)this;
    156     }
    157     else if (aUuid == PVH324MLogicalChannelInfoUuid)
    158     {
    159         aPtr = (LogicalChannelInfo*)this;
    160     }
    161     else
    162     {
    163         OSCL_LEAVE(OsclErrNotSupported);
    164     }
    165 }
    166 
    167 void H223LogicalChannel::Pause()
    168 {
    169     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Pause lcn=%d", lcn));
    170     iPaused = true;
    171     // flush any pending media data
    172     Flush();
    173 }
    174 
    175 void H223LogicalChannel::Resume()
    176 {
    177     iPaused = false;
    178 }
    179 
    180 H223OutgoingChannel::H223OutgoingChannel(TPVChannelId num,
    181         bool segmentable,
    182         OsclSharedPtr<AdaptationLayer>& al,
    183         PS_DataType data_type,
    184         LogicalChannelObserver* observer,
    185         uint32 bitrate,
    186         uint32 sample_interval,
    187         uint32 num_media_data)
    188         : H223LogicalChannel(num, segmentable, al, data_type, observer, bitrate, sample_interval, num_media_data),
    189         iMediaMsgMemoryPool(NULL),
    190         iMediaDataEntryAlloc(NULL),
    191         iMediaFragGroupAlloc(NULL),
    192         iPduPktMemPool(NULL)
    193 {
    194     iLogger = PVLogger::GetLoggerObject("3g324m.h223.H223OutgoingChannel");
    195     iOutgoingVideoLogger = PVLogger::GetLoggerObject("datapath.outgoing.video.h223.lcn");
    196     iOutgoingAudioLogger = PVLogger::GetLoggerObject("datapath.outgoing.audio.h223.lcn");
    197 
    198     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::H223OutgoingChannel - num(%d),segmentable(%d)", num, segmentable));
    199     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::H223OutgoingChannel - AL SDU size(%d), hdr(%d), trlr(%d)", iAl->GetSduSize(), iAl->GetHdrSz(), iAl->GetTrlrSz()));
    200     ResetStats();
    201     lastMediaData = NULL;
    202 
    203     iSetBufferMediaMs = 0;
    204     iSetBufferMediaBytes = 0;
    205     iBufferMediaMs = 0;
    206     iBufferMediaBytes = 0;
    207     iCurPduTimestamp = 0;
    208     iNumPendingPdus = 0;
    209     iMuxingStarted = false;
    210     iWaitForRandomAccessPoint = false;
    211     iBufferSizeMs = DEF_OUTGOING_CHANNEL_BUFFER_SIZE_MS;
    212 
    213 }
    214 
    215 H223OutgoingChannel::~H223OutgoingChannel()
    216 {
    217     if (iDataType)
    218     {
    219         Delete_DataType(iDataType);
    220         OSCL_DEFAULT_FREE(iDataType);
    221         iDataType = NULL;
    222     }
    223     Flush();
    224     iMediaFragGroupAlloc->removeRef();
    225     OSCL_DELETE(iPduPktMemPool);
    226     OSCL_DELETE(iMediaDataEntryAlloc);
    227     OSCL_DELETE(iMediaMsgMemoryPool);
    228 
    229 }
    230 
    231 void H223OutgoingChannel::Init()
    232 {
    233     H223LogicalChannel::Init();
    234     iMediaMsgMemoryPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (H223_OUTGOING_CHANNEL_NUM_MEDIA_MSG));
    235     iMediaMsgMemoryPool->enablenullpointerreturn();
    236     iMediaDataEntryAlloc = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (iNumMediaData, sizeof(LCMediaDataEntry)));
    237     iMediaDataEntryAlloc->enablenullpointerreturn();
    238     iPduPktMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (iNumMediaData));
    239     iPduPktMemPool->enablenullpointerreturn();
    240     iMediaFragGroupAlloc = OSCL_NEW(PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>, (iNumMediaData, 10, iPduPktMemPool));
    241     iMediaFragGroupAlloc->create();
    242 }
    243 
    244 
    245 void H223OutgoingChannel::BufferMedia(uint16 aMs)
    246 {
    247     if (iBufferSizeMs && aMs > iBufferSizeMs)
    248     {
    249         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::BufferMedia ERROR buffer interval=%d > buffer size=%d", aMs, iBufferSizeMs));
    250     }
    251     iSetBufferMediaMs = iBufferMediaMs = aMs;
    252     iSetBufferMediaBytes = iBufferMediaBytes = ((iBufferSizeMs * iBitrate + 4000) / 8000);
    253     //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223OutgoingChannel::BufferMedia ms=%d,bytes=%d", iBufferMediaMs,iBufferMediaBytes));
    254 }
    255 
    256 void H223OutgoingChannel::Resume()
    257 {
    258     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Resume lcn=%d", lcn));
    259     H223LogicalChannel::Resume();
    260     iPaused = false;
    261     // start muxing on a random access point
    262     //iWaitForRandomAccessPoint=true;
    263 }
    264 
    265 void H223OutgoingChannel::SetBufferSizeMs(uint32 buffer_size_ms)
    266 {
    267     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingLogicalChannel::SetBufferSizeMs buffer_size_ms=%d", buffer_size_ms));
    268     iBufferSizeMs = buffer_size_ms;
    269 }
    270 
    271 
    272 
    273 PVMFStatus H223OutgoingChannel::PutData(PVMFSharedMediaMsgPtr media_msg)
    274 {
    275     PVMFStatus ret = PVMFSuccess;
    276     PVMFSharedMediaDataPtr mediaData;
    277     convertToPVMFMediaData(mediaData, media_msg);
    278 
    279     PV_STAT_SET_TIME(iStartTime, iNumPacketsIn)
    280     PV_STAT_INCR(iNumPacketsIn, 1)
    281 
    282     /* zero through 255 is reserved for media data */
    283     if (media_msg->getFormatID() >= PVMF_MEDIA_CMD_FORMAT_IDS_START)
    284     {
    285         return PVMFSuccess;
    286     }
    287 
    288     PV_STAT_INCR(iNumBytesIn, (mediaData->getFilledSize()))
    289     TimeValue timenow;
    290     if (iMediaType.isCompressed() && iMediaType.isAudio())
    291     {
    292         PVMF_OUTGOING_AUDIO_LOGDATATRAFFIC((0, "Outgoing audio frames received. Stats: Entry time=%ud, lcn=%d, size=%d", timenow.to_msec(), lcn, mediaData->getFilledSize()));
    293     }
    294     else if (iMediaType.isCompressed() && iMediaType.isVideo())
    295     {
    296         PVMF_OUTGOING_VIDEO_LOGDATATRAFFIC((0, "Outgoing video frames received.Stats: Entry time=%ud, lcn=%d, size=%d", timenow.to_msec(), lcn, mediaData->getFilledSize()));
    297     }
    298 
    299     if (iNumPacketsIn % 20 == 0)
    300     {
    301         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData lcn=%d, size=%d, ts=%d", lcn, mediaData->getFilledSize(), mediaData->getTimestamp()));
    302     }
    303 
    304     // Check for FormatSpecificInfo.  Sending FSI with data is being obsoleted, but there is no harm in leaving this in for now.
    305     if (mediaData->getFormatSpecificInfo(iFsiFrag) && iFsiFrag.getMemFragPtr() && iFsiFrag.getMemFragSize())
    306     {
    307         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData Received Format Specific Info, len=%d", iFsiFrag.getMemFragSize()));
    308         iObserver->ReceivedFormatSpecificInfo(lcn, (uint8*)iFsiFrag.getMemFragPtr(), iFsiFrag.getMemFragSize());
    309     }
    310 
    311     if (IsSegmentable() && iWaitForRandomAccessPoint)
    312     {
    313         if ((mediaData->getMarkerInfo()&PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT) == 0)
    314         {
    315             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData Not random access point.  Dropping media data."));
    316             return PVMFErrInvalidState;
    317         }
    318         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData Found random access point."));
    319         iWaitForRandomAccessPoint = false;
    320     }
    321     else if (iNumPendingPdus == (iNumMediaData - 1))
    322     {
    323         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - ERROR Overflow, iNumPendingPdus=%d", iNumPendingPdus));
    324         return PVMFErrOverflow;
    325     }
    326 
    327     uint32 num_frags_required = 0;
    328     uint32 frag_num = 0;
    329     for (frag_num = 0; frag_num < mediaData->getNumFragments(); frag_num++)
    330     {
    331         OsclRefCounterMemFrag memfrag;
    332         mediaData->getMediaFragment(frag_num, memfrag);
    333         if (memfrag.getMemFragSize() > iMaxSduSize)
    334         {
    335             num_frags_required++;
    336         }
    337     }
    338 
    339     if ((mediaData->getNumFragments() + num_frags_required + iNumPendingPdus) >= (iNumMediaData - 1))
    340     {
    341         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - ERROR Overflow, iNumPendingPdus=%d, num_frags_required=%d,iNumMediaData=%d", iNumPendingPdus, num_frags_required, iNumMediaData));
    342         Flush();
    343         /* Start re-buffering */
    344         BufferMedia((uint16)iSetBufferMediaMs);
    345         return PVMFErrOverflow;
    346     }
    347 
    348     /* Fragment the sdu if needed */
    349     PVMFSharedMediaDataPtr& fragmentedMediaData = mediaData;
    350     if (num_frags_required)
    351     {
    352         if (true != FragmentPacket(mediaData, fragmentedMediaData))
    353         {
    354             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - Memory allocation failure on Fragment\n"));
    355             return PVMFErrOverflow;
    356         }
    357     }
    358 
    359     uint32 sdu_size = 0;
    360     if (iCurPdu.GetRep())
    361     {
    362         sdu_size = iCurPdu->getFilledSize() - iAl->GetHdrSz();
    363         /* Is the timestamp different ? */
    364         if (iCurPduTimestamp != fragmentedMediaData->getTimestamp() || !IsSegmentable())
    365         {
    366             if (PVMFSuccess != CompletePdu())
    367             {
    368                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - Memory allocation failure on CompletePdu\n"));
    369                 return PVMFErrOverflow;
    370             }
    371             sdu_size = 0;
    372         }
    373     }
    374     if (sdu_size == 0)
    375     {
    376         //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223OutgoingChannel::PutData Sdu size == 0"));
    377         iCurPdu = StartAlPdu();
    378         if (!iCurPdu)
    379         {
    380             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    381                             (0, "H223OutgoingChannel::PutData - Memory allocation failure on StartAlPdu\n"));
    382             return PVMFErrOverflow;
    383         }
    384 
    385         if (iFsiFrag.getMemFragSize())
    386         {
    387             iCurPdu->appendMediaFragment(iFsiFrag);
    388             // reset the FSI frag
    389             OsclRefCounterMemFrag frag;
    390             iFsiFrag = frag;
    391         }
    392     }
    393 
    394     for (frag_num = 0; frag_num < fragmentedMediaData->getNumFragments(); frag_num++)
    395     {
    396         OsclRefCounterMemFrag frag;
    397         fragmentedMediaData->getMediaFragment(frag_num, frag);
    398         OSCL_ASSERT(frag.getMemFragSize() <= iMaxSduSize);
    399 
    400         if (sdu_size &&
    401                 ((sdu_size + frag.getMemFragSize() > iMaxSduSize) || !IsSegmentable()))
    402         {
    403             if (PVMFSuccess != CompletePdu())
    404             {
    405                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - Memory allocation failure on CompletePdu\n"));
    406                 return PVMFErrOverflow;
    407             }
    408             sdu_size = 0;
    409 
    410             iCurPdu = StartAlPdu();
    411 
    412             if (!iCurPdu)
    413             {
    414                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
    415                                 (0, "H223OutgoingChannel::PutData - Memory allocation failure on StartAlPdu\n"));
    416                 return PVMFErrOverflow;
    417             }
    418         }
    419 
    420         iCurPdu->appendMediaFragment(frag);
    421         sdu_size += frag.getMemFragSize();
    422         iCurPduTimestamp = fragmentedMediaData->getTimestamp();
    423 
    424     }
    425 
    426     if (iMediaType.isCompressed() && iMediaType.isAudio())
    427     {
    428         PVMF_OUTGOING_AUDIO_LOGDATATRAFFIC((0, "Stats of the outgoing audio SDU are: timestamp=%d, size=%d", iCurPduTimestamp, sdu_size));
    429     }
    430     else if (iMediaType.isCompressed() && iMediaType.isVideo())
    431     {
    432         PVMF_OUTGOING_VIDEO_LOGDATATRAFFIC((0, "Stats of the outgoing video SDU are: timestamp=%d, size=%d", iCurPduTimestamp, sdu_size));
    433     }
    434     return ret;
    435 }
    436 
    437 bool H223OutgoingChannel::FragmentPacket(PVMFSharedMediaDataPtr& aMediaData, PVMFSharedMediaDataPtr& aFragmentedMediaData)
    438 {
    439     OsclRefCounterMemFrag memfrag;
    440     OsclSharedPtr<PVMFMediaDataImpl> newpack;
    441     newpack = iMediaFragGroupAlloc->allocate();
    442     if (!newpack.GetRep())
    443     {
    444         return false;
    445     }
    446 
    447     int32 pkt_size = 0;
    448     PVMFTimestamp timestamp = aMediaData->getTimestamp();
    449     for (uint32 frag_num = 0; frag_num < aMediaData->getNumFragments(); frag_num++)
    450     {
    451         aMediaData->getMediaFragment(frag_num, memfrag);
    452         pkt_size = memfrag.getMemFragSize();
    453         if ((unsigned)pkt_size <= iMaxSduSize)
    454         {
    455             newpack->appendMediaFragment(memfrag);
    456         }
    457         else  /* Need to fragment it */
    458         {
    459             uint8* pos = (uint8*)memfrag.getMemFragPtr();
    460             int32 trim_frag_sz = iMaxSduSize;
    461             while (pkt_size)
    462             {
    463                 trim_frag_sz = ((unsigned)pkt_size > iMaxSduSize) ? iMaxSduSize : pkt_size;
    464                 pkt_size -= trim_frag_sz;
    465                 OsclRefCounterMemFrag trim_frag(memfrag);
    466                 trim_frag.getMemFrag().ptr = pos;
    467                 trim_frag.getMemFrag().len = trim_frag_sz;
    468                 newpack->appendMediaFragment(trim_frag);
    469                 pos += trim_frag_sz;
    470             }
    471         }
    472     }
    473     aFragmentedMediaData = PVMFMediaData::createMediaData(newpack, iMediaMsgMemoryPool);
    474     if (aFragmentedMediaData.GetRep())
    475     {
    476         aFragmentedMediaData->setTimestamp(timestamp);
    477         return true;
    478     }
    479     return false;
    480 }
    481 
    482 OsclSharedPtr<PVMFMediaDataImpl> H223OutgoingChannel::StartAlPdu()
    483 {
    484     PV_STAT_INCR(iNumSdusIn, 1)
    485 
    486     // allocate packet
    487     OsclSharedPtr<PVMFMediaDataImpl> pdu = iMediaFragGroupAlloc->allocate();
    488     if (pdu)
    489     {
    490         // Add header
    491         PVMFStatus status = iAl->StartPacket(pdu);
    492         if (status != PVMFSuccess)
    493         {
    494             pdu.Unbind();
    495             return pdu;
    496         }
    497         iNumPendingPdus++;
    498     }
    499 
    500     return pdu;
    501 }
    502 
    503 PVMFStatus H223OutgoingChannel::CompletePdu()
    504 {
    505     PVMFStatus status = iAl->CompletePacket(iCurPdu);
    506     if (status != PVMFSuccess)
    507     {
    508         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::CompletePdu Memory allocation failedlcn=%d, CompletePacket status=%d", lcn, status));
    509         return status;
    510     }
    511     // Add it to the outgoing queue
    512     status = AppendOutgoingPkt(iCurPdu, iCurPduTimestamp);
    513     if (status != PVMFSuccess)
    514     {
    515         return status;
    516     }
    517     iCurPdu.Unbind();
    518     iCurPduTimestamp = 0;
    519     return PVMFSuccess;
    520 }
    521 
    522 PVMFStatus H223OutgoingChannel::AppendOutgoingPkt(OsclSharedPtr<PVMFMediaDataImpl>& pdu,
    523         PVMFTimestamp timestamp,
    524         OsclRefCounterMemFrag* fsi)
    525 {
    526     PVMFSharedMediaDataPtr mediaData = PVMFMediaData::createMediaData(pdu, iMediaMsgMemoryPool);
    527     if (mediaData.GetRep() == NULL)
    528     {
    529         return PVMFErrNoMemory;
    530     }
    531 
    532     mediaData->setTimestamp(timestamp);
    533     if (fsi)
    534     {
    535         mediaData->setFormatSpecificInfo(*fsi);
    536     }
    537     void* memory_for_entry = iMediaDataEntryAlloc->allocate(sizeof(LCMediaDataEntry));
    538     if (!memory_for_entry)
    539     {
    540         // if couldn't allocate memory - leave
    541         return PVMFErrNoMemory;
    542     }
    543     LCMediaDataEntry* entry = new(memory_for_entry) LCMediaDataEntry();
    544     entry->mediaData = mediaData;
    545 
    546     LCMediaDataEntry* first = entry;
    547     PVMFTimestamp lastTS = timestamp;
    548     if (lastMediaData)
    549     {
    550         first = lastMediaData->next;
    551         lastMediaData->next = entry;
    552         lastTS = lastMediaData->mediaData->getTimestamp();
    553     }
    554     lastMediaData = entry;
    555     entry->next = first;
    556 
    557     /* Adjust buffering parameters */
    558     if (iBufferMediaMs)
    559     {
    560         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::AppendOutgoingPkt lcn=%d, last ts=%d,cur ts=%d", lcn, lastTS, timestamp));
    561         /* Compute delta_t from last media data */
    562         int32 delta_t = timestamp - lastTS;
    563         if (delta_t < 0)
    564             delta_t += TIMESTAMP_MAX;
    565         iBufferMediaMs -= delta_t;
    566         iBufferMediaBytes -= mediaData->getFilledSize();
    567         if (iBufferMediaMs <= 0 || iBufferMediaBytes <= 0)
    568         {
    569             iBufferMediaMs = 0;
    570             iBufferMediaBytes = 0;
    571         }
    572     }
    573     return PVMFSuccess;
    574 }
    575 
    576 bool H223OutgoingChannel::GetNextPacket(PVMFSharedMediaDataPtr& aMediaData, PVMFStatus aStatus)
    577 {
    578     if (!iMuxingStarted && aStatus == PVMFSuccess)
    579         iMuxingStarted = true;
    580 
    581     if (lastMediaData == NULL)
    582     {
    583         return false;
    584     }
    585     if ((aStatus == PVMFSuccess) && iPaused)
    586     {
    587         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::GetNextPacket Logical channel %d paused.", lcn));
    588         return false;
    589 
    590     }
    591     if ((aStatus == PVMFSuccess) && iBufferMediaMs && iBufferMediaBytes)
    592     {
    593         /* Still buffering */
    594         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::GetNextPacket Buffering lcn=%d, ms left=%d", lcn, iBufferMediaMs));
    595         return false;
    596     }
    597 
    598     LCMediaDataEntry* first = lastMediaData->next;
    599     aMediaData = first->mediaData;
    600 
    601     if (first == lastMediaData)
    602     {
    603         lastMediaData = NULL;
    604     }
    605     else
    606     {
    607         lastMediaData->next = first->next;
    608     }
    609     first->~LCMediaDataEntry();
    610     iMediaDataEntryAlloc->deallocate(first);
    611 
    612     iNumPendingPdus--;
    613     return true;
    614 }
    615 
    616 OsclAny H223OutgoingChannel::ReleasePacket(PVMFSharedMediaDataPtr& aMediaData)
    617 {
    618     OsclSharedPtr<PVMFMediaDataImpl> aMediaDataImpl;
    619     aMediaData->getMediaDataImpl(aMediaDataImpl);
    620     aMediaDataImpl->clearMediaFragments();
    621 }
    622 
    623 OsclAny H223OutgoingChannel::Flush()
    624 {
    625     //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223OutgoingChannel::Flush\n"));
    626 
    627     PVMFSharedMediaDataPtr aMediaData;
    628     // clear messages in input queue
    629     ClearMsgQueues();
    630     // go through pending queue
    631     while (GetNextPacket(aMediaData, PVMFErrCancelled))
    632     {
    633         PV_STAT_INCR(iNumBytesFlushed, aMediaData->getFilledSize())
    634         OsclSharedPtr<PVMFMediaDataImpl> aMediaDataImpl;
    635         aMediaData->getMediaDataImpl(aMediaDataImpl);
    636         aMediaDataImpl->clearMediaFragments();
    637     }
    638     if (iCurPdu.GetRep())
    639     {
    640         iCurPdu->clearMediaFragments();
    641         iCurPdu.Unbind();
    642     }
    643     iCurPduTimestamp = 0;
    644     iNumPendingPdus = 0;
    645 }
    646 OsclAny H223OutgoingChannel::ResetStats()
    647 {
    648     iNumPacketsIn = 0;
    649     iNumSdusIn = 0;
    650     iNumBytesIn = 0;
    651     iNumSdusDropped = 0;
    652     iNumSdusOut = 0;
    653     iNumBytesOut = 0;
    654     iMaxPacketMuxTime = 0;
    655     iMaxSduMuxTime = 0;
    656     iNumFlush = 0;
    657     iNumBytesFlushed = 0;
    658 }
    659 
    660 OsclAny H223OutgoingChannel::LogStats()
    661 {
    662     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Outgoing Logical Channel %d Statistics:\n", lcn));
    663     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Adaptation layer header bytes -  %d\n", iAl->GetHdrSz()));
    664     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Adaptation layer trailer bytes -  %d\n", iAl->GetTrlrSz()));
    665     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num packets received - %d\n", iNumPacketsIn));
    666     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus received - %d\n", iNumSdusIn));
    667     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes received - %d\n", iNumBytesIn));
    668     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus dropped - %d\n", iNumSdusDropped));
    669     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus output - %d\n", iNumSdusOut));
    670     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes output - %d\n", iNumBytesOut));
    671     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Max packet mux time - %d\n", iMaxPacketMuxTime));
    672     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Max sdu mux time - %d\n", iMaxSduMuxTime));
    673     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num flush - %d\n", iNumFlush));
    674     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes flushed - %d\n", iNumBytesFlushed));
    675 }
    676 
    677 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::Connect(PVMFPortInterface* aPort)
    678 {
    679     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect, aPort=%x", aPort));
    680 
    681     if (iConnectedPort)
    682     {
    683         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect Error: Already connected"));
    684         return PVMFFailure;
    685     }
    686 
    687     PvmiCapabilityAndConfig* config = NULL;
    688     OsclAny* tempInterface = NULL;
    689     aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, tempInterface);
    690     config = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, tempInterface);
    691     if (!config)
    692     {
    693         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect: Error - Peer port does not support capability interface"));
    694         return PVMFFailure;
    695     }
    696 
    697     PVMFStatus status = NegotiateInputSettings(config);
    698 
    699     if (status != PVMFSuccess)
    700     {
    701         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect: Error - Settings negotiation failed. status=%d", status));
    702         return status;
    703     }
    704 
    705     //Automatically connect the peer.
    706     if ((status = aPort->PeerConnect(this)) != PVMFSuccess)
    707     {
    708         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect: Error - Peer Connect failed. status=%d", status));
    709         return status;
    710     }
    711 
    712     iConnectedPort = aPort;
    713 
    714     PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
    715     return PVMFSuccess;
    716 }
    717 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::PeerConnect(PVMFPortInterface* aPort)
    718 {
    719 
    720     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PeerConnect aPort=0x%x", this, aPort));
    721     if (!aPort)
    722     {
    723         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "0x%x H223OutgoingChannel::PeerConnect: Error - Connecting to invalid port", this));
    724         return PVMFErrArgument;
    725     }
    726     if (iConnectedPort)
    727     {
    728         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "0x%x H223OutgoingChannel::PeerConnect: Error - Already connected", this));
    729         return PVMFFailure;
    730     }
    731 
    732     OsclAny* config = NULL;
    733     aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, config);
    734     if (!config)
    735     {
    736         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::PeerConnect: Error - Peer port does not support capability interface"));
    737         return PVMFFailure;
    738     }
    739 
    740 
    741     PVMFStatus status = PVMFSuccess;
    742 
    743     status = NegotiateInputSettings((PvmiCapabilityAndConfig*)config);
    744 
    745     if (status != PVMFSuccess)
    746     {
    747         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::PeerConnect: Error - Settings negotiation failed. status=%d", status));
    748         return status;
    749     }
    750 
    751 
    752     iConnectedPort = aPort;
    753     PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
    754 
    755     return status;
    756 }
    757 
    758 PVMFStatus H223OutgoingChannel::NegotiateFSISettings(PvmiCapabilityAndConfig* aConfig)
    759 {
    760     PvmiKvp* kvp = NULL;
    761     int numParams = 0;
    762 
    763     // Preconfigured FSI
    764     uint8* pc_fsi = NULL;
    765     unsigned pc_fsilen = ::GetFormatSpecificInfo(iDataType, pc_fsi);
    766     if (pc_fsilen && pc_fsi)
    767     {
    768         /*
    769          * Create PvmiKvp for capability settings
    770          */
    771         OsclMemAllocator alloc;
    772         PvmiKvp kvp;
    773         kvp.key = NULL;
    774         kvp.length = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY) + 1; // +1 for \0
    775         kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
    776         if (kvp.key == NULL)
    777         {
    778             return PVMFFailure;
    779         }
    780         oscl_strncpy(kvp.key, PVMF_FORMAT_SPECIFIC_INFO_KEY, kvp.length);
    781 
    782         kvp.value.key_specific_value = (OsclAny*)pc_fsi;
    783         kvp.capacity = pc_fsilen;
    784         kvp.length = pc_fsilen;
    785 
    786         PvmiKvp* retKvp = NULL; // for return value
    787         int32 err;
    788         OSCL_TRY(err, aConfig->setParametersSync(NULL, &kvp, 1, retKvp););
    789         alloc.deallocate((OsclAny*)(kvp.key));
    790         if (err)
    791         {
    792             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::NegotiateFSISettings, Failed to set FSI on peer, err=%d", err));
    793         }
    794         return err;
    795     }
    796 
    797 
    798     // No preconfigured FSI.  In this case try to get the FSI from the peer.
    799     PVMFStatus status = aConfig->getParametersSync(NULL, (PvmiKeyType)PVMF_FORMAT_SPECIFIC_INFO_KEY, kvp, numParams, NULL);
    800     if (status != PVMFSuccess || numParams != 1)
    801     {
    802         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateFSISettings: Failed to get FSI from peer"));
    803         return PVMFSuccess;
    804     }
    805     else
    806     {
    807         ReceivedFSIFromPeer(kvp);
    808         aConfig->releaseParameters(NULL, kvp, numParams);
    809     }
    810 
    811     kvp = NULL;
    812     numParams = 0;
    813     return PVMFSuccess;
    814 
    815 }
    816 
    817 PVMFStatus H223OutgoingChannel::ReceivedFSIFromPeer(PvmiKvp* kvp)
    818 {
    819     // Create mem frag for VOL header
    820     OsclRefCounter* my_refcnt;
    821     OsclMemAllocDestructDealloc<uint8> my_alloc;
    822     uint aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
    823     uint8* my_ptr = (uint8*) my_alloc.allocate(aligned_refcnt_size + kvp->length);
    824     my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
    825     my_ptr += aligned_refcnt_size;
    826 
    827     oscl_memcpy(my_ptr, kvp->value.key_specific_value, kvp->length);
    828 
    829     OsclMemoryFragment memfrag;
    830     memfrag.len = kvp->length;
    831     memfrag.ptr = my_ptr;
    832 
    833     OsclRefCounterMemFrag configinfo(memfrag, my_refcnt, kvp->length);
    834     iFsiFrag = configinfo;
    835 
    836     SetFormatSpecificInfo((uint8*)kvp->value.key_specific_value, kvp->length);
    837 
    838     iObserver->ReceivedFormatSpecificInfo(lcn, (uint8*)kvp->value.key_specific_value, kvp->length);
    839     return PVMFSuccess;
    840 }
    841 
    842 
    843 PVMFStatus H223OutgoingChannel::NegotiateInputSettings(PvmiCapabilityAndConfig* aConfig)
    844 {
    845     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::NegotiateInputSettings, aConfig=%x", aConfig));
    846 
    847     PvmiKvp* kvp = NULL;
    848     int numParams = 0;
    849     int32 i = 0;
    850 
    851     // Get supported output formats from peer
    852     PVMFStatus status = aConfig->getParametersSync(NULL,
    853                         OSCL_CONST_CAST(char*, OUTPUT_FORMATS_CAP_QUERY),
    854                         kvp, numParams, NULL);
    855     if (status != PVMFSuccess || numParams == 0)
    856     {
    857         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error:  getParametersSync failed.  status=%d", status));
    858         return status;
    859     }
    860 
    861     PvmiKvp* selectedKvp = NULL;
    862     PVCodecType_t codec_type = GetCodecType(iDataType);
    863     PVMFFormatType lcn_format_type = PVCodecTypeToPVMFFormatType(codec_type);
    864 
    865     for (i = 0; i < numParams && !selectedKvp; i++)
    866     {
    867         if (lcn_format_type == kvp[i].value.pChar_value)
    868             selectedKvp = &(kvp[i]);
    869     }
    870 
    871     if (!selectedKvp)
    872     {
    873         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error:  Input format not supported by peer"));
    874         return PVMFFailure;
    875     }
    876     if (PVMFSuccess != setConfigParametersSync(selectedKvp, aConfig))
    877     {
    878         return PVMFFailure;
    879     }
    880 
    881     aConfig->releaseParameters(NULL, kvp, numParams);
    882     kvp = NULL;
    883     numParams = 0;
    884 
    885 
    886     if (iMediaType.isVideo())
    887     {
    888         // frame width negotiations
    889         uint32 width = GetVideoFrameSize(iDataType, true);
    890         status = aConfig->getParametersSync(NULL, (PvmiKeyType)VIDEO_OUTPUT_WIDTH_CAP_QUERY, kvp, numParams, NULL);
    891         if (status != PVMFSuccess || numParams != 1)
    892         {
    893             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - config->getParametersSync(cap width) failed"));
    894             // do not report error for now as enc nodes dont implemlement some parameters
    895 
    896         }
    897         else
    898         {
    899             if (kvp[0].value.uint32_value > width)
    900             {
    901                 OsclMemAllocator alloc;
    902                 PvmiKvp kvp;
    903                 kvp.key = NULL;
    904                 kvp.length = oscl_strlen(VIDEO_OUTPUT_WIDTH_CUR_QUERY) + 1; // +1 for \0
    905                 kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
    906                 if (kvp.key == NULL)
    907                 {
    908                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - alloc failed for VIDEO_OUTPUT_WIDTH_CUR_QUERY kvp "));
    909                     return PVMFErrNoMemory;
    910                 }
    911                 oscl_strncpy(kvp.key, VIDEO_OUTPUT_WIDTH_CUR_QUERY, kvp.length);
    912                 kvp.value.uint32_value = width;
    913 
    914                 if (PVMFSuccess != setConfigParametersSync(&kvp, aConfig))
    915                 {
    916                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error:  setConfigParametersSync width failed"));
    917                     //dont return PVMFFailure for now ;
    918                 }
    919 
    920 
    921                 alloc.deallocate((OsclAny*)(kvp.key));
    922 
    923             }
    924             aConfig->releaseParameters(NULL, kvp, numParams);
    925         }
    926 
    927         kvp = NULL;
    928         numParams = 0;
    929 
    930 
    931 
    932         // frame height negotiations
    933         uint32 height = GetVideoFrameSize(iDataType, false);
    934         status = aConfig->getParametersSync(NULL, (PvmiKeyType)VIDEO_OUTPUT_HEIGHT_CAP_QUERY, kvp, numParams, NULL);
    935         if (status != PVMFSuccess || numParams != 1)
    936         {
    937             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - config->getParametersSync(cap height) failed"));
    938             // do not report error for now as enc nodes dont implemlement some parameters
    939 
    940         }
    941         else
    942         {
    943             if (kvp[0].value.uint32_value > height)
    944             {
    945                 OsclMemAllocator alloc;
    946                 PvmiKvp kvp;
    947                 kvp.key = NULL;
    948                 kvp.length = oscl_strlen(VIDEO_OUTPUT_HEIGHT_CUR_QUERY) + 1; // +1 for \0
    949                 kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
    950                 if (kvp.key == NULL)
    951                 {
    952                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - alloc failed for VIDEO_OUTPUT_HEIGHT_CUR_QUERY kvp "));
    953                     return PVMFErrNoMemory;
    954                 }
    955                 oscl_strncpy(kvp.key, VIDEO_OUTPUT_HEIGHT_CUR_QUERY, kvp.length);
    956                 kvp.value.uint32_value = height;
    957 
    958                 if (PVMFSuccess != setConfigParametersSync(&kvp, aConfig))
    959                 {
    960                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error:  setConfigParametersSync height failed"));
    961                     //dont return PVMFFailure for now;
    962                 }
    963                 alloc.deallocate((OsclAny*)(kvp.key));
    964 
    965             }
    966             aConfig->releaseParameters(NULL, kvp, numParams);
    967         }
    968 
    969         kvp = NULL;
    970         numParams = 0;
    971 
    972         // frame rate negotiations
    973         uint32 framerate = GetMaxFrameRate(iDataType);
    974         // VIDEO_OUTPUT_FRAME_RATE_CAP_QUERY not available
    975         status = aConfig->getParametersSync(NULL, (PvmiKeyType)VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY, kvp, numParams, NULL);
    976         if (status != PVMFSuccess || numParams != 1)
    977         {
    978             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - config->getParametersSync(cap frame rate failed"));
    979             // do not report error for now as enc nodes dont implemlement some parameters
    980 
    981         }
    982         else
    983         {
    984             if (kvp[0].value.float_value > framerate)
    985             {
    986                 OsclMemAllocator alloc;
    987                 PvmiKvp kvp;
    988                 kvp.key = NULL;
    989                 kvp.length = oscl_strlen(VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY) + 1; // +1 for \0
    990                 kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
    991                 if (kvp.key == NULL)
    992                 {
    993                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - alloc failed for VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY kvp "));
    994                     return PVMFErrNoMemory;
    995                 }
    996                 oscl_strncpy(kvp.key, VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY, kvp.length);
    997                 kvp.value.float_value = (float)framerate;
    998 
    999                 if (PVMFSuccess != setConfigParametersSync(&kvp, aConfig))
   1000                 {
   1001                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error:  setConfigParametersSync frame rate failed"));
   1002                     //dont return PVMFFailure for now ;
   1003                 }
   1004                 alloc.deallocate((OsclAny*)(kvp.key));
   1005 
   1006             }
   1007             aConfig->releaseParameters(NULL, kvp, numParams);
   1008         }
   1009 
   1010         kvp = NULL;
   1011         numParams = 0;
   1012     }
   1013 
   1014     return NegotiateFSISettings(aConfig);
   1015 }
   1016 ////////////////////////////////////////////////////////////////////////////
   1017 //                  PvmiCapabilityAndConfig
   1018 ////////////////////////////////////////////////////////////////////////////
   1019 OSCL_EXPORT_REF void H223OutgoingChannel::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
   1020 {
   1021     // Not supported
   1022     OSCL_UNUSED_ARG(aObserver);
   1023     OSCL_LEAVE(OsclErrNotSupported);
   1024 }
   1025 
   1026 ////////////////////////////////////////////////////////////////////////////
   1027 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::getParametersSync(PvmiMIOSession session,
   1028         PvmiKeyType identifier,
   1029         PvmiKvp*& parameters,
   1030         int& num_parameter_elements,
   1031         PvmiCapabilityContext context)
   1032 {
   1033     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::getParametersSync"));
   1034     OSCL_UNUSED_ARG(session);
   1035     OSCL_UNUSED_ARG(context);
   1036 
   1037     parameters = NULL;
   1038     num_parameter_elements = 0;
   1039 
   1040     if (pv_mime_strcmp(identifier, INPUT_FORMATS_CAP_QUERY) == 0)
   1041     {
   1042         num_parameter_elements = 1;
   1043         PVMFStatus status = AllocateKvp(iKvpMemAlloc, parameters,
   1044                                         OSCL_CONST_CAST(char*, INPUT_FORMATS_VALTYPE),
   1045                                         num_parameter_elements);
   1046         if (status != PVMFSuccess)
   1047         {
   1048             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::getParametersSync: Error - AllocateKvp failed. status=%d", status));
   1049             return status;
   1050         }
   1051         PVCodecType_t codec_type = GetCodecType(iDataType);
   1052 
   1053         PVMFFormatType format = PVCodecTypeToPVMFFormatType(codec_type).getMIMEStrPtr();
   1054         if (format == PVMF_MIME_AMR_IF2)
   1055             parameters[0].value.pChar_value = (char*) PVMF_MIME_AMR_IF2;
   1056         else if (format == PVMF_MIME_PCM16)
   1057             parameters[0].value.pChar_value = (char*) PVMF_MIME_PCM16;
   1058         else if (format ==  PVMF_MIME_YUV420)
   1059             parameters[0].value.pChar_value = (char*) PVMF_MIME_YUV420;
   1060         else if (format ==  PVMF_MIME_M4V)
   1061             parameters[0].value.pChar_value = (char*) PVMF_MIME_M4V;
   1062         else if (format ==  PVMF_MIME_H2632000)
   1063             parameters[0].value.pChar_value = (char*) PVMF_MIME_H2632000;
   1064         else if (format ==  PVMF_MIME_H2631998)
   1065             parameters[0].value.pChar_value = (char*) PVMF_MIME_H2631998;
   1066         else
   1067             parameters[0].value.pChar_value = (char*) PVMF_MIME_FORMAT_UNKNOWN;
   1068     }
   1069 
   1070     return PVMFSuccess;
   1071 }
   1072 
   1073 ////////////////////////////////////////////////////////////////////////////
   1074 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::releaseParameters(PvmiMIOSession session,
   1075         PvmiKvp* parameters,
   1076         int num_elements)
   1077 {
   1078     OSCL_UNUSED_ARG(session);
   1079     OSCL_UNUSED_ARG(num_elements);
   1080 
   1081     if (parameters)
   1082     {
   1083         iKvpMemAlloc.deallocate((OsclAny*)parameters);
   1084         return PVMFSuccess;
   1085     }
   1086     else
   1087     {
   1088         return PVMFFailure;
   1089     }
   1090 }
   1091 
   1092 ////////////////////////////////////////////////////////////////////////////
   1093 OSCL_EXPORT_REF void H223OutgoingChannel::createContext(PvmiMIOSession session, PvmiCapabilityContext& context)
   1094 {
   1095     OSCL_UNUSED_ARG(session);
   1096     OSCL_UNUSED_ARG(context);
   1097 }
   1098 
   1099 ////////////////////////////////////////////////////////////////////////////
   1100 OSCL_EXPORT_REF void H223OutgoingChannel::setContextParameters(PvmiMIOSession session,
   1101         PvmiCapabilityContext& context,
   1102         PvmiKvp* parameters, int num_parameter_elements)
   1103 {
   1104     OSCL_UNUSED_ARG(session);
   1105     OSCL_UNUSED_ARG(context);
   1106     OSCL_UNUSED_ARG(parameters);
   1107     OSCL_UNUSED_ARG(num_parameter_elements);
   1108 }
   1109 
   1110 ////////////////////////////////////////////////////////////////////////////
   1111 OSCL_EXPORT_REF void H223OutgoingChannel::DeleteContext(PvmiMIOSession session, PvmiCapabilityContext& context)
   1112 {
   1113     OSCL_UNUSED_ARG(session);
   1114     OSCL_UNUSED_ARG(context);
   1115 }
   1116 
   1117 ////////////////////////////////////////////////////////////////////////////
   1118 OSCL_EXPORT_REF void H223OutgoingChannel::setParametersSync(PvmiMIOSession session, PvmiKvp* parameters,
   1119         int num_elements, PvmiKvp*& ret_kvp)
   1120 {
   1121     OSCL_UNUSED_ARG(session);
   1122     PVMFStatus status = PVMFSuccess;
   1123     ret_kvp = NULL;
   1124 
   1125     for (int32 i = 0; i < num_elements; i++)
   1126     {
   1127         status = VerifyAndSetParameter(&(parameters[i]), true);
   1128         if (status != PVMFSuccess)
   1129         {
   1130             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::setParametersSync: Error - VerifiyAndSetParameter failed on parameter #%d", i));
   1131             ret_kvp = &(parameters[i]);
   1132             /* Silently ignore unrecognized codecs untill CapEx is supported by peer */
   1133             //OSCL_LEAVE(OsclErrArgument);
   1134         }
   1135     }
   1136 }
   1137 
   1138 PVMFStatus H223OutgoingChannel::VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam)
   1139 {
   1140     OSCL_UNUSED_ARG(aSetParam);
   1141     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::VerifyAndSetParameter: aKvp=0x%x, aSetParam=%d", aKvp, aSetParam));
   1142 
   1143     if (!aKvp)
   1144     {
   1145         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::VerifyAndSetParameter: Error - Invalid key-value pair"));
   1146         return PVMFFailure;
   1147     }
   1148 
   1149     if (iDataType == NULL)
   1150     {
   1151         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::VerifyAndSetParameter: Error - DataType == NULL"));
   1152         return PVMFErrNotSupported;
   1153     }
   1154 
   1155     if (pv_mime_strcmp(aKvp->key, INPUT_FORMATS_VALTYPE) == 0)
   1156     {
   1157         PVCodecType_t codec_type = GetCodecType(iDataType);
   1158         PVMFFormatType lcn_format_type = PVCodecTypeToPVMFFormatType(codec_type);
   1159         if (pv_mime_strcmp(lcn_format_type.getMIMEStrPtr(), aKvp->value.pChar_value) != 0)
   1160         {
   1161             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::VerifyAndSetParameter: Error - Input format %s not supported", aKvp->value.pChar_value));
   1162             return PVMFErrNotSupported;
   1163         }
   1164     }
   1165     else if (pv_mime_strcmp(aKvp->key, PVMF_FORMAT_SPECIFIC_INFO_KEY) == 0)
   1166     {
   1167         ReceivedFSIFromPeer(aKvp);
   1168     }
   1169 
   1170     return PVMFSuccess;
   1171 }
   1172 
   1173 ////////////////////////////////////////////////////////////////////////////
   1174 OSCL_EXPORT_REF PVMFCommandId H223OutgoingChannel::setParametersAsync(PvmiMIOSession session,
   1175         PvmiKvp* parameters,
   1176         int num_elements,
   1177         PvmiKvp*& ret_kvp,
   1178         OsclAny* context)
   1179 {
   1180     OSCL_UNUSED_ARG(session);
   1181     OSCL_UNUSED_ARG(parameters);
   1182     OSCL_UNUSED_ARG(num_elements);
   1183     OSCL_UNUSED_ARG(ret_kvp);
   1184     OSCL_UNUSED_ARG(context);
   1185     return -1;
   1186 }
   1187 
   1188 ////////////////////////////////////////////////////////////////////////////
   1189 OSCL_EXPORT_REF uint32 H223OutgoingChannel::getCapabilityMetric(PvmiMIOSession session)
   1190 {
   1191     OSCL_UNUSED_ARG(session);
   1192     return 1;
   1193 }
   1194 
   1195 ////////////////////////////////////////////////////////////////////////////
   1196 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::verifyParametersSync(PvmiMIOSession session,
   1197         PvmiKvp* parameters, int num_elements)
   1198 {
   1199     OSCL_UNUSED_ARG(session);
   1200 
   1201     PVMFStatus status = PVMFSuccess;
   1202     for (int32 i = 0; (i < num_elements) && (status == PVMFSuccess); i++)
   1203         status = VerifyAndSetParameter(&(parameters[i]), true);
   1204 
   1205     return status;
   1206 }
   1207 
   1208 void H223OutgoingChannel::HandlePortActivity(const PVMFPortActivity &aActivity)
   1209 {
   1210     if (aActivity.iType != PVMF_PORT_ACTIVITY_INCOMING_MSG &&
   1211             aActivity.iType != PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY)
   1212     {
   1213         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::HandlePortActivity Unhandled port activity: %d", aActivity.iType));
   1214         return;
   1215     }
   1216     PVMFStatus aStatus;
   1217     PVMFSharedMediaMsgPtr aMsg;
   1218     while (IncomingMsgQueueSize())
   1219     {
   1220         aStatus = DequeueIncomingMsg(aMsg);
   1221         if (aStatus == PVMFSuccess)
   1222         {
   1223             PutData(aMsg);
   1224         }
   1225         else
   1226         {
   1227             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::HandlePortActivity Failed to DeQueue incoming message: %d", aStatus));
   1228             break;
   1229         }
   1230     }
   1231 }
   1232 
   1233 OSCL_EXPORT_REF PVMFStatus H223OutgoingControlChannel::PeerConnect(PVMFPortInterface* aPort)
   1234 {
   1235     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PeerConnect aPort=0x%x", this, aPort));
   1236     if (!aPort)
   1237     {
   1238         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "0x%x H223OutgoingControlChannel::PeerConnect: Error - Connecting to invalid port", this));
   1239         return PVMFErrArgument;
   1240     }
   1241     if (iConnectedPort)
   1242     {
   1243         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "0x%x H223OutgoingControlChannel::PeerConnect: Error - Already connected", this));
   1244         return PVMFFailure;
   1245     }
   1246 
   1247     iConnectedPort = aPort;
   1248     PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
   1249 
   1250     return PVMFSuccess;
   1251 
   1252 }
   1253 PVMFStatus H223OutgoingControlChannel::PutData(PVMFSharedMediaMsgPtr aMsg)
   1254 {
   1255     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PutData - iNumPendingPdus=%d,iNumMediaData=%d", iNumPendingPdus, iNumMediaData));
   1256 
   1257     PVMFSharedMediaDataPtr mediaData;
   1258     convertToPVMFMediaData(mediaData, aMsg);
   1259 
   1260     PV_STAT_SET_TIME(iStartTime, iNumPacketsIn)
   1261     PV_STAT_INCR(iNumPacketsIn, 1)
   1262     PV_STAT_INCR(iNumSdusIn, 1)
   1263     PV_STAT_INCR(iNumBytesIn, (mediaData->getFilledSize()))
   1264 
   1265     OsclSharedPtr<PVMFMediaDataImpl> pdu;
   1266     pdu = iMediaFragGroupAlloc->allocate();
   1267 
   1268     if (!pdu)
   1269     {
   1270         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PutData - Memory allocation failure on iMediaFragGroupAlloc->allocate\n"));
   1271         return PVMFErrNoMemory;
   1272     }
   1273 
   1274     TimeValue timenow;
   1275     OsclRefCounterMemFrag frag;
   1276     for (uint frag_num = 0; frag_num < mediaData->getNumFragments(); frag_num++)
   1277     {
   1278         mediaData->getMediaFragment(frag_num, frag);
   1279         // Add data fragments
   1280         pdu->appendMediaFragment(frag);
   1281     }
   1282 
   1283     PVMFStatus status = iAl->CompletePacket(pdu);
   1284     if (status != PVMFSuccess)
   1285     {
   1286         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PutData - Memory allocation failure on iAl->CompletePacket()"));
   1287         return status;
   1288     }
   1289 
   1290     OsclRefCounterMemFrag fsi;
   1291     bool fsi_available = mediaData->getFormatSpecificInfo(fsi);
   1292     // Add it to the outgoing queue
   1293     if (PVMFSuccess != AppendOutgoingPkt(pdu, timenow.to_msec(), (fsi_available ? &fsi : NULL)))
   1294     {
   1295         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PutData - Memory allocation failure on AppendOutgoingPkt()"));
   1296         return PVMFErrNoMemory;
   1297     }
   1298     return PVMFSuccess;
   1299 }
   1300 
   1301 void H223LogicalChannel::SetDatapathLatency(uint32 aLatency)
   1302 {
   1303     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LogicalChannel::SetDatapathLatency lcn=%d, aLatency=%d", lcn, aLatency));
   1304     iDatapathLatency = aLatency;
   1305 }
   1306 
   1307 PVMFStatus H223LogicalChannel::setConfigParametersSync(PvmiKvp* selectedKvp,
   1308         PvmiCapabilityAndConfig* aConfig,
   1309         PVMFFormatType lcn_format_type,
   1310         bool aTryTwice)
   1311 {
   1312     int32 err = 0;
   1313     PvmiKvp* retKvp = NULL;
   1314     if (!aTryTwice)
   1315     {
   1316         OSCL_TRY(err, aConfig->setParametersSync(NULL, selectedKvp, 1, retKvp););
   1317         OSCL_FIRST_CATCH_ANY(err,
   1318                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::setConfigParametersSync, Error:  setParametersSync failed, err=%d", err));
   1319                              return PVMFFailure;
   1320                             );
   1321     }
   1322     else
   1323     {
   1324         int32 err = 0;
   1325         OSCL_TRY(err, aConfig->setParametersSync(NULL, selectedKvp, 1, retKvp););
   1326         if (err)
   1327         {
   1328             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::setConfigParametersSync, Error:  setParametersSync failed for pChar value, trying uint32, err=%d", err));
   1329             selectedKvp->value.pChar_value = OSCL_STATIC_CAST(mbchar*, lcn_format_type.getMIMEStrPtr());
   1330             err = 0;
   1331             OSCL_TRY(err, aConfig->setParametersSync(NULL, selectedKvp, 1, retKvp););
   1332             if (err)
   1333             {
   1334                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::setConfigParametersSync, Error:  setParametersSync failed, err=%d", err));
   1335                 return PVMFFailure;
   1336             }
   1337         }
   1338     }
   1339     return PVMFSuccess;
   1340 }
   1341 H223IncomingChannel::H223IncomingChannel(TPVChannelId num,
   1342         bool segmentable,
   1343         OsclSharedPtr<AdaptationLayer>& al,
   1344         PS_DataType data_type,
   1345         LogicalChannelObserver* observer,
   1346         uint32 bitrate,
   1347         uint32 sample_interval,
   1348         uint32 num_media_data)
   1349         : H223LogicalChannel(num, segmentable, al, data_type, observer, bitrate, sample_interval, num_media_data),
   1350         iMediaMsgMemoryPool(NULL),
   1351         iMediaFragGroupAlloc(NULL),
   1352         iPduPktMemPool(NULL),
   1353         iMediaDataAlloc(&iMemAlloc),
   1354         iPduSize(al->GetPduSize()),
   1355         iCurPduSize(0),
   1356         iRenderingSkew(0)
   1357 {
   1358     iLogger = PVLogger::GetLoggerObject("3g324m.h223.H223IncomingChannel");
   1359     iIncomingAudioLogger = PVLogger::GetLoggerObject("datapath.incoming.audio.h223.lcn");
   1360     iIncomingVideoLogger = PVLogger::GetLoggerObject("datapath.incoming.video.h223.lcn");
   1361     iAlPduFragPos = NULL;
   1362     ResetStats();
   1363 }
   1364 
   1365 H223IncomingChannel::~H223IncomingChannel()
   1366 {
   1367     Flush();
   1368     OsclRefCounterMemFrag frag;
   1369     iAlPduFrag = frag;
   1370     if (iMediaFragGroupAlloc)
   1371     {
   1372         iMediaFragGroupAlloc->removeRef();
   1373     }
   1374     if (iPduPktMemPool)
   1375     {
   1376         OSCL_DELETE(iPduPktMemPool);
   1377     }
   1378     if (iMediaMsgMemoryPool)
   1379     {
   1380         OSCL_DELETE(iMediaMsgMemoryPool);
   1381     }
   1382 }
   1383 
   1384 void H223IncomingChannel::Init()
   1385 {
   1386     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Init"));
   1387     H223LogicalChannel::Init();
   1388 
   1389     int bitrate = (GetBitrate() > 0) ? GetBitrate() : DEF_CHANNEL_BITRATE;
   1390     int mem_size = (DEF_INCOMING_CHANNEL_BUFFER_SIZE_MS * bitrate) >> PV2WAY_BPS_TO_BYTES_PER_MSEC_RIGHT_SHIFT;
   1391     int num_fragments = (mem_size / H223_INCOMING_CHANNEL_FRAGMENT_SIZE) + 1;
   1392     iMediaMsgMemoryPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (H223_INCOMING_CHANNEL_NUM_MEDIA_MSG));
   1393     if (iMediaMsgMemoryPool == NULL)
   1394     {
   1395         OSCL_LEAVE(PVMFErrNoMemory);
   1396     }
   1397     iMediaMsgMemoryPool->enablenullpointerreturn();
   1398 
   1399     iPduPktMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (H223_INCOMING_CHANNEL_NUM_MEDIA_DATA));
   1400     if (iPduPktMemPool == NULL)
   1401     {
   1402         OSCL_LEAVE(PVMFErrNoMemory);
   1403     }
   1404     iPduPktMemPool->enablenullpointerreturn();
   1405 
   1406     iMediaFragGroupAlloc = OSCL_NEW(PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>, (H223_INCOMING_CHANNEL_NUM_MEDIA_DATA, H223_INCOMING_CHANNEL_NUM_FRAGS_IN_MEDIA_DATA, iPduPktMemPool));
   1407     if (iMediaFragGroupAlloc == NULL)
   1408     {
   1409         OSCL_LEAVE(PVMFErrNoMemory);
   1410     }
   1411     iMediaFragGroupAlloc->create();
   1412 
   1413     iMemFragmentAlloc.SetLeaveOnAllocFailure(false);
   1414     iMemFragmentAlloc.size((uint16)num_fragments, (uint16)H223_INCOMING_CHANNEL_FRAGMENT_SIZE);
   1415 
   1416     ResetAlPdu();
   1417     AllocateAlPdu();
   1418     iCurTimestamp = 0;
   1419     iNumSdusIn = 0;
   1420     iNumPdusIn = 0;
   1421 }
   1422 
   1423 OsclAny H223IncomingChannel::ResetAlPdu()
   1424 {
   1425     iAlPduFragPos = NULL;
   1426     iCurPduSize = 0;
   1427     OsclRefCounterMemFrag frag;
   1428     iAlPduFrag = frag;
   1429     iAlPduMediaData.Unbind();
   1430 }
   1431 
   1432 OsclAny H223IncomingChannel::AllocateAlPdu()
   1433 {
   1434     iAlPduMediaData = iMediaFragGroupAlloc->allocate();
   1435     if (iAlPduMediaData.GetRep() == NULL)
   1436     {
   1437         return;
   1438     }
   1439     AppendAlPduFrag();
   1440 }
   1441 
   1442 OsclAny H223IncomingChannel::AppendAlPduFrag()
   1443 {
   1444     OsclRefCounterMemFrag ref_counter_mem_frag = iMemFragmentAlloc.get();
   1445     if (ref_counter_mem_frag.getMemFragPtr() == NULL)
   1446     {
   1447         return;
   1448     }
   1449     ref_counter_mem_frag.getMemFrag().len = 0;
   1450     iAlPduFrag = ref_counter_mem_frag;
   1451     iAlPduFragPos = (uint8*)iAlPduFrag.getMemFragPtr();
   1452 }
   1453 
   1454 uint32 H223IncomingChannel::CopyAlPduData(uint8* buf, uint16 len)
   1455 {
   1456     int32 remaining = len;
   1457     uint32 copied = 0;
   1458     do
   1459     {
   1460         copied = CopyToCurrentFrag(buf, (uint16)remaining);
   1461         buf += copied;
   1462         remaining -= copied;
   1463     }
   1464     while (remaining && copied);
   1465     return (uint32)(len - remaining);
   1466 }
   1467 
   1468 uint32 H223IncomingChannel::CopyToCurrentFrag(uint8* buf, uint16 len)
   1469 {
   1470     if (iAlPduMediaData.GetRep() == NULL)
   1471     {
   1472         AllocateAlPdu();
   1473     }
   1474     else if (iAlPduFragPos == NULL)
   1475     {
   1476         AppendAlPduFrag();
   1477     }
   1478     if (iAlPduFragPos == NULL)
   1479     {
   1480         return 0;
   1481     }
   1482 
   1483     uint32 space_in_current_frag = ((uint8*)iAlPduFrag.getMemFragPtr() + iAlPduFrag.getCapacity() - iAlPduFragPos);
   1484     OSCL_ASSERT(space_in_current_frag > 0);
   1485     uint32 num_bytes_copied = (len > space_in_current_frag) ? space_in_current_frag : len;
   1486     oscl_memcpy(iAlPduFragPos, buf, num_bytes_copied);
   1487     iAlPduFrag.getMemFrag().len += num_bytes_copied;
   1488     iAlPduFragPos += num_bytes_copied;
   1489     space_in_current_frag -= num_bytes_copied;
   1490     if (space_in_current_frag == 0)
   1491     {
   1492         iAlPduMediaData->appendMediaFragment(iAlPduFrag);
   1493         iAlPduFragPos = NULL;
   1494     }
   1495     PVLOGGER_LOG_USE_ONLY(
   1496         if (iAlPduMediaData->getFilledSize() > iPduSize)
   1497 {
   1498     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::CopyToCurrentFrag WARNING current pdu size=%d > iPduSize=%d", iAlPduMediaData->getFilledSize(), iPduSize));
   1499     }
   1500     );
   1501     return num_bytes_copied;
   1502 }
   1503 
   1504 void H223IncomingChannel::PreAlPduData()
   1505 
   1506 {
   1507     if (iSendFormatSpecificInfo)
   1508     {
   1509         SendFormatSpecificInfo();
   1510     }
   1511 
   1512     if (iPaused)
   1513     {
   1514         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::PreAlPduData Logical channel paused.  Dropping media data."));
   1515         return;
   1516     }
   1517 }
   1518 
   1519 PVMFStatus H223IncomingChannel::AlPduData(uint8* buf, uint16 len)
   1520 {
   1521     PV_STAT_INCR(iNumBytesIn, len)
   1522     PV_STAT_SET_TIME(iStartTime, iNumBytesIn)
   1523 
   1524     PreAlPduData();
   1525     if (PVMFSuccess != DispatchPendingSdus())
   1526     {
   1527         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlPduData lcn=%d, Failed to dispatch pending sdus", lcn));
   1528     }
   1529     if (iAlPduMediaData.GetRep() == NULL || iAlPduMediaData->getFilledSize() == 0)
   1530     {
   1531         bool overflow = false;
   1532         iClock->GetCurrentTime32(iCurTimestamp, overflow, PVMF_MEDIA_CLOCK_MSEC);
   1533     }
   1534     uint32 copied = CopyAlPduData(buf, len);
   1535     return (copied == len) ? PVMFSuccess : PVMFFailure;
   1536 }
   1537 
   1538 PVMFStatus H223IncomingChannel::AlDispatch()
   1539 {
   1540     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatch lcn=%d, iCurPduSize=%d, sn=%d", lcn, iCurPduSize, iNumSdusIn));
   1541     IncomingALPduInfo info;
   1542 
   1543     if (iPaused)
   1544     {
   1545         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatch Logical channel paused."));
   1546         return PVMFFailure;
   1547     }
   1548 
   1549     /*  Nothing to dispatch */
   1550     if (!iAlPduMediaData.GetRep())
   1551     {
   1552         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatch Nothing to dispatch."));
   1553         ResetAlPdu();
   1554         return PVMFSuccess;
   1555     }
   1556 
   1557     /*  Add pending fragment to the media message */
   1558     if (iAlPduFragPos)
   1559     {
   1560         iAlPduMediaData->appendMediaFragment(iAlPduFrag);
   1561     }
   1562 
   1563     /* Parse AL headers etc */
   1564     iAl->ParsePacket(iAlPduMediaData, info);
   1565     int32 len = info.sdu_size;
   1566     if (len <= 0)
   1567     {
   1568         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::AlDispatch Empty SDU lcn=%d, len=%d", lcn, len));
   1569         ResetAlPdu();
   1570         return PVMFErrCorrupt;
   1571     }
   1572 
   1573     PV_STAT_INCR_COND(iNumCrcErrors, 1, info.crc_error)
   1574     PV_STAT_INCR_COND(iNumSeqNumErrors, 1, info.seq_num_error)
   1575     PVMFStatus status = PVMFSuccess;
   1576 
   1577     // set the errors flag
   1578     uint32 errorsFlag = 0;
   1579     if (info.crc_error)
   1580     {
   1581         errorsFlag |= PVMF_MEDIA_DATA_BIT_ERRORS;
   1582         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::AlDispatch CRC error lcn=%d, size=%d", lcn, len));
   1583         status =  PVMFErrCorrupt;
   1584     }
   1585     else
   1586     {
   1587         PV_STAT_INCR(iNumSdusIn, 1)
   1588     }
   1589     if (info.seq_num_error)
   1590     {
   1591         errorsFlag |= PVMF_MEDIA_DATA_PACKET_LOSS;
   1592         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::AlDispatch Sequence number error lcn=%d, size=%d", lcn, len));
   1593         status = PVMFErrCorrupt;
   1594     }
   1595 
   1596     OsclSharedPtr<PVMFMediaData> aMediaData = PVMFMediaData::createMediaData(iAlPduMediaData, iMediaMsgMemoryPool);
   1597     if (aMediaData.GetRep() == NULL)
   1598     {
   1599         return PVMFErrNoMemory;
   1600     }
   1601 
   1602     PVMFTimestamp baseTimestamp = 0;
   1603     SetSampleTimestamps(baseTimestamp);
   1604     aMediaData->setTimestamp(baseTimestamp);
   1605 
   1606     iAlPduMediaData->setErrorsFlag(errorsFlag);
   1607 
   1608     PVMFSharedMediaMsgPtr aMediaMsg;
   1609     convertToPVMFMediaMsg(aMediaMsg, aMediaData);
   1610 
   1611     PVMFFormatType mediaType = GetFormatType();
   1612     if (mediaType.isCompressed() && mediaType.isAudio())
   1613     {
   1614         // we are using only full audio frames
   1615         aMediaData->setMarkerInfo(PVMF_MEDIA_DATA_MARKER_INFO_M_BIT);
   1616     }
   1617 
   1618     if (IsConnected())
   1619     {
   1620         if (mediaType.isCompressed() && mediaType.isAudio())
   1621         {
   1622             PVMF_INCOMING_AUDIO_LOGDATATRAFFIC((0, "Incoming audio SDU received. Stats: Entry time=%d, lcn=%d, size=%d,FmtType=%s", iCurTimestamp, lcn, aMediaData->getFilledSize(), mediaType.getMIMEStrPtr()));
   1623         }
   1624         else if (mediaType.isCompressed() && mediaType.isVideo())
   1625         {
   1626             PVMF_INCOMING_VIDEO_LOGDATATRAFFIC((0, "Incoming video SDU received.Stats: Entry time=%d, lcn=%d, size=%d,FmtType=%s", iCurTimestamp, lcn, aMediaData->getFilledSize(), mediaType.getMIMEStrPtr()));
   1627         }
   1628         PVMFStatus dispatch_status = QueueOutgoingMsg(aMediaMsg);
   1629         if (dispatch_status != PVMFSuccess)
   1630         {
   1631             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::AlDispatch Failed to queue outgoing media message lcn=%d, size=%d, status=%d", lcn, len, dispatch_status));
   1632             status = dispatch_status;
   1633         }
   1634     }
   1635     else if (IsSegmentable())
   1636     {
   1637         iPendingSdus.push_back(aMediaMsg);
   1638     }
   1639     else
   1640     {
   1641         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatchL Dropping pdu lcn=%d, iCurPduSize=%d", lcn, iCurPduSize));
   1642         status = PVMFErrNotReady;
   1643     }
   1644     ResetAlPdu();
   1645     AllocateAlPdu();
   1646     return status;
   1647 }
   1648 
   1649 OsclAny H223IncomingChannel::Flush()
   1650 {
   1651     PV_STAT_INCR(iNumBytesFlushed, (iAlPduFragPos - (uint8*)iAlPduFrag.getMemFragPtr()))
   1652     PV_STAT_INCR_COND(iNumAbort, 1, (iAlPduFragPos - (uint8*)iAlPduFrag.getMemFragPtr()))
   1653     iPendingSdus.clear();
   1654     ResetAlPdu();
   1655 
   1656 }
   1657 
   1658 PVMFStatus H223IncomingChannel::Connect(PVMFPortInterface* aPort)
   1659 {
   1660     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect lcn(%d)\n", lcn));
   1661     if (iConnectedPort)
   1662     {
   1663         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect Error: Already connected"));
   1664         return PVMFFailure;
   1665     }
   1666 
   1667     PvmiCapabilityAndConfig* config = NULL;
   1668     OsclAny * tempInterface = NULL;
   1669     aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, tempInterface);
   1670     config = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, tempInterface);
   1671     if (!config)
   1672     {
   1673         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect: Error - Peer port does not support capability interface"));
   1674         return PVMFFailure;
   1675     }
   1676 
   1677     PVMFStatus status = NegotiateOutputSettings(config);
   1678 
   1679     if (status != PVMFSuccess)
   1680     {
   1681         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect: Error - Settings negotiation failed. status=%d", status));
   1682         return status;
   1683     }
   1684 
   1685     //Automatically connect the peer.
   1686     if ((status = aPort->PeerConnect(this)) != PVMFSuccess)
   1687     {
   1688         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect: Error - Peer Connect failed. status=%d", status));
   1689         return status;
   1690     }
   1691 
   1692     iConnectedPort = aPort;
   1693 
   1694     //Check the BOS command status
   1695     status = SendBeginOfStreamMediaCommand();
   1696 
   1697     if (status != PVMFSuccess)
   1698     {
   1699         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect: Failed to send BOS message status=%d", status));
   1700         return status;
   1701     }
   1702 
   1703     /* Send any format specific info if available */
   1704     if (iSendFormatSpecificInfo)
   1705         SendFormatSpecificInfo();
   1706 
   1707     DispatchPendingSdus();
   1708 
   1709     PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
   1710 
   1711     return PVMFSuccess;
   1712 }
   1713 
   1714 OsclAny H223IncomingChannel::ResetStats()
   1715 {
   1716     iNumSdusIn = 0;
   1717     iNumBytesIn = 0;
   1718     iSduSizeExceededCnt = 0;
   1719     iNumCrcErrors = 0;
   1720     iNumSeqNumErrors = 0;
   1721     iNumBytesFlushed = 0;
   1722     iNumAbort = 0;
   1723 }
   1724 
   1725 OsclAny H223IncomingChannel::LogStats()
   1726 {
   1727     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Incoming Logical Channel %d Statistics:\n", lcn));
   1728     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus received - %d\n", iNumSdusIn));
   1729     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes received - %d\n", iNumBytesIn));
   1730     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num times sdu size exceeded - %d\n", iSduSizeExceededCnt));
   1731     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus with CRC errors - %d\n", iNumCrcErrors));
   1732     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus with sequence number errors - %d\n", iNumSeqNumErrors));
   1733     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus aborted - %d\n", iNumAbort));
   1734     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes aborted - %d\n", iNumBytesFlushed));
   1735 }
   1736 
   1737 PVMFStatus H223IncomingChannel::DispatchPendingSdus()
   1738 {
   1739     if (!iConnectedPort)
   1740         return PVMFFailure;
   1741     if (iPendingSdus.size())
   1742     {
   1743         /* Dispatch any pending sdus */
   1744         for (unsigned i = 0; i < iPendingSdus.size(); i++)
   1745         {
   1746             PVMFStatus status = QueueOutgoingMsg(iPendingSdus[i]);
   1747             if (status != PVMFSuccess)
   1748             {
   1749                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect Error: PutData failed for buffered sdus lcn=%d, status=%d, i=%d", lcn, status, i));
   1750                 iObserver->LogicalChannelError(INCOMING, lcn, status);
   1751                 return PVMFFailure;
   1752             }
   1753         }
   1754         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect lcn=%d,num sdus=%d", lcn, iPendingSdus.size()));
   1755         iPendingSdus.clear();
   1756     }
   1757     return PVMFSuccess;
   1758 }
   1759 
   1760 OsclAny H223IncomingChannel::SendFormatSpecificInfo()
   1761 {
   1762     //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223IncomingChannel::SendFormatSpecificInfo lcn=%d, iFormatSpecificInfoLen=%d, iFormatSpecificInfo=%x", lcn,iFormatSpecificInfoLen,iFormatSpecificInfo));
   1763     //printBuffer(iLogger, iFormatSpecificInfo, (uint16)iFormatSpecificInfoLen);
   1764     if (!IsConnected())
   1765     {
   1766         //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223IncomingChannel::SendFormatSpecificInfo ERROR Not connected."));
   1767         //OSCL_LEAVE(PVMFErrNotReady);
   1768         return;
   1769     }
   1770 
   1771     // Create mem frag for VOL header
   1772     // Create new media data buffer for header fragment
   1773     OsclSharedPtr<PVMFMediaDataImpl> hdrImpl = iMediaDataAlloc.allocate(iFormatSpecificInfoLen);
   1774     if (!hdrImpl)
   1775     {
   1776         return;
   1777     }
   1778     PVMFSharedMediaDataPtr hdrMediaData = PVMFMediaData::createMediaData(hdrImpl);
   1779     OsclRefCounterMemFrag myVolHeader;
   1780     hdrMediaData->getMediaFragment(0, myVolHeader);
   1781     oscl_memcpy(myVolHeader.getMemFragPtr(), iFormatSpecificInfo, iFormatSpecificInfoLen);
   1782     myVolHeader.getMemFrag().len = iFormatSpecificInfoLen;
   1783 
   1784     // Create new media data buffer for the message
   1785     OsclSharedPtr<PVMFMediaDataImpl> emptyImpl = iMediaDataAlloc.allocate(0);
   1786     if (!emptyImpl)
   1787     {
   1788         return;
   1789     }
   1790     PVMFSharedMediaDataPtr volData = PVMFMediaData::createMediaData(emptyImpl);
   1791 
   1792     // Set format specific info in media data message
   1793     volData->setFormatSpecificInfo(myVolHeader);
   1794 
   1795     // Send VOL header to downstream node
   1796     PVMFSharedMediaMsgPtr volMsg;
   1797     convertToPVMFMediaMsg(volMsg, volData);
   1798     PVMFStatus status = QueueOutgoingMsg(volMsg);
   1799     if (status != PVMFSuccess)
   1800     {
   1801         OSCL_LEAVE(status);
   1802     }
   1803     iSendFormatSpecificInfo = false;
   1804 }
   1805 
   1806 MuxSduData::MuxSduData()
   1807 {
   1808     size = 0;
   1809     cur_frag_num = 0;
   1810     cur_pos = 0;
   1811 }
   1812 PVMFStatus H223IncomingChannel::NegotiateOutputSettings(PvmiCapabilityAndConfig* aConfig)
   1813 {
   1814     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::NegotiateInputSettings, aConfig=%x", aConfig));
   1815 
   1816     PvmiKvp* kvp = NULL;
   1817     int numParams = 0;
   1818     int32 i = 0;
   1819 
   1820     // Get supported input formats from peer
   1821     PVMFStatus status = aConfig->getParametersSync(NULL,
   1822                         OSCL_CONST_CAST(char*, INPUT_FORMATS_CAP_QUERY),
   1823                         kvp, numParams, NULL);
   1824 
   1825     if (status != PVMFSuccess)
   1826     {
   1827         status = aConfig->getParametersSync(NULL,
   1828                                             OSCL_CONST_CAST(char*, "x-pvmf/video/decode/input_formats"),
   1829                                             kvp, numParams, NULL);
   1830     }
   1831 
   1832     if (status != PVMFSuccess || numParams == 0)
   1833     {
   1834         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::NegotiateInputSettings, Error:  getParametersSync failed.  status=%d", status));
   1835 
   1836         return PVMFSuccess;
   1837     }
   1838 
   1839     PvmiKvp* selectedKvp = NULL;
   1840     PVCodecType_t codec_type = GetCodecType(iDataType);
   1841     PVMFFormatType lcn_format_type = PVCodecTypeToPVMFFormatType(codec_type);
   1842 
   1843     for (i = 0; i < numParams && !selectedKvp; i++)
   1844     {
   1845         if (lcn_format_type == kvp[i].value.pChar_value)
   1846             selectedKvp = &(kvp[i]);
   1847     }
   1848 
   1849     if (!selectedKvp)
   1850     {
   1851         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::NegotiateInputSettings, Error:  Input format not supported by peer"));
   1852         return PVMFFailure;
   1853     }
   1854 
   1855     /* This is for the silly problem of MIO components having the convention
   1856        of returning uint32 for a query and requiring pChar for a setting
   1857        we don't know if we are talking to an MIO or a decoder node
   1858        (which will want a uint32), so we try both.  Try the pchar
   1859        first, because if its expecting pchar and gets uint32, it will
   1860        crash.
   1861     */
   1862     if (PVMFSuccess != setConfigParametersSync(selectedKvp, aConfig, lcn_format_type, true))
   1863         return PVMFFailure;
   1864 
   1865     aConfig->releaseParameters(NULL, kvp, numParams);
   1866     kvp = NULL;
   1867     numParams = 0;
   1868 
   1869     return PVMFSuccess;
   1870 }
   1871 
   1872 ////////////////////////////////////////////////////////////////////////////
   1873 //                  PvmiCapabilityAndConfig
   1874 ////////////////////////////////////////////////////////////////////////////
   1875 OSCL_EXPORT_REF void H223IncomingChannel::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
   1876 {
   1877     // Not supported
   1878     OSCL_UNUSED_ARG(aObserver);
   1879     OSCL_LEAVE(OsclErrNotSupported);
   1880 }
   1881 
   1882 ////////////////////////////////////////////////////////////////////////////
   1883 OSCL_EXPORT_REF PVMFStatus H223IncomingChannel::getParametersSync(PvmiMIOSession session,
   1884         PvmiKeyType identifier,
   1885         PvmiKvp*& parameters,
   1886         int& num_parameter_elements,
   1887         PvmiCapabilityContext context)
   1888 {
   1889     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::getParametersSync"));
   1890     OSCL_UNUSED_ARG(session);
   1891     OSCL_UNUSED_ARG(context);
   1892 
   1893     parameters = NULL;
   1894     num_parameter_elements = 0;
   1895 
   1896     if (pv_mime_strcmp(identifier, OUTPUT_FORMATS_CAP_QUERY) == 0)
   1897     {
   1898         num_parameter_elements = 1;
   1899         PVMFStatus status = AllocateKvp(iKvpMemAlloc, parameters,
   1900                                         OSCL_CONST_CAST(char*, OUTPUT_FORMATS_VALTYPE),
   1901                                         num_parameter_elements);
   1902         if (status != PVMFSuccess)
   1903         {
   1904             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::getParametersSync: Error - AllocateKvp failed. status=%d", status));
   1905             return status;
   1906         }
   1907         PVCodecType_t codec_type = GetCodecType(iDataType);
   1908         PVMFFormatType format = PVCodecTypeToPVMFFormatType(codec_type).getMIMEStrPtr();
   1909         if (format == PVMF_MIME_AMR_IF2)
   1910             parameters[0].value.pChar_value = (char*) PVMF_MIME_AMR_IF2;
   1911         else if (format == PVMF_MIME_PCM16)
   1912             parameters[0].value.pChar_value = (char*) PVMF_MIME_PCM16;
   1913         else if (format ==  PVMF_MIME_YUV420)
   1914             parameters[0].value.pChar_value = (char*) PVMF_MIME_YUV420;
   1915         else if (format ==  PVMF_MIME_M4V)
   1916             parameters[0].value.pChar_value = (char*) PVMF_MIME_M4V;
   1917         else if (format ==  PVMF_MIME_H2632000)
   1918             parameters[0].value.pChar_value = (char*) PVMF_MIME_H2632000;
   1919         else if (format ==  PVMF_MIME_H2631998)
   1920             parameters[0].value.pChar_value = (char*) PVMF_MIME_H2631998;
   1921         else
   1922             parameters[0].value.pChar_value = (char*) PVMF_MIME_FORMAT_UNKNOWN;
   1923 
   1924     }
   1925 
   1926     return PVMFSuccess;
   1927 }
   1928 
   1929 ////////////////////////////////////////////////////////////////////////////
   1930 OSCL_EXPORT_REF PVMFStatus H223IncomingChannel::releaseParameters(PvmiMIOSession session,
   1931         PvmiKvp* parameters,
   1932         int num_elements)
   1933 {
   1934     OSCL_UNUSED_ARG(session);
   1935     OSCL_UNUSED_ARG(num_elements);
   1936 
   1937     if (parameters)
   1938     {
   1939         iKvpMemAlloc.deallocate((OsclAny*)parameters);
   1940         return PVMFSuccess;
   1941     }
   1942     else
   1943     {
   1944         return PVMFFailure;
   1945     }
   1946 }
   1947 
   1948 ////////////////////////////////////////////////////////////////////////////
   1949 OSCL_EXPORT_REF void H223IncomingChannel::createContext(PvmiMIOSession session, PvmiCapabilityContext& context)
   1950 {
   1951     OSCL_UNUSED_ARG(session);
   1952     OSCL_UNUSED_ARG(context);
   1953 }
   1954 
   1955 ////////////////////////////////////////////////////////////////////////////
   1956 OSCL_EXPORT_REF void H223IncomingChannel::setContextParameters(PvmiMIOSession session,
   1957         PvmiCapabilityContext& context,
   1958         PvmiKvp* parameters, int num_parameter_elements)
   1959 {
   1960     OSCL_UNUSED_ARG(session);
   1961     OSCL_UNUSED_ARG(context);
   1962     OSCL_UNUSED_ARG(parameters);
   1963     OSCL_UNUSED_ARG(num_parameter_elements);
   1964 }
   1965 
   1966 ////////////////////////////////////////////////////////////////////////////
   1967 OSCL_EXPORT_REF void H223IncomingChannel::DeleteContext(PvmiMIOSession session, PvmiCapabilityContext& context)
   1968 {
   1969     OSCL_UNUSED_ARG(session);
   1970     OSCL_UNUSED_ARG(context);
   1971 }
   1972 
   1973 ////////////////////////////////////////////////////////////////////////////
   1974 OSCL_EXPORT_REF void H223IncomingChannel::setParametersSync(PvmiMIOSession session, PvmiKvp* parameters,
   1975         int num_elements, PvmiKvp*& ret_kvp)
   1976 {
   1977     OSCL_UNUSED_ARG(session);
   1978     PVMFStatus status = PVMFSuccess;
   1979     ret_kvp = NULL;
   1980 
   1981     for (int32 i = 0; i < num_elements; i++)
   1982     {
   1983         status = VerifyAndSetParameter(&(parameters[i]), true);
   1984         if (status != PVMFSuccess)
   1985         {
   1986             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::setParametersSync: Error - VerifiyAndSetParameter failed on parameter #%d", i));
   1987             ret_kvp = &(parameters[i]);
   1988             /* Silently ignore unrecognized codecs untill CapEx is supported by peer */
   1989             //OSCL_LEAVE(OsclErrArgument);
   1990         }
   1991     }
   1992 }
   1993 
   1994 PVMFStatus H223IncomingChannel::VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam)
   1995 {
   1996     OSCL_UNUSED_ARG(aSetParam);
   1997     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::VerifyAndSetParameter: aKvp=0x%x, aSetParam=%d", aKvp, aSetParam));
   1998 
   1999     if (!aKvp)
   2000     {
   2001         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::VerifyAndSetParameter: Error - Invalid key-value pair"));
   2002         return PVMFFailure;
   2003     }
   2004 
   2005     if (iDataType == NULL)
   2006     {
   2007         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::VerifyAndSetParameter: Error - DataType == NULL"));
   2008         return PVMFErrNotSupported;
   2009     }
   2010 
   2011     if (pv_mime_strcmp(aKvp->key, OUTPUT_FORMATS_VALTYPE) == 0)
   2012     {
   2013         PVCodecType_t codec_type = GetCodecType(iDataType);
   2014         PVMFFormatType lcn_format_type = PVCodecTypeToPVMFFormatType(codec_type);
   2015         if (lcn_format_type != aKvp->value.pChar_value)
   2016         {
   2017             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::VerifyAndSetParameter: Error - Output format %s not supported", aKvp->value.pChar_value));
   2018             return PVMFErrNotSupported;
   2019         }
   2020     }
   2021 
   2022     return PVMFSuccess;
   2023 }
   2024 
   2025 ////////////////////////////////////////////////////////////////////////////
   2026 OSCL_EXPORT_REF PVMFCommandId H223IncomingChannel::setParametersAsync(PvmiMIOSession session,
   2027         PvmiKvp* parameters,
   2028         int num_elements,
   2029         PvmiKvp*& ret_kvp,
   2030         OsclAny* context)
   2031 {
   2032     OSCL_UNUSED_ARG(session);
   2033     OSCL_UNUSED_ARG(parameters);
   2034     OSCL_UNUSED_ARG(num_elements);
   2035     OSCL_UNUSED_ARG(ret_kvp);
   2036     OSCL_UNUSED_ARG(context);
   2037     return -1;
   2038 }
   2039 
   2040 ////////////////////////////////////////////////////////////////////////////
   2041 OSCL_EXPORT_REF uint32 H223IncomingChannel::getCapabilityMetric(PvmiMIOSession session)
   2042 {
   2043     OSCL_UNUSED_ARG(session);
   2044     return 1;
   2045 }
   2046 
   2047 ////////////////////////////////////////////////////////////////////////////
   2048 OSCL_EXPORT_REF PVMFStatus H223IncomingChannel::verifyParametersSync(PvmiMIOSession session,
   2049         PvmiKvp* parameters, int num_elements)
   2050 {
   2051     OSCL_UNUSED_ARG(session);
   2052 
   2053     PVMFStatus status = PVMFSuccess;
   2054     for (int32 i = 0; (i < num_elements) && (status == PVMFSuccess); i++)
   2055         status = VerifyAndSetParameter(&(parameters[i]), true);
   2056 
   2057     return status;
   2058 }
   2059 
   2060 void H223IncomingChannel::HandlePortActivity(const PVMFPortActivity &aActivity)
   2061 {
   2062     if (aActivity.iType != PVMF_PORT_ACTIVITY_OUTGOING_MSG &&
   2063             aActivity.iType != PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY)
   2064     {
   2065         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::HandlePortActivity Unhandled port activity: %d", aActivity.iType));
   2066         return;
   2067     }
   2068     PVMFStatus aStatus;
   2069     PVMFSharedMediaMsgPtr aMsg;
   2070     while (OutgoingMsgQueueSize())
   2071     {
   2072         aStatus = Send();
   2073         if (aStatus != PVMFSuccess)
   2074         {
   2075             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::HandlePortActivity Failed to DeQueue incoming message: %d", aStatus));
   2076             break;
   2077         }
   2078     }
   2079 }
   2080 
   2081 PVMFStatus H223IncomingChannel::SendBeginOfStreamMediaCommand()
   2082 {
   2083     PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
   2084     sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
   2085 
   2086     sharedMediaCmdPtr->setTimestamp(iCurTimestamp);
   2087 
   2088     uint32 seqNum = 0;
   2089     uint32 streamID = 0;
   2090     sharedMediaCmdPtr->setSeqNum(seqNum);
   2091 
   2092     PVMFSharedMediaMsgPtr mediaMsgOut;
   2093     convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
   2094     mediaMsgOut->setStreamID(streamID);
   2095 
   2096     PVMFStatus status = QueueOutgoingMsg(mediaMsgOut);
   2097     if (status != PVMFSuccess)
   2098     {
   2099         // Output queue is busy, so wait for the output queue being ready
   2100         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
   2101                         (0, "H223IncomingChannel::SendBeginOfMediaStreamCommand: Outgoing queue busy. "));
   2102         return status;
   2103     }
   2104     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::SendBeginOfMediaStreamCommand() BOS Sent StreamId %d ", streamID));
   2105     return status;
   2106 }
   2107 
   2108 void H223IncomingChannel::SetSampleTimestamps(PVMFTimestamp& aTSOffset)
   2109 {
   2110     iRenderingSkew = iAudioLatency - iVideoLatency;
   2111     uint32 skewDelta = 0;
   2112     if (iRenderingSkew >= (int32)iIncomingSkew)
   2113     {
   2114         skewDelta = iRenderingSkew - iIncomingSkew;
   2115         if (iMediaType.isCompressed() && iMediaType.isAudio())
   2116         {
   2117             aTSOffset = (PVMFTimestamp)(iAudioLatency + PARSING_JITTER_DURATION);
   2118         }
   2119         else if (iMediaType.isCompressed() && iMediaType.isVideo())
   2120         {
   2121             aTSOffset = (PVMFTimestamp)(iVideoLatency + skewDelta + PARSING_JITTER_DURATION);
   2122         }
   2123     }
   2124     else if (iRenderingSkew < (int32)iIncomingSkew)
   2125     {
   2126         skewDelta = iIncomingSkew - iRenderingSkew;
   2127         if (iMediaType.isCompressed() && iMediaType.isAudio())
   2128         {
   2129             aTSOffset = (PVMFTimestamp)(iAudioLatency + PARSING_JITTER_DURATION + skewDelta);
   2130         }
   2131         else if (iMediaType.isCompressed() && iMediaType.isVideo())
   2132         {
   2133             aTSOffset = (PVMFTimestamp)(iVideoLatency + PARSING_JITTER_DURATION);
   2134         }
   2135     }
   2136     aTSOffset += iCurTimestamp;
   2137 }
   2138 
   2139 
   2140