/* ------------------------------------------------------------------
 * Copyright (C) 2008 PacketVideo
 * Copyright (C) 2008 HTC Inc.
 *
 * 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_VIDEOENC_CALLBACKS_H_INCLUDED
#define PVMF_OMX_VIDEOENC_CALLBACKS_H_INCLUDED


#ifndef THREADSAFE_CALLBACK_AO_H_INCLUDED
#include "threadsafe_callback_ao.h"
#endif

#ifndef THREADSAFE_MEMPOOL_H_INCLUDED
#include "threadsafe_mempool.h"
#endif


#ifndef OMX_Types_h
#include "omx_types.h"
#endif

#ifndef OMX_Core_h
#include "omx_core.h"
#endif

#ifndef OSCL_MEM_MEMPOOL_H_INCLUDED
#include "oscl_mem_mempool.h"
#endif
// structure that contains EventHandler callback type parameters:
typedef struct EventHandlerSpecificData
{
	OMX_HANDLETYPE hComponent;
	OMX_PTR pAppData;
	OMX_EVENTTYPE eEvent;
	OMX_U32 nData1;
	OMX_U32 nData2;
	OMX_PTR pEventData;
} EventHandlerSpecificData;


// structure that contains EmptyBufferDone callback type parameters:
typedef struct EmptyBufferDoneSpecificData
{
	OMX_HANDLETYPE hComponent;
	OMX_PTR pAppData;
	OMX_BUFFERHEADERTYPE* pBuffer;
} EmptyBufferDoneSpecificData;


// structure that contains FillBufferDone callback type parameters:
typedef struct FillBufferDoneSpecificData
{
	OMX_HANDLETYPE hComponent;
	OMX_PTR pAppData;
	OMX_BUFFERHEADERTYPE* pBuffer;
} FillBufferDoneSpecificData;


// This class defines the callback AO that handles the callbacks from the remote thread in a thread-safe way.
// The callback events arriving from the remote thread are queued and processed later in PV thread context.
// The class is DERIVED from the "ThreadSafeCallbackAO" class defined in "threadsafe_callback_ao.h/cpp"
// OVERLOAD THE METHOD : "ProcessEvent" so that it does something meaningful


// Test AO receives the remote thread specific API callback and then calls the generic API "ReceiveEvent"
const char EventHandlerAOName[] = "EventHandlerCallbackAO";
const char EmptyBufferDoneAOName[] = "EventHandlerCallbackAO";
const char FillBufferDoneAOName[] = "EventHandlerCallbackAO";


/**************** CLASS FOR EVENT HANDLER *************/
class EventHandlerThreadSafeCallbackAO : public ThreadSafeCallbackAO
{
public:
	// Constructor
	EventHandlerThreadSafeCallbackAO(
										void* aObserver = NULL,
										uint32 aDepth = DEFAULT_QUEUE_DEPTH,
										const char* aAOname = EventHandlerAOName,
										int32 aPriority = OsclActiveObject::EPriorityNominal);


	// OVERLOADED ProcessEvent
	OsclReturnCode ProcessEvent(OsclAny* EventData);

	// overloaded Run and DeQueue to optimize performance (and process more than 1 event per Run)
	virtual void Run();
	virtual OsclAny* DeQueue(OsclReturnCode &stat);

	virtual ~EventHandlerThreadSafeCallbackAO();
	ThreadSafeMemPoolFixedChunkAllocator *iMemoryPool;

};


/**************** CLASS FOR EVENT HANDLER *************/
class EmptyBufferDoneThreadSafeCallbackAO : public ThreadSafeCallbackAO
{
public:
	// Constructor
	EmptyBufferDoneThreadSafeCallbackAO(
										void* aObserver = NULL,
										uint32 aDepth = DEFAULT_QUEUE_DEPTH,
										const char* aAOname = EmptyBufferDoneAOName,
										int32 aPriority = OsclActiveObject::EPriorityNominal);

	// OVERLOADED ProcessEvent
	OsclReturnCode ProcessEvent(OsclAny* EventData);

	// overloaded Run and DeQueue to optimize performance (and process more than 1 event per Run)
	virtual void Run();
	virtual OsclAny* DeQueue(OsclReturnCode &stat);

	virtual ~EmptyBufferDoneThreadSafeCallbackAO();
	ThreadSafeMemPoolFixedChunkAllocator *iMemoryPool;
};




/**************** CLASS FOR EVENT HANDLER *************/
class FillBufferDoneThreadSafeCallbackAO : public ThreadSafeCallbackAO
{
public:
	// Constructor
	FillBufferDoneThreadSafeCallbackAO(void* aObserver = NULL,
										uint32 aDepth = DEFAULT_QUEUE_DEPTH,
										const char* aAOname = FillBufferDoneAOName,
										int32 aPriority = OsclActiveObject::EPriorityNominal);

	// OVERLOADED ProcessEvent
	OsclReturnCode ProcessEvent(OsclAny* EventData);
	// overloaded Run and DeQueue to optimize performance (and process more than 1 event per Run)
	virtual void Run();
	virtual OsclAny* DeQueue(OsclReturnCode &stat);

	virtual ~FillBufferDoneThreadSafeCallbackAO();
	ThreadSafeMemPoolFixedChunkAllocator *iMemoryPool;
};

#endif	//#ifndef PVMF_OMX_VIDEODEC_CALLBACKS_H_INLCUDED
