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 #ifndef OSCL_MIME_STRING_UTILS_H_INCLUDED
19 #include "pv_mime_string_utils.h"
20 #endif
21 #ifndef OSCL_STRING_UTILS_H_INCLUDED
22 #include "oscl_string_utils.h"
23 #endif
24 #ifndef OSCL_ASSERT_H_INCLUDED
25 #include "oscl_assert.h"
26 #endif
27 #ifndef OSCL_DLL_H_INCLUDED
28 #include "oscl_dll.h"
29 #endif
30 #ifndef PVMF_MEDIA_CMD_H_INCLUDED
31 #include "pvmf_media_cmd.h"
32 #endif
33 #ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
34 #include "pvmf_media_msg_format_ids.h"
35 #endif
36 #ifndef PVMF_BASIC_ERRORINFOMESSAGE_H_INCLUDED
37 #include "pvmf_basic_errorinfomessage.h"
38 #endif
39 #ifndef PVMF_ERRORINFOMESSAGE_EXTENSION_H_INCLUDED
40 #include "pvmf_errorinfomessage_extension.h"
41 #endif
42 #ifndef MEDIAINFO_H_INCLUDED
43 #include "media_info.h"
44 #endif
45 #ifndef PVMF_SM_TUNABLES_H_INCLUDED
46 #include "pvmf_sm_tunables.h"
47 #endif
48 #ifndef PVMF_MEDIALAYER_NODE_H_INCLUDED
49 #include "pvmf_medialayer_node.h"
50 #endif
51 #ifndef PVMF_MEDIA_MSG_HEADER_H_INCLUDED
52 #include "pvmf_media_msg_header.h"
53 #endif
54 #ifndef PVMF_SM_CONFIG_H_INCLUDED
55 #include "pvmf_sm_config.h"
56 #endif
57
58 #define RETURN_ERROR_WHEN_MINUS_TIMESTAMP
59 // Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()60 OSCL_DLL_ENTRY_POINT_DEFAULT()
61
62 /**
63 * Node Constructor & Destructor
64 */
65 OSCL_EXPORT_REF PVMFMediaLayerNode::PVMFMediaLayerNode(int32 aPriority)
66 : OsclActiveObject(aPriority, "PVMFMediaLayerNode")
67 {
68 iLogger = NULL;
69 iDataPathLogger = NULL;
70 iDataPathLoggerFlowCtrl = NULL;
71 iClockLogger = NULL;
72 iOsclErrorTrapImp = NULL;
73 iExtensionInterface = NULL;
74 iPayLoadParserRegistry = NULL;
75 oPortDataLog = false;
76 iLogFileIndex = '0';
77 iClientPlayBackClock = NULL;
78 iDecryptionInterface = NULL;
79 srcPtr = NULL;
80 diffAudioVideoTS = 0;
81 iAdjustTimeReady = false;
82 oEOSsendunits = false;
83 iTimerNoDataTrack = 10 * 1000;
84 iReposTime = 0;
85 preroll64 = 0;
86 iStreamID = 0;
87 iExtensionInterface = NULL;
88 iNumRunL = 0;
89 iDiagnosticsLogged = false;
90
91 int32 err;
92 OSCL_TRY(err,
93 /*
94 * Create the input command queue.Use a reserve to avoid lots of
95 * dynamic memory allocation.
96 */
97 iInputCommands.Construct(MEDIA_LAYER_NODE_CMD_START,
98 MEDIA_LAYER_NODE_CMD_QUE_RESERVE);
99
100 /*
101 * Create the "current command" queue. It will only contain one
102 * command at a time, so use a reserve of 1.
103 */
104 iCurrentCommand.Construct(0, 1);
105
106 /* Create the port vector */
107 iPortVector.Construct(MEDIA_LAYER_NODE_VECTOR_RESERVE);
108
109 /*
110 * Set the node capability data.
111 * This node can support an unlimited number of ports.
112 */
113 iCapability.iCanSupportMultipleInputPorts = true;
114 iCapability.iCanSupportMultipleOutputPorts = true;
115 iCapability.iHasMaxNumberOfPorts = false;
116 iCapability.iMaxNumberOfPorts = 0; /* no maximum */
117
118 iCapability.iInputFormatCapability.push_back(PVMF_MIME_RTP);
119 iCapability.iOutputFormatCapability.push_back(PVMF_MIME_M4V);
120 iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
121
122 );
123
124
125
126 if (err != OsclErrNone)
127 {
128 //if a leave happened, cleanup and re-throw the error
129 iInputCommands.clear();
130 iCurrentCommand.clear();
131 iPortVector.clear();
132 iCapability.iInputFormatCapability.clear();
133 iCapability.iOutputFormatCapability.clear();
134 OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
135 OSCL_CLEANUP_BASE_CLASS(OsclActiveObject);
136 OSCL_LEAVE(err);
137 }
138 }
139
~PVMFMediaLayerNode()140 OSCL_EXPORT_REF PVMFMediaLayerNode::~PVMFMediaLayerNode()
141 {
142 LogSessionDiagnostics();
143
144 Cancel();
145 if (iExtensionInterface)
146 {
147 iExtensionInterface->removeRef();
148 }
149
150 /* delete related decryption */
151 iDecryptionInterface = NULL;
152 if (srcPtr != NULL)
153 oscl_free((uint8*)srcPtr);
154 srcPtr = NULL;
155
156 /* thread logoff */
157 if (IsAdded())
158 RemoveFromScheduler();
159
160 /*
161 * Cleanup allocated ports
162 * The port vector is self-deleting, but we want to notify
163 * observers that ports are being deleted
164 */
165 while (!iPortVector.empty())
166 {
167 /* delete corresponding port params */
168 Oscl_Vector<PVMFMediaLayerPortContainer, PVMFMediaLayerNodeAllocator>::iterator it;
169
170 for (it = iPortParamsQueue.begin();
171 it != iPortParamsQueue.end();
172 it++)
173 {
174 if (it->iPort == iPortVector.front())
175 {
176 if (it->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT)
177 {
178 DestroyPayLoadParser(&(it->iMimeType), it->iPayLoadParser);
179 if (oPortDataLog)
180 {
181 if (it->iBinAppenderPtr.GetRep() != NULL)
182 {
183 it->iPortLogger->RemoveAppender(it->iBinAppenderPtr);
184 it->iBinAppenderPtr.Unbind();
185 }
186 }
187 }
188 if (it->ipFragGroupAllocator != NULL)
189 {
190 it->ipFragGroupAllocator->CancelFreeChunkAvailableCallback();
191 it->ipFragGroupAllocator->removeRef();
192 }
193 if (it->ipFragGroupMemPool != NULL)
194 {
195 it->ipFragGroupMemPool->removeRef();
196 }
197 it->CleanUp();
198 iPortParamsQueue.erase(it);
199 break;
200 }
201 }
202 iPortVector.Erase(&iPortVector.front());
203 }
204
205 /*
206 * Cleanup commands
207 * The command queues are self-deleting, but we want to
208 * notify the observer of unprocessed commands.
209 */
210 while (!iCurrentCommand.empty())
211 {
212 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
213 }
214 while (!iInputCommands.empty())
215 {
216 CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
217 }
218 }
219
220 /**
221 * Public Node API implementation
222 */
223
224 /**
225 * Do thread-specific node creation and go to "Idle" state.
226 */
ThreadLogon()227 OSCL_EXPORT_REF PVMFStatus PVMFMediaLayerNode::ThreadLogon()
228 {
229 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:ThreadLogon"));
230 PVMFStatus status;
231 switch (iInterfaceState)
232 {
233 case EPVMFNodeCreated:
234 {
235 if (!IsAdded())
236 AddToScheduler();
237 iLogger = PVLogger::GetLoggerObject("PVMFMediaLayerNode");
238 iRunlLogger = PVLogger::GetLoggerObject("Run.PVMFMediaLayerNode");
239 iDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode.medialayer");
240 iDataPathLoggerIn = PVLogger::GetLoggerObject("datapath.sourcenode.medialayer.in");
241 iDataPathLoggerOut = PVLogger::GetLoggerObject("datapath.sourcenode.medialayer.out");
242 iDataPathLoggerFlowCtrl = PVLogger::GetLoggerObject("datapath.sourcenode.medialayer.portflowcontrol");
243 if (iDataPathLoggerFlowCtrl != NULL)
244 {
245 iDataPathLoggerFlowCtrl->DisableAppenderInheritance();
246 }
247 iClockLogger = PVLogger::GetLoggerObject("clock");
248 iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.streamingmanager.medialayer");
249 iDiagnosticsLogged = false;
250 iReposLogger = PVLogger::GetLoggerObject("pvplayerrepos.sourcenode.streamingmanager.medialayer");
251 iOsclErrorTrapImp = OsclErrorTrap::GetErrorTrapImp();
252 SetState(EPVMFNodeIdle);
253 status = PVMFSuccess;
254 }
255 break;
256 default:
257 status = PVMFErrInvalidState;
258 break;
259 }
260 return status;
261 }
262
263 /**
264 * Do thread-specific node cleanup and go to "Created" state.
265 */
ThreadLogoff()266 OSCL_EXPORT_REF PVMFStatus PVMFMediaLayerNode::ThreadLogoff()
267 {
268 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:ThreadLogoff"));
269 PVMFStatus status;
270 switch (iInterfaceState)
271 {
272 case EPVMFNodeIdle:
273 {
274 if (IsAdded())
275 {
276 RemoveFromScheduler();
277 }
278 iLogger = NULL;
279 iDataPathLogger = NULL;
280 iDataPathLoggerFlowCtrl = NULL;
281 iClockLogger = NULL;
282 iDiagnosticsLogger = NULL;
283 iOsclErrorTrapImp = NULL;
284 SetState(EPVMFNodeCreated);
285 status = PVMFSuccess;
286 }
287 break;
288
289 default:
290 status = PVMFErrInvalidState;
291 break;
292 }
293 return status;
294 }
295
296 /**
297 * retrieve node capabilities.
298 */
299 OSCL_EXPORT_REF
GetCapability(PVMFNodeCapability & aNodeCapability)300 PVMFStatus PVMFMediaLayerNode::GetCapability(PVMFNodeCapability& aNodeCapability)
301 {
302 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:GetCapability"));
303 aNodeCapability = iCapability;
304 return PVMFSuccess;
305 }
306
307 /**
308 * retrieve a port iterator.
309 */
310 OSCL_EXPORT_REF
GetPorts(const PVMFPortFilter * aFilter)311 PVMFPortIter* PVMFMediaLayerNode::GetPorts(const PVMFPortFilter* aFilter)
312 {
313 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:GetPorts"));
314 OSCL_UNUSED_ARG(aFilter);//port filter is not implemented.
315 iPortVector.Reset();
316 return &iPortVector;
317 }
318
319 /**
320 * Queue an asynchronous node command
321 */
322 OSCL_EXPORT_REF
QueryUUID(PVMFSessionId s,const PvmfMimeString & aMimeType,Oscl_Vector<PVUuid,OsclMemAllocator> & aUuids,bool aExactUuidsOnly,const OsclAny * aContext)323 PVMFCommandId PVMFMediaLayerNode::QueryUUID(PVMFSessionId s,
324 const PvmfMimeString& aMimeType,
325 Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
326 bool aExactUuidsOnly,
327 const OsclAny* aContext)
328 {
329 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:QueryUUID"));
330 PVMFMediaLayerNodeCommand cmd;
331 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
332 PVMF_MEDIA_LAYER_NODE_QUERYUUID,
333 aMimeType,
334 aUuids,
335 aExactUuidsOnly,
336 aContext);
337 return QueueCommandL(cmd);
338 }
339
340 /**
341 * Queue an asynchronous node command
342 */
343 OSCL_EXPORT_REF
QueryInterface(PVMFSessionId s,const PVUuid & aUuid,PVInterface * & aInterfacePtr,const OsclAny * aContext)344 PVMFCommandId PVMFMediaLayerNode::QueryInterface(PVMFSessionId s,
345 const PVUuid& aUuid,
346 PVInterface*& aInterfacePtr,
347 const OsclAny* aContext)
348 {
349 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:QueryInterface"));
350 PVMFMediaLayerNodeCommand cmd;
351 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
352 PVMF_MEDIA_LAYER_NODE_QUERYINTERFACE,
353 aUuid,
354 aInterfacePtr,
355 aContext);
356 return QueueCommandL(cmd);
357 }
358
359 /**
360 * Queue an asynchronous node command
361 */
362 OSCL_EXPORT_REF
RequestPort(PVMFSessionId aSession,int32 aPortTag,const PvmfMimeString * aPortConfig,const OsclAny * aContext)363 PVMFCommandId PVMFMediaLayerNode::RequestPort(PVMFSessionId aSession,
364 int32 aPortTag,
365 const PvmfMimeString* aPortConfig,
366 const OsclAny* aContext)
367 {
368 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:RequestPort"));
369 PVMFMediaLayerNodeCommand cmd;
370 cmd.PVMFMediaLayerNodeCommandBase::Construct(aSession,
371 PVMF_MEDIA_LAYER_NODE_REQUESTPORT,
372 aPortTag,
373 aPortConfig,
374 aContext);
375 return QueueCommandL(cmd);
376 }
377
378 /**
379 * Queue an asynchronous node command
380 */
381 OSCL_EXPORT_REF
ReleasePort(PVMFSessionId s,PVMFPortInterface & aPort,const OsclAny * aContext)382 PVMFCommandId PVMFMediaLayerNode::ReleasePort(PVMFSessionId s,
383 PVMFPortInterface& aPort,
384 const OsclAny* aContext)
385 {
386 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:ReleasePort"));
387 PVMFMediaLayerNodeCommand cmd;
388 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
389 PVMF_MEDIA_LAYER_NODE_RELEASEPORT,
390 aPort,
391 aContext);
392 return QueueCommandL(cmd);
393 }
394
395 /**
396 * Queue an asynchronous node command
397 */
398 OSCL_EXPORT_REF
Init(PVMFSessionId s,const OsclAny * aContext)399 PVMFCommandId PVMFMediaLayerNode::Init(PVMFSessionId s,
400 const OsclAny* aContext)
401 {
402 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:Init"));
403 PVMFMediaLayerNodeCommand cmd;
404 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
405 PVMF_MEDIA_LAYER_NODE_INIT,
406 aContext);
407 return QueueCommandL(cmd);
408 }
409
410 /**
411 * Queue an asynchronous node command
412 */
413 OSCL_EXPORT_REF
Prepare(PVMFSessionId s,const OsclAny * aContext)414 PVMFCommandId PVMFMediaLayerNode::Prepare(PVMFSessionId s,
415 const OsclAny* aContext)
416 {
417 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:Prepare"));
418 PVMFMediaLayerNodeCommand cmd;
419 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
420 PVMF_MEDIA_LAYER_NODE_PREPARE,
421 aContext);
422 return QueueCommandL(cmd);
423 }
424
425 /**
426 * Queue an asynchronous node command
427 */
428 OSCL_EXPORT_REF
Start(PVMFSessionId s,const OsclAny * aContext)429 PVMFCommandId PVMFMediaLayerNode::Start(PVMFSessionId s,
430 const OsclAny* aContext)
431 {
432 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:Start"));
433 PVMFMediaLayerNodeCommand cmd;
434 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
435 PVMF_MEDIA_LAYER_NODE_START,
436 aContext);
437 return QueueCommandL(cmd);
438 }
439
440 /**
441 * Queue an asynchronous node command
442 */
443 OSCL_EXPORT_REF
Stop(PVMFSessionId s,const OsclAny * aContext)444 PVMFCommandId PVMFMediaLayerNode::Stop(PVMFSessionId s,
445 const OsclAny* aContext)
446 {
447 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:Stop"));
448 PVMFMediaLayerNodeCommand cmd;
449 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
450 PVMF_MEDIA_LAYER_NODE_STOP,
451 aContext);
452 return QueueCommandL(cmd);
453 }
454
455 /**
456 * Queue an asynchronous node command
457 */
458 OSCL_EXPORT_REF
Flush(PVMFSessionId s,const OsclAny * aContext)459 PVMFCommandId PVMFMediaLayerNode::Flush(PVMFSessionId s,
460 const OsclAny* aContext)
461 {
462 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:Flush"));
463 PVMFMediaLayerNodeCommand cmd;
464 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
465 PVMF_MEDIA_LAYER_NODE_FLUSH,
466 aContext);
467 return QueueCommandL(cmd);
468 }
469
470 /**
471 * Queue an asynchronous node command
472 */
473 OSCL_EXPORT_REF
Pause(PVMFSessionId s,const OsclAny * aContext)474 PVMFCommandId PVMFMediaLayerNode::Pause(PVMFSessionId s,
475 const OsclAny* aContext)
476 {
477 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:Pause"));
478 PVMFMediaLayerNodeCommand cmd;
479 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
480 PVMF_MEDIA_LAYER_NODE_PAUSE,
481 aContext);
482 return QueueCommandL(cmd);
483 }
484
485 /**
486 * Queue an asynchronous node command
487 */
488 OSCL_EXPORT_REF
Reset(PVMFSessionId s,const OsclAny * aContext)489 PVMFCommandId PVMFMediaLayerNode::Reset(PVMFSessionId s,
490 const OsclAny* aContext)
491 {
492 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:Reset"));
493 PVMFMediaLayerNodeCommand cmd;
494 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
495 PVMF_MEDIA_LAYER_NODE_RESET,
496 aContext);
497 return QueueCommandL(cmd);
498 }
499
500 /**
501 * Queue an asynchronous node command
502 */
503 OSCL_EXPORT_REF
CancelAllCommands(PVMFSessionId s,const OsclAny * aContext)504 PVMFCommandId PVMFMediaLayerNode::CancelAllCommands(PVMFSessionId s,
505 const OsclAny* aContext)
506 {
507 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:CancelAllCommands"));
508 PVMFMediaLayerNodeCommand cmd;
509 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
510 PVMF_MEDIA_LAYER_NODE_CANCELALLCOMMANDS,
511 aContext);
512 return QueueCommandL(cmd);
513 }
514
515 /**
516 * Queue an asynchronous node command
517 */
518 OSCL_EXPORT_REF
CancelCommand(PVMFSessionId s,PVMFCommandId aCmdId,const OsclAny * aContext)519 PVMFCommandId PVMFMediaLayerNode::CancelCommand(PVMFSessionId s,
520 PVMFCommandId aCmdId,
521 const OsclAny* aContext)
522 {
523 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:CancelCommand"));
524 PVMFMediaLayerNodeCommand cmd;
525 cmd.PVMFMediaLayerNodeCommandBase::Construct(s,
526 PVMF_MEDIA_LAYER_NODE_CANCELCOMMAND,
527 aCmdId,
528 aContext);
529 return QueueCommandL(cmd);
530 }
531
532
533 /**
534 * This routine is called by various command APIs to queue an
535 * asynchronous command for processing by the command handler AO.
536 * This function may leave if the command can't be queued due to
537 * memory allocation failure.
538 */
QueueCommandL(PVMFMediaLayerNodeCommand & aCmd)539 PVMFCommandId PVMFMediaLayerNode::QueueCommandL(PVMFMediaLayerNodeCommand& aCmd)
540 {
541 PVMFCommandId id;
542 id = iInputCommands.AddL(aCmd);
543 if (IsAdded())
544 {
545 //wakeup the AO
546 RunIfNotReady();
547 }
548 return id;
549 }
550
551 void
MoveCmdToCurrentQueue(PVMFMediaLayerNodeCommand & aCmd)552 PVMFMediaLayerNode::MoveCmdToCurrentQueue(PVMFMediaLayerNodeCommand& aCmd)
553 {
554 int32 err;
555 OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
556 if (err != OsclErrNone)
557 {
558 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
559 return;
560 }
561 iInputCommands.Erase(&aCmd);
562 return;
563 }
564
565 /**
566 * Asynchronous Command processing routines.
567 * These routines are all called under the AO.
568 */
569
570 /**
571 * Called by the command handler AO to process a command from
572 * the input queue.
573 * Return true if a command was processed, false if the command
574 * processor is busy and can't process another command now.
575 */
ProcessCommand(PVMFMediaLayerNodeCommand & aCmd)576 bool PVMFMediaLayerNode::ProcessCommand(PVMFMediaLayerNodeCommand& aCmd)
577 {
578 /*
579 * normally this node will not start processing one command
580 * until the prior one is finished. However, a hi priority
581 * command such as Cancel must be able to interrupt a command
582 * in progress.
583 */
584 if (!iCurrentCommand.empty() && !aCmd.hipri())
585 return false;
586
587 switch (aCmd.iCmd)
588 {
589 case PVMF_MEDIA_LAYER_NODE_QUERYUUID:
590 DoQueryUuid(aCmd);
591 break;
592
593 case PVMF_MEDIA_LAYER_NODE_QUERYINTERFACE:
594 DoQueryInterface(aCmd);
595 break;
596
597 case PVMF_MEDIA_LAYER_NODE_REQUESTPORT:
598 DoRequestPort(aCmd);
599 break;
600
601 case PVMF_MEDIA_LAYER_NODE_RELEASEPORT:
602 DoReleasePort(aCmd);
603 break;
604
605 case PVMF_MEDIA_LAYER_NODE_INIT:
606 DoInit(aCmd);
607 break;
608
609 case PVMF_MEDIA_LAYER_NODE_PREPARE:
610 DoPrepare(aCmd);
611 break;
612
613 case PVMF_MEDIA_LAYER_NODE_START:
614 DoStart(aCmd);
615 break;
616
617 case PVMF_MEDIA_LAYER_NODE_STOP:
618 DoStop(aCmd);
619 break;
620
621 case PVMF_MEDIA_LAYER_NODE_FLUSH:
622 DoFlush(aCmd);
623 break;
624
625 case PVMF_MEDIA_LAYER_NODE_PAUSE:
626 DoPause(aCmd);
627 break;
628
629 case PVMF_MEDIA_LAYER_NODE_RESET:
630 DoReset(aCmd);
631 break;
632
633 case PVMF_MEDIA_LAYER_NODE_CANCELALLCOMMANDS:
634 DoCancelAllCommands(aCmd);
635 break;
636
637 case PVMF_MEDIA_LAYER_NODE_CANCELCOMMAND:
638 DoCancelCommand(aCmd);
639 break;
640
641 default:
642 {
643 /* unknown command type */
644 CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
645 }
646 break;
647 }
648
649 return true;
650 }
651
652 /**
653 * The various command handlers call this when a command is complete.
654 */
CommandComplete(MediaLayerNodeCmdQ & aCmdQ,PVMFMediaLayerNodeCommand & aCmd,PVMFStatus aStatus,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)655 void PVMFMediaLayerNode::CommandComplete(MediaLayerNodeCmdQ& aCmdQ,
656 PVMFMediaLayerNodeCommand& aCmd,
657 PVMFStatus aStatus,
658 OsclAny* aEventData,
659 PVUuid* aEventUUID,
660 int32* aEventCode)
661 {
662 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
663 , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
664
665 PVInterface* extif = NULL;
666 PVMFBasicErrorInfoMessage* errormsg = NULL;
667 if (aEventUUID && aEventCode)
668 {
669 PVMF_MEDIA_LAYER_NEW(NULL, PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL), errormsg);
670 extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
671 }
672
673 /* create response */
674 PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
675 PVMFSessionId session = aCmd.iSession;
676
677 /* Erase the command from the queue. */
678 aCmdQ.Erase(&aCmd);
679
680 /* Report completion to the session observer */
681 ReportCmdCompleteEvent(session, resp);
682
683 if (errormsg)
684 {
685 errormsg->removeRef();
686 }
687 /*
688 * Transition to error state in case of select errors only, viz.
689 * PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
690 * Any other status implies that the node is probably in a recoverable
691 * state
692 */
693 if ((aStatus == PVMFFailure) ||
694 (aStatus == PVMFErrNoMemory) ||
695 (aStatus == PVMFErrNoResources))
696 {
697 SetState(EPVMFNodeError);
698 }
699 }
700
701 /**
702 * Called by the command handler AO to do the node Reset.
703 */
DoReset(PVMFMediaLayerNodeCommand & aCmd)704 void PVMFMediaLayerNode::DoReset(PVMFMediaLayerNodeCommand& aCmd)
705 {
706 LogSessionDiagnostics();
707
708 switch (iInterfaceState)
709 {
710 case EPVMFNodeStarted:
711 case EPVMFNodePaused:
712 {
713 /* Clear queued messages in ports */
714 uint32 i;
715 for (i = 0; i < iPortVector.size(); i++)
716 {
717 iPortVector[i]->ClearMsgQueues();
718 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
719 GetPortContainer(iPortVector[i], portContainerPtr);
720 if (portContainerPtr)
721 portContainerPtr->ResetParams();
722 }
723 }
724 /* Intentional fall thru */
725 case EPVMFNodeCreated:
726 case EPVMFNodeIdle:
727 case EPVMFNodeInitialized:
728 case EPVMFNodePrepared:
729 case EPVMFNodeError:
730 {
731 /* delete related decryption */
732 iDecryptionInterface = NULL;
733 if (srcPtr != NULL)
734 oscl_free((uint8*)srcPtr);
735 srcPtr = NULL;
736
737 Oscl_Vector<PVMFMediaLayerPortContainer, PVMFMediaLayerNodeAllocator>::iterator it;
738 for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
739 {
740 if (it->ipFragGroupAllocator != NULL)
741 it->ipFragGroupAllocator->CancelFreeChunkAvailableCallback();
742 }
743
744 /* delete all ports and notify observer */
745 while (!iPortVector.empty())
746 {
747 iPortVector.Erase(&iPortVector.front());
748 }
749
750 /* delete port params */
751 while (!iPortParamsQueue.empty())
752 {
753 it = iPortParamsQueue.begin();
754 if (it->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT)
755 {
756 DestroyPayLoadParser(&(it->iMimeType), it->iPayLoadParser);
757 if (oPortDataLog)
758 {
759 if (it->iBinAppenderPtr.GetRep() != NULL)
760 {
761 it->iPortLogger->RemoveAppender(it->iBinAppenderPtr);
762 it->iBinAppenderPtr.Unbind();
763 }
764 }
765 }
766 if (it->ipFragGroupAllocator != NULL)
767 {
768 it->ipFragGroupAllocator->CancelFreeChunkAvailableCallback();
769 it->ipFragGroupAllocator->removeRef();
770 }
771 if (it->ipFragGroupMemPool != NULL)
772 {
773 it->ipFragGroupMemPool->removeRef();
774 }
775 it->CleanUp();
776 iPortParamsQueue.erase(it);
777 }
778 /* restore original port vector reserve */
779 iPortVector.Reconstruct();
780
781 SetState(EPVMFNodeIdle);
782 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
783 }
784 break;
785
786 default:
787 CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
788 break;
789 }
790 }
791
792 /**
793 * Called by the command handler AO to do the Query UUID
794 */
DoQueryUuid(PVMFMediaLayerNodeCommand & aCmd)795 void PVMFMediaLayerNode::DoQueryUuid(PVMFMediaLayerNodeCommand& aCmd)
796 {
797 /* This node supports Query UUID from any state */
798 OSCL_String* mimetype;
799 Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
800 bool exactmatch;
801 aCmd.PVMFMediaLayerNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
802
803 /*
804 * Try to match the input mimetype against any of
805 * the custom interfaces for this node
806 */
807
808 /*
809 * Match against custom interface1...
810 * also match against base mimetypes for custom interface1,
811 * unless exactmatch is set.
812 */
813 if (*mimetype == PVMF_MEDIALAYER_CUSTOMINTERFACE_MIMETYPE
814 || (!exactmatch && *mimetype == PVMF_MEDIALAYER_MIMETYPE)
815 || (!exactmatch && *mimetype == PVMF_MEDIALAYER_BASEMIMETYPE))
816 {
817 PVUuid uuid(PVMF_MEDIALAYERNODE_EXTENSIONINTERFACE_UUID);
818 uuidvec->push_back(uuid);
819 }
820 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
821 }
822
823 /**
824 * Called by the command handler AO to do the Query Interface.
825 */
DoQueryInterface(PVMFMediaLayerNodeCommand & aCmd)826 void PVMFMediaLayerNode::DoQueryInterface(PVMFMediaLayerNodeCommand& aCmd)
827 {
828 /* This node supports Query Interface from any state */
829 PVUuid* uuid;
830 PVInterface** ptr;
831 aCmd.PVMFMediaLayerNodeCommandBase::Parse(uuid, ptr);
832
833 if (*uuid == PVUuid(PVMF_MEDIALAYERNODE_EXTENSIONINTERFACE_UUID))
834 {
835 if (!iExtensionInterface)
836 {
837 PVMFMediaLayerNodeAllocator alloc;
838 int32 err;
839 OsclAny*ptr = NULL;
840 OSCL_TRY(err,
841 ptr = alloc.ALLOCATE(sizeof(PVMFMediaLayerNodeExtensionInterfaceImpl));
842 );
843 if (err != OsclErrNone || !ptr)
844 {
845 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
846 return;
847 }
848 iExtensionInterface =
849 OSCL_PLACEMENT_NEW(ptr, PVMFMediaLayerNodeExtensionInterfaceImpl(this));
850 }
851
852 if (iExtensionInterface->queryInterface(*uuid, *ptr))
853 {
854 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
855 }
856 else
857 {
858 CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
859 }
860 }
861 else
862 {
863 //not supported
864 *ptr = NULL;
865 CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
866 }
867 }
868
869 /**
870 * Called by the command handler AO to do the port request
871 */
DoRequestPort(PVMFMediaLayerNodeCommand & aCmd)872 void PVMFMediaLayerNode::DoRequestPort(PVMFMediaLayerNodeCommand& aCmd)
873 {
874 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::DoRequestPort"));
875
876 /* retrieve port tag and mime string */
877 int32 tag;
878 OSCL_String* portConfig;
879 aCmd.PVMFMediaLayerNodeCommandBase::Parse(tag, portConfig);
880
881 /* Allocate a new port */
882 OsclAny *ptr = NULL;
883 bool retVal;
884
885 retVal = Allocate(ptr);
886
887 if (retVal == false || !ptr)
888 {
889 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::DoRequestPort: Error - iPortVector Out of memory"));
890 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
891 return;
892 }
893
894 OsclExclusivePtr<PVMFMediaLayerPort> portAutoPtr;
895 PVMFMediaLayerPort* port = NULL;
896 PVMFMediaLayerPortContainer portParams;
897 OSCL_StackString<8> asf(_STRLIT_CHAR("asf"));
898 OSCL_StackString<8> rtp(_STRLIT_CHAR("rtp"));
899
900 /*
901 * Odd numbered ports are output
902 */
903 if (tag % 2)
904 {
905 portParams.tag = PVMF_MEDIALAYER_PORT_TYPE_OUTPUT;
906 port = OSCL_PLACEMENT_NEW(ptr, PVMFMediaLayerPort(tag, this, "MediaLayerOut"));
907 portAutoPtr.set(port);
908 portParams.iPort = port;
909 portParams.id = tag;
910 portParams.iMimeType = portConfig->get_cstr();
911
912 // parse the mime string to find out the associated input port
913 uint inputPort;
914 if ((portConfig == NULL) ||
915 (oscl_strncmp(portConfig->get_cstr(), asf.get_cstr(), 3) != 0))
916 {
917 // no mime string -> use the old mapping from output port to input port
918 // input port tag = output port tag - 1
919
920 inputPort = tag - 1;
921 portParams.iTransportType = rtp;
922 }
923 else
924 {
925 portParams.iTransportType = asf;
926
927 if (!parseOutputPortMime(portConfig, inputPort))
928 {
929 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error"
930 " - cannot parse mime string: %s for output port %d",
931 this, portConfig, tag));
932 }
933
934 // according to our tag scheme, the input port tag should be even
935 if (inputPort % 2)
936 {
937 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error"
938 " - invalid input port tag %d in output port mime %s",
939 this, inputPort, portConfig));
940 CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
941 return;
942 }
943 }
944
945 // now, we have the tag for the input port - try to find it in the queue
946 uint index;
947 for (index = 0; index < iPortParamsQueue.size(); index++)
948 {
949 if ((uint)iPortParamsQueue[index].id == inputPort)
950 {
951 break;
952 }
953 }
954
955 if (index == iPortParamsQueue.size())
956 {
957 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error"
958 " - input port %d not yet commissioned (output port %d setup)",
959 this, inputPort, tag));
960 CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
961 return;
962 }
963
964 // add the index of the input port in the counter port vector for the output port
965 portParams.vCounterPorts.push_back(index);
966
967 // create frag group allocator
968 portParams.ipFragGroupMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (MEDIALAYERNODE_MAXNUM_MEDIA_DATA));
969 if (portParams.ipFragGroupMemPool == NULL)
970 {
971 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error - Unable to allocate mempool", this));
972 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
973 portAutoPtr.release();
974 return;
975 }
976 portParams.ipFragGroupAllocator = new PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>(
977 MEDIALAYERNODE_MAXNUM_MEDIA_DATA,
978 MEDIALAYERNODE_MAXNUM_MEDIA_DATA,
979 portParams.ipFragGroupMemPool);
980 if (portParams.ipFragGroupAllocator == NULL)
981 {
982 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error - Unable to create frag group allocator", this));
983 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
984 return;
985 }
986 portParams.ipFragGroupAllocator->create();
987
988 // add the output port to the queue
989 int newIndex = iPortParamsQueue.size();
990
991 retVal = Push(portParams);
992 if (retVal == false)
993 {
994 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error - iPortParamsQueue.push_back() failed", this));
995 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
996 return;
997 }
998
999 // now, add the new output port's index to the input port's counter port vector
1000 iPortParamsQueue[index].vCounterPorts.push_back(newIndex);
1001 }
1002 /*
1003 * Even numbered ports are input
1004 */
1005 else
1006 {
1007 portParams.tag = PVMF_MEDIALAYER_PORT_TYPE_INPUT;
1008 port = OSCL_PLACEMENT_NEW(ptr, PVMFMediaLayerPort(tag, this, "MediaLayerIn"));
1009 portAutoPtr.set(port);
1010 portParams.iPort = port;
1011 portParams.id = tag;
1012
1013 {
1014 portParams.iTransportType = rtp;
1015 }
1016
1017 IPayloadParser* parser = CreatePayLoadParser(portConfig);
1018 if (parser != NULL)
1019 {
1020 portParams.iPayLoadParser = parser;
1021 portParams.iMimeType = portConfig->get_cstr();
1022 }
1023 else
1024 {
1025 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error - CreatePayLoadParser() failed", this));
1026 CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
1027 portAutoPtr.release();
1028 return;
1029 }
1030
1031 if (oPortDataLog)
1032 {
1033 OSCL_StackString<32> iMLPortLoggerTag("PVMFMLNode");
1034 iMLPortLoggerTag += iLogFileIndex;
1035 iLogFileIndex += 1;
1036 iMLPortLoggerTag += portConfig->get_cstr();
1037 portParams.iPortLogger = PVLogger::GetLoggerObject(iMLPortLoggerTag.get_cstr());
1038 OSCL_StackString<32> MLPortLogFile;
1039 MLPortLogFile = portLogPath;
1040 MLPortLogFile += iMLPortLoggerTag.get_cstr();
1041 portParams.iLogFile = MLPortLogFile;
1042
1043 PVLoggerAppender *binAppender =
1044 BinaryFileAppender::CreateAppender((char*)(portParams.iLogFile.get_cstr()));
1045
1046 if (binAppender == NULL)
1047 {
1048 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error - Binary Appender Create failed", this));
1049 CommandComplete(iInputCommands, aCmd, PVMFErrNoResources);
1050 portAutoPtr.release();
1051 return;
1052 }
1053 OsclRefCounterSA<PVMFMediaLayerNodeLoggerDestructDealloc>* binAppenderRefCounter =
1054 new OsclRefCounterSA<PVMFMediaLayerNodeLoggerDestructDealloc>(binAppender);
1055
1056 OsclSharedPtr<PVLoggerAppender> appenderSharedPtr(binAppender, binAppenderRefCounter);
1057 portParams.iBinAppenderPtr = appenderSharedPtr;
1058 portParams.iPortLogger->AddAppender(portParams.iBinAppenderPtr);
1059 }
1060
1061 retVal = Push(portParams);
1062 if (retVal == false)
1063 {
1064 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DoRequestPort: Error - iPortParamsQueue.push_back() failed", this));
1065 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
1066 return;
1067 }
1068 }
1069
1070 /* Add the port to the port vector. */
1071 retVal = AddPort(port);
1072
1073 if (retVal == false)
1074 {
1075 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
1076 portAutoPtr.release();
1077 return;
1078 }
1079
1080 portAutoPtr.release();
1081
1082 /* Return the port pointer to the caller. */
1083 CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)port);
1084 }
1085
Allocate(OsclAny * & ptr)1086 bool PVMFMediaLayerNode::Allocate(OsclAny*& ptr)
1087 {
1088 int32 err;
1089 OSCL_TRY(err, ptr = iPortVector.Allocate(););
1090 if (err != OsclErrNone)
1091 {
1092 return false;
1093 }
1094 return true;
1095 }
1096
Push(PVMFMediaLayerPortContainer portParams)1097 bool PVMFMediaLayerNode::Push(PVMFMediaLayerPortContainer portParams)
1098 {
1099 int32 err;
1100 OSCL_TRY(err, iPortParamsQueue.push_back(portParams););
1101 if (err != OsclErrNone)
1102 {
1103 return false;
1104 }
1105 return true;
1106 }
1107
AddPort(PVMFMediaLayerPort * port)1108 bool PVMFMediaLayerNode::AddPort(PVMFMediaLayerPort* port)
1109 {
1110 int32 err;
1111 OSCL_TRY(err, iPortVector.AddL(port););
1112 if (err != OsclErrNone)
1113 {
1114 return false;
1115 }
1116 return true;
1117 }
1118 /**
1119 * Called by the command handler AO to do the port release
1120 */
DoReleasePort(PVMFMediaLayerNodeCommand & aCmd)1121 void PVMFMediaLayerNode::DoReleasePort(PVMFMediaLayerNodeCommand& aCmd)
1122 {
1123 /* This node supports release port from any state */
1124
1125 /* Find the port in the port vector */
1126 PVMFPortInterface* p = NULL;
1127 aCmd.PVMFMediaLayerNodeCommandBase::Parse(p);
1128
1129 PVMFMediaLayerPort* port = (PVMFMediaLayerPort*)p;
1130
1131 PVMFMediaLayerPort** portPtr = iPortVector.FindByValue(port);
1132 if (portPtr)
1133 {
1134 /* delete corresponding port params */
1135 Oscl_Vector<PVMFMediaLayerPortContainer, PVMFMediaLayerNodeAllocator>::iterator it;
1136
1137 for (it = iPortParamsQueue.begin();
1138 it != iPortParamsQueue.end();
1139 it++)
1140 {
1141 if (it->iPort == port)
1142 {
1143 if (it->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT)
1144 {
1145 DestroyPayLoadParser(&(it->iMimeType), it->iPayLoadParser);
1146 if (oPortDataLog)
1147 {
1148 if (it->iBinAppenderPtr.GetRep() != NULL)
1149 {
1150 it->iPortLogger->RemoveAppender(it->iBinAppenderPtr);
1151 it->iBinAppenderPtr.Unbind();
1152 }
1153 }
1154 }
1155 if (it->ipFragGroupAllocator != NULL)
1156 {
1157 it->ipFragGroupAllocator->CancelFreeChunkAvailableCallback();
1158 it->ipFragGroupAllocator->removeRef();
1159 }
1160 if (it->ipFragGroupMemPool != NULL)
1161 {
1162 it->ipFragGroupMemPool->removeRef();
1163 }
1164 it->CleanUp();
1165 iPortParamsQueue.erase(it);
1166 break;
1167 }
1168 }
1169 iPortVector.Erase(portPtr);
1170 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
1171 }
1172 else
1173 {
1174 /* port not found */
1175 CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
1176 }
1177 }
1178
1179 /**
1180 * Called by the command handler AO to do the node Init
1181 */
DoInit(PVMFMediaLayerNodeCommand & aCmd)1182 void PVMFMediaLayerNode::DoInit(PVMFMediaLayerNodeCommand& aCmd)
1183 {
1184 switch (iInterfaceState)
1185 {
1186 case EPVMFNodeIdle:
1187 {
1188 SetState(EPVMFNodeInitialized);
1189 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
1190 }
1191 break;
1192
1193 default:
1194 CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
1195 break;
1196 }
1197 }
1198 /**
1199
1200 * Called by the command handler AO to do the node Prepare
1201 */
DoPrepare(PVMFMediaLayerNodeCommand & aCmd)1202 void PVMFMediaLayerNode::DoPrepare(PVMFMediaLayerNodeCommand& aCmd)
1203 {
1204 switch (iInterfaceState)
1205 {
1206 case EPVMFNodeInitialized:
1207 {
1208 SetState(EPVMFNodePrepared);
1209 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
1210 }
1211 break;
1212
1213 default:
1214 CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
1215 break;
1216 }
1217 }
1218
1219 IPayloadParser*
CreatePayLoadParser(PvmfMimeString * aPortConfig)1220 PVMFMediaLayerNode::CreatePayLoadParser(PvmfMimeString* aPortConfig)
1221 {
1222 PayloadParserRegistry* registry = iPayLoadParserRegistry;
1223
1224 if (registry == NULL)
1225 {
1226 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::CreatePayLoadParser: Error - Invalid Registry", this));
1227 return NULL;
1228 }
1229
1230 OsclMemoryFragment memFrag;
1231 memFrag.ptr = (OsclAny*)(aPortConfig->get_cstr());
1232 memFrag.len = aPortConfig->get_size();
1233 IPayloadParserFactory* factory = registry->lookupPayloadParserFactory(memFrag);
1234 if (factory == NULL)
1235 {
1236 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::CreatePayLoadParser: Error - Invalid Factory", this));
1237 return NULL;
1238 }
1239 return (factory->createPayloadParser());
1240 }
1241
1242 void
DestroyPayLoadParser(PvmfMimeString * aPortConfig,IPayloadParser * aParser)1243 PVMFMediaLayerNode::DestroyPayLoadParser(PvmfMimeString* aPortConfig,
1244 IPayloadParser* aParser)
1245 {
1246 PayloadParserRegistry* registry = iPayLoadParserRegistry;
1247
1248 if (registry == NULL)
1249 {
1250 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DestroyPayLoadParser: Error - Invalid Registry", this));
1251 OSCL_LEAVE(OsclErrBadHandle);
1252 }
1253
1254 OsclMemoryFragment memFrag;
1255 memFrag.ptr = (OsclAny*)(aPortConfig->get_cstr());
1256 memFrag.len = aPortConfig->get_size();
1257 IPayloadParserFactory* factory =
1258 registry->lookupPayloadParserFactory(memFrag);
1259 if (factory == NULL)
1260 {
1261 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::DestroyPayLoadParser: Error - Invalid Factory", this));
1262 OSCL_LEAVE(OsclErrBadHandle);
1263 }
1264 factory->destroyPayloadParser(aParser);
1265 }
1266
1267 /**
1268 * Called by the command handler AO to do the node Start
1269 */
DoStart(PVMFMediaLayerNodeCommand & aCmd)1270 void PVMFMediaLayerNode::DoStart(PVMFMediaLayerNodeCommand& aCmd)
1271 {
1272 iDiagnosticsLogged = false;
1273 PVMFStatus status = PVMFSuccess;
1274 switch (iInterfaceState)
1275 {
1276 case EPVMFNodePrepared:
1277 case EPVMFNodePaused:
1278 {
1279 /* transition to Started */
1280 SetState(EPVMFNodeStarted);
1281 }
1282 break;
1283
1284 default:
1285 status = PVMFErrInvalidState;
1286 break;
1287 }
1288
1289 CommandComplete(iInputCommands, aCmd, status);
1290 }
1291
1292 /**
1293 * Called by the command handler AO to do the node Stop
1294 */
DoStop(PVMFMediaLayerNodeCommand & aCmd)1295 void PVMFMediaLayerNode::DoStop(PVMFMediaLayerNodeCommand& aCmd)
1296 {
1297 LogSessionDiagnostics();
1298
1299 switch (iInterfaceState)
1300 {
1301 case EPVMFNodeStarted:
1302 case EPVMFNodePaused:
1303 {
1304 /* Clear queued messages in ports */
1305 uint32 i;
1306 for (i = 0; i < iPortVector.size(); i++)
1307 {
1308 iPortVector[i]->ClearMsgQueues();
1309
1310 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
1311 bool bRet = GetPortContainer(iPortVector[i], portContainerPtr);
1312 if (bRet)
1313 {
1314 portContainerPtr->ResetParams();
1315 portContainerPtr->vAccessUnits.clear();
1316 }
1317 }
1318 /* transition to Prepared state */
1319 Oscl_Int64_Utils::set_uint64(preroll64, 0, 0);
1320 oEOSsendunits = false;
1321 SetState(EPVMFNodePrepared);
1322 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
1323 }
1324 break;
1325
1326 default:
1327 CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
1328 break;
1329 }
1330 }
1331
1332 /**
1333 * Called by the command handler AO to do the node Flush
1334 */
DoFlush(PVMFMediaLayerNodeCommand & aCmd)1335 void PVMFMediaLayerNode::DoFlush(PVMFMediaLayerNodeCommand& aCmd)
1336 {
1337 switch (iInterfaceState)
1338 {
1339 case EPVMFNodeStarted:
1340 case EPVMFNodePaused:
1341 {
1342 /*
1343 * the flush is asynchronous. move the command from
1344 * the input command queue to the current command, where
1345 * it will remain until the flush completes.
1346 */
1347 int32 err;
1348 OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
1349 if (err != OsclErrNone)
1350 {
1351 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
1352 return;
1353 }
1354 iInputCommands.Erase(&aCmd);
1355 /* Notify all ports to suspend their input */
1356 for (uint32 i = 0; i < iPortVector.size(); i++)
1357 iPortVector[i]->SuspendInput();
1358 }
1359 break;
1360
1361 default:
1362 CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
1363 break;
1364 }
1365 }
1366
1367 /**
1368 * A routine to tell if a flush operation is in progress.
1369 */
FlushPending()1370 bool PVMFMediaLayerNode::FlushPending()
1371 {
1372 return (iCurrentCommand.size() > 0
1373 && iCurrentCommand.front().iCmd == PVMF_MEDIA_LAYER_NODE_FLUSH);
1374 }
1375
1376
1377 /**
1378 * Called by the command handler AO to do the node Pause
1379 */
DoPause(PVMFMediaLayerNodeCommand & aCmd)1380 void PVMFMediaLayerNode::DoPause(PVMFMediaLayerNodeCommand& aCmd)
1381 {
1382 PVMFStatus status;
1383 switch (iInterfaceState)
1384 {
1385 case EPVMFNodeStarted:
1386 {
1387 /* transition to paused state */
1388 SetState(EPVMFNodePaused);
1389 status = PVMFSuccess;
1390 }
1391 break;
1392
1393 case EPVMFNodePaused:
1394 /* Ignore Pause if already paused */
1395 status = PVMFSuccess;
1396 break;
1397
1398 default:
1399 status = PVMFErrInvalidState;
1400 break;
1401 }
1402 CommandComplete(iInputCommands, aCmd, status);
1403 return;
1404 }
1405
1406 /**
1407 * Called by the command handler AO to do the Cancel All
1408 */
DoCancelAllCommands(PVMFMediaLayerNodeCommand & aCmd)1409 void PVMFMediaLayerNode::DoCancelAllCommands(PVMFMediaLayerNodeCommand& aCmd)
1410 {
1411 /* first cancel the current command if any */
1412 {
1413 while (!iCurrentCommand.empty())
1414 CommandComplete(iCurrentCommand, iCurrentCommand[0], PVMFErrCancelled);
1415 }
1416
1417 /* next cancel all queued commands */
1418 {
1419 /* start at element 1 since this cancel command is element 0 */
1420 while (iInputCommands.size() > 1)
1421 CommandComplete(iInputCommands, iInputCommands[1], PVMFErrCancelled);
1422 }
1423
1424 /* finally, report cancel complete */
1425 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
1426 }
1427
1428 /**
1429 * Called by the command handler AO to do the Cancel single command
1430 */
DoCancelCommand(PVMFMediaLayerNodeCommand & aCmd)1431 void PVMFMediaLayerNode::DoCancelCommand(PVMFMediaLayerNodeCommand& aCmd)
1432 {
1433 /* extract the command ID from the parameters */
1434 PVMFCommandId id;
1435 aCmd.PVMFMediaLayerNodeCommandBase::Parse(id);
1436
1437 /* first check "current" command if any */
1438 {
1439 PVMFMediaLayerNodeCommand* cmd = iCurrentCommand.FindById(id);
1440 if (cmd)
1441 {
1442 /* cancel the queued command */
1443 CommandComplete(iCurrentCommand, *cmd, PVMFErrCancelled);
1444 /* report cancel success */
1445 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
1446 return;
1447 }
1448 }
1449
1450 /* next check input queue */
1451 {
1452 /* start at element 1 since this cancel command is element 0 */
1453 PVMFMediaLayerNodeCommand* cmd = iInputCommands.FindById(id, 1);
1454 if (cmd)
1455 {
1456 /* cancel the queued command */
1457 CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
1458 /* report cancel success */
1459 CommandComplete(iInputCommands, aCmd, PVMFSuccess);
1460 return;
1461 }
1462 }
1463 /* if we get here the command isn't queued so the cancel fails */
1464 CommandComplete(iInputCommands, aCmd, PVMFFailure);
1465 }
1466
1467
1468 /////////////////////////////////////////////////////
1469 // Event reporting routines.
1470 /////////////////////////////////////////////////////
SetState(TPVMFNodeInterfaceState s)1471 void PVMFMediaLayerNode::SetState(TPVMFNodeInterfaceState s)
1472 {
1473 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:SetState %d", s));
1474 PVMFNodeInterface::SetState(s);
1475 }
1476
ReportErrorEvent(PVMFEventType aEventType,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)1477 void PVMFMediaLayerNode::ReportErrorEvent(PVMFEventType aEventType,
1478 OsclAny* aEventData,
1479 PVUuid* aEventUUID,
1480 int32* aEventCode)
1481 {
1482 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode:NodeErrorEvent Type %d Data %d"
1483 , aEventType, aEventData));
1484
1485 if (aEventUUID && aEventCode)
1486 {
1487 PVMFBasicErrorInfoMessage* eventmsg;
1488 PVMF_MEDIA_LAYER_NEW(NULL, PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL), eventmsg);
1489 PVMFAsyncEvent asyncevent(PVMFErrorEvent,
1490 aEventType,
1491 NULL,
1492 OSCL_STATIC_CAST(PVInterface*, eventmsg),
1493 aEventData,
1494 NULL,
1495 0);
1496 PVMFNodeInterface::ReportErrorEvent(asyncevent);
1497 eventmsg->removeRef();
1498 }
1499 else
1500 {
1501 PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
1502 }
1503 }
1504
ReportInfoEvent(PVMFEventType aEventType,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)1505 void PVMFMediaLayerNode::ReportInfoEvent(PVMFEventType aEventType,
1506 OsclAny* aEventData,
1507 PVUuid* aEventUUID,
1508 int32* aEventCode)
1509 {
1510 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode:NodeInfoEvent Type %d Data %d"
1511 , aEventType, aEventData));
1512
1513 if (aEventUUID && aEventCode)
1514 {
1515 PVMFBasicErrorInfoMessage* eventmsg;
1516 PVMF_MEDIA_LAYER_NEW(NULL, PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL), eventmsg);
1517 PVMFAsyncEvent asyncevent(PVMFInfoEvent,
1518 aEventType,
1519 NULL,
1520 OSCL_STATIC_CAST(PVInterface*, eventmsg),
1521 aEventData,
1522 NULL,
1523 0);
1524 PVMFNodeInterface::ReportInfoEvent(asyncevent);
1525 eventmsg->removeRef();
1526 }
1527 else
1528 {
1529 PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
1530 }
1531 }
1532
1533 /////////////////////////////////////////////////////
1534 // Port Processing routines
1535 /////////////////////////////////////////////////////
QueuePortActivity(PVMFMediaLayerPortContainer * aPortContainer,const PVMFPortActivity & aActivity)1536 void PVMFMediaLayerNode::QueuePortActivity(PVMFMediaLayerPortContainer* aPortContainer,
1537 const PVMFPortActivity &aActivity)
1538 {
1539 OSCL_UNUSED_ARG(aPortContainer);
1540 OSCL_UNUSED_ARG(aActivity);
1541 if (IsAdded())
1542 {
1543 RunIfNotReady();
1544 }
1545 }
1546
freechunkavailable(PVMFPortInterface * aPort)1547 void PVMFMediaLayerNode::freechunkavailable(PVMFPortInterface* aPort)
1548 {
1549 PVMF_MLNODE_LOGINFO((0, "0x%x PVMFMediaLayerNode::freechunkavailable: port=0x%x",
1550 this, aPort));
1551
1552 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
1553
1554 if (!GetPortContainer(aPort, portContainerPtr))
1555 {
1556 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aPort));
1557 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::freechunkavailable: Error - GetPortContainer failed", this));
1558 return;
1559 }
1560
1561 portContainerPtr->oProcessIncomingMessages = true;
1562 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
1563 "PVMFMediaLayerNode::freechunkavailable: Mime=%s, QSize =%d", portContainerPtr->iMimeType.get_cstr(), aPort->IncomingMsgQueueSize()));
1564 /*
1565 * An input port will call this when memory is available in the rtp
1566 * payload parser. We may need to wake up the input data processing.
1567 */
1568 if (IsAdded())
1569 {
1570 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
1571 "PVMFMediaLayerNode::freechunkavailable: - Calling RunIfNotReady"));
1572 RunIfNotReady();
1573 }
1574 }
1575
HandlePortActivity(const PVMFPortActivity & aActivity)1576 void PVMFMediaLayerNode::HandlePortActivity(const PVMFPortActivity &aActivity)
1577 {
1578 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::PortActivity: port=0x%x, type=%d",
1579 aActivity.iPort, aActivity.iType));
1580
1581 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
1582
1583 if (aActivity.iType != PVMF_PORT_ACTIVITY_DELETED)
1584 {
1585 if (!GetPortContainer(aActivity.iPort, portContainerPtr))
1586 {
1587 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1588 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HPA: Error - GetPortContainer failed"));
1589 return;
1590 }
1591 }
1592
1593 /*
1594 * A port is reporting some activity or state change. This code
1595 * figures out whether we need to queue a processing event
1596 * for the AO, and/or report a node event to the observer.
1597 */
1598
1599 switch (aActivity.iType)
1600 {
1601 case PVMF_PORT_ACTIVITY_CREATED:
1602 /*
1603 * Report port created info event to the node.
1604 */
1605 ReportInfoEvent(PVMFInfoPortCreated, (OsclAny*)aActivity.iPort);
1606 break;
1607
1608 case PVMF_PORT_ACTIVITY_DELETED:
1609 {
1610 /*
1611 * Report port deleted info event to the node.
1612 */
1613 ReportInfoEvent(PVMFInfoPortDeleted, (OsclAny*)aActivity.iPort);
1614 }
1615 break;
1616
1617 case PVMF_PORT_ACTIVITY_CONNECT:
1618 break;
1619
1620 case PVMF_PORT_ACTIVITY_DISCONNECT:
1621 break;
1622
1623 case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
1624 {
1625 /*
1626 * An outgoing message was queued on this port.
1627 * Only output ports have outgoing messages in
1628 * this node
1629 */
1630 int32 portTag = portContainerPtr->tag;
1631 switch (portTag)
1632 {
1633 case PVMF_MEDIALAYER_PORT_TYPE_OUTPUT:
1634 if (portContainerPtr->oProcessOutgoingMessages)
1635 QueuePortActivity(portContainerPtr, aActivity);
1636 break;
1637
1638 default:
1639 OSCL_ASSERT(false);
1640 break;
1641 }
1642 }
1643 break;
1644
1645 case PVMF_PORT_ACTIVITY_INCOMING_MSG:
1646 {
1647 /*
1648 * An incoming message was queued on this port.
1649 * Input ports only get incoming messages in this
1650 * node
1651 */
1652 int32 portTag = portContainerPtr->tag;
1653
1654 switch (portTag)
1655 {
1656 case PVMF_MEDIALAYER_PORT_TYPE_INPUT:
1657 if (portContainerPtr->oProcessIncomingMessages)
1658 QueuePortActivity(portContainerPtr, aActivity);
1659 break;
1660
1661 default:
1662 OSCL_ASSERT(false);
1663 break;
1664 }
1665 }
1666 break;
1667
1668 case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
1669 {
1670 int32 portTag = portContainerPtr->tag;
1671 switch (portTag)
1672 {
1673 case PVMF_MEDIALAYER_PORT_TYPE_INPUT:
1674 /*
1675 * Input ports do not use their outgoing queues
1676 * in this node.
1677 */
1678 OSCL_ASSERT(false);
1679 break;
1680
1681 case PVMF_MEDIALAYER_PORT_TYPE_OUTPUT:
1682 {
1683 /*
1684 * This implies that this output port cannot accept any more
1685 * msgs on its outgoing queue. This implies that the corresponding
1686 * input port must stop processing messages.
1687 */
1688 PVMFPortInterface* inPort = getPortCounterpart(portContainerPtr);
1689 if (inPort != NULL)
1690 {
1691 PVMFMediaLayerPortContainer* inPortContainerPtr = NULL;
1692 if (!GetPortContainer(inPort, inPortContainerPtr))
1693 {
1694 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1695 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HandlePortActivity: Error - GetPortContainer failed"));
1696 return;
1697 }
1698 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0, "PVMFMediaLayerNode::HPA: Output Port Queue Busy - Mime=%s",
1699 inPortContainerPtr->iMimeType.get_cstr()));
1700 inPortContainerPtr->oProcessIncomingMessages = false;
1701 }
1702 else
1703 {
1704 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1705 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HandlePortActivity: Error - getPortCounterpart failed"));
1706 return;
1707 }
1708 }
1709 break;
1710
1711 default:
1712 OSCL_ASSERT(false);
1713 break;
1714 }
1715 }
1716 break;
1717
1718 case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
1719 {
1720 /*
1721 * Outgoing queue was previously busy, but is now ready.
1722 * We may need to schedule new processing events depending
1723 * on the port type.
1724 */
1725 int32 portTag = portContainerPtr->tag;
1726 switch (portTag)
1727 {
1728 case PVMF_MEDIALAYER_PORT_TYPE_INPUT:
1729 /*
1730 * Input ports do not use their outgoing queues
1731 * in this node.
1732 */
1733 OSCL_ASSERT(false);
1734 break;
1735
1736 case PVMF_MEDIALAYER_PORT_TYPE_OUTPUT:
1737 {
1738 /*
1739 * This implies that this output port can accept more
1740 * msgs on its outgoing queue. This implies that the corresponding
1741 * input port can start processing messages again.
1742 */
1743 PVMFPortInterface* inPort = getPortCounterpart(portContainerPtr);
1744 if (inPort != NULL)
1745 {
1746 PVMFMediaLayerPortContainer* inPortContainerPtr = NULL;
1747 if (!GetPortContainer(inPort, inPortContainerPtr))
1748 {
1749 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1750 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HandlePortActivity: Error - GetPortContainer failed"));
1751 return;
1752 }
1753 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0, "PVMFMediaLayerNode::HPA: Output Port Queue Ready - Mime=%s",
1754 inPortContainerPtr->iMimeType.get_cstr()));
1755 inPortContainerPtr->oProcessIncomingMessages = true;
1756 }
1757 else
1758 {
1759 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1760 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HandlePortActivity: Error - getPortCounterpart failed"));
1761 return;
1762 }
1763 }
1764 break;
1765
1766 default:
1767 OSCL_ASSERT(false);
1768 break;
1769 }
1770 if (IsAdded())
1771 {
1772 RunIfNotReady();
1773 }
1774 }
1775 break;
1776
1777 case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
1778 {
1779 /*
1780 * The connected port has become busy (its incoming queue is
1781 * busy).
1782 */
1783 int32 portTag = portContainerPtr->tag;
1784 switch (portTag)
1785 {
1786 case PVMF_MEDIALAYER_PORT_TYPE_INPUT:
1787 /*
1788 * Input ports do not use their outgoing queues
1789 * in this node.
1790 */
1791 OSCL_ASSERT(false);
1792 break;
1793
1794 case PVMF_MEDIALAYER_PORT_TYPE_OUTPUT:
1795 {
1796 /*
1797 * This implies that this output port cannot send any more
1798 * msgs from its outgoing queue. It should stop processing
1799 * messages till the connect port is ready.
1800 */
1801 portContainerPtr->oProcessOutgoingMessages = false;
1802 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0, "PVMFMediaLayerNode::HPA: Connected port busy - Mime=%s",
1803 portContainerPtr->iMimeType.get_cstr()));
1804 PVMFPortInterface* inPort = getPortCounterpart(portContainerPtr);
1805 if (inPort != NULL)
1806 {
1807 PVMFMediaLayerPortContainer* inPortContainerPtr = NULL;
1808 if (!GetPortContainer(inPort, inPortContainerPtr))
1809 {
1810 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1811 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HandlePortActivity: Error - GetPortContainer failed"));
1812 return;
1813 }
1814 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0, "PVMFMediaLayerNode::HPA: Connected port busy - Stop Input - Mime=%s",
1815 inPortContainerPtr->iMimeType.get_cstr()));
1816 if (checkOutputPortsBusy(inPortContainerPtr))
1817 {
1818 inPortContainerPtr->oProcessIncomingMessages = false;
1819 }
1820 }
1821 else
1822 {
1823 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1824 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HandlePortActivity: Error - getPortCounterpart failed"));
1825 return;
1826 }
1827 }
1828 break;
1829
1830 default:
1831 OSCL_ASSERT(false);
1832 break;
1833 }
1834 }
1835 break;
1836
1837 case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
1838 {
1839 /*
1840 * The connected port has transitioned from Busy to Ready.
1841 * It's time to start processing messages outgoing again.
1842 */
1843 int32 portTag = portContainerPtr->tag;
1844 switch (portTag)
1845 {
1846 case PVMF_MEDIALAYER_PORT_TYPE_INPUT:
1847 /*
1848 * Input ports do not use their outgoing queues
1849 * in this node.
1850 */
1851 OSCL_ASSERT(false);
1852 break;
1853
1854 case PVMF_MEDIALAYER_PORT_TYPE_OUTPUT:
1855 {
1856 /*
1857 * This implies that this output port can now send
1858 * msgs from its outgoing queue. It can start processing
1859 * messages now.
1860 */
1861 portContainerPtr->oProcessOutgoingMessages = true;
1862 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0, "PVMFMediaLayerNode::HPA: Connected port ready - Mime=%s",
1863 portContainerPtr->iMimeType.get_cstr()));
1864 PVMFPortInterface* inPort = getPortCounterpart(portContainerPtr);
1865 if (inPort != NULL)
1866 {
1867 PVMFMediaLayerPortContainer* inPortContainerPtr = NULL;
1868 if (!GetPortContainer(inPort, inPortContainerPtr))
1869 {
1870 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1871 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HandlePortActivity: Error - GetPortContainer failed"));
1872 return;
1873 }
1874 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0, "PVMFMediaLayerNode::HPA: Connected port busy - Resume Input - Mime=%s",
1875 inPortContainerPtr->iMimeType.get_cstr()));
1876 inPortContainerPtr->oProcessIncomingMessages = true;
1877 }
1878 else
1879 {
1880 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
1881 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::HandlePortActivity: Error - getPortCounterpart failed"));
1882 return;
1883 }
1884 }
1885 break;
1886
1887 default:
1888 OSCL_ASSERT(false);
1889 break;
1890 }
1891 if (IsAdded())
1892 {
1893 RunIfNotReady();
1894 }
1895 }
1896 break;
1897
1898
1899 default:
1900 break;
1901 }
1902 }
1903
1904 /*
1905 * called by the AO to process a port activity message
1906 */
ProcessPortActivity(PVMFMediaLayerPortContainer * aPortContainer)1907 bool PVMFMediaLayerNode::ProcessPortActivity(PVMFMediaLayerPortContainer* aPortContainer)
1908 {
1909 PVMFStatus status = PVMFSuccess;
1910 switch (aPortContainer->tag)
1911 {
1912 case PVMF_MEDIALAYER_PORT_TYPE_OUTPUT:
1913 {
1914 if ((aPortContainer->oProcessOutgoingMessages) &&
1915 (aPortContainer->iPort->OutgoingMsgQueueSize() > 0))
1916 {
1917 status = ProcessOutgoingMsg(aPortContainer);
1918 }
1919 else
1920 {
1921 status = PVMFErrBusy;
1922 }
1923 }
1924 break;
1925
1926 case PVMF_MEDIALAYER_PORT_TYPE_INPUT:
1927 {
1928 /*
1929 * attempt to send any left over payloads first
1930 * If both output port payload msg is not available or outgoing queue is busy,
1931 * oProcessIncomingMessages is set to false and PVMFErrBusy is replied.
1932 */
1933 status = sendAccessUnits(aPortContainer);
1934 /*
1935 * Process any incoming messages if the output ports are not busy
1936 * and if there are media msgs available
1937 */
1938 if (status == PVMFSuccess && aPortContainer->iPort->IncomingMsgQueueSize() > 0)
1939 {
1940 if (aPortContainer->oProcessIncomingMessages)
1941 {
1942 status = ProcessIncomingMsg(aPortContainer);
1943 }
1944 else
1945 {
1946 status = PVMFErrBusy;
1947 }
1948 }
1949 }
1950 break;
1951
1952 default:
1953 OSCL_ASSERT(false);
1954 break;
1955 }
1956
1957 /* report a failure in port processing */
1958 if (status != PVMFErrBusy && status != PVMFSuccess)
1959 {
1960 PVMF_MLNODE_LOGERROR((0,
1961 "PVMFMediaLayerNode::ProcessPortActivity: Error - ProcessPortActivity failed. port=0x%x",
1962 aPortContainer->iPort));
1963 ReportErrorEvent(PVMFErrPortProcessing);
1964 }
1965
1966 /* return true if we processed an activity */
1967 return (status != PVMFErrBusy);
1968 }
1969
ProcessIncomingMsg(PVMFMediaLayerPortContainer * pinputPort)1970 PVMFStatus PVMFMediaLayerNode::ProcessIncomingMsg(PVMFMediaLayerPortContainer* pinputPort)
1971 {
1972 PVMFStatus status;
1973
1974 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::ProcessIncomingMsg: aPort=0x%x",
1975 pinputPort->iPort));
1976
1977 if (pinputPort->tag != PVMF_MEDIALAYER_PORT_TYPE_INPUT)
1978 {
1979 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(pinputPort->iPort));
1980 PVMF_MLNODE_LOGERROR((0,
1981 "PVMFMediaLayerNode::ProcessIncomingMsg: Error - Not an Input Port"));
1982 return PVMFFailure;
1983 }
1984
1985 //
1986 // Check if the output port is busy.
1987 //
1988 if (checkOutputPortsBusy(pinputPort))
1989 {
1990 PVUuid eventuuid = PVMFMediaLayerNodeEventTypeUUID;
1991
1992 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
1993 "PVMFMediaLayerNode::ProcessIncomingMsg: Cant Send Data - Output Queue Busy"));
1994 /*
1995 * Processing will resume when we get outgoing queue ready notification
1996 * in the port activity
1997 */
1998 pinputPort->oProcessIncomingMessages = false;
1999 return PVMFErrBusy;
2000 }
2001
2002 //
2003 // dequeue the message
2004 // if it is EOS leave it on the port queue until we are
2005 // done sending all payloads
2006 //
2007 PVMFSharedMediaMsgPtr msgIn;
2008 PVMFSharedMediaDataPtr peekDataPtr;
2009 if (!oEOSsendunits)
2010 {
2011 bool oIsEOSCmd = false;
2012
2013 PVMFMediaLayerPort* mlPort =
2014 OSCL_STATIC_CAST(PVMFMediaLayerPort*, pinputPort->iPort);
2015 status = mlPort->peekHead(peekDataPtr, oIsEOSCmd);
2016 if (status != PVMFSuccess)
2017 {
2018 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(pinputPort->iPort));
2019 PVMF_MLNODE_LOGERROR((0,
2020 "0x%x PVMFMediaLayerNode::ProcessIncomingMsg: Error - peekHead failed", this));
2021 return status;
2022 }
2023 if (oIsEOSCmd == true)
2024 {
2025 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::ProcessIncomingMsg() Detect EOS message"));
2026
2027 //EOS msg is received. Before sending EOS, we send left payload msgs.
2028 bool IsAccessUnitsEmpty = false;
2029 status = checkPortCounterpartAccessUnitQueue(pinputPort, &IsAccessUnitsEmpty);
2030 if (status != PVMFSuccess)
2031 {
2032 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(pinputPort->iPort));
2033 PVMF_MLNODE_LOGERROR((0,
2034 "0x%x PVMFMediaLayerNode::ProcessIncomingMsg: Error - checkPortCounterpartAccessUnitQueue failed", this));
2035 return status;
2036 }
2037 if (IsAccessUnitsEmpty)
2038 {
2039 oEOSsendunits = true;
2040 return sendAccessUnits(pinputPort);
2041 }
2042 }
2043 }
2044 else
2045 {
2046 bool IsAccessUnitsEmpty = false;
2047 status = checkPortCounterpartAccessUnitQueue(pinputPort, &IsAccessUnitsEmpty);
2048 if (status != PVMFSuccess)
2049 {
2050 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(pinputPort->iPort));
2051 PVMF_MLNODE_LOGERROR((0,
2052 "0x%x PVMFMediaLayerNode::ProcessIncomingMsg: Error - checkPortCounterpartAccessUnitQueue failed", this));
2053 return status;
2054 }
2055 if (IsAccessUnitsEmpty)
2056 {
2057 return sendAccessUnits(pinputPort);
2058 }
2059 else
2060 {
2061 oEOSsendunits = false;
2062 }
2063 }
2064 status = pinputPort->iPort->DequeueIncomingMsg(msgIn);
2065 if (status != PVMFSuccess)
2066 {
2067 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(pinputPort->iPort));
2068 PVMF_MLNODE_LOGERROR((0,
2069 "0x%x PVMFMediaLayerNode::ProcessIncomingMsg: Error - DequeueIncomingMsg failed", this));
2070 return status;
2071 }
2072 //
2073 // what kind of demuxing are we doing?
2074 //
2075 bool isOneToN = pinputPort->iIsOneToN;
2076
2077 PVUid32 msgFormatID = msgIn->getFormatID();
2078
2079 if (msgFormatID > PVMF_MEDIA_CMD_FORMAT_IDS_START)
2080 {
2081 if (msgFormatID == PVMF_MEDIA_CMD_BOS_FORMAT_ID)
2082 {
2083 iStreamID = msgIn->getStreamID();
2084 PVMF_MLNODE_LOGDATATRAFFIC_IN((0, "PVMFMediaLayerNode::ProcessInputMsg_OneToN: Sending MediaCmd - BOS Received"));
2085 PVMF_MLNODE_LOG_REPOS((0, "PVMFMediaLayerNode::ProcessInputMsg_OneToN: Sending MediaCmd - BOS Received"));
2086 // send BOS on every output port
2087 for (uint i = 0; i < pinputPort->vCounterPorts.size(); i++)
2088 {
2089 PVMFMediaLayerPortContainer* poutPort = &this->iPortParamsQueue[pinputPort->vCounterPorts[i]];
2090 // set BOS Timestamp to last media ts sent on this port
2091 msgIn->setTimestamp(poutPort->iContinuousTimeStamp);
2092 status = poutPort->iPort->QueueOutgoingMsg(msgIn);
2093
2094 if (status != PVMFSuccess)
2095 {
2096 PVMF_MLNODE_LOGERROR((0,
2097 "0x%x PVMFMediaLayerNode::ProcessInputMsg_OneToN: "
2098 "Error - QueueOutgoingMsg for BOS failed", this));
2099 return status;
2100 }
2101 else
2102 {
2103 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
2104 uint32 timebase32 = 0;
2105 uint32 clientClock32 = 0;
2106 bool overflowFlag = false;
2107 iClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag,
2108 PVMF_MEDIA_CLOCK_MSEC, timebase32);
2109 PVMF_MLNODE_LOGDATATRAFFIC_OUT((0,
2110 "PVMFMediaLayerNode::ProcessInputMsg_OneToN: Sending BOS - MimeType=%s Clock=%d",
2111 poutPort->iMimeType.get_cstr(), clientClock32));
2112 PVMF_MLNODE_LOG_REPOS((0,
2113 "PVMFMediaLayerNode::ProcessInputMsg_OneToN: Sending BOS - MimeType=%s Clock=%d",
2114 poutPort->iMimeType.get_cstr(), clientClock32));
2115 #endif
2116 }
2117 }
2118
2119 }
2120 else if (msgFormatID == PVMF_MEDIA_CMD_EOS_FORMAT_ID)
2121 {
2122 //
2123 // check for EOS
2124 //
2125 // Upstream EOS recvd
2126 pinputPort->oUpStreamEOSRecvd = true;
2127 pinputPort->oEOSReached = true;
2128
2129 // send EOS on every output port
2130 for (uint i = 0; i < pinputPort->vCounterPorts.size(); i++)
2131 {
2132 PVMFMediaLayerPortContainer* poutPort = &this->iPortParamsQueue[pinputPort->vCounterPorts[i]];
2133 // set EOS Timestamp to last media ts sent on this port
2134 if (poutPort->oDisableTrack == false && poutPort->oEOSReached == false)
2135 {
2136 poutPort->iContinuousTimeStamp += PVMF_MEDIA_LAYER_NODE_ASF_REPOS_TIME_OFFSET_IN_MS;
2137 msgIn->setTimestamp(poutPort->iContinuousTimeStamp);
2138 msgIn->setStreamID(iStreamID);
2139 status = poutPort->iPort->QueueOutgoingMsg(msgIn);
2140
2141 if (status != PVMFSuccess)
2142 {
2143 PVMF_MLNODE_LOGERROR((0,
2144 "0x%x PVMFMediaLayerNode::ProcessInputMsg_OneToN: "
2145 "Error - QueueOutgoingMsg for EOS failed", this));
2146 return status;
2147 }
2148 else
2149 {
2150 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
2151 uint32 timebase32 = 0;
2152 uint32 clientClock32 = 0;
2153 bool overflowFlag = false;
2154 iClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag,
2155 PVMF_MEDIA_CLOCK_MSEC, timebase32);
2156 PVMF_MLNODE_LOGDATATRAFFIC_OUT((0,
2157 "PVMFMediaLayerNode::ProcessInputMsg_OneToN: Sending EOS - MimeType=%s, StreamId=%d, Clock=%d",
2158 pinputPort->iMimeType.get_cstr(),
2159 msgIn->getStreamID(),
2160 clientClock32));
2161 #endif
2162 }
2163 }
2164 }
2165 }
2166 else
2167 {
2168
2169 /* unknown command - pass it along */
2170 for (uint i = 0; i < pinputPort->vCounterPorts.size(); i++)
2171 {
2172 PVMFMediaLayerPortContainer* poutPort = &this->iPortParamsQueue[pinputPort->vCounterPorts[i]];
2173 status = poutPort->iPort->QueueOutgoingMsg(msgIn);
2174
2175 if (status != PVMFSuccess)
2176 {
2177 PVMF_MLNODE_LOGERROR((0,
2178 "0x%x PVMFMediaLayerNode::ProcessInputMsg_OneToN: "
2179 "Error - QueueOutgoingMsg for MediaCmd=%d failed", msgFormatID, this));
2180 return status;
2181 }
2182 else
2183 {
2184 poutPort->iReConfig = false;
2185 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
2186 uint32 timebase32 = 0;
2187 uint32 clientClock32 = 0;
2188 bool overflowFlag = false;
2189 iClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
2190 PVMF_MLNODE_LOGDATATRAFFIC_OUT((0,
2191 "PVMFMediaLayerNode::ProcessInputMsg_OneToN: Sending MediaCmd - CmdId=%d, MimeType=%s Clock=%2d",
2192 msgFormatID, pinputPort->iMimeType.get_cstr(), clientClock32));
2193 #endif
2194 }
2195 }
2196 }
2197 return status;
2198 }
2199
2200 //If error is detected in track config info, EOS should be sent.
2201 for (uint k = 0; k < pinputPort->vCounterPorts.size(); k++)
2202 {
2203 PVMFMediaLayerPortContainer* poutPort = &this->iPortParamsQueue[pinputPort->vCounterPorts[k]];
2204 if (poutPort->oDisableTrack == true && poutPort->oDetectBrokenTrack == true)
2205 {
2206 poutPort->oDetectBrokenTrack = false;
2207 poutPort->iFirstFrameAfterRepositioning = false;
2208 poutPort->iContinuousTimeStamp += PVMF_MEDIA_LAYER_NODE_ASF_REPOS_TIME_OFFSET_IN_MS;
2209 status = sendEndOfTrackCommand(poutPort);
2210 if (status != PVMFSuccess)
2211 {
2212 PVMF_MLNODE_LOGERROR((0,
2213 "0x%x PVMFMediaLayerNode::ProcessInputMsg_OneToN: "
2214 "Error - QueueOutgoingMsg for EOS failed", this));
2215 return status;
2216 }
2217 }
2218 }
2219
2220 if (pinputPort->oEOSReached == true)
2221 {
2222 PVMF_MLNODE_LOGWARNING((0,
2223 "PVMFMediaLayerNode::ProcessInputMsg_OneToN: "
2224 "Msg too late, discard - EOS already sent"));
2225 return PVMFSuccess;
2226 }
2227
2228 //
2229 // unpack the payload data
2230 //
2231 PVMFSharedMediaDataPtr dataIn;
2232 convertToPVMFMediaData(dataIn, msgIn);
2233 iPayLoad.vfragments.clear();
2234 iPayLoad.stream = dataIn->getStreamID();
2235 iPayLoad.marker = (dataIn->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_M_BIT);
2236 if (dataIn->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT)
2237 iPayLoad.randAccessPt = true;
2238 iPayLoad.sequence = dataIn->getSeqNum();
2239 iPayLoad.timestamp = dataIn->getTimestamp();
2240 pinputPort->iCurrFormatId = dataIn->getFormatID();
2241 OsclRefCounterMemFrag fsi;
2242 dataIn->getFormatSpecificInfo(fsi);
2243
2244 pinputPort->iCurrFormatSpecInfo = fsi;
2245
2246 for (uint f = 0; f < dataIn->getNumFragments(); f++)
2247 {
2248 OsclRefCounterMemFrag memFrag;
2249 dataIn->getMediaFragment(f, memFrag);
2250 iPayLoad.vfragments.push_back(memFrag);
2251 }
2252
2253 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
2254 uint32 inputDataSize = 0;
2255 /* Get input size for logging */
2256 uint32 inputNumFrags = dataIn->getNumFragments();
2257 for (uint32 i = 0; i < inputNumFrags; i++)
2258 {
2259 OsclRefCounterMemFrag memFrag;
2260 dataIn->getMediaFragment(i, memFrag);
2261 inputDataSize += memFrag.getMemFragSize();
2262 }
2263
2264 uint32 timebase32 = 0;
2265 uint32 clientClock32 = 0;
2266 bool overflowFlag = false;
2267 iClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
2268 PVMF_MLNODE_LOGDATATRAFFIC_IN((0,
2269 "PVMFMediaLayerNode::ProcessInputMsg_OneToN - Input: MimeType=%s, TS=%d, SEQNUM=%d, SIZE=%d, Clock=%d",
2270 pinputPort->iMimeType.get_cstr(), msgIn->getTimestamp(), msgIn->getSeqNum(), inputDataSize, clientClock32));
2271 #endif
2272
2273 PVMFMediaLayerPortContainer* poutPort = NULL;
2274 bool bRet = false;
2275 if (isOneToN == false)
2276 {
2277 bRet = GetPortContainer(getPortCounterpart(pinputPort), poutPort);
2278 }
2279
2280 //
2281 // parse the payload data until all payloads are extracted.
2282 // in case of http streaming, we parse audio & video data to each output port access units.
2283 //
2284 PayloadParserStatus retVal = PayloadParserStatus_InputNotExhausted;
2285 while (retVal == PayloadParserStatus_InputNotExhausted)
2286 {
2287 {
2288 if (bRet)
2289 {
2290 retVal =
2291 pinputPort->iPayLoadParser->Parse(iPayLoad,
2292 poutPort->vAccessUnits);
2293 }
2294 }
2295
2296 if ((retVal == PayloadParserStatus_MemorAllocFail) ||
2297 (retVal == PayloadParserStatus_Failure))
2298 {
2299 PVUuid eventuuid = PVMFMediaLayerNodeEventTypeUUID;
2300 int32 infocode = PVMFMediaLayerNodePayloadParserError;
2301 ReportInfoEvent(PVMFErrProcessing, (OsclAny*)(&(pinputPort->iMimeType)), &eventuuid, &infocode);
2302 PVMF_MLNODE_LOGWARNING((0,
2303 "PVMFMediaLayerNode::ProcessIncomingMsg: Error - parse Payload failed ErrCode = %d", retVal));
2304 status = PVMFFailure;
2305 }
2306 }
2307
2308 if (retVal != PayloadParserStatus_Success)
2309 {
2310 // no data ready yet
2311 return PVMFSuccess;
2312 }
2313
2314 return sendAccessUnits(pinputPort);
2315 }
2316
2317
sendAccessUnits(PVMFMediaLayerPortContainer * pinputPort)2318 PVMFStatus PVMFMediaLayerNode::sendAccessUnits(PVMFMediaLayerPortContainer* pinputPort)
2319 {
2320
2321 PVMFStatus status = PVMFSuccess;
2322 bool checkAccessUnitsSize = false;
2323
2324 for (uint i = 0; i < pinputPort->vCounterPorts.size(); i++)
2325 {
2326 PVMFMediaLayerPortContainer* poutPort =
2327 &this->iPortParamsQueue[pinputPort->vCounterPorts[i]];
2328
2329 if (poutPort->vAccessUnits.size() > 0)
2330 {
2331 checkAccessUnitsSize = true;
2332
2333 if ((poutPort->iPort->IsOutgoingQueueBusy() == false) &&
2334 (poutPort->ipFragGroupAllocator->IsMsgAvailable() == true))
2335 {
2336 //send each access unit to its respective port
2337 status = dispatchAccessUnits(pinputPort, poutPort);
2338 }
2339 else
2340 {
2341 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
2342 "PVMFMediaLayerNode::sendAccessUnits: Port / Mem Pool Busy - Mime=%s vQ=%d",
2343 poutPort->iMimeType.get_cstr(), poutPort->vAccessUnits.size()));
2344 status = PVMFErrBusy;
2345 }
2346 if (status == PVMFErrBusy)
2347 {
2348 // Processing will resume when we get freechunkavailable notice from the port.
2349 pinputPort->oProcessIncomingMessages = false;
2350 {
2351 if (!poutPort->ipFragGroupAllocator->IsMsgAvailable())
2352 {
2353 poutPort->ipFragGroupAllocator->notifyfreechunkavailable(*((PVMFMediaLayerPort*)pinputPort->iPort));
2354 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
2355 "PVMFMediaLayerNode::sendAccessUnits: Calling notifyfreechunkavailable - Mime=%s vQ=%d",
2356 poutPort->iMimeType.get_cstr(), poutPort->vAccessUnits.size()));
2357 }
2358 }
2359 if (pinputPort->oProcessIncomingMessages == false)
2360 {
2361 // no media msgs available on any output port.
2362 // then we set oProcessIncomingMessages as false not to call ProcessIncomingMsg.
2363 status = PVMFErrBusy;
2364 break;
2365 }
2366 else
2367 {
2368 //at least, media msgs on one output port is available and we set oProcessIncomingMessages to true again.
2369 status = PVMFSuccess;
2370 continue;
2371 }
2372 }
2373 }
2374 }
2375 //in case that both output port vAccessUnits is empty and oProcessIncomingMessages is set as false,
2376 //we never set oProcessIncomingMessages to true and cannot call ProcessIncomingMsg.
2377 //to escape this situation, we check IsMsgAvailable for both output port here.
2378 if (checkAccessUnitsSize == false)
2379 {
2380 if (pinputPort->oProcessIncomingMessages == false)
2381 {
2382 if (pinputPort->oProcessIncomingMessages == false)
2383 {
2384 // no media msgs available on any output port
2385 status = PVMFErrBusy;
2386 }
2387 else
2388 {
2389 //at least, media msgs on one output port is available and we set oProcessIncomingMessages to true again.
2390 status = PVMFSuccess;
2391 }
2392 }
2393 }
2394 return status;
2395 }
2396
dispatchAccessUnits(PVMFMediaLayerPortContainer * pinputPort,PVMFMediaLayerPortContainer * poutPort)2397 PVMFStatus PVMFMediaLayerNode::dispatchAccessUnits(PVMFMediaLayerPortContainer* pinputPort,
2398 PVMFMediaLayerPortContainer* poutPort)
2399 {
2400 PVMFStatus status = PVMFSuccess;
2401 //
2402 // send each access unit to its respective port
2403 //
2404 typedef Oscl_Vector<IPayloadParser::Payload, OsclMemAllocator>::iterator iterator_type;
2405 iterator_type it;
2406 for (it = poutPort->vAccessUnits.begin(); it != poutPort->vAccessUnits.end(); it++)
2407 {
2408 // check out port status
2409 if (poutPort->iPort->IsOutgoingQueueBusy())
2410 {
2411 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
2412 "PVMFMediaLayerNode::dispatchAccessUnits: Output Port Busy - Mime=%s", poutPort->iMimeType.get_cstr()));
2413 status = PVMFErrBusy;
2414 break;
2415 }
2416 //
2417 // check if a media message is available
2418 //
2419 if (!poutPort->ipFragGroupAllocator->IsMsgAvailable())
2420 {
2421 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0, "PVMFMediaLayerNode::dispatchAccessUnits: Can't send - Waiting for free buffers - Mime=%s vQ=%d", poutPort->iMimeType.get_cstr(), poutPort->vAccessUnits.size()));
2422 status = PVMFErrBusy;
2423 break;
2424 }
2425
2426 // retrieve a data implementation
2427 OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
2428 bool retVal;
2429 retVal = Allocate(mediaDataImplOut, poutPort);
2430
2431 if (retVal == false)
2432 {
2433 status = PVMFErrNoMemory;
2434 break;
2435 }
2436
2437 // Once we detect received DATA is same as reconfig streamID, we send reconfig msg first.
2438 // Reconfig streamID is informed from SM node at switchstream.
2439 if (poutPort->iReConfig == true && poutPort->oReconfigId == it->stream)
2440 {
2441 if (poutPort->oMsgReconfig.GetRep() != NULL)
2442 {
2443 PVMFSharedMediaDataPtr mediaData;
2444 convertToPVMFMediaData(mediaData, poutPort->oMsgReconfig);
2445
2446 status = poutPort->iPort->QueueOutgoingMsg(poutPort->oMsgReconfig);
2447
2448 if (status != PVMFSuccess)
2449 {
2450 PVMF_MLNODE_LOGERROR((0,
2451 "0x%x PVMFMediaLayerNode::dispatchAccessUnits: "
2452 "Error - QueueOutgoingMsg for ReConfig failed", this));
2453 return status;
2454 }
2455 else
2456 {
2457 poutPort->iReConfig = false;
2458 poutPort->oReconfigId = 0;
2459 poutPort->oMsgReconfig.Unbind();
2460 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
2461 uint32 timebase32 = 0;
2462 uint32 clientClock32 = 0;
2463 bool overflowFlag = false;
2464 iClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
2465 PVMF_MLNODE_LOGDATATRAFFIC_OUT((0,
2466 "PVMFMediaLayerNode::dispatchAccessUnits: Sending ReConfig - MimeType=%s Clock=%2d",
2467 poutPort->iMimeType.get_cstr(), clientClock32));
2468 #endif
2469 }
2470 }
2471 else
2472 {
2473 poutPort->iReConfig = false;
2474 PVUuid eventuuid = PVMFMediaLayerNodeEventTypeUUID;
2475 int32 infocode = PVMFMediaLayerNodePayloadParserError;
2476 ReportErrorEvent(PVMFErrResourceConfiguration, (OsclAny*)(&(poutPort->iMimeType)), &eventuuid, &infocode);
2477
2478 PVMF_MLNODE_LOGDATATRAFFIC_E((0, "PVMFMediaLayerNode::dispatchAccessUnits: Error - We don't receive Reconfig msg yet - Mime=%s vQ=%d", poutPort->iMimeType.get_cstr(), poutPort->vAccessUnits.size()));
2479 SetState(EPVMFNodeError);
2480 status = PVMFFailure;
2481 break;
2482 }
2483 }
2484
2485
2486 // fill the data implementation with the contents of the payload structure
2487 uint32 markerInfo = 0;
2488 if (it->marker == 1)
2489 {
2490 markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_M_BIT;
2491 }
2492 if (it->randAccessPt == true)
2493 {
2494 markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT;
2495 }
2496
2497 if (it->endOfNAL)
2498 {
2499 markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_END_OF_NAL_BIT;
2500 }
2501
2502 mediaDataImplOut->setMarkerInfo(markerInfo);
2503 mediaDataImplOut->setRandomAccessPoint(it->randAccessPt);
2504 for (uint j = 0; j < it->vfragments.size(); j++)
2505 {
2506 mediaDataImplOut->appendMediaFragment(it->vfragments[j]);
2507 }
2508
2509 // create a data message
2510 PVMFMediaMsgHeader newMsgHeader;
2511 newMsgHeader.format_id = pinputPort->iCurrFormatId;
2512 PVMFSharedMediaDataPtr mediaDataOut =
2513 PVMFMediaData::createMediaData(mediaDataImplOut, &newMsgHeader);
2514 /*
2515 * Could happen during bitstream switching,
2516 * asf payload parser starts seq num for each stream from zero
2517 */
2518 if (it->sequence < poutPort->iPrevMsgSeqNum)
2519 {
2520 poutPort->iPrevMsgSeqNum++;
2521 it->sequence = poutPort->iPrevMsgSeqNum;
2522 }
2523 else
2524 {
2525 poutPort->iPrevMsgSeqNum = it->sequence;
2526 }
2527 mediaDataOut->setSeqNum(it->sequence);
2528 mediaDataOut->setStreamID(it->stream);
2529 mediaDataOut->setTimestamp(it->timestamp);
2530 mediaDataOut->setFormatSpecificInfo(pinputPort->iCurrFormatSpecInfo);
2531
2532 /* Decrypt sample if protected */
2533 if (iDecryptionInterface != NULL)
2534 {
2535 if (iDecryptionInterface->CanDecryptInPlace())
2536 {
2537 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::dispatchAccessUnits() Decryption is needed"));
2538
2539 /* Retrieve memory fragment to write to */
2540 OsclRefCounterMemFrag refCtrMemFragOut;
2541 OsclMemoryFragment memFragOut;
2542 uint32 num = mediaDataOut->getNumFragments();
2543 uint32 totalPayloadSize = mediaDataOut->getFilledSize();
2544 uint8* srcDrmPtr = srcPtr;
2545 uint32 payloadSize = 0;
2546
2547 for (uint32 i = 0; i < num; i++)
2548 {
2549 mediaDataOut->getMediaFragment(i, refCtrMemFragOut);
2550 memFragOut.ptr = refCtrMemFragOut.getMemFrag().ptr;
2551 payloadSize = refCtrMemFragOut.getMemFrag().len;
2552 oscl_memcpy(srcDrmPtr, (uint8*)(memFragOut.ptr), (payloadSize*sizeof(uint8)));
2553
2554 srcDrmPtr += payloadSize;
2555 payloadSize = 0;
2556
2557 }
2558
2559 if (totalPayloadSize > maxPacketSize)
2560 {
2561 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::dispatchAccessUnits() - PayloadSize is bigger than Packet size"));
2562 return PVMFFailure;
2563 }
2564
2565 bool oDecryptRet =
2566 iDecryptionInterface->DecryptAccessUnit(srcPtr,
2567 totalPayloadSize);
2568 srcDrmPtr = srcPtr;
2569 for (uint32 j = 0; j < num; j++)
2570 {
2571 mediaDataOut->getMediaFragment(j, refCtrMemFragOut);
2572 memFragOut.ptr = refCtrMemFragOut.getMemFrag().ptr;
2573 payloadSize = refCtrMemFragOut.getMemFrag().len;
2574 oscl_memcpy((uint8*)(memFragOut.ptr), srcDrmPtr, (payloadSize*sizeof(uint8)));
2575
2576 srcDrmPtr += payloadSize;
2577 payloadSize = 0;
2578
2579 }
2580 if (oDecryptRet != true)
2581 {
2582 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::dispatchAccessUnits() - Decrypt Sample Failed"));
2583 return PVMFFailure;
2584 }
2585
2586 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::dispatchAccessUnits() Decryption completed : payload lenght=%d", totalPayloadSize));
2587 }
2588 else
2589 {
2590 /* We always decrpt in place for Janus */
2591 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::dispatchAccessUnits() - Inplace Decrypt Not available"));
2592 OSCL_ASSERT(false);
2593 }
2594 }
2595
2596 // queue the message
2597 PVMFSharedMediaMsgPtr msgOut;
2598 convertToPVMFMediaMsg(msgOut, mediaDataOut);
2599
2600
2601 // send the message
2602 msgOut->setStreamID(iStreamID);
2603 status = poutPort->iPort->QueueOutgoingMsg(msgOut);
2604
2605 if (status == PVMFErrBusy)
2606 {
2607 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
2608 "PVMFMediaLayerNode::dispatchAccessUnits: Outgoing Queue Busy - MimeType=%s", poutPort->iMimeType.get_cstr()));
2609 break;
2610 }
2611 else if (status != PVMFSuccess)
2612 {
2613 PVMF_MLNODE_LOGERROR((0,
2614 "0x%x PVMFMediaLayerNode::sendAccessUnits: "
2615 "Error - QueueOutgoingMsg failed", this));
2616 break;
2617 }
2618 else
2619 {
2620 #if (PVLOGGER_INST_LEVEL > PVLOGMSG_INST_LLDBG)
2621 if (oPortDataLog)
2622 {
2623 LogMediaData(mediaDataOut, pinputPort->iPort);
2624 }
2625
2626 uint32 timebase32 = 0;
2627 uint32 clientClock32 = 0;
2628 bool overflowFlag = false;
2629 iClientPlayBackClock->GetCurrentTime32(clientClock32, overflowFlag, PVMF_MEDIA_CLOCK_MSEC, timebase32);
2630
2631 /* Get size for log purposes */
2632 uint32 numFrags = mediaDataOut->getNumFragments();
2633 uint32 size = 0;
2634 OsclRefCounterMemFrag memFrag;
2635 for (uint32 sizecount = 0; sizecount < numFrags; sizecount++)
2636 {
2637 mediaDataOut->getMediaFragment(sizecount, memFrag);
2638 size += memFrag.getMemFragSize();
2639 }
2640 PVMF_MLNODE_LOGDATATRAFFIC_OUT((0,
2641 "PVMFMediaLayerNode::dispatchAccessUnits: "
2642 "SSRC=%d, MimeType=%s SIZE=%d, TS=%d, SEQNUM=%d, MBIT=%d, KEY=%d, Clock=%d Delta=%d",
2643 msgOut->getStreamID(), poutPort->iMimeType.get_cstr(),
2644 size, msgOut->getTimestamp(), msgOut->getSeqNum(),
2645 (mediaDataOut->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_M_BIT),
2646 (mediaDataOut->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT),
2647 clientClock32, (msgOut->getTimestamp() - clientClock32)));
2648 #endif
2649 }
2650 }
2651 // clear payloads successfully sent
2652 if (it != poutPort->vAccessUnits.begin())
2653 {
2654 // there is something to delete (if it == v.begin() then nothing was processed in the loop)
2655 it = poutPort->vAccessUnits.erase(poutPort->vAccessUnits.begin(), it);
2656 }
2657 return status;
2658 }
2659
Allocate(OsclSharedPtr<PVMFMediaDataImpl> & mediaDataImplOut,PVMFMediaLayerPortContainer * poutPort)2660 bool PVMFMediaLayerNode::Allocate(OsclSharedPtr<PVMFMediaDataImpl>& mediaDataImplOut, PVMFMediaLayerPortContainer* poutPort)
2661 {
2662 int32 err;
2663 OSCL_TRY_NO_TLS(iOsclErrorTrapImp, err, mediaDataImplOut = poutPort->ipFragGroupAllocator->allocate());
2664 OSCL_ASSERT(err == OsclErrNone); // we just checked that a message is available
2665
2666 if (err != OsclErrNone)
2667 {
2668 return false;
2669 }
2670 return true;
2671 }
2672
checkOutputPortsBusy(PVMFMediaLayerPortContainer * pinputPort)2673 bool PVMFMediaLayerNode::checkOutputPortsBusy(PVMFMediaLayerPortContainer* pinputPort)
2674 {
2675 OSCL_ASSERT(pinputPort->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT);
2676
2677 // check each output port's queue status
2678 // return true only if ALL output ports are busy
2679 for (uint i = 0; i < pinputPort->vCounterPorts.size(); i++)
2680 {
2681 if (iPortParamsQueue[pinputPort->vCounterPorts[i]].iPort->IsOutgoingQueueBusy() == false)
2682 {
2683 return false;
2684 }
2685 }
2686
2687 return true;
2688 }
2689
ProcessOutgoingMsg(PVMFMediaLayerPortContainer * aPortContainer)2690 PVMFStatus PVMFMediaLayerNode::ProcessOutgoingMsg(PVMFMediaLayerPortContainer* aPortContainer)
2691 {
2692 PVMFPortInterface* aPort = aPortContainer->iPort;
2693 PVMF_MLNODE_LOGINFO((0, "0x%x PVMFMediaLayerNode::ProcessOutgoingMsg: aPort=0x%x", this, aPort));
2694
2695 PVMFStatus status;
2696 if (aPortContainer->tag == PVMF_MEDIALAYER_PORT_TYPE_OUTPUT)
2697 {
2698 /*
2699 * If connected port is busy, the outgoing message cannot be process. It will be
2700 * queued to be processed again after receiving PORT_ACTIVITY_CONNECTED_PORT_READY
2701 * from this port.
2702 */
2703 if (aPort->IsConnectedPortBusy())
2704 {
2705 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
2706 "0x%x PVMFMediaLayerNode::ProcessOutgoingMsg: Connected port is busy", this));
2707 aPortContainer->oProcessOutgoingMessages = false;
2708 return PVMFErrBusy;
2709 }
2710
2711 status = aPort->Send();
2712 if (status == PVMFErrBusy)
2713 {
2714 PVMF_MLNODE_LOGDATATRAFFIC_FLOWCTRL((0,
2715 "0x%x PVMFMediaLayerNode::ProcessOutgoingMsg: Connected port goes into busy state", this));
2716 aPortContainer->oProcessOutgoingMessages = false;
2717 }
2718 PVMF_MLNODE_LOGINFO((0,
2719 "PVMFMediaLayerNode::ProcessOutgoingMsg: Send - %s", aPortContainer->iMimeType.get_cstr()));
2720 }
2721 else
2722 {
2723 ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aPort));
2724 PVMF_MLNODE_LOGERROR((0,
2725 "0x%x PVMFMediaLayerNode::ProcessOutgoingMsg: Error - Not an Output Port", this));
2726 status = PVMFFailure;
2727 }
2728 return status;
2729 }
2730
CheckForPortRescheduling()2731 bool PVMFMediaLayerNode::CheckForPortRescheduling()
2732 {
2733 uint32 i;
2734 for (i = 0; i < iPortVector.size(); i++)
2735 {
2736 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
2737
2738 if (!GetPortContainer(iPortVector[i], portContainerPtr))
2739 {
2740 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::CheckForPortRescheduling: Error - GetPortContainer failed", this));
2741 return false;
2742 }
2743
2744 if (portContainerPtr->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT)
2745 {
2746 if (portContainerPtr->iPort->IncomingMsgQueueSize() > 0)
2747 {
2748 if (portContainerPtr->oProcessIncomingMessages)
2749 {
2750 if (oEOSsendunits)
2751 return false;
2752 /*
2753 * Found a port that has outstanding activity and
2754 * is not busy.
2755 */
2756 return true;
2757 }
2758 }
2759 }
2760 else if (portContainerPtr->tag == PVMF_MEDIALAYER_PORT_TYPE_OUTPUT)
2761 {
2762 /*
2763 * If there are output msgs waiting and if the connected port
2764 * is not busy - reschedule
2765 */
2766 if ((portContainerPtr->iPort->OutgoingMsgQueueSize() > 0) &&
2767 (portContainerPtr->oProcessOutgoingMessages))
2768 {
2769 /*
2770 * Found a port that has outstanding activity and
2771 * is not busy.
2772 */
2773 return true;
2774 }
2775 /*
2776 * If there are payload access units msgs waiting and if the connected port
2777 * is not busy or message is available - reschedule
2778 * If another output port is ok and the connected port is busy, we do not reschedule.
2779 */
2780 if (portContainerPtr->vAccessUnits.size() > 0)
2781 {
2782 if ((portContainerPtr->iPort->IsOutgoingQueueBusy() == false) &&
2783 (portContainerPtr->ipFragGroupAllocator->IsMsgAvailable() == true))
2784 {
2785 /*
2786 * Found payload access units msgs that is available and outgoing queue
2787 * is not busy.
2788 */
2789 return true;
2790 }
2791 }
2792 }
2793 }
2794 /*
2795 * No port processing needed - either all port activity queues are empty
2796 * or the ports are backed up due to flow control.
2797 */
2798 return false;
2799 }
2800
CheckForPortActivityQueues()2801 bool PVMFMediaLayerNode::CheckForPortActivityQueues()
2802 {
2803 uint32 i;
2804 for (i = 0; i < iPortVector.size(); i++)
2805 {
2806 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
2807
2808 if (!GetPortContainer(iPortVector[i], portContainerPtr))
2809 {
2810 PVMF_MLNODE_LOGERROR((0, "0x%x PVMFMediaLayerNode::CheckForPortRescheduling: Error - GetPortContainer failed", this));
2811 return false;
2812 }
2813
2814 if ((portContainerPtr->iPort->IncomingMsgQueueSize() > 0) ||
2815 (portContainerPtr->iPort->OutgoingMsgQueueSize() > 0))
2816 {
2817 /*
2818 * Found a port that still has an outstanding activity.
2819 */
2820 return true;
2821 }
2822 }
2823 /*
2824 * All port activity queues are empty
2825 */
2826 return false;
2827 }
2828
2829 /**
2830 * Active object implementation
2831 */
2832 /**
2833 * This AO handles both API commands and port activity.
2834 * The AO will either process one command or service all connected
2835 * ports once per call. It will re-schedule itself and run continuously
2836 * until it runs out of things to do.
2837 */
Run()2838 void PVMFMediaLayerNode::Run()
2839 {
2840 iNumRunL++;
2841
2842 uint32 startticks = OsclTickCount::TickCount();
2843 uint32 starttime = OsclTickCount::TicksToMsec(startticks);
2844
2845 uint32 i;
2846 /* Process commands */
2847 if (!iInputCommands.empty())
2848 {
2849 if (ProcessCommand(iInputCommands.front()))
2850 {
2851 /*
2852 * note: need to check the state before re-scheduling
2853 * since the node could have been reset in the ProcessCommand
2854 * call.
2855 */
2856 if (iInterfaceState != EPVMFNodeCreated)
2857 {
2858 if (IsAdded())
2859 {
2860 RunIfNotReady();
2861 }
2862 }
2863 return;
2864 }
2865 }
2866
2867 /*
2868 * Process ports activity - This node would run thru the entire
2869 * list of ports and would try and process atleast one actvity per
2870 * port.
2871 */
2872 if (iInterfaceState == EPVMFNodeStarted || FlushPending())
2873 {
2874 bool oRescheduleBasedOnPorts = false;
2875 bool oContinueToProcess = true;
2876 uint32 count = 0;
2877 uint32 timespentinloop = 0;
2878 while (oContinueToProcess)
2879 {
2880 count++;
2881 for (i = 0; i < iPortVector.size(); i++)
2882 {
2883 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
2884
2885 if (!GetPortContainer(iPortVector[i], portContainerPtr))
2886 {
2887 PVMF_MLNODE_LOGERROR((0, "PVMFMediaLayerNode::Run: Error - GetPortContainer failed"));
2888 return;
2889 }
2890
2891 ProcessPortActivity(portContainerPtr);
2892 }
2893
2894 oRescheduleBasedOnPorts = CheckForPortRescheduling();
2895
2896 uint32 currticks = OsclTickCount::TickCount();
2897 uint32 currtime = OsclTickCount::TicksToMsec(currticks);
2898 timespentinloop += (currtime - starttime);
2899
2900 if (timespentinloop < MEDIALAYERNODE_MAX_RUNL_TIME_IN_MS)
2901 {
2902 if (oRescheduleBasedOnPorts == false)
2903 {
2904 // we have time, but we have nothing to do
2905 oContinueToProcess = false;
2906 }
2907 }
2908 else
2909 {
2910 //we have exceeded time limit so yield, if we have more stuff to do
2911 //we will reschedule below
2912 oContinueToProcess = false;
2913 }
2914 }
2915 if (oRescheduleBasedOnPorts)
2916 {
2917 if (IsAdded())
2918 {
2919 /*
2920 * Re-schedule since there is atleast one port that needs processing
2921 */
2922 RunIfNotReady();
2923 }
2924 }
2925 PVMF_MLNODE_LOG_RUNL((0, "PVMFMediaLayerNode::Run: NumLoops=%d, TotalTime=%d ms", count, timespentinloop));
2926 return;
2927 }
2928
2929 /*
2930 * If we get here we did not process any ports or commands.
2931 * Check for completion of a flush command...
2932 */
2933 if (FlushPending() && (!CheckForPortActivityQueues()))
2934 {
2935 /*
2936 * Debug check-- all the port queues should be empty at
2937 * this point.
2938 */
2939 for (i = 0; i < iPortVector.size(); i++)
2940 {
2941 if (iPortVector[i]->IncomingMsgQueueSize() > 0 ||
2942 iPortVector[i]->OutgoingMsgQueueSize() > 0)
2943 {
2944 OSCL_ASSERT(false);
2945 }
2946 }
2947 /*
2948 * Flush is complete. Go to prepared state.
2949 */
2950 SetState(EPVMFNodePrepared);
2951 /*
2952 * resume port input so the ports can be re-started.
2953 */
2954 for (i = 0; i < iPortVector.size(); i++)
2955 {
2956 iPortVector[i]->ResumeInput();
2957 }
2958 CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
2959 if (IsAdded())
2960 {
2961 RunIfNotReady();
2962 }
2963 }
2964 }
2965
DoCancel()2966 void PVMFMediaLayerNode::DoCancel()
2967 {
2968 /* the base class cancel operation is sufficient */
2969 OsclActiveObject::DoCancel();
2970 }
2971
2972 bool
GetPortContainer(PVMFPortInterface * aPort,PVMFMediaLayerPortContainer & aContainer)2973 PVMFMediaLayerNode::GetPortContainer(PVMFPortInterface* aPort,
2974 PVMFMediaLayerPortContainer& aContainer)
2975 {
2976 uint32 i;
2977 for (i = 0; i < iPortParamsQueue.size(); i++)
2978 {
2979 PVMFMediaLayerPortContainer portParams = iPortParamsQueue[i];
2980
2981 if (portParams.iPort == aPort)
2982 {
2983 aContainer = portParams;
2984 return true;
2985 }
2986 }
2987 return false;
2988 }
2989
2990 bool
GetPortContainer(PVMFPortInterface * aPort,int & index)2991 PVMFMediaLayerNode::GetPortContainer(PVMFPortInterface* aPort, int& index)
2992 {
2993 for (index = 0; index < (int)iPortParamsQueue.size(); index++)
2994 {
2995 if (iPortParamsQueue[index].iPort == aPort)
2996 {
2997 return true;
2998 }
2999 }
3000
3001 return false;
3002 }
3003 bool
GetPortContainer(PVMFPortInterface * aPort,PVMFMediaLayerPortContainer * & aContainerPtr)3004 PVMFMediaLayerNode::GetPortContainer(PVMFPortInterface* aPort,
3005 PVMFMediaLayerPortContainer*& aContainerPtr)
3006 {
3007 Oscl_Vector<PVMFMediaLayerPortContainer, PVMFMediaLayerNodeAllocator>::iterator it;
3008 for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
3009 {
3010 if (it->iPort == aPort)
3011 {
3012 aContainerPtr = it;
3013 return true;
3014 }
3015 }
3016 return false;
3017 }
3018
3019 PVMFPortInterface*
getPortCounterpart(PVMFMediaLayerPortContainer aContainer)3020 PVMFMediaLayerNode::getPortCounterpart(PVMFMediaLayerPortContainer aContainer)
3021 {
3022 return iPortParamsQueue[aContainer.vCounterPorts[0]].iPort;
3023 }
3024
3025 PVMFPortInterface*
getPortCounterpart(PVMFMediaLayerPortContainer * aContainerPtr)3026 PVMFMediaLayerNode::getPortCounterpart(PVMFMediaLayerPortContainer* aContainerPtr)
3027 {
3028 return iPortParamsQueue[aContainerPtr->vCounterPorts[0]].iPort;
3029 }
3030
3031 void
LogMediaData(PVMFSharedMediaDataPtr data,PVMFPortInterface * aPort)3032 PVMFMediaLayerNode::LogMediaData(PVMFSharedMediaDataPtr data,
3033 PVMFPortInterface* aPort)
3034 {
3035 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
3036 if (!GetPortContainer(aPort, portContainerPtr))
3037 {
3038 return;
3039 }
3040
3041 PVMFMediaData* mediaData = data.GetRep();
3042
3043 if (mediaData != NULL)
3044 {
3045 OsclRefCounterMemFrag memFrag;
3046 /* Get Format Specific Info, if any */
3047 mediaData->getFormatSpecificInfo(memFrag);
3048 OsclAny* ptr = memFrag.getMemFragPtr();
3049 uint32 size = memFrag.getMemFragSize();
3050
3051 OSCL_StackString<8> h264("H264");
3052 if ((size > 0) && (portContainerPtr->oFormatSpecificInfoLogged == false))
3053 {
3054 portContainerPtr->oFormatSpecificInfoLogged = true;
3055 if (!oscl_strcmp(portContainerPtr->iMimeType.get_cstr(), h264.get_cstr()))
3056 {
3057 PVMF_MLNODE_LOGBIN(portContainerPtr->iPortLogger, (0, 1, sizeof(uint32), &size));
3058 }
3059 PVMF_MLNODE_LOGBIN(portContainerPtr->iPortLogger, (0, 1, size, ptr));
3060 }
3061
3062 /* Log Media Fragments */
3063 uint32 numFrags = mediaData->getNumFragments();
3064 for (uint32 i = 0; i < numFrags; i++)
3065 {
3066 mediaData->getMediaFragment(i, memFrag);
3067 ptr = memFrag.getMemFragPtr();
3068 size = memFrag.getMemFragSize();
3069 if (!oscl_strcmp(portContainerPtr->iMimeType.get_cstr(), h264.get_cstr()))
3070 {
3071 PVMF_MLNODE_LOGBIN(portContainerPtr->iPortLogger, (0, 1, sizeof(uint32), &size));
3072 }
3073 PVMF_MLNODE_LOGBIN(portContainerPtr->iPortLogger, (0, 1, size, ptr));
3074 }
3075 }
3076 }
3077
3078
CheckForEOS()3079 bool PVMFMediaLayerNode::CheckForEOS()
3080 {
3081 Oscl_Vector<PVMFMediaLayerPortContainer, PVMFMediaLayerNodeAllocator>::iterator it;
3082 for (it = iPortParamsQueue.begin();
3083 it != iPortParamsQueue.end();
3084 it++)
3085 {
3086 if (it->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT)
3087 {
3088 if (it->oEOSReached == false)
3089 {
3090 return false;
3091 }
3092 }
3093 }
3094 return true;
3095 }
3096
3097 bool
setPortMediaParams(PVMFPortInterface * aPort,OsclRefCounterMemFrag & aConfig,mediaInfo * aMediaInfo)3098 PVMFMediaLayerNode::setPortMediaParams(PVMFPortInterface* aPort,
3099 OsclRefCounterMemFrag& aConfig,
3100 mediaInfo* aMediaInfo)
3101 {
3102 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
3103
3104 if (!GetPortContainer(aPort, portContainerPtr))
3105 {
3106 return false;
3107 }
3108
3109 /*
3110 * there is a previously set config. make a note of it.
3111 * in case a re config media cmd comes along we would send out this config
3112 */
3113 if (portContainerPtr->iTrackConfig.getMemFragSize() > 0)
3114 {
3115 portContainerPtr->iReConfig = true;
3116 }
3117 portContainerPtr->iTrackConfig = aConfig;
3118
3119 // this method is called for input and output ports
3120 if (portContainerPtr->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT)
3121 {
3122 return portContainerPtr->iPayLoadParser->Init(aMediaInfo);
3123 }
3124 else
3125 {
3126 return true;
3127 }
3128
3129 }
3130
3131 PVMFStatus
verifyPortConfigParams(const char * aFormatValType,PVMFPortInterface * aPort,OsclAny * aConfig,mediaInfo * aMediaInfo)3132 PVMFMediaLayerNode::verifyPortConfigParams(const char* aFormatValType,
3133 PVMFPortInterface* aPort,
3134 OsclAny* aConfig,
3135 mediaInfo* aMediaInfo)
3136 {
3137 OSCL_UNUSED_ARG(aMediaInfo);
3138 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
3139 if (GetPortContainer(aPort, portContainerPtr))
3140 {
3141 if (portContainerPtr->tag == PVMF_MEDIALAYER_PORT_TYPE_OUTPUT)
3142 {
3143 PVMFMediaLayerPort* mediaLayerNodePort = OSCL_STATIC_CAST(PVMFMediaLayerPort*, aPort);
3144
3145 PVMFStatus status =
3146 mediaLayerNodePort->pvmiVerifyPortFormatSpecificInfoSync(aFormatValType,
3147 aConfig);
3148 return status;
3149 }
3150 }
3151 return PVMFErrArgument;
3152 }
3153
3154 bool
setTrackDisable(PVMFPortInterface * aPort)3155 PVMFMediaLayerNode::setTrackDisable(PVMFPortInterface* aPort)
3156 {
3157 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
3158 if (GetPortContainer(aPort, portContainerPtr))
3159 {
3160 portContainerPtr->oDetectBrokenTrack = true;
3161 portContainerPtr->oDisableTrack = true;
3162 return true;
3163 }
3164 return false;
3165 }
3166
3167 bool
setOutPortStreamParams(PVMFPortInterface * aPort,uint streamid,uint32 aPreroll,bool aLiveStream)3168 PVMFMediaLayerNode::setOutPortStreamParams(PVMFPortInterface* aPort,
3169 uint streamid,
3170 uint32 aPreroll,
3171 bool aLiveStream)
3172 {
3173 OSCL_UNUSED_ARG(streamid);
3174 OSCL_UNUSED_ARG(aPreroll);
3175 OSCL_UNUSED_ARG(aLiveStream);
3176 PVMFMediaLayerPortContainer* outPort = NULL;
3177 int id;
3178
3179 if (!GetPortContainer(aPort, id))
3180 {
3181 return false;
3182 }
3183 else
3184 {
3185 outPort = &iPortParamsQueue[id];
3186 }
3187
3188 return true;
3189 }
3190
parseOutputPortMime(OSCL_String * pmime,uint & inputPort)3191 bool PVMFMediaLayerNode::parseOutputPortMime(OSCL_String* pmime,
3192 uint& inputPort)
3193 {
3194 char* param = NULL;
3195
3196 // get the input-port parameter from the mime string
3197 pv_mime_string_extract_param(0, (char*)pmime->get_cstr(), param);
3198 if (param == NULL)
3199 {
3200 return false;
3201 }
3202
3203 // now, find where the parameter value starts
3204 do
3205 {
3206 if (*param++ == '=')
3207 {
3208 break;
3209 }
3210 }
3211 while (*param != 0);
3212
3213 if (*param == 0)
3214 {
3215 // end of string
3216 return false;
3217 }
3218
3219 // retrieve the numeric parameter value
3220 return PV_atoi(param, 'd', (uint32&)inputPort);
3221 }
3222
3223
setInPortReposFlag(PVMFPortInterface * aPort,uint32 aSeekTimeInMS)3224 void PVMFMediaLayerNode::setInPortReposFlag(PVMFPortInterface* aPort, uint32 aSeekTimeInMS)
3225 {
3226 PVMFMediaLayerPortContainer* portContainerPtr = NULL;
3227
3228 PVMF_MLNODE_LOGINFO((0, "0x%x PVMFMediaLayerNode::setInPortReposFlag In", this));
3229
3230 GetPortContainer(aPort, portContainerPtr);
3231
3232 OSCL_ASSERT(portContainerPtr != NULL);
3233 OSCL_ASSERT(portContainerPtr->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT);
3234 OSCL_ASSERT(portContainerPtr->iPayLoadParser != NULL);
3235
3236 portContainerPtr->oEOSReached = false;
3237
3238 // sequence numbers down to decoder must be sequential- find out min. packet seq number for each stream
3239 // before we delete unsent buffer so that subsequent seq numbers can be adjusted and gap closed
3240
3241 typedef Oscl_Vector<uint32, OsclMemAllocator> OsclUintVector;
3242 typedef Oscl_Vector<IPayloadParser::Payload, OsclMemAllocator>::iterator payload_iterator;
3243
3244 // maximum sequence number for given stream
3245 OsclUintVector vecMinSeqNum;
3246 // list of all streams that have unsent packets and need to be adjusted
3247 OsclUintVector vecStreamsRequiringAdjustment;
3248
3249 for (payload_iterator it = portContainerPtr->vAccessUnits.begin();
3250 it != portContainerPtr->vAccessUnits.end(); it++)
3251 {
3252 const uint32 currStreamNum = it->stream;
3253 const uint32 currSeq = it->sequence;
3254
3255 // check whether we have this stream number already in our records
3256 bool bStreamAlreadyListed = false;
3257 for (uint32 uiS = 0; uiS < vecStreamsRequiringAdjustment.size(); ++uiS)
3258 {
3259 if (vecStreamsRequiringAdjustment[uiS] == currStreamNum)
3260 {
3261 bStreamAlreadyListed = true;
3262 break;
3263 }
3264 }
3265 if (!bStreamAlreadyListed)
3266 vecStreamsRequiringAdjustment.push_back(currStreamNum);
3267
3268 // extend vector to cover all streams
3269 while (currStreamNum + 1 > vecMinSeqNum.size())
3270 vecMinSeqNum.push_back(0xFFFFFFFF);
3271
3272 // keep track of smallest value so far
3273 if (currSeq < vecMinSeqNum[currStreamNum])
3274 vecMinSeqNum[currStreamNum] = currSeq;
3275 }
3276
3277 // sequence generator keeps track of current sequence numbers. update it for all streams
3278
3279 for (OsclUintVector::iterator itStream = vecStreamsRequiringAdjustment.begin();
3280 itStream != vecStreamsRequiringAdjustment.end(); ++itStream)
3281 {
3282 portContainerPtr->iPayLoadParser->Reposition(true, *itStream, vecMinSeqNum[*itStream]);
3283 }
3284
3285 portContainerPtr->iPayLoadParser->Reposition();
3286 portContainerPtr->vAccessUnits.clear();
3287 for (uint i = 0; i < portContainerPtr->vCounterPorts.size(); i++)
3288 {
3289 PVMFMediaLayerPortContainer* poutPort = &this->iPortParamsQueue[portContainerPtr->vCounterPorts[i]];
3290 poutPort->vAccessUnits.clear();
3291 }
3292 portContainerPtr->iFirstFrameAfterRepositioning = true;
3293 portContainerPtr->iFirstFrameAfterReposTimeStamp = aSeekTimeInMS;
3294 portContainerPtr->iPort->ClearMsgQueues();
3295
3296 diffAudioVideoTS = 0;
3297 iAdjustTimeReady = false;
3298 oEOSsendunits = false;
3299
3300 PVMF_MLNODE_LOGINFO((0, "0x%x PVMFMediaLayerNode::setInPortReposFlag Out", this));
3301 }
3302
getMaxOutPortTimestamp(PVMFPortInterface * aPort,bool oPeek)3303 uint32 PVMFMediaLayerNode::getMaxOutPortTimestamp(PVMFPortInterface* aPort,
3304 bool oPeek)
3305 {
3306 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::getMaxOutPortTimestamp() In"));
3307
3308 PVMFMediaLayerPortContainer* inportContainerPtr = NULL;
3309
3310 GetPortContainer(aPort, inportContainerPtr);
3311
3312 OSCL_ASSERT(inportContainerPtr != NULL);
3313 OSCL_ASSERT(inportContainerPtr->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT);
3314 OSCL_ASSERT(inportContainerPtr->iPayLoadParser != NULL);
3315
3316 inportContainerPtr->oEOSReached = false;
3317
3318 uint32 max = 0;
3319 uint i;
3320 for (i = 0; i < inportContainerPtr->vCounterPorts.size(); i++)
3321 {
3322 PVMFMediaLayerPortContainer* outportContainerPtr =
3323 &this->iPortParamsQueue[inportContainerPtr->vCounterPorts[i]];
3324
3325 uint64 ts64 = outportContainerPtr->iContinuousTimeStamp;
3326 uint32 ts32 = Oscl_Int64_Utils::get_uint64_lower32(ts64);
3327 if (ts32 > max)
3328 {
3329 max = ts32;
3330 }
3331 outportContainerPtr->oEOSReached = false;
3332 }
3333 if (oPeek == false)
3334 {
3335 /* reset all continuous ts to max */
3336 uint64 max64 = 0;
3337 Oscl_Int64_Utils::set_uint64(max64, 0, max);
3338 for (i = 0; i < inportContainerPtr->vCounterPorts.size(); i++)
3339 {
3340 PVMFMediaLayerPortContainer* outportContainerPtr =
3341 &this->iPortParamsQueue[inportContainerPtr->vCounterPorts[i]];
3342 outportContainerPtr->iContinuousTimeStamp = max64;
3343 }
3344 }
3345 return max;
3346 }
3347
sendEndOfTrackCommand(PVMFMediaLayerPortContainer * poutputPort)3348 PVMFStatus PVMFMediaLayerNode::sendEndOfTrackCommand(PVMFMediaLayerPortContainer* poutputPort)
3349 {
3350 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::sendEndOfTrackCommand() In"));
3351
3352 PVMFStatus retval;
3353
3354 PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
3355 // Set the format ID
3356 sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
3357
3358 //Set stream ID
3359 sharedMediaCmdPtr->setStreamID(iStreamID);
3360
3361 // Set the timestamp
3362 sharedMediaCmdPtr->setTimestamp(poutputPort->iContinuousTimeStamp);
3363
3364 // Set the sequence number
3365 sharedMediaCmdPtr->setSeqNum(poutputPort->iPrevMsgSeqNum);
3366
3367 PVMFSharedMediaMsgPtr mediaMsgOut;
3368 convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
3369 retval = poutputPort->iPort->QueueOutgoingMsg(mediaMsgOut);
3370 if (retval != PVMFSuccess)
3371 {
3372 PVMF_MLNODE_LOGERROR((0,
3373 "0x%x PVMFMediaLayerNode::sendEndOfTrackCommand: "
3374 "Error - QueueOutgoingMsg for EOS failed", this));
3375 return retval;
3376 }
3377
3378 PVMF_MLNODE_LOGDATATRAFFIC_OUT((0, "PVMFMediaLayerNode::sendEndOfTrackCommand() MimeType=%s, StreamID=%d, TS=%d",
3379 poutputPort->iMimeType.get_cstr(),
3380 iStreamID,
3381 poutputPort->iContinuousTimeStamp));
3382 PVMF_MLNODE_LOGINFO((0, "PVMFMediaLayerNode::sendEndOfTrackCommand() Out"));
3383 return retval;
3384 }
3385
setPlayRange(int32 aStartTimeInMS,int32 aStopTimeInMS,bool oRepositioning)3386 bool PVMFMediaLayerNode::setPlayRange(int32 aStartTimeInMS,
3387 int32 aStopTimeInMS,
3388 bool oRepositioning)
3389 {
3390 iPlayStartTime = aStartTimeInMS;
3391 iPlayStopTime = aStopTimeInMS;
3392 Oscl_Vector<PVMFMediaLayerPortContainer, PVMFMediaLayerNodeAllocator>::iterator it;
3393 for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
3394 {
3395 if (oRepositioning)
3396 {
3397 it->iPort->ClearMsgQueues();
3398 it->vAccessUnits.clear();
3399 }
3400
3401 if (it->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT)
3402 it->oEOSReached = false;
3403 }
3404 return true;
3405 }
3406
checkPortCounterpartAccessUnitQueue(PVMFMediaLayerPortContainer * pinputPort,bool * IsAccessUnitsEmpty)3407 PVMFStatus PVMFMediaLayerNode::checkPortCounterpartAccessUnitQueue(PVMFMediaLayerPortContainer* pinputPort, bool* IsAccessUnitsEmpty)
3408 {
3409 for (uint i = 0; i < pinputPort->vCounterPorts.size(); i++)
3410 {
3411 PVMFMediaLayerPortContainer* poutPort =
3412 &this->iPortParamsQueue[pinputPort->vCounterPorts[i]];
3413
3414 if (poutPort->vAccessUnits.size() > 0)
3415 {
3416 *IsAccessUnitsEmpty = true;
3417 }
3418 }
3419 return PVMFSuccess;
3420 }
3421
3422
LogPayLoadParserStats()3423 PVMFStatus PVMFMediaLayerNode::LogPayLoadParserStats()
3424 {
3425 return PVMFSuccess;
3426 }
3427
LogSessionDiagnostics()3428 void PVMFMediaLayerNode::LogSessionDiagnostics()
3429 {
3430 if (iDiagnosticsLogged == false)
3431 {
3432 iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.streamingmanager.medialayer");
3433
3434 PVMF_MLNODE_LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
3435 PVMF_MLNODE_LOGDIAGNOSTICS((0, "PVMFMediaLayerNode - iNumRunL = %d", iNumRunL));
3436
3437 Oscl_Vector<PVMFMediaLayerPortContainer, PVMFMediaLayerNodeAllocator>::iterator it;
3438 for (it = iPortParamsQueue.begin(); it != iPortParamsQueue.end(); it++)
3439 {
3440 PvmfPortBaseImpl* ptr =
3441 OSCL_STATIC_CAST(PvmfPortBaseImpl*, it->iPort);
3442 PvmfPortBaseImplStats stats;
3443 ptr->GetStats(stats);
3444
3445 if (it->tag == PVMF_MEDIALAYER_PORT_TYPE_INPUT)
3446 {
3447 PVMF_MLNODE_LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
3448 PVMF_MLNODE_LOGDIAGNOSTICS((0, "PVMF_MEDIALAYER_PORT_TYPE_INPUT"));
3449 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iIncomingMsgRecv = %d", stats.iIncomingMsgRecv));
3450 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iIncomingMsgConsumed = %d", stats.iIncomingMsgConsumed));
3451 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iIncomingQueueBusy = %d", stats.iIncomingQueueBusy));
3452 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgQueued = %d", stats.iOutgoingMsgQueued));
3453 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgSent = %d", stats.iOutgoingMsgSent));
3454 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iOutgoingQueueBusy = %d", stats.iOutgoingQueueBusy));
3455 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgDiscarded = %d", stats.iOutgoingMsgDiscarded));
3456 }
3457 else if (it->tag == PVMF_MEDIALAYER_PORT_TYPE_OUTPUT)
3458 {
3459 PVMF_MLNODE_LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
3460 PVMF_MLNODE_LOGDIAGNOSTICS((0, "PVMF_MEDIALAYER_PORT_TYPE_OUTPUT"));
3461 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iIncomingMsgRecv = %d", stats.iIncomingMsgRecv));
3462 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iIncomingMsgConsumed = %d", stats.iIncomingMsgConsumed));
3463 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iIncomingQueueBusy = %d", stats.iIncomingQueueBusy));
3464 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgQueued = %d", stats.iOutgoingMsgQueued));
3465 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgSent = %d", stats.iOutgoingMsgSent));
3466 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iOutgoingQueueBusy = %d", stats.iOutgoingQueueBusy));
3467 PVMF_MLNODE_LOGDIAGNOSTICS((0, "iOutgoingMsgDiscarded = %d", stats.iOutgoingMsgDiscarded));
3468 }
3469 }
3470 iDiagnosticsLogged = true;
3471 }
3472 }
3473
3474
3475 /*********************************************************************/
3476 /* Extension interface */
PVMFMediaLayerNodeExtensionInterfaceImpl(PVMFMediaLayerNode * c)3477 PVMFMediaLayerNodeExtensionInterfaceImpl::PVMFMediaLayerNodeExtensionInterfaceImpl(PVMFMediaLayerNode*c)
3478 : PVInterfaceImpl<PVMFMediaLayerNodeAllocator>(PVUuid(PVMF_MEDIALAYERNODE_EXTENSIONINTERFACE_UUID))
3479 , iContainer(c)
3480 {}
3481
~PVMFMediaLayerNodeExtensionInterfaceImpl()3482 PVMFMediaLayerNodeExtensionInterfaceImpl::~PVMFMediaLayerNodeExtensionInterfaceImpl()
3483 {}
3484
3485 PVMFStatus
setDRMDecryptionInterface(uint32 maxPacketSize,PVMFCPMPluginAccessUnitDecryptionInterface * aDecryptionInterface)3486 PVMFMediaLayerNodeExtensionInterfaceImpl::setDRMDecryptionInterface(uint32 maxPacketSize,
3487 PVMFCPMPluginAccessUnitDecryptionInterface* aDecryptionInterface)
3488 {
3489 return (iContainer->setDRMDecryptionInterface(maxPacketSize, aDecryptionInterface));
3490 }
3491
3492 PVMFStatus
setPayloadParserRegistry(PayloadParserRegistry * registry)3493 PVMFMediaLayerNodeExtensionInterfaceImpl::setPayloadParserRegistry(PayloadParserRegistry* registry)
3494 {
3495 iContainer->setPayloadParserRegistry(registry);
3496 return PVMFSuccess;
3497 }
3498
3499 PVMFStatus
setPortDataLogging(bool logEnable,OSCL_String * logPath)3500 PVMFMediaLayerNodeExtensionInterfaceImpl::setPortDataLogging(bool logEnable,
3501 OSCL_String* logPath)
3502 {
3503 return (iContainer->setPortDataLogging(logEnable, logPath));
3504 }
3505
3506 bool
setPlayRange(int32 aStartTimeInMS,int32 aStopTimeInMS,bool oRepositioning)3507 PVMFMediaLayerNodeExtensionInterfaceImpl::setPlayRange(int32 aStartTimeInMS,
3508 int32 aStopTimeInMS,
3509 bool oRepositioning)
3510 {
3511 return (iContainer->setPlayRange(aStartTimeInMS, aStopTimeInMS, oRepositioning));
3512 }
3513
3514 bool
setClientPlayBackClock(PVMFMediaClock * aClientPlayBackClock)3515 PVMFMediaLayerNodeExtensionInterfaceImpl::setClientPlayBackClock(PVMFMediaClock* aClientPlayBackClock)
3516 {
3517 return (iContainer->setClientPlayBackClock(aClientPlayBackClock));
3518 }
3519
3520 bool
setPortMediaParams(PVMFPortInterface * aPort,OsclRefCounterMemFrag & aConfig,mediaInfo * aMediaInfo)3521 PVMFMediaLayerNodeExtensionInterfaceImpl::setPortMediaParams(PVMFPortInterface* aPort,
3522 OsclRefCounterMemFrag& aConfig,
3523 mediaInfo* aMediaInfo)
3524 {
3525 return (iContainer->setPortMediaParams(aPort, aConfig, aMediaInfo));
3526 }
3527
3528 PVMFStatus
verifyPortConfigParams(const char * aFormatValType,PVMFPortInterface * aPort,OsclAny * aConfig,mediaInfo * aMediaInfo)3529 PVMFMediaLayerNodeExtensionInterfaceImpl::verifyPortConfigParams(const char* aFormatValType,
3530 PVMFPortInterface* aPort,
3531 OsclAny* aConfig,
3532 mediaInfo* aMediaInfo)
3533 {
3534 return (iContainer->verifyPortConfigParams(aFormatValType, aPort, aConfig, aMediaInfo));
3535 }
3536
3537 bool
setTrackDisable(PVMFPortInterface * aPort)3538 PVMFMediaLayerNodeExtensionInterfaceImpl::setTrackDisable(PVMFPortInterface* aPort)
3539 {
3540 return (iContainer->setTrackDisable(aPort));
3541 }
3542
3543 void
setMediaLayerTimerDurationMS(uint32 aTimer)3544 PVMFMediaLayerNodeExtensionInterfaceImpl::setMediaLayerTimerDurationMS(uint32 aTimer)
3545 {
3546 iContainer->setMediaLayerTimerDurationMS(aTimer);
3547 }
3548
3549 bool
setOutPortStreamParams(PVMFPortInterface * aPort,uint streamid,uint32 aPreroll,bool aLiveStream)3550 PVMFMediaLayerNodeExtensionInterfaceImpl::setOutPortStreamParams(PVMFPortInterface* aPort,
3551 uint streamid,
3552 uint32 aPreroll,
3553 bool aLiveStream)
3554 {
3555 return (iContainer->setOutPortStreamParams(aPort, streamid, aPreroll, aLiveStream));
3556 }
3557
setInPortReposFlag(PVMFPortInterface * aPort,uint32 aSeekTimeInMS)3558 void PVMFMediaLayerNodeExtensionInterfaceImpl::setInPortReposFlag(PVMFPortInterface* aPort, uint32 aSeekTimeInMS)
3559 {
3560 iContainer->setInPortReposFlag(aPort, aSeekTimeInMS);
3561 }
3562
3563 uint32
getMaxOutPortTimestamp(PVMFPortInterface * aPort,bool oPeek)3564 PVMFMediaLayerNodeExtensionInterfaceImpl::getMaxOutPortTimestamp(PVMFPortInterface* aPort,
3565 bool oPeek)
3566 {
3567 return iContainer->getMaxOutPortTimestamp(aPort, oPeek);
3568 }
3569