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 * 20 * @file pvmi_io_interface_node_inport.h 21 * @brief Input port for media io interface wrapper node 22 * 23 */ 24 25 #ifndef PV_MEDIA_OUTPUT_NODE_INPORT_H_INCLUDED 26 #define PV_MEDIA_OUTPUT_NODE_INPORT_H_INCLUDED 27 28 #ifndef OSCL_BASE_H_INCLUDED 29 #include "oscl_base.h" 30 #endif 31 #ifndef OSCL_VECTOR_H_INCLUDED 32 #include "oscl_vector.h" 33 #endif 34 #ifndef OSCL_MEM_H_INCLUDED 35 #include "oscl_mem.h" 36 #endif 37 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED 38 #include "oscl_scheduler_ao.h" 39 #endif 40 #ifndef PVMF_MEDIA_DATA_H_INCLUDED 41 #include "pvmf_media_data.h" 42 #endif 43 #ifndef PVMF_PORT_BASE_IMPL_H_INCLUDED 44 #include "pvmf_port_base_impl.h" 45 #endif 46 #ifndef PVMI_MEDIA_TRANSFER_H_INCLUDED 47 #include "pvmi_media_transfer.h" 48 #endif 49 #ifndef PVMF_NODES_SYNC_CONTROL_H_INCLUDED 50 #include "pvmf_nodes_sync_control.h" 51 #endif 52 #ifndef PVMF_SYNC_UTIL_DATA_QUEUE_H_INCLUDED 53 #include "pvmf_sync_util_data_queue.h" 54 #endif 55 #ifndef PVMI_KVP_H_INCLUDED 56 #include "pvmi_kvp.h" 57 #endif 58 #ifndef PVMF_NODE_INTERFACE_H_INCLUDED 59 #include "pvmf_node_interface.h" 60 #endif 61 #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED 62 #include "pvmi_config_and_capability.h" 63 #endif 64 #ifndef OSCL_STRING_CONTAINERS_H_INCLUDED 65 #include "oscl_string_containers.h" 66 #endif 67 68 // Forward declaration 69 class PVMediaOutputNode; 70 71 enum PVMFMediaOutputNodePortMediaTimeStatus 72 { 73 PVMF_MEDIAOUTPUTNODEPORT_MEDIA_ERROR, 74 PVMF_MEDIAOUTPUTNODEPORT_MEDIA_ON_TIME, 75 PVMF_MEDIAOUTPUTNODEPORT_MEDIA_LATE, 76 PVMF_MEDIAOUTPUTNODEPORT_MEDIA_EARLY 77 }; 78 79 #define THRESHOLD_FOR_DROPPED_VIDEO_FRAMES 120 80 81 class PVMediaOutputNodePort : public OsclTimerObject 82 , public PvmfPortBaseImpl 83 , public PvmfNodesSyncControlInterface 84 , public PvmiMediaTransfer 85 , public PVMFPortActivityHandler 86 , public PvmiCapabilityAndConfig 87 , public PVMFMediaClockObserver 88 , public PVMFMediaClockStateObserver 89 , public PVMFMediaClockNotificationsObs 90 { 91 public: 92 PVMediaOutputNodePort(PVMediaOutputNode* aNode); 93 ~PVMediaOutputNodePort(); 94 95 void NodeStarted(); 96 97 PVMFStatus Configure(OSCL_String&); 98 void PutData(PVMFSharedMediaMsgPtr& aMsg); 99 100 //these override the PvmfPortBaseImpl routines 101 OSCL_IMPORT_REF PVMFStatus Connect(PVMFPortInterface* aPort); 102 OSCL_IMPORT_REF PVMFStatus Disconnect(); 103 OSCL_IMPORT_REF PVMFStatus PeerConnect(PVMFPortInterface* aPort); 104 OSCL_IMPORT_REF PVMFStatus PeerDisconnect(); 105 OSCL_IMPORT_REF PVMFStatus ClearMsgQueues(); 106 107 //from PVMFPortActivityHandler 108 void HandlePortActivity(const PVMFPortActivity& aActivity); 109 110 // Pure virtual from PVInterface 111 void addRef(); 112 void removeRef(); 113 bool queryInterface(const PVUuid& uuid, PVInterface*& iface); 114 115 // Pure virtuals from PvmfNodesSyncControlInterface 116 PVMFStatus SetClock(PVMFMediaClock* aClock); 117 PVMFStatus ChangeClockRate(int32 aRate); 118 PVMFStatus SetMargins(int32 aEarlyMargin, int32 aLateMargin); 119 void ClockStarted(); 120 void ClockStopped(); 121 PVMFCommandId SkipMediaData(int32, 122 PVMFTimestamp aResumeTimestamp, 123 uint32 aStreamID, 124 bool aPlayBackPositionContinuous = false, 125 OsclAny* aContext = NULL) 126 { 127 OSCL_UNUSED_ARG(aResumeTimestamp); 128 OSCL_UNUSED_ARG(aStreamID); 129 OSCL_UNUSED_ARG(aPlayBackPositionContinuous); 130 OSCL_UNUSED_ARG(aContext); 131 OSCL_LEAVE(OsclErrNotSupported); 132 return -1; 133 } 134 135 //active vs passive mio 136 void EnableMediaSync(); 137 138 // Pure virtuals from PvmfSyncUtilDataQueueObserver 139 void ScheduleProcessData(PvmfSyncUtilDataQueue* aDataQueue, uint32 aTimeMilliseconds); 140 // sends and info event to engine when the skipping of data is complete 141 void SkipMediaDataComplete(); 142 // after seeing bos for every skipmediadata command issues command complete to engine 143 void SkipMediaCommandComplete(); 144 145 // Pure virtuals from PvmiMediaTransfer 146 void setPeer(PvmiMediaTransfer *aPeer); 147 void useMemoryAllocators(OsclMemAllocator* write_alloc = NULL); 148 PVMFCommandId writeAsync(uint8 format_type, int32 format_index, uint8* data, uint32 data_len, 149 const PvmiMediaXferHeader& data_header_info, OsclAny* aContext = NULL); 150 void writeComplete(PVMFStatus aStatus, PVMFCommandId write_cmd_id, OsclAny* aContext); 151 PVMFCommandId readAsync(uint8* data, uint32 max_data_len, OsclAny* aContext = NULL, 152 int32* formats = NULL, uint16 num_formats = 0); 153 void readComplete(PVMFStatus aStatus, PVMFCommandId read_cmd_id, int32 format_index, 154 const PvmiMediaXferHeader& data_header_info, OsclAny* aContext); 155 void statusUpdate(uint32 status_flags); 156 void cancelCommand(PVMFCommandId command_id); 157 void cancelAllCommands(); 158 159 // Implement pure virtuals from PvmiCapabilityAndConfig interface 160 OSCL_IMPORT_REF virtual PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, 161 PvmiKvp*& aParameters, int& num_parameter_elements, PvmiCapabilityContext aContext); 162 OSCL_IMPORT_REF virtual PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 163 OSCL_IMPORT_REF virtual void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, 164 int num_elements, PvmiKvp * & aRet_kvp); 165 OSCL_IMPORT_REF virtual PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 166 167 // Unsupported PvmiCapabilityAndConfig methods setObserver(PvmiConfigAndCapabilityCmdObserver *)168 void virtual setObserver(PvmiConfigAndCapabilityCmdObserver*) {}; createContext(PvmiMIOSession,PvmiCapabilityContext &)169 void virtual createContext(PvmiMIOSession , PvmiCapabilityContext&) {}; setContextParameters(PvmiMIOSession,PvmiCapabilityContext &,PvmiKvp *,int)170 void virtual setContextParameters(PvmiMIOSession , PvmiCapabilityContext& , PvmiKvp* , int) {}; DeleteContext(PvmiMIOSession,PvmiCapabilityContext &)171 void virtual DeleteContext(PvmiMIOSession , PvmiCapabilityContext&) {}; 172 PVMFCommandId virtual setParametersAsync(PvmiMIOSession , PvmiKvp* , int , PvmiKvp*& , OsclAny* context = NULL) 173 { 174 OSCL_UNUSED_ARG(context); 175 return -1; 176 } getCapabilityMetric(PvmiMIOSession)177 uint32 virtual getCapabilityMetric(PvmiMIOSession) 178 { 179 return 0; 180 } 181 182 // To support config interface QueryInterface(const PVUuid & aUuid,OsclAny * & aPtr)183 void QueryInterface(const PVUuid &aUuid, OsclAny*&aPtr) 184 { 185 if (aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID) 186 { 187 aPtr = (PvmiCapabilityAndConfig*)this; 188 } 189 else 190 { 191 aPtr = NULL; 192 } 193 } 194 195 //From PVMFMediaClockObserver 196 void ClockTimebaseUpdated(); 197 void ClockCountUpdated(); 198 void ClockAdjusted(); 199 //From OsclClockStateObserver 200 void ClockStateUpdated(); 201 void NotificationsInterfaceDestroyed(); 202 203 //To allow the node to set the port format. 204 PVMFFormatType iPortFormat; 205 bool IsFormatSupported(PVMFFormatType); 206 void FormatUpdated(); 207 208 //for processing the callbacks for the notifications requested to iClockNotificationsInf 209 void ProcessCallBack(uint32 callBackID, PVTimeComparisonUtils::MediaTimeStatus aTimerAccuracy, uint32 aDelta, const OsclAny* aContextData, PVMFStatus aStatus); 210 211 void ProcessIncomingMessageIfPossible(); 212 // MIO node sets this status when MIO component's config is complete. 213 void SetMIOComponentConfigStatus(bool aStatus); 214 215 void SetSkipTimeStamp(uint32 aSkipTS, uint32 aStreamID); 216 void CancelSkip(); 217 218 bool isUnCompressedMIO; 219 uint32 iFramesDropped; 220 uint32 iTotalFrames; 221 222 //BOS related 223 Oscl_Vector<uint32, OsclMemAllocator> iBOSStreamIDVec; 224 void ClearPreviousBOSStreamIDs(uint32 aID); 225 226 int32 WriteDataToMIO(int32 &aCmdId, PvmiMediaXferHeader &aMediaxferhdr, OsclRefCounterMemFrag &aFrag); getMediaTransfer()227 PvmiMediaTransfer* getMediaTransfer() 228 { 229 return iMediaTransfer; 230 } 231 private: 232 void Run(); 233 bool peekHead(PVMFSharedMediaMsgPtr& dataPtr, bool& bBos); 234 PVMFStatus ConfigMIO(PvmiKvp* aParameters, PvmiKvp* &aRetParameters); 235 PVMFStatus SetMIOParameterInt32(PvmiKeyType aKey, int32 aValue); 236 PVMFStatus SetMIOParameterUint32(PvmiKeyType aKey, uint32 aValue); 237 PVMFStatus SetMIOParameterPchar(PvmiKeyType aKey, char* aValue); 238 PVMFStatus SetMIOParameterFormat(PvmiKeyType aKey, PVMFFormatType aFormatType); 239 240 // Container node 241 PVMediaOutputNode* iNode; 242 243 uint32 iExtensionRefCount; 244 OSCL_HeapString<OsclMemAllocator> iSinkFormatString; 245 PVMFFormatType iSinkFormat; 246 247 //data transfer related 248 PvmiMediaTransfer* iMediaTransfer; 249 PVMFCommandId iMioInfoErrorCmdId; 250 enum PVMFMediaType 251 { 252 PVMF_MEDIA_UNKNOWN = 0, 253 PVMF_MEDIA_UNCOMPRESSED_AUDIO, 254 PVMF_MEDIA_COMPRESSED_AUDIO, 255 PVMF_MEDIA_UNCOMPRESSED_VIDEO, 256 PVMF_MEDIA_COMPRESSED_VIDEO, 257 PVMF_MEDIA_TEXT 258 } iMediaType; 259 enum WriteState {EWriteBusy, EWriteWait, EWriteOK}; 260 WriteState iWriteState; 261 //media data cleanup queue 262 class CleanupQueueElement 263 { 264 public: CleanupQueueElement(PVMFSharedMediaDataPtr d,PVMFCommandId id)265 CleanupQueueElement(PVMFSharedMediaDataPtr d, PVMFCommandId id): iData(d), iCmdId(id) {} CleanupQueueElement(PVMFCommandId id)266 CleanupQueueElement(PVMFCommandId id): iCmdId(id) {} 267 PVMFSharedMediaDataPtr iData; 268 PVMFCommandId iCmdId; 269 }; 270 Oscl_Vector<CleanupQueueElement, OsclMemAllocator> iCleanupQueue; 271 uint32 iWriteAsyncContext; 272 uint32 iWriteAsyncEOSContext; 273 uint32 iWriteAsyncReConfigContext; 274 PVMFMediaClock* iClock; 275 PVMFMediaClockNotificationsInterface *iClockNotificationsInf; 276 bool oClockCallBackPending; 277 uint32 iDelayEarlyFrameCallBkId; 278 int32 iClockRate; 279 uint32 iEarlyMargin; 280 uint32 iLateMargin; 281 bool oActiveMediaOutputComp; 282 bool oProcessIncomingMessage; 283 bool oMIOComponentConfigured; 284 uint32 iConsecutiveFramesDropped; 285 bool iLateFrameEventSent; 286 PVMFSharedMediaMsgPtr iCurrentMediaMsg; 287 uint32 iFragIndex; 288 //for sending any data 289 void SendData(); 290 //for sending media data to the Mout. 291 void SendMediaData(); 292 //for sending the end-of-data notice to the Mout. 293 void SendEndOfData(); 294 //for sending reconfig notice to the Mout 295 void SendReConfigNotification(); 296 void ClearCleanupQueue(); 297 void CleanupMediaTransfer(); 298 299 //skip related 300 PVMFMediaOutputNodePortMediaTimeStatus CheckMediaTimeStamp(uint32& aDelta); 301 PVMFMediaOutputNodePortMediaTimeStatus CheckMediaFrameStep(); 302 uint32 iRecentStreamID; 303 304 //iEosStreamIDVec is used as a FIFO to store the steamids of eos sent to mio comp. 305 //streamid is pushed in at front when call writeasync(eos) to mio comp. 306 //streamid is poped out from end when mio comp. calls writecomplete(eos), 307 //we report PVMFInfoEndOfData with the poped streamid. 308 //This logic depends on Mio comp. process data(at least eos msg) in a sequencial style. 309 Oscl_Vector<uint32, OsclMemAllocator> iEosStreamIDVec; 310 uint32 iSkipTimestamp; 311 bool iSendStartOfDataEvent; 312 bool DataToSkip(PVMFSharedMediaMsgPtr& aMsg); 313 314 //frame step related 315 bool iFrameStepMode; 316 int32 iClockFrameCount; 317 int32 iSyncFrameCount; 318 319 //for datapath logging 320 void LogMediaDataInfo(const char* msg, PVMFSharedMediaDataPtr mediaData, int32 p1, int32 p2); 321 void LogMediaDataInfo(const char* msg, PVMFSharedMediaDataPtr mediaData); 322 void LogDatapath(const char* msg); 323 324 OsclErrorTrapImp* iOsclErrorTrapImp; 325 PVLogger* iLogger; 326 PVLogger* iDatapathLogger; 327 PVLogger* iDatapathLoggerIn; 328 PVLogger* iDatapathLoggerOut; 329 PVLogger* iReposLogger; 330 331 }; 332 333 #endif // PVMI_IO_INTERFACE_NODE_INPORT_H_INCLUDED 334