blob: e57ed350315ae220b338e5e159ead9501ec54619 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
/**
*
* @file pvmi_io_interface_node_inport.h
* @brief Input port for media io interface wrapper node
*
*/
#ifndef PV_MEDIA_OUTPUT_NODE_INPORT_H_INCLUDED
#define PV_MEDIA_OUTPUT_NODE_INPORT_H_INCLUDED
#ifndef OSCL_BASE_H_INCLUDED
#include "oscl_base.h"
#endif
#ifndef OSCL_VECTOR_H_INCLUDED
#include "oscl_vector.h"
#endif
#ifndef OSCL_MEM_H_INCLUDED
#include "oscl_mem.h"
#endif
#ifndef OSCL_SCHEDULER_AO_H_INCLUDED
#include "oscl_scheduler_ao.h"
#endif
#ifndef PVMF_MEDIA_DATA_H_INCLUDED
#include "pvmf_media_data.h"
#endif
#ifndef PVMF_PORT_BASE_IMPL_H_INCLUDED
#include "pvmf_port_base_impl.h"
#endif
#ifndef PVMI_MEDIA_TRANSFER_H_INCLUDED
#include "pvmi_media_transfer.h"
#endif
#ifndef PVMF_NODES_SYNC_CONTROL_H_INCLUDED
#include "pvmf_nodes_sync_control.h"
#endif
#ifndef PVMF_SYNC_UTIL_DATA_QUEUE_H_INCLUDED
#include "pvmf_sync_util_data_queue.h"
#endif
#ifndef PVMI_KVP_H_INCLUDED
#include "pvmi_kvp.h"
#endif
#ifndef PVMF_NODE_INTERFACE_H_INCLUDED
#include "pvmf_node_interface.h"
#endif
#ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED
#include "pvmi_config_and_capability.h"
#endif
#ifndef OSCL_STRING_CONTAINERS_H_INCLUDED
#include "oscl_string_containers.h"
#endif
// Forward declaration
class PVMediaOutputNode;
enum PVMFMediaOutputNodePortMediaTimeStatus
{
PVMF_MEDIAOUTPUTNODEPORT_MEDIA_ERROR,
PVMF_MEDIAOUTPUTNODEPORT_MEDIA_ON_TIME,
PVMF_MEDIAOUTPUTNODEPORT_MEDIA_LATE,
PVMF_MEDIAOUTPUTNODEPORT_MEDIA_EARLY
};
#define THRESHOLD_FOR_DROPPED_VIDEO_FRAMES 120
class PVMediaOutputNodePort : public OsclTimerObject
, public PvmfPortBaseImpl
, public PvmfNodesSyncControlInterface
, public PvmiMediaTransfer
, public PVMFPortActivityHandler
, public PvmiCapabilityAndConfig
, public PVMFMediaClockObserver
, public PVMFMediaClockStateObserver
, public PVMFMediaClockNotificationsObs
{
public:
PVMediaOutputNodePort(PVMediaOutputNode* aNode);
~PVMediaOutputNodePort();
void NodeStarted();
PVMFStatus Configure(OSCL_String&);
void PutData(PVMFSharedMediaMsgPtr& aMsg);
//these override the PvmfPortBaseImpl routines
OSCL_IMPORT_REF PVMFStatus Connect(PVMFPortInterface* aPort);
OSCL_IMPORT_REF PVMFStatus Disconnect();
OSCL_IMPORT_REF PVMFStatus PeerConnect(PVMFPortInterface* aPort);
OSCL_IMPORT_REF PVMFStatus PeerDisconnect();
OSCL_IMPORT_REF PVMFStatus ClearMsgQueues();
//from PVMFPortActivityHandler
void HandlePortActivity(const PVMFPortActivity& aActivity);
// Pure virtual from PVInterface
void addRef();
void removeRef();
bool queryInterface(const PVUuid& uuid, PVInterface*& iface);
// Pure virtuals from PvmfNodesSyncControlInterface
PVMFStatus SetClock(PVMFMediaClock* aClock);
PVMFStatus ChangeClockRate(int32 aRate);
PVMFStatus SetMargins(int32 aEarlyMargin, int32 aLateMargin);
void ClockStarted();
void ClockStopped();
PVMFCommandId SkipMediaData(int32,
PVMFTimestamp aResumeTimestamp,
uint32 aStreamID,
bool aPlayBackPositionContinuous = false,
OsclAny* aContext = NULL)
{
OSCL_UNUSED_ARG(aResumeTimestamp);
OSCL_UNUSED_ARG(aStreamID);
OSCL_UNUSED_ARG(aPlayBackPositionContinuous);
OSCL_UNUSED_ARG(aContext);
OSCL_LEAVE(OsclErrNotSupported);
return -1;
}
//active vs passive mio
void EnableMediaSync();
// Pure virtuals from PvmfSyncUtilDataQueueObserver
void ScheduleProcessData(PvmfSyncUtilDataQueue* aDataQueue, uint32 aTimeMilliseconds);
// sends and info event to engine when the skipping of data is complete
void SkipMediaDataComplete();
// after seeing bos for every skipmediadata command issues command complete to engine
void SkipMediaCommandComplete();
// Pure virtuals from PvmiMediaTransfer
void setPeer(PvmiMediaTransfer *aPeer);
void useMemoryAllocators(OsclMemAllocator* write_alloc = NULL);
PVMFCommandId writeAsync(uint8 format_type, int32 format_index, uint8* data, uint32 data_len,
const PvmiMediaXferHeader& data_header_info, OsclAny* aContext = NULL);
void writeComplete(PVMFStatus aStatus, PVMFCommandId write_cmd_id, OsclAny* aContext);
PVMFCommandId readAsync(uint8* data, uint32 max_data_len, OsclAny* aContext = NULL,
int32* formats = NULL, uint16 num_formats = 0);
void readComplete(PVMFStatus aStatus, PVMFCommandId read_cmd_id, int32 format_index,
const PvmiMediaXferHeader& data_header_info, OsclAny* aContext);
void statusUpdate(uint32 status_flags);
void cancelCommand(PVMFCommandId command_id);
void cancelAllCommands();
// Implement pure virtuals from PvmiCapabilityAndConfig interface
OSCL_IMPORT_REF virtual PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier,
PvmiKvp*& aParameters, int& num_parameter_elements, PvmiCapabilityContext aContext);
OSCL_IMPORT_REF virtual PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
OSCL_IMPORT_REF virtual void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
int num_elements, PvmiKvp * & aRet_kvp);
OSCL_IMPORT_REF virtual PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements);
// Unsupported PvmiCapabilityAndConfig methods
void virtual setObserver(PvmiConfigAndCapabilityCmdObserver*) {};
void virtual createContext(PvmiMIOSession , PvmiCapabilityContext&) {};
void virtual setContextParameters(PvmiMIOSession , PvmiCapabilityContext& , PvmiKvp* , int) {};
void virtual DeleteContext(PvmiMIOSession , PvmiCapabilityContext&) {};
PVMFCommandId virtual setParametersAsync(PvmiMIOSession , PvmiKvp* , int , PvmiKvp*& , OsclAny* context = NULL)
{
OSCL_UNUSED_ARG(context);
return -1;
}
uint32 virtual getCapabilityMetric(PvmiMIOSession)
{
return 0;
}
// To support config interface
void QueryInterface(const PVUuid &aUuid, OsclAny*&aPtr)
{
if (aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
{
aPtr = (PvmiCapabilityAndConfig*)this;
}
else
{
aPtr = NULL;
}
}
//From PVMFMediaClockObserver
void ClockTimebaseUpdated();
void ClockCountUpdated();
void ClockAdjusted();
//From OsclClockStateObserver
void ClockStateUpdated();
void NotificationsInterfaceDestroyed();
//To allow the node to set the port format.
PVMFFormatType iPortFormat;
bool IsFormatSupported(PVMFFormatType);
void FormatUpdated();
//for processing the callbacks for the notifications requested to iClockNotificationsInf
void ProcessCallBack(uint32 callBackID, PVTimeComparisonUtils::MediaTimeStatus aTimerAccuracy, uint32 aDelta, const OsclAny* aContextData, PVMFStatus aStatus);
void ProcessIncomingMessageIfPossible();
// MIO node sets this status when MIO component's config is complete.
void SetMIOComponentConfigStatus(bool aStatus);
void SetSkipTimeStamp(uint32 aSkipTS, uint32 aStreamID);
void CancelSkip();
bool isUnCompressedMIO;
uint32 iFramesDropped;
uint32 iTotalFrames;
//BOS related
Oscl_Vector<uint32, OsclMemAllocator> iBOSStreamIDVec;
void ClearPreviousBOSStreamIDs(uint32 aID);
int32 WriteDataToMIO(int32 &aCmdId, PvmiMediaXferHeader &aMediaxferhdr, OsclRefCounterMemFrag &aFrag);
PvmiMediaTransfer* getMediaTransfer()
{
return iMediaTransfer;
}
private:
void Run();
bool peekHead(PVMFSharedMediaMsgPtr& dataPtr, bool& bBos);
PVMFStatus ConfigMIO(PvmiKvp* aParameters, PvmiKvp* &aRetParameters);
PVMFStatus SetMIOParameterInt32(PvmiKeyType aKey, int32 aValue);
PVMFStatus SetMIOParameterUint32(PvmiKeyType aKey, uint32 aValue);
PVMFStatus SetMIOParameterPchar(PvmiKeyType aKey, char* aValue);
PVMFStatus SetMIOParameterFormat(PvmiKeyType aKey, PVMFFormatType aFormatType);
// Container node
PVMediaOutputNode* iNode;
uint32 iExtensionRefCount;
OSCL_HeapString<OsclMemAllocator> iSinkFormatString;
PVMFFormatType iSinkFormat;
//data transfer related
PvmiMediaTransfer* iMediaTransfer;
PVMFCommandId iMioInfoErrorCmdId;
enum PVMFMediaType
{
PVMF_MEDIA_UNKNOWN = 0,
PVMF_MEDIA_UNCOMPRESSED_AUDIO,
PVMF_MEDIA_COMPRESSED_AUDIO,
PVMF_MEDIA_UNCOMPRESSED_VIDEO,
PVMF_MEDIA_COMPRESSED_VIDEO,
PVMF_MEDIA_TEXT
} iMediaType;
enum WriteState {EWriteBusy, EWriteWait, EWriteOK};
WriteState iWriteState;
//media data cleanup queue
class CleanupQueueElement
{
public:
CleanupQueueElement(PVMFSharedMediaDataPtr d, PVMFCommandId id): iData(d), iCmdId(id) {}
CleanupQueueElement(PVMFCommandId id): iCmdId(id) {}
PVMFSharedMediaDataPtr iData;
PVMFCommandId iCmdId;
};
Oscl_Vector<CleanupQueueElement, OsclMemAllocator> iCleanupQueue;
uint32 iWriteAsyncContext;
uint32 iWriteAsyncEOSContext;
uint32 iWriteAsyncReConfigContext;
PVMFMediaClock* iClock;
PVMFMediaClockNotificationsInterface *iClockNotificationsInf;
bool oClockCallBackPending;
uint32 iDelayEarlyFrameCallBkId;
int32 iClockRate;
uint32 iEarlyMargin;
uint32 iLateMargin;
bool oActiveMediaOutputComp;
bool oProcessIncomingMessage;
bool oMIOComponentConfigured;
uint32 iConsecutiveFramesDropped;
bool iLateFrameEventSent;
PVMFSharedMediaMsgPtr iCurrentMediaMsg;
uint32 iFragIndex;
//for sending any data
void SendData();
//for sending media data to the Mout.
void SendMediaData();
//for sending the end-of-data notice to the Mout.
void SendEndOfData();
//for sending reconfig notice to the Mout
void SendReConfigNotification();
void ClearCleanupQueue();
void CleanupMediaTransfer();
//skip related
PVMFMediaOutputNodePortMediaTimeStatus CheckMediaTimeStamp(uint32& aDelta);
PVMFMediaOutputNodePortMediaTimeStatus CheckMediaFrameStep();
uint32 iRecentStreamID;
//iEosStreamIDVec is used as a FIFO to store the steamids of eos sent to mio comp.
//streamid is pushed in at front when call writeasync(eos) to mio comp.
//streamid is poped out from end when mio comp. calls writecomplete(eos),
//we report PVMFInfoEndOfData with the poped streamid.
//This logic depends on Mio comp. process data(at least eos msg) in a sequencial style.
Oscl_Vector<uint32, OsclMemAllocator> iEosStreamIDVec;
uint32 iSkipTimestamp;
bool iSendStartOfDataEvent;
bool DataToSkip(PVMFSharedMediaMsgPtr& aMsg);
//frame step related
bool iFrameStepMode;
int32 iClockFrameCount;
int32 iSyncFrameCount;
//for datapath logging
void LogMediaDataInfo(const char* msg, PVMFSharedMediaDataPtr mediaData, int32 p1, int32 p2);
void LogMediaDataInfo(const char* msg, PVMFSharedMediaDataPtr mediaData);
void LogDatapath(const char* msg);
OsclErrorTrapImp* iOsclErrorTrapImp;
PVLogger* iLogger;
PVLogger* iDatapathLogger;
PVLogger* iDatapathLoggerIn;
PVLogger* iDatapathLoggerOut;
PVLogger* iReposLogger;
};
#endif // PVMI_IO_INTERFACE_NODE_INPORT_H_INCLUDED