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