khronosfws/openmax_al/src/mediarecorder/xamediarecorder.c
author hgs
Tue, 21 Sep 2010 11:38:43 -0500
changeset 53 eabc8c503852
parent 43 9894ed580e4a
permissions -rw-r--r--
201037

/*
 * 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: MediaRecoder Object Impl
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xamediarecorder.h"
#include "xaaudioencoderitf.h"
#include "xadynintmgmtitf.h"
#include "xarecorditf.h"
#include "xathreadsafety.h"
#include "xacapabilitiesmgr.h"
#include "xamediarecorderadaptctxmmf.h"
#include "xamediarecorderadaptctx.h"
/* Static mapping of enumeration XAMediaRecorderInterfaces to interface iids */
static const XAInterfaceID* xaMediaRecorderItfIIDs[MR_ITFCOUNT] =
    {
    &XA_IID_OBJECT,
    &XA_IID_AUDIOENCODER,
    &XA_IID_DYNAMICINTERFACEMANAGEMENT,
    &XA_IID_RECORD
    };

/* Global methods */

/* XAResult XAMediaRecorderImpl_Create
 * Create object
 */
XAresult XAMediaRecorderImpl_CreateMediaRecorder(FrameworkMap* mapper,
        XACapabilities* capabilities, XAObjectItf* pRecorder,
        XADataSource* pAudioSrc, XADataSource* pImageVideoSrc,
        XADataSink* pDataSnk, XAuint32 numInterfaces,
        const XAInterfaceID *pInterfaceIds,
        const XAboolean *pInterfaceRequired)
    {
    XAMediaRecorderImpl* pImpl = NULL;
    XAObjectItfImpl* pBaseObj = NULL;
    FWMgrFwType fwType;
    XAuint8 itfIdx;
    XAMediaType mediaType = XA_MEDIATYPE_UNKNOWN;
    XAresult ret = XA_RESULT_SUCCESS;
    const char *uri = NULL;

    DEBUG_API("->XAMediaRecorderImpl_CreateMediaRecorder");
    XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaRecorder );

    /* check sink&source parameters */
    ret = XACommon_ValidateDataLocator(3, pAudioSrc, pImageVideoSrc,
                    pDataSnk);
    if (ret != XA_RESULT_SUCCESS)
        {
        XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
        DEBUG_API("<-XAMediaRecorderImpl_CreateMediaRecorder");
        return ret;
        }
    
    /* check only sink media type, do not care about return value (availability) */
    XACommon_CheckDataSource((XADataSource*) pDataSnk, &mediaType);
    
    if (!pRecorder || (!pAudioSrc && !pImageVideoSrc) || !pDataSnk)
        {
        /* invalid parameter */
        XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        DEBUG_API("<-XAMediaRecorderImpl_CreateMediaRecorder");
        return XA_RESULT_PARAMETER_INVALID;
        }

    /* instantiate object implementation */
    pImpl = (XAMediaRecorderImpl*) calloc(1, sizeof(XAMediaRecorderImpl));
    if (!pImpl)
        {
        /* memory allocation failed */
        XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
        DEBUG_ERR("XA_RESULT_MEMORY_FAILURE");
        DEBUG_API("<-XAMediaRecorderImpl_CreateMediaRecorder");
        return XA_RESULT_MEMORY_FAILURE;
        }
    
    pBaseObj = &pImpl->baseObj;

    /* Initialize base object default implementation */
    XAObjectItfImpl_Init(pBaseObj, MR_ITFCOUNT, xaMediaRecorderItfIIDs,
            XAMediaRecorderImpl_DoRealize, XAMediaRecorderImpl_DoResume,
            XAMediaRecorderImpl_FreeResources);
        
    /* Mark interfaces that need to be exposed */
    /* Mandated Implicit interfaces */
    pBaseObj->interfaceMap[MR_DIMITF].required = XA_BOOLEAN_TRUE;

    /* Mark interfaces that can be handled dynamically */
    /* Mandated dynamic itfs */

    /*Mandated  Explicit interfaces */
    if ((numInterfaces != 0) && pInterfaceIds && pInterfaceRequired)
        {
        /* Check required interfaces */
        for (itfIdx = 0; itfIdx < numInterfaces; itfIdx++)
            {
            /* If mapEntry is null then required interface is not supported.*/
            XAObjItfMapEntry *entry = XAObjectItfImpl_GetItfEntry(
                    (XAObjectItf) &(pBaseObj), pInterfaceIds[itfIdx]);
            if (!entry)
                {
                if (pInterfaceRequired[itfIdx])
                    {
                    /* required interface cannot be accommodated - fail creation */
                    DEBUG_ERR("Required interface not found - abort creation!");
                    ret = XA_RESULT_FEATURE_UNSUPPORTED;
                    break;
                    }
                else
                    {
                    DEBUG_INFO("Requested (not required) interface not found - continue creation");
                    }
                }
            else
                {
                entry->required = XA_BOOLEAN_TRUE;
                }
            }
        }

    if (ret != XA_RESULT_SUCCESS)
        { /* creation fails */
        XAObjectItfImpl_Destroy((XAObjectItf) &(pBaseObj));
        XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
        DEBUG_API("<-XAMediaRecorderImpl_CreateMediaRecorder");
        return ret;
        }
    
    /* Initialize XAMediaRecorderImpl variables */
    pImpl->audioSrc = pAudioSrc;
    pImpl->dataSnk = pDataSnk;
    pImpl->imageVideoSrc = pImageVideoSrc;
    pImpl->recModes |= XA_RECMODE_STREAM;

    /* Determine framework type that can handle recording */
    fwType = (FWMgrFwType) FWMgrMOUnknown;
    /**/
    if (pDataSnk->pLocator)
        {
        XADataLocator_URI* dataLoc = (XADataLocator_URI*) pDataSnk->pLocator;
        if (dataLoc->locatorType == XA_DATALOCATOR_URI)
            {
            uri = (char*) dataLoc->URI;
            }
        }
    
    fwType = XAFrameworkMgr_GetFramework(mapper, uri, FWMgrMORecorder);

    switch(fwType)
        {
        case FWMgrFWMMF:
            {

            pImpl->adaptationCtx = XAMediaRecorderAdaptMMF_Create(
                    pImpl->audioSrc, pImpl->imageVideoSrc, pImpl->dataSnk,
                    pImpl->recModes);
            }
            break;
        case FWMgrFWGST:
            {
            pImpl->adaptationCtx = XAMediaRecorderAdapt_Create(pImpl->audioSrc,
                    pImpl->imageVideoSrc, pImpl->dataSnk, pImpl->recModes);
            break;
            }
        case FWMgrFWUknown:
        default:
            {
            ret = XA_RESULT_CONTENT_UNSUPPORTED;
            break;
            }
        }
    
    if (ret != XA_RESULT_SUCCESS)
        { /* creation fails */
        XAObjectItfImpl_Destroy((XAObjectItf) &(pBaseObj));
        XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
        DEBUG_API("<-XAMediaRecorderImpl_CreateMediaRecorder");
        return ret;
        }
    
    if (pImpl->adaptationCtx)
        {
        pImpl->adaptationCtx->capslist = capabilities;
        pImpl->adaptationCtx->fwtype = fwType;
        }
    else
        {
        ret = XA_RESULT_MEMORY_FAILURE;
        XAObjectItfImpl_Destroy((XAObjectItf) &(pBaseObj));
        XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
        DEBUG_API("<-XAMediaRecorderImpl_CreateMediaRecorder");
        return ret;
        }

    /* Set ObjectItf to point to newly created object */
    *pRecorder = (XAObjectItf) &(pBaseObj->self);
    
    XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
    DEBUG_API("<-XAMediaRecorderImpl_CreateMediaRecorder");
    return XA_RESULT_SUCCESS;
    }

/* XAResult XAMediaRecorderImpl_QueryNumSupportedInterfaces
 * Statically query supported interfaces
 */
XAresult XAMediaRecorderImpl_QueryNumSupportedInterfaces(
        XAuint32 *pNumSupportedInterfaces)
    {
    DEBUG_API("->XAMediaRecorderImpl_QueryNumSupportedInterfaces");
    *pNumSupportedInterfaces = MR_ITFCOUNT;
    DEBUG_API("<-XAMediaRecorderImpl_QueryNumSupportedInterfaces");
    return XA_RESULT_SUCCESS;
    }
/* XAResult XAMediaRecorderImpl_QuerySupportedInterfaces
 * Statically query supported interfaces
 */
XAresult XAMediaRecorderImpl_QuerySupportedInterfaces(XAuint32 index,
        XAInterfaceID *pInterfaceId)
    {
    DEBUG_API("->XAMediaRecorderImpl_QuerySupportedInterfaces");
    if (index >= MR_ITFCOUNT)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        return XA_RESULT_PARAMETER_INVALID;
        }
    else
        {
        *pInterfaceId = *(xaMediaRecorderItfIIDs[index]);
        DEBUG_API("<-XAMediaRecorderImpl_QuerySupportedInterfaces");
        return XA_RESULT_SUCCESS;
        }
    }

/*****************************************************************************
 * base object XAObjectItfImpl methods
 *****************************************************************************/

/* XAresult XAMediaRecorderImpl_DoRealize( XAObjectItf self )
 * Description: Realize all implicit and explicitly wanted interfaces.
 * Create and initialize implementation-specific variables.
 * Called from base object XAObjectItfImpl
 */
XAresult XAMediaRecorderImpl_DoRealize(XAObjectItf self)
    {
    XAuint8 itfIdx;
    XAObjectItfImpl* pObj = (XAObjectItfImpl*) (*self);
    XAMediaRecorderImpl* pObjImpl = (XAMediaRecorderImpl*) (pObj);
    XAresult ret = XA_RESULT_SUCCESS;

    DEBUG_API("->XAMediaRecorderImpl_DoRealize");
    XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaRecorder );

    /* check casting from correct pointer type */
    if (!pObjImpl || pObj != pObjImpl->baseObj.self)
        {
        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
        /* invalid parameter */
        XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
        return XA_RESULT_PARAMETER_INVALID;
        }
 
    /* Realize all implicit and explicitly wanted interfaces */
    for (itfIdx = 0; itfIdx < MR_ITFCOUNT; itfIdx++)
        {
        if (!(pObj->interfaceMap[itfIdx].pItf)
                && pObj->interfaceMap[itfIdx].required)
            {
            void *pItf = NULL;
            switch (itfIdx)
                {
                case MR_DIMITF:
                    pItf = XADIMItfImpl_Create();
                    if (pItf)
                        {
                        XADIMItfImpl_Init(pItf, self,
                                XAMediaRecorderImpl_DoAddItf,
                                XAMediaRecorderImpl_DoResumeItf,
                                XAMediaRecorderImpl_DoRemoveItf);
                        }
                    break;
                case MR_RECORDITF:
                    pItf = XARecordItfImpl_Create(pObjImpl);
                    break;
                case MR_AUDIOENCODERITF:
                    pItf = XAAudioEncoderItfImpl_Create(pObjImpl);
                    break;
                default:
                    break;
                }
            if (!pItf)
                {
                DEBUG_ERR("XA_RESULT_MEMORY_FAILURE");
                /* memory allocation failed */
                XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
                return XA_RESULT_MEMORY_FAILURE;
                }
            else
                {
                pObj->interfaceMap[itfIdx].pItf = pItf;
                }
            }
        }

    /* init adaptation */
    if (pObjImpl->adaptationCtx->fwtype == FWMgrFWMMF)
        {
        ret = XAMediaRecorderAdaptMMF_PostInit(
                (XAAdaptationMMFCtx*) pObjImpl->adaptationCtx);
        }
    else
        {
        ret = XAMediaRecorderAdapt_PostInit(
                (XAAdaptationGstCtx*) pObjImpl->adaptationCtx);
        }

    if (ret != XA_RESULT_SUCCESS)
        {
        XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
        return ret;
        }

    XAAdaptationBase_AddEventHandler(pObjImpl->adaptationCtx,
            &XAMediaRecorderImpl_AdaptCb, XA_OBJECTITFEVENTS, pObjImpl);
    
    pObj->state = XA_OBJECT_STATE_REALIZED;
    DEBUG_API("<-XAMediaRecorderImpl_DoRealize");
    XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
    return XA_RESULT_SUCCESS;
    }

/* XAresult XAMediaRecorderImpl_DoResume
 * Description: Resume object from suspended state
 */
XAresult XAMediaRecorderImpl_DoResume(XAObjectItf self)
    {
    DEBUG_API("->XAMediaRecorderImpl_DoResume");
    DEBUG_API("<-XAMediaRecorderImpl_DoResume");
    /* This implementation does not support suspended state */
    return XA_RESULT_PRECONDITIONS_VIOLATED;
    }

/* void XAMediaRecorderImpl_FreeResources
 * Description: Free all resources reserved at XAMediaRecorderImpl_DoRealize()
 */
void XAMediaRecorderImpl_FreeResources(XAObjectItf self)
    {
    XAObjectItfImpl* pObj = (XAObjectItfImpl*) (*self);
    XAMediaRecorderImpl* pObjImpl = (XAMediaRecorderImpl*) (pObj);
    XAuint8 itfIdx;
    XAMediaRecorderImpl* pImpl = (XAMediaRecorderImpl*) (*self);
    DEBUG_API("->XAMediaRecorderImpl_FreeResources");
    XA_IMPL_THREAD_SAFETY_ENTRY_FOR_VOID_FUNCTIONS( XATSMediaRecorder );

    /* free all allocated interfaces */
    for (itfIdx = 0; itfIdx < MR_ITFCOUNT; itfIdx++)
        {
        void *pItf = pObj->interfaceMap[itfIdx].pItf;
        if (pItf)
            {
            switch (itfIdx)
                {
                case MR_AUDIOENCODERITF:
                    XAAudioEncoderItfImpl_Free(pItf);
                    break;
                case MR_DIMITF:
                    XADIMItfImpl_Free(pItf);
                    break;
                case MR_RECORDITF:
                    XARecordItfImpl_Free(pItf);
                    break;
                default:
                    break;
                }
            pObj->interfaceMap[itfIdx].pItf = NULL;
            }
        }

    if (pImpl->adaptationCtx != NULL)
        {
        if (pImpl->adaptationCtx->fwtype == FWMgrFWMMF)
            {
            XAMediaRecorderAdaptMMF_Destroy(
                    (XAAdaptationMMFCtx*) pObjImpl->adaptationCtx);
            }
        else
            {
            XAMediaRecorderAdapt_Destroy(
                    (XAAdaptationGstCtx*) pImpl->adaptationCtx);
            }
        pImpl->adaptationCtx = NULL;
        }

    /* free all other allocated resources*/

    DEBUG_API("<-XAMediaRecorderImpl_FreeResources");
    XA_IMPL_THREAD_SAFETY_EXIT_FOR_VOID_FUNCTIONS( XATSMediaRecorder );
    return;
    }

/* void XARecordItfImpl_AdaptCb
 * Description: Listen changes in adaptation
 */
void XAMediaRecorderImpl_AdaptCb(void *pHandlerCtx, XAAdaptEvent *event)
    {
    XAObjectItfImpl* impl = (XAObjectItfImpl*) pHandlerCtx;
    DEBUG_API("->XAMediaRecorderImpl_AdaptCb");

    if (!impl)
        {
        DEBUG_ERR("XAMediaRecorderImpl_AdaptCb, invalid context pointer!");
        DEBUG_API("<-XAMediaRecorderImpl_AdaptCb");
        return;
        }

    if(impl->callBack)
        {
        if(event)
            {
            XAObjItfCBData* data = (XAObjItfCBData*)(event->data);
            if(data->event == XA_OBJECT_EVENT_RESOURCES_LOST )
                {
                impl->state = data->param;
                }
            impl->callBack(impl->cbPtrToSelf, impl->context, data->event, data->result, data->param, data->interface);
            }
        }
    
    DEBUG_API("<-XAMediaRecorderImpl_AdaptCb");
    }


/*****************************************************************************
 * MediaRecorderImpl -specific methods
 *****************************************************************************/

/* XAMediaRecorderImpl_DoAddItf
 * Dynamically add an interface, object specific parts
 */
XAresult XAMediaRecorderImpl_DoAddItf(XAObjectItf self,
        XAObjItfMapEntry *mapEntry)
    {
    XAresult ret = XA_RESULT_SUCCESS;

    DEBUG_API("->XAMediaRecorderImpl_DoAddItf");
    XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaRecorder );

    if (mapEntry)
        {
        switch (mapEntry->mapIdx)
            {
            default:
                DEBUG_ERR("XAMediaRecorderImpl_DoAddItf unknown id");
                ret = XA_RESULT_FEATURE_UNSUPPORTED;
                break;
            }

        if (!mapEntry->pItf && ret == XA_RESULT_SUCCESS)
            {
            DEBUG_ERR("XAMediaRecorderImpl_DoAddItf itf creation failed");
            ret = XA_RESULT_MEMORY_FAILURE;
            }
        }
    else
        {
        ret = XA_RESULT_PARAMETER_INVALID;
        }

    XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
    DEBUG_API("<-XAMediaRecorderImpl_DoAddItf");
    return ret;
    }

/* XAMediaRecorderImpl_DoResumeItf
 * Try to resume lost interface, object specific parts
 */
XAresult XAMediaRecorderImpl_DoResumeItf(XAObjectItf self,
        XAObjItfMapEntry *mapEntry)
    {
    XAresult ret;
    /* For now, no difference between suspended and unrealised itfs */
    DEBUG_API("->XAMediaRecorderImpl_DoResumeItf");
    XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaRecorder );
    ret = XAMediaRecorderImpl_DoAddItf(self, mapEntry);
    XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
    DEBUG_API("<-XAMediaRecorderImpl_DoResumeItf");
    return ret;
    }

/* XAMediaRecorderImpl_DoRemoveItf
 * Dynamically remove an interface, object specific parts
 */
XAresult XAMediaRecorderImpl_DoRemoveItf(XAObjectItf self,
        XAObjItfMapEntry *mapEntry)
    {
    XAresult ret = XA_RESULT_SUCCESS;
    DEBUG_API("->XAMediaRecorderImpl_DoRemoveItf");
    XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaRecorder );
    if (mapEntry)
        {
        switch (mapEntry->mapIdx)
            {
            default:
                DEBUG_ERR("XAMediaRecorderImpl_DoRemoveItf unknown id");
                ret = XA_RESULT_FEATURE_UNSUPPORTED;
                break;
            }
        mapEntry->pItf = NULL;
        }
    else
        {
        ret = XA_RESULT_PARAMETER_INVALID;
        }

    XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaRecorder );
    DEBUG_API("<-XAMediaRecorderImpl_DoRemoveItf");
    return ret;
    }

/* END OF FILE */