| /* ------------------------------------------------------------------ |
| * Copyright (C) 1998-2009 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| #ifndef PV_2WAY_SDKINFO_H_INCLUDED |
| #include "pv_2way_sdkinfo.h" |
| #endif |
| |
| #ifndef PV_2WAY_ENGINE_H_INCLUDED |
| #include "pv_2way_engine.h" |
| #endif |
| |
| #include "pv_2way_dec_data_channel_datapath.h" |
| #include "pv_2way_enc_data_channel_datapath.h" |
| #include "pv_2way_mux_datapath.h" |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| #include "pv_2way_preview_datapath.h" |
| #include "playfromfilenode.h" |
| #endif |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| #include "pv_2way_rec_datapath.h" |
| |
| #include "pvmp4ffcn_factory.h" |
| #include "pvmp4ffcn_trackconfig.h" |
| #include "pvmp4ffcn_clipconfig.h" |
| #include "pvmf_composer_size_and_duration.h" |
| #endif |
| |
| #if (defined(PV_RECORD_TO_FILE_SUPPORT) || defined(PV_PLAY_FROM_FILE_SUPPORT)) |
| #include "pvmf_splitter_node.h" |
| #endif |
| |
| #include "pvmf_videoparser_node.h" |
| |
| #ifdef PV2WAY_USE_OMX |
| #include "OMX_Core.h" |
| #include "pv_omxcore.h" |
| #include "pvmf_omx_videodec_factory.h" |
| #include "pvmf_omx_enc_factory.h" |
| #include "pvmf_omx_audiodec_factory.h" |
| #include "pvmf_audio_encnode_extension.h" |
| #else |
| #include "pvmf_videodec_factory.h" |
| #include "pvmf_videoenc_node_factory.h" |
| #include "pvmfamrencnode_extension.h" |
| #include "pvmf_gsmamrdec_factory.h" |
| #include "pvmf_amrenc_node_factory.h" |
| #endif |
| |
| #include "pvmf_video.h" |
| #include "pvmp4h263encextension.h" |
| |
| #ifndef PV_ENGINE_OBSERVER_H_INCLUDED |
| #include "pv_engine_observer.h" |
| #endif |
| |
| #ifndef PV_DISABLE_VIDRECNODE |
| #include "pvvideoencmdfnode_factory.h" |
| #endif |
| |
| #ifndef PV_DISABLE_DEVSOUNDNODES |
| #include "pvdevsound_node_base.h" |
| #endif |
| |
| #include "pvlogger.h" |
| |
| #include "oscl_dll.h" |
| |
| #ifndef NO_2WAY_324 |
| #include "tsc_h324m_config_interface.h" |
| #endif |
| |
| |
| #include "pvmf_nodes_sync_control.h" |
| |
| #include "pv_2way_track_info_impl.h" |
| |
| #include "pvmi_config_and_capability.h" |
| |
| |
| #ifdef MEM_TRACK |
| #include "oscl_mem.h" |
| #include "oscl_mem_audit.h" |
| #endif |
| |
| // Define entry point for this DLL |
| OSCL_DLL_ENTRY_POINT_DEFAULT() |
| |
| //Record defaults |
| #define DEFAULT_RECORDED_CALL_FILENAME _STRLIT("c:\\recorded_call.mp4") |
| #define DEFAULT_RECORDED_CALL_TIMESCALE 1000 |
| #define DEFAULT_RECORDED_CALL_TYPE PVMP4FFCN_NO_TEMP_FILE_AUTHORING_MODE |
| |
| #define NUM_MANDATORY_2WAY_AUDIO_CODECS 1 |
| #define NUM_MANDATORY_2WAY_VIDEO_CODECS 2 |
| #define PV_VIDEO_FRAME_RATE_NUMERATOR 10 |
| #define PV_VIDEO_FRAME_RATE_DENOMINATOR 1 |
| |
| //Default skipMediaData params |
| const uint32 resume_timestamp = 0; |
| #define STREAMID 0 |
| #define PBPOSITION_CONTINUOUS false |
| //Early and late margins for audio and video frames |
| #define SYNC_EARLY_MARGIN 100 |
| #define SYNC_LATE_MARGIN 100 |
| |
| //Preferred codecs |
| #define VIDEO_CODEC_MPEG4 1 |
| #define VIDEO_CODEC_H263 2 |
| #define AUDIO_CODEC_GSM 3 |
| #define AUDIO_CODEC_G723 4 |
| #define PREFERRED_VIDEO_CODEC VIDEO_CODEC_MPEG4 |
| #define PREFERRED_AUDIO_CODEC AUDIO_CODEC_GSM |
| |
| const uint32 KSamplingRate = 8000; |
| const uint32 KBitsPerSample = 16; |
| const uint32 KNumChannels = 1; |
| const uint32 KNumPCMFrames = 2; // 10 |
| |
| //TEMP -RH |
| #define PV2WAY_UNKNOWN_PORT -1 |
| #define PV2WAY_IN_PORT 0 |
| #define PV2WAY_OUT_PORT 1 |
| #define PV2WAY_IO_PORT 3 |
| |
| #define INVALID_TRACK_ID 255 |
| |
| #define AUDIO_FIRST 1 |
| |
| #ifndef PV_DISABLE_VIDRECNODE |
| #define CREATE_VIDEO_ENC_NODE() PVVideoEncMDFNodeFactory::Create(this,this,this) |
| #define DELETE_VIDEO_ENC_NODE(n) PVVideoEncMDFNodeFactory::Delete(n) |
| #else |
| #ifndef PV2WAY_USE_OMX |
| #define CREATE_VIDEO_ENC_NODE() PVMFVideoEncNodeFactory::CreateVideoEncNode() |
| #define DELETE_VIDEO_ENC_NODE(n) PVMFVideoEncNodeFactory::DeleteVideoEncNode(n) |
| #endif // PV2WAY_USE_OMX |
| #endif |
| |
| #ifndef PV_DISABLE_DEVVIDEOPLAYNODE |
| #define CREATE_VIDEO_DEC_NODE() PVDevVideoPlayNode::Create() |
| #define DELETE_VIDEO_DEC_NODE(n) OSCL_DELETE(n) |
| #else |
| #ifdef PV2WAY_USE_OMX |
| #define CREATE_OMX_VIDEO_DEC_NODE() PVMFOMXVideoDecNodeFactory::CreatePVMFOMXVideoDecNode() |
| #define DELETE_OMX_VIDEO_DEC_NODE(n) PVMFOMXVideoDecNodeFactory::DeletePVMFOMXVideoDecNode(n) |
| #endif // PV2WAY_USE_OMX |
| #define CREATE_VIDEO_DEC_NODE() PVMFVideoDecNodeFactory::CreatePVMFVideoDecNode() |
| #define DELETE_VIDEO_DEC_NODE(n) PVMFVideoDecNodeFactory::DeletePVMFVideoDecNode(n) |
| #endif |
| |
| #ifdef PV2WAY_USE_OMX |
| #define CREATE_OMX_ENC_NODE() PVMFOMXEncNodeFactory::CreatePVMFOMXEncNode() |
| #define DELETE_OMX_ENC_NODE(n) PVMFOMXEncNodeFactory::DeletePVMFOMXEncNode(n); |
| #endif // PV2WAY_USE_OMX |
| |
| #ifndef PV2WAY_USE_OMX |
| #define CREATE_AUDIO_ENC_NODE() PvmfAmrEncNodeFactory::Create() |
| #define DELETE_AUDIO_ENC_NODE(n) PvmfAmrEncNodeFactory::Delete(n) |
| #endif // PV2WAY_USE_OMX |
| |
| |
| #ifdef PV2WAY_USE_OMX |
| #define CREATE_OMX_AUDIO_DEC_NODE() PVMFOMXAudioDecNodeFactory::CreatePVMFOMXAudioDecNode() |
| #define DELETE_OMX_AUDIO_DEC_NODE(n) PVMFOMXAudioDecNodeFactory::DeletePVMFOMXAudioDecNode(n) |
| #else |
| #define CREATE_AUDIO_DEC_NODE() PVMFGSMAMRDecNodeFactory::CreatePVMFGSMAMRDecNode() |
| #define DELETE_AUDIO_DEC_NODE(n) PVMFGSMAMRDecNodeFactory::DeletePVMFGSMAMRDecNode(n) |
| #endif // PV2WAY_USE_OMX |
| |
| |
| |
| #define FILL_FORMAT_INFO(format_type, format_info)\ |
| GetSampleSize(format_type,&format_info.min_sample_size,&format_info.max_sample_size);\ |
| format_info.format = format_type; |
| |
| OSCL_EXPORT_REF CPV324m2Way *CPV324m2Way::NewL(PVMFNodeInterface* aTsc, |
| TPVTerminalType aTerminalType, |
| PVCommandStatusObserver* aCmdStatusObserver, |
| PVInformationalEventObserver *aInfoEventObserver, |
| PVErrorEventObserver *aErrorEventObserver) |
| { |
| CPV324m2Way* aRet = OSCL_NEW(CPV324m2Way, ()); |
| if (aRet) |
| { |
| int32 error = Construct(aRet, aTsc, aTerminalType, aCmdStatusObserver, |
| aInfoEventObserver, aErrorEventObserver); |
| if (error) |
| { |
| OSCL_DELETE(aRet); |
| aRet = NULL; |
| OSCL_LEAVE(error); |
| } |
| } |
| else |
| { |
| OSCL_LEAVE(PVMFErrNoMemory); |
| } |
| |
| return aRet; |
| } |
| |
| int32 CPV324m2Way::Construct(CPV324m2Way* aRet, |
| PVMFNodeInterface* aTsc, |
| TPVTerminalType aTerminalType, |
| PVCommandStatusObserver* aCmdStatusObserver, |
| PVInformationalEventObserver *aInfoEventObserver, |
| PVErrorEventObserver *aErrorEventObserver) |
| { |
| int32 error = 0; |
| OSCL_TRY(error, aRet->ConstructL(aTsc, |
| aTerminalType, |
| aCmdStatusObserver, |
| aInfoEventObserver, |
| aErrorEventObserver)); |
| return error; |
| } |
| |
| OSCL_EXPORT_REF void CPV324m2Way::Delete(CPV324m2Way *aTerminal) |
| { |
| OSCL_DELETE(aTerminal); |
| } |
| |
| CPV324m2Way::CPV324m2Way() : |
| OsclActiveObject(OsclActiveObject::EPriorityNominal, "PV2WayEngine"), |
| iState(EIdle), |
| iLastState(EIdle), |
| iCmdStatusObserver(NULL), |
| iInfoEventObserver(NULL), |
| iErrorEventObserver(NULL), |
| iCommandId(0), |
| iVideoEncDatapath(NULL), |
| iVideoDecDatapath(NULL), |
| iAudioEncDatapath(NULL), |
| iAudioDecDatapath(NULL), |
| iIsStackConnected(false), |
| iMuxDatapath(NULL), |
| iInitInfo(NULL), |
| iConnectInfo(NULL), |
| iDisconnectInfo(NULL), |
| iResetInfo(NULL), |
| iCancelInfo(NULL), |
| iSessionParamsInfo(NULL), |
| iLogger(NULL), |
| iMinIFrameRequestInterval(DEFAULT_MIN_IFRAME_REQ_INT), |
| iIFrameReqTimer("IFrameReqTimer"), |
| iEndSessionTimer(NULL), |
| iRemoteDisconnectTimer(NULL), |
| isIFrameReqTimerActive(false), |
| #ifndef NO_2WAY_324 |
| iIncomingAudioTrackTag(INVALID_TRACK_ID), |
| iIncomingVideoTrackTag(INVALID_TRACK_ID), |
| iOutgoingAudioTrackTag(INVALID_TRACK_ID), |
| iOutgoingVideoTrackTag(INVALID_TRACK_ID), |
| #endif |
| iVideoEncQueryIntCmdId(-1), |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| iRecordFileState(File2WayIdle), |
| iInitRecFileInfo(NULL), |
| iResetRecFileInfo(NULL), |
| iFFComposerNode(NULL), |
| iAudioRecDatapath(NULL), |
| iVideoRecDatapath(NULL), |
| iRecFileSizeNotificationInterval(0), |
| iRecFileSizeNotificationTimer("iRecFileSizeNotificationTimer"), |
| isRecFileSizeNotificationTimerActive(false), |
| #endif |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| iAudioPreviewDatapath(NULL), |
| iVideoPreviewDatapath(NULL), |
| iPlayFileState(File2WayIdle), |
| iUsePlayFileAsSource(false), |
| iInitPlayFileInfo(NULL), |
| iResetPlayFileInfo(NULL), |
| iPlayFileCmdInfo(NULL), |
| iPlayFromFileNode(NULL), |
| #endif |
| iTSCInterface(NULL), |
| iTSC324mInterface(NULL), |
| iPendingTscReset(-1), |
| iPendingAudioEncReset(-1), |
| iPendingVideoEncReset(-1), |
| iAudioDatapathLatency(0), |
| iVideoDatapathLatency(0) |
| { |
| iLogger = PVLogger::GetLoggerObject("2wayEngine"); |
| iSyncControlPVUuid = PvmfNodesSyncControlUuid; |
| iVideoEncPVUuid = PVMp4H263EncExtensionUUID; |
| iCapConfigPVUuid = PVMI_CAPABILITY_AND_CONFIG_PVUUID; |
| |
| #ifdef PV2WAY_USE_OMX |
| iAudioEncPVUuid = PVAudioEncExtensionUUID; |
| #else |
| iAudioEncPVUuid = PVAMREncExtensionUUID; |
| #endif |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| iFFClipConfigPVUuid = KPVMp4FFCNClipConfigUuid; |
| iFFTrackConfigPVUuid = KPVMp4FFCNTrackConfigUuid; |
| iFFSizeAndDurationPVUuid = PvmfComposerSizeAndDurationUuid; |
| #endif |
| iAddDataSourceVideoCmd = NULL; |
| #ifdef PV2WAY_USE_OMX |
| OMX_MasterInit(); |
| #endif // PV2WAY_USE_OMX |
| |
| //creating timers |
| iEndSessionTimer = OSCL_NEW(OsclTimer<OsclMemAllocator>, (END_SESSION_TIMER, END_SESSION_TIMER_FREQUENCY)); |
| iRemoteDisconnectTimer = OSCL_NEW(OsclTimer<OsclMemAllocator>, (REMOTE_DISCONNECT_TIMER, REMOTE_DISCONNECT_TIMER_FREQUENCY)); |
| } |
| |
| CPV324m2Way::~CPV324m2Way() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::~CPV324m2Way\n")); |
| |
| Oscl_Map<PVMFFormatType, CPvtMediaCapability*, OsclMemAllocator, pvmf_format_type_key_compare_class>::iterator it = iStackSupportedFormats.begin(); |
| while (it != iStackSupportedFormats.end()) |
| { |
| CPvtMediaCapability* media_capability = (*it++).second; |
| OSCL_DELETE(media_capability); |
| } |
| iStackSupportedFormats.clear(); |
| |
| Cancel(); |
| iIncomingChannelParams.clear(); |
| iOutgoingChannelParams.clear(); |
| |
| iIncomingAudioCodecs.clear(); |
| iOutgoingAudioCodecs.clear(); |
| iIncomingVideoCodecs.clear(); |
| iOutgoingVideoCodecs.clear(); |
| iFormatCapability.clear(); |
| iClock.Stop(); |
| iSinkNodeList.clear(); |
| ClearVideoEncNode(); |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| if (iVideoPreviewDatapath) |
| { |
| OSCL_DELETE(iVideoPreviewDatapath); |
| iVideoPreviewDatapath = NULL; |
| } |
| |
| if (iAudioPreviewDatapath) |
| { |
| OSCL_DELETE(iAudioPreviewDatapath); |
| iAudioPreviewDatapath = NULL; |
| } |
| #endif |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| if (iVideoRecDatapath) |
| { |
| OSCL_DELETE(iVideoRecDatapath); |
| iVideoRecDatapath = NULL; |
| } |
| |
| if (iAudioRecDatapath) |
| { |
| OSCL_DELETE(iAudioRecDatapath); |
| iAudioRecDatapath = NULL; |
| } |
| #endif |
| |
| if (iVideoEncDatapath) |
| { |
| OSCL_DELETE(iVideoEncDatapath); |
| iVideoEncDatapath = NULL; |
| } |
| |
| if (iVideoDecDatapath) |
| { |
| OSCL_DELETE(iVideoDecDatapath); |
| iVideoDecDatapath = NULL; |
| } |
| |
| if (iAudioEncDatapath) |
| { |
| OSCL_DELETE(iAudioEncDatapath); |
| iAudioEncDatapath = NULL; |
| } |
| |
| if (iAudioDecDatapath) |
| { |
| OSCL_DELETE(iAudioDecDatapath); |
| iAudioDecDatapath = NULL; |
| } |
| |
| if (iMuxDatapath) |
| { |
| OSCL_DELETE(iMuxDatapath); |
| iMuxDatapath = NULL; |
| } |
| |
| PVMFNodeInterface * nodeIFace = (PVMFNodeInterface *)iTscNode; |
| if (nodeIFace) |
| { |
| OSCL_DELETE(nodeIFace); |
| iTscNode.Clear(); |
| } |
| |
| #ifdef PV2WAY_USE_OMX |
| OMX_MasterDeinit(); |
| #endif |
| |
| if (iEndSessionTimer) |
| { |
| iEndSessionTimer->Clear(); |
| OSCL_DELETE(iEndSessionTimer); |
| iEndSessionTimer = NULL; |
| } |
| |
| if (iRemoteDisconnectTimer) |
| { |
| iRemoteDisconnectTimer->Clear(); |
| OSCL_DELETE(iRemoteDisconnectTimer); |
| iRemoteDisconnectTimer = NULL; |
| } |
| |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::~CPV324m2Way - done\n")); |
| } |
| |
| void CPV324m2Way::ClearVideoEncNode() |
| { |
| PVMFNodeInterface * nodeIFace = (PVMFNodeInterface *)iVideoEncNode; |
| if (nodeIFace) |
| { |
| nodeIFace->ThreadLogoff(); |
| if (iVideoEncNodeInterface.iInterface) iVideoEncNodeInterface.iInterface->removeRef(); |
| #ifndef PV_DISABLE_VIDRECNODE |
| PVVideoEncMDFNodeFactory::Delete(nodeIFace); |
| #else |
| |
| #ifdef PV2WAY_USE_OMX |
| DELETE_OMX_ENC_NODE(nodeIFace); |
| #else |
| DELETE_VIDEO_ENC_NODE(nodeIFace); |
| #endif // PV2WAY_USE_OMX |
| #endif // PV_DISABLE_VIDRECNODE |
| iVideoEncNode.Clear() ; |
| iVideoEncNodeInterface.Reset(); |
| } |
| } |
| |
| PVCommandId CPV324m2Way::GetSDKInfo(PVSDKInfo &aSDKInfo, OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::GetSDKInfo\n")); |
| |
| FillSDKInfo(aSDKInfo); |
| |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| cmd->type = PVT_COMMAND_GET_SDK_INFO; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->status = PVMFSuccess; |
| Dispatch(cmd); |
| return iCommandId++; |
| } |
| |
| PVCommandId CPV324m2Way::GetSDKModuleInfo(PVSDKModuleInfo &aSDKModuleInfo, |
| OsclAny* aContextData) |
| { |
| OSCL_UNUSED_ARG(aSDKModuleInfo); |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::GetSDKModuleInfo\n")); |
| |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| cmd->type = PVT_COMMAND_GET_SDK_MODULE_INFO; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->status = PVMFSuccess; |
| Dispatch(cmd); |
| return iCommandId++; |
| } |
| |
| void CPV324m2Way::PreInit() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::PreInit\n")); |
| |
| PVMFNodeSessionInfo sessionInfo; |
| bool allocSuccessful = true; |
| |
| switch (iState) |
| { |
| case EIdle: |
| |
| if (iTerminalType == PV_324M) |
| { |
| #ifndef NO_2WAY_324 |
| iTscNode = TPV2WayNode(new TSC_324m(PV_LOOPBACK_MUX)); |
| iTSC324mInterface = (TSC_324m *)iTscNode.iNode; |
| iTSCInterface = (TSC *)iTSC324mInterface; |
| // Create the list of stack supported formats |
| GetStackSupportedFormats(); |
| #endif |
| } |
| |
| if (((PVMFNodeInterface *)iTscNode) == NULL) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::PreInit unable to allocate tsc node\n")); |
| allocSuccessful = false; |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::PreInit created TSC Node(%x)", (PVMFNodeInterface *)iTscNode)); |
| |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::Init Error - invalid state\n")); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| } |
| } |
| |
| PVCommandId CPV324m2Way::Init(PV2WayInitInfo& aInitInfo, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::InitL\n")); |
| |
| PVMFNodeSessionInfo sessionInfo; |
| |
| bool allocSuccessful = true; |
| |
| switch (iState) |
| { |
| case EIdle: |
| { |
| if (iInitInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::PreInit cmd already sent out")); |
| OSCL_LEAVE(PVMFErrBusy); |
| } |
| |
| ((TSC_324m*)(iTscNode.iNode))->SetTscObserver(this); |
| InitiateSession(iTscNode); |
| |
| ((TSC_324m*)(iTscNode.iNode))->SetMultiplexingDelayMs(0); |
| ((TSC_324m*)(iTscNode.iNode))->SetClock(&iClock); |
| |
| SetPreferredCodecs(aInitInfo); |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| OSCL_TRY(error, iVideoDecSplitterNode = |
| TPV2WayNode(PVMFSplitterNode::Create());); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::PreInit unable to allocate video splitter node\n")); |
| allocSuccessful = false;); |
| |
| OSCL_TRY(error, iFFComposerNode = |
| TPV2WayNode(PVMp4FFComposerNodeFactory::CreateMp4FFComposer(this, this, this));; |
| iFFComposerNode->SetClock(&iClock);); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::PreInit unable to allocate ff composer node\n")); |
| allocSuccessful = false;); |
| #endif |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| OSCL_TRY(error, iAudioSrcSplitterNode = |
| TPV2WayNode(PVMFSplitterNode::Create());); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::PreInit unable to allocate audio src splitter node\n")); |
| allocSuccessful = false;); |
| |
| OSCL_TRY(error, iVideoSrcSplitterNode = |
| TPV2WayNode(PVMFSplitterNode::Create());); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::PreInit unable to allocate video src splitter node\n")); |
| allocSuccessful = false;); |
| |
| |
| OSCL_TRY(error, iPlayFromFileNode = |
| TPV2WayNode(PlayFromFileNode::NewL()); |
| iPlayFromFileNode->SetClock(&iClock);); |
| if (iPlayFromFileNode == NULL) error = PVMFErrNoMemory; |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::PreInit unable to allocate playfromfile node\n")); |
| allocSuccessful = false;); |
| #endif |
| |
| if (!allocSuccessful) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::Init allocation failed\n")); |
| } |
| else |
| { |
| |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| InitiateSession(iVideoDecSplitterNode); |
| InitiateSession(iFFComposerNode); |
| #endif |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| InitiateSession(iAudioSrcSplitterNode); |
| InitiateSession(iVideoSrcSplitterNode); |
| InitiateSession(iPlayFromFileNode); |
| #endif |
| //Set incoming channel capabilities. |
| // TBD: Incoming capabilities need to be queried from the registry and passed to the stack |
| H324ChannelParameters inAudioChannelParams(INCOMING, PVMF_MIME_AMR_IF2, MAX_AUDIO_BITRATE); |
| H324ChannelParameters inVideoChannelParams(INCOMING, PVMF_MIME_H2632000, MAX_VIDEO_BITRATE); |
| H324ChannelParameters inDtmfParams(INCOMING, PVMF_MIME_USERINPUT_BASIC_STRING, 0); |
| |
| ConvertMapToVector(iIncomingAudioCodecs, iFormatCapability); |
| inAudioChannelParams.SetCodecs(iFormatCapability); |
| |
| ConvertMapToVector(iIncomingVideoCodecs, iFormatCapability); |
| inVideoChannelParams.SetCodecs(iFormatCapability); |
| inDtmfParams.SetCodecs(iIncomingUserInputFormats); |
| iIncomingChannelParams.push_back(inAudioChannelParams); |
| iIncomingChannelParams.push_back(inVideoChannelParams); |
| iIncomingChannelParams.push_back(inDtmfParams); |
| |
| //Set outgoing channel capabilities. |
| H324ChannelParameters outAudioChannelParams(OUTGOING, |
| PVMF_MIME_AMR_IF2, MAX_AUDIO_BITRATE); |
| ConvertMapToVector(iOutgoingAudioCodecs, iFormatCapability); |
| outAudioChannelParams.SetCodecs(iFormatCapability); |
| iOutgoingChannelParams.push_back(outAudioChannelParams); |
| |
| H324ChannelParameters outVideoChannelParams(OUTGOING, |
| PVMF_MIME_H2632000, MAX_VIDEO_BITRATE); |
| |
| ConvertMapToVector(iOutgoingVideoCodecs, iFormatCapability); |
| outVideoChannelParams.SetCodecs(iFormatCapability); |
| iOutgoingChannelParams.push_back(outVideoChannelParams); |
| } |
| |
| iInitInfo = GetCmdInfoL(); |
| iInitInfo->type = PVT_COMMAND_INIT; |
| iInitInfo->contextData = aContextData; |
| iInitInfo->id = iCommandId; |
| |
| SetState(EInitializing); |
| |
| CheckState(); |
| #ifdef MEM_TRACK |
| printf("\nMemStats at Engine Init\n"); |
| MemStats(); |
| #endif |
| break; |
| } |
| |
| case ESetup: |
| iInitInfo = GetCmdInfoL(); |
| iInitInfo->type = PVT_COMMAND_INIT; |
| iInitInfo->id = iCommandId; |
| iInitInfo->contextData = aContextData; |
| iInitInfo->status = PVMFSuccess; |
| Dispatch(iInitInfo); |
| iInitInfo = NULL; |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::Init Error - invalid state\n")); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| } |
| |
| return iCommandId++; |
| } |
| |
| |
| PVCommandId CPV324m2Way::Reset(OsclAny* aContextData) |
| { |
| uint32 ii = 0; |
| //checking if any sources or sinks still added. |
| for (ii = 0; ii < iSinkNodes.size(); ii++) |
| { |
| if (iSinkNodes[ii]) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ResetL SinkNodes not removed before Reset")); |
| OSCL_LEAVE(PVMFFailure); |
| } |
| } |
| |
| for (ii = 0; ii < iSourceNodes.size(); ii++) |
| { |
| if (iSourceNodes[ii]) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ResetL SourceNodes not removed before Reset")); |
| OSCL_LEAVE(PVMFFailure); |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::ResetL %d\n", iState)); |
| |
| if (iResetInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ResetL cmd already sent out\n")); |
| OSCL_LEAVE(PVMFErrBusy); |
| } |
| |
| switch (iState) |
| { |
| case EIdle: |
| iResetInfo = GetCmdInfoL(); |
| iResetInfo->type = PVT_COMMAND_RESET; |
| iResetInfo->id = iCommandId; |
| iResetInfo->contextData = aContextData; |
| iResetInfo->status = PVMFSuccess; |
| Dispatch(iResetInfo); |
| iResetInfo = NULL; |
| break; |
| |
| case EInitializing: |
| //Notify application that init command has been cancelled. |
| iInitInfo->status = PVMFErrCancelled; |
| Dispatch(iInitInfo); |
| iInitInfo = NULL; |
| //Fall through to next case. |
| |
| case ESetup: |
| iResetInfo = GetCmdInfoL(); |
| iResetInfo->type = PVT_COMMAND_RESET; |
| iResetInfo->contextData = aContextData; |
| iResetInfo->id = iCommandId; |
| |
| InitiateReset(); |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ResetL - invalid state %d\n", iState)); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| } |
| #ifdef MEM_TRACK |
| printf("\nMemStats After Engine Reset\n"); |
| MemStats(); |
| #endif |
| return iCommandId++; |
| } |
| |
| PVCommandId CPV324m2Way::AddDataSource(PVTrackId aChannelId, |
| PVMFNodeInterface& aDataSource, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::AddDataSourceL aChannelId=%d, (%x, %x, %x)", |
| aChannelId, &aDataSource, 0, aContextData)); |
| if (!((TSC_324m *)(PVMFNodeInterface *)iTscNode.iNode)->IsEstablishedLogicalChannel(OUTGOING, |
| aChannelId)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::AddDataSourceL Not an established logical channel in the stack")); |
| OSCL_LEAVE(PVMFErrArgument); |
| } |
| TPV2WayNode* srcNode; |
| PVMFNodeInterface *node = &aDataSource; |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| switch (iState) |
| { |
| case EIdle: |
| case EInitializing: |
| case EResetting: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::AddDataSourceL - invalid state(%d)", iState)); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| default: |
| //State check okay. |
| break; |
| } |
| |
| //As of v4, we'll need to initialize the node first before |
| //querying its capabilities |
| |
| // Add the Data Source to the list of source nodes. |
| srcNode = OSCL_NEW(TPV2WayNode, (node)); |
| InitiateSession(*srcNode); |
| iSourceNodes.push_back(srcNode); |
| |
| cmd = GetCmdInfoL(); |
| cmd->type = PVT_COMMAND_ADD_DATA_SOURCE; |
| cmd->status = PVMFSuccess; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->iPvtCmdData = aChannelId; |
| |
| SendNodeCmdL(PV2WAY_NODE_CMD_INIT, srcNode, this, cmd); |
| return iCommandId++; |
| } |
| |
| void CPV324m2Way::DoAddDataSource(TPV2WayNode& aNode, |
| const PVMFCmdResp& aResponse) |
| { |
| TPV2WayNode* srcNode = &aNode; |
| PVMFNodeInterface *node = srcNode->iNode; |
| PVMFNodeCapability capability; |
| CPVDatapathNode datapathnode; |
| CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext(); |
| TPV2WayCmdInfo *cmd = (TPV2WayCmdInfo *)data->iContextData; |
| |
| cmd->status = aResponse.GetCmdStatus(); |
| |
| if (node->GetCapability(capability) != PVMFSuccess || !capability.iOutputFormatCapability.size()) |
| { |
| OSCL_DELETE(srcNode); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::AddDataSourceL - unable to get capability")); |
| OSCL_LEAVE(PVMFFailure); |
| } |
| |
| CPV2WayEncDataChannelDatapath* datapath = NULL; |
| PVMFFormatType media_type = capability.iOutputFormatCapability[0]; |
| if (media_type.isAudio()) |
| { |
| datapath = iAudioEncDatapath; |
| } |
| else if (media_type.isVideo()) |
| { |
| datapath = iVideoEncDatapath; |
| } |
| else |
| { |
| OSCL_LEAVE(PVMFErrArgument); |
| } |
| |
| bool formatSupported = false; |
| for (uint i = 0; i < capability.iOutputFormatCapability.size(); i++) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "CPV324m2Way::AddDataSourceL - format %s\n", (capability.iOutputFormatCapability[i]).getMIMEStrPtr())); |
| if (datapath->GetSourceSinkFormat() == capability.iOutputFormatCapability[i]) |
| { |
| formatSupported = true; |
| break; |
| } |
| } |
| if (!formatSupported) |
| { |
| OSCL_LEAVE(PVMFErrNotSupported); |
| } |
| |
| if (datapath->GetSourceSinkFormat() == PVMF_MIME_YUV420) |
| { |
| // video media type |
| if (datapath->GetState() == EClosed) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::AddDataSource - creating video datapath, channel id =%d\n", |
| cmd->iPvtCmdData)); |
| datapath->SetChannelId(cmd->iPvtCmdData); |
| |
| //Add source node to datapath |
| datapathnode.iNode = *srcNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iLoggoffOnReset = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| //Add video src splitter node to datapath |
| datapathnode.iNode = iVideoSrcSplitterNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EUserDefined; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_YUV420; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iCanCancelPort = false; |
| datapathnode.iOutputPort.iPortSetType = EUserDefined; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_YUV420; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| #endif |
| //Add video enc node to datapath |
| datapathnode.iNode = iVideoEncNode; |
| datapathnode.iConfigure = this; |
| datapathnode.iConfigTime = EConfigBeforeInit; |
| datapathnode.iCanNodePause = true; |
| datapathnode.iLoggoffOnReset = false; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EUserDefined; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_YUV420; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| |
| //Add tsc node to datapath |
| datapathnode.iNode = iTscNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iLoggoffOnReset = false; |
| datapathnode.iIgnoreNodeState = true; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeStarted; |
| datapathnode.iInputPort.iCanCancelPort = true; |
| datapathnode.iInputPort.iPortSetType = EAppDefined; |
| datapathnode.iInputPort.iFormatType = datapath->GetFormat(); |
| datapathnode.iInputPort.iPortTag = cmd->iPvtCmdData; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; |
| datapath->AddNode(datapathnode); |
| |
| // Check if FSI exists and Extension Interface is queried |
| uint32 fsi_len = 0; |
| if (datapath->GetFormatSpecificInfo(&fsi_len) && |
| iVideoEncNodeInterface.iState == PV2WayNodeInterface::NoInterface) |
| { |
| iAddDataSourceVideoCmd = cmd; |
| } |
| else |
| { |
| datapath->SetCmd(cmd); |
| } |
| } |
| else |
| { |
| OSCL_LEAVE(PVMFErrInvalidState); |
| } |
| } |
| |
| else if ((datapath->GetSourceSinkFormat() == PVMF_MIME_H2632000) || (datapath->GetSourceSinkFormat() == PVMF_MIME_H2631998) || (datapath->GetSourceSinkFormat() == PVMF_MIME_M4V)) |
| { |
| // video media type |
| if (datapath->GetState() == EClosed) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::AddDataSource - creating video datapath, channel id=%d", |
| cmd->iPvtCmdData)); |
| datapath->SetChannelId(cmd->iPvtCmdData); |
| //Add source node to datapath |
| datapathnode.iNode = *srcNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iLoggoffOnReset = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| |
| datapath->AddNode(datapathnode); |
| //Add tsc node to datapath |
| datapathnode.iNode = iTscNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iLoggoffOnReset = false; |
| datapathnode.iIgnoreNodeState = true; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeStarted; |
| datapathnode.iInputPort.iCanCancelPort = true; |
| datapathnode.iInputPort.iPortSetType = EAppDefined; |
| datapathnode.iInputPort.iFormatType = datapath->GetFormat(); |
| datapathnode.iInputPort.iPortTag = cmd->iPvtCmdData; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; |
| datapath->AddNode(datapathnode); |
| |
| datapath->SetCmd(cmd); |
| } |
| else |
| { |
| OSCL_LEAVE(PVMFErrInvalidState); |
| } |
| } |
| |
| else if ((datapath->GetSourceSinkFormat() == PVMF_MIME_AMR_IF2) || (datapath->GetSourceSinkFormat() == PVMF_MIME_AMR_IETF) || (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16)) |
| { |
| if (datapath->GetState() == EClosed) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::AddDataSourceL - creating audio datapath\n")); |
| datapath->SetChannelId(cmd->iPvtCmdData); |
| |
| //Add source node to datapath |
| datapathnode.iNode = *srcNode; |
| |
| #ifndef PV_DISABLE_DEVSOUNDNODES |
| datapathnode.iConfigure = this; |
| datapathnode.iConfigTime = EConfigBeforeInit; |
| #else |
| datapathnode.iConfigure = NULL; |
| #endif |
| datapathnode.iCanNodePause = true; |
| datapathnode.iLoggoffOnReset = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| //Add audio src splitter node to datapath |
| datapathnode.iNode = iAudioSrcSplitterNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EUseOtherNodePortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iCanCancelPort = false; |
| datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| #endif |
| |
| if (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16) |
| { |
| //Add audio enc node to datapath |
| datapathnode.iNode = iAudioEncNode; |
| datapathnode.iConfigure = this; |
| datapathnode.iConfigTime = EConfigBeforeInit; |
| datapathnode.iCanNodePause = true; |
| datapathnode.iLoggoffOnReset = false; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EUserDefined; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_PCM16; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| } |
| |
| //Add tsc node to datapath |
| datapathnode.iNode = iTscNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iLoggoffOnReset = false; |
| datapathnode.iIgnoreNodeState = true; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeStarted; |
| datapathnode.iInputPort.iCanCancelPort = true; |
| datapathnode.iInputPort.iPortSetType = EAppDefined; |
| datapathnode.iInputPort.iPortTag = cmd->iPvtCmdData; |
| datapathnode.iInputPort.iFormatType = datapath->GetFormat(); |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; |
| datapath->AddNode(datapathnode); |
| |
| datapath->SetCmd(cmd); |
| } |
| else |
| { |
| OSCL_LEAVE(PVMFErrInvalidState); |
| } |
| } |
| |
| return; |
| } |
| |
| PVCommandId CPV324m2Way::DoRemoveDataSourceSink(PVMFNodeInterface& aEndPt, |
| OsclAny* aContextData) |
| { |
| CPV2WayDataChannelDatapath *datapath = NULL; |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| if ((iVideoEncDatapath) && iVideoEncDatapath->IsNodeInDatapath(&aEndPt)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::RemoveDataSource remove video source, state %d\n", |
| iVideoEncDatapath->GetState())); |
| datapath = iVideoEncDatapath; |
| cmd->type = PVT_COMMAND_REMOVE_DATA_SOURCE; |
| } |
| else if ((iAudioEncDatapath) && iAudioEncDatapath->IsNodeInDatapath(&aEndPt)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::RemoveDataSource remove audio source, state %d\n", |
| iAudioEncDatapath->GetState())); |
| datapath = iAudioEncDatapath; |
| cmd->type = PVT_COMMAND_REMOVE_DATA_SOURCE; |
| } |
| else if ((iVideoDecDatapath) && iVideoDecDatapath->IsNodeInDatapath(&aEndPt)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::RemoveDataSink remove video sink, state %d\n", |
| iVideoDecDatapath->GetState())); |
| datapath = iVideoDecDatapath; |
| cmd->type = PVT_COMMAND_REMOVE_DATA_SINK; |
| } |
| else if ((iAudioDecDatapath) && iAudioDecDatapath->IsNodeInDatapath(&aEndPt)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::RemoveDataSink remove audio sink, state %d\n", |
| iAudioDecDatapath->GetState())); |
| datapath = iAudioDecDatapath; |
| cmd->type = PVT_COMMAND_REMOVE_DATA_SINK; |
| } |
| else |
| { |
| // Just remove the node from sink and source nodes list if still in the list |
| |
| TPV2WayNode* node = 0; |
| |
| node = RemoveTPV2WayNode(iSinkNodes, &aEndPt); |
| |
| if (!node) |
| { |
| // Not there in sink node list . Check in source nodes |
| node = RemoveTPV2WayNode(iSourceNodes, &aEndPt); |
| } |
| |
| if (node) |
| { |
| //Successfully found and removed the node from sink or source nodes ,so delete it. |
| OSCL_DELETE(node); |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::RemoveDataSinkSource unknown sink!\n")); |
| OSCL_LEAVE(PVMFErrArgument); |
| } |
| |
| switch (datapath->GetState()) |
| { |
| case EClosing: |
| //Close command already in progress |
| if (datapath->GetCmdInfo()) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::RemoveDataSourceL cmd already sent out")); |
| OSCL_LEAVE(PVMFErrBusy); |
| } |
| //Already closing because of error or remote close |
| else |
| { |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| datapath->SetCmd(cmd); |
| } |
| break; |
| |
| case EOpened: |
| case EOpening: |
| case EPaused: |
| case EPausing: |
| case EUnpausing: |
| { |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| datapath->SetCmd(cmd); |
| } |
| break; |
| case EClosed: |
| // Remove the node if exists in sink or source even data path is closed |
| break; |
| |
| default: |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::RemoveDataSourceL - invalid path state\n")); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| } |
| |
| TPV2WayNode* node = 0; |
| |
| if (cmd->type == PVT_COMMAND_REMOVE_DATA_SINK) |
| { |
| node = RemoveTPV2WayNode(iSinkNodes, &aEndPt); |
| } |
| else if (cmd->type == PVT_COMMAND_REMOVE_DATA_SOURCE) |
| { |
| node = RemoveTPV2WayNode(iSourceNodes, &aEndPt); |
| } |
| OSCL_DELETE(node); |
| return iCommandId++; |
| } |
| |
| PVCommandId CPV324m2Way::RemoveDataSource(PVMFNodeInterface& aDataSource, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveDataSourceL(%x, %x, %x)", |
| &aDataSource, 0, aContextData)); |
| |
| switch (iState) |
| { |
| case EIdle: |
| case EInitializing: |
| case EResetting: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::RemoveDataSourceL - invalid state(%d)", |
| iState)); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| |
| default: |
| //State check okay. |
| break; |
| } |
| return DoRemoveDataSourceSink(aDataSource, aContextData); |
| } |
| |
| |
| PVCommandId CPV324m2Way::AddDataSink(PVTrackId aChannelId, |
| PVMFNodeInterface& aDataSink, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::AddDataSinkL(%x, %d, %x)", &aDataSink, 0, |
| aContextData)); |
| TPV2WayNode* sinkNode; |
| CPVDatapathNode datapathnode; |
| TPV2WayCmdInfo *cmd = 0; |
| |
| switch (iState) |
| { |
| case EIdle: |
| case EInitializing: |
| case EResetting: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::AddDataSinkL - invalid state(%d)", |
| iState)); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| |
| default: |
| //State check okay. |
| break; |
| } |
| |
| //As of v4, we'll need to initialize the node first before |
| //querying its capabilities. |
| |
| sinkNode = OSCL_NEW(TPV2WayNode, (&aDataSink)); |
| InitiateSession(*sinkNode); |
| iSinkNodes.push_back(sinkNode); |
| SupportedSinkNodeInterfaces(sinkNode); |
| cmd = GetCmdInfoL(); |
| cmd->type = PVT_COMMAND_ADD_DATA_SINK; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->iPvtCmdData = aChannelId; |
| SendNodeCmdL(PV2WAY_NODE_CMD_INIT, sinkNode, this, cmd); |
| return iCommandId++; |
| } |
| |
| void CPV324m2Way::DoAddDataSink(TPV2WayNode& aNode, |
| const PVMFCmdResp& aResponse) |
| { |
| TPV2WayNode* sinkNode = &aNode; |
| PVMFNodeCapability capability; |
| PVMFNodeInterface *node = sinkNode->iNode; |
| CPVDatapathNode datapathnode; |
| CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext(); |
| TPV2WayCmdInfo *cmd = (TPV2WayCmdInfo *)data->iContextData; |
| cmd->status = aResponse.GetCmdStatus(); |
| |
| if (node->GetCapability(capability) != PVMFSuccess) |
| { |
| OSCL_DELETE(sinkNode); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::AddDataSinkL - unable to get capability\n")); |
| OSCL_LEAVE(PVMFFailure); |
| } |
| |
| CPV2WayDecDataChannelDatapath* datapath = NULL; |
| PVMFFormatType media_type = capability.iInputFormatCapability[0]; |
| if (media_type.isAudio()) |
| { |
| datapath = iAudioDecDatapath; |
| } |
| else if (media_type.isVideo()) |
| { |
| datapath = iVideoDecDatapath; |
| } |
| else |
| { |
| OSCL_LEAVE(PVMFErrArgument); |
| } |
| |
| bool formatSupported = false; |
| for (uint i = 0; i < capability.iInputFormatCapability.size(); i++) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "CPV324m2Way::AddDataSinkL - format %s\n", (capability.iInputFormatCapability[i]).getMIMEStrPtr())); |
| if (datapath->GetSourceSinkFormat() == capability.iInputFormatCapability[i]) |
| { |
| formatSupported = true; |
| break; |
| } |
| } |
| if (!formatSupported) |
| { |
| OSCL_LEAVE(PVMFErrNotSupported); |
| } |
| |
| if ((datapath->GetSourceSinkFormat() == PVMF_MIME_H2632000) || (datapath->GetSourceSinkFormat() == PVMF_MIME_M4V)) |
| { |
| if (datapath) |
| { |
| if (datapath->GetState() == EClosed) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::AddDataSinkL - creating video datapath\n")); |
| |
| //Add tsc node to datapath |
| datapathnode.iNode = iTscNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iIgnoreNodeState = true; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeStarted; |
| datapathnode.iOutputPort.iCanCancelPort = true; |
| datapathnode.iOutputPort.iPortSetType = EAppDefined; |
| datapathnode.iOutputPort.iFormatType = datapath->GetFormat(); |
| datapathnode.iOutputPort.iPortTag = -cmd->iPvtCmdData; |
| datapath->AddNode(datapathnode); |
| |
| //Add video parser node to datapath |
| datapathnode.iNode = iVideoParserNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iCanCancelPort = false; |
| datapathnode.iOutputPort.iPortSetType = EUseOtherNodePortFormat; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| |
| //Add sink node to datapath |
| datapathnode.iNode.iNode = sinkNode->iNode; |
| datapathnode.iNode.iSessionId = sinkNode->iSessionId; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iLoggoffOnReset = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; |
| datapath->AddNode(datapathnode); |
| |
| datapath->SetCmd(cmd); |
| datapath->SetChannelId(cmd->iPvtCmdData); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::AddDataSinkL - invalid video dec datapath state %d\n", |
| datapath->GetState())); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| } |
| } |
| } |
| |
| else if ((datapath->GetSourceSinkFormat() == PVMF_MIME_YUV420)) |
| { |
| if (datapath) |
| { |
| if (datapath->GetState() == EClosed) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::AddDataSinkL - creating video datapath\n")); |
| |
| //Add tsc node to datapath |
| datapathnode.iNode = iTscNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iIgnoreNodeState = true; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeStarted; |
| datapathnode.iOutputPort.iCanCancelPort = true; |
| datapathnode.iOutputPort.iPortSetType = EAppDefined; |
| datapathnode.iOutputPort.iFormatType = datapath->GetFormat(); |
| //datapathnode.iOutputPort.iPortTag = GetStackNodePortTag(EPV2WayVideoOut); |
| datapathnode.iOutputPort.iPortTag = -cmd->iPvtCmdData; |
| datapath->AddNode(datapathnode); |
| |
| //Add video parser node to datapath |
| datapathnode.iNode = iVideoParserNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iCanCancelPort = false; |
| datapathnode.iOutputPort.iPortSetType = EUseOtherNodePortFormat; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| |
| //Add video dec node to datapath |
| datapathnode.iNode = iVideoDecNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iPortSetType = EUserDefined; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_YUV420; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| |
| //Add sink node to datapath |
| datapathnode.iNode.iNode = sinkNode->iNode; |
| datapathnode.iNode.iSessionId = sinkNode->iSessionId; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| if (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16) |
| { |
| //Add audio dec node to datapath |
| datapathnode.iNode = iAudioDecNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iPortSetType = EUserDefined; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_PCM16; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| iAudioDecDatapath->AddNode(datapathnode); |
| } |
| |
| //Add sink node to datapath |
| datapathnode.iNode = *sinkNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = true; |
| datapathnode.iLoggoffOnReset = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; |
| datapath->AddNode(datapathnode); |
| |
| datapath->SetChannelId(cmd->iPvtCmdData); |
| datapath->SetCmd(cmd); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::AddDataSinkL - invalid video dec datapath state %d\n", |
| iVideoDecDatapath->GetState())); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| } |
| } |
| } |
| |
| else if ((datapath->GetSourceSinkFormat() == PVMF_MIME_AMR_IF2) || (datapath->GetSourceSinkFormat() == PVMF_MIME_AMR_IETF) || (datapath->GetSourceSinkFormat() == PVMF_MIME_G723) || (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16)) |
| { |
| if (datapath->GetState() == EClosed) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::AddDataSinkL - adding - audio sink node\n")); |
| |
| //Add tsc node to datapath |
| datapathnode.iNode = iTscNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = false; |
| datapathnode.iIgnoreNodeState = true; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeStarted; |
| datapathnode.iOutputPort.iCanCancelPort = true; |
| datapathnode.iOutputPort.iPortSetType = EAppDefined; |
| datapathnode.iOutputPort.iFormatType = datapath->GetFormat(); |
| // Need to put in the LC number here |
| //datapathnode.iOutputPort.iPortTag = GetStackNodePortTag(EPV2WayAudioOut); |
| datapathnode.iOutputPort.iPortTag = -cmd->iPvtCmdData; |
| datapath->AddNode(datapathnode); |
| |
| if (datapath->GetSourceSinkFormat() == PVMF_MIME_PCM16) |
| { |
| //Add audio dec node to datapath |
| datapathnode.iNode = iAudioDecNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iOutputPort.iPortSetType = EUserDefined; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_PCM16; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_OUT_PORT; |
| datapath->AddNode(datapathnode); |
| } |
| |
| //Add sink node to datapath |
| datapathnode.iNode = *sinkNode; |
| datapathnode.iConfigure = NULL; |
| datapathnode.iCanNodePause = true; |
| datapathnode.iLoggoffOnReset = true; |
| datapathnode.iIgnoreNodeState = false; |
| datapathnode.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| datapathnode.iInputPort.iPortSetType = EConnectedPortFormat; |
| datapathnode.iInputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iInputPort.iPortTag = PV2WAY_IN_PORT; |
| datapathnode.iOutputPort.iCanCancelPort = false; |
| datapathnode.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| datapathnode.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; |
| datapath->AddNode(datapathnode); |
| |
| datapath->SetChannelId(cmd->iPvtCmdData); |
| |
| datapath->SetCmd(cmd); |
| } |
| else |
| { |
| OSCL_ASSERT(datapath); |
| } |
| } |
| |
| } |
| |
| PVCommandId CPV324m2Way::RemoveDataSink(PVMFNodeInterface& aDataSink, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveDataSinkL(%x, %x, %x)", 0, 0, |
| aContextData)); |
| |
| |
| switch (iState) |
| { |
| case EIdle: |
| case EInitializing: |
| case EResetting: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::RemoveDataSinkL - invalid state(%d)", |
| iState)); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| |
| default: |
| //State check okay. |
| break; |
| } |
| |
| return DoRemoveDataSourceSink(aDataSink, aContextData); |
| } |
| |
| PVCommandId CPV324m2Way::Connect(const PV2WayConnectOptions& aOptions, |
| PVMFNodeInterface* aCommServer, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::ConnectL()")); |
| CPVDatapathNode node; |
| |
| // validate aCommServer |
| if (aCommServer == NULL) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ConnectL comm server is null")); |
| OSCL_LEAVE(PVMFErrArgument); |
| } |
| |
| if (iConnectInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConnectL cmd already sent out")); |
| OSCL_LEAVE(PVMFErrBusy); |
| } |
| |
| /* set clock to 0 and start */ |
| uint32 startTime = 0; |
| bool overflowFlag = false; |
| |
| if (!iClock.SetStartTime32(startTime, PVMF_MEDIA_CLOCK_MSEC, overflowFlag)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::Connect: unable to set clock time")); |
| OSCL_LEAVE(PVMFFailure); |
| } |
| |
| switch (iState) |
| { |
| case ESetup: |
| iConnectInfo = GetCmdInfoL(); |
| |
| iLoopbackMode = aOptions.iLoopbackMode; |
| ((TSC_324m *)(PVMFNodeInterface *)iTscNode.iNode)->SetLoopbackMode(iLoopbackMode); |
| ((TSC_324m *)(PVMFNodeInterface *)iTscNode.iNode)->SetEndSessionTimeout(((PV2Way324ConnectOptions *)(&aOptions))->iDisconnectTimeoutInterval); |
| |
| // Store reference to comm server |
| iCommNode = TPV2WayNode(aCommServer); |
| InitiateSession(iCommNode); |
| |
| //Add tsc node to datapath |
| node.iNode = iTscNode; |
| node.iConfigure = this; |
| node.iIgnoreNodeState = false; |
| node.iConfigTime = EConfigBeforeStart; |
| node.iOutputPort.iRequestPortState = EPVMFNodeInitialized; |
| node.iOutputPort.iPortSetType = EUserDefined; |
| node.iOutputPort.iFormatType = PVMF_MIME_H223; |
| //node.iOutputPort.iPortType = EPVIOPort; |
| node.iOutputPort.iPortTag = PV_MULTIPLEXED; |
| iMuxDatapath->AddNode(node); |
| |
| //Add rcomm node to datapath |
| node.iNode = iCommNode; |
| node.iLoggoffOnReset = true; |
| node.iConfigure = NULL; |
| node.iIgnoreNodeState = false; |
| node.iLoggoffOnReset = false; |
| node.iInputPort.iRequestPortState = EPVMFNodeInitialized; |
| node.iInputPort.iPortSetType = EUserDefined; |
| node.iInputPort.iFormatType = PVMF_MIME_H223; |
| node.iInputPort.iPortTag = PV2WAY_IO_PORT; |
| //node.iInputPort.iProperty.iPortType = EPVIOPort; |
| node.iOutputPort.iFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| //node.iOutputPort.iPortType = EPVInvalidPortType; |
| node.iOutputPort.iPortTag = PV2WAY_UNKNOWN_PORT; |
| iMuxDatapath->AddNode(node); |
| |
| iConnectInfo->type = PVT_COMMAND_CONNECT; |
| iConnectInfo->id = iCommandId; |
| iConnectInfo->contextData = aContextData; |
| SetState(EConnecting); |
| |
| iMuxDatapath->Open(); |
| break; |
| |
| case EConnected: |
| iConnectInfo = GetCmdInfoL(); |
| iConnectInfo->type = PVT_COMMAND_CONNECT; |
| iConnectInfo->status = PVMFSuccess; |
| iConnectInfo->id = iCommandId; |
| iConnectInfo->contextData = aContextData; |
| Dispatch(iConnectInfo); |
| iConnectInfo = NULL; |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ConnectL - invalid state(%d)", iState)); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| } |
| |
| /* |
| // start enc datapaths that are already created |
| if (iAudioEncDatapath->GetState() != EClosed) |
| { |
| iAudioEncDatapath->CheckOpen(); |
| } |
| if (iVideoEncDatapath->GetState() != EClosed) |
| { |
| iVideoEncDatapath->CheckOpen(); |
| } |
| */ |
| return iCommandId++; |
| } |
| |
| PVCommandId CPV324m2Way::Disconnect(OsclAny* aContextData) |
| { |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::Disconnect()")); |
| |
| if (iDisconnectInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::Disconnect cmd already sent out")); |
| OSCL_LEAVE(PVMFErrBusy); |
| } |
| |
| switch (iState) |
| { |
| case EConnecting: |
| //Connect in progress, notify application that it has been cancelled. |
| iConnectInfo->status = PVMFErrCancelled; |
| Dispatch(iConnectInfo); |
| iConnectInfo = NULL; |
| //Fall through to next case |
| |
| case EConnected: |
| |
| iTSC324mInterface->EndSessionCommand(); |
| |
| iEndSessionTimer->SetObserver(this); |
| iEndSessionTimer->Request(END_SESSION_TIMER_ID, END_SESSION_TIMER_ID, |
| END_SESSION_TIMER_VALUE, this); |
| |
| iDisconnectInfo = GetCmdInfoL(); |
| |
| iDisconnectInfo->type = PVT_COMMAND_DISCONNECT; |
| iDisconnectInfo->contextData = aContextData; |
| iDisconnectInfo->id = iCommandId; |
| |
| //We wait to InitiateDisconnect() till iEndSessionTimer timer expires |
| break; |
| |
| case EDisconnecting: |
| //If at this point, then remote disconnect is in progress, just treat as user disconnect. |
| iDisconnectInfo = GetCmdInfoL(); |
| |
| iDisconnectInfo->type = PVT_COMMAND_DISCONNECT; |
| iDisconnectInfo->contextData = aContextData; |
| iDisconnectInfo->id = iCommandId; |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::Disconnect - invalid state(%d)", iState)); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| } |
| |
| return iCommandId++; |
| } |
| |
| void CPV324m2Way::InitiateDisconnect() |
| { |
| SetState(EDisconnecting); |
| CheckState(); |
| } |
| |
| void CPV324m2Way::InitiateReset() |
| { |
| SetState(EResetting); |
| |
| if (isIFrameReqTimerActive) |
| { |
| iIFrameReqTimer.Cancel(IFRAME_REQ_TIMERID); |
| isIFrameReqTimerActive = false; |
| } |
| |
| if ((iAudioDecDatapath != NULL) && (iAudioDecDatapath->GetState() != EClosed)) |
| { |
| iAudioDecDatapath->SetCmd(NULL); |
| } |
| |
| if ((iAudioEncDatapath != NULL) && (iAudioEncDatapath->GetState() != EClosed)) |
| { |
| iAudioEncDatapath->SetCmd(NULL); |
| } |
| |
| if ((iVideoDecDatapath != NULL) && (iVideoDecDatapath->GetState() != EClosed)) |
| { |
| iVideoDecDatapath->SetCmd(NULL); |
| } |
| |
| if ((iVideoEncDatapath != NULL) && (iVideoEncDatapath->GetState() != EClosed)) |
| { |
| iVideoEncDatapath->SetCmd(NULL); |
| } |
| |
| CheckState(); |
| } |
| |
| void CPV324m2Way::CheckState() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::CheckState state %d\n", iState)); |
| switch (iState) |
| { |
| case EInitializing: |
| CheckInit(); |
| break; |
| |
| case EConnecting: |
| CheckConnect(); |
| break; |
| |
| case EDisconnecting: |
| CheckDisconnect(); |
| break; |
| |
| case EResetting: |
| CheckReset(); |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, |
| (0, "CPV324m2Way::CheckState warning: static state!")); |
| break; |
| } |
| } |
| |
| void CPV324m2Way::CheckInit() |
| { |
| // 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)); |
| int32 error; |
| |
| if (((PVMFNodeInterface *)iTscNode)->GetState() == EPVMFNodeIdle) |
| { |
| OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_INIT, &iTscNode, this)); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckInit unable to init tsc node!\n")); |
| SetState(EResetting); |
| CheckState(); |
| return;); |
| } |
| if (((PVMFNodeInterface *)iTscNode)->GetState() == EPVMFNodeInitialized) |
| { |
| |
| SetState(ESetup); |
| |
| iInitInfo->status = PVMFSuccess; |
| Dispatch(iInitInfo); |
| iInitInfo = NULL; |
| } |
| } |
| |
| void CPV324m2Way::CheckConnect() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::CheckConnect state %d, comm state %d, tsc state %d\n", |
| iState, ((PVMFNodeInterface *)iCommNode)->GetState(), |
| ((PVMFNodeInterface *)iTscNode)->GetState())); |
| |
| if ((iMuxDatapath->GetState() == EOpened) && iIsStackConnected) |
| { |
| /* Increase video encoder bitrate if required */ |
| // PVMp4H263EncExtensionInterface *ptr = (PVMp4H263EncExtensionInterface *) iVideoEncNodeInterface.iInterface; |
| // ptr->SetOutputBitRate(0, VIDEO_ENCODER_BITRATE); |
| SetState(EConnected); |
| |
| iConnectInfo->status = PVMFSuccess; |
| Dispatch(iConnectInfo); |
| iConnectInfo = NULL; |
| } |
| } |
| |
| |
| void CPV324m2Way::CheckDisconnect() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::CheckDisconnect state %d, mux datapath state %d, stack connected %d\n", |
| iState, iMuxDatapath->GetState(), iIsStackConnected)); |
| if ((iMuxDatapath->GetState() == EClosed) && |
| !iIsStackConnected) |
| { |
| SetState(ESetup); |
| |
| //Connect failed |
| if (iConnectInfo) |
| { |
| iConnectInfo->status = PVMFFailure; |
| Dispatch(iConnectInfo); |
| iConnectInfo = NULL; |
| } |
| //Else command cancelled |
| else if (iCancelInfo) |
| { |
| iCancelInfo->status = PVMFSuccess; |
| Dispatch(iCancelInfo); |
| iCancelInfo = NULL; |
| } |
| //Else local disconnect |
| else if (iDisconnectInfo) |
| { |
| iDisconnectInfo->status = PVMFSuccess; |
| Dispatch(iDisconnectInfo); |
| iDisconnectInfo = NULL; |
| } |
| //Else remote disconnect |
| else |
| { |
| TPV2WayEventInfo* aEvent = NULL; |
| if (!GetEventInfo(aEvent)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckDisconnect unable to notify app!\n")); |
| return; |
| } |
| aEvent->type = PVT_INDICATION_DISCONNECT; |
| Dispatch(aEvent); |
| } |
| } |
| else |
| { |
| iMuxDatapath->Close(); |
| } |
| } |
| |
| void CPV324m2Way::CheckReset() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::CheckReset state %d \n", iState)); |
| int32 error; |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| switch (iRecordFileState) |
| { |
| case File2WayInitializing: |
| case File2WayInitialized: |
| InitiateResetRecordFile(); |
| break; |
| |
| case File2WayIdle: |
| case File2WayResetting: |
| break; |
| } |
| #endif |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| switch (iPlayFileState) |
| { |
| case File2WayInitializing: |
| case File2WayInitialized: |
| InitiateResetPlayFile(); |
| break; |
| |
| case File2WayIdle: |
| case File2WayResetting: |
| break; |
| } |
| #endif |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| if (iRecordFileState != File2WayIdle) return; |
| #endif |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| if (iPlayFileState != File2WayIdle) return; |
| #endif |
| |
| |
| |
| if ((iAudioEncDatapath != NULL) && (iAudioEncDatapath->GetState() == EClosed) && |
| (iAudioDecDatapath != NULL) && (iAudioDecDatapath->GetState() == EClosed) && |
| (iVideoEncDatapath != NULL) && (iVideoEncDatapath->GetState() == EClosed) && |
| (iVideoDecDatapath != NULL) && (iVideoDecDatapath->GetState() == EClosed)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::CheckReset state %d, AD state %d, VD state %d, AE state %d, VE state %d\n", |
| iState, |
| iAudioDecDatapath->GetState(), |
| iVideoDecDatapath->GetState(), |
| iAudioEncDatapath->GetState(), |
| iVideoEncDatapath->GetState())); |
| |
| TPVMFNodeInterfaceState vidEncState; |
| |
| if (iVideoEncNode != NULL) |
| { |
| vidEncState = ((PVMFNodeInterface *)iVideoEncNode)->GetState() ; |
| if ((vidEncState == EPVMFNodeInitialized) || (vidEncState == EPVMFNodeError)) |
| { |
| OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_RESET, &iVideoEncNode, this)); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckReset unable to reset video encoder node!\n")); |
| return;); |
| } |
| } |
| |
| if (iAudioEncNode != NULL) |
| { |
| if ((iAudioEncNode.iNode->GetState() == EPVMFNodeInitialized) || |
| (iAudioEncNode.iNode->GetState() == EPVMFNodeError)) |
| { |
| OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_RESET, &iAudioEncNode, this)); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckReset unable to reset audio encoder node!\n")); |
| return;); |
| } |
| } |
| } |
| |
| TPVMFNodeInterfaceState tscState = ((PVMFNodeInterface *)iTscNode)->GetState() ; |
| |
| if ((tscState == EPVMFNodeInitialized) || |
| (tscState == EPVMFNodeError)) |
| { |
| OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_RESET, &iTscNode, this)); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckReset unable to reset tsc node!\n")); |
| return;); |
| } |
| bool aFlag = false; |
| if ((tscState == EPVMFNodeIdle) && |
| (iVideoEncNodeInterface.iState != PV2WayNodeInterface::QueryInterface)) |
| { |
| if (iVideoEncNode.iNode != NULL) |
| aFlag = IsNodeReset(*(iVideoEncNode.iNode)); |
| else |
| aFlag = true; |
| |
| } |
| |
| if (aFlag == true) |
| { |
| iIncomingChannelParams.clear(); |
| iOutgoingChannelParams.clear(); |
| |
| SetState(EIdle); |
| |
| //Init failed |
| if (iInitInfo) |
| { |
| iInitInfo->status = PVMFFailure; |
| Dispatch(iInitInfo); |
| iInitInfo = NULL; |
| } |
| //Else command cancelled |
| else if (iCancelInfo) |
| { |
| iCancelInfo->status = PVMFSuccess; |
| Dispatch(iCancelInfo); |
| iCancelInfo = NULL; |
| } |
| //Else local reset |
| else |
| { |
| iResetInfo->status = PVMFSuccess; |
| Dispatch(iResetInfo); |
| iResetInfo = NULL; |
| } |
| } |
| |
| } |
| |
| |
| void CPV324m2Way::RemoveAudioDecPath() |
| { |
| if (iAudioDecDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveAudioDecPath audio dec path state %d\n", |
| iAudioDecDatapath->GetState())); |
| } |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| RemoveAudioRecPath(); |
| #endif |
| |
| if ((iAudioDecDatapath != NULL) && |
| (iAudioDecDatapath->GetState() == EClosed)) |
| { |
| iAudioDecDatapath->ResetDatapath(); |
| iAudioSinkNode.Clear(); |
| } |
| } |
| |
| void CPV324m2Way::RemoveAudioEncPath() |
| { |
| if (iAudioEncDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveAudioEncPath audio enc path state %d\n", |
| iAudioEncDatapath->GetState())); |
| } |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| RemoveAudioPreviewPath(); |
| #endif |
| |
| if ((iAudioEncDatapath != NULL) && |
| (iAudioEncDatapath->GetState() == EClosed)) |
| { |
| iAudioEncDatapath->SetSourceInputPort(NULL); |
| iAudioEncDatapath->ResetDatapath(); |
| iAudioSrcNode.Clear(); |
| } |
| } |
| |
| void CPV324m2Way::RemoveVideoDecPath() |
| { |
| if (iVideoDecDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveVideoDecPath video dec path state %d\n", |
| iVideoDecDatapath->GetState())); |
| } |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| RemoveVideoRecPath(); |
| #endif |
| |
| if ((iVideoDecDatapath != NULL) && |
| (iVideoDecDatapath->GetState() == EClosed)) |
| { |
| iVideoDecDatapath->ResetDatapath(); |
| } |
| } |
| |
| void CPV324m2Way::RemoveVideoEncPath() |
| { |
| if (iVideoEncDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveVideoEncPath video enc path state %d\n", |
| iVideoEncDatapath->GetState())); |
| } |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| RemoveVideoPreviewPath(); |
| #endif |
| |
| if ((iVideoEncDatapath != NULL) && |
| (iVideoEncDatapath->GetState() == EClosed)) |
| { |
| //Video encoder will be deleted at reset time. |
| |
| iVideoEncDatapath->ResetDatapath(); |
| } |
| } |
| |
| void CPV324m2Way::HandleCommNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleCommNodeCmd type %d\n", aType)); |
| |
| switch (aType) |
| { |
| case PV2WAY_NODE_CMD_INIT: |
| if (aResponse.GetCmdStatus() != PVMFSuccess) |
| { |
| SetState(EResetting); |
| } |
| |
| CheckState(); |
| break; |
| |
| case PV2WAY_NODE_CMD_RESET: |
| CheckState(); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| void CPV324m2Way::HandleTscNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleTscNodeCmd type %d\n", aType)); |
| |
| switch (aType) |
| { |
| case PV2WAY_NODE_CMD_INIT: |
| if (aResponse.GetCmdStatus() == PVMFSuccess) |
| { |
| ((TSC_324m *)((PVMFNodeInterface *)iTscNode))->SetIncomingChannelConfig(iIncomingChannelParams); |
| ((TSC_324m *)((PVMFNodeInterface *)iTscNode))->SetOutgoingChannelConfig(iOutgoingChannelParams); |
| } |
| else |
| { |
| SetState(EResetting); |
| } |
| |
| CheckState(); |
| break; |
| |
| case PV2WAY_NODE_CMD_RESET: |
| CheckState(); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| |
| void CPV324m2Way::HandleVideoDecNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| OSCL_UNUSED_ARG(aType); |
| OSCL_UNUSED_ARG(aResponse); |
| } |
| |
| void CPV324m2Way::HandleVideoEncNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| if (iVideoEncDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleVideoEncNodeCmd type %d, video enc path state %d\n", |
| aType, iVideoEncDatapath->GetState())); |
| } |
| |
| switch (aType) |
| { |
| case PV2WAY_NODE_CMD_QUERY_INTERFACE: |
| |
| if (aResponse.GetCmdId() == iVideoEncQueryIntCmdId) |
| { |
| iVideoEncQueryIntCmdId = -1; |
| if (aResponse.GetCmdStatus() == PVMFSuccess) |
| { |
| iVideoEncNodeInterface.iState = PV2WayNodeInterface::HasInterface; |
| // Set the FormatSpecificInfo if available |
| uint32 fsi_len = 0; |
| uint8* fsi = iVideoEncDatapath->GetFormatSpecificInfo(&fsi_len); |
| if (fsi && fsi_len) |
| { |
| OSCL_STATIC_CAST(PVMp4H263EncExtensionInterface *, |
| iVideoEncNodeInterface.iInterface)->SetFSIParam(fsi, fsi_len); |
| if (iAddDataSourceVideoCmd) |
| { |
| iVideoEncDatapath->SetCmd(iAddDataSourceVideoCmd); |
| iAddDataSourceVideoCmd = NULL; |
| } |
| } |
| } |
| else |
| { |
| iVideoEncNodeInterface.iState = PV2WayNodeInterface::NoInterface; |
| SetState(EResetting); |
| } |
| |
| } |
| |
| CheckState(); |
| break; |
| |
| case PV2WAY_NODE_CMD_INIT: |
| CheckState(); |
| break; |
| |
| case PV2WAY_NODE_CMD_RESET: |
| CheckState(); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| void CPV324m2Way::HandleSinkNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse, |
| TPV2WayNode* aNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleSinkNodeCmd type %d\n", aType)); |
| switch (aType) |
| { |
| case PV2WAY_NODE_CMD_INIT: |
| if (aResponse.GetCmdStatus() != PVMFSuccess) |
| { |
| SetState(EResetting); |
| CheckState(); |
| } |
| else |
| { |
| DoAddDataSink(*aNode, aResponse); |
| } |
| break; |
| case PV2WAY_NODE_CMD_QUERY_INTERFACE: |
| if (aResponse.GetCmdStatus() == PVMFSuccess) |
| { |
| for (uint32 ii = 0; ii < iSinkNodeList.size(); ii++) |
| { |
| if ((aNode == iSinkNodeList[ii].iSinkNode) && |
| (aResponse.GetCmdId() == iSinkNodeList[ii].iNodeInterface.iId)) |
| { |
| iSinkNodeList[ii].iNodeInterface.iInterface = |
| iClockSyncInterface.iInterface; |
| iClockSyncInterface.Reset(); |
| if (iSinkNodeList[ii].iNodeInterface.iInterface != NULL) |
| { |
| iSinkNodeList[ii].iNodeInterface.iState = |
| PV2WayNodeInterface::HasInterface; |
| PvmfNodesSyncControlInterface* ptr = NULL; |
| ptr = OSCL_STATIC_CAST(PvmfNodesSyncControlInterface*, |
| iSinkNodeList[ii].iNodeInterface.iInterface); |
| ptr->SetClock(&iClock); |
| } |
| break; |
| } |
| } |
| } |
| else |
| { |
| SetState(EResetting); |
| CheckState(); |
| } |
| break; |
| case PV2WAY_NODE_CMD_SKIP_MEDIA_DATA: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleSinkNodeCmd type %d, SkipComplete for Node %x ", |
| aType, aNode->iNode)); |
| if (iAudioDecDatapath) iAudioDecDatapath->SkipComplete(aNode); |
| if (iVideoDecDatapath) iVideoDecDatapath->SkipComplete(aNode); |
| RunIfNotReady(); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| void CPV324m2Way::SupportedSinkNodeInterfaces(TPV2WayNode* aNode) |
| { |
| |
| int32 error; |
| |
| //Currently this only checks if the sink node support PvmfSyncNodeControlInterface |
| |
| TPV2WayNodeQueryInterfaceParams queryParam; |
| queryParam.iUuid = (PVUuid *) & iSyncControlPVUuid; |
| SinkNodeIFList sinkNode; |
| sinkNode.iSinkNode = aNode; |
| queryParam.iInterfacePtr = &iClockSyncInterface.iInterface; |
| OSCL_TRY(error, sinkNode.iNodeInterface.iId = |
| SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, aNode, this, &queryParam)); |
| |
| iSinkNodeList.push_back(sinkNode); |
| |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SupportedSinkNodeInterfaces unable to query for MediaOutputNode extension interface!\n")); |
| SetState(EResetting); |
| CheckState(); |
| return;); |
| } |
| |
| |
| void CPV324m2Way::HandleAudioEncNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| if (iAudioEncDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleAudioEncNodeCmd type %d, audio enc path state %d\n", |
| aType, iAudioEncDatapath->GetState())); |
| } |
| OSCL_UNUSED_ARG(aResponse); |
| OSCL_UNUSED_ARG(aType); |
| |
| switch (aType) |
| { |
| case PV2WAY_NODE_CMD_QUERY_INTERFACE: |
| |
| if (aResponse.GetCmdStatus() == PVMFSuccess) |
| { |
| iAudioEncNodeInterface.iState = PV2WayNodeInterface::HasInterface; |
| |
| } |
| else |
| { |
| iAudioEncNodeInterface.iState = PV2WayNodeInterface::NoInterface; |
| SetState(EResetting); |
| } |
| |
| CheckState(); |
| break; |
| |
| case PV2WAY_NODE_CMD_INIT: |
| CheckState(); |
| break; |
| |
| case PV2WAY_NODE_CMD_RESET: |
| CheckState(); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| void CPV324m2Way::GenerateIFrame(PVMFPortInterface *aPort) |
| { |
| if (iVideoEncDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::GenerateIFrame, vid enc path state %d\n", |
| iVideoEncDatapath->GetState())); |
| |
| if ((iVideoEncDatapath->IsPortInDatapath(aPort)) && |
| (iVideoEncDatapath->GetState() == EOpened)) |
| { |
| if (!((PVMp4H263EncExtensionInterface *) iVideoEncNodeInterface.iInterface)->RequestIFrame()) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::GenerateIFrame - unable to generate iframe")); |
| } |
| } |
| } |
| } |
| |
| void CPV324m2Way::RequestRemoteIFrame(PVMFPortInterface *aPort) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::RequestRemoteIFrame, timer active %d\n", isIFrameReqTimerActive)); |
| TSC_324m *nodeIface = (TSC_324m *)((PVMFNodeInterface *)iTscNode); |
| if (nodeIface && |
| !isIFrameReqTimerActive && |
| (nodeIface->RequestFrameUpdate(aPort) == EPVT_Success)) |
| { |
| //Still need to actually send an iframe request!!!! |
| iIFrameReqTimer.Request(IFRAME_REQ_TIMERID, (int32)this, |
| iMinIFrameRequestInterval, this); |
| isIFrameReqTimerActive = true; |
| } |
| } |
| |
| PVCommandId CPV324m2Way::GetState(PV2WayState& aState, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::GetPV2WayState %d\n", iState)); |
| |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| cmd->type = PVT_COMMAND_GET_PV2WAY_STATE; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->status = PVMFSuccess; |
| |
| aState = iState; |
| |
| Dispatch(cmd); |
| |
| return iCommandId++; |
| } |
| |
| |
| PVCommandId CPV324m2Way::SetLatencyQualityTradeoff(PVMFNodeInterface& aTrack, |
| int32 aTradeoff, |
| OsclAny* aContextData) |
| { |
| OSCL_UNUSED_ARG(aTrack); |
| OSCL_UNUSED_ARG(aTradeoff); |
| OSCL_UNUSED_ARG(aContextData); |
| return iCommandId++; |
| } |
| |
| |
| PVCommandId CPV324m2Way::Pause(PV2WayDirection aDirection, |
| PVTrackId aTrackId, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV324m2Way::Pause\n")); |
| OSCL_UNUSED_ARG(aDirection); |
| OSCL_UNUSED_ARG(aTrackId); |
| OSCL_UNUSED_ARG(aContextData); |
| |
| OSCL_LEAVE(PVMFErrNotSupported); |
| return iCommandId++; |
| } |
| |
| |
| PVCommandId CPV324m2Way::Resume(PV2WayDirection aDirection, |
| PVTrackId aTrackId, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::Resume\n")); |
| OSCL_UNUSED_ARG(aDirection); |
| OSCL_UNUSED_ARG(aTrackId); |
| OSCL_UNUSED_ARG(aContextData); |
| OSCL_LEAVE(PVMFErrNotSupported); |
| |
| return iCommandId++; |
| } |
| |
| |
| PVCommandId CPV324m2Way::SetLogAppender(const char * aTag, |
| OsclSharedPtr<PVLoggerAppender>& aAppender, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::SetLogAppenderL\n")); |
| |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| PVLogger *logger = PVLogger::GetLoggerObject(aTag); |
| logger->AddAppender(aAppender); |
| |
| // print sdk info |
| PVSDKInfo sdkinfo; |
| FillSDKInfo(sdkinfo); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "PV RELEASE LABEL = %s", sdkinfo.iLabel.get_cstr())); |
| |
| cmd->type = PVT_COMMAND_SET_LOG_APPENDER; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->status = PVMFSuccess; |
| |
| Dispatch(cmd); |
| return iCommandId++; |
| } |
| |
| PVCommandId CPV324m2Way::RemoveLogAppender(const char * aTag, |
| OsclSharedPtr<PVLoggerAppender>& aAppender, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveLogAppenderL\n")); |
| |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| cmd->type = PVT_COMMAND_REMOVE_LOG_APPENDER; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->status = PVMFSuccess; |
| |
| PVLogger *logger = PVLogger::GetLoggerObject(aTag); |
| logger->RemoveAppender(aAppender); |
| |
| Dispatch(cmd); |
| return iCommandId++; |
| } |
| |
| PVCommandId CPV324m2Way::SetLogLevel(const char * aTag, |
| int32 aLevel, |
| bool aSetSubtree, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::SetLogLevelL\n")); |
| OSCL_UNUSED_ARG(aSetSubtree); |
| |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| cmd->type = PVT_COMMAND_SET_LOG_LEVEL; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->status = PVMFSuccess; |
| |
| PVLogger *logger = PVLogger::GetLoggerObject(aTag); |
| logger->SetLogLevel(aLevel); |
| |
| Dispatch(cmd); |
| return iCommandId++; |
| } |
| |
| PVCommandId CPV324m2Way::GetLogLevel(const char * aTag, |
| int32& aLogInfo, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::GetLogLevelL\n")); |
| |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| |
| cmd->type = PVT_COMMAND_GET_LOG_LEVEL; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->status = PVMFSuccess; |
| |
| PVLogger *logger = PVLogger::GetLoggerObject(aTag); |
| aLogInfo = logger->GetLogLevel(); |
| |
| Dispatch(cmd); |
| return iCommandId++; |
| } |
| |
| |
| PVCommandId CPV324m2Way::QueryInterface(const PVUuid& aUuid, |
| PVInterface*& aInterfacePtr, |
| OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::QueryInterface()\n")); |
| |
| TPV2WayNodeQueryInterfaceParams queryParam; |
| queryParam.iUuid = (PVUuid*) & aUuid; |
| queryParam.iInterfacePtr = &aInterfacePtr; |
| |
| TPV2WayCmdInfo *cmd = GetCmdInfoL(); |
| cmd->type = PVT_COMMAND_QUERY_INTERFACE; |
| cmd->id = iCommandId; |
| cmd->contextData = aContextData; |
| cmd->status = PVMFPending; |
| aInterfacePtr = NULL; |
| |
| if (aUuid == PVH324MConfigUuid && ((PVMFNodeInterface *)iTscNode)) |
| { |
| int32 error = 0; |
| OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, |
| &iTscNode, this, &queryParam, cmd)); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::QueryInterface failed!\n")); |
| cmd->status = PVMFFailure; |
| Dispatch(cmd);); |
| cmd->status = PVMFSuccess; //ks added |
| } |
| else if (aUuid == PVMp4H263EncExtensionUUID && |
| ((PVMFNodeInterface *)iVideoEncNode)) |
| { |
| int32 error = 0; |
| OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, &iVideoEncNode, |
| this, &queryParam, cmd)); |
| OSCL_FIRST_CATCH_ANY(error, |
| cmd->status = PVMFFailure; |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::QueryInterface unable to query for video encoder interface!\n"));); |
| } |
| else |
| { |
| aInterfacePtr = NULL; |
| cmd->status = PVMFErrNotSupported; |
| } |
| if (cmd->status != PVMFPending) |
| Dispatch(cmd); |
| |
| return iCommandId++; |
| } |
| |
| PVCommandId CPV324m2Way::QueryUUID(const PvmfMimeString& aMimeType, |
| Oscl_Vector<PVUuid, BasicAlloc>& aUuids, |
| bool aExactUuidsOnly, |
| OsclAny* aContextData) |
| { |
| OSCL_UNUSED_ARG(aMimeType); |
| OSCL_UNUSED_ARG(aUuids); |
| OSCL_UNUSED_ARG(aExactUuidsOnly); |
| OSCL_UNUSED_ARG(aContextData); |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::QueryUUID\n")); |
| OSCL_LEAVE(PVMFErrNotSupported); |
| return 0; |
| } |
| |
| PVCommandId CPV324m2Way::CancelAllCommands(OsclAny* aContextData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::CancelAllCommands state %d\n", iState)); |
| |
| if (iCancelInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::CancelAllCommands, cancel in progress!\n")); |
| OSCL_LEAVE(PVMFErrBusy); |
| } |
| |
| switch (iState) |
| { |
| case EInitializing: |
| iCancelInfo = GetCmdInfoL(); |
| iCancelInfo->type = PVT_COMMAND_CANCEL_ALL_COMMANDS; |
| iCancelInfo->id = iCommandId; |
| iCancelInfo->contextData = aContextData; |
| SetState(EResetting); |
| |
| if (!iInitInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CancelAllCommands, no init info!\n")); |
| } |
| else |
| { |
| iInitInfo->status = PVMFErrCancelled; |
| Dispatch(iInitInfo); |
| iInitInfo = NULL; |
| } |
| |
| CheckState(); |
| break; |
| |
| case EConnecting: |
| iCancelInfo = GetCmdInfoL(); |
| iCancelInfo->type = PVT_COMMAND_CANCEL_ALL_COMMANDS; |
| iCancelInfo->id = iCommandId; |
| iCancelInfo->contextData = aContextData; |
| SetState(EDisconnecting); |
| |
| if (!iConnectInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CancelAllCommands, no connect info!\n")); |
| } |
| else |
| { |
| iConnectInfo->status = PVMFErrCancelled; |
| Dispatch(iConnectInfo); |
| iConnectInfo = NULL; |
| } |
| |
| CheckState(); |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CancelAllCommands invalid state!\n")); |
| OSCL_LEAVE(PVMFErrInvalidState); |
| break; |
| } |
| |
| return iCommandId++; |
| } |
| |
| |
| void CPV324m2Way::ConstructL(PVMFNodeInterface* aTsc, |
| TPVTerminalType aType, |
| PVCommandStatusObserver* aCmdStatusObserver, |
| PVInformationalEventObserver *aInfoEventObserver, |
| PVErrorEventObserver *aErrorEventObserver) |
| { |
| OSCL_UNUSED_ARG(aTsc); |
| |
| iTerminalType = aType; |
| |
| /* Initialize the clock */ |
| if (!iClock.SetClockTimebase(iTickCountTimeBase)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ConstructL: unable to initialize clock")); |
| OSCL_LEAVE(PVMFFailure); |
| } |
| |
| FormatCapabilityInfo inFormat; |
| inFormat.dir = INCOMING; |
| |
| /* Add user input types */ |
| inFormat.format = PVMF_MIME_USERINPUT_DTMF; |
| iIncomingUserInputFormats.push_back(inFormat); |
| inFormat.format = PVMF_MIME_USERINPUT_IA5_STRING; |
| iIncomingUserInputFormats.push_back(inFormat); |
| inFormat.format = PVMF_MIME_USERINPUT_BASIC_STRING; |
| iIncomingUserInputFormats.push_back(inFormat); |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::ConstructL (%x, %x, %x, %x)", |
| aTsc, aCmdStatusObserver, |
| aInfoEventObserver, aErrorEventObserver)); |
| iMuxDatapath = CPV2WayMuxDatapath::NewL(iLogger, PVMF_MIME_H223, this); |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| iRecFilename = DEFAULT_RECORDED_CALL_FILENAME; |
| |
| iAudioRecDatapath = CPV2WayRecDatapath::NewL(iLogger, PVMF_COMPRESSED_AUDIO_FORMAT, |
| *iAudioDecDatapath, this); |
| iVideoRecDatapath = CPV2WayRecDatapath::NewL(iLogger, PVMF_COMPRESSED_VIDEO_FORMAT, |
| *iVideoDecDatapath, this); |
| |
| //Set up recording datapath dependencies |
| iAudioDecDatapath->AddDependentDatapath(*iAudioRecDatapath); |
| iVideoDecDatapath->AddDependentDatapath(*iVideoRecDatapath); |
| iAudioRecDatapath->AddParentDatapath(*iAudioDecDatapath); |
| iVideoRecDatapath->AddParentDatapath(*iVideoDecDatapath); |
| #endif |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| iAudioPreviewDatapath = CPV2WayPreviewDatapath::NewL(iLogger, |
| PVMF_COMPRESSED_AUDIO_FORMAT, this); |
| iVideoPreviewDatapath = CPV2WayPreviewDatapath::NewL(iLogger, |
| PVMF_COMPRESSED_VIDEO_FORMAT, this); |
| |
| //Set up preview sink datapath dependencies |
| iAudioEncDatapath->AddDependentDatapath(*iAudioPreviewDatapath); |
| iVideoEncDatapath->AddDependentDatapath(*iVideoPreviewDatapath); |
| iAudioPreviewDatapath->AddParentDatapath(*iAudioEncDatapath); |
| iVideoPreviewDatapath->AddParentDatapath(*iVideoEncDatapath); |
| #endif |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "Full pv_2way_engine\n")); |
| #ifdef PV_DISABLE_VIDRECNODE |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "VidRec node disabled\n")); |
| #else |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "VidRec node enabled\n")); |
| #endif |
| |
| #ifdef PV_DISABLE_DEVSOUNDNODES |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "DevSound nodes disabled\n")); |
| #else |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "DevSound nodes enabled\n")); |
| #endif |
| |
| SetDefaults(); |
| iCmdStatusObserver = aCmdStatusObserver; |
| iInfoEventObserver = aInfoEventObserver; |
| iErrorEventObserver = aErrorEventObserver; |
| |
| iPendingNotifications.reserve(MAX_PENDING_2WAY_COMMANDS + MAX_PENDING_2WAY_EVENTS); |
| iPendingNodeCmdInfo.reserve(MAX_PENDING_2WAY_NODE_COMMANDS); |
| iIncomingChannelParams.reserve(MAX_LOGICAL_CHANNEL_PARAMS); |
| iOutgoingChannelParams.reserve(MAX_LOGICAL_CHANNEL_PARAMS); |
| |
| int32 i; |
| for (i = 0; i < MAX_PENDING_2WAY_COMMANDS; i++) |
| { |
| iFreeCmdInfo.push_back(&iCmdInfo[i]); |
| } |
| |
| for (i = 0; i < MAX_PENDING_2WAY_EVENTS; i++) |
| { |
| iFreeEventInfo.push_back(&iEventInfo[i]); |
| } |
| |
| for (i = 0; i < MAX_PENDING_2WAY_NODE_COMMANDS; i++) |
| { |
| iFreeNodeCmdInfo.push_back(&iNodeCmdInfo[i]); |
| } |
| |
| iSourceNodes.reserve(3); |
| iSinkNodes.reserve(3); |
| |
| AddToScheduler(); |
| |
| PreInit(); |
| |
| return; |
| } |
| |
| void CPV324m2Way::SetDefaults() |
| { |
| uint32 i; |
| SetState(EIdle); |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| if (iPlayFromFileNode.iNode) |
| { |
| iPlayFromFileNode.iNode->ThreadLogoff(); |
| OSCL_DELETE(iPlayFromFileNode.iNode); |
| iPlayFromFileNode.Clear();; |
| } |
| |
| if (iVideoSrcSplitterNode.iNode) |
| { |
| iVideoSrcSplitterNode.iNode->ThreadLogoff(); |
| OSCL_DELETE(iVideoSrcSplitterNode.iNode); |
| iVideoSrcSplitterNode = NULL; |
| } |
| |
| if (iAudioSrcSplitterNode) |
| { |
| iAudioSrcSplitterNode->ThreadLogoff(); |
| OSCL_DELETE(iAudioSrcSplitterNode); |
| iAudioSrcSplitterNode = NULL; |
| } |
| #endif |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| if (iFFComposerNode) |
| { |
| iFFComposerNode->ThreadLogoff(); |
| PVMp4FFComposerNodeFactory::DeleteMp4FFComposer(iFFComposerNode); |
| iFFComposerNode = NULL; |
| } |
| |
| if (iVideoDecSplitterNode) |
| { |
| iVideoDecSplitterNode->ThreadLogoff(); |
| OSCL_DELETE(iVideoDecSplitterNode); |
| iVideoDecSplitterNode = NULL; |
| } |
| #endif |
| |
| if (iVideoParserNode.iNode) |
| { |
| iVideoParserNode.iNode->ThreadLogoff(); |
| OSCL_DELETE(iVideoParserNode.iNode); |
| iVideoParserNode.Clear(); |
| } |
| |
| if (iVideoDecNode.iNode) |
| { |
| iVideoDecNode.iNode->ThreadLogoff(); |
| |
| #ifdef PV2WAY_USE_OMX |
| DELETE_OMX_VIDEO_DEC_NODE(iVideoDecNode.iNode); |
| #else |
| DELETE_VIDEO_DEC_NODE(iVideoDecNode.iNode); |
| #endif // PV2WAY_USE_OMX |
| |
| iVideoDecNode.Clear(); |
| } |
| |
| if (iAudioDecNode.iNode) |
| { |
| iAudioDecNode.iNode->ThreadLogoff(); |
| #ifdef PV2WAY_USE_OMX |
| DELETE_OMX_AUDIO_DEC_NODE(iAudioDecNode.iNode); |
| #else |
| DELETE_AUDIO_DEC_NODE(iAudioDecNode.iNode); |
| #endif // PV2WAY_USE_OMX |
| |
| iAudioDecNode.Clear(); |
| } |
| |
| if (iTscNode.iNode) |
| { |
| iTscNode.iNode->ThreadLogoff(); |
| } |
| |
| if (iAudioEncNode.iNode) |
| { |
| iAudioEncNode.iNode->ThreadLogoff(); |
| if (iAudioEncNodeInterface.iInterface) |
| iAudioEncNodeInterface.iInterface->removeRef(); |
| #ifdef PV2WAY_USE_OMX |
| DELETE_OMX_ENC_NODE(iAudioEncNode.iNode); |
| #else |
| DELETE_AUDIO_ENC_NODE(iAudioEncNode.iNode); |
| #endif |
| iAudioEncNode.Clear() ; |
| iAudioEncNodeInterface.Reset(); |
| } |
| |
| ClearVideoEncNode(); |
| |
| if (iCommNode.iNode) |
| { |
| iCommNode.iNode->ThreadLogoff(); |
| iCommNode.Clear(); |
| } |
| |
| iFormatCapability.clear(); |
| iIncomingAudioCodecs.clear(); |
| iOutgoingAudioCodecs.clear(); |
| iIncomingVideoCodecs.clear(); |
| iOutgoingVideoCodecs.clear(); |
| |
| /* Stop the clock */ |
| iClock.Stop(); |
| |
| /* Delete the list of sink/source nodes */ |
| for (i = 0; i < iSourceNodes.size(); i++) |
| { |
| TPV2WayNode* lNode = iSourceNodes[i]; |
| OSCL_DELETE(lNode); |
| iSourceNodes[i] = 0; |
| } |
| iSourceNodes.clear(); |
| iSourceNodes.destroy(); |
| |
| for (i = 0; i < iSinkNodes.size(); i++) |
| { |
| TPV2WayNode* lNode = iSinkNodes[i] ; |
| OSCL_DELETE(lNode); |
| iSinkNodes[i] = 0; |
| } |
| iSinkNodes.clear(); |
| iSinkNodes.destroy(); |
| iAddDataSourceVideoCmd = NULL; |
| return; |
| } |
| |
| void CPV324m2Way::DoCancel() |
| { |
| |
| } |
| |
| void CPV324m2Way::Run() |
| { |
| int32 error; |
| TPV2WayCmdInfo* cmd = NULL; |
| TPV2WayEventInfo* event = NULL; |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Run state %d, number of notifications pending %d\n", |
| iState, iPendingNotifications.size())); |
| |
| while (!iPendingNotifications.empty()) |
| { |
| if (iPendingNotifications[0]->notificationType == |
| TPV2WayNotificationInfo::EPV2WayCommandType) |
| { |
| cmd = (TPV2WayCmdInfo *) iPendingNotifications[0]; |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Run Calling CommandCompleted CmdType %d CmdId %d CmdStatus %d\n", |
| cmd->type, cmd->id, cmd->status)); |
| |
| switch (cmd->type) |
| { |
| case PVT_COMMAND_INIT: |
| if ((cmd->status != PVMFSuccess) && |
| (cmd->status != PVMFErrCancelled)) |
| { |
| SetDefaults(); |
| } |
| break; |
| |
| case PVT_COMMAND_RESET: |
| RemoveAudioEncPath(); |
| RemoveVideoEncPath(); |
| RemoveAudioDecPath(); |
| RemoveVideoDecPath(); |
| SetDefaults(); |
| break; |
| |
| case PVT_COMMAND_CONNECT: |
| if ((cmd->status != PVMFSuccess) && |
| (cmd->status != PVMFErrCancelled)) |
| { |
| iMuxDatapath->ResetDatapath(); |
| iCommNode.iNode->ThreadLogoff(); |
| iCommNode.Clear(); |
| } |
| break; |
| |
| case PVT_COMMAND_DISCONNECT: |
| iMuxDatapath->ResetDatapath(); |
| iCommNode.iNode->ThreadLogoff(); |
| iCommNode.Clear(); |
| break; |
| |
| case PVT_COMMAND_ADD_DATA_SOURCE: |
| if (cmd->status == PVMFSuccess) |
| { |
| if (iAudioEncDatapath && (iAudioEncDatapath->GetState() == EOpened) && |
| iVideoEncDatapath && (iVideoEncDatapath->GetState() == EOpened)) |
| { |
| TSC_324m *tsc_node = (TSC_324m *)(iTscNode.iNode); |
| tsc_node->SetSkewReference(iVideoEncDatapath->GetTSCPort(), |
| iAudioEncDatapath->GetTSCPort()); |
| } |
| } |
| else |
| { |
| if (cmd->status != PVMFErrCancelled) |
| { |
| RemoveAudioEncPath(); |
| RemoveVideoEncPath(); |
| } |
| } |
| break; |
| |
| case PVT_COMMAND_ADD_DATA_SINK: |
| { |
| CPV2WayDecDataChannelDatapath* datapath = NULL; |
| if (cmd->iPvtCmdData == iAudioDecDatapath->GetChannelId()) |
| { |
| datapath = iAudioDecDatapath; |
| } |
| else if (cmd->iPvtCmdData == iVideoDecDatapath->GetChannelId()) |
| { |
| datapath = iVideoDecDatapath; |
| } |
| if (datapath == NULL) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Run ERROR Failed to lookup dec datapath.\n")); |
| break; |
| } |
| |
| if ((cmd->status != PVMFSuccess) && |
| (cmd->status != PVMFErrCancelled)) |
| { |
| if (datapath == iAudioDecDatapath) |
| RemoveAudioDecPath(); |
| else if (datapath == iVideoDecDatapath) |
| RemoveVideoDecPath(); |
| break; |
| } |
| |
| if (!datapath->IsSkipComplete()) |
| return; |
| } |
| break; |
| |
| case PVT_COMMAND_REMOVE_DATA_SOURCE: |
| RemoveAudioEncPath(); |
| RemoveVideoEncPath(); |
| break; |
| |
| case PVT_COMMAND_REMOVE_DATA_SINK: |
| RemoveAudioDecPath(); |
| RemoveVideoDecPath(); |
| break; |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| case PVT_COMMAND_START_RECORD: |
| if ((cmd->status != PVMFSuccess) && |
| (cmd->status != PVMFErrCancelled)) |
| { |
| RemoveAudioRecPath(); |
| RemoveVideoRecPath(); |
| } |
| break; |
| |
| case PVT_COMMAND_STOP_RECORD: |
| RemoveAudioRecPath(); |
| RemoveVideoRecPath(); |
| break; |
| #endif |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| case PVT_COMMAND_ADD_PREVIEW_SINK: |
| if ((cmd->status != PVMFSuccess) && |
| (cmd->status != PVMFErrCancelled)) |
| { |
| RemoveAudioPreviewPath(); |
| RemoveVideoPreviewPath(); |
| } |
| break; |
| |
| case PVT_COMMAND_REMOVE_PREVIEW_SINK: |
| RemoveAudioPreviewPath(); |
| RemoveVideoPreviewPath(); |
| break; |
| |
| #endif |
| case PVT_COMMAND_CANCEL_ALL_COMMANDS: |
| //Init cancelled |
| if (iState == EIdle) |
| { |
| SetDefaults(); |
| } |
| if (iState == ESetup) |
| { |
| if (iMuxDatapath->GetState() == EClosed) |
| { |
| iMuxDatapath->ResetDatapath(); |
| iCommNode.iNode->ThreadLogoff(); |
| iCommNode.Clear(); |
| } |
| } |
| break; |
| |
| default: |
| break; |
| } |
| |
| { |
| PVCmdResponse resp(cmd->id, cmd->contextData, cmd->status, NULL, 0); |
| OSCL_TRY(error, iCmdStatusObserver->CommandCompleted(resp)); |
| OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, |
| PVLOGMSG_ERR, (0, "CPV324m2Way::Run CommandCompletedL leave %d\n", |
| error))); |
| } |
| |
| iPendingNotifications.erase(iPendingNotifications.begin()); |
| FreeCmdInfo(cmd); |
| |
| } |
| else if (iPendingNotifications[0]->notificationType == |
| TPV2WayNotificationInfo::EPV2WayEventType) |
| { |
| event = (TPV2WayEventInfo *) iPendingNotifications[0]; |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Run Calling HandleInformationalEventL EventType %d\n", |
| event->type)); |
| |
| switch (event->type) |
| { |
| case PVT_INDICATION_CLOSE_TRACK: |
| { |
| TPVChannelId* id = (TPVChannelId*)(event->localBuffer + 4); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Run PVT_INDICATION_CLOSE_TRACK direction %d, channel id=%d", |
| event->localBuffer[0], *id)); |
| if (event->localBuffer[0] == INCOMING) |
| { |
| if (iAudioDecDatapath && (*id == iAudioDecDatapath->GetChannelId())) |
| { |
| RemoveAudioDecPath(); |
| } |
| else if (iVideoDecDatapath && (*id == iVideoDecDatapath->GetChannelId())) |
| { |
| RemoveVideoDecPath(); |
| } |
| } |
| else if (event->localBuffer[0] == OUTGOING) |
| { |
| if (iAudioEncDatapath && (*id == iAudioEncDatapath->GetChannelId())) |
| { |
| RemoveAudioEncPath(); |
| } |
| else if (iVideoEncDatapath && (*id == iVideoEncDatapath->GetChannelId())) |
| { |
| RemoveVideoEncPath(); |
| } |
| } |
| |
| CheckState(); |
| } |
| break; |
| |
| case PVT_INDICATION_DISCONNECT: |
| iMuxDatapath->ResetDatapath(); |
| iCommNode.Clear(); |
| break; |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| case PVT_INDICATION_RECORDING_ERROR: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Run PVT_INDICATION_RECORD_ERROR media %d\n", |
| event->localBuffer[0])); |
| if (event->localBuffer[0] == PV_AUDIO) |
| { |
| RemoveAudioRecPath(); |
| } |
| else |
| { |
| RemoveVideoRecPath(); |
| } |
| break; |
| #endif |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| |
| case PVT_INDICATION_PREVIEW_ERROR: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Run PVT_INDICATION_PREVIEW_ERROR media %d\n", |
| event->localBuffer[0])); |
| if (event->localBuffer[0] == PV_AUDIO) |
| { |
| RemoveAudioPreviewPath(); |
| } |
| else |
| { |
| RemoveVideoPreviewPath(); |
| } |
| break; |
| #endif |
| default: |
| break; |
| } |
| |
| { |
| PVAsyncInformationalEvent aEvent(event->type, event->exclusivePtr, |
| &event->localBuffer[0], event->localBufferSize); |
| OSCL_TRY(error, iInfoEventObserver->HandleInformationalEvent(aEvent)); |
| OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, |
| PVLOGMSG_ERR, (0, "CPV324m2Way::Run HandleInformationalEventL leave %d\n", |
| error))); |
| } |
| |
| iPendingNotifications.erase(iPendingNotifications.begin()); |
| FreeEventInfo(event); |
| } |
| } |
| } |
| |
| void CPV324m2Way::Dispatch(TPV2WayCmdInfo* aCmdInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Dispatch Appending command to queue CmdType %d CmdId %d CmdStatus %d\n", |
| aCmdInfo->type, aCmdInfo->id, aCmdInfo->status)); |
| if (aCmdInfo->status != PVMFSuccess) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Dispatch Command failed\n")); |
| } |
| iPendingNotifications.push_back(aCmdInfo); |
| RunIfNotReady(); |
| } |
| |
| void CPV324m2Way::Dispatch(TPV2WayEventInfo* aEventInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::Dispatch Appending event to queue event type %d\n", |
| aEventInfo->type)); |
| |
| iPendingNotifications.push_back(aEventInfo); |
| RunIfNotReady(); |
| } |
| |
| |
| bool CPV324m2Way::IsNodeInList(Oscl_Vector<TPV2WayNode*, OsclMemAllocator>& aList, |
| PVMFNodeInterface* aNode) |
| { |
| for (uint32 i = 0; i < aList.size(); i++) |
| { |
| TPV2WayNode* lNode = aList[i]; |
| if (lNode && lNode->iNode == aNode) |
| return true; |
| } |
| return false; |
| } |
| |
| bool CPV324m2Way::IsSourceNode(PVMFNodeInterface* aNode) |
| { |
| return IsNodeInList(iSourceNodes, aNode); |
| } |
| |
| bool CPV324m2Way::IsSinkNode(PVMFNodeInterface* aNode) |
| { |
| return IsNodeInList(iSinkNodes, aNode); |
| } |
| |
| TPV2WayNode* CPV324m2Way::GetTPV2WayNode(Oscl_Vector<TPV2WayNode*, OsclMemAllocator>& aList, |
| PVMFNodeInterface* aNode) |
| { |
| for (uint32 i = 0; i < aList.size(); i++) |
| { |
| TPV2WayNode* lNode = aList[i]; |
| if (lNode && lNode->iNode == aNode) |
| return lNode; |
| } |
| return NULL; |
| } |
| |
| TPV2WayNode* CPV324m2Way::RemoveTPV2WayNode(Oscl_Vector<TPV2WayNode*, OsclMemAllocator>& aList, |
| PVMFNodeInterface* aNode) |
| { |
| for (uint32 i = 0; i < aList.size(); i++) |
| { |
| TPV2WayNode* lNode = aList[i]; |
| if (lNode && lNode->iNode == aNode) |
| { |
| aList[i] = 0; |
| return lNode; |
| } |
| } |
| return NULL; |
| } |
| |
| // from PVMFNodeCmdEventObserver |
| void CPV324m2Way::NodeCommandCompleted(const PVMFCmdResp& aResponse) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::NodeCommandCompleted status %d, context %x\n", |
| aResponse.GetCmdStatus(), aResponse.GetContext())); |
| |
| if (aResponse.GetCmdStatus() != PVMFSuccess) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::NodeCommandCompleted Command failed")); |
| } |
| CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext(); |
| TPV2WayNodeCmdInfo *info = FindPendingNodeCmd(data->iNode, aResponse.GetCmdId()); |
| |
| data->iObserver->CommandHandler(info->type, aResponse); |
| |
| // check if node cmd response requires engine cmd response |
| if (info->engineCmdInfo != NULL) |
| { |
| info->engineCmdInfo->status = aResponse.GetCmdStatus(); |
| Dispatch(info->engineCmdInfo); |
| } |
| |
| //Remove the command from the pending list. |
| RemovePendingNodeCmd(data->iNode, aResponse.GetCmdId()); |
| } |
| |
| // from PVMFNodeInfoEventObserver |
| void CPV324m2Way::HandleNodeInformationalEvent(const PVMFAsyncEvent& aEvent) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent type %d\n", |
| aEvent.GetEventType())); |
| |
| if (aEvent.GetContext() == iTscNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent tsc node\n")); |
| uint8 *buf = aEvent.GetLocalBuffer(); |
| switch (buf[0]) |
| { |
| case PV_H324COMPONENT_H223: |
| switch (buf[2]) |
| { |
| case INCOMING: |
| { |
| TPVChannelId id = CHANNEL_ID_UNKNOWN; |
| if (buf[1] == PV_MUX_COMPONENT_LOGICAL_CHANNEL) |
| { |
| id = *((TPVChannelId*)(buf + 4)); |
| |
| // See if error is in video datapath |
| if (id == iVideoDecDatapath->GetChannelId()) |
| { |
| // request for I-frame |
| RequestRemoteIFrame(iVideoDecDatapath->GetTSCPort()); |
| } |
| } |
| } |
| break; |
| |
| case OUTGOING: |
| GenerateIFrame(iVideoEncDatapath->GetTSCPort()); |
| break; |
| |
| default: |
| break; |
| } |
| break; |
| |
| default: |
| break; |
| } |
| } |
| else if (aEvent.GetContext() == iCommNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent comm node\n")); |
| } |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| else if (aEvent.GetContext() == iFFComposerNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent ff composer node\n")); |
| } |
| #endif |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| else if (aEvent.GetContext() == iPlayFromFileNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent playfromfile node\n")); |
| TPV2WayEventInfo* event = NULL; |
| switch (aEvent.GetEventType()) |
| { |
| case PFF_NODE_INFO_EVENT_EOS_INFO_EVENT: |
| if (!GetEventInfo(event)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent unable to notify app!\n")); |
| return; |
| } |
| event->type = PVT_INDICATION_PLAY_EOS; |
| event->localBufferSize = 1; |
| |
| //Check which port received the EOS. |
| if (iAudioPlayPort.GetPort() == aEvent.GetEventData()) |
| { |
| event->localBuffer[0] = PV_AUDIO; |
| Dispatch(event); |
| } |
| else if (iVideoPlayPort.GetPort() == aEvent.GetEventData()) |
| { |
| event->localBuffer[0] = PV_VIDEO; |
| Dispatch(event); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent unknown pff port for EOS %x\n", |
| aEvent.GetEventData())); |
| FreeEventInfo(event); |
| } |
| |
| break; |
| |
| default: |
| break; |
| } |
| |
| } |
| #endif |
| else if (aEvent.GetContext() == iVideoDecNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent video dec node\n")); |
| } |
| else if (aEvent.GetContext() == iVideoParserNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent video parser node\n")); |
| } |
| else if (aEvent.GetContext() == iVideoEncNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent video encoder node\n")); |
| } |
| else if (iAudioEncDatapath && iAudioEncDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent audio enc datapath\n")); |
| } |
| else if (iAudioDecDatapath && iAudioDecDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent audio dec datapath\n")); |
| PVMFEventType event = aEvent.GetEventType(); |
| if (event == PVMFInfoStartOfData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent audio dec datapath PVMFInfoStartOfData received, Clock started\n")); |
| } |
| } |
| else if ((iVideoEncDatapath != NULL) && |
| (iVideoEncDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext()))) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent video enc datapath\n")); |
| } |
| else if ((iVideoDecDatapath != NULL) && |
| (iVideoDecDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext()))) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent video dec datapath\n")); |
| PVMFEventType event = aEvent.GetEventType(); |
| if (event == PVMFInfoStartOfData) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent video dec datapath PVMFInfoStartOfData received, Clock started\n")); |
| } |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandleNodeInformationalEvent unknown node!")); |
| } |
| } |
| |
| // from PVMFNodeErrorEventObserver |
| void CPV324m2Way::HandleNodeErrorEvent(const PVMFAsyncEvent& aEvent) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleNodeErrorEvent type %d\n", aEvent.GetEventType())); |
| |
| if (aEvent.GetContext() == iTscNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleNodeErrorEvent tsc node\n")); |
| |
| switch (iState) |
| { |
| case EDisconnecting: |
| CheckState(); |
| break; |
| |
| case EConnecting: |
| case EConnected: |
| //InitiateDisconnect(); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| else if (aEvent.GetContext() == iCommNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeErrorEvent comm node\n")); |
| switch (iState) |
| { |
| case EDisconnecting: |
| CheckState(); |
| break; |
| |
| case EConnecting: |
| case EConnected: |
| InitiateDisconnect(); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| else if (aEvent.GetContext() == iFFComposerNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeErrorEvent ff composer node state %d\n", |
| iRecordFileState)); |
| switch (iRecordFileState) |
| { |
| case File2WayResetting: |
| CheckRecordFileState(); |
| break; |
| |
| case File2WayInitializing: |
| case File2WayInitialized: |
| InitiateResetRecordFile(); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| #endif |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| else if (aEvent.GetContext() == iPlayFromFileNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeErrorEvent playfromfile node state %d\n", |
| iPlayFromFileNode->GetState())); |
| switch (iPlayFileState) |
| { |
| case File2WayResetting: |
| CheckPlayFileState(); |
| break; |
| |
| case File2WayInitializing: |
| case File2WayInitialized: |
| InitiateResetPlayFile(); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| #endif |
| else if (iVideoEncDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeErrorEvent video enc datapath\n")); |
| iVideoEncDatapath->SetCmd(NULL); |
| } |
| else if (iVideoDecDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeErrorEvent video dec datapath\n")); |
| iVideoDecDatapath->SetCmd(NULL); |
| } |
| else if (iAudioEncDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeErrorEvent audio enc datapath\n")); |
| |
| iAudioEncDatapath->UseFilePlayPort(false); |
| iAudioEncDatapath->SetSourceInputPort(NULL); |
| |
| #ifndef PV_DISABLE_DEVSOUNDNODES |
| switch (aEvent.GetEventType()) |
| { |
| |
| case PVMF_DEVSOUND_ERR_PORT_GETDATA_ERROR: |
| case PVMF_DEVSOUND_ERR_PORT_PUTDATA_ERROR: |
| case PVMF_DEVSOUND_ERR_SOURCE_SINK_EVENT_ERROR: |
| case PVMF_DEVSOUND_ERR_BITSTREAM_ERROR: |
| case PVMF_DEVSOUND_ERR_PORT_FRAME_TRANSFER_ERROR: |
| case PVMF_DEVSOUND_ERR_SOURCE_SINK_FRAME_TRANSFER_ERROR: |
| case PVMF_DEVSOUND_ERR_DATA_PROCESSING_ERROR: |
| case PVMF_DEVSOUND_ERR_RECORD_DATA_LOST: |
| case PVMF_DEVSOUND_ERR_MEMPOOL_ALLOC_ERROR: |
| case PVMF_DEVSOUND_ERR_MEDIADATAALLOC_ALLOC_ERROR: |
| //data dropped, recording will continue |
| break; |
| |
| default: |
| iAudioEncDatapath->SetCmd(NULL); |
| break; |
| } |
| #else |
| iAudioEncDatapath->SetCmd(NULL); |
| #endif |
| } |
| else if (iAudioDecDatapath->IsNodeInDatapath((PVMFNodeInterface *) aEvent.GetContext())) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::HandleNodeErrorEvent audio dec datapath\n")); |
| |
| #ifndef PV_DISABLE_DEVSOUNDNODES |
| switch (aEvent.GetEventType()) |
| { |
| case PVMF_DEVSOUND_ERR_PORT_GETDATA_ERROR: |
| case PVMF_DEVSOUND_ERR_PORT_PUTDATA_ERROR: |
| case PVMF_DEVSOUND_ERR_SOURCE_SINK_EVENT_ERROR: |
| case PVMF_DEVSOUND_ERR_BITSTREAM_ERROR: |
| case PVMF_DEVSOUND_ERR_PORT_FRAME_TRANSFER_ERROR: |
| case PVMF_DEVSOUND_ERR_SOURCE_SINK_FRAME_TRANSFER_ERROR: |
| case PVMF_DEVSOUND_ERR_DATA_PROCESSING_ERROR: |
| case PVMF_DEVSOUND_ERR_MEMPOOL_ALLOC_ERROR: |
| case PVMF_DEVSOUND_ERR_MEDIADATAALLOC_ALLOC_ERROR: |
| //data dropped, playback will continue |
| break; |
| |
| default: |
| iAudioDecDatapath->SetCmd(NULL); |
| break; |
| } |
| #else |
| iAudioDecDatapath->SetCmd(NULL); |
| |
| #endif |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandleNodeErrorEvent unknown node!")); |
| } |
| } |
| |
| void CPV324m2Way::CommandHandler(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler, state %d, type %d\n", iState, aType)); |
| |
| CPV2WayNodeContextData *data = (CPV2WayNodeContextData *) aResponse.GetContext(); |
| |
| if (data->iNode == iCommNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler comm node\n")); |
| HandleCommNodeCmd(aType, aResponse); |
| } |
| else if (data->iNode == iTscNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler TSC node\n")); |
| HandleTscNodeCmd(aType, aResponse); |
| } |
| else if (data->iNode == iVideoDecNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler video decoder node\n")); |
| HandleVideoDecNodeCmd(aType, aResponse); |
| } |
| else if (data->iNode == iVideoEncNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler video encoder node\n")); |
| HandleVideoEncNodeCmd(aType, aResponse); |
| } |
| else if (IsSourceNode(data->iNode)) |
| { |
| /* Do Add Data Source Here */ |
| TPV2WayNode *source_node = GetTPV2WayNode(iSourceNodes, data->iNode); |
| OSCL_ASSERT(source_node); |
| DoAddDataSource(*source_node, aResponse); |
| } |
| else if (IsSinkNode(data->iNode)) |
| { |
| TPV2WayNode *sink_node = GetTPV2WayNode(iSinkNodes, data->iNode); |
| OSCL_ASSERT(sink_node); |
| HandleSinkNodeCmd(aType, aResponse, sink_node); |
| } |
| else if (data->iNode == iAudioEncNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler audio encoder node\n")); |
| HandleAudioEncNodeCmd(aType, aResponse); |
| } |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| else if (data->iNode == iFFComposerNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler ff composer node\n")); |
| HandleFFComposerNodeCmd(aType, aResponse); |
| } |
| #endif |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| else if (data->iNode == iPlayFromFileNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler pff node\n")); |
| HandlePFFNodeCmd(aType, aResponse); |
| } |
| else if (data->iNode == iAudioSrcNode.iNode) |
| { |
| // This will happen only after the node had been added to a datapath succussfully |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CommandHandler audio src node\n")); |
| HandleAudioSrcNodeCmd(aType, aResponse); |
| } |
| #endif |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CommandHandler unknown node!")); |
| } |
| } |
| |
| PVMFStatus CPV324m2Way::ConfigureNode(CPVDatapathNode *aNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode, state %d\n", iState)); |
| |
| PVMFNodeInterface *node = aNode->iNode.iNode; |
| |
| if (node == iTscNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode configuring tsc node\n")); |
| return PVMFSuccess; |
| } |
| else if (node == iCommNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode configuring comm node\n")); |
| return PVMFSuccess; |
| } |
| else if (node == iVideoEncNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, (0, "CPV324m2Way::ConfigureNode configuring video enc node\n")); |
| |
| |
| PVMp4H263EncExtensionInterface *ptr = |
| (PVMp4H263EncExtensionInterface *) iVideoEncNodeInterface.iInterface; |
| |
| |
| uint32 bitrate_bps_100 = VIDEO_ENCODER_BITRATE / 100; |
| PVMFVideoResolution aVideoResolution(VIDEO_ENCODER_WIDTH, |
| VIDEO_ENCODER_HEIGHT); |
| double aFrameRate = VIDEO_ENCODER_FRAME_RATE; |
| |
| LogicalChannelInfo* lcn_info = NULL; |
| |
| if (aNode->iOutputPort.iPortPair->iDestPort.GetStatus() != EHasPort) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode waiting for tsc port to determine video codec type.\n")); |
| return PVMFPending; |
| } |
| #ifndef NO_2WAY_324 |
| if (iTerminalType == PV_324M) |
| { |
| OsclAny * tempInterface = NULL; |
| aNode->iOutputPort.iPortPair->iDestPort.GetPort()->QueryInterface( |
| PVH324MLogicalChannelInfoUuid, tempInterface); |
| lcn_info = OSCL_STATIC_CAST(LogicalChannelInfo*, tempInterface); |
| if (lcn_info == NULL) |
| { |
| return PVMFFailure; |
| } |
| PVMFFormatType aFormatType = lcn_info->GetFormatType(); |
| |
| if (iTSC324mInterface != NULL) |
| { |
| CPvtTerminalCapability* remote_caps = iTSC324mInterface->GetRemoteCapability(); |
| |
| if (remote_caps) |
| { |
| for (uint16 i = 0; i < remote_caps->GetNumCapabilityItems(); i++) |
| { |
| CPvtMediaCapability * RemoteCapItem = |
| remote_caps->GetCapabilityItem(i); |
| if (RemoteCapItem->GetFormatType() == aFormatType) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode Found codec match for bitrate - capability(%d), default(%d)", remote_caps->GetCapabilityItem(i)->GetBitrate(), bitrate_bps_100)); |
| if (RemoteCapItem->GetBitrate() < bitrate_bps_100) |
| { |
| bitrate_bps_100 = RemoteCapItem->GetBitrate(); |
| } |
| |
| PVMFVideoResolution *video_resolution; |
| uint32 frame_rate; |
| video_resolution = ((CPvtVideoCapability*)RemoteCapItem)->GetMaxResolution(frame_rate); |
| if ((video_resolution->width < aVideoResolution.width) && |
| (video_resolution->height < aVideoResolution.height)) |
| { |
| aVideoResolution.width = video_resolution->width; |
| aVideoResolution.height = video_resolution->height; |
| |
| } |
| |
| if (frame_rate < aFrameRate) |
| aFrameRate = frame_rate; |
| |
| break; |
| } |
| } |
| } |
| } |
| } |
| #endif |
| ptr->SetNumLayers(1); |
| ptr->SetOutputBitRate(0, bitrate_bps_100*100); |
| ptr->SetOutputFrameSize(0, aVideoResolution.width, aVideoResolution.height); |
| ptr->SetOutputFrameRate(0, (float)aFrameRate); |
| |
| ptr->SetSegmentTargetSize(0, VIDEO_ENCODER_SEGMENT_SIZE); |
| ptr->SetRateControlType(0, VIDEO_ENCODER_RATE_CONTROL); |
| ptr->SetDataPartitioning(VIDEO_ENCODER_DATA_PARTITIONING); |
| ptr->SetRVLC(VIDEO_ENCODER_RVLC); |
| ptr->SetIFrameInterval(VIDEO_ENCODER_I_FRAME_INTERVAL); |
| return PVMFSuccess; |
| |
| } |
| else if (node == iVideoDecNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode configuring video dec node\n")); |
| return PVMFSuccess; |
| } |
| #ifndef PV_DISABLE_DEVSOUNDNODES |
| else if (node == iAudioSrcNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode configuring audio node\n")); |
| PVMFPortProperty prop; |
| if (aNode->iOutputPort.iPortPair->iDestPort.GetStatus() != EHasPort) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode waiting for tsc port to determine audio codec type.\n")); |
| return PVMFPending; |
| } |
| |
| aNode->iOutputPort.iPortPair->iDestPort.GetPort()->Query(prop); |
| |
| //Set video encoder parameters |
| if (prop.iFormatType == PVMF_MIME_AMR_IF2) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode AMR IF2.\n")); |
| //Can't set audio codec type yet |
| } |
| else if (prop.iFormatType == PVMF_MIME_G723) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode G723.\n")); |
| //Can't set audio codec type yet |
| } |
| |
| uint32 bitrate_bps = MAX_AUDIO_BITRATE; |
| |
| CPvtTerminalCapability* remote_caps = iTscNode.node->GetRemoteCapability(); |
| if (remote_caps) |
| { |
| for (uint16 i = 0; i < remote_caps->GetNumCapabilityItems(); i++) |
| { |
| if ((remote_caps->GetCapabilityItem(i)->GetFormatType() == PVMF_AMR_IF2 || |
| remote_caps->GetCapabilityItem(i)->GetFormatType() == PVMF_MIME_G723) && |
| remote_caps->GetCapabilityItem(i)->GetBitrate() < bitrate_bps / 100) |
| { |
| bitrate_bps = remote_caps->GetCapabilityItem(i)->GetBitrate() * 100; |
| } |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode audio bitrate %d.\n", bitrate_bps)); |
| |
| // set max bitrate in devsound |
| PVDevSoundOptions options; |
| ((PVDevSoundNodeBase *) iAudioSrcNode)->GetOptions(options); |
| if (bitrate_bps >= 12200) |
| { |
| options.iRecordAmrBitrate = PVMFAmrEncBitrate122; |
| } |
| else if (bitrate_bps >= 10200) |
| { |
| options.iRecordAmrBitrate = PVMFAmrEncBitrate102; |
| } |
| else if (bitrate_bps >= 7950) |
| { |
| options.iRecordAmrBitrate = PVMFAmrEncBitrate795; |
| } |
| else if (bitrate_bps >= 7400) |
| { |
| options.iRecordAmrBitrate = PVMFAmrEncBitrate74; |
| } |
| else if (bitrate_bps >= 6700) |
| { |
| options.iRecordAmrBitrate = PVMFAmrEncBitrate67; |
| } |
| else if (bitrate_bps >= 5900) |
| { |
| options.iRecordAmrBitrate = PVMFAmrEncBitrate59; |
| } |
| else if (bitrate_bps >= 5150) |
| { |
| options.iRecordAmrBitrate = PVMFAmrEncBitrate515; |
| } |
| else |
| { |
| options.iRecordAmrBitrate = PVMFAmrEncBitrate475; |
| } |
| |
| ((PVDevSoundNodeBase *) iAudioSrcNode)->UpdateOptions(options); |
| |
| return PVMFSuccess; |
| } |
| #endif |
| else if (node == iAudioEncNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode configuring audio enc node\n")); |
| //PVMFPortProperty prop; |
| #ifdef PV2WAY_USE_OMX |
| PVAudioEncExtensionInterface *ptr = |
| (PVAudioEncExtensionInterface *) iAudioEncNodeInterface.iInterface; |
| #else |
| PVAMREncExtensionInterface *ptr = |
| (PVAMREncExtensionInterface *) iAudioEncNodeInterface.iInterface; |
| #endif // PV2WAY_USE_OMX |
| if (aNode->iOutputPort.iPortPair->iDestPort.GetStatus() != EHasPort) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode waiting for tsc port to determine audio codec type.\n")); |
| return PVMFPending; |
| } |
| |
| //aNode->iOutputPort.iPortPair->iDestPort.GetPort()->Query(prop); |
| |
| //ptr->SetOutputFormat(PVMF_AMR_IF2); |
| //ptr->SetInputSamplingRate(KSamplingRate); |
| //ptr->SetInputBitsPerSample(KBitsPerSample); |
| //ptr->SetInputNumChannels(KNumChannels); |
| ptr->SetOutputBitRate(GSM_AMR_12_2); |
| ptr->SetMaxNumOutputFramesPerBuffer(KNumPCMFrames); |
| |
| return PVMFSuccess; |
| |
| } |
| else if (node == iAudioDecNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode configuring audio dec node\n")); |
| return PVMFSuccess; |
| } |
| else if (node == iVideoParserNode.iNode) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::ConfigureNode configuring video parser node\n")); |
| return PVMFSuccess; |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ConfigureNode unknown node\n")); |
| return PVMFFailure; |
| } |
| return PVMFFailure; |
| } |
| |
| // Implementations of TSC Observer virtuals |
| void CPV324m2Way::ConnectComplete(PVMFStatus status) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ConnectComplete, state %d, status %d\n", iState, status)); |
| if (status == PVMFSuccess) |
| { |
| iIsStackConnected = true; |
| } |
| else |
| { |
| iIsStackConnected = false; |
| SetState(EDisconnecting); |
| } |
| |
| CheckState(); |
| } |
| |
| void CPV324m2Way::InternalError() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::InternalError, state %d\n", iState)); |
| |
| switch (iState) |
| { |
| case EDisconnecting: |
| iAudioDecDatapath->TSCPortClosed(); |
| iAudioEncDatapath->TSCPortClosed(); |
| iVideoDecDatapath->TSCPortClosed(); |
| iVideoEncDatapath->TSCPortClosed(); |
| |
| CheckState(); |
| break; |
| |
| case EConnecting: |
| case EConnected: |
| iAudioDecDatapath->TSCPortClosed(); |
| iAudioEncDatapath->TSCPortClosed(); |
| iVideoDecDatapath->TSCPortClosed(); |
| iVideoEncDatapath->TSCPortClosed(); |
| |
| InitiateDisconnect(); |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::InternalError invalid state\n")); |
| break; |
| } |
| } |
| |
| void CPV324m2Way::DisconnectRequestReceived() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::DisconnectRequestReceived state %d\n", iState)); |
| |
| iIsStackConnected = false; |
| if (iDisconnectInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::DisconnectRequestReceived Doing nothing as disconnect is in progress")); |
| } |
| else |
| { |
| |
| switch (iState) |
| { |
| case EDisconnecting: |
| iAudioDecDatapath->TSCPortClosed(); |
| iAudioEncDatapath->TSCPortClosed(); |
| iVideoDecDatapath->TSCPortClosed(); |
| iVideoEncDatapath->TSCPortClosed(); |
| |
| CheckState(); |
| break; |
| |
| case EConnecting: |
| case EConnected: |
| iAudioDecDatapath->TSCPortClosed(); |
| iAudioEncDatapath->TSCPortClosed(); |
| iVideoDecDatapath->TSCPortClosed(); |
| iVideoEncDatapath->TSCPortClosed(); |
| |
| |
| iRemoteDisconnectTimer->SetObserver(this); |
| iRemoteDisconnectTimer->Request(REMOTE_DISCONNECT_TIMER_ID, REMOTE_DISCONNECT_TIMER_ID, |
| REMOTE_DISCONNECT_TIMER_VALUE, this); |
| |
| |
| //We do InitiateDisconnect() once above timer expires |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::DisconnectRequestReceived invalid state\n")); |
| break; |
| } |
| } |
| } |
| |
| PVMFStatus CPV324m2Way::EstablishChannel(TPVDirection aDir, |
| TPVChannelId aId, |
| PVCodecType_t aCodec, |
| uint8* aFormatSpecificInfo, uint32 aFormatSpecificInfoLen) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::EstablishChannel aDir=%d, channel id=%d, codec %d\n", |
| aDir, aId, aCodec)); |
| |
| PV2WayMediaType media_type = ::GetMediaType(aCodec); |
| OSCL_ASSERT(media_type == PV_AUDIO || media_type == PV_VIDEO); |
| PVMFFormatType aFormatType = PVCodecTypeToPVMFFormatType(aCodec); |
| PVMFFormatType aAppFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| |
| TPV2WayEventInfo* aEvent = NULL; |
| if (!GetEventInfo(aEvent)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::EstablishChannel Memory allocation failed!\n")); |
| return PVMFErrNoMemory; |
| } |
| |
| Oscl_Map<PVMFFormatType, FormatCapabilityInfo, OsclMemAllocator, pvmf_format_type_key_compare_class>* codec_list = NULL; |
| Oscl_Map<PVMFFormatType, PVMFFormatType, OsclMemAllocator, pvmf_format_type_key_compare_class>* app_format_for_engine_format = NULL; |
| |
| CPV2WayDataChannelDatapath* datapath = NULL; |
| |
| if (aDir == INCOMING) |
| { |
| if (media_type == PV_AUDIO) |
| { |
| if (!(iAudioDecDatapath)) |
| { |
| iAudioDecDatapath = CPV2WayDecDataChannelDatapath::NewL(iLogger, |
| aFormatType, this); |
| |
| } |
| |
| AddAudioDecoderNode(); |
| uint32 audioLatency = LookupMioLatency(PVCodecTypeToPVMFFormatType(aCodec), true); |
| ((TSC_324m*)(iTscNode.iNode))->SetMioLatency((audioLatency + iAudioDatapathLatency), true); |
| |
| datapath = iAudioDecDatapath; |
| codec_list = &iIncomingAudioCodecs; |
| } |
| else if (media_type == PV_VIDEO) |
| { |
| if (!(iVideoDecDatapath)) |
| { |
| iVideoDecDatapath = CPV2WayDecDataChannelDatapath::NewL(iLogger, aFormatType, this); |
| } |
| iVideoDecDatapath->SetFormatSpecificInfo(aFormatSpecificInfo, (uint16)aFormatSpecificInfoLen); |
| |
| AddVideoDecoderNode(aFormatSpecificInfo, aFormatSpecificInfoLen); |
| uint32 videoLatency = LookupMioLatency(PVCodecTypeToPVMFFormatType(aCodec), false); |
| ((TSC_324m*)(iTscNode.iNode))->SetMioLatency((videoLatency + iVideoDatapathLatency), false); |
| |
| datapath = iVideoDecDatapath; |
| codec_list = &iIncomingVideoCodecs; |
| } |
| app_format_for_engine_format = &iAppFormatForEngineFormatIncoming; |
| iClock.Start(); |
| } |
| |
| else |
| { |
| if (media_type == PV_AUDIO) |
| { |
| if (!(iAudioEncDatapath)) |
| { |
| iAudioEncDatapath = CPV2WayEncDataChannelDatapath::NewL(iLogger, |
| aFormatType, this); |
| } |
| |
| AddAudioEncoderNode(); |
| |
| datapath = iAudioEncDatapath; |
| codec_list = &iOutgoingAudioCodecs; |
| } |
| else if (media_type == PV_VIDEO) |
| { |
| if (!(iVideoEncDatapath)) |
| { |
| iVideoEncDatapath = CPV2WayEncDataChannelDatapath::NewL(iLogger, aFormatType, this); |
| } |
| iVideoEncDatapath->SetFormatSpecificInfo(aFormatSpecificInfo, (uint16)aFormatSpecificInfoLen); |
| |
| AddVideoEncoderNode(); |
| datapath = iVideoEncDatapath; |
| codec_list = &iOutgoingVideoCodecs; |
| } |
| app_format_for_engine_format = &iAppFormatForEngineFormatOutgoing; |
| } |
| Oscl_Map<PVMFFormatType, FormatCapabilityInfo, OsclMemAllocator, pvmf_format_type_key_compare_class>::iterator it = codec_list->find(aFormatType); |
| |
| if (it == codec_list->end()) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::EstablishChannel Failed to lookup codec=%d\n", aCodec)); |
| return PVMFFailure; |
| } |
| |
| if ((*it).second.iPriority == ENG) |
| { |
| // Set the app format to the stored raw format type |
| aAppFormatType = (*app_format_for_engine_format)[aFormatType]; |
| } |
| else |
| { |
| // Set the app format to the compressed type |
| aAppFormatType = aFormatType; |
| } |
| datapath->SetFormat(aFormatType); |
| datapath->SetSourceSinkFormat(aAppFormatType); |
| |
| // Send the informational event to the app |
| aEvent->localBuffer[0] = (uint8) media_type; |
| // bytes 1,2,3 are unused |
| *((TPVChannelId*)(aEvent->localBuffer + 4)) = aId; |
| aEvent->localBufferSize = 8; |
| |
| PVEventType aEventType = (aDir == INCOMING) ? PVT_INDICATION_INCOMING_TRACK : PVT_INDICATION_OUTGOING_TRACK; |
| PVUuid puuid = PV2WayTrackInfoInterfaceUUID; |
| PV2WayTrackInfoInterface* pTrackInfo = OSCL_NEW(PV2WayTrackInfoImpl, |
| (aAppFormatType, aFormatSpecificInfo, aFormatSpecificInfoLen, aEventType, puuid)); |
| PVAsyncInformationalEvent infoEvent(aEventType, NULL, |
| OSCL_STATIC_CAST(PVInterface*, pTrackInfo), NULL, |
| aEvent->localBuffer, aEvent->localBufferSize); |
| if (iInfoEventObserver != NULL) |
| { |
| iInfoEventObserver->HandleInformationalEvent(infoEvent); |
| } |
| pTrackInfo->removeRef(); |
| |
| return EPVT_Success; |
| } |
| |
| void CPV324m2Way::OutgoingChannelEstablished(TPVChannelId aId, |
| PVCodecType_t aCodec, |
| uint8* aFormatSpecificInfo, |
| uint32 aFormatSpecificInfoLen) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::OutgoingChannelEstablished id=%d, codec=%d, fsi=%x, fsi_len=%d", |
| aId, aCodec, aFormatSpecificInfo, aFormatSpecificInfoLen)); |
| EstablishChannel(OUTGOING, aId, aCodec, aFormatSpecificInfo, aFormatSpecificInfoLen); |
| } |
| |
| TPVStatusCode CPV324m2Way::IncomingChannel(TPVChannelId aId, |
| PVCodecType_t aCodec, |
| uint8* aFormatSpecificInfo, |
| uint32 aFormatSpecificInfoLen) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::IncomingChannel channel id=%d, codec %d\n", |
| aId, aCodec)); |
| return EstablishChannel(INCOMING, aId, aCodec, aFormatSpecificInfo, aFormatSpecificInfoLen); |
| } |
| |
| bool CPV324m2Way::GetEventInfo(TPV2WayEventInfo*& event) |
| { |
| int32 error = 0; |
| OSCL_TRY(error, event = GetEventInfoL()); |
| OSCL_FIRST_CATCH_ANY(error, |
| return false); |
| return true; |
| } |
| |
| void CPV324m2Way::ChannelClosed(TPVDirection direction, |
| TPVChannelId id, |
| PVCodecType_t codec, |
| PVMFStatus status) |
| { |
| OSCL_UNUSED_ARG(status); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed id %d, codec %d, direction %d\n", id, codec, direction)); |
| PV2WayMediaType media_type = ::GetMediaType(codec); |
| TPV2WayEventInfo* event = NULL; |
| bool track_closed = false; |
| // Send the closing track indication |
| if (!GetEventInfo(event)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ChannelClosed unable to allocate memory")); |
| return; |
| } |
| |
| event->type = PVT_INDICATION_CLOSING_TRACK; |
| event->localBufferSize = 8; |
| event->localBuffer[0] = (uint8)direction; |
| // bytes 1,2,3 are unused |
| *((TPVChannelId*)(event->localBuffer + 4)) = id; |
| Dispatch(event); |
| |
| switch (media_type) |
| { |
| case PV_AUDIO: |
| switch (direction) |
| { |
| case INCOMING: |
| if (iAudioDecDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed audio dec path state %d, id %d\n", |
| iAudioDecDatapath->GetState(), iAudioDecDatapath->GetChannelId())); |
| if (iAudioDecDatapath->GetChannelId() == CHANNEL_ID_UNKNOWN) |
| { |
| track_closed = true; |
| } |
| else if (id == iAudioDecDatapath->GetChannelId()) |
| { |
| switch (iAudioDecDatapath->GetState()) |
| { |
| case EClosing: |
| break; |
| case EClosed: |
| track_closed = true; |
| break; |
| default: |
| iAudioDecDatapath->SetCmd(NULL); |
| break; |
| } |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed ERROR Channel id mismatch id=%d, datapath id=%d\n", |
| id, iAudioDecDatapath->GetChannelId())); |
| } |
| } |
| break; |
| |
| case OUTGOING: |
| if (iAudioEncDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed audio enc path state %d, id %d\n", |
| iAudioEncDatapath->GetState(), iAudioEncDatapath->GetChannelId())); |
| if (iAudioEncDatapath->GetChannelId() == CHANNEL_ID_UNKNOWN) |
| { |
| track_closed = true; |
| } |
| else if (id == iAudioEncDatapath->GetChannelId()) |
| { |
| switch (iAudioEncDatapath->GetState()) |
| { |
| case EClosing: |
| break; |
| case EClosed: |
| track_closed = true; |
| break; |
| default: |
| iAudioEncDatapath->SetCmd(NULL); |
| break; |
| } |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed ERROR Channel id mismatch id=%d, datapath id=%d\n", |
| id, iAudioEncDatapath->GetChannelId())); |
| } |
| } |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ChannelClosed unknown audio direction %d\n", |
| direction)); |
| break; |
| } |
| break; |
| case PV_VIDEO: |
| switch (direction) |
| { |
| case INCOMING: |
| if (iVideoDecDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed video dec path state %d, id %d\n", |
| iVideoDecDatapath->GetState(), |
| iVideoDecDatapath->GetChannelId())); |
| if (iVideoDecDatapath->GetChannelId() == CHANNEL_ID_UNKNOWN) |
| { |
| track_closed = true; |
| } |
| else if (id == iVideoDecDatapath->GetChannelId()) |
| { |
| switch (iVideoDecDatapath->GetState()) |
| { |
| case EClosing: |
| break; |
| case EClosed: |
| track_closed = true; |
| break; |
| default: |
| iVideoDecDatapath->SetCmd(NULL); |
| break; |
| } |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed ERROR Channel id mismatch id=%d, datapath id=%d\n", |
| id, iVideoDecDatapath->GetChannelId())); |
| } |
| } |
| break; |
| |
| case OUTGOING: |
| if (iVideoEncDatapath) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed video enc path state %d, id %d\n", |
| iVideoEncDatapath->GetState(), |
| iVideoEncDatapath->GetChannelId())); |
| if (iVideoEncDatapath->GetChannelId() == CHANNEL_ID_UNKNOWN) |
| { |
| track_closed = true; |
| } |
| else if (id == iVideoEncDatapath->GetChannelId()) |
| { |
| switch (iVideoEncDatapath->GetState()) |
| { |
| case EClosing: |
| break; |
| case EClosed: |
| track_closed = true; |
| break; |
| default: |
| iVideoEncDatapath->SetCmd(NULL); |
| break; |
| } |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::ChannelClosed ERROR Channel id mismatch id=%d, datapath id=%d\n", |
| id, iVideoEncDatapath->GetChannelId())); |
| } |
| } |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ChannelClosed unknown video direction %d\n", |
| direction)); |
| break; |
| } |
| break; |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ChannelClosed unknown media type %d\n", |
| media_type)); |
| break; |
| } |
| |
| if (!track_closed) |
| return; |
| |
| if (!GetEventInfo(event)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::ChannelClosed unable to allocate memory")); |
| return; |
| } |
| event->type = PVT_INDICATION_CLOSE_TRACK; |
| event->localBufferSize = 8; |
| event->localBuffer[0] = (uint8)direction; |
| // bytes 1,2,3 are unused |
| *((TPVChannelId*)(event->localBuffer + 4)) = id; |
| Dispatch(event); |
| } |
| |
| void CPV324m2Way::RequestFrameUpdate(PVMFPortInterface* aPort) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RequestFrameUpdate\n")); |
| if (iVideoEncDatapath) |
| { |
| GenerateIFrame(aPort); |
| } |
| } |
| |
| |
| void CPV324m2Way::TimeoutOccurred(int32 timerID, |
| int32 timeoutInfo) |
| { |
| OSCL_UNUSED_ARG(timeoutInfo); |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::TimeoutOccurred id %d, info %d\n", timerID, timeoutInfo)); |
| |
| if (timerID == IFRAME_REQ_TIMERID) |
| { |
| isIFrameReqTimerActive = false; |
| } |
| else if ((timerID == END_SESSION_TIMER_ID) || (timerID == REMOTE_DISCONNECT_TIMER_ID)) |
| { |
| // Cancel out both timers if any one expires, as both do InitiateDisconnect() |
| if (iEndSessionTimer) |
| { |
| iEndSessionTimer->Cancel(END_SESSION_TIMER_ID); |
| } |
| |
| if (iRemoteDisconnectTimer) |
| { |
| iRemoteDisconnectTimer->Cancel(REMOTE_DISCONNECT_TIMER_ID); |
| } |
| |
| InitiateDisconnect(); |
| } |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| if (timerID == RECORDED_FILESIZE_NOTIFICATION_TIMERID) |
| { |
| int32 error; |
| uint32 fileSize; |
| TPV2WayEventInfo* aEvent = NULL; |
| PvmfComposerSizeAndDurationInterface *ptr = |
| (PvmfComposerSizeAndDurationInterface *) iFFSizeAndDuration.iInterface; |
| |
| if (!GetEventInfo(aEvent)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::TimeoutOccurred unable to notify app of recorded filesize!\n")); |
| return; |
| } |
| aEvent->type = PVT_INDICATION_RECORDED_FILE_SIZE; |
| |
| ptr->GetFileSize(fileSize); |
| *((uint32 *)(aEvent->localBuffer)) = fileSize; |
| |
| aEvent->localBufferSize = sizeof(uint32); |
| Dispatch(aEvent); |
| } |
| #endif |
| } |
| |
| TPV2WayCmdInfo *CPV324m2Way::GetCmdInfoL() |
| { |
| if (iFreeCmdInfo.empty()) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::GetFreeCmdInfo unable to allocate cmd info!")); |
| OSCL_LEAVE(PVMFErrNoMemory); |
| } |
| else |
| { |
| TPV2WayCmdInfo *cmd = (TPV2WayCmdInfo *)iFreeCmdInfo[0]; |
| iFreeCmdInfo.erase(iFreeCmdInfo.begin()); |
| return cmd; |
| } |
| |
| return NULL; |
| } |
| |
| void CPV324m2Way::FreeCmdInfo(TPV2WayCmdInfo *info) |
| { |
| info->Clear(); |
| iFreeCmdInfo.push_back(info); |
| } |
| |
| TPV2WayEventInfo *CPV324m2Way::GetEventInfoL() |
| { |
| if (iFreeEventInfo.empty()) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::GetFreeEventInfo unable to allocate event info!")); |
| OSCL_LEAVE(PVMFErrNoMemory); |
| } |
| else |
| { |
| TPV2WayEventInfo *cmd = (TPV2WayEventInfo *)iFreeEventInfo[0]; |
| iFreeEventInfo.erase(iFreeEventInfo.begin()); |
| return cmd; |
| } |
| |
| return NULL; |
| } |
| |
| void CPV324m2Way::FreeEventInfo(TPV2WayEventInfo *info) |
| { |
| info->Clear(); |
| iFreeEventInfo.push_back(info); |
| } |
| |
| PVMFCommandId CPV324m2Way::SendNodeCmdL(PV2WayNodeCmdType aCmd, |
| TPV2WayNode *aNode, |
| CPV2WayNodeCommandObserver *aObserver, |
| void *aParam, |
| TPV2WayCmdInfo *a2WayCmdInfo) |
| { |
| int32 error = 0; |
| PVMFCommandId id = 0; |
| TPV2WayNodeCmdInfo *info; |
| PVMFNodeInterface * nodeIFace = (PVMFNodeInterface *)aNode->iNode; |
| PvmfNodesSyncControlInterface* ptr = NULL; |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::SendNodeCmdL state %d, cmd %d, session %d\n", |
| iState, aCmd, aNode->iSessionId)); |
| |
| if (aNode == NULL) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL node ptr is null!\n")); |
| OSCL_LEAVE(PVMFErrArgument); |
| } |
| |
| if (iFreeNodeCmdInfo.empty()) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL unable to allocate node command info!\n")); |
| OSCL_LEAVE(PVMFErrNoMemory); |
| } |
| |
| info = (TPV2WayNodeCmdInfo *)iFreeNodeCmdInfo[0]; |
| iFreeNodeCmdInfo.erase(iFreeNodeCmdInfo.begin()); |
| |
| info->type = aCmd; |
| info->context.iObserver = aObserver; |
| info->context.iNode = nodeIFace; |
| info->engineCmdInfo = a2WayCmdInfo; |
| |
| PVMFSessionId sessionId = aNode->GetSessionId(); |
| |
| switch (aCmd) |
| { |
| case PV2WAY_NODE_CMD_QUERY_UUID: |
| if (aParam != NULL) |
| { |
| TPV2WayNodeQueryUuidParams *queryParam = (TPV2WayNodeQueryUuidParams *) aParam; |
| OSCL_TRY(error, id = nodeIFace->QueryUUID(sessionId, |
| queryParam->mimetype, *queryParam->iUuids, |
| true, (OsclAny *) & info->context)); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL RequestPort param is null!\n")); |
| error = PVMFErrArgument; |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_QUERY_INTERFACE: |
| if (aParam != NULL) |
| { |
| TPV2WayNodeQueryInterfaceParams *queryParam = |
| (TPV2WayNodeQueryInterfaceParams *) aParam; |
| OSCL_TRY(error, id = nodeIFace->QueryInterface(sessionId, |
| *queryParam->iUuid, *queryParam->iInterfacePtr, |
| (OsclAny *) & info->context)); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL RequestPort param is null!\n")); |
| error = PVMFErrArgument; |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_INIT: |
| info->context.iContextData = aParam; |
| OSCL_TRY(error, id = nodeIFace->Init(sessionId, |
| (OsclAny *) & info->context)); |
| break; |
| |
| case PV2WAY_NODE_CMD_REQUESTPORT: |
| if (aParam != NULL) |
| { |
| OSCL_HeapString<OsclMemAllocator> mimeType; |
| TPV2WayNodeRequestPortParams *params = (TPV2WayNodeRequestPortParams *) aParam; |
| mimeType = params->format.getMIMEStrPtr(); |
| //Get mime string from format type |
| OSCL_TRY(error, id = nodeIFace->RequestPort(sessionId, |
| params->portTag, &mimeType, (OsclAny *) & info->context)); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL RequestPort param is null!\n")); |
| error = PVMFErrArgument; |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_PREPARE: |
| OSCL_TRY(error, id = nodeIFace->Prepare(sessionId, |
| (OsclAny *) & info->context)); |
| break; |
| |
| case PV2WAY_NODE_CMD_START: |
| OSCL_TRY(error, id = nodeIFace->Start(sessionId, |
| (OsclAny *) & info->context)); |
| break; |
| |
| case PV2WAY_NODE_CMD_PAUSE: |
| OSCL_TRY(error, id = nodeIFace->Pause(sessionId, |
| (OsclAny *) & info->context)); |
| break; |
| |
| case PV2WAY_NODE_CMD_STOP: |
| OSCL_TRY(error, id = nodeIFace->Stop(sessionId, |
| (OsclAny *) & info->context)); |
| break; |
| |
| case PV2WAY_NODE_CMD_RELEASEPORT: |
| if (aParam != NULL) |
| { |
| OSCL_TRY(error, id = nodeIFace->ReleasePort(sessionId, |
| *((PVMFPortInterface *) aParam), (OsclAny *) & info->context)); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL ReleasePort param is null!\n")); |
| error = PVMFErrArgument; |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_RESET: |
| OSCL_TRY(error, id = nodeIFace->Reset(sessionId, |
| (OsclAny *) & info->context)); |
| break; |
| |
| case PV2WAY_NODE_CMD_CANCELCMD: |
| if (aParam != NULL) |
| { |
| OSCL_TRY(error, id = nodeIFace->CancelCommand(sessionId, |
| *((PVMFCommandId *) aParam), (OsclAny *) & info->context)); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL CancelCommand param is null!\n")); |
| error = PVMFErrArgument; |
| } |
| |
| //Remove commands on pending list |
| if (!error) |
| { |
| RemovePendingNodeCmd((PVMFNodeInterface *)aNode, |
| *((PVMFCommandId *) aParam)); |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_CANCELALL: |
| OSCL_TRY(error, id = nodeIFace->CancelAllCommands(sessionId, |
| (OsclAny *) & info->context)); |
| |
| //Remove commands on pending list |
| if (!error) |
| { |
| RemovePendingNodeCmd((PVMFNodeInterface *)aNode, 0, true); |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_SKIP_MEDIA_DATA: |
| { |
| for (uint32 ii = 0; ii < iSinkNodeList.size(); ii++) |
| { |
| if ((aNode == iSinkNodeList[ii].iSinkNode) |
| && (iSinkNodeList[ii].iNodeInterface.iState == |
| PV2WayNodeInterface::HasInterface)) |
| { |
| ptr = (PvmfNodesSyncControlInterface*) |
| iSinkNodeList[ii].iNodeInterface.iInterface; |
| if (ptr != NULL) |
| { |
| //Pause the clock, since this gives a chance to register |
| // the clock observer notifications |
| iClock.Pause(); |
| ptr->SetClock(&iClock); |
| ptr->SetMargins(SYNC_EARLY_MARGIN, SYNC_LATE_MARGIN); |
| OSCL_TRY(error, id = |
| ptr->SkipMediaData(aNode->iSessionId, |
| resume_timestamp, STREAMID, false, |
| (OsclAny *) & info->context)); |
| //Re-start the clock, since by now, the sink node and MIO component |
| // would've registered itself as the clock observer |
| iClock.Start(); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL SkipMediaData param is null!\n")); |
| error = PVMFErrArgument; |
| } |
| break; |
| } |
| } |
| } |
| break; |
| case PV2WAY_NODE_CMD_INVALID: |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::SendNodeCmdL invalid command!\n")); |
| OSCL_LEAVE(PVMFErrArgument); |
| break; |
| } |
| |
| if (error) |
| { |
| info->Clear(); |
| iFreeNodeCmdInfo.push_back(info); |
| OSCL_LEAVE(error); |
| } |
| |
| info->id = id; |
| |
| iPendingNodeCmdInfo.push_back(info); |
| return id; |
| } |
| |
| TPV2WayNodeCmdInfo *CPV324m2Way::FindPendingNodeCmd(PVMFNodeInterface *aNode, |
| PVMFCommandId aId) |
| { |
| for (uint32 i = 0; i < iPendingNodeCmdInfo.size(); i++) |
| { |
| if ((iPendingNodeCmdInfo[i]->context.iNode == aNode) && |
| (iPendingNodeCmdInfo[i]->id == aId)) |
| { |
| return iPendingNodeCmdInfo[i]; |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::FindPendingNodeCmd unable to find command, node %x, id %d!\n", aNode, aId)); |
| return NULL; |
| } |
| |
| void CPV324m2Way::RemovePendingNodeCmd(PVMFNodeInterface *aNode, |
| PVMFCommandId aId, |
| bool aAllCmds) |
| { |
| TPV2WayNodeCmdInfo **info = NULL; |
| |
| info = iPendingNodeCmdInfo.begin(); |
| while (info != iPendingNodeCmdInfo.end()) |
| { |
| if (((*info)->context.iNode == aNode) && |
| (aAllCmds || ((*info)->id == aId))) |
| { |
| (*info)->Clear(); |
| iFreeNodeCmdInfo.push_back(*info); |
| iPendingNodeCmdInfo.erase(info); |
| info = iPendingNodeCmdInfo.begin(); |
| continue; |
| } |
| |
| info++; |
| } |
| |
| return; |
| } |
| |
| |
| void CPV324m2Way::FillSDKInfo(PVSDKInfo &aSDKInfo) |
| { |
| //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| // (0, "CPV324m2Way::FillSDKInfo")); |
| aSDKInfo.iLabel = PV2WAY_ENGINE_SDKINFO_LABEL; |
| aSDKInfo.iDate = PV2WAY_ENGINE_SDKINFO_DATE; |
| } |
| |
| bool CPV324m2Way::CheckMandatoryCodecs(const PVMFFormatType *aMandatoryList, |
| uint32 aMandatorySize, |
| Oscl_Vector<PVMFFormatType, OsclMemAllocator> &aCodecList) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::CheckMandatoryCodecs")); |
| uint32 i, j; |
| bool found; |
| |
| if (aCodecList.empty()) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CheckMandatoryCodecs empty codecs list, use default")); |
| return true; |
| } |
| |
| for (i = 0; i < aMandatorySize; i++) |
| { |
| found = false; |
| for (j = 0; j < aCodecList.size(); j++) |
| { |
| if (aMandatoryList[i] == aCodecList[j]) |
| { |
| found = true; |
| break; |
| } |
| } |
| |
| if (!found) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckMandatoryCodecs %s not found!", |
| (aMandatoryList[i]).getMIMEStrPtr())); |
| return false; |
| } |
| } |
| |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, |
| (0, "CPV324m2Way::CheckMandatoryCodecs all codecs found")); |
| return true; |
| } |
| |
| void CPV324m2Way::InitiateSession(TPV2WayNode& aNode) |
| { |
| PVMFNodeInterface * nodeIFace = (PVMFNodeInterface *)aNode ; |
| PVMFNodeSessionInfo session(this, this, aNode, this, aNode); |
| aNode.iSessionId = nodeIFace->Connect(session); |
| nodeIFace->ThreadLogon(); |
| } |
| |
| bool CPV324m2Way::IsNodeReset(PVMFNodeInterface& aNode) |
| { |
| TPVMFNodeInterfaceState node_state = aNode.GetState(); |
| |
| if (node_state == EPVMFNodeCreated || node_state == EPVMFNodeIdle) |
| return true; |
| return false; |
| } |
| |
| |
| void CPV324m2Way::SetPreferredCodecs(TPVDirection aDir, |
| Oscl_Vector<const char*, OsclMemAllocator>& aAppAudioFormats, |
| Oscl_Vector<const char*, OsclMemAllocator>& aAppVideoFormats) |
| { |
| /* Iterate over formats supported by the stack */ |
| Oscl_Map<PVMFFormatType, CPvtMediaCapability*, OsclMemAllocator, pvmf_format_type_key_compare_class>::iterator it = iStackSupportedFormats.begin(); |
| while (it != iStackSupportedFormats.end()) |
| { |
| CPvtMediaCapability* media_capability = (*it++).second; |
| const char* format_str = NULL; |
| // Is format present in application formats ? |
| format_str = FindFormatType(media_capability->GetFormatType(), aAppAudioFormats, aAppVideoFormats); |
| if (format_str) |
| { |
| DoSelectFormat(aDir, media_capability->GetFormatType(), format_str, APP); |
| } |
| else |
| { |
| PV2WayMediaType media_type = ::GetMediaType(PVMFFormatTypeToPVCodecType(media_capability->GetFormatType())); |
| const char* can_convert_format = NULL; |
| |
| if (media_type == PV_AUDIO) |
| { |
| can_convert_format = CanConvertFormat(aDir, media_capability->GetFormatType(), aAppAudioFormats); |
| } |
| else if (media_type == PV_VIDEO) |
| { |
| can_convert_format = CanConvertFormat(aDir, media_capability->GetFormatType(), aAppVideoFormats); |
| } |
| |
| if (can_convert_format) |
| { |
| // Engine can convert the format using a conversion node |
| DoSelectFormat(aDir, media_capability->GetFormatType(), format_str, ENG, can_convert_format); |
| } |
| else |
| { |
| // Check if it is a mandatory codec |
| if (media_capability->IsMandatory()) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::SetPreferredCodecs, ERROR Mandatory codec=%s not supported", |
| (media_capability->GetFormatType()).getMIMEStrPtr())); |
| OSCL_LEAVE(PVMFErrResource); |
| } |
| } |
| } |
| } |
| } |
| |
| void CPV324m2Way::SetPreferredCodecs(PV2WayInitInfo& aInitInfo) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::SetPreferredCodecs")); |
| SetPreferredCodecs(INCOMING, aInitInfo.iIncomingAudioFormats, aInitInfo.iIncomingVideoFormats); |
| SetPreferredCodecs(OUTGOING, aInitInfo.iOutgoingAudioFormats, aInitInfo.iOutgoingVideoFormats); |
| } |
| |
| |
| #if defined(PV_RECORD_TO_FILE_SUPPORT) |
| void CPV324m2Way::HandleFFComposerNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleFFComposerNodeCmd type %d, status %d\n", |
| aType, aResponse.GetCmdStatus())); |
| |
| switch (aType) |
| { |
| case PV2WAY_NODE_CMD_QUERY_INTERFACE: |
| if (aResponse.GetCmdId() == iFFClipConfig.iId) |
| { |
| if (aResponse.GetCmdStatus() == PVMFSuccess) |
| { |
| iFFClipConfig.iState = PV2WayNodeInterface::HasInterface; |
| } |
| else |
| { |
| iFFClipConfig.iState = PV2WayNodeInterface::NoInterface; |
| iRecordFileState = File2WayResetting; |
| } |
| } |
| else if (aResponse.GetCmdId() == iFFTrackConfig.iId) |
| { |
| if (aResponse.GetCmdStatus() == PVMFSuccess) |
| { |
| iFFTrackConfig.iState = PV2WayNodeInterface::HasInterface; |
| } |
| else |
| { |
| iFFTrackConfig.iState = PV2WayNodeInterface::NoInterface; |
| iRecordFileState = File2WayResetting; |
| } |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_INIT: |
| case PV2WAY_NODE_CMD_START: |
| if (aResponse.GetCmdStatus() != PVMFSuccess) |
| { |
| iRecordFileState = File2WayResetting; |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_STOP: |
| case PV2WAY_NODE_CMD_RESET: |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandleFFComposerNodeCmd unhandled command\n")); |
| break; |
| } |
| |
| CheckRecordFileState(); |
| return; |
| } |
| |
| void CPV324m2Way::RemoveAudioRecPath() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveAudioRecPath audio rec path state %d\n", |
| iAudioRecDatapath->GetState())); |
| if (iAudioRecDatapath->GetState() == EClosed) |
| { |
| iAudioRecDatapath->ResetDatapath(); |
| } |
| } |
| |
| void CPV324m2Way::RemoveVideoRecPath() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveVideoRecPath video rec path state %d\n", |
| iVideoRecDatapath->GetState())); |
| if (iVideoRecDatapath->GetState() == EClosed) |
| { |
| iVideoRecDatapath->ResetDatapath(); |
| } |
| } |
| |
| void CPV324m2Way::CheckRecordFileState() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::CheckRecordFileState state %d\n", |
| iRecordFileState)); |
| |
| switch (iRecordFileState) |
| { |
| case File2WayInitializing: |
| CheckRecordFileInit(); |
| break; |
| |
| case File2WayResetting: |
| CheckRecordFileReset(); |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, |
| (0, "CPV324m2Way::CheckRecordFileState warning: static state!")); |
| break; |
| } |
| } |
| |
| void CPV324m2Way::CheckRecordFileInit() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::CheckRecordFileInit ff composer node state %d\n", |
| iFFComposerNode->GetState())); |
| |
| // int32 error; |
| return; |
| } |
| |
| void CPV324m2Way::CheckRecordFileReset() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::CheckRecordFileReset audio rec state %d, video rec state %d\n", |
| iAudioRecDatapath->GetState(), iVideoRecDatapath->GetState())); |
| |
| // int32 error; |
| return; |
| } |
| |
| void CPV324m2Way::InitiateResetRecordFile() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::InitiateResetRecordFile state %d, record state %d\n", |
| iState, iRecordFileState)); |
| |
| iRecordFileState = File2WayResetting; |
| |
| if (iAudioRecDatapath->GetState() != EClosed) |
| { |
| iAudioRecDatapath->SetCmd(NULL); |
| } |
| |
| if (iVideoRecDatapath->GetState() != EClosed) |
| { |
| iVideoRecDatapath->SetCmd(NULL); |
| } |
| |
| CheckRecordFileState(); |
| } |
| #endif |
| |
| #if defined(PV_PLAY_FROM_FILE_SUPPORT) |
| void CPV324m2Way::RemoveAudioPreviewPath() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveAudioPreviewPath audio preview path state %d\n", |
| iAudioPreviewDatapath->GetState())); |
| if (iAudioPreviewDatapath->GetState() == EClosed) |
| { |
| iAudioPreviewDatapath->ResetDatapath(); |
| } |
| } |
| |
| void CPV324m2Way::RemoveVideoPreviewPath() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::RemoveVideoPreviewPath video preview path state %d\n", |
| iVideoPreviewDatapath->GetState())); |
| if (iVideoPreviewDatapath->GetState() == EClosed) |
| { |
| iVideoPreviewDatapath->ResetDatapath(); |
| } |
| } |
| |
| void CPV324m2Way::HandlePFFNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandlePFFNodeCmd type %d, status %d\n", |
| aType, aResponse.GetCmdStatus())); |
| |
| CPV2WayPort *port; |
| |
| switch (aType) |
| { |
| case PV2WAY_NODE_CMD_INIT: |
| if (aResponse.GetCmdStatus() != PVMFSuccess) |
| { |
| iPlayFileState = File2WayResetting; |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_REQUESTPORT: |
| if (aResponse.GetCmdId() == iAudioPlayPort.GetCmdId()) |
| { |
| port = &iAudioPlayPort; |
| } |
| else if (aResponse.GetCmdId() == iVideoPlayPort.GetCmdId()) |
| { |
| port = &iVideoPlayPort; |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandlePFFNodeCmd unknown req port id %d\n", |
| aResponse.GetCmdId())); |
| iPlayFileState = File2WayResetting; |
| break; |
| } |
| |
| if (aResponse.GetCmdStatus() == PVMFSuccess) |
| { |
| port->SetPort((PVMFPortInterface *) aResponse.GetEventData()); |
| } |
| else |
| { |
| port->SetPort(NULL); |
| iPlayFileState = File2WayResetting; |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_START: |
| case PV2WAY_NODE_CMD_PAUSE: |
| case PV2WAY_NODE_CMD_STOP: |
| if (iPlayFileCmdInfo) |
| { |
| iPlayFileCmdInfo->status = aResponse.GetCmdStatus(); |
| Dispatch(iPlayFileCmdInfo); |
| iPlayFileCmdInfo = NULL; |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_RESET: |
| CheckPlayFileState(); |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandlePFFNodeCmd unhandled command\n")); |
| break; |
| } |
| |
| CheckPlayFileState(); |
| return; |
| } |
| |
| void CPV324m2Way::CheckPlayFileState() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::CheckPlayFileState state %d\n", |
| iRecordFileState)); |
| |
| switch (iPlayFileState) |
| { |
| case File2WayInitializing: |
| CheckPlayFileInit(); |
| break; |
| |
| case File2WayResetting: |
| CheckPlayFileReset(); |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_WARNING, |
| (0, "CPV324m2Way::CheckPlayFileState warning: static state!")); |
| break; |
| } |
| } |
| |
| void CPV324m2Way::CheckPlayFileInit() |
| { |
| return; |
| } |
| |
| void CPV324m2Way::CheckPlayFileReset() |
| { |
| return; |
| } |
| |
| void CPV324m2Way::InitiateResetPlayFile() |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::InitiateResetPlayFile state %d, record state %d\n", |
| iState, iPlayFileState)); |
| |
| //Use play file as data source |
| if (iAudioEncDatapath->GetState() == EOpened) |
| { |
| iAudioEncDatapath->UseFilePlayPort(false); |
| } |
| |
| if (iVideoEncDatapath->GetState() == EOpened) |
| { |
| iVideoEncDatapath->UseFilePlayPort(false); |
| } |
| |
| iUsePlayFileAsSource = false; |
| |
| iPlayFileState = File2WayResetting; |
| |
| CheckPlayFileState(); |
| } |
| |
| void CPV324m2Way::CheckAudioSourceMixingPort() |
| { |
| return; |
| } |
| |
| void CPV324m2Way::HandleAudioSrcNodeCmd(PV2WayNodeCmdType aType, |
| const PVMFCmdResp& aResponse) |
| { |
| int32 error; |
| TPV2WayEventInfo* aEvent = NULL; |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, |
| (0, "CPV324m2Way::HandleAudioSrcNodeCmd type %d, status %d\n", |
| aType, aResponse.GetCmdStatus())); |
| |
| //The only response this handler is expecting is a request for an audio src node input port |
| |
| switch (aType) |
| { |
| case PV2WAY_NODE_CMD_REQUESTPORT: |
| if (aResponse.GetCmdId() == |
| iAudioEncDatapath->GetSourceInputPort()->GetCmdId()) |
| { |
| if (aResponse.GetCmdStatus() == PVMFSuccess) |
| { |
| iAudioEncDatapath->SetSourceInputPort((PVMFPortInterface *) |
| aResponse.GetEventData()); |
| iAudioEncDatapath->UseFilePlayPort(iUsePlayFileAsSource); |
| } |
| else |
| { |
| iAudioEncDatapath->SetSourceInputPort(NULL); |
| |
| if (!GetEventInfo(aEvent)) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandleAudioSrcNodeCmdn unable to allocate event %d!\n", |
| error)); |
| return; |
| } |
| |
| aEvent->type = PVT_INDICATION_PLAY_ERROR; |
| aEvent->localBuffer[0] = (uint8) PV_AUDIO; |
| aEvent->localBufferSize = 1; |
| Dispatch(aEvent); |
| } |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandleAudioSrcNodeCmd unknown req port id %d\n", |
| aResponse.GetCmdId())); |
| } |
| break; |
| |
| case PV2WAY_NODE_CMD_RELEASEPORT: |
| if (aResponse.GetCmdId() == iAudioEncDatapath->GetSourceInputPort()->GetCmdId()) |
| { |
| iAudioEncDatapath->SetSourceInputPort(NULL); |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandleAudioSrcNodeCmd unknown req port id %d\n", |
| aResponse.GetCmdId())); |
| } |
| break; |
| |
| default: |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::HandleAudioSrcNodeCmd unhandled command\n")); |
| break; |
| } |
| |
| CheckAudioSourceMixingPort(); |
| |
| // Audio encode datapath will wait for stable mixing port before continuing to close. |
| if (iAudioEncDatapath->GetState() == EClosing) |
| { |
| iAudioEncDatapath->CheckPath(); |
| } |
| |
| return; |
| } |
| #endif |
| |
| bool CPV324m2Way::Supports(PVMFNodeCapability &capability, |
| PVMFFormatType aFormat, |
| bool isInput/*=true*/) |
| { |
| if (isInput) |
| { |
| for (uint16 i = 0; i < capability.iInputFormatCapability.size(); i++) |
| { |
| if (capability.iInputFormatCapability[i] == aFormat) |
| return true; |
| } |
| } |
| else |
| { |
| for (uint16 i = 0; i < capability.iOutputFormatCapability.size(); i++) |
| { |
| if (capability.iOutputFormatCapability[i] == aFormat) |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| int32 CPV324m2Way::GetStackNodePortTag(TPV2WayPortTagType tagType) |
| { |
| switch (tagType) |
| { |
| |
| case EPV2WayVideoIn: |
| if (iTerminalType == PV_324M) |
| { |
| return PV_VIDEO; |
| } |
| else |
| { |
| return -1; |
| } |
| break; |
| |
| case EPV2WayAudioIn: |
| if (iTerminalType == PV_324M) |
| { |
| return PV_AUDIO; |
| } |
| else |
| { |
| return -1; |
| } |
| break; |
| |
| case EPV2WayVideoOut: |
| if (iTerminalType == PV_324M) |
| { |
| return iVideoDecDatapath->GetTSCPortTag(); |
| } |
| else |
| { |
| return -1; |
| } |
| break; |
| |
| case EPV2WayAudioOut: |
| if (iTerminalType == PV_324M) |
| { |
| return iAudioDecDatapath->GetTSCPortTag(); |
| } |
| else |
| { |
| return -1; |
| } |
| break; |
| |
| default: |
| break; |
| |
| } |
| return -1; |
| } |
| |
| #ifndef NO_2WAY_324 |
| |
| bool CPV324m2Way::AllChannelsOpened() |
| { |
| return ((iIncomingAudioTrackTag != INVALID_TRACK_ID || |
| !iIncomingAudioCodecs.size()) && |
| (iIncomingVideoTrackTag != INVALID_TRACK_ID || |
| !iIncomingVideoCodecs.size()) && |
| (iOutgoingAudioTrackTag != INVALID_TRACK_ID || |
| !iOutgoingAudioCodecs.size()) && |
| (iOutgoingVideoTrackTag != INVALID_TRACK_ID || |
| !iOutgoingVideoCodecs.size())); |
| } |
| |
| #endif //NO_2WAY_324 |
| |
| void CPV324m2Way::ConvertMapToVector(Oscl_Map < PVMFFormatType, |
| FormatCapabilityInfo, |
| OsclMemAllocator, |
| pvmf_format_type_key_compare_class > & aCodecs, |
| Oscl_Vector < FormatCapabilityInfo, |
| OsclMemAllocator > & aFormatCapability) |
| { |
| iFormatCapability.clear(); |
| Oscl_Map < PVMFFormatType, FormatCapabilityInfo, OsclMemAllocator, |
| pvmf_format_type_key_compare_class >::iterator it; |
| it = aCodecs.begin(); |
| for (it = aCodecs.begin() ; it != aCodecs.end(); it++) |
| { |
| iFormatCapability.push_back(aCodecs[(*it).first]); |
| } |
| |
| aFormatCapability = iFormatCapability; |
| |
| } |
| |
| |
| void CPV324m2Way::AddVideoEncoderNode() |
| { |
| int32 error; |
| |
| if (iVideoEncNode != NULL) |
| return; |
| #ifdef PV2WAY_USE_OMX |
| iVideoEncNode = TPV2WayNode(CREATE_OMX_ENC_NODE()); |
| #else |
| iVideoEncNode = TPV2WayNode(CREATE_VIDEO_ENC_NODE()); |
| #endif // PV2WAY_USE_OMX |
| |
| if (iVideoEncNode.iNode == NULL) |
| OSCL_LEAVE(PVMFErrNoMemory); |
| InitiateSession(iVideoEncNode); |
| |
| if (iVideoEncNodeInterface.iState == PV2WayNodeInterface::NoInterface) |
| { |
| TPV2WayNodeQueryInterfaceParams queryParam; |
| queryParam.iInterfacePtr = &iVideoEncNodeInterface.iInterface; |
| |
| queryParam.iUuid = (PVUuid *) & iVideoEncPVUuid; |
| |
| OSCL_TRY(error, iVideoEncQueryIntCmdId = SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, |
| &iVideoEncNode, this, &queryParam)); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckInit unable to query for video encoder interface!\n")); |
| SetState(EResetting); |
| CheckState(); |
| return;); |
| |
| iVideoEncNodeInterface.iState = PV2WayNodeInterface::QueryInterface; |
| } |
| |
| |
| } |
| void CPV324m2Way::AddAudioEncoderNode() |
| { |
| int32 error; |
| |
| if (iAudioEncNode != NULL) |
| return; |
| |
| #ifdef PV2WAY_USE_OMX |
| OSCL_TRY(error, iAudioEncNode = TPV2WayNode(CREATE_OMX_ENC_NODE())); |
| #else |
| OSCL_TRY(error, iAudioEncNode = |
| TPV2WayNode(CREATE_AUDIO_ENC_NODE());); |
| #endif |
| OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, |
| iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::InitL unable to allocate audio encoder node\n"))); |
| |
| InitiateSession(iAudioEncNode); |
| |
| if (iAudioEncNodeInterface.iState == PV2WayNodeInterface::NoInterface) |
| { |
| TPV2WayNodeQueryInterfaceParams queryParam; |
| queryParam.iInterfacePtr = &iAudioEncNodeInterface.iInterface; |
| |
| queryParam.iUuid = (PVUuid *) & iAudioEncPVUuid; |
| |
| OSCL_TRY(error, iAudioEncNodeInterface.iId = |
| SendNodeCmdL(PV2WAY_NODE_CMD_QUERY_INTERFACE, |
| &iAudioEncNode, this, &queryParam)); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, |
| iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckInit unable to query for audio encoder interface!\n")); |
| SetState(EResetting); |
| CheckState(); |
| return;); |
| |
| iAudioEncNodeInterface.iState = PV2WayNodeInterface::QueryInterface; |
| } |
| else if ((iAudioEncNode.iNode)->GetState() == EPVMFNodeError) |
| { |
| OSCL_TRY(error, SendNodeCmdL(PV2WAY_NODE_CMD_RESET, &iAudioEncNode, this)); |
| OSCL_FIRST_CATCH_ANY(error, |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, |
| (0, "CPV324m2Way::CheckInit unable to reset audio encoder node after error!\n")); |
| return;); |
| } |
| |
| |
| // start enc datapaths that are already created |
| if (iAudioEncDatapath->GetState() != EClosed) |
| { |
| iAudioEncDatapath->CheckOpen(); |
| } |
| |
| } |
| void CPV324m2Way::AddVideoDecoderNode(uint8* aFormatSpecificInfo, uint32 aFormatSpecificInfoLen) |
| { |
| int32 error = 0; |
| if (iVideoDecNode != NULL) |
| return; |
| |
| #ifdef PV2WAY_USE_OMX |
| OSCL_TRY(error, iVideoDecNode = TPV2WayNode(CREATE_OMX_VIDEO_DEC_NODE());); |
| #else |
| OSCL_TRY(error, iVideoDecNode = TPV2WayNode(CREATE_VIDEO_DEC_NODE());); |
| #endif // PV2WAY_USE_OMX |
| |
| |
| OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, |
| PVLOGMSG_ERR, (0, "CPV324m2Way::InitL unable to allocate video decoder node\n"))); |
| |
| OSCL_TRY(error, iVideoParserNode = TPV2WayNode(PVMFVideoParserNode::Create(aFormatSpecificInfo, aFormatSpecificInfoLen));); |
| OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, |
| PVLOGMSG_ERR, (0, "CPV324m2Way::InitL unable to allocate video parser node\n"))); |
| |
| InitiateSession(iVideoDecNode); |
| InitiateSession(iVideoParserNode); |
| } |
| |
| void CPV324m2Way::AddAudioDecoderNode() |
| { |
| int32 error; |
| |
| if (iAudioDecNode != NULL) |
| return; |
| |
| #ifdef PV2WAY_USE_OMX |
| OSCL_TRY(error, iAudioDecNode = |
| TPV2WayNode(CREATE_OMX_AUDIO_DEC_NODE());); |
| #else |
| OSCL_TRY(error, iAudioDecNode = |
| TPV2WayNode(CREATE_AUDIO_DEC_NODE()); |
| /*iAudioDecNode->SetClock(&iClock);*/); |
| #endif // PV2WAY_USE_OMX |
| |
| OSCL_FIRST_CATCH_ANY(error, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, |
| PVLOGMSG_ERR, (0, "CPV324m2Way::InitL unable to allocate audio decoder node\n"))); |
| |
| InitiateSession(iAudioDecNode); |
| } |
| |
| void CPV324m2Way::RegisterMioLatency(const char* aMimeStr, |
| bool aAudio, |
| PVMFFormatType aFmtType) |
| { |
| uint32 latencyVal = 0; |
| if (aMimeStr != NULL) |
| { |
| const char* latencyStr = oscl_strstr(aMimeStr, "latency"); |
| if (latencyStr != NULL) |
| { |
| const char* latVal = oscl_strstr(latencyStr, "="); |
| if (latVal != NULL) |
| { |
| latVal += 1; |
| PV_atoi(latVal, 'd', latencyVal); |
| } |
| } |
| } |
| if (aAudio) |
| { |
| iAudioLatency[(char*)aFmtType.getMIMEStrPtr()] = latencyVal; |
| } |
| else |
| { |
| iVideoLatency[(char*)aFmtType.getMIMEStrPtr()] = latencyVal; |
| } |
| } |
| |
| uint32 CPV324m2Way::LookupMioLatency(PVMFFormatType aFmtType, |
| bool aAudio) |
| { |
| Oscl_Map<char*, uint32, OsclMemAllocator>::iterator it; |
| if (aAudio) |
| { |
| it = iAudioLatency.find((char*)(aFmtType.getMIMEStrPtr())); |
| if (!(it == iAudioLatency.end())) |
| { |
| return (((*it).second)); |
| } |
| else |
| { |
| return 0; //if no latency is specified, then default is 0 |
| } |
| } |
| else |
| { |
| it = iVideoLatency.find((char*)aFmtType.getMIMEStrPtr()); |
| if (!(it == iVideoLatency.end())) |
| { |
| return (((*it).second)); |
| } |
| else |
| { |
| return 0; //if no latency is specified, then default is 0 |
| } |
| } |
| } |
| |
| #ifdef MEM_TRACK |
| void CPV324m2Way::MemStats() |
| { |
| #if !(OSCL_BYPASS_MEMMGT) |
| |
| OsclAuditCB auditCB; |
| OsclMemInit(auditCB); |
| if (auditCB.pAudit) |
| { |
| MM_Stats_t* stats = auditCB.pAudit->MM_GetStats(""); |
| if (stats) |
| { |
| printf(" numBytes %d\n", stats->numBytes); |
| printf(" peakNumBytes %d\n", stats->peakNumBytes); |
| printf(" numAllocs %d\n", stats->numAllocs); |
| printf(" peakNumAllocs %d\n", stats->peakNumAllocs); |
| printf(" numAllocFails %d\n", stats->numAllocFails); |
| printf(" totalNumAllocs %d\n", stats->totalNumAllocs); |
| printf(" totalNumBytes %d\n", stats->totalNumBytes); |
| } |
| |
| } |
| #endif |
| } |
| #endif |
| |
| /* This should be changed to query the node registry */ |
| bool CPV324m2Way::IsSupported(const PVMFFormatType& aInputFmtType, const PVMFFormatType& aOutputFmtType) |
| { |
| if (aInputFmtType == PVMF_MIME_AMR_IF2) |
| { |
| if ((aOutputFmtType == PVMF_MIME_PCM8) || (aOutputFmtType == PVMF_MIME_PCM16)) |
| { |
| return true; |
| } |
| return false; |
| } |
| else if ((aInputFmtType == PVMF_MIME_M4V) || (aInputFmtType == PVMF_MIME_H2632000)) |
| { |
| if (aOutputFmtType == PVMF_MIME_YUV420) |
| { |
| return true; |
| } |
| return false; |
| } |
| else if ((aInputFmtType == PVMF_MIME_PCM8) || (aInputFmtType == PVMF_MIME_PCM16)) |
| { |
| if (aOutputFmtType == PVMF_MIME_AMR_IF2) |
| { |
| return true; |
| } |
| return false; |
| } |
| else if ((aInputFmtType == PVMF_MIME_YUV420)) |
| { |
| if (aOutputFmtType == PVMF_MIME_M4V || aOutputFmtType == PVMF_MIME_H2632000) |
| { |
| return true; |
| } |
| return false; |
| } |
| else |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "CPV324m2Way::IsSupported() Not supported format\n")); |
| return false; |
| } |
| } |
| |
| /* This should be changed to query the formats from the stack */ |
| void CPV324m2Way::GetStackSupportedFormats() |
| { |
| iStackSupportedFormats[PVMF_MIME_AMR_IF2] = OSCL_NEW(CPvtAudioCapability, (PVMF_MIME_AMR_IF2, MAX_AMR_BITRATE)); |
| iStackSupportedFormats[PVMF_MIME_M4V] = OSCL_NEW(CPvtMpeg4Capability, (MAX_VIDEO_BITRATE)); |
| iStackSupportedFormats[PVMF_MIME_H2632000] = OSCL_NEW(CPvtH263Capability, (MAX_VIDEO_BITRATE)); |
| } |
| |
| const char* CPV324m2Way::FindFormatType(PVMFFormatType aFormatType, |
| Oscl_Vector<const char*, OsclMemAllocator>& aAudioFormats, |
| Oscl_Vector<const char*, OsclMemAllocator>& aVideoFormats) |
| { |
| PVMFFormatType aThatFormatType = PVMF_MIME_FORMAT_UNKNOWN; |
| uint32 i = 0; |
| |
| for (i = 0; i < aAudioFormats.size(); i++) |
| { |
| aThatFormatType = aAudioFormats[i]; |
| if (aFormatType == aThatFormatType) |
| { |
| return aAudioFormats[i]; |
| } |
| } |
| |
| for (i = 0; i < aVideoFormats.size(); i++) |
| { |
| aThatFormatType = aVideoFormats[i]; |
| if (aFormatType == aThatFormatType) |
| { |
| return aVideoFormats[i]; |
| } |
| } |
| return NULL; |
| } |
| |
| const char* CPV324m2Way::CanConvertFormat(TPVDirection aDir, const PVMFFormatType& aThisFmtType, Oscl_Vector<const char*, OsclMemAllocator>& aThatFormatList) |
| { |
| PVMFFormatType aInputFmtType = PVMF_MIME_FORMAT_UNKNOWN; |
| PVMFFormatType aOutputFmtType = PVMF_MIME_FORMAT_UNKNOWN; |
| |
| OSCL_ASSERT(aDir == INCOMING || aDir == OUTGOING); |
| |
| for (uint32 i = 0; i < aThatFormatList.size(); i++) |
| { |
| PVMFFormatType thatFmtType = aThatFormatList[i]; |
| aInputFmtType = (aDir == INCOMING) ? aThisFmtType : thatFmtType; |
| aOutputFmtType = (aDir == INCOMING) ? thatFmtType : aThisFmtType; |
| if (IsSupported(aInputFmtType, aOutputFmtType)) |
| { |
| return aThatFormatList[i]; |
| } |
| } |
| return NULL; |
| } |
| |
| void CPV324m2Way::DoSelectFormat(TPVDirection aDir, PVMFFormatType aFormatType, const char* aFormatStr, TPVPriority aPriority, PVMFFormatType aFormatTypeApp) |
| { |
| PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE, |
| (0, "CPV324m2Way::DoSelectFormat, aDir=%d, aFormatType=%s, aPriority=%d", |
| aDir, aFormatType.getMIMEStrPtr(), aPriority)); |
| |
| FormatCapabilityInfo format_cap_info; |
| PV2WayMediaType media_type = GetMediaType(PVMFFormatTypeToPVCodecType(aFormatType)); |
| Oscl_Map<PVMFFormatType, FormatCapabilityInfo, OsclMemAllocator, pvmf_format_type_key_compare_class>* the_engine_map = NULL; |
| Oscl_Map<PVMFFormatType, PVMFFormatType, OsclMemAllocator, pvmf_format_type_key_compare_class>* the_app_map = NULL; |
| |
| format_cap_info.dir = aDir; |
| FILL_FORMAT_INFO(aFormatType, format_cap_info); |
| format_cap_info.iPriority = aPriority; |
| |
| switch (aDir) |
| { |
| case OUTGOING: |
| the_engine_map = (media_type == PV_AUDIO) ? &iOutgoingAudioCodecs : &iOutgoingVideoCodecs; |
| the_app_map = &iAppFormatForEngineFormatOutgoing; |
| break; |
| case INCOMING: |
| the_engine_map = (media_type == PV_AUDIO) ? &iIncomingAudioCodecs : &iIncomingVideoCodecs; |
| the_app_map = &iAppFormatForEngineFormatIncoming; |
| break; |
| default: |
| return; |
| } |
| (*the_engine_map)[aFormatType] = format_cap_info; |
| (*the_app_map)[aFormatType] = aFormatTypeApp; |
| |
| RegisterMioLatency(aFormatStr, true, aFormatType); |
| } |
| |
| // This function returns a priority index for each format type. |
| #define PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_START 0 |
| #define PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_END 0xFF |
| uint32 GetPriorityIndexForPVMFFormatType(PVMFFormatType aFormatType) |
| { |
| if (aFormatType == PVMF_MIME_AMR_IF2) |
| return PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_START; |
| else if (aFormatType == PVMF_MIME_M4V) |
| return PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_START + 1; |
| else if (aFormatType == PVMF_MIME_H2632000) |
| return PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_START + 2; |
| else |
| return PV2WAY_ENGINE_PRIORITY_INDEX_FOR_FORMAT_TYPE_END; |
| } |