1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #include "pv_2way_datapath.h"
19 #include "pvmi_config_and_capability.h"
20 #include "pv_mime_string_utils.h"
21
Connect()22 bool CPV2WayPortPair::Connect()
23 {
24 if ((iSrcPort.GetStatus() == EHasPort) &&
25 (iDestPort.GetStatus() == EHasPort))
26 {
27 if (iSrcPort.GetPort()->Connect(iDestPort.GetPort()) == PVMFSuccess)
28 {
29 iIsConnected = true;
30 return true;
31 }
32 }
33 return false;
34 }
35
Disconnect()36 bool CPV2WayPortPair::Disconnect()
37 {
38 if ((iSrcPort.GetStatus() == EHasPort) &&
39 (iDestPort.GetStatus() == EHasPort))
40 {
41 if (iSrcPort.GetPort()->Disconnect() == PVMFSuccess)
42 {
43 iIsConnected = false;
44 return true;
45 }
46 }
47 return false;
48 }
49
operator =(const CPVDatapathPort & a)50 CPVDatapathPort& CPVDatapathPort::operator=(const CPVDatapathPort & a)
51 {
52 iRequestPortState = a.iRequestPortState;
53 iCanCancelPort = a.iCanCancelPort;
54 iPortSetType = a.iPortSetType;
55 iFormatType = a.iFormatType;
56 iDefaultFormatType = a.iDefaultFormatType;
57 iPortTag = a.iPortTag;
58 iPortPair = a.iPortPair;
59 return *this;
60 }
61
operator =(const CPVDatapathNode & a)62 CPVDatapathNode& CPVDatapathNode::operator=(const CPVDatapathNode & a)
63 {
64 iNode = a.iNode;
65 iConfigure = a.iConfigure;
66 iConfigTime = a.iConfigTime;
67 iCanNodePause = a.iCanNodePause;
68 iLoggoffOnReset = a.iLoggoffOnReset;
69 iOriginalState = a.iOriginalState;
70 iInputPort = a.iInputPort;
71 iOutputPort = a.iOutputPort;
72 iCommandIssued = a.iCommandIssued;
73 return *this;
74 }
75
IsPortInDatapath(PVMFPortInterface * aPort)76 bool CPV2WayDatapath::IsPortInDatapath(PVMFPortInterface *aPort)
77 {
78 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::IsPortInDatapath state %d, num port pairs %d\n", iState, iPortPairList.size()));
79 if (aPort)
80 {
81 for (uint32 i = 0; i < iPortPairList.size(); i++)
82 {
83 if ((iPortPairList[i].iSrcPort.GetPort() == aPort) ||
84 (iPortPairList[i].iDestPort.GetPort() == aPort))
85 {
86 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::IsPortInDatapath port found at idx %d\n", i));
87 return true;
88 }
89 }
90 }
91
92 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::IsPortInDatapath no node found\n"));
93 return false;
94 }
95
IsNodeInDatapath(PVMFNodeInterface * aNode)96 bool CPV2WayDatapath::IsNodeInDatapath(PVMFNodeInterface *aNode)
97 {
98 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::IsNodeInDatapath state %d, num nodes %d\n", iState, iNodeList.size()));
99 if (aNode)
100 {
101 for (uint32 i = 0; i < iNodeList.size(); i++)
102 {
103 if ((PVMFNodeInterface *)iNodeList[i].iNode == aNode)
104 {
105 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::IsNodeInDatapath node found at idx %d\n", i));
106 return true;
107 }
108 }
109 }
110
111 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::IsNodeInDatapath no node found\n"));
112 return false;
113 }
114
ResetDatapath()115 bool CPV2WayDatapath::ResetDatapath()
116 {
117 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::ResetDatapath state %d, num nodes %d\n", iState, iNodeList.size()));
118
119 if (iState == EClosed)
120 {
121 for (uint32 i = 0; i < iNodeList.size(); i++)
122 {
123 if (iNodeList[i].iLoggoffOnReset)
124 {
125 PVLOGGER_LOG_USE_ONLY(PVMFStatus status =)((PVMFNodeInterface *)iNodeList[i].iNode)->ThreadLogoff();
126 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::ResetDatapath thread logoff status %d\n", status));
127 }
128 }
129
130 iPortPairList.clear();
131 iNodeList.clear();
132 return true;
133 }
134 else
135 {
136 return false;
137 }
138 }
139
AddNode(const CPVDatapathNode & aNode)140 bool CPV2WayDatapath::AddNode(const CPVDatapathNode &aNode)
141 {
142 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::AddNode path state %d, num nodes %d\n", iState, iNodeList.size()));
143
144 if ((iState == EClosed) &&
145 (iNodeList.size() < MAX_DATAPATH_NODES))
146 {
147 CPVDatapathNode node(aNode);
148
149 node.iOriginalState = ((PVMFNodeInterface *)(node.iNode))->GetState();
150 node.iInputPort.iPortPair = NULL;
151 node.iOutputPort.iPortPair = NULL;
152
153 if (!iNodeList.empty())
154 {
155 CPV2WayPortPair portPair;
156 iPortPairList.push_back(portPair);
157 iNodeList.back().iOutputPort.iPortPair = &(iPortPairList.back());
158 node.iInputPort.iPortPair = &(iPortPairList.back());
159 }
160
161 iNodeList.push_back(node);
162 return true;
163 }
164 return false;
165 }
166
Open()167 bool CPV2WayDatapath::Open()
168 {
169 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath(%s)::Open path type %d, state %d, num nodes %d\n", iFormat.getMIMEStrPtr(), iType, iState, iNodeList.size()));
170 if (SingleNodeOpen() || iNodeList.size() > 1)
171 {
172 switch (iState)
173 {
174 case EClosed:
175 SetState(EOpening);
176 CheckPath();
177 //Fall through to next case.
178
179 case EOpening:
180 return true;
181
182 default:
183 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::Open invalid state to open\n"));
184 break;
185 }
186 }
187 return false;
188 }
189
Close()190 bool CPV2WayDatapath::Close()
191 {
192 uint32 i;
193 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::Close path type %d, state %d\n", iType, iState));
194
195 if (iFsi)
196 {
197 OSCL_DEFAULT_FREE(iFsi);
198 iFsi = NULL;
199 }
200 iFsiLen = 0;
201
202 switch (iState)
203 {
204 default:
205 //Disconnect all port connections
206 for (i = 0; i < iPortPairList.size(); i++)
207 {
208 iPortPairList[i].Disconnect();
209 }
210
211 iAllPortsConnected = false;
212
213 iStateBeforeClose = iState;
214 SetState(EClosing);
215
216 //Close dependent paths
217 for (i = 0; i < iDependentPathList.size(); i++)
218 {
219 iDependentPathList[i]->Close();
220 }
221
222 CheckPath();
223 //Fall through to next case.
224
225 case EClosing:
226 return true;
227
228 case EClosed:
229 return false;
230 }
231 }
232
Pause()233 bool CPV2WayDatapath::Pause()
234 {
235 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::Pause path type %d, state %d\n", iType, iState));
236 switch (iState)
237 {
238 case EOpened:
239 SetState(EPausing);
240 CheckPath();
241 //Fall through to next case.
242
243 case EPausing:
244 return true;
245
246 default:
247 return false;
248 }
249 }
250
Resume()251 bool CPV2WayDatapath::Resume()
252 {
253 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::Resume path type %d, state %d\n", iType, iState));
254 switch (iState)
255 {
256 case EPaused:
257 SetState(EUnpausing);
258 CheckPath();
259 //Fall through to next case.
260
261 case EUnpausing:
262 return true;
263
264 default:
265 return false;
266 }
267 }
268
AddParentDatapath(CPV2WayDatapath & aDatapath)269 bool CPV2WayDatapath::AddParentDatapath(CPV2WayDatapath &aDatapath)
270 {
271 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::AddParentDatapath path state %d, num paths %d\n", iState, iParentPathList.size()));
272
273 if ((iState == EClosed) &&
274 (iParentPathList.size() < MAX_PARENT_PATHS))
275 {
276 iParentPathList.push_back(&aDatapath);
277 return true;
278 }
279 return false;
280 }
281
AddDependentDatapath(CPV2WayDatapath & aDatapath)282 bool CPV2WayDatapath::AddDependentDatapath(CPV2WayDatapath &aDatapath)
283 {
284 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV2WayDatapath::AddDependentDatapath path state %d, num paths %d\n", iState, iDependentPathList.size()));
285
286 if ((iState == EClosed) &&
287 (iDependentPathList.size() < MAX_PARENT_PATHS))
288 {
289 iDependentPathList.push_back(&aDatapath);
290 return true;
291 }
292 return false;
293 }
294
ConstructL()295 void CPV2WayDatapath::ConstructL()
296 {
297 iNodeList.reserve(MAX_DATAPATH_NODES);
298 iPortPairList.reserve(MAX_DATAPATH_NODES);
299 iParentPathList.reserve(MAX_PARENT_PATHS);
300 iDependentPathList.reserve(MAX_DEPENDENT_PATHS);
301 iFsi = NULL;
302 iFsiLen = 0;
303 }
304
SetState(TPV2WayDatapathState aState)305 void CPV2WayDatapath::SetState(TPV2WayDatapathState aState)
306 {
307 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath(%d)::SetState cur %d, new %d\n", iType, iState, aState));
308 iState = aState;
309 }
310
IsDatapathNodeClosed(CPVDatapathNode & aNode)311 bool CPV2WayDatapath::IsDatapathNodeClosed(CPVDatapathNode &aNode)
312 {
313 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::IsDatapathNodeClosed\n"));
314 if (aNode.iCommandIssued) return false;
315
316 if (aNode.iInputPort.iPortPair &&
317 (aNode.iInputPort.iPortPair->iDestPort.GetStatus() != ENoPort)) return false;
318
319 if (aNode.iOutputPort.iPortPair &&
320 (aNode.iOutputPort.iPortPair->iSrcPort.GetStatus() != ENoPort)) return false;
321
322 /* Gkl - We check for node states that are less than or equal to the state in which the node was added
323 This is becoz the states are assymetric which sucks*/
324 if (!aNode.iIgnoreNodeState &&
325 (((PVMFNodeInterface *)(aNode.iNode))->GetState() > aNode.iOriginalState)) return false;
326
327 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::IsDatapathNodeClosed node is closed\n"));
328
329 return true;
330 }
331
CheckNodePortsL(CPVDatapathNode & aNode)332 bool CPV2WayDatapath::CheckNodePortsL(CPVDatapathNode &aNode)
333 {
334 PVMFStatus status;
335 TPV2WayNodeRequestPortParams reqPortParams;
336 CPV2WayPortPair *inPortPair = aNode.iInputPort.iPortPair;
337 CPV2WayPortPair *outPortPair = aNode.iOutputPort.iPortPair;
338 CPVDatapathPort *dataPort;
339 bool requestPort;
340 bool portRequestDone = true;
341
342
343 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckNodePorts in req port state %d, port %x\n", aNode.iInputPort.iRequestPortState, inPortPair));
344
345 if (((PVMFNodeInterface *)(aNode.iNode))->GetState() >= aNode.iInputPort.iRequestPortState)
346 {
347 if (inPortPair)
348 {
349 dataPort = (CPVDatapathPort *) & aNode.iInputPort;
350
351 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckNodePorts in port state %d\n", inPortPair->iDestPort.GetStatus()));
352 if (inPortPair->iDestPort.GetStatus() == ENoPort)
353 {
354 requestPort = false;
355 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckNodePorts in port request set type %d\n", aNode.iInputPort.iPortSetType));
356
357 switch (dataPort->iPortSetType)
358 {
359 case EUserDefined:
360 requestPort = true;
361 break;
362
363 case EConnectedPortFormat:
364 if (inPortPair->iSrcPort.GetStatus() == EHasPort)
365 {
366 dataPort->iFormatType = GetPortFormatType(*inPortPair->iSrcPort.GetPort(), false, inPortPair->iDestPort.GetPort());
367 OSCL_ASSERT(dataPort->iFormatType != PVMF_MIME_FORMAT_UNKNOWN);
368 requestPort = true;
369 }
370 break;
371
372 case EUseOtherNodePortFormat:
373 if (outPortPair->iSrcPort.GetStatus() == EHasPort)
374 {
375 dataPort->iFormatType = GetPortFormatType(*outPortPair->iSrcPort.GetPort(), false, outPortPair->iDestPort.GetPort());
376 OSCL_ASSERT(dataPort->iFormatType != PVMF_MIME_FORMAT_UNKNOWN);
377 requestPort = true;
378 }
379 break;
380
381 case EAppDefined:
382 requestPort = true;
383 break;
384
385 default:
386 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckNodePorts undefined set type\n"));
387 break;
388 }
389
390 if (requestPort)
391 {
392 reqPortParams.portTag = dataPort->iPortTag;
393 reqPortParams.format = dataPort->iFormatType;
394
395 status = CheckConfig(EConfigBeforeReqInPort, aNode);
396 switch (status)
397 {
398 case PVMFPending:
399 break;
400
401 case PVMFSuccess:
402 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckNodePorts request input port, format %s, tag %d\n", reqPortParams.format.getMIMEStrPtr(), reqPortParams.portTag));
403 inPortPair->iDestPort.SetCmdId(SendNodeCmdL(PV2WAY_NODE_CMD_REQUESTPORT, aNode, &reqPortParams));
404 inPortPair->iDestPort.SetStatus(ERequestPort);
405 break;
406
407 default:
408 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckNodePorts node config failed\n"));
409 OSCL_LEAVE(status);
410 return false;
411 }
412 }
413 }
414
415 if (inPortPair->iDestPort.GetStatus() != EHasPort)
416 {
417 portRequestDone = false;
418 }
419 }
420 }
421
422 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckNodePorts out req port state %d, port %x\n", aNode.iOutputPort.iRequestPortState, outPortPair));
423
424 if (((PVMFNodeInterface *)(aNode.iNode))->GetState() >= aNode.iOutputPort.iRequestPortState)
425 {
426 if (outPortPair)
427 {
428 dataPort = (CPVDatapathPort *) & aNode.iOutputPort;
429
430 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckNodePorts out port state %d\n", outPortPair->iSrcPort.GetStatus()));
431 if (outPortPair->iSrcPort.GetStatus() == ENoPort)
432 {
433 requestPort = false;
434 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckNodePorts out port request set type %d\n", aNode.iOutputPort.iPortSetType));
435
436 switch (dataPort->iPortSetType)
437 {
438 case EUserDefined:
439 requestPort = true;
440 break;
441
442 case EConnectedPortFormat:
443 if (outPortPair->iDestPort.GetStatus() == EHasPort)
444 {
445 dataPort->iFormatType = GetPortFormatType(*outPortPair->iDestPort.GetPort(), true, outPortPair->iSrcPort.GetPort());
446 OSCL_ASSERT(dataPort->iFormatType != PVMF_MIME_FORMAT_UNKNOWN);
447 requestPort = true;
448 }
449 break;
450
451 case EUseOtherNodePortFormat:
452 if (inPortPair->iDestPort.GetStatus() == EHasPort)
453 {
454 dataPort->iFormatType = GetPortFormatType(*inPortPair->iDestPort.GetPort(), true, inPortPair->iSrcPort.GetPort());
455 OSCL_ASSERT(dataPort->iFormatType != PVMF_MIME_FORMAT_UNKNOWN);
456 requestPort = true;
457 }
458 break;
459
460 case EAppDefined:
461 requestPort = true;
462 break;
463
464 default:
465 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckNodePorts undefined set type\n"));
466 break;
467 }
468
469 if (requestPort)
470 {
471 reqPortParams.portTag = dataPort->iPortTag;
472 reqPortParams.format = dataPort->iFormatType;
473
474 status = CheckConfig(EConfigBeforeReqOutPort, aNode);
475 switch (status)
476 {
477 case PVMFPending:
478 break;
479
480 case PVMFSuccess:
481 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckNodePorts request output port, format %s, type %d\n", reqPortParams.format.getMIMEStrPtr(), reqPortParams.portTag));
482 outPortPair->iSrcPort.SetCmdId(SendNodeCmdL(PV2WAY_NODE_CMD_REQUESTPORT, aNode, &reqPortParams));
483 outPortPair->iSrcPort.SetStatus(ERequestPort);
484 break;
485
486 default:
487 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckNodePorts node config failed\n"));
488 OSCL_LEAVE(status);
489 return false;
490 }
491 }
492 }
493
494 if (outPortPair->iSrcPort.GetStatus() != EHasPort)
495 {
496 portRequestDone = false;
497 }
498 }
499 }
500
501 return portRequestDone;
502 }
503
PortStatusChange(PVMFNodeInterface * aNode,PVMFCommandId aId,PVMFPortInterface * aPort)504 PVMFStatus CPV2WayDatapath::PortStatusChange(PVMFNodeInterface *aNode, PVMFCommandId aId, PVMFPortInterface *aPort)
505 {
506 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::PortStatusChange id %d, port %x\n", aId, aPort));
507 PVMFStatus status = PVMFFailure;
508 int32 error = 0;
509 CPV2WayPort *port = NULL;
510 OsclAny *configPtr = NULL;
511 PvmiKvp portParams;
512 PvmiKvp *portParamsReturn = NULL;
513 PVMFFormatType format = PVMF_MIME_FORMAT_UNKNOWN;
514 CPV2WayPortPair *portPair = NULL;
515 bool isInputPort = false;
516 bool isAppDefined;
517
518 for (uint32 i = 0; i < iNodeList.size(); i++)
519 {
520 if (((PVMFNodeInterface *)(iNodeList[i].iNode)) == aNode)
521 {
522 CPV2WayPortPair* inPortPair = iNodeList[i].iInputPort.iPortPair;
523 CPV2WayPortPair* outPortPair = iNodeList[i].iOutputPort.iPortPair;
524 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE,
525 (0, "CPV2WayDatapath::PortStatusChange node %d\n", i));
526 if (inPortPair &&
527 (inPortPair->iDestPort.GetCmdId() == aId))
528 {
529 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE,
530 (0, "CPV2WayDatapath::PortStatusChange found input port\n"));
531 format = iNodeList[i].iInputPort.iFormatType;
532 port = &inPortPair->iDestPort;
533 portPair = inPortPair;
534 isInputPort = true;
535 isAppDefined = (iNodeList[i].iInputPort.iPortSetType == EAppDefined);
536 }
537 else if (outPortPair &&
538 (outPortPair->iSrcPort.GetCmdId() == aId))
539 {
540 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE,
541 (0, "CPV2WayDatapath::PortStatusChange found output port\n"));
542 format = iNodeList[i].iOutputPort.iFormatType;
543 port = &outPortPair->iSrcPort;
544 portPair = outPortPair;
545 isInputPort = false;
546 isAppDefined = (iNodeList[i].iOutputPort.iPortSetType == EAppDefined);
547 }
548 break;
549 }
550 }
551
552 if (port)
553 {
554 if (aPort && !isAppDefined)
555 {
556 aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, configPtr);
557
558 //If config ptr exists, otherwise assume port has been configured.
559 if (configPtr)
560 {
561 if (isInputPort)
562 {
563 portParams.key = OSCL_CONST_CAST(char*, INPUT_FORMATS_VALTYPE);
564 portParams.length = oscl_strlen(INPUT_FORMATS_VALTYPE);
565 portParams.capacity = oscl_strlen(INPUT_FORMATS_VALTYPE);
566 }
567 else
568 {
569 portParams.key = OSCL_CONST_CAST(char*, OUTPUT_FORMATS_VALTYPE);
570 portParams.length = oscl_strlen(OUTPUT_FORMATS_VALTYPE);
571 portParams.capacity = oscl_strlen(OUTPUT_FORMATS_VALTYPE);
572 }
573
574 portParams.value.pChar_value = OSCL_STATIC_CAST(mbchar*, format.getMIMEStrPtr());
575 error = SetParametersSync((PvmiCapabilityAndConfig *)configPtr, &portParams, portParamsReturn);
576
577 if (error || portParamsReturn != NULL)
578 {
579 portParamsReturn = NULL;
580 portParams.key = OSCL_CONST_CAST(char*, "x-pvmf/port/formattype;valtype=char*");
581 portParams.length = oscl_strlen("x-pvmf/port/formattype;valtype=char*");
582 portParams.capacity = portParams.length;
583 portParams.value.pChar_value = OSCL_STATIC_CAST(mbchar*, format.getMIMEStrPtr());
584 error = SetParametersSync((PvmiCapabilityAndConfig *)configPtr,
585 &portParams, portParamsReturn);
586 }
587
588 if ((error || portParamsReturn != NULL) && isInputPort)
589 {
590 // this would be a file MIO component which requires explicit setting of audio and video formats
591 portParamsReturn = NULL;
592 if (format.isAudio())
593 portParams.key = OSCL_CONST_CAST(char*, MOUT_AUDIO_FORMAT_KEY);
594 else
595 portParams.key = OSCL_CONST_CAST(char*, MOUT_VIDEO_FORMAT_KEY);
596 portParams.length = oscl_strlen(portParams.key);
597 portParams.capacity = portParams.length;
598
599
600 /* This is for the MIO components having the convention
601 of returning uint32 for a query and requiring pChar for a setting
602 we don't know if we are talking to an MIO or a decoder node
603 (which will want a uint32), so we try both. Try the pchar
604 first, because if its expecting pchar and gets uint32, it will
605 crash.
606 */
607
608 portParams.value.pChar_value = OSCL_STATIC_CAST(mbchar*, format.getMIMEStrPtr());
609
610 error = SetParametersSync((PvmiCapabilityAndConfig *)configPtr, &portParams, portParamsReturn);
611 if (error)
612 {
613 portParams.value.pChar_value = OSCL_STATIC_CAST(mbchar*, format.getMIMEStrPtr());
614 error = SetParametersSync((PvmiCapabilityAndConfig *)configPtr, &portParams, portParamsReturn);
615 }
616 portParamsReturn = NULL;
617 if (format.isAudio())
618 {
619 portParams.key = OSCL_CONST_CAST(char*, MOUT_AUDIO_SAMPLING_RATE_KEY);
620 portParams.value.uint32_value = 8000;
621 }
622 else
623 {
624 portParams.key = OSCL_CONST_CAST(char*, MOUT_VIDEO_HEIGHT_KEY);
625 portParams.value.uint32_value = 176;
626 }
627 portParams.length = oscl_strlen(portParams.key);
628 portParams.capacity = portParams.length;
629 error = SetParametersSync((PvmiCapabilityAndConfig *)configPtr,
630 &portParams, portParamsReturn);
631 if (error && portParamsReturn != NULL)
632 {
633 error = 0;
634 portParamsReturn = NULL;
635 }
636 }
637
638 if (error || portParamsReturn != NULL)
639 {
640 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::PortStatusChange setParametersSync failed %d at parameter %x!\n", error, portParamsReturn));
641 }
642 else
643 {
644 status = PVMFSuccess;
645 }
646 }
647 else
648 {
649 status = PVMFSuccess;
650 }
651 }
652 else
653 {
654 status = isAppDefined ? PVMFSuccess : PVMFFailure;
655 }
656
657 SetPort(*port, aPort);
658 if (status != PVMFSuccess)
659 {
660 if (portPair->iDestPort.GetPort() && portPair->iSrcPort.GetPort())
661 {
662 PVMFFormatType format2 = PVMF_MIME_FORMAT_UNKNOWN;
663 // now try with two ports
664 if (isInputPort)
665 {
666 portParams.key = OSCL_CONST_CAST(char*, INPUT_FORMATS_VALTYPE);
667 portParams.length = oscl_strlen(INPUT_FORMATS_VALTYPE);
668 portParams.capacity = oscl_strlen(INPUT_FORMATS_VALTYPE);
669 }
670 else
671 {
672 portParams.key = OSCL_CONST_CAST(char*, OUTPUT_FORMATS_VALTYPE);
673 portParams.length = oscl_strlen(OUTPUT_FORMATS_VALTYPE);
674 portParams.capacity = oscl_strlen(OUTPUT_FORMATS_VALTYPE);
675 }
676 format2 = GetPortFormatType(*portPair->iDestPort.GetPort(),
677 true, portPair->iSrcPort.GetPort());
678 portParams.value.pChar_value = OSCL_STATIC_CAST(mbchar*, format2.getMIMEStrPtr());
679 error = SetParametersSync((PvmiCapabilityAndConfig *)configPtr, &portParams, portParamsReturn);
680 if (!error)
681 {
682 status = PVMFSuccess;
683 }
684 }
685 }
686
687 if (status == PVMFSuccess)
688 {
689 if ((portPair->iSrcPort.GetStatus() == EHasPort) &&
690 (portPair->iDestPort.GetStatus() == EHasPort))
691 {
692 if (!portPair->Connect())
693 return PVMFFailure;
694 }
695 }
696
697 return status;
698 }
699 else
700 {
701 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::PortStatusChange no port found!\n"));
702 return status;
703 }
704 }
705
SetParametersSync(PvmiCapabilityAndConfig * configPtr,PvmiKvp * portParams,PvmiKvp * & portParamsReturn)706 int32 CPV2WayDatapath::SetParametersSync(PvmiCapabilityAndConfig * configPtr,
707 PvmiKvp* portParams,
708 PvmiKvp*& portParamsReturn)
709 {
710 int32 error;
711 OSCL_TRY(error, configPtr->setParametersSync(NULL, portParams, 1, portParamsReturn));
712 return error;
713 }
714
CloseNodePorts(CPVDatapathNode & aNode)715 void CPV2WayDatapath::CloseNodePorts(CPVDatapathNode &aNode)
716 {
717 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CloseNodePorts\n"));
718
719 CPV2WayPortPair *portPair;
720
721 portPair = aNode.iInputPort.iPortPair;
722 if (portPair &&
723 (portPair->iDestPort.GetStatus() == EHasPort))
724 {
725 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CloseNodePorts closing input port\n"));
726 portPair->iDestPort.SetPort(NULL);
727 }
728
729 portPair = aNode.iOutputPort.iPortPair;
730 if (portPair &&
731 (portPair->iSrcPort.GetStatus() == EHasPort))
732 {
733 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CloseNodePorts closing output port\n"));
734 portPair->iSrcPort.SetPort(NULL);
735 }
736
737 return;
738 }
739
SendNodeCmdL(PV2WayNodeCmdType aCmd,CPVDatapathNode & aNode,void * aParam)740 PVMFCommandId CPV2WayDatapath::SendNodeCmdL(PV2WayNodeCmdType aCmd,
741 CPVDatapathNode &aNode,
742 void *aParam)
743 {
744 PVMFCommandId id;
745 id = i2Way->SendNodeCmdL(aCmd, &aNode.iNode, this, aParam);
746 aNode.iCommandIssued = true;
747 return id;
748 }
749
CheckConfig(TPVNodeConfigTimeType aConfigTime,CPVDatapathNode & aNode)750 PVMFStatus CPV2WayDatapath::CheckConfig(TPVNodeConfigTimeType aConfigTime, CPVDatapathNode &aNode)
751 {
752 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckConfig config %x, time %d\n", aNode.iConfigure, aConfigTime));
753 if (aNode.iConfigure &&
754 (aNode.iConfigTime == aConfigTime))
755 {
756 return aNode.iConfigure->ConfigureNode(&aNode);
757 }
758
759 return PVMFSuccess;
760 }
761
CheckOpen()762 void CPV2WayDatapath::CheckOpen()
763 {
764 uint32 i;
765 bool checkPort = false;
766 bool nodesStarted = true;
767
768 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckOpen state %d\n", iState));
769
770 for (i = 0; i < iNodeList.size(); i++)
771 {
772 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckOpen (0x%x) node %d state %d, cmd issued %d\n", this, i, iNodeList[i].iNode.iNode->GetState(), iNodeList[i].iCommandIssued));
773
774 if (iNodeList[i].iCommandIssued)
775 {
776 nodesStarted = false;
777 continue;
778 }
779
780 switch (iNodeList[i].iNode.iNode->GetState())
781 {
782 case EPVMFNodeIdle:
783 nodesStarted = false;
784 switch (CheckConfig(EConfigBeforeInit, iNodeList[i]))
785 {
786 case PVMFPending:
787 continue;
788
789 case PVMFSuccess:
790 break;
791
792 default:
793 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckOpen node config failed\n"));
794 DatapathError();
795 return;
796 }
797
798 if (!SendNodeCmd(PV2WAY_NODE_CMD_INIT, i))
799 {
800 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckOpen unable to initialize node\n"));
801 DatapathError();
802 return;
803 }
804 break;
805
806 case EPVMFNodeInitialized:
807 nodesStarted = false;
808
809 if (!CheckNodePorts(checkPort, i))
810 {
811 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckOpen problem checking ports\n"));
812 DatapathError();
813 return;
814 }
815
816 if (checkPort)
817 {
818 switch (CheckConfig(EConfigBeforeStart, iNodeList[i]))
819 {
820 case PVMFPending:
821 continue;
822
823 case PVMFSuccess:
824 break;
825
826 default:
827 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckOpen node config failed\n"));
828 DatapathError();
829 return;
830 }
831
832 if (!SendNodeCmd(PV2WAY_NODE_CMD_PREPARE, i))
833 {
834 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckOpen unable to start node\n"));
835 DatapathError();
836 return;
837 }
838 }
839 break;
840
841 case EPVMFNodePrepared:
842 nodesStarted = false;
843 //Make sure downstream node is started first.
844 if ((i == iNodeList.size() - 1) || (iNodeList[i+1].iNode.iNode->GetState() == EPVMFNodeStarted))
845 {
846 switch (CheckConfig(EConfigBeforeStart, iNodeList[i]))
847 {
848 case PVMFPending:
849 continue;
850
851 case PVMFSuccess:
852 break;
853
854 default:
855 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckOpen node config failed\n"));
856 DatapathError();
857 return;
858 }
859
860 if (!CheckPathSpecificStart())
861 {
862 continue;
863 }
864
865 if (iAllPortsConnected || SingleNodeOpen())
866 {
867 if (!SendNodeCmd(PV2WAY_NODE_CMD_START, i))
868 {
869 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckOpen unable to start node\n"));
870 DatapathError();
871 return;
872 }
873 }
874 }
875 break;
876
877 case EPVMFNodeStarted:
878 if (!CheckNodePorts(checkPort, i))
879 {
880 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckOpen problem checking ports\n"));
881 DatapathError();
882 return;
883 }
884 break;
885
886 default:
887 nodesStarted = false;
888 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckOpen transitional node state!\n"));
889 break;
890 }
891 }
892
893 //All nodes in path have not been started yet.
894 if (!nodesStarted) return;
895
896 //Check if all ports have been connected.
897 if (!iAllPortsConnected && !SingleNodeOpen()) return;
898
899 //Make path specific check
900 if (!CheckPathSpecificOpen())
901 {
902 return;
903 }
904
905 //Connect is done when both ports in a port pair are requested
906 // //If reached this point then all ports have been allocated and datapath is deemed open, connect ports and notify upper layer.
907
908
909 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckOpen open complete\n"));
910
911 SetState(EOpened);
912 OpenComplete();
913 return;
914 }
915
CheckNodePorts(bool & aCheckPort,int32 i)916 bool CPV2WayDatapath::CheckNodePorts(bool& aCheckPort, int32 i)
917 {
918 int32 error;
919 OSCL_TRY(error, aCheckPort = CheckNodePortsL(iNodeList[i]));
920 OSCL_FIRST_CATCH_ANY(error,
921 return false;);
922 return true;
923 }
924
CheckPause()925 void CPV2WayDatapath::CheckPause()
926 {
927 uint32 i;
928
929 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckPause state %d\n", iState));
930
931 for (i = 0; i < iNodeList.size(); i++)
932 {
933 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckPause node %d state %d, can pause %d, cmd issued %d\n", i, iNodeList[i].iNode.iNode->GetState(), iNodeList[i].iCanNodePause, iNodeList[i].iCommandIssued));
934
935 if (!iNodeList[i].iCanNodePause) continue;
936 if (iNodeList[i].iCommandIssued) continue;
937
938 switch (iNodeList[i].iNode.iNode->GetState())
939 {
940 case EPVMFNodeStarted:
941 if (!SendNodeCmd(PV2WAY_NODE_CMD_PAUSE, i))
942 {
943 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckPause unable to pause node\n"));
944 DatapathError();
945 return;
946 }
947
948 break;
949
950 default:
951 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckPause transitional node state!\n"));
952 break;
953 }
954 }
955
956 for (i = 0; i < iNodeList.size(); i++)
957 {
958 //If possible pause node is not paused.
959 if (iNodeList[i].iCanNodePause && (iNodeList[i].iNode.iNode->GetState() != EPVMFNodePaused))
960 {
961 return;
962 }
963 }
964
965 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckPause pause complete\n"));
966
967 //If reached this point then the datapath is deemed paused, notify upper layer.
968 SetState(EPaused);
969 PauseComplete();
970 return;
971 }
972
CheckResume()973 void CPV2WayDatapath::CheckResume()
974 {
975 uint32 i;
976
977 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckResume state %d\n", iState));
978
979 for (i = 0; i < iNodeList.size(); i++)
980 {
981 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckResume node %d state %d, can pause %d, cmd issued %d\n", i, iNodeList[i].iNode.iNode->GetState(), iNodeList[i].iCanNodePause, iNodeList[i].iCommandIssued));
982
983 if (!iNodeList[i].iCanNodePause) continue;
984 if (iNodeList[i].iCommandIssued) continue;
985
986 switch (iNodeList[i].iNode.iNode->GetState())
987 {
988 case EPVMFNodePaused:
989 if (!SendNodeCmd(PV2WAY_NODE_CMD_START, i))
990 {
991 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckResume unable to pause node\n"));
992 DatapathError();
993 return;
994 }
995 break;
996
997 default:
998 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckResume transitional node state!\n"));
999 break;
1000 }
1001 }
1002
1003 for (i = 0; i < iNodeList.size(); i++)
1004 {
1005 //If possible pause node is not started.
1006 if (iNodeList[i].iCanNodePause && (iNodeList[i].iNode.iNode->GetState() != EPVMFNodeStarted))
1007 {
1008 return;
1009 }
1010 }
1011
1012 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckResume resume complete\n"));
1013
1014 //If reached this point then the datapath is deemed resumed, notify upper layer.
1015 SetState(EOpened);
1016 ResumeComplete();
1017 return;
1018 }
1019
SendNodeCmd(PV2WayNodeCmdType cmd,int32 i)1020 bool CPV2WayDatapath::SendNodeCmd(PV2WayNodeCmdType cmd, int32 i)
1021 {
1022 int32 error;
1023 OSCL_TRY(error, SendNodeCmdL(cmd, iNodeList[i]));
1024 OSCL_FIRST_CATCH_ANY(error,
1025 return false;);
1026 return true;
1027 }
1028
CheckClosed()1029 void CPV2WayDatapath::CheckClosed()
1030 {
1031 int32 i;
1032 int32 error;
1033 PVMFCommandId id;
1034 CPV2WayPortPair *inPortPair;
1035 CPV2WayPortPair *outPortPair;
1036
1037 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckClosed state %d\n", iState));
1038
1039 if (!HaveAllDependentPathsClosed())
1040 {
1041 return;
1042 }
1043
1044 if (!PathSpecificClose())
1045 {
1046 return;
1047 }
1048
1049 // List must be closed one node at a time starting from the destination to the source to make sure all memory fragments are freed up to the correct node.
1050 for (i = (int32) iNodeList.size() - 1; i >= 0 ; i--)
1051 {
1052
1053 if (IsDatapathNodeClosed(iNodeList[i])) continue;
1054 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckClosed node %d cur state %d, orig state %d, cmd issued %d\n", i, iNodeList[i].iNode.iNode->GetState(), iNodeList[i].iOriginalState, iNodeList[i].iCommandIssued));
1055
1056 if (iNodeList[i].iCommandIssued) return;
1057
1058 switch (iNodeList[i].iNode.iNode->GetState())
1059 {
1060 case EPVMFNodeCreated:
1061 case EPVMFNodeIdle:
1062 CloseNodePorts(iNodeList[i]);
1063 continue;
1064
1065 case EPVMFNodeInitialized:
1066 case EPVMFNodePrepared:
1067 case EPVMFNodeError:
1068 CloseNodePorts(iNodeList[i]);
1069 if (iNodeList[i].CloseableState())
1070 continue;
1071
1072 if (!SendNodeCmd(PV2WAY_NODE_CMD_RESET, i))
1073 {
1074 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckClosed unable to reset node\n"));
1075 return;
1076 }
1077 return;
1078
1079 case EPVMFNodeStarted:
1080 case EPVMFNodePaused:
1081 {
1082 inPortPair = iNodeList[i].iInputPort.iPortPair;
1083 outPortPair = iNodeList[i].iOutputPort.iPortPair;
1084
1085 //Must at least release ports.
1086
1087 if (inPortPair)
1088 {
1089 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckClosed release in port, state %d, can cancel %d\n", inPortPair->iDestPort.GetStatus(), iNodeList[i].iInputPort.iCanCancelPort));
1090 if (inPortPair->iDestPort.GetStatus() == EHasPort)
1091 {
1092 OSCL_TRY(error, inPortPair->iDestPort.SetCmdId(SendNodeCmdL(PV2WAY_NODE_CMD_RELEASEPORT, iNodeList[i], inPortPair->iDestPort.GetPort())));
1093 OSCL_FIRST_CATCH_ANY(error,
1094 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckClosed unable to release input port\n"));
1095 return;);
1096
1097 inPortPair->iDestPort.SetStatus(EReleasePort);
1098 return;
1099 }
1100 else if ((inPortPair->iDestPort.GetStatus() == ERequestPort) &&
1101 iNodeList[i].iInputPort.iCanCancelPort)
1102 {
1103 id = inPortPair->iDestPort.GetCmdId();
1104 OSCL_TRY(error, inPortPair->iDestPort.SetCmdId(SendNodeCmdL(PV2WAY_NODE_CMD_CANCELCMD, iNodeList[i], &id)));
1105 OSCL_FIRST_CATCH_ANY(error,
1106 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckClosed unable to cancel request input port\n"));
1107 return;);
1108
1109 inPortPair->iDestPort.SetStatus(EReleasePort);
1110 return;
1111 }
1112 }
1113
1114 if (outPortPair)
1115 {
1116 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckClosed release out port, state %d, can cancel %d\n", outPortPair->iSrcPort.GetStatus(), iNodeList[i].iOutputPort.iCanCancelPort));
1117 if (outPortPair->iSrcPort.GetStatus() == EHasPort)
1118 {
1119 OSCL_TRY(error, outPortPair->iSrcPort.SetCmdId(SendNodeCmdL(PV2WAY_NODE_CMD_RELEASEPORT, iNodeList[i], outPortPair->iSrcPort.GetPort())));
1120 OSCL_FIRST_CATCH_ANY(error,
1121 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckClosed unable to release output port\n"));
1122 return;);
1123
1124 outPortPair->iSrcPort.SetStatus(EReleasePort);
1125 return;
1126 }
1127 else if ((outPortPair->iSrcPort.GetStatus() == EHasPort) &&
1128 iNodeList[i].iOutputPort.iCanCancelPort)
1129 {
1130 id = outPortPair->iSrcPort.GetCmdId();
1131 OSCL_TRY(error, outPortPair->iSrcPort.SetCmdId(SendNodeCmdL(PV2WAY_NODE_CMD_CANCELCMD, iNodeList[i], &id)));
1132 OSCL_FIRST_CATCH_ANY(error,
1133 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckClosed unable to cancel request output port\n"));
1134 return;);
1135
1136 outPortPair->iSrcPort.SetStatus(EReleasePort);
1137 return;
1138 }
1139 }
1140
1141 if (inPortPair)
1142 {
1143 switch (inPortPair->iDestPort.GetStatus())
1144 {
1145 case EHasPort:
1146 case ENoPort:
1147 break;
1148
1149 default:
1150 return;
1151 }
1152 }
1153
1154 if (outPortPair)
1155 {
1156 switch (outPortPair->iSrcPort.GetStatus())
1157 {
1158 case EHasPort:
1159 case ENoPort:
1160 break;
1161
1162 default:
1163 return;
1164 }
1165 }
1166
1167 if (!SendNodeCmd(PV2WAY_NODE_CMD_STOP, i))
1168 {
1169 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CheckClosed unable to stop node\n"));
1170 return;
1171 }
1172
1173 return;
1174 }
1175
1176 default:
1177 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckClosed transitional node state!\n"));
1178 return;
1179 }
1180 }
1181
1182 for (i = 0; i < (int32) iNodeList.size(); i ++)
1183 {
1184 //If node is not in its original state when datapath was opened then not closed yet.
1185 if (!IsDatapathNodeClosed(iNodeList[i])) return;
1186 }
1187
1188 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckClosed close complete\n"));
1189
1190 //If reached this point then all ports have been deallocated and datapath is deemed closed, notify upper layer.
1191 SetState(EClosed);
1192 CloseComplete();
1193 NotifyParentPaths();
1194
1195 return;
1196 }
1197
CheckPath()1198 void CPV2WayDatapath::CheckPath()
1199 {
1200 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CheckPath path type %d, format %s, state %d\n", iType, iFormat.getMIMEStrPtr(), iState));
1201
1202 switch (iState)
1203 {
1204 case EOpening:
1205 CheckOpen();
1206 break;
1207 case EPausing:
1208 CheckPause();
1209 break;
1210 case EUnpausing:
1211 CheckResume();
1212 break;
1213 case EClosing:
1214 CheckClosed();
1215 break;
1216 default:
1217 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, (0, "CPV2WayDatapath::CheckPath warning: static state\n"));
1218 break;
1219 }
1220 }
1221
CommandHandler(PV2WayNodeCmdType aType,const PVMFCmdResp & aResponse)1222 void CPV2WayDatapath::CommandHandler(PV2WayNodeCmdType aType, const PVMFCmdResp& aResponse)
1223 {
1224 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::CommandHandler path type %d, state %d, cmd type %d, status %d\n", iType, iState, aType, aResponse.GetCmdStatus()));
1225 CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext();
1226 uint16 i;
1227
1228 for (i = 0; i < iNodeList.size(); i++)
1229 {
1230 if (iNodeList[i].iNode.iNode == data->iNode)
1231 {
1232 iNodeList[i].iCommandIssued = false;
1233 break;
1234 }
1235 }
1236
1237 switch (aType)
1238 {
1239 case PV2WAY_NODE_CMD_REQUESTPORT:
1240 if (aResponse.GetCmdStatus() != PVMFSuccess)
1241 {
1242 PortStatusChange(data->iNode, aResponse.GetCmdId(), NULL);
1243 DatapathError();
1244 }
1245 else
1246 {
1247 if (PortStatusChange(data->iNode, aResponse.GetCmdId(), (PVMFPortInterface *) aResponse.GetEventData()) != PVMFSuccess)
1248 {
1249 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::CommandHandler PortStatusChange failed!\n"));
1250 DatapathError();
1251 }
1252 else
1253 {
1254
1255 bool isConnected;
1256 //Check if all ports have been allocated.
1257 for (i = 0, isConnected = true; i < iPortPairList.size(); i++)
1258 {
1259 if (!iPortPairList[i].iIsConnected)
1260 {
1261 //If all ports have not been connected yet
1262 isConnected = false;
1263 break;
1264 }
1265 // right here- check for negotiated between the two!
1266 }
1267
1268 iAllPortsConnected = isConnected;
1269 }
1270 }
1271 break;
1272
1273 case PV2WAY_NODE_CMD_RELEASEPORT:
1274 case PV2WAY_NODE_CMD_CANCELCMD:
1275 PortStatusChange(data->iNode, aResponse.GetCmdId(), NULL);
1276 break;
1277 case PV2WAY_NODE_CMD_START:
1278 if (aResponse.GetCmdStatus() == PVMFSuccess)
1279 {
1280 if (i2Way->IsSinkNode(data->iNode))
1281 {
1282 TPV2WayNode* sink_node = i2Way->GetTPV2WayNode(i2Way->iSinkNodes, data->iNode);
1283 OSCL_ASSERT(sink_node);
1284
1285 i2Way->SendNodeCmdL(PV2WAY_NODE_CMD_SKIP_MEDIA_DATA, sink_node, i2Way);
1286 }
1287 }
1288 else
1289 {
1290 DatapathError();
1291 }
1292 break;
1293 default:
1294 if (aResponse.GetCmdStatus() != PVMFSuccess)
1295 {
1296 DatapathError();
1297 }
1298 break;
1299 }
1300
1301 CheckPath();
1302 return;
1303 }
1304
DependentPathClosed(CPV2WayDatapath * aDependentPath)1305 void CPV2WayDatapath::DependentPathClosed(CPV2WayDatapath *aDependentPath)
1306 {
1307 OSCL_UNUSED_ARG(aDependentPath);
1308 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::DependentPathClosed path state %d\n", iState));
1309 if (iState == EClosing)
1310 {
1311 //Start closing this path.
1312 CheckPath();
1313 }
1314 return;
1315 }
1316
HaveAllDependentPathsClosed()1317 bool CPV2WayDatapath::HaveAllDependentPathsClosed()
1318 {
1319 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::HaveAllDependentPathsClosed path state %d\n", iState));
1320 for (uint32 i = 0; i < iDependentPathList.size(); i ++)
1321 {
1322 if (iDependentPathList[i]->GetState() != EClosed)
1323 {
1324 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::DependentPathClosed not all dependent paths closed, %d\n", i));
1325 return false;
1326 }
1327 }
1328
1329 return true;
1330 }
1331
IsParentClosing()1332 bool CPV2WayDatapath::IsParentClosing()
1333 {
1334 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::IsParentClosing path state %d\n", iState));
1335 for (uint32 i = 0; i < iParentPathList.size(); i++)
1336 {
1337 if (iParentPathList[i]->GetState() == EClosing)
1338 {
1339 //Parent datapath is closing
1340 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::IsParentClosing parent path closing, %d\n", i));
1341 return true;
1342 }
1343 }
1344
1345 //No parent datapath is closing
1346 return false;
1347 }
1348
NotifyParentPaths()1349 void CPV2WayDatapath::NotifyParentPaths()
1350 {
1351 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::NotifyParentPaths path state %d\n", iState));
1352 for (uint32 i = 0; i < iParentPathList.size(); i++)
1353 {
1354 iParentPathList[i]->DependentPathClosed(this);
1355 }
1356 return;
1357 }
1358
ParentIsClosing()1359 bool CPV2WayDatapath::ParentIsClosing()
1360 {
1361 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "CPV2WayDatapath::ParentIsClosing path state %d\n", iState));
1362 return Close();
1363 }
1364
GetKvp(PVMFPortInterface & aPort,bool aInput,PvmiKvp * & aKvp,int32 & aNumKvpElem,OsclAny * & aconfigPtr)1365 PVMFStatus CPV2WayDatapath::GetKvp(PVMFPortInterface &aPort,
1366 bool aInput,
1367 PvmiKvp*& aKvp,
1368 int32& aNumKvpElem,
1369 OsclAny*& aconfigPtr)
1370 {
1371 PVMFStatus status = PVMFFailure;
1372 PvmiCapabilityContext context = NULL;
1373 PvmiKeyType keyType;
1374
1375 aPort.QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, aconfigPtr);
1376 if (aconfigPtr)
1377 {
1378 if (aInput)
1379 {
1380 keyType = OSCL_CONST_CAST(char*, INPUT_FORMATS_CAP_QUERY);
1381 }
1382 else
1383 {
1384 keyType = OSCL_CONST_CAST(char*, OUTPUT_FORMATS_CAP_QUERY);
1385 }
1386
1387 status = ((PvmiCapabilityAndConfig *)aconfigPtr)->getParametersSync(NULL,
1388 keyType, aKvp, aNumKvpElem, context);
1389
1390 if (status != PVMFSuccess && aInput)
1391 {
1392 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1393 (0, "CPV2WayDatapath::GetKvp 1st getParametersSync failed %d. Trying another\n", status));
1394
1395 keyType = OSCL_CONST_CAST(char*, "x-pvmf/video/decode/input_formats");
1396 status = ((PvmiCapabilityAndConfig *)aconfigPtr)->getParametersSync(NULL,
1397 keyType, aKvp, aNumKvpElem, context);
1398 }
1399
1400 if (status != PVMFSuccess && !aInput)
1401 {
1402 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1403 (0, "CPV2WayDatapath::GetKvp 2nd getParametersSync failed %d. Trying another\n", status));
1404
1405 keyType = OSCL_CONST_CAST(char*, "x-pvmf/audio/decode/output_formats");
1406 status = ((PvmiCapabilityAndConfig *)aconfigPtr)->getParametersSync(NULL,
1407 keyType, aKvp, aNumKvpElem, context);
1408 }
1409 }
1410 return status;
1411 }
1412
GetPortFormatType(PVMFPortInterface & aPort,bool aInput,PVMFPortInterface * aOtherPort)1413 PVMFFormatType CPV2WayDatapath::GetPortFormatType(PVMFPortInterface &aPort,
1414 bool aInput,
1415 PVMFPortInterface *aOtherPort)
1416 {
1417 PVMFStatus status = PVMFFailure;
1418 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE,
1419 (0, "CPV2WayDatapath::GetPortFormatType, is input %d\n", aInput));
1420 PvmiKvp *kvp = NULL;
1421 int32 numkvpElements = 0;
1422 PvmiKvp *kvpOther = NULL;
1423 int32 numkvpOtherElements = 0;
1424 OsclAny *configPtr = NULL;
1425 OsclAny *configOtherPtr = NULL;
1426 PVMFFormatType format = PVMF_MIME_FORMAT_UNKNOWN;
1427 PVMFFormatType format_datapath_media_type = PVMF_MIME_FORMAT_UNKNOWN;
1428
1429
1430 //If config ptr exists, otherwise assume port has been configured.
1431 status = GetKvp(aPort, aInput, kvp, numkvpElements, configPtr);
1432 if (status == PVMFSuccess && (aOtherPort != NULL))
1433 {
1434 status = GetKvp(*aOtherPort, !aInput, kvpOther, numkvpOtherElements, configOtherPtr);
1435 }
1436
1437 if (status == PVMFSuccess)
1438 {
1439 for (int32 ii = 0; ii < numkvpElements; ++ii)
1440 {
1441 if ((pv_mime_strcmp(kvp[ii].key, "x-pvmf/port/formattype;valtype=char*") == 0) ||
1442 (aInput && (pv_mime_strcmp(kvp[ii].key, INPUT_FORMATS_VALTYPE) == 0)) ||
1443 (pv_mime_strcmp(kvp[ii].key, OUTPUT_FORMATS_VALTYPE) == 0))
1444 {
1445 format = kvp[ii].value.pChar_value;
1446 if ((format.isAudio() && iFormat.isAudio()) ||
1447 (format.isVideo() && iFormat.isVideo()) ||
1448 (format.isFile() && iFormat.isFile()))
1449 {
1450 format_datapath_media_type = format;
1451 }
1452 // loop through other port, look for a match
1453 // if there is a match return it
1454 for (int jj = 0; jj < numkvpOtherElements; ++jj)
1455 {
1456 if ((format == kvpOther[jj].value.pChar_value) &&
1457 ((pv_mime_strcmp(kvpOther[jj].key, "x-pvmf/port/formattype;valtype=char*") == 0) ||
1458 (pv_mime_strcmp(kvpOther[ii].key, INPUT_FORMATS_VALTYPE) == 0) ||
1459 (pv_mime_strcmp(kvpOther[ii].key, OUTPUT_FORMATS_VALTYPE) == 0)))
1460 {
1461 ((PvmiCapabilityAndConfig *)configPtr)->releaseParameters(NULL,
1462 kvp, numkvpElements);
1463 if (configOtherPtr != NULL)
1464 {
1465 ((PvmiCapabilityAndConfig *)configOtherPtr)->releaseParameters(NULL,
1466 kvpOther, numkvpOtherElements);
1467 }
1468 return format;
1469 }
1470 }
1471 }
1472 }
1473 ((PvmiCapabilityAndConfig *)configPtr)->releaseParameters(NULL, kvp, numkvpElements);
1474 if (configOtherPtr != NULL)
1475 {
1476 ((PvmiCapabilityAndConfig *)configOtherPtr)->releaseParameters(NULL, kvpOther, numkvpOtherElements);
1477 }
1478 return format_datapath_media_type;
1479 }
1480 else
1481 {
1482 if (configPtr != NULL)
1483 {
1484 ((PvmiCapabilityAndConfig *)configPtr)->releaseParameters(NULL, kvp, numkvpElements);
1485 }
1486 if (configOtherPtr != NULL)
1487 {
1488 ((PvmiCapabilityAndConfig *)configOtherPtr)->releaseParameters(NULL, kvpOther, numkvpOtherElements);
1489 }
1490 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "CPV2WayDatapath::GetPortFormatType 3rd getParametersSync failed %d, using configured format\n", status));
1491 }
1492
1493 return format_datapath_media_type;
1494 }
1495
SetFormatSpecificInfo(uint8 * fsi,uint16 fsi_len)1496 void CPV2WayDatapath::SetFormatSpecificInfo(uint8* fsi, uint16 fsi_len)
1497 {
1498 if (iFsi)
1499 {
1500 OSCL_DEFAULT_FREE(iFsi);
1501 iFsi = NULL;
1502 iFsiLen = 0;
1503 }
1504 iFsi = (uint8*)OSCL_DEFAULT_MALLOC(fsi_len);
1505 iFsiLen = fsi_len;
1506 oscl_memcpy(iFsi, fsi, iFsiLen);
1507 }
1508
1509
GetFormatSpecificInfo(uint32 * len)1510 uint8* CPV2WayDatapath::GetFormatSpecificInfo(uint32* len)
1511 {
1512 *len = iFsiLen;
1513 return iFsi;
1514 }
1515
SetSourceSinkFormat(PVMFFormatType aFormatType)1516 void CPV2WayDatapath::SetSourceSinkFormat(PVMFFormatType aFormatType)
1517 {
1518 iSourceSinkFormat = aFormatType;
1519 }
1520
GetSourceSinkFormat() const1521 PVMFFormatType CPV2WayDatapath::GetSourceSinkFormat() const
1522 {
1523 return iSourceSinkFormat;
1524 }
1525
1526
1527
1528
1529