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 pvmi_io_interface_node_inport.h
     21  * @brief Input port for media io interface wrapper node
     22  *
     23  */
     24 
     25 #ifndef PV_MEDIA_OUTPUT_NODE_INPORT_H_INCLUDED
     26 #define PV_MEDIA_OUTPUT_NODE_INPORT_H_INCLUDED
     27 
     28 #ifndef OSCL_BASE_H_INCLUDED
     29 #include "oscl_base.h"
     30 #endif
     31 #ifndef OSCL_VECTOR_H_INCLUDED
     32 #include "oscl_vector.h"
     33 #endif
     34 #ifndef OSCL_MEM_H_INCLUDED
     35 #include "oscl_mem.h"
     36 #endif
     37 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED
     38 #include "oscl_scheduler_ao.h"
     39 #endif
     40 #ifndef PVMF_MEDIA_DATA_H_INCLUDED
     41 #include "pvmf_media_data.h"
     42 #endif
     43 #ifndef PVMF_PORT_BASE_IMPL_H_INCLUDED
     44 #include "pvmf_port_base_impl.h"
     45 #endif
     46 #ifndef PVMI_MEDIA_TRANSFER_H_INCLUDED
     47 #include "pvmi_media_transfer.h"
     48 #endif
     49 #ifndef PVMF_NODES_SYNC_CONTROL_H_INCLUDED
     50 #include "pvmf_nodes_sync_control.h"
     51 #endif
     52 #ifndef PVMF_SYNC_UTIL_DATA_QUEUE_H_INCLUDED
     53 #include "pvmf_sync_util_data_queue.h"
     54 #endif
     55 #ifndef PVMI_KVP_H_INCLUDED
     56 #include "pvmi_kvp.h"
     57 #endif
     58 #ifndef PVMF_NODE_INTERFACE_H_INCLUDED
     59 #include "pvmf_node_interface.h"
     60 #endif
     61 #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED
     62 #include "pvmi_config_and_capability.h"
     63 #endif
     64 #ifndef OSCL_STRING_CONTAINERS_H_INCLUDED
     65 #include "oscl_string_containers.h"
     66 #endif
     67 
     68 // Forward declaration
     69 class PVMediaOutputNode;
     70 
     71 enum PVMFMediaOutputNodePortMediaTimeStatus
     72 {
     73     PVMF_MEDIAOUTPUTNODEPORT_MEDIA_ERROR,
     74     PVMF_MEDIAOUTPUTNODEPORT_MEDIA_ON_TIME,
     75     PVMF_MEDIAOUTPUTNODEPORT_MEDIA_LATE,
     76     PVMF_MEDIAOUTPUTNODEPORT_MEDIA_EARLY
     77 };
     78 
     79 #define THRESHOLD_FOR_DROPPED_VIDEO_FRAMES 120
     80 
     81 class PVMediaOutputNodePort : public OsclTimerObject
     82         , public PvmfPortBaseImpl
     83         , public PvmfNodesSyncControlInterface
     84         , public PvmiMediaTransfer
     85         , public PVMFPortActivityHandler
     86         , public PvmiCapabilityAndConfig
     87         , public PVMFMediaClockObserver
     88         , public PVMFMediaClockStateObserver
     89         , public PVMFMediaClockNotificationsObs
     90 {
     91     public:
     92         PVMediaOutputNodePort(PVMediaOutputNode* aNode);
     93         ~PVMediaOutputNodePort();
     94 
     95         void NodeStarted();
     96 
     97         PVMFStatus Configure(OSCL_String&);
     98         void PutData(PVMFSharedMediaMsgPtr& aMsg);
     99 
    100         //these override the PvmfPortBaseImpl routines
    101         OSCL_IMPORT_REF PVMFStatus Connect(PVMFPortInterface* aPort);
    102         OSCL_IMPORT_REF PVMFStatus Disconnect();
    103         OSCL_IMPORT_REF PVMFStatus PeerConnect(PVMFPortInterface* aPort);
    104         OSCL_IMPORT_REF PVMFStatus PeerDisconnect();
    105         OSCL_IMPORT_REF PVMFStatus ClearMsgQueues();
    106 
    107         //from PVMFPortActivityHandler
    108         void HandlePortActivity(const PVMFPortActivity& aActivity);
    109 
    110         // Pure virtual from PVInterface
    111         void addRef();
    112         void removeRef();
    113         bool queryInterface(const PVUuid& uuid, PVInterface*& iface);
    114 
    115         // Pure virtuals from PvmfNodesSyncControlInterface
    116         PVMFStatus SetClock(PVMFMediaClock* aClock);
    117         PVMFStatus ChangeClockRate(int32 aRate);
    118         PVMFStatus SetMargins(int32 aEarlyMargin, int32 aLateMargin);
    119         void ClockStarted();
    120         void ClockStopped();
    121         PVMFCommandId SkipMediaData(int32,
    122                                     PVMFTimestamp aResumeTimestamp,
    123                                     uint32 aStreamID,
    124                                     bool aPlayBackPositionContinuous = false,
    125                                     OsclAny* aContext = NULL)
    126         {
    127             OSCL_UNUSED_ARG(aResumeTimestamp);
    128             OSCL_UNUSED_ARG(aStreamID);
    129             OSCL_UNUSED_ARG(aPlayBackPositionContinuous);
    130             OSCL_UNUSED_ARG(aContext);
    131             OSCL_LEAVE(OsclErrNotSupported);
    132             return -1;
    133         }
    134 
    135         //active vs passive mio
    136         void EnableMediaSync();
    137 
    138         // Pure virtuals from PvmfSyncUtilDataQueueObserver
    139         void ScheduleProcessData(PvmfSyncUtilDataQueue* aDataQueue, uint32 aTimeMilliseconds);
    140         // sends and info event to engine when the skipping of data is complete
    141         void SkipMediaDataComplete();
    142         // after seeing bos for every skipmediadata command issues command complete to engine
    143         void SkipMediaCommandComplete();
    144 
    145         // Pure virtuals from PvmiMediaTransfer
    146         void setPeer(PvmiMediaTransfer *aPeer);
    147         void useMemoryAllocators(OsclMemAllocator* write_alloc = NULL);
    148         PVMFCommandId writeAsync(uint8 format_type, int32 format_index, uint8* data, uint32 data_len,
    149                                  const PvmiMediaXferHeader& data_header_info, OsclAny* aContext = NULL);
    150         void writeComplete(PVMFStatus aStatus, PVMFCommandId write_cmd_id, OsclAny* aContext);
    151         PVMFCommandId readAsync(uint8* data, uint32 max_data_len, OsclAny* aContext = NULL,
    152                                 int32* formats = NULL, uint16 num_formats = 0);
    153         void readComplete(PVMFStatus aStatus, PVMFCommandId  read_cmd_id, int32 format_index,
    154                           const PvmiMediaXferHeader& data_header_info, OsclAny* aContext);
    155         void statusUpdate(uint32 status_flags);
    156         void cancelCommand(PVMFCommandId  command_id);
    157         void cancelAllCommands();
    158 
    159         // Implement pure virtuals from PvmiCapabilityAndConfig interface
    160         OSCL_IMPORT_REF virtual PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier,
    161                 PvmiKvp*& aParameters, int& num_parameter_elements, PvmiCapabilityContext aContext);
    162         OSCL_IMPORT_REF virtual PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
    163         OSCL_IMPORT_REF virtual void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
    164                 int num_elements, PvmiKvp * & aRet_kvp);
    165         OSCL_IMPORT_REF virtual PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
    166 
    167         // Unsupported PvmiCapabilityAndConfig methods
    168         void virtual setObserver(PvmiConfigAndCapabilityCmdObserver*) {};
    169         void virtual createContext(PvmiMIOSession , PvmiCapabilityContext&) {};
    170         void virtual setContextParameters(PvmiMIOSession , PvmiCapabilityContext& , PvmiKvp* , int) {};
    171         void virtual DeleteContext(PvmiMIOSession , PvmiCapabilityContext&) {};
    172         PVMFCommandId virtual setParametersAsync(PvmiMIOSession , PvmiKvp* , int , PvmiKvp*& , OsclAny* context = NULL)
    173         {
    174             OSCL_UNUSED_ARG(context);
    175             return -1;
    176         }
    177         uint32 virtual getCapabilityMetric(PvmiMIOSession)
    178         {
    179             return 0;
    180         }
    181 
    182         // To support config interface
    183         void QueryInterface(const PVUuid &aUuid, OsclAny*&aPtr)
    184         {
    185             if (aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
    186             {
    187                 aPtr = (PvmiCapabilityAndConfig*)this;
    188             }
    189             else
    190             {
    191                 aPtr = NULL;
    192             }
    193         }
    194 
    195         //From PVMFMediaClockObserver
    196         void ClockTimebaseUpdated();
    197         void ClockCountUpdated();
    198         void ClockAdjusted();
    199         //From OsclClockStateObserver
    200         void ClockStateUpdated();
    201         void NotificationsInterfaceDestroyed();
    202 
    203         //To allow the node to set the port format.
    204         PVMFFormatType iPortFormat;
    205         bool IsFormatSupported(PVMFFormatType);
    206         void FormatUpdated();
    207 
    208         //for processing the callbacks for the notifications requested to iClockNotificationsInf
    209         void ProcessCallBack(uint32 callBackID, PVTimeComparisonUtils::MediaTimeStatus aTimerAccuracy, uint32 aDelta, const OsclAny* aContextData, PVMFStatus aStatus);
    210 
    211         void ProcessIncomingMessageIfPossible();
    212         // MIO node sets this status when MIO component's config is complete.
    213         void SetMIOComponentConfigStatus(bool aStatus);
    214 
    215         void SetSkipTimeStamp(uint32 aSkipTS, uint32 aStreamID);
    216         void CancelSkip();
    217 
    218         bool isUnCompressedMIO;
    219         uint32 iFramesDropped;
    220         uint32 iTotalFrames;
    221 
    222         //BOS related
    223         Oscl_Vector<uint32, OsclMemAllocator> iBOSStreamIDVec;
    224         void ClearPreviousBOSStreamIDs(uint32 aID);
    225 
    226         int32 WriteDataToMIO(int32 &aCmdId, PvmiMediaXferHeader &aMediaxferhdr, OsclRefCounterMemFrag &aFrag);
    227         PvmiMediaTransfer* getMediaTransfer()
    228         {
    229             return iMediaTransfer;
    230         }
    231     private:
    232         void Run();
    233         bool peekHead(PVMFSharedMediaMsgPtr& dataPtr, bool& bBos);
    234         PVMFStatus ConfigMIO(PvmiKvp* aParameters, PvmiKvp* &aRetParameters);
    235         PVMFStatus SetMIOParameterInt32(PvmiKeyType aKey, int32 aValue);
    236         PVMFStatus SetMIOParameterUint32(PvmiKeyType aKey, uint32 aValue);
    237         PVMFStatus SetMIOParameterPchar(PvmiKeyType aKey, char* aValue);
    238         PVMFStatus SetMIOParameterFormat(PvmiKeyType aKey, PVMFFormatType aFormatType);
    239 
    240         // Container node
    241         PVMediaOutputNode* iNode;
    242 
    243         uint32 iExtensionRefCount;
    244         OSCL_HeapString<OsclMemAllocator> iSinkFormatString;
    245         PVMFFormatType iSinkFormat;
    246 
    247         //data transfer related
    248         PvmiMediaTransfer* iMediaTransfer;
    249         PVMFCommandId iMioInfoErrorCmdId;
    250         enum PVMFMediaType
    251         {
    252             PVMF_MEDIA_UNKNOWN = 0,
    253             PVMF_MEDIA_UNCOMPRESSED_AUDIO,
    254             PVMF_MEDIA_COMPRESSED_AUDIO,
    255             PVMF_MEDIA_UNCOMPRESSED_VIDEO,
    256             PVMF_MEDIA_COMPRESSED_VIDEO,
    257             PVMF_MEDIA_TEXT
    258         } iMediaType;
    259         enum WriteState {EWriteBusy, EWriteWait, EWriteOK};
    260         WriteState iWriteState;
    261         //media data cleanup queue
    262         class CleanupQueueElement
    263         {
    264             public:
    265                 CleanupQueueElement(PVMFSharedMediaDataPtr d, PVMFCommandId id): iData(d), iCmdId(id) {}
    266                 CleanupQueueElement(PVMFCommandId id): iCmdId(id) {}
    267                 PVMFSharedMediaDataPtr iData;
    268                 PVMFCommandId iCmdId;
    269         };
    270         Oscl_Vector<CleanupQueueElement, OsclMemAllocator> iCleanupQueue;
    271         uint32 iWriteAsyncContext;
    272         uint32 iWriteAsyncEOSContext;
    273         uint32 iWriteAsyncReConfigContext;
    274         PVMFMediaClock* iClock;
    275         PVMFMediaClockNotificationsInterface *iClockNotificationsInf;
    276         bool oClockCallBackPending;
    277         uint32 iDelayEarlyFrameCallBkId;
    278         int32 iClockRate;
    279         uint32 iEarlyMargin;
    280         uint32 iLateMargin;
    281         bool oActiveMediaOutputComp;
    282         bool oProcessIncomingMessage;
    283         bool oMIOComponentConfigured;
    284         uint32 iConsecutiveFramesDropped;
    285         bool iLateFrameEventSent;
    286         PVMFSharedMediaMsgPtr iCurrentMediaMsg;
    287         uint32 iFragIndex;
    288         //for sending any data
    289         void SendData();
    290         //for sending media data to the Mout.
    291         void SendMediaData();
    292         //for sending the end-of-data notice to the Mout.
    293         void SendEndOfData();
    294         //for sending reconfig notice to the Mout
    295         void SendReConfigNotification();
    296         void ClearCleanupQueue();
    297         void CleanupMediaTransfer();
    298 
    299         //skip related
    300         PVMFMediaOutputNodePortMediaTimeStatus CheckMediaTimeStamp(uint32& aDelta);
    301         PVMFMediaOutputNodePortMediaTimeStatus CheckMediaFrameStep();
    302         uint32 iRecentStreamID;
    303 
    304         //iEosStreamIDVec is used as a FIFO to store the steamids of eos sent to mio comp.
    305         //streamid is pushed in at front when call writeasync(eos) to mio comp.
    306         //streamid is poped out from end when mio comp. calls writecomplete(eos),
    307         //we report PVMFInfoEndOfData with the poped streamid.
    308         //This logic depends on Mio comp. process data(at least eos msg) in a sequencial style.
    309         Oscl_Vector<uint32, OsclMemAllocator> iEosStreamIDVec;
    310         uint32 iSkipTimestamp;
    311         bool iSendStartOfDataEvent;
    312         bool DataToSkip(PVMFSharedMediaMsgPtr& aMsg);
    313 
    314         //frame step related
    315         bool iFrameStepMode;
    316         int32 iClockFrameCount;
    317         int32 iSyncFrameCount;
    318 
    319         //for datapath logging
    320         void LogMediaDataInfo(const char* msg, PVMFSharedMediaDataPtr mediaData, int32 p1, int32 p2);
    321         void LogMediaDataInfo(const char* msg, PVMFSharedMediaDataPtr mediaData);
    322         void LogDatapath(const char* msg);
    323 
    324         OsclErrorTrapImp* iOsclErrorTrapImp;
    325         PVLogger* iLogger;
    326         PVLogger* iDatapathLogger;
    327         PVLogger* iDatapathLoggerIn;
    328         PVLogger* iDatapathLoggerOut;
    329         PVLogger* iReposLogger;
    330 
    331 };
    332 
    333 #endif // PVMI_IO_INTERFACE_NODE_INPORT_H_INCLUDED
    334