Home | History | Annotate | Download | only in src
      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 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1510 uint8* CPV2WayDatapath::GetFormatSpecificInfo(uint32* len)
   1511 {
   1512     *len = iFsiLen;
   1513     return iFsi;
   1514 }
   1515 
   1516 void CPV2WayDatapath::SetSourceSinkFormat(PVMFFormatType aFormatType)
   1517 {
   1518     iSourceSinkFormat = aFormatType;
   1519 }
   1520 
   1521 PVMFFormatType CPV2WayDatapath::GetSourceSinkFormat() const
   1522 {
   1523     return iSourceSinkFormat;
   1524 }
   1525 
   1526 
   1527 
   1528 
   1529