1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #ifndef PV_2WAY_SDKINFO_H_INCLUDED 19 #include "pv_2way_sdkinfo.h" 20 #endif 21 22 #ifndef PV_2WAY_ENGINE_H_INCLUDED 23 #include "pv_2way_engine.h" 24 #endif 25 26 #include "pv_2way_dec_data_channel_datapath.h" 27 #include "pv_2way_enc_data_channel_datapath.h" 28 #include "pv_2way_mux_datapath.h" 29 30 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 31 #include "pv_2way_preview_datapath.h" 32 #include "playfromfilenode.h" 33 #endif 34 35 #if defined(PV_RECORD_TO_FILE_SUPPORT) 36 #include "pv_2way_rec_datapath.h" 37 38 #include "pvmp4ffcn_factory.h" 39 #include "pvmp4ffcn_trackconfig.h" 40 #include "pvmp4ffcn_clipconfig.h" 41 #include "pvmf_composer_size_and_duration.h" 42 #endif 43 44 #if (defined(PV_RECORD_TO_FILE_SUPPORT) || defined(PV_PLAY_FROM_FILE_SUPPORT)) 45 #include "pvmf_splitter_node.h" 46 #endif 47 48 #include "pvmf_videoparser_node.h" 49 50 #ifdef PV2WAY_USE_OMX 51 #include "OMX_Core.h" 52 #include "pv_omxcore.h" 53 #include "pvmf_omx_videodec_factory.h" 54 #include "pvmf_omx_enc_factory.h" 55 #include "pvmf_omx_audiodec_factory.h" 56 #include "pvmf_audio_encnode_extension.h" 57 #else 58 #include "pvmf_videodec_factory.h" 59 #include "pvmf_videoenc_node_factory.h" 60 #include "pvmfamrencnode_extension.h" 61 #include "pvmf_gsmamrdec_factory.h" 62 #include "pvmf_amrenc_node_factory.h" 63 #endif 64 65 #include "pvmf_video.h" 66 #include "pvmp4h263encextension.h" 67 68 #ifndef PV_ENGINE_OBSERVER_H_INCLUDED 69 #include "pv_engine_observer.h" 70 #endif 71 72 #ifndef PV_DISABLE_VIDRECNODE 73 #include "pvvideoencmdfnode_factory.h" 74 #endif 75 76 #ifndef PV_DISABLE_DEVSOUNDNODES 77 #include "pvdevsound_node_base.h" 78 #endif 79 80 #include "pvlogger.h" 81 82 #include "oscl_dll.h" 83 84 #ifndef NO_2WAY_324 85 #include "tsc_h324m_config_interface.h" 86 #endif 87 88 89 #include "pvmf_nodes_sync_control.h" 90 91 #include "pv_2way_track_info_impl.h" 92 93 #include "pvmi_config_and_capability.h" 94 95 96 #ifdef MEM_TRACK 97 #include "oscl_mem.h" 98 #include "oscl_mem_audit.h" 99 #endif 100 101 // Define entry point for this DLL 102 OSCL_DLL_ENTRY_POINT_DEFAULT() 103 104 //Record defaults 105 #define DEFAULT_RECORDED_CALL_FILENAME _STRLIT("c:\\recorded_call.mp4") 106 #define DEFAULT_RECORDED_CALL_TIMESCALE 1000 107 #define DEFAULT_RECORDED_CALL_TYPE PVMP4FFCN_NO_TEMP_FILE_AUTHORING_MODE 108 109 #define NUM_MANDATORY_2WAY_AUDIO_CODECS 1 110 #define NUM_MANDATORY_2WAY_VIDEO_CODECS 2 111 #define PV_VIDEO_FRAME_RATE_NUMERATOR 10 112 #define PV_VIDEO_FRAME_RATE_DENOMINATOR 1 113 114 //Default skipMediaData params 115 const uint32 resume_timestamp = 0; 116 #define STREAMID 0 117 #define PBPOSITION_CONTINUOUS false 118 //Early and late margins for audio and video frames 119 #define SYNC_EARLY_MARGIN 100 120 #define SYNC_LATE_MARGIN 100 121 122 //Preferred codecs 123 #define VIDEO_CODEC_MPEG4 1 124 #define VIDEO_CODEC_H263 2 125 #define AUDIO_CODEC_GSM 3 126 #define AUDIO_CODEC_G723 4 127 #define PREFERRED_VIDEO_CODEC VIDEO_CODEC_MPEG4 128 #define PREFERRED_AUDIO_CODEC AUDIO_CODEC_GSM 129 130 const uint32 KSamplingRate = 8000; 131 const uint32 KBitsPerSample = 16; 132 const uint32 KNumChannels = 1; 133 const uint32 KNumPCMFrames = 2; // 10 134 135 //TEMP -RH 136 #define PV2WAY_UNKNOWN_PORT -1 137 #define PV2WAY_IN_PORT 0 138 #define PV2WAY_OUT_PORT 1 139 #define PV2WAY_IO_PORT 3 140 141 #define INVALID_TRACK_ID 255 142 143 #define AUDIO_FIRST 1 144 145 #ifndef PV_DISABLE_VIDRECNODE 146 #define CREATE_VIDEO_ENC_NODE() PVVideoEncMDFNodeFactory::Create(this,this,this) 147 #define DELETE_VIDEO_ENC_NODE(n) PVVideoEncMDFNodeFactory::Delete(n) 148 #else 149 #ifndef PV2WAY_USE_OMX 150 #define CREATE_VIDEO_ENC_NODE() PVMFVideoEncNodeFactory::CreateVideoEncNode() 151 #define DELETE_VIDEO_ENC_NODE(n) PVMFVideoEncNodeFactory::DeleteVideoEncNode(n) 152 #endif // PV2WAY_USE_OMX 153 #endif 154 155 #ifndef PV_DISABLE_DEVVIDEOPLAYNODE 156 #define CREATE_VIDEO_DEC_NODE() PVDevVideoPlayNode::Create() 157 #define DELETE_VIDEO_DEC_NODE(n) OSCL_DELETE(n) 158 #else 159 #ifdef PV2WAY_USE_OMX 160 #define CREATE_OMX_VIDEO_DEC_NODE() PVMFOMXVideoDecNodeFactory::CreatePVMFOMXVideoDecNode() 161 #define DELETE_OMX_VIDEO_DEC_NODE(n) PVMFOMXVideoDecNodeFactory::DeletePVMFOMXVideoDecNode(n) 162 #endif // PV2WAY_USE_OMX 163 #define CREATE_VIDEO_DEC_NODE() PVMFVideoDecNodeFactory::CreatePVMFVideoDecNode() 164 #define DELETE_VIDEO_DEC_NODE(n) PVMFVideoDecNodeFactory::DeletePVMFVideoDecNode(n) 165 #endif 166 167 #ifdef PV2WAY_USE_OMX 168 #define CREATE_OMX_ENC_NODE() PVMFOMXEncNodeFactory::CreatePVMFOMXEncNode() 169 #define DELETE_OMX_ENC_NODE(n) PVMFOMXEncNodeFactory::DeletePVMFOMXEncNode(n); 170 #endif // PV2WAY_USE_OMX 171 172 #ifndef PV2WAY_USE_OMX 173 #define CREATE_AUDIO_ENC_NODE() PvmfAmrEncNodeFactory::Create() 174 #define DELETE_AUDIO_ENC_NODE(n) PvmfAmrEncNodeFactory::Delete(n) 175 #endif // PV2WAY_USE_OMX 176 177 178 #ifdef PV2WAY_USE_OMX 179 #define CREATE_OMX_AUDIO_DEC_NODE() PVMFOMXAudioDecNodeFactory::CreatePVMFOMXAudioDecNode() 180 #define DELETE_OMX_AUDIO_DEC_NODE(n) PVMFOMXAudioDecNodeFactory::DeletePVMFOMXAudioDecNode(n) 181 #else 182 #define CREATE_AUDIO_DEC_NODE() PVMFGSMAMRDecNodeFactory::CreatePVMFGSMAMRDecNode() 183 #define DELETE_AUDIO_DEC_NODE(n) PVMFGSMAMRDecNodeFactory::DeletePVMFGSMAMRDecNode(n) 184 #endif // PV2WAY_USE_OMX 185 186 187 188 #define FILL_FORMAT_INFO(format_type, format_info)\ 189 GetSampleSize(format_type,&format_info.min_sample_size,&format_info.max_sample_size);\ 190 format_info.format = format_type; 191 192 OSCL_EXPORT_REF CPV324m2Way *CPV324m2Way::NewL(PVMFNodeInterface* aTsc, 193 TPVTerminalType aTerminalType, 194 PVCommandStatusObserver* aCmdStatusObserver, 195 PVInformationalEventObserver *aInfoEventObserver, 196 PVErrorEventObserver *aErrorEventObserver) 197 { 198 CPV324m2Way* aRet = OSCL_NEW(CPV324m2Way, ()); 199 if (aRet) 200 { 201 int32 error = Construct(aRet, aTsc, aTerminalType, aCmdStatusObserver, 202 aInfoEventObserver, aErrorEventObserver); 203 if (error) 204 { 205 OSCL_DELETE(aRet); 206 aRet = NULL; 207 OSCL_LEAVE(error); 208 } 209 } 210 else 211 { 212 OSCL_LEAVE(PVMFErrNoMemory); 213 } 214 215 return aRet; 216 } 217 218 int32 CPV324m2Way::Construct(CPV324m2Way* aRet, 219 PVMFNodeInterface* aTsc, 220 TPVTerminalType aTerminalType, 221 PVCommandStatusObserver* aCmdStatusObserver, 222 PVInformationalEventObserver *aInfoEventObserver, 223 PVErrorEventObserver *aErrorEventObserver) 224 { 225 int32 error = 0; 226 OSCL_TRY(error, aRet->ConstructL(aTsc, 227 aTerminalType, 228 aCmdStatusObserver, 229 aInfoEventObserver, 230 aErrorEventObserver)); 231 return error; 232 } 233 234 OSCL_EXPORT_REF void CPV324m2Way::Delete(CPV324m2Way *aTerminal) 235 { 236 OSCL_DELETE(aTerminal); 237 } 238 239 CPV324m2Way::CPV324m2Way() : 240 OsclActiveObject(OsclActiveObject::EPriorityNominal, "PV2WayEngine"), 241 iState(EIdle), 242 iLastState(EIdle), 243 iCmdStatusObserver(NULL), 244 iInfoEventObserver(NULL), 245 iErrorEventObserver(NULL), 246 iCommandId(0), 247 iVideoEncDatapath(NULL), 248 iVideoDecDatapath(NULL), 249 iAudioEncDatapath(NULL), 250 iAudioDecDatapath(NULL), 251 iIsStackConnected(false), 252 iMuxDatapath(NULL), 253 iInitInfo(NULL), 254 iConnectInfo(NULL), 255 iDisconnectInfo(NULL), 256 iResetInfo(NULL), 257 iCancelInfo(NULL), 258 iSessionParamsInfo(NULL), 259 iLogger(NULL), 260 iMinIFrameRequestInterval(DEFAULT_MIN_IFRAME_REQ_INT), 261 iIFrameReqTimer("IFrameReqTimer"), 262 iEndSessionTimer(NULL), 263 iRemoteDisconnectTimer(NULL), 264 isIFrameReqTimerActive(false), 265 #ifndef NO_2WAY_324 266 iIncomingAudioTrackTag(INVALID_TRACK_ID), 267 iIncomingVideoTrackTag(INVALID_TRACK_ID), 268 iOutgoingAudioTrackTag(INVALID_TRACK_ID), 269 iOutgoingVideoTrackTag(INVALID_TRACK_ID), 270 #endif 271 iVideoEncQueryIntCmdId(-1), 272 #if defined(PV_RECORD_TO_FILE_SUPPORT) 273 iRecordFileState(File2WayIdle), 274 iInitRecFileInfo(NULL), 275 iResetRecFileInfo(NULL), 276 iFFComposerNode(NULL), 277 iAudioRecDatapath(NULL), 278 iVideoRecDatapath(NULL), 279 iRecFileSizeNotificationInterval(0), 280 iRecFileSizeNotificationTimer("iRecFileSizeNotificationTimer"), 281 isRecFileSizeNotificationTimerActive(false), 282 #endif 283 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 284 iAudioPreviewDatapath(NULL), 285 iVideoPreviewDatapath(NULL), 286 iPlayFileState(File2WayIdle), 287 iUsePlayFileAsSource(false), 288 iInitPlayFileInfo(NULL), 289 iResetPlayFileInfo(NULL), 290 iPlayFileCmdInfo(NULL), 291 iPlayFromFileNode(NULL), 292 #endif 293 iTSCInterface(NULL), 294 iTSC324mInterface(NULL), 295 iPendingTscReset(-1), 296 iPendingAudioEncReset(-1), 297 iPendingVideoEncReset(-1), 298 iAudioDatapathLatency(0), 299 iVideoDatapathLatency(0) 300 { 301 iLogger = PVLogger::GetLoggerObject("2wayEngine"); 302 iSyncControlPVUuid = PvmfNodesSyncControlUuid; 303 iVideoEncPVUuid = PVMp4H263EncExtensionUUID; 304 iCapConfigPVUuid = PVMI_CAPABILITY_AND_CONFIG_PVUUID; 305 306 #ifdef PV2WAY_USE_OMX 307 iAudioEncPVUuid = PVAudioEncExtensionUUID; 308 #else 309 iAudioEncPVUuid = PVAMREncExtensionUUID; 310 #endif 311 312 #if defined(PV_RECORD_TO_FILE_SUPPORT) 313 iFFClipConfigPVUuid = KPVMp4FFCNClipConfigUuid; 314 iFFTrackConfigPVUuid = KPVMp4FFCNTrackConfigUuid; 315 iFFSizeAndDurationPVUuid = PvmfComposerSizeAndDurationUuid; 316 #endif 317 iAddDataSourceVideoCmd = NULL; 318 #ifdef PV2WAY_USE_OMX 319 OMX_MasterInit(); 320 #endif // PV2WAY_USE_OMX 321 322 //creating timers 323 iEndSessionTimer = OSCL_NEW(OsclTimer<OsclMemAllocator>, (END_SESSION_TIMER, END_SESSION_TIMER_FREQUENCY)); 324 iRemoteDisconnectTimer = OSCL_NEW(OsclTimer<OsclMemAllocator>, (REMOTE_DISCONNECT_TIMER, REMOTE_DISCONNECT_TIMER_FREQUENCY)); 325 } 326 327 CPV324m2Way::~CPV324m2Way() 328 { 329 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 330 (0, "CPV324m2Way::~CPV324m2Way\n")); 331 332 Oscl_Map<PVMFFormatType, CPvtMediaCapability*, OsclMemAllocator, pvmf_format_type_key_compare_class>::iterator it = iStackSupportedFormats.begin(); 333 while (it != iStackSupportedFormats.end()) 334 { 335 CPvtMediaCapability* media_capability = (*it++).second; 336 OSCL_DELETE(media_capability); 337 } 338 iStackSupportedFormats.clear(); 339 340 Cancel(); 341 iIncomingChannelParams.clear(); 342 iOutgoingChannelParams.clear(); 343 344 iIncomingAudioCodecs.clear(); 345 iOutgoingAudioCodecs.clear(); 346 iIncomingVideoCodecs.clear(); 347 iOutgoingVideoCodecs.clear(); 348 iFormatCapability.clear(); 349 iClock.Stop(); 350 iSinkNodeList.clear(); 351 ClearVideoEncNode(); 352 353 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 354 if (iVideoPreviewDatapath) 355 { 356 OSCL_DELETE(iVideoPreviewDatapath); 357 iVideoPreviewDatapath = NULL; 358 } 359 360 if (iAudioPreviewDatapath) 361 { 362 OSCL_DELETE(iAudioPreviewDatapath); 363 iAudioPreviewDatapath = NULL; 364 } 365 #endif 366 367 #if defined(PV_RECORD_TO_FILE_SUPPORT) 368 if (iVideoRecDatapath) 369 { 370 OSCL_DELETE(iVideoRecDatapath); 371 iVideoRecDatapath = NULL; 372 } 373 374 if (iAudioRecDatapath) 375 { 376 OSCL_DELETE(iAudioRecDatapath); 377 iAudioRecDatapath = NULL; 378 } 379 #endif 380 381 if (iVideoEncDatapath) 382 { 383 OSCL_DELETE(iVideoEncDatapath); 384 iVideoEncDatapath = NULL; 385 } 386 387 if (iVideoDecDatapath) 388 { 389 OSCL_DELETE(iVideoDecDatapath); 390 iVideoDecDatapath = NULL; 391 } 392 393 if (iAudioEncDatapath) 394 { 395 OSCL_DELETE(iAudioEncDatapath); 396 iAudioEncDatapath = NULL; 397 } 398 399 if (iAudioDecDatapath) 400 { 401 OSCL_DELETE(iAudioDecDatapath); 402 iAudioDecDatapath = NULL; 403 } 404 405 if (iMuxDatapath) 406 { 407 OSCL_DELETE(iMuxDatapath); 408 iMuxDatapath = NULL; 409 } 410 411 PVMFNodeInterface * nodeIFace = (PVMFNodeInterface *)iTscNode; 412 if (nodeIFace) 413 { 414 OSCL_DELETE(nodeIFace); 415 iTscNode.Clear(); 416 } 417 418 #ifdef PV2WAY_USE_OMX 419 OMX_MasterDeinit(); 420 #endif 421 422 if (iEndSessionTimer) 423 { 424 iEndSessionTimer->Clear(); 425 OSCL_DELETE(iEndSessionTimer); 426 iEndSessionTimer = NULL; 427 } 428 429 if (iRemoteDisconnectTimer) 430 { 431 iRemoteDisconnectTimer->Clear(); 432 OSCL_DELETE(iRemoteDisconnectTimer); 433 iRemoteDisconnectTimer = NULL; 434 } 435 436 437 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 438 (0, "CPV324m2Way::~CPV324m2Way - done\n")); 439 } 440 441 void CPV324m2Way::ClearVideoEncNode() 442 { 443 PVMFNodeInterface * nodeIFace = (PVMFNodeInterface *)iVideoEncNode; 444 if (nodeIFace) 445 { 446 nodeIFace->ThreadLogoff(); 447 if (iVideoEncNodeInterface.iInterface) iVideoEncNodeInterface.iInterface->removeRef(); 448 #ifndef PV_DISABLE_VIDRECNODE 449 PVVideoEncMDFNodeFactory::Delete(nodeIFace); 450 #else 451 452 #ifdef PV2WAY_USE_OMX 453 DELETE_OMX_ENC_NODE(nodeIFace); 454 #else 455 DELETE_VIDEO_ENC_NODE(nodeIFace); 456 #endif // PV2WAY_USE_OMX 457 #endif // PV_DISABLE_VIDRECNODE 458 iVideoEncNode.Clear() ; 459 iVideoEncNodeInterface.Reset(); 460 } 461 } 462 463 PVCommandId CPV324m2Way::GetSDKInfo(PVSDKInfo &aSDKInfo, OsclAny* aContextData) 464 { 465 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 466 (0, "CPV324m2Way::GetSDKInfo\n")); 467 468 FillSDKInfo(aSDKInfo); 469 470 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 471 472 cmd->type = PVT_COMMAND_GET_SDK_INFO; 473 cmd->id = iCommandId; 474 cmd->contextData = aContextData; 475 cmd->status = PVMFSuccess; 476 Dispatch(cmd); 477 return iCommandId++; 478 } 479 480 PVCommandId CPV324m2Way::GetSDKModuleInfo(PVSDKModuleInfo &aSDKModuleInfo, 481 OsclAny* aContextData) 482 { 483 OSCL_UNUSED_ARG(aSDKModuleInfo); 484 485 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 486 (0, "CPV324m2Way::GetSDKModuleInfo\n")); 487 488 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 489 490 cmd->type = PVT_COMMAND_GET_SDK_MODULE_INFO; 491 cmd->id = iCommandId; 492 cmd->contextData = aContextData; 493 cmd->status = PVMFSuccess; 494 Dispatch(cmd); 495 return iCommandId++; 496 } 497 498 void CPV324m2Way::PreInit() 499 { 500 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 501 (0, "CPV324m2Way::PreInit\n")); 502 503 PVMFNodeSessionInfo sessionInfo; 504 bool allocSuccessful = true; 505 506 switch (iState) 507 { 508 case EIdle: 509 510 if (iTerminalType == PV_324M) 511 { 512 #ifndef NO_2WAY_324 513 iTscNode = TPV2WayNode(new TSC_324m(PV_LOOPBACK_MUX)); 514 iTSC324mInterface = (TSC_324m *)iTscNode.iNode; 515 iTSCInterface = (TSC *)iTSC324mInterface; 516 // Create the list of stack supported formats 517 GetStackSupportedFormats(); 518 #endif 519 } 520 521 if (((PVMFNodeInterface *)iTscNode) == NULL) 522 { 523 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 524 (0, "CPV324m2Way::PreInit unable to allocate tsc node\n")); 525 allocSuccessful = false; 526 } 527 528 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 529 (0, "CPV324m2Way::PreInit created TSC Node(%x)", (PVMFNodeInterface *)iTscNode)); 530 531 break; 532 533 default: 534 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 535 (0, "CPV324m2Way::Init Error - invalid state\n")); 536 OSCL_LEAVE(PVMFErrInvalidState); 537 break; 538 } 539 } 540 541 PVCommandId CPV324m2Way::Init(PV2WayInitInfo& aInitInfo, 542 OsclAny* aContextData) 543 { 544 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 545 (0, "CPV324m2Way::InitL\n")); 546 547 PVMFNodeSessionInfo sessionInfo; 548 549 bool allocSuccessful = true; 550 551 switch (iState) 552 { 553 case EIdle: 554 { 555 if (iInitInfo) 556 { 557 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 558 (0, "CPV324m2Way::PreInit cmd already sent out")); 559 OSCL_LEAVE(PVMFErrBusy); 560 } 561 562 ((TSC_324m*)(iTscNode.iNode))->SetTscObserver(this); 563 InitiateSession(iTscNode); 564 565 ((TSC_324m*)(iTscNode.iNode))->SetMultiplexingDelayMs(0); 566 ((TSC_324m*)(iTscNode.iNode))->SetClock(&iClock); 567 568 SetPreferredCodecs(aInitInfo); 569 570 #if defined(PV_RECORD_TO_FILE_SUPPORT) 571 OSCL_TRY(error, iVideoDecSplitterNode = 572 TPV2WayNode(PVMFSplitterNode::Create());); 573 OSCL_FIRST_CATCH_ANY(error, 574 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 575 (0, "CPV324m2Way::PreInit unable to allocate video splitter node\n")); 576 allocSuccessful = false;); 577 578 OSCL_TRY(error, iFFComposerNode = 579 TPV2WayNode(PVMp4FFComposerNodeFactory::CreateMp4FFComposer(this, this, this));; 580 iFFComposerNode->SetClock(&iClock);); 581 OSCL_FIRST_CATCH_ANY(error, 582 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 583 (0, "CPV324m2Way::PreInit unable to allocate ff composer node\n")); 584 allocSuccessful = false;); 585 #endif 586 587 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 588 OSCL_TRY(error, iAudioSrcSplitterNode = 589 TPV2WayNode(PVMFSplitterNode::Create());); 590 OSCL_FIRST_CATCH_ANY(error, 591 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 592 (0, "CPV324m2Way::PreInit unable to allocate audio src splitter node\n")); 593 allocSuccessful = false;); 594 595 OSCL_TRY(error, iVideoSrcSplitterNode = 596 TPV2WayNode(PVMFSplitterNode::Create());); 597 OSCL_FIRST_CATCH_ANY(error, 598 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 599 (0, "CPV324m2Way::PreInit unable to allocate video src splitter node\n")); 600 allocSuccessful = false;); 601 602 603 OSCL_TRY(error, iPlayFromFileNode = 604 TPV2WayNode(PlayFromFileNode::NewL()); 605 iPlayFromFileNode->SetClock(&iClock);); 606 if (iPlayFromFileNode == NULL) error = PVMFErrNoMemory; 607 OSCL_FIRST_CATCH_ANY(error, 608 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 609 (0, "CPV324m2Way::PreInit unable to allocate playfromfile node\n")); 610 allocSuccessful = false;); 611 #endif 612 613 if (!allocSuccessful) 614 { 615 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 616 (0, "CPV324m2Way::Init allocation failed\n")); 617 } 618 else 619 { 620 621 622 #if defined(PV_RECORD_TO_FILE_SUPPORT) 623 InitiateSession(iVideoDecSplitterNode); 624 InitiateSession(iFFComposerNode); 625 #endif 626 627 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 628 InitiateSession(iAudioSrcSplitterNode); 629 InitiateSession(iVideoSrcSplitterNode); 630 InitiateSession(iPlayFromFileNode); 631 #endif 632 //Set incoming channel capabilities. 633 // TBD: Incoming capabilities need to be queried from the registry and passed to the stack 634 H324ChannelParameters inAudioChannelParams(INCOMING, PVMF_MIME_AMR_IF2, MAX_AUDIO_BITRATE); 635 H324ChannelParameters inVideoChannelParams(INCOMING, PVMF_MIME_H2632000, MAX_VIDEO_BITRATE); 636 H324ChannelParameters inDtmfParams(INCOMING, PVMF_MIME_USERINPUT_BASIC_STRING, 0); 637 638 ConvertMapToVector(iIncomingAudioCodecs, iFormatCapability); 639 inAudioChannelParams.SetCodecs(iFormatCapability); 640 641 ConvertMapToVector(iIncomingVideoCodecs, iFormatCapability); 642 inVideoChannelParams.SetCodecs(iFormatCapability); 643 inDtmfParams.SetCodecs(iIncomingUserInputFormats); 644 iIncomingChannelParams.push_back(inAudioChannelParams); 645 iIncomingChannelParams.push_back(inVideoChannelParams); 646 iIncomingChannelParams.push_back(inDtmfParams); 647 648 //Set outgoing channel capabilities. 649 H324ChannelParameters outAudioChannelParams(OUTGOING, 650 PVMF_MIME_AMR_IF2, MAX_AUDIO_BITRATE); 651 ConvertMapToVector(iOutgoingAudioCodecs, iFormatCapability); 652 outAudioChannelParams.SetCodecs(iFormatCapability); 653 iOutgoingChannelParams.push_back(outAudioChannelParams); 654 655 H324ChannelParameters outVideoChannelParams(OUTGOING, 656 PVMF_MIME_H2632000, MAX_VIDEO_BITRATE); 657 658 ConvertMapToVector(iOutgoingVideoCodecs, iFormatCapability); 659 outVideoChannelParams.SetCodecs(iFormatCapability); 660 iOutgoingChannelParams.push_back(outVideoChannelParams); 661 } 662 663 iInitInfo = GetCmdInfoL(); 664 iInitInfo->type = PVT_COMMAND_INIT; 665 iInitInfo->contextData = aContextData; 666 iInitInfo->id = iCommandId; 667 668 SetState(EInitializing); 669 670 CheckState(); 671 #ifdef MEM_TRACK 672 printf("\nMemStats at Engine Init\n"); 673 MemStats(); 674 #endif 675 break; 676 } 677 678 case ESetup: 679 iInitInfo = GetCmdInfoL(); 680 iInitInfo->type = PVT_COMMAND_INIT; 681 iInitInfo->id = iCommandId; 682 iInitInfo->contextData = aContextData; 683 iInitInfo->status = PVMFSuccess; 684 Dispatch(iInitInfo); 685 iInitInfo = NULL; 686 break; 687 688 default: 689 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 690 (0, "CPV324m2Way::Init Error - invalid state\n")); 691 OSCL_LEAVE(PVMFErrInvalidState); 692 break; 693 } 694 695 return iCommandId++; 696 } 697 698 699 PVCommandId CPV324m2Way::Reset(OsclAny* aContextData) 700 { 701 uint32 ii = 0; 702 //checking if any sources or sinks still added. 703 for (ii = 0; ii < iSinkNodes.size(); ii++) 704 { 705 if (iSinkNodes[ii]) 706 { 707 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 708 (0, "CPV324m2Way::ResetL SinkNodes not removed before Reset")); 709 OSCL_LEAVE(PVMFFailure); 710 } 711 } 712 713 for (ii = 0; ii < iSourceNodes.size(); ii++) 714 { 715 if (iSourceNodes[ii]) 716 { 717 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 718 (0, "CPV324m2Way::ResetL SourceNodes not removed before Reset")); 719 OSCL_LEAVE(PVMFFailure); 720 } 721 } 722 723 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 724 (0, "CPV324m2Way::ResetL %d\n", iState)); 725 726 if (iResetInfo) 727 { 728 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 729 (0, "CPV324m2Way::ResetL cmd already sent out\n")); 730 OSCL_LEAVE(PVMFErrBusy); 731 } 732 733 switch (iState) 734 { 735 case EIdle: 736 iResetInfo = GetCmdInfoL(); 737 iResetInfo->type = PVT_COMMAND_RESET; 738 iResetInfo->id = iCommandId; 739 iResetInfo->contextData = aContextData; 740 iResetInfo->status = PVMFSuccess; 741 Dispatch(iResetInfo); 742 iResetInfo = NULL; 743 break; 744 745 case EInitializing: 746 //Notify application that init command has been cancelled. 747 iInitInfo->status = PVMFErrCancelled; 748 Dispatch(iInitInfo); 749 iInitInfo = NULL; 750 //Fall through to next case. 751 752 case ESetup: 753 iResetInfo = GetCmdInfoL(); 754 iResetInfo->type = PVT_COMMAND_RESET; 755 iResetInfo->contextData = aContextData; 756 iResetInfo->id = iCommandId; 757 758 InitiateReset(); 759 break; 760 761 default: 762 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 763 (0, "CPV324m2Way::ResetL - invalid state %d\n", iState)); 764 OSCL_LEAVE(PVMFErrInvalidState); 765 break; 766 } 767 #ifdef MEM_TRACK 768 printf("\nMemStats After Engine Reset\n"); 769 MemStats(); 770 #endif 771 return iCommandId++; 772 } 773 774 PVCommandId CPV324m2Way::AddDataSource(PVTrackId aChannelId, 775 PVMFNodeInterface& aDataSource, 776 OsclAny* aContextData) 777 { 778 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 779 (0, "CPV324m2Way::AddDataSourceL aChannelId=%d, (%x, %x, %x)", 780 aChannelId, &aDataSource, 0, aContextData)); 781 if (!((TSC_324m *)(PVMFNodeInterface *)iTscNode.iNode)->IsEstablishedLogicalChannel(OUTGOING, 782 aChannelId)) 783 { 784 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 785 (0, "CPV324m2Way::AddDataSourceL Not an established logical channel in the stack")); 786 OSCL_LEAVE(PVMFErrArgument); 787 } 788 TPV2WayNode* srcNode; 789 PVMFNodeInterface *node = &aDataSource; 790 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 791 792 switch (iState) 793 { 794 case EIdle: 795 case EInitializing: 796 case EResetting: 797 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 798 (0, "CPV324m2Way::AddDataSourceL - invalid state(%d)", iState)); 799 OSCL_LEAVE(PVMFErrInvalidState); 800 break; 801 default: 802 //State check okay. 803 break; 804 } 805 806 //As of v4, we'll need to initialize the node first before 807 //querying its capabilities 808 809 // Add the Data Source to the list of source nodes. 810 srcNode = OSCL_NEW(TPV2WayNode, (node)); 811 InitiateSession(*srcNode); 812 iSourceNodes.push_back(srcNode); 813 814 cmd = GetCmdInfoL(); 815 cmd->type = PVT_COMMAND_ADD_DATA_SOURCE; 816 cmd->status = PVMFSuccess; 817 cmd->id = iCommandId; 818 cmd->contextData = aContextData; 819 cmd->iPvtCmdData = aChannelId; 820 821 SendNodeCmdL(PV2WAY_NODE_CMD_INIT, srcNode, this, cmd); 822 return iCommandId++; 823 } 824 825 void CPV324m2Way::DoAddDataSource(TPV2WayNode& aNode, 826 const PVMFCmdResp& aResponse) 827 { 828 TPV2WayNode* srcNode = &aNode; 829 PVMFNodeInterface *node = srcNode->iNode; 830 PVMFNodeCapability capability; 831 CPVDatapathNode datapathnode; 832 CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext(); 833 TPV2WayCmdInfo *cmd = (TPV2WayCmdInfo *)data->iContextData; 834 835 cmd->status = aResponse.GetCmdStatus(); 836 837 if (node->GetCapability(capability) != PVMFSuccess || !capability.iOutputFormatCapability.size()) 838 { 839 OSCL_DELETE(srcNode); 840 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 841 (0, "CPV324m2Way::AddDataSourceL - unable to get capability")); 842 OSCL_LEAVE(PVMFFailure); 843 } 844 845 CPV2WayEncDataChannelDatapath* datapath = NULL; 846 PVMFFormatType media_type = capability.iOutputFormatCapability[0]; 847 if (media_type.isAudio()) 848 { 849 datapath = iAudioEncDatapath; 850 } 851 else if (media_type.isVideo()) 852 { 853 datapath = iVideoEncDatapath; 854 } 855 else 856 { 857 OSCL_LEAVE(PVMFErrArgument); 858 } 859 860 bool formatSupported = false; 861 for (uint i = 0; i < capability.iOutputFormatCapability.size(); i++) 862 { 863 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "CPV324m2Way::AddDataSourceL - format %s\n", (capability.iOutputFormatCapability[i]).getMIMEStrPtr())); 864 if (datapath->GetSourceSinkFormat() == capability.iOutputFormatCapability[i]) 865 { 866 formatSupported = true; 867 break; 868 } 869 } 870 if (!formatSupported) 871 { 872 OSCL_LEAVE(PVMFErrNotSupported); 873 } 874 875 if (datapath->GetSourceSinkFormat() == PVMF_MIME_YUV420) 876 { 877 // video media type 878 if (datapath->GetState() == EClosed) 879 { 880 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 881 (0, "CPV324m2Way::AddDataSource - creating video datapath, channel id =%d\n", 882 cmd->iPvtCmdData)); 883 datapath->SetChannelId(cmd->iPvtCmdData); 884 885 //Add source node to datapath 886 datapathnode.iNode = *srcNode; 887 datapathnode.iConfigure = NULL; 888 datapathnode.iLoggoffOnReset = true; 889 datapathnode.iIgnoreNodeState = false; 890 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 891 datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; 892 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 893 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 894 datapath->AddNode(datapathnode); 895 896 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 897 //Add video src splitter node to datapath 898 datapathnode.iNode = iVideoSrcSplitterNode; 899 datapathnode.iConfigure = NULL; 900 datapathnode.iCanNodePause = false; 901 datapathnode.iIgnoreNodeState = false; 902 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 903 datapathnode.iInputPort.iPortSetType = EUserDefined; 904 datapathnode.iInputPort.iFormatType = PVMF_MIME_YUV420; 905 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 906 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 907 datapathnode.iOutputPort.iCanCancelPort = false; 908 datapathnode.iOutputPort.iPortSetType = EUserDefined; 909 datapathnode.iOutputPort.iFormatType = PVMF_MIME_YUV420; 910 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 911 datapath->AddNode(datapathnode); 912 #endif 913 //Add video enc node to datapath 914 datapathnode.iNode = iVideoEncNode; 915 datapathnode.iConfigure = this; 916 datapathnode.iConfigTime = EConfigBeforeInit; 917 datapathnode.iCanNodePause = true; 918 datapathnode.iLoggoffOnReset = false; 919 datapathnode.iIgnoreNodeState = false; 920 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 921 datapathnode.iInputPort.iPortSetType = EUserDefined; 922 datapathnode.iInputPort.iFormatType = PVMF_MIME_YUV420; 923 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 924 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 925 datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; 926 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 927 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 928 datapath->AddNode(datapathnode); 929 930 //Add tsc node to datapath 931 datapathnode.iNode = iTscNode; 932 datapathnode.iConfigure = NULL; 933 datapathnode.iCanNodePause = false; 934 datapathnode.iLoggoffOnReset = false; 935 datapathnode.iIgnoreNodeState = true; 936 datapathnode.iInputPort.iRequestPortState = EPVMFNodeStarted; 937 datapathnode.iInputPort.iCanCancelPort = true; 938 datapathnode.iInputPort.iPortSetType = EAppDefined; 939 datapathnode.iInputPort.iFormatType = datapath->GetFormat(); 940 datapathnode.iInputPort.iPortTag = cmd->iPvtCmdData; 941 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 942 datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; 943 datapath->AddNode(datapathnode); 944 945 // Check if FSI exists and Extension Interface is queried 946 uint32 fsi_len = 0; 947 if (datapath->GetFormatSpecificInfo(&fsi_len) && 948 iVideoEncNodeInterface.iState == PV2WayNodeInterface::NoInterface) 949 { 950 iAddDataSourceVideoCmd = cmd; 951 } 952 else 953 { 954 datapath->SetCmd(cmd); 955 } 956 } 957 else 958 { 959 OSCL_LEAVE(PVMFErrInvalidState); 960 } 961 } 962 963 else if ((datapath->GetSourceSinkFormat() == PVMF_MIME_H2632000) || (datapath->GetSourceSinkFormat() == PVMF_MIME_H2631998) || (datapath->GetSourceSinkFormat() == PVMF_MIME_M4V)) 964 { 965 // video media type 966 if (datapath->GetState() == EClosed) 967 { 968 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 969 (0, "CPV324m2Way::AddDataSource - creating video datapath, channel id=%d", 970 cmd->iPvtCmdData)); 971 datapath->SetChannelId(cmd->iPvtCmdData); 972 //Add source node to datapath 973 datapathnode.iNode = *srcNode; 974 datapathnode.iConfigure = NULL; 975 datapathnode.iLoggoffOnReset = true; 976 datapathnode.iIgnoreNodeState = false; 977 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 978 datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; 979 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 980 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 981 982 datapath->AddNode(datapathnode); 983 //Add tsc node to datapath 984 datapathnode.iNode = iTscNode; 985 datapathnode.iConfigure = NULL; 986 datapathnode.iCanNodePause = false; 987 datapathnode.iLoggoffOnReset = false; 988 datapathnode.iIgnoreNodeState = true; 989 datapathnode.iInputPort.iRequestPortState = EPVMFNodeStarted; 990 datapathnode.iInputPort.iCanCancelPort = true; 991 datapathnode.iInputPort.iPortSetType = EAppDefined; 992 datapathnode.iInputPort.iFormatType = datapath->GetFormat(); 993 datapathnode.iInputPort.iPortTag = cmd->iPvtCmdData; 994 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 995 datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; 996 datapath->AddNode(datapathnode); 997 998 datapath->SetCmd(cmd); 999 } 1000 else 1001 { 1002 OSCL_LEAVE(PVMFErrInvalidState); 1003 } 1004 } 1005 1006 else if ((datapath->GetSourceSinkFormat() == PVMF_MIME_AMR_IF2) || (datapath->GetSourceSinkFormat() == PVMF_MIME_AMR_IETF) || (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16)) 1007 { 1008 if (datapath->GetState() == EClosed) 1009 { 1010 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1011 (0, "CPV324m2Way::AddDataSourceL - creating audio datapath\n")); 1012 datapath->SetChannelId(cmd->iPvtCmdData); 1013 1014 //Add source node to datapath 1015 datapathnode.iNode = *srcNode; 1016 1017 #ifndef PV_DISABLE_DEVSOUNDNODES 1018 datapathnode.iConfigure = this; 1019 datapathnode.iConfigTime = EConfigBeforeInit; 1020 #else 1021 datapathnode.iConfigure = NULL; 1022 #endif 1023 datapathnode.iCanNodePause = true; 1024 datapathnode.iLoggoffOnReset = true; 1025 datapathnode.iIgnoreNodeState = false; 1026 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1027 datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; 1028 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1029 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 1030 datapath->AddNode(datapathnode); 1031 1032 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 1033 //Add audio src splitter node to datapath 1034 datapathnode.iNode = iAudioSrcSplitterNode; 1035 datapathnode.iConfigure = NULL; 1036 datapathnode.iCanNodePause = false; 1037 datapathnode.iIgnoreNodeState = false; 1038 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1039 datapathnode.iInputPort.iPortSetType = EUseOtherNodePortFormat; 1040 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1041 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1042 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1043 datapathnode.iOutputPort.iCanCancelPort = false; 1044 datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; 1045 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1046 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 1047 datapath->AddNode(datapathnode); 1048 #endif 1049 1050 if (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16) 1051 { 1052 //Add audio enc node to datapath 1053 datapathnode.iNode = iAudioEncNode; 1054 datapathnode.iConfigure = this; 1055 datapathnode.iConfigTime = EConfigBeforeInit; 1056 datapathnode.iCanNodePause = true; 1057 datapathnode.iLoggoffOnReset = false; 1058 datapathnode.iIgnoreNodeState = false; 1059 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1060 datapathnode.iInputPort.iPortSetType = EUserDefined; 1061 datapathnode.iInputPort.iFormatType = PVMF_MIME_PCM16; 1062 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1063 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1064 datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; 1065 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1066 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 1067 datapath->AddNode(datapathnode); 1068 } 1069 1070 //Add tsc node to datapath 1071 datapathnode.iNode = iTscNode; 1072 datapathnode.iConfigure = NULL; 1073 datapathnode.iCanNodePause = false; 1074 datapathnode.iLoggoffOnReset = false; 1075 datapathnode.iIgnoreNodeState = true; 1076 datapathnode.iInputPort.iRequestPortState = EPVMFNodeStarted; 1077 datapathnode.iInputPort.iCanCancelPort = true; 1078 datapathnode.iInputPort.iPortSetType = EAppDefined; 1079 datapathnode.iInputPort.iPortTag = cmd->iPvtCmdData; 1080 datapathnode.iInputPort.iFormatType = datapath->GetFormat(); 1081 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1082 datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; 1083 datapath->AddNode(datapathnode); 1084 1085 datapath->SetCmd(cmd); 1086 } 1087 else 1088 { 1089 OSCL_LEAVE(PVMFErrInvalidState); 1090 } 1091 } 1092 1093 return; 1094 } 1095 1096 PVCommandId CPV324m2Way::DoRemoveDataSourceSink(PVMFNodeInterface& aEndPt, 1097 OsclAny* aContextData) 1098 { 1099 CPV2WayDataChannelDatapath *datapath = NULL; 1100 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 1101 1102 if ((iVideoEncDatapath) && iVideoEncDatapath->IsNodeInDatapath(&aEndPt)) 1103 { 1104 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 1105 (0, "CPV324m2Way::RemoveDataSource remove video source, state %d\n", 1106 iVideoEncDatapath->GetState())); 1107 datapath = iVideoEncDatapath; 1108 cmd->type = PVT_COMMAND_REMOVE_DATA_SOURCE; 1109 } 1110 else if ((iAudioEncDatapath) && iAudioEncDatapath->IsNodeInDatapath(&aEndPt)) 1111 { 1112 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 1113 (0, "CPV324m2Way::RemoveDataSource remove audio source, state %d\n", 1114 iAudioEncDatapath->GetState())); 1115 datapath = iAudioEncDatapath; 1116 cmd->type = PVT_COMMAND_REMOVE_DATA_SOURCE; 1117 } 1118 else if ((iVideoDecDatapath) && iVideoDecDatapath->IsNodeInDatapath(&aEndPt)) 1119 { 1120 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 1121 (0, "CPV324m2Way::RemoveDataSink remove video sink, state %d\n", 1122 iVideoDecDatapath->GetState())); 1123 datapath = iVideoDecDatapath; 1124 cmd->type = PVT_COMMAND_REMOVE_DATA_SINK; 1125 } 1126 else if ((iAudioDecDatapath) && iAudioDecDatapath->IsNodeInDatapath(&aEndPt)) 1127 { 1128 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1129 (0, "CPV324m2Way::RemoveDataSink remove audio sink, state %d\n", 1130 iAudioDecDatapath->GetState())); 1131 datapath = iAudioDecDatapath; 1132 cmd->type = PVT_COMMAND_REMOVE_DATA_SINK; 1133 } 1134 else 1135 { 1136 // Just remove the node from sink and source nodes list if still in the list 1137 1138 TPV2WayNode* node = 0; 1139 1140 node = RemoveTPV2WayNode(iSinkNodes, &aEndPt); 1141 1142 if (!node) 1143 { 1144 // Not there in sink node list . Check in source nodes 1145 node = RemoveTPV2WayNode(iSourceNodes, &aEndPt); 1146 } 1147 1148 if (node) 1149 { 1150 //Successfully found and removed the node from sink or source nodes ,so delete it. 1151 OSCL_DELETE(node); 1152 } 1153 1154 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1155 (0, "CPV324m2Way::RemoveDataSinkSource unknown sink!\n")); 1156 OSCL_LEAVE(PVMFErrArgument); 1157 } 1158 1159 switch (datapath->GetState()) 1160 { 1161 case EClosing: 1162 //Close command already in progress 1163 if (datapath->GetCmdInfo()) 1164 { 1165 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1166 (0, "CPV324m2Way::RemoveDataSourceL cmd already sent out")); 1167 OSCL_LEAVE(PVMFErrBusy); 1168 } 1169 //Already closing because of error or remote close 1170 else 1171 { 1172 cmd->id = iCommandId; 1173 cmd->contextData = aContextData; 1174 datapath->SetCmd(cmd); 1175 } 1176 break; 1177 1178 case EOpened: 1179 case EOpening: 1180 case EPaused: 1181 case EPausing: 1182 case EUnpausing: 1183 { 1184 cmd->id = iCommandId; 1185 cmd->contextData = aContextData; 1186 datapath->SetCmd(cmd); 1187 } 1188 break; 1189 case EClosed: 1190 // Remove the node if exists in sink or source even data path is closed 1191 break; 1192 1193 default: 1194 1195 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1196 (0, "CPV324m2Way::RemoveDataSourceL - invalid path state\n")); 1197 OSCL_LEAVE(PVMFErrInvalidState); 1198 break; 1199 } 1200 1201 TPV2WayNode* node = 0; 1202 1203 if (cmd->type == PVT_COMMAND_REMOVE_DATA_SINK) 1204 { 1205 node = RemoveTPV2WayNode(iSinkNodes, &aEndPt); 1206 } 1207 else if (cmd->type == PVT_COMMAND_REMOVE_DATA_SOURCE) 1208 { 1209 node = RemoveTPV2WayNode(iSourceNodes, &aEndPt); 1210 } 1211 OSCL_DELETE(node); 1212 return iCommandId++; 1213 } 1214 1215 PVCommandId CPV324m2Way::RemoveDataSource(PVMFNodeInterface& aDataSource, 1216 OsclAny* aContextData) 1217 { 1218 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1219 (0, "CPV324m2Way::RemoveDataSourceL(%x, %x, %x)", 1220 &aDataSource, 0, aContextData)); 1221 1222 switch (iState) 1223 { 1224 case EIdle: 1225 case EInitializing: 1226 case EResetting: 1227 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1228 (0, "CPV324m2Way::RemoveDataSourceL - invalid state(%d)", 1229 iState)); 1230 OSCL_LEAVE(PVMFErrInvalidState); 1231 break; 1232 1233 default: 1234 //State check okay. 1235 break; 1236 } 1237 return DoRemoveDataSourceSink(aDataSource, aContextData); 1238 } 1239 1240 1241 PVCommandId CPV324m2Way::AddDataSink(PVTrackId aChannelId, 1242 PVMFNodeInterface& aDataSink, 1243 OsclAny* aContextData) 1244 { 1245 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1246 (0, "CPV324m2Way::AddDataSinkL(%x, %d, %x)", &aDataSink, 0, 1247 aContextData)); 1248 TPV2WayNode* sinkNode; 1249 CPVDatapathNode datapathnode; 1250 TPV2WayCmdInfo *cmd = 0; 1251 1252 switch (iState) 1253 { 1254 case EIdle: 1255 case EInitializing: 1256 case EResetting: 1257 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1258 (0, "CPV324m2Way::AddDataSinkL - invalid state(%d)", 1259 iState)); 1260 OSCL_LEAVE(PVMFErrInvalidState); 1261 break; 1262 1263 default: 1264 //State check okay. 1265 break; 1266 } 1267 1268 //As of v4, we'll need to initialize the node first before 1269 //querying its capabilities. 1270 1271 sinkNode = OSCL_NEW(TPV2WayNode, (&aDataSink)); 1272 InitiateSession(*sinkNode); 1273 iSinkNodes.push_back(sinkNode); 1274 SupportedSinkNodeInterfaces(sinkNode); 1275 cmd = GetCmdInfoL(); 1276 cmd->type = PVT_COMMAND_ADD_DATA_SINK; 1277 cmd->id = iCommandId; 1278 cmd->contextData = aContextData; 1279 cmd->iPvtCmdData = aChannelId; 1280 SendNodeCmdL(PV2WAY_NODE_CMD_INIT, sinkNode, this, cmd); 1281 return iCommandId++; 1282 } 1283 1284 void CPV324m2Way::DoAddDataSink(TPV2WayNode& aNode, 1285 const PVMFCmdResp& aResponse) 1286 { 1287 TPV2WayNode* sinkNode = &aNode; 1288 PVMFNodeCapability capability; 1289 PVMFNodeInterface *node = sinkNode->iNode; 1290 CPVDatapathNode datapathnode; 1291 CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext(); 1292 TPV2WayCmdInfo *cmd = (TPV2WayCmdInfo *)data->iContextData; 1293 cmd->status = aResponse.GetCmdStatus(); 1294 1295 if (node->GetCapability(capability) != PVMFSuccess) 1296 { 1297 OSCL_DELETE(sinkNode); 1298 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1299 (0, "CPV324m2Way::AddDataSinkL - unable to get capability\n")); 1300 OSCL_LEAVE(PVMFFailure); 1301 } 1302 1303 CPV2WayDecDataChannelDatapath* datapath = NULL; 1304 PVMFFormatType media_type = capability.iInputFormatCapability[0]; 1305 if (media_type.isAudio()) 1306 { 1307 datapath = iAudioDecDatapath; 1308 } 1309 else if (media_type.isVideo()) 1310 { 1311 datapath = iVideoDecDatapath; 1312 } 1313 else 1314 { 1315 OSCL_LEAVE(PVMFErrArgument); 1316 } 1317 1318 bool formatSupported = false; 1319 for (uint i = 0; i < capability.iInputFormatCapability.size(); i++) 1320 { 1321 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "CPV324m2Way::AddDataSinkL - format %s\n", (capability.iInputFormatCapability[i]).getMIMEStrPtr())); 1322 if (datapath->GetSourceSinkFormat() == capability.iInputFormatCapability[i]) 1323 { 1324 formatSupported = true; 1325 break; 1326 } 1327 } 1328 if (!formatSupported) 1329 { 1330 OSCL_LEAVE(PVMFErrNotSupported); 1331 } 1332 1333 if ((datapath->GetSourceSinkFormat() == PVMF_MIME_H2632000) || (datapath->GetSourceSinkFormat() == PVMF_MIME_M4V)) 1334 { 1335 if (datapath) 1336 { 1337 if (datapath->GetState() == EClosed) 1338 { 1339 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1340 (0, "CPV324m2Way::AddDataSinkL - creating video datapath\n")); 1341 1342 //Add tsc node to datapath 1343 datapathnode.iNode = iTscNode; 1344 datapathnode.iConfigure = NULL; 1345 datapathnode.iCanNodePause = false; 1346 datapathnode.iIgnoreNodeState = true; 1347 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeStarted; 1348 datapathnode.iOutputPort.iCanCancelPort = true; 1349 datapathnode.iOutputPort.iPortSetType = EAppDefined; 1350 datapathnode.iOutputPort.iFormatType = datapath->GetFormat(); 1351 datapathnode.iOutputPort.iPortTag = -cmd->iPvtCmdData; 1352 datapath->AddNode(datapathnode); 1353 1354 //Add video parser node to datapath 1355 datapathnode.iNode = iVideoParserNode; 1356 datapathnode.iConfigure = NULL; 1357 datapathnode.iCanNodePause = false; 1358 datapathnode.iIgnoreNodeState = false; 1359 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1360 datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; 1361 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1362 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1363 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1364 datapathnode.iOutputPort.iCanCancelPort = false; 1365 datapathnode.iOutputPort.iPortSetType = EUseOtherNodePortFormat; 1366 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1367 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 1368 datapath->AddNode(datapathnode); 1369 1370 //Add sink node to datapath 1371 datapathnode.iNode.iNode = sinkNode->iNode; 1372 datapathnode.iNode.iSessionId = sinkNode->iSessionId; 1373 datapathnode.iConfigure = NULL; 1374 datapathnode.iCanNodePause = false; 1375 datapathnode.iLoggoffOnReset = true; 1376 datapathnode.iIgnoreNodeState = false; 1377 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1378 datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; 1379 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1380 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1381 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1382 datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; 1383 datapath->AddNode(datapathnode); 1384 1385 datapath->SetCmd(cmd); 1386 datapath->SetChannelId(cmd->iPvtCmdData); 1387 } 1388 else 1389 { 1390 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1391 (0, "CPV324m2Way::AddDataSinkL - invalid video dec datapath state %d\n", 1392 datapath->GetState())); 1393 OSCL_LEAVE(PVMFErrInvalidState); 1394 } 1395 } 1396 } 1397 1398 else if ((datapath->GetSourceSinkFormat() == PVMF_MIME_YUV420)) 1399 { 1400 if (datapath) 1401 { 1402 if (datapath->GetState() == EClosed) 1403 { 1404 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1405 (0, "CPV324m2Way::AddDataSinkL - creating video datapath\n")); 1406 1407 //Add tsc node to datapath 1408 datapathnode.iNode = iTscNode; 1409 datapathnode.iConfigure = NULL; 1410 datapathnode.iCanNodePause = false; 1411 datapathnode.iIgnoreNodeState = true; 1412 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeStarted; 1413 datapathnode.iOutputPort.iCanCancelPort = true; 1414 datapathnode.iOutputPort.iPortSetType = EAppDefined; 1415 datapathnode.iOutputPort.iFormatType = datapath->GetFormat(); 1416 //datapathnode.iOutputPort.iPortTag = GetStackNodePortTag(EPV2WayVideoOut); 1417 datapathnode.iOutputPort.iPortTag = -cmd->iPvtCmdData; 1418 datapath->AddNode(datapathnode); 1419 1420 //Add video parser node to datapath 1421 datapathnode.iNode = iVideoParserNode; 1422 datapathnode.iConfigure = NULL; 1423 datapathnode.iCanNodePause = false; 1424 datapathnode.iIgnoreNodeState = false; 1425 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1426 datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; 1427 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1428 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1429 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1430 datapathnode.iOutputPort.iCanCancelPort = false; 1431 datapathnode.iOutputPort.iPortSetType = EUseOtherNodePortFormat; 1432 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1433 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 1434 datapath->AddNode(datapathnode); 1435 1436 //Add video dec node to datapath 1437 datapathnode.iNode = iVideoDecNode; 1438 datapathnode.iConfigure = NULL; 1439 datapathnode.iCanNodePause = true; 1440 datapathnode.iIgnoreNodeState = false; 1441 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1442 datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; 1443 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1444 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1445 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1446 datapathnode.iOutputPort.iPortSetType = EUserDefined; 1447 datapathnode.iOutputPort.iFormatType = PVMF_MIME_YUV420; 1448 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 1449 datapath->AddNode(datapathnode); 1450 1451 //Add sink node to datapath 1452 datapathnode.iNode.iNode = sinkNode->iNode; 1453 datapathnode.iNode.iSessionId = sinkNode->iSessionId; 1454 datapathnode.iConfigure = NULL; 1455 datapathnode.iCanNodePause = false; 1456 if (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16) 1457 { 1458 //Add audio dec node to datapath 1459 datapathnode.iNode = iAudioDecNode; 1460 datapathnode.iConfigure = NULL; 1461 datapathnode.iCanNodePause = true; 1462 datapathnode.iIgnoreNodeState = false; 1463 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1464 datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; 1465 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1466 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1467 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1468 datapathnode.iOutputPort.iPortSetType = EUserDefined; 1469 datapathnode.iOutputPort.iFormatType = PVMF_MIME_PCM16; 1470 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 1471 iAudioDecDatapath->AddNode(datapathnode); 1472 } 1473 1474 //Add sink node to datapath 1475 datapathnode.iNode = *sinkNode; 1476 datapathnode.iConfigure = NULL; 1477 datapathnode.iCanNodePause = true; 1478 datapathnode.iLoggoffOnReset = true; 1479 datapathnode.iIgnoreNodeState = false; 1480 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1481 datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; 1482 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1483 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1484 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1485 datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; 1486 datapath->AddNode(datapathnode); 1487 1488 datapath->SetChannelId(cmd->iPvtCmdData); 1489 datapath->SetCmd(cmd); 1490 } 1491 else 1492 { 1493 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1494 (0, "CPV324m2Way::AddDataSinkL - invalid video dec datapath state %d\n", 1495 iVideoDecDatapath->GetState())); 1496 OSCL_LEAVE(PVMFErrInvalidState); 1497 } 1498 } 1499 } 1500 1501 else if ((datapath->GetSourceSinkFormat() == PVMF_MIME_AMR_IF2) || (datapath->GetSourceSinkFormat() == PVMF_MIME_AMR_IETF) || (datapath->GetSourceSinkFormat() == PVMF_MIME_G723) || (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16)) 1502 { 1503 if (datapath->GetState() == EClosed) 1504 { 1505 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1506 (0, "CPV324m2Way::AddDataSinkL - adding - audio sink node\n")); 1507 1508 //Add tsc node to datapath 1509 datapathnode.iNode = iTscNode; 1510 datapathnode.iConfigure = NULL; 1511 datapathnode.iCanNodePause = false; 1512 datapathnode.iIgnoreNodeState = true; 1513 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeStarted; 1514 datapathnode.iOutputPort.iCanCancelPort = true; 1515 datapathnode.iOutputPort.iPortSetType = EAppDefined; 1516 datapathnode.iOutputPort.iFormatType = datapath->GetFormat(); 1517 // Need to put in the LC number here 1518 //datapathnode.iOutputPort.iPortTag = GetStackNodePortTag(EPV2WayAudioOut); 1519 datapathnode.iOutputPort.iPortTag = -cmd->iPvtCmdData; 1520 datapath->AddNode(datapathnode); 1521 1522 if (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16) 1523 { 1524 //Add audio dec node to datapath 1525 datapathnode.iNode = iAudioDecNode; 1526 datapathnode.iConfigure = NULL; 1527 datapathnode.iCanNodePause = true; 1528 datapathnode.iIgnoreNodeState = false; 1529 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1530 datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; 1531 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1532 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1533 datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1534 datapathnode.iOutputPort.iPortSetType = EUserDefined; 1535 datapathnode.iOutputPort.iFormatType = PVMF_MIME_PCM16; 1536 datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; 1537 datapath->AddNode(datapathnode); 1538 } 1539 1540 //Add sink node to datapath 1541 datapathnode.iNode = *sinkNode; 1542 datapathnode.iConfigure = NULL; 1543 datapathnode.iCanNodePause = true; 1544 datapathnode.iLoggoffOnReset = true; 1545 datapathnode.iIgnoreNodeState = false; 1546 datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1547 datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; 1548 datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1549 datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; 1550 datapathnode.iOutputPort.iCanCancelPort = false; 1551 datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1552 datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; 1553 datapath->AddNode(datapathnode); 1554 1555 datapath->SetChannelId(cmd->iPvtCmdData); 1556 1557 datapath->SetCmd(cmd); 1558 } 1559 else 1560 { 1561 OSCL_ASSERT(datapath); 1562 } 1563 } 1564 1565 } 1566 1567 PVCommandId CPV324m2Way::RemoveDataSink(PVMFNodeInterface& aDataSink, 1568 OsclAny* aContextData) 1569 { 1570 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1571 (0, "CPV324m2Way::RemoveDataSinkL(%x, %x, %x)", 0, 0, 1572 aContextData)); 1573 1574 1575 switch (iState) 1576 { 1577 case EIdle: 1578 case EInitializing: 1579 case EResetting: 1580 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1581 (0, "CPV324m2Way::RemoveDataSinkL - invalid state(%d)", 1582 iState)); 1583 OSCL_LEAVE(PVMFErrInvalidState); 1584 break; 1585 1586 default: 1587 //State check okay. 1588 break; 1589 } 1590 1591 return DoRemoveDataSourceSink(aDataSink, aContextData); 1592 } 1593 1594 PVCommandId CPV324m2Way::Connect(const PV2WayConnectOptions& aOptions, 1595 PVMFNodeInterface* aCommServer, 1596 OsclAny* aContextData) 1597 { 1598 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1599 (0, "CPV324m2Way::ConnectL()")); 1600 CPVDatapathNode node; 1601 1602 // validate aCommServer 1603 if (aCommServer == NULL) 1604 { 1605 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1606 (0, "CPV324m2Way::ConnectL comm server is null")); 1607 OSCL_LEAVE(PVMFErrArgument); 1608 } 1609 1610 if (iConnectInfo) 1611 { 1612 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1613 (0, "CPV324m2Way::ConnectL cmd already sent out")); 1614 OSCL_LEAVE(PVMFErrBusy); 1615 } 1616 1617 /* set clock to 0 and start */ 1618 uint32 startTime = 0; 1619 bool overflowFlag = false; 1620 1621 if (!iClock.SetStartTime32(startTime, PVMF_MEDIA_CLOCK_MSEC, overflowFlag)) 1622 { 1623 PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR, 1624 (0, "CPV324m2Way::Connect: unable to set clock time")); 1625 OSCL_LEAVE(PVMFFailure); 1626 } 1627 1628 switch (iState) 1629 { 1630 case ESetup: 1631 iConnectInfo = GetCmdInfoL(); 1632 1633 iLoopbackMode = aOptions.iLoopbackMode; 1634 ((TSC_324m *)(PVMFNodeInterface *)iTscNode.iNode)->SetLoopbackMode(iLoopbackMode); 1635 ((TSC_324m *)(PVMFNodeInterface *)iTscNode.iNode)->SetEndSessionTimeout(((PV2Way324ConnectOptions *)(&aOptions))->iDisconnectTimeoutInterval); 1636 1637 // Store reference to comm server 1638 iCommNode = TPV2WayNode(aCommServer); 1639 InitiateSession(iCommNode); 1640 1641 //Add tsc node to datapath 1642 node.iNode = iTscNode; 1643 node.iConfigure = this; 1644 node.iIgnoreNodeState = false; 1645 node.iConfigTime = EConfigBeforeStart; 1646 node.iOutputPort.iRequestPortState = EPVMFNodeInitialized; 1647 node.iOutputPort.iPortSetType = EUserDefined; 1648 node.iOutputPort.iFormatType = PVMF_MIME_H223; 1649 //node.iOutputPort.iPortType = EPVIOPort; 1650 node.iOutputPort.iPortTag = PV_MULTIPLEXED; 1651 iMuxDatapath->AddNode(node); 1652 1653 //Add rcomm node to datapath 1654 node.iNode = iCommNode; 1655 node.iLoggoffOnReset = true; 1656 node.iConfigure = NULL; 1657 node.iIgnoreNodeState = false; 1658 node.iLoggoffOnReset = false; 1659 node.iInputPort.iRequestPortState = EPVMFNodeInitialized; 1660 node.iInputPort.iPortSetType = EUserDefined; 1661 node.iInputPort.iFormatType = PVMF_MIME_H223; 1662 node.iInputPort.iPortTag = PV2WAY_IO_PORT; 1663 //node.iInputPort.iProperty.iPortType = EPVIOPort; 1664 node.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; 1665 //node.iOutputPort.iPortType = EPVInvalidPortType; 1666 node.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; 1667 iMuxDatapath->AddNode(node); 1668 1669 iConnectInfo->type = PVT_COMMAND_CONNECT; 1670 iConnectInfo->id = iCommandId; 1671 iConnectInfo->contextData = aContextData; 1672 SetState(EConnecting); 1673 1674 iMuxDatapath->Open(); 1675 break; 1676 1677 case EConnected: 1678 iConnectInfo = GetCmdInfoL(); 1679 iConnectInfo->type = PVT_COMMAND_CONNECT; 1680 iConnectInfo->status = PVMFSuccess; 1681 iConnectInfo->id = iCommandId; 1682 iConnectInfo->contextData = aContextData; 1683 Dispatch(iConnectInfo); 1684 iConnectInfo = NULL; 1685 break; 1686 1687 default: 1688 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1689 (0, "CPV324m2Way::ConnectL - invalid state(%d)", iState)); 1690 OSCL_LEAVE(PVMFErrInvalidState); 1691 break; 1692 } 1693 1694 /* 1695 // start enc datapaths that are already created 1696 if (iAudioEncDatapath->GetState() != EClosed) 1697 { 1698 iAudioEncDatapath->CheckOpen(); 1699 } 1700 if (iVideoEncDatapath->GetState() != EClosed) 1701 { 1702 iVideoEncDatapath->CheckOpen(); 1703 } 1704 */ 1705 return iCommandId++; 1706 } 1707 1708 PVCommandId CPV324m2Way::Disconnect(OsclAny* aContextData) 1709 { 1710 1711 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1712 (0, "CPV324m2Way::Disconnect()")); 1713 1714 if (iDisconnectInfo) 1715 { 1716 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1717 (0, "CPV324m2Way::Disconnect cmd already sent out")); 1718 OSCL_LEAVE(PVMFErrBusy); 1719 } 1720 1721 switch (iState) 1722 { 1723 case EConnecting: 1724 //Connect in progress, notify application that it has been cancelled. 1725 iConnectInfo->status = PVMFErrCancelled; 1726 Dispatch(iConnectInfo); 1727 iConnectInfo = NULL; 1728 //Fall through to next case 1729 1730 case EConnected: 1731 1732 iTSC324mInterface->EndSessionCommand(); 1733 1734 iEndSessionTimer->SetObserver(this); 1735 iEndSessionTimer->Request(END_SESSION_TIMER_ID, END_SESSION_TIMER_ID, 1736 END_SESSION_TIMER_VALUE, this); 1737 1738 iDisconnectInfo = GetCmdInfoL(); 1739 1740 iDisconnectInfo->type = PVT_COMMAND_DISCONNECT; 1741 iDisconnectInfo->contextData = aContextData; 1742 iDisconnectInfo->id = iCommandId; 1743 1744 //We wait to InitiateDisconnect() till iEndSessionTimer timer expires 1745 break; 1746 1747 case EDisconnecting: 1748 //If at this point, then remote disconnect is in progress, just treat as user disconnect. 1749 iDisconnectInfo = GetCmdInfoL(); 1750 1751 iDisconnectInfo->type = PVT_COMMAND_DISCONNECT; 1752 iDisconnectInfo->contextData = aContextData; 1753 iDisconnectInfo->id = iCommandId; 1754 break; 1755 1756 default: 1757 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1758 (0, "CPV324m2Way::Disconnect - invalid state(%d)", iState)); 1759 OSCL_LEAVE(PVMFErrInvalidState); 1760 break; 1761 } 1762 1763 return iCommandId++; 1764 } 1765 1766 void CPV324m2Way::InitiateDisconnect() 1767 { 1768 SetState(EDisconnecting); 1769 CheckState(); 1770 } 1771 1772 void CPV324m2Way::InitiateReset() 1773 { 1774 SetState(EResetting); 1775 1776 if (isIFrameReqTimerActive) 1777 { 1778 iIFrameReqTimer.Cancel(IFRAME_REQ_TIMERID); 1779 isIFrameReqTimerActive = false; 1780 } 1781 1782 if ((iAudioDecDatapath != NULL) && (iAudioDecDatapath->GetState() != EClosed)) 1783 { 1784 iAudioDecDatapath->SetCmd(NULL); 1785 } 1786 1787 if ((iAudioEncDatapath != NULL) && (iAudioEncDatapath->GetState() != EClosed)) 1788 { 1789 iAudioEncDatapath->SetCmd(NULL); 1790 } 1791 1792 if ((iVideoDecDatapath != NULL) && (iVideoDecDatapath->GetState() != EClosed)) 1793 { 1794 iVideoDecDatapath->SetCmd(NULL); 1795 } 1796 1797 if ((iVideoEncDatapath != NULL) && (iVideoEncDatapath->GetState() != EClosed)) 1798 { 1799 iVideoEncDatapath->SetCmd(NULL); 1800 } 1801 1802 CheckState(); 1803 } 1804 1805 void CPV324m2Way::CheckState() 1806 { 1807 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1808 (0, "CPV324m2Way::CheckState state %d\n", iState)); 1809 switch (iState) 1810 { 1811 case EInitializing: 1812 CheckInit(); 1813 break; 1814 1815 case EConnecting: 1816 CheckConnect(); 1817 break; 1818 1819 case EDisconnecting: 1820 CheckDisconnect(); 1821 break; 1822 1823 case EResetting: 1824 CheckReset(); 1825 break; 1826 1827 default: 1828 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 1829 (0, "CPV324m2Way::CheckState warning: static state!")); 1830 break; 1831 } 1832 } 1833 1834 void CPV324m2Way::CheckInit() 1835 { 1836 // PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0,"CPV324m2Way::CheckInit state %d, video enc node state %d, interface state %d\n", iState, ((PVMFNodeInterface *)iVideoEncNode)->GetState(), iVideoEncNodeInterface.iState)); 1837 int32 error; 1838 1839 if (((PVMFNodeInterface *)iTscNode)->GetState() == EPVMFNodeIdle) 1840 { 1841 OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_INIT, &iTscNode, this)); 1842 OSCL_FIRST_CATCH_ANY(error, 1843 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1844 (0, "CPV324m2Way::CheckInit unable to init tsc node!\n")); 1845 SetState(EResetting); 1846 CheckState(); 1847 return;); 1848 } 1849 if (((PVMFNodeInterface *)iTscNode)->GetState() == EPVMFNodeInitialized) 1850 { 1851 1852 SetState(ESetup); 1853 1854 iInitInfo->status = PVMFSuccess; 1855 Dispatch(iInitInfo); 1856 iInitInfo = NULL; 1857 } 1858 } 1859 1860 void CPV324m2Way::CheckConnect() 1861 { 1862 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 1863 (0, "CPV324m2Way::CheckConnect state %d, comm state %d, tsc state %d\n", 1864 iState, ((PVMFNodeInterface *)iCommNode)->GetState(), 1865 ((PVMFNodeInterface *)iTscNode)->GetState())); 1866 1867 if ((iMuxDatapath->GetState() == EOpened) && iIsStackConnected) 1868 { 1869 /* Increase video encoder bitrate if required */ 1870 // PVMp4H263EncExtensionInterface *ptr = (PVMp4H263EncExtensionInterface *) iVideoEncNodeInterface.iInterface; 1871 // ptr->SetOutputBitRate(0, VIDEO_ENCODER_BITRATE); 1872 SetState(EConnected); 1873 1874 iConnectInfo->status = PVMFSuccess; 1875 Dispatch(iConnectInfo); 1876 iConnectInfo = NULL; 1877 } 1878 } 1879 1880 1881 void CPV324m2Way::CheckDisconnect() 1882 { 1883 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 1884 (0, "CPV324m2Way::CheckDisconnect state %d, mux datapath state %d, stack connected %d\n", 1885 iState, iMuxDatapath->GetState(), iIsStackConnected)); 1886 if ((iMuxDatapath->GetState() == EClosed) && 1887 !iIsStackConnected) 1888 { 1889 SetState(ESetup); 1890 1891 //Connect failed 1892 if (iConnectInfo) 1893 { 1894 iConnectInfo->status = PVMFFailure; 1895 Dispatch(iConnectInfo); 1896 iConnectInfo = NULL; 1897 } 1898 //Else command cancelled 1899 else if (iCancelInfo) 1900 { 1901 iCancelInfo->status = PVMFSuccess; 1902 Dispatch(iCancelInfo); 1903 iCancelInfo = NULL; 1904 } 1905 //Else local disconnect 1906 else if (iDisconnectInfo) 1907 { 1908 iDisconnectInfo->status = PVMFSuccess; 1909 Dispatch(iDisconnectInfo); 1910 iDisconnectInfo = NULL; 1911 } 1912 //Else remote disconnect 1913 else 1914 { 1915 TPV2WayEventInfo* aEvent = NULL; 1916 if (!GetEventInfo(aEvent)) 1917 { 1918 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1919 (0, "CPV324m2Way::CheckDisconnect unable to notify app!\n")); 1920 return; 1921 } 1922 aEvent->type = PVT_INDICATION_DISCONNECT; 1923 Dispatch(aEvent); 1924 } 1925 } 1926 else 1927 { 1928 iMuxDatapath->Close(); 1929 } 1930 } 1931 1932 void CPV324m2Way::CheckReset() 1933 { 1934 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 1935 (0, "CPV324m2Way::CheckReset state %d \n", iState)); 1936 int32 error; 1937 1938 #if defined(PV_RECORD_TO_FILE_SUPPORT) 1939 switch (iRecordFileState) 1940 { 1941 case File2WayInitializing: 1942 case File2WayInitialized: 1943 InitiateResetRecordFile(); 1944 break; 1945 1946 case File2WayIdle: 1947 case File2WayResetting: 1948 break; 1949 } 1950 #endif 1951 1952 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 1953 switch (iPlayFileState) 1954 { 1955 case File2WayInitializing: 1956 case File2WayInitialized: 1957 InitiateResetPlayFile(); 1958 break; 1959 1960 case File2WayIdle: 1961 case File2WayResetting: 1962 break; 1963 } 1964 #endif 1965 1966 #if defined(PV_RECORD_TO_FILE_SUPPORT) 1967 if (iRecordFileState != File2WayIdle) return; 1968 #endif 1969 1970 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 1971 if (iPlayFileState != File2WayIdle) return; 1972 #endif 1973 1974 1975 1976 if ((iAudioEncDatapath != NULL) && (iAudioEncDatapath->GetState() == EClosed) && 1977 (iAudioDecDatapath != NULL) && (iAudioDecDatapath->GetState() == EClosed) && 1978 (iVideoEncDatapath != NULL) && (iVideoEncDatapath->GetState() == EClosed) && 1979 (iVideoDecDatapath != NULL) && (iVideoDecDatapath->GetState() == EClosed)) 1980 { 1981 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 1982 (0, "CPV324m2Way::CheckReset state %d, AD state %d, VD state %d, AE state %d, VE state %d\n", 1983 iState, 1984 iAudioDecDatapath->GetState(), 1985 iVideoDecDatapath->GetState(), 1986 iAudioEncDatapath->GetState(), 1987 iVideoEncDatapath->GetState())); 1988 1989 TPVMFNodeInterfaceState vidEncState; 1990 1991 if (iVideoEncNode != NULL) 1992 { 1993 vidEncState = ((PVMFNodeInterface *)iVideoEncNode)->GetState() ; 1994 if ((vidEncState == EPVMFNodeInitialized) || (vidEncState == EPVMFNodeError)) 1995 { 1996 OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_RESET, &iVideoEncNode, this)); 1997 OSCL_FIRST_CATCH_ANY(error, 1998 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1999 (0, "CPV324m2Way::CheckReset unable to reset video encoder node!\n")); 2000 return;); 2001 } 2002 } 2003 2004 if (iAudioEncNode != NULL) 2005 { 2006 if ((iAudioEncNode.iNode->GetState() == EPVMFNodeInitialized) || 2007 (iAudioEncNode.iNode->GetState() == EPVMFNodeError)) 2008 { 2009 OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_RESET, &iAudioEncNode, this)); 2010 OSCL_FIRST_CATCH_ANY(error, 2011 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2012 (0, "CPV324m2Way::CheckReset unable to reset audio encoder node!\n")); 2013 return;); 2014 } 2015 } 2016 } 2017 2018 TPVMFNodeInterfaceState tscState = ((PVMFNodeInterface *)iTscNode)->GetState() ; 2019 2020 if ((tscState == EPVMFNodeInitialized) || 2021 (tscState == EPVMFNodeError)) 2022 { 2023 OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_RESET, &iTscNode, this)); 2024 OSCL_FIRST_CATCH_ANY(error, 2025 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2026 (0, "CPV324m2Way::CheckReset unable to reset tsc node!\n")); 2027 return;); 2028 } 2029 bool aFlag = false; 2030 if ((tscState == EPVMFNodeIdle) && 2031 (iVideoEncNodeInterface.iState != PV2WayNodeInterface::QueryInterface)) 2032 { 2033 if (iVideoEncNode.iNode != NULL) 2034 aFlag = IsNodeReset(*(iVideoEncNode.iNode)); 2035 else 2036 aFlag = true; 2037 2038 } 2039 2040 if (aFlag == true) 2041 { 2042 iIncomingChannelParams.clear(); 2043 iOutgoingChannelParams.clear(); 2044 2045 SetState(EIdle); 2046 2047 //Init failed 2048 if (iInitInfo) 2049 { 2050 iInitInfo->status = PVMFFailure; 2051 Dispatch(iInitInfo); 2052 iInitInfo = NULL; 2053 } 2054 //Else command cancelled 2055 else if (iCancelInfo) 2056 { 2057 iCancelInfo->status = PVMFSuccess; 2058 Dispatch(iCancelInfo); 2059 iCancelInfo = NULL; 2060 } 2061 //Else local reset 2062 else 2063 { 2064 iResetInfo->status = PVMFSuccess; 2065 Dispatch(iResetInfo); 2066 iResetInfo = NULL; 2067 } 2068 } 2069 2070 } 2071 2072 2073 void CPV324m2Way::RemoveAudioDecPath() 2074 { 2075 if (iAudioDecDatapath) 2076 { 2077 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2078 (0, "CPV324m2Way::RemoveAudioDecPath audio dec path state %d\n", 2079 iAudioDecDatapath->GetState())); 2080 } 2081 2082 #if defined(PV_RECORD_TO_FILE_SUPPORT) 2083 RemoveAudioRecPath(); 2084 #endif 2085 2086 if ((iAudioDecDatapath != NULL) && 2087 (iAudioDecDatapath->GetState() == EClosed)) 2088 { 2089 iAudioDecDatapath->ResetDatapath(); 2090 iAudioSinkNode.Clear(); 2091 } 2092 } 2093 2094 void CPV324m2Way::RemoveAudioEncPath() 2095 { 2096 if (iAudioEncDatapath) 2097 { 2098 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2099 (0, "CPV324m2Way::RemoveAudioEncPath audio enc path state %d\n", 2100 iAudioEncDatapath->GetState())); 2101 } 2102 2103 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 2104 RemoveAudioPreviewPath(); 2105 #endif 2106 2107 if ((iAudioEncDatapath != NULL) && 2108 (iAudioEncDatapath->GetState() == EClosed)) 2109 { 2110 iAudioEncDatapath->SetSourceInputPort(NULL); 2111 iAudioEncDatapath->ResetDatapath(); 2112 iAudioSrcNode.Clear(); 2113 } 2114 } 2115 2116 void CPV324m2Way::RemoveVideoDecPath() 2117 { 2118 if (iVideoDecDatapath) 2119 { 2120 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2121 (0, "CPV324m2Way::RemoveVideoDecPath video dec path state %d\n", 2122 iVideoDecDatapath->GetState())); 2123 } 2124 2125 #if defined(PV_RECORD_TO_FILE_SUPPORT) 2126 RemoveVideoRecPath(); 2127 #endif 2128 2129 if ((iVideoDecDatapath != NULL) && 2130 (iVideoDecDatapath->GetState() == EClosed)) 2131 { 2132 iVideoDecDatapath->ResetDatapath(); 2133 } 2134 } 2135 2136 void CPV324m2Way::RemoveVideoEncPath() 2137 { 2138 if (iVideoEncDatapath) 2139 { 2140 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2141 (0, "CPV324m2Way::RemoveVideoEncPath video enc path state %d\n", 2142 iVideoEncDatapath->GetState())); 2143 } 2144 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 2145 RemoveVideoPreviewPath(); 2146 #endif 2147 2148 if ((iVideoEncDatapath != NULL) && 2149 (iVideoEncDatapath->GetState() == EClosed)) 2150 { 2151 //Video encoder will be deleted at reset time. 2152 2153 iVideoEncDatapath->ResetDatapath(); 2154 } 2155 } 2156 2157 void CPV324m2Way::HandleCommNodeCmd(PV2WayNodeCmdType aType, 2158 const PVMFCmdResp& aResponse) 2159 { 2160 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 2161 (0, "CPV324m2Way::HandleCommNodeCmd type %d\n", aType)); 2162 2163 switch (aType) 2164 { 2165 case PV2WAY_NODE_CMD_INIT: 2166 if (aResponse.GetCmdStatus() != PVMFSuccess) 2167 { 2168 SetState(EResetting); 2169 } 2170 2171 CheckState(); 2172 break; 2173 2174 case PV2WAY_NODE_CMD_RESET: 2175 CheckState(); 2176 break; 2177 2178 default: 2179 break; 2180 } 2181 } 2182 2183 void CPV324m2Way::HandleTscNodeCmd(PV2WayNodeCmdType aType, 2184 const PVMFCmdResp& aResponse) 2185 { 2186 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 2187 (0, "CPV324m2Way::HandleTscNodeCmd type %d\n", aType)); 2188 2189 switch (aType) 2190 { 2191 case PV2WAY_NODE_CMD_INIT: 2192 if (aResponse.GetCmdStatus() == PVMFSuccess) 2193 { 2194 ((TSC_324m *)((PVMFNodeInterface *)iTscNode))->SetIncomingChannelConfig(iIncomingChannelParams); 2195 ((TSC_324m *)((PVMFNodeInterface *)iTscNode))->SetOutgoingChannelConfig(iOutgoingChannelParams); 2196 } 2197 else 2198 { 2199 SetState(EResetting); 2200 } 2201 2202 CheckState(); 2203 break; 2204 2205 case PV2WAY_NODE_CMD_RESET: 2206 CheckState(); 2207 break; 2208 2209 default: 2210 break; 2211 } 2212 } 2213 2214 2215 void CPV324m2Way::HandleVideoDecNodeCmd(PV2WayNodeCmdType aType, 2216 const PVMFCmdResp& aResponse) 2217 { 2218 OSCL_UNUSED_ARG(aType); 2219 OSCL_UNUSED_ARG(aResponse); 2220 } 2221 2222 void CPV324m2Way::HandleVideoEncNodeCmd(PV2WayNodeCmdType aType, 2223 const PVMFCmdResp& aResponse) 2224 { 2225 if (iVideoEncDatapath) 2226 { 2227 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 2228 (0, "CPV324m2Way::HandleVideoEncNodeCmd type %d, video enc path state %d\n", 2229 aType, iVideoEncDatapath->GetState())); 2230 } 2231 2232 switch (aType) 2233 { 2234 case PV2WAY_NODE_CMD_QUERY_INTERFACE: 2235 2236 if (aResponse.GetCmdId() == iVideoEncQueryIntCmdId) 2237 { 2238 iVideoEncQueryIntCmdId = -1; 2239 if (aResponse.GetCmdStatus() == PVMFSuccess) 2240 { 2241 iVideoEncNodeInterface.iState = PV2WayNodeInterface::HasInterface; 2242 // Set the FormatSpecificInfo if available 2243 uint32 fsi_len = 0; 2244 uint8* fsi = iVideoEncDatapath->GetFormatSpecificInfo(&fsi_len); 2245 if (fsi && fsi_len) 2246 { 2247 OSCL_STATIC_CAST(PVMp4H263EncExtensionInterface *, 2248 iVideoEncNodeInterface.iInterface)->SetFSIParam(fsi, fsi_len); 2249 if (iAddDataSourceVideoCmd) 2250 { 2251 iVideoEncDatapath->SetCmd(iAddDataSourceVideoCmd); 2252 iAddDataSourceVideoCmd = NULL; 2253 } 2254 } 2255 } 2256 else 2257 { 2258 iVideoEncNodeInterface.iState = PV2WayNodeInterface::NoInterface; 2259 SetState(EResetting); 2260 } 2261 2262 } 2263 2264 CheckState(); 2265 break; 2266 2267 case PV2WAY_NODE_CMD_INIT: 2268 CheckState(); 2269 break; 2270 2271 case PV2WAY_NODE_CMD_RESET: 2272 CheckState(); 2273 break; 2274 2275 default: 2276 break; 2277 } 2278 } 2279 2280 void CPV324m2Way::HandleSinkNodeCmd(PV2WayNodeCmdType aType, 2281 const PVMFCmdResp& aResponse, 2282 TPV2WayNode* aNode) 2283 { 2284 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 2285 (0, "CPV324m2Way::HandleSinkNodeCmd type %d\n", aType)); 2286 switch (aType) 2287 { 2288 case PV2WAY_NODE_CMD_INIT: 2289 if (aResponse.GetCmdStatus() != PVMFSuccess) 2290 { 2291 SetState(EResetting); 2292 CheckState(); 2293 } 2294 else 2295 { 2296 DoAddDataSink(*aNode, aResponse); 2297 } 2298 break; 2299 case PV2WAY_NODE_CMD_QUERY_INTERFACE: 2300 if (aResponse.GetCmdStatus() == PVMFSuccess) 2301 { 2302 for (uint32 ii = 0; ii < iSinkNodeList.size(); ii++) 2303 { 2304 if ((aNode == iSinkNodeList[ii].iSinkNode) && 2305 (aResponse.GetCmdId() == iSinkNodeList[ii].iNodeInterface.iId)) 2306 { 2307 iSinkNodeList[ii].iNodeInterface.iInterface = 2308 iClockSyncInterface.iInterface; 2309 iClockSyncInterface.Reset(); 2310 if (iSinkNodeList[ii].iNodeInterface.iInterface != NULL) 2311 { 2312 iSinkNodeList[ii].iNodeInterface.iState = 2313 PV2WayNodeInterface::HasInterface; 2314 PvmfNodesSyncControlInterface* ptr = NULL; 2315 ptr = OSCL_STATIC_CAST(PvmfNodesSyncControlInterface*, 2316 iSinkNodeList[ii].iNodeInterface.iInterface); 2317 ptr->SetClock(&iClock); 2318 } 2319 break; 2320 } 2321 } 2322 } 2323 else 2324 { 2325 SetState(EResetting); 2326 CheckState(); 2327 } 2328 break; 2329 case PV2WAY_NODE_CMD_SKIP_MEDIA_DATA: 2330 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 2331 (0, "CPV324m2Way::HandleSinkNodeCmd type %d, SkipComplete for Node %x ", 2332 aType, aNode->iNode)); 2333 if (iAudioDecDatapath) iAudioDecDatapath->SkipComplete(aNode); 2334 if (iVideoDecDatapath) iVideoDecDatapath->SkipComplete(aNode); 2335 RunIfNotReady(); 2336 break; 2337 default: 2338 break; 2339 } 2340 } 2341 2342 void CPV324m2Way::SupportedSinkNodeInterfaces(TPV2WayNode* aNode) 2343 { 2344 2345 int32 error; 2346 2347 //Currently this only checks if the sink node support PvmfSyncNodeControlInterface 2348 2349 TPV2WayNodeQueryInterfaceParams queryParam; 2350 queryParam.iUuid = (PVUuid *) & iSyncControlPVUuid; 2351 SinkNodeIFList sinkNode; 2352 sinkNode.iSinkNode = aNode; 2353 queryParam.iInterfacePtr = &iClockSyncInterface.iInterface; 2354 OSCL_TRY(error, sinkNode.iNodeInterface.iId = 2355 SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, aNode, this, &queryParam)); 2356 2357 iSinkNodeList.push_back(sinkNode); 2358 2359 OSCL_FIRST_CATCH_ANY(error, 2360 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2361 (0, "CPV324m2Way::SupportedSinkNodeInterfaces unable to query for MediaOutputNode extension interface!\n")); 2362 SetState(EResetting); 2363 CheckState(); 2364 return;); 2365 } 2366 2367 2368 void CPV324m2Way::HandleAudioEncNodeCmd(PV2WayNodeCmdType aType, 2369 const PVMFCmdResp& aResponse) 2370 { 2371 if (iAudioEncDatapath) 2372 { 2373 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 2374 (0, "CPV324m2Way::HandleAudioEncNodeCmd type %d, audio enc path state %d\n", 2375 aType, iAudioEncDatapath->GetState())); 2376 } 2377 OSCL_UNUSED_ARG(aResponse); 2378 OSCL_UNUSED_ARG(aType); 2379 2380 switch (aType) 2381 { 2382 case PV2WAY_NODE_CMD_QUERY_INTERFACE: 2383 2384 if (aResponse.GetCmdStatus() == PVMFSuccess) 2385 { 2386 iAudioEncNodeInterface.iState = PV2WayNodeInterface::HasInterface; 2387 2388 } 2389 else 2390 { 2391 iAudioEncNodeInterface.iState = PV2WayNodeInterface::NoInterface; 2392 SetState(EResetting); 2393 } 2394 2395 CheckState(); 2396 break; 2397 2398 case PV2WAY_NODE_CMD_INIT: 2399 CheckState(); 2400 break; 2401 2402 case PV2WAY_NODE_CMD_RESET: 2403 CheckState(); 2404 break; 2405 2406 default: 2407 break; 2408 } 2409 } 2410 2411 void CPV324m2Way::GenerateIFrame(PVMFPortInterface *aPort) 2412 { 2413 if (iVideoEncDatapath) 2414 { 2415 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 2416 (0, "CPV324m2Way::GenerateIFrame, vid enc path state %d\n", 2417 iVideoEncDatapath->GetState())); 2418 2419 if ((iVideoEncDatapath->IsPortInDatapath(aPort)) && 2420 (iVideoEncDatapath->GetState() == EOpened)) 2421 { 2422 if (!((PVMp4H263EncExtensionInterface *) iVideoEncNodeInterface.iInterface)->RequestIFrame()) 2423 { 2424 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2425 (0, "CPV324m2Way::GenerateIFrame - unable to generate iframe")); 2426 } 2427 } 2428 } 2429 } 2430 2431 void CPV324m2Way::RequestRemoteIFrame(PVMFPortInterface *aPort) 2432 { 2433 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 2434 (0, "CPV324m2Way::RequestRemoteIFrame, timer active %d\n", isIFrameReqTimerActive)); 2435 TSC_324m *nodeIface = (TSC_324m *)((PVMFNodeInterface *)iTscNode); 2436 if (nodeIface && 2437 !isIFrameReqTimerActive && 2438 (nodeIface->RequestFrameUpdate(aPort) == EPVT_Success)) 2439 { 2440 //Still need to actually send an iframe request!!!! 2441 iIFrameReqTimer.Request(IFRAME_REQ_TIMERID, (int32)this, 2442 iMinIFrameRequestInterval, this); 2443 isIFrameReqTimerActive = true; 2444 } 2445 } 2446 2447 PVCommandId CPV324m2Way::GetState(PV2WayState& aState, 2448 OsclAny* aContextData) 2449 { 2450 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2451 (0, "CPV324m2Way::GetPV2WayState %d\n", iState)); 2452 2453 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 2454 2455 cmd->type = PVT_COMMAND_GET_PV2WAY_STATE; 2456 cmd->id = iCommandId; 2457 cmd->contextData = aContextData; 2458 cmd->status = PVMFSuccess; 2459 2460 aState = iState; 2461 2462 Dispatch(cmd); 2463 2464 return iCommandId++; 2465 } 2466 2467 2468 PVCommandId CPV324m2Way::SetLatencyQualityTradeoff(PVMFNodeInterface& aTrack, 2469 int32 aTradeoff, 2470 OsclAny* aContextData) 2471 { 2472 OSCL_UNUSED_ARG(aTrack); 2473 OSCL_UNUSED_ARG(aTradeoff); 2474 OSCL_UNUSED_ARG(aContextData); 2475 return iCommandId++; 2476 } 2477 2478 2479 PVCommandId CPV324m2Way::Pause(PV2WayDirection aDirection, 2480 PVTrackId aTrackId, 2481 OsclAny* aContextData) 2482 { 2483 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV324m2Way::Pause\n")); 2484 OSCL_UNUSED_ARG(aDirection); 2485 OSCL_UNUSED_ARG(aTrackId); 2486 OSCL_UNUSED_ARG(aContextData); 2487 2488 OSCL_LEAVE(PVMFErrNotSupported); 2489 return iCommandId++; 2490 } 2491 2492 2493 PVCommandId CPV324m2Way::Resume(PV2WayDirection aDirection, 2494 PVTrackId aTrackId, 2495 OsclAny* aContextData) 2496 { 2497 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2498 (0, "CPV324m2Way::Resume\n")); 2499 OSCL_UNUSED_ARG(aDirection); 2500 OSCL_UNUSED_ARG(aTrackId); 2501 OSCL_UNUSED_ARG(aContextData); 2502 OSCL_LEAVE(PVMFErrNotSupported); 2503 2504 return iCommandId++; 2505 } 2506 2507 2508 PVCommandId CPV324m2Way::SetLogAppender(const char * aTag, 2509 OsclSharedPtr<PVLoggerAppender>& aAppender, 2510 OsclAny* aContextData) 2511 { 2512 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2513 (0, "CPV324m2Way::SetLogAppenderL\n")); 2514 2515 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 2516 2517 PVLogger *logger = PVLogger::GetLoggerObject(aTag); 2518 logger->AddAppender(aAppender); 2519 2520 // print sdk info 2521 PVSDKInfo sdkinfo; 2522 FillSDKInfo(sdkinfo); 2523 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2524 (0, "PV RELEASE LABEL = %s", sdkinfo.iLabel.get_cstr())); 2525 2526 cmd->type = PVT_COMMAND_SET_LOG_APPENDER; 2527 cmd->id = iCommandId; 2528 cmd->contextData = aContextData; 2529 cmd->status = PVMFSuccess; 2530 2531 Dispatch(cmd); 2532 return iCommandId++; 2533 } 2534 2535 PVCommandId CPV324m2Way::RemoveLogAppender(const char * aTag, 2536 OsclSharedPtr<PVLoggerAppender>& aAppender, 2537 OsclAny* aContextData) 2538 { 2539 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2540 (0, "CPV324m2Way::RemoveLogAppenderL\n")); 2541 2542 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 2543 2544 cmd->type = PVT_COMMAND_REMOVE_LOG_APPENDER; 2545 cmd->id = iCommandId; 2546 cmd->contextData = aContextData; 2547 cmd->status = PVMFSuccess; 2548 2549 PVLogger *logger = PVLogger::GetLoggerObject(aTag); 2550 logger->RemoveAppender(aAppender); 2551 2552 Dispatch(cmd); 2553 return iCommandId++; 2554 } 2555 2556 PVCommandId CPV324m2Way::SetLogLevel(const char * aTag, 2557 int32 aLevel, 2558 bool aSetSubtree, 2559 OsclAny* aContextData) 2560 { 2561 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2562 (0, "CPV324m2Way::SetLogLevelL\n")); 2563 OSCL_UNUSED_ARG(aSetSubtree); 2564 2565 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 2566 2567 cmd->type = PVT_COMMAND_SET_LOG_LEVEL; 2568 cmd->id = iCommandId; 2569 cmd->contextData = aContextData; 2570 cmd->status = PVMFSuccess; 2571 2572 PVLogger *logger = PVLogger::GetLoggerObject(aTag); 2573 logger->SetLogLevel(aLevel); 2574 2575 Dispatch(cmd); 2576 return iCommandId++; 2577 } 2578 2579 PVCommandId CPV324m2Way::GetLogLevel(const char * aTag, 2580 int32& aLogInfo, 2581 OsclAny* aContextData) 2582 { 2583 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2584 (0, "CPV324m2Way::GetLogLevelL\n")); 2585 2586 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 2587 2588 cmd->type = PVT_COMMAND_GET_LOG_LEVEL; 2589 cmd->id = iCommandId; 2590 cmd->contextData = aContextData; 2591 cmd->status = PVMFSuccess; 2592 2593 PVLogger *logger = PVLogger::GetLoggerObject(aTag); 2594 aLogInfo = logger->GetLogLevel(); 2595 2596 Dispatch(cmd); 2597 return iCommandId++; 2598 } 2599 2600 2601 PVCommandId CPV324m2Way::QueryInterface(const PVUuid& aUuid, 2602 PVInterface*& aInterfacePtr, 2603 OsclAny* aContextData) 2604 { 2605 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2606 (0, "CPV324m2Way::QueryInterface()\n")); 2607 2608 TPV2WayNodeQueryInterfaceParams queryParam; 2609 queryParam.iUuid = (PVUuid*) & aUuid; 2610 queryParam.iInterfacePtr = &aInterfacePtr; 2611 2612 TPV2WayCmdInfo *cmd = GetCmdInfoL(); 2613 cmd->type = PVT_COMMAND_QUERY_INTERFACE; 2614 cmd->id = iCommandId; 2615 cmd->contextData = aContextData; 2616 cmd->status = PVMFPending; 2617 aInterfacePtr = NULL; 2618 2619 if (aUuid == PVH324MConfigUuid && ((PVMFNodeInterface *)iTscNode)) 2620 { 2621 int32 error = 0; 2622 OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, 2623 &iTscNode, this, &queryParam, cmd)); 2624 OSCL_FIRST_CATCH_ANY(error, 2625 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2626 (0, "CPV324m2Way::QueryInterface failed!\n")); 2627 cmd->status = PVMFFailure; 2628 Dispatch(cmd);); 2629 cmd->status = PVMFSuccess; //ks added 2630 } 2631 else if (aUuid == PVMp4H263EncExtensionUUID && 2632 ((PVMFNodeInterface *)iVideoEncNode)) 2633 { 2634 int32 error = 0; 2635 OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, &iVideoEncNode, 2636 this, &queryParam, cmd)); 2637 OSCL_FIRST_CATCH_ANY(error, 2638 cmd->status = PVMFFailure; 2639 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2640 (0, "CPV324m2Way::QueryInterface unable to query for video encoder interface!\n"));); 2641 } 2642 else 2643 { 2644 aInterfacePtr = NULL; 2645 cmd->status = PVMFErrNotSupported; 2646 } 2647 if (cmd->status != PVMFPending) 2648 Dispatch(cmd); 2649 2650 return iCommandId++; 2651 } 2652 2653 PVCommandId CPV324m2Way::QueryUUID(const PvmfMimeString& aMimeType, 2654 Oscl_Vector<PVUuid, BasicAlloc>& aUuids, 2655 bool aExactUuidsOnly, 2656 OsclAny* aContextData) 2657 { 2658 OSCL_UNUSED_ARG(aMimeType); 2659 OSCL_UNUSED_ARG(aUuids); 2660 OSCL_UNUSED_ARG(aExactUuidsOnly); 2661 OSCL_UNUSED_ARG(aContextData); 2662 2663 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2664 (0, "CPV324m2Way::QueryUUID\n")); 2665 OSCL_LEAVE(PVMFErrNotSupported); 2666 return 0; 2667 } 2668 2669 PVCommandId CPV324m2Way::CancelAllCommands(OsclAny* aContextData) 2670 { 2671 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2672 (0, "CPV324m2Way::CancelAllCommands state %d\n", iState)); 2673 2674 if (iCancelInfo) 2675 { 2676 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2677 (0, "CPV324m2Way::CancelAllCommands, cancel in progress!\n")); 2678 OSCL_LEAVE(PVMFErrBusy); 2679 } 2680 2681 switch (iState) 2682 { 2683 case EInitializing: 2684 iCancelInfo = GetCmdInfoL(); 2685 iCancelInfo->type = PVT_COMMAND_CANCEL_ALL_COMMANDS; 2686 iCancelInfo->id = iCommandId; 2687 iCancelInfo->contextData = aContextData; 2688 SetState(EResetting); 2689 2690 if (!iInitInfo) 2691 { 2692 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2693 (0, "CPV324m2Way::CancelAllCommands, no init info!\n")); 2694 } 2695 else 2696 { 2697 iInitInfo->status = PVMFErrCancelled; 2698 Dispatch(iInitInfo); 2699 iInitInfo = NULL; 2700 } 2701 2702 CheckState(); 2703 break; 2704 2705 case EConnecting: 2706 iCancelInfo = GetCmdInfoL(); 2707 iCancelInfo->type = PVT_COMMAND_CANCEL_ALL_COMMANDS; 2708 iCancelInfo->id = iCommandId; 2709 iCancelInfo->contextData = aContextData; 2710 SetState(EDisconnecting); 2711 2712 if (!iConnectInfo) 2713 { 2714 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2715 (0, "CPV324m2Way::CancelAllCommands, no connect info!\n")); 2716 } 2717 else 2718 { 2719 iConnectInfo->status = PVMFErrCancelled; 2720 Dispatch(iConnectInfo); 2721 iConnectInfo = NULL; 2722 } 2723 2724 CheckState(); 2725 break; 2726 2727 default: 2728 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 2729 (0, "CPV324m2Way::CancelAllCommands invalid state!\n")); 2730 OSCL_LEAVE(PVMFErrInvalidState); 2731 break; 2732 } 2733 2734 return iCommandId++; 2735 } 2736 2737 2738 void CPV324m2Way::ConstructL(PVMFNodeInterface* aTsc, 2739 TPVTerminalType aType, 2740 PVCommandStatusObserver* aCmdStatusObserver, 2741 PVInformationalEventObserver *aInfoEventObserver, 2742 PVErrorEventObserver *aErrorEventObserver) 2743 { 2744 OSCL_UNUSED_ARG(aTsc); 2745 2746 iTerminalType = aType; 2747 2748 /* Initialize the clock */ 2749 if (!iClock.SetClockTimebase(iTickCountTimeBase)) 2750 { 2751 PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR, 2752 (0, "CPV324m2Way::ConstructL: unable to initialize clock")); 2753 OSCL_LEAVE(PVMFFailure); 2754 } 2755 2756 FormatCapabilityInfo inFormat; 2757 inFormat.dir = INCOMING; 2758 2759 /* Add user input types */ 2760 inFormat.format = PVMF_MIME_USERINPUT_DTMF; 2761 iIncomingUserInputFormats.push_back(inFormat); 2762 inFormat.format = PVMF_MIME_USERINPUT_IA5_STRING; 2763 iIncomingUserInputFormats.push_back(inFormat); 2764 inFormat.format = PVMF_MIME_USERINPUT_BASIC_STRING; 2765 iIncomingUserInputFormats.push_back(inFormat); 2766 2767 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2768 (0, "CPV324m2Way::ConstructL (%x, %x, %x, %x)", 2769 aTsc, aCmdStatusObserver, 2770 aInfoEventObserver, aErrorEventObserver)); 2771 iMuxDatapath = CPV2WayMuxDatapath::NewL(iLogger, PVMF_MIME_H223, this); 2772 2773 #if defined(PV_RECORD_TO_FILE_SUPPORT) 2774 iRecFilename = DEFAULT_RECORDED_CALL_FILENAME; 2775 2776 iAudioRecDatapath = CPV2WayRecDatapath::NewL(iLogger, PVMF_COMPRESSED_AUDIO_FORMAT, 2777 *iAudioDecDatapath, this); 2778 iVideoRecDatapath = CPV2WayRecDatapath::NewL(iLogger, PVMF_COMPRESSED_VIDEO_FORMAT, 2779 *iVideoDecDatapath, this); 2780 2781 //Set up recording datapath dependencies 2782 iAudioDecDatapath->AddDependentDatapath(*iAudioRecDatapath); 2783 iVideoDecDatapath->AddDependentDatapath(*iVideoRecDatapath); 2784 iAudioRecDatapath->AddParentDatapath(*iAudioDecDatapath); 2785 iVideoRecDatapath->AddParentDatapath(*iVideoDecDatapath); 2786 #endif 2787 2788 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 2789 iAudioPreviewDatapath = CPV2WayPreviewDatapath::NewL(iLogger, 2790 PVMF_COMPRESSED_AUDIO_FORMAT, this); 2791 iVideoPreviewDatapath = CPV2WayPreviewDatapath::NewL(iLogger, 2792 PVMF_COMPRESSED_VIDEO_FORMAT, this); 2793 2794 //Set up preview sink datapath dependencies 2795 iAudioEncDatapath->AddDependentDatapath(*iAudioPreviewDatapath); 2796 iVideoEncDatapath->AddDependentDatapath(*iVideoPreviewDatapath); 2797 iAudioPreviewDatapath->AddParentDatapath(*iAudioEncDatapath); 2798 iVideoPreviewDatapath->AddParentDatapath(*iVideoEncDatapath); 2799 #endif 2800 2801 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2802 (0, "Full pv_2way_engine\n")); 2803 #ifdef PV_DISABLE_VIDRECNODE 2804 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2805 (0, "VidRec node disabled\n")); 2806 #else 2807 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2808 (0, "VidRec node enabled\n")); 2809 #endif 2810 2811 #ifdef PV_DISABLE_DEVSOUNDNODES 2812 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2813 (0, "DevSound nodes disabled\n")); 2814 #else 2815 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 2816 (0, "DevSound nodes enabled\n")); 2817 #endif 2818 2819 SetDefaults(); 2820 iCmdStatusObserver = aCmdStatusObserver; 2821 iInfoEventObserver = aInfoEventObserver; 2822 iErrorEventObserver = aErrorEventObserver; 2823 2824 iPendingNotifications.reserve(MAX_PENDING_2WAY_COMMANDS + MAX_PENDING_2WAY_EVENTS); 2825 iPendingNodeCmdInfo.reserve(MAX_PENDING_2WAY_NODE_COMMANDS); 2826 iIncomingChannelParams.reserve(MAX_LOGICAL_CHANNEL_PARAMS); 2827 iOutgoingChannelParams.reserve(MAX_LOGICAL_CHANNEL_PARAMS); 2828 2829 int32 i; 2830 for (i = 0; i < MAX_PENDING_2WAY_COMMANDS; i++) 2831 { 2832 iFreeCmdInfo.push_back(&iCmdInfo[i]); 2833 } 2834 2835 for (i = 0; i < MAX_PENDING_2WAY_EVENTS; i++) 2836 { 2837 iFreeEventInfo.push_back(&iEventInfo[i]); 2838 } 2839 2840 for (i = 0; i < MAX_PENDING_2WAY_NODE_COMMANDS; i++) 2841 { 2842 iFreeNodeCmdInfo.push_back(&iNodeCmdInfo[i]); 2843 } 2844 2845 iSourceNodes.reserve(3); 2846 iSinkNodes.reserve(3); 2847 2848 AddToScheduler(); 2849 2850 PreInit(); 2851 2852 return; 2853 } 2854 2855 void CPV324m2Way::SetDefaults() 2856 { 2857 uint32 i; 2858 SetState(EIdle); 2859 2860 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 2861 if (iPlayFromFileNode.iNode) 2862 { 2863 iPlayFromFileNode.iNode->ThreadLogoff(); 2864 OSCL_DELETE(iPlayFromFileNode.iNode); 2865 iPlayFromFileNode.Clear();; 2866 } 2867 2868 if (iVideoSrcSplitterNode.iNode) 2869 { 2870 iVideoSrcSplitterNode.iNode->ThreadLogoff(); 2871 OSCL_DELETE(iVideoSrcSplitterNode.iNode); 2872 iVideoSrcSplitterNode = NULL; 2873 } 2874 2875 if (iAudioSrcSplitterNode) 2876 { 2877 iAudioSrcSplitterNode->ThreadLogoff(); 2878 OSCL_DELETE(iAudioSrcSplitterNode); 2879 iAudioSrcSplitterNode = NULL; 2880 } 2881 #endif 2882 2883 #if defined(PV_RECORD_TO_FILE_SUPPORT) 2884 if (iFFComposerNode) 2885 { 2886 iFFComposerNode->ThreadLogoff(); 2887 PVMp4FFComposerNodeFactory::DeleteMp4FFComposer(iFFComposerNode); 2888 iFFComposerNode = NULL; 2889 } 2890 2891 if (iVideoDecSplitterNode) 2892 { 2893 iVideoDecSplitterNode->ThreadLogoff(); 2894 OSCL_DELETE(iVideoDecSplitterNode); 2895 iVideoDecSplitterNode = NULL; 2896 } 2897 #endif 2898 2899 if (iVideoParserNode.iNode) 2900 { 2901 iVideoParserNode.iNode->ThreadLogoff(); 2902 OSCL_DELETE(iVideoParserNode.iNode); 2903 iVideoParserNode.Clear(); 2904 } 2905 2906 if (iVideoDecNode.iNode) 2907 { 2908 iVideoDecNode.iNode->ThreadLogoff(); 2909 2910 #ifdef PV2WAY_USE_OMX 2911 DELETE_OMX_VIDEO_DEC_NODE(iVideoDecNode.iNode); 2912 #else 2913 DELETE_VIDEO_DEC_NODE(iVideoDecNode.iNode); 2914 #endif // PV2WAY_USE_OMX 2915 2916 iVideoDecNode.Clear(); 2917 } 2918 2919 if (iAudioDecNode.iNode) 2920 { 2921 iAudioDecNode.iNode->ThreadLogoff(); 2922 #ifdef PV2WAY_USE_OMX 2923 DELETE_OMX_AUDIO_DEC_NODE(iAudioDecNode.iNode); 2924 #else 2925 DELETE_AUDIO_DEC_NODE(iAudioDecNode.iNode); 2926 #endif // PV2WAY_USE_OMX 2927 2928 iAudioDecNode.Clear(); 2929 } 2930 2931 if (iTscNode.iNode) 2932 { 2933 iTscNode.iNode->ThreadLogoff(); 2934 } 2935 2936 if (iAudioEncNode.iNode) 2937 { 2938 iAudioEncNode.iNode->ThreadLogoff(); 2939 if (iAudioEncNodeInterface.iInterface) 2940 iAudioEncNodeInterface.iInterface->removeRef(); 2941 #ifdef PV2WAY_USE_OMX 2942 DELETE_OMX_ENC_NODE(iAudioEncNode.iNode); 2943 #else 2944 DELETE_AUDIO_ENC_NODE(iAudioEncNode.iNode); 2945 #endif 2946 iAudioEncNode.Clear() ; 2947 iAudioEncNodeInterface.Reset(); 2948 } 2949 2950 ClearVideoEncNode(); 2951 2952 if (iCommNode.iNode) 2953 { 2954 iCommNode.iNode->ThreadLogoff(); 2955 iCommNode.Clear(); 2956 } 2957 2958 iFormatCapability.clear(); 2959 iIncomingAudioCodecs.clear(); 2960 iOutgoingAudioCodecs.clear(); 2961 iIncomingVideoCodecs.clear(); 2962 iOutgoingVideoCodecs.clear(); 2963 2964 /* Stop the clock */ 2965 iClock.Stop(); 2966 2967 /* Delete the list of sink/source nodes */ 2968 for (i = 0; i < iSourceNodes.size(); i++) 2969 { 2970 TPV2WayNode* lNode = iSourceNodes[i]; 2971 OSCL_DELETE(lNode); 2972 iSourceNodes[i] = 0; 2973 } 2974 iSourceNodes.clear(); 2975 iSourceNodes.destroy(); 2976 2977 for (i = 0; i < iSinkNodes.size(); i++) 2978 { 2979 TPV2WayNode* lNode = iSinkNodes[i] ; 2980 OSCL_DELETE(lNode); 2981 iSinkNodes[i] = 0; 2982 } 2983 iSinkNodes.clear(); 2984 iSinkNodes.destroy(); 2985 iAddDataSourceVideoCmd = NULL; 2986 return; 2987 } 2988 2989 void CPV324m2Way::DoCancel() 2990 { 2991 2992 } 2993 2994 void CPV324m2Way::Run() 2995 { 2996 int32 error; 2997 TPV2WayCmdInfo* cmd = NULL; 2998 TPV2WayEventInfo* event = NULL; 2999 3000 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3001 (0, "CPV324m2Way::Run state %d, number of notifications pending %d\n", 3002 iState, iPendingNotifications.size())); 3003 3004 while (!iPendingNotifications.empty()) 3005 { 3006 if (iPendingNotifications[0]->notificationType == 3007 TPV2WayNotificationInfo::EPV2WayCommandType) 3008 { 3009 cmd = (TPV2WayCmdInfo *) iPendingNotifications[0]; 3010 3011 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3012 (0, "CPV324m2Way::Run Calling CommandCompleted CmdType %d CmdId %d CmdStatus %d\n", 3013 cmd->type, cmd->id, cmd->status)); 3014 3015 switch (cmd->type) 3016 { 3017 case PVT_COMMAND_INIT: 3018 if ((cmd->status != PVMFSuccess) && 3019 (cmd->status != PVMFErrCancelled)) 3020 { 3021 SetDefaults(); 3022 } 3023 break; 3024 3025 case PVT_COMMAND_RESET: 3026 RemoveAudioEncPath(); 3027 RemoveVideoEncPath(); 3028 RemoveAudioDecPath(); 3029 RemoveVideoDecPath(); 3030 SetDefaults(); 3031 break; 3032 3033 case PVT_COMMAND_CONNECT: 3034 if ((cmd->status != PVMFSuccess) && 3035 (cmd->status != PVMFErrCancelled)) 3036 { 3037 iMuxDatapath->ResetDatapath(); 3038 iCommNode.iNode->ThreadLogoff(); 3039 iCommNode.Clear(); 3040 } 3041 break; 3042 3043 case PVT_COMMAND_DISCONNECT: 3044 iMuxDatapath->ResetDatapath(); 3045 iCommNode.iNode->ThreadLogoff(); 3046 iCommNode.Clear(); 3047 break; 3048 3049 case PVT_COMMAND_ADD_DATA_SOURCE: 3050 if (cmd->status == PVMFSuccess) 3051 { 3052 if (iAudioEncDatapath && (iAudioEncDatapath->GetState() == EOpened) && 3053 iVideoEncDatapath && (iVideoEncDatapath->GetState() == EOpened)) 3054 { 3055 TSC_324m *tsc_node = (TSC_324m *)(iTscNode.iNode); 3056 tsc_node->SetSkewReference(iVideoEncDatapath->GetTSCPort(), 3057 iAudioEncDatapath->GetTSCPort()); 3058 } 3059 } 3060 else 3061 { 3062 if (cmd->status != PVMFErrCancelled) 3063 { 3064 RemoveAudioEncPath(); 3065 RemoveVideoEncPath(); 3066 } 3067 } 3068 break; 3069 3070 case PVT_COMMAND_ADD_DATA_SINK: 3071 { 3072 CPV2WayDecDataChannelDatapath* datapath = NULL; 3073 if (cmd->iPvtCmdData == iAudioDecDatapath->GetChannelId()) 3074 { 3075 datapath = iAudioDecDatapath; 3076 } 3077 else if (cmd->iPvtCmdData == iVideoDecDatapath->GetChannelId()) 3078 { 3079 datapath = iVideoDecDatapath; 3080 } 3081 if (datapath == NULL) 3082 { 3083 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3084 (0, "CPV324m2Way::Run ERROR Failed to lookup dec datapath.\n")); 3085 break; 3086 } 3087 3088 if ((cmd->status != PVMFSuccess) && 3089 (cmd->status != PVMFErrCancelled)) 3090 { 3091 if (datapath == iAudioDecDatapath) 3092 RemoveAudioDecPath(); 3093 else if (datapath == iVideoDecDatapath) 3094 RemoveVideoDecPath(); 3095 break; 3096 } 3097 3098 if (!datapath->IsSkipComplete()) 3099 return; 3100 } 3101 break; 3102 3103 case PVT_COMMAND_REMOVE_DATA_SOURCE: 3104 RemoveAudioEncPath(); 3105 RemoveVideoEncPath(); 3106 break; 3107 3108 case PVT_COMMAND_REMOVE_DATA_SINK: 3109 RemoveAudioDecPath(); 3110 RemoveVideoDecPath(); 3111 break; 3112 3113 #if defined(PV_RECORD_TO_FILE_SUPPORT) 3114 case PVT_COMMAND_START_RECORD: 3115 if ((cmd->status != PVMFSuccess) && 3116 (cmd->status != PVMFErrCancelled)) 3117 { 3118 RemoveAudioRecPath(); 3119 RemoveVideoRecPath(); 3120 } 3121 break; 3122 3123 case PVT_COMMAND_STOP_RECORD: 3124 RemoveAudioRecPath(); 3125 RemoveVideoRecPath(); 3126 break; 3127 #endif 3128 3129 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 3130 case PVT_COMMAND_ADD_PREVIEW_SINK: 3131 if ((cmd->status != PVMFSuccess) && 3132 (cmd->status != PVMFErrCancelled)) 3133 { 3134 RemoveAudioPreviewPath(); 3135 RemoveVideoPreviewPath(); 3136 } 3137 break; 3138 3139 case PVT_COMMAND_REMOVE_PREVIEW_SINK: 3140 RemoveAudioPreviewPath(); 3141 RemoveVideoPreviewPath(); 3142 break; 3143 3144 #endif 3145 case PVT_COMMAND_CANCEL_ALL_COMMANDS: 3146 //Init cancelled 3147 if (iState == EIdle) 3148 { 3149 SetDefaults(); 3150 } 3151 if (iState == ESetup) 3152 { 3153 if (iMuxDatapath->GetState() == EClosed) 3154 { 3155 iMuxDatapath->ResetDatapath(); 3156 iCommNode.iNode->ThreadLogoff(); 3157 iCommNode.Clear(); 3158 } 3159 } 3160 break; 3161 3162 default: 3163 break; 3164 } 3165 3166 { 3167 PVCmdResponse resp(cmd->id, cmd->contextData, cmd->status, NULL, 0); 3168 OSCL_TRY(error, iCmdStatusObserver->CommandCompleted(resp)); 3169 OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, 3170 PVLOGMSG_ERR, (0, "CPV324m2Way::Run CommandCompletedL leave %d\n", 3171 error))); 3172 } 3173 3174 iPendingNotifications.erase(iPendingNotifications.begin()); 3175 FreeCmdInfo(cmd); 3176 3177 } 3178 else if (iPendingNotifications[0]->notificationType == 3179 TPV2WayNotificationInfo::EPV2WayEventType) 3180 { 3181 event = (TPV2WayEventInfo *) iPendingNotifications[0]; 3182 3183 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3184 (0, "CPV324m2Way::Run Calling HandleInformationalEventL EventType %d\n", 3185 event->type)); 3186 3187 switch (event->type) 3188 { 3189 case PVT_INDICATION_CLOSE_TRACK: 3190 { 3191 TPVChannelId* id = (TPVChannelId*)(event->localBuffer + 4); 3192 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3193 (0, "CPV324m2Way::Run PVT_INDICATION_CLOSE_TRACK direction %d, channel id=%d", 3194 event->localBuffer[0], *id)); 3195 if (event->localBuffer[0] == INCOMING) 3196 { 3197 if (iAudioDecDatapath && (*id == iAudioDecDatapath->GetChannelId())) 3198 { 3199 RemoveAudioDecPath(); 3200 } 3201 else if (iVideoDecDatapath && (*id == iVideoDecDatapath->GetChannelId())) 3202 { 3203 RemoveVideoDecPath(); 3204 } 3205 } 3206 else if (event->localBuffer[0] == OUTGOING) 3207 { 3208 if (iAudioEncDatapath && (*id == iAudioEncDatapath->GetChannelId())) 3209 { 3210 RemoveAudioEncPath(); 3211 } 3212 else if (iVideoEncDatapath && (*id == iVideoEncDatapath->GetChannelId())) 3213 { 3214 RemoveVideoEncPath(); 3215 } 3216 } 3217 3218 CheckState(); 3219 } 3220 break; 3221 3222 case PVT_INDICATION_DISCONNECT: 3223 iMuxDatapath->ResetDatapath(); 3224 iCommNode.Clear(); 3225 break; 3226 3227 #if defined(PV_RECORD_TO_FILE_SUPPORT) 3228 case PVT_INDICATION_RECORDING_ERROR: 3229 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3230 (0, "CPV324m2Way::Run PVT_INDICATION_RECORD_ERROR media %d\n", 3231 event->localBuffer[0])); 3232 if (event->localBuffer[0] == PV_AUDIO) 3233 { 3234 RemoveAudioRecPath(); 3235 } 3236 else 3237 { 3238 RemoveVideoRecPath(); 3239 } 3240 break; 3241 #endif 3242 3243 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 3244 3245 case PVT_INDICATION_PREVIEW_ERROR: 3246 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3247 (0, "CPV324m2Way::Run PVT_INDICATION_PREVIEW_ERROR media %d\n", 3248 event->localBuffer[0])); 3249 if (event->localBuffer[0] == PV_AUDIO) 3250 { 3251 RemoveAudioPreviewPath(); 3252 } 3253 else 3254 { 3255 RemoveVideoPreviewPath(); 3256 } 3257 break; 3258 #endif 3259 default: 3260 break; 3261 } 3262 3263 { 3264 PVAsyncInformationalEvent aEvent(event->type, event->exclusivePtr, 3265 &event->localBuffer[0], event->localBufferSize); 3266 OSCL_TRY(error, iInfoEventObserver->HandleInformationalEvent(aEvent)); 3267 OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, 3268 PVLOGMSG_ERR, (0, "CPV324m2Way::Run HandleInformationalEventL leave %d\n", 3269 error))); 3270 } 3271 3272 iPendingNotifications.erase(iPendingNotifications.begin()); 3273 FreeEventInfo(event); 3274 } 3275 } 3276 } 3277 3278 void CPV324m2Way::Dispatch(TPV2WayCmdInfo* aCmdInfo) 3279 { 3280 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3281 (0, "CPV324m2Way::Dispatch Appending command to queue CmdType %d CmdId %d CmdStatus %d\n", 3282 aCmdInfo->type, aCmdInfo->id, aCmdInfo->status)); 3283 if (aCmdInfo->status != PVMFSuccess) 3284 { 3285 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3286 (0, "CPV324m2Way::Dispatch Command failed\n")); 3287 } 3288 iPendingNotifications.push_back(aCmdInfo); 3289 RunIfNotReady(); 3290 } 3291 3292 void CPV324m2Way::Dispatch(TPV2WayEventInfo* aEventInfo) 3293 { 3294 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3295 (0, "CPV324m2Way::Dispatch Appending event to queue event type %d\n", 3296 aEventInfo->type)); 3297 3298 iPendingNotifications.push_back(aEventInfo); 3299 RunIfNotReady(); 3300 } 3301 3302 3303 bool CPV324m2Way::IsNodeInList(Oscl_Vector<TPV2WayNode*, OsclMemAllocator>& aList, 3304 PVMFNodeInterface* aNode) 3305 { 3306 for (uint32 i = 0; i < aList.size(); i++) 3307 { 3308 TPV2WayNode* lNode = aList[i]; 3309 if (lNode && lNode->iNode == aNode) 3310 return true; 3311 } 3312 return false; 3313 } 3314 3315 bool CPV324m2Way::IsSourceNode(PVMFNodeInterface* aNode) 3316 { 3317 return IsNodeInList(iSourceNodes, aNode); 3318 } 3319 3320 bool CPV324m2Way::IsSinkNode(PVMFNodeInterface* aNode) 3321 { 3322 return IsNodeInList(iSinkNodes, aNode); 3323 } 3324 3325 TPV2WayNode* CPV324m2Way::GetTPV2WayNode(Oscl_Vector<TPV2WayNode*, OsclMemAllocator>& aList, 3326 PVMFNodeInterface* aNode) 3327 { 3328 for (uint32 i = 0; i < aList.size(); i++) 3329 { 3330 TPV2WayNode* lNode = aList[i]; 3331 if (lNode && lNode->iNode == aNode) 3332 return lNode; 3333 } 3334 return NULL; 3335 } 3336 3337 TPV2WayNode* CPV324m2Way::RemoveTPV2WayNode(Oscl_Vector<TPV2WayNode*, OsclMemAllocator>& aList, 3338 PVMFNodeInterface* aNode) 3339 { 3340 for (uint32 i = 0; i < aList.size(); i++) 3341 { 3342 TPV2WayNode* lNode = aList[i]; 3343 if (lNode && lNode->iNode == aNode) 3344 { 3345 aList[i] = 0; 3346 return lNode; 3347 } 3348 } 3349 return NULL; 3350 } 3351 3352 // from PVMFNodeCmdEventObserver 3353 void CPV324m2Way::NodeCommandCompleted(const PVMFCmdResp& aResponse) 3354 { 3355 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3356 (0, "CPV324m2Way::NodeCommandCompleted status %d, context %x\n", 3357 aResponse.GetCmdStatus(), aResponse.GetContext())); 3358 3359 if (aResponse.GetCmdStatus() != PVMFSuccess) 3360 { 3361 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3362 (0, "CPV324m2Way::NodeCommandCompleted Command failed")); 3363 } 3364 CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext(); 3365 TPV2WayNodeCmdInfo *info = FindPendingNodeCmd(data->iNode, aResponse.GetCmdId()); 3366 3367 data->iObserver->CommandHandler(info->type, aResponse); 3368 3369 // check if node cmd response requires engine cmd response 3370 if (info->engineCmdInfo != NULL) 3371 { 3372 info->engineCmdInfo->status = aResponse.GetCmdStatus(); 3373 Dispatch(info->engineCmdInfo); 3374 } 3375 3376 //Remove the command from the pending list. 3377 RemovePendingNodeCmd(data->iNode, aResponse.GetCmdId()); 3378 } 3379 3380 // from PVMFNodeInfoEventObserver 3381 void CPV324m2Way::HandleNodeInformationalEvent(const PVMFAsyncEvent& aEvent) 3382 { 3383 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3384 (0, "CPV324m2Way::HandleNodeInformationalEvent type %d\n", 3385 aEvent.GetEventType())); 3386 3387 if (aEvent.GetContext() == iTscNode) 3388 { 3389 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3390 (0, "CPV324m2Way::HandleNodeInformationalEvent tsc node\n")); 3391 uint8 *buf = aEvent.GetLocalBuffer(); 3392 switch (buf[0]) 3393 { 3394 case PV_H324COMPONENT_H223: 3395 switch (buf[2]) 3396 { 3397 case INCOMING: 3398 { 3399 TPVChannelId id = CHANNEL_ID_UNKNOWN; 3400 if (buf[1] == PV_MUX_COMPONENT_LOGICAL_CHANNEL) 3401 { 3402 id = *((TPVChannelId*)(buf + 4)); 3403 3404 // See if error is in video datapath 3405 if (id == iVideoDecDatapath->GetChannelId()) 3406 { 3407 // request for I-frame 3408 RequestRemoteIFrame(iVideoDecDatapath->GetTSCPort()); 3409 } 3410 } 3411 } 3412 break; 3413 3414 case OUTGOING: 3415 GenerateIFrame(iVideoEncDatapath->GetTSCPort()); 3416 break; 3417 3418 default: 3419 break; 3420 } 3421 break; 3422 3423 default: 3424 break; 3425 } 3426 } 3427 else if (aEvent.GetContext() == iCommNode) 3428 { 3429 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3430 (0, "CPV324m2Way::HandleNodeInformationalEvent comm node\n")); 3431 } 3432 #if defined(PV_RECORD_TO_FILE_SUPPORT) 3433 else if (aEvent.GetContext() == iFFComposerNode) 3434 { 3435 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3436 (0, "CPV324m2Way::HandleNodeInformationalEvent ff composer node\n")); 3437 } 3438 #endif 3439 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 3440 else if (aEvent.GetContext() == iPlayFromFileNode) 3441 { 3442 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3443 (0, "CPV324m2Way::HandleNodeInformationalEvent playfromfile node\n")); 3444 TPV2WayEventInfo* event = NULL; 3445 switch (aEvent.GetEventType()) 3446 { 3447 case PFF_NODE_INFO_EVENT_EOS_INFO_EVENT: 3448 if (!GetEventInfo(event)) 3449 { 3450 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 3451 (0, "CPV324m2Way::HandleNodeInformationalEvent unable to notify app!\n")); 3452 return; 3453 } 3454 event->type = PVT_INDICATION_PLAY_EOS; 3455 event->localBufferSize = 1; 3456 3457 //Check which port received the EOS. 3458 if (iAudioPlayPort.GetPort() == aEvent.GetEventData()) 3459 { 3460 event->localBuffer[0] = PV_AUDIO; 3461 Dispatch(event); 3462 } 3463 else if (iVideoPlayPort.GetPort() == aEvent.GetEventData()) 3464 { 3465 event->localBuffer[0] = PV_VIDEO; 3466 Dispatch(event); 3467 } 3468 else 3469 { 3470 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3471 (0, "CPV324m2Way::HandleNodeInformationalEvent unknown pff port for EOS %x\n", 3472 aEvent.GetEventData())); 3473 FreeEventInfo(event); 3474 } 3475 3476 break; 3477 3478 default: 3479 break; 3480 } 3481 3482 } 3483 #endif 3484 else if (aEvent.GetContext() == iVideoDecNode) 3485 { 3486 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3487 (0, "CPV324m2Way::HandleNodeInformationalEvent video dec node\n")); 3488 } 3489 else if (aEvent.GetContext() == iVideoParserNode) 3490 { 3491 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3492 (0, "CPV324m2Way::HandleNodeInformationalEvent video parser node\n")); 3493 } 3494 else if (aEvent.GetContext() == iVideoEncNode) 3495 { 3496 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3497 (0, "CPV324m2Way::HandleNodeInformationalEvent video encoder node\n")); 3498 } 3499 else if (iAudioEncDatapath && iAudioEncDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) 3500 { 3501 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3502 (0, "CPV324m2Way::HandleNodeInformationalEvent audio enc datapath\n")); 3503 } 3504 else if (iAudioDecDatapath && iAudioDecDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) 3505 { 3506 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3507 (0, "CPV324m2Way::HandleNodeInformationalEvent audio dec datapath\n")); 3508 PVMFEventType event = aEvent.GetEventType(); 3509 if (event == PVMFInfoStartOfData) 3510 { 3511 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3512 (0, "CPV324m2Way::HandleNodeInformationalEvent audio dec datapath PVMFInfoStartOfData received, Clock started\n")); 3513 } 3514 } 3515 else if ((iVideoEncDatapath != NULL) && 3516 (iVideoEncDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext()))) 3517 { 3518 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3519 (0, "CPV324m2Way::HandleNodeInformationalEvent video enc datapath\n")); 3520 } 3521 else if ((iVideoDecDatapath != NULL) && 3522 (iVideoDecDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext()))) 3523 { 3524 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3525 (0, "CPV324m2Way::HandleNodeInformationalEvent video dec datapath\n")); 3526 PVMFEventType event = aEvent.GetEventType(); 3527 if (event == PVMFInfoStartOfData) 3528 { 3529 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3530 (0, "CPV324m2Way::HandleNodeInformationalEvent video dec datapath PVMFInfoStartOfData received, Clock started\n")); 3531 } 3532 } 3533 else 3534 { 3535 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 3536 (0, "CPV324m2Way::HandleNodeInformationalEvent unknown node!")); 3537 } 3538 } 3539 3540 // from PVMFNodeErrorEventObserver 3541 void CPV324m2Way::HandleNodeErrorEvent(const PVMFAsyncEvent& aEvent) 3542 { 3543 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3544 (0, "CPV324m2Way::HandleNodeErrorEvent type %d\n", aEvent.GetEventType())); 3545 3546 if (aEvent.GetContext() == iTscNode) 3547 { 3548 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 3549 (0, "CPV324m2Way::HandleNodeErrorEvent tsc node\n")); 3550 3551 switch (iState) 3552 { 3553 case EDisconnecting: 3554 CheckState(); 3555 break; 3556 3557 case EConnecting: 3558 case EConnected: 3559 //InitiateDisconnect(); 3560 break; 3561 3562 default: 3563 break; 3564 } 3565 } 3566 else if (aEvent.GetContext() == iCommNode) 3567 { 3568 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3569 (0, "CPV324m2Way::HandleNodeErrorEvent comm node\n")); 3570 switch (iState) 3571 { 3572 case EDisconnecting: 3573 CheckState(); 3574 break; 3575 3576 case EConnecting: 3577 case EConnected: 3578 InitiateDisconnect(); 3579 break; 3580 3581 default: 3582 break; 3583 } 3584 } 3585 #if defined(PV_RECORD_TO_FILE_SUPPORT) 3586 else if (aEvent.GetContext() == iFFComposerNode) 3587 { 3588 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3589 (0, "CPV324m2Way::HandleNodeErrorEvent ff composer node state %d\n", 3590 iRecordFileState)); 3591 switch (iRecordFileState) 3592 { 3593 case File2WayResetting: 3594 CheckRecordFileState(); 3595 break; 3596 3597 case File2WayInitializing: 3598 case File2WayInitialized: 3599 InitiateResetRecordFile(); 3600 break; 3601 3602 default: 3603 break; 3604 } 3605 } 3606 #endif 3607 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 3608 else if (aEvent.GetContext() == iPlayFromFileNode) 3609 { 3610 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3611 (0, "CPV324m2Way::HandleNodeErrorEvent playfromfile node state %d\n", 3612 iPlayFromFileNode->GetState())); 3613 switch (iPlayFileState) 3614 { 3615 case File2WayResetting: 3616 CheckPlayFileState(); 3617 break; 3618 3619 case File2WayInitializing: 3620 case File2WayInitialized: 3621 InitiateResetPlayFile(); 3622 break; 3623 3624 default: 3625 break; 3626 } 3627 } 3628 #endif 3629 else if (iVideoEncDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) 3630 { 3631 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3632 (0, "CPV324m2Way::HandleNodeErrorEvent video enc datapath\n")); 3633 iVideoEncDatapath->SetCmd(NULL); 3634 } 3635 else if (iVideoDecDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) 3636 { 3637 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3638 (0, "CPV324m2Way::HandleNodeErrorEvent video dec datapath\n")); 3639 iVideoDecDatapath->SetCmd(NULL); 3640 } 3641 else if (iAudioEncDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) 3642 { 3643 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3644 (0, "CPV324m2Way::HandleNodeErrorEvent audio enc datapath\n")); 3645 3646 iAudioEncDatapath->UseFilePlayPort(false); 3647 iAudioEncDatapath->SetSourceInputPort(NULL); 3648 3649 #ifndef PV_DISABLE_DEVSOUNDNODES 3650 switch (aEvent.GetEventType()) 3651 { 3652 3653 case PVMF_DEVSOUND_ERR_PORT_GETDATA_ERROR: 3654 case PVMF_DEVSOUND_ERR_PORT_PUTDATA_ERROR: 3655 case PVMF_DEVSOUND_ERR_SOURCE_SINK_EVENT_ERROR: 3656 case PVMF_DEVSOUND_ERR_BITSTREAM_ERROR: 3657 case PVMF_DEVSOUND_ERR_PORT_FRAME_TRANSFER_ERROR: 3658 case PVMF_DEVSOUND_ERR_SOURCE_SINK_FRAME_TRANSFER_ERROR: 3659 case PVMF_DEVSOUND_ERR_DATA_PROCESSING_ERROR: 3660 case PVMF_DEVSOUND_ERR_RECORD_DATA_LOST: 3661 case PVMF_DEVSOUND_ERR_MEMPOOL_ALLOC_ERROR: 3662 case PVMF_DEVSOUND_ERR_MEDIADATAALLOC_ALLOC_ERROR: 3663 //data dropped, recording will continue 3664 break; 3665 3666 default: 3667 iAudioEncDatapath->SetCmd(NULL); 3668 break; 3669 } 3670 #else 3671 iAudioEncDatapath->SetCmd(NULL); 3672 #endif 3673 } 3674 else if (iAudioDecDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) 3675 { 3676 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3677 (0, "CPV324m2Way::HandleNodeErrorEvent audio dec datapath\n")); 3678 3679 #ifndef PV_DISABLE_DEVSOUNDNODES 3680 switch (aEvent.GetEventType()) 3681 { 3682 case PVMF_DEVSOUND_ERR_PORT_GETDATA_ERROR: 3683 case PVMF_DEVSOUND_ERR_PORT_PUTDATA_ERROR: 3684 case PVMF_DEVSOUND_ERR_SOURCE_SINK_EVENT_ERROR: 3685 case PVMF_DEVSOUND_ERR_BITSTREAM_ERROR: 3686 case PVMF_DEVSOUND_ERR_PORT_FRAME_TRANSFER_ERROR: 3687 case PVMF_DEVSOUND_ERR_SOURCE_SINK_FRAME_TRANSFER_ERROR: 3688 case PVMF_DEVSOUND_ERR_DATA_PROCESSING_ERROR: 3689 case PVMF_DEVSOUND_ERR_MEMPOOL_ALLOC_ERROR: 3690 case PVMF_DEVSOUND_ERR_MEDIADATAALLOC_ALLOC_ERROR: 3691 //data dropped, playback will continue 3692 break; 3693 3694 default: 3695 iAudioDecDatapath->SetCmd(NULL); 3696 break; 3697 } 3698 #else 3699 iAudioDecDatapath->SetCmd(NULL); 3700 3701 #endif 3702 } 3703 else 3704 { 3705 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 3706 (0, "CPV324m2Way::HandleNodeErrorEvent unknown node!")); 3707 } 3708 } 3709 3710 void CPV324m2Way::CommandHandler(PV2WayNodeCmdType aType, 3711 const PVMFCmdResp& aResponse) 3712 { 3713 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3714 (0, "CPV324m2Way::CommandHandler, state %d, type %d\n", iState, aType)); 3715 3716 CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext(); 3717 3718 if (data->iNode == iCommNode.iNode) 3719 { 3720 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3721 (0, "CPV324m2Way::CommandHandler comm node\n")); 3722 HandleCommNodeCmd(aType, aResponse); 3723 } 3724 else if (data->iNode == iTscNode.iNode) 3725 { 3726 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3727 (0, "CPV324m2Way::CommandHandler TSC node\n")); 3728 HandleTscNodeCmd(aType, aResponse); 3729 } 3730 else if (data->iNode == iVideoDecNode.iNode) 3731 { 3732 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3733 (0, "CPV324m2Way::CommandHandler video decoder node\n")); 3734 HandleVideoDecNodeCmd(aType, aResponse); 3735 } 3736 else if (data->iNode == iVideoEncNode.iNode) 3737 { 3738 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3739 (0, "CPV324m2Way::CommandHandler video encoder node\n")); 3740 HandleVideoEncNodeCmd(aType, aResponse); 3741 } 3742 else if (IsSourceNode(data->iNode)) 3743 { 3744 /* Do Add Data Source Here */ 3745 TPV2WayNode *source_node = GetTPV2WayNode(iSourceNodes, data->iNode); 3746 OSCL_ASSERT(source_node); 3747 DoAddDataSource(*source_node, aResponse); 3748 } 3749 else if (IsSinkNode(data->iNode)) 3750 { 3751 TPV2WayNode *sink_node = GetTPV2WayNode(iSinkNodes, data->iNode); 3752 OSCL_ASSERT(sink_node); 3753 HandleSinkNodeCmd(aType, aResponse, sink_node); 3754 } 3755 else if (data->iNode == iAudioEncNode.iNode) 3756 { 3757 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3758 (0, "CPV324m2Way::CommandHandler audio encoder node\n")); 3759 HandleAudioEncNodeCmd(aType, aResponse); 3760 } 3761 #if defined(PV_RECORD_TO_FILE_SUPPORT) 3762 else if (data->iNode == iFFComposerNode.iNode) 3763 { 3764 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3765 (0, "CPV324m2Way::CommandHandler ff composer node\n")); 3766 HandleFFComposerNodeCmd(aType, aResponse); 3767 } 3768 #endif 3769 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 3770 else if (data->iNode == iPlayFromFileNode.iNode) 3771 { 3772 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3773 (0, "CPV324m2Way::CommandHandler pff node\n")); 3774 HandlePFFNodeCmd(aType, aResponse); 3775 } 3776 else if (data->iNode == iAudioSrcNode.iNode) 3777 { 3778 // This will happen only after the node had been added to a datapath succussfully 3779 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3780 (0, "CPV324m2Way::CommandHandler audio src node\n")); 3781 HandleAudioSrcNodeCmd(aType, aResponse); 3782 } 3783 #endif 3784 else 3785 { 3786 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 3787 (0, "CPV324m2Way::CommandHandler unknown node!")); 3788 } 3789 } 3790 3791 PVMFStatus CPV324m2Way::ConfigureNode(CPVDatapathNode *aNode) 3792 { 3793 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3794 (0, "CPV324m2Way::ConfigureNode, state %d\n", iState)); 3795 3796 PVMFNodeInterface *node = aNode->iNode.iNode; 3797 3798 if (node == iTscNode.iNode) 3799 { 3800 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3801 (0, "CPV324m2Way::ConfigureNode configuring tsc node\n")); 3802 return PVMFSuccess; 3803 } 3804 else if (node == iCommNode.iNode) 3805 { 3806 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3807 (0, "CPV324m2Way::ConfigureNode configuring comm node\n")); 3808 return PVMFSuccess; 3809 } 3810 else if (node == iVideoEncNode.iNode) 3811 { 3812 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "CPV324m2Way::ConfigureNode configuring video enc node\n")); 3813 3814 3815 PVMp4H263EncExtensionInterface *ptr = 3816 (PVMp4H263EncExtensionInterface *) iVideoEncNodeInterface.iInterface; 3817 3818 3819 uint32 bitrate_bps_100 = VIDEO_ENCODER_BITRATE / 100; 3820 PVMFVideoResolution aVideoResolution(VIDEO_ENCODER_WIDTH, 3821 VIDEO_ENCODER_HEIGHT); 3822 double aFrameRate = VIDEO_ENCODER_FRAME_RATE; 3823 3824 LogicalChannelInfo* lcn_info = NULL; 3825 3826 if (aNode->iOutputPort.iPortPair->iDestPort.GetStatus() != EHasPort) 3827 { 3828 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3829 (0, "CPV324m2Way::ConfigureNode waiting for tsc port to determine video codec type.\n")); 3830 return PVMFPending; 3831 } 3832 #ifndef NO_2WAY_324 3833 if (iTerminalType == PV_324M) 3834 { 3835 OsclAny * tempInterface = NULL; 3836 aNode->iOutputPort.iPortPair->iDestPort.GetPort()->QueryInterface( 3837 PVH324MLogicalChannelInfoUuid, tempInterface); 3838 lcn_info = OSCL_STATIC_CAST(LogicalChannelInfo*, tempInterface); 3839 if (lcn_info == NULL) 3840 { 3841 return PVMFFailure; 3842 } 3843 PVMFFormatType aFormatType = lcn_info->GetFormatType(); 3844 3845 if (iTSC324mInterface != NULL) 3846 { 3847 CPvtTerminalCapability* remote_caps = iTSC324mInterface->GetRemoteCapability(); 3848 3849 if (remote_caps) 3850 { 3851 for (uint16 i = 0; i < remote_caps->GetNumCapabilityItems(); i++) 3852 { 3853 CPvtMediaCapability * RemoteCapItem = 3854 remote_caps->GetCapabilityItem(i); 3855 if (RemoteCapItem->GetFormatType() == aFormatType) 3856 { 3857 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3858 (0, "CPV324m2Way::ConfigureNode Found codec match for bitrate - capability(%d), default(%d)", remote_caps->GetCapabilityItem(i)->GetBitrate(), bitrate_bps_100)); 3859 if (RemoteCapItem->GetBitrate() < bitrate_bps_100) 3860 { 3861 bitrate_bps_100 = RemoteCapItem->GetBitrate(); 3862 } 3863 3864 PVMFVideoResolution *video_resolution; 3865 uint32 frame_rate; 3866 video_resolution = ((CPvtVideoCapability*)RemoteCapItem)->GetMaxResolution(frame_rate); 3867 if ((video_resolution->width < aVideoResolution.width) && 3868 (video_resolution->height < aVideoResolution.height)) 3869 { 3870 aVideoResolution.width = video_resolution->width; 3871 aVideoResolution.height = video_resolution->height; 3872 3873 } 3874 3875 if (frame_rate < aFrameRate) 3876 aFrameRate = frame_rate; 3877 3878 break; 3879 } 3880 } 3881 } 3882 } 3883 } 3884 #endif 3885 ptr->SetNumLayers(1); 3886 ptr->SetOutputBitRate(0, bitrate_bps_100*100); 3887 ptr->SetOutputFrameSize(0, aVideoResolution.width, aVideoResolution.height); 3888 ptr->SetOutputFrameRate(0, (float)aFrameRate); 3889 3890 ptr->SetSegmentTargetSize(0, VIDEO_ENCODER_SEGMENT_SIZE); 3891 ptr->SetRateControlType(0, VIDEO_ENCODER_RATE_CONTROL); 3892 ptr->SetDataPartitioning(VIDEO_ENCODER_DATA_PARTITIONING); 3893 ptr->SetRVLC(VIDEO_ENCODER_RVLC); 3894 ptr->SetIFrameInterval(VIDEO_ENCODER_I_FRAME_INTERVAL); 3895 return PVMFSuccess; 3896 3897 } 3898 else if (node == iVideoDecNode.iNode) 3899 { 3900 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3901 (0, "CPV324m2Way::ConfigureNode configuring video dec node\n")); 3902 return PVMFSuccess; 3903 } 3904 #ifndef PV_DISABLE_DEVSOUNDNODES 3905 else if (node == iAudioSrcNode) 3906 { 3907 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3908 (0, "CPV324m2Way::ConfigureNode configuring audio node\n")); 3909 PVMFPortProperty prop; 3910 if (aNode->iOutputPort.iPortPair->iDestPort.GetStatus() != EHasPort) 3911 { 3912 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3913 (0, "CPV324m2Way::ConfigureNode waiting for tsc port to determine audio codec type.\n")); 3914 return PVMFPending; 3915 } 3916 3917 aNode->iOutputPort.iPortPair->iDestPort.GetPort()->Query(prop); 3918 3919 //Set video encoder parameters 3920 if (prop.iFormatType == PVMF_MIME_AMR_IF2) 3921 { 3922 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3923 (0, "CPV324m2Way::ConfigureNode AMR IF2.\n")); 3924 //Can't set audio codec type yet 3925 } 3926 else if (prop.iFormatType == PVMF_MIME_G723) 3927 { 3928 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3929 (0, "CPV324m2Way::ConfigureNode G723.\n")); 3930 //Can't set audio codec type yet 3931 } 3932 3933 uint32 bitrate_bps = MAX_AUDIO_BITRATE; 3934 3935 CPvtTerminalCapability* remote_caps = iTscNode.node->GetRemoteCapability(); 3936 if (remote_caps) 3937 { 3938 for (uint16 i = 0; i < remote_caps->GetNumCapabilityItems(); i++) 3939 { 3940 if ((remote_caps->GetCapabilityItem(i)->GetFormatType() == PVMF_AMR_IF2 || 3941 remote_caps->GetCapabilityItem(i)->GetFormatType() == PVMF_MIME_G723) && 3942 remote_caps->GetCapabilityItem(i)->GetBitrate() < bitrate_bps / 100) 3943 { 3944 bitrate_bps = remote_caps->GetCapabilityItem(i)->GetBitrate() * 100; 3945 } 3946 } 3947 } 3948 3949 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3950 (0, "CPV324m2Way::ConfigureNode audio bitrate %d.\n", bitrate_bps)); 3951 3952 // set max bitrate in devsound 3953 PVDevSoundOptions options; 3954 ((PVDevSoundNodeBase *) iAudioSrcNode)->GetOptions(options); 3955 if (bitrate_bps >= 12200) 3956 { 3957 options.iRecordAmrBitrate = PVMFAmrEncBitrate122; 3958 } 3959 else if (bitrate_bps >= 10200) 3960 { 3961 options.iRecordAmrBitrate = PVMFAmrEncBitrate102; 3962 } 3963 else if (bitrate_bps >= 7950) 3964 { 3965 options.iRecordAmrBitrate = PVMFAmrEncBitrate795; 3966 } 3967 else if (bitrate_bps >= 7400) 3968 { 3969 options.iRecordAmrBitrate = PVMFAmrEncBitrate74; 3970 } 3971 else if (bitrate_bps >= 6700) 3972 { 3973 options.iRecordAmrBitrate = PVMFAmrEncBitrate67; 3974 } 3975 else if (bitrate_bps >= 5900) 3976 { 3977 options.iRecordAmrBitrate = PVMFAmrEncBitrate59; 3978 } 3979 else if (bitrate_bps >= 5150) 3980 { 3981 options.iRecordAmrBitrate = PVMFAmrEncBitrate515; 3982 } 3983 else 3984 { 3985 options.iRecordAmrBitrate = PVMFAmrEncBitrate475; 3986 } 3987 3988 ((PVDevSoundNodeBase *) iAudioSrcNode)->UpdateOptions(options); 3989 3990 return PVMFSuccess; 3991 } 3992 #endif 3993 else if (node == iAudioEncNode.iNode) 3994 { 3995 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 3996 (0, "CPV324m2Way::ConfigureNode configuring audio enc node\n")); 3997 //PVMFPortProperty prop; 3998 #ifdef PV2WAY_USE_OMX 3999 PVAudioEncExtensionInterface *ptr = 4000 (PVAudioEncExtensionInterface *) iAudioEncNodeInterface.iInterface; 4001 #else 4002 PVAMREncExtensionInterface *ptr = 4003 (PVAMREncExtensionInterface *) iAudioEncNodeInterface.iInterface; 4004 #endif // PV2WAY_USE_OMX 4005 if (aNode->iOutputPort.iPortPair->iDestPort.GetStatus() != EHasPort) 4006 { 4007 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 4008 (0, "CPV324m2Way::ConfigureNode waiting for tsc port to determine audio codec type.\n")); 4009 return PVMFPending; 4010 } 4011 4012 //aNode->iOutputPort.iPortPair->iDestPort.GetPort()->Query(prop); 4013 4014 //ptr->SetOutputFormat(PVMF_AMR_IF2); 4015 //ptr->SetInputSamplingRate(KSamplingRate); 4016 //ptr->SetInputBitsPerSample(KBitsPerSample); 4017 //ptr->SetInputNumChannels(KNumChannels); 4018 ptr->SetOutputBitRate(GSM_AMR_12_2); 4019 ptr->SetMaxNumOutputFramesPerBuffer(KNumPCMFrames); 4020 4021 return PVMFSuccess; 4022 4023 } 4024 else if (node == iAudioDecNode.iNode) 4025 { 4026 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 4027 (0, "CPV324m2Way::ConfigureNode configuring audio dec node\n")); 4028 return PVMFSuccess; 4029 } 4030 else if (node == iVideoParserNode.iNode) 4031 { 4032 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 4033 (0, "CPV324m2Way::ConfigureNode configuring video parser node\n")); 4034 return PVMFSuccess; 4035 } 4036 else 4037 { 4038 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4039 (0, "CPV324m2Way::ConfigureNode unknown node\n")); 4040 return PVMFFailure; 4041 } 4042 return PVMFFailure; 4043 } 4044 4045 // Implementations of TSC Observer virtuals 4046 void CPV324m2Way::ConnectComplete(PVMFStatus status) 4047 { 4048 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4049 (0, "CPV324m2Way::ConnectComplete, state %d, status %d\n", iState, status)); 4050 if (status == PVMFSuccess) 4051 { 4052 iIsStackConnected = true; 4053 } 4054 else 4055 { 4056 iIsStackConnected = false; 4057 SetState(EDisconnecting); 4058 } 4059 4060 CheckState(); 4061 } 4062 4063 void CPV324m2Way::InternalError() 4064 { 4065 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4066 (0, "CPV324m2Way::InternalError, state %d\n", iState)); 4067 4068 switch (iState) 4069 { 4070 case EDisconnecting: 4071 iAudioDecDatapath->TSCPortClosed(); 4072 iAudioEncDatapath->TSCPortClosed(); 4073 iVideoDecDatapath->TSCPortClosed(); 4074 iVideoEncDatapath->TSCPortClosed(); 4075 4076 CheckState(); 4077 break; 4078 4079 case EConnecting: 4080 case EConnected: 4081 iAudioDecDatapath->TSCPortClosed(); 4082 iAudioEncDatapath->TSCPortClosed(); 4083 iVideoDecDatapath->TSCPortClosed(); 4084 iVideoEncDatapath->TSCPortClosed(); 4085 4086 InitiateDisconnect(); 4087 break; 4088 4089 default: 4090 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4091 (0, "CPV324m2Way::InternalError invalid state\n")); 4092 break; 4093 } 4094 } 4095 4096 void CPV324m2Way::DisconnectRequestReceived() 4097 { 4098 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4099 (0, "CPV324m2Way::DisconnectRequestReceived state %d\n", iState)); 4100 4101 iIsStackConnected = false; 4102 if (iDisconnectInfo) 4103 { 4104 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 4105 (0, "CPV324m2Way::DisconnectRequestReceived Doing nothing as disconnect is in progress")); 4106 } 4107 else 4108 { 4109 4110 switch (iState) 4111 { 4112 case EDisconnecting: 4113 iAudioDecDatapath->TSCPortClosed(); 4114 iAudioEncDatapath->TSCPortClosed(); 4115 iVideoDecDatapath->TSCPortClosed(); 4116 iVideoEncDatapath->TSCPortClosed(); 4117 4118 CheckState(); 4119 break; 4120 4121 case EConnecting: 4122 case EConnected: 4123 iAudioDecDatapath->TSCPortClosed(); 4124 iAudioEncDatapath->TSCPortClosed(); 4125 iVideoDecDatapath->TSCPortClosed(); 4126 iVideoEncDatapath->TSCPortClosed(); 4127 4128 4129 iRemoteDisconnectTimer->SetObserver(this); 4130 iRemoteDisconnectTimer->Request(REMOTE_DISCONNECT_TIMER_ID, REMOTE_DISCONNECT_TIMER_ID, 4131 REMOTE_DISCONNECT_TIMER_VALUE, this); 4132 4133 4134 //We do InitiateDisconnect() once above timer expires 4135 break; 4136 4137 default: 4138 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4139 (0, "CPV324m2Way::DisconnectRequestReceived invalid state\n")); 4140 break; 4141 } 4142 } 4143 } 4144 4145 PVMFStatus CPV324m2Way::EstablishChannel(TPVDirection aDir, 4146 TPVChannelId aId, 4147 PVCodecType_t aCodec, 4148 uint8* aFormatSpecificInfo, uint32 aFormatSpecificInfoLen) 4149 { 4150 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4151 (0, "CPV324m2Way::EstablishChannel aDir=%d, channel id=%d, codec %d\n", 4152 aDir, aId, aCodec)); 4153 4154 PV2WayMediaType media_type = ::GetMediaType(aCodec); 4155 OSCL_ASSERT(media_type == PV_AUDIO || media_type == PV_VIDEO); 4156 PVMFFormatType aFormatType = PVCodecTypeToPVMFFormatType(aCodec); 4157 PVMFFormatType aAppFormatType = PVMF_MIME_FORMAT_UNKNOWN; 4158 4159 TPV2WayEventInfo* aEvent = NULL; 4160 if (!GetEventInfo(aEvent)) 4161 { 4162 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4163 (0, "CPV324m2Way::EstablishChannel Memory allocation failed!\n")); 4164 return PVMFErrNoMemory; 4165 } 4166 4167 Oscl_Map<PVMFFormatType, FormatCapabilityInfo, OsclMemAllocator, pvmf_format_type_key_compare_class>* codec_list = NULL; 4168 Oscl_Map<PVMFFormatType, PVMFFormatType, OsclMemAllocator, pvmf_format_type_key_compare_class>* app_format_for_engine_format = NULL; 4169 4170 CPV2WayDataChannelDatapath* datapath = NULL; 4171 4172 if (aDir == INCOMING) 4173 { 4174 if (media_type == PV_AUDIO) 4175 { 4176 if (!(iAudioDecDatapath)) 4177 { 4178 iAudioDecDatapath = CPV2WayDecDataChannelDatapath::NewL(iLogger, 4179 aFormatType, this); 4180 4181 } 4182 4183 AddAudioDecoderNode(); 4184 uint32 audioLatency = LookupMioLatency(PVCodecTypeToPVMFFormatType(aCodec), true); 4185 ((TSC_324m*)(iTscNode.iNode))->SetMioLatency((audioLatency + iAudioDatapathLatency), true); 4186 4187 datapath = iAudioDecDatapath; 4188 codec_list = &iIncomingAudioCodecs; 4189 } 4190 else if (media_type == PV_VIDEO) 4191 { 4192 if (!(iVideoDecDatapath)) 4193 { 4194 iVideoDecDatapath = CPV2WayDecDataChannelDatapath::NewL(iLogger, aFormatType, this); 4195 } 4196 iVideoDecDatapath->SetFormatSpecificInfo(aFormatSpecificInfo, (uint16)aFormatSpecificInfoLen); 4197 4198 AddVideoDecoderNode(aFormatSpecificInfo, aFormatSpecificInfoLen); 4199 uint32 videoLatency = LookupMioLatency(PVCodecTypeToPVMFFormatType(aCodec), false); 4200 ((TSC_324m*)(iTscNode.iNode))->SetMioLatency((videoLatency + iVideoDatapathLatency), false); 4201 4202 datapath = iVideoDecDatapath; 4203 codec_list = &iIncomingVideoCodecs; 4204 } 4205 app_format_for_engine_format = &iAppFormatForEngineFormatIncoming; 4206 iClock.Start(); 4207 } 4208 4209 else 4210 { 4211 if (media_type == PV_AUDIO) 4212 { 4213 if (!(iAudioEncDatapath)) 4214 { 4215 iAudioEncDatapath = CPV2WayEncDataChannelDatapath::NewL(iLogger, 4216 aFormatType, this); 4217 } 4218 4219 AddAudioEncoderNode(); 4220 4221 datapath = iAudioEncDatapath; 4222 codec_list = &iOutgoingAudioCodecs; 4223 } 4224 else if (media_type == PV_VIDEO) 4225 { 4226 if (!(iVideoEncDatapath)) 4227 { 4228 iVideoEncDatapath = CPV2WayEncDataChannelDatapath::NewL(iLogger, aFormatType, this); 4229 } 4230 iVideoEncDatapath->SetFormatSpecificInfo(aFormatSpecificInfo, (uint16)aFormatSpecificInfoLen); 4231 4232 AddVideoEncoderNode(); 4233 datapath = iVideoEncDatapath; 4234 codec_list = &iOutgoingVideoCodecs; 4235 } 4236 app_format_for_engine_format = &iAppFormatForEngineFormatOutgoing; 4237 } 4238 Oscl_Map<PVMFFormatType, FormatCapabilityInfo, OsclMemAllocator, pvmf_format_type_key_compare_class>::iterator it = codec_list->find(aFormatType); 4239 4240 if (it == codec_list->end()) 4241 { 4242 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4243 (0, "CPV324m2Way::EstablishChannel Failed to lookup codec=%d\n", aCodec)); 4244 return PVMFFailure; 4245 } 4246 4247 if ((*it).second.iPriority == ENG) 4248 { 4249 // Set the app format to the stored raw format type 4250 aAppFormatType = (*app_format_for_engine_format)[aFormatType]; 4251 } 4252 else 4253 { 4254 // Set the app format to the compressed type 4255 aAppFormatType = aFormatType; 4256 } 4257 datapath->SetFormat(aFormatType); 4258 datapath->SetSourceSinkFormat(aAppFormatType); 4259 4260 // Send the informational event to the app 4261 aEvent->localBuffer[0] = (uint8) media_type; 4262 // bytes 1,2,3 are unused 4263 *((TPVChannelId*)(aEvent->localBuffer + 4)) = aId; 4264 aEvent->localBufferSize = 8; 4265 4266 PVEventType aEventType = (aDir == INCOMING) ? PVT_INDICATION_INCOMING_TRACK : PVT_INDICATION_OUTGOING_TRACK; 4267 PVUuid puuid = PV2WayTrackInfoInterfaceUUID; 4268 PV2WayTrackInfoInterface* pTrackInfo = OSCL_NEW(PV2WayTrackInfoImpl, 4269 (aAppFormatType, aFormatSpecificInfo, aFormatSpecificInfoLen, aEventType, puuid)); 4270 PVAsyncInformationalEvent infoEvent(aEventType, NULL, 4271 OSCL_STATIC_CAST(PVInterface*, pTrackInfo), NULL, 4272 aEvent->localBuffer, aEvent->localBufferSize); 4273 if (iInfoEventObserver != NULL) 4274 { 4275 iInfoEventObserver->HandleInformationalEvent(infoEvent); 4276 } 4277 pTrackInfo->removeRef(); 4278 4279 return EPVT_Success; 4280 } 4281 4282 void CPV324m2Way::OutgoingChannelEstablished(TPVChannelId aId, 4283 PVCodecType_t aCodec, 4284 uint8* aFormatSpecificInfo, 4285 uint32 aFormatSpecificInfoLen) 4286 { 4287 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4288 (0, "CPV324m2Way::OutgoingChannelEstablished id=%d, codec=%d, fsi=%x, fsi_len=%d", 4289 aId, aCodec, aFormatSpecificInfo, aFormatSpecificInfoLen)); 4290 EstablishChannel(OUTGOING, aId, aCodec, aFormatSpecificInfo, aFormatSpecificInfoLen); 4291 } 4292 4293 TPVStatusCode CPV324m2Way::IncomingChannel(TPVChannelId aId, 4294 PVCodecType_t aCodec, 4295 uint8* aFormatSpecificInfo, 4296 uint32 aFormatSpecificInfoLen) 4297 { 4298 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4299 (0, "CPV324m2Way::IncomingChannel channel id=%d, codec %d\n", 4300 aId, aCodec)); 4301 return EstablishChannel(INCOMING, aId, aCodec, aFormatSpecificInfo, aFormatSpecificInfoLen); 4302 } 4303 4304 bool CPV324m2Way::GetEventInfo(TPV2WayEventInfo*& event) 4305 { 4306 int32 error = 0; 4307 OSCL_TRY(error, event = GetEventInfoL()); 4308 OSCL_FIRST_CATCH_ANY(error, 4309 return false); 4310 return true; 4311 } 4312 4313 void CPV324m2Way::ChannelClosed(TPVDirection direction, 4314 TPVChannelId id, 4315 PVCodecType_t codec, 4316 PVMFStatus status) 4317 { 4318 OSCL_UNUSED_ARG(status); 4319 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4320 (0, "CPV324m2Way::ChannelClosed id %d, codec %d, direction %d\n", id, codec, direction)); 4321 PV2WayMediaType media_type = ::GetMediaType(codec); 4322 TPV2WayEventInfo* event = NULL; 4323 bool track_closed = false; 4324 // Send the closing track indication 4325 if (!GetEventInfo(event)) 4326 { 4327 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4328 (0, "CPV324m2Way::ChannelClosed unable to allocate memory")); 4329 return; 4330 } 4331 4332 event->type = PVT_INDICATION_CLOSING_TRACK; 4333 event->localBufferSize = 8; 4334 event->localBuffer[0] = (uint8)direction; 4335 // bytes 1,2,3 are unused 4336 *((TPVChannelId*)(event->localBuffer + 4)) = id; 4337 Dispatch(event); 4338 4339 switch (media_type) 4340 { 4341 case PV_AUDIO: 4342 switch (direction) 4343 { 4344 case INCOMING: 4345 if (iAudioDecDatapath) 4346 { 4347 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4348 (0, "CPV324m2Way::ChannelClosed audio dec path state %d, id %d\n", 4349 iAudioDecDatapath->GetState(), iAudioDecDatapath->GetChannelId())); 4350 if (iAudioDecDatapath->GetChannelId() == CHANNEL_ID_UNKNOWN) 4351 { 4352 track_closed = true; 4353 } 4354 else if (id == iAudioDecDatapath->GetChannelId()) 4355 { 4356 switch (iAudioDecDatapath->GetState()) 4357 { 4358 case EClosing: 4359 break; 4360 case EClosed: 4361 track_closed = true; 4362 break; 4363 default: 4364 iAudioDecDatapath->SetCmd(NULL); 4365 break; 4366 } 4367 } 4368 else 4369 { 4370 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4371 (0, "CPV324m2Way::ChannelClosed ERROR Channel id mismatch id=%d, datapath id=%d\n", 4372 id, iAudioDecDatapath->GetChannelId())); 4373 } 4374 } 4375 break; 4376 4377 case OUTGOING: 4378 if (iAudioEncDatapath) 4379 { 4380 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4381 (0, "CPV324m2Way::ChannelClosed audio enc path state %d, id %d\n", 4382 iAudioEncDatapath->GetState(), iAudioEncDatapath->GetChannelId())); 4383 if (iAudioEncDatapath->GetChannelId() == CHANNEL_ID_UNKNOWN) 4384 { 4385 track_closed = true; 4386 } 4387 else if (id == iAudioEncDatapath->GetChannelId()) 4388 { 4389 switch (iAudioEncDatapath->GetState()) 4390 { 4391 case EClosing: 4392 break; 4393 case EClosed: 4394 track_closed = true; 4395 break; 4396 default: 4397 iAudioEncDatapath->SetCmd(NULL); 4398 break; 4399 } 4400 } 4401 else 4402 { 4403 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4404 (0, "CPV324m2Way::ChannelClosed ERROR Channel id mismatch id=%d, datapath id=%d\n", 4405 id, iAudioEncDatapath->GetChannelId())); 4406 } 4407 } 4408 break; 4409 4410 default: 4411 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4412 (0, "CPV324m2Way::ChannelClosed unknown audio direction %d\n", 4413 direction)); 4414 break; 4415 } 4416 break; 4417 case PV_VIDEO: 4418 switch (direction) 4419 { 4420 case INCOMING: 4421 if (iVideoDecDatapath) 4422 { 4423 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4424 (0, "CPV324m2Way::ChannelClosed video dec path state %d, id %d\n", 4425 iVideoDecDatapath->GetState(), 4426 iVideoDecDatapath->GetChannelId())); 4427 if (iVideoDecDatapath->GetChannelId() == CHANNEL_ID_UNKNOWN) 4428 { 4429 track_closed = true; 4430 } 4431 else if (id == iVideoDecDatapath->GetChannelId()) 4432 { 4433 switch (iVideoDecDatapath->GetState()) 4434 { 4435 case EClosing: 4436 break; 4437 case EClosed: 4438 track_closed = true; 4439 break; 4440 default: 4441 iVideoDecDatapath->SetCmd(NULL); 4442 break; 4443 } 4444 } 4445 else 4446 { 4447 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4448 (0, "CPV324m2Way::ChannelClosed ERROR Channel id mismatch id=%d, datapath id=%d\n", 4449 id, iVideoDecDatapath->GetChannelId())); 4450 } 4451 } 4452 break; 4453 4454 case OUTGOING: 4455 if (iVideoEncDatapath) 4456 { 4457 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4458 (0, "CPV324m2Way::ChannelClosed video enc path state %d, id %d\n", 4459 iVideoEncDatapath->GetState(), 4460 iVideoEncDatapath->GetChannelId())); 4461 if (iVideoEncDatapath->GetChannelId() == CHANNEL_ID_UNKNOWN) 4462 { 4463 track_closed = true; 4464 } 4465 else if (id == iVideoEncDatapath->GetChannelId()) 4466 { 4467 switch (iVideoEncDatapath->GetState()) 4468 { 4469 case EClosing: 4470 break; 4471 case EClosed: 4472 track_closed = true; 4473 break; 4474 default: 4475 iVideoEncDatapath->SetCmd(NULL); 4476 break; 4477 } 4478 } 4479 else 4480 { 4481 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 4482 (0, "CPV324m2Way::ChannelClosed ERROR Channel id mismatch id=%d, datapath id=%d\n", 4483 id, iVideoEncDatapath->GetChannelId())); 4484 } 4485 } 4486 break; 4487 4488 default: 4489 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4490 (0, "CPV324m2Way::ChannelClosed unknown video direction %d\n", 4491 direction)); 4492 break; 4493 } 4494 break; 4495 default: 4496 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4497 (0, "CPV324m2Way::ChannelClosed unknown media type %d\n", 4498 media_type)); 4499 break; 4500 } 4501 4502 if (!track_closed) 4503 return; 4504 4505 if (!GetEventInfo(event)) 4506 { 4507 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4508 (0, "CPV324m2Way::ChannelClosed unable to allocate memory")); 4509 return; 4510 } 4511 event->type = PVT_INDICATION_CLOSE_TRACK; 4512 event->localBufferSize = 8; 4513 event->localBuffer[0] = (uint8)direction; 4514 // bytes 1,2,3 are unused 4515 *((TPVChannelId*)(event->localBuffer + 4)) = id; 4516 Dispatch(event); 4517 } 4518 4519 void CPV324m2Way::RequestFrameUpdate(PVMFPortInterface* aPort) 4520 { 4521 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 4522 (0, "CPV324m2Way::RequestFrameUpdate\n")); 4523 if (iVideoEncDatapath) 4524 { 4525 GenerateIFrame(aPort); 4526 } 4527 } 4528 4529 4530 void CPV324m2Way::TimeoutOccurred(int32 timerID, 4531 int32 timeoutInfo) 4532 { 4533 OSCL_UNUSED_ARG(timeoutInfo); 4534 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 4535 (0, "CPV324m2Way::TimeoutOccurred id %d, info %d\n", timerID, timeoutInfo)); 4536 4537 if (timerID == IFRAME_REQ_TIMERID) 4538 { 4539 isIFrameReqTimerActive = false; 4540 } 4541 else if ((timerID == END_SESSION_TIMER_ID) || (timerID == REMOTE_DISCONNECT_TIMER_ID)) 4542 { 4543 // Cancel out both timers if any one expires, as both do InitiateDisconnect() 4544 if (iEndSessionTimer) 4545 { 4546 iEndSessionTimer->Cancel(END_SESSION_TIMER_ID); 4547 } 4548 4549 if (iRemoteDisconnectTimer) 4550 { 4551 iRemoteDisconnectTimer->Cancel(REMOTE_DISCONNECT_TIMER_ID); 4552 } 4553 4554 InitiateDisconnect(); 4555 } 4556 4557 #if defined(PV_RECORD_TO_FILE_SUPPORT) 4558 if (timerID == RECORDED_FILESIZE_NOTIFICATION_TIMERID) 4559 { 4560 int32 error; 4561 uint32 fileSize; 4562 TPV2WayEventInfo* aEvent = NULL; 4563 PvmfComposerSizeAndDurationInterface *ptr = 4564 (PvmfComposerSizeAndDurationInterface *) iFFSizeAndDuration.iInterface; 4565 4566 if (!GetEventInfo(aEvent)) 4567 { 4568 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4569 (0, "CPV324m2Way::TimeoutOccurred unable to notify app of recorded filesize!\n")); 4570 return; 4571 } 4572 aEvent->type = PVT_INDICATION_RECORDED_FILE_SIZE; 4573 4574 ptr->GetFileSize(fileSize); 4575 *((uint32 *)(aEvent->localBuffer)) = fileSize; 4576 4577 aEvent->localBufferSize = sizeof(uint32); 4578 Dispatch(aEvent); 4579 } 4580 #endif 4581 } 4582 4583 TPV2WayCmdInfo *CPV324m2Way::GetCmdInfoL() 4584 { 4585 if (iFreeCmdInfo.empty()) 4586 { 4587 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4588 (0, "CPV324m2Way::GetFreeCmdInfo unable to allocate cmd info!")); 4589 OSCL_LEAVE(PVMFErrNoMemory); 4590 } 4591 else 4592 { 4593 TPV2WayCmdInfo *cmd = (TPV2WayCmdInfo *)iFreeCmdInfo[0]; 4594 iFreeCmdInfo.erase(iFreeCmdInfo.begin()); 4595 return cmd; 4596 } 4597 4598 return NULL; 4599 } 4600 4601 void CPV324m2Way::FreeCmdInfo(TPV2WayCmdInfo *info) 4602 { 4603 info->Clear(); 4604 iFreeCmdInfo.push_back(info); 4605 } 4606 4607 TPV2WayEventInfo *CPV324m2Way::GetEventInfoL() 4608 { 4609 if (iFreeEventInfo.empty()) 4610 { 4611 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4612 (0, "CPV324m2Way::GetFreeEventInfo unable to allocate event info!")); 4613 OSCL_LEAVE(PVMFErrNoMemory); 4614 } 4615 else 4616 { 4617 TPV2WayEventInfo *cmd = (TPV2WayEventInfo *)iFreeEventInfo[0]; 4618 iFreeEventInfo.erase(iFreeEventInfo.begin()); 4619 return cmd; 4620 } 4621 4622 return NULL; 4623 } 4624 4625 void CPV324m2Way::FreeEventInfo(TPV2WayEventInfo *info) 4626 { 4627 info->Clear(); 4628 iFreeEventInfo.push_back(info); 4629 } 4630 4631 PVMFCommandId CPV324m2Way::SendNodeCmdL(PV2WayNodeCmdType aCmd, 4632 TPV2WayNode *aNode, 4633 CPV2WayNodeCommandObserver *aObserver, 4634 void *aParam, 4635 TPV2WayCmdInfo *a2WayCmdInfo) 4636 { 4637 int32 error = 0; 4638 PVMFCommandId id = 0; 4639 TPV2WayNodeCmdInfo *info; 4640 PVMFNodeInterface * nodeIFace = (PVMFNodeInterface *)aNode->iNode; 4641 PvmfNodesSyncControlInterface* ptr = NULL; 4642 4643 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 4644 (0, "CPV324m2Way::SendNodeCmdL state %d, cmd %d, session %d\n", 4645 iState, aCmd, aNode->iSessionId)); 4646 4647 if (aNode == NULL) 4648 { 4649 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4650 (0, "CPV324m2Way::SendNodeCmdL node ptr is null!\n")); 4651 OSCL_LEAVE(PVMFErrArgument); 4652 } 4653 4654 if (iFreeNodeCmdInfo.empty()) 4655 { 4656 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4657 (0, "CPV324m2Way::SendNodeCmdL unable to allocate node command info!\n")); 4658 OSCL_LEAVE(PVMFErrNoMemory); 4659 } 4660 4661 info = (TPV2WayNodeCmdInfo *)iFreeNodeCmdInfo[0]; 4662 iFreeNodeCmdInfo.erase(iFreeNodeCmdInfo.begin()); 4663 4664 info->type = aCmd; 4665 info->context.iObserver = aObserver; 4666 info->context.iNode = nodeIFace; 4667 info->engineCmdInfo = a2WayCmdInfo; 4668 4669 PVMFSessionId sessionId = aNode->GetSessionId(); 4670 4671 switch (aCmd) 4672 { 4673 case PV2WAY_NODE_CMD_QUERY_UUID: 4674 if (aParam != NULL) 4675 { 4676 TPV2WayNodeQueryUuidParams *queryParam = (TPV2WayNodeQueryUuidParams *) aParam; 4677 OSCL_TRY(error, id = nodeIFace->QueryUUID(sessionId, 4678 queryParam->mimetype, *queryParam->iUuids, 4679 true, (OsclAny *) & info->context)); 4680 } 4681 else 4682 { 4683 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4684 (0, "CPV324m2Way::SendNodeCmdL RequestPort param is null!\n")); 4685 error = PVMFErrArgument; 4686 } 4687 break; 4688 4689 case PV2WAY_NODE_CMD_QUERY_INTERFACE: 4690 if (aParam != NULL) 4691 { 4692 TPV2WayNodeQueryInterfaceParams *queryParam = 4693 (TPV2WayNodeQueryInterfaceParams *) aParam; 4694 OSCL_TRY(error, id = nodeIFace->QueryInterface(sessionId, 4695 *queryParam->iUuid, *queryParam->iInterfacePtr, 4696 (OsclAny *) & info->context)); 4697 } 4698 else 4699 { 4700 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4701 (0, "CPV324m2Way::SendNodeCmdL RequestPort param is null!\n")); 4702 error = PVMFErrArgument; 4703 } 4704 break; 4705 4706 case PV2WAY_NODE_CMD_INIT: 4707 info->context.iContextData = aParam; 4708 OSCL_TRY(error, id = nodeIFace->Init(sessionId, 4709 (OsclAny *) & info->context)); 4710 break; 4711 4712 case PV2WAY_NODE_CMD_REQUESTPORT: 4713 if (aParam != NULL) 4714 { 4715 OSCL_HeapString<OsclMemAllocator> mimeType; 4716 TPV2WayNodeRequestPortParams *params = (TPV2WayNodeRequestPortParams *) aParam; 4717 mimeType = params->format.getMIMEStrPtr(); 4718 //Get mime string from format type 4719 OSCL_TRY(error, id = nodeIFace->RequestPort(sessionId, 4720 params->portTag, &mimeType, (OsclAny *) & info->context)); 4721 } 4722 else 4723 { 4724 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4725 (0, "CPV324m2Way::SendNodeCmdL RequestPort param is null!\n")); 4726 error = PVMFErrArgument; 4727 } 4728 break; 4729 4730 case PV2WAY_NODE_CMD_PREPARE: 4731 OSCL_TRY(error, id = nodeIFace->Prepare(sessionId, 4732 (OsclAny *) & info->context)); 4733 break; 4734 4735 case PV2WAY_NODE_CMD_START: 4736 OSCL_TRY(error, id = nodeIFace->Start(sessionId, 4737 (OsclAny *) & info->context)); 4738 break; 4739 4740 case PV2WAY_NODE_CMD_PAUSE: 4741 OSCL_TRY(error, id = nodeIFace->Pause(sessionId, 4742 (OsclAny *) & info->context)); 4743 break; 4744 4745 case PV2WAY_NODE_CMD_STOP: 4746 OSCL_TRY(error, id = nodeIFace->Stop(sessionId, 4747 (OsclAny *) & info->context)); 4748 break; 4749 4750 case PV2WAY_NODE_CMD_RELEASEPORT: 4751 if (aParam != NULL) 4752 { 4753 OSCL_TRY(error, id = nodeIFace->ReleasePort(sessionId, 4754 *((PVMFPortInterface *) aParam), (OsclAny *) & info->context)); 4755 } 4756 else 4757 { 4758 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4759 (0, "CPV324m2Way::SendNodeCmdL ReleasePort param is null!\n")); 4760 error = PVMFErrArgument; 4761 } 4762 break; 4763 4764 case PV2WAY_NODE_CMD_RESET: 4765 OSCL_TRY(error, id = nodeIFace->Reset(sessionId, 4766 (OsclAny *) & info->context)); 4767 break; 4768 4769 case PV2WAY_NODE_CMD_CANCELCMD: 4770 if (aParam != NULL) 4771 { 4772 OSCL_TRY(error, id = nodeIFace->CancelCommand(sessionId, 4773 *((PVMFCommandId *) aParam), (OsclAny *) & info->context)); 4774 } 4775 else 4776 { 4777 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4778 (0, "CPV324m2Way::SendNodeCmdL CancelCommand param is null!\n")); 4779 error = PVMFErrArgument; 4780 } 4781 4782 //Remove commands on pending list 4783 if (!error) 4784 { 4785 RemovePendingNodeCmd((PVMFNodeInterface *)aNode, 4786 *((PVMFCommandId *) aParam)); 4787 } 4788 break; 4789 4790 case PV2WAY_NODE_CMD_CANCELALL: 4791 OSCL_TRY(error, id = nodeIFace->CancelAllCommands(sessionId, 4792 (OsclAny *) & info->context)); 4793 4794 //Remove commands on pending list 4795 if (!error) 4796 { 4797 RemovePendingNodeCmd((PVMFNodeInterface *)aNode, 0, true); 4798 } 4799 break; 4800 4801 case PV2WAY_NODE_CMD_SKIP_MEDIA_DATA: 4802 { 4803 for (uint32 ii = 0; ii < iSinkNodeList.size(); ii++) 4804 { 4805 if ((aNode == iSinkNodeList[ii].iSinkNode) 4806 && (iSinkNodeList[ii].iNodeInterface.iState == 4807 PV2WayNodeInterface::HasInterface)) 4808 { 4809 ptr = (PvmfNodesSyncControlInterface*) 4810 iSinkNodeList[ii].iNodeInterface.iInterface; 4811 if (ptr != NULL) 4812 { 4813 //Pause the clock, since this gives a chance to register 4814 // the clock observer notifications 4815 iClock.Pause(); 4816 ptr->SetClock(&iClock); 4817 ptr->SetMargins(SYNC_EARLY_MARGIN, SYNC_LATE_MARGIN); 4818 OSCL_TRY(error, id = 4819 ptr->SkipMediaData(aNode->iSessionId, 4820 resume_timestamp, STREAMID, false, 4821 (OsclAny *) & info->context)); 4822 //Re-start the clock, since by now, the sink node and MIO component 4823 // would've registered itself as the clock observer 4824 iClock.Start(); 4825 } 4826 else 4827 { 4828 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4829 (0, "CPV324m2Way::SendNodeCmdL SkipMediaData param is null!\n")); 4830 error = PVMFErrArgument; 4831 } 4832 break; 4833 } 4834 } 4835 } 4836 break; 4837 case PV2WAY_NODE_CMD_INVALID: 4838 default: 4839 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4840 (0, "CPV324m2Way::SendNodeCmdL invalid command!\n")); 4841 OSCL_LEAVE(PVMFErrArgument); 4842 break; 4843 } 4844 4845 if (error) 4846 { 4847 info->Clear(); 4848 iFreeNodeCmdInfo.push_back(info); 4849 OSCL_LEAVE(error); 4850 } 4851 4852 info->id = id; 4853 4854 iPendingNodeCmdInfo.push_back(info); 4855 return id; 4856 } 4857 4858 TPV2WayNodeCmdInfo *CPV324m2Way::FindPendingNodeCmd(PVMFNodeInterface *aNode, 4859 PVMFCommandId aId) 4860 { 4861 for (uint32 i = 0; i < iPendingNodeCmdInfo.size(); i++) 4862 { 4863 if ((iPendingNodeCmdInfo[i]->context.iNode == aNode) && 4864 (iPendingNodeCmdInfo[i]->id == aId)) 4865 { 4866 return iPendingNodeCmdInfo[i]; 4867 } 4868 } 4869 4870 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4871 (0, "CPV324m2Way::FindPendingNodeCmd unable to find command, node %x, id %d!\n", aNode, aId)); 4872 return NULL; 4873 } 4874 4875 void CPV324m2Way::RemovePendingNodeCmd(PVMFNodeInterface *aNode, 4876 PVMFCommandId aId, 4877 bool aAllCmds) 4878 { 4879 TPV2WayNodeCmdInfo **info = NULL; 4880 4881 info = iPendingNodeCmdInfo.begin(); 4882 while (info != iPendingNodeCmdInfo.end()) 4883 { 4884 if (((*info)->context.iNode == aNode) && 4885 (aAllCmds || ((*info)->id == aId))) 4886 { 4887 (*info)->Clear(); 4888 iFreeNodeCmdInfo.push_back(*info); 4889 iPendingNodeCmdInfo.erase(info); 4890 info = iPendingNodeCmdInfo.begin(); 4891 continue; 4892 } 4893 4894 info++; 4895 } 4896 4897 return; 4898 } 4899 4900 4901 void CPV324m2Way::FillSDKInfo(PVSDKInfo &aSDKInfo) 4902 { 4903 //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 4904 // (0, "CPV324m2Way::FillSDKInfo")); 4905 aSDKInfo.iLabel = PV2WAY_ENGINE_SDKINFO_LABEL; 4906 aSDKInfo.iDate = PV2WAY_ENGINE_SDKINFO_DATE; 4907 } 4908 4909 bool CPV324m2Way::CheckMandatoryCodecs(const PVMFFormatType *aMandatoryList, 4910 uint32 aMandatorySize, 4911 Oscl_Vector<PVMFFormatType, OsclMemAllocator> &aCodecList) 4912 { 4913 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 4914 (0, "CPV324m2Way::CheckMandatoryCodecs")); 4915 uint32 i, j; 4916 bool found; 4917 4918 if (aCodecList.empty()) 4919 { 4920 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 4921 (0, "CPV324m2Way::CheckMandatoryCodecs empty codecs list, use default")); 4922 return true; 4923 } 4924 4925 for (i = 0; i < aMandatorySize; i++) 4926 { 4927 found = false; 4928 for (j = 0; j < aCodecList.size(); j++) 4929 { 4930 if (aMandatoryList[i] == aCodecList[j]) 4931 { 4932 found = true; 4933 break; 4934 } 4935 } 4936 4937 if (!found) 4938 { 4939 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 4940 (0, "CPV324m2Way::CheckMandatoryCodecs %s not found!", 4941 (aMandatoryList[i]).getMIMEStrPtr())); 4942 return false; 4943 } 4944 } 4945 4946 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 4947 (0, "CPV324m2Way::CheckMandatoryCodecs all codecs found")); 4948 return true; 4949 } 4950 4951 void CPV324m2Way::InitiateSession(TPV2WayNode& aNode) 4952 { 4953 PVMFNodeInterface * nodeIFace = (PVMFNodeInterface *)aNode ; 4954 PVMFNodeSessionInfo session(this, this, aNode, this, aNode); 4955 aNode.iSessionId = nodeIFace->Connect(session); 4956 nodeIFace->ThreadLogon(); 4957 } 4958 4959 bool CPV324m2Way::IsNodeReset(PVMFNodeInterface& aNode) 4960 { 4961 TPVMFNodeInterfaceState node_state = aNode.GetState(); 4962 4963 if (node_state == EPVMFNodeCreated || node_state == EPVMFNodeIdle) 4964 return true; 4965 return false; 4966 } 4967 4968 4969 void CPV324m2Way::SetPreferredCodecs(TPVDirection aDir, 4970 Oscl_Vector<const char*, OsclMemAllocator>& aAppAudioFormats, 4971 Oscl_Vector<const char*, OsclMemAllocator>& aAppVideoFormats) 4972 { 4973 /* Iterate over formats supported by the stack */ 4974 Oscl_Map<PVMFFormatType, CPvtMediaCapability*, OsclMemAllocator, pvmf_format_type_key_compare_class>::iterator it = iStackSupportedFormats.begin(); 4975 while (it != iStackSupportedFormats.end()) 4976 { 4977 CPvtMediaCapability* media_capability = (*it++).second; 4978 const char* format_str = NULL; 4979 // Is format present in application formats ? 4980 format_str = FindFormatType(media_capability->GetFormatType(), aAppAudioFormats, aAppVideoFormats); 4981 if (format_str) 4982 { 4983 DoSelectFormat(aDir, media_capability->GetFormatType(), format_str, APP); 4984 } 4985 else 4986 { 4987 PV2WayMediaType media_type = ::GetMediaType(PVMFFormatTypeToPVCodecType(media_capability->GetFormatType())); 4988 const char* can_convert_format = NULL; 4989 4990 if (media_type == PV_AUDIO) 4991 { 4992 can_convert_format = CanConvertFormat(aDir, media_capability->GetFormatType(), aAppAudioFormats); 4993 } 4994 else if (media_type == PV_VIDEO) 4995 { 4996 can_convert_format = CanConvertFormat(aDir, media_capability->GetFormatType(), aAppVideoFormats); 4997 } 4998 4999 if (can_convert_format) 5000 { 5001 // Engine can convert the format using a conversion node 5002 DoSelectFormat(aDir, media_capability->GetFormatType(), format_str, ENG, can_convert_format); 5003 } 5004 else 5005 { 5006 // Check if it is a mandatory codec 5007 if (media_capability->IsMandatory()) 5008 { 5009 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5010 (0, "CPV324m2Way::SetPreferredCodecs, ERROR Mandatory codec=%s not supported", 5011 (media_capability->GetFormatType()).getMIMEStrPtr())); 5012 OSCL_LEAVE(PVMFErrResource); 5013 } 5014 } 5015 } 5016 } 5017 } 5018 5019 void CPV324m2Way::SetPreferredCodecs(PV2WayInitInfo& aInitInfo) 5020 { 5021 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5022 (0, "CPV324m2Way::SetPreferredCodecs")); 5023 SetPreferredCodecs(INCOMING, aInitInfo.iIncomingAudioFormats, aInitInfo.iIncomingVideoFormats); 5024 SetPreferredCodecs(OUTGOING, aInitInfo.iOutgoingAudioFormats, aInitInfo.iOutgoingVideoFormats); 5025 } 5026 5027 5028 #if defined(PV_RECORD_TO_FILE_SUPPORT) 5029 void CPV324m2Way::HandleFFComposerNodeCmd(PV2WayNodeCmdType aType, 5030 const PVMFCmdResp& aResponse) 5031 { 5032 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 5033 (0, "CPV324m2Way::HandleFFComposerNodeCmd type %d, status %d\n", 5034 aType, aResponse.GetCmdStatus())); 5035 5036 switch (aType) 5037 { 5038 case PV2WAY_NODE_CMD_QUERY_INTERFACE: 5039 if (aResponse.GetCmdId() == iFFClipConfig.iId) 5040 { 5041 if (aResponse.GetCmdStatus() == PVMFSuccess) 5042 { 5043 iFFClipConfig.iState = PV2WayNodeInterface::HasInterface; 5044 } 5045 else 5046 { 5047 iFFClipConfig.iState = PV2WayNodeInterface::NoInterface; 5048 iRecordFileState = File2WayResetting; 5049 } 5050 } 5051 else if (aResponse.GetCmdId() == iFFTrackConfig.iId) 5052 { 5053 if (aResponse.GetCmdStatus() == PVMFSuccess) 5054 { 5055 iFFTrackConfig.iState = PV2WayNodeInterface::HasInterface; 5056 } 5057 else 5058 { 5059 iFFTrackConfig.iState = PV2WayNodeInterface::NoInterface; 5060 iRecordFileState = File2WayResetting; 5061 } 5062 } 5063 break; 5064 5065 case PV2WAY_NODE_CMD_INIT: 5066 case PV2WAY_NODE_CMD_START: 5067 if (aResponse.GetCmdStatus() != PVMFSuccess) 5068 { 5069 iRecordFileState = File2WayResetting; 5070 } 5071 break; 5072 5073 case PV2WAY_NODE_CMD_STOP: 5074 case PV2WAY_NODE_CMD_RESET: 5075 break; 5076 5077 default: 5078 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5079 (0, "CPV324m2Way::HandleFFComposerNodeCmd unhandled command\n")); 5080 break; 5081 } 5082 5083 CheckRecordFileState(); 5084 return; 5085 } 5086 5087 void CPV324m2Way::RemoveAudioRecPath() 5088 { 5089 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5090 (0, "CPV324m2Way::RemoveAudioRecPath audio rec path state %d\n", 5091 iAudioRecDatapath->GetState())); 5092 if (iAudioRecDatapath->GetState() == EClosed) 5093 { 5094 iAudioRecDatapath->ResetDatapath(); 5095 } 5096 } 5097 5098 void CPV324m2Way::RemoveVideoRecPath() 5099 { 5100 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5101 (0, "CPV324m2Way::RemoveVideoRecPath video rec path state %d\n", 5102 iVideoRecDatapath->GetState())); 5103 if (iVideoRecDatapath->GetState() == EClosed) 5104 { 5105 iVideoRecDatapath->ResetDatapath(); 5106 } 5107 } 5108 5109 void CPV324m2Way::CheckRecordFileState() 5110 { 5111 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5112 (0, "CPV324m2Way::CheckRecordFileState state %d\n", 5113 iRecordFileState)); 5114 5115 switch (iRecordFileState) 5116 { 5117 case File2WayInitializing: 5118 CheckRecordFileInit(); 5119 break; 5120 5121 case File2WayResetting: 5122 CheckRecordFileReset(); 5123 break; 5124 5125 default: 5126 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 5127 (0, "CPV324m2Way::CheckRecordFileState warning: static state!")); 5128 break; 5129 } 5130 } 5131 5132 void CPV324m2Way::CheckRecordFileInit() 5133 { 5134 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5135 (0, "CPV324m2Way::CheckRecordFileInit ff composer node state %d\n", 5136 iFFComposerNode->GetState())); 5137 5138 // int32 error; 5139 return; 5140 } 5141 5142 void CPV324m2Way::CheckRecordFileReset() 5143 { 5144 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5145 (0, "CPV324m2Way::CheckRecordFileReset audio rec state %d, video rec state %d\n", 5146 iAudioRecDatapath->GetState(), iVideoRecDatapath->GetState())); 5147 5148 // int32 error; 5149 return; 5150 } 5151 5152 void CPV324m2Way::InitiateResetRecordFile() 5153 { 5154 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5155 (0, "CPV324m2Way::InitiateResetRecordFile state %d, record state %d\n", 5156 iState, iRecordFileState)); 5157 5158 iRecordFileState = File2WayResetting; 5159 5160 if (iAudioRecDatapath->GetState() != EClosed) 5161 { 5162 iAudioRecDatapath->SetCmd(NULL); 5163 } 5164 5165 if (iVideoRecDatapath->GetState() != EClosed) 5166 { 5167 iVideoRecDatapath->SetCmd(NULL); 5168 } 5169 5170 CheckRecordFileState(); 5171 } 5172 #endif 5173 5174 #if defined(PV_PLAY_FROM_FILE_SUPPORT) 5175 void CPV324m2Way::RemoveAudioPreviewPath() 5176 { 5177 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5178 (0, "CPV324m2Way::RemoveAudioPreviewPath audio preview path state %d\n", 5179 iAudioPreviewDatapath->GetState())); 5180 if (iAudioPreviewDatapath->GetState() == EClosed) 5181 { 5182 iAudioPreviewDatapath->ResetDatapath(); 5183 } 5184 } 5185 5186 void CPV324m2Way::RemoveVideoPreviewPath() 5187 { 5188 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5189 (0, "CPV324m2Way::RemoveVideoPreviewPath video preview path state %d\n", 5190 iVideoPreviewDatapath->GetState())); 5191 if (iVideoPreviewDatapath->GetState() == EClosed) 5192 { 5193 iVideoPreviewDatapath->ResetDatapath(); 5194 } 5195 } 5196 5197 void CPV324m2Way::HandlePFFNodeCmd(PV2WayNodeCmdType aType, 5198 const PVMFCmdResp& aResponse) 5199 { 5200 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 5201 (0, "CPV324m2Way::HandlePFFNodeCmd type %d, status %d\n", 5202 aType, aResponse.GetCmdStatus())); 5203 5204 CPV2WayPort *port; 5205 5206 switch (aType) 5207 { 5208 case PV2WAY_NODE_CMD_INIT: 5209 if (aResponse.GetCmdStatus() != PVMFSuccess) 5210 { 5211 iPlayFileState = File2WayResetting; 5212 } 5213 break; 5214 5215 case PV2WAY_NODE_CMD_REQUESTPORT: 5216 if (aResponse.GetCmdId() == iAudioPlayPort.GetCmdId()) 5217 { 5218 port = &iAudioPlayPort; 5219 } 5220 else if (aResponse.GetCmdId() == iVideoPlayPort.GetCmdId()) 5221 { 5222 port = &iVideoPlayPort; 5223 } 5224 else 5225 { 5226 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5227 (0, "CPV324m2Way::HandlePFFNodeCmd unknown req port id %d\n", 5228 aResponse.GetCmdId())); 5229 iPlayFileState = File2WayResetting; 5230 break; 5231 } 5232 5233 if (aResponse.GetCmdStatus() == PVMFSuccess) 5234 { 5235 port->SetPort((PVMFPortInterface *) aResponse.GetEventData()); 5236 } 5237 else 5238 { 5239 port->SetPort(NULL); 5240 iPlayFileState = File2WayResetting; 5241 } 5242 break; 5243 5244 case PV2WAY_NODE_CMD_START: 5245 case PV2WAY_NODE_CMD_PAUSE: 5246 case PV2WAY_NODE_CMD_STOP: 5247 if (iPlayFileCmdInfo) 5248 { 5249 iPlayFileCmdInfo->status = aResponse.GetCmdStatus(); 5250 Dispatch(iPlayFileCmdInfo); 5251 iPlayFileCmdInfo = NULL; 5252 } 5253 break; 5254 5255 case PV2WAY_NODE_CMD_RESET: 5256 CheckPlayFileState(); 5257 break; 5258 5259 default: 5260 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5261 (0, "CPV324m2Way::HandlePFFNodeCmd unhandled command\n")); 5262 break; 5263 } 5264 5265 CheckPlayFileState(); 5266 return; 5267 } 5268 5269 void CPV324m2Way::CheckPlayFileState() 5270 { 5271 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5272 (0, "CPV324m2Way::CheckPlayFileState state %d\n", 5273 iRecordFileState)); 5274 5275 switch (iPlayFileState) 5276 { 5277 case File2WayInitializing: 5278 CheckPlayFileInit(); 5279 break; 5280 5281 case File2WayResetting: 5282 CheckPlayFileReset(); 5283 break; 5284 5285 default: 5286 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, 5287 (0, "CPV324m2Way::CheckPlayFileState warning: static state!")); 5288 break; 5289 } 5290 } 5291 5292 void CPV324m2Way::CheckPlayFileInit() 5293 { 5294 return; 5295 } 5296 5297 void CPV324m2Way::CheckPlayFileReset() 5298 { 5299 return; 5300 } 5301 5302 void CPV324m2Way::InitiateResetPlayFile() 5303 { 5304 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5305 (0, "CPV324m2Way::InitiateResetPlayFile state %d, record state %d\n", 5306 iState, iPlayFileState)); 5307 5308 //Use play file as data source 5309 if (iAudioEncDatapath->GetState() == EOpened) 5310 { 5311 iAudioEncDatapath->UseFilePlayPort(false); 5312 } 5313 5314 if (iVideoEncDatapath->GetState() == EOpened) 5315 { 5316 iVideoEncDatapath->UseFilePlayPort(false); 5317 } 5318 5319 iUsePlayFileAsSource = false; 5320 5321 iPlayFileState = File2WayResetting; 5322 5323 CheckPlayFileState(); 5324 } 5325 5326 void CPV324m2Way::CheckAudioSourceMixingPort() 5327 { 5328 return; 5329 } 5330 5331 void CPV324m2Way::HandleAudioSrcNodeCmd(PV2WayNodeCmdType aType, 5332 const PVMFCmdResp& aResponse) 5333 { 5334 int32 error; 5335 TPV2WayEventInfo* aEvent = NULL; 5336 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, 5337 (0, "CPV324m2Way::HandleAudioSrcNodeCmd type %d, status %d\n", 5338 aType, aResponse.GetCmdStatus())); 5339 5340 //The only response this handler is expecting is a request for an audio src node input port 5341 5342 switch (aType) 5343 { 5344 case PV2WAY_NODE_CMD_REQUESTPORT: 5345 if (aResponse.GetCmdId() == 5346 iAudioEncDatapath->GetSourceInputPort()->GetCmdId()) 5347 { 5348 if (aResponse.GetCmdStatus() == PVMFSuccess) 5349 { 5350 iAudioEncDatapath->SetSourceInputPort((PVMFPortInterface *) 5351 aResponse.GetEventData()); 5352 iAudioEncDatapath->UseFilePlayPort(iUsePlayFileAsSource); 5353 } 5354 else 5355 { 5356 iAudioEncDatapath->SetSourceInputPort(NULL); 5357 5358 if (!GetEventInfo(aEvent)) 5359 { 5360 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5361 (0, "CPV324m2Way::HandleAudioSrcNodeCmdn unable to allocate event %d!\n", 5362 error)); 5363 return; 5364 } 5365 5366 aEvent->type = PVT_INDICATION_PLAY_ERROR; 5367 aEvent->localBuffer[0] = (uint8) PV_AUDIO; 5368 aEvent->localBufferSize = 1; 5369 Dispatch(aEvent); 5370 } 5371 } 5372 else 5373 { 5374 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5375 (0, "CPV324m2Way::HandleAudioSrcNodeCmd unknown req port id %d\n", 5376 aResponse.GetCmdId())); 5377 } 5378 break; 5379 5380 case PV2WAY_NODE_CMD_RELEASEPORT: 5381 if (aResponse.GetCmdId() == iAudioEncDatapath->GetSourceInputPort()->GetCmdId()) 5382 { 5383 iAudioEncDatapath->SetSourceInputPort(NULL); 5384 } 5385 else 5386 { 5387 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5388 (0, "CPV324m2Way::HandleAudioSrcNodeCmd unknown req port id %d\n", 5389 aResponse.GetCmdId())); 5390 } 5391 break; 5392 5393 default: 5394 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5395 (0, "CPV324m2Way::HandleAudioSrcNodeCmd unhandled command\n")); 5396 break; 5397 } 5398 5399 CheckAudioSourceMixingPort(); 5400 5401 // Audio encode datapath will wait for stable mixing port before continuing to close. 5402 if (iAudioEncDatapath->GetState() == EClosing) 5403 { 5404 iAudioEncDatapath->CheckPath(); 5405 } 5406 5407 return; 5408 } 5409 #endif 5410 5411 bool CPV324m2Way::Supports(PVMFNodeCapability &capability, 5412 PVMFFormatType aFormat, 5413 bool isInput/*=true*/) 5414 { 5415 if (isInput) 5416 { 5417 for (uint16 i = 0; i < capability.iInputFormatCapability.size(); i++) 5418 { 5419 if (capability.iInputFormatCapability[i] == aFormat) 5420 return true; 5421 } 5422 } 5423 else 5424 { 5425 for (uint16 i = 0; i < capability.iOutputFormatCapability.size(); i++) 5426 { 5427 if (capability.iOutputFormatCapability[i] == aFormat) 5428 return true; 5429 } 5430 } 5431 5432 return false; 5433 } 5434 5435 int32 CPV324m2Way::GetStackNodePortTag(TPV2WayPortTagType tagType) 5436 { 5437 switch (tagType) 5438 { 5439 5440 case EPV2WayVideoIn: 5441 if (iTerminalType == PV_324M) 5442 { 5443 return PV_VIDEO; 5444 } 5445 else 5446 { 5447 return -1; 5448 } 5449 break; 5450 5451 case EPV2WayAudioIn: 5452 if (iTerminalType == PV_324M) 5453 { 5454 return PV_AUDIO; 5455 } 5456 else 5457 { 5458 return -1; 5459 } 5460 break; 5461 5462 case EPV2WayVideoOut: 5463 if (iTerminalType == PV_324M) 5464 { 5465 return iVideoDecDatapath->GetTSCPortTag(); 5466 } 5467 else 5468 { 5469 return -1; 5470 } 5471 break; 5472 5473 case EPV2WayAudioOut: 5474 if (iTerminalType == PV_324M) 5475 { 5476 return iAudioDecDatapath->GetTSCPortTag(); 5477 } 5478 else 5479 { 5480 return -1; 5481 } 5482 break; 5483 5484 default: 5485 break; 5486 5487 } 5488 return -1; 5489 } 5490 5491 #ifndef NO_2WAY_324 5492 5493 bool CPV324m2Way::AllChannelsOpened() 5494 { 5495 return ((iIncomingAudioTrackTag != INVALID_TRACK_ID || 5496 !iIncomingAudioCodecs.size()) && 5497 (iIncomingVideoTrackTag != INVALID_TRACK_ID || 5498 !iIncomingVideoCodecs.size()) && 5499 (iOutgoingAudioTrackTag != INVALID_TRACK_ID || 5500 !iOutgoingAudioCodecs.size()) && 5501 (iOutgoingVideoTrackTag != INVALID_TRACK_ID || 5502 !iOutgoingVideoCodecs.size())); 5503 } 5504 5505 #endif //NO_2WAY_324 5506 5507 void CPV324m2Way::ConvertMapToVector(Oscl_Map < PVMFFormatType, 5508 FormatCapabilityInfo, 5509 OsclMemAllocator, 5510 pvmf_format_type_key_compare_class > & aCodecs, 5511 Oscl_Vector < FormatCapabilityInfo, 5512 OsclMemAllocator > & aFormatCapability) 5513 { 5514 iFormatCapability.clear(); 5515 Oscl_Map < PVMFFormatType, FormatCapabilityInfo, OsclMemAllocator, 5516 pvmf_format_type_key_compare_class >::iterator it; 5517 it = aCodecs.begin(); 5518 for (it = aCodecs.begin() ; it != aCodecs.end(); it++) 5519 { 5520 iFormatCapability.push_back(aCodecs[(*it).first]); 5521 } 5522 5523 aFormatCapability = iFormatCapability; 5524 5525 } 5526 5527 5528 void CPV324m2Way::AddVideoEncoderNode() 5529 { 5530 int32 error; 5531 5532 if (iVideoEncNode != NULL) 5533 return; 5534 #ifdef PV2WAY_USE_OMX 5535 iVideoEncNode = TPV2WayNode(CREATE_OMX_ENC_NODE()); 5536 #else 5537 iVideoEncNode = TPV2WayNode(CREATE_VIDEO_ENC_NODE()); 5538 #endif // PV2WAY_USE_OMX 5539 5540 if (iVideoEncNode.iNode == NULL) 5541 OSCL_LEAVE(PVMFErrNoMemory); 5542 InitiateSession(iVideoEncNode); 5543 5544 if (iVideoEncNodeInterface.iState == PV2WayNodeInterface::NoInterface) 5545 { 5546 TPV2WayNodeQueryInterfaceParams queryParam; 5547 queryParam.iInterfacePtr = &iVideoEncNodeInterface.iInterface; 5548 5549 queryParam.iUuid = (PVUuid *) & iVideoEncPVUuid; 5550 5551 OSCL_TRY(error, iVideoEncQueryIntCmdId = SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, 5552 &iVideoEncNode, this, &queryParam)); 5553 OSCL_FIRST_CATCH_ANY(error, 5554 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5555 (0, "CPV324m2Way::CheckInit unable to query for video encoder interface!\n")); 5556 SetState(EResetting); 5557 CheckState(); 5558 return;); 5559 5560 iVideoEncNodeInterface.iState = PV2WayNodeInterface::QueryInterface; 5561 } 5562 5563 5564 } 5565 void CPV324m2Way::AddAudioEncoderNode() 5566 { 5567 int32 error; 5568 5569 if (iAudioEncNode != NULL) 5570 return; 5571 5572 #ifdef PV2WAY_USE_OMX 5573 OSCL_TRY(error, iAudioEncNode = TPV2WayNode(CREATE_OMX_ENC_NODE())); 5574 #else 5575 OSCL_TRY(error, iAudioEncNode = 5576 TPV2WayNode(CREATE_AUDIO_ENC_NODE());); 5577 #endif 5578 OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, 5579 iLogger, PVLOGMSG_ERR, 5580 (0, "CPV324m2Way::InitL unable to allocate audio encoder node\n"))); 5581 5582 InitiateSession(iAudioEncNode); 5583 5584 if (iAudioEncNodeInterface.iState == PV2WayNodeInterface::NoInterface) 5585 { 5586 TPV2WayNodeQueryInterfaceParams queryParam; 5587 queryParam.iInterfacePtr = &iAudioEncNodeInterface.iInterface; 5588 5589 queryParam.iUuid = (PVUuid *) & iAudioEncPVUuid; 5590 5591 OSCL_TRY(error, iAudioEncNodeInterface.iId = 5592 SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, 5593 &iAudioEncNode, this, &queryParam)); 5594 OSCL_FIRST_CATCH_ANY(error, 5595 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, 5596 iLogger, PVLOGMSG_ERR, 5597 (0, "CPV324m2Way::CheckInit unable to query for audio encoder interface!\n")); 5598 SetState(EResetting); 5599 CheckState(); 5600 return;); 5601 5602 iAudioEncNodeInterface.iState = PV2WayNodeInterface::QueryInterface; 5603 } 5604 else if ((iAudioEncNode.iNode)->GetState() == EPVMFNodeError) 5605 { 5606 OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_RESET, &iAudioEncNode, this)); 5607 OSCL_FIRST_CATCH_ANY(error, 5608 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 5609 (0, "CPV324m2Way::CheckInit unable to reset audio encoder node after error!\n")); 5610 return;); 5611 } 5612 5613 5614 // start enc datapaths that are already created 5615 if (iAudioEncDatapath->GetState() != EClosed) 5616 { 5617 iAudioEncDatapath->CheckOpen(); 5618 } 5619 5620 } 5621 void CPV324m2Way::AddVideoDecoderNode(uint8* aFormatSpecificInfo, uint32 aFormatSpecificInfoLen) 5622 { 5623 int32 error = 0; 5624 if (iVideoDecNode != NULL) 5625 return; 5626 5627 #ifdef PV2WAY_USE_OMX 5628 OSCL_TRY(error, iVideoDecNode = TPV2WayNode(CREATE_OMX_VIDEO_DEC_NODE());); 5629 #else 5630 OSCL_TRY(error, iVideoDecNode = TPV2WayNode(CREATE_VIDEO_DEC_NODE());); 5631 #endif // PV2WAY_USE_OMX 5632 5633 5634 OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, 5635 PVLOGMSG_ERR, (0, "CPV324m2Way::InitL unable to allocate video decoder node\n"))); 5636 5637 OSCL_TRY(error, iVideoParserNode = TPV2WayNode(PVMFVideoParserNode::Create(aFormatSpecificInfo, aFormatSpecificInfoLen));); 5638 OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, 5639 PVLOGMSG_ERR, (0, "CPV324m2Way::InitL unable to allocate video parser node\n"))); 5640 5641 InitiateSession(iVideoDecNode); 5642 InitiateSession(iVideoParserNode); 5643 } 5644 5645 void CPV324m2Way::AddAudioDecoderNode() 5646 { 5647 int32 error; 5648 5649 if (iAudioDecNode != NULL) 5650 return; 5651 5652 #ifdef PV2WAY_USE_OMX 5653 OSCL_TRY(error, iAudioDecNode = 5654 TPV2WayNode(CREATE_OMX_AUDIO_DEC_NODE());); 5655 #else 5656 OSCL_TRY(error, iAudioDecNode = 5657 TPV2WayNode(CREATE_AUDIO_DEC_NODE()); 5658 /*iAudioDecNode->SetClock(&iClock);*/); 5659 #endif // PV2WAY_USE_OMX 5660 5661 OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, 5662 PVLOGMSG_ERR, (0, "CPV324m2Way::InitL unable to allocate audio decoder node\n"))); 5663 5664 InitiateSession(iAudioDecNode); 5665 } 5666 5667 void CPV324m2Way::RegisterMioLatency(const char* aMimeStr, 5668 bool aAudio, 5669 PVMFFormatType aFmtType) 5670 { 5671 uint32 latencyVal = 0; 5672 if (aMimeStr != NULL) 5673 { 5674 const char* latencyStr = oscl_strstr(aMimeStr, "latency"); 5675 if (latencyStr != NULL) 5676 { 5677 const char* latVal = oscl_strstr(latencyStr, "="); 5678 if (latVal != NULL) 5679 { 5680 latVal += 1; 5681 PV_atoi(latVal, 'd', latencyVal); 5682 } 5683 } 5684 } 5685 if (aAudio) 5686 { 5687 iAudioLatency[(char*)aFmtType.getMIMEStrPtr()] = latencyVal; 5688 } 5689 else 5690 { 5691 iVideoLatency[(char*)aFmtType.getMIMEStrPtr()] = latencyVal; 5692 } 5693 } 5694 5695 uint32 CPV324m2Way::LookupMioLatency(PVMFFormatType aFmtType, 5696 bool aAudio) 5697 { 5698 Oscl_Map<char*, uint32, OsclMemAllocator>::iterator it; 5699 if (aAudio) 5700 { 5701 it = iAudioLatency.find((char*)(aFmtType.getMIMEStrPtr())); 5702 if (!(it == iAudioLatency.end())) 5703 { 5704 return (((*it).second)); 5705 } 5706 else 5707 { 5708 return 0; //if no latency is specified, then default is 0 5709 } 5710 } 5711 else 5712 { 5713 it = iVideoLatency.find((char*)aFmtType.getMIMEStrPtr()); 5714 if (!(it == iVideoLatency.end())) 5715 { 5716 return (((*it).second)); 5717 } 5718 else 5719 { 5720 return 0; //if no latency is specified, then default is 0 5721 } 5722 } 5723 } 5724 5725 #ifdef MEM_TRACK 5726 void CPV324m2Way::MemStats() 5727 { 5728 #if !(OSCL_BYPASS_MEMMGT) 5729 5730 OsclAuditCB auditCB; 5731 OsclMemInit(auditCB); 5732 if (auditCB.pAudit) 5733 { 5734 MM_Stats_t* stats = auditCB.pAudit->MM_GetStats(""); 5735 if (stats) 5736 { 5737 printf(" numBytes %d\n", stats->numBytes); 5738 printf(" peakNumBytes %d\n", stats->peakNumBytes); 5739 printf(" numAllocs %d\n", stats->numAllocs); 5740 printf(" peakNumAllocs %d\n", stats->peakNumAllocs); 5741 printf(" numAllocFails %d\n", stats->numAllocFails); 5742 printf(" totalNumAllocs %d\n", stats->totalNumAllocs); 5743 printf(" totalNumBytes %d\n", stats->totalNumBytes); 5744 } 5745 5746 } 5747 #endif 5748 } 5749 #endif 5750 5751 /* This should be changed to query the node registry */ 5752 bool CPV324m2Way::IsSupported(const PVMFFormatType& aInputFmtType, const PVMFFormatType& aOutputFmtType) 5753 { 5754 if (aInputFmtType == PVMF_MIME_AMR_IF2) 5755 { 5756 if ((aOutputFmtType == PVMF_MIME_PCM8) || (aOutputFmtType == PVMF_MIME_PCM16)) 5757 { 5758 return true; 5759 } 5760 return false; 5761 } 5762 else if ((aInputFmtType == PVMF_MIME_M4V) || (aInputFmtType == PVMF_MIME_H2632000)) 5763 { 5764 if (aOutputFmtType == PVMF_MIME_YUV420) 5765 { 5766 return true; 5767 } 5768 return false; 5769 } 5770 else if ((aInputFmtType == PVMF_MIME_PCM8) || (aInputFmtType == PVMF_MIME_PCM16)) 5771 { 5772 if (aOutputFmtType == PVMF_MIME_AMR_IF2) 5773 { 5774 return true; 5775 } 5776 return false; 5777 } 5778 else if ((aInputFmtType == PVMF_MIME_YUV420)) 5779 { 5780 if (aOutputFmtType == PVMF_MIME_M4V || aOutputFmtType == PVMF_MIME_H2632000) 5781 { 5782 return true; 5783 } 5784 return false; 5785 } 5786 else 5787 { 5788 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV324m2Way::IsSupported() Not supported format\n")); 5789 return false; 5790 } 5791 } 5792 5793 /* This should be changed to query the formats from the stack */ 5794 void CPV324m2Way::GetStackSupportedFormats() 5795 { 5796 iStackSupportedFormats[PVMF_MIME_AMR_IF2] = OSCL_NEW(CPvtAudioCapability, (PVMF_MIME_AMR_IF2, MAX_AMR_BITRATE)); 5797 iStackSupportedFormats[PVMF_MIME_M4V] = OSCL_NEW(CPvtMpeg4Capability, (MAX_VIDEO_BITRATE)); 5798 iStackSupportedFormats[PVMF_MIME_H2632000] = OSCL_NEW(CPvtH263Capability, (MAX_VIDEO_BITRATE)); 5799 } 5800 5801 const char* CPV324m2Way::FindFormatType(PVMFFormatType aFormatType, 5802 Oscl_Vector<const char*, OsclMemAllocator>& aAudioFormats, 5803 Oscl_Vector<const char*, OsclMemAllocator>& aVideoFormats) 5804 { 5805 PVMFFormatType aThatFormatType = PVMF_MIME_FORMAT_UNKNOWN; 5806 uint32 i = 0; 5807 5808 for (i = 0; i < aAudioFormats.size(); i++) 5809 { 5810 aThatFormatType = aAudioFormats[i]; 5811 if (aFormatType == aThatFormatType) 5812 { 5813 return aAudioFormats[i]; 5814 } 5815 } 5816 5817 for (i = 0; i < aVideoFormats.size(); i++) 5818 { 5819 aThatFormatType = aVideoFormats[i]; 5820 if (aFormatType == aThatFormatType) 5821 { 5822 return aVideoFormats[i]; 5823 } 5824 } 5825 return NULL; 5826 } 5827 5828 const char* CPV324m2Way::CanConvertFormat(TPVDirection aDir, const PVMFFormatType& aThisFmtType, Oscl_Vector<const char*, OsclMemAllocator>& aThatFormatList) 5829 { 5830 PVMFFormatType aInputFmtType = PVMF_MIME_FORMAT_UNKNOWN; 5831 PVMFFormatType aOutputFmtType = PVMF_MIME_FORMAT_UNKNOWN; 5832 5833 OSCL_ASSERT(aDir == INCOMING || aDir == OUTGOING); 5834 5835 for (uint32 i = 0; i < aThatFormatList.size(); i++) 5836 { 5837 PVMFFormatType thatFmtType = aThatFormatList[i]; 5838 aInputFmtType = (aDir == INCOMING) ? aThisFmtType : thatFmtType; 5839 aOutputFmtType = (aDir == INCOMING) ? thatFmtType : aThisFmtType; 5840 if (IsSupported(aInputFmtType, aOutputFmtType)) 5841 { 5842 return aThatFormatList[i]; 5843 } 5844 } 5845 return NULL; 5846 } 5847 5848 void CPV324m2Way::DoSelectFormat(TPVDirection aDir, PVMFFormatType aFormatType, const char* aFormatStr, TPVPriority aPriority, PVMFFormatType aFormatTypeApp) 5849 { 5850 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, 5851 (0, "CPV324m2Way::DoSelectFormat, aDir=%d, aFormatType=%s, aPriority=%d", 5852 aDir, aFormatType.getMIMEStrPtr(), aPriority)); 5853 5854 FormatCapabilityInfo format_cap_info; 5855 PV2WayMediaType media_type = GetMediaType(PVMFFormatTypeToPVCodecType(aFormatType)); 5856 Oscl_Map<PVMFFormatType, FormatCapabilityInfo, OsclMemAllocator, pvmf_format_type_key_compare_class>* the_engine_map = NULL; 5857 Oscl_Map<PVMFFormatType, PVMFFormatType, OsclMemAllocator, pvmf_format_type_key_compare_class>* the_app_map = NULL; 5858 5859 format_cap_info.dir = aDir; 5860 FILL_FORMAT_INFO(aFormatType, format_cap_info); 5861 format_cap_info.iPriority = aPriority; 5862 5863 switch (aDir) 5864 { 5865 case OUTGOING: 5866 the_engine_map = (media_type == PV_AUDIO) ? &iOutgoingAudioCodecs : &iOutgoingVideoCodecs; 5867 the_app_map = &iAppFormatForEngineFormatOutgoing; 5868 break; 5869 case INCOMING: 5870 the_engine_map = (media_type == PV_AUDIO) ? &iIncomingAudioCodecs : &iIncomingVideoCodecs; 5871 the_app_map = &iAppFormatForEngineFormatIncoming; 5872 break; 5873 default: 5874 return; 5875 } 5876 (*the_engine_map)[aFormatType] = format_cap_info; 5877 (*the_app_map)[aFormatType] = aFormatTypeApp; 5878 5879 RegisterMioLatency(aFormatStr, true, aFormatType); 5880 } 5881 5882 // This function returns a priority index for each format type. 5883 #define PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_START 0 5884 #define PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_END 0xFF 5885 uint32 GetPriorityIndexForPVMFFormatType(PVMFFormatType aFormatType) 5886 { 5887 if (aFormatType == PVMF_MIME_AMR_IF2) 5888 return PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_START; 5889 else if (aFormatType == PVMF_MIME_M4V) 5890 return PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_START + 1; 5891 else if (aFormatType == PVMF_MIME_H2632000) 5892 return PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_START + 2; 5893 else 5894 return PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_END; 5895 } 5896