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 pvmf_fileoutput_node.h 21 * @brief Simple file output node. Writes incoming data to specified 22 * file without any media type specific file format 23 * 24 */ 25 26 #ifndef PVMF_FILEOUTPUT_NODE_H_INCLUDED 27 #define PVMF_FILEOUTPUT_NODE_H_INCLUDED 28 29 #ifndef OSCL_BASE_H_INCLUDED 30 #include "oscl_base.h" 31 #endif 32 #ifndef OSCLCONFIG_IO_H_INCLUDED 33 #include "osclconfig_io.h" 34 #endif 35 #ifndef OSCL_MEM_H_INCLUDED 36 #include "oscl_mem.h" 37 #endif 38 #ifndef OSCL_FILE_IO_H_INCLUDED 39 #include "oscl_file_io.h" 40 #endif 41 #ifndef OSCL_PRIQUEUE_H_INCLUDED 42 #include "oscl_priqueue.h" 43 #endif 44 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED 45 #include "oscl_scheduler_ao.h" 46 #endif 47 #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED 48 #include "pvmf_media_clock.h" 49 #endif 50 #ifndef PVMF_FORMAT_TYPE_H_INCLUDED 51 #include "pvmf_format_type.h" 52 #endif 53 #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED 54 #include "pvmf_simple_media_buffer.h" 55 #endif 56 #ifndef PVMF_MEDIA_DATA_H_INCLUDED 57 #include "pvmf_media_data.h" 58 #endif 59 #ifndef PVMF_NODE_INTERFACE_H_INCLUDED 60 #include "pvmf_node_interface.h" 61 #endif 62 #ifndef PVMF_FILEOUTPUT_CONFIG_H_INCLUDED 63 #include "pvmf_fileoutput_config.h" 64 #endif 65 #ifndef PVMF_FILEOUTPUT_FACTORY_H_INCLUDED 66 #include "pvmf_fileoutput_factory.h" 67 #endif 68 #ifndef PVMF_COMPOSER_SIZE_AND_DURATION_H_INCLUDED 69 #include "pvmf_composer_size_and_duration.h" 70 #endif 71 #ifndef PVMF_NODES_SYNC_CONTROL_H_INCLUDED 72 #include "pvmf_nodes_sync_control.h" 73 #endif 74 #ifndef PVMF_NODE_UTILS_H_INCLUDED 75 #include "pvmf_node_utils.h" 76 #endif 77 #ifndef PVMF_FILEOUTPUT_INPORT_H 78 #include "pvmf_fileoutput_inport.h" 79 #endif 80 81 // Macros for AMR header 82 #define AMR_HEADER "#!AMR\n" 83 #define AMR_HEADER_SIZE 6 84 85 // Macros for AMR-WB header 86 #define AMRWB_HEADER "#!AMR-WB\n" 87 #define AMRWB_HEADER_SIZE 9 88 89 //////////////////////////////////////////////////////////////////////////// 90 class PVMFFileOutputAlloc : public Oscl_DefAlloc 91 { 92 public: allocate(const uint32 size)93 void* allocate(const uint32 size) 94 { 95 void* tmp = (void*)oscl_malloc(size); 96 return tmp; 97 } 98 deallocate(void * p)99 void deallocate(void* p) 100 { 101 oscl_free(p); 102 } 103 }; 104 105 //////////////////////////////////////////////////////////////////////////// 106 //Default vector reserve size 107 #define PVMF_FILE_OUTPUT_NODE_COMMAND_VECTOR_RESERVE 10 108 109 //Starting value for command IDs 110 #define PVMF_FILE_OUTPUT_NODE_COMMAND_ID_START 6000 111 112 //memory allocator type for this node. 113 typedef OsclMemAllocator PVMFFileOutputNodeAllocator; 114 115 // Forward declaration 116 class PVMFFileOutputInPort; 117 class PVLogger; 118 119 //Node command type. 120 typedef PVMFGenericNodeCommand<PVMFFileOutputNodeAllocator> PVMFFileOutputNodeCommandBase; 121 class PVMFFileOutputNodeCommand: public PVMFFileOutputNodeCommandBase 122 { 123 public: 124 //constructor for Custom2 command Construct(PVMFSessionId s,int32 cmd,int32 arg1,int32 arg2,int32 & arg3,const OsclAny * aContext)125 void Construct(PVMFSessionId s, int32 cmd, int32 arg1, int32 arg2, int32& arg3, const OsclAny*aContext) 126 { 127 PVMFFileOutputNodeCommandBase::Construct(s, cmd, aContext); 128 iParam1 = (OsclAny*)arg1; 129 iParam2 = (OsclAny*)arg2; 130 iParam3 = (OsclAny*) & arg3; 131 } Parse(int32 & arg1,int32 & arg2,int32 * & arg3)132 void Parse(int32&arg1, int32&arg2, int32*&arg3) 133 { 134 arg1 = (int32)iParam1; 135 arg2 = (int32)iParam2; 136 arg3 = (int32*)iParam3; 137 } 138 139 enum PVFileOutputNodeCmdType 140 { 141 PVFILEOUTPUT_NODE_CMD_QUERYUUID, 142 PVFILEOUTPUT_NODE_CMD_QUERYINTERFACE, 143 PVFILEOUTPUT_NODE_CMD_INIT, 144 PVFILEOUTPUT_NODE_CMD_REQUESTPORT, 145 PVFILEOUTPUT_NODE_CMD_START, 146 PVFILEOUTPUT_NODE_CMD_PAUSE, 147 PVFILEOUTPUT_NODE_CMD_STOP, 148 PVFILEOUTPUT_NODE_CMD_RELEASEPORT, 149 PVFILEOUTPUT_NODE_CMD_RESET, 150 PVFILEOUTPUT_NODE_CMD_CANCELCMD, 151 PVFILEOUTPUT_NODE_CMD_CANCELALL, 152 PVFILEOUTPUT_NODE_CMD_SKIPMEDIADATA, 153 PVFILEOUTPUT_NODE_CMD_INVALID 154 }; 155 }; 156 //Command queue type 157 typedef PVMFNodeCommandQueue<PVMFFileOutputNodeCommand, PVMFFileOutputNodeAllocator> PVMFFileOutputNodeCmdQ; 158 159 //Mimetypes for the custom interface 160 #define PVMF_FILE_OUTPUT_NODE_CUSTOM1_MIMETYPE "pvxxx/FileOutputNode/Custom1" 161 #define PVMF_FILE_OUTPUT_NODE_MIMETYPE "pvxxx/FileOutputNode" 162 #define PVMF_BASEMIMETYPE "pvxxx" 163 164 //////////////////////////////////////////////////////////////////////////// 165 class PVMFFileOutputNode : public OsclActiveObject, public PVMFNodeInterface, 166 public PvmfFileOutputNodeConfigInterface, 167 public PvmfComposerSizeAndDurationInterface, 168 public PvmfNodesSyncControlInterface, 169 public PvmiCapabilityAndConfig 170 { 171 public: 172 PVMFFileOutputNode(int32 aPriority); 173 ~PVMFFileOutputNode(); 174 175 // Virtual functions of PVMFNodeInterface 176 PVMFStatus ThreadLogon(); 177 PVMFStatus ThreadLogoff(); 178 PVMFStatus GetCapability(PVMFNodeCapability& aNodeCapability); 179 PVMFPortIter* GetPorts(const PVMFPortFilter* aFilter = NULL); 180 PVMFCommandId QueryUUID(PVMFSessionId, const PvmfMimeString& aMimeType, 181 Oscl_Vector<PVUuid, PVMFFileOutputNodeAllocator>& aUuids, 182 bool aExactUuidsOnly = false, 183 const OsclAny* aContext = NULL); 184 PVMFCommandId QueryInterface(PVMFSessionId, const PVUuid& aUuid, 185 PVInterface*& aInterfacePtr, 186 const OsclAny* aContext = NULL); 187 188 PVMFCommandId RequestPort(PVMFSessionId aSession 189 , int32 aPortTag 190 , const PvmfMimeString* aPortConfig = NULL 191 , const OsclAny* aContext = NULL); 192 193 PVMFCommandId ReleasePort(PVMFSessionId, PVMFPortInterface& aPort, const OsclAny* aContext = NULL); 194 PVMFCommandId Init(PVMFSessionId, const OsclAny* aContext = NULL); 195 PVMFCommandId Prepare(PVMFSessionId, const OsclAny* aContext = NULL); 196 PVMFCommandId Start(PVMFSessionId, const OsclAny* aContext = NULL); 197 PVMFCommandId Stop(PVMFSessionId, const OsclAny* aContext = NULL); 198 PVMFCommandId Flush(PVMFSessionId, const OsclAny* aContext = NULL); 199 PVMFCommandId Pause(PVMFSessionId, const OsclAny* aContext = NULL); 200 PVMFCommandId Reset(PVMFSessionId, const OsclAny* aContext = NULL); 201 PVMFCommandId CancelAllCommands(PVMFSessionId, const OsclAny* aContextData = NULL); 202 PVMFCommandId CancelCommand(PVMFSessionId, PVMFCommandId aCmdId, const OsclAny* aContextData = NULL); 203 204 // Pure virtual from PvInterface 205 void addRef(); 206 void removeRef(); 207 bool queryInterface(const PVUuid& uuid, PVInterface*& iface); 208 209 //from PVMFPortActivityHandler 210 void HandlePortActivity(const PVMFPortActivity& aActivity); 211 212 // Pure virtual from PvmfFileOutputNodeConfigInterface 213 PVMFStatus SetOutputFileName(const OSCL_wString& aFileName); 214 PVMFStatus SetOutputFileDescriptor(const OsclFileHandle* aFileHandle); 215 216 // Pure virtual from PvmfComposerSizeAndDurationInterface 217 PVMFStatus SetMaxFileSize(bool aEnable, uint32 aMaxFileSizeBytes); 218 void GetMaxFileSizeConfig(bool& aEnable, uint32& aMaxFileSizeBytes); 219 PVMFStatus SetMaxDuration(bool aEnable, uint32 aMaxDurationMilliseconds); 220 void GetMaxDurationConfig(bool& aEnable, uint32& aMaxDurationMilliseconds); 221 PVMFStatus SetFileSizeProgressReport(bool aEnable, uint32 aReportFrequency); 222 void GetFileSizeProgressReportConfig(bool& aEnable, uint32& aReportFrequency); 223 PVMFStatus SetDurationProgressReport(bool aEnable, uint32 aReportFrequency); 224 void GetDurationProgressReportConfig(bool& aEnable, uint32& aReportFrequency); 225 226 // Pure virtuals from PvmfNodesSyncControlInterface 227 PVMFStatus SetClock(PVMFMediaClock* aClock); 228 PVMFStatus ChangeClockRate(int32 aRate); 229 PVMFStatus SetMargins(int32 aEarlyMargin, int32 aLateMargin); 230 void ClockStarted(void); 231 void ClockStopped(void); 232 PVMFCommandId SkipMediaData(PVMFSessionId aSessionId, 233 PVMFTimestamp aResumeTimestamp, 234 uint32 aStreamID, 235 bool aPlayBackPositionContinuous = false, 236 OsclAny* aContext = NULL); 237 238 friend class PVMFFileOutputInPort; 239 friend class PVFileOutputNodeFactory; 240 241 242 // implemetation of PvmiCapabilityAndConfig class functions here 243 244 void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver); 245 246 PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, 247 PvmiKvp*& aParameters, int& num_parameter_elements, 248 PvmiCapabilityContext aContext); 249 PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 250 void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); 251 void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, 252 PvmiKvp* aParameters, int num_parameter_elements); 253 void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); 254 void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, 255 int num_elements, PvmiKvp * & aRet_kvp); 256 PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, 257 int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context = NULL); 258 uint32 getCapabilityMetric(PvmiMIOSession aSession); 259 PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements); 260 261 // function used in VerifyParametersSync n SetParametersSync of capability class 262 PVMFStatus VerifyAndSetConfigParameter(PvmiKvp& aParameter, bool aSetParam); 263 264 // function used in getParametersSync of capability class 265 PVMFStatus GetConfigParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr); 266 267 268 private: 269 void ConstructL(); 270 void Run(); 271 272 void CommandComplete(PVMFFileOutputNodeCmdQ&, PVMFFileOutputNodeCommand&, PVMFStatus, OsclAny* aData = NULL); 273 274 PVMFCommandId QueueCommandL(PVMFFileOutputNodeCommand& aCmd); 275 /** 276 * Process a port activity. This method is called by Run to process a port activity. 277 * 278 */ 279 bool ProcessPortActivity(); 280 void QueuePortActivity(const PVMFPortActivity &aActivity); 281 282 bool ProcessCommand(PVMFFileOutputNodeCommand&); 283 bool FlushPending(); 284 285 //Command handlers. 286 void DoReset(PVMFFileOutputNodeCommand&); 287 void DoQueryUuid(PVMFFileOutputNodeCommand&); 288 void DoQueryInterface(PVMFFileOutputNodeCommand&); 289 void DoRequestPort(PVMFFileOutputNodeCommand&); 290 void DoReleasePort(PVMFFileOutputNodeCommand&); 291 void DoInit(PVMFFileOutputNodeCommand&); 292 void DoPrepare(PVMFFileOutputNodeCommand&); 293 void DoStart(PVMFFileOutputNodeCommand&); 294 void DoStop(PVMFFileOutputNodeCommand&); 295 void DoFlush(PVMFFileOutputNodeCommand&); 296 void DoPause(PVMFFileOutputNodeCommand&); 297 void DoCancelAllCommands(PVMFFileOutputNodeCommand&); 298 void DoCancelCommand(PVMFFileOutputNodeCommand&); 299 300 301 void CloseOutputFile(); 302 void ChangeNodeState(TPVMFNodeInterfaceState aNewState); 303 304 // Handle command and data events 305 PVMFStatus ProcessIncomingData(PVMFSharedMediaDataPtr aMediaData); 306 307 PVMFStatus ProcessIncomingMsg(PVMFPortInterface* aPort); 308 309 /** 310 * Send file size progress report if enabled. 311 * @return PVMFFailure if informational observer is not set, else PVMFSuccess 312 */ 313 PVMFStatus SendFileSizeProgress(); 314 315 /** 316 * Send duration progress report if enabled. 317 * @param aTimestamp Timestamp of current frame in milliseconds. 318 * @return PVMFFailure if informational observer is not set, else PVMFSuccess 319 */ 320 PVMFStatus SendDurationProgress(uint32 aTimestamp); 321 322 /** 323 * Check if maximum file size or duration is reached if a maximum is set. 324 * 325 * @param aFrameSize Size of current frame in bytes. 326 * @return PVMFSuccess if feature is enabled and the maximum file size / duration is reached. 327 * PVMFPending if feature is enabled and the max file size / duration has not been reached. 328 * PVMFErrNotSupported if feature is not enabled. 329 * PVMFFailure if informational observer is not set or if max file size or duration is set 330 * but the finalizing output file failed. 331 */ 332 PVMFStatus CheckMaxFileSize(uint32 aFrameSize); 333 334 /** 335 * Check if maximum file size or duration is reached if a maximum is set. 336 * 337 * @param aTimestamp Timestamp of current frame in milliseconds. 338 * @return PVMFSuccess if feature is enabled and the maximum file size / duration is reached. 339 * PVMFPending if feature is enabled and the max file size / duration has not been reached. 340 * PVMFErrNotSupported if feature is not enabled. 341 * PVMFFailure if informational observer is not set or if max file size or duration is set 342 * but the finalizing output file failed. 343 */ 344 PVMFStatus CheckMaxDuration(uint32 aTimestamp); 345 346 /** 347 * Write data to output file. 348 * 349 * @param aData Data to be written to file. 350 * @param aSize Size of data to be written to file. 351 * @return PVMFSuccess if data is written, or maximum file size is reached, else PVMFFailure. 352 */ 353 PVMFStatus WriteData(OsclAny* aData, uint32 aSize); 354 355 /** 356 * Write memory fragment to output file. 357 * 358 * @param aMemFrag Memory fragment object whose data has to be written to output file. 359 * @param aTimestamp Timestamp of the frame to be written in milliseconds. 360 * @return PVMFSuccess if memory fragment is written, or max file size or duration is reached, else PVMFFailure. 361 */ 362 PVMFStatus WriteData(OsclRefCounterMemFrag aMemFrag, uint32 aTimestamp); 363 364 /** 365 * Write format specific info to output file. 366 * 367 * @param aData Data to be written to file. 368 * @param aSize Size of data to be written to file. 369 * @return PVMFSuccess if data is written, or maximum file size is reached, else PVMFFailure. 370 */ 371 PVMFStatus WriteFormatSpecificInfo(OsclAny* aPtr, uint32 aSize); 372 373 /** Clear all pending port activity after max file size or duration is reached. */ 374 void ClearPendingPortActivity(); 375 376 // Queue of commands 377 PVMFCommandId iCmdIdCounter; 378 379 // Input port 380 PVMFPortInterface* iInPort; 381 382 // Output file name 383 OSCL_wHeapString<OsclMemAllocator> iOutputFileName; 384 OsclFileHandle* iFileHandle; 385 386 // Allocator 387 Oscl_DefAlloc* iAlloc; 388 389 // Output file 390 Oscl_FileServer iFs; 391 Oscl_File iOutputFile; 392 int32 iFileOpened; 393 394 bool iFirstMediaData; 395 396 PVLogger* iLogger; 397 398 PVMFFormatType iFormat; 399 400 uint32 iExtensionRefCount; 401 PVMFNodeCapability iCapability; 402 403 PVMFFileOutputNodeCmdQ iInputCommands; 404 PVMFFileOutputNodeCmdQ iCurrentCommand; 405 406 PVMFPortVector<PVMFFileOutputInPort, PVMFFileOutputNodeAllocator> iPortVector; 407 Oscl_Vector<PVMFPortActivity, PVMFFileOutputNodeAllocator> iPortActivityQueue; 408 409 // Variables for max file size and duration feature 410 bool iMaxFileSizeEnabled; 411 bool iMaxDurationEnabled; 412 uint32 iMaxFileSize; 413 uint32 iMaxDuration; 414 uint32 iFileSize; 415 416 // Variables for progress report feature 417 bool iFileSizeReportEnabled; 418 bool iDurationReportEnabled; 419 uint32 iFileSizeReportFreq; 420 uint32 iDurationReportFreq; 421 uint32 iNextFileSizeReport; 422 uint32 iNextDurationReport; 423 424 // Variables for media data queue and synchronization 425 PVMFMediaClock* iClock; 426 int32 iEarlyMargin; 427 int32 iLateMargin; 428 }; 429 430 #endif // PVMF_FILEOUTPUT_NODE_H_INCLUDED 431