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 #ifndef PVMI_MIO_AVIFILE_H_INCLUDED 19 #define PVMI_MIO_AVIFILE_H_INCLUDED 20 21 #ifndef OSCL_BASE_H_INCLUDED 22 #include "oscl_base.h" 23 #endif 24 25 #ifndef OSCLCONFIG_IO_H_INCLUDED 26 #include "osclconfig_io.h" 27 #endif 28 29 #ifndef OSCL_STRING_H_INCLUDED 30 #include "oscl_string.h" 31 #endif 32 33 #ifndef OSCL_FILE_IO_H_INCLUDED 34 #include "oscl_file_io.h" 35 #endif 36 37 #ifndef OSCL_MEM_MEMPOOL_H_INCLUDED 38 #include "oscl_mem_mempool.h" 39 #endif 40 41 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED 42 #include "oscl_scheduler_ao.h" 43 #endif 44 45 #ifndef OSCL_VECTOR_H_INCLUDED 46 #include "oscl_vector.h" 47 #endif 48 49 #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED 50 #include "pvmf_media_clock.h" 51 #endif 52 53 #ifndef PVLOGGER_H_INCLUDED 54 #include "pvlogger.h" 55 #endif 56 57 #ifndef PVMI_MIO_CONTROL_H_INCLUDED 58 #include "pvmi_mio_control.h" 59 #endif 60 61 #ifndef PVMI_MEDIA_TRANSFER_H_INCLUDED 62 #include "pvmi_media_transfer.h" 63 #endif 64 65 #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED 66 #include "pvmi_config_and_capability.h" 67 #endif 68 69 #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED 70 #include "pvmf_simple_media_buffer.h" 71 #endif 72 73 #ifndef PVMI_MIO_AVIFILE_FACTORY_H_INCLUDED 74 #include "pvmi_mio_avi_wav_file_factory.h" 75 #endif 76 77 #ifndef PVWAVFILEPARSER_H_INCLUDED 78 #include "pvwavfileparser.h" 79 #endif 80 81 #ifndef PVLOGGER_FILE_APPENDER_H_INCLUDED 82 #include "pvlogger_file_appender.h" 83 #endif 84 85 86 #define MAKE_FOURCC(a , b, c, d) ((uint32(a) << 24) | (uint32(b) << 16) | (uint32(c) << 8) | uint32(d)) 87 88 // Forward declaration 89 class PvmiMIOAviWavFileSettings; 90 91 /** 92 * Enumerated list of asychronous commands for PvmiMIOAviWavFile 93 */ 94 typedef enum 95 { 96 CMD_QUERY_UUID, 97 CMD_QUERY_INTERFACE, 98 CMD_INIT, 99 CMD_START, 100 CMD_PAUSE, 101 CMD_FLUSH, 102 CMD_STOP, 103 CMD_CANCEL_ALL_COMMANDS, 104 CMD_CANCEL_COMMAND, 105 CMD_RESET, 106 DATA_EVENT, 107 INVALID_CMD 108 } PvmiMIOAviWavFileCmdType; 109 110 const uint32 YUV_FMT[] = 111 { 112 MAKE_FOURCC('A', 'Y', 'U', 'V'), 113 MAKE_FOURCC('a', 'y', 'u', 'v'), 114 MAKE_FOURCC('C', 'L', 'J', 'R'), 115 MAKE_FOURCC('c', 'l', 'j', 'r'), 116 MAKE_FOURCC('I', 'Y', 'U', 'V'), 117 MAKE_FOURCC('i', 'y', 'u', 'v'), 118 MAKE_FOURCC('G', 'R', 'E', 'Y'), 119 MAKE_FOURCC('g', 'r', 'e', 'y'), 120 MAKE_FOURCC('I', 'Y', '4', '1'), 121 MAKE_FOURCC('i', 'y', '4', '1'), 122 MAKE_FOURCC('I', 'Y', 'U', '1'), 123 MAKE_FOURCC('i', 'y', 'u', '1'), 124 MAKE_FOURCC('Y', '4', '1', 'P'), 125 MAKE_FOURCC('y', '4', '1', 'p'), 126 MAKE_FOURCC('Y', '4', '1', '1'), 127 MAKE_FOURCC('y', '4', '1', '1'), 128 MAKE_FOURCC('Y', '4', '1', 'T'), 129 MAKE_FOURCC('y', '4', '1', 't'), 130 MAKE_FOURCC('Y', '4', '2', 'T'), 131 MAKE_FOURCC('y', '4', '2', 't'), 132 MAKE_FOURCC('Y', '8', '0', '0'), 133 MAKE_FOURCC('y', '8', '0', '0'), 134 MAKE_FOURCC('Y', '8', ' ', ' '), 135 MAKE_FOURCC('y', '8', ' ', ' '), 136 MAKE_FOURCC('Y', '2', '1', '1'), 137 MAKE_FOURCC('y', '2', '1', '1'), 138 MAKE_FOURCC('I', '4', '2', '0'), 139 MAKE_FOURCC('i', '4', '2', '0'), 140 MAKE_FOURCC('I', 'Y', 'U', '1'), 141 MAKE_FOURCC('i', 'y', 'u', '1'), 142 MAKE_FOURCC('Y', 'V', '1', '6'), 143 MAKE_FOURCC('y', 'v', '1', '6'), 144 MAKE_FOURCC('Y', 'V', '1', '2'), 145 MAKE_FOURCC('y', 'v', '1', '2'), 146 MAKE_FOURCC('C', 'L', 'P', 'L'), 147 MAKE_FOURCC('c', 'l', 'p', 'l'), 148 MAKE_FOURCC('N', 'V', '1', '2'), 149 MAKE_FOURCC('n', 'v', '1', '2'), 150 MAKE_FOURCC('N', 'V', '2', '1'), 151 MAKE_FOURCC('n', 'v', '2', '1'), 152 MAKE_FOURCC('I', 'M', 'C', '1'), 153 MAKE_FOURCC('i', 'm', 'c', '1'), 154 MAKE_FOURCC('I', 'M', 'C', '2'), 155 MAKE_FOURCC('i', 'm', 'c', '2'), 156 MAKE_FOURCC('I', 'M', 'C', '3'), 157 MAKE_FOURCC('i', 'm', 'c', '3'), 158 MAKE_FOURCC('I', 'M', 'C', '4'), 159 MAKE_FOURCC('i', 'm', 'c', '4'), 160 MAKE_FOURCC('C', 'X', 'Y', '1'), 161 MAKE_FOURCC('c', 'x', 'y', '1'), 162 MAKE_FOURCC('Y', 'V', 'Y', '2'), 163 MAKE_FOURCC('y', 'v', 'y', '2'), 164 MAKE_FOURCC('U', 'Y', 'V', 'Y'), 165 MAKE_FOURCC('u', 'y', 'v', 'y'), 166 }; 167 const uint32 BITS_PER_SAMPLE8 = 8; 168 const uint32 BITS_PER_SAMPLE12 = 12; 169 const uint32 BITS_PER_SAMPLE16 = 16; 170 const uint32 BITS_PER_SAMPLE24 = 24; 171 const uint32 PVWAV_MSEC_PER_BUFFER = 100; 172 const uint32 BYTE_COUNT = 8; 173 const uint32 DATA_BUFF_THRESHOLD = 1; 174 const uint32 NUM_YUV_FMT = 54; 175 176 #define PROFILING_ON (PVLOGGER_INST_LEVEL >= PVLOGMSG_INST_PROF) 177 178 //////////////////////////////////////////////////////////////////////////// 179 /** 180 * Class containing information for a command or data event 181 */ 182 class PvmiMIOAviWavFileCmd 183 { 184 public: PvmiMIOAviWavFileCmd()185 PvmiMIOAviWavFileCmd() 186 { 187 iId = 0; 188 iType = INVALID_CMD; 189 iContext = NULL; 190 iData1 = NULL; 191 } 192 PvmiMIOAviWavFileCmd(const PvmiMIOAviWavFileCmd & aCmd)193 PvmiMIOAviWavFileCmd(const PvmiMIOAviWavFileCmd& aCmd) 194 { 195 Copy(aCmd); 196 } 197 ~PvmiMIOAviWavFileCmd()198 ~PvmiMIOAviWavFileCmd() {} 199 200 PvmiMIOAviWavFileCmd& operator=(const PvmiMIOAviWavFileCmd& aCmd) 201 { 202 Copy(aCmd); 203 return (*this); 204 } 205 206 PVMFCommandId iId; /** ID assigned to this command */ 207 int32 iType; /** PvmiMIOAviWavFileCmdType value */ 208 OsclAny* iContext; /** Other data associated with this command */ 209 OsclAny* iData1; /** Other data associated with this command */ 210 211 private: 212 Copy(const PvmiMIOAviWavFileCmd & aCmd)213 void Copy(const PvmiMIOAviWavFileCmd& aCmd) 214 { 215 iId = aCmd.iId; 216 iType = aCmd.iType; 217 iContext = aCmd.iContext; 218 iData1 = aCmd.iData1; 219 } 220 }; 221 222 class PvmiMIOAviWavFileMediaData 223 { 224 public: PvmiMIOAviWavFileMediaData()225 PvmiMIOAviWavFileMediaData() 226 { 227 iId = 0; 228 iData = NULL; 229 } 230 PvmiMIOAviWavFileMediaData(const PvmiMIOAviWavFileMediaData & aData)231 PvmiMIOAviWavFileMediaData(const PvmiMIOAviWavFileMediaData& aData) 232 { 233 iId = aData.iId; 234 iData = aData.iData; 235 } 236 237 PVMFCommandId iId; 238 OsclAny* iData; 239 }; 240 241 class PvmiMIOAviWavFile : public OsclTimerObject, 242 public PvmiMIOControl, 243 public PvmiMediaTransfer, 244 public PvmiCapabilityAndConfig 245 { 246 public: 247 PvmiMIOAviWavFile(uint32 aNumLoops, bool aRecordingMode, uint32 aStreamNo, OsclAny* aFileParser, FileFormatType aFileType, int32& arError); 248 virtual ~PvmiMIOAviWavFile(); 249 250 // Pure virtuals from PvmiMIOControl 251 OSCL_IMPORT_REF PVMFStatus connect(PvmiMIOSession& aSession, PvmiMIOObserver* aObserver); 252 OSCL_IMPORT_REF PVMFStatus disconnect(PvmiMIOSession aSession); 253 OSCL_IMPORT_REF PvmiMediaTransfer* createMediaTransfer(PvmiMIOSession& aSession, 254 PvmiKvp* aRead_formats = NULL, 255 int32 aRead_flags = 0, 256 PvmiKvp* aWrite_formats = NULL, 257 int32 aWrite_flags = 0); 258 OSCL_IMPORT_REF void deleteMediaTransfer(PvmiMIOSession& aSession, 259 PvmiMediaTransfer* aMedia_transfer); 260 OSCL_IMPORT_REF PVMFCommandId QueryUUID(const PvmfMimeString& aMimeType, 261 Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids, 262 bool aExactUuidsOnly = false, 263 const OsclAny* aContext = NULL); 264 OSCL_IMPORT_REF PVMFCommandId QueryInterface(const PVUuid& aUuid, 265 PVInterface*& aInterfacePtr, 266 const OsclAny* aContext = NULL); 267 OSCL_IMPORT_REF PVMFCommandId Init(const OsclAny* aContext = NULL); 268 OSCL_IMPORT_REF PVMFCommandId Start(const OsclAny* aContext = NULL); 269 OSCL_IMPORT_REF PVMFCommandId Reset(const OsclAny* aContext = NULL); 270 OSCL_IMPORT_REF PVMFCommandId Pause(const OsclAny* aContext = NULL); 271 OSCL_IMPORT_REF PVMFCommandId Flush(const OsclAny* aContext = NULL); 272 OSCL_IMPORT_REF PVMFCommandId DiscardData(PVMFTimestamp aTimestamp, const OsclAny* aContext = NULL); 273 OSCL_IMPORT_REF PVMFCommandId DiscardData(const OsclAny* aContext = NULL); 274 OSCL_IMPORT_REF PVMFCommandId Stop(const OsclAny* aContext = NULL); 275 OSCL_IMPORT_REF PVMFCommandId CancelCommand(PVMFCommandId aCmdId, const OsclAny* aContext = NULL); 276 OSCL_IMPORT_REF PVMFCommandId CancelAllCommands(const OsclAny* aContext = NULL); 277 OSCL_IMPORT_REF void ThreadLogon(); 278 OSCL_IMPORT_REF void ThreadLogoff(); 279 280 // Pure virtuals from PvmiMediaTransfer 281 OSCL_IMPORT_REF void setPeer(PvmiMediaTransfer* aPeer); 282 OSCL_IMPORT_REF void useMemoryAllocators(OsclMemAllocator* aWrite_alloc = NULL); 283 OSCL_IMPORT_REF PVMFCommandId writeAsync(uint8 aFormat_type, int32 aFormat_index, 284 uint8* aData, uint32 aData_len, 285 const PvmiMediaXferHeader& aData_header_info, 286 OsclAny* aContext = NULL); 287 OSCL_IMPORT_REF void writeComplete(PVMFStatus aStatus, PVMFCommandId aWrite_cmd_id, 288 OsclAny* aContext); 289 OSCL_IMPORT_REF PVMFCommandId readAsync(uint8* aData, uint32 aMax_data_len, OsclAny* aContext = NULL, 290 int32* aFormats = NULL, uint16 aNum_formats = 0); 291 OSCL_IMPORT_REF void readComplete(PVMFStatus aStatus, PVMFCommandId aRead_cmd_id, 292 int32 aFormat_index, 293 const PvmiMediaXferHeader& aData_header_info, 294 OsclAny* aContext); 295 OSCL_IMPORT_REF void statusUpdate(uint32 aStatus_flags); 296 OSCL_IMPORT_REF void cancelCommand(PVMFCommandId aCmdId); 297 OSCL_IMPORT_REF void cancelAllCommands(); 298 299 // Pure virtuals from PvmiCapabilityAndConfig 300 OSCL_IMPORT_REF void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver); 301 OSCL_IMPORT_REF PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, 302 PvmiKvp*& aParameters, int& aNum_parameter_elements, 303 PvmiCapabilityContext aContext); 304 OSCL_IMPORT_REF PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, 305 int aNum_elements); 306 OSCL_IMPORT_REF void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); 307 OSCL_IMPORT_REF void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, 308 PvmiKvp* aParameters, int aNum_parameter_elements); 309 OSCL_IMPORT_REF void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext); 310 OSCL_IMPORT_REF void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, 311 int aNum_elements, PvmiKvp * & aRet_kvp); 312 OSCL_IMPORT_REF PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, 313 int aNum_elements, PvmiKvp*& aRet_kvp, 314 OsclAny* aContext = NULL); 315 OSCL_IMPORT_REF uint32 getCapabilityMetric(PvmiMIOSession aSession); 316 OSCL_IMPORT_REF PVMFStatus verifyParametersSync(PvmiMIOSession aSession, 317 PvmiKvp* aParameters, int aNum_elements); getStreamDuration()318 OSCL_IMPORT_REF uint32 getStreamDuration() 319 { 320 return iStreamDuration; 321 } 322 323 private: 324 325 void Run(); 326 int32 InitComp(OsclAny* aFileParser, FileFormatType aFileType); 327 328 PVMFCommandId AddCmdToQueue(PvmiMIOAviWavFileCmdType aType, const OsclAny* aContext, OsclAny* aData1 = NULL); 329 void AddDataEventToQueue(uint32 aMicroSecondsToEvent); 330 void DoRequestCompleted(const PvmiMIOAviWavFileCmd& aCmd, PVMFStatus aStatus, OsclAny* aEventData = NULL); 331 332 PVMFStatus DoInit(); 333 PVMFStatus DoStart(); 334 PVMFStatus DoReset(); 335 PVMFStatus DoPause(); 336 PVMFStatus DoFlush(); 337 PVMFStatus DoStop(); 338 PVMFStatus DoRead(); 339 340 PVMFStatus GetMediaData(uint8* aData, uint32& aDataSize, uint32& aTimeStamp); 341 uint32 GetDataSize(); 342 PVMFStatus CalcMicroSecPerDataEvent(uint32 aDataSize); 343 344 /** 345 * Allocate a specified number of key-value pairs and set the keys 346 * 347 * @param aKvp Output parameter to hold the allocated key-value pairs 348 * @param aKey Key for the allocated key-value pairs 349 * @param aNumParams Number of key-value pairs to be allocated 350 * @return Completion status 351 */ 352 PVMFStatus AllocateKvp(PvmiKvp*& aKvp, PvmiKeyType aKey, int32 aNumParams); 353 354 /** 355 * Verify one key-value pair parameter against capability of the port and 356 * if the aSetParam flag is set, set the value of the parameter corresponding to 357 * the key. 358 * 359 * @param aKvp Key-value pair parameter to be verified 360 * @param aSetParam If true, set the value of parameter corresponding to the key. 361 * @return PVMFSuccess if parameter is supported, else PVMFFailure 362 */ 363 PVMFStatus VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam = false); 364 void UpdateCurrentTimeStamp(uint32 aDataSize); 365 void LogDiagnostics(); 366 bool IsYUVFormat_Supported(uint32 aFcc); 367 uint8* AllocateMemPool(OsclMemPoolFixedChunkAllocator*&, uint32, int32&); 368 int32 WriteAsyncDataHdr(uint32&, PvmiMediaTransfer*&, uint32&, PvmiMediaXferHeader&, uint8*, uint32, uint32); 369 370 // Command queue 371 uint32 iCmdIdCounter; 372 Oscl_Vector<PvmiMIOAviWavFileCmd, OsclMemAllocator> iCmdQueue; 373 374 // PvmiMIO sessions 375 Oscl_Vector<PvmiMIOObserver*, OsclMemAllocator> iObservers; 376 377 PvmiMediaTransfer* iPeer; 378 379 // Thread logon 380 bool iThreadLoggedOn; 381 382 // Input file 383 PvmiMIOAviWavFileSettings iSettings; 384 385 // Counter and size info for file read 386 PVAviFile* iPVAviFile; 387 PV_Wav_Parser* iPVWavFile; 388 389 PVAviFileMainHeaderStruct iAviFileHeader; 390 PVAviFileStreamHeaderStruct iAviFileStreamHeader; 391 OsclRefCounterMemFrag iFormatSpecificDataFrag; 392 393 int32 iDataEventCounter; 394 int32 iTotalNumFrames; 395 int32 iFileHeaderSize; 396 // Timing 397 int32 iMilliSecondsPerDataEvent; 398 int32 iMicroSecondsPerDataEvent; 399 400 // Allocator for simple media data buffer 401 OsclMemAllocator iAlloc; 402 OsclMemPoolFixedChunkAllocator* iMediaBufferMemPool; 403 404 Oscl_Vector<PvmiMIOAviWavFileMediaData, OsclMemAllocator> iSentMediaData; 405 406 // Logger 407 PVLogger* iLogger; 408 PVLogger* iDiagnosticsLogger; 409 PVLogger* iDiagnosticsLoggerAVIFF; 410 PVLogger* iDataPathLogger; 411 412 // State machine 413 enum PvmiMIOAviWavFileState 414 { 415 STATE_IDLE, 416 STATE_INITIALIZED, 417 STATE_STARTED, 418 STATE_FLUSHING, 419 STATE_PAUSED, 420 STATE_STOPPED 421 }; 422 423 PvmiMIOAviWavFileState iState; 424 PVMFMediaClock* iMioClock; 425 PVMFTimebase_Tickcount iClockTimeBase; 426 bool iWaitingOnClock; 427 uint32 iDataSize; 428 uint32 iTimeStamp; 429 uint32 iStreamDuration ; // in microsec 430 uint32 iCurrentTimeStamp; 431 enum WriteState {EWriteBusy, EWriteOK}; 432 WriteState iWriteState; 433 uint8* iData; 434 435 #if PROFILING_ON 436 //for diagnostics purpose 437 uint32 iNumEarlyFrames; 438 uint32 iNumLateFrames; 439 uint32 iTotalFrames; 440 uint32 iPercFramesDropped; 441 uint32 iMaxDataSize; 442 uint32 iMinDataSize; 443 uint32 iMaxFileReadTime; 444 uint32 iMinFileReadTime; 445 bool oDiagnosticsLogged; 446 #endif 447 448 bool iNoMemBufferData; 449 }; 450 451 #endif // PVMI_MIO_AVIFILE_H_INCLUDED 452