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