/**
  src/components/ddpdec/omx_ddpdec_component.c

  OpenMAX ddpdec_component component. This component does not perform any multimedia
  processing.  It is provides the media and the reference clock for all the clients connected to it.

  Copyright (C) 2008-2009 STMicroelectronics
  Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).

  This library is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free
  Software Foundation; either version 2.1 of the License, or (at your option)
  any later version.

  This library is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
  details.

  You should have received a copy of the GNU Lesser General Public License
  along with this library; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St, Fifth Floor, Boston, MA
  02110-1301  USA

*/

#include <omxcore.h>
#include <omx_base_clock_port.h>
#include <omx_ddpdec_component.h>
#include <config.h>
#include <unistd.h>
#include <dlfcn.h>

#define LOG(_stmt...) \
	do{ \
		if(0) \
		{ \
			printf("[omx-ddp-dec]Func:%s Line:%d--->: ", __FUNCTION__, __LINE__);   \
			printf(_stmt); \
			printf("\n"); \
		} \
	  }   \
	while(0)

OMX_COMPONENTTYPE *g_omxhandle = NULL;
void* pOmxModule = NULL;

OMX_ERRORTYPE omx_ddpdec_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName)
{
    LOG ("in");

    OMX_ERRORTYPE err = OMX_ErrorNone;

    OMX_COMPONENTTYPE* (*pMtkOmxComponentCreate)(OMX_STRING);
    pOmxModule = dlopen ("/usr/lib/libMtkOmxEac3Dec.so", RTLD_LAZY);
    if (NULL == pOmxModule)
    {
        LOG ("dlopen failed, %s", dlerror());
        err = OMX_ErrorComponentNotFound;
        return err;
    }

    pMtkOmxComponentCreate = (OMX_COMPONENTTYPE* (*)(OMX_STRING))dlsym(pOmxModule, "MtkOmxComponentCreate");
    if (NULL == pMtkOmxComponentCreate)
    {
        LOG("%d:: dlsym failed for module %p, dlerror=%s", __LINE__, pOmxModule, dlerror());
        err = OMX_ErrorInvalidComponent;
        return err;
    }

    g_omxhandle = (*pMtkOmxComponentCreate)(cComponentName);
    if ((void *)g_omxhandle == NULL)
    {
        err = OMX_ErrorInsufficientResources;
        LOG("%d:: malloc failed", __LINE__);
        return err;
    }
	openmaxStandComp->pComponentPrivate = g_omxhandle->pComponentPrivate;
	
	openmaxStandComp->ComponentDeInit = omx_ddpdec_component_Destructor;
	openmaxStandComp->SetCallbacks = omx_ddpdec_component_SetCallbacks;
	openmaxStandComp->SendCommand = omx_ddpdec_component_SendCommand;
	openmaxStandComp->SetParameter = omx_ddpdec_component_SetParameter;
	openmaxStandComp->GetParameter = omx_ddpdec_component_GetParameter;
	openmaxStandComp->GetExtensionIndex = omx_ddpdec_component_GetExtensionIndex;
	openmaxStandComp->GetState = omx_ddpdec_component_GetState;
	openmaxStandComp->SetConfig = omx_ddpdec_component_SetConfig;
	openmaxStandComp->GetConfig = omx_ddpdec_component_GetConfig;
	openmaxStandComp->AllocateBuffer = omx_ddpdec_component_AllocateBuffer;	
	openmaxStandComp->UseBuffer = omx_ddpdec_component_UseBuffer;
	openmaxStandComp->FreeBuffer = omx_ddpdec_component_FreeBuffer;
	openmaxStandComp->EmptyThisBuffer = omx_ddpdec_component_EmptyThisBuffer;
	openmaxStandComp->FillThisBuffer = omx_ddpdec_component_FillThisBuffer;
	openmaxStandComp->ComponentRoleEnum = omx_ddpdec_component_ComponentRoleEnum;
	openmaxStandComp->GetComponentVersion = omx_ddpdec_component_GetComponentVersion;

    LOG ("out");
    return OMX_ErrorNone;
}


OMX_ERRORTYPE omx_ddpdec_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp)
{
	LOG ("in");
	g_omxhandle->ComponentDeInit((void*)openmaxStandComp); // deinit aud_dec_base
	dlclose(pOmxModule);							 // uninstall libomxddpdec.so
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_SetCallbacks(
	OMX_HANDLETYPE hComponent,
    OMX_CALLBACKTYPE *pCallBacks,
    OMX_PTR pAppData)
{
	LOG ("in");
	g_omxhandle->SetCallbacks(hComponent, pCallBacks, pAppData);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_SendCommand(
    OMX_HANDLETYPE hComponent,
    OMX_COMMANDTYPE Cmd,
    OMX_U32 nParam,
    OMX_PTR pCmdData)
{
	LOG ("in");
	g_omxhandle->SendCommand(hComponent, Cmd, nParam, pCmdData);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_SetParameter(
    OMX_HANDLETYPE hComponent,
    OMX_INDEXTYPE nParamIndex,
    OMX_PTR ComponentParameterStructure)
{
	LOG ("in");
	g_omxhandle->SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_GetParameter(
    OMX_HANDLETYPE hComponent,
    OMX_INDEXTYPE nParamIndex,
    OMX_PTR ComponentParameterStructure)
{
	LOG ("in");
	g_omxhandle->GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
	LOG ("out");
    return OMX_ErrorNone;
}


OMX_ERRORTYPE omx_ddpdec_component_GetExtensionIndex(
		OMX_HANDLETYPE hComponent,
		OMX_STRING cParameterName,
		OMX_INDEXTYPE* pIndexType)
{
	LOG ("in");
	g_omxhandle->GetExtensionIndex(hComponent, cParameterName, pIndexType);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_GetState(
		OMX_HANDLETYPE hComponent,
		OMX_STATETYPE* pState)
{
	LOG ("in");
	g_omxhandle->GetState(hComponent, pState);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_SetConfig(
		OMX_HANDLETYPE hComponent,
		OMX_INDEXTYPE nIndex,
		OMX_PTR pComponentConfigStructure)
{
	LOG ("in");
	g_omxhandle->SetConfig(hComponent, nIndex, pComponentConfigStructure);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_GetConfig(
    OMX_HANDLETYPE hComponent,
    OMX_INDEXTYPE nIndex,
    OMX_PTR pComponentConfigStructure)
{
	LOG ("in");
	g_omxhandle->GetConfig(hComponent, nIndex, pComponentConfigStructure);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_AllocateBuffer(
		OMX_HANDLETYPE hComponent,
		OMX_BUFFERHEADERTYPE** ppBuffer,
		OMX_U32 nPortIndex,
		OMX_PTR pAppPrivate,
		OMX_U32 nSizeBytes)
{
	LOG ("in");
	g_omxhandle->AllocateBuffer(hComponent, ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_UseBuffer(
		OMX_HANDLETYPE hComponent,
		OMX_BUFFERHEADERTYPE** ppBufferHdr,
		OMX_U32 nPortIndex,
		OMX_PTR pAppPrivate,
		OMX_U32 nSizeBytes,
		OMX_U8* pBuffer)
{
	LOG ("in");
	g_omxhandle->UseBuffer(hComponent, ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, pBuffer);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_FreeBuffer(
		OMX_HANDLETYPE hComponent,
		OMX_U32 nPortIndex,
		OMX_BUFFERHEADERTYPE* pBuffer)
{
	LOG ("in");
	g_omxhandle->FreeBuffer(hComponent, nPortIndex, pBuffer);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_EmptyThisBuffer(
		OMX_HANDLETYPE hComponent,
		OMX_BUFFERHEADERTYPE* pBuffer)
{
	LOG ("[YF][ddpdec-comp]EmptyThisBuffer in");
	g_omxhandle->EmptyThisBuffer(hComponent, pBuffer);
	LOG ("[YF][ddpdec-comp]EmptyThisBuffer out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_FillThisBuffer(
		OMX_HANDLETYPE hComponent,
		OMX_BUFFERHEADERTYPE* pBuffer)
{
	LOG ("[YF][ddpdec-comp]FillThisBuffer in");
	g_omxhandle->FillThisBuffer(hComponent, pBuffer);
	LOG ("[YF][ddpdec-comp]FillThisBuffer out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_ComponentRoleEnum(
	OMX_HANDLETYPE hComponent,
	OMX_U8 *cRole,
	OMX_U32 nIndex)
{
	LOG ("in");
	g_omxhandle->ComponentRoleEnum(hComponent, cRole, nIndex);
	LOG ("out");
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_ddpdec_component_GetComponentVersion(
		OMX_HANDLETYPE hComponent,
		OMX_STRING pComponentName,
		OMX_VERSIONTYPE* pComponentVersion,
		OMX_VERSIONTYPE* pSpecVersion,
		OMX_UUIDTYPE* pComponentUUID)
{
	LOG ("in");
	g_omxhandle->GetComponentVersion(hComponent, pComponentName, pComponentVersion, pSpecVersion, pComponentUUID);
	LOG ("out");
    return OMX_ErrorNone;
}

