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