Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #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