blob: 58c2bed4705bcf35a9d1ef441731f723c075019d [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 2008 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 OSCL_SNPRINTF_H_INCLUDED
#include "oscl_snprintf.h"
#endif
#ifndef OSCL_EXCLUSIVE_PTR_H_INCLUDED
#include "oscl_exclusive_ptr.h"
#endif
#ifndef PVLOGGER_H_INCLUDED
#include "pvlogger.h"
#endif
#ifndef OSCL_MIME_STRING_UTILS_H
#include "pv_mime_string_utils.h"
#endif
#ifndef PVMF_SM_NODE_FACTORY_H_INCLUDED
#include "pvmf_sm_node_factory.h"
#endif
#ifndef PVMF_SM_TUNABLES_H_INCLUDED
#include "pvmf_sm_tunables.h"
#endif
#ifndef PVMF_STREAMING_MANAGER_NODE_H_INCLUDED
#include "pvmf_streaming_manager_node.h"
#endif
#ifndef PVMF_STREAMING_MANAGER_INTERNAL_H_INCLUDED
#include "pvmf_streaming_manager_internal.h"
#endif
#ifndef PVMF_SM_CAPCONFIG_H_INCLUDED
#include "pvmf_sm_capconfig.h"
#endif
#ifndef PVMF_SOCKET_NODE_H_INCLUDED
#include "pvmf_socket_node.h"
#endif
#ifndef PVMF_RTSP_ENGINE_NODE_FACTORY_H_INCLUDED
#include "pvrtsp_client_engine_factory.h"
#endif
#ifndef PVMF_JITTER_BUFFER_NODE_H_INCLUDED
#include "pvmf_jitter_buffer_node.h"
#endif
#ifndef PVMF_MEDIALAYER_NODE_H_INCLUDED
#include "pvmf_medialayer_node.h"
#endif
#ifndef PVRTSP_ENGINE_NODE_EXTENSION_INTERFACE_H_INCLUDED
#include "pvrtspenginenodeextensioninterface.h"
#endif
#ifndef PVMF_MEDIA_PRESENTATION_INFO_H_INCLUDED
#include "pvmf_media_presentation_info.h"
#endif
#ifndef SDP_PARSER_H
#include "sdp_parser.h"
#endif
#ifndef PVMF_BASIC_ERRORINFOMESSAGE_H_INCLUDED
#include "pvmf_basic_errorinfomessage.h"
#endif
#ifndef PVMF_ERRORINFOMESSAGE_EXTENSION_H_INCLUDED
#include "pvmf_errorinfomessage_extension.h"
#endif
#ifndef OSCL_STRING_UTILS_H_INCLUDED
#include "oscl_string_utils.h"
#endif
#ifndef PVMI_KVP_UTIL_H_INCLUDED
#include "pvmi_kvp_util.h"
#endif
#ifndef OSCL_DLL_H_INCLUDED
#include "oscl_dll.h"
#endif
#ifndef PVMF_PROTOCOLENGINE_FACTORY_H_INCLUDED
#include "pvmf_protocol_engine_factory.h"
#endif
#ifndef PVMF_PROTOCOLENGINE_DEFS_H_INCLUDED
#include "pvmf_protocol_engine_defs.h"
#endif
#ifndef PVMFPROTOCOLENGINENODE_EXTENSION_H_INCLUDED
#include "pvmf_protocol_engine_node_extension.h"
#endif
#ifndef PVMF_STREAMING_ASF_INTERFACES_INCLUDED
#include "pvmf_streaming_asf_interfaces.h"
#endif
#ifndef PVMI_DRM_KVP_H_INCLUDED
#include "pvmi_drm_kvp.h"
#endif
#ifndef OSCL_UTF8CONV_H
#include "oscl_utf8conv.h"
#endif
#ifndef PVMF_SM_CONFIG_H_INCLUDED
#include "pvmf_sm_config.h"
#endif
// Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()
// Number of metadata keys supported in this node.
#define PVMFSTREAMINGMGRNODE_NUM_METADATAKEYS 16
// Constant character strings for metadata keys
static const char PVMFSTREAMINGMGRNODE_AUTHOR_KEY[] = "author";
static const char PVMFSTREAMINGMGRNODE_ARTIST_KEY[] = "artist";
static const char PVMFSTREAMINGMGRNODE_TITLE_KEY[] = "title";
static const char PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY[] = "description";
static const char PVMFSTREAMINGMGRNODE_RATING_KEY[] = "rating";
static const char PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY[] = "copyright";
static const char PVMFSTREAMINGMGRNODE_GENRE_KEY[] = "genre";
static const char PVMFSTREAMINGMGRNODE_LYRICS_KEY[] = "lyrics";
static const char PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY[] = "classification";
static const char PVMFSTREAMINGMGRNODE_KEYWORDS_KEY[] = "keywords";
static const char PVMFSTREAMINGMGRNODE_LOCATION_KEY[] = "location";
static const char PVMFSTREAMINGMGRNODE_DURATION_KEY[] = "duration";
static const char PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY[] = "num-tracks";
static const char PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY[] = "random-access-denied";
static const char PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY[] = "graphic/num-frames;format=APIC";
static const char PVMFSTREAMINGMGRNODE_GRAPHICS_KEY[] = "graphic;format=APIC";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY[] = "track-info/type";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY[] = "track-info/duration";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_BITRATE_KEY[] = "track-info/bit-rate";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_MAX_BITRATE_KEY[] = "track-info/max-bitrate";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY[] = "track-info/selected";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY[] = "track-info/video/width";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY[] = "track-info/video/height";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY[] = "track-info/sample-rate";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY[] = "track-info/audio/channels";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY[] = "track-info/audio/bits-per-sample";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY[] = "track-info/track-id";
static const char PVMFSTREAMINGMGRNODE_SEMICOLON[] = ";";
static const char PVMFSTREAMINGMGRNODE_TIMESCALE[] = "timescale=";
static const char PVMFSTREAMINGMGRNODE_INDEX[] = "index=";
static const char PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY[] = "clip-type";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY[] = "track-info/frame-rate";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY[] = "track-info/codec-name";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY[] = "track-info/codec-description";
static const char PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY[] = "track-info/codec-specific-info";
static const char PVMFSTREAMINGMGRNODE_MAXSIZE[] = "maxsize=";
static const char PVMFSTREAMINGMGRNODE_REQSIZE[] = "reqsize=";
static const char PVMFSTREAMINGMGRNODE_TRUNCATE_FLAG[] = "truncate=";
///////////////////////////////////////////////////////////////////////////////
//
// Capability and config interface related constants and definitions
// - based on pv_player_engine.h
//
///////////////////////////////////////////////////////////////////////////////
static const StreamingManagerKeyStringData StreamingManagerConfig_BaseKeys[] =
{
{"delay", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"jitterBufferNumResize", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"jitterBufferResizeSize", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"user-agent", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_WCHARPTR},
{"keep-alive-interval", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"keep-alive-during-play", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_BOOL},
{"switch-streams", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_CHARPTR},
{"speed", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"http-version", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_CHARPTR},
{"num-redirect-attempts", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"protocol-extension-header", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_CHARPTR},
{"http-timeout", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"http-streaming-logging-timeout", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"x-str-header", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_BOOL},
{"max-streaming-asf-header-size", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"max-tcp-recv-buffer-size", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"rebuffering-threshold", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"accel-bitrate", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"accel-duration", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
{"disable-firewall-packets", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_BOOL}
};
static const uint StreamingManagerConfig_NumBaseKeys =
(sizeof(StreamingManagerConfig_BaseKeys) /
sizeof(StreamingManagerKeyStringData));
enum BaseKeys_IndexMapType
{
BASEKEY_DELAY = 0,
BASEKEY_JITTERBUFFER_NUMRESIZE,
BASEKEY_JITTERBUFFER_RESIZESIZE,
BASEKEY_SESSION_CONTROLLER_USER_AGENT,
BASEKEY_SESSION_CONTROLLER_KEEP_ALIVE_INTERVAL,
BASEKEY_SESSION_CONTROLLER_KEEP_ALIVE_DURING_PLAY,
BASEKEY_STREAMING_MGR_SWITCH_STREAMS,
BASEKEY_STREAMING_SPEED,
BASEKEY_HTTP_VERSION,
BASEKEY_NUM_REDIRECT_ATTEMPTS,
BASEKEY_PROTOCOL_EXTENSION_HEADER,
BASEKEY_SESSION_CONTROLLER_HTTP_TIMEOUT,
BASEKEY_SESSION_CONTROLLER_HTTP_STREAMING_LOGGING_TIMEOUT,
BASEKEY_SESSION_CONTROLLER_XSTR_HTTP_HEADER,
BASEKEY_MAX_STREAMING_ASF_HEADER_SIZE,
BASEKEY_MAX_TCP_RECV_BUFFER_SIZE,
BASEKEY_REBUFFERING_THRESHOLD,
BASEKEY_ACCEL_BITRATE,
BASEKEY_ACCEL_DURATION,
BASEKEY_DISABLE_FIREWALL_PACKETS
};
///////////////////////////////////////////////////////////////////////////////
void
PVMFStreamingManagerNodeCommand::Copy(const PVMFGenericNodeCommand<OsclMemAllocator>& aCmd)
{
PVMFGenericNodeCommand<OsclMemAllocator>::Copy(aCmd);
switch (aCmd.iCmd)
{
case PVMF_STREAMING_MANAGER_NODE_GETNODEMETADATAKEYS:
if (aCmd.iParam4)
{
/* copy the allocated string */
OSCL_HeapString<OsclMemAllocator>* aStr =
(OSCL_HeapString<OsclMemAllocator>*)aCmd.iParam4;
Oscl_TAlloc<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> str;
iParam4 = str.ALLOC_AND_CONSTRUCT(*aStr);
}
break;
default:
break;
}
}
/* need to overlaod the base Destroy routine to cleanup metadata key */
void PVMFStreamingManagerNodeCommand::Destroy()
{
PVMFGenericNodeCommand<OsclMemAllocator>::Destroy();
switch (iCmd)
{
case PVMF_STREAMING_MANAGER_NODE_GETNODEMETADATAKEYS:
if (iParam4)
{
/* cleanup the allocated string */
Oscl_TAlloc<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> str;
str.destruct_and_dealloc(iParam4);
}
break;
default:
break;
}
}
/**
//////////////////////////////////////////////////
// Node Constructor & Destructor
//////////////////////////////////////////////////
*/
OSCL_EXPORT_REF PVMFStreamingManagerNode::PVMFStreamingManagerNode(int32 aPriority)
: OsclActiveObject(aPriority, "StreamingManagerNode")
{
iLogger = NULL;
iCmdSeqLogger = NULL;
iReposLogger = NULL;
iLogger = PVLogger::GetLoggerObject("StreamingManagerNode");
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::PVMFStreamingManagerNode - In"));
iExtensionInterface = NULL;
iExtensionInterfacePlaceholder = NULL;
iQueryUUIDComplete = false;
iQueryInterfaceComplete = false;
iTotalNumRequestPortsComplete = 0;
iNumRequestPortsPending = 0;
iTotalNumInitPhaseRequestPortsComplete = 0;
iTotalNumInitPhaseRequestPortsPending = 0;
oGraphConstructComplete = false;
oGraphConnectComplete = false;
iSessionStartTime = 0;
iSessionStopTime = 0;
iSessionStopTimeAvailable = true;
iSessionSeekAvailable = true;
oRepositioning = false;
oPlayListRepositioning = false;
iRepositionRequestedStartNPTInMS = 0;
iActualRepositionStartNPTInMS = 0;
iActualMediaDataTS = 0;
iActualRepositionStartNPTInMSPtr = NULL;
iActualMediaDataTSPtr = NULL;
iPVMFDataSourcePositionParamsPtr = NULL;
iJumpToIFrame = false;
iJitterBufferDurationInMilliSeconds = DEFAULT_JITTER_BUFFER_DURATION_IN_MS;
iAutoPausePending = false;
iAutoResumePending = 0;
iAutoPaused = false;
iStreamThinningInProgress = false;
iPlaylistPlayInProgress = false;
iSwitchStreamIFrameVideo = false;
iErrorDuringProcess = SM_NO_ERROR;
iErrorResponseInf = NULL;
iCmdErrStatus = PVMFFailure;
iEventData = NULL;
ibRdtTransport = false;
ibCloaking = false;
ipRealChallengeGen = NULL;
ipRdtParser = NULL;
iStreamID = 0;
iSourceContextDataValid = false;
iUseCPMPluginRegistry = false;
iPreviewMode = false;
iDRMResetPending = false;
iCPMInitPending = false;
maxPacketSize = 0;
iPVMFStreamingManagerNodeMetadataValueCount = 0;
iCPMMetaDataExtensionInterface = NULL;
iCPMLicenseInterface = NULL;
iCPMGetMetaDataKeysCmdId = 0;
iCPMGetMetaDataValuesCmdId = 0;
iCPMGetLicenseInterfaceCmdId = 0;
iCPMGetLicenseCmdId = 0;
iCPMCancelGetLicenseCmdId = 0;
iCPM = NULL;
iCPMSessionID = 0xFFFFFFFF;
iCPMContentType = PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
iCPMContentAccessFactory = NULL;
iDecryptionInterface = NULL;
iCPMInitCmdId = 0;
iCPMOpenSessionCmdId = 0;
iCPMRegisterContentCmdId = 0;
iCPMRequestUsageId = 0;
iCPMUsageCompleteCmdId = 0;
iCPMCloseSessionCmdId = 0;
iCPMResetCmdId = 0;
iRequestedUsage.key = NULL;
iApprovedUsage.key = NULL;
iAuthorizationDataKvp.key = NULL;
CleanupCPMdata();
int32 err;
OSCL_TRY(err,
/*
* Create the input command queue. Use a reserve to avoid lots of
* dynamic memory allocation.
*/
iInputCommands.Construct(PVMF_STREAMING_MANAGER_NODE_COMMAND_ID_START,
PVMF_STREAMING_MANAGER_VECTOR_RESERVE);
/*
* Create the "current command" queue. It will only contain one
* command at a time, so use a reserve of 1.
*/
iCurrentCommand.Construct(0, 1);
/*
* Create the "cancel command" queue. It will only contain one
* command at a time, so use a reserve of 1.
*/
iCancelCommand.Construct(0, 1);
/*
* Set the node capability data.
* This node can support an unlimited number of ports.
*/
iCapability.iCanSupportMultipleInputPorts = false;
iCapability.iCanSupportMultipleOutputPorts = true;
iCapability.iHasMaxNumberOfPorts = false;
iCapability.iMaxNumberOfPorts = 0;//no maximum
PVMF_STREAMING_MANAGER_NEW(NULL,
PVMFSMSessionSourceInfo,
(),
iSessionSourceInfo);
/*
* Create Socket Node
*/
OsclExclusivePtr<PVMFNodeInterface> socketNodeAutoPtr;
PVMFNodeInterface* iSocketNode;
PVMF_STREAMING_MANAGER_NEW(NULL,
PVMFSocketNode,
(OsclActiveObject::EPriorityNominal),
iSocketNode);
socketNodeAutoPtr.set(iSocketNode);
PVMFSMNodeContainer sSocketNodeContainer;
PVMFNodeSessionInfo socketNodeSession(this,
this,
OSCL_REINTERPRET_CAST(OsclAny*,
iSocketNode),
this,
OSCL_REINTERPRET_CAST(OsclAny*,
iSocketNode));
sSocketNodeContainer.iNode = iSocketNode;
sSocketNodeContainer.iSessionId =
iSocketNode->Connect(socketNodeSession);
sSocketNodeContainer.iNodeTag =
PVMF_STREAMING_MANAGER_SOCKET_NODE;
sSocketNodeContainer.commandStartOffset =
PVMF_STREAMING_MANAGER_SOCKET_NODE_COMMAND_START;
/* Push back the known UUID in case there are no queries */
PVUuid uuid(PVMF_SOCKET_NODE_EXTENSION_INTERFACE_UUID);
sSocketNodeContainer.iExtensionUuids.push_back(uuid);
iNodeContainerVec.push_back(sSocketNodeContainer);
/*
* Create Session Controller Node
*/
OsclExclusivePtr<PVMFNodeInterface> sessionControllerAutoPtr;
PVMFNodeInterface* iSessionControllerNode = PVMFRrtspEngineNodeFactory::CreatePVMFRtspEngineNode(OsclActiveObject::EPriorityNominal);
sessionControllerAutoPtr.set(iSessionControllerNode);
PVMFSMNodeContainer sSessionControllerNodeContainer;
PVMFNodeSessionInfo sessionControllerSession(this,
this,
OSCL_REINTERPRET_CAST(OsclAny*,
iSessionControllerNode),
this,
OSCL_REINTERPRET_CAST(OsclAny*,
iSessionControllerNode));
sSessionControllerNodeContainer.iNode = iSessionControllerNode;
sSessionControllerNodeContainer.iSessionId =
iSessionControllerNode->Connect(sessionControllerSession);
sSessionControllerNodeContainer.iNodeTag =
PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE;
sSessionControllerNodeContainer.commandStartOffset =
PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_COMMAND_START;
/* Push back the known UUID in case there are no queries */
sSessionControllerNodeContainer.iExtensionUuids.push_back(KPVRTSPEngineNodeExtensionUuid);
iNodeContainerVec.push_back(sSessionControllerNodeContainer);
/*
* Create jitter buffer node
*/
OsclExclusivePtr<PVMFNodeInterface> jitterBufferNodeAutoPtr;
PVMFNodeInterface* iJitterBufferNode;
PVMF_STREAMING_MANAGER_NEW(NULL,
PVMFJitterBufferNode,
(OsclActiveObject::EPriorityNominal),
iJitterBufferNode);
jitterBufferNodeAutoPtr.set(iJitterBufferNode);
PVMFSMNodeContainer sJitterBufferNodeContainer;
PVMFNodeSessionInfo jitterBufferSession(this,
this,
OSCL_REINTERPRET_CAST(OsclAny*,
iJitterBufferNode),
this,
OSCL_REINTERPRET_CAST(OsclAny*,
iJitterBufferNode));
sJitterBufferNodeContainer.iNode = iJitterBufferNode;
sJitterBufferNodeContainer.iSessionId =
iJitterBufferNode->Connect(jitterBufferSession);
sJitterBufferNodeContainer.iNodeTag =
PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE;
sJitterBufferNodeContainer.commandStartOffset =
PVMF_STREAMING_MANAGER_JITTER_BUFFER_CONTROLLER_COMMAND_START;
/* Push back the known UUID in case there are no queries */
sJitterBufferNodeContainer.iExtensionUuids.push_back(PVMF_JITTERBUFFERNODE_EXTENSIONINTERFACE_UUID);
iNodeContainerVec.push_back(sJitterBufferNodeContainer);
/*
* Create media layer node
*/
OsclExclusivePtr<PVMFNodeInterface> mediaLayerNodeAutoPtr;
PVMFNodeInterface* iMediaLayerNode;
PVMF_STREAMING_MANAGER_NEW(NULL,
PVMFMediaLayerNode,
(OsclActiveObject::EPriorityNominal),
iMediaLayerNode);
mediaLayerNodeAutoPtr.set(iMediaLayerNode);
PVMFSMNodeContainer sMediaLayerNodeContainer;
PVMFNodeSessionInfo mediaLayerSession(this,
this,
OSCL_REINTERPRET_CAST(OsclAny*,
iMediaLayerNode),
this,
OSCL_REINTERPRET_CAST(OsclAny*,
iMediaLayerNode));
sMediaLayerNodeContainer.iNode = iMediaLayerNode;
sMediaLayerNodeContainer.iSessionId =
iMediaLayerNode->Connect(mediaLayerSession);
sMediaLayerNodeContainer.iNodeTag =
PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE;
sMediaLayerNodeContainer.commandStartOffset =
PVMF_STREAMING_MANAGER_MEDIA_LAYER_COMMAND_START;
/* Push back the known UUID in case there are no queries */
sMediaLayerNodeContainer.iExtensionUuids.push_back(PVMF_MEDIALAYERNODE_EXTENSIONINTERFACE_UUID);
iNodeContainerVec.push_back(sMediaLayerNodeContainer);
for (int32 i = 0; i < PVMF_STREAMING_MANAGER_INTERNAL_CMDQ_SIZE; i++)
{
iInternalCmdPool[i].cmd = PVMF_STREAMING_MANAGER_INTERNAL_COMMAND_NONE;
iInternalCmdPool[i].oFree = true;
}
sessionControllerAutoPtr.release();
socketNodeAutoPtr.release();
jitterBufferNodeAutoPtr.release();
mediaLayerNodeAutoPtr.release();
// Allocate memory for metadata key list
iAvailableMetadataKeys.reserve(PVMFSTREAMINGMGRNODE_NUM_METADATAKEYS);
iAvailableMetadataKeys.clear();
);
if (err != OsclErrNone)
{
CleanUp();
OSCL_LEAVE(err);
}
if (err != OsclErrNone)
{
CleanUp();
OSCL_LEAVE(err);
}
if (err != OsclErrNone)
{
CleanUp();
OSCL_LEAVE(err);
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::PVMFStreamingManagerNode - Out"));
}
void PVMFStreamingManagerNode::CleanUp()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CleanUp - In"));
/*
* if a leave happened, cleanup and re-throw the error
*/
iInputCommands.clear();
iCurrentCommand.clear();
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFSMSessionSourceInfo,
iSessionSourceInfo);
/*
* Clean up all children nodes
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_SOCKET_NODE)
{
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFSocketNode,
((PVMFSocketNode*)(iNodeContainerVec[i].iNode)));
}
else if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE)
{
PVMFRrtspEngineNodeFactory::DeletePVMFRtspEngineNode(iNodeContainerVec[i].iNode);
iNodeContainerVec[i].iNode = NULL;
}
else if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE)
{
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFJitterBufferNode,
((PVMFJitterBufferNode*)(iNodeContainerVec[i].iNode)));
}
else if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE)
{
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFMediaLayerNode,
((PVMFMediaLayerNode*)(iNodeContainerVec[i].iNode)));
}
else if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_RTPPACKETSOURCE_NODE)
{
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFMediaLayerNode,
((PVMFMediaLayerNode*)(iNodeContainerVec[i].iNode)));
}
}
iNodeContainerVec.clear();
iCapability.iInputFormatCapability.clear();
iCapability.iOutputFormatCapability.clear();
OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
OSCL_CLEANUP_BASE_CLASS(OsclActiveObject);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CleanUp - Out"));
return;
}
OSCL_EXPORT_REF PVMFStreamingManagerNode::~PVMFStreamingManagerNode()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::~PVMFStreamingManagerNode - In"));
Cancel();
/* Reset the metadata key list */
/* Clean up CPM related variables */
CleanupCPMdata();
/*Cleanup CPM instance*/
if (iCPM != NULL)
{
iCPM->ThreadLogoff();
PVMFCPMFactory::DestroyContentPolicyManager(iCPM);
iCPM = NULL;
}
/* thread logoff */
if (IsAdded())
RemoveFromScheduler();
/* Cleanup any old key */
if (iRequestedUsage.key)
{
OSCL_ARRAY_DELETE(iRequestedUsage.key);
iRequestedUsage.key = NULL;
}
if (iApprovedUsage.key)
{
OSCL_ARRAY_DELETE(iApprovedUsage.key);
iApprovedUsage.key = NULL;
}
if (iAuthorizationDataKvp.key)
{
OSCL_ARRAY_DELETE(iAuthorizationDataKvp.key);
iAuthorizationDataKvp.key = NULL;
}
/* Cleanup allocated interfaces */
if (iExtensionInterface)
{
/*
* clear the interface container
* the interface can't function without the node.
*/
iExtensionInterface->iContainer = NULL;
iExtensionInterface->removeRef();
}
/*
* Cleanup commands
* The command queues are self-deleting, but we want to
* notify the observer of unprocessed commands.
*/
while (iCurrentCommand.size() > 0)
{
CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
}
while (iInputCommands.size() > 0)
{
CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
}
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFSMSessionSourceInfo,
iSessionSourceInfo);
/*
* Clean up all children nodes & interfaces
*/
uint32 i, j;
for (i = 0; i < iNodeContainerVec.size(); i++)
{
for (j = 0; j < iNodeContainerVec[i].iExtensions.size(); j++)
{
PVInterface* extIntf = iNodeContainerVec[i].iExtensions[j];
extIntf->removeRef();
}
if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_SOCKET_NODE)
{
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFSocketNode,
((PVMFSocketNode*)(iNodeContainerVec[i].iNode)));
}
else if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE)
{
PVMFRrtspEngineNodeFactory::DeletePVMFRtspEngineNode(iNodeContainerVec[i].iNode);
iNodeContainerVec[i].iNode = NULL;
}
else if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE)
{
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFJitterBufferNode,
((PVMFJitterBufferNode*)(iNodeContainerVec[i].iNode)));
}
else if (iNodeContainerVec[i].iNodeTag == PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE)
{
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFMediaLayerNode,
((PVMFMediaLayerNode*)(iNodeContainerVec[i].iNode)));
}
}
iNodeContainerVec.clear();
// destroy the payload parser registry
destroyPayloadParserRegistry();
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::~PVMFStreamingManagerNode - Out"));
}
void PVMFStreamingManagerNode::CleanupCPMdata()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CleanupCPMdata() Called"));
/* Clean up CPM related variables */
iSourceContextDataValid = false;
iUseCPMPluginRegistry = false;
if (iCPMContentAccessFactory != NULL)
{
if (iDecryptionInterface != NULL)
{
iDecryptionInterface->Reset();
/* Remove the decrpytion interface */
PVUuid uuid = PVMFCPMPluginDecryptionInterfaceUuid;
iCPMContentAccessFactory->DestroyPVMFCPMPluginAccessInterface(uuid, iDecryptionInterface);
iDecryptionInterface = NULL;
}
iCPMContentAccessFactory->removeRef();
iCPMContentAccessFactory = NULL;
}
iCPMContentType = PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
iPreviewMode = false;
iCPMInitPending = false;
iCPMMetadataKeys.clear();
}
/* Called during a Reset */
void PVMFStreamingManagerNode::ResetNodeParams()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ResetNodeParams - In"));
iTotalNumRequestPortsComplete = 0;
iNumRequestPortsPending = 0;
iTotalNumInitPhaseRequestPortsComplete = 0;
iTotalNumInitPhaseRequestPortsPending = 0;
oGraphConstructComplete = false;
oGraphConnectComplete = false;
iAutoPausePending = false;
iAutoResumePending = 0;
iAutoPaused = false;
iStreamThinningInProgress = false;
iPlaylistPlayInProgress = false;
iSwitchStreamIFrameVideo = false;
iMetaDataInfo.Reset();
iTrackInfoVec.clear();
PVMFSMNodeContainerVector::iterator it;
for (it = iNodeContainerVec.begin(); it != iNodeContainerVec.end(); it++)
{
it->Reset();
}
/* Delete current session info and recreate a new one */
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFSMSessionSourceInfo,
iSessionSourceInfo);
iSessionSourceInfo = NULL;
PVMF_STREAMING_MANAGER_NEW(NULL,
PVMFSMSessionSourceInfo,
(),
iSessionSourceInfo);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ResetNodeParams - Out"));
}
/**
* Do thread-specific node creation and go to "Idle" state.
*/
OSCL_EXPORT_REF PVMFStatus PVMFStreamingManagerNode::ThreadLogon()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ThreadLogon - In"));
PVMFStatus status = PVMFSuccess;
switch (iInterfaceState)
{
case EPVMFNodeCreated:
{
if (!IsAdded())
AddToScheduler();
iCmdSeqLogger = PVLogger::GetLoggerObject("pvplayercmdseq.streamingmanager");
iReposLogger = PVLogger::GetLoggerObject("pvplayerrepos.sourcenode.streamingmanager");
/*
* Call thread logon for all the children nodes
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNode->ThreadLogon() != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode - Child Node:ThreadLogon Failed, Node Tag %d", iNodeContainerVec[i].iNodeTag));
status = PVMFFailure;
}
}
if (status == PVMFSuccess)
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::ThreadLogon() - State - EPVMFNodeIdle"));
SetState(EPVMFNodeIdle);
}
}
break;
default:
status = PVMFErrInvalidState;
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ThreadLogon - Out"));
return (status);
}
/**
* Do thread-specific node cleanup and go to "Created" state.
*/
OSCL_EXPORT_REF PVMFStatus PVMFStreamingManagerNode::ThreadLogoff()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ThreadLogoff - In"));
PVMFStatus status = PVMFSuccess;
switch (iInterfaceState)
{
case EPVMFNodeIdle:
{
/* Reset the metadata key list */
/* Clean up CPM related variables */
CleanupCPMdata();
if (IsAdded())
RemoveFromScheduler();
iLogger = NULL;
iCmdSeqLogger = NULL;
iReposLogger = NULL;
/*
* Call thread logon for all the children nodes
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFNodeInterface* node = iNodeContainerVec[i].iNode;
if (node->GetState() != EPVMFNodeCreated)
{
if (node->ThreadLogoff() != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode - Child Node:ThreadLogoff Failed, Node Tag %d", iNodeContainerVec[i].iNodeTag));
status = PVMFFailure;
}
}
}
if (status == PVMFSuccess)
{
SetState(EPVMFNodeCreated);
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::ThreadLogoff() - State - EPVMFNodeIdle"));
}
else
{
SetState(EPVMFNodeError);
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::ThreadLogoff() - State - EPVMFNodeError"));
}
}
break;
case EPVMFNodeCreated:
status = PVMFSuccess;
break;
default:
status = PVMFErrInvalidState;
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ThreadLogoff - Out"));
return (status);
}
/**
* retrieve node capabilities.
*/
OSCL_EXPORT_REF PVMFStatus PVMFStreamingManagerNode::GetCapability(PVMFNodeCapability& aNodeCapability)
{
PVMF_SM_LOGINFO((0, "StreamingManagerNode:GetCapability"));
aNodeCapability = iCapability;
return PVMFSuccess;
}
/**
* retrive a port iterator.
*/
OSCL_EXPORT_REF PVMFPortIter* PVMFStreamingManagerNode::GetPorts(const PVMFPortFilter* aFilter)
{
PVMF_SM_LOGINFO((0, "StreamingManagerNode:GetPorts"));
OSCL_UNUSED_ARG(aFilter);//port filter is not implemented.
return NULL;
}
/**
* Queue an asynchronous QueryUUID command
* QueryUUID for the streaming manager node is not complete until QueryUUIDs
* are complete for all the children node (viz. session controller, jitter buffer
* controller etc)
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
bool aExactUuidsOnly,
const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::QueryUUID - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_QUERYUUID, aMimeType, aUuids, aExactUuidsOnly, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::QueryUUID - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::QueryUUID() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the Query UUID
*/
void PVMFStreamingManagerNode::DoQueryUuid(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoQueryUuid - In"));
if (iQueryUUIDComplete == false)
{
/*
* QueryUUID for streaming manager cannot be completed unless
* QueryUUID for all the children nodes are complete
*/
PVMFSMCommandContext* internalCmd = NULL;
OsclAny *cmdContextData = NULL;
/*
* QueryUUID from socket node
*/
OSCL_StackString<50> socketNodeExtMimeType(PVMF_SOCKET_NODE_EXTENSION_INTERFACE_MIMETYPE);
internalCmd = RequestNewInternalCmd();
if (internalCmd == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoQueryUuid:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
internalCmd->cmd = PVMF_STREAMING_MANAGER_SOCKET_NODE_QUERY_UUID;
internalCmd->parentCmd = aCmd.iCmd;
cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFSMNodeContainer* iSocketNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_SOCKET_NODE);
if (iSocketNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFNodeInterface* iSocketNode = iSocketNodeContainer->iNode;
iSocketNode->QueryUUID(iSocketNodeContainer->iSessionId,
socketNodeExtMimeType,
iSocketNodeContainer->iExtensionUuids,
true,
cmdContextData);
iSocketNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
/*
* QueryUUID from rtsp session controller
*/
OSCL_StackString<50> sessionControllerExtMimeType(PVMF_RTSPENGINENODE_CUSTOM1_MIMETYPE);
internalCmd = RequestNewInternalCmd();
if (internalCmd == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoQueryUuid:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
internalCmd->cmd = PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_QUERY_UUID;
internalCmd->parentCmd = aCmd.iCmd;
cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFNodeInterface* iSessionControllerNode = iSessionControllerNodeContainer->iNode;
iSessionControllerNode->QueryUUID(iSessionControllerNodeContainer->iSessionId,
sessionControllerExtMimeType,
iSessionControllerNodeContainer->iExtensionUuids,
true,
cmdContextData);
iSessionControllerNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
/*
* QueryUUID from jitter buffer node
*/
OSCL_StackString<50> jitterBufferExtMimeType(PVMF_JITTERBUFFER_CUSTOMINTERFACE_MIMETYPE);
internalCmd = RequestNewInternalCmd();
if (internalCmd == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoQueryUuid:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
internalCmd->cmd = PVMF_STREAMING_MANAGER_JITTER_BUFFER_QUERY_UUID;
internalCmd->parentCmd = aCmd.iCmd;
cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFNodeInterface* iJitterBufferNode = iJitterBufferNodeContainer->iNode;
iJitterBufferNode->QueryUUID(iJitterBufferNodeContainer->iSessionId,
jitterBufferExtMimeType,
iJitterBufferNodeContainer->iExtensionUuids,
true,
cmdContextData);
iJitterBufferNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
/*
* QueryUUID from media layer node
*/
OSCL_StackString<50> mediaLayerExtMimeType(PVMF_MEDIALAYER_CUSTOMINTERFACE_MIMETYPE);
internalCmd = RequestNewInternalCmd();
if (internalCmd == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoQueryUuid:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
internalCmd->cmd = PVMF_STREAMING_MANAGER_MEDIA_LAYER_QUERY_UUID;
internalCmd->parentCmd = aCmd.iCmd;
cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFSMNodeContainer* iMediaLayerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE);
if (iMediaLayerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFNodeInterface* iMediaLayerNode = iMediaLayerNodeContainer->iNode;
iMediaLayerNode->QueryUUID(iMediaLayerNodeContainer->iSessionId,
mediaLayerExtMimeType,
iMediaLayerNodeContainer->iExtensionUuids,
true,
cmdContextData);
iMediaLayerNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
/*
* QueryUUID from HTTP PE node
*/
OSCL_StackString<50> httpNodeExtMimeType(PVMF_PROTOCOL_ENGINE_MSHTTP_STREAMING_EXTENSION_MIMETYPE);
internalCmd = RequestNewInternalCmd();
if (internalCmd == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoQueryUuid:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
internalCmd->cmd = PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_QUERY_UUID;
internalCmd->parentCmd = aCmd.iCmd;
cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFSMNodeContainer* iHTTPNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE);
if (iHTTPNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFNodeInterface* iHTTPNode = iHTTPNodeContainer->iNode;
iHTTPNode->QueryUUID(iHTTPNodeContainer->iSessionId,
httpNodeExtMimeType,
iHTTPNodeContainer->iExtensionUuids,
true,
cmdContextData);
iHTTPNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
/*
* This node supports Query UUID from any state
* Query UUID is asynchronous. move the command from
* the input command queue to the current command, where
* it will remain until the Query UUID completes.
*/
MoveCmdToCurrentQueue(aCmd);
}
else if (iQueryUUIDComplete == true)
{
/*
* We have already queried the child nodes for UUID
*/
MoveCmdToCurrentQueue(aCmd);
CompleteQueryUuid();
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoQueryUuid - Out"));
return;
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesQueryUuid()
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE)
{
return false;
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteQueryUuid()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteQueryUuid - In"));
if (CheckChildrenNodesQueryUuid() || iQueryUUIDComplete == true)
{
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
OSCL_String* mimetype;
Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
bool exactmatch;
aCmd.PVMFStreamingManagerNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
/*
* Try to match the input mimetype against any of
* the custom interfaces for this node
* Match against extension interface...
* also match against base mimetypes for extension interface,
* unless exactmatch is set.
*/
if (*mimetype == PVMF_STREAMINGMANAGER_CUSTOMINTERFACE_MIMETYPE)
{
PVUuid uuid(PVMF_STREAMINGMANAGERNODE_EXTENSIONINTERFACE_UUID);
uuidvec->push_back(uuid);
}
else if (*mimetype == PVMF_DATA_SOURCE_INIT_INTERFACE_MIMETYPE)
{
PVUuid uuid(PVMF_DATA_SOURCE_INIT_INTERFACE_UUID);
uuidvec->push_back(uuid);
}
else if (*mimetype == PVMF_TRACK_SELECTION_INTERFACE_MIMETYPE)
{
PVUuid uuid(PVMF_TRACK_SELECTION_INTERFACE_UUID);
uuidvec->push_back(uuid);
}
else if (*mimetype == PVMF_DATA_SOURCE_PLAYBACK_CONTROL_INTERFACE_MIMETYPE)
{
PVUuid uuid(PvmfDataSourcePlaybackControlUuid);
uuidvec->push_back(uuid);
}
else if (*mimetype == PVMF_META_DATA_EXTENSION_INTERFACE_MIMETYPE)
{
PVUuid uuid(KPVMFMetadataExtensionUuid);
uuidvec->push_back(uuid);
}
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::QueryUUID() - CmdComplete - PVMFSuccess"));
iQueryUUIDComplete = true;
CommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode::QueryUuid Complete"));
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteQueryUuid - Out"));
}
/**
* Queue an asynchronous node command QueryInterface
*/
OSCL_EXPORT_REF PVMFCommandId
PVMFStreamingManagerNode::QueryInterface(PVMFSessionId s,
const PVUuid& aUuid,
PVInterface*& aInterfacePtr,
const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::QueryInterface - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::QueryInterface - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::QueryInterface() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the Query Interface.
*/
void PVMFStreamingManagerNode::DoQueryInterface(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoQueryInterface - In"));
if (iQueryInterfaceComplete == false)
{
/*
* QueryInterface for streaming manager cannot be completed unless
* QueryInterface for all the children nodes are complete
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_QUERY_INTERFACE_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->QueryInterface(iNodeContainerVec[i].iSessionId,
iNodeContainerVec[i].iExtensionUuids.front(),
iExtensionInterfacePlaceholder,
cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoQueryInterface:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
/*
* This node supports QueryInterface from any state
* QueryInterface is asynchronous. move the command from
* the input command queue to the current command, where
* it will remain until the QueryInterface completes.
*/
MoveCmdToCurrentQueue(aCmd);
}
else if (iQueryInterfaceComplete == true)
{
/*
* We have already queried the child nodes for interface
*/
MoveCmdToCurrentQueue(aCmd);
CompleteQueryInterface();
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoQueryInterface - Out"));
return;
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesQueryInterface()
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE)
{
return false;
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteQueryInterface()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteQueryInterface - In"));
if (CheckChildrenNodesQueryInterface() || iQueryInterfaceComplete == true)
{
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
PVUuid* uuid;
PVInterface** ptr;
aCmd.PVMFStreamingManagerNodeCommandBase::Parse(uuid, ptr);
if ((*uuid == PVUuid(PVMF_STREAMINGMANAGERNODE_EXTENSIONINTERFACE_UUID)) ||
(*uuid == PVUuid(PVMF_DATA_SOURCE_INIT_INTERFACE_UUID)) ||
(*uuid == PVUuid(PVMF_TRACK_SELECTION_INTERFACE_UUID)) ||
(*uuid == PVUuid(PvmfDataSourcePlaybackControlUuid)) ||
(*uuid == PVUuid(KPVMFMetadataExtensionUuid)) ||
(*uuid == PVUuid(PVMI_CAPABILITY_AND_CONFIG_PVUUID)) ||
(*uuid == PVUuid(PVMFCPMPluginLicenseInterfaceUuid)))
{
if (!iExtensionInterface)
{
PVMFStreamingManagerNodeAllocator alloc;
int32 err;
OsclAny*ptr = NULL;
OSCL_TRY(err,
ptr = alloc.ALLOCATE(sizeof(PVMFStreamingManagerExtensionInterfaceImpl));
);
if (err != OsclErrNone || !ptr)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode CompleteQueryInterface Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
iExtensionInterface =
new(ptr) PVMFStreamingManagerExtensionInterfaceImpl(this,
aCmd.iSession);
}
iQueryInterfaceComplete = true;
iExtensionInterface->queryInterface(*uuid, *ptr);
iExtensionInterface->addRef();
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::QueryInterface() - CmdComplete - PVMFSuccess"));
CommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode CompleteQueryInterface Success"));
}
else
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::QueryInterface() - CmdFailed - PVMFErrNotSupported"));
//not supported
*ptr = NULL;
CommandComplete(aCmd, PVMFErrNotSupported);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteQueryInterface - Out"));
}
/**
* Queue an asynchronous node command - RequestPort
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::RequestPort(PVMFSessionId s,
int32 aPortTag,
const PvmfMimeString* aPortConfig,
const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::RequestPort - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s,
PVMF_STREAMING_MANAGER_NODE_REQUESTPORT,
aPortTag,
aPortConfig,
aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::RequestPort - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::RequestPort() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the port request
*/
void PVMFStreamingManagerNode::DoRequestPort(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoRequestPort - In"));
/*
* This node supports port request only after the graph
* has been fully constructed
*/
if (oGraphConstructComplete)
{
/*
* retrieve port tag
*/
OSCL_String* mimetype;
int32 tag;
aCmd.PVMFStreamingManagerNodeCommandBase::Parse(tag, mimetype);
/*
* Do not Allocate a new port. Streaming manager treats the output
* port from the media layer as its own output port. Find the media
* layer output port corresponding to the input mimetype and hand the
* same out
*/
PVMFSMTrackInfo* trackInfo = FindTrackInfo(tag);
PVUuid eventuuid = PVMFStreamingManagerNodeEventTypeUUID;
int32 errcode = PVMFStreamingManagerNodeErrorInvalidRequestPortTag;
if (trackInfo == NULL)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::DoRequestPort: FindTrackInfo failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrArgument, NULL, &eventuuid, &errcode);
return;
}
if (trackInfo->iMediaLayerOutputPort == NULL)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::DoRequestPort: iMediaLayerOutputPort NULL"));
CommandComplete(iInputCommands, aCmd, PVMFFailure, NULL, &eventuuid, &errcode);
return;
}
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::RequestPort() - CmdComplete - PVMFSuccess"));
/*
* Return the port pointer to the caller.
*/
CommandComplete(iInputCommands,
aCmd,
PVMFSuccess,
(OsclAny*)(trackInfo->iMediaLayerOutputPort));
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode::DoRequestPort Success"));
}
else
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::RequestPort() - CmdFailed - PVMFErrInvalidState"));
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::DoRequestPort Failed - InvalidState"));
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoRequestPort - Out"));
}
/**
* Queue an asynchronous node command
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ReleasePort - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_RELEASEPORT, aPort, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ReleasePort - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::ReleasePort() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the port release
*/
void PVMFStreamingManagerNode::DoReleasePort(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoReleasePort - In"));
/*
* Since the streaming manager does not have ports of its own,
* a release port command typically translates to disconnecting
* the underlying media layer port.
*/
PVMFPortInterface* port;
aCmd.PVMFStreamingManagerNodeCommandBase::Parse((PVMFPortInterface*&)port);
/*
* Find TrackInfo that corresponds to the Media Layer Output port
* on which the current relase is being called.
*/
PVMFSMTrackInfoVector::iterator it;
PVMFSMTrackInfo* trackInfo = NULL;
for (it = iTrackInfoVec.begin();
it != iTrackInfoVec.end();
it++)
{
if (it->iMediaLayerOutputPort == port)
{
trackInfo = it;
break;
}
}
PVUuid eventuuid = PVMFStreamingManagerNodeEventTypeUUID;
if (trackInfo == NULL)
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::ReleasePort() - CmdFailed - PVMFErrArgument"));
/* invalid port */
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::DoReleasePort Failed - Invalid Port"));
int32 errcode = PVMFStreamingManagerNodeErrorInvalidPort;
CommandComplete(iInputCommands, aCmd, PVMFErrArgument, NULL, &eventuuid, &errcode);
return;
}
PVMFStatus status = it->iMediaLayerOutputPort->Disconnect();
if (status != PVMFSuccess)
{
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode::DoReleasePort Success"));
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::DoReleasePort Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrPortProcessing);
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoReleasePort - Out"));
}
/**
* Queue an asynchronous node command - Init
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::Init(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Init - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_INIT, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Init - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Init() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Call by DoInit as a prep step
*/
PVMFStatus PVMFStreamingManagerNode::DoPreInit(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoPreInit - In"));
PVMFStatus status = PVMFSuccess;
if (iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE)
{
}
else if (iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE)
{
status = ProcessSDP();
if (status == PVMFSuccess)
{
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
/*
* This vector is intentionally left uninitialized.
* Streaming manager does not have any track selection info
* at this stage. "SetSDPInfo" would be called again before
* prepare complete to set up all the selected tracks. This
* call is needed here to indicate to Session Controller node
* that it is NOT a RTSP URL based session
*/
Oscl_Vector<StreamInfo, OsclMemAllocator> aSelectedStream;
status = rtspExtIntf->SetSDPInfo(iSessionSourceInfo->_sdpInfo,
aSelectedStream);
if (status != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoPreInit - SetSDPInfo Failed"));
}
}
else
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoPreInit - ProcessSDP Failed"));
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoPreInit - Out"));
return status;
}
void PVMFStreamingManagerNode::CompletePreInit()
{
OSCL_ASSERT(iSessionSourceInfo->_sessionType ==
PVMF_DATA_SOURCE_MS_HTTP_STREAMING_URL);
Asf_CompletePreInit();
}
/**
* Called by the command handler AO to do the node Init
*/
void PVMFStreamingManagerNode::DoInit(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoInit - In"));
switch (iInterfaceState)
{
case EPVMFNodeIdle:
{
/*
* At first Init, PVMFErrLicneseRequest is replied from Janus.
* Then iCPMInitPending is set into true.
* If second Init is called, just to check license authentication is required.
*/
if (iCPMInitPending == true)
{
MoveCmdToCurrentQueue(aCmd);
{
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
PVMFFailure,
NULL, NULL, NULL);
return;
}
}
else
{
/* An asynchronous method that prepare's the node for init */
PVMFStatus status = DoPreInit(aCmd);
DeleteUnusedSessionControllerNode();
if (status == PVMFSuccess)
{
/*
* Init for streaming manager cannot be completed unless Init
* for all the children nodes are complete
*/
PVMFSMNodeContainerVector::iterator it;
for (it = iNodeContainerVec.begin(); it != iNodeContainerVec.end(); it++)
{
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
it->commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_INIT_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData =
OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = it->iNode;
iNode->Init(it->iSessionId, cmdContextData);
it->iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoInit:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
}
MoveCmdToCurrentQueue(aCmd);
}
else if (status == PVMFPending)
{
MoveCmdToCurrentQueue(aCmd);
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoInit: DoPreInit() - Failed"));
PVUuid eventuuid = PVMFStreamingManagerNodeEventTypeUUID;
int32 errcode = PVMFStreamingManagerNodeErrorParseSDPFailed;
CommandComplete(iInputCommands, aCmd, PVMFFailure, NULL, &eventuuid, &errcode);
return;
}
}
}
break;
default:
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::DoInit Failed - Invalid State"));
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
}
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoInit - Out"));
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesInit()
{
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE)
{
return false;
}
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteInit()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteInit - In"));
if (CheckChildrenNodesInit() && iErrorDuringProcess == SM_NO_ERROR)
{
if (!iCurrentCommand.empty() && iCancelCommand.empty())
{
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
if (aCmd.iCmd == PVMF_STREAMING_MANAGER_NODE_INIT)
{
// create and pass the payload parser registry on to the media layer node
PopulatePayloadParserRegistry();
PVMFStatus status = PVMFSuccess;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL))
{
status = ProcessSDP();
}
if (status == PVMFSuccess)
{
status = InitMetaData();
if (status == PVMFSuccess)
{
}
else
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteInit - InitMetaData fail"));
}
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Init() - CmdComplete - PVMFSuccess"));
//Init is completed at unprotected clip
SetState(EPVMFNodeInitialized);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode::CompleteInit Success"));
CommandComplete(aCmd, PVMFSuccess);
}
else
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Init() - Cmd Failed - PVMFStreamingManagerNodeErrorParseSDPFailed"));
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::CompleteInit Failure"));
PVUuid eventuuid = PVMFStreamingManagerNodeEventTypeUUID;
int32 errcode = PVMFStreamingManagerNodeErrorParseSDPFailed;
CommandComplete(aCmd, status, NULL, &eventuuid, &errcode);
}
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteInit - Out"));
return;
}
/**
* Queue an asynchronous node command - Prepare
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::Prepare(PVMFSessionId s,
const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Prepare - In"));
/* Queue an internal command for Graph construct */
PVMFStreamingManagerNodeCommand cmdGC;
cmdGC.PVMFStreamingManagerNodeCommandBase::Construct(s,
PVMF_STREAMING_MANAGER_NODE_CONSTRUCT_SESSION,
NULL);
QueueCommandL(cmdGC);
PVMFStreamingManagerNodeCommand cmdPrep;
cmdPrep.PVMFStreamingManagerNodeCommandBase::Construct(s,
PVMF_STREAMING_MANAGER_NODE_PREPARE,
aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Prepare - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Prepare() - Cmd Recvd"));
return QueueCommandL(cmdPrep);
}
/**
* Called by the command handler AO to do the node Prepare
*/
void PVMFStreamingManagerNode::DoPrepare(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoPrepare - In"));
switch (iInterfaceState)
{
case EPVMFNodeInitialized:
{
if (oGraphConstructComplete)
{
/*
* Connect the graph here. This is needed since we would send firewall packets
* as part of Prepare.
*/
if (GraphConnect() == false)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoPrepare - GraphConnect Failed"));
SetState(EPVMFNodeError);
PVUuid eventuuid = PVMFStreamingManagerNodeEventTypeUUID;
int32 errcode = PVMFStreamingManagerNodeGraphConnectFailed;
CommandComplete(aCmd, PVMFFailure, NULL, &eventuuid, &errcode);
return;
}
{
/*
* Prepare for streaming manager cannot be completed unless Prepare
* for all the children nodes are complete
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_PREPARE_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData =
OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Prepare(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoPrepare:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
}
MoveCmdToCurrentQueue(aCmd);
}
else
{
/* Graph construction not complete, so cant prep */
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoPrepare Failed - Incomplete Graph"));
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
}
}
break;
default:
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoPrepare Failed - Invalid State"));
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoPrepare - Out"));
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesPrepare()
{
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE)
{
return false;
}
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompletePrepare()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompletePrepare - In"));
if ((CheckChildrenNodesPrepare()) && (oGraphConstructComplete) && iErrorDuringProcess == SM_NO_ERROR)
{
if (!iCurrentCommand.empty() && iCancelCommand.empty())
{
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
if (aCmd.iCmd == PVMF_STREAMING_MANAGER_NODE_PREPARE)
{
SetState(EPVMFNodePrepared);
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Prepare() - CmdComplete - PVMFSuccess"));
CommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompletePrepare - Out"));
return;
}
/**
* Queue an asynchronous node command
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::Start(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Start - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_START, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Start - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Start() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the node Start
*/
void PVMFStreamingManagerNode::DoStart(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoStart - In"));
switch (iInterfaceState)
{
case EPVMFNodePrepared:
{
/*
* Connect the graph if not already connected. Usually the graph is
* disconnected as part of Stop. In case we are doing a start after
* stop, we would need to connect the graph again.
*/
if (GraphConnect() == false)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:CompleteStart - GraphConnect Failed"));
SetState(EPVMFNodeError);
PVUuid eventuuid = PVMFStreamingManagerNodeEventTypeUUID;
int32 errcode = PVMFStreamingManagerNodeGraphConnectFailed;
CommandComplete(aCmd, PVMFFailure, NULL, &eventuuid, &errcode);
return;
}
/*
* Start for streaming manager cannot be completed unless
* Start for all the children nodes are complete
*/
{
if (iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE)
{
uint32 duration = 2000;
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
/* Set jitter buffer duration */
jbExtIntf->setJitterBufferDurationInMilliSeconds(duration);
}
/*
* Start for streaming manager cannot be completed unless
* Start for all the children nodes are complete
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_START_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Start(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoStart:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
}
MoveCmdToCurrentQueue(aCmd);
}
break;
/*
* GraphConnect() not needed if starting from a paused state
*/
case EPVMFNodePaused:
{
/*
* Start for streaming manager cannot be completed unless
* Start for all the children nodes are complete
*/
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iAutoPaused == false)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_START_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Start(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoStart:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
}
}
MoveCmdToCurrentQueue(aCmd);
}
break;
case EPVMFNodeStarted:
//Ignore start if already started
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
break;
default:
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoStart - Out"));
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesStart()
{
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMNodeCmdState tmp = iNodeContainerVec[i].iNodeCmdState;
uint32 tag = iNodeContainerVec[i].iNodeTag;
if (iNodeContainerVec[i].iNodeCmdState == PVMFSM_NODE_CMD_PENDING)
{
return false;
}
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteStart()
{
int32 localMode = 0;
if (iPVMFDataSourcePositionParamsPtr != NULL)
{
localMode = iPVMFDataSourcePositionParamsPtr->iMode;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteStart - In"));
if (CheckChildrenNodesStart() && iErrorDuringProcess == SM_NO_ERROR)
{
if (!iCurrentCommand.empty() && iCancelCommand.empty())
{
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
if ((aCmd.iCmd == PVMF_STREAMING_MANAGER_NODE_START) ||
(aCmd.iCmd == PVMF_STREAMING_MANAGER_NODE_SET_DATASOURCE_POSITION))
{
if (oRepositioning)
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::SetDataSourcePosition() - CmdComplete - PMVFSuccess"));
oRepositioning = false;
oPlayListRepositioning = false;
if ((localMode == 0) || (localMode == -1))
{
GetAcutalMediaTSAfterSeek();
}
iPVMFDataSourcePositionParamsPtr = NULL;
}
if ((iAutoResumePending == 2) && (iAutoPaused == true))
{
iAutoResumePending = 1;
/* internal command - session id does not matter */
PVMFSessionId s = 0;
PVMFStreamingManagerNodeCommand cmdAutoResume;
cmdAutoResume.PVMFStreamingManagerNodeCommandBase::Construct(s,
PVMF_STREAMING_MANAGER_NODE_AUTO_RESUME,
NULL);
QueueCommandL(cmdAutoResume);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:CompleteStart: - AutoResume Queued"));
}
if ((localMode == 0) || (localMode == -1))
{
SetState(EPVMFNodeStarted);
if (IsAdded())
{
/* wakeup the AO */
RunIfNotReady();
}
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Start() - CmdComplete - PMVFSuccess"));
}
CommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteStart - Out"));
return;
}
/**
* Called by the command handler AO to do the Auto Resume
*/
void PVMFStreamingManagerNode::DoAutoResume(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoAutoResume - In"));
if (iSessionStopTimeAvailable == false)
{
/* Implies an open ended session - no pause or reposition */
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoAutoResume in live - PVMFErrNotSupported"));
InternalCommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
return;
}
bool oCmdSent = false;
switch (iInterfaceState)
{
case EPVMFNodeStarted:
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
/* We only pause session controller and socket nodes in auto-pause */
int32 nodeTag = iNodeContainerVec[i].iNodeTag;
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
if ((nodeTag == PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE))
{
if (iNode->GetState() != EPVMFNodeStarted)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_START_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
iNode->Start(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
oCmdSent = true;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoAutoResume:RequestNewInternalCmd - Failed"));
InternalCommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
}
}
if (oCmdSent)
{
MoveCmdToCurrentQueue(aCmd);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:DoAutoResume: - Start Sent"));
}
else
{
iAutoResumePending = 0;
InternalCommandComplete(iInputCommands, aCmd, PVMFSuccess);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:DoAutoResume: - Done"));
}
}
break;
case EPVMFNodePaused:
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
int32 nodeTag = iNodeContainerVec[i].iNodeTag;
if (nodeTag == PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE)
{
iNodeContainerVec[i].iAutoPaused = false;
}
}
iAutoResumePending = 0;
InternalCommandComplete(iInputCommands, aCmd, PVMFSuccess);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:DoAutoResume in EPVMFNodePaused: - Done"));
}
break;
default:
{
iAutoResumePending = 0;
InternalCommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
}
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoAutoResume - Out"));
return;
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesAutoResume()
{
PVMFSMNodeContainerVector::iterator it;
for (it = iNodeContainerVec.begin(); it != iNodeContainerVec.end(); it++)
{
int32 nodeTag = it->iNodeTag;
if ((nodeTag == PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE))
{
if (it->iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE
&& it->iNodeCmdState != PVMFSM_NODE_CMD_NO_PENDING)
{
return false;
}
else
{
it->iAutoPaused = false;
}
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteAutoResume()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteAutoResume - In"));
if (CheckChildrenNodesAutoResume() && iErrorDuringProcess == SM_NO_ERROR)
{
iAutoResumePending = 0;
iAutoPaused = false;
/* Notify jitter buffer so that it may pause its estimated server clock */
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
if (jbExtIntf == NULL) OSCL_LEAVE(OsclErrBadHandle);
jbExtIntf->NotifyAutoResumeComplete();
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
InternalCommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:DoAutoResume: - Done"));
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteAutoResume - Out"));
return;
}
/**
* Queue an asynchronous node command
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::Stop(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Stop - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_STOP, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Stop - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Stop() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the node Stop
*/
void PVMFStreamingManagerNode::DoStop(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoStop - In"));
switch (iInterfaceState)
{
case EPVMFNodeStarted:
case EPVMFNodePaused:
{
{
/*
* Stop for streaming manager cannot be completed unless
* Stop for all the children nodes are complete
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_STOP_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Stop(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoStop:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
}
MoveCmdToCurrentQueue(aCmd);
}
break;
default:
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::DoStop Failure - Invalid State"));
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoStop - Out"));
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesStop()
{
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE)
{
return false;
}
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteStop()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteStop - In"));
if (CheckChildrenNodesStop() && iErrorDuringProcess == SM_NO_ERROR)
{
if (!iCurrentCommand.empty() && iCancelCommand.empty())
{
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
if (aCmd.iCmd == PVMF_STREAMING_MANAGER_NODE_STOP)
{
/* transition to Prepared state */
ResetStopCompleteParams();
SetState(EPVMFNodePrepared);
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Stop() - CmdComplete - PVMFSuccess"));
CommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteStop - Out"));
return;
}
void PVMFStreamingManagerNode::ResetStopCompleteParams()
{
iStreamThinningInProgress = false;
iPlaylistPlayInProgress = false;
iSwitchStreamIFrameVideo = false;
iRepositionRequestedStartNPTInMS = 0;
}
/**
* Queue an asynchronous node command
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::Flush(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Flush - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_FLUSH, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Flush - Out"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the node Flush
*/
void PVMFStreamingManagerNode::DoFlush(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoFlush - In"));
switch (iInterfaceState)
{
case EPVMFNodeStarted:
case EPVMFNodePaused:
{
/*
* Flush for streaming manager cannot be completed unless
* Flush for all the children nodes are complete
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_FLUSH_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Flush(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoFlush:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
MoveCmdToCurrentQueue(aCmd);
/*
* Notify all ports to suspend their input - TBD
*/
/*
* If the node is not running we need to wakeup the
* AO to further complete the flush, which means all
* port activity needs to be completed.
*/
if (IsAdded())
{
RunIfNotReady();
}
}
break;
default:
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoFlush - Out"));
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesFlush()
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE)
{
return false;
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteFlush()
{
/*
* If the node is not running we need to wakeup the
* AO to further complete the flush, which means all
* port activity needs to be completed.
*/
if (iInterfaceState != EPVMFNodeStarted)
{
if (IsAdded())
{
RunIfNotReady();
}
}
return;
}
/**
* Queue an asynchronous node command
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::Pause(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Pause - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_PAUSE, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Pause - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Pause() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the node Pause
*/
void PVMFStreamingManagerNode::DoPause(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoPause - In"));
switch (iInterfaceState)
{
case EPVMFNodeStarted:
{
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
/*
* Pause only if not already paused - could happen that
* some of the nodes could be paused due to flow control
*/
if ((iNodeContainerVec[i].iNode->GetState()) != EPVMFNodePaused)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_PAUSE_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Pause(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoPause:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
}
}
MoveCmdToCurrentQueue(aCmd);
}
break;
default:
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoPause - Out"));
return;
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesPause()
{
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE
&& iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_NO_PENDING)
{
return false;
}
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompletePause()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompletePause - In"));
if (CheckChildrenNodesPause() && iErrorDuringProcess == SM_NO_ERROR)
{
SetState(EPVMFNodePaused);
if (oRepositioning)
{
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
/*
* Pause request generated by a reposition command
* complete. Issue a start.
*/
if (iPVMFDataSourcePositionParamsPtr == NULL)
{
DoRepositioningStart3GPPStreaming();
}
}
}
else
{
if (!iCurrentCommand.empty() && iCancelCommand.empty())
{
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Pause() - CmdComplete - PVMFSuccess"));
CommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompletePause - Out"));
return;
}
/**
* Called by the command handler AO to do the Auto Pause
*/
void PVMFStreamingManagerNode::DoAutoPause(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoAutoPause - In"));
if (iSessionStopTimeAvailable == false)
{
/* Implies an open ended session - no pause or reposition */
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoAutoPause in live - PVMFErrNotSupported"));
InternalCommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
return;
}
bool oCmdSent = false;
switch (iInterfaceState)
{
case EPVMFNodeStarted:
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
/* We only pause session controller and socket nodes in auto-pause */
int32 nodeTag = iNodeContainerVec[i].iNodeTag;
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
if ((nodeTag == PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE))
{
if (iNode->GetState() != EPVMFNodePaused)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_PAUSE_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
iNode->Pause(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
oCmdSent = true;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoAutoPause:RequestNewInternalCmd - Failed"));
InternalCommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
}
}
if (oCmdSent == true)
{
MoveCmdToCurrentQueue(aCmd);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:DoAutoPause: - Pause Sent"));
}
else
{
iAutoPausePending = false;
InternalCommandComplete(iInputCommands, aCmd, PVMFSuccess);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:DoAutoPause: - Done"));
}
}
break;
case EPVMFNodePaused:
{
/*
* If state is EPVMFNodePaused when Highwatermark event is reported, we ignore this event.
* But if Highwatermark event is reported while pause cmd is pending,
* we call DoAutoPause and JB node expect SM node go to autopause. So we set iAutoPaused to true.
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
int32 nodeTag = iNodeContainerVec[i].iNodeTag;
if (nodeTag == PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE)
{
iNodeContainerVec[i].iAutoPaused = true;
}
}
iAutoPausePending = false;
iAutoPaused = true;
InternalCommandComplete(iInputCommands, aCmd, PVMFSuccess);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:DoAutoPause in EPVMFNodePaused: - Done"));
}
break;
default:
{
iAutoPausePending = false;
InternalCommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
}
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoAutoPause - Out"));
return;
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesAutoPause()
{
PVMFSMNodeContainerVector::iterator it;
for (it = iNodeContainerVec.begin(); it != iNodeContainerVec.end(); it++)
{
int32 nodeTag = it->iNodeTag;
if ((nodeTag == PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE))
{
if (it->iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE
&& it->iNodeCmdState != PVMFSM_NODE_CMD_NO_PENDING)
{
return false;
}
else
{
it->iAutoPaused = true;
}
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteAutoPause()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteAutoPause - In"));
if (CheckChildrenNodesAutoPause() && iErrorDuringProcess == SM_NO_ERROR)
{
iAutoPausePending = false;
iAutoPaused = true;
/* Notify jitter buffer so that it may pause its estimated server clock */
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
if (jbExtIntf == NULL) OSCL_LEAVE(OsclErrBadHandle);
jbExtIntf->NotifyAutoPauseComplete();
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
InternalCommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:DoAutoPause: - Done"));
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteAutoPause - Out"));
return;
}
/**
* Queue an asynchronous node command
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::Reset(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Reset - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_RESET, aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::Reset - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Reset() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Called by the command handler AO to do the node Reset.
*/
void PVMFStreamingManagerNode::DoReset(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoReset - In"));
/* this node allows a reset from any idle or error state */
switch (iInterfaceState)
{
case EPVMFNodeCreated:
case EPVMFNodeIdle:
case EPVMFNodeInitialized:
case EPVMFNodePrepared:
case EPVMFNodeStarted:
case EPVMFNodePaused:
case EPVMFNodeError:
{
/*
* Reset for streaming manager cannot be completed unless
* Reset for all the children nodes are complete
*/
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_RESET_CMD_OFFSET;
internalCmd->parentCmd = aCmd.iCmd;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Reset(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoReset:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
MoveCmdToCurrentQueue(aCmd);
}
break;
default:
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::DoReset Failure - Invalid State"));
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoReset - Out"));
}
bool
PVMFStreamingManagerNode::CheckChildrenNodesReset()
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_COMPLETE)
{
return false;
}
}
return true;
}
void PVMFStreamingManagerNode::CompleteReset()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteReset - In"));
if (CheckChildrenNodesReset() && iDRMResetPending == false)
{
ResetNodeContainerCmdState();
if (!iCurrentCommand.empty() && iCancelCommand.empty())
{
/* Indicates that the init for Children Nodes was successfull */
/* At protected clip, Reset CPM also was successfull */
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
if (aCmd.iCmd == PVMF_STREAMING_MANAGER_NODE_RESET)
{
/* Reset Params */
ResetNodeParams();
/* Reset the metadata key list */
/* Clean up CPM related variables */
CleanupCPMdata();
/* logoff & go back to Created state */
SetState(EPVMFNodeIdle);
PVMFStatus status = ThreadLogoff();
if (iErrorDuringProcess == SM_NO_ERROR)
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::Reset() - CmdComplete - Status=%d", status));
CommandComplete(aCmd, status);
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::CompleteReset -- CPM Reset error"));
CommandComplete(aCmd, PVMFFailure, iErrorResponseInf);
if (iErrorResponseInf != NULL)
{
iErrorResponseInf->removeRef();
iErrorResponseInf = NULL;
}
iErrorDuringProcess = SM_NO_ERROR;
}
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
// destroy the payload parser registry
destroyPayloadParserRegistry();
}
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteReset - Out"));
return;
}
/**
* Queue an asynchronous node command
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_SM_LOGINFO((0, "StreamingManagerNode:CancelAllCommands"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS, aContext);
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::CancelAllCommands() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* Queue an asynchronous node command
*/
OSCL_EXPORT_REF PVMFCommandId PVMFStreamingManagerNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
{
PVMF_SM_LOGINFO((0, "StreamingManagerNode:CancelCommand"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommandBase::Construct(s, PVMF_STREAMING_MANAGER_NODE_CANCELCOMMAND, aCmdId, aContext);
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::CancelCommand() - Cmd Recvd"));
return QueueCommandL(cmd);
}
/**
* This routine is called by various command APIs to queue an
* asynchronous command for processing by the command handler AO.
* This function may leave if the command can't be queued due to
* memory allocation failure.
*/
PVMFCommandId PVMFStreamingManagerNode::QueueCommandL(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMFCommandId id;
id = iInputCommands.AddL(aCmd);
if (IsAdded())
{
//wakeup the AO
RunIfNotReady();
}
return id;
}
/**
* Called by the command handler AO to process a command from
* the input queue.
* Return true if a command was processed, false if the command
* processor is busy and can't process another command now.
*/
bool PVMFStreamingManagerNode::ProcessCommand(PVMFStreamingManagerNodeCommand& aCmd)
{
/*
* normally this node will not start processing one command
* until the prior one is finished. However, a hi priority
* command such as Cancel must be able to interrupt a command
* in progress.
*/
if ((iCurrentCommand.size() > 0 && !aCmd.hipri()
&& aCmd.iCmd != PVMF_STREAMING_MANAGER_NODE_CANCEL_GET_LICENSE)
|| iCancelCommand.size() > 0)
return false;
switch (aCmd.iCmd)
{
case PVMF_STREAMING_MANAGER_NODE_QUERYUUID:
DoQueryUuid(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_QUERYINTERFACE:
DoQueryInterface(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_REQUESTPORT:
DoRequestPort(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_RELEASEPORT:
DoReleasePort(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_INIT:
DoInit(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_PREPARE:
DoPrepare(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_START:
DoStart(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_STOP:
DoStop(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_FLUSH:
DoFlush(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_PAUSE:
DoPause(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_RESET:
DoReset(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS:
DoCancelAllCommands(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_CANCELCOMMAND:
DoCancelCommand(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_CONSTRUCT_SESSION:
{
if (!GraphConstruct())
{
InternalCommandComplete(iInputCommands,
aCmd,
PVMFFailure);
}
else
{
/*
* Move it to current command queue where it would
* stay until "GraphConstruct" is complete
*/
MoveCmdToCurrentQueue(aCmd);
}
}
break;
case PVMF_STREAMING_MANAGER_NODE_SET_DATASOURCE_POSITION:
{
{
DoSetDataSourcePosition(aCmd);
}
}
break;
case PVMF_STREAMING_MANAGER_NODE_QUERY_DATASOURCE_POSITION:
DoQueryDataSourcePosition(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_GETNODEMETADATAKEYS:
{
PVMFStatus status = DoGetMetadataKeys(aCmd);
if (status != PVMFPending)
{
CommandComplete(iInputCommands, aCmd, status);
}
else
{
MoveCmdToCurrentQueue(aCmd);
}
}
break;
case PVMF_STREAMING_MANAGER_NODE_GETNODEMETADATAVALUES:
{
PVMFStatus status = DoGetMetadataValues(aCmd);
if (status != PVMFPending)
{
CommandComplete(iInputCommands, aCmd, status);
}
else
{
MoveCmdToCurrentQueue(aCmd);
}
}
break;
case PVMF_STREAMING_MANAGER_NODE_CAPCONFIG_SETPARAMS:
{
PvmiMIOSession session;
PvmiKvp* aParameters;
int num_elements;
PvmiKvp** ppRet_kvp;
aCmd.Parse(session, aParameters, num_elements, ppRet_kvp);
setParametersSync(NULL, aParameters, num_elements, *ppRet_kvp);
ciObserver->SignalEvent(aCmd.iId);
}
case PVMF_STREAMING_MANAGER_NODE_AUTO_PAUSE:
DoAutoPause(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_AUTO_RESUME:
DoAutoResume(aCmd);
break;
case PVMF_STREAMING_MANAGER_NODE_GET_LICENSE_W:
{
PVMFStatus status = DoGetLicense(aCmd, true);
if (status == PVMFPending)
{
MoveCmdToCurrentQueue(aCmd);
}
else
{
CommandComplete(iInputCommands, aCmd, status);
}
}
break;
case PVMF_STREAMING_MANAGER_NODE_GET_LICENSE:
{
PVMFStatus status = DoGetLicense(aCmd);
if (status == PVMFPending)
{
MoveCmdToCurrentQueue(aCmd);
}
else
{
CommandComplete(iInputCommands, aCmd, status);
}
}
break;
case PVMF_STREAMING_MANAGER_NODE_CANCEL_GET_LICENSE:
DoCancelGetLicense(aCmd);
break;
default:
/* unknown command type */
CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
break;
}
return true;
}
/**
* The various command handlers call this when a command is complete.
*/
void PVMFStreamingManagerNode::CommandComplete(PVMFStreamingManagerNodeCmdQ& aCmdQ,
PVMFStreamingManagerNodeCommand& aCmd,
PVMFStatus aStatus,
OsclAny* aEventData,
PVUuid* aEventUUID,
int32* aEventCode,
PVInterface* aExtMsg)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
PVInterface* extif = NULL;
PVMFBasicErrorInfoMessage* errormsg = NULL;
if (aExtMsg)
{
extif = aExtMsg;
}
else if (aEventUUID && aEventCode)
{
errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
}
/* create response */
PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
PVMFSessionId session = aCmd.iSession;
/* Erase the command from the queue */
aCmdQ.Erase(&aCmd);
/* Report completion to the session observer */
ReportCmdCompleteEvent(session, resp);
if (errormsg)
{
errormsg->removeRef();
}
/* Reschedule AO if input command queue is not empty */
if (!iInputCommands.empty())
{
if (IsAdded())
{
RunIfNotReady();
}
}
/*
* Transition to error state in case of select errors only, viz.
* PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
* Any other error implies that the node is probably in a recoverable
* state
*/
if (IsFatalErrorEvent(aStatus))
{
SetState(EPVMFNodeError);
}
}
void PVMFStreamingManagerNode::CommandComplete(PVMFStreamingManagerNodeCmdQ& aCmdQ,
PVMFStreamingManagerNodeCommand& aCmd,
PVMFStatus aStatus,
OsclAny* aEventData,
PVUuid* aEventUUID,
int32* aEventCode)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
PVInterface* extif = NULL;
PVMFBasicErrorInfoMessage* errormsg = NULL;
if (aEventUUID && aEventCode)
{
errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
}
/* create response */
PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
PVMFSessionId session = aCmd.iSession;
/* Erase the command from the queue */
aCmdQ.Erase(&aCmd);
/* Report completion to the session observer */
ReportCmdCompleteEvent(session, resp);
if (errormsg)
{
errormsg->removeRef();
}
/* Reschedule AO if input command queue is not empty */
if (!iInputCommands.empty() && IsAdded())
{
if (IsAdded())
{
RunIfNotReady();
}
}
/*
* Transition to error state in case of select errors only, viz.
* PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
* Any other error implies that the node is probably in a recoverable
* state
*/
if (IsFatalErrorEvent(aStatus))
{
SetState(EPVMFNodeError);
}
}
void PVMFStreamingManagerNode::CommandComplete(PVMFStreamingManagerNodeCommand& aCmd,
PVMFStatus aStatus,
OsclAny* aEventData,
PVUuid* aEventUUID,
int32* aEventCode)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
PVInterface* extif = NULL;
PVMFBasicErrorInfoMessage* errormsg = NULL;
if (aEventUUID && aEventCode)
{
errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
}
/* create response */
PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
PVMFSessionId session = aCmd.iSession;
/* Report completion to the session observer */
ReportCmdCompleteEvent(session, resp);
if (errormsg)
{
errormsg->removeRef();
}
/* Reschedule AO if input command queue is not empty */
if (!iInputCommands.empty())
{
if (IsAdded())
{
RunIfNotReady();
}
}
/*
* Transition to error state in case of select errors only, viz.
* PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
* Any other status implies that the node is probably in a recoverable
* state
*/
if (IsFatalErrorEvent(aStatus))
{
SetState(EPVMFNodeError);
}
}
/**
* The various command handlers call this when a command is complete.
*/
void PVMFStreamingManagerNode::CommandComplete(PVMFStreamingManagerNodeCmdQ& aCmdQ,
PVMFStreamingManagerNodeCommand& aCmd,
PVMFStatus aStatus,
PVInterface* aErrorExtIntf)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:CommandComplete Id %d Cmd %d Status %d Context %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext));
/* create response */
PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, aErrorExtIntf, NULL);
PVMFSessionId session = aCmd.iSession;
/* Erase the command from the queue */
aCmdQ.Erase(&aCmd);
/* Report completion to the session observer */
ReportCmdCompleteEvent(session, resp);
/* Reschedule AO if input command queue is not empty */
if (!iInputCommands.empty())
{
if (IsAdded())
{
RunIfNotReady();
}
}
/*
* Transition to error state in case of select errors only, viz.
* PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
* Any other error implies that the node is probably in a recoverable
* state
*/
if (IsFatalErrorEvent(aStatus))
{
SetState(EPVMFNodeError);
}
}
void PVMFStreamingManagerNode::CommandComplete(PVMFStreamingManagerNodeCommand& aCmd,
PVMFStatus aStatus,
PVInterface* aErrorExtIntf,
OsclAny* aData)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:CommandComplete Id %d Cmd %d Status %d Context %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext));
/* create response */
PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, aErrorExtIntf, aData);
PVMFSessionId session = aCmd.iSession;
/* Report completion to the session observer */
ReportCmdCompleteEvent(session, resp);
/* Reschedule AO if input command queue is not empty */
if (!iInputCommands.empty())
{
if (IsAdded())
{
RunIfNotReady();
}
}
/*
* Transition to error state in case of select errors only, viz.
* PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
* Any other status implies that the node is probably in a recoverable
* state
*/
if (IsFatalErrorEvent(aStatus))
{
SetState(EPVMFNodeError);
}
}
/**
* The various command handlers call this when an internal command is complete.
* Does not report events to the observer
*/
void
PVMFStreamingManagerNode::InternalCommandComplete(PVMFStreamingManagerNodeCmdQ& aCmdQ,
PVMFStreamingManagerNodeCommand& aCmd,
PVMFStatus aStatus,
OsclAny* aEventData)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
/* Erase the command from the queue */
aCmdQ.Erase(&aCmd);
/* Reschedule AO if input command queue is not empty */
if (!iInputCommands.empty())
{
if (IsAdded())
{
RunIfNotReady();
}
}
/*
* Transition to error state in case of select errors only, viz.
* PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
* Any other status implies that the node is probably in a recoverable
* state
*/
if (IsFatalErrorEvent(aStatus))
{
SetState(EPVMFNodeError);
}
}
void
PVMFStreamingManagerNode::InternalCommandComplete(PVMFStreamingManagerNodeCommand& aCmd,
PVMFStatus aStatus,
OsclAny* aEventData)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
/* Reschedule AO if input command queue is not empty */
if (!iInputCommands.empty())
{
if (IsAdded())
{
RunIfNotReady();
}
}
/*
* Transition to error state in case of select errors only, viz.
* PVMFFailure, PVMFErrNoMemory, PVMFErrNoResources
* Any other status implies that the node is probably in a recoverable
* state
*/
if (IsFatalErrorEvent(aStatus))
{
SetState(EPVMFNodeError);
}
}
/**
//A routine to tell if a flush operation is in progress.
*/
bool PVMFStreamingManagerNode::FlushPending()
{
if ((iCurrentCommand.size() > 0) &&
(iCurrentCommand.front().iCmd == PVMF_STREAMING_MANAGER_NODE_FLUSH) &&
(CheckChildrenNodesFlush() == false))
{
return true;
}
return false;
}
/**
//Called by the command handler AO to do the Cancel All
*/
void PVMFStreamingManagerNode::DoCancelAllCommands(PVMFStreamingManagerNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFStreamingManagerNode::DoCancelAllCommands In"));
//first cancel the current command if any
if (iCurrentCommand.size() > 0)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFStreamingManagerNode::DoCancelAllCommands iCurrentCommand.size()>0"));
/*
* As of now we only allow cancelling the start command. Also only jitter buffer start
* needs to be cancelled. Rest of the nodes dont do anything in start.
*/
{
ResetNodeContainerCmdState();
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_CANCEL_ALL_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->CancelAllCommands(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_CANCEL_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoCancelAllCommands:RequestNewInternalCmd - Failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
}
/* Wait for jitter buffer cancel all to complete */
/* If current command is not start then just wait for current command to complete */
}
MoveCmdToCancelQueue(aCmd);
}
else
{
//no current command - just cancel all queued commands, if any
{
//start at element 1 since this cancel command is element 0.
while (iInputCommands.size() > 1)
{
if (IsInternalCmd(iInputCommands.front().iCmd) == false)
{
CommandComplete(iInputCommands.front(), PVMFErrCancelled);
}
/* Erase the command from the input queue */
iInputCommands.Erase(&iInputCommands.front());
}
}
//finally, report cancel complete.
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFStreamingManagerNode::DoCancelAllCommands Out"));
}
bool PVMFStreamingManagerNode::CheckChildrenNodesCancelAll()
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState != PVMFSM_NODE_CMD_CANCEL_COMPLETE)
{
return false;
}
}
ResetNodeContainerCmdState();
return true;
}
void PVMFStreamingManagerNode::CompleteCancelAll()
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteCancelAll - In"));
if (CheckChildrenNodesCancelAll())
{
if (iCancelCommand.front().iContext)
{
/*
* CancelAllCommands is issued by upper layer
*/
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::CancelCommand() - CmdComplete - PVMFErrCancelled"));
if (!iCurrentCommand.empty())
{
//not need to send commandcmp during GraphConstruct
if (IsInternalCmd(iCurrentCommand.front().iCmd) == false)
{
CommandComplete(iCurrentCommand.front(), PVMFErrCancelled);
}
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
/*
* cancel all queued commands, if any
*/
while (iInputCommands.size() > 0)
{
if (IsInternalCmd(iInputCommands.front().iCmd) == false)
CommandComplete(iInputCommands, iInputCommands.front(), PVMFErrCancelled);
}
/* finally send command complete for the cancel all command */
if (iErrorDuringProcess == SM_NO_ERROR)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteCancelAll - CancelAllCommands complete"));
CommandComplete(iCancelCommand,
iCancelCommand.front(),
PVMFSuccess);
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::CompleteCancelAll - CancelAllCommands complete error"));
CommandComplete(iCancelCommand, iCancelCommand.front(), PVMFFailure, iErrorResponseInf);
if (iErrorResponseInf != NULL)
{
iErrorResponseInf->removeRef();
iErrorResponseInf = NULL;
}
iErrorDuringProcess = SM_NO_ERROR;
}
}
else
{
/*
* CancelAllCommands is issued due to error
*/
if (iCurrentCommand.front().iCmd == PVMF_STREAMING_MANAGER_NODE_RESET)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::CompleteCancelAll Shound not issue CancelAllCommands durint Reset"));
OSCL_ASSERT(false);
}
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::CompleteCancelAll() due to error - CmdComplete"));
/* Erase the command from the cancel queue */
iCancelCommand.Erase(&iCancelCommand.front());
if (!iCurrentCommand.empty())
{
/*
* not need to send commandcmp for internal purpose
*/
if (IsInternalCmd(iCurrentCommand.front().iCmd) == false)
{
CommandComplete(iCurrentCommand.front(), iCmdErrStatus, iErrorResponseInf, iEventData);
}
if (iErrorResponseInf != NULL)
{
iErrorResponseInf->removeRef();
iErrorResponseInf = NULL;
}
iCmdErrStatus = PVMFFailure;
iEventData = NULL;
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
/*
* cancel all queued commands, if any
*/
if (iErrorDuringProcess == SM_NODE_COMMAND_COMPLETION)
{
while (iInputCommands.size() > 0)
{
if (IsInternalCmd(iInputCommands.front().iCmd) == false)
{
CommandComplete(iInputCommands.front(), PVMFErrCancelled);
}
/* Erase the command from the input queue */
iInputCommands.Erase(&iInputCommands.front());
}
}
iErrorDuringProcess = SM_NO_ERROR;
}
}
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteCancelAll - Out"));
return;
}
/**
//Called by the command handler AO to do the Cancel single command
*/
void PVMFStreamingManagerNode::DoCancelCommand(PVMFStreamingManagerNodeCommand& aCmd)
{
//extract the command ID from the parameters.
PVMFCommandId id;
aCmd.PVMFStreamingManagerNodeCommandBase::Parse(id);
//first check "current" command if any
{
PVMFStreamingManagerNodeCommand* cmd = iCurrentCommand.FindById(id);
if (cmd)
{
//cancel the queued command
CommandComplete(iCurrentCommand, *cmd, PVMFErrCancelled);
//report cancel success
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
}
//next check input queue.
{
//start at element 1 since this cancel command is element 0.
PVMFStreamingManagerNodeCommand* cmd = iInputCommands.FindById(id, 1);
if (cmd)
{
//cancel the queued command
CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
//report cancel success
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
}
//if we get here the command isn't queued so the cancel fails.
CommandComplete(iInputCommands, aCmd, PVMFFailure);
}
/////////////////////////////////////////////////////
// Event reporting routines.
/////////////////////////////////////////////////////
void PVMFStreamingManagerNode::SetState(TPVMFNodeInterfaceState s)
{
PVMF_SM_LOGINFO((0, "StreamingManagerNode:SetState %d", s));
PVMFNodeInterface::SetState(s);
}
void PVMFStreamingManagerNode::ReportErrorEvent(PVMFEventType aEventType,
OsclAny* aEventData,
PVUuid* aEventUUID,
int32* aEventCode)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:NodeErrorEvent Type %d Data %d"
, aEventType, aEventData));
if (aEventUUID && aEventCode)
{
PVMFBasicErrorInfoMessage* eventmsg =
OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
PVMFAsyncEvent asyncevent(PVMFErrorEvent,
aEventType,
NULL,
OSCL_STATIC_CAST(PVInterface*, eventmsg),
aEventData,
NULL,
0);
PVMFNodeInterface::ReportErrorEvent(asyncevent);
eventmsg->removeRef();
}
else
{
PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
}
}
void PVMFStreamingManagerNode::ReportInfoEvent(PVMFEventType aEventType,
OsclAny* aEventData,
PVUuid* aEventUUID,
int32* aEventCode)
{
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:NodeInfoEvent Type %d Data %d"
, aEventType, aEventData));
if (aEventUUID && aEventCode)
{
PVMFBasicErrorInfoMessage* eventmsg =
OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
PVMFAsyncEvent asyncevent(PVMFInfoEvent,
aEventType,
NULL,
OSCL_STATIC_CAST(PVInterface*, eventmsg),
aEventData,
NULL,
0);
PVMFNodeInterface::ReportInfoEvent(asyncevent);
eventmsg->removeRef();
}
else
{
PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
}
}
void
PVMFStreamingManagerNode::HandlePortActivity(const PVMFPortActivity& aActivity)
{
OSCL_UNUSED_ARG(aActivity);
PVMF_SM_LOGSTACKTRACE((0, "StreamingManagerNode:HandlePortActivity - Not Implemented"));
}
/**
* Active object implementation
* The AO will either process one command or service one connected
* port per call. It will re-schedule itself and run continuously
* until it runs out of things to do.
*/
void PVMFStreamingManagerNode::Run()
{
/* Process commands */
if (!iInputCommands.empty())
{
if (ProcessCommand(iInputCommands.front()))
{
/*
* re-schedule if more commands to do
* and node isn't reset.
*/
if (!iInputCommands.empty() && iInterfaceState != EPVMFNodeCreated)
{
if (IsAdded())
{
RunIfNotReady();
}
}
return;
}
}
/*
* If we get here we did not process any commands.
* Check for completion of a flush command...
*/
if (FlushPending())
{
/*
* Flush is complete. Go to initialized state.
*/
SetState(EPVMFNodeInitialized);
CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
if (IsAdded())
{
RunIfNotReady();
}
}
}
void PVMFStreamingManagerNode::DoCancel()
{
/* the base class cancel operation is sufficient */
OsclActiveObject::DoCancel();
}
void
PVMFStreamingManagerNode::NodeCommandCompleted(const PVMFCmdResp& aResponse)
{
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode::NodeCommandCompleted"));
bool oResponseOverRide = false;
PVMFSMCommandContext *cmdContextData =
OSCL_REINTERPRET_CAST(PVMFSMCommandContext*, aResponse.GetContext());
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:NodeCommandCompleted: %d", cmdContextData->cmd));
if ((cmdContextData->cmd >=
PVMF_STREAMING_MANAGER_SOCKET_NODE_COMMAND_START) &&
(cmdContextData->cmd <
PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_COMMAND_START))
{
HandleSocketNodeCommandCompleted(aResponse);
}
else if ((cmdContextData->cmd >=
PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_COMMAND_START) &&
(cmdContextData->cmd <
PVMF_STREAMING_MANAGER_JITTER_BUFFER_CONTROLLER_COMMAND_START))
{
HandleRTSPSessionControllerCommandCompleted(aResponse, oResponseOverRide);
}
else if ((cmdContextData->cmd >=
PVMF_STREAMING_MANAGER_JITTER_BUFFER_CONTROLLER_COMMAND_START) &&
(cmdContextData->cmd <
PVMF_STREAMING_MANAGER_MEDIA_LAYER_COMMAND_START))
{
HandleJitterBufferCommandCompleted(aResponse);
}
else if ((cmdContextData->cmd >=
PVMF_STREAMING_MANAGER_MEDIA_LAYER_COMMAND_START) &&
(cmdContextData->cmd <
PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_COMMAND_START))
{
HandleMediaLayerCommandCompleted(aResponse);
}
else if (cmdContextData->cmd >=
PVMF_STREAMING_MANAGER_RTPPACKETSOURCE_NODE_COMMAND_START)
{
}
if ((aResponse.GetCmdStatus() != PVMFSuccess) &&
(aResponse.GetCmdStatus() != PVMFErrCancelled) &&
(oResponseOverRide == false))
{
if (iCancelCommand.size() > 0)
{
if (cmdContextData->parentCmd == PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS)
{
/*
* During CancelAllComands, error happen from child node.
* Then we save this err and after all current cmd is canceled in child node, we send this err code.
* If CancelAllCommands is issued by internal error handling, iErrorDuringProcess should be true.
*/
if (iErrorDuringProcess == SM_NO_ERROR)
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode:NodeCommandCompleted: - Reset Error during CancelAll"));
if (iErrorResponseInf != NULL)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::NodeCommandCompleted - iErrorResponseInf is not NULL"));
OSCL_ASSERT(false);
}
/*
* Only first error msg from cancelall completion in child node is stored.
*/
if (aResponse.GetEventExtensionInterface())
{
iErrorResponseInf = aResponse.GetEventExtensionInterface();
iErrorResponseInf->addRef();
}
iErrorDuringProcess = SM_NODE_COMMAND_COMPLETION;
}
CompleteCancelAll();
}
/*
* If Error is recieved for Current Cmd during cancelling, we just ignore.
*/
}
else if (iCurrentCommand.size() > 0)
{
/*
* If error is recieved while current cmd is ongoing, we save this error code and issue CancelAllCommands.
* After all current cmd is canceled in child node,
* we send this error code if current cmd is not internal use.
*/
if (iErrorDuringProcess == SM_NO_ERROR)
{
if (iErrorResponseInf != NULL)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::NodeCommandCompleted - iErrorResponseInf is not NULL"));
OSCL_ASSERT(false);
}
if (aResponse.GetEventExtensionInterface())
{
iErrorResponseInf = aResponse.GetEventExtensionInterface();
iErrorResponseInf->addRef();
}
iCmdErrStatus = aResponse.GetCmdStatus();
iEventData = aResponse.GetEventData();
iErrorDuringProcess = SM_NODE_COMMAND_COMPLETION;
/*
* We don't interupt any Reset cmd for child node.
* After all Reset cmd is completed in child node, we send this error.
*/
if (cmdContextData->parentCmd != PVMF_STREAMING_MANAGER_NODE_RESET)
{
PVMFSessionId s = 0;
PVMFStreamingManagerNodeCommand cmdCancelPendingCmd;
cmdCancelPendingCmd.PVMFStreamingManagerNodeCommandBase::Construct(s,
PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS,
NULL);
QueueCommandL(cmdCancelPendingCmd);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:NodeCommandCompleted: - CancelAllCommands Queued"));
ResetNodeContainerCmdState();
}
}
else
{
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:NodeCommandCompleted: - CancelAllCommands already Queued"));
}
}
}
return;
}
void
PVMFStreamingManagerNode::HandleSocketNodeCommandCompleted(const PVMFCmdResp& aResponse)
{
PVMFSMNodeContainer* iSocketNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_SOCKET_NODE);
if (iSocketNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFSMCommandContext *cmdContextData =
OSCL_REINTERPRET_CAST(PVMFSMCommandContext*, aResponse.GetContext());
if (iSocketNodeContainer->iNodeCmdState == PVMFSM_NODE_CMD_PENDING)
{
iSocketNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_COMPLETE;
}
else if (iSocketNodeContainer->iNodeCmdState == PVMFSM_NODE_CMD_CANCEL_PENDING)
{
if (cmdContextData->parentCmd == PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS)
iSocketNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_CANCEL_COMPLETE;
}
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::HandleSocketNodeCommandCompleted - Command failed - context=0x%x, status=0x%x", aResponse.GetContext(), aResponse.GetCmdStatus()));
if (IsBusy())
{
Cancel();
RunIfNotReady();
}
return;
}
cmdContextData->oFree = true;
switch (cmdContextData->cmd)
{
case PVMF_STREAMING_MANAGER_SOCKET_NODE_QUERY_UUID:
CompleteQueryUuid();
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_QUERY_INTERFACE:
{
if (iExtensionInterfacePlaceholder == NULL) OSCL_LEAVE(OsclErrBadHandle);
iSocketNodeContainer->iExtensions.push_back(iExtensionInterfacePlaceholder);
CompleteQueryInterface();
}
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_INIT:
{
{
CompleteInit();
}
}
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_PREPARE:
{
{
CompletePrepare();
}
}
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_START:
{
{
{
CompleteStart();
}
}
}
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_STOP:
{
CompleteStop();
}
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_FLUSH:
CompleteFlush();
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_PAUSE:
{
{
CompletePause();
}
}
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_RESET:
CompleteReset();
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_REQUEST_PORT:
{
PVMFPortInterface* port =
(PVMFPortInterface*)aResponse.GetEventData();
{
/*
* Save the port in TrackInfo
*/
PVMFSMTrackInfo* trackInfo =
FindTrackInfo(cmdContextData->portContext.trackID);
if (cmdContextData->portContext.portTag ==
PVMF_SOCKET_NODE_PORT_TYPE_SOURCE)
{
trackInfo->iNetworkNodePort = port;
iSocketNodeContainer->iOutputPorts.push_back(port);
}
else if (cmdContextData->portContext.portTag ==
PVMF_SOCKET_NODE_PORT_TYPE_SINK)
{
trackInfo->iNetworkNodeRTCPPort = port;
iSocketNodeContainer->iInputPorts.push_back(port);
}
CompleteGraphConstruct();
}
}
break;
case PVMF_STREAMING_MANAGER_SOCKET_NODE_CANCEL_ALL_COMMANDS:
{
CompleteCancelAll();
}
break;
default:
break;
}
return;
}
void
PVMFStreamingManagerNode::HandleRTSPSessionControllerCommandCompleted(const PVMFCmdResp& aResponse,
bool& aResponseOverRide)
{
aResponseOverRide = false;
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFSMCommandContext *cmdContextData =
OSCL_REINTERPRET_CAST(PVMFSMCommandContext*, aResponse.GetContext());
if (iSessionControllerNodeContainer->iNodeCmdState == PVMFSM_NODE_CMD_PENDING)
{
iSessionControllerNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_COMPLETE;
}
else if (iSessionControllerNodeContainer->iNodeCmdState == PVMFSM_NODE_CMD_CANCEL_PENDING)
{
if (cmdContextData->parentCmd == PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS)
iSessionControllerNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_CANCEL_COMPLETE;
}
cmdContextData->oFree = true;
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
if (cmdContextData->cmd == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_PAUSE)
{
/*
* Check if it is a pause failure - suppress pause failures if they
* happen after a session is complete
*/
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
bool oSessionExpired = false;
jbExtIntf->HasSessionDurationExpired(oSessionExpired);
if (oSessionExpired == true)
{
aResponseOverRide = true;
}
}
/* if a failure has been overridden just fall thru */
if (aResponseOverRide == false)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::HandleRTSPSessionControllerCommandCompleted - Command failed - context=0x%x, status=0x%x", aResponse.GetContext(), aResponse.GetCmdStatus()));
if (IsBusy())
{
Cancel();
RunIfNotReady();
}
return;
}
}
switch (cmdContextData->cmd)
{
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_QUERY_UUID:
CompleteQueryUuid();
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_QUERY_INTERFACE:
{
if (iExtensionInterfacePlaceholder == NULL) OSCL_LEAVE(OsclErrBadHandle);
iSessionControllerNodeContainer->iExtensions.push_back(iExtensionInterfacePlaceholder);
CompleteQueryInterface();
}
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_INIT:
CompleteInit();
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_PREPARE:
{
if (iSessionSourceInfo->iRTSPTunnelling == false)
{
/* Complete set up of feedback channels */
CompleteFeedBackPortsSetup();
}
/*
* Send start complete params to child nodes
* viz. SSRC etc
*/
SendSessionControlPrepareCompleteParams();
CompletePrepare();
}
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_START:
{
{
/*
* Send start complete params to child nodes
* viz. actual play range, rtp info params etc
*/
SendSessionControlStartCompleteParams();
CompleteStart();
}
}
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_STOP:
{
CompleteStop();
}
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_FLUSH:
CompleteFlush();
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_PAUSE:
{
{
CompletePause();
}
}
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_RESET:
CompleteReset();
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_REQUEST_PORT:
{
/*
* Save the port in TrackInfo
*/
PVMFSMTrackInfo* trackInfo =
FindTrackInfo(cmdContextData->portContext.trackID);
PVMFPortInterface* port =
(PVMFPortInterface*)aResponse.GetEventData();
if (cmdContextData->portContext.portTag ==
PVMF_RTSP_NODE_PORT_TYPE_OUTPUT)
{
trackInfo->iSessionControllerOutputPort = port;
iSessionControllerNodeContainer->iOutputPorts.push_back(port);
}
else if (cmdContextData->portContext.portTag ==
PVMF_RTSP_NODE_PORT_TYPE_INPUT)
{
iSessionControllerNodeContainer->iInputPorts.push_back(port);
}
else if (cmdContextData->portContext.portTag ==
PVMF_RTSP_NODE_PORT_TYPE_INPUT_OUTPUT)
{
trackInfo->iSessionControllerFeedbackPort = port;
iSessionControllerNodeContainer->iFeedBackPorts.push_back(port);
}
CompleteGraphConstruct();
}
break;
case PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_CANCEL_ALL_COMMANDS:
{
CompleteCancelAll();
}
break;
default:
break;
}
return;
}
void
PVMFStreamingManagerNode::HandleJitterBufferCommandCompleted(const PVMFCmdResp& aResponse)
{
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFSMCommandContext *cmdContextData =
OSCL_REINTERPRET_CAST(PVMFSMCommandContext*, aResponse.GetContext());
if (iJitterBufferNodeContainer->iNodeCmdState == PVMFSM_NODE_CMD_PENDING)
{
iJitterBufferNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_COMPLETE;
}
else if (iJitterBufferNodeContainer->iNodeCmdState == PVMFSM_NODE_CMD_CANCEL_PENDING)
{
if (cmdContextData->parentCmd == PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS)
iJitterBufferNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_CANCEL_COMPLETE;
}
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::HandleJitterBufferCommandCompleted - Command failed - context=0x%x, status=0x%x", aResponse.GetContext(), aResponse.GetCmdStatus()));
if (IsBusy())
{
Cancel();
RunIfNotReady();
}
return;
}
cmdContextData->oFree = true;
switch (cmdContextData->cmd)
{
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_QUERY_UUID:
CompleteQueryUuid();
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_QUERY_INTERFACE:
{
if (iExtensionInterfacePlaceholder == NULL) OSCL_LEAVE(OsclErrBadHandle);
iJitterBufferNodeContainer->iExtensions.push_back(iExtensionInterfacePlaceholder);
CompleteQueryInterface();
}
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_INIT:
{
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
if (jbExtIntf == NULL) OSCL_LEAVE(OsclErrBadHandle);
if (IsRTPPacketSourcePresent())
{
jbExtIntf->SetBroadCastSession();
}
bool disableFireWallPackets = true;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
if (iSessionSourceInfo->iRTSPTunnelling == false)
{
//do not disable fw pkts run time
//apps can still disable it compile time or using KVP
//for UDP sessions ofcourse
disableFireWallPackets = false;
}
}
if (disableFireWallPackets == true)
{
jbExtIntf->DisableFireWallPackets();
}
CompleteInit();
}
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_PREPARE:
CompletePrepare();
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_START:
{
/* If start has been cancelled wait for cancel success */
if (aResponse.GetCmdStatus() != PVMFErrCancelled)
{
CompleteStart();
}
}
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_STOP:
{
CompleteStop();
}
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_FLUSH:
CompleteFlush();
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_PAUSE:
CompletePause();
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_RESET:
CompleteReset();
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_REQUEST_PORT:
{
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
if (jbExtIntf == NULL) OSCL_LEAVE(OsclErrBadHandle);
/*
* Save the port in TrackInfo
*/
PVMFSMTrackInfo* trackInfo =
FindTrackInfo(cmdContextData->portContext.trackID);
PVMFPortInterface* port =
(PVMFPortInterface*)aResponse.GetEventData();
uint32 bitrate = 0;
if (cmdContextData->portContext.portTag ==
PVMF_JITTER_BUFFER_PORT_TYPE_INPUT)
{
bitrate = trackInfo->bitRate;
trackInfo->iJitterBufferInputPort = port;
iJitterBufferNodeContainer->iInputPorts.push_back(port);
}
else if (cmdContextData->portContext.portTag ==
PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT)
{
trackInfo->iJitterBufferOutputPort = port;
iJitterBufferNodeContainer->iOutputPorts.push_back(port);
}
else if (cmdContextData->portContext.portTag ==
PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK)
{
trackInfo->iJitterBufferRTCPPort = port;
iJitterBufferNodeContainer->iFeedBackPorts.push_back(port);
//if RTP packet source is present, it implies a DVBH session
//and we disable RTCP RRs for DVB sessions
if (IsRTPPacketSourcePresent())
{
//The packet source does not process RTCP reader reports.
//So, disable them by setting the RR bandwidth to zero.
//The RS bandwidth is set to the RFC default of 800 bps but
//actual bandwidth is allocated by the fraction RS/(RR+RS), so
//the number used for RS in this case is arbitrary because
//sender reports will get 100% of the RTCP bandwidth as RS/RS = 100%.
jbExtIntf->setPortRTCPParams(port,
iTrackInfoVec.size(),
0,
800);
}
else
{
if (trackInfo->iRTCPBwSpecified)
{
jbExtIntf->setPortRTCPParams(port, iTrackInfoVec.size(), trackInfo->iRR, trackInfo->iRS);
}
}
}
jbExtIntf->setPortParams(port,
trackInfo->trackTimeScale,
bitrate,
trackInfo->iTrackConfig,
trackInfo->iRateAdaptation,
trackInfo->iRateAdaptationFeedBackFrequency);
CompleteGraphConstruct();
}
break;
case PVMF_STREAMING_MANAGER_JITTER_BUFFER_CANCEL_ALL_COMMANDS:
{
CompleteCancelAll();
}
break;
default:
break;
}
return;
}
void
PVMFStreamingManagerNode::HandleMediaLayerCommandCompleted(const PVMFCmdResp& aResponse)
{
PVMFSMNodeContainer* iMediaLayerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE);
if (iMediaLayerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFSMCommandContext *cmdContextData =
OSCL_REINTERPRET_CAST(PVMFSMCommandContext*, aResponse.GetContext());
if (iMediaLayerNodeContainer->iNodeCmdState == PVMFSM_NODE_CMD_PENDING)
{
iMediaLayerNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_COMPLETE;
}
else if (iMediaLayerNodeContainer->iNodeCmdState == PVMFSM_NODE_CMD_CANCEL_PENDING)
{
if (cmdContextData->parentCmd == PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS)
iMediaLayerNodeContainer->iNodeCmdState = PVMFSM_NODE_CMD_CANCEL_COMPLETE;
}
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::HandleMediaLayerCommandCompleted - Command failed - context=0x%x, status=0x%x", aResponse.GetContext(), aResponse.GetCmdStatus()));
if (IsBusy())
{
Cancel();
RunIfNotReady();
}
return;
}
cmdContextData->oFree = true;
switch (cmdContextData->cmd)
{
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_QUERY_UUID:
CompleteQueryUuid();
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_QUERY_INTERFACE:
{
if (iExtensionInterfacePlaceholder == NULL) OSCL_LEAVE(OsclErrBadHandle);
iMediaLayerNodeContainer->iExtensions.push_back(iExtensionInterfacePlaceholder);
CompleteQueryInterface();
}
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_INIT:
CompleteInit();
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_PREPARE:
CompletePrepare();
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_START:
{
CompleteStart();
}
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_STOP:
{
CompleteStop();
}
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_FLUSH:
CompleteFlush();
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_PAUSE:
CompletePause();
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_RESET:
CompleteReset();
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_REQUEST_PORT:
{
PVMFMediaLayerNodeExtensionInterface* mlExtIntf =
(PVMFMediaLayerNodeExtensionInterface*)
(iMediaLayerNodeContainer->iExtensions[0]);
if (mlExtIntf == NULL) OSCL_LEAVE(OsclErrBadHandle);
/*
* Save the port in TrackInfo
*/
PVMFSMTrackInfo* trackInfo =
FindTrackInfo(cmdContextData->portContext.trackID);
PVMFPortInterface* port =
(PVMFPortInterface*)aResponse.GetEventData();
if (cmdContextData->portContext.portTag ==
PVMF_MEDIALAYER_PORT_TYPE_INPUT)
{
trackInfo->iMediaLayerInputPort = port;
iMediaLayerNodeContainer->iInputPorts.push_back(port);
}
else if (cmdContextData->portContext.portTag ==
PVMF_MEDIALAYER_PORT_TYPE_OUTPUT)
{
trackInfo->iMediaLayerOutputPort = port;
iMediaLayerNodeContainer->iOutputPorts.push_back(port);
}
mediaInfo* mInfo = NULL;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
SDPInfo* sdpInfo = iSessionSourceInfo->_sdpInfo.GetRep();
if (sdpInfo == NULL) OSCL_LEAVE(OsclErrBadHandle);
mInfo = sdpInfo->getMediaInfoBasedOnID(trackInfo->trackID);
}
mlExtIntf->setPortMediaParams(port, trackInfo->iTrackConfig, mInfo);
CompleteGraphConstruct();
}
break;
case PVMF_STREAMING_MANAGER_MEDIA_LAYER_CANCEL_ALL_COMMANDS:
{
CompleteCancelAll();
}
break;
default:
break;
}
return;
}
bool PVMFStreamingManagerNode::IsFatalErrorEvent(const PVMFEventType& event)
{
bool retval = false;
switch (event)
{
case PVMFErrCorrupt:
case PVMFErrOverflow:
case PVMFErrResource:
case PVMFErrProcessing:
case PVMFErrUnderflow:
case PVMFErrNoResources:
case PVMFErrResourceConfiguration:
case PVMFErrTimeout:
case PVMFErrNoMemory:
case PVMFFailure:
retval = true;
break;
default:
retval = false;
}
return retval;
}
void
PVMFStreamingManagerNode::HandleNodeErrorEvent(const PVMFAsyncEvent& aEvent)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::HandleNodeErrorEvent - In iCancelCommand.empty() [%d] current command id[%d] event type [%d]", iCancelCommand.empty(), iCurrentCommand.front().iCmd, aEvent.GetEventType()));
//Check if fatal error occurred, then we may need to enque the cancelallcommand due to error
if (IsFatalErrorEvent(aEvent.GetEventType())
&& !iCurrentCommand.empty()
&& iCancelCommand.empty())
{
if ((IsInternalCmd(iCurrentCommand.front().iCmd) == true))
{
/*
* cancel all queued commands, if any
*/
while (iInputCommands.size() > 0)
{
if (IsInternalCmd(iInputCommands.front().iCmd) == false)
{
CommandComplete(iInputCommands.front(), PVMFErrCancelled);
}
/* Erase the command from the input queue */
iInputCommands.Erase(&iInputCommands.front());
}
/*
* After the completion of the cancel due to error, we will complete the current command in which failure occurred.
*/
iErrorDuringProcess = SM_ERROR_EVENT;
PVMFSessionId s = 0;
PVMFStreamingManagerNodeCommand cmdCancelPendingCmd;
cmdCancelPendingCmd.PVMFStreamingManagerNodeCommandBase::Construct(s,
PVMF_STREAMING_MANAGER_NODE_CANCELALLCOMMANDS,
NULL);
QueueCommandL(cmdCancelPendingCmd);
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode:HandleNodeErrorEvent: - CancelAllCommands Queued"));
}
}
//just pass the error event up
PVMFAsyncEvent event = OSCL_CONST_CAST(PVMFAsyncEvent, aEvent);
PVMFNodeInterface::ReportErrorEvent(event);
return;
}
void
PVMFStreamingManagerNode::HandleNodeInformationalEvent(const PVMFAsyncEvent& aEvent)
{
PVMFAsyncEvent event = OSCL_CONST_CAST(PVMFAsyncEvent, aEvent);
PVMFEventType infoEvent = aEvent.GetEventType();
if (infoEvent == PVMFInfoEndOfData)
{
/* Notify jitter buffer */
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
jbExtIntf->NotifyOutOfBandEOS();
}
else
{
/* Just pass the info event up */
PVMFNodeInterface::ReportInfoEvent(event);
}
}
PVMFSMCommandContext* PVMFStreamingManagerNode::RequestNewInternalCmd()
{
int32 i = 0;
/* Search for the next free node command in the pool */
while (i < PVMF_STREAMING_MANAGER_INTERNAL_CMDQ_SIZE)
{
if (iInternalCmdPool[i].oFree)
{
iInternalCmdPool[i].oFree = false;
return &(iInternalCmdPool[i]);
}
++i;
}
/* Free one not found so return NULL */
return NULL;
}
void
PVMFStreamingManagerNode::MoveCmdToCurrentQueue(PVMFStreamingManagerNodeCommand& aCmd)
{
int32 err;
OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
if (err != OsclErrNone)
{
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
iInputCommands.Erase(&aCmd);
return;
}
void
PVMFStreamingManagerNode::MoveCmdToCancelQueue(PVMFStreamingManagerNodeCommand& aCmd)
{
/*
* note: the StoreL cannot fail since the queue is never more than 1 deep
* and we reserved space.
*/
iCancelCommand.StoreL(aCmd);
iInputCommands.Erase(&aCmd);
return;
}
PVMFSMNodeContainer*
PVMFStreamingManagerNode::getNodeContainer(int32 tag)
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeTag == tag)
{
return (&(iNodeContainerVec[i]));
}
}
return NULL;
}
bool PVMFStreamingManagerNode::PopulateTrackInfoVec()
{
if (iSelectedMediaPresetationInfo.getNumTracks() == 0)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:PopulateTrackInfoVec - Selected Track List Empty"));
return false;
}
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
/*
* Get selected tracks
*/
SDPInfo* sdpInfo = iSessionSourceInfo->_sdpInfo;
int32 numTracks = sdpInfo->getNumMediaObjects();
if (numTracks > 0)
{
for (int32 i = 0; i < numTracks; i++)
{
/*
* Get the vector of mediaInfo as there can
* alternates for each track
*/
Oscl_Vector<mediaInfo*, SDPParserAlloc> mediaInfoVec =
sdpInfo->getMediaInfo(i);
uint32 minfoVecLen = mediaInfoVec.size();
for (uint32 j = 0; j < minfoVecLen; j++)
{
mediaInfo* mInfo = mediaInfoVec[j];
if (mInfo == NULL)
{
return false;
}
if (mInfo->getSelect())
{
PVMFSMTrackInfo trackInfo;
{
trackInfo.iTransportType += _STRLIT_CHAR("RTP");
}
trackInfo.trackID = mInfo->getMediaInfoID();
Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadVector;
payloadVector = mInfo->getPayloadSpecificInfoVector();
if (payloadVector.size() == 0)
{
return false;
}
/*
* There can be multiple payloads per media segment.
* We only support one for now, so
* use just the first payload
*/
PayloadSpecificInfoTypeBase* payloadInfo = payloadVector[0];
trackInfo.trackTimeScale = payloadInfo->sampleRate;
// set config for later
int32 configSize = payloadInfo->configSize;
OsclAny* config = payloadInfo->configHeader.GetRep();
const char* mimeType = mInfo->getMIMEType();
OSCL_StackString<32> h263(_STRLIT_CHAR("H263"));
{
trackInfo.iMimeType += mimeType;
}
trackInfo.portTag = mInfo->getMediaInfoID();
trackInfo.bitRate = mInfo->getBitrate();
if (mInfo->getReportFrequency() > 0)
{
trackInfo.iRateAdaptation = true;
trackInfo.iRateAdaptationFeedBackFrequency =
mInfo->getReportFrequency();
}
if ((mInfo->getRTCPReceiverBitRate() >= 0) &&
(mInfo->getRTCPSenderBitRate() >= 0))
{
trackInfo.iRR = mInfo->getRTCPReceiverBitRate();
trackInfo.iRS = mInfo->getRTCPSenderBitRate();
trackInfo.iRTCPBwSpecified = true;
}
if ((configSize > 0) && (config != NULL))
{
OsclMemAllocDestructDealloc<uint8> my_alloc;
OsclRefCounter* my_refcnt;
uint aligned_refcnt_size =
oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
uint8* my_ptr = NULL;
int32 errcode = 0;
OSCL_TRY(errcode, my_ptr = (uint8*) my_alloc.ALLOCATE(aligned_refcnt_size + configSize));
my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
my_ptr += aligned_refcnt_size;
OsclMemoryFragment memfrag;
memfrag.len = (uint32)configSize;
memfrag.ptr = my_ptr;
oscl_memcpy((void*)(memfrag.ptr), (const void*)config, memfrag.len);
OsclRefCounterMemFrag tmpRefcntMemFrag(memfrag, my_refcnt, memfrag.len);
trackInfo.iTrackConfig = tmpRefcntMemFrag;
}
iTrackInfoVec.push_back(trackInfo);
}
}
}
}
else
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:PopulateTrackInfoVec - Selected Track List Empty"));
return false;
}
}
return true;
}
PVMFSMTrackInfo*
PVMFStreamingManagerNode::FindTrackInfo(uint32 trackID)
{
PVMFSMTrackInfoVector::iterator it;
for (it = iTrackInfoVec.begin();
it != iTrackInfoVec.end();
it++)
{
if (it->trackID == trackID)
{
return (it);
}
}
return NULL;
}
PVMFSMTrackInfo*
PVMFStreamingManagerNode::FindTrackInfo(PvmfMimeString* trackMimeType)
{
PVMFSMTrackInfoVector::iterator it;
for (it = iTrackInfoVec.begin();
it != iTrackInfoVec.end();
it++)
{
if (!(oscl_CIstrcmp(it->iMimeType.get_cstr(),
trackMimeType->get_cstr())))
{
return (it);
}
}
return NULL;
}
bool PVMFStreamingManagerNode::ReserveSockets()
{
uint32 sockid = 0;
char portConfigBuf[64];
oscl_memset((OsclAny*)portConfigBuf, 0, 64);
oscl_snprintf(portConfigBuf, 64, "%d", sockid);
OSCL_StackString<128> portConfig("UDP");
portConfig += _STRLIT_CHAR("/remote_address=0.0.0.0");
portConfig += _STRLIT_CHAR(";client_port=");
portConfig += portConfigBuf;
PVMFSMNodeContainer* iSocketNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_SOCKET_NODE);
if (iSocketNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFSocketNode* socketNode =
(PVMFSocketNode*)(iSocketNodeContainer->iNode);
PVMFSMTrackInfoVector::iterator it;
uint32 startPortNum = 0;
{
TimeValue current_time;
current_time.set_to_current_time();
uint32 my_seed = current_time.get_sec();
OsclRand random_num;
random_num.Seed(my_seed);
int32 first = random_num.Rand();
uint32 myport = (first & 0x1FFF) + 0x2000; //start from 8192
startPortNum = (myport >> 1) << 1; //start from even
}
for (it = iTrackInfoVec.begin();
it != iTrackInfoVec.end();
it++)
{
OSCL_StackString<128> portConfigWithMime;
portConfigWithMime += portConfig;
portConfigWithMime += _STRLIT_CHAR(";mime=");
portConfigWithMime += it->iMimeType;
PVMFStatus status = socketNode->AllocateConsecutivePorts(&portConfigWithMime,
it->iRTPSocketID,
it->iRTCPSocketID, startPortNum);
if (status != PVMFSuccess)
{
return false;
}
}
return true;
}
bool PVMFStreamingManagerNode::RequestNetworkNodePorts(int32 portTag,
uint32& numPortsRequested)
{
numPortsRequested = 0;
PVMFSMNodeContainer* nodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_SOCKET_NODE);
if (nodeContainer == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:RequestNetworkNodePorts - getNodeContainer Failed"));
return false;
}
for (uint32 i = 0; i < iTrackInfoVec.size(); i++)
{
PVMFSMTrackInfo trackInfo = iTrackInfoVec[i];
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
nodeContainer->commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_REQUEST_PORT_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_CONSTRUCT_SESSION;
internalCmd->portContext.trackID = trackInfo.trackID;
internalCmd->portContext.portTag = portTag;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = nodeContainer->iNode;
uint32 sockid = 0;
bool oRTCP = false;
if (portTag == PVMF_SOCKET_NODE_PORT_TYPE_SOURCE)
{
sockid = trackInfo.iRTPSocketID;
}
else if (portTag == PVMF_SOCKET_NODE_PORT_TYPE_SINK)
{
sockid = trackInfo.iRTCPSocketID;
oRTCP = true;
}
char portConfigBuf[64];
oscl_memset((OsclAny*)portConfigBuf, 0, 64);
oscl_snprintf(portConfigBuf, 64, "%d", sockid);
OSCL_StackString<128> portConfig("UDP");
portConfig += _STRLIT_CHAR("/remote_address=0.0.0.0");
portConfig += _STRLIT_CHAR(";client_port=");
portConfig += portConfigBuf;
portConfig += _STRLIT_CHAR(";mime=");
portConfig += trackInfo.iMimeType.get_cstr();
if (oRTCP == true)
{
portConfig += _STRLIT_CHAR("/rtp");
}
else
{
portConfig += _STRLIT_CHAR("/rtcp");
}
iNode->RequestPort(nodeContainer->iSessionId,
internalCmd->portContext.portTag,
&portConfig,
cmdContextData);
numPortsRequested++;
}
else
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:RequestNetworkNodePorts - RequestNewInternalCmd Failed"));
return false;
}
}
return true;
}
bool PVMFStreamingManagerNode::RequestRTSPNodePorts(int32 portTag,
uint32& numPortsRequested)
{
numPortsRequested = 0;
PVMFSMNodeContainer* nodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (nodeContainer == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:RequestNetworkNodePorts - getNodeContainer Failed"));
return false;
}
for (uint32 i = 0; i < iTrackInfoVec.size(); i++)
{
PVMFSMTrackInfo trackInfo = iTrackInfoVec[i];
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
nodeContainer->commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_REQUEST_PORT_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_CONSTRUCT_SESSION;
internalCmd->portContext.trackID = trackInfo.trackID;
internalCmd->portContext.portTag = portTag;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = nodeContainer->iNode;
char portConfigBuf[64];
oscl_memset((OsclAny*)portConfigBuf, 0, 64);
oscl_snprintf(portConfigBuf, 64, "sdpTrackIndex=%d", trackInfo.trackID);
OSCL_StackString<128> portConfig;
portConfig += portConfigBuf;
if (portTag == PVMF_RTSP_NODE_PORT_TYPE_OUTPUT)
{
portConfig += _STRLIT_CHAR("/media");
}
if (portTag == PVMF_RTSP_NODE_PORT_TYPE_INPUT_OUTPUT)
{
portConfig += _STRLIT_CHAR("/feedback");
}
iNode->RequestPort(nodeContainer->iSessionId,
internalCmd->portContext.portTag,
&portConfig,
cmdContextData);
numPortsRequested++;
}
else
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:RequestNetworkNodePorts - RequestNewInternalCmd Failed"));
return false;
}
}
return true;
}
bool
PVMFStreamingManagerNode::RequestJitterBufferPorts(int32 portType,
uint32 &numPortsRequested)
{
PVMFSMNodeContainer* nodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (nodeContainer == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:RequestJitterBufferPorts - getNodeContainer Failed"));
return false;
}
numPortsRequested = 0;
/*
* Request port - all jitter buffer input ports
* are even numbered and output and rtcp ports are odd numbered
*/
int32 portTagStart = portType;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
for (uint32 i = 0; i < iTrackInfoVec.size(); i++)
{
PVMFSMTrackInfo trackInfo = iTrackInfoVec[i];
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
nodeContainer->commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_REQUEST_PORT_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_CONSTRUCT_SESSION;
internalCmd->portContext.trackID = trackInfo.trackID;
internalCmd->portContext.portTag = portType;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = nodeContainer->iNode;
OSCL_StackString<32> portConfig = trackInfo.iTransportType;
portConfig += _STRLIT_CHAR("/");
portConfig += trackInfo.iMimeType;
iNode->RequestPort(nodeContainer->iSessionId,
portTagStart,
&(portConfig),
cmdContextData);
numPortsRequested++;
}
else
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:RequestJitterBufferPorts - RequestNewInternalCmd Failed"));
return false;
}
portTagStart += 3;
}
return true;
}
// error
return false;
}
bool
PVMFStreamingManagerNode::RequestMediaLayerPorts(int32 portType,
uint32& numPortsRequested)
{
PVMFSMNodeContainer* nodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE);
if (nodeContainer == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:RequestMediaLayerPorts - getNodeContainer Failed"));
return false;
}
numPortsRequested = 0;
/*
* Request port - all media layer input ports
* are even numbered and output are odd numbered
*/
int32 portTagStart = portType;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
for (uint32 i = 0; i < iTrackInfoVec.size(); i++)
{
PVMFSMTrackInfo trackInfo = iTrackInfoVec[i];
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
nodeContainer->commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_REQUEST_PORT_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_CONSTRUCT_SESSION;
internalCmd->portContext.trackID = trackInfo.trackID;
internalCmd->portContext.portTag = portType;
OsclAny *cmdContextData =
OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = nodeContainer->iNode;
iNode->RequestPort(nodeContainer->iSessionId,
portTagStart,
&(trackInfo.iMimeType),
cmdContextData);
numPortsRequested++;
}
else
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:RequestMediaLayerPorts - RequestNewInternalCmd Failed"));
return false;
}
portTagStart += 2;
}
return true;
}
//error
return false;
}
bool PVMFStreamingManagerNode::ConstructGraphFor3GPPUDPStreaming()
{
uint32 numPortsRequested = 0;
/*
* Reserve UDP socket pairs
*/
if (!ReserveSockets())
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPUDPStreaming - ReserveSockets() Failed"));
return false;
}
/*
* Request data UDP ports
*/
if (!RequestNetworkNodePorts(PVMF_SOCKET_NODE_PORT_TYPE_SOURCE,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPUDPStreaming - RequestNetworkNodePorts(PVMF_SOCKET_NODE_PORT_TYPE_SOURCE) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
/*
* Request feedback (RTCP) UDP ports
*/
if (!RequestNetworkNodePorts(PVMF_SOCKET_NODE_PORT_TYPE_SINK,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPUDPStreaming - RequestNetworkNodePorts(PVMF_SOCKET_NODE_PORT_TYPE_SINK) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_INPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPUDPStreaming - RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_INPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPUDPStreaming - RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPUDPStreaming - RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestMediaLayerPorts(PVMF_MEDIALAYER_PORT_TYPE_INPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPUDPStreaming - RequestMediaLayerPorts(PVMF_MEDIALAYER_PORT_TYPE_INPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestMediaLayerPorts(PVMF_MEDIALAYER_PORT_TYPE_OUTPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPUDPStreaming - RequestMediaLayerPorts(PVMF_MEDIALAYER_PORT_TYPE_OUTPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
return true;
}
bool PVMFStreamingManagerNode::ConstructGraphFor3GPPTCPStreaming()
{
uint32 numPortsRequested = 0;
/*
* Request media ports
*/
if (!RequestRTSPNodePorts(PVMF_RTSP_NODE_PORT_TYPE_OUTPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPTCPStreaming - RequestRTSPNodePorts(PVMF_RTSP_NODE_PORT_TYPE_OUTPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
/*
* Request feedback (RTCP) ports
*/
if (!RequestRTSPNodePorts(PVMF_RTSP_NODE_PORT_TYPE_INPUT_OUTPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPTCPStreaming - RequestRTSPNodePorts(PVMF_RTSP_NODE_PORT_TYPE_INPUT_OUTPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_INPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPTCPStreaming - RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_INPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPTCPStreaming - RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_OUTPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPTCPStreaming - RequestJitterBufferPorts(PVMF_JITTER_BUFFER_PORT_TYPE_FEEDBACK) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestMediaLayerPorts(PVMF_MEDIALAYER_PORT_TYPE_INPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPTCPStreaming - RequestMediaLayerPorts(PVMF_MEDIALAYER_PORT_TYPE_INPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
if (!RequestMediaLayerPorts(PVMF_MEDIALAYER_PORT_TYPE_OUTPUT,
numPortsRequested))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConstructGraphFor3GPPTCPStreaming - RequestMediaLayerPorts(PVMF_MEDIALAYER_PORT_TYPE_OUTPUT) Failed"));
return false;
}
iNumRequestPortsPending += numPortsRequested;
return true;
}
bool
PVMFStreamingManagerNode::GraphConstruct()
{
/*
* Session source info must have been set
*/
if (iSessionSourceInfo->_sessionType == PVMF_FORMAT_UNKNOWN)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:GraphConstruct - Invalid Session Type"));
return false;
}
if (!PopulateTrackInfoVec())
{
return false;
}
if (iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE)
{
}
else if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
if (iSessionSourceInfo->iRTSPTunnelling == true)
{
return (ConstructGraphFor3GPPTCPStreaming());
}
else
{
return (ConstructGraphFor3GPPUDPStreaming());
}
}
//error
return false;
}
/*
* Called by the call back routine whenever a "RequestPort" call
* completes successfully.
*/
void PVMFStreamingManagerNode::CompleteGraphConstruct()
{
iTotalNumRequestPortsComplete++;
/*
* Once all port requests are complete, connect the graph
*/
if (iTotalNumRequestPortsComplete == iNumRequestPortsPending)
{
PVMFStreamingManagerNodeCommand aCmd = iCurrentCommand.front();
if (!SendSessionSourceInfoToSessionController())
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:CompleteGraphConstruct - SendSessionSourceInfoToSessionController Failed"));
InternalCommandComplete(aCmd, PVMFFailure);
iCurrentCommand.Erase(&iCurrentCommand.front());
}
else
{
oGraphConstructComplete = true;
InternalCommandComplete(aCmd, PVMFSuccess);
/* Erase the command from the current queue */
iCurrentCommand.Erase(&iCurrentCommand.front());
}
}
}
PVMFStatus
PVMFStreamingManagerNode::ConnectPortPairs(PVMFPortInterface* aPort1,
PVMFPortInterface* aPort2)
{
PVMFStatus status;
status = aPort1->Connect(aPort2);
if (status != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ConnectPortPairs - Connect Failed"));
return status;
}
return status;
}
bool PVMFStreamingManagerNode::GraphConnectFor3GPPUDPStreaming()
{
if (oGraphConnectComplete == false)
{
/*
* Go over the track list and connect:
* network_node_port -> jitter_buffer_node_input_port;
* jitter_buffer_node_output_port -> media_layer_input_port
*/
PVMFStatus status;
for (uint32 i = 0; i < iTrackInfoVec.size(); i++)
{
PVMFSMTrackInfo trackInfo = iTrackInfoVec[i];
if ((trackInfo.iNetworkNodePort == NULL) ||
(trackInfo.iNetworkNodeRTCPPort == NULL) ||
(trackInfo.iJitterBufferInputPort == NULL) ||
(trackInfo.iJitterBufferOutputPort == NULL) ||
(trackInfo.iJitterBufferRTCPPort == NULL) ||
(trackInfo.iMediaLayerInputPort == NULL) ||
(trackInfo.iMediaLayerOutputPort == NULL))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:GraphConnectFor3GPPUDPStreaming - Invalid Ports"));
return false;
}
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnect - Track MimeType %s", trackInfo.iMimeType.get_cstr()));
/* connect network_node_port <-> jitter_buffer_node_input_port */
status = ConnectPortPairs(trackInfo.iJitterBufferInputPort,
trackInfo.iNetworkNodePort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPUDPStreaming - Connected Network - JB Input"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPUDPStreaming - NetworkPort=0x%x - JBInputPort=0x%x", trackInfo.iNetworkNodePort, trackInfo.iJitterBufferInputPort));
if (status != PVMFSuccess)
{
return false;
}
/*
* connect jitter_buffer_node_output_port <->
* media_layer_input_port
*/
status = ConnectPortPairs(trackInfo.iJitterBufferOutputPort,
trackInfo.iMediaLayerInputPort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPUDPStreaming - JB Output - ML Input"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPUDPStreaming - JB Output=0x%x - ML Input=0x%x", trackInfo.iJitterBufferOutputPort, trackInfo.iMediaLayerInputPort));
if (status != PVMFSuccess)
{
return false;
}
/*
* connect network_rtcp_port <-> jitter_buffer_rtcp_port
*/
status = ConnectPortPairs(trackInfo.iJitterBufferRTCPPort,
trackInfo.iNetworkNodeRTCPPort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPUDPStreaming - NetworkRTCPPort - JBRTCPPort"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPUDPStreaming - NetworkRTCPPort=0x%x - JBRTCPPort=0x%x", trackInfo.iNetworkNodeRTCPPort, trackInfo.iJitterBufferRTCPPort));
if (status != PVMFSuccess)
{
return false;
}
}
oGraphConnectComplete = true;
}
return true;
}
bool PVMFStreamingManagerNode::GraphConnectForRTPPacketSource()
{
if (oGraphConnectComplete == false)
{
/*
* Go over the track list and connect:
* network_node_port -> jitter_buffer_node_input_port;
* jitter_buffer_node_output_port -> media_layer_input_port
*/
PVMFStatus status;
for (uint32 i = 0; i < iTrackInfoVec.size(); i++)
{
PVMFSMTrackInfo trackInfo = iTrackInfoVec[i];
if ((trackInfo.iNetworkNodePort == NULL) ||
(trackInfo.iJitterBufferInputPort == NULL) ||
(trackInfo.iJitterBufferOutputPort == NULL) ||
(trackInfo.iMediaLayerInputPort == NULL) ||
(trackInfo.iMediaLayerOutputPort == NULL))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:GraphConnectForRTPPacketSource - Invalid Ports"));
return false;
}
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnect - Track MimeType %s", trackInfo.iMimeType.get_cstr()));
/* connect network_node_port <-> jitter_buffer_node_input_port */
status = ConnectPortPairs(trackInfo.iJitterBufferInputPort,
trackInfo.iNetworkNodePort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectForRTPPacketSource - Connected Network - JB Input"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectForRTPPacketSource - NetworkPort=0x%x - JBInputPort=0x%x", trackInfo.iNetworkNodePort, trackInfo.iJitterBufferInputPort));
if (status != PVMFSuccess)
{
return false;
}
/*
* connect jitter_buffer_node_output_port <->
* media_layer_input_port
*/
status = ConnectPortPairs(trackInfo.iJitterBufferOutputPort,
trackInfo.iMediaLayerInputPort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectForRTPPacketSource - JB Output - ML Input"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectForRTPPacketSource - JB Output=0x%x - ML Input=0x%x", trackInfo.iJitterBufferOutputPort, trackInfo.iMediaLayerInputPort));
if (status != PVMFSuccess)
{
return false;
}
/*
* connect network_rtcp_port <-> jitter_buffer_rtcp_port
*/
status = ConnectPortPairs(trackInfo.iJitterBufferRTCPPort,
trackInfo.iNetworkNodeRTCPPort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPUDPStreaming - NetworkRTCPPort - JBRTCPPort"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPUDPStreaming - NetworkRTCPPort=0x%x - JBRTCPPort=0x%x", trackInfo.iNetworkNodeRTCPPort, trackInfo.iJitterBufferRTCPPort));
if (status != PVMFSuccess)
{
return false;
}
}
oGraphConnectComplete = true;
}
return true;
}
bool PVMFStreamingManagerNode::GraphConnectFor3GPPTCPStreaming()
{
if (oGraphConnectComplete == false)
{
/*
* Go over the track list and connect:
* network_node_port -> jitter_buffer_node_input_port;
* jitter_buffer_node_output_port -> media_layer_input_port
*/
PVMFStatus status;
for (uint32 i = 0; i < iTrackInfoVec.size(); i++)
{
PVMFSMTrackInfo trackInfo = iTrackInfoVec[i];
if ((trackInfo.iSessionControllerOutputPort == NULL) ||
(trackInfo.iSessionControllerFeedbackPort == NULL) ||
(trackInfo.iJitterBufferInputPort == NULL) ||
(trackInfo.iJitterBufferOutputPort == NULL) ||
(trackInfo.iJitterBufferRTCPPort == NULL) ||
(trackInfo.iMediaLayerInputPort == NULL) ||
(trackInfo.iMediaLayerOutputPort == NULL))
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:GraphConnectFor3GPPTCPStreaming - Invalid Ports"));
return false;
}
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPTCPStreaming - Track MimeType %s", trackInfo.iMimeType.get_cstr()));
/* connect sessioncontroller_node_output_port <-> jitter_buffer_node_input_port */
status = ConnectPortPairs(trackInfo.iJitterBufferInputPort,
trackInfo.iSessionControllerOutputPort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPTCPStreaming - Connected SessionController Output - JB Input"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPTCPStreaming - SessionControllerPort=0x%x - JBInputPort=0x%x", trackInfo.iSessionControllerOutputPort, trackInfo.iJitterBufferInputPort));
if (status != PVMFSuccess)
{
return false;
}
/*
* connect jitter_buffer_node_output_port <->
* media_layer_input_port
*/
status = ConnectPortPairs(trackInfo.iJitterBufferOutputPort,
trackInfo.iMediaLayerInputPort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPTCPStreaming - JB Output - ML Input"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPTCPStreaming - JB Output=0x%x - ML Input=0x%x", trackInfo.iJitterBufferOutputPort, trackInfo.iMediaLayerInputPort));
if (status != PVMFSuccess)
{
return false;
}
/*
* connect sessioncontroller_node_feedback_port <-> jitter_buffer_rtcp_port
*/
status = ConnectPortPairs(trackInfo.iJitterBufferRTCPPort,
trackInfo.iSessionControllerFeedbackPort);
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPTCPStreaming - SessionControllerFeedbackPort - JBRTCPPort"));
PVMF_SM_LOGINFO((0, "PVMFSM:GraphConnectFor3GPPTCPStreaming - SessionControllerFeedbackPort=0x%x - JBRTCPPort=0x%x", trackInfo.iSessionControllerFeedbackPort, trackInfo.iJitterBufferRTCPPort));
if (status != PVMFSuccess)
{
return false;
}
}
oGraphConnectComplete = true;
}
return true;
}
/*
* Called by command handler AO once all request ports are complete
*/
bool PVMFStreamingManagerNode::GraphConnect()
{
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
if (iSessionSourceInfo->iRTSPTunnelling == true)
{
return (GraphConnectFor3GPPTCPStreaming());
}
else
{
return (GraphConnectFor3GPPUDPStreaming());
}
}
else if (iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE)
{
return (GraphConnectForRTPPacketSource());
}
//error
return false;
}
/*
* Called when all port requests are complete, in order to send the
* UDP port information to RTSP
*/
bool
PVMFStreamingManagerNode::SendSessionSourceInfoToSessionController()
{
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
PVMFSMNodeContainer* iSocketNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_SOCKET_NODE);
if (iSocketNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFSocketNode* socketNode =
(PVMFSocketNode*)(iSocketNodeContainer->iNode);
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
Oscl_Vector<StreamInfo, OsclMemAllocator> aSelectedStream;
for (uint32 i = 0; i < iTrackInfoVec.size(); i++)
{
PVMFSMTrackInfo trackInfo = iTrackInfoVec[i];
OsclNetworkAddress localAdd;
OsclNetworkAddress remoteAdd;
StreamInfo sInfo;
sInfo.iSDPStreamId = trackInfo.trackID;
if (iSessionSourceInfo->iRTSPTunnelling == false)
{
if (trackInfo.iNetworkNodePort == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SendSessionSourceInfoToSessionController - Invalid Port"));
return false;
}
socketNode->GetPortConfig(*trackInfo.iNetworkNodePort,
localAdd,
remoteAdd);
sInfo.iCliRTPPort = localAdd.port;
socketNode->GetPortConfig(*trackInfo.iNetworkNodeRTCPPort,
localAdd,
remoteAdd);
sInfo.iCliRTCPPort = localAdd.port;
}
/* Set Rate Adaptation parameters */
sInfo.b3gppAdaptationIsSet = false;
if (trackInfo.iRateAdaptation)
{
sInfo.b3gppAdaptationIsSet = true;
/* Compute buffer size based on bitrate and jitter duration*/
uint32 sizeInBytes = MIN_RTP_SOCKET_MEM_POOL_SIZE_IN_BYTES;
if (((int32)iJitterBufferDurationInMilliSeconds > 0) &&
((int32)trackInfo.bitRate > 0))
{
uint32 byteRate = trackInfo.bitRate / 8;
uint32 overhead = (byteRate * PVMF_JITTER_BUFFER_NODE_MEM_POOL_OVERHEAD) / 100;
uint32 durationInSec = iJitterBufferDurationInMilliSeconds / 1000;
sizeInBytes = ((byteRate + overhead) * durationInSec);
if (sizeInBytes < MIN_RTP_SOCKET_MEM_POOL_SIZE_IN_BYTES)
{
sizeInBytes = MIN_RTP_SOCKET_MEM_POOL_SIZE_IN_BYTES;
}
sizeInBytes += 2 * MAX_SOCKET_BUFFER_SIZE;
}
sInfo.iBufSize = sizeInBytes;
sInfo.iTargetTime = iJitterBufferDurationInMilliSeconds;
}
aSelectedStream.push_back(sInfo);
}
if (rtspExtIntf->SetSDPInfo(iSessionSourceInfo->_sdpInfo,
aSelectedStream) != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SendSessionSourceInfoToSessionController - SetSDPInfo Failed"));
return false;
}
/* Set play range from SDP */
sessionDescription* sessionInfo = iSessionSourceInfo->_sdpInfo->getSessionInfo();
RtspRangeType *rtspRange = OSCL_CONST_CAST(RtspRangeType*, (sessionInfo->getRange()));
rtspRange->convertToMilliSec((int32&)iSessionStartTime, (int32&)iSessionStopTime);
if (rtspRange->end_is_set == false)
{
iSessionStopTime = -1;
iSessionStopTimeAvailable = false;
}
if ((rtspRange->format != RtspRangeType::INVALID_RANGE) &&
(rtspRange->start_is_set != false))
{
if (rtspExtIntf->SetRequestPlayRange(*rtspRange) != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SendRequestPlayRangeToSessionController - SetRequestPlayRange Failed"));
return false;
}
}
}
return true;
}
bool
PVMFStreamingManagerNode::SendSessionControlPrepareCompleteParams()
{
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
Oscl_Vector<StreamInfo, OsclMemAllocator> aSelectedStream;
if (rtspExtIntf->GetStreamInfo(aSelectedStream) != PVMFSuccess)
{
OSCL_LEAVE(OsclErrGeneral);
}
for (uint32 i = 0; i < aSelectedStream.size(); i++)
{
StreamInfo streamInfo = aSelectedStream[i];
PVMFSMTrackInfo* trackInfo = FindTrackInfo(streamInfo.iSDPStreamId);
if (trackInfo == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SendSessionControlPrepareCompleteParams - FindTrackInfo Failed"));
return false;
}
if (trackInfo->iJitterBufferInputPort == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SendSessionControlPrepareCompleteParams - Invalid Port"));
return false;
}
if (streamInfo.ssrcIsSet)
{
jbExtIntf->setPortSSRC(trackInfo->iJitterBufferInputPort,
streamInfo.iSSRC);
}
}
/* Set server info */
PVRTSPEngineNodeServerInfo rtspServerInfo;
PVMFJitterBufferFireWallPacketInfo fireWallPktInfo;
rtspExtIntf->GetServerInfo(rtspServerInfo);
if (rtspServerInfo.iIsPVServer)
{
fireWallPktInfo.iFormat = PVMF_JB_FW_PKT_FORMAT_PV;
}
fireWallPktInfo.iServerRoundTripDelayInMS = rtspServerInfo.iRoundTripDelayInMS;
fireWallPktInfo.iNumAttempts = PVMF_JITTER_BUFFER_NODE_DEFAULT_FIREWALL_PKT_ATTEMPTS;
jbExtIntf->setServerInfo(fireWallPktInfo);
}
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_REAL_HTTP_CLOAKING_URL))
{
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
}
return true;
}
bool
PVMFStreamingManagerNode::SendSessionControlStartCompleteParams()
{
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
PVMFSMNodeContainer* iMediaLayerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE);
if (iMediaLayerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFMediaLayerNodeExtensionInterface* mlExtIntf =
(PVMFMediaLayerNodeExtensionInterface*)
(iMediaLayerNodeContainer->iExtensions[0]);
bool end_is_set = true;
int32 startTime = 0;
int32 stopTime = 0;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
/* Get Actual Play Range */
RtspRangeType rangeType;
if (rtspExtIntf->GetActualPlayRange(rangeType) != PVMFSuccess)
{
return false;
}
rangeType.convertToMilliSec(startTime, stopTime);
/* Use from SDP if not set */
end_is_set = rangeType.end_is_set;
if (end_is_set == false)
{
stopTime = iSessionStopTime;
}
if (oRepositioning)
{
iActualRepositionStartNPTInMS = startTime;
if (iActualRepositionStartNPTInMSPtr != NULL)
{
*iActualRepositionStartNPTInMSPtr = startTime;
}
if (iPVMFDataSourcePositionParamsPtr != NULL)
{
iPVMFDataSourcePositionParamsPtr->iActualNPT = startTime;
}
}
Oscl_Vector<StreamInfo, OsclMemAllocator> aSelectedStream;
if (rtspExtIntf->GetStreamInfo(aSelectedStream) != PVMFSuccess)
{
OSCL_LEAVE(OsclErrGeneral);
}
for (uint32 i = 0; i < aSelectedStream.size(); i++)
{
StreamInfo streamInfo = aSelectedStream[i];
PVMFSMTrackInfo* trackInfo = FindTrackInfo(streamInfo.iSDPStreamId);
if (trackInfo == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SendStartCompleteSessionControlParams - FindTrackInfo Failed"));
return false;
}
if (trackInfo->iJitterBufferInputPort == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SendStartCompleteSessionControlParams - Invalid Port"));
return false;
}
if (streamInfo.seqIsSet != true)
{
streamInfo.seqIsSet = false;
streamInfo.seq = 0;
}
if (streamInfo.rtptimeIsSet != true)
{
streamInfo.rtptimeIsSet = false;
streamInfo.rtptime = 0;
}
jbExtIntf->setPortRTPParams(trackInfo->iJitterBufferInputPort,
streamInfo.seqIsSet,
streamInfo.seq,
streamInfo.rtptimeIsSet,
streamInfo.rtptime,
startTime,
oRepositioning);
}
}
/* Send actual stop time to Jitter Buffer */
if (jbExtIntf->setPlayRange(startTime,
stopTime,
oRepositioning,
end_is_set) != true)
{
return false;
}
if (mlExtIntf->setPlayRange(startTime, stopTime) != true)
{
return false;
}
return true;
}
bool
PVMFStreamingManagerNode::SendPacketSourceStartCompleteParams()
{
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
PVMFSMNodeContainer* iMediaLayerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE);
if (iMediaLayerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFMediaLayerNodeExtensionInterface* mlExtIntf =
(PVMFMediaLayerNodeExtensionInterface*)
(iMediaLayerNodeContainer->iExtensions[0]);
bool end_is_set = true;
int32 startTime = 0;
int32 stopTime = 0;
/* Get Actual Play Range */
RtspRangeType rangeType;
rangeType.convertToMilliSec(startTime, stopTime);
/* Use from SDP if not set */
end_is_set = false;
stopTime = -1;
PVMFSMTrackInfoVector::iterator it;
for (it = iTrackInfoVec.begin();
it != iTrackInfoVec.end();
it++)
{
StreamInfo streamInfo;
streamInfo.seqIsSet = false;
streamInfo.seq = 0;
streamInfo.rtptimeIsSet = false;
streamInfo.rtptime = 0;
jbExtIntf->setPortRTPParams(it->iJitterBufferInputPort,
streamInfo.seqIsSet,
streamInfo.seq,
streamInfo.rtptimeIsSet,
streamInfo.rtptime,
startTime,
oRepositioning);
}
/* Send actual stop time to Jitter Buffer */
if (jbExtIntf->setPlayRange(startTime, stopTime, false, end_is_set) != true)
{
return false;
}
if (mlExtIntf->setPlayRange(startTime, stopTime) != true)
{
return false;
}
return true;
}
bool
PVMFStreamingManagerNode::CompleteFeedBackPortsSetup()
{
PVMFSMNodeContainer* iSocketNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_SOCKET_NODE);
if (iSocketNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFSocketNode* socketNode =
(PVMFSocketNode*)(iSocketNodeContainer->iNode);
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
Oscl_Vector<StreamInfo, OsclMemAllocator> aSelectedStream;
if (rtspExtIntf->GetStreamInfo(aSelectedStream) != PVMFSuccess)
{
OSCL_LEAVE(OsclErrGeneral);
}
for (uint32 i = 0; i < aSelectedStream.size(); i++)
{
StreamInfo streamInfo = aSelectedStream[i];
PVMFSMTrackInfo* trackInfo = FindTrackInfo(streamInfo.iSDPStreamId);
if (trackInfo == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:CompleteFeedBackPortsSetup - FindTrackInfo Failed"));
return false;
}
if (trackInfo->iNetworkNodeRTCPPort == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:CompleteFeedBackPortsSetup - Invalid RTCP Port"));
return false;
}
OsclNetworkAddress localAddRTCP;
OsclNetworkAddress remoteAddRTCP;
localAddRTCP.port = streamInfo.iCliRTCPPort;
remoteAddRTCP.port = streamInfo.iSerRTCPPort;
remoteAddRTCP.ipAddr = streamInfo.iSerIpAddr;
socketNode->SetPortConfig(*(trackInfo->iNetworkNodeRTCPPort),
localAddRTCP,
remoteAddRTCP);
if (trackInfo->iNetworkNodePort == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:CompleteFeedBackPortsSetup - Invalid RTP Port"));
return false;
}
OsclNetworkAddress localAddRTP;
OsclNetworkAddress remoteAddRTP;
localAddRTP.port = streamInfo.iCliRTPPort;
remoteAddRTP.port = streamInfo.iSerRTPPort;
remoteAddRTP.ipAddr = streamInfo.iSerIpAddr;
socketNode->SetPortConfig(*(trackInfo->iNetworkNodePort),
localAddRTP,
remoteAddRTP);
}
return true;
}
PVMFStatus
PVMFStreamingManagerNode::DeleteUnusedSessionControllerNode()
{
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
/* Delete HTTP PE Node */
PVMFSMNodeContainerVector::iterator it;
for (it = iNodeContainerVec.begin(); it != iNodeContainerVec.end(); it++)
{
if (it->iNodeTag == PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE)
{
for (uint32 j = 0; j < it->iExtensions.size(); j++)
{
PVInterface* extIntf = it->iExtensions[j];
extIntf->removeRef();
}
PVMFProtocolEngineNodeFactory::DeletePVMFProtocolEngineNode(it->iNode);
it->iNode = NULL;
iNodeContainerVec.erase(it);
break;
}
}
}
DeleteUnusedNodes();
return PVMFSuccess;
}
PVMFStatus
PVMFStreamingManagerNode::DeleteUnusedNodes()
{
if (iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE)
{
PVMFSMNodeContainerVector::iterator it;
for (it = iNodeContainerVec.begin(); it != iNodeContainerVec.end(); it++)
{
/* Delete Unused Socket Node */
if (it->iNodeTag == PVMF_STREAMING_MANAGER_SOCKET_NODE)
{
for (uint32 j = 0; j < it->iExtensions.size(); j++)
{
PVInterface* extIntf = it->iExtensions[j];
extIntf->removeRef();
}
PVMF_STREAMING_MANAGER_DELETE(NULL,
PVMFSocketNode,
((PVMFSocketNode*)(it->iNode)));
it->iNode = NULL;
iNodeContainerVec.erase(it);
break;
}
}
for (it = iNodeContainerVec.begin(); it != iNodeContainerVec.end(); it++)
{
/* Delete Unused RTSP Session Controller Node */
if (it->iNodeTag == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE)
{
for (uint32 j = 0; j < it->iExtensions.size(); j++)
{
PVInterface* extIntf = it->iExtensions[j];
extIntf->removeRef();
}
PVMFRrtspEngineNodeFactory::DeletePVMFRtspEngineNode(it->iNode);
it->iNode = NULL;
iNodeContainerVec.erase(it);
break;
}
}
for (it = iNodeContainerVec.begin(); it != iNodeContainerVec.end(); it++)
{
/* Delete Unused HTTP Session Controller Node */
if (it->iNodeTag == PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE)
{
for (uint32 j = 0; j < it->iExtensions.size(); j++)
{
PVInterface* extIntf = it->iExtensions[j];
extIntf->removeRef();
}
PVMFProtocolEngineNodeFactory::DeletePVMFProtocolEngineNode(it->iNode);
it->iNode = NULL;
iNodeContainerVec.erase(it);
break;
}
}
}
else
{
}
return PVMFSuccess;
}
PVMFStatus
PVMFStreamingManagerNode::setSessionSourceInfo(OSCL_wString& aSourceURL,
PVMFFormatType aSourceFormatType,
OsclAny* aSourceData)
{
if (((aSourceFormatType == PVMF_DATA_SOURCE_RTSP_URL) ||
(aSourceFormatType == PVMF_DATA_SOURCE_SDP_FILE)) && (aSourceData != NULL))
{
PVInterface* pvInterface = OSCL_STATIC_CAST(PVInterface*, aSourceData);
PVInterface* sourceDataContext = NULL;
PVUuid sourceContextUuid(PVMF_SOURCE_CONTEXT_DATA_UUID);
if (pvInterface->queryInterface(sourceContextUuid, sourceDataContext))
{
if (sourceDataContext)
{
PVInterface* streamingDataContext = NULL;
PVUuid streamingContextUuid(PVMF_SOURCE_CONTEXT_DATA_STREAMING_UUID);
if (sourceDataContext->queryInterface(streamingContextUuid, streamingDataContext))
{
if (streamingDataContext)
{
PVMFSourceContextDataStreaming* sContext =
OSCL_STATIC_CAST(PVMFSourceContextDataStreaming*, streamingDataContext);
if (sContext->iProxyName.get_size() > 0)
{
PVMFSMNodeContainer* iSessionControllerNodeContainer = NULL;
iSessionControllerNodeContainer = getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer)
{
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)(iSessionControllerNodeContainer->iExtensions[0]);
if (rtspExtIntf)
{//the proxyname doesn't need to be unicode
OsclMemAllocator alloc;
char *buf = (char*)alloc.allocate(sContext->iProxyName.get_size() + 1);
if (!buf)
return PVMFErrNoMemory;
uint32 size = oscl_UnicodeToUTF8(sContext->iProxyName.get_cstr(), sContext->iProxyName.get_size(), buf, sContext->iProxyName.get_size() + 1);
if (size == 0)
{
alloc.deallocate(buf);
return PVMFErrNoMemory;
}
OSCL_FastString myProxyName(buf, size);
rtspExtIntf->SetRtspProxy(myProxyName, sContext->iProxyPort);
alloc.deallocate(buf);
}
}
}
}
}
}
}
}
if ((aSourceFormatType == PVMF_DATA_SOURCE_RTSP_URL) ||
(aSourceFormatType == PVMF_DATA_SOURCE_REAL_HTTP_CLOAKING_URL))
{
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
OSCL_wStackString<8> rtspScheme(_STRLIT_WCHAR("rtsp"));
OSCL_wStackString<8> rtsptScheme(_STRLIT_WCHAR("rtspt"));
OSCL_wStackString<8> schemeDelimiter(_STRLIT_WCHAR("://"));
oscl_wchar* actualURL = NULL;
if (oscl_strncmp(rtsptScheme.get_cstr(), aSourceURL.get_cstr(), 5) == 0)
{
iSessionSourceInfo->iRTSPTunnelling = true;
actualURL = oscl_strstr(aSourceURL.get_cstr(), schemeDelimiter.get_cstr());
if (actualURL == NULL)
{
return PVMFErrArgument;
}
//skip over ://
actualURL += schemeDelimiter.get_size();
iSessionSourceInfo->_sessionType = aSourceFormatType;
iSessionSourceInfo->_sessionURL += rtspScheme.get_str();
iSessionSourceInfo->_sessionURL += schemeDelimiter.get_str();
iSessionSourceInfo->_sessionURL += actualURL;
}
else
{
iSessionSourceInfo->_sessionType = aSourceFormatType;
iSessionSourceInfo->_sessionURL = aSourceURL;
}
if (iSessionSourceInfo->iRTSPTunnelling == true)
{
rtspExtIntf->SetStreamingType(PVRTSP_3GPP_TCP);
}
else
{
/* default to UDP */
rtspExtIntf->SetStreamingType(PVRTSP_3GPP_UDP);
}
return (rtspExtIntf->SetSessionURL(iSessionSourceInfo->_sessionURL));
}
else if (aSourceFormatType == PVMF_DATA_SOURCE_SDP_FILE)
{
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
iSessionSourceInfo->_sessionType = aSourceFormatType;
iSessionSourceInfo->_sessionURL = aSourceURL;
rtspExtIntf->SetStreamingType(PVRTSP_3GPP_UDP);
return PVMFSuccess;
}
else if (aSourceFormatType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE)
{
iSessionSourceInfo->_sessionType = aSourceFormatType;
iSessionSourceInfo->_sessionURL = aSourceURL;
return PVMFSuccess;
}
return PVMFErrNotSupported;
}
PVMFStatus PVMFStreamingManagerNode::ProcessSDP()
{
PVMFStatus status;
OsclRefCounterMemFrag iSDPText;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_REAL_HTTP_CLOAKING_URL))
{
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
status = rtspExtIntf->GetSDP(iSDPText);
if (status != PVMFSuccess)
{
return status;
}
}
else if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
/* Parse SDP file contents into a buffer */
Oscl_FileServer fileServ;
Oscl_File osclFile;
fileServ.Connect();
if (osclFile.Open(iSessionSourceInfo->_sessionURL.get_cstr(),
Oscl_File::MODE_READ,
fileServ) != 0)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ProcessSDP - Unable to open SDP file"));
return PVMFFailure;
}
/* Get File Size */
osclFile.Seek(0, Oscl_File::SEEKEND);
int32 fileSize = osclFile.Tell();
osclFile.Seek(0, Oscl_File::SEEKSET);
if (fileSize <= 0)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ProcessSDP - Corrupt SDP file"));
return PVMFFailure;
}
OsclMemAllocDestructDealloc<uint8> my_alloc;
OsclRefCounter* my_refcnt;
uint aligned_refcnt_size =
oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
uint8* my_ptr = NULL;
int32 errcode = 0;
/*
* To acct for null char, as SDP buffer is treated akin to a string by the
* SDP parser lib.
*/
uint allocsize = oscl_mem_aligned_size(aligned_refcnt_size + fileSize + 2);
OSCL_TRY(errcode, my_ptr = (uint8*) my_alloc.ALLOCATE(allocsize));
if (errcode != OsclErrNone)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:ProcessSDP - Unable to process SDP file"));
return PVMFFailure;
}
my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
my_ptr += aligned_refcnt_size;
OsclMemoryFragment memfrag;
memfrag.len = fileSize;
memfrag.ptr = my_ptr;
OsclRefCounterMemFrag tmpRefcntMemFrag(memfrag, my_refcnt, memfrag.len);
iSDPText = tmpRefcntMemFrag;
osclFile.Read(memfrag.ptr, 1, fileSize);
osclFile.Close();
fileServ.Close();
}
PVMFSMSharedPtrAlloc<SDPInfo> sdpAlloc;
SDPInfo* sdpInfo = sdpAlloc.allocate();
SDP_Parser *sdpParser;
PVMF_STREAMING_MANAGER_NEW(NULL, SDP_Parser, (), sdpParser);
int32 sdpRetVal =
sdpParser->parseSDP((const char*)(iSDPText.getMemFragPtr()),
iSDPText.getMemFragSize(),
sdpInfo);
// save the SDP file name - the packet source node will need this
sdpInfo->setSDPFilename(iSessionSourceInfo->_sessionURL);
PVMF_STREAMING_MANAGER_DELETE(NULL, SDP_Parser, sdpParser);
OsclRefCounterSA< PVMFSMSharedPtrAlloc<SDPInfo> > *refcnt =
new OsclRefCounterSA< PVMFSMSharedPtrAlloc<SDPInfo> >(sdpInfo);
OsclSharedPtr<SDPInfo> sharedSDPInfo(sdpInfo, refcnt);
if (sdpRetVal != SDP_SUCCESS)
{
return PVMFFailure;
}
iSessionSourceInfo->_sdpInfo = sharedSDPInfo;
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::RecognizeAndProcessHeader()
{
OSCL_ASSERT(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_MS_HTTP_STREAMING_URL);
return Asf_RecognizeAndProcessHeader();
}
PVMFStatus
PVMFStreamingManagerNode::GetMediaPresentationInfo(PVMFMediaPresentationInfo& aInfo)
{
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
SDPInfo* sdpInfo = iSessionSourceInfo->_sdpInfo.GetRep();
/* Get SDP Session Info */
sessionDescription* sessionInfo = sdpInfo->getSessionInfo();
RtspRangeType *sessionRange = OSCL_CONST_CAST(RtspRangeType*, (sessionInfo->getRange()));
int32 sessionStartTime = 0, sessionStopTime = 0;
sessionRange->convertToMilliSec(sessionStartTime, sessionStopTime);
int32 duration_msec = (sessionStopTime - sessionStartTime);
uint64 duration64;
Oscl_Int64_Utils::set_uint64(duration64, 0, (uint32)duration_msec);
if (sessionRange->end_is_set == true)
{
aInfo.setDurationValue(duration64);
aInfo.setDurationTimeScale(1000);
}
else
{
aInfo.SetDurationAvailable(false);
}
aInfo.setSeekableFlag((!(sessionInfo->getRandomAccessDenied())));
int32 numTracks = sdpInfo->getNumMediaObjects();
SDPAltGroupType sdpAltGroupType = sessionInfo->getSDPAltGroupType();
PVMF_TRACK_INFO_TRACK_ALTERNATE_TYPE iAltType = PVMF_TRACK_ALTERNATE_TYPE_UNDEFINED;
if (sdpAltGroupType == SDP_ALT_GROUP_LANGUAGE)
{
iAltType = PVMF_TRACK_ALTERNATE_TYPE_LANGUAGE;
}
else if (sdpAltGroupType == SDP_ALT_GROUP_BANDWIDTH)
{
iAltType = PVMF_TRACK_ALTERNATE_TYPE_BANDWIDTH;
}
for (int32 i = 0; i < numTracks; i++)
{
/*
* Get the vector of mediaInfo as there can
* alternates for each track
*/
Oscl_Vector<mediaInfo*, SDPParserAlloc> mediaInfoVec =
sdpInfo->getMediaInfo(i);
uint32 minfoVecLen = mediaInfoVec.size();
for (uint32 j = 0; j < minfoVecLen; j++)
{
mediaInfo* mInfo = mediaInfoVec[j];
if (mInfo == NULL)
{
return PVMFFailure;
}
RtspRangeType *mediaRange = mInfo->getRtspRange();
int32 mediaStartTime = 0, mediaStopTime = 0;
mediaRange->convertToMilliSec(mediaStartTime, mediaStopTime);
int32 mediaDuration_ms = mediaStopTime - mediaStartTime;
uint64 mediaDuration64;
Oscl_Int64_Utils::set_uint64(mediaDuration64, 0, (uint32)mediaDuration_ms);
PVMFTrackInfo trackInfo;
Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadVector;
payloadVector = mInfo->getPayloadSpecificInfoVector();
if (payloadVector.size() == 0)
{
return false;
}
/*
* There can be multiple payloads per media segment.
* We only support one for now, so
* use just the first payload
*/
PayloadSpecificInfoTypeBase* payloadInfo = payloadVector[0];
// set config for later
int32 configSize = payloadInfo->configSize;
OsclAny* config = payloadInfo->configHeader.GetRep();
OSCL_StackString<256> mimeString;
const char* mimeType = mInfo->getMIMEType();
{
mimeString += mimeType;
}
trackInfo.setTrackMimeType(mimeString);
uint32 trackID = mInfo->getMediaInfoID();
trackInfo.setTrackID(trackID);
trackInfo.setPortTag(trackID);
trackInfo.setTrackBitRate(mInfo->getBitrate());
if (mediaRange->end_is_set == true)
{
trackInfo.setTrackDurationValue(mediaDuration64);
}
else
{
trackInfo.SetDurationAvailable(false);
}
if ((configSize > 0) && (config != NULL))
{
OsclMemAllocDestructDealloc<uint8> my_alloc;
OsclRefCounter* my_refcnt;
uint aligned_refcnt_size =
oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
uint8* my_ptr = NULL;
int32 errcode = 0;
OSCL_TRY(errcode, my_ptr = (uint8*) my_alloc.ALLOCATE(aligned_refcnt_size + configSize));
my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
my_ptr += aligned_refcnt_size;
OsclMemoryFragment memfrag;
memfrag.len = (uint32)configSize;
memfrag.ptr = my_ptr;
oscl_memcpy((void*)(memfrag.ptr), (const void*)config, memfrag.len);
OsclRefCounterMemFrag tmpRefcntMemFrag(memfrag, my_refcnt, memfrag.len);
trackInfo.setTrackConfigInfo(tmpRefcntMemFrag);
}
int32 dependsOnTrackID = mInfo->getDependsOnTrackID();
if (dependsOnTrackID != -1)
{
trackInfo.setDependsOn();
mediaInfo* baseMediaInfo = sdpInfo->getMediaInfoBasedOnDependsOnID(dependsOnTrackID);
if (baseMediaInfo == NULL)
{
return PVMFFailure;
}
trackInfo.addDependsOnTrackID(baseMediaInfo->getMediaInfoID());
}
if (iAltType != PVMF_TRACK_ALTERNATE_TYPE_UNDEFINED)
{
/* Expose alternate track ids */
trackInfo.setTrackAlternates(iAltType);
for (uint32 k = 0; k < minfoVecLen; k++)
{
mediaInfo* mInfo = mediaInfoVec[k];
if (mInfo == NULL)
{
return PVMFFailure;
}
uint32 altID = mInfo->getMediaInfoID();
if (altID != trackID)
{
trackInfo.addAlternateTrackID((int32)altID);
}
}
}
aInfo.addTrackInfo(trackInfo);
}
}
iCompleteMediaPresetationInfo = aInfo;
return PVMFSuccess;
}
return PVMFErrNotSupported;
}
PVMFStatus
PVMFStreamingManagerNode::SelectTracks(PVMFMediaPresentationInfo& aInfo,
PVMFSessionId s)
{
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
SDPInfo* sdpInfo = iSessionSourceInfo->_sdpInfo.GetRep();
if (sdpInfo == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SelectTracks - SDP Not Available"));
return PVMFErrArgument;
}
int32 numTracks = aInfo.getNumTracks();
for (int32 i = 0; i < numTracks; i++)
{
PVMFTrackInfo* trackInfo = aInfo.getTrackInfo(i);
uint32 trackID = trackInfo->getTrackID();
mediaInfo* mInfo =
sdpInfo->getMediaInfoBasedOnID(trackID);
if (mInfo == NULL)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:SelectTracks - Invalid SDP TrackID"));
return PVMFErrArgument;
}
mInfo->setSelect();
/* Set selected field in meta info */
Oscl_Vector<PVMFSMTrackMetaDataInfo, PVMFStreamingManagerNodeAllocator>::iterator it;
for (it = iMetaDataInfo.iTrackMetaDataInfoVec.begin(); it != iMetaDataInfo.iTrackMetaDataInfoVec.end(); it++)
{
if (it->iTrackID == trackID)
{
it->iTrackSelected = true;
}
}
}
iSelectedMediaPresetationInfo = aInfo;
return PVMFSuccess;
}
return PVMFErrNotSupported;
}
PVMFCommandId
PVMFStreamingManagerNode::SetDataSourcePosition(PVMFSessionId aSessionId,
PVMFTimestamp aTargetNPT,
PVMFTimestamp& aActualNPT,
PVMFTimestamp& aActualMediaDataTS,
bool aJumpToIFrame,
uint32 aStreamID,
OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::SetDataSourcePosition - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommand::Construct(aSessionId,
PVMF_STREAMING_MANAGER_NODE_SET_DATASOURCE_POSITION,
aTargetNPT,
&aActualNPT,
&aActualMediaDataTS,
aJumpToIFrame,
aStreamID,
aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::SetDataSourcePosition - Out"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::SetDataSourcePosition() - Cmd Recvd"));
return QueueCommandL(cmd);
}
PVMFCommandId
PVMFStreamingManagerNode::SetDataSourcePosition(PVMFSessionId aSessionId,
PVMFDataSourcePositionParams& aPVMFDataSourcePositionParams,
OsclAny* aContext)
{
PVMFStreamingManagerNodeCommand cmd;
return QueueCommandL(cmd);
}
void PVMFStreamingManagerNode::DoSetDataSourcePosition(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoSetDataSourcePosition - In"));
iActualRepositionStartNPTInMSPtr = NULL;
iActualMediaDataTSPtr = NULL;
iPVMFDataSourcePositionParamsPtr = NULL;
iJumpToIFrame = false;
uint32 streamID = 0;
aCmd.PVMFStreamingManagerNodeCommand::Parse(iRepositionRequestedStartNPTInMS,
iActualRepositionStartNPTInMSPtr,
iActualMediaDataTSPtr,
iJumpToIFrame,
streamID);
PVMF_SM_LOG_COMMAND_REPOS((0, "PVMFStreamingManagerNode::DoSetDataSourcePosition - TargetNPT = %d", iRepositionRequestedStartNPTInMS));
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
bool retVal = false;
// duplicate bos has been received
// dont perform reposition at source node
if (iStreamID == streamID) retVal = true; // data is already present in the graph
iStreamID = streamID;
jbExtIntf->SendBOSMessage(iStreamID);
*iActualRepositionStartNPTInMSPtr = 0;
*iActualMediaDataTSPtr = 0;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
if (iInterfaceState == EPVMFNodePrepared)
{
/*
* SetDataSource from a prepared state could mean two things:
* - In Play-Stop-Play usecase engine does a SetDataSourcePosition
* to get the start media TS to set its playback clock
* - Engine is trying to do a play with a non-zero start offset
*/
if (iRepositionRequestedStartNPTInMS < iSessionStopTime && iRepositionRequestedStartNPTInMS != iSessionStartTime)
{
/* Set Requested Play Range */
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
RtspRangeType rtspRange;
rtspRange.format = RtspRangeType::NPT_RANGE;
rtspRange.start_is_set = true;
rtspRange.npt_start.npt_format = NptTimeFormat::NPT_SEC;
rtspRange.npt_start.npt_sec.sec = iRepositionRequestedStartNPTInMS / 1000;
rtspRange.npt_start.npt_sec.milli_sec =
(iRepositionRequestedStartNPTInMS - ((iRepositionRequestedStartNPTInMS / 1000) * 1000));
rtspRange.end_is_set = true;
rtspRange.npt_end.npt_format = NptTimeFormat::NPT_SEC;
rtspRange.npt_end.npt_sec.sec = iSessionStopTime / 1000;
rtspRange.npt_end.npt_sec.milli_sec =
(iSessionStopTime - ((iSessionStopTime / 1000) * 1000));
if (rtspExtIntf->SetRequestPlayRange(rtspRange) != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoSetDataSourcePosition - SetRequestPlayRange Failed"));
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::SetDataSourcePosition() - Cmd Failed - PVMFFailure"));
CommandComplete(iInputCommands, aCmd, PVMFFailure);
return;
}
// we need to use part of the logic of repositioning to start
// streaming from a non-zero offset. Enabled only for 3gpp streaming
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
oRepositioning = true;
/* Start the nodes */
if (!DoRepositioningStart3GPPStreaming())
{
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
MoveCmdToCurrentQueue(aCmd);
return;
}
}
GetAcutalMediaTSAfterSeek();
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::SetDataSourcePosition() - CmdComplete"));
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
else if ((iInterfaceState == EPVMFNodeStarted) || (iInterfaceState == EPVMFNodePaused))
{
bool oRandAccessDenied = true;
sessionDescription* sessionInfo =
iSessionSourceInfo->_sdpInfo->getSessionInfo();
oRandAccessDenied = sessionInfo->getRandomAccessDenied();
if ((oRandAccessDenied == true) ||
(iSessionStopTimeAvailable == false) ||
(((int32)iRepositionRequestedStartNPTInMS < (int32)iSessionStartTime) ||
((int32)iRepositionRequestedStartNPTInMS >= (int32)iSessionStopTime)))
{
/*
* Implies an open ended session or invalid request time
* - no pause or reposition
*/
CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
return;
}
oRepositioning = true;
/* Put the jitter buffer into a state of transition */
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
jbExtIntf->PrepareForRepositioning();
/* If node is running, pause first */
if (iInterfaceState == EPVMFNodeStarted)
{
if (!DoRepositioningPause3GPPStreaming())
{
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
}
}
/* If already paused do not pause */
else if (iInterfaceState == EPVMFNodePaused)
{
/* Start the nodes */
if (!DoRepositioningStart3GPPStreaming())
{
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
}
}
MoveCmdToCurrentQueue(aCmd);
}
else
{
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
return;
}
}
else
{
PVMF_SM_LOG_COMMAND_SEQ((0, "PVMFStreamingManagerNode::SetDataSourcePosition() - Cmd Failed - PVMFErrArgument"));
CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
return;
}
return;
}
bool PVMFStreamingManagerNode::DoRepositioningPause3GPPStreaming()
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
int32 nodeTag = iNodeContainerVec[i].iNodeTag;
if ((nodeTag == PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_SOCKET_NODE))
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_PAUSE_CMD_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_SET_DATASOURCE_POSITION;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Pause(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoRepositioningPause:RequestNewInternalCmd - Failed"));
return false;
}
}
}
return true;
}
bool PVMFStreamingManagerNode::DoRepositioningPauseMSHTTPStreaming()
{
/* Pause session controller */
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
int32 nodeTag = iNodeContainerVec[i].iNodeTag;
if ((nodeTag == PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE))
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_PAUSE_CMD_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_SET_DATASOURCE_POSITION;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Pause(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoRepositioningPause:RequestNewInternalCmd - Failed"));
return false;
}
}
}
return true;
}
bool PVMFStreamingManagerNode::DoRepositioningStart3GPPStreaming()
{
/* Set Requested Play Range */
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
RtspRangeType rtspRange;
rtspRange.format = RtspRangeType::NPT_RANGE;
rtspRange.start_is_set = true;
rtspRange.npt_start.npt_format = NptTimeFormat::NPT_SEC;
rtspRange.npt_start.npt_sec.sec = iRepositionRequestedStartNPTInMS / 1000;
rtspRange.npt_start.npt_sec.milli_sec =
(iRepositionRequestedStartNPTInMS - ((iRepositionRequestedStartNPTInMS / 1000) * 1000));
rtspRange.end_is_set = true;
rtspRange.npt_end.npt_format = NptTimeFormat::NPT_SEC;
rtspRange.npt_end.npt_sec.sec = iSessionStopTime / 1000;
rtspRange.npt_end.npt_sec.milli_sec =
(iSessionStopTime - ((iSessionStopTime / 1000) * 1000));
if (rtspExtIntf->SetRequestPlayRange(rtspRange) != PVMFSuccess)
{
PVMF_SM_LOGERROR((0, "StreamingManagerNode:DoRepositioningStart - SetRequestPlayRange Failed"));
return false;
}
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_START_CMD_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_SET_DATASOURCE_POSITION;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Start(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoRepositioningStart:RequestNewInternalCmd - Failed"));
return false;
}
}
return true;
}
bool PVMFStreamingManagerNode::DoRepositioningStartMSHTTPStreaming()
{
PVMFSMNodeContainer* iMediaLayerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE);
if (iMediaLayerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFMediaLayerNodeExtensionInterface* mlExtIntf =
(PVMFMediaLayerNodeExtensionInterface*)
(iMediaLayerNodeContainer->iExtensions[0]);
if (mlExtIntf == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFPortInterface* mlInPort = iMediaLayerNodeContainer->iInputPorts[0];
mlExtIntf->setInPortReposFlag(mlInPort);
//Check Track Config. If error is detected, MediaLayer send EOS.
PVMFSMTrackInfoVector::iterator it;
for (it = iTrackInfoVec.begin(); it != iTrackInfoVec.end(); it++)
{
if (it->iTrackDisable == true)
mlExtIntf->setTrackDisable(it->iMediaLayerOutputPort);
}
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
int32 nodeTag = iNodeContainerVec[i].iNodeTag;
if ((nodeTag == PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE) ||
(nodeTag == PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE) ||
(iInterfaceState == EPVMFNodePrepared && nodeTag != PVMF_STREAMING_MANAGER_SOCKET_NODE))
{
PVMFSMCommandContext* internalCmd = RequestNewInternalCmd();
if (internalCmd != NULL)
{
internalCmd->cmd =
iNodeContainerVec[i].commandStartOffset +
PVMF_STREAMING_MANAGER_NODE_INTERNAL_START_CMD_OFFSET;
internalCmd->parentCmd = PVMF_STREAMING_MANAGER_NODE_SET_DATASOURCE_POSITION;
OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
PVMFNodeInterface* iNode = iNodeContainerVec[i].iNode;
iNode->Start(iNodeContainerVec[i].iSessionId, cmdContextData);
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_PENDING;
}
else
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode:DoRepositioningStartMSHTTPStreaming:RequestNewInternalCmd - Failed"));
return false;
}
}
}
return true;
}
void PVMFStreamingManagerNode::GetAcutalMediaTSAfterSeek()
{
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
if (iJitterBufferNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)
(iJitterBufferNodeContainer->iExtensions[0]);
PVMFSMNodeContainer* iMediaLayerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_MEDIA_LAYER_NODE);
if (iMediaLayerNodeContainer == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFMediaLayerNodeExtensionInterface* mlExtIntf =
(PVMFMediaLayerNodeExtensionInterface*)
(iMediaLayerNodeContainer->iExtensions[0]);
if (mlExtIntf == NULL) OSCL_LEAVE(OsclErrBadHandle);
PVMFPortInterface* mlInPort = iMediaLayerNodeContainer->iInputPorts[0];
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
iActualMediaDataTS = jbExtIntf->getActualMediaDataTSAfterSeek();
if (iActualMediaDataTSPtr != NULL)
{
*iActualMediaDataTSPtr = iActualMediaDataTS;
PVMF_SM_LOG_COMMAND_REPOS((0, "PVMFStreamingManagerNode::GetAcutalMediaTSAfterSeek - TargetNPT = %d, ActualNPT=%d, ActualMediaDataTS=%d",
iRepositionRequestedStartNPTInMS, *iActualRepositionStartNPTInMSPtr, *iActualMediaDataTSPtr));
}
if (iPVMFDataSourcePositionParamsPtr != NULL)
{
iPVMFDataSourcePositionParamsPtr->iActualMediaDataTS = iActualMediaDataTS;
PVMF_SM_LOG_COMMAND_REPOS((0, "PVMFStreamingManagerNode::GetAcutalMediaTSAfterSeek - ActualMediaDataTS=%d",
iPVMFDataSourcePositionParamsPtr->iActualMediaDataTS));
}
}
}
PVMFCommandId
PVMFStreamingManagerNode::QueryDataSourcePosition(PVMFSessionId aSessionId,
PVMFTimestamp aTargetNPT,
PVMFTimestamp& aActualNPT,
bool aSeekToSyncPoint,
OsclAny* aContext)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::QueryDataSourcePosition - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommand::Construct(aSessionId,
PVMF_STREAMING_MANAGER_NODE_QUERY_DATASOURCE_POSITION,
aTargetNPT,
&aActualNPT,
aSeekToSyncPoint,
aContext);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::QueryDataSourcePosition - Out"));
return QueueCommandL(cmd);
}
PVMFCommandId
PVMFStreamingManagerNode::QueryDataSourcePosition(PVMFSessionId aSessionId,
PVMFTimestamp aTargetNPT,
PVMFTimestamp& aSeekPointBeforeTargetNPT,
PVMFTimestamp& aSeekPointAfterTargetNPT,
OsclAny* aContext,
bool aSeekToSyncPoint)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::QueryDataSourcePosition - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommand::Construct(aSessionId,
PVMF_STREAMING_MANAGER_NODE_QUERY_DATASOURCE_POSITION,
aTargetNPT,
&aSeekPointBeforeTargetNPT,
&aSeekPointAfterTargetNPT,
aContext,
aSeekToSyncPoint);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::QueryDataSourcePosition - Out"));
return QueueCommandL(cmd);
}
void PVMFStreamingManagerNode::DoQueryDataSourcePosition(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoQueryDataSourcePosition - In"));
PVMFTimestamp repositionrequestedstartnptinms = 0;
PVMFTimestamp* actualrepositionstartnptinmsptr = NULL;
bool seektosyncpoint = false;
aCmd.PVMFStreamingManagerNodeCommand::Parse(repositionrequestedstartnptinms,
actualrepositionstartnptinmsptr,
seektosyncpoint);
if (actualrepositionstartnptinmsptr == NULL)
{
CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
return;
}
*actualrepositionstartnptinmsptr = 0;
// This query is not supported for streaming sessions
CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoQueryDataSourcePosition - Out"));
return;
}
PVMFCommandId
PVMFStreamingManagerNode::SetDataSourceRate(PVMFSessionId aSessionId,
int32 aRate,
OsclTimebase* aTimebase,
OsclAny* aContext)
{
OSCL_UNUSED_ARG(aSessionId);
OSCL_UNUSED_ARG(aRate);
OSCL_UNUSED_ARG(aTimebase);
OSCL_UNUSED_ARG(aContext);
OSCL_LEAVE(OsclErrNotSupported);
return 0;
}
void PVMFStreamingManagerNode::DoSetDataSourceRate(PVMFStreamingManagerNodeCommand& aCmd)
{
CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
}
uint32
PVMFStreamingManagerNode::GetNumMetadataKeys(char* aQueryKeyString)
{
uint32 num_entries = 0;
if (aQueryKeyString == NULL)
{
// No query key so just return all the available keys
num_entries = iAvailableMetadataKeys.size();
}
else
{
// Determine the number of metadata keys based on the query key string provided
uint32 i;
for (i = 0; i < iAvailableMetadataKeys.size(); i++)
{
// Check if the key matches the query key
if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
{
num_entries++;
}
}
for (i = 0; i < iCPMMetadataKeys.size(); i++)
{
/* Check if the key matches the query key */
if (pv_mime_strcmp(iCPMMetadataKeys[i].get_cstr(),
aQueryKeyString) >= 0)
{
num_entries++;
}
}
}
return num_entries;
}
uint32
PVMFStreamingManagerNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
{
uint32 numkeys = aKeyList.size();
if (numkeys == 0)
{
return 0;
}
SDPInfo* sdpInfo = NULL;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
sdpInfo = iSessionSourceInfo->_sdpInfo.GetRep();
if (sdpInfo == NULL)
{
return 0;
}
}
// Get Num Tracks
uint32 numtracks = iMetaDataInfo.iNumTracks;
uint32 numvalentries = 0;
for (uint32 lcv = 0; lcv < numkeys; lcv++)
{
if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_AUTHOR_KEY) == 0 &&
iMetaDataInfo.iAuthorPresent)
{
// Author
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_ARTIST_KEY) == 0 &&
iMetaDataInfo.iPerformerPresent)
{
// Artist/performer
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TITLE_KEY) == 0 &&
iMetaDataInfo.iTitlePresent)
{
// Title
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY) == 0 &&
iMetaDataInfo.iDescriptionPresent)
{
// Description
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_RATING_KEY) == 0 &&
iMetaDataInfo.iRatingPresent)
{
// Rating
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY) == 0 &&
iMetaDataInfo.iCopyRightPresent)
{
// Copyright
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_GENRE_KEY) == 0 &&
iMetaDataInfo.iGenrePresent)
{
// Genre
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_LYRICS_KEY) == 0 &&
iMetaDataInfo.iLyricsPresent)
{
// Lyrics
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY) == 0 &&
iMetaDataInfo.iWMPicturePresent)
{
// Num Picture
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_GRAPHICS_KEY) == 0 &&
iMetaDataInfo.iWMPicturePresent)
{
// Picture
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY) == 0 &&
iMetaDataInfo.iClassificationPresent)
{
// Classification
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_KEYWORDS_KEY) == 0 &&
iMetaDataInfo.iKeyWordsPresent)
{
// Keywords
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_LOCATION_KEY) == 0 &&
iMetaDataInfo.iLocationPresent)
{
// Location
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_DURATION_KEY) == 0)
{
// Session Duration
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY) == 0 &&
numtracks > 0)
{
// Number of tracks
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY) == 0)
{
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY) == 0)
{
// Increment the counter for the number of values found so far
++numvalentries;
}
else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY) != NULL)
{
// Track type
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = numtracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
{
continue;
}
// Increment the counter for the number of values found so far
numvalentries += (endindex + 1 - startindex);
}
else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY) != NULL)
{
// Track duration
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = numtracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
{
continue;
}
// Increment the counter for the number of values found so far
numvalentries += (endindex + 1 - startindex);
}
else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_BITRATE_KEY) != NULL)
{
// Track bitrate
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = numtracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
{
continue;
}
// Increment the counter for the number of values found so far
numvalentries += (endindex + 1 - startindex);
}
else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_MAX_BITRATE_KEY) != NULL)
{
// Track bitrate
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = numtracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
{
continue;
}
// Increment the counter for the number of values found so far
numvalentries += (endindex + 1 - startindex);
}
else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY) != NULL)
{
// Track selected
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = numtracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
{
continue;
}
// Increment the counter for the number of values found so far
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY) != NULL))
{
/*
* Codec Name
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY) != NULL))
{
/*
* Codec Description
* Determine the index requested.
*/
uint32 startindex = 0;
uint32 endindex = 0;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(),
PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if ((startindex > endindex) ||
(startindex >= (uint32)numtracks) ||
(endindex >= (uint32)numtracks))
{
continue;
}
numvalentries += (endindex + 1 - startindex);
}
else
{
/* Check the extended meta data list */
for (uint32 i = 0; i < iMetaDataInfo.iExtendedMetaDataNameVec.size(); i++)
{
OSCL_HeapString<PVMFStreamingManagerNodeAllocator> extMetaDataName =
iMetaDataInfo.iExtendedMetaDataNameVec[i];
if (oscl_strcmp(aKeyList[lcv].get_cstr(), extMetaDataName.get_cstr()) == 0)
{
/*
* Increment the counter for the number of values found so far
*/
++numvalentries;
}
}
}
}
return numvalentries; // Number of elements
}
PVMFStatus PVMFStreamingManagerNode::InitMetaData()
{
// Init Metadata
{
// Clear out the existing key list
iAvailableMetadataKeys.clear();
iCPMMetadataKeys.clear();
int32 leavecode = 0;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_REAL_HTTP_CLOAKING_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
// Get the SDP info
SDPInfo* sdpInfo = iSessionSourceInfo->_sdpInfo.GetRep();
if (sdpInfo == NULL)
{
return PVMFErrInvalidState;
}
// Get Asset Info
sessionDescription* sessionInfo = sdpInfo->getSessionInfo();
if (sessionInfo != NULL)
{
iMetaDataInfo.iRandomAccessDenied = sessionInfo->getRandomAccessDenied();
AssetInfoType assetInfo = sessionInfo->getAssetInfo();
iMetaDataInfo.iTitlePresent = assetInfo.oTitlePresent;
iMetaDataInfo.iDescriptionPresent = assetInfo.oDescriptionPresent;
iMetaDataInfo.iCopyRightPresent = assetInfo.oCopyRightPresent;
iMetaDataInfo.iPerformerPresent = assetInfo.oPerformerPresent;
iMetaDataInfo.iAuthorPresent = assetInfo.oAuthorPresent;
iMetaDataInfo.iGenrePresent = assetInfo.oGenrePresent;
iMetaDataInfo.iRatingPresent = assetInfo.oRatingPresent;
iMetaDataInfo.iClassificationPresent = assetInfo.oClassificationPresent;
iMetaDataInfo.iKeyWordsPresent = assetInfo.oKeyWordsPresent;
iMetaDataInfo.iLocationPresent = assetInfo.oLocationPresent;
if (iMetaDataInfo.iTitlePresent)
{
iMetaDataInfo.iTitle = assetInfo.Box[AssetInfoType::TITLE];
}
if (iMetaDataInfo.iDescriptionPresent)
{
iMetaDataInfo.iDescription = assetInfo.Box[AssetInfoType::DESCRIPTION];
}
if (iMetaDataInfo.iCopyRightPresent)
{
iMetaDataInfo.iCopyright = assetInfo.Box[AssetInfoType::COPYRIGHT];
}
if (iMetaDataInfo.iPerformerPresent)
{
iMetaDataInfo.iPerformer = assetInfo.Box[AssetInfoType::PERFORMER];
}
if (iMetaDataInfo.iAuthorPresent)
{
iMetaDataInfo.iAuthor = assetInfo.Box[AssetInfoType::AUTHOR];
}
if (iMetaDataInfo.iRatingPresent)
{
iMetaDataInfo.iRating = assetInfo.Box[AssetInfoType::RATING];
}
if (iMetaDataInfo.iClassificationPresent)
{
iMetaDataInfo.iClassification = assetInfo.Box[AssetInfoType::CLASSIFICATION];
}
if (iMetaDataInfo.iKeyWordsPresent)
{
iMetaDataInfo.iKeyWords = assetInfo.Box[AssetInfoType::KEYWORDS];
}
if (iMetaDataInfo.iLocationPresent)
{
iMetaDataInfo.iLocation = assetInfo.Box[AssetInfoType::LOCATION];
}
RtspRangeType *sessionRange = OSCL_CONST_CAST(RtspRangeType*, (sessionInfo->getRange()));
if (sessionRange->end_is_set == true)
{
iMetaDataInfo.iSessionDurationAvailable = true;
int32 sessionStartTime = 0, sessionStopTime = 0;
sessionRange->convertToMilliSec(sessionStartTime, sessionStopTime);
uint32 duration = 0;
if (sessionStopTime > sessionStartTime && sessionStartTime >= 0)
{
duration = (uint32)(sessionStopTime - sessionStartTime);
}
Oscl_Int64_Utils::set_uint64(iMetaDataInfo.iSessionDuration, 0, duration);
iMetaDataInfo.iSessionDurationTimeScale = 1000;
}
}
iMetaDataInfo.iNumTracks = sdpInfo->getNumMediaObjects();
for (uint32 i = 0; i < iMetaDataInfo.iNumTracks; i++)
{
Oscl_Vector<mediaInfo*, SDPParserAlloc> mediaInfoVec = sdpInfo->getMediaInfo(i);
for (uint32 j = 0; j < mediaInfoVec.size(); ++j)
{
mediaInfo* mInfo = mediaInfoVec[j];
if (mInfo != NULL)
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo;
trackMetaDataInfo.iTrackID = mInfo->getMediaInfoID();
const char* mimeType = mInfo->getMIMEType();
OSCL_StackString<32> h263(_STRLIT_CHAR("H263"));
{
trackMetaDataInfo.iMimeType += mimeType;
}
Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadVector;
payloadVector = mInfo->getPayloadSpecificInfoVector();
if (payloadVector.size() != 0)
{
/*
* There can be multiple payloads per media segment.
* We only support one for now, so
* use just the first payload
*/
PayloadSpecificInfoTypeBase* payloadInfo = payloadVector[0];
if (oscl_strstr(mimeType, h263.get_cstr()) != NULL)
{
H263PayloadSpecificInfoType* h263PayloadInfo =
OSCL_STATIC_CAST(H263PayloadSpecificInfoType*, payloadInfo);
trackMetaDataInfo.iTrackWidth = h263PayloadInfo->getFrameWidth();
trackMetaDataInfo.iTrackHeight = h263PayloadInfo->getFrameHeight();
}
}
trackMetaDataInfo.iTrackBitRate = (uint32)(mInfo->getBitrate());
RtspRangeType *mediaRange = mInfo->getRtspRange();
if (mediaRange->end_is_set == true)
{
int32 mediaStartTime = 0, mediaStopTime = 0;
mediaRange->convertToMilliSec(mediaStartTime, mediaStopTime);
uint32 trackduration = 0;
if (mediaStopTime > mediaStartTime && mediaStartTime >= 0)
{
trackduration = (uint32)(mediaStopTime - mediaStartTime);
}
uint64 trackduration64 = 0;
Oscl_Int64_Utils::set_uint64(trackduration64, 0, trackduration);
trackMetaDataInfo.iTrackDuration = trackduration64;
trackMetaDataInfo.iTrackDurationTimeScale = 1000;
trackMetaDataInfo.iTrackDurationAvailable = true;
}
else
{
trackMetaDataInfo.iTrackDurationAvailable = false;
}
iMetaDataInfo.iTrackMetaDataInfoVec.push_back(trackMetaDataInfo);
}
}
}
}
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_DURATION_KEY));
if (iMetaDataInfo.iTitlePresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_TITLE_KEY));
}
if (iMetaDataInfo.iDescriptionPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY));
}
if (iMetaDataInfo.iCopyRightPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY));
}
if (iMetaDataInfo.iPerformerPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_ARTIST_KEY));
}
if (iMetaDataInfo.iAuthorPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_AUTHOR_KEY));
}
if (iMetaDataInfo.iGenrePresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_GENRE_KEY));
}
if (iMetaDataInfo.iLyricsPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_LYRICS_KEY));
}
if (iMetaDataInfo.iWMPicturePresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY));
}
if (iMetaDataInfo.iWMPicturePresent)
{
// Create the parameter string for the index range
char indexparam[18];
oscl_snprintf(indexparam, 18, ";index=0...%d", (iMetaDataInfo.iWMPictureIndexVec.size() - 1));
indexparam[17] = NULL_TERM_CHAR;
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_GRAPHICS_KEY);
iAvailableMetadataKeys[0] += indexparam;);
}
if (iMetaDataInfo.iRatingPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_RATING_KEY));
}
if (iMetaDataInfo.iClassificationPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY));
}
if (iMetaDataInfo.iKeyWordsPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_KEYWORDS_KEY));
}
if (iMetaDataInfo.iLocationPresent)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_LOCATION_KEY));
}
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY));
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY));
if (iMetaDataInfo.iNumTracks > 0)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY));
// Create the parameter string for the index range
char indexparam[18];
oscl_snprintf(indexparam, 18, ";index=0...%d", (iMetaDataInfo.iNumTracks - 1));
indexparam[17] = NULL_TERM_CHAR;
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY);
iAvailableMetadataKeys[0] += indexparam;);
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY);
iAvailableMetadataKeys[0] += indexparam;);
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY);
iAvailableMetadataKeys[0] += indexparam;);
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY);
iAvailableMetadataKeys[0] += indexparam;);
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY);
iAvailableMetadataKeys[0] += indexparam;);
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY);
iAvailableMetadataKeys[0] += indexparam;);
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY);
iAvailableMetadataKeys[0] += indexparam;);
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_REAL_HTTP_CLOAKING_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE))
{
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_BITRATE_KEY);
iAvailableMetadataKeys[0] += indexparam;);
}
}
uint32 i;
for (i = 0; i < iMetaDataInfo.iExtendedMetaDataDescriptorCount; i++)
{
leavecode = 0;
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(iMetaDataInfo.iExtendedMetaDataNameVec[i]));
}
for (i = 0; i < iMetaDataInfo.iTrackMetaDataInfoVec.size(); i++)
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
char indexparam[18];
oscl_snprintf(indexparam, 18, ";index=%d", (i));
indexparam[17] = NULL;
if (trackMetaDataInfo.iTrackWidth > 0)
{
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY);
iAvailableMetadataKeys[0] += indexparam;);
}
if (trackMetaDataInfo.iTrackHeight > 0)
{
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY);
iAvailableMetadataKeys[0] += indexparam;);
}
if (trackMetaDataInfo.iVideoFrameRate > 0)
{
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY);
iAvailableMetadataKeys[0] += indexparam;);
}
if (trackMetaDataInfo.iAudioSampleRate > 0)
{
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY);
iAvailableMetadataKeys[0] += indexparam;);
}
if (trackMetaDataInfo.iAudioNumChannels > 0)
{
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY);
iAvailableMetadataKeys[0] += indexparam;);
}
if (trackMetaDataInfo.iAudioBitsPerSample > 0)
{
leavecode = 0;
OSCL_TRY(leavecode,
iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY);
iAvailableMetadataKeys[0] += indexparam;);
}
}
return PVMFSuccess;
}
}
PVMFStatus
PVMFStreamingManagerNode::DoGetMetadataKeys(PVMFStreamingManagerNodeCommand& aCmd)
{
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
SDPInfo* sdpInfo = iSessionSourceInfo->_sdpInfo.GetRep();
if (sdpInfo == NULL)
{
return PVMFErrInvalidState;
}
}
return (CompleteGetMetadataKeys(aCmd));
}
PVMFStatus
PVMFStreamingManagerNode::CompleteGetMetadataKeys(PVMFStreamingManagerNodeCommand& aCmd)
{
PVMFMetadataList* keylistptr = NULL;
uint32 starting_index;
int32 max_entries;
char* query_key = NULL;
aCmd.PVMFStreamingManagerNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);
// Check parameters
if (keylistptr == NULL)
{
// The list pointer is invalid
return PVMFErrArgument;
}
if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
{
// Invalid starting index and/or max entries
return PVMFErrArgument;
}
// Copy the requested keys
uint32 num_entries = 0;
int32 num_added = 0;
int32 leavecode = 0;
uint32 lcv = 0;
for (lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
{
if (query_key == NULL)
{
// No query key so this key is counted
++num_entries;
if (num_entries > starting_index)
{
// Past the starting index so copy the key
leavecode = 0;
OSCL_TRY(leavecode, keylistptr->push_back(iAvailableMetadataKeys[lcv]));
OSCL_FIRST_CATCH_ANY(leavecode,
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::DoGetMetadataKeys() Memory allocation failure when copying metadata key"));
return PVMFErrNoMemory);
num_added++;
}
}
else
{
// Check if the key matche the query key
if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
{
// This key is counted
++num_entries;
if (num_entries > starting_index)
{
// Past the starting index so copy the key
leavecode = 0;
OSCL_TRY(leavecode, keylistptr->push_back(iAvailableMetadataKeys[lcv]));
OSCL_FIRST_CATCH_ANY(leavecode,
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::DoGetMetadataKeys() Memory allocation failure when copying metadata key"));
return PVMFErrNoMemory);
num_added++;
}
}
}
}
for (lcv = 0; lcv < iCPMMetadataKeys.size(); lcv++)
{
if (query_key == NULL)
{
/* No query key so this key is counted */
++num_entries;
if (num_entries > (uint32)starting_index)
{
/* Past the starting index so copy the key */
leavecode = 0;
OSCL_TRY(leavecode, keylistptr->push_back(iCPMMetadataKeys[lcv]));
OSCL_FIRST_CATCH_ANY(leavecode,
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::CompleteGetMetadataKeys() Memory allocation failure when copying metadata key"));
return PVMFErrNoMemory);
num_added++;
}
}
else
{
/* Check if the key matches the query key */
if (pv_mime_strcmp(iCPMMetadataKeys[lcv].get_cstr(), query_key) >= 0)
{
/* This key is counted */
++num_entries;
if (num_entries > (uint32)starting_index)
{
/* Past the starting index so copy the key */
leavecode = 0;
OSCL_TRY(leavecode, keylistptr->push_back(iCPMMetadataKeys[lcv]));
OSCL_FIRST_CATCH_ANY(leavecode,
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::CompleteGetMetadataKeys() Memory allocation failure when copying metadata key"));
return PVMFErrNoMemory);
num_added++;
}
}
}
// Check if max number of entries have been copied
if (max_entries > 0 && num_added >= max_entries)
{
break;
}
}
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::GetIndexParamValues(char* aString, uint32& aStartIndex, uint32& aEndIndex)
{
// This parses a string of the form "index=N1...N2" and extracts the integers N1 and N2.
// If string is of the format "index=N1" then N2=N1
if (aString == NULL)
{
return PVMFErrArgument;
}
// Go to end of "index="
char* n1string = aString + 6;
PV_atoi(n1string, 'd', oscl_strlen(n1string), aStartIndex);
char* n2string = oscl_strstr(aString, _STRLIT_CHAR("..."));
if (n2string == NULL)
{
aEndIndex = aStartIndex;
}
else
{
// Go to end of "index=N1..."
n2string += 3;
PV_atoi(n2string, 'd', oscl_strlen(n2string), aEndIndex);
}
return PVMFSuccess;
}
PVMFStatus
PVMFStreamingManagerNode::DoGetMetadataValues(PVMFStreamingManagerNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFStreamingManagerNode::DoGetMetadataValues() In"));
SDPInfo* sdpInfo = NULL;
if ((iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTSP_URL) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_SDP_FILE) ||
(iSessionSourceInfo->_sessionType == PVMF_DATA_SOURCE_RTP_PACKET_SOURCE))
{
sdpInfo = iSessionSourceInfo->_sdpInfo.GetRep();
if (sdpInfo == NULL)
{
return PVMFErrInvalidState;
}
}
PVMFMetadataList* keylistptr = NULL;
Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
uint32 starting_index;
int32 max_entries;
aCmd.PVMFStreamingManagerNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries);
// Check the parameters
if (keylistptr == NULL || valuelistptr == NULL)
{
return PVMFErrArgument;
}
uint32 numkeys = keylistptr->size();
if (starting_index > (numkeys - 1) || numkeys <= 0 || max_entries == 0)
{
// Don't do anything
return PVMFErrArgument;
}
uint32 numvalentries = 0;
int32 numentriesadded = 0;
for (uint32 lcv = 0; lcv < numkeys; lcv++)
{
int32 leavecode = 0;
PvmiKvp KeyVal;
KeyVal.key = NULL;
KeyVal.value.pWChar_value = NULL;
KeyVal.value.pChar_value = NULL;
if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_AUTHOR_KEY) == 0 &&
iMetaDataInfo.iAuthorPresent)
{
// Author
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsAuthorUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_AUTHOR_KEY,
iMetaDataInfo.iAuthor.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_AUTHOR_KEY,
iMetaDataInfo.iAuthorUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_ARTIST_KEY) == 0 &&
iMetaDataInfo.iPerformerPresent)
{
// Artist/performer
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsPerformerUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_ARTIST_KEY,
iMetaDataInfo.iPerformer.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_ARTIST_KEY,
iMetaDataInfo.iPerformerUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TITLE_KEY) == 0 &&
iMetaDataInfo.iTitlePresent)
{
// Title
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsTitleUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_TITLE_KEY,
iMetaDataInfo.iTitle.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_TITLE_KEY,
iMetaDataInfo.iTitleUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY) == 0 &&
iMetaDataInfo.iDescriptionPresent)
{
// Description
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsDescriptionUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY,
iMetaDataInfo.iDescription.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY,
iMetaDataInfo.iDescriptionUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_RATING_KEY) == 0 &&
iMetaDataInfo.iRatingPresent)
{
// Rating
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsRatingUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_RATING_KEY,
iMetaDataInfo.iRating.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_RATING_KEY,
iMetaDataInfo.iRatingUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY) == 0 &&
iMetaDataInfo.iCopyRightPresent)
{
// Copyright
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsCopyRightUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY,
iMetaDataInfo.iCopyright.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY,
iMetaDataInfo.iCopyrightUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_GENRE_KEY) == 0 &&
iMetaDataInfo.iGenrePresent)
{
// Genre
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsGenreUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_GENRE_KEY,
iMetaDataInfo.iGenre.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_GENRE_KEY,
iMetaDataInfo.iGenreUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_LYRICS_KEY) == 0 &&
iMetaDataInfo.iLyricsPresent)
{
// Lyrics
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsLyricsUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_LYRICS_KEY,
iMetaDataInfo.iLyrics.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_LYRICS_KEY,
iMetaDataInfo.iLyricsUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY) == 0 &&
iMetaDataInfo.iWMPicturePresent)
{
/*
* Num Picture
* Increment the counter for the number of values found so far
*/
++numvalentries;
/* Create a value entry if past the starting index */
if (numvalentries > (uint32)starting_index)
{
PVMFStatus retval =
PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal,
PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY,
iMetaDataInfo.iNumWMPicture,
NULL);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY) == 0 &&
iMetaDataInfo.iClassificationPresent)
{
// Classification
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsClassificationUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY,
iMetaDataInfo.iClassification.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY,
iMetaDataInfo.iClassificationUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_KEYWORDS_KEY) == 0 &&
iMetaDataInfo.iKeyWordsPresent)
{
// Keywords
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsKeyWordsUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_KEYWORDS_KEY,
iMetaDataInfo.iKeyWords.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_KEYWORDS_KEY,
iMetaDataInfo.iKeyWordUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_LOCATION_KEY) == 0 &&
iMetaDataInfo.iLocationPresent)
{
// Location
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval;
if (iMetaDataInfo.iIsLocationUnicode == false)
{
retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_LOCATION_KEY,
iMetaDataInfo.iLocation.get_cstr());
}
else
{
retval = CreateKVPForWideCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_LOCATION_KEY,
iMetaDataInfo.iLocationUnicode.get_cstr());
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_DURATION_KEY) == 0)
{
// Session Duration
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
if (iMetaDataInfo.iSessionDurationAvailable == true)
{
uint32 duration = Oscl_Int64_Utils::get_uint64_lower32(iMetaDataInfo.iSessionDuration);
char timescalestr[20];
oscl_snprintf(timescalestr, 20, ";%s%d", PVMFSTREAMINGMGRNODE_TIMESCALE, iMetaDataInfo.iSessionDurationTimeScale);
timescalestr[19] = NULL_TERM_CHAR;
PVMFStatus retval = CreateKVPForUInt32Value(KeyVal,
PVMFSTREAMINGMGRNODE_DURATION_KEY,
duration,
timescalestr);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
else
{
OSCL_StackString<32> unknownDuration(_STRLIT_CHAR("unknown"));
PVMFStatus retval = CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_DURATION_KEY,
unknownDuration.get_cstr());
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY) == 0 &&
iMetaDataInfo.iNumTracks > 0)
{
// Number of tracks
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval = CreateKVPForUInt32Value(KeyVal,
PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY,
iMetaDataInfo.iNumTracks);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY) == 0)
{
// random access
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
PVMFStatus retval = CreateKVPForBoolValue(KeyVal,
PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY,
iMetaDataInfo.iRandomAccessDenied);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY) == 0)
{
/*
* Clip Type
* Increment the counter for the number of values found so far
*/
++numvalentries;
/* Create a value entry if past the starting index */
if (numvalentries > (uint32)starting_index)
{
uint32 len = 0;
char* clipType = NULL;
len = oscl_strlen("streaming");
clipType = OSCL_ARRAY_NEW(char, len + 1);
oscl_memset(clipType, 0, len + 1);
oscl_strncpy(clipType, ("streaming"), len);
PVMFStatus retval =
PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY,
clipType);
OSCL_ARRAY_DELETE(clipType);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY) != NULL)
{
// Track type
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
trackkvp.value.pChar_value = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL_TERM_CHAR;
const char* mimeType = trackMetaDataInfo.iMimeType.get_cstr();
retval = CreateKVPForCharStringValue(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY,
mimeType,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
if (trackkvp.value.pChar_value != NULL)
{
OSCL_ARRAY_DELETE(trackkvp.value.pChar_value);
trackkvp.value.pChar_value = NULL;
}
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY) != NULL)
{
// Track duration
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
if (trackMetaDataInfo.iTrackDurationAvailable == true)
{
char indextimescaleparam[36];
oscl_snprintf(indextimescaleparam, 36, ";%s%d;%s%d", PVMFSTREAMINGMGRNODE_INDEX, i, PVMFSTREAMINGMGRNODE_TIMESCALE, trackMetaDataInfo.iTrackDurationTimeScale);
indextimescaleparam[35] = NULL_TERM_CHAR;
uint32 trackduration =
Oscl_Int64_Utils::get_uint64_lower32(trackMetaDataInfo.iTrackDuration);
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY,
trackduration,
indextimescaleparam);
}
else
{
char indextimescaleparam[36];
oscl_snprintf(indextimescaleparam, 36, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indextimescaleparam[35] = NULL_TERM_CHAR;
OSCL_StackString<32> unknownDuration(_STRLIT_CHAR("unknown"));
PVMFStatus retval = CreateKVPForCharStringValue(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY,
unknownDuration.get_cstr(),
indextimescaleparam);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_BITRATE_KEY) != NULL)
{
// Track bitrate
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL_TERM_CHAR;
uint32 trackbitrate = trackMetaDataInfo.iTrackBitRate;
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_BITRATE_KEY,
trackbitrate,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_MAX_BITRATE_KEY) != NULL)
{
// Track bitrate
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL_TERM_CHAR;
uint32 trackbitrate = trackMetaDataInfo.iTrackMaxBitRate;
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_MAX_BITRATE_KEY,
trackbitrate,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY) != NULL)
{
// Track bitrate
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL_TERM_CHAR;
bool selected = trackMetaDataInfo.iTrackSelected;
retval = CreateKVPForBoolValue(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY,
selected,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY) != NULL)
{
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL;
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY,
trackMetaDataInfo.iTrackWidth,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY) != NULL)
{
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL;
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY,
trackMetaDataInfo.iTrackHeight,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY) != NULL)
{
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL;
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY,
trackMetaDataInfo.iVideoFrameRate,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY) != NULL)
{
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL;
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY,
trackMetaDataInfo.iAudioSampleRate,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY) != NULL)
{
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL;
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY,
trackMetaDataInfo.iAudioNumChannels,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY) != NULL)
{
// Determine the index requested. Default to all tracks
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
// Check if the index parameter is present
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
// Retrieve the index values
GetIndexParamValues(indexstr, startindex, endindex);
}
// Validate the indices
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
// Return a KVP for each index
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
// Increment the counter for the number of values found so far
++numvalentries;
// Add the value entry if past the starting index
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
indexparam[15] = NULL;
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY,
trackMetaDataInfo.iAudioBitsPerSample,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY) != NULL)
{
/* Codec Name */
/* Determine the index requested. Default to all tracks */
uint32 startindex = 0;
uint32 endindex = iMetaDataInfo.iNumTracks - 1;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
/* Return a KVP for each index */
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
/* Increment the counter for the number of values found so far */
++numvalentries;
/* Add the value entry if past the starting index */
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > (uint32)starting_index)
{
char indexparam[29];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
char* maxsizestr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_MAXSIZE);
char* truncatestr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRUNCATE_FLAG);
uint32 maxSize = 0xFFFFFFFF;
if (maxsizestr != NULL)
{
if (GetMaxSizeValue(maxsizestr, maxSize) != PVMFSuccess)
{
break;
}
}
uint32 truncateFlag = true;
if (truncatestr != NULL)
{
if (GetTruncateFlagValue(truncatestr, truncateFlag) != PVMFSuccess)
{
break;
}
}
uint32 codecNameLen = trackMetaDataInfo.iCodecName.get_size();
char maxsizemessage[13];
maxsizemessage[0] = '\0';
if (maxSize < codecNameLen)
{
if (!truncateFlag)
{
oscl_snprintf(maxsizemessage, 13, ";%s%d", PVMFSTREAMINGMGRNODE_REQSIZE, codecNameLen);
oscl_strncat(indexparam, maxsizemessage, oscl_strlen(maxsizemessage));
}
}
retval =
PVMFCreateKVPUtils::CreateKVPForWStringValue(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY,
(trackMetaDataInfo.iCodecName),
indexparam, maxSize, truncateFlag);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY) != NULL)
{
/* Codec Description */
/* Determine the index requested. Default to all tracks */
uint32 startindex = 0;
uint32 endindex = (uint32)iMetaDataInfo.iNumTracks - 1;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
/* Return a KVP for each index */
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
/* Increment the counter for the number of values found so far */
++numvalentries;
/* Add the value entry if past the starting index */
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > (uint32)starting_index)
{
char indexparam[29];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
char* maxsizestr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_MAXSIZE);
char* truncatestr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRUNCATE_FLAG);
uint32 maxSize = 0xFFFFFFFF;
if (maxsizestr != NULL)
{
if (GetMaxSizeValue(maxsizestr, maxSize) != PVMFSuccess)
{
break;
}
}
uint32 truncateFlag = true;
if (truncatestr != NULL)
{
if (GetTruncateFlagValue(truncatestr, truncateFlag) != PVMFSuccess)
{
break;
}
}
uint32 codecDescLen = trackInfo.iCodecDescription.get_size();
char maxsizemessage[13];
maxsizemessage[0] = '\0';
if (maxSize < codecDescLen)
{
if (!truncateFlag)
{
oscl_snprintf(maxsizemessage, 13, ";%s%d", PVMFSTREAMINGMGRNODE_REQSIZE, codecDescLen);
oscl_strncat(indexparam, maxsizemessage, oscl_strlen(maxsizemessage));
}
}
retval =
PVMFCreateKVPUtils::CreateKVPForWStringValue(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY,
(trackInfo.iCodecDescription),
indexparam, maxSize, truncateFlag);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY) != NULL)
{
/* Codec Description */
/* Determine the index requested. Default to all tracks */
uint32 startindex = 0;
uint32 endindex = (uint32)iMetaDataInfo.iNumTracks - 1;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
/* Return a KVP for each index */
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
/* Increment the counter for the number of values found so far */
++numvalentries;
/* Add the value entry if past the starting index */
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > (uint32)starting_index)
{
char indexparam[29];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
retval =
PVMFCreateKVPUtils::CreateKVPForByteArrayValue(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY,
(uint8*)(trackInfo.iCodecSpecificInfo.getMemFragPtr()),
(uint32)trackInfo.iCodecSpecificInfo.getMemFragSize()
, indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY) != NULL)
{
/* Codec Description */
/* Determine the index requested. Default to all tracks */
uint32 startindex = 0;
uint32 endindex = (uint32)iMetaDataInfo.iNumTracks - 1;
/* Check if the index parameter is present */
char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX);
if (indexstr != NULL)
{
/* Retrieve the index values */
GetIndexParamValues(indexstr, startindex, endindex);
}
/* Validate the indices */
if (startindex > endindex || startindex >= iMetaDataInfo.iNumTracks || endindex >= iMetaDataInfo.iNumTracks)
{
continue;
}
/* Return a KVP for each index */
for (uint32 i = startindex; i <= endindex; ++i)
{
if (i < iMetaDataInfo.iTrackMetaDataInfoVec.size())
{
PVMFSMTrackMetaDataInfo trackInfo = iMetaDataInfo.iTrackMetaDataInfoVec[i];
PvmiKvp trackkvp;
trackkvp.key = NULL;
/* Increment the counter for the number of values found so far */
++numvalentries;
/* Add the value entry if past the starting index */
PVMFStatus retval = PVMFErrArgument;
if (numvalentries > (uint32)starting_index)
{
char indexparam[29];
oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
retval = CreateKVPForUInt32Value(trackkvp,
PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY,
trackInfo.iTrackID,
indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
if (trackkvp.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(trackkvp));
if (leavecode != 0)
{
OSCL_ARRAY_DELETE(trackkvp.key);
trackkvp.key = NULL;
}
else
{
// Increment the value list entry counter
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
}
}
}
}
// Add the KVP to the list if the key string was created
if (KeyVal.key != NULL)
{
leavecode = 0;
OSCL_TRY(leavecode, (*valuelistptr).push_back(KeyVal));
if (leavecode != 0)
{
switch (GetValTypeFromKeyString(KeyVal.key))
{
case PVMI_KVPVALTYPE_CHARPTR:
if (KeyVal.value.pChar_value != NULL)
{
OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
KeyVal.value.pChar_value = NULL;
}
break;
default:
// Add more case statements if other value types are returned
break;
}
OSCL_ARRAY_DELETE(KeyVal.key);
KeyVal.key = NULL;
}
else
{
// Increment the counter for number of value entries added to the list
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
// Maximum number of values added so break out of the loop
break;
}
}
}
iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::CreateKVPForCharStringValue(PvmiKvp& aKeyVal, const char* aKeyTypeString, const char* aValString, char* aMiscKeyParam)
{
// Check parameters
if (aKeyVal.key != NULL || aKeyTypeString == NULL)
{
return PVMFErrArgument;
}
// Determine the length of strings
uint32 keylen = oscl_strlen(aKeyTypeString) + 1; // for key string and ";"
keylen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
keylen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator
if (aMiscKeyParam)
{
keylen += oscl_strlen(aMiscKeyParam);
}
uint32 valuelen = oscl_strlen(aValString) + 1;
// Allocate memory for the strings
int32 leavecode = 0;
OSCL_TRY(leavecode,
aKeyVal.key = OSCL_ARRAY_NEW(char, keylen);
aKeyVal.value.pChar_value = OSCL_ARRAY_NEW(char, valuelen);
);
if (leavecode == 0)
{
// Copy the key string
oscl_strncpy(aKeyVal.key, aKeyTypeString, oscl_strlen(aKeyTypeString) + 1);
oscl_strncat(aKeyVal.key, PVMFSTREAMINGMGRNODE_SEMICOLON, oscl_strlen(PVMFSTREAMINGMGRNODE_SEMICOLON));
oscl_strncat(aKeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
oscl_strncat(aKeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
if (aMiscKeyParam)
{
oscl_strncat(aKeyVal.key, aMiscKeyParam, oscl_strlen(aMiscKeyParam));
}
aKeyVal.key[keylen-1] = NULL_TERM_CHAR;
// Copy the value
oscl_strncpy(aKeyVal.value.pChar_value, aValString, valuelen);
aKeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
// Set the length and capacity
aKeyVal.length = valuelen;
aKeyVal.capacity = valuelen;
}
else
{
// Memory allocation failed so clean up
if (aKeyVal.key)
{
OSCL_ARRAY_DELETE(aKeyVal.key);
aKeyVal.key = NULL;
}
if (aKeyVal.value.pChar_value)
{
OSCL_ARRAY_DELETE(aKeyVal.value.pChar_value);
}
return PVMFErrNoMemory;
}
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::CreateKVPForWideCharStringValue(PvmiKvp& aKeyVal, const char* aKeyTypeString, const oscl_wchar* aValString, char* aMiscKeyParam)
{
// Check parameters
if (aKeyVal.key != NULL || aKeyTypeString == NULL)
{
return PVMFErrArgument;
}
// Determine the length of strings
uint32 keylen = oscl_strlen(aKeyTypeString) + 1; // for key string and ";"
keylen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
keylen += oscl_strlen(PVMI_KVPVALTYPE_WCHARPTR_STRING_CONSTCHAR) + 1; // for "wchar*" and NULL terminator
if (aMiscKeyParam)
{
keylen += oscl_strlen(aMiscKeyParam);
}
uint32 valuelen = oscl_strlen(aValString) + 1;
// Allocate memory for the strings
int32 leavecode = 0;
OSCL_TRY(leavecode,
aKeyVal.key = OSCL_ARRAY_NEW(char, keylen);
aKeyVal.value.pWChar_value = OSCL_ARRAY_NEW(oscl_wchar, valuelen);
);
if (leavecode == 0)
{
// Copy the key string
oscl_strncpy(aKeyVal.key, aKeyTypeString, oscl_strlen(aKeyTypeString) + 1);
oscl_strncat(aKeyVal.key, PVMFSTREAMINGMGRNODE_SEMICOLON, oscl_strlen(PVMFSTREAMINGMGRNODE_SEMICOLON));
oscl_strncat(aKeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
oscl_strncat(aKeyVal.key, PVMI_KVPVALTYPE_WCHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_WCHARPTR_STRING_CONSTCHAR));
if (aMiscKeyParam)
{
oscl_strncat(aKeyVal.key, aMiscKeyParam, oscl_strlen(aMiscKeyParam));
}
aKeyVal.key[keylen-1] = NULL_TERM_CHAR;
// Copy the value
oscl_strncpy(aKeyVal.value.pWChar_value, aValString, valuelen);
aKeyVal.value.pWChar_value[valuelen-1] = NULL_TERM_CHAR;
// Set the length and capacity
aKeyVal.length = valuelen;
aKeyVal.capacity = valuelen;
}
else
{
// Memory allocation failed so clean up
if (aKeyVal.key)
{
OSCL_ARRAY_DELETE(aKeyVal.key);
aKeyVal.key = NULL;
}
if (aKeyVal.value.pChar_value)
{
OSCL_ARRAY_DELETE(aKeyVal.value.pWChar_value);
}
return PVMFErrNoMemory;
}
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::CreateKVPForUInt32Value(PvmiKvp& aKeyVal, const char* aKeyTypeString, uint32& aValueUInt32, char* aMiscKeyParam)
{
// Check parameters
if (aKeyVal.key != NULL || aKeyTypeString == NULL)
{
return PVMFErrArgument;
}
// Determine the length of strings
uint32 keylen = oscl_strlen(aKeyTypeString) + 1; // for key string and ";"
keylen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
keylen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
if (aMiscKeyParam)
{
keylen += oscl_strlen(aMiscKeyParam);
}
// Allocate memory for the strings
int32 leavecode = 0;
OSCL_TRY(leavecode,
aKeyVal.key = OSCL_ARRAY_NEW(char, keylen);
);
if (leavecode == 0)
{
// Copy the key string
oscl_strncpy(aKeyVal.key, aKeyTypeString, oscl_strlen(aKeyTypeString) + 1);
oscl_strncat(aKeyVal.key, PVMFSTREAMINGMGRNODE_SEMICOLON, oscl_strlen(PVMFSTREAMINGMGRNODE_SEMICOLON));
oscl_strncat(aKeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
oscl_strncat(aKeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
if (aMiscKeyParam)
{
oscl_strncat(aKeyVal.key, aMiscKeyParam, oscl_strlen(aMiscKeyParam));
}
aKeyVal.key[keylen-1] = NULL_TERM_CHAR;
// Copy the value
aKeyVal.value.uint32_value = aValueUInt32;
// Set the length and capacity
aKeyVal.length = 1;
aKeyVal.capacity = 1;
}
else
{
// Memory allocation failed so clean up
if (aKeyVal.key)
{
OSCL_ARRAY_DELETE(aKeyVal.key);
aKeyVal.key = NULL;
}
return PVMFErrNoMemory;
}
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::CreateKVPForBoolValue(PvmiKvp& aKeyVal, const char* aKeyTypeString, bool& aValueBool, char* aMiscKeyParam)
{
// Check parameters
if (aKeyVal.key != NULL || aKeyTypeString == NULL)
{
return PVMFErrArgument;
}
// Determine the length of strings
uint32 keylen = oscl_strlen(aKeyTypeString) + 1; // for key string and ";"
keylen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
keylen += oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING_CONSTCHAR) + 1; // for "bool" and NULL terminator
if (aMiscKeyParam)
{
keylen += oscl_strlen(aMiscKeyParam);
}
// Allocate memory for the strings
int32 leavecode = 0;
OSCL_TRY(leavecode,
aKeyVal.key = OSCL_ARRAY_NEW(char, keylen);
);
if (leavecode == 0)
{
// Copy the key string
oscl_strncpy(aKeyVal.key, aKeyTypeString, oscl_strlen(aKeyTypeString) + 1);
oscl_strncat(aKeyVal.key, PVMFSTREAMINGMGRNODE_SEMICOLON, oscl_strlen(PVMFSTREAMINGMGRNODE_SEMICOLON));
oscl_strncat(aKeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
oscl_strncat(aKeyVal.key, PVMI_KVPVALTYPE_BOOL_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING_CONSTCHAR));
if (aMiscKeyParam)
{
oscl_strncat(aKeyVal.key, aMiscKeyParam, oscl_strlen(aMiscKeyParam));
}
aKeyVal.key[keylen-1] = NULL_TERM_CHAR;
// Copy the value
aKeyVal.value.bool_value = aValueBool;
// Set the length and capacity
aKeyVal.length = 1;
aKeyVal.capacity = 1;
}
else
{
// Memory allocation failed so clean up
if (aKeyVal.key)
{
OSCL_ARRAY_DELETE(aKeyVal.key);
aKeyVal.key = NULL;
}
return PVMFErrNoMemory;
}
return PVMFSuccess;
}
PVMFCommandId
PVMFStreamingManagerNode::GetNodeMetadataKeys(PVMFSessionId aSessionId,
PVMFMetadataList& aKeyList,
uint32 starting_index,
int32 max_entries,
char* query_key,
const OsclAny* aContextData)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::GetNodeMetadataKeys - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommand::Construct(aSessionId,
PVMF_STREAMING_MANAGER_NODE_GETNODEMETADATAKEYS,
aKeyList,
starting_index,
max_entries,
query_key,
aContextData);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::GetNodeMetadataKeys - Out"));
return QueueCommandL(cmd);
}
PVMFCommandId
PVMFStreamingManagerNode::GetNodeMetadataValues(PVMFSessionId aSessionId,
PVMFMetadataList& aKeyList,
Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
uint32 starting_index,
int32 max_entries,
const OsclAny* aContextData)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::GetNodeMetadataValues - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommand::Construct(aSessionId,
PVMF_STREAMING_MANAGER_NODE_GETNODEMETADATAVALUES,
aKeyList,
aValueList,
starting_index,
max_entries,
aContextData);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::GetNodeMetadataValues - Out"));
return QueueCommandL(cmd);
}
// From PVMFMetadataExtensionInterface
PVMFStatus PVMFStreamingManagerNode::ReleaseNodeMetadataKeys(PVMFMetadataList& ,
uint32 ,
uint32)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFStreamingManagerNode::ReleaseNodeMetadataKeys() called"));
//nothing needed-- there's no dynamic allocation in this node's key list
return PVMFSuccess;
}
// From PVMFMetadataExtensionInterface
PVMFStatus PVMFStreamingManagerNode::ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
uint32 start,
uint32 end)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFStreamingManagerNode::ReleaseNodeMetadataValues() called"));
if (start > end || aValueList.size() == 0)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::ReleaseNodeMetadataValues() Invalid start/end index"));
return PVMFErrArgument;
}
//Only CPM related metadata is retrived. Then this one should be 0.
if (iPVMFStreamingManagerNodeMetadataValueCount == 0) return PVMFSuccess;
//To remove madatada related with un-drm value
end = iPVMFStreamingManagerNodeMetadataValueCount - 1;
if (end >= aValueList.size())
{
end = aValueList.size() - 1;
}
for (uint32 i = start; i <= end; i++)
{
if (aValueList[i].key != NULL)
{
switch (GetValTypeFromKeyString(aValueList[i].key))
{
case PVMI_KVPVALTYPE_WCHARPTR:
if (aValueList[i].value.pWChar_value != NULL)
{
OSCL_ARRAY_DELETE(aValueList[i].value.pWChar_value);
aValueList[i].value.pWChar_value = NULL;
}
break;
case PVMI_KVPVALTYPE_CHARPTR:
if (aValueList[i].value.pChar_value != NULL)
{
OSCL_ARRAY_DELETE(aValueList[i].value.pChar_value);
aValueList[i].value.pChar_value = NULL;
}
break;
case PVMI_KVPVALTYPE_UINT8PTR:
if (aValueList[i].value.pUint8_value != NULL)
{
OSCL_ARRAY_DELETE(aValueList[i].value.pUint8_value);
aValueList[i].value.pUint8_value = NULL;
}
break;
case PVMI_KVPVALTYPE_UINT32:
case PVMI_KVPVALTYPE_FLOAT:
case PVMI_KVPVALTYPE_BOOL:
// No need to free memory for this valtype
break;
default:
// Should not get a value that wasn't created from this node
OSCL_ASSERT(false);
break;
}
OSCL_ARRAY_DELETE(aValueList[i].key);
aValueList[i].key = NULL;
}
}
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::getParametersSync(
PvmiMIOSession aSession, PvmiKeyType aIdentifier,
PvmiKvp*& aParameters, int& aNumParamElements,
PvmiCapabilityContext aContext)
{
OSCL_UNUSED_ARG(aSession);
OSCL_UNUSED_ARG(aContext);
// Initialize the output parameters
aNumParamElements = 0;
aParameters = NULL;
// Count the number of components and parameters in the key
int compcount = pv_mime_string_compcnt(aIdentifier);
// Retrieve the first component from the key string
char* compstr = NULL;
pv_mime_string_extract_type(0, aIdentifier, compstr);
if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
{
// First component should be "x-pvmf" and there must
// be at least two components to go past x-pvmf
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::getParametersSync() Invalid key string"));
return PVMFErrArgument;
}
// Retrieve the second component from the key string
pv_mime_string_extract_type(1, aIdentifier, compstr);
// Check if it is key string for streaming manager
if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) < 0)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::getParametersSync() Unsupported key"));
return PVMFFailure;
}
if (compcount == 2)
{
// Since key is "x-pvmf/net" return all
// nodes available at this level. Ignore attribute
// since capability is only allowed
// Allocate memory for the KVP list
aParameters = (PvmiKvp*)oscl_malloc(StreamingManagerConfig_NumBaseKeys * sizeof(PvmiKvp));
if (aParameters == NULL)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::getParametersSync() Memory allocation for KVP failed"));
return PVMFErrNoMemory;
}
oscl_memset(aParameters, 0, StreamingManagerConfig_NumBaseKeys*sizeof(PvmiKvp));
// Allocate memory for the key strings in each KVP
PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(StreamingManagerConfig_NumBaseKeys * SMCONFIG_KEYSTRING_SIZE * sizeof(char));
if (memblock == NULL)
{
oscl_free(aParameters);
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::getParametersSync() Memory allocation for key string failed"));
return PVMFErrNoMemory;
}
oscl_strset(memblock, 0, StreamingManagerConfig_NumBaseKeys*SMCONFIG_KEYSTRING_SIZE*sizeof(char));
// Assign the key string buffer to each KVP
uint32 j;
for (j = 0; j < StreamingManagerConfig_NumBaseKeys; ++j)
{
aParameters[j].key = memblock + (j * SMCONFIG_KEYSTRING_SIZE);
}
// Copy the requested info
for (j = 0; j < StreamingManagerConfig_NumBaseKeys; ++j)
{
oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/net/"), 17);
oscl_strncat(aParameters[j].key, StreamingManagerConfig_BaseKeys[j].iString, oscl_strlen(StreamingManagerConfig_BaseKeys[j].iString));
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type="), 6);
switch (StreamingManagerConfig_BaseKeys[j].iType)
{
case PVMI_KVPTYPE_AGGREGATE:
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_AGGREGATE_STRING), oscl_strlen(PVMI_KVPTYPE_AGGREGATE_STRING));
break;
case PVMI_KVPTYPE_POINTER:
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_POINTER_STRING), oscl_strlen(PVMI_KVPTYPE_POINTER_STRING));
break;
case PVMI_KVPTYPE_VALUE:
default:
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_VALUE_STRING), oscl_strlen(PVMI_KVPTYPE_VALUE_STRING));
break;
}
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype="), 9);
switch (StreamingManagerConfig_BaseKeys[j].iValueType)
{
case PVMI_KVPVALTYPE_RANGE_INT32:
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
break;
case PVMI_KVPVALTYPE_KSV:
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
break;
case PVMI_KVPVALTYPE_CHARPTR:
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING), oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
break;
case PVMI_KVPVALTYPE_BOOL:
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
break;
case PVMI_KVPVALTYPE_UINT32:
default:
oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
break;
}
aParameters[j].key[SMCONFIG_KEYSTRING_SIZE-1] = 0;
}
aNumParamElements = StreamingManagerConfig_NumBaseKeys;
}
else if (compcount == 3)
{
pv_mime_string_extract_type(2, aIdentifier, compstr);
// Determine what is requested
PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
if (reqattr == PVMI_KVPATTR_UNKNOWN)
{
reqattr = PVMI_KVPATTR_CUR;
}
uint i;
for (i = 0; i < StreamingManagerConfig_NumBaseKeys; i++)
{
if (pv_mime_strcmp(compstr, (char*)(StreamingManagerConfig_BaseKeys[i].iString)) >= 0)
{
break;
}
}
if (i == StreamingManagerConfig_NumBaseKeys)
{
// no match found
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::getParametersSync() Unsupported key"));
return PVMFErrNoMemory;
}
PVMFStatus retval = GetConfigParameter(aParameters, aNumParamElements, i, reqattr);
if (retval != PVMFSuccess)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::getParametersSync() "
"Retrieving streaming manager parameter failed"));
return retval;
}
}
else
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFStreamingManagerNode::getParametersSync() Unsupported key"));
return PVMFErrArgument;
}
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::releaseParameters(PvmiMIOSession aSession,
PvmiKvp* aParameters,
int num_elements)
{
OSCL_UNUSED_ARG(aSession);
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFStreamingManagerNode::releaseParameters() In"));
if (aParameters == NULL || num_elements < 1)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::releaseParameters() KVP list is NULL or number of elements is 0"));
return PVMFErrArgument;
}
// Count the number of components and parameters in the key
int compcount = pv_mime_string_compcnt(aParameters[0].key);
// Retrieve the first component from the key string
char* compstr = NULL;
pv_mime_string_extract_type(0, aParameters[0].key, compstr);
if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
{
// First component should be "x-pvmf" and there must
// be at least two components to go past x-pvmf
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::releaseParameters() Unsupported key"));
return PVMFErrArgument;
}
// Retrieve the second component from the key string
pv_mime_string_extract_type(1, aParameters[0].key, compstr);
// Assume all the parameters come from the same component so the base components are the same
if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) >= 0)
{
// Go through each KVP and release memory for value if allocated from heap
for (int32 i = 0; i < num_elements; ++i)
{
// Next check if it is a value type that allocated memory
PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[i].key);
if (kvptype == PVMI_KVPTYPE_VALUE || kvptype == PVMI_KVPTYPE_UNKNOWN)
{
PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[i].key);
if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::releaseParameters() Valtype not specified in key string"));
return PVMFErrArgument;
}
if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
{
oscl_free(aParameters[i].value.pChar_value);
aParameters[i].value.pChar_value = NULL;
}
else if (keyvaltype == PVMI_KVPVALTYPE_WCHARPTR && aParameters[i].value.pWChar_value != NULL)
{
oscl_free(aParameters[i].value.pWChar_value);
aParameters[i].value.pWChar_value = NULL;
}
else if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
{
oscl_free(aParameters[i].value.pChar_value);
aParameters[i].value.pChar_value = NULL;
}
else if (keyvaltype == PVMI_KVPVALTYPE_KSV && aParameters[i].value.key_specific_value != NULL)
{
oscl_free(aParameters[i].value.key_specific_value);
aParameters[i].value.key_specific_value = NULL;
}
else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_INT32 && aParameters[i].value.key_specific_value != NULL)
{
range_int32* ri32 = (range_int32*)aParameters[i].value.key_specific_value;
aParameters[i].value.key_specific_value = NULL;
oscl_free(ri32);
}
else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_UINT32 && aParameters[i].value.key_specific_value != NULL)
{
range_uint32* rui32 = (range_uint32*)aParameters[i].value.key_specific_value;
aParameters[i].value.key_specific_value = NULL;
oscl_free(rui32);
}
}
}
oscl_free(aParameters[0].key);
// Free memory for the parameter list
oscl_free(aParameters);
aParameters = NULL;
}
else
{
// Unknown key string
return PVMFErrArgument;
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFStreamingManagerNode::releaseParameters() Out"));
return PVMFSuccess;
}
void PVMFStreamingManagerNode::createContext(PvmiMIOSession aSession,
PvmiCapabilityContext& aContext)
{
OSCL_UNUSED_ARG(aSession);
OSCL_UNUSED_ARG(aContext);
// not supported
OSCL_LEAVE(PVMFErrNotSupported);
}
void PVMFStreamingManagerNode::setContextParameters(PvmiMIOSession aSession,
PvmiCapabilityContext& aContext,
PvmiKvp* aParameters,
int num_parameter_elements)
{
OSCL_UNUSED_ARG(aSession);
OSCL_UNUSED_ARG(aContext);
OSCL_UNUSED_ARG(aParameters);
OSCL_UNUSED_ARG(num_parameter_elements);
// not supported
OSCL_LEAVE(PVMFErrNotSupported);
}
void PVMFStreamingManagerNode::DeleteContext(PvmiMIOSession aSession,
PvmiCapabilityContext& aContext)
{
OSCL_UNUSED_ARG(aSession);
OSCL_UNUSED_ARG(aContext);
// not supported
OSCL_LEAVE(PVMFErrNotSupported);
}
void PVMFStreamingManagerNode::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
int num_elements, PvmiKvp* &aRet_kvp)
{
OSCL_UNUSED_ARG(aSession);
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFStreamingManagerNode::setParametersSync() In"));
// Go through each parameter
for (int paramind = 0; paramind < num_elements; ++paramind)
{
// Count the number of components and parameters in the key
int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
// Retrieve the first component from the key string
char* compstr = NULL;
pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);
if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
{
// First component should be "x-pvmf" and there must
// be at least two components to go past x-pvmf
aRet_kvp = &aParameters[paramind];
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::setParametersSync() Unsupported key"));
return;
}
// Retrieve the second component from the key string
pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);
// First check if it is key string for the streaming manager
if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) >= 0)
{
if (compcount == 3)
{
pv_mime_string_extract_type(2, aParameters[paramind].key, compstr);
uint i;
for (i = 0; i < StreamingManagerConfig_NumBaseKeys; i++)
{
if (pv_mime_strcmp(compstr, (char*)(StreamingManagerConfig_BaseKeys[i].iString)) >= 0)
{
break;
}
}
if (StreamingManagerConfig_NumBaseKeys == i)
{
// invalid third component
aRet_kvp = &aParameters[paramind];
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::setParametersSync() Unsupported key"));
return;
}
// Verify and set the passed-in setting
PVMFStatus retval = VerifyAndSetConfigParameter(i, aParameters[paramind], true);
if (retval != PVMFSuccess)
{
aRet_kvp = &aParameters[paramind];
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::setParametersSync() Setting "
"parameter %d failed", paramind));
return;
}
}
else
{
// Do not support more than 3 components right now
aRet_kvp = &aParameters[paramind];
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::setParametersSync() Unsupported key"));
return;
}
}
else
{
// Unknown key string
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::setParametersSync() Unsupported key"));
return;
}
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFStreamingManagerNode::setParametersSync() Out"));
}
PVMFCommandId PVMFStreamingManagerNode::setParametersAsync(PvmiMIOSession aSession,
PvmiKvp* aParameters,
int num_elements,
PvmiKvp*& aRet_kvp,
OsclAny* context)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::setParametersAsync - In"));
PVMFStreamingManagerNodeCommand cmd;
cmd.PVMFStreamingManagerNodeCommand::Construct(0,
PVMF_STREAMING_MANAGER_NODE_CAPCONFIG_SETPARAMS,
aSession, aParameters, num_elements, aRet_kvp, context);
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::setParametersAsync - Out"));
return QueueCommandL(cmd);
}
uint32 PVMFStreamingManagerNode::getCapabilityMetric(PvmiMIOSession aSession)
{
OSCL_UNUSED_ARG(aSession);
return 0;
}
PVMFStatus PVMFStreamingManagerNode::verifyParametersSync(PvmiMIOSession aSession,
PvmiKvp* aParameters,
int num_elements)
{
OSCL_UNUSED_ARG(aSession);
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFStreamingManagerNode::verifyParametersSync() In"));
if (aParameters == NULL || num_elements < 1)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFStreamingManagerNode::verifyParametersSync() Passed in parameter invalid"));
return PVMFErrArgument;
}
// Go through each parameter and verify
for (int32 paramind = 0; paramind < num_elements; ++paramind)
{
// Count the number of components and parameters in the key
int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
// Retrieve the first component from the key string
char* compstr = NULL;
pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);
if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
{
// First component should be "x-pvmf" and there must
// be at least two components to go past x-pvmf
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::verifyParametersSync() Unsupported key"));
return PVMFErrArgument;
}
// Retrieve the second component from the key string
pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);
// First check if it is key string for this node
if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) >= 0) && (compcount == 3))
{
pv_mime_string_extract_type(2, aParameters[paramind].key, compstr);
uint i;
for (i = 0; i < StreamingManagerConfig_NumBaseKeys; i++)
{
if (pv_mime_strcmp(compstr, (char*)(StreamingManagerConfig_BaseKeys[i].iString)) >= 0)
{
break;
}
}
if (StreamingManagerConfig_NumBaseKeys == i)
{
return PVMFErrArgument;
}
// Verify the passed-in player setting
PVMFStatus retval = VerifyAndSetConfigParameter(i, aParameters[paramind], false);
if (retval != PVMFSuccess)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Verifying parameter %d failed", paramind));
return retval;
}
}
else
{
// Unknown key string
return PVMFErrArgument;
}
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoCapConfigVerifyParameters() Out"));
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::GetConfigParameter(PvmiKvp*& aParameters,
int& aNumParamElements,
int32 aIndex, PvmiKvpAttr reqattr)
{
PVMF_SM_LOGINFO((0, "PVMFStreamingManagerNode::GetConfigParameter() In"));
aNumParamElements = 0;
// Allocate memory for the KVP
aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
if (aParameters == NULL)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::GetConfigParameter() Memory allocation for KVP failed"));
return PVMFErrNoMemory;
}
oscl_memset(aParameters, 0, sizeof(PvmiKvp));
// Allocate memory for the key string in KVP
PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(SMCONFIG_KEYSTRING_SIZE * sizeof(char));
if (memblock == NULL)
{
oscl_free(aParameters);
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::GetConfigParameter() Memory allocation for key string failed"));
return PVMFErrNoMemory;
}
oscl_strset(memblock, 0, SMCONFIG_KEYSTRING_SIZE*sizeof(char));
// Assign the key string buffer to KVP
aParameters[0].key = memblock;
// Copy the key string
oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/net/"), 17);
oscl_strncat(aParameters[0].key, StreamingManagerConfig_BaseKeys[aIndex].iString,
oscl_strlen(StreamingManagerConfig_BaseKeys[aIndex].iString));
oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
switch (StreamingManagerConfig_BaseKeys[aIndex].iValueType)
{
case PVMI_KVPVALTYPE_RANGE_INT32:
oscl_strncat(aParameters[0].key,
_STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING),
oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
break;
case PVMI_KVPVALTYPE_KSV:
oscl_strncat(aParameters[0].key,
_STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING),
oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
break;
case PVMI_KVPVALTYPE_CHARPTR:
oscl_strncat(aParameters[0].key,
_STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING),
oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
break;
case PVMI_KVPVALTYPE_WCHARPTR:
oscl_strncat(aParameters[0].key,
_STRLIT_CHAR(PVMI_KVPVALTYPE_WCHARPTR_STRING),
oscl_strlen(PVMI_KVPVALTYPE_WCHARPTR_STRING));
break;
case PVMI_KVPVALTYPE_BOOL:
oscl_strncat(aParameters[0].key,
_STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING),
oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
break;
case PVMI_KVPVALTYPE_UINT32:
default:
if (reqattr == PVMI_KVPATTR_CAP)
{
oscl_strncat(aParameters[0].key,
_STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING),
oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
}
else
{
oscl_strncat(aParameters[0].key,
_STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING),
oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
}
break;
}
aParameters[0].key[SMCONFIG_KEYSTRING_SIZE-1] = 0;
// Copy the requested info
switch (aIndex)
{
case BASEKEY_DELAY:
if (reqattr == PVMI_KVPATTR_CUR)
{
// Return current value
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->getJitterBufferDurationInMilliSeconds(aParameters[0].value.uint32_value);
}
else if (reqattr == PVMI_KVPATTR_DEF)
{
// Return default
aParameters[0].value.uint32_value = DEFAULT_JITTER_BUFFER_DURATION_IN_MS;
}
else
{
// Return capability
range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
if (rui32 == NULL)
{
oscl_free(aParameters[0].key);
oscl_free(aParameters);
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::GetConfigParameter() "
"Memory allocation for range uint32 failed"));
return PVMFErrNoMemory;
}
rui32->min = MIN_JITTER_BUFFER_DURATION_IN_MS;
rui32->max = MAX_JITTER_BUFFER_DURATION_IN_MS;
aParameters[0].value.key_specific_value = (void*)rui32;
}
break;
case BASEKEY_REBUFFERING_THRESHOLD:
{
if (reqattr == PVMI_KVPATTR_CUR)
{
// Return current value
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->getJitterBufferRebufferingThresholdInMilliSeconds(aParameters[0].value.uint32_value);
}
else if (reqattr == PVMI_KVPATTR_DEF)
{
// Return default
aParameters[0].value.uint32_value = DEFAULT_JITTER_BUFFER_UNDERFLOW_THRESHOLD_IN_MS;
}
else
{
// Return capability
range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
if (rui32 == NULL)
{
oscl_free(aParameters[0].key);
oscl_free(aParameters);
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::GetConfigParameter() "
"Memory allocation for range uint32 failed"));
return PVMFErrNoMemory;
}
rui32->min = DEFAULT_JITTER_BUFFER_UNDERFLOW_THRESHOLD_IN_MS;
rui32->max = DEFAULT_JITTER_BUFFER_UNDERFLOW_THRESHOLD_IN_MS;
aParameters[0].value.key_specific_value = (void*)rui32;
}
}
break;
case BASEKEY_JITTERBUFFER_NUMRESIZE:
if (reqattr == PVMI_KVPATTR_CUR)
{
// Return current value
uint32 numResize, resizeSize;
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->GetSharedBufferResizeParams(numResize, resizeSize);
aParameters[0].value.uint32_value = numResize;
}
else if (reqattr == PVMI_KVPATTR_DEF)
{
// Return default
aParameters[0].value.uint32_value = DEFAULT_MAX_NUM_SOCKETMEMPOOL_RESIZES;
}
else
{
// Return capability
range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
if (rui32 == NULL)
{
oscl_free(aParameters[0].key);
oscl_free(aParameters);
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::GetConfigParameter() "
"Memory allocation for range uint32 failed"));
return PVMFErrNoMemory;
}
rui32->min = MIN_NUM_SOCKETMEMPOOL_RESIZES;
rui32->max = MAX_NUM_SOCKETMEMPOOL_RESIZES;
aParameters[0].value.key_specific_value = (void*)rui32;
}
break;
case BASEKEY_JITTERBUFFER_RESIZESIZE:
if (reqattr == PVMI_KVPATTR_CUR)
{
// Return current value
uint32 numResize, resizeSize;
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->GetSharedBufferResizeParams(numResize, resizeSize);
aParameters[0].value.uint32_value = resizeSize;
}
else if (reqattr == PVMI_KVPATTR_DEF)
{
// Return default
aParameters[0].value.uint32_value = DEFAULT_MAX_SOCKETMEMPOOL_RESIZELEN_INPUT_PORT;
}
else
{
// Return capability
range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
if (rui32 == NULL)
{
oscl_free(aParameters[0].key);
oscl_free(aParameters);
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::GetConfigParameter() "
"Memory allocation for range uint32 failed"));
return PVMFErrNoMemory;
}
rui32->min = MIN_SOCKETMEMPOOL_RESIZELEN_INPUT_PORT;
rui32->max = MAX_SOCKETMEMPOOL_RESIZELEN_INPUT_PORT;
aParameters[0].value.key_specific_value = (void*)rui32;
}
break;
case BASEKEY_SESSION_CONTROLLER_USER_AGENT:
if ((reqattr == PVMI_KVPATTR_CUR) || (reqattr == PVMI_KVPATTR_DEF))
{
aParameters[0].value.pWChar_value = NULL;
/* As of now just RTSP node supports an external config of user agent */
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
OSCL_wHeapString<OsclMemAllocator> userAgent;
if (rtspExtIntf->GetUserAgent(userAgent) == PVMFSuccess)
{
// Return current value
oscl_wchar* ptr = (oscl_wchar*)oscl_malloc(sizeof(oscl_wchar) * (userAgent.get_size()));
if (ptr)
{
oscl_memcpy(ptr, userAgent.get_cstr(), userAgent.get_size());
aParameters[0].value.pWChar_value = ptr;
}
else
{
oscl_free(aParameters[0].key);
oscl_free(aParameters);
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::GetConfigParameter() "
"Memory allocation for user agent failed"));
return PVMFErrNoMemory;
}
}
}
}
else
{
// Return capability - no concept of capability for user agent
// do nothing
}
break;
case BASEKEY_SESSION_CONTROLLER_KEEP_ALIVE_INTERVAL:
case BASEKEY_SESSION_CONTROLLER_KEEP_ALIVE_DURING_PLAY:
if ((reqattr == PVMI_KVPATTR_CUR) || (reqattr == PVMI_KVPATTR_DEF))
{
if (aIndex == BASEKEY_SESSION_CONTROLLER_KEEP_ALIVE_INTERVAL)
{
aParameters[0].value.uint32_value = PVRTSPENGINENODE_DEFAULT_KEEP_ALIVE_INTERVAL;
}
else
{
aParameters[0].value.bool_value = false;
}
/* As of now just RTSP node supports an external config of user agent */
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
uint32 timeout;
bool okeepalivemethod;
bool okeepaliveinplay;
rtspExtIntf->GetKeepAliveMethod((int32&)timeout, okeepalivemethod, okeepaliveinplay);
if (aIndex == BASEKEY_SESSION_CONTROLLER_KEEP_ALIVE_INTERVAL)
{
aParameters[0].value.uint32_value = timeout;
}
else
{
aParameters[0].value.bool_value = okeepaliveinplay;
}
}
}
else
{
// Return capability - no concept of capability for keep alive interval
// do nothing
}
break;
case BASEKEY_STREAMING_MGR_SWITCH_STREAMS:
/* Do nothing - things like current, default, and capability do not make sense here */
break;
case BASEKEY_STREAMING_SPEED:
{
if ((reqattr == PVMI_KVPATTR_CUR) || (reqattr == PVMI_KVPATTR_DEF))
{
{
aParameters[0].value.uint32_value = 1;
}
}
else
{
// Return capability - no concept of capability for streaming speed
// do nothing
}
}
break;
case BASEKEY_HTTP_VERSION:
{
if ((reqattr == PVMI_KVPATTR_CUR) || (reqattr == PVMI_KVPATTR_DEF))
{
{
oscl_free(aParameters[0].key);
oscl_free(aParameters);
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::GetConfigParameter - HTTP Version Not Supported"));
return PVMFErrArgument;
}
}
else
{
// Return capability - no concept of capability for http version
// do nothing
}
}
break;
case BASEKEY_NUM_REDIRECT_ATTEMPTS:
{
if ((reqattr == PVMI_KVPATTR_CUR) || (reqattr == PVMI_KVPATTR_DEF))
{
{
//seems like there is no reasonable default here ??
aParameters[0].value.uint32_value = 0;
}
}
else
{
// Return capability - no concept of capability for num redirect attempts
// do nothing
}
}
break;
case BASEKEY_PROTOCOL_EXTENSION_HEADER:
/* Do nothing - things like current, default, and capability do not make sense here */
break;
case BASEKEY_SESSION_CONTROLLER_HTTP_TIMEOUT:
break;
case BASEKEY_SESSION_CONTROLLER_HTTP_STREAMING_LOGGING_TIMEOUT:
break;
case BASEKEY_ACCEL_BITRATE:
/* Do nothing - things like current, default, and capability do not make sense here */
break;
case BASEKEY_ACCEL_DURATION:
/* Do nothing - things like current, default, and capability do not make sense here */
break;
case BASEKEY_MAX_TCP_RECV_BUFFER_SIZE:
{
if (IsHttpExtensionHeaderValid(aParameters[0]))
{
PVMFSMNodeContainer* iSocketNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_SOCKET_NODE);
if (iSocketNodeContainer != NULL)
{
PVMFSocketNode* socketNode =
(PVMFSocketNode*)(iSocketNodeContainer->iNode);
if ((reqattr == PVMI_KVPATTR_CUR) || (reqattr == PVMI_KVPATTR_DEF))
{
uint32 size = 0;
socketNode->GetMaxTCPRecvBufferSize(size);
aParameters[0].value.uint32_value = size;
}
}
}
}
break;
case BASEKEY_DISABLE_FIREWALL_PACKETS:
{
if ((reqattr == PVMI_KVPATTR_CUR) || (reqattr == PVMI_KVPATTR_DEF))
{
aParameters[0].value.bool_value = false;
}
}
break;
default:
// Invalid index
oscl_free(aParameters[0].key);
oscl_free(aParameters);
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVPlayerEngine::DoGetPlayerParameter() Invalid index to player parameter"));
return PVMFErrArgument;
}
aNumParamElements = 1;
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVPlayerEngine::DoGetPlayerParameter() Out"));
return PVMFSuccess;
}
PVMFStatus PVMFStreamingManagerNode::VerifyAndSetConfigParameter(int index, PvmiKvp& aParameter, bool set)
{
PVMF_SM_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::VerifyAndSetConfigParameter() In"));
// Determine the valtype
PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::VerifyAndSetConfigParameter() "
"Valtype in key string unknown"));
return PVMFErrArgument;
}
// Verify the valtype
if (keyvaltype != StreamingManagerConfig_BaseKeys[index].iValueType)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::VerifyAndSetConfigParameter() "
"Valtype does not match for key"));
return PVMFErrArgument;
}
switch (index)
{
case BASEKEY_DELAY:
{
// Validate
if ((aParameter.value.uint32_value < MIN_JITTER_BUFFER_DURATION_IN_MS) ||
(aParameter.value.uint32_value > MAX_JITTER_BUFFER_DURATION_IN_MS))
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::VerifyAndSetConfigParameter() "
"Trying to set delay to 0"));
return PVMFErrArgument;
}
if (set)
{
// save value locally
setJitterBufferDurationInMilliSeconds(aParameter.value.uint32_value);
// pass the value on to the jitter buffer node
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->setJitterBufferDurationInMilliSeconds(aParameter.value.uint32_value);
}
}
break;
case BASEKEY_REBUFFERING_THRESHOLD:
{
uint32 jbDuration = 0;
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->getJitterBufferDurationInMilliSeconds(jbDuration);
// Validate
if (aParameter.value.uint32_value >= jbDuration)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::VerifyAndSetConfigParameter() "
"Trying to set rebuffering threshold greater than equal to jitter buffer duration"));
return PVMFErrArgument;
}
if (set)
{
// pass the value on to the jitter buffer node
jbExtIntf->setJitterBufferRebufferingThresholdInMilliSeconds(aParameter.value.uint32_value);
}
}
break;
case BASEKEY_JITTERBUFFER_NUMRESIZE:
{
if (set)
{
// retrieve and update
uint32 numResize, resizeSize;
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->GetSharedBufferResizeParams(numResize, resizeSize);
jbExtIntf->SetSharedBufferResizeParams(aParameter.value.uint32_value, resizeSize);
}
}
break;
case BASEKEY_JITTERBUFFER_RESIZESIZE:
{
if (set)
{
// retrieve and update
uint32 numResize, resizeSize;
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->GetSharedBufferResizeParams(numResize, resizeSize);
jbExtIntf->SetSharedBufferResizeParams(numResize, aParameter.value.uint32_value);
}
}
break;
case BASEKEY_SESSION_CONTROLLER_USER_AGENT:
{
if (set)
{
// user agent update
PVMFSMNodeContainer* iSessionControllerNodeContainer = NULL;
iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
OSCL_wHeapString<OsclMemAllocator> userAgent;
OSCL_wHeapString<OsclMemAllocator> dummy;
userAgent = aParameter.value.pWChar_value;
rtspExtIntf->SetClientParameters(userAgent, dummy, dummy);
}
iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE);
OSCL_wHeapString<OsclMemAllocator> userAgent = aParameter.value.pWChar_value;
if (iSessionControllerNodeContainer != NULL)
{
PVMFProtocolEngineNodeMSHTTPStreamingExtensionInterface* httpExtIntf =
(PVMFProtocolEngineNodeMSHTTPStreamingExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
httpExtIntf->SetUserAgent(userAgent);
}
// save user-agent kvp for cpm
if (iCPM)
{
PVMFStatus status = iCPMKvpStore.addKVPString(aParameter.key, userAgent);
if (status != PVMFSuccess) return status;
}
}
}
break;
case BASEKEY_HTTP_VERSION:
{
if (set)
{
PVMFSMNodeContainer* iSessionControllerNodeContainer = NULL;
iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
PVMF_SM_LOGERROR((0, "PVMFStreamingManagerNode::VerifyAndSetConfigParameter() "
"Setting HTTP Protocol Version Not supported"));
return PVMFErrNotSupported;
}
}
}
break;
case BASEKEY_NUM_REDIRECT_ATTEMPTS:
{
if (set)
{
if (IsHttpExtensionHeaderValid(aParameter))
{
PVMFSMNodeContainer* iSessionControllerNodeContainer = NULL;
iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
//do nothing for now - till RTSP node has an api to set this
}
iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
PVMFProtocolEngineNodeMSHTTPStreamingExtensionInterface* httpExtIntf =
(PVMFProtocolEngineNodeMSHTTPStreamingExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
httpExtIntf->SetNumRedirectTrials(aParameter.value.uint32_value);
}
}
else
{
OSCL_StackString<32> dlamode(_STRLIT_CHAR("mode=dla"));
bool isDlaMode = (oscl_strstr(OSCL_CONST_CAST(char*, aParameter.key), dlamode.get_cstr()) != NULL);
if (isDlaMode)
{
if (iCPM)
{
PVMFStatus status = iCPMKvpStore.addKVPuint32Value(aParameter.key, aParameter.value.uint32_value);
if (status != PVMFSuccess)
return status;
}
}
}
}
}
break;
case BASEKEY_SESSION_CONTROLLER_KEEP_ALIVE_INTERVAL:
{
if (set)
{
// user agent update
/* As of now just RTSP node supports an external config of user agent */
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
rtspExtIntf->SetKeepAliveMethod_timeout(aParameter.value.uint32_value);
}
iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_HTTP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
PVMFProtocolEngineNodeMSHTTPStreamingExtensionInterface* httpExtIntf =
(PVMFProtocolEngineNodeMSHTTPStreamingExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
httpExtIntf->SetKeepAliveTimeout(aParameter.value.uint32_value);
}
}
}
break;
case BASEKEY_SESSION_CONTROLLER_KEEP_ALIVE_DURING_PLAY:
{
if (set)
{
// keep-alive during play update
/* As of now just RTSP node supports an external config of keep-alive during play */
PVMFSMNodeContainer* iSessionControllerNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_RTSP_SESSION_CONTROLLER_NODE);
if (iSessionControllerNodeContainer != NULL)
{
PVRTSPEngineNodeExtensionInterface* rtspExtIntf =
(PVRTSPEngineNodeExtensionInterface*)
(iSessionControllerNodeContainer->iExtensions[0]);
rtspExtIntf->SetKeepAliveMethod_keep_alive_in_play(aParameter.value.bool_value);
}
}
}
break;
case BASEKEY_MAX_TCP_RECV_BUFFER_SIZE:
{
if (IsHttpExtensionHeaderValid(aParameter))
{
if (set)
{
PVMFSMNodeContainer* iSocketNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_SOCKET_NODE);
if (iSocketNodeContainer != NULL)
{
PVMFSocketNode* socketNode =
(PVMFSocketNode*)(iSocketNodeContainer->iNode);
socketNode->SetMaxTCPRecvBufferSize(aParameter.value.uint32_value);
}
}
}
}
break;
case BASEKEY_DISABLE_FIREWALL_PACKETS:
{
if (set)
{
PVMFSMNodeContainer* iJitterBufferNodeContainer =
getNodeContainer(PVMF_STREAMING_MANAGER_JITTER_BUFFER_NODE);
PVMFJitterBufferExtensionInterface* jbExtIntf =
(PVMFJitterBufferExtensionInterface*)iJitterBufferNodeContainer->iExtensions[0];
jbExtIntf->DisableFireWallPackets();
}
}
break;
default:
return PVMFErrNotSupported;
}
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFStreamingManagerNode::VerifyAndSetPlayerParameter() Out"));
return PVMFSuccess;
}
// remove the ending ';', ',' or ' ' and calulate value length
uint32 PVMFStreamingManagerNode::getItemLen(char *ptrItemStart, char *ptrItemEnd)
{
char *ptr = ptrItemEnd - 1;
uint32 itemLen = ptr - ptrItemStart;
for (uint32 i = 0; i < itemLen; i++)
{
if (*ptr == ';' || *ptr == ',' || *ptr == ' ') --ptr;
else break;
}
itemLen = ptr - ptrItemStart + 1;
return itemLen;
}
bool PVMFStreamingManagerNode::IsInternalCmd(PVMFCommandId aId)
{
if ((aId == PVMF_STREAMING_MANAGER_NODE_CONSTRUCT_SESSION) ||
(aId == PVMF_STREAMING_MANAGER_NODE_AUTO_PAUSE) ||
(aId == PVMF_STREAMING_MANAGER_NODE_AUTO_RESUME) ||
(aId == PVMF_STREAMING_MANAGER_NODE_THIN_STREAM))
{
return true;
}
return false;
}
bool PVMFStreamingManagerNode::IsHttpExtensionHeaderValid(PvmiKvp &aParameter)
{
OSCL_StackString<32> downloadMode(_STRLIT_CHAR("mode=download"));
OSCL_StackString<32> streamingMode(_STRLIT_CHAR("mode=streaming"));
OSCL_StackString<32> dlaMode(_STRLIT_CHAR("mode=dla"));
bool isDownloadMode = (oscl_strstr(OSCL_CONST_CAST(char*, aParameter.key), downloadMode.get_cstr()) != NULL);
bool isStreamingMode = (oscl_strstr(OSCL_CONST_CAST(char*, aParameter.key), streamingMode.get_cstr()) != NULL);
bool isDlaMode = (oscl_strstr(OSCL_CONST_CAST(char*, aParameter.key), dlaMode.get_cstr()) != NULL);
// download mode only would fail, streaming mode specified or not specified will be viewed as true
if (isDownloadMode && !isStreamingMode) return false;
// dla mode only would fail, streaming mode specified or not specified will be viewed as true
if (isDlaMode && !isStreamingMode) return false;
return true;
}
PVMFStatus
PVMFStreamingManagerNode::GetMaxSizeValue(char* aString, uint32& aMaxSize)
{
aMaxSize = 0xFFFFFFFF;
/*
* This parses a string of the form "maxsize=N1" and extracts the integer N1.
*/
if (aString == NULL)
{
return PVMFErrArgument;
}
/* Go to end of "maxsize=" */
char* n1string = aString + 8;
char* truncatestr = oscl_strstr(n1string, PVMFSTREAMINGMGRNODE_TRUNCATE_FLAG);
uint32 maxsizelen = 0;
if (truncatestr != NULL)
{
maxsizelen = oscl_strlen(n1string) - (oscl_strlen(truncatestr) + 1);
n1string[maxsizelen] = '\0';
}
if (PV_atoi(n1string, 'd', oscl_strlen(n1string), aMaxSize))
{
return PVMFSuccess;
}
return PVMFFailure;
}
PVMFStatus
PVMFStreamingManagerNode::GetTruncateFlagValue(char* aString, uint32& aTruncateFlag)
{
aTruncateFlag = 0;
/*
* This parses a string of the form "truncate=N1" and extracts the integer N1.
*/
if (aString == NULL)
{
return PVMFErrArgument;
}
/* Go to end of "truncate=" */
char* n1string = aString + 9;
if (!oscl_strcmp(n1string, "true"))
{
aTruncateFlag = true;
}
else if (!oscl_strcmp(n1string, "false"))
{
aTruncateFlag = false;
}
else
{
return PVMFFailure;
}
return PVMFSuccess;
}
void
PVMFStreamingManagerNode::ResetNodeContainerCmdState()
{
for (uint32 i = 0; i < iNodeContainerVec.size(); i++)
{
if (iNodeContainerVec[i].iNodeCmdState == PVMFSM_NODE_CMD_COMPLETE)
{
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_NO_PENDING;
}
else if (iNodeContainerVec[i].iNodeCmdState == PVMFSM_NODE_CMD_CANCEL_PENDING)
{
iNodeContainerVec[i].iNodeCmdState = PVMFSM_NODE_CMD_CANCEL_COMPLETE;
}
}
}
//////////////////// PVMFSMNodeKVPStore Implementation /////////////////////////////////////////////////////////
// add kvp string with W-string value
PVMFStatus PVMFSMNodeKVPStore::addKVPString(const char* aKeyTypeString, OSCL_wString& aValString)
{
PvmiKvp aKeyVal;
aKeyVal.key = NULL;
PVMFStatus status = PVMFCreateKVPUtils::CreateKVPForWStringValue(aKeyVal, aKeyTypeString, aValString);
if (status != PVMFSuccess) return status;
int32 err = 0;
OSCL_TRY(err,
iKvpVector.push_back(aKeyVal);
KVPValueTypeForMemoryRelease valType = KVPValueTypeForMemoryRelease_WString;
iKVPValueTypeForMemoryRelease.push_back((uint32)valType);
);
return (err == 0 ? PVMFSuccess : PVMFErrNoMemory);
}
// add kvp string with normal string value
PVMFStatus PVMFSMNodeKVPStore::addKVPString(const char* aKeyTypeString, const char* aValString)
{
PvmiKvp aKeyVal;
aKeyVal.key = NULL;
PVMFStatus status = PVMFCreateKVPUtils::CreateKVPForCharStringValue(aKeyVal, aKeyTypeString, aValString);
if (status != PVMFSuccess) return status;
int32 err = 0;
OSCL_TRY(err,
iKvpVector.push_back(aKeyVal);
KVPValueTypeForMemoryRelease valType = KVPValueTypeForMemoryRelease_String;
iKVPValueTypeForMemoryRelease.push_back((uint32)valType);
);
return (err == 0 ? PVMFSuccess : PVMFErrNoMemory);
}
void PVMFSMNodeKVPStore::releaseMemory()
{
OSCL_ASSERT(iKvpVector.size() == iKVPValueTypeForMemoryRelease.size());
for (uint32 i = 0; i < iKvpVector.size(); i++)
{
if (iKvpVector[i].key) OSCL_ARRAY_DELETE(iKvpVector[i].key);
// release memory for appropriate types of KVP value
if ((KVPValueTypeForMemoryRelease)iKVPValueTypeForMemoryRelease[i] == KVPValueTypeForMemoryRelease_WString &&
iKvpVector[i].value.pWChar_value) OSCL_ARRAY_DELETE(iKvpVector[i].value.pWChar_value);
if ((KVPValueTypeForMemoryRelease)iKVPValueTypeForMemoryRelease[i] == KVPValueTypeForMemoryRelease_String &&
iKvpVector[i].value.pChar_value) OSCL_ARRAY_DELETE(iKvpVector[i].value.pChar_value);
}
}
PVMFStatus PVMFSMNodeKVPStore::addKVPuint32Value(const char* aKeyTypeString, uint32 aValue)
{
PvmiKvp aKeyVal;
aKeyVal.key = NULL;
PVMFStatus status = PVMFCreateKVPUtils::CreateKVPForUInt32Value(aKeyVal, aKeyTypeString, aValue);
if (status != PVMFSuccess) return status;
int32 err = 0;
OSCL_TRY(err,
iKvpVector.push_back(aKeyVal);
KVPValueTypeForMemoryRelease valType = KVPValueTypeForMemoryRelease_NoInterest;
iKVPValueTypeForMemoryRelease.push_back((uint32)valType);
);
return (err == 0 ? PVMFSuccess : PVMFErrNoMemory);
}
//Check for RTP packet source
bool
PVMFStreamingManagerNode::IsRTPPacketSourcePresent()
{
return false;
}