diff -r 80975da52420 -r 43d09473c595 khronosfws/openmax_al/src/gst_adaptation/xaoutputmixitfadaptation.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/khronosfws/openmax_al/src/gst_adaptation/xaoutputmixitfadaptation.c Fri May 14 16:22:35 2010 +0300 @@ -0,0 +1,203 @@ +/* +* 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 +#include +#include "xaoutputmixadaptctx.h" +#include "xaoutputmixitfadaptation.h" +#include "xaadaptationgst.h" +#include "xacapabilitiesmgr.h" + +/* + * XAresult XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs( XAAdaptationGstCtx *bCtx, + * XAint32 * pNumDevices, + * XAuint32 * pDeviceIDs ) + * @param XAAdaptationGstCtx *bCtx - Pointer to OutputMix adaptation context + * @param XAint32 * pNumDevices - [in] Length of pDeviceIDs array + * [out] number of destination devices + * @param XAuint32 * pDeviceIDs - List of DeviceIDs + * @return XAresult success value + * Description: Returns audio output deviceIDs that are currently connected + */ +XAresult XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs( XAAdaptationGstCtx *bCtx, XAint32 * pNumDevices, XAuint32 * pDeviceIDs ) +{ + XAOutputMixAdaptationCtx* mCtx = NULL; + XAint32 iterator = 0; + DEBUG_API_A1("->XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs pNumDevices:%ld",*pNumDevices); + if(!bCtx || bCtx->baseObj.ctxId != XAOutputMixAdaptation ) + { + DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); + DEBUG_API("<-XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs"); + return XA_RESULT_PARAMETER_INVALID; + } + mCtx = (XAOutputMixAdaptationCtx*) bCtx; + if(!mCtx) + { + DEBUG_ERR("NULL context!"); + return XA_RESULT_PARAMETER_INVALID; + } + + if ( pNumDevices ) + { + *pNumDevices = mCtx->availableDevices->len; + } + else + { + DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); + DEBUG_API("<-XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs"); + return XA_RESULT_PARAMETER_INVALID; + } + + if(pDeviceIDs) + { /*query devices*/ + if ( *pNumDevices < mCtx->availableDevices->len ) + { /* Lenght of pDeviceIDs is insufficient for all connected audio devices */ + DEBUG_ERR("XA_RESULT_BUFFER_INSUFFICIENT"); + DEBUG_API("<-XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs"); + return XA_RESULT_BUFFER_INSUFFICIENT; + } + + for ( iterator = 0; iterator < mCtx->availableDevices->len; iterator++ ) + { + pDeviceIDs[iterator] = g_array_index(mCtx->availableDevices,XAuint32,iterator); + } + } + + DEBUG_API("<-XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs"); + return XA_RESULT_SUCCESS; +} + + +/* + * XAresult XAOutputMixItfAdapt_ReRoute( XAAdaptationGstCtx *bCtx, + * XAint32 numOutputDevices, + * XAuint32 * pOutputDeviceIDs) + * @param XAAdaptationGstCtx *bCtx - Ponter to OutputMix adaptation context + * @param XAint32 numOutputDevices - Length of pOutputDeviceIDs + * @param XAuint32 * pOutputDeviceIDs - List of requested audio output device IDs + * @return XAresult success value + * Description: Reroutes audio output to requested destination devices + */ +XAresult XAOutputMixItfAdapt_ReRoute( XAAdaptationGstCtx *bCtx, XAint32 numOutputDevices, XAuint32 * pOutputDeviceIDs) +{ + XAresult ret = XA_RESULT_SUCCESS; + gint32 idx = 0; + XAOutputMixAdaptationCtx* mCtx = NULL; + XAuint32 devId=0; + GstElement* newsink = NULL; + GstElement* current = NULL; + gchar* currentname= NULL; + XACapabilities temp; + + DEBUG_API_A1("->XAOutputMixItfAdapt_ReRoute numOutputDevices:%ld",numOutputDevices); + if(!bCtx || + bCtx->baseObj.ctxId != XAOutputMixAdaptation || + !pOutputDeviceIDs ) + { + DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); + return XA_RESULT_PARAMETER_INVALID; + } + + mCtx = (XAOutputMixAdaptationCtx*) bCtx; + + if( numOutputDevices > 1 ) + { + /* currently, only routing to single output at time supported */ + return XA_RESULT_FEATURE_UNSUPPORTED; + } + devId = pOutputDeviceIDs[0]; + + for ( idx = 0; idx < mCtx->connectedObjects->len; idx++ ) + { + /*find wanted output plugin name*/ + if( XA_RESULT_SUCCESS == + XACapabilitiesMgr_GetCapsById(NULL, (XACapsType)(XACAP_DEVSNK|XACAP_AUDIO), devId, &temp) ) + { + XAAdaptationGstCtx* ctx = g_array_index(mCtx->connectedObjects,XAOMixAdaptConnObj,idx).ctx; + if(!ctx) + { + DEBUG_ERR_A1("Context in connected objects array (index %u) is NULL!", idx); + return XA_RESULT_INTERNAL_ERROR; + } + /*check current output plugin name*/ + current = g_array_index(mCtx->connectedObjects,XAOMixAdaptConnObj,idx).currentSink; + currentname = gst_element_get_name(current); + DEBUG_INFO_A2("OMix pl%d - current output: \"%s\"", (int)idx, (char*)currentname); + DEBUG_INFO_A3("OMix pl%d - wanted output: \"%s\" (id 0x%x)", (int)idx, (char*)temp.adaptId, (int)devId); + if(strcmp(currentname,(char*)temp.adaptId)!=0) + { + if(ret==XA_RESULT_SUCCESS) + { + mCtx->currentrouting = devId; + g_array_index(mCtx->connectedObjects,XAOMixAdaptConnObj,idx).currentSink = newsink; + } + newsink = gst_bin_get_by_name(GST_BIN(ctx->bin), (char*)temp.adaptId); + if(!newsink) + { /*not existing yet, create*/ + newsink = gst_element_factory_make((char*)temp.adaptId,(char*)temp.adaptId); + gst_bin_add(GST_BIN(ctx->bin), newsink); + } + if(!newsink) + { + DEBUG_ERR_A1("Could not create wanted sink \"%s\"!", (char*)temp.adaptId); + ret = XA_RESULT_PARAMETER_INVALID; + } + else + { + /* switch routing: pause, block, unlink old, link new, unblock pipe, play*/ + GstPad *sinkpad=NULL, *blockpad=NULL; + sinkpad = gst_element_get_static_pad(current,"sink"); + if(sinkpad) + { + blockpad = gst_pad_get_peer(sinkpad); + } + if(blockpad && gst_pad_is_active(blockpad)) + { + DEBUG_INFO("block pad"); + gst_pad_set_blocked_async(blockpad,TRUE,XAAdaptationGst_PadBlockCb,NULL); + } + gst_pad_unlink(blockpad, sinkpad); + sinkpad = gst_element_get_static_pad(newsink,"sink"); + gst_pad_link(blockpad, sinkpad); + if(gst_pad_is_blocked(blockpad)) + { + DEBUG_INFO("unblock pad"); + gst_pad_set_blocked_async(blockpad,FALSE,XAAdaptationGst_PadBlockCb,NULL); + } + /*set sink to same state as the mp bin*/ + gst_element_sync_state_with_parent(newsink); + mCtx->currentrouting = devId; + g_array_index(mCtx->connectedObjects,XAOMixAdaptConnObj,idx).currentSink = newsink; + } + } + else + { + DEBUG_INFO("No routing switch needed"); + } + } + else + { + DEBUG_ERR_A1("Could not find audio device by id 0x%x", (int)devId); + ret = XA_RESULT_PARAMETER_INVALID; + } + } + + DEBUG_API("<-XAOutputMixItfAdapt_ReRoute"); + return ret; +} + +