Home | History | Annotate | Download | only in src
      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:
     93         void* allocate(const uint32 size)
     94         {
     95             void* tmp = (void*)oscl_malloc(size);
     96             return tmp;
     97         }
     98 
     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
    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         }
    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