--- /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 <string.h>
+#include <gst.h>
+#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;
+}
+
+