• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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