• 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_MEDIA_IO_FILEOUTPUT_H_INCLUDED
19 #define PVMI_MEDIA_IO_FILEOUTPUT_H_INCLUDED
20 
21 #ifndef PVMI_MIO_CONTROL_H_INCLUDED
22 #include "pvmi_mio_control.h"
23 #endif
24 #ifndef PVMI_MEDIA_TRANSFER_H_INCLUDED
25 #include "pvmi_media_transfer.h"
26 #endif
27 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED
28 #include "oscl_scheduler_ao.h"
29 #endif
30 #ifndef PVMI_MEDIA_IO_OBSERVER_H_INCLUDED
31 #include "pvmi_media_io_observer.h"
32 #endif
33 #ifndef OSCL_FILE_IO_H_INCLUDED
34 #include "oscl_file_io.h"
35 #endif
36 #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED
37 #include "pvmi_config_and_capability.h"
38 #endif
39 #ifndef OSCL_STRING_CONTAINERS_H_INCLUDED
40 #include "oscl_string_containers.h"
41 #endif
42 #ifndef PVMI_MEDIA_IO_CLOCK_EXTENSION_H_INCLUDED
43 #include "pvmi_media_io_clock_extension.h"
44 #endif
45 
46 #ifndef AVI_WRITE_H_INCLUDED
47 #include "avi_write.h"
48 #endif
49 
50 #define TEST_BUFFER_ALLOCATOR 0
51 
52 #if TEST_BUFFER_ALLOCATOR
53 #ifndef PV_INTERFACE_H
54 #include "pv_interface.h"
55 #endif
56 
57 #ifndef PVMF_FIXEDSIZE_BUFFER_ALLOC_H_INCLUDED
58 #include "pvmf_fixedsize_buffer_alloc.h"
59 #endif
60 #endif
61 
62 class PVLogger;
63 class PVRefFileOutputTestObserver;
64 class PVMFMediaClock;
65 class PVRefFileOutput;
66 
67 #define DEFAULT_NUM_DECODED_FRAMES_CAPABILITY   6
68 
69 // To maintain the count of supported uncompressed audio formats.
70 // Should be updated whenever new format is added
71 #define PVMF_SUPPORTED_UNCOMPRESSED_AUDIO_FORMATS_COUNT 6
72 
73 // To maintain the count of supported uncompressed video formats.
74 // Should be updated whenever new format is added
75 #define PVMF_SUPPORTED_UNCOMPRESSED_VIDEO_FORMATS_COUNT 6
76 
77 // To maintain the count of supported compressed audio formats.
78 // Should be updated whenever new format is added
79 #define PVMF_SUPPORTED_COMPRESSED_AUDIO_FORMATS_COUNT 18
80 
81 // To maintain the count of supported compressed video formats.
82 // Should be updated whenever new format is added
83 #define PVMF_SUPPORTED_COMPRESSED_VIDEO_FORMATS_COUNT 8
84 
85 #define PVMF_SUPPORTED_TEXT_FORMAT_COUNT 1
86 
87 
88 
89 
90 typedef struct
91 {
92     uint32      chunkID;
93     uint32      chunkSize;
94     uint32      format;
95 } RIFFChunk;
96 
97 typedef struct
98 {
99     uint32      subchunk1ID;
100     uint32      subchunk1Size;
101     uint16     audioFormat;
102     uint16     numChannels;
103     uint32      sampleRate;
104     uint32      byteRate;
105     uint16     blockAlign;
106     uint16     bitsPerSample;
107 } fmtSubchunk;
108 
109 typedef struct
110 {
111     uint32      subchunk2ID;
112     uint32      subchunk2Size;
113 } dataSubchunk;
114 
115 typedef enum
116 {
117     MEDIATYPE_VIDEO,
118     MEDIATYPE_AUDIO,
119     MEDIATYPE_TEXT,
120     MEDIATYPE_UNKNOWN
121 } MediaType;
122 
123 // A test feature for simulating a component with active timing.
124 class PVRefFileOutputActiveTimingSupport: public PvmiClockExtensionInterface
125 {
126     public:
127 
PVRefFileOutputActiveTimingSupport(uint32 limit)128         PVRefFileOutputActiveTimingSupport(uint32 limit)
129                 : iLastTimestampValid(false)
130                 , iDelay(0)
131                 , iQueueLimit(limit)
132                 , iClock(NULL)
133                 , iLogger(NULL)
134         {}
~PVRefFileOutputActiveTimingSupport()135         virtual ~PVRefFileOutputActiveTimingSupport()
136         {}
137 
138         //from PvmiClockExtensionInterface
139         OSCL_IMPORT_REF PVMFStatus SetClock(PVMFMediaClock *clockVal) ;
140 
141         //from PVInterface
142         OSCL_IMPORT_REF void addRef() ;
143         OSCL_IMPORT_REF void removeRef() ;
144         OSCL_IMPORT_REF bool queryInterface(const PVUuid& uuid, PVInterface*& iface) ;
145 
146         void queryUuid(PVUuid& uuid);
147 
148         uint32 GetDelayMsec(PVMFTimestamp&);
149         void AdjustClock(PVMFTimestamp& aTs);
150 
151         PVMFTimestamp iLastTimestamp;
152         bool iLastTimestampValid;
153         uint32 iDelay;
154 
155         uint32 iQueueLimit;
156 
157         PVMFMediaClock* iClock;
158         PVLogger* iLogger;
159 
160         //query for whether playback clock is in frame-step mode.
161         bool FrameStepMode();
162 
163 };
164 
165 
166 // This class implements the reference media IO for file output.
167 // This class constitutes the Media IO component
168 
169 class PVRefFileOutput : public OsclTimerObject
170         , public PvmiMIOControl
171         , public PvmiMediaTransfer
172         , public PvmiCapabilityAndConfig
173         , public PvmiClockExtensionInterface
174 
175 {
176     public:
177         OSCL_IMPORT_REF PVRefFileOutput(const oscl_wchar* aFileName,
178                                         bool aActiveTiming = false);
179 
180         OSCL_IMPORT_REF PVRefFileOutput(const oscl_wchar* aFileName,
181                                         MediaType aMediaType,
182                                         bool aCompressedMedia = false);
183 
184         OSCL_IMPORT_REF PVRefFileOutput(const OSCL_wString& aFileName, bool logStrings = false);
185 
186         // Expanded constructor with test features.
187         OSCL_IMPORT_REF PVRefFileOutput(const OSCL_wString& aFileName
188                                         , PVRefFileOutputTestObserver*aObserver
189                                         , bool aActiveTiming, uint32 aQueueLimit
190                                         , bool aSimFlowControl
191                                         , bool logStrings = true);
192 
193         ~PVRefFileOutput();
194 
195         // APIs from PvmiMIOControl
196 
197 
198         PVMFStatus connect(PvmiMIOSession& aSession, PvmiMIOObserver* aObserver);
199 
200         PVMFStatus disconnect(PvmiMIOSession aSession);
201 
202         PVMFCommandId QueryUUID(const PvmfMimeString& aMimeType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
203                                 bool aExactUuidsOnly = false, const OsclAny* aContext = NULL);
204 
205         PVMFCommandId QueryInterface(const PVUuid& aUuid, PVInterface*& aInterfacePtr, const OsclAny* aContext = NULL);
206 
207         PvmiMediaTransfer* createMediaTransfer(PvmiMIOSession& aSession, PvmiKvp* read_formats = NULL, int32 read_flags = 0,
208                                                PvmiKvp* write_formats = NULL, int32 write_flags = 0);
209 
210         void deleteMediaTransfer(PvmiMIOSession& aSession, PvmiMediaTransfer* media_transfer);
211 
212         PVMFCommandId Init(const OsclAny* aContext = NULL);
213 
214         PVMFCommandId Reset(const OsclAny* aContext = NULL);
215 
216         PVMFCommandId Start(const OsclAny* aContext = NULL);
217 
218         PVMFCommandId Pause(const OsclAny* aContext = NULL);
219 
220         PVMFCommandId Flush(const OsclAny* aContext = NULL);
221 
222         PVMFCommandId DiscardData(const OsclAny* aContext = NULL);
223 
224         PVMFCommandId DiscardData(PVMFTimestamp aTimestamp, const OsclAny* aContext = NULL);
225 
226         PVMFCommandId Stop(const OsclAny* aContext = NULL);
227 
228         PVMFCommandId CancelAllCommands(const OsclAny* aContext = NULL);
229 
230         PVMFCommandId CancelCommand(PVMFCommandId aCmdId, const OsclAny* aContext = NULL);
231 
232         void ThreadLogon();
233 
234         void ThreadLogoff();
235 
236         // APIs from PvmiMediaTransfer
237 
238         void setPeer(PvmiMediaTransfer* aPeer);
239 
240         void useMemoryAllocators(OsclMemAllocator* write_alloc = NULL);
241 
242         PVMFCommandId writeAsync(uint8 format_type, int32 format_index,
243                                  uint8* data, uint32 data_len,
244                                  const PvmiMediaXferHeader& data_header_info,
245                                  OsclAny* aContext = NULL);
246 
247         void writeComplete(PVMFStatus aStatus,
248                            PVMFCommandId  write_cmd_id,
249                            OsclAny* aContext);
250 
251         PVMFCommandId  readAsync(uint8* data, uint32 max_data_len,
252                                  OsclAny* aContext = NULL,
253                                  int32* formats = NULL, uint16 num_formats = 0);
254 
255         void readComplete(PVMFStatus aStatus, PVMFCommandId  read_cmd_id, int32 format_index,
256                           const PvmiMediaXferHeader& data_header_info, OsclAny* aContext);
257 
258         void statusUpdate(uint32 status_flags);
259 
260         void cancelCommand(PVMFCommandId  command_id);
261 
262         void cancelAllCommands();
263 
264         void setUserClockExtnInterface(bool aEnable);
265 
266         // Pure virtuals from PvmiCapabilityAndConfig
267 
268         void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver);
269 
270         PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier,
271                                      PvmiKvp*& aParameters, int& num_parameter_elements, PvmiCapabilityContext aContext);
272 
273         PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
274 
275         void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
276 
277         void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext,
278                                   PvmiKvp* aParameters, int num_parameter_elements);
279 
280         void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
281 
282         void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
283                                int num_elements, PvmiKvp * & aRet_kvp);
284 
285         PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters,
286                                          int num_elements, PvmiKvp*& aRet_kvp, OsclAny* context = NULL);
287 
288         uint32 getCapabilityMetric(PvmiMIOSession aSession);
289 
290         PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
291 
292         void setFormatMask(uint32 mask);
293 
294         void UpdateWaveChunkSize();
295 
296         void WriteHeaders();
297         void InitializeAVI(int width, int height);
298         void AddChunk(uint8* chunk, uint32 size, uint32 ckid);
299         int32 yuv2rgb(uint8 * pBufRGBRev, uint8 * pBufYUV, int32 width, int32 height);
300         void UpdateVideoChunkHeaderIdx();
301 
302         //from PvmiClockExtensionInterface
303         OSCL_IMPORT_REF PVMFStatus SetClock(PVMFMediaClock *clockVal) ;
304 
305         //from PVInterface
306         OSCL_IMPORT_REF void addRef() ;
307         OSCL_IMPORT_REF void removeRef() ;
308         OSCL_IMPORT_REF bool queryInterface(const PVUuid& uuid, PVInterface*& iface) ;
309         void queryUuid(PVUuid& uuid);
310 
311     private:
312         void initData();
313 
314         // From OsclTimerObject
315         void Run();
316 
317         void Reschedule();
318 
319         void Cleanup();
320         void ResetData();
321 
322         PvmiMediaTransfer* iPeer;
323 
324         // The PvmiMIOControl class observer.
325         PvmiMIOObserver* iObserver;
326 
327         //for generating command IDs
328         uint32 iCommandCounter;
329 
330         //State
331         enum PVRefFOState
332         {
333             STATE_IDLE
334             , STATE_LOGGED_ON
335             , STATE_INITIALIZED
336             , STATE_STARTED
337             , STATE_PAUSED
338         };
339         PVRefFOState iState;
340 
341         //Control command handling.
342         class CommandResponse
343         {
344             public:
CommandResponse(PVMFStatus s,PVMFCommandId id,const OsclAny * ctx)345                 CommandResponse(PVMFStatus s, PVMFCommandId id, const OsclAny* ctx)
346                         : iStatus(s), iCmdId(id), iContext(ctx)
347                 {}
348 
349                 PVMFStatus iStatus;
350                 PVMFCommandId iCmdId;
351                 const OsclAny* iContext;
352         };
353         Oscl_Vector<CommandResponse, OsclMemAllocator> iCommandResponseQueue;
354         void QueueCommandResponse(CommandResponse&);
355 
356         //Write command handling
357         class WriteResponse
358         {
359             public:
WriteResponse(PVMFStatus s,PVMFCommandId id,const OsclAny * ctx,const PVMFTimestamp & ts,bool discard)360                 WriteResponse(PVMFStatus s, PVMFCommandId id, const OsclAny* ctx, const PVMFTimestamp& ts, bool discard)
361                         : iStatus(s), iCmdId(id), iContext(ctx), iTimestamp(ts), iDiscard(discard)
362                 {}
363 
364                 PVMFStatus iStatus;
365                 PVMFCommandId iCmdId;
366                 const OsclAny* iContext;
367                 PVMFTimestamp iTimestamp;
368                 bool iDiscard;
369         };
370         Oscl_Vector<WriteResponse, OsclMemAllocator> iWriteResponseQueue;
371 
372         // Output file parameters
373         OSCL_wHeapString<OsclMemAllocator> iOutputFileName;
374         Oscl_FileServer iFs;
375         bool iFsConnected;
376         Oscl_File iOutputFile;
377         bool iFileOpened;
378 
379         // Audio parameters.
380         OSCL_HeapString<OsclMemAllocator> iAudioFormatString;
381         PVMFFormatType iAudioFormat;
382         int32 iAudioNumChannels;
383         bool iAudioNumChannelsValid;
384         int32 iAudioSamplingRate;
385         bool iAudioSamplingRateValid;
386 
387         // Video parameters
388         OSCL_HeapString<OsclMemAllocator> iVideoFormatString;
389         PVMFFormatType iVideoFormat;
390         int32 iVideoHeight;
391         bool iVideoHeightValid;
392         int32 iVideoWidth;
393         bool iVideoWidthValid;
394         int32 iVideoDisplayHeight;
395         bool iVideoDisplayHeightValid;
396         int32 iVideoDisplayWidth;
397         bool iVideoDisplayWidthValid;
398 
399         int32 iNumberOfBuffers;
400         int32 iBufferSize;
401 
402         // Text parameters
403         OSCL_HeapString<OsclMemAllocator> iTextFormatString;
404         PVMFFormatType iTextFormat;
405 
406         //For logging
407         PVLogger* iLogger;
408 
409         //A switch for selecting whether to log some strings along
410         //with the media data in the output file.
411         bool iLogStrings;
412         bool iParametersLogged;
413         void LogParameters();
414         void LogFrame(uint32 aSeqNum, const PVMFTimestamp& aTimestamp, uint32);
415         void LogEndOfStream(uint32 aSeqNum, const PVMFTimestamp& aTimestamp);
416         void LogCodecHeader(uint32 aSeqNum, const PVMFTimestamp& aTimestamp, uint32);
417 
418         //For implementing the write flow control
419         bool iWriteBusy;
420         uint32 iWriteBusySeqNum;
421         bool CheckWriteBusy(uint32);
422 
423         //a test feature for testing flow control in the peer.
424         bool iSimFlowControl;
425 
426         //a test observer class
427         PVRefFileOutputTestObserver* iTestObserver;
428 
429         //a test feature for simulating active timing.
430         PVRefFileOutputActiveTimingSupport* iActiveTiming;
431 
432         //a test feature to allow the commands such as GetCapability
433         //to return a distinctive format type
434         uint32 iFormatMask;
435 
436         //called when re-config notification is recvd
437         PVMFStatus HandleReConfig(uint32 aReconfigSeqNum);
438 
439         //if iUseClockExtension set to true, no data is dropped
440         bool iUseClockExtension;
441 
442         //Used for deciding when to send ConfigComplete event to MIO node
443         bool iIsMIOConfigured;
444 
445         // used to create the WAV file output.
446         RIFFChunk    iRIFFChunk;
447         fmtSubchunk  iFmtSubchunk;
448         dataSubchunk iDataSubchunk;
449         bool         iHeaderWritten;
450         PVMFTimestamp iVideoLastTimeStamp;
451         bool         iInitializeAVIDone;
452 
453         AVIMainHeader iAVIMainHeader;
454         AVIStreamHeader iAVIStreamHeader;
455         BitMapInfoHeader bi_hdr;
456         AVIIndex         iAVIIndex;
457         uint32        iAVIChunkSize;
458         uint32        iVideoHeaderPosition;
459         IndexBuffer   iIndexBuffer;
460         uint32        iAVIMainHeaderPosition;
461         uint32        iAVIStreamHeaderPosition;
462         uint32        iVideoCount;
463         uint32        iPreviousOffset;
464 
465         MediaType     iMediaType;
466         bool          iCompressedMedia;
467         PVMFMediaClock* iClock;
468         const bool iLogOutputToFile;
469 };
470 
471 //An observer class for test support.
472 class PVRefFileOutputTestObserver
473 {
474     public:
~PVRefFileOutputTestObserver()475         virtual ~PVRefFileOutputTestObserver() {}
476 
477         OSCL_IMPORT_REF virtual void Pos(PVMFTimestamp& aTimestamp) = 0;
478 };
479 
480 #if TEST_BUFFER_ALLOCATOR
481 
482 class PVRefBufferAlloc: public PVInterface, public PVMFFixedSizeBufferAlloc
483 {
484     public:
485 
486         PVRefBufferAlloc(uint32 size, uint32 buffers);
487 
488         virtual ~PVRefBufferAlloc();
489 
490         virtual void addRef();
491 
492         virtual void removeRef();
493 
494         virtual bool queryInterface(const PVUuid& uuid, PVInterface*& aInterface) ;
495 
496         virtual OsclAny* allocate();
497 
498         virtual void deallocate(OsclAny* ptr) ;
499 
500         virtual uint32 getBufferSize() ;
501 
502         virtual uint32 getNumBuffers() ;
503 
504     private:
505         int32 refCount;
506         int32 bufferSize;
507         int32 maxBuffers;
508         int32 numAllocated;
509 };
510 
511 #endif
512 
513 #endif // PVMI_MEDIA_IO_FILEOUTPUT_H_INCLUDED
514 
515