1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /** 19 * @file pvmi_io_interface_node.h 20 * @brief 21 */ 22 23 #ifndef PV_MEDIA_OUTPUT_NODE_H_INCLUDED 24 #define PV_MEDIA_OUTPUT_NODE_H_INCLUDED 25 26 #ifndef OSCL_BASE_H_INCLUDED 27 #include "oscl_base.h" 28 #endif 29 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED 30 #include "oscl_scheduler_ao.h" 31 #endif 32 #ifndef OSCL_PRIQUEUE_H_INCLUDED 33 #include "oscl_priqueue.h" 34 #endif 35 #ifndef PVLOGGER_H_INCLUDED 36 #include "pvlogger.h" 37 #endif 38 #ifndef PVMF_RETURN_CODES_H_INCLUDED 39 #include "pvmf_return_codes.h" 40 #endif 41 #ifndef PVMF_NODE_INTERFACE_H_INCLUDED 42 #include "pvmf_node_interface.h" 43 #endif 44 #ifndef PVMF_NODE_UTILS_H_INCLUDED 45 #include "pvmf_node_utils.h" 46 #endif 47 #ifndef PVMF_PORT_INTERFACE_H_INCLUDED 48 #include "pvmf_port_interface.h" 49 #endif 50 #ifndef PVMI_MIO_CONTROL_H_INCLUDED 51 #include "pvmi_mio_control.h" 52 #endif 53 #ifndef PVMI_MEDIA_IO_OBSERVER_H_INCLUDED 54 #include "pvmi_media_io_observer.h" 55 #endif 56 #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED 57 #include "pvmi_config_and_capability.h" 58 #endif 59 #ifndef PVMF_NODES_SYNC_CONTROL_H_INCLUDED 60 #include "pvmf_nodes_sync_control.h" 61 #endif 62 #ifndef PV_MEDIA_OUTPUT_NODE_INPORT_H_INCLUDED 63 #include "pv_media_output_node_inport.h" 64 #endif 65 #ifndef PV_MEDIA_OUTPUT_NODE_EVENTS_H_INCLUDED 66 #include "pv_media_output_node_events.h" 67 #endif 68 #ifndef PVMI_MEDIA_IO_CLOCK_EXTENSION_H_INCLUDED 69 #include "pvmi_media_io_clock_extension.h" 70 #endif 71 72 /** Port tags. For now engine must use these directly since 73 * port tag query is not yet implemented 74 */ 75 enum PVMediaOutputNodePortTags 76 { 77 PVMF_MEDIAIO_NODE_INPUT_PORT_TAG = 0 78 }; 79 80 81 /** 82 * Command queue for internal use in the node 83 */ 84 85 //command type enums. This node has one extra async command. 86 enum PVMediaOutputNodeCmdType 87 { 88 PVMF_MEDIAOUTPUTNODE_SKIPMEDIADATA = PVMF_GENERIC_NODE_COMMAND_LAST 89 }; 90 91 //command class 92 class PVMediaOutputNodeCmd: public PVMFGenericNodeCommand<OsclMemAllocator> 93 { 94 public: 95 //for SkipMediaData Construct(PVMFSessionId s,int32 aCmd,PVMFTimestamp aResumeTimestamp,uint32 aStreamID,bool aPlayBackPositionContinuous,const OsclAny * aContext)96 void Construct(PVMFSessionId s, int32 aCmd 97 , PVMFTimestamp aResumeTimestamp 98 , uint32 aStreamID 99 , bool aPlayBackPositionContinuous 100 , const OsclAny* aContext) 101 { 102 iSession = s; 103 iCmd = aCmd; 104 iContext = aContext; 105 iParam1 = (OsclAny*)aResumeTimestamp; 106 iParam2 = (OsclAny*)aPlayBackPositionContinuous; 107 iParam3 = (OsclAny*)aStreamID; 108 iEventCode = PVMFMoutNodeErr_First; 109 } Parse(PVMFTimestamp & aResumeTimestamp,bool & aPlayBackPositionContinuous,uint32 & aStreamID)110 void Parse(PVMFTimestamp& aResumeTimestamp 111 , bool& aPlayBackPositionContinuous 112 , uint32& aStreamID) 113 { 114 aResumeTimestamp = (PVMFTimestamp)iParam1; 115 aPlayBackPositionContinuous = (iParam2) ? true : false; 116 aStreamID = (uint32)iParam3; 117 } 118 //this holds an event code associated with the command status 119 PVMFStatus iEventCode; 120 121 //need to override base construct routine due to additional parameter. BaseConstruct(PVMFSessionId s,int32 aCmd,const OsclAny * aContext)122 void BaseConstruct(PVMFSessionId s, int32 aCmd, const OsclAny* aContext) 123 { 124 PVMFGenericNodeCommand<OsclMemAllocator>::BaseConstruct(s, aCmd, aContext); 125 iEventCode = PVMFMoutNodeErr_First; 126 } 127 //need to override base copy routine due to additional parameter Copy(PVMediaOutputNodeCmd & aCmd)128 void Copy(PVMediaOutputNodeCmd& aCmd) 129 { 130 PVMFGenericNodeCommand<OsclMemAllocator>::Copy(aCmd); 131 iEventCode = aCmd.iEventCode; 132 } caninterrupt()133 bool caninterrupt() 134 { //this routine identifies commands that can interrupt current command. 135 return (iCmd == PVMF_GENERIC_NODE_CANCELALLCOMMANDS 136 || iCmd == PVMF_GENERIC_NODE_CANCELCOMMAND); 137 } 138 139 }; 140 //define a synonym for the base class. 141 //a typedef creates compiler warnings so use #define 142 #define PVMediaOutputNodeCmdBase PVMFGenericNodeCommand<OsclMemAllocator> 143 144 //command queue type 145 typedef PVMFNodeCommandQueue<PVMediaOutputNodeCmd, OsclMemAllocator> PVMediaOutputNodeCmdQ; 146 147 148 /** 149 * class PVMediaOutputNode is a node wrapper around the io interface 150 */ 151 class PVMediaOutputNode : public OsclActiveObject, 152 public PVMFNodeInterface, 153 public PvmiMIOObserver, 154 public PvmfNodesSyncControlInterface, 155 public PvmiCapabilityAndConfig 156 { 157 public: 158 static PVMFNodeInterface* Create(PvmiMIOControl* aIOInterfacePtr); 159 static void Release(PVMFNodeInterface*); 160 161 ~PVMediaOutputNode(); 162 // PVMFNodeInterface implementation 163 OSCL_IMPORT_REF PVMFStatus ThreadLogon(); 164 OSCL_IMPORT_REF PVMFStatus ThreadLogoff(); 165 OSCL_IMPORT_REF PVMFStatus GetCapability(PVMFNodeCapability& aNodeCapability); 166 OSCL_IMPORT_REF PVMFPortIter* GetPorts(const PVMFPortFilter* aFilter = NULL); 167 OSCL_IMPORT_REF PVMFCommandId QueryUUID(PVMFSessionId aSession 168 , const PvmfMimeString& aMimeType 169 , Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids 170 , bool aExactUuidsOnly = false 171 , const OsclAny* aContext = NULL) ; 172 OSCL_IMPORT_REF PVMFCommandId QueryInterface(PVMFSessionId aSession 173 , const PVUuid& aUuid 174 , PVInterface*& aInterfacePtr 175 , const OsclAny* aContext = NULL) ; 176 OSCL_IMPORT_REF PVMFCommandId RequestPort(PVMFSessionId aSession 177 , int32 aPortTag 178 , const PvmfMimeString* aPortConfig = NULL 179 , const OsclAny* aContext = NULL); 180 OSCL_IMPORT_REF PVMFCommandId ReleasePort(PVMFSessionId aSession 181 , PVMFPortInterface& aPort 182 , const OsclAny* aContext = NULL); 183 OSCL_IMPORT_REF PVMFCommandId Init(PVMFSessionId aSession 184 , const OsclAny* aContext = NULL); 185 OSCL_IMPORT_REF PVMFCommandId Prepare(PVMFSessionId aSession 186 , const OsclAny* aContext = NULL); 187 OSCL_IMPORT_REF PVMFCommandId Start(PVMFSessionId aSession 188 , const OsclAny* aContext = NULL); 189 OSCL_IMPORT_REF PVMFCommandId Stop(PVMFSessionId aSession 190 , const OsclAny* aContext = NULL); 191 OSCL_IMPORT_REF PVMFCommandId Flush(PVMFSessionId aSession 192 , const OsclAny* aContext = NULL); 193 OSCL_IMPORT_REF PVMFCommandId Pause(PVMFSessionId aSession 194 , const OsclAny* aContext = NULL); 195 OSCL_IMPORT_REF PVMFCommandId Reset(PVMFSessionId aSession 196 , const OsclAny* aContext = NULL); 197 OSCL_IMPORT_REF PVMFCommandId CancelAllCommands(PVMFSessionId aSession 198 , const OsclAny* aContextData = NULL) ; 199 OSCL_IMPORT_REF PVMFCommandId CancelCommand(PVMFSessionId aSession 200 , PVMFCommandId aCmdId 201 , const OsclAny* aContextData = NULL) ; HandlePortActivity(const PVMFPortActivity & aActivity)202 void HandlePortActivity(const PVMFPortActivity& aActivity) 203 { 204 OSCL_UNUSED_ARG(aActivity); 205 } 206 207 // Pure virtual from PvInterface 208 OSCL_IMPORT_REF void addRef(); 209 OSCL_IMPORT_REF void removeRef(); 210 OSCL_IMPORT_REF bool queryInterface(const PVUuid& uuid, PVInterface*& iface); 211 212 // Pure virtuals from PvmfNodesSyncControlInterface 213 OSCL_IMPORT_REF PVMFStatus SetClock(PVMFMediaClock* aClock); 214 OSCL_IMPORT_REF PVMFStatus ChangeClockRate(int32 aRate); 215 OSCL_IMPORT_REF PVMFStatus SetMargins(int32 aEarlyMargin, int32 aLateMargin); 216 OSCL_IMPORT_REF void ClockStarted(void); 217 OSCL_IMPORT_REF void ClockStopped(void); 218 OSCL_IMPORT_REF PVMFCommandId SkipMediaData(PVMFSessionId aSession, 219 PVMFTimestamp aResumeTimestamp, 220 uint32 aStreamID = 0, 221 bool aPlayBackPositionContinuous = false, 222 OsclAny* aContext = NULL); 223 224 // PvmiMIOObserver implementation 225 OSCL_IMPORT_REF void RequestCompleted(const PVMFCmdResp& aResponse); 226 OSCL_IMPORT_REF void ReportErrorEvent(PVMFEventType aEventType, PVInterface* aExtMsg = NULL); 227 OSCL_IMPORT_REF void ReportInfoEvent(PVMFEventType aEventType, PVInterface* aExtMsg = NULL); 228 229 IsMioRequestPending()230 bool IsMioRequestPending() 231 { 232 return (iMediaIORequest != ENone); 233 }; 234 235 // From PvmiCapabilityAndConfig 236 // Implement pure virtuals from PvmiCapabilityAndConfig interface 237 OSCL_IMPORT_REF virtual PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements); 238 OSCL_IMPORT_REF virtual PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext); 239 OSCL_IMPORT_REF virtual PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements); 240 241 // Unsupported PvmiCapabilityAndConfig methods setObserver(PvmiConfigAndCapabilityCmdObserver * aObserver)242 void virtual setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver) 243 { 244 OSCL_UNUSED_ARG(aObserver); 245 }; createContext(PvmiMIOSession aSession,PvmiCapabilityContext & aContext)246 void virtual createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext) 247 { 248 OSCL_UNUSED_ARG(aSession); 249 OSCL_UNUSED_ARG(aContext); 250 }; setContextParameters(PvmiMIOSession aSession,PvmiCapabilityContext & aContext,PvmiKvp * aParameters,int aNumParamElements)251 void virtual setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, PvmiKvp* aParameters, int aNumParamElements) 252 { 253 OSCL_UNUSED_ARG(aSession); 254 OSCL_UNUSED_ARG(aContext); 255 OSCL_UNUSED_ARG(aParameters); 256 OSCL_UNUSED_ARG(aNumParamElements); 257 }; DeleteContext(PvmiMIOSession aSession,PvmiCapabilityContext & aContext)258 void virtual DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext) 259 { 260 OSCL_UNUSED_ARG(aSession); 261 OSCL_UNUSED_ARG(aContext); 262 }; setParametersSync(PvmiMIOSession aSession,PvmiKvp * aParameters,int aNumElements,PvmiKvp * & aRetKVP)263 void virtual setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP) 264 { 265 OSCL_UNUSED_ARG(aSession); 266 OSCL_UNUSED_ARG(aParameters); 267 OSCL_UNUSED_ARG(aNumElements); 268 OSCL_UNUSED_ARG(aRetKVP); 269 }; 270 PVMFCommandId virtual setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP, OsclAny* aContext = NULL) 271 { 272 OSCL_UNUSED_ARG(aSession); 273 OSCL_UNUSED_ARG(aParameters); 274 OSCL_UNUSED_ARG(aNumElements); 275 OSCL_UNUSED_ARG(aRetKVP); 276 OSCL_UNUSED_ARG(aContext); 277 return -1; 278 } getCapabilityMetric(PvmiMIOSession aSession)279 uint32 virtual getCapabilityMetric(PvmiMIOSession aSession) 280 { 281 OSCL_UNUSED_ARG(aSession); 282 return 0; 283 }; 284 getClockRate()285 uint32 getClockRate() 286 { 287 return iClockRate; 288 }; 289 290 void ReportBOS(); 291 292 private: 293 friend class PVMediaOutputNodePort; 294 friend class PVMediaOutputNodeFactory; 295 296 PVMediaOutputNode(); 297 298 void ConstructL(PvmiMIOControl* aIOInterfacePtr); 299 300 //from OsclActiveObject 301 void Run(); 302 303 //Command processing 304 PVMFCommandId QueueCommandL(PVMediaOutputNodeCmd&); 305 void ProcessCommand(); 306 void CommandComplete(PVMediaOutputNodeCmdQ& aCmdQ, PVMediaOutputNodeCmd& aCmd, PVMFStatus aStatus, OsclAny*aEventData = NULL); 307 PVMediaOutputNodeCmdQ iInputCommands; 308 PVMediaOutputNodeCmdQ iCurrentCommand; 309 PVMediaOutputNodeCmdQ iCancelCommand; 310 311 //generic node Command handlers. 312 PVMFStatus DoReset(PVMediaOutputNodeCmd&); 313 PVMFStatus DoQueryUuid(PVMediaOutputNodeCmd&); 314 PVMFStatus DoQueryInterface(PVMediaOutputNodeCmd&); 315 PVMFStatus DoRequestPort(PVMediaOutputNodeCmd&, OsclAny*&); 316 PVMFStatus DoReleasePort(PVMediaOutputNodeCmd&); 317 PVMFStatus DoInit(PVMediaOutputNodeCmd&); 318 PVMFStatus DoPrepare(PVMediaOutputNodeCmd&); 319 PVMFStatus DoStart(PVMediaOutputNodeCmd&); 320 PVMFStatus DoStop(PVMediaOutputNodeCmd&); 321 PVMFStatus DoFlush(PVMediaOutputNodeCmd&); 322 PVMFStatus DoPause(PVMediaOutputNodeCmd&); 323 PVMFStatus DoCancelAllCommands(PVMediaOutputNodeCmd&); 324 PVMFStatus DoCancelCommand(PVMediaOutputNodeCmd&); 325 //extra command handlers. 326 PVMFStatus DoSkipMediaData(PVMediaOutputNodeCmd&); 327 void CompleteSkipMediaData(); 328 329 // Event reporting 330 PVUuid iEventUuid; 331 void ReportErrorEvent(PVMFEventType aEventType, OsclAny* aEventData = NULL, PVMFStatus aEventCode = PVMFMoutNodeErr_First); ReportErrorEvent(PVMFAsyncEvent & aEvent)332 void ReportErrorEvent(PVMFAsyncEvent& aEvent) 333 { 334 PVMFNodeInterface::ReportErrorEvent(aEvent); 335 } 336 void ReportInfoEvent(PVMFEventType aEventType, OsclAny* aEventData = NULL, PVMFStatus aEventCode = PVMFMoutNodeErr_First); ReportInfoEvent(PVMFAsyncEvent & aEvent)337 void ReportInfoEvent(PVMFAsyncEvent& aEvent) 338 { 339 PVMFNodeInterface::ReportInfoEvent(aEvent); 340 } 341 void SetState(TPVMFNodeInterfaceState); 342 343 //node capability. 344 PVMFNodeCapability iCapability; 345 346 // Media IO control 347 PvmiMIOControl* iMIOControl; 348 PvmiMIOSession iMIOSession; 349 PvmiCapabilityAndConfig* iMIOConfig; 350 PVInterface* iMIOConfigPVI; 351 enum EMioRequest 352 { 353 ENone 354 , EQueryCapability 355 , EQueryClockExtension 356 , EInit 357 , EStart 358 , EPause 359 , EStop 360 , EDiscard 361 , EReset 362 } ; 363 EMioRequest iMediaIORequest; 364 enum MioStates 365 { 366 STATE_IDLE 367 , STATE_LOGGED_ON 368 , STATE_INITIALIZED 369 , STATE_STARTED 370 , STATE_PAUSED 371 }; 372 MioStates iMediaIOState; 373 PVMFCommandId iMediaIOCmdId; 374 PVMFCommandId iMediaIOCancelCmdId; 375 bool iMediaIOCancelPending; 376 PVMFStatus SendMioRequest(PVMediaOutputNodeCmd& aCmd, EMioRequest); 377 PVMFStatus CancelMioRequest(PVMediaOutputNodeCmd& aCmd); 378 379 // Ports 380 PVMFPortVector<PVMediaOutputNodePort, OsclMemAllocator> iInPortVector; 381 bool PortQueuesEmpty(); 382 383 // Variables for media data queue and synchronization 384 PVMFMediaClock* iClock; 385 int32 iEarlyMargin; 386 int32 iLateMargin; 387 int32 iClockRate; 388 PvmiClockExtensionInterface* iMIOClockExtension; 389 PVInterface* iMIOClockExtensionPVI; 390 391 /* Diagnostic log related */ 392 PVLogger* iDiagnosticsLogger; 393 bool iDiagnosticsLogged; 394 void LogDiagnostics(); 395 396 // Extension reference counter 397 uint32 iExtensionRefCount; 398 399 // Counter for number of callbacks for skip media data completion 400 bool SkipMediaDataComplete(); 401 402 //logger 403 PVLogger* iLogger; 404 PVLogger* iReposLogger; 405 406 OSCL_HeapString<OsclMemAllocator> iSinkFormatString; 407 408 uint32 iRecentBOSStreamID; 409 PVMFStatus CheckForBOS(); 410 }; 411 412 413 #endif // PVMI_IO_INTERFACE_NODE_H_INCLUDED 414 415 416 417 418 419