khronosfws/openmax_al/src/gst_adaptation/xaoutputmixitfadaptation.c
changeset 16 43d09473c595
child 20 b67dd1fc57c5
equal deleted inserted replaced
14:80975da52420 16:43d09473c595
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include <string.h>
       
    19 #include <gst.h>
       
    20 #include "xaoutputmixadaptctx.h"
       
    21 #include "xaoutputmixitfadaptation.h"
       
    22 #include "xaadaptationgst.h"
       
    23 #include "xacapabilitiesmgr.h"
       
    24 
       
    25 /*
       
    26  * XAresult XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs( XAAdaptationGstCtx *bCtx,
       
    27  *                                                              XAint32 * pNumDevices,
       
    28  *                                                              XAuint32 * pDeviceIDs )
       
    29  * @param XAAdaptationGstCtx *bCtx - Pointer to OutputMix adaptation context
       
    30  * @param XAint32 * pNumDevices - [in] Length of pDeviceIDs array
       
    31  *                                [out] number of destination devices
       
    32  * @param XAuint32 * pDeviceIDs - List of DeviceIDs
       
    33  * @return XAresult success value
       
    34  * Description: Returns audio output deviceIDs that are currently connected
       
    35  */
       
    36 XAresult XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs( XAAdaptationGstCtx *bCtx, XAint32 * pNumDevices, XAuint32 * pDeviceIDs )
       
    37 {
       
    38     XAOutputMixAdaptationCtx* mCtx = NULL;
       
    39     XAint32 iterator = 0;
       
    40     DEBUG_API_A1("->XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs pNumDevices:%ld",*pNumDevices);
       
    41     if(!bCtx || bCtx->baseObj.ctxId != XAOutputMixAdaptation )
       
    42     {
       
    43         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
       
    44         DEBUG_API("<-XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs");
       
    45         return XA_RESULT_PARAMETER_INVALID;
       
    46     }
       
    47     mCtx = (XAOutputMixAdaptationCtx*) bCtx;
       
    48     if(!mCtx)
       
    49     {
       
    50         DEBUG_ERR("NULL context!");
       
    51         return XA_RESULT_PARAMETER_INVALID;
       
    52     }
       
    53 
       
    54     if ( pNumDevices )
       
    55     {
       
    56         *pNumDevices = mCtx->availableDevices->len;
       
    57     }
       
    58     else
       
    59     {
       
    60         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
       
    61         DEBUG_API("<-XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs");
       
    62         return XA_RESULT_PARAMETER_INVALID;
       
    63     }
       
    64 
       
    65     if(pDeviceIDs)
       
    66     {   /*query devices*/
       
    67         if ( *pNumDevices < mCtx->availableDevices->len )
       
    68         {    /* Lenght of pDeviceIDs is insufficient for all connected audio devices */
       
    69             DEBUG_ERR("XA_RESULT_BUFFER_INSUFFICIENT");
       
    70             DEBUG_API("<-XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs");
       
    71             return XA_RESULT_BUFFER_INSUFFICIENT;
       
    72         }
       
    73 
       
    74         for ( iterator = 0; iterator <  mCtx->availableDevices->len; iterator++ )
       
    75         {
       
    76             pDeviceIDs[iterator] = g_array_index(mCtx->availableDevices,XAuint32,iterator);
       
    77         }
       
    78     }
       
    79 
       
    80     DEBUG_API("<-XAOutputMixItfAdapt_GetDestinationOutputDeviceIDs");
       
    81     return XA_RESULT_SUCCESS;
       
    82 }
       
    83 
       
    84 
       
    85 /*
       
    86  * XAresult XAOutputMixItfAdapt_ReRoute( XAAdaptationGstCtx *bCtx,
       
    87  *                                       XAint32 numOutputDevices,
       
    88  *                                       XAuint32 * pOutputDeviceIDs)
       
    89  * @param XAAdaptationGstCtx *bCtx - Ponter to OutputMix adaptation context
       
    90  * @param XAint32 numOutputDevices - Length of pOutputDeviceIDs
       
    91  * @param XAuint32 * pOutputDeviceIDs - List of requested audio output device IDs
       
    92  * @return XAresult success value
       
    93  * Description: Reroutes audio output to requested destination devices
       
    94  */
       
    95 XAresult XAOutputMixItfAdapt_ReRoute( XAAdaptationGstCtx *bCtx, XAint32 numOutputDevices, XAuint32 * pOutputDeviceIDs)
       
    96 {
       
    97     XAresult ret = XA_RESULT_SUCCESS;
       
    98     gint32 idx = 0;
       
    99     XAOutputMixAdaptationCtx* mCtx = NULL;
       
   100     XAuint32 devId=0;
       
   101     GstElement* newsink = NULL;
       
   102     GstElement* current = NULL;
       
   103     gchar* currentname= NULL;
       
   104     XACapabilities temp;
       
   105 
       
   106     DEBUG_API_A1("->XAOutputMixItfAdapt_ReRoute numOutputDevices:%ld",numOutputDevices);
       
   107     if(!bCtx ||
       
   108         bCtx->baseObj.ctxId != XAOutputMixAdaptation ||
       
   109         !pOutputDeviceIDs )
       
   110     {
       
   111         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
       
   112         return XA_RESULT_PARAMETER_INVALID;
       
   113     }
       
   114 
       
   115     mCtx = (XAOutputMixAdaptationCtx*) bCtx;
       
   116 
       
   117     if( numOutputDevices > 1 )
       
   118     {
       
   119         /* currently, only routing to single output at time supported */
       
   120         return XA_RESULT_FEATURE_UNSUPPORTED;
       
   121     }
       
   122     devId = pOutputDeviceIDs[0];
       
   123 
       
   124     for ( idx = 0; idx < mCtx->connectedObjects->len; idx++ )
       
   125     {
       
   126         /*find wanted output plugin name*/
       
   127         if( XA_RESULT_SUCCESS ==
       
   128             XACapabilitiesMgr_GetCapsById(NULL, (XACapsType)(XACAP_DEVSNK|XACAP_AUDIO), devId, &temp) )
       
   129         {
       
   130             XAAdaptationGstCtx* ctx = g_array_index(mCtx->connectedObjects,XAOMixAdaptConnObj,idx).ctx;
       
   131             if(!ctx)
       
   132             {
       
   133                 DEBUG_ERR_A1("Context in connected objects array (index %u) is NULL!", idx);
       
   134                 return XA_RESULT_INTERNAL_ERROR;
       
   135             }
       
   136             /*check current output plugin name*/
       
   137             current = g_array_index(mCtx->connectedObjects,XAOMixAdaptConnObj,idx).currentSink;
       
   138             currentname = gst_element_get_name(current);
       
   139             DEBUG_INFO_A2("OMix pl%d - current output: \"%s\"", (int)idx, (char*)currentname);
       
   140             DEBUG_INFO_A3("OMix pl%d -  wanted output: \"%s\" (id 0x%x)", (int)idx, (char*)temp.adaptId, (int)devId);
       
   141             if(strcmp(currentname,(char*)temp.adaptId)!=0)
       
   142             {
       
   143                 if(ret==XA_RESULT_SUCCESS)
       
   144                 {
       
   145                     mCtx->currentrouting = devId;
       
   146                     g_array_index(mCtx->connectedObjects,XAOMixAdaptConnObj,idx).currentSink = newsink;
       
   147                 }
       
   148                 newsink = gst_bin_get_by_name(GST_BIN(ctx->bin), (char*)temp.adaptId);
       
   149                 if(!newsink)
       
   150                 {   /*not existing yet, create*/
       
   151                     newsink = gst_element_factory_make((char*)temp.adaptId,(char*)temp.adaptId);
       
   152                     gst_bin_add(GST_BIN(ctx->bin), newsink);
       
   153                 }
       
   154                 if(!newsink)
       
   155                 {
       
   156                     DEBUG_ERR_A1("Could not create wanted sink \"%s\"!", (char*)temp.adaptId);
       
   157                     ret = XA_RESULT_PARAMETER_INVALID;
       
   158                 }
       
   159                 else
       
   160                 {
       
   161                     /* switch routing: pause, block, unlink old, link new, unblock pipe, play*/
       
   162                     GstPad *sinkpad=NULL, *blockpad=NULL;
       
   163                     sinkpad = gst_element_get_static_pad(current,"sink");
       
   164                     if(sinkpad)
       
   165                     {
       
   166                         blockpad = gst_pad_get_peer(sinkpad);
       
   167                     }
       
   168                     if(blockpad && gst_pad_is_active(blockpad))
       
   169                     {
       
   170                         DEBUG_INFO("block pad");
       
   171                         gst_pad_set_blocked_async(blockpad,TRUE,XAAdaptationGst_PadBlockCb,NULL);
       
   172                     }
       
   173                     gst_pad_unlink(blockpad, sinkpad);
       
   174                     sinkpad = gst_element_get_static_pad(newsink,"sink");
       
   175                     gst_pad_link(blockpad, sinkpad);
       
   176                     if(gst_pad_is_blocked(blockpad))
       
   177                     {
       
   178                         DEBUG_INFO("unblock pad");
       
   179                         gst_pad_set_blocked_async(blockpad,FALSE,XAAdaptationGst_PadBlockCb,NULL);
       
   180                     }
       
   181                     /*set sink to same state as the mp bin*/
       
   182                     gst_element_sync_state_with_parent(newsink);
       
   183                     mCtx->currentrouting = devId;
       
   184                     g_array_index(mCtx->connectedObjects,XAOMixAdaptConnObj,idx).currentSink = newsink;
       
   185                 }
       
   186             }
       
   187             else
       
   188             {
       
   189                 DEBUG_INFO("No routing switch needed");
       
   190             }
       
   191         }
       
   192         else
       
   193         {
       
   194             DEBUG_ERR_A1("Could not find audio device by id 0x%x", (int)devId);
       
   195             ret = XA_RESULT_PARAMETER_INVALID;
       
   196         }
       
   197     }
       
   198 
       
   199     DEBUG_API("<-XAOutputMixItfAdapt_ReRoute");
       
   200     return ret;
       
   201 }
       
   202 
       
   203