• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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