khronosfws/openmax_al/src/common/xaobjectitf.c
changeset 12 5a06f39ad45b
child 16 43d09473c595
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/khronosfws/openmax_al/src/common/xaobjectitf.c	Fri Apr 16 15:29:42 2010 +0300
@@ -0,0 +1,530 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "xaobjectitf.h"
+
+/**
+ * Base interface XAObjectItf implementation
+ */
+XAresult XAObjectItfImpl_Realize(XAObjectItf self, XAboolean async)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    XAresult retval = XA_RESULT_SUCCESS;
+
+    DEBUG_API("->XAObjectItfImpl_Realize");
+    if( !pObjImp || pObjImp != pObjImp->self)
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XAObjectItfImpl_Realize");
+        /* invalid parameter */
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+
+    if( async )
+    {
+        /* invoke asynchronously */
+        if( !pObjImp->callBack )
+        {
+            retval = XA_RESULT_PARAMETER_INVALID;
+        }
+        else
+        {
+            /* check if another async operation is processed */
+            if(pObjImp->asyncOngoing)
+            {
+                /* abort ongoing operation */
+                XAImpl_CancelThread(pObjImp->asyncThr);
+            }
+            pObjImp->asyncOngoing = XA_BOOLEAN_TRUE;
+            if(XAImpl_StartThread(pObjImp->asyncThr, NULL,
+                    XAObjectItfImpl_AsyncRealize,(void*)(self)))
+            {
+                pObjImp->asyncOngoing = XA_BOOLEAN_FALSE;
+                retval = XA_RESULT_RESOURCE_ERROR;
+            }
+            else
+            {
+                retval = XA_RESULT_SUCCESS;
+            }
+        }
+    }
+    else
+    {
+        /* Check if the object is in unrealized state */
+        if(pObjImp->state != XA_OBJECT_STATE_UNREALIZED)
+        {
+            DEBUG_ERR("XA_RESULT_PRECONDITIONS_VIOLATED");
+            DEBUG_API("<-XAObjectItfImpl_Realize");
+            return XA_RESULT_PRECONDITIONS_VIOLATED;
+        }
+        /* invoke synchronously */
+        if( pObjImp->DoRealizeImpl )
+        {
+            retval = pObjImp->DoRealizeImpl(self);
+        }
+    }
+    DEBUG_API("<-XAObjectItfImpl_Realize");
+    return retval;
+}
+
+XAresult XAObjectItfImpl_Resume(XAObjectItf self, XAboolean async)
+{
+    XAresult retval = XA_RESULT_SUCCESS;
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    DEBUG_API("->XAObjectItfImpl_Resume");
+
+    if( !pObjImp || pObjImp != pObjImp->self )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XAObjectItfImpl_Resume");
+        /* invalid parameter */
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+    if( async )
+    {
+        /* invoke asynchronously */
+        if( !pObjImp->callBack )
+        {
+            retval = XA_RESULT_PARAMETER_INVALID;
+        }
+        else
+        {
+            /* check if another async operation is processed */
+            if(pObjImp->asyncOngoing)
+            {
+                /* abort ongoing operation */
+                XAImpl_CancelThread(pObjImp->asyncThr);
+            }
+            pObjImp->asyncOngoing = XA_BOOLEAN_TRUE;
+            if(XAImpl_StartThread(pObjImp->asyncThr, NULL,
+                    XAObjectItfImpl_AsyncResume,(void*)(self)))
+            {
+                pObjImp->asyncOngoing = XA_BOOLEAN_FALSE;
+                retval = XA_RESULT_RESOURCE_ERROR;
+            }
+            else
+            {
+                retval = XA_RESULT_SUCCESS;
+            }
+        }
+    }
+    else
+    {
+        /* invoke synchronously */
+        if( pObjImp->DoResumeImpl )
+        {
+            retval = pObjImp->DoResumeImpl(self);
+        }
+    }
+    DEBUG_API("<-XAObjectItfImpl_Resume");
+    return retval;
+}
+
+XAresult XAObjectItfImpl_GetState(XAObjectItf self, XAuint32 *pState)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    DEBUG_API("->XAObjectItfImpl_GetState");
+    if( !pObjImp || pObjImp != pObjImp->self || !pState )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XAObjectItfImpl_GetState");
+        /* invalid parameter */
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+    *pState = pObjImp->state;
+
+    DEBUG_API("<-XAObjectItfImpl_GetState");
+    return XA_RESULT_SUCCESS;
+}
+
+XAresult XAObjectItfImpl_GetInterface(XAObjectItf self, const XAInterfaceID iid,
+                                       void *pInterface)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    XAObjItfMapEntry *mapEntry = NULL;
+    DEBUG_API("->XAObjectItfImpl_GetInterface");
+
+    if( !pObjImp || pObjImp != pObjImp->self || !pInterface || !iid )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XAObjectItfImpl_GetInterface");
+        /* invalid parameter */
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+
+    if(pObjImp->state != XA_OBJECT_STATE_REALIZED)
+    {
+        DEBUG_ERR("XA_RESULT_PRECONDITIONS_VIOLATED");
+        DEBUG_API("<-XAObjectItfImpl_GetInterface");
+        /*state is not correct */
+        return XA_RESULT_PRECONDITIONS_VIOLATED;
+    }
+
+    mapEntry = XAObjectItfImpl_GetItfEntry(self, iid);
+    if( mapEntry && mapEntry->pItf )
+    {
+        *(void**)pInterface = &(mapEntry->pItf);
+        DEBUG_API("<-XAObjectItfImpl_GetInterface");
+        return XA_RESULT_SUCCESS;
+    }
+    else
+    {
+        DEBUG_ERR("XA_RESULT_FEATURE_UNSUPPORTED");
+        DEBUG_API("<-XAObjectItfImpl_GetInterface");
+        return XA_RESULT_FEATURE_UNSUPPORTED;
+    }
+}
+
+
+XAresult XAObjectItfImpl_RegisterCallback(XAObjectItf self,
+                                       xaObjectCallback callback,
+                                       void *pContext)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    DEBUG_API("->XAObjectItfImpl_RegisterCallback");
+
+    if( !pObjImp || pObjImp != pObjImp->self )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XAObjectItfImpl_RegisterCallback");
+        /* invalid parameter */
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+    pObjImp->callBack = callback;
+    pObjImp->context = pContext;
+    pObjImp->cbPtrToSelf = self;
+
+    DEBUG_API("<-XAObjectItfImpl_RegisterCallback");
+    return XA_RESULT_SUCCESS;
+}
+
+void XAObjectItfImpl_AbortAsyncOperation(XAObjectItf self)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    DEBUG_API("->XAObjectItfImpl_AbortAsyncOperation");
+
+    if( pObjImp &&
+       (pObjImp == pObjImp->self) &&
+        pObjImp->callBack &&
+        pObjImp->asyncOngoing )
+    {
+        /* abort ongoing operation */
+        XAImpl_CancelThread(pObjImp->asyncThr);
+    }
+
+    DEBUG_API("<-XAObjectItfImpl_AbortAsyncOperation");
+}
+
+void XAObjectItfImpl_Destroy(XAObjectItf self)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    DEBUG_API("->XAObjectItfImpl_Destroy");
+
+    if( pObjImp && pObjImp == pObjImp->self )
+    {
+        if( pObjImp->asyncOngoing )
+        {
+            /* abort ongoing operation */
+            XAImpl_CancelThread(pObjImp->asyncThr);
+        }
+        /* free object specific resources */
+        if( pObjImp->FreeResourcesImpl )
+        {
+            pObjImp->FreeResourcesImpl(self);
+        }
+        free(pObjImp->interfaceMap);
+        XAImpl_DeleteThreadHandle(pObjImp->asyncThr);
+        free(pObjImp);
+    }
+
+    DEBUG_API("<-XAObjectItfImpl_Destroy");
+}
+
+XAresult XAObjectItfImpl_SetPriority(XAObjectItf self, XAint32 priority,
+                                  XAboolean preemptable)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    DEBUG_API("->XAObjectItfImpl_SetPriority");
+
+    if( !pObjImp || pObjImp != pObjImp->self )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XAObjectItfImpl_SetPriority");
+        /* invalid parameter */
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+    pObjImp->priority = priority;
+    pObjImp->preemptable = preemptable;
+
+    DEBUG_API("<-XAObjectItfImpl_SetPriority");
+    return XA_RESULT_SUCCESS;
+}
+
+XAresult XAObjectItfImpl_GetPriority(XAObjectItf self, XAint32 *pPriority,
+                                  XAboolean *pPreemptable)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    DEBUG_API("->XAObjectItfImpl_GetPriority");
+
+    if( !pObjImp || pObjImp != pObjImp->self )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XAObjectItfImpl_GetPriority");
+        /* invalid parameter */
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+    *pPriority = pObjImp->priority;
+    *pPreemptable = pObjImp->preemptable;
+
+    DEBUG_API("<-XAObjectItfImpl_GetPriority");
+    return XA_RESULT_SUCCESS;
+}
+
+XAresult XAObjectItfImpl_SetLossOfControlInterfaces(XAObjectItf self,
+                                              XAint16 numInterfaces,
+                                              XAInterfaceID *pInterfaceIDs,
+                                              XAboolean enabled)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    XAint32 itfIndex = 0;
+    XAObjItfMapEntry *mapEntry = NULL;
+    DEBUG_API("->XAObjectItfImpl_SetLossOfControlInterfaces");
+
+    if( !pObjImp || pObjImp != pObjImp->self || !pInterfaceIDs )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XAObjectItfImpl_SetLossOfControlInterfaces");
+        /* invalid parameter */
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+    if( pInterfaceIDs )
+    {
+        for(itfIndex = 0; itfIndex < numInterfaces; itfIndex++)
+        {
+            mapEntry = XAObjectItfImpl_GetItfEntry(self, pInterfaceIDs[itfIndex]);
+            if( mapEntry )
+            {
+                mapEntry->locEnabled = enabled;
+            }
+        }
+    }
+
+    DEBUG_API("<-XAObjectItfImpl_SetLossOfControlInterfaces");
+    return XA_RESULT_SUCCESS;
+}
+
+/**
+ * XAObjectItfImpl -specific methods
+ **/
+
+/*
+ * Allocate and init new object itf instance
+ */
+XAresult XAObjectItfImpl_Init(XAObjectItfImpl* self,
+                              XAuint32 itfCount,
+                              const XAInterfaceID** itfIIDs,
+                              xaDoRealizeImpl doRealizeImpl,
+                              xaDoResumeImpl doResumeImpl,
+                              xaFreeResourcesImpl freeResourcesImpl)
+{
+    XAuint32 i = 0;
+    DEBUG_API("->XAObjectItfImpl_Init");
+
+    assert( self && itfIIDs && doRealizeImpl && doResumeImpl && freeResourcesImpl );
+
+    self->interfaceMap =
+       (XAObjItfMapEntry*)calloc(itfCount, sizeof(XAObjItfMapEntry));
+    if( !self->interfaceMap )
+    {
+        free(self);
+        DEBUG_ERR("XA_RESULT_MEMORY_FAILURE");
+        DEBUG_API("<-XAObjectItfImpl_Init");
+        return XA_RESULT_MEMORY_FAILURE;
+    }
+    if( XAImpl_CreateThreadHandle(&(self->asyncThr)) != XA_RESULT_SUCCESS )
+    {
+        free(self);
+        DEBUG_ERR("XA_RESULT_MEMORY_FAILURE");
+        DEBUG_API("<-XAObjectItfImpl_Init");
+        return XA_RESULT_MEMORY_FAILURE;
+    }
+    for(i=0;i<itfCount;i++)
+    {
+        self->interfaceMap[i].mapIdx = i;
+        self->interfaceMap[i].iid = *(itfIIDs[i]);
+        self->interfaceMap[i].pItf = NULL;
+        self->interfaceMap[i].locEnabled = XA_BOOLEAN_FALSE;
+        self->interfaceMap[i].required = XA_BOOLEAN_FALSE;
+        self->interfaceMap[i].isDynamic = XA_BOOLEAN_FALSE;
+    }
+    self->interfaceMap[0].pItf = self;
+    self->interfaceMap[0].required = XA_BOOLEAN_TRUE;
+
+    self->interfaceCount = itfCount;
+    self->priority = XA_PRIORITY_NORMAL;
+    self->preemptable = XA_BOOLEAN_FALSE;
+    self->state = XA_OBJECT_STATE_UNREALIZED;
+    self->callBack = NULL;
+    self->context = NULL;
+    self->asyncOngoing = XA_BOOLEAN_FALSE;
+    self->cbPtrToSelf = NULL;
+
+    self->DoRealizeImpl = doRealizeImpl;
+    self->DoResumeImpl = doResumeImpl;
+    self->FreeResourcesImpl = freeResourcesImpl;
+
+    /* init itf default implementation */
+    self->itf.Realize = XAObjectItfImpl_Realize;
+    self->itf.Resume = XAObjectItfImpl_Resume;
+    self->itf.GetState = XAObjectItfImpl_GetState;
+    self->itf.GetInterface = XAObjectItfImpl_GetInterface;
+    self->itf.RegisterCallback = XAObjectItfImpl_RegisterCallback;
+    self->itf.AbortAsyncOperation = XAObjectItfImpl_AbortAsyncOperation;
+    self->itf.Destroy = XAObjectItfImpl_Destroy;
+    self->itf.SetPriority = XAObjectItfImpl_SetPriority;
+    self->itf.GetPriority = XAObjectItfImpl_GetPriority;
+    self->itf.SetLossOfControlInterfaces  = XAObjectItfImpl_SetLossOfControlInterfaces;
+    self->self = self;
+
+    DEBUG_API("<-XAObjectItfImpl_Init");
+    return XA_RESULT_SUCCESS;
+}
+
+/*
+ * Asynchronous invocation of Realize
+ */
+void* XAObjectItfImpl_AsyncRealize(void* args)
+{
+    XAresult retval = XA_RESULT_SUCCESS;
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*(XAObjectItf)(args));
+    DEBUG_API("->XAObjectItfImpl_AsyncRealize");
+
+    if( pObjImp && pObjImp == pObjImp->self)
+    {
+        /* Check if the object is in unrealized state */
+        if(pObjImp->state != XA_OBJECT_STATE_UNREALIZED)
+        {
+            retval = XA_RESULT_PRECONDITIONS_VIOLATED;
+        }
+        else if( pObjImp->DoRealizeImpl )
+        {
+            retval = pObjImp->DoRealizeImpl((XAObjectItf)(args));
+        }
+        if( pObjImp->callBack )
+        {
+            pObjImp->callBack(pObjImp->cbPtrToSelf, pObjImp->context,
+                              XA_OBJECT_EVENT_ASYNC_TERMINATION,
+                              retval, pObjImp->state, NULL);
+        }
+        pObjImp->asyncOngoing = XA_BOOLEAN_FALSE;
+        XAImpl_ExitThread(pObjImp->asyncThr);
+    }
+    else
+    {
+        DEBUG_API("XAObjectItfImpl_AsyncRealize: INVALID args");
+    }
+    
+
+    DEBUG_API("<-XAObjectItfImpl_AsyncRealize");
+    return NULL;
+}
+
+
+/*
+ * Asynchronous invocation of Resume
+ */
+void* XAObjectItfImpl_AsyncResume(void* args)
+{
+    XAresult retval = XA_RESULT_SUCCESS;
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*(XAObjectItf)(args));
+    DEBUG_API("->XAObjectItfImpl_AsyncResume");
+
+    if( pObjImp && pObjImp == pObjImp->self )
+    {
+        if( pObjImp->DoResumeImpl )
+        {
+            retval = pObjImp->DoResumeImpl((XAObjectItf)(args));
+        }
+        if( pObjImp->callBack )
+        {
+            pObjImp->callBack(pObjImp->cbPtrToSelf, pObjImp->context,
+                              XA_OBJECT_EVENT_ASYNC_TERMINATION,
+                              retval, pObjImp->state, NULL);
+        }
+        pObjImp->asyncOngoing = XA_BOOLEAN_FALSE;
+        XAImpl_ExitThread(pObjImp->asyncThr);
+    }
+    else
+    {
+        DEBUG_API("XAObjectItfImpl_AsyncResume: INVALID args");
+    }
+    
+
+    DEBUG_API("<-XAObjectItfImpl_AsyncResume");
+    return NULL;
+}
+
+void XAObjectItfImpl_AsyncCleanup(void* args)
+{
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*(XAObjectItf)(args));
+    DEBUG_API("->XAObjectItfImpl_AsyncCleanup");
+
+    if( pObjImp &&
+       (pObjImp == pObjImp->self) &&
+        pObjImp->FreeResourcesImpl )
+    {
+        pObjImp->FreeResourcesImpl((XAObjectItf)(args));
+    }
+    else
+    {
+        DEBUG_API("XAObjectItfImpl_AsyncCleanup: INVALID args");
+    }
+
+    DEBUG_API("<-XAObjectItfImpl_AsyncCleanup");
+}
+
+XAObjItfMapEntry* XAObjectItfImpl_GetItfEntry(const XAObjectItf self,
+                                              const XAInterfaceID iid)
+{
+    XAuint32 mapIndex = 0;
+    XAObjectItfImpl* pObjImp = (XAObjectItfImpl*)(*self);
+    DEBUG_API("->XAObjectItfImpl_GetItfEntry");
+
+    if( pObjImp &&
+       (pObjImp == pObjImp->self) &&
+        pObjImp->interfaceMap &&
+        iid )
+    {
+        /* Check interface */
+        for(mapIndex = 0; mapIndex < pObjImp->interfaceCount; mapIndex++)
+        {
+            if(XACommon_EqualIIds(pObjImp->interfaceMap[mapIndex].iid, iid))
+            {
+                DEBUG_API("<-XAObjectItfImpl_GetItfEntry");
+                return &(pObjImp->interfaceMap[mapIndex]);
+            }
+        }
+    }
+
+    DEBUG_API("<-XAObjectItfImpl_GetItfEntry");
+    return NULL;
+}
+