blob: c5db838762f39e18614fbe78296bd15e6db151e4 [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.
* -------------------------------------------------------------------
*/
#ifndef PVMF_OMX_BASEDEC_NODE_H_INCLUDED
#define PVMF_OMX_BASEDEC_NODE_H_INCLUDED
#ifndef OSCL_BASE_H_INCLUDED
#include "oscl_base.h"
#endif
#ifndef OSCL_SCHEDULER_AO_H_INCLUDED
#include "oscl_scheduler_ao.h"
#endif
#ifndef PVMF_FORMAT_TYPE_H_INCLUDED
#include "pvmf_format_type.h"
#endif
#ifndef PVMF_NODE_INTERFACE_H_INCLUDED
#include "pvmf_node_interface.h"
#endif
#ifndef OSCL_PRIQUEUE_H_INCLUDED
#include "oscl_priqueue.h"
#endif
#ifndef PVMF_MEDIA_DATA_H_INCLUDED
#include "pvmf_media_data.h"
#endif
#ifndef OSCL_MEM_MEMPOOL_H_INCLUDED
#include "oscl_mem_mempool.h"
#endif
#ifndef PVMF_MEMPOOL_H_INCLUDED
#include "pvmf_mempool.h"
#endif
#ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED
#include "pvmf_simple_media_buffer.h"
#endif
#ifndef PVMF_POOL_BUFFER_ALLOCATOR_H_INCLUDED
#include "pvmf_pool_buffer_allocator.h"
#endif
#ifndef PVMF_POOL_BUFFER_ALLOCATOR_H_INCLUDED
#include "pvmf_pool_buffer_allocator.h"
#endif
#ifndef PVMF_NODE_UTILS_H_INCLUDED
#include "pvmf_node_utils.h"
#endif
#ifndef PVMF_OMX_BASEDEC_PORT_H_INCLUDED
#include "pvmf_omx_basedec_port.h"
#endif
#ifndef PVMF_OMX_BASEDEC_NODE_EXTENSION_INTERFACE_H_INCLUDED
#include "pvmf_omx_basedec_node_extension_interface.h"
#endif
#ifndef PVMF_META_DATA_EXTENSION_H_INCLUDED
#include "pvmf_meta_data_extension.h"
#endif
#ifndef PV_MIME_STRING_UTILS_H_INCLUDED
#include "pv_mime_string_utils.h"
#endif
#ifndef OMX_Core_h
#include "OMX_Core.h"
#endif
#ifndef OMX_Component_h
#include "OMX_Component.h"
#endif
#ifndef PVMF_OMX_BASEDEC_CALLBACKS_H_INCLUDED
#include "pvmf_omx_basedec_callbacks.h"
#endif
#ifndef OSCLCONFIG_IO_H_INCLUDED
#include "osclconfig_io.h"
#endif
#ifndef OSCL_MEM_H_INCLUDED
#include "oscl_mem.h"
#endif
#if (PVLOGGER_INST_LEVEL >= PVLOGMSG_INST_REL)
#ifndef PVMF_MEDIA_CLOCK_H_INCLUDED
#include "pvmf_media_clock.h"
#endif
#endif
#ifndef PVMF_FIXEDSIZE_BUFFER_ALLOC_H_INCLUDED
#include "pvmf_fixedsize_buffer_alloc.h"
#endif
#ifndef __MEDIA_CLOCK_CONVERTER_H
#include "media_clock_converter.h"
#endif
#define MAX_NAL_PER_FRAME 100
typedef struct OutputBufCtrlStruct
{
OMX_BUFFERHEADERTYPE *pBufHdr;
} OutputBufCtrlStruct;
#if 0
typedef struct InputBufCtrlStruct
{
OMX_BUFFERHEADERTYPE *pBufHdr;
PVMFSharedMediaDataPtr pMediaData;
} InputBufCtrlStruct;
#else
class InputBufCtrlStruct
{
public:
InputBufCtrlStruct(): pBufHdr(NULL) {}
public:
OMX_BUFFERHEADERTYPE *pBufHdr;
PVMFSharedMediaDataPtr pMediaData;
};
#endif
// fwd class declaration
class PVLogger;
//memory allocator type for this node.
typedef OsclMemAllocator PVMFOMXBaseDecNodeAllocator;
// CALLBACK PROTOTYPES
OMX_ERRORTYPE CallbackEventHandler(OMX_OUT OMX_HANDLETYPE aComponent,
OMX_OUT OMX_PTR aAppData,
OMX_OUT OMX_EVENTTYPE aEvent,
OMX_OUT OMX_U32 aData1,
OMX_OUT OMX_U32 aData2,
OMX_OUT OMX_PTR aEventData);
OMX_ERRORTYPE CallbackEmptyBufferDone(OMX_OUT OMX_HANDLETYPE aComponent,
OMX_OUT OMX_PTR aAppData,
OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer);
OMX_ERRORTYPE CallbackFillBufferDone(OMX_OUT OMX_HANDLETYPE aComponent,
OMX_OUT OMX_PTR aAppData,
OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer);
//Default values for number of Input/Output buffers. If the component needs more than this, it will be
// negotiated. If the component does not need more than this number, the default is used
#define NUMBER_INPUT_BUFFER 5
#define NUMBER_OUTPUT_BUFFER 9
// nal start code is 0001
#define NAL_START_CODE_SIZE 4
const unsigned char NAL_START_CODE[4] = {0, 0, 0, 1};
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////
/////////////////////////
/////////////////////////
// CUSTOM DEALLOCATOR FOR MEDIA DATA SHARED PTR WRAPPER:
// 1) Deallocates the underlying output buffer
// 2) Deallocates the pvci buffer wrapper and the rest of accompanying structures
// Deallocator is created as part of the wrapper, and travels with the buffer wrapper
class PVOMXDecBufferSharedPtrWrapperCombinedCleanupDA : public OsclDestructDealloc
{
public:
PVOMXDecBufferSharedPtrWrapperCombinedCleanupDA(Oscl_DefAlloc* allocator, void *pMempoolData) :
buf_alloc(allocator), ptr_to_data_to_dealloc(pMempoolData) {};
virtual ~PVOMXDecBufferSharedPtrWrapperCombinedCleanupDA() {};
virtual void destruct_and_dealloc(OsclAny* ptr)
{
// call buffer deallocator
if (buf_alloc != NULL)
{
buf_alloc->deallocate(ptr_to_data_to_dealloc);
}
// finally, free the shared ptr wrapper memory
oscl_free(ptr);
}
private:
Oscl_DefAlloc* buf_alloc;
void *ptr_to_data_to_dealloc;
};
#define PVMFOMXBaseDecNodeCommandBase PVMFGenericNodeCommand<PVMFOMXBaseDecNodeAllocator>
class PVMFOMXBaseDecNodeCommand: public PVMFOMXBaseDecNodeCommandBase
{
public:
//constructor for Custom2 command
void Construct(PVMFSessionId s, int32 cmd, int32 arg1, int32 arg2, int32& arg3, const OsclAny*aContext)
{
PVMFOMXBaseDecNodeCommandBase::Construct(s, cmd, aContext);
iParam1 = (OsclAny*)arg1;
iParam2 = (OsclAny*)arg2;
iParam3 = (OsclAny*) & arg3;
}
void Parse(int32&arg1, int32&arg2, int32*&arg3)
{
arg1 = (int32)iParam1;
arg2 = (int32)iParam2;
arg3 = (int32*)iParam3;
}
void Construct(PVMFSessionId s, int32 cmd, PVMFMetadataList* aKeyList, uint32 aStartIndex, int32 aMaxEntries, char* aQueryKey, const OsclAny* aContext)
{
PVMFOMXBaseDecNodeCommandBase::Construct(s, cmd, aContext);
iStartIndex = aStartIndex;
iMaxEntries = aMaxEntries;
if (aQueryKey == NULL)
{
query_key[0] = 0;
}
else
{
if (aQueryKey != NULL)
oscl_strncpy(query_key, aQueryKey, oscl_strlen(aQueryKey) + 1);
}
iParam1 = (OsclAny*)aKeyList;
iParam2 = NULL;
iParam3 = NULL;
iParam4 = NULL;
iParam5 = NULL;
}
void Parse(PVMFMetadataList*& MetaDataListPtr, uint32 &aStartingIndex, int32 &aMaxEntries, char*&aQueryKey)
{
MetaDataListPtr = (PVMFMetadataList*)iParam1;
aStartingIndex = iStartIndex;
aMaxEntries = iMaxEntries;
if (query_key[0] == 0)
{
aQueryKey = NULL;
}
else
{
aQueryKey = query_key;
}
}
// Constructor and parser for GetNodeMetadataValue
void Construct(PVMFSessionId s, int32 cmd, PVMFMetadataList* aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>* aValueList, uint32 aStartIndex, int32 aMaxEntries, const OsclAny* aContext)
{
PVMFOMXBaseDecNodeCommandBase::Construct(s, cmd, aContext);
iParam1 = (OsclAny*)aKeyList;
iParam2 = (OsclAny*)aValueList;
iStartIndex = aStartIndex;
iMaxEntries = aMaxEntries;
iParam3 = NULL;
iParam4 = NULL;
iParam5 = NULL;
}
void Parse(PVMFMetadataList* &aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>* &aValueList, uint32 &aStartingIndex, int32 &aMaxEntries)
{
aKeyList = (PVMFMetadataList*)iParam1;
aValueList = (Oscl_Vector<PvmiKvp, OsclMemAllocator>*)iParam2;
aStartingIndex = iStartIndex;
aMaxEntries = iMaxEntries;
}
virtual bool hipri()
{
//this routine identifies commands that need to
//go at the front of the queue. derived command
//classes can override it if needed.
return (iCmd == PVOMXBASEDEC_NODE_CMD_CANCELALL
|| iCmd == PVOMXBASEDEC_NODE_CMD_CANCELCMD);
}
enum PVOMXBaseDecNodeCmdType
{
PVOMXBASEDEC_NODE_CMD_QUERYUUID,
PVOMXBASEDEC_NODE_CMD_QUERYINTERFACE,
PVOMXBASEDEC_NODE_CMD_INIT,
PVOMXBASEDEC_NODE_CMD_PREPARE,
PVOMXBASEDEC_NODE_CMD_REQUESTPORT,
PVOMXBASEDEC_NODE_CMD_START,
PVOMXBASEDEC_NODE_CMD_PAUSE,
PVOMXBASEDEC_NODE_CMD_STOP,
PVOMXBASEDEC_NODE_CMD_FLUSH,
PVOMXBASEDEC_NODE_CMD_RELEASEPORT,
PVOMXBASEDEC_NODE_CMD_RESET,
PVOMXBASEDEC_NODE_CMD_CANCELCMD,
PVOMXBASEDEC_NODE_CMD_CANCELALL,
PVOMXBASEDEC_NODE_CMD_INVALID,
PVOMXBASEDEC_NODE_CMD_GETNODEMETADATAKEY,
PVOMXBASEDEC_NODE_CMD_GETNODEMETADATAVALUE
};
private:
uint32 iStartIndex;
uint32 iMaxEntries;
char query_key[256];
};
//Default vector reserve size
#define PVMF_OMXBASEDEC_NODE_COMMAND_VECTOR_RESERVE 10
//Starting value for command IDs
#define PVMF_OMXBASEDEC_NODE_COMMAND_ID_START 6000
///////////////////////////////////////////////////////////////////////////////////////////////////////
//CAPABILITY AND CONFIG
// Structure to hold the key string info for
// capability-and-config
struct PVOMXBaseDecNodeKeyStringData
{
char iString[64];
PvmiKvpType iType;
PvmiKvpValueType iValueType;
};
// The number of characters to allocate for the key string
#define PVOMXBASEDECNODECONFIG_KEYSTRING_SIZE 128
//Mimetypes for the custom interface
#define PVMF_OMX_BASE_DEC_NODE_MIMETYPE "pvxxx/OMXBaseDecNode"
#define PVMF_BASEMIMETYPE "pvxxx"
//Command queue type
typedef PVMFNodeCommandQueue<PVMFOMXBaseDecNodeCommand, PVMFOMXBaseDecNodeAllocator> PVMFOMXBaseDecNodeCmdQ;
class PVMFOMXBaseDecNode
: public OsclActiveObject
, public PVMFNodeInterface
, public OsclMemPoolFixedChunkAllocatorObserver
, public PVMFOMXBaseDecNodeExtensionInterface
, public PVMFMetadataExtensionInterface
, public PvmiCapabilityAndConfig
{
public:
OSCL_IMPORT_REF PVMFOMXBaseDecNode(int32 aPriority, const char aAOName[], bool aHwAccelerated = true);
OSCL_IMPORT_REF virtual ~PVMFOMXBaseDecNode();
// From PVMFNodeInterface
OSCL_IMPORT_REF virtual PVMFStatus ThreadLogon() = 0;
OSCL_IMPORT_REF PVMFStatus ThreadLogoff();
OSCL_IMPORT_REF PVMFStatus GetCapability(PVMFNodeCapability& aNodeCapability);
OSCL_IMPORT_REF PVMFPortIter* GetPorts(const PVMFPortFilter* aFilter = NULL);
OSCL_IMPORT_REF PVMFCommandId QueryUUID(PVMFSessionId, const PvmfMimeString& aMimeType,
Oscl_Vector<PVUuid, PVMFOMXBaseDecNodeAllocator>& aUuids,
bool aExactUuidsOnly = false,
const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId QueryInterface(PVMFSessionId, const PVUuid& aUuid,
PVInterface*& aInterfacePtr,
const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId RequestPort(PVMFSessionId
, int32 aPortTag, const PvmfMimeString* aPortConfig = NULL, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId ReleasePort(PVMFSessionId, PVMFPortInterface& aPort, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Init(PVMFSessionId, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Prepare(PVMFSessionId, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Start(PVMFSessionId, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Stop(PVMFSessionId, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Flush(PVMFSessionId, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Pause(PVMFSessionId, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId Reset(PVMFSessionId, const OsclAny* aContext = NULL);
OSCL_IMPORT_REF PVMFCommandId CancelAllCommands(PVMFSessionId, const OsclAny* aContextData = NULL);
OSCL_IMPORT_REF PVMFCommandId CancelCommand(PVMFSessionId, PVMFCommandId aCmdId, const OsclAny* aContextData = NULL);
// From PVMFPortActivityHandler
OSCL_IMPORT_REF void HandlePortActivity(const PVMFPortActivity& aActivity);
// From PVInterface
OSCL_IMPORT_REF virtual void addRef();
OSCL_IMPORT_REF virtual void removeRef();
OSCL_IMPORT_REF virtual bool queryInterface(const PVUuid& uuid, PVInterface*& iface);
OSCL_IMPORT_REF virtual PVMFStatus SetDecoderNodeConfiguration(PVMFOMXBaseDecNodeConfig& aConfig);
//**********begin PVMFMetadataExtensionInterface
OSCL_IMPORT_REF virtual uint32 GetNumMetadataKeys(char* query_key = NULL) = 0;
OSCL_IMPORT_REF virtual uint32 GetNumMetadataValues(PVMFMetadataList& aKeyList) = 0;
OSCL_IMPORT_REF PVMFCommandId GetNodeMetadataKeys(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, uint32 starting_index, int32 max_entries,
char* query_key = NULL, const OsclAny* aContextData = NULL);
OSCL_IMPORT_REF PVMFCommandId GetNodeMetadataValues(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList,
Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 starting_index, int32 max_entries, const OsclAny* aContextData = NULL);
OSCL_IMPORT_REF PVMFStatus ReleaseNodeMetadataKeys(PVMFMetadataList& aKeyList, uint32 starting_index, uint32 end_index);
OSCL_IMPORT_REF PVMFStatus ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 starting_index, uint32 end_index);
//**********End PVMFMetadataExtensionInterface
OSCL_IMPORT_REF virtual bool VerifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements) = 0;
//********** CB Functions to serve OpenMAX Decoder
//Process callback functions. They will be executed in testapp thread context
// These callbacks are used only in the Multithreaded component case
OSCL_IMPORT_REF OsclReturnCode ProcessCallbackEventHandler_MultiThreaded(OsclAny* P);
OSCL_IMPORT_REF OsclReturnCode ProcessCallbackEmptyBufferDone_MultiThreaded(OsclAny* P);
OSCL_IMPORT_REF OsclReturnCode ProcessCallbackFillBufferDone_MultiThreaded(OsclAny* P);
//Callback objects - again, these are used only in the case of Multithreaded component
EventHandlerThreadSafeCallbackAO* iThreadSafeHandlerEventHandler;
EmptyBufferDoneThreadSafeCallbackAO* iThreadSafeHandlerEmptyBufferDone;
FillBufferDoneThreadSafeCallbackAO* iThreadSafeHandlerFillBufferDone;
OMX_CALLBACKTYPE iCallbacks; // structure that contains callback ptrs.
// OMX CALLBACKS
// 1) AO OMX component running in the same thread as the OMX node
// In this case, the callbacks can be called directly from the component
// The callback: OMX Component->CallbackEventHandler->EventHandlerProcessing
// The callback can perform do RunIfNotReady
// 2) Multithreaded component
// In this case, the callback is made using the threadsafe callback (TSCB) AO
// Component thread : OMX Component->CallbackEventHandler->TSCB(ReceiveEvent)
// Node thread : TSCB(ProcessEvent)->ProcessCallbackEventHandler_MultiThreaded->EventHandlerProcessing
//==============================================================================
OSCL_IMPORT_REF virtual OMX_ERRORTYPE EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
OMX_OUT OMX_PTR aAppData,
OMX_OUT OMX_EVENTTYPE aEvent,
OMX_OUT OMX_U32 aData1,
OMX_OUT OMX_U32 aData2,
OMX_OUT OMX_PTR aEventData) = 0;
OSCL_IMPORT_REF OMX_ERRORTYPE EmptyBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
OMX_OUT OMX_PTR aAppData,
OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer);
OSCL_IMPORT_REF OMX_ERRORTYPE FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
OMX_OUT OMX_PTR aAppData,
OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer);
bool IsComponentMultiThreaded()
{
return iIsOMXComponentMultiThreaded;
};
// From PvmiCapabilityAndConfig
OSCL_IMPORT_REF void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver);
OSCL_IMPORT_REF PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext);
OSCL_IMPORT_REF PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements);
OSCL_IMPORT_REF void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
OSCL_IMPORT_REF void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, PvmiKvp* aParameters, int aNumParamElements);
OSCL_IMPORT_REF void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
OSCL_IMPORT_REF void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP);
OSCL_IMPORT_REF PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP, OsclAny* aContext = NULL);
OSCL_IMPORT_REF uint32 getCapabilityMetric(PvmiMIOSession aSession);
OSCL_IMPORT_REF PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements);
OSCL_IMPORT_REF virtual bool ProcessIncomingMsg(PVMFPortInterface* aPort);
OSCL_IMPORT_REF void Run();
protected:
OSCL_IMPORT_REF void CommandComplete(PVMFOMXBaseDecNodeCmdQ& aCmdQ, PVMFOMXBaseDecNodeCommand& aCmd, PVMFStatus aStatus, OsclAny* aEventData = NULL);
virtual void DoQueryUuid(PVMFOMXBaseDecNodeCommand&) = 0;
void DoQueryInterface(PVMFOMXBaseDecNodeCommand&);
virtual void DoRequestPort(PVMFOMXBaseDecNodeCommand&) = 0;
virtual void DoReleasePort(PVMFOMXBaseDecNodeCommand&) = 0;
void DoInit(PVMFOMXBaseDecNodeCommand&);
void DoPrepare(PVMFOMXBaseDecNodeCommand&);
void DoStart(PVMFOMXBaseDecNodeCommand&);
void DoStop(PVMFOMXBaseDecNodeCommand&);
void DoPause(PVMFOMXBaseDecNodeCommand&);
void DoReset(PVMFOMXBaseDecNodeCommand&);
void DoFlush(PVMFOMXBaseDecNodeCommand&);
virtual PVMFStatus DoGetNodeMetadataKey(PVMFOMXBaseDecNodeCommand&) = 0;
virtual PVMFStatus DoGetNodeMetadataValue(PVMFOMXBaseDecNodeCommand&) = 0;
void DoCancelAllCommands(PVMFOMXBaseDecNodeCommand&);
void DoCancelCommand(PVMFOMXBaseDecNodeCommand&);
bool ProcessCommand(PVMFOMXBaseDecNodeCommand& aCmd);
bool ProcessOutgoingMsg(PVMFPortInterface* aPort);
PVMFStatus HandleProcessingState();
virtual PVMFStatus HandlePortReEnable() = 0;
virtual bool InitDecoder(PVMFSharedMediaDataPtr&) = 0;
OSCL_IMPORT_REF OsclAny* AllocateKVPKeyArray(int32& aLeaveCode, PvmiKvpValueType aValueType, int32 aNumElements);
int32 PushKVPKey(OSCL_HeapString<OsclMemAllocator>& aString, PVMFMetadataList* aKeyList)
{
int32 leavecode = OsclErrNone;
OSCL_TRY(leavecode, aKeyList->push_back(aString));
return leavecode;
}
int32 PushKVPKey(const char* aString, PVMFMetadataList& aKeyList)
{
int32 leavecode = OsclErrNone;
OSCL_TRY(leavecode, aKeyList.push_back(aString));
return leavecode;
}
int32 PushKVP(PvmiKvp aKVP, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList)
{
int32 leavecode = OsclErrNone;
OSCL_TRY(leavecode, aValueList.push_back(aKVP));
return leavecode;
}
int32 AllocateChunkFromMemPool(OsclAny*& aCtrlStructPtr, OsclMemPoolFixedChunkAllocator *aMemPool, int32 aAllocSize)
{
int32 leavecode = OsclErrNone;
OSCL_TRY(leavecode, aCtrlStructPtr = (OsclAny *) aMemPool->allocate(aAllocSize));
return leavecode;
}
// DV:
virtual bool NegotiateComponentParameters(OMX_PTR aOutputParameters) = 0;
bool SetDefaultCapabilityFlags();
OSCL_IMPORT_REF bool CreateOutMemPool(uint32 num);
OSCL_IMPORT_REF bool CreateInputMemPool(uint32 num);
OSCL_IMPORT_REF bool ProvideBuffersToComponent(OsclMemPoolFixedChunkAllocator *aMemPool, // allocator
uint32 aAllocSize, // size to allocate from pool (hdr only or hdr+ buffer)
uint32 aNumBuffers, // number of buffers
uint32 aActualBufferSize, // aactual buffer size
uint32 aPortIndex, // port idx
bool aUseBufferOK, // can component use OMX_UseBuffer?
bool aIsThisInputBuffer // is this input or output
);
bool FreeBuffersFromComponent(OsclMemPoolFixedChunkAllocator *aMemPool, // allocator
uint32 aAllocSize, // size to allocate from pool (hdr only or hdr+ buffer)
uint32 aNumBuffers, // number of buffers
uint32 aPortIndex, // port idx
bool aIsThisInputBuffer // is this input or output
);
OsclSharedPtr<class PVMFMediaDataImpl> WrapOutputBuffer(uint8 *pData, uint32 aDataLen, OsclAny *pContext);
virtual bool QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediadataimplout, uint32 aDataLen) = 0;
bool SendOutputBufferToOMXComponent();
OSCL_IMPORT_REF bool SendInputBufferToOMXComponent();
OSCL_IMPORT_REF bool SendConfigBufferToOMXComponent(uint8 *initbuffer, uint32 initbufsize);
bool SendEOSBufferToOMXComponent();
bool HandleRepositioning(void);
bool SendBeginOfMediaStreamCommand(void);
bool SendEndOfTrackCommand(void);
bool AppendExtraDataToBuffer(InputBufCtrlStruct* aInputBuffer, OMX_EXTRADATATYPE aType, uint8* aExtraData, uint8 aDataLength);
virtual bool ReleaseAllPorts() = 0;
bool DeleteOMXBaseDecoder();
OSCL_IMPORT_REF void ChangeNodeState(TPVMFNodeInterfaceState aNewState);
OSCL_IMPORT_REF void HandleComponentStateChange(OMX_U32 decoder_state);
// Capability And Config Helper Methods
OSCL_IMPORT_REF virtual PVMFStatus DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext);
OSCL_IMPORT_REF virtual PVMFStatus DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements);
OSCL_IMPORT_REF virtual void DoCapConfigSetParameters(PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP);
OSCL_IMPORT_REF virtual PVMFStatus DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements);
// From OsclMemPoolFixedChunkAllocatorObserver
OSCL_IMPORT_REF void freechunkavailable(OsclAny*);
OSCL_IMPORT_REF PVMFCommandId QueueCommandL(PVMFOMXBaseDecNodeCommand& aCmd);
friend class PVMFOMXBaseDecPort;
// Ports pointers
PVMFPortInterface* iInPort;
PVMFPortInterface* iOutPort;
// Commands
PVMFOMXBaseDecNodeCmdQ iInputCommands;
PVMFOMXBaseDecNodeCmdQ iCurrentCommand;
// Shared pointer for Media Msg.Input buffer
PVMFSharedMediaDataPtr iDataIn;
// OUTPUT BUFFER RELATED MEMBERS
// Output buffer memory pool
OsclMemPoolFixedChunkAllocator *iOutBufMemoryPool;
// Memory pool for simple media data
OsclMemPoolFixedChunkAllocator *iMediaDataMemPool;
// Fragment pool for format specific info
PVMFBufferPoolAllocator iFsiFragmentAlloc;
// Fragment pool for private data format specific info
PVMFBufferPoolAllocator iPrivateDataFsiFragmentAlloc;
// Size of output buffer (negotiated with component)
uint32 iOMXComponentOutputBufferSize;
// size of output to allocate (OMX_ALLOCATE_BUFFER = size of buf header )
// (OMX_USE_BUFFER = size of buf header + iOMXCoponentOutputBufferSize)
uint32 iOutputAllocSize;
// Number of output buffers (negotiated with component)
uint32 iNumOutputBuffers;
// Number of output buffers in possession of the component or downstream,
// namely, number of unavailable buffers
uint32 iNumOutstandingOutputBuffers;
// flag to prevent sending output buffers downstream during flushing etc.
bool iDoNotSendOutputBuffersDownstreamFlag;
// flag to prevent freeing the buffers twice
bool iOutputBuffersFreed;
OsclAny *ipPrivateData;
// INPUT BUFFER RELATED MEMBERS
OsclMemPoolFixedChunkAllocator *iInBufMemoryPool;
uint32 iOMXComponentInputBufferSize; // size of input buffer that the component sees (negotiated with the component)
uint32 iInputAllocSize; // size of input buffer to allocate (OMX_ALLOCATE_BUFFER = size of buf header )
// (OMX_USE_BUFFER = size of buf header + iOMXCoponentInputBufferSize)
uint32 iNumInputBuffers; // total num of input buffers (negotiated with component)
uint32 iNumOutstandingInputBuffers; // number of input buffers in use (i.e. unavailable)
bool iDoNotSaveInputBuffersFlag;
// flag to prevent freeing buffers twice
bool iInputBuffersFreed;
// input buffer fragmentation etc.
uint32 iCopyPosition; // for copying memfrag data into a buffer
uint32 iFragmentSizeRemainingToCopy;
bool iIsNewDataFragment;
// partial frame assembly logic flags
bool iFirstPieceOfPartialFrame;
bool iObtainNewInputBuffer;
bool iKeepDroppingMsgsUntilMarkerBit;
bool iFirstDataMsgAfterBOS;
InputBufCtrlStruct *iInputBufferUnderConstruction;
bool iIncompleteFrame;
OSCL_IMPORT_REF void DropCurrentBufferUnderConstruction();
OSCL_IMPORT_REF void SendIncompleteBufferUnderConstruction();
// input data info
uint32 iCurrFragNum;
uint32 iCodecSeqNum; // sequence number tracking
uint32 iInPacketSeqNum;
uint32 iInTimestamp;
uint32 iInDuration;
uint32 iInNumFrags;
uint32 iCurrentMsgMarkerBit;
// DYNAMIC PORT RE-CONFIGURATION
uint32 iInputPortIndex;
uint32 iOutputPortIndex;
OMX_PARAM_PORTDEFINITIONTYPE iParamPort;
uint32 iPortIndexForDynamicReconfig;
bool iSecondPortReportedChange;
bool iDynamicReconfigInProgress;
uint32 iSecondPortToReconfig;
bool iPauseCommandWasSentToComponent;
bool iStopCommandWasSentToComponent;
OMX_BUFFERHEADERTYPE *iInputBufferToResendToComponent; // ptr to input buffer that is not empty, but that the OMX component returned
// we need to resend this same buffer back to the component
////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
bool iOMXComponentSupportsExternalOutputBufferAlloc;
bool iOMXComponentSupportsExternalInputBufferAlloc;
bool iOMXComponentSupportsMovableInputBuffers;
bool iSetMarkerBitForEveryFrag; // is every fragment complete frame (e.g. AVC file playback = each fragment is a NAL)
bool iIsOMXComponentMultiThreaded;
bool iOMXComponentSupportsPartialFrames;
bool iOMXComponentUsesNALStartCodes;
bool iOMXComponentUsesFullAVCFrames;
bool iOMXComponentCanHandleIncompleteFrames;
// State definitions for HandleProcessingState() state machine
typedef enum
{
EPVMFOMXBaseDecNodeProcessingState_Idle, //default state after constraction/reset
EPVMFOMXBaseDecNodeProcessingState_InitDecoder, //initialization of H264 decoder after handle was obtained
EPVMFOMXBaseDecNodeProcessingState_WaitForInitCompletion, // waiting for init completion
EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode, //nornal operation state of the decoder
EPVMFOMXBaseDecNodeProcessingState_WaitForOutputBuffer, //wait state for avalible media output buffer
EPVMFOMXBaseDecNodeProcessingState_WaitForOutputPort, //wait state, output port is busy
EPVMFOMXBaseDecNodeProcessingState_WaitForOutgoingQueue, //wait state, outgoing queue
EPVMFOMXBaseDecNodeProcessingState_PortReconfig, // Dynamic Port Reconfiguration - step 1
EPVMFOMXBaseDecNodeProcessingState_WaitForBufferReturn, // step 2
EPVMFOMXBaseDecNodeProcessingState_WaitForPortDisable, // Dynamic Port Reconfiguration - step 3
EPVMFOMXBaseDecNodeProcessingState_PortReEnable, // Dynamic Port Reconfiguration - step 4
EPVMFOMXBaseDecNodeProcessingState_WaitForPortEnable, // step 5
EPVMFOMXBaseDecNodeProcessingState_Stopping, // when STOP command is issued, the node has to wait for component to transition into
// idle state. The buffers keep coming back , the node is rescheduled
// to run. Prevent the node from sending buffers back
EPVMFOMXBaseDecNodeProcessingState_Pausing // when PAUSE command is issued, the node has to wait for component to transition into
// paused state.
// Video: This prevents the node from sending buffers back
// Audio: The buffers may still keep coming back , the node is rescheduled
// to run. Prevent the node from sending buffers back to component
} PVMFOMXBaseDecNode_ProcessingState;
// State of HandleProcessingState() state machine
PVMFOMXBaseDecNode_ProcessingState iProcessingState;
// Handle of OMX Component
OMX_HANDLETYPE iOMXDecoder;
// Current State of the component
OMX_STATETYPE iCurrentDecoderState;
// BOS
bool iSendBOS;
uint32 iStreamID;
uint32 iBOSTimestamp;
// repositioning related flags
bool iIsRepositioningRequestSentToComponent;
bool iIsRepositionDoneReceivedFromComponent;
bool iIsOutputPortFlushed;
bool iIsInputPortFlushed;
//EOS control flags
bool iIsEOSSentToComponent;
bool iIsEOSReceivedFromComponent;
// Send Fsi configuration flag
bool sendFsi;
// Pointer to input data fragment
uint8* iBitstreamBuffer;
// Size of input data fragment
int32 iBitstreamSize;
// Output frame sequence counter
uint32 iSeqNum;
// Input frame sequence counter
uint32 iSeqNum_In;
// Added to Scheduler Flag
bool iIsAdded;
// Log related
PVLogger* iLogger;
PVLogger* iDataPathLogger;
PVLogger* iClockLogger;
PVLogger *iRunlLogger;
// Counter of fragment read from current Media Msg.Input buffer
uint fragnum;
// Number of fragments in the Media Msg.Input buffer
uint numfrags;
// Time stamp to be used on output buffer
uint32 iOutTimeStamp;
// Node configuration update
PVMFOMXBaseDecNodeConfig iNodeConfig;
// Capability exchange
PVMFNodeCapability iCapability;
// Reference counter for extension
uint32 iExtensionRefCount;
// Vector for KVP
Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> iAvailableMetadataKeys;
// EOS flag
bool iEndOfDataReached;
// Time stame upon EOS
PVMFTimestamp iEndOfDataTimestamp;
/* Diagnostic log related */
PVLogger* iDiagnosticsLogger;
bool iDiagnosticsLogged;
void LogDiagnostics();
uint32 iFrameCounter;
uint32 iAvgBitrateValue;
bool iResetInProgress;
bool iResetMsgSent;
bool iStopInResetMsgSent;
// AVC NAL counter and size array
uint32 iNALCount;
uint32 iNALSizeArray[MAX_NAL_PER_FRAME]; // NAL count shouldn't exceed 100
OsclAny **out_ctrl_struct_ptr ;
OsclAny **out_buff_hdr_ptr ;
OsclAny **in_ctrl_struct_ptr ;
OsclAny **in_buff_hdr_ptr ;
PVInterface* ipExternalOutputBufferAllocatorInterface;
PVMFFixedSizeBufferAlloc* ipFixedSizeBufferAlloc;
bool iCompactFSISettingSucceeded;
// Timestamp, timescale, OMX Ticks related conversions
uint32 iInTimeScale;
uint32 iOutTimeScale;
uint32 iTimeScale;
MediaClockConverter iInputTimestampClock;
OMX_TICKS iOMXTicksTimestamp;
OSCL_IMPORT_REF OMX_TICKS ConvertTimestampIntoOMXTicks(const MediaClockConverter &src);
uint32 ConvertOMXTicksIntoTimestamp(const OMX_TICKS &src);
OMX_BOOL bHWAccelerated;
};
#endif // PVMF_OMXBASEDEC_NODE_H_INCLUDED