1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 #include "oscl_rand.h"
21 #include "pvmf_simple_media_buffer.h"
22 #include "pvmf_media_data.h"
23 #include "pvmf_media_cmd.h"
24 #include "pvmf_media_msg_format_ids.h"
26 #ifndef OSCL_MIME_STRING_UTILS_H
27 #include "pv_mime_string_utils.h"
30 #include "logicalchannel.h"
33 #include "h245_copier.h"
37 #include "h245_deleter.h"
39 // decreasing DEF_CHANNEL_BUFFER_SIZE_MS can result out of memory errors,
40 // please change also PV_MAX_VIDEO_FRAME_SIZE to lower value.
41 #define DEF_CHANNEL_BITRATE 64000
42 #define DEF_INCOMING_CHANNEL_BUFFER_SIZE_MS 2800
43 #define DEF_OUTGOING_CHANNEL_BUFFER_SIZE_MS 2800
44 #define TIMESTAMP_MAX INT_MAX
45 #define DEF_SEGMENTABLE_CHANNEL_OH_BPS 2000
46 #define H223_INCOMING_CHANNEL_NUM_MEDIA_MSG 300
47 #define H223_OUTGOING_CHANNEL_NUM_MEDIA_MSG 300
48 #define H223_INCOMING_CHANNEL_FRAGMENT_SIZE 128
49 #define H223_INCOMING_CHANNEL_NUM_MEDIA_DATA 300
50 #define H223_INCOMING_CHANNEL_NUM_FRAGS_IN_MEDIA_DATA (3*1024/128)
51 #define PV2WAY_BPS_TO_BYTES_PER_MSEC_RIGHT_SHIFT 13
52 #define H223_LCN_IN_TIMESTAMP_BASE 40
53 #ifdef LIP_SYNC_TESTING
55 #define H263_START_BYTE_1 0x00
56 #define H263_START_BYTE_2 0x00
57 #define H263_START_BYTE_3 0x80
59 #define VOP_START_BYTE_1 0x00
60 #define VOP_START_BYTE_2 0x00
61 #define VOP_START_BYTE_3 0x01
62 #define VOP_START_BYTE_4 0xB6
63 #define VOP_START_BYTE_5 0xB0
66 #ifdef LIP_SYNC_TESTING
67 /***********************Outgoing side********************/
68 uint32 g_Checkcount = 0;
69 int g_CheckSampleTime = -1;
70 uint32 g_Incmtsmsec = 0;
71 bool g_OnlyOneTime = true;
72 /*****************************************************************/
74 uint32 g_IncmAudioTS = 0;
75 uint32 g_IncmVideoTS = 0;
76 uint32 g_TotalCountIncm = 0;
77 int g_DiffIncmVidAudTS = 0;
78 int g_iSqrIncCalVidAudTS = 0;
79 int g_IncRtMnSqCalc = 0;
80 /**********************************************************************/
81 int g_RecTimeStamp = 0;
85 H223LogicalChannel::H223LogicalChannel(TPVChannelId num,
87 OsclSharedPtr<AdaptationLayer>& al,
88 PS_DataType data_type,
89 LogicalChannelObserver* observer,
91 uint32 sample_interval,
92 uint32 num_media_data)
93 : PvmfPortBaseImpl(num, this),
100 iFormatSpecificInfo(NULL),
101 iFormatSpecificInfoLen(0),
107 iSegmentable = segmentable;
109 iLastSduTimestamp = 0;
110 iSampleInterval = sample_interval;
111 uint32 bitrate_overhead = IsSegmentable() ? DEF_SEGMENTABLE_CHANNEL_OH_BPS :
112 (uint32)((2000 / sample_interval + 1) >> 1) * (al->GetHdrSz() + al->GetTrlrSz());
113 iBitrate = bitrate + bitrate_overhead;
114 iNumMediaData = num_media_data;
115 iMaxSduSize = (uint16)(iAl->GetSduSize() - iAl->GetHdrSz() - iAl->GetTrlrSz());
118 iDataType = Copy_DataType(data_type);
120 iMediaType = GetFormatType();
125 H223LogicalChannel::~H223LogicalChannel()
129 Delete_DataType(iDataType);
130 OSCL_DEFAULT_FREE(iDataType);
133 if (iFormatSpecificInfo)
135 oscl_free(iFormatSpecificInfo);
136 iFormatSpecificInfo = NULL;
137 iFormatSpecificInfoLen = 0;
140 // we need to clear the activity handler, since otherwise the PvmfPortBaseImpl destructor
141 // ends up calling back onto our HandlePortActivity method, which no longer exists because
142 // this objects's destructor has already been called.
143 SetActivityHandler(NULL);
146 void H223LogicalChannel::Init()
148 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LogicalChannel::Init"));
149 iSendFormatSpecificInfo = false;
152 PVMFStatus H223LogicalChannel::SetFormatSpecificInfo(uint8* info, uint16 info_len)
154 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LogicalChannel::SetFormatSpecificInfo lcn=%d, info_len=%d, info=%x", lcn, info_len, info));
155 iSendFormatSpecificInfo = false;
156 if (iFormatSpecificInfo)
158 oscl_free(iFormatSpecificInfo);
159 iFormatSpecificInfo = NULL;
160 iFormatSpecificInfoLen = 0;
163 if (info == NULL || info_len == 0)
166 iFormatSpecificInfo = (uint8*)oscl_malloc(info_len);
167 oscl_memcpy(iFormatSpecificInfo, info, info_len);
168 iFormatSpecificInfoLen = info_len;
169 iSendFormatSpecificInfo = true;
173 const uint8* H223LogicalChannel::GetFormatSpecificInfo(uint32* info_len)
175 if (info_len == NULL)
177 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LogicalChannel::GetFormatSpecificInfo ERROR info_len==NULL"));
180 *info_len = iFormatSpecificInfoLen;
181 return iFormatSpecificInfo;
185 OSCL_EXPORT_REF void H223LogicalChannel::QueryInterface(const PVUuid& aUuid, OsclAny*& aPtr)
188 if (aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
190 aPtr = (PvmiCapabilityAndConfig*)this;
192 else if (aUuid == PVH324MLogicalChannelInfoUuid)
194 aPtr = (LogicalChannelInfo*)this;
198 OSCL_LEAVE(OsclErrNotSupported);
202 void H223LogicalChannel::Pause()
204 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Pause lcn=%d", lcn));
206 // flush any pending media data
210 void H223LogicalChannel::Resume()
215 H223OutgoingChannel::H223OutgoingChannel(TPVChannelId num,
217 OsclSharedPtr<AdaptationLayer>& al,
218 PS_DataType data_type,
219 LogicalChannelObserver* observer,
221 uint32 sample_interval,
222 uint32 num_media_data)
223 : H223LogicalChannel(num, segmentable, al, data_type, observer, bitrate, sample_interval, num_media_data),
224 iMediaMsgMemoryPool(NULL),
225 iMediaDataEntryAlloc(NULL),
226 iMediaFragGroupAlloc(NULL),
227 iPduPktMemPool(NULL),
228 iMediaDataAlloc(&iMemAlloc)
233 iLogger = PVLogger::GetLoggerObject("3g324m.h223.H223OutgoingChannel");
234 iOutgoingVideoLogger = PVLogger::GetLoggerObject("datapath.outgoing.video.h223.lcn");
235 iOutgoingAudioLogger = PVLogger::GetLoggerObject("datapath.outgoing.audio.h223.lcn");
237 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::H223OutgoingChannel - num(%d),segmentable(%d)", num, segmentable));
238 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()));
240 lastMediaData = NULL;
242 iSetBufferMediaMs = 0;
243 iSetBufferMediaBytes = 0;
245 iBufferMediaBytes = 0;
246 iCurPduTimestamp = 0;
250 #ifdef LIP_SYNC_TESTING
253 iDiffVideoAudioTS = 0;
257 iParams = ShareParams::Instance();
259 iMuxingStarted = false;
260 iWaitForRandomAccessPoint = false;
261 iBufferSizeMs = DEF_OUTGOING_CHANNEL_BUFFER_SIZE_MS;
265 H223OutgoingChannel::~H223OutgoingChannel()
269 Delete_DataType(iDataType);
270 OSCL_DEFAULT_FREE(iDataType);
274 iMediaFragGroupAlloc->removeRef();
275 OSCL_DELETE(iPduPktMemPool);
276 OSCL_DELETE(iMediaDataEntryAlloc);
277 OSCL_DELETE(iMediaMsgMemoryPool);
281 void H223OutgoingChannel::Init()
283 H223LogicalChannel::Init();
284 iMediaMsgMemoryPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (H223_OUTGOING_CHANNEL_NUM_MEDIA_MSG));
285 iMediaMsgMemoryPool->enablenullpointerreturn();
286 iMediaDataEntryAlloc = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (iNumMediaData, sizeof(LCMediaDataEntry)));
287 iMediaDataEntryAlloc->enablenullpointerreturn();
288 iPduPktMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (iNumMediaData));
289 iPduPktMemPool->enablenullpointerreturn();
290 iMediaFragGroupAlloc = OSCL_NEW(PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>, (iNumMediaData, 10, iPduPktMemPool));
291 iMediaFragGroupAlloc->create();
295 void H223OutgoingChannel::BufferMedia(uint16 aMs)
297 if (iBufferSizeMs && aMs > iBufferSizeMs)
299 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::BufferMedia ERROR buffer interval=%d > buffer size=%d", aMs, iBufferSizeMs));
301 iSetBufferMediaMs = iBufferMediaMs = aMs;
302 iSetBufferMediaBytes = iBufferMediaBytes = ((iBufferSizeMs * iBitrate + 4000) / 8000);
303 //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223OutgoingChannel::BufferMedia ms=%d,bytes=%d", iBufferMediaMs,iBufferMediaBytes));
306 void H223OutgoingChannel::Resume()
308 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Resume lcn=%d", lcn));
309 H223LogicalChannel::Resume();
311 // start muxing on a random access point
312 //iWaitForRandomAccessPoint=true;
315 void H223OutgoingChannel::SetBufferSizeMs(uint32 buffer_size_ms)
317 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingLogicalChannel::SetBufferSizeMs buffer_size_ms=%d", buffer_size_ms));
318 iBufferSizeMs = buffer_size_ms;
323 PVMFStatus H223OutgoingChannel::PutData(PVMFSharedMediaMsgPtr media_msg)
325 PVMFStatus ret = PVMFSuccess;
326 PVMFSharedMediaDataPtr mediaData;
327 convertToPVMFMediaData(mediaData, media_msg);
329 PV_STAT_SET_TIME(iStartTime, iNumPacketsIn)
330 PV_STAT_INCR(iNumPacketsIn, 1)
332 /* zero through 255 is reserved for media data */
333 if (media_msg->getFormatID() >= PVMF_MEDIA_CMD_FORMAT_IDS_START)
338 PV_STAT_INCR(iNumBytesIn, (mediaData->getFilledSize()))
340 if (iMediaType.isCompressed() && iMediaType.isAudio())
342 PVMF_OUTGOING_AUDIO_LOGDATATRAFFIC((0, "Outgoing audio frames received. Stats: Entry time=%ud, lcn=%d, size=%d", timenow.to_msec(), lcn, mediaData->getFilledSize()));
344 else if (iMediaType.isCompressed() && iMediaType.isVideo())
346 PVMF_OUTGOING_VIDEO_LOGDATATRAFFIC((0, "Outgoing video frames received.Stats: Entry time=%ud, lcn=%d, size=%d", timenow.to_msec(), lcn, mediaData->getFilledSize()));
349 if (iNumPacketsIn % 20 == 0)
351 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData lcn=%d, size=%d, ts=%d", lcn, mediaData->getFilledSize(), mediaData->getTimestamp()));
354 // Check for FormatSpecificInfo. Sending FSI with data is being obsoleted, but there is no harm in leaving this in for now.
355 if (mediaData->getFormatSpecificInfo(iFsiFrag) && iFsiFrag.getMemFragPtr() && iFsiFrag.getMemFragSize())
357 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData Received Format Specific Info, len=%d", iFsiFrag.getMemFragSize()));
358 iObserver->ReceivedFormatSpecificInfo(lcn, (uint8*)iFsiFrag.getMemFragPtr(), iFsiFrag.getMemFragSize());
361 if (IsSegmentable() && iWaitForRandomAccessPoint)
363 if ((mediaData->getMarkerInfo()&PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT) == 0)
365 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData Not random access point. Dropping media data."));
366 return PVMFErrInvalidState;
368 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData Found random access point."));
369 iWaitForRandomAccessPoint = false;
371 else if (iNumPendingPdus == (iNumMediaData - 1))
373 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - ERROR Overflow, iNumPendingPdus=%u", iNumPendingPdus));
374 return PVMFErrOverflow;
377 uint32 num_frags_required = 0;
379 for (frag_num = 0; frag_num < mediaData->getNumFragments(); frag_num++)
381 OsclRefCounterMemFrag memfrag;
382 mediaData->getMediaFragment(frag_num, memfrag);
383 if (memfrag.getMemFragSize() > iMaxSduSize)
385 num_frags_required++;
389 if ((mediaData->getNumFragments() + num_frags_required + iNumPendingPdus) >= (iNumMediaData - 1))
391 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - ERROR Overflow, iNumPendingPdus=%u, num_frags_required=%d,iNumMediaData=%d", iNumPendingPdus, num_frags_required, iNumMediaData));
393 /* Start re-buffering */
394 BufferMedia((uint16)iSetBufferMediaMs);
395 return PVMFErrOverflow;
398 /* Fragment the sdu if needed */
399 PVMFSharedMediaDataPtr& fragmentedMediaData = mediaData;
400 if (num_frags_required)
402 if (true != FragmentPacket(mediaData, fragmentedMediaData))
404 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - Memory allocation failure on Fragment\n"));
405 return PVMFErrOverflow;
410 if (iCurPdu.GetRep())
412 sdu_size = iCurPdu->getFilledSize() - iAl->GetHdrSz();
413 /* Is the timestamp different ? */
414 if (iCurPduTimestamp != fragmentedMediaData->getTimestamp() || !IsSegmentable())
416 if (PVMFSuccess != CompletePdu())
418 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - Memory allocation failure on CompletePdu\n"));
419 return PVMFErrOverflow;
426 //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223OutgoingChannel::PutData Sdu size == 0"));
427 iCurPdu = StartAlPdu();
430 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
431 (0, "H223OutgoingChannel::PutData - Memory allocation failure on StartAlPdu\n"));
432 return PVMFErrOverflow;
435 if (iFsiFrag.getMemFragSize())
437 iCurPdu->appendMediaFragment(iFsiFrag);
438 // reset the FSI frag
439 OsclRefCounterMemFrag frag;
444 for (frag_num = 0; frag_num < fragmentedMediaData->getNumFragments(); frag_num++)
446 OsclRefCounterMemFrag frag;
447 fragmentedMediaData->getMediaFragment(frag_num, frag);
448 OSCL_ASSERT(frag.getMemFragSize() <= iMaxSduSize);
451 ((sdu_size + frag.getMemFragSize() > iMaxSduSize) || !IsSegmentable()))
453 if (PVMFSuccess != CompletePdu())
455 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PutData - Memory allocation failure on CompletePdu\n"));
456 return PVMFErrOverflow;
460 iCurPdu = StartAlPdu();
464 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
465 (0, "H223OutgoingChannel::PutData - Memory allocation failure on StartAlPdu\n"));
466 return PVMFErrOverflow;
470 iCurPdu->appendMediaFragment(frag);
471 sdu_size += frag.getMemFragSize();
472 iCurPduTimestamp = fragmentedMediaData->getTimestamp();
476 if (iMediaType.isCompressed() && iMediaType.isAudio())
478 PVMF_OUTGOING_AUDIO_LOGDATATRAFFIC((0, "Stats of the outgoing audio SDU are: timestamp=%d, size=%d", iCurPduTimestamp, sdu_size));
480 else if (iMediaType.isCompressed() && iMediaType.isVideo())
482 PVMF_OUTGOING_VIDEO_LOGDATATRAFFIC((0, "Stats of the outgoing video SDU are: timestamp=%d, size=%d", iCurPduTimestamp, sdu_size));
487 bool H223OutgoingChannel::FragmentPacket(PVMFSharedMediaDataPtr& aMediaData, PVMFSharedMediaDataPtr& aFragmentedMediaData)
489 OsclRefCounterMemFrag memfrag;
490 OsclSharedPtr<PVMFMediaDataImpl> newpack;
491 newpack = iMediaFragGroupAlloc->allocate();
492 if (!newpack.GetRep())
498 PVMFTimestamp timestamp = aMediaData->getTimestamp();
499 for (uint32 frag_num = 0; frag_num < aMediaData->getNumFragments(); frag_num++)
501 aMediaData->getMediaFragment(frag_num, memfrag);
502 pkt_size = memfrag.getMemFragSize();
503 if ((unsigned)pkt_size <= iMaxSduSize)
505 newpack->appendMediaFragment(memfrag);
507 else /* Need to fragment it */
509 uint8* pos = (uint8*)memfrag.getMemFragPtr();
510 int32 trim_frag_sz = iMaxSduSize;
513 trim_frag_sz = ((unsigned)pkt_size > iMaxSduSize) ? iMaxSduSize : pkt_size;
514 pkt_size -= trim_frag_sz;
515 OsclRefCounterMemFrag trim_frag(memfrag);
516 trim_frag.getMemFrag().ptr = pos;
517 trim_frag.getMemFrag().len = trim_frag_sz;
518 newpack->appendMediaFragment(trim_frag);
523 aFragmentedMediaData = PVMFMediaData::createMediaData(newpack, iMediaMsgMemoryPool);
524 if (aFragmentedMediaData.GetRep())
526 aFragmentedMediaData->setTimestamp(timestamp);
532 OsclSharedPtr<PVMFMediaDataImpl> H223OutgoingChannel::StartAlPdu()
534 PV_STAT_INCR(iNumSdusIn, 1)
537 OsclSharedPtr<PVMFMediaDataImpl> pdu = iMediaFragGroupAlloc->allocate();
541 PVMFStatus status = iAl->StartPacket(pdu);
542 if (status != PVMFSuccess)
553 PVMFStatus H223OutgoingChannel::CompletePdu()
555 PVMFStatus status = iAl->CompletePacket(iCurPdu);
556 if (status != PVMFSuccess)
558 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::CompletePdu Memory allocation failedlcn=%d, CompletePacket status=%d", lcn, status));
563 #ifdef LIP_SYNC_TESTING
564 if (iParams->iUncompressed == true)
571 // Add it to the outgoing queue
572 status = AppendOutgoingPkt(iCurPdu, iCurPduTimestamp);
573 if (status != PVMFSuccess)
578 iCurPduTimestamp = 0;
582 PVMFStatus H223OutgoingChannel::AppendOutgoingPkt(OsclSharedPtr<PVMFMediaDataImpl>& pdu,
583 PVMFTimestamp timestamp,
584 OsclRefCounterMemFrag* fsi)
586 PVMFSharedMediaDataPtr mediaData = PVMFMediaData::createMediaData(pdu, iMediaMsgMemoryPool);
587 if (mediaData.GetRep() == NULL)
589 return PVMFErrNoMemory;
592 mediaData->setTimestamp(timestamp);
595 mediaData->setFormatSpecificInfo(*fsi);
597 void* memory_for_entry = iMediaDataEntryAlloc->allocate(sizeof(LCMediaDataEntry));
598 if (!memory_for_entry)
600 // if couldn't allocate memory - leave
601 return PVMFErrNoMemory;
603 LCMediaDataEntry* entry = OSCL_PLACEMENT_NEW(memory_for_entry, LCMediaDataEntry());
604 entry->mediaData = mediaData;
606 LCMediaDataEntry* first = entry;
607 PVMFTimestamp lastTS = timestamp;
610 first = lastMediaData->next;
611 lastMediaData->next = entry;
612 lastTS = lastMediaData->mediaData->getTimestamp();
614 lastMediaData = entry;
617 /* Adjust buffering parameters */
620 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::AppendOutgoingPkt lcn=%d, last ts=%d,cur ts=%d", lcn, lastTS, timestamp));
621 /* Compute delta_t from last media data */
622 int32 delta_t = timestamp - lastTS;
624 delta_t += TIMESTAMP_MAX;
625 iBufferMediaMs -= delta_t;
626 iBufferMediaBytes -= mediaData->getFilledSize();
627 if (iBufferMediaMs <= 0 || iBufferMediaBytes <= 0)
630 iBufferMediaBytes = 0;
636 bool H223OutgoingChannel::GetNextPacket(PVMFSharedMediaDataPtr& aMediaData, PVMFStatus aStatus)
639 if (!iMuxingStarted && aStatus == PVMFSuccess)
640 iMuxingStarted = true;
642 if (lastMediaData == NULL)
646 if ((aStatus == PVMFSuccess) && iPaused)
648 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::GetNextPacket Logical channel %d paused.", lcn));
652 if ((aStatus == PVMFSuccess) && iBufferMediaMs && iBufferMediaBytes)
654 /* Still buffering */
655 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::GetNextPacket Buffering lcn=%d, ms left=%d", lcn, iBufferMediaMs));
659 LCMediaDataEntry* first = lastMediaData->next;
660 aMediaData = first->mediaData;
662 if (first == lastMediaData)
664 lastMediaData = NULL;
668 lastMediaData->next = first->next;
673 first->~LCMediaDataEntry();
674 iMediaDataEntryAlloc->deallocate(first);
677 OSCL_ASSERT(iNumPendingPdus);
682 OsclAny H223OutgoingChannel::ReleasePacket(PVMFSharedMediaDataPtr& aMediaData)
684 OsclSharedPtr<PVMFMediaDataImpl> aMediaDataImpl;
685 aMediaData->getMediaDataImpl(aMediaDataImpl);
686 aMediaDataImpl->clearMediaFragments();
689 OsclAny H223OutgoingChannel::Flush()
691 //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223OutgoingChannel::Flush\n"));
693 PVMFSharedMediaDataPtr aMediaData;
695 // clear messages in input queue
697 // go through pending queue
698 while (GetNextPacket(aMediaData, PVMFErrCancelled))
700 PV_STAT_INCR(iNumBytesFlushed, aMediaData->getFilledSize())
701 OsclSharedPtr<PVMFMediaDataImpl> aMediaDataImpl;
702 aMediaData->getMediaDataImpl(aMediaDataImpl);
703 aMediaDataImpl->clearMediaFragments();
705 if (iCurPdu.GetRep())
707 iCurPdu->clearMediaFragments();
710 iCurPduTimestamp = 0;
713 OsclAny H223OutgoingChannel::ResetStats()
721 iMaxPacketMuxTime = 0;
724 iNumBytesFlushed = 0;
727 OsclAny H223OutgoingChannel::LogStats()
729 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Outgoing Logical Channel %d Statistics:\n", lcn));
730 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Adaptation layer header bytes - %d\n", iAl->GetHdrSz()));
731 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Adaptation layer trailer bytes - %d\n", iAl->GetTrlrSz()));
732 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num packets received - %d\n", iNumPacketsIn));
733 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus received - %d\n", iNumSdusIn));
734 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes received - %d\n", iNumBytesIn));
735 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus dropped - %d\n", iNumSdusDropped));
736 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus output - %d\n", iNumSdusOut));
737 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes output - %d\n", iNumBytesOut));
738 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Max packet mux time - %d\n", iMaxPacketMuxTime));
739 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Max sdu mux time - %d\n", iMaxSduMuxTime));
740 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num flush - %d\n", iNumFlush));
741 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes flushed - %d\n", iNumBytesFlushed));
744 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::Connect(PVMFPortInterface* aPort)
746 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect, aPort=%x", aPort));
750 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect Error: Already connected"));
754 PvmiCapabilityAndConfig* config = NULL;
756 OsclAny* tempInterface = NULL;
757 aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, tempInterface);
758 config = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, tempInterface);
761 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect: Error - Peer port does not support capability interface"));
765 PVMFStatus status = NegotiateInputSettings(config);
767 if (status != PVMFSuccess)
769 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect: Error - Settings negotiation failed. status=%d", status));
773 //Automatically connect the peer.
774 if ((status = aPort->PeerConnect(this)) != PVMFSuccess)
776 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::Connect: Error - Peer Connect failed. status=%d", status));
780 iConnectedPort = aPort;
782 PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
785 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::PeerConnect(PVMFPortInterface* aPort)
788 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::PeerConnect aPort=0x%x", this, aPort));
791 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "0x%x H223OutgoingChannel::PeerConnect: Error - Connecting to invalid port", this));
792 return PVMFErrArgument;
796 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "0x%x H223OutgoingChannel::PeerConnect: Error - Already connected", this));
800 OsclAny* config = NULL;
801 aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, config);
804 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::PeerConnect: Error - Peer port does not support capability interface"));
809 PVMFStatus status = PVMFSuccess;
811 status = NegotiateInputSettings((PvmiCapabilityAndConfig*)config);
813 if (status != PVMFSuccess)
815 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::PeerConnect: Error - Settings negotiation failed. status=%d", status));
816 // Ignore errors for now
817 status = PVMFSuccess;
821 iConnectedPort = aPort;
822 PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
827 PVMFStatus H223OutgoingChannel::NegotiateFSISettings(PvmiCapabilityAndConfig* aConfig)
832 uint8* pc_fsi = NULL;
833 unsigned pc_fsilen = ::GetFormatSpecificInfo(iDataType, pc_fsi);
834 if (pc_fsilen && pc_fsi)
837 * Create PvmiKvp for capability settings
839 OsclMemAllocator alloc;
842 kvp.length = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY) + 1; // +1 for \0
843 kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
848 oscl_strncpy(kvp.key, PVMF_FORMAT_SPECIFIC_INFO_KEY, kvp.length);
850 kvp.value.key_specific_value = (OsclAny*)pc_fsi;
851 kvp.capacity = pc_fsilen;
852 kvp.length = pc_fsilen;
854 PvmiKvp* retKvp = NULL; // for return value
856 OSCL_TRY(err, aConfig->setParametersSync(NULL, &kvp, 1, retKvp););
857 alloc.deallocate((OsclAny*)(kvp.key));
860 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::NegotiateFSISettings, Failed to set FSI on peer, err=%d", err));
862 // Temp change to return success. Enc node does not support setting FSI yet. This will cause port connect to fail.
867 // No preconfigured FSI. In this case try to get the FSI from the peer.
868 PVMFStatus status = aConfig->getParametersSync(NULL, (PvmiKeyType)PVMF_FORMAT_SPECIFIC_INFO_KEY, kvp, numParams, NULL);
869 if (status != PVMFSuccess || numParams != 1)
871 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateFSISettings: Failed to get FSI from peer"));
876 ReceivedFSIFromPeer(kvp);
877 aConfig->releaseParameters(NULL, kvp, numParams);
886 PVMFStatus H223OutgoingChannel::ReceivedFSIFromPeer(PvmiKvp* kvp)
888 // Create mem frag for VOL header
889 OsclRefCounter* my_refcnt;
890 OsclMemAllocDestructDealloc<uint8> my_alloc;
891 uint aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
892 uint8* my_ptr = (uint8*) my_alloc.allocate(aligned_refcnt_size + kvp->length);
893 my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
894 my_ptr += aligned_refcnt_size;
896 oscl_memcpy(my_ptr, kvp->value.key_specific_value, kvp->length);
898 OsclMemoryFragment memfrag;
899 memfrag.len = kvp->length;
900 memfrag.ptr = my_ptr;
902 OsclRefCounterMemFrag configinfo(memfrag, my_refcnt, kvp->length);
903 iFsiFrag = configinfo;
905 SetFormatSpecificInfo((uint8*)kvp->value.key_specific_value, kvp->length);
907 iObserver->ReceivedFormatSpecificInfo(lcn, (uint8*)kvp->value.key_specific_value, kvp->length);
912 PVMFStatus H223OutgoingChannel::NegotiateInputSettings(PvmiCapabilityAndConfig* aConfig)
914 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::NegotiateInputSettings, aConfig=%x", aConfig));
920 // Get supported output formats from peer
921 PVMFStatus status = aConfig->getParametersSync(NULL,
922 OSCL_CONST_CAST(char*, OUTPUT_FORMATS_CAP_QUERY),
923 kvp, numParams, NULL);
924 if (status != PVMFSuccess || numParams == 0)
926 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error: getParametersSync failed. status=%d", status));
930 PvmiKvp* selectedKvp = NULL;
931 PVCodecType_t codec_type = GetCodecType(iDataType);
932 PVMFFormatType lcn_format_type = PVCodecTypeToPVMFFormatType(codec_type);
934 for (i = 0; i < numParams && !selectedKvp; i++)
936 if (lcn_format_type == kvp[i].value.pChar_value)
937 selectedKvp = &(kvp[i]);
942 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error: Input format not supported by peer"));
945 if (PVMFSuccess != setConfigParametersSync(selectedKvp, aConfig))
950 aConfig->releaseParameters(NULL, kvp, numParams);
955 if (iMediaType.isVideo())
957 // frame width negotiations
958 uint32 width = GetVideoFrameSize(iDataType, true);
959 status = aConfig->getParametersSync(NULL, (PvmiKeyType)VIDEO_OUTPUT_WIDTH_CAP_QUERY, kvp, numParams, NULL);
960 if (status != PVMFSuccess || numParams != 1)
962 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - config->getParametersSync(cap width) failed"));
963 // do not report error for now as enc nodes dont implemlement some parameters
968 if (kvp[0].value.uint32_value > width)
970 OsclMemAllocator alloc;
973 kvp.length = oscl_strlen(VIDEO_OUTPUT_WIDTH_CUR_QUERY) + 1; // +1 for \0
974 kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
977 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - alloc failed for VIDEO_OUTPUT_WIDTH_CUR_QUERY kvp "));
978 return PVMFErrNoMemory;
980 oscl_strncpy(kvp.key, VIDEO_OUTPUT_WIDTH_CUR_QUERY, kvp.length);
981 kvp.value.uint32_value = width;
983 if (PVMFSuccess != setConfigParametersSync(&kvp, aConfig))
985 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error: setConfigParametersSync width failed"));
986 //dont return PVMFFailure for now ;
990 alloc.deallocate((OsclAny*)(kvp.key));
993 aConfig->releaseParameters(NULL, kvp, numParams);
1001 // frame height negotiations
1002 uint32 height = GetVideoFrameSize(iDataType, false);
1003 status = aConfig->getParametersSync(NULL, (PvmiKeyType)VIDEO_OUTPUT_HEIGHT_CAP_QUERY, kvp, numParams, NULL);
1004 if (status != PVMFSuccess || numParams != 1)
1006 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - config->getParametersSync(cap height) failed"));
1007 // do not report error for now as enc nodes dont implemlement some parameters
1012 if (kvp[0].value.uint32_value > height)
1014 OsclMemAllocator alloc;
1017 kvp.length = oscl_strlen(VIDEO_OUTPUT_HEIGHT_CUR_QUERY) + 1; // +1 for \0
1018 kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
1019 if (kvp.key == NULL)
1021 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - alloc failed for VIDEO_OUTPUT_HEIGHT_CUR_QUERY kvp "));
1022 return PVMFErrNoMemory;
1024 oscl_strncpy(kvp.key, VIDEO_OUTPUT_HEIGHT_CUR_QUERY, kvp.length);
1025 kvp.value.uint32_value = height;
1027 if (PVMFSuccess != setConfigParametersSync(&kvp, aConfig))
1029 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error: setConfigParametersSync height failed"));
1030 //dont return PVMFFailure for now;
1032 alloc.deallocate((OsclAny*)(kvp.key));
1035 aConfig->releaseParameters(NULL, kvp, numParams);
1041 // frame rate negotiations
1042 uint32 framerate = GetMaxFrameRate(iDataType);
1043 // VIDEO_OUTPUT_FRAME_RATE_CAP_QUERY not available
1044 status = aConfig->getParametersSync(NULL, (PvmiKeyType)VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY, kvp, numParams, NULL);
1045 if (status != PVMFSuccess || numParams != 1)
1047 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - config->getParametersSync(cap frame rate failed"));
1048 // do not report error for now as enc nodes dont implemlement some parameters
1053 if (kvp[0].value.float_value > framerate)
1055 OsclMemAllocator alloc;
1058 kvp.length = oscl_strlen(VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY) + 1; // +1 for \0
1059 kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
1060 if (kvp.key == NULL)
1062 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings: Error - alloc failed for VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY kvp "));
1063 return PVMFErrNoMemory;
1065 oscl_strncpy(kvp.key, VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY, kvp.length);
1066 kvp.value.float_value = (float)framerate;
1068 if (PVMFSuccess != setConfigParametersSync(&kvp, aConfig))
1070 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "H223OutgoingChannel::NegotiateInputSettings, Error: setConfigParametersSync frame rate failed"));
1071 //dont return PVMFFailure for now ;
1073 alloc.deallocate((OsclAny*)(kvp.key));
1076 aConfig->releaseParameters(NULL, kvp, numParams);
1083 return NegotiateFSISettings(aConfig);
1085 ////////////////////////////////////////////////////////////////////////////
1086 // PvmiCapabilityAndConfig
1087 ////////////////////////////////////////////////////////////////////////////
1088 OSCL_EXPORT_REF void H223OutgoingChannel::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
1091 OSCL_UNUSED_ARG(aObserver);
1092 OSCL_LEAVE(OsclErrNotSupported);
1095 ////////////////////////////////////////////////////////////////////////////
1096 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::getParametersSync(PvmiMIOSession session,
1097 PvmiKeyType identifier,
1098 PvmiKvp*& parameters,
1099 int& num_parameter_elements,
1100 PvmiCapabilityContext context)
1102 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::getParametersSync"));
1103 OSCL_UNUSED_ARG(session);
1104 OSCL_UNUSED_ARG(context);
1107 num_parameter_elements = 0;
1109 if (pv_mime_strcmp(identifier, INPUT_FORMATS_CAP_QUERY) == 0)
1111 num_parameter_elements = 1;
1112 PVMFStatus status = AllocateKvp(iKvpMemAlloc, parameters,
1113 OSCL_CONST_CAST(char*, INPUT_FORMATS_VALTYPE),
1114 num_parameter_elements);
1115 if (status != PVMFSuccess)
1117 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::getParametersSync: Error - AllocateKvp failed. status=%d", status));
1120 PVCodecType_t codec_type = GetCodecType(iDataType);
1122 PVMFFormatType format = PVCodecTypeToPVMFFormatType(codec_type).getMIMEStrPtr();
1123 if (format == PVMF_MIME_AMR_IF2)
1124 parameters[0].value.pChar_value = (char*) PVMF_MIME_AMR_IF2;
1125 else if (format == PVMF_MIME_PCM16)
1126 parameters[0].value.pChar_value = (char*) PVMF_MIME_PCM16;
1127 else if (format == PVMF_MIME_YUV420)
1128 parameters[0].value.pChar_value = (char*) PVMF_MIME_YUV420;
1129 else if (format == PVMF_MIME_M4V)
1130 parameters[0].value.pChar_value = (char*) PVMF_MIME_M4V;
1131 else if (format == PVMF_MIME_H2632000)
1132 parameters[0].value.pChar_value = (char*) PVMF_MIME_H2632000;
1133 else if (format == PVMF_MIME_H2631998)
1134 parameters[0].value.pChar_value = (char*) PVMF_MIME_H2631998;
1136 parameters[0].value.pChar_value = (char*) PVMF_MIME_FORMAT_UNKNOWN;
1142 ////////////////////////////////////////////////////////////////////////////
1143 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::releaseParameters(PvmiMIOSession session,
1144 PvmiKvp* parameters,
1147 OSCL_UNUSED_ARG(session);
1148 OSCL_UNUSED_ARG(num_elements);
1152 iKvpMemAlloc.deallocate((OsclAny*)parameters);
1161 ////////////////////////////////////////////////////////////////////////////
1162 OSCL_EXPORT_REF void H223OutgoingChannel::createContext(PvmiMIOSession session, PvmiCapabilityContext& context)
1164 OSCL_UNUSED_ARG(session);
1165 OSCL_UNUSED_ARG(context);
1168 ////////////////////////////////////////////////////////////////////////////
1169 OSCL_EXPORT_REF void H223OutgoingChannel::setContextParameters(PvmiMIOSession session,
1170 PvmiCapabilityContext& context,
1171 PvmiKvp* parameters, int num_parameter_elements)
1173 OSCL_UNUSED_ARG(session);
1174 OSCL_UNUSED_ARG(context);
1175 OSCL_UNUSED_ARG(parameters);
1176 OSCL_UNUSED_ARG(num_parameter_elements);
1179 ////////////////////////////////////////////////////////////////////////////
1180 OSCL_EXPORT_REF void H223OutgoingChannel::DeleteContext(PvmiMIOSession session, PvmiCapabilityContext& context)
1182 OSCL_UNUSED_ARG(session);
1183 OSCL_UNUSED_ARG(context);
1186 ////////////////////////////////////////////////////////////////////////////
1187 OSCL_EXPORT_REF void H223OutgoingChannel::setParametersSync(PvmiMIOSession session, PvmiKvp* parameters,
1188 int num_elements, PvmiKvp*& ret_kvp)
1190 OSCL_UNUSED_ARG(session);
1191 PVMFStatus status = PVMFSuccess;
1194 for (int32 i = 0; i < num_elements; i++)
1196 status = VerifyAndSetParameter(&(parameters[i]), true);
1197 if (status != PVMFSuccess)
1199 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::setParametersSync: Error - VerifiyAndSetParameter failed on parameter #%d", i));
1200 ret_kvp = &(parameters[i]);
1201 /* Silently ignore unrecognized codecs untill CapEx is supported by peer */
1202 //OSCL_LEAVE(OsclErrArgument);
1207 PVMFStatus H223OutgoingChannel::VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam)
1209 OSCL_UNUSED_ARG(aSetParam);
1210 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::VerifyAndSetParameter: aKvp=0x%x, aSetParam=%d", aKvp, aSetParam));
1214 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::VerifyAndSetParameter: Error - Invalid key-value pair"));
1218 if (iDataType == NULL)
1220 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::VerifyAndSetParameter: Error - DataType == NULL"));
1221 return PVMFErrNotSupported;
1224 if (pv_mime_strcmp(aKvp->key, INPUT_FORMATS_VALTYPE) == 0)
1226 PVCodecType_t codec_type = GetCodecType(iDataType);
1227 PVMFFormatType lcn_format_type = PVCodecTypeToPVMFFormatType(codec_type);
1228 if (pv_mime_strcmp(lcn_format_type.getMIMEStrPtr(), aKvp->value.pChar_value) != 0)
1230 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::VerifyAndSetParameter: Error - Input format %s not supported", aKvp->value.pChar_value));
1231 return PVMFErrNotSupported;
1234 else if (pv_mime_strcmp(aKvp->key, PVMF_FORMAT_SPECIFIC_INFO_KEY) == 0)
1236 ReceivedFSIFromPeer(aKvp);
1242 ////////////////////////////////////////////////////////////////////////////
1243 OSCL_EXPORT_REF PVMFCommandId H223OutgoingChannel::setParametersAsync(PvmiMIOSession session,
1244 PvmiKvp* parameters,
1249 OSCL_UNUSED_ARG(session);
1250 OSCL_UNUSED_ARG(parameters);
1251 OSCL_UNUSED_ARG(num_elements);
1252 OSCL_UNUSED_ARG(ret_kvp);
1253 OSCL_UNUSED_ARG(context);
1257 ////////////////////////////////////////////////////////////////////////////
1258 OSCL_EXPORT_REF uint32 H223OutgoingChannel::getCapabilityMetric(PvmiMIOSession session)
1260 OSCL_UNUSED_ARG(session);
1264 ////////////////////////////////////////////////////////////////////////////
1265 OSCL_EXPORT_REF PVMFStatus H223OutgoingChannel::verifyParametersSync(PvmiMIOSession session,
1266 PvmiKvp* parameters, int num_elements)
1268 OSCL_UNUSED_ARG(session);
1270 PVMFStatus status = PVMFSuccess;
1271 for (int32 i = 0; (i < num_elements) && (status == PVMFSuccess); i++)
1272 status = VerifyAndSetParameter(&(parameters[i]), true);
1277 void H223OutgoingChannel::HandlePortActivity(const PVMFPortActivity &aActivity)
1279 if (aActivity.iType != PVMF_PORT_ACTIVITY_INCOMING_MSG &&
1280 aActivity.iType != PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY)
1282 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::HandlePortActivity Unhandled port activity: %d", aActivity.iType));
1286 PVMFSharedMediaMsgPtr aMsg;
1287 while (IncomingMsgQueueSize())
1289 aStatus = DequeueIncomingMsg(aMsg);
1290 if (aStatus == PVMFSuccess)
1293 DetectSkewInd(aMsg);
1299 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223OutgoingChannel::HandlePortActivity Failed to DeQueue incoming message: %d", aStatus));
1305 OSCL_EXPORT_REF PVMFStatus H223OutgoingControlChannel::PeerConnect(PVMFPortInterface* aPort)
1307 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PeerConnect aPort=0x%x", this, aPort));
1310 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "0x%x H223OutgoingControlChannel::PeerConnect: Error - Connecting to invalid port", this));
1311 return PVMFErrArgument;
1315 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "0x%x H223OutgoingControlChannel::PeerConnect: Error - Already connected", this));
1319 iConnectedPort = aPort;
1320 PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
1325 PVMFStatus H223OutgoingControlChannel::PutData(PVMFSharedMediaMsgPtr aMsg)
1327 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PutData - iNumPendingPdus=%u,iNumMediaData=%u\n", iNumPendingPdus, iNumMediaData));
1329 PVMFSharedMediaDataPtr mediaData;
1330 convertToPVMFMediaData(mediaData, aMsg);
1332 PV_STAT_SET_TIME(iStartTime, iNumPacketsIn)
1333 PV_STAT_INCR(iNumPacketsIn, 1)
1334 PV_STAT_INCR(iNumSdusIn, 1)
1335 PV_STAT_INCR(iNumBytesIn, (mediaData->getFilledSize()))
1337 OsclSharedPtr<PVMFMediaDataImpl> pdu;
1342 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PutData - Memory allocation failure on iMediaFragGroupAlloc->allocate\n"));
1343 return PVMFErrNoMemory;
1347 OsclRefCounterMemFrag frag;
1348 for (uint frag_num = 0; frag_num < mediaData->getNumFragments(); frag_num++)
1350 mediaData->getMediaFragment(frag_num, frag);
1351 // Add data fragments
1352 pdu->appendMediaFragment(frag);
1355 PVMFStatus status = iAl->CompletePacket(pdu);
1356 if (status != PVMFSuccess)
1358 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PutData - Memory allocation failure on iAl->CompletePacket()"));
1362 OsclRefCounterMemFrag fsi;
1363 bool fsi_available = mediaData->getFormatSpecificInfo(fsi);
1364 // Add it to the outgoing queue
1365 if (PVMFSuccess != AppendOutgoingPkt(pdu, timenow.to_msec(), (fsi_available ? &fsi : NULL)))
1367 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingControlChannel::PutData - Memory allocation failure on AppendOutgoingPkt()"));
1368 return PVMFErrNoMemory;
1373 void H223LogicalChannel::SetDatapathLatency(uint32 aLatency)
1375 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223LogicalChannel::SetDatapathLatency lcn=%d, aLatency=%d", lcn, aLatency));
1376 iDatapathLatency = aLatency;
1379 PVMFStatus H223LogicalChannel::setConfigParametersSync(PvmiKvp* selectedKvp,
1380 PvmiCapabilityAndConfig* aConfig,
1381 PVMFFormatType lcn_format_type,
1385 PvmiKvp* retKvp = NULL;
1388 OSCL_TRY(err, aConfig->setParametersSync(NULL, selectedKvp, 1, retKvp););
1389 OSCL_FIRST_CATCH_ANY(err,
1390 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223OutgoingChannel::setConfigParametersSync, Error: setParametersSync failed, err=%d", err));
1397 OSCL_TRY(err, aConfig->setParametersSync(NULL, selectedKvp, 1, retKvp););
1400 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::setConfigParametersSync, Error: setParametersSync failed for pChar value, trying uint32, err=%d", err));
1401 selectedKvp->value.pChar_value = OSCL_STATIC_CAST(mbchar*, lcn_format_type.getMIMEStrPtr());
1403 OSCL_TRY(err, aConfig->setParametersSync(NULL, selectedKvp, 1, retKvp););
1406 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::setConfigParametersSync, Error: setParametersSync failed, err=%d", err));
1413 H223IncomingChannel::H223IncomingChannel(TPVChannelId num,
1415 OsclSharedPtr<AdaptationLayer>& al,
1416 PS_DataType data_type,
1417 LogicalChannelObserver* observer,
1419 uint32 sample_interval,
1420 uint32 num_media_data)
1421 : H223LogicalChannel(num, segmentable, al, data_type, observer, bitrate, sample_interval, num_media_data),
1422 iMediaMsgMemoryPool(NULL),
1423 iMediaFragGroupAlloc(NULL),
1424 iPduPktMemPool(NULL),
1425 iMediaDataAlloc(&iMemAlloc),
1426 iPduSize(al->GetPduSize()),
1431 #ifdef LIP_SYNC_TESTING
1432 iParam = ShareParams::Instance();
1434 iLogger = PVLogger::GetLoggerObject("3g324m.h223.H223IncomingChannel");
1435 iIncomingAudioLogger = PVLogger::GetLoggerObject("datapath.incoming.audio.h223.lcn");
1436 iIncomingVideoLogger = PVLogger::GetLoggerObject("datapath.incoming.video.h223.lcn");
1437 iAlPduFragPos = NULL;
1443 H223IncomingChannel::~H223IncomingChannel()
1446 OsclRefCounterMemFrag frag;
1448 if (iMediaFragGroupAlloc)
1450 iMediaFragGroupAlloc->removeRef();
1454 OSCL_DELETE(iPduPktMemPool);
1456 if (iMediaMsgMemoryPool)
1458 OSCL_DELETE(iMediaMsgMemoryPool);
1462 void H223IncomingChannel::Init()
1464 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Init"));
1465 H223LogicalChannel::Init();
1467 int bitrate = (GetBitrate() > 0) ? GetBitrate() : DEF_CHANNEL_BITRATE;
1468 int mem_size = (DEF_INCOMING_CHANNEL_BUFFER_SIZE_MS * bitrate) >> PV2WAY_BPS_TO_BYTES_PER_MSEC_RIGHT_SHIFT;
1469 int num_fragments = (mem_size / H223_INCOMING_CHANNEL_FRAGMENT_SIZE) + 1;
1470 iMediaMsgMemoryPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (H223_INCOMING_CHANNEL_NUM_MEDIA_MSG));
1471 if (iMediaMsgMemoryPool == NULL)
1473 OSCL_LEAVE(PVMFErrNoMemory);
1475 iMediaMsgMemoryPool->enablenullpointerreturn();
1477 iPduPktMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (H223_INCOMING_CHANNEL_NUM_MEDIA_DATA));
1478 if (iPduPktMemPool == NULL)
1480 OSCL_LEAVE(PVMFErrNoMemory);
1482 iPduPktMemPool->enablenullpointerreturn();
1484 iMediaFragGroupAlloc = OSCL_NEW(PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>, (H223_INCOMING_CHANNEL_NUM_MEDIA_DATA, H223_INCOMING_CHANNEL_NUM_FRAGS_IN_MEDIA_DATA, iPduPktMemPool));
1485 if (iMediaFragGroupAlloc == NULL)
1487 OSCL_LEAVE(PVMFErrNoMemory);
1489 iMediaFragGroupAlloc->create();
1491 iMemFragmentAlloc.SetLeaveOnAllocFailure(false);
1492 iMemFragmentAlloc.size((uint16)num_fragments, (uint16)H223_INCOMING_CHANNEL_FRAGMENT_SIZE);
1501 OsclAny H223IncomingChannel::ResetAlPdu()
1503 iAlPduFragPos = NULL;
1505 OsclRefCounterMemFrag frag;
1507 iAlPduMediaData.Unbind();
1510 OsclAny H223IncomingChannel::AllocateAlPdu()
1512 iAlPduMediaData = iMediaFragGroupAlloc->allocate();
1513 if (iAlPduMediaData.GetRep() == NULL)
1520 OsclAny H223IncomingChannel::AppendAlPduFrag()
1522 OsclRefCounterMemFrag ref_counter_mem_frag = iMemFragmentAlloc.get();
1523 if (ref_counter_mem_frag.getMemFragPtr() == NULL)
1527 ref_counter_mem_frag.getMemFrag().len = 0;
1528 iAlPduFrag = ref_counter_mem_frag;
1529 iAlPduFragPos = (uint8*)iAlPduFrag.getMemFragPtr();
1532 uint32 H223IncomingChannel::CopyAlPduData(uint8* buf, uint16 len)
1534 int32 remaining = len;
1538 copied = CopyToCurrentFrag(buf, (uint16)remaining);
1540 remaining -= copied;
1542 while (remaining && copied);
1543 return (uint32)(len - remaining);
1546 uint32 H223IncomingChannel::CopyToCurrentFrag(uint8* buf, uint16 len)
1548 if (iAlPduMediaData.GetRep() == NULL)
1552 else if (iAlPduFragPos == NULL)
1556 if (iAlPduFragPos == NULL)
1561 uint32 space_in_current_frag = ((uint8*)iAlPduFrag.getMemFragPtr() + iAlPduFrag.getCapacity() - iAlPduFragPos);
1562 OSCL_ASSERT(space_in_current_frag > 0);
1563 uint32 num_bytes_copied = (len > space_in_current_frag) ? space_in_current_frag : len;
1564 oscl_memcpy(iAlPduFragPos, buf, num_bytes_copied);
1565 iAlPduFrag.getMemFrag().len += num_bytes_copied;
1566 iAlPduFragPos += num_bytes_copied;
1567 space_in_current_frag -= num_bytes_copied;
1568 if (space_in_current_frag == 0)
1570 iAlPduMediaData->appendMediaFragment(iAlPduFrag);
1571 iAlPduFragPos = NULL;
1573 PVLOGGER_LOG_USE_ONLY(
1574 if (iAlPduMediaData->getFilledSize() > iPduSize)
1576 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::CopyToCurrentFrag WARNING current pdu size=%d > iPduSize=%d", iAlPduMediaData->getFilledSize(), iPduSize));
1579 return num_bytes_copied;
1582 void H223IncomingChannel::PreAlPduData()
1585 if (iSendFormatSpecificInfo)
1587 SendFormatSpecificInfo();
1592 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::PreAlPduData Logical channel paused. Dropping media data."));
1597 PVMFStatus H223IncomingChannel::AlPduData(uint8* buf, uint16 len)
1599 PV_STAT_INCR(iNumBytesIn, len)
1600 PV_STAT_SET_TIME(iStartTime, iNumBytesIn)
1603 if (PVMFSuccess != DispatchPendingSdus())
1605 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlPduData lcn=%d, Failed to dispatch pending sdus", lcn));
1607 if (iAlPduMediaData.GetRep() == NULL || iAlPduMediaData->getFilledSize() == 0)
1609 bool overflow = false;
1610 if (lcn != 0 && iClock)
1612 // not the control channel
1613 iClock->GetCurrentTime32(iCurTimestamp, overflow, PVMF_MEDIA_CLOCK_MSEC);
1616 uint32 copied = CopyAlPduData(buf, len);
1617 return (copied == len) ? PVMFSuccess : PVMFFailure;
1620 PVMFStatus H223IncomingChannel::AlDispatch()
1623 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatch lcn=%d, iCurPduSize=%d, sn=%d", lcn, iCurPduSize, iNumSdusIn));
1624 IncomingALPduInfo info;
1628 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatch Logical channel paused."));
1632 /* Nothing to dispatch */
1633 if (!iAlPduMediaData.GetRep())
1635 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatch Nothing to dispatch."));
1640 /* Add pending fragment to the media message */
1643 iAlPduMediaData->appendMediaFragment(iAlPduFrag);
1646 PVMFFormatType mediaType = GetFormatType();
1647 #ifdef LIP_SYNC_TESTING
1648 if ((mediaType.isVideo() && iParam->iUncompressed == true))
1654 /* Parse AL headers etc */
1655 iAl->ParsePacket(iAlPduMediaData, info);
1656 int32 len = info.sdu_size;
1659 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatch Empty SDU lcn=%d, len=%d", lcn, len));
1661 return PVMFErrCorrupt;
1664 PV_STAT_INCR_COND(iNumCrcErrors, 1, info.crc_error)
1665 PV_STAT_INCR_COND(iNumSeqNumErrors, 1, info.seq_num_error)
1666 PVMFStatus status = PVMFSuccess;
1668 // set the errors flag
1669 uint32 errorsFlag = 0;
1672 errorsFlag |= PVMF_MEDIA_DATA_BIT_ERRORS;
1673 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::AlDispatch CRC error lcn=%d, size=%d", lcn, len));
1674 status = PVMFErrCorrupt;
1678 PV_STAT_INCR(iNumSdusIn, 1)
1680 if (info.seq_num_error)
1682 errorsFlag |= PVMF_MEDIA_DATA_PACKET_LOSS;
1683 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::AlDispatch Sequence number error lcn=%d, size=%d", lcn, len));
1684 status = PVMFErrCorrupt;
1687 OsclSharedPtr<PVMFMediaData> aMediaData = PVMFMediaData::createMediaData(iAlPduMediaData, iMediaMsgMemoryPool);
1688 if (aMediaData.GetRep() == NULL)
1690 return PVMFErrNoMemory;
1694 PVMFTimestamp baseTimestamp = 0;
1695 SetSampleTimestamps(baseTimestamp);
1696 aMediaData->setTimestamp(baseTimestamp);
1697 aMediaData->setSeqNum(info.seq_num);
1698 iAlPduMediaData->setErrorsFlag(errorsFlag);
1700 PVMFSharedMediaMsgPtr aMediaMsg;
1701 convertToPVMFMediaMsg(aMediaMsg, aMediaData);
1703 if (mediaType.isCompressed() && mediaType.isAudio())
1705 // we are using only full audio frames
1706 aMediaData->setMarkerInfo(PVMF_MEDIA_DATA_MARKER_INFO_M_BIT);
1708 #ifdef LIP_SYNC_TESTING
1710 if (mediaType.isAudio() || mediaType.isVideo())
1712 OsclRefCounterMemFrag memFrag;
1713 aMediaData->getMediaFragment(0, memFrag);
1714 uint8* buf = (uint8*)memFrag.getMemFragPtr();
1715 // we are using only full audio frames
1716 DetectFrameBoundary(buf, baseTimestamp);
1724 if (mediaType.isCompressed() && mediaType.isAudio())
1726 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()));
1728 else if (mediaType.isCompressed() && mediaType.isVideo())
1730 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()));
1732 PVMFStatus dispatch_status = QueueOutgoingMsg(aMediaMsg);
1733 if (dispatch_status != PVMFSuccess)
1735 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));
1736 status = dispatch_status;
1739 else if (IsSegmentable())
1741 iPendingSdus.push_back(aMediaMsg);
1745 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::AlDispatchL Dropping pdu lcn=%d, iCurPduSize=%d", lcn, iCurPduSize));
1746 status = PVMFErrNotReady;
1753 OsclAny H223IncomingChannel::Flush()
1755 PV_STAT_INCR(iNumBytesFlushed, (iAlPduFragPos - (uint8*)iAlPduFrag.getMemFragPtr()))
1756 PV_STAT_INCR_COND(iNumAbort, 1, (iAlPduFragPos - (uint8*)iAlPduFrag.getMemFragPtr()))
1757 iPendingSdus.clear();
1762 PVMFStatus H223IncomingChannel::Connect(PVMFPortInterface* aPort)
1764 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect lcn(%d)\n", lcn));
1767 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect Error: Already connected"));
1772 PvmiCapabilityAndConfig* config = NULL;
1773 OsclAny * tempInterface = NULL;
1774 aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, tempInterface);
1775 config = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, tempInterface);
1778 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect: Error - Peer port does not support capability interface"));
1782 PVMFStatus status = NegotiateOutputSettings(config);
1784 if (status != PVMFSuccess)
1786 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect: Error - Settings negotiation failed. status=%d", status));
1790 //Automatically connect the peer.
1791 if ((status = aPort->PeerConnect(this)) != PVMFSuccess)
1793 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect: Error - Peer Connect failed. status=%d", status));
1797 iConnectedPort = aPort;
1799 //Check the BOS command status
1800 status = SendBeginOfStreamMediaCommand();
1802 if (status != PVMFSuccess)
1804 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect: Failed to send BOS message status=%d", status));
1808 /* Send any format specific info if available */
1809 if (iSendFormatSpecificInfo)
1810 SendFormatSpecificInfo();
1812 DispatchPendingSdus();
1814 PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
1819 OsclAny H223IncomingChannel::ResetStats()
1823 iSduSizeExceededCnt = 0;
1825 iNumSeqNumErrors = 0;
1826 iNumBytesFlushed = 0;
1830 OsclAny H223IncomingChannel::LogStats()
1832 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Incoming Logical Channel %d Statistics:\n", lcn));
1833 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus received - %d\n", iNumSdusIn));
1834 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes received - %d\n", iNumBytesIn));
1835 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num times sdu size exceeded - %d\n", iSduSizeExceededCnt));
1836 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus with CRC errors - %d\n", iNumCrcErrors));
1837 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus with sequence number errors - %d\n", iNumSeqNumErrors));
1838 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num sdus aborted - %d\n", iNumAbort));
1839 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "Num bytes aborted - %d\n", iNumBytesFlushed));
1842 PVMFStatus H223IncomingChannel::DispatchPendingSdus()
1844 if (!iConnectedPort)
1846 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::DispatchPendingSdus: Not connected"));
1849 if (iPendingSdus.size())
1851 /* Dispatch any pending sdus */
1852 for (unsigned i = 0; i < iPendingSdus.size(); i++)
1854 PVMFStatus status = QueueOutgoingMsg(iPendingSdus[i]);
1855 if (status != PVMFSuccess)
1857 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));
1858 iObserver->LogicalChannelError(INCOMING, lcn, status);
1862 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::Connect lcn=%d,num sdus=%d", lcn, iPendingSdus.size()));
1863 iPendingSdus.clear();
1868 OsclAny H223IncomingChannel::SendFormatSpecificInfo()
1870 //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223IncomingChannel::SendFormatSpecificInfo lcn=%d, iFormatSpecificInfoLen=%d, iFormatSpecificInfo=%x", lcn,iFormatSpecificInfoLen,iFormatSpecificInfo));
1871 //printBuffer(iLogger, iFormatSpecificInfo, (uint16)iFormatSpecificInfoLen);
1874 //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"H223IncomingChannel::SendFormatSpecificInfo ERROR Not connected."));
1875 //OSCL_LEAVE(PVMFErrNotReady);
1879 // Create mem frag for VOL header
1880 // Create new media data buffer for header fragment
1881 OsclSharedPtr<PVMFMediaDataImpl> hdrImpl = iMediaDataAlloc.allocate(iFormatSpecificInfoLen);
1886 PVMFSharedMediaDataPtr hdrMediaData = PVMFMediaData::createMediaData(hdrImpl);
1887 OsclRefCounterMemFrag myVolHeader;
1888 hdrMediaData->getMediaFragment(0, myVolHeader);
1889 oscl_memcpy(myVolHeader.getMemFragPtr(), iFormatSpecificInfo, iFormatSpecificInfoLen);
1890 myVolHeader.getMemFrag().len = iFormatSpecificInfoLen;
1892 // Create new media data buffer for the message
1893 OsclSharedPtr<PVMFMediaDataImpl> emptyImpl = iMediaDataAlloc.allocate(0);
1898 PVMFSharedMediaDataPtr volData = PVMFMediaData::createMediaData(emptyImpl);
1900 // Set format specific info in media data message
1901 volData->setFormatSpecificInfo(myVolHeader);
1903 // Send VOL header to downstream node
1904 PVMFSharedMediaMsgPtr volMsg;
1905 convertToPVMFMediaMsg(volMsg, volData);
1906 PVMFStatus status = QueueOutgoingMsg(volMsg);
1907 if (status != PVMFSuccess)
1911 iSendFormatSpecificInfo = false;
1914 MuxSduData::MuxSduData()
1920 PVMFStatus H223IncomingChannel::NegotiateOutputSettings(PvmiCapabilityAndConfig* aConfig)
1922 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::NegotiateInputSettings, aConfig=%x", aConfig));
1924 PvmiKvp* kvp = NULL;
1928 // Get supported input formats from peer
1929 PVMFStatus status = aConfig->getParametersSync(NULL,
1930 OSCL_CONST_CAST(char*, INPUT_FORMATS_CAP_QUERY),
1931 kvp, numParams, NULL);
1933 if (status != PVMFSuccess)
1935 status = aConfig->getParametersSync(NULL,
1936 OSCL_CONST_CAST(char*, "x-pvmf/video/decode/input_formats"),
1937 kvp, numParams, NULL);
1940 if (status != PVMFSuccess || numParams == 0)
1942 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::NegotiateInputSettings, Error: getParametersSync failed. status=%d", status));
1947 PvmiKvp* selectedKvp = NULL;
1948 PVCodecType_t codec_type = GetCodecType(iDataType);
1949 PVMFFormatType lcn_format_type = PVCodecTypeToPVMFFormatType(codec_type);
1951 for (i = 0; i < numParams && !selectedKvp; i++)
1953 if (lcn_format_type == kvp[i].value.pChar_value)
1954 selectedKvp = &(kvp[i]);
1959 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::NegotiateInputSettings, Error: Input format not supported by peer"));
1963 /* This is for the silly problem of MIO components having the convention
1964 of returning uint32 for a query and requiring pChar for a setting
1965 we don't know if we are talking to an MIO or a decoder node
1966 (which will want a uint32), so we try both. Try the pchar
1967 first, because if its expecting pchar and gets uint32, it will
1970 if (PVMFSuccess != setConfigParametersSync(selectedKvp, aConfig, lcn_format_type, true))
1973 aConfig->releaseParameters(NULL, kvp, numParams);
1980 ////////////////////////////////////////////////////////////////////////////
1981 // PvmiCapabilityAndConfig
1982 ////////////////////////////////////////////////////////////////////////////
1983 OSCL_EXPORT_REF void H223IncomingChannel::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
1986 OSCL_UNUSED_ARG(aObserver);
1987 OSCL_LEAVE(OsclErrNotSupported);
1990 ////////////////////////////////////////////////////////////////////////////
1991 OSCL_EXPORT_REF PVMFStatus H223IncomingChannel::getParametersSync(PvmiMIOSession session,
1992 PvmiKeyType identifier,
1993 PvmiKvp*& parameters,
1994 int& num_parameter_elements,
1995 PvmiCapabilityContext context)
1997 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::getParametersSync"));
1998 OSCL_UNUSED_ARG(session);
1999 OSCL_UNUSED_ARG(context);
2002 num_parameter_elements = 0;
2004 if (pv_mime_strcmp(identifier, OUTPUT_FORMATS_CAP_QUERY) == 0)
2006 num_parameter_elements = 1;
2007 PVMFStatus status = AllocateKvp(iKvpMemAlloc, parameters,
2008 OSCL_CONST_CAST(char*, OUTPUT_FORMATS_VALTYPE),
2009 num_parameter_elements);
2010 if (status != PVMFSuccess)
2012 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::getParametersSync: Error - AllocateKvp failed. status=%d", status));
2015 PVCodecType_t codec_type = GetCodecType(iDataType);
2016 PVMFFormatType format = PVCodecTypeToPVMFFormatType(codec_type).getMIMEStrPtr();
2017 if (format == PVMF_MIME_AMR_IF2)
2018 parameters[0].value.pChar_value = (char*) PVMF_MIME_AMR_IF2;
2019 else if (format == PVMF_MIME_PCM16)
2020 parameters[0].value.pChar_value = (char*) PVMF_MIME_PCM16;
2021 else if (format == PVMF_MIME_YUV420)
2022 parameters[0].value.pChar_value = (char*) PVMF_MIME_YUV420;
2023 else if (format == PVMF_MIME_M4V)
2024 parameters[0].value.pChar_value = (char*) PVMF_MIME_M4V;
2025 else if (format == PVMF_MIME_H2632000)
2026 parameters[0].value.pChar_value = (char*) PVMF_MIME_H2632000;
2027 else if (format == PVMF_MIME_H2631998)
2028 parameters[0].value.pChar_value = (char*) PVMF_MIME_H2631998;
2030 parameters[0].value.pChar_value = (char*) PVMF_MIME_FORMAT_UNKNOWN;
2037 ////////////////////////////////////////////////////////////////////////////
2038 OSCL_EXPORT_REF PVMFStatus H223IncomingChannel::releaseParameters(PvmiMIOSession session,
2039 PvmiKvp* parameters,
2042 OSCL_UNUSED_ARG(session);
2043 OSCL_UNUSED_ARG(num_elements);
2047 iKvpMemAlloc.deallocate((OsclAny*)parameters);
2056 ////////////////////////////////////////////////////////////////////////////
2057 OSCL_EXPORT_REF void H223IncomingChannel::createContext(PvmiMIOSession session, PvmiCapabilityContext& context)
2059 OSCL_UNUSED_ARG(session);
2060 OSCL_UNUSED_ARG(context);
2063 ////////////////////////////////////////////////////////////////////////////
2064 OSCL_EXPORT_REF void H223IncomingChannel::setContextParameters(PvmiMIOSession session,
2065 PvmiCapabilityContext& context,
2066 PvmiKvp* parameters, int num_parameter_elements)
2068 OSCL_UNUSED_ARG(session);
2069 OSCL_UNUSED_ARG(context);
2070 OSCL_UNUSED_ARG(parameters);
2071 OSCL_UNUSED_ARG(num_parameter_elements);
2074 ////////////////////////////////////////////////////////////////////////////
2075 OSCL_EXPORT_REF void H223IncomingChannel::DeleteContext(PvmiMIOSession session, PvmiCapabilityContext& context)
2077 OSCL_UNUSED_ARG(session);
2078 OSCL_UNUSED_ARG(context);
2081 ////////////////////////////////////////////////////////////////////////////
2082 OSCL_EXPORT_REF void H223IncomingChannel::setParametersSync(PvmiMIOSession session, PvmiKvp* parameters,
2083 int num_elements, PvmiKvp*& ret_kvp)
2085 OSCL_UNUSED_ARG(session);
2086 PVMFStatus status = PVMFSuccess;
2089 for (int32 i = 0; i < num_elements; i++)
2091 status = VerifyAndSetParameter(&(parameters[i]), true);
2092 if (status != PVMFSuccess)
2094 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::setParametersSync: Error - VerifiyAndSetParameter failed on parameter #%d", i));
2095 ret_kvp = &(parameters[i]);
2096 /* Silently ignore unrecognized codecs untill CapEx is supported by peer */
2097 //OSCL_LEAVE(OsclErrArgument);
2102 PVMFStatus H223IncomingChannel::VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam)
2104 OSCL_UNUSED_ARG(aSetParam);
2105 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::VerifyAndSetParameter: aKvp=0x%x, aSetParam=%d", aKvp, aSetParam));
2109 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::VerifyAndSetParameter: Error - Invalid key-value pair"));
2113 if (iDataType == NULL)
2115 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::VerifyAndSetParameter: Error - DataType == NULL"));
2116 return PVMFErrNotSupported;
2119 if (pv_mime_strcmp(aKvp->key, OUTPUT_FORMATS_VALTYPE) == 0)
2121 PVCodecType_t codec_type = GetCodecType(iDataType);
2122 PVMFFormatType lcn_format_type = PVCodecTypeToPVMFFormatType(codec_type);
2123 if (lcn_format_type != aKvp->value.pChar_value)
2125 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::VerifyAndSetParameter: Error - Output format %s not supported", aKvp->value.pChar_value));
2126 return PVMFErrNotSupported;
2133 ////////////////////////////////////////////////////////////////////////////
2134 OSCL_EXPORT_REF PVMFCommandId H223IncomingChannel::setParametersAsync(PvmiMIOSession session,
2135 PvmiKvp* parameters,
2140 OSCL_UNUSED_ARG(session);
2141 OSCL_UNUSED_ARG(parameters);
2142 OSCL_UNUSED_ARG(num_elements);
2143 OSCL_UNUSED_ARG(ret_kvp);
2144 OSCL_UNUSED_ARG(context);
2148 ////////////////////////////////////////////////////////////////////////////
2149 OSCL_EXPORT_REF uint32 H223IncomingChannel::getCapabilityMetric(PvmiMIOSession session)
2151 OSCL_UNUSED_ARG(session);
2155 ////////////////////////////////////////////////////////////////////////////
2156 OSCL_EXPORT_REF PVMFStatus H223IncomingChannel::verifyParametersSync(PvmiMIOSession session,
2157 PvmiKvp* parameters, int num_elements)
2159 OSCL_UNUSED_ARG(session);
2161 PVMFStatus status = PVMFSuccess;
2162 for (int32 i = 0; (i < num_elements) && (status == PVMFSuccess); i++)
2163 status = VerifyAndSetParameter(&(parameters[i]), true);
2168 void H223IncomingChannel::HandlePortActivity(const PVMFPortActivity &aActivity)
2170 if (aActivity.iType != PVMF_PORT_ACTIVITY_OUTGOING_MSG &&
2171 aActivity.iType != PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY)
2173 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::HandlePortActivity Unhandled port activity: %d", aActivity.iType));
2177 PVMFSharedMediaMsgPtr aMsg;
2178 while (OutgoingMsgQueueSize())
2181 if (aStatus != PVMFSuccess)
2183 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "H223IncomingChannel::HandlePortActivity Failed to DeQueue incoming message: %d", aStatus));
2189 PVMFStatus H223IncomingChannel::SendBeginOfStreamMediaCommand()
2191 PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
2192 sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
2194 sharedMediaCmdPtr->setTimestamp(iCurTimestamp);
2197 uint32 streamID = 0;
2198 sharedMediaCmdPtr->setSeqNum(seqNum);
2200 PVMFSharedMediaMsgPtr mediaMsgOut;
2201 convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
2202 mediaMsgOut->setStreamID(streamID);
2204 PVMFStatus status = QueueOutgoingMsg(mediaMsgOut);
2205 if (status != PVMFSuccess)
2207 // Output queue is busy, so wait for the output queue being ready
2208 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING,
2209 (0, "H223IncomingChannel::SendBeginOfMediaStreamCommand: Outgoing queue busy. "));
2212 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "H223IncomingChannel::SendBeginOfMediaStreamCommand() BOS Sent StreamId %d ", streamID));
2216 void H223IncomingChannel::SetSampleTimestamps(PVMFTimestamp& aTSOffset)
2218 iRenderingSkew = iAudioLatency - iVideoLatency;
2219 uint32 skewDelta = 0;
2220 if (iRenderingSkew >= (int32)iIncomingSkew)
2222 skewDelta = iRenderingSkew - iIncomingSkew;
2223 if (iMediaType.isCompressed() && iMediaType.isAudio())
2225 aTSOffset = (PVMFTimestamp)(iAudioLatency);
2227 else if (iMediaType.isCompressed() && iMediaType.isVideo())
2229 aTSOffset = (PVMFTimestamp)(iVideoLatency + skewDelta + PARSING_JITTER_DURATION);
2232 else if (iRenderingSkew < (int32)iIncomingSkew)
2234 skewDelta = iIncomingSkew - iRenderingSkew;
2235 if (iMediaType.isCompressed() && iMediaType.isAudio())
2237 aTSOffset = (PVMFTimestamp)(iAudioLatency + skewDelta);
2239 else if (iMediaType.isCompressed() && iMediaType.isVideo())
2241 aTSOffset = (PVMFTimestamp)(iVideoLatency + PARSING_JITTER_DURATION);
2245 #ifdef LIP_SYNC_TESTING
2247 /**************************************************************************************************
2248 this is the check, to get unique sample TS on dummy output node side.So for this purpose, we are
2249 checking the original video TS with the previous TS.If this condition is true then only we are
2250 modifying the value of aTSOffset.
2252 ***************************************************************************************************/
2254 if ((g_CheckSampleTime != g_RecTimeStamp) && (iParam->iUncompressed == true))
2256 g_CheckSampleTime = g_RecTimeStamp;
2258 aTSOffset += g_Checkcount;
2263 aTSOffset += iCurTimestamp;
2266 /* *****************************************************************************************************
2267 * Function : DetectSkewInd()
2269 * Purpose : The purpose of this function is to calculate skew (difference b/w audio and video TS)
2270 * on stack outgoing side.Audio and Video both sending TS through observer and we are calculating
2271 actual skew in cpvh223multiplex.cpp. Function name CalculateSkew()
2276 * *************************************************************************************************/
2277 void H223OutgoingChannel::DetectSkewInd(PVMFSharedMediaMsgPtr aMsg)
2280 PVMFFormatType mediaType = GetFormatType();
2283 if (mediaType.isCompressed() && (mediaType.isAudio() || mediaType.isVideo()))
2285 if (mediaType.isCompressed() && mediaType.isAudio())
2287 audio = (uint32)aMsg->getTimestamp();
2288 iObserver->CalculateSkew(lcn, 0, audio, 0);
2291 else if (mediaType.isCompressed() && mediaType.isVideo())
2293 video = (uint32)aMsg->getTimestamp();
2294 iObserver->CalculateSkew(lcn, 1, video, 0);
2295 CalcRMSInfo(video, audio);
2300 /* *****************************************************************************************************
2301 * Function : CalcRMSInfo()
2303 * Purpose : The purpose of this function is to Calculate skew on stack outgoing side.In this function we are
2304 reciving the video and audio TS. The main thing is that we are calculting the skew, when we
2305 recieves the video TS with last Audio TS.This function is also for lip-sync calculation
2306 * INPUT : VideoData,AudioData
2310 * *************************************************************************************************/
2311 void H223OutgoingChannel::CalcRMSInfo(uint32 aVideoData, uint32 aAudioData)
2314 if (iOnlyOnce == false)
2317 uint32 tick_ct_val = OsclTickCount::TickCount();
2318 iTsmsec = OsclTickCount::TicksToMsec(tick_ct_val);
2322 int Diff = aVideoData - iTsmsec;
2325 /*End Of TIMER EOT=1*/
2327 iObserver->CalculateSkew(lcn, 0, 0, 1);
2335 #ifdef LIP_SYNC_TESTING
2337 /* *****************************************************************************************************
2338 * Function : CalculateRMSInfo()
2340 * Purpose : The purpose of this function is to Calculate skew on stack incoming side.In this function we are
2341 reciving the video and audio TS. The main thing is that we are calculting the skew, when we
2342 recieves the video TS with last Audio TS.
2343 * INPUT : VideoData,AudioData
2347 * *************************************************************************************************/
2348 void H223IncomingChannel::CalculateRMSInfo(uint32 aVideoData, uint32 aAudioData)
2350 g_DiffIncmVidAudTS = aVideoData - aAudioData;
2351 g_iSqrIncCalVidAudTS += (g_DiffIncmVidAudTS * g_DiffIncmVidAudTS);
2356 tick_ct_val = OsclTickCount::TickCount();
2357 g_Incmtsmsec = OsclTickCount::TicksToMsec(tick_ct_val);
2363 int Diff = aVideoData - g_Incmtsmsec;
2366 if (g_TotalCountIncm == 0)
2368 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2369 (0, "Not be able to calculate RMS because Total count value is zero TotalCount=%d", g_TotalCountIncm));
2374 g_IncRtMnSqCalc = (int32)sqrt(g_iSqrIncCalVidAudTS / g_TotalCountIncm);
2382 /* *****************************************************************************************************
2383 * Function : DetectFrameBoundary()
2385 * Purpose : The purpose of this function is to Detect frame boundary that whether the format is MPEG-4 or H263,
2386 In this function we are sending original VideoTS to dummy output MIO node through observer.
2387 The reason is we dont want to pass the same to specific decoder, as decoder will modify the TS.
2388 This is we are doing for calculating lip-sync skew.
2390 * INPUT : buf,aTimestamp
2394 * *************************************************************************************************/
2395 void H223IncomingChannel::DetectFrameBoundary(uint8* aBuf, uint32 aTimestamp)
2397 PVMFFormatType mediaType = GetFormatType();
2399 /********************This is for MPEG-4 Header and H263 Header***********************************/
2400 if ((mediaType.isCompressed() && (mediaType.isAudio() || mediaType.isVideo())))
2403 if (mediaType.isCompressed() && mediaType.isAudio())
2405 g_IncmAudioTS = *(((uint32*)aBuf));
2409 if (mediaType.isCompressed() && mediaType.isVideo())
2411 /*This check is for VOL header*/
2412 if ((aBuf[0] == VOP_START_BYTE_1) &&
2413 (aBuf[1] == VOP_START_BYTE_2) &&
2414 (aBuf[2] == VOP_START_BYTE_3) &&
2415 (aBuf[3] == VOP_START_BYTE_5))
2418 g_IncmVideoTS = g_RecTimeStamp;
2419 CalculateRMSInfo(g_IncmVideoTS, g_IncmAudioTS);
2420 iParam->iObserver->MIOFramesTimeStamps(0, g_RecTimeStamp, aTimestamp);
2423 /*This Check is for MP4 Header*/
2424 else if ((aBuf[0] == VOP_START_BYTE_1) &&
2425 (aBuf[1] == VOP_START_BYTE_2) &&
2426 (aBuf[2] == VOP_START_BYTE_3) &&
2427 (aBuf[3] == VOP_START_BYTE_4))
2430 g_IncmVideoTS = g_RecTimeStamp;
2431 CalculateRMSInfo(g_IncmVideoTS, g_IncmAudioTS);
2432 iParam->iObserver->MIOFramesTimeStamps(0, g_RecTimeStamp, aTimestamp);
2437 /*This check is for H263 Header*/
2438 else if ((aBuf[0] == H263_START_BYTE_1) &&
2439 (aBuf[1] == H263_START_BYTE_2) &&
2440 (aBuf[2] == H263_START_BYTE_3))
2443 g_IncmVideoTS = *(((uint32*)aBuf) + 1);
2444 CalculateRMSInfo(g_IncmVideoTS, g_IncmAudioTS);
2455 /* *****************************************************************************************************
2456 * Function : ExtractTimestamp()
2458 * Purpose : The purpose of this function is to extract original TS on stack incoming side.So for each SDU's
2459 we are extracting original video TS.This also we are doing for uncompressed video.Later we will
2460 add the same functionality for uncompressed audio only.This functionality is also for lip-sync
2466 * *************************************************************************************************/
2467 void H223IncomingChannel::ExtractTimestamp()
2469 PVMFFormatType mediaType = GetFormatType();
2472 if (mediaType.isCompressed() && mediaType.isVideo())
2474 OsclRefCounterMemFrag MemFrag;
2475 OsclRefCounterMemFrag tsFrag;
2476 OsclRefCounterMemFrag frag;
2477 uint32 FragSize = 0;
2478 uint8* CheckTSbuff = 0;
2479 for (uint32 i = 0; i < iAlPduMediaData->getNumFragments(); i++)
2481 iAlPduMediaData->getMediaFragment(i, frag);
2482 uint8* buf = (uint8*)frag.getMemFragPtr();
2483 FragSize = frag.getMemFragSize();
2484 CheckTSbuff = (uint8*)(buf + FragSize);
2486 uint8* TimeStamp = (uint8*)(CheckTSbuff - 4);
2487 g_RecTimeStamp = (uint32)(*((uint32*)TimeStamp));
2488 iAlPduMediaData->getMediaFragment(0, tsFrag);
2489 iAlPduMediaData->setMediaFragFilledLen(iAlPduMediaData->getNumFragments() - 1, FragSize - 4);
2497 /* ***********************************************************************************
2498 * Function : AppendLipSyncTS()
2500 * Purpose : The purpose of this function is to append four bytes(Video TS)
2501 * on every sdu's.Here we are doing for Video only.this is
2502 * we are doing for to get original Video TS at stack incoming side.
2508 * **********************************************************************************/
2509 void H223OutgoingChannel::AppendLipSyncTS()
2513 if (iMediaType.isCompressed() && iMediaType.isVideo())
2515 PVMFSharedMediaDataPtr hdrTSData;
2516 OsclRefCounterMemFrag tsFrag;
2517 OsclSharedPtr<PVMFMediaDataImpl> addTsImpl = iMediaDataAlloc.allocate(4);
2518 hdrTSData = PVMFMediaData::createMediaData(addTsImpl);
2520 hdrTSData->getMediaFragment(0, tsFrag);
2521 tsFrag.getMemFrag().len = 4;
2522 uint32* SendBuff = (uint32*) tsFrag.getMemFragPtr();
2523 SendBuff[0] = iCurPduTimestamp;
2524 iCurPdu->appendMediaFragment(tsFrag);