khronosfws/openmax_al/src/gst_adaptation/xaadaptationgst.c
changeset 16 43d09473c595
child 21 2ed61feeead6
child 31 8dfd592727cb
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 <assert.h>
       
    19 #include <string.h>
       
    20 #include "gst/gst.h"
       
    21 #include "gst/gstbuffer.h"
       
    22 #include "gst/app/gstappsrc.h"
       
    23 #include "xaobjectitf.h"
       
    24 #include "xacameradevice.h"
       
    25 #include "xaradiodevice.h"
       
    26 #include "xaoutputmix.h"
       
    27 #include "xamediaplayeradaptctx.h"
       
    28 #include "xacameraadaptctx.h"
       
    29 #include <stdlib.h>
       
    30 extern XAboolean cameraRealized;
       
    31 extern XACameraAdaptationCtx_* cameraCtx;
       
    32 /*
       
    33  * XAAdaptationGstCtx* XAAdaptationGst_Create()
       
    34  * 1st phase initialization function for Adaptation Base context structure.
       
    35  * Reserves memory for base context and initializes GStreamer FW.
       
    36  */
       
    37 XAresult XAAdaptationGst_Init( XAAdaptationGstCtx* pSelf, XAuint32 ctxId )
       
    38 {
       
    39     DEBUG_API("->XAAdaptationGst_Init");
       
    40 
       
    41     if ( pSelf )
       
    42     {
       
    43         if(XAAdaptationBase_Init(&(pSelf->baseObj), ctxId) != XA_RESULT_SUCCESS)
       
    44             {
       
    45             DEBUG_ERR("Failed to init base context!!!");
       
    46             free(pSelf);
       
    47             pSelf = NULL;
       
    48             }
       
    49         else
       
    50             {
       
    51             GError* gerror = 0;
       
    52     
       
    53     /*         Add default handler for Gst-bus messages */
       
    54             pSelf->busCb = XAAdaptationGst_GstBusCb;
       
    55     
       
    56             // VASU MOD BEGINS
       
    57             pSelf->cond_mutx_inited = XA_BOOLEAN_FALSE;
       
    58             // VASU MOD ENDS
       
    59     
       
    60             sem_init(&(pSelf->semAsyncWait),0,0);
       
    61     
       
    62     
       
    63             if ( !gst_init_check( NULL, NULL, &gerror ) )
       
    64                 {
       
    65                     DEBUG_ERR("Gst Initalization failure.");
       
    66                     return XA_RESULT_INTERNAL_ERROR;
       
    67                 }
       
    68         
       
    69             }
       
    70     }
       
    71     else
       
    72     {
       
    73         DEBUG_ERR("Invalid Gst Base Context.")
       
    74         return XA_RESULT_PARAMETER_INVALID;
       
    75     }
       
    76 
       
    77     DEBUG_API("<-XAAdaptationGst_Init");
       
    78     return XA_RESULT_SUCCESS;
       
    79 }
       
    80 
       
    81 /*
       
    82  * XAresult XAAdaptationGst_PostInit()
       
    83  * 2nd phase initialization for Adaptation Base.
       
    84  */
       
    85 XAresult XAAdaptationGst_PostInit( XAAdaptationGstCtx* ctx )
       
    86 {
       
    87     XAresult ret = XA_RESULT_SUCCESS;
       
    88     DEBUG_API("->XAAdaptationGst_PostInit");
       
    89     // VASU MOD BEGINS
       
    90     XAAdaptationBase_PostInit(&ctx->baseObj);
       
    91     
       
    92     ctx->thread_launched = XA_BOOLEAN_FALSE;
       
    93     pthread_mutex_init(&(ctx->ds_mutex), NULL);
       
    94     pthread_cond_init(&(ctx->ds_condition), NULL);
       
    95     ctx->cond_mutx_inited = XA_BOOLEAN_TRUE;
       
    96     
       
    97     
       
    98     // VASU MOD ENDS
       
    99     DEBUG_API("<-XAAdaptationGst_PostInit");
       
   100     return ret;
       
   101 }
       
   102 
       
   103 /*
       
   104  * void XAAdaptationGst_Free( XAAdaptationGstCtx* ctx )
       
   105  * Frees all Base context variables .
       
   106  */
       
   107 void XAAdaptationGst_Free( XAAdaptationGstCtx* ctx )
       
   108 {
       
   109 	GstElement* fakesink = NULL;
       
   110     DEBUG_API("->XAAdaptationGst_Free");
       
   111 
       
   112     if ( ctx->bin )
       
   113     {
       
   114     	fakesink = gst_bin_get_by_name(GST_BIN(ctx->bin), "fakesink");
       
   115 		if ( fakesink )
       
   116 		{
       
   117 			gst_element_set_state( GST_ELEMENT(fakesink), GST_STATE_NULL);
       
   118 			gst_object_unref(fakesink);
       
   119 		}
       
   120 
       
   121         if ( gst_element_set_state(GST_ELEMENT(ctx->bin), GST_STATE_NULL )!=GST_STATE_CHANGE_SUCCESS )
       
   122         {   /*not much we can do*/
       
   123             DEBUG_ERR("WARNING: Failed to change to NULL state before deletion!!")
       
   124         }
       
   125     }
       
   126 
       
   127     if(ctx->asynctimer)
       
   128     {   /*cancel timer*/
       
   129         g_source_remove(ctx->asynctimer);
       
   130     }
       
   131     sem_post(&(ctx->semAsyncWait));
       
   132     sem_destroy(&(ctx->semAsyncWait));
       
   133 
       
   134     XAAdaptationGst_StopGstListener(ctx);
       
   135 
       
   136     if ( ctx->bin )
       
   137     {
       
   138         gst_object_unref(ctx->bin);
       
   139     }
       
   140 
       
   141     //g_array_free(ctx->evtHdlrs, TRUE);
       
   142     // VASU MOD BEGINS
       
   143     if (ctx->cond_mutx_inited == XA_BOOLEAN_TRUE)
       
   144         {
       
   145         ctx->thread_launched = XA_BOOLEAN_FALSE;
       
   146         pthread_mutex_destroy(&(ctx->ds_mutex));
       
   147         pthread_cond_destroy(&(ctx->ds_condition));
       
   148         ctx->cond_mutx_inited = XA_BOOLEAN_FALSE;
       
   149         }
       
   150     // VASU MOD ENDS
       
   151     XAAdaptationBase_Free(&ctx->baseObj);
       
   152     
       
   153     DEBUG_API("<-XAAdaptationGst_Free");
       
   154 }
       
   155 
       
   156 
       
   157 /*
       
   158  * gboolean XAAdaptationBase_GstBusCb( GstBus *bus, GstMessage *message, gpointer data )
       
   159  * Default Gst-bus message handler (Callback)
       
   160  */
       
   161 gboolean XAAdaptationGst_GstBusCb( GstBus *bus, GstMessage *message, gpointer data )
       
   162 {
       
   163     GError *error;
       
   164     gchar *debug;
       
   165     DEBUG_API("->XAAdaptationGst_GstBusCb");
       
   166     DEBUG_INFO_A2("Received Gst callback \"%s\" from \"%s\"",
       
   167                     GST_MESSAGE_TYPE_NAME(message),
       
   168                     GST_OBJECT_NAME(GST_MESSAGE_SRC(message)));
       
   169 
       
   170     switch( GST_MESSAGE_TYPE(message))
       
   171     {
       
   172         case GST_MESSAGE_ERROR:
       
   173             gst_message_parse_error( message, &error, &debug );
       
   174             DEBUG_INFO_A1("%s", debug);
       
   175             break;
       
   176         case GST_MESSAGE_EOS:
       
   177             break;
       
   178         case GST_MESSAGE_UNKNOWN:
       
   179             break;
       
   180         case GST_MESSAGE_WARNING:
       
   181             break;
       
   182         case GST_MESSAGE_INFO:
       
   183             break;
       
   184         case GST_MESSAGE_TAG:
       
   185             break;
       
   186         case GST_MESSAGE_BUFFERING:
       
   187             break;
       
   188         case GST_MESSAGE_STATE_CHANGED:
       
   189             break;
       
   190         case GST_MESSAGE_STATE_DIRTY:
       
   191             break;
       
   192         case GST_MESSAGE_STEP_DONE:
       
   193             break;
       
   194         case GST_MESSAGE_CLOCK_PROVIDE:
       
   195             break;
       
   196         case GST_MESSAGE_CLOCK_LOST:
       
   197             break;
       
   198         case GST_MESSAGE_NEW_CLOCK:
       
   199             break;
       
   200         case GST_MESSAGE_STRUCTURE_CHANGE:
       
   201             break;
       
   202         case GST_MESSAGE_STREAM_STATUS:
       
   203             break;
       
   204         case GST_MESSAGE_APPLICATION:
       
   205             break;
       
   206         case GST_MESSAGE_ELEMENT:
       
   207             break;
       
   208         case GST_MESSAGE_SEGMENT_START:
       
   209             break;
       
   210         case GST_MESSAGE_SEGMENT_DONE:
       
   211             break;
       
   212         case GST_MESSAGE_DURATION:
       
   213             break;
       
   214         case GST_MESSAGE_LATENCY:
       
   215             break;
       
   216         case GST_MESSAGE_ASYNC_START:
       
   217             break;
       
   218         case GST_MESSAGE_ASYNC_DONE:
       
   219             break;
       
   220         case GST_MESSAGE_ANY:
       
   221             break;
       
   222         default:
       
   223             DEBUG_INFO("Unhandled Gst-Bus message");
       
   224             break;
       
   225     }
       
   226     DEBUG_API("<-XAAdaptationGst_GstBusCb");
       
   227     return TRUE;
       
   228 }
       
   229 
       
   230 XAresult XAAdaptationGst_InitGstListener(XAAdaptationGstCtx* ctx)
       
   231 {
       
   232     int ret;
       
   233     DEBUG_API("->XAAdaptationGst_InitGstListener");
       
   234     if ( ctx->bin )
       
   235     {
       
   236         ctx->bus = gst_pipeline_get_bus( GST_PIPELINE( ctx->bin ));
       
   237     }
       
   238     if( !ctx->bus )
       
   239     {
       
   240         DEBUG_ERR("could not get gst bus!")
       
   241         return XA_RESULT_INTERNAL_ERROR;
       
   242     }
       
   243     ret = pthread_create(&(ctx->busloopThr), NULL, (XAAdaptationGst_LaunchGstListener),(void*)ctx);
       
   244     // VASU MOD BEGINS
       
   245     if ( ctx->thread_launched == XA_BOOLEAN_FALSE )
       
   246     {
       
   247         // Wait until the thread is created
       
   248         pthread_mutex_lock(&(ctx->ds_mutex));
       
   249         pthread_cond_wait(&(ctx->ds_condition), &(ctx->ds_mutex));
       
   250         pthread_mutex_unlock(&(ctx->ds_mutex));
       
   251         // VASU MOD ENDS
       
   252     }
       
   253     if(ret)
       
   254     {
       
   255         DEBUG_ERR_A1("could not create thread!! (%d)",ret)
       
   256         return XA_RESULT_INTERNAL_ERROR;
       
   257     }
       
   258     DEBUG_API("<-XAAdaptationGst_InitGstListener");
       
   259     return XA_RESULT_SUCCESS;
       
   260 }
       
   261 
       
   262 void * XAAdaptationGst_LaunchGstListener(void* args)
       
   263 {
       
   264     XAAdaptationGstCtx* ctx = (XAAdaptationGstCtx*)args;
       
   265     DEBUG_API("->XAAdaptationGst_LaunchGstListener");
       
   266     // VASU MOD BEGINS
       
   267     // Signal calling thread that this thread creation is completed
       
   268     ctx->thread_launched = XA_BOOLEAN_TRUE;
       
   269     pthread_mutex_lock(&(ctx->ds_mutex));
       
   270     pthread_cond_signal(&(ctx->ds_condition));
       
   271     pthread_mutex_unlock(&(ctx->ds_mutex));
       
   272     // VASU MOD ENDS
       
   273 
       
   274     ctx->busloop = g_main_loop_new( NULL, FALSE );
       
   275     if ( !ctx->busloop )
       
   276     {
       
   277         DEBUG_ERR("Glib main loop failure.")
       
   278         DEBUG_API("<-XAAdaptationGst_LaunchGstListener");
       
   279         assert(0);
       
   280     }
       
   281     else
       
   282     {
       
   283         DEBUG_INFO("Start Glib main loop")
       
   284         g_main_loop_run(ctx->busloop);
       
   285         DEBUG_INFO("Glib main loop stopped - exiting thread")
       
   286         DEBUG_API("<-XAAdaptationGst_LaunchGstListener");
       
   287         pthread_exit(NULL);
       
   288     }
       
   289    return NULL;
       
   290 }
       
   291 
       
   292 void XAAdaptationGst_StopGstListener(XAAdaptationGstCtx* ctx)
       
   293 {
       
   294     DEBUG_API("->XAAdaptationGst_StopGstListener");
       
   295     if(ctx->busloop)
       
   296     {
       
   297         g_main_loop_quit (ctx->busloop);
       
   298         g_main_loop_unref(ctx->busloop);
       
   299     }
       
   300     if(ctx->bus)
       
   301     {
       
   302         gst_object_unref(ctx->bus);
       
   303         ctx->bus = NULL;
       
   304     }
       
   305     DEBUG_API("<-XAAdaptationGst_StopGstListener");
       
   306 }
       
   307 
       
   308 /*
       
   309  * ASynchronous operation managing
       
   310  **/
       
   311 
       
   312 /* NOTE: This should NOT be called from gst callbacks - danger of deadlock!!
       
   313  */
       
   314 void XAAdaptationGst_PrepareAsyncWait(XAAdaptationGstCtx* ctx)
       
   315 {
       
   316     DEBUG_API("->XAAdaptationGst_PrepareAsyncWait");
       
   317 
       
   318     if( ctx->waitingasyncop )
       
   319     {   /*wait previous async op*/
       
   320         DEBUG_INFO("::WARNING:: previous asynch still ongoing!!!");
       
   321         DEBUG_INFO(">>>>  WAIT PREVIOUS");
       
   322         sem_wait(&(ctx->semAsyncWait));
       
   323         DEBUG_INFO("<<<<  PREVIOUS COMPLETED");
       
   324     }
       
   325     sem_init(&(ctx->semAsyncWait),0,0);
       
   326 
       
   327     ctx->waitingasyncop = XA_BOOLEAN_TRUE;
       
   328     DEBUG_API("<-XAAdaptationGst_PrepareAsyncWait");
       
   329 }
       
   330 
       
   331 void XAAdaptationGst_StartAsyncWait(XAAdaptationGstCtx* ctx)
       
   332 {
       
   333     DEBUG_API("->XAAdaptationGst_StartAsyncWait");
       
   334 
       
   335     /* timeout to try to avoid gst freeze in rollup */
       
   336     ctx->asynctimer = g_timeout_add(XA_ADAPT_ASYNC_TIMEOUT,
       
   337                                     XAAdaptationGst_CancelAsyncWait, ctx);
       
   338     /* check flag once again if callback already happened before wait */
       
   339     if(ctx->waitingasyncop)
       
   340     {
       
   341         DEBUG_INFO(">>>>  ASYNC STARTS");
       
   342         sem_wait(&(ctx->semAsyncWait));
       
   343         DEBUG_INFO("<<<<  ASYNC COMPLETED");
       
   344     }
       
   345     else
       
   346     {
       
   347         DEBUG_INFO("<> async completed already");
       
   348     }
       
   349     /*cancel timer*/
       
   350     if(ctx->asynctimer)
       
   351     {
       
   352         g_source_remove(ctx->asynctimer);
       
   353     }
       
   354     ctx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   355 
       
   356     DEBUG_API("<-XAAdaptationGst_StartAsyncWait");
       
   357 }
       
   358 
       
   359 /* async operation timeout callback*/
       
   360 gboolean XAAdaptationGst_CancelAsyncWait(gpointer ctx)
       
   361 {
       
   362     XAAdaptationGstCtx* bCtx = (XAAdaptationGstCtx*)ctx;
       
   363     DEBUG_API("->XAAdaptationGst_CancelAsyncWait");
       
   364     if( bCtx->waitingasyncop )
       
   365     {
       
   366         DEBUG_ERR_A3("ASYNC TIMED OUT : current %d, gsttarget %d, wanted %d",
       
   367                       GST_STATE(bCtx->bin), GST_STATE_TARGET(bCtx->bin), bCtx->binWantedState);
       
   368         bCtx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   369         sem_post(&(bCtx->semAsyncWait));
       
   370     }
       
   371     DEBUG_API("<-XAAdaptationGst_CancelAsyncWait");
       
   372     /* return false to remove timer */
       
   373     return FALSE;
       
   374 }
       
   375 
       
   376 void XAAdaptationGst_CompleteAsyncWait(XAAdaptationGstCtx* ctx)
       
   377 {
       
   378     DEBUG_API("->XAAdaptationGst_CompleteAsyncWait");
       
   379     if( ctx->waitingasyncop )
       
   380     {
       
   381         int i;
       
   382         ctx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   383         sem_getvalue(&(ctx->semAsyncWait),&i);
       
   384         DEBUG_INFO_A1("Asynch operation succeeded, sem value %d",i);
       
   385         if(i<=0)
       
   386         {   /* only post if locked */
       
   387             sem_post(&(ctx->semAsyncWait));
       
   388         }
       
   389         else if(i>0)
       
   390         {   /* should not be, reset semaphore */
       
   391             sem_init(&(ctx->semAsyncWait),0,0);
       
   392         }
       
   393     }
       
   394     DEBUG_API("<-XAAdaptationGst_CompleteAsyncWait");
       
   395 }
       
   396 
       
   397 /**
       
   398  * GstElement* XAAdaptationGst_CreateGstSource( XADataSource* xaSrc, const XAchar *name )
       
   399  * @param XADataSource* xaSnk - XADataSource defining gst source to create
       
   400  * @param const XAchar *name - string for naming the gst element
       
   401  * @param XAboolean *isobj - (out param) is source another XA object?
       
   402  * @return GstElement* - return newly created gst source element
       
   403  * Description: Create gst source element corresponding to XA source structure
       
   404  */
       
   405 GstElement* XAAdaptationGst_CreateGstSource( XADataSource* xaSrc, const char *name, XAboolean *isobj, XAboolean *isPCM, XAboolean *isRawImage  )
       
   406 {
       
   407     XAuint32 locType = 0;
       
   408     GstElement* gstSrc = NULL;
       
   409     char* fname=NULL;
       
   410     XADataLocator_URI* uri = NULL;
       
   411     XADataLocator_IODevice* ioDevice = NULL;
       
   412     XACameraDeviceImpl* cameraDevice = NULL;
       
   413     XARadioDeviceImpl* radioDevice = NULL;
       
   414     XAObjectItfImpl* pObj = NULL;
       
   415 
       
   416     DEBUG_API("->XAAdaptationGst_CreateGstSource");
       
   417     if( !xaSrc || !xaSrc->pLocator || !isobj )
       
   418     {
       
   419         return NULL;
       
   420     }
       
   421     *isobj = XA_BOOLEAN_FALSE;
       
   422     if( xaSrc && xaSrc->pFormat && *((XAuint32*)(xaSrc->pFormat))==XA_DATAFORMAT_PCM && isPCM )
       
   423     {
       
   424         *isPCM = XA_BOOLEAN_TRUE;
       
   425     }
       
   426     if( xaSrc && xaSrc->pFormat && *((XAuint32*)(xaSrc->pFormat))==XA_DATAFORMAT_RAWIMAGE && isRawImage )
       
   427     {
       
   428         *isRawImage = XA_BOOLEAN_TRUE;
       
   429     }
       
   430     locType = *((XAuint32*)(xaSrc->pLocator));
       
   431     switch ( locType )
       
   432     {
       
   433         case XA_DATALOCATOR_URI:
       
   434             DEBUG_INFO("XA_DATALOCATOR_URI");
       
   435             uri = (XADataLocator_URI*)xaSrc->pLocator;
       
   436             gstSrc = gst_element_factory_make("filesrc",name);
       
   437             if ( uri->URI != NULL )
       
   438             {
       
   439                 DEBUG_INFO_A1("URI: %s", uri->URI);
       
   440                 if(strncmp((char *)uri->URI, "file:///", 8) == 0)
       
   441                     {
       
   442                     fname = (char *)&((uri->URI)[8]);
       
   443                     }
       
   444                 else
       
   445                     {
       
   446                     fname = (char *)uri->URI;
       
   447                     }
       
   448                 DEBUG_INFO_A1("->filesystem path %s", fname);
       
   449                 g_object_set( G_OBJECT(gstSrc), "location", fname, NULL );
       
   450                 /*check for pcm - decodebin does not know how to handle raw PCM files */
       
   451                 if( isPCM && strstr(fname, ".pcm") )
       
   452                 {
       
   453                     DEBUG_INFO("PCM file detected");
       
   454                     *isPCM=XA_BOOLEAN_TRUE;
       
   455                 }
       
   456             }
       
   457             else
       
   458             {
       
   459                 DEBUG_ERR("No uri specified.");
       
   460                 return NULL;
       
   461             }
       
   462             break; /* XA_DATALOCATOR_URI */
       
   463 
       
   464 
       
   465         case XA_DATALOCATOR_IODEVICE:
       
   466             DEBUG_INFO("XA_DATALOCATOR_IODEVICE");
       
   467             ioDevice = (XADataLocator_IODevice*)(xaSrc->pLocator);
       
   468             switch ( ioDevice->deviceType )
       
   469             {
       
   470                 case XA_IODEVICE_AUDIOINPUT:
       
   471                 {
       
   472                     DEBUG_INFO("XA_IODEVICE_AUDIOINPUT");
       
   473                     DEBUG_INFO_A1("ioDevice->deviceID: %x", ioDevice->deviceID);
       
   474                     switch (ioDevice->deviceID )
       
   475                     {
       
   476                     //case XA_ADAPTID_ALSASRC: //Krishna
       
   477                     case XA_ADAPTID_DEVSOUNDSRC:
       
   478                         //DEBUG_INFO("alsasrc"); //Krishna
       
   479                         DEBUG_INFO("devsoundsrc");
       
   480                         gstSrc = gst_element_factory_make("devsoundsrc",name); //Krishna - changed to devsoundsrc
       
   481                         g_object_set (G_OBJECT (gstSrc), "num-buffers", 80, NULL);
       
   482                         break;
       
   483                     case XA_ADAPTID_AUDIOTESTSRC:
       
   484                         /*fall through*/
       
   485                     default:
       
   486                         DEBUG_INFO("audiotestsrc");
       
   487                         gstSrc = gst_element_factory_make("audiotestsrc",name);
       
   488                         break;
       
   489                     }
       
   490                     break;
       
   491                 }
       
   492                 case XA_IODEVICE_CAMERA:
       
   493                 {
       
   494                     DEBUG_INFO("XA_IODEVICE_CAMERA");
       
   495                     if ( ioDevice->device )
       
   496                     {   /*source is camera object*/
       
   497                         DEBUG_INFO("Use camerabin as source.");
       
   498                         /* Get camerabin from source object */
       
   499                         pObj = (XAObjectItfImpl*)(*ioDevice->device);
       
   500                         cameraDevice = (XACameraDeviceImpl*)(pObj);
       
   501                         /*TODO we had to remove this line below since adaptationCtx
       
   502                          * was  not a member of structure*/
       
   503 
       
   504                         gstSrc = GST_ELEMENT(((XAAdaptationGstCtx*)(cameraDevice->adaptationCtx))->bin);
       
   505                         /* refcount increase is needed to keep this not being deleted after use */
       
   506                         gst_object_ref(GST_OBJECT(gstSrc));
       
   507                         *isobj = XA_BOOLEAN_TRUE;
       
   508                     }
       
   509                     else
       
   510                     {
       
   511                         DEBUG_INFO_A1("ioDevice->deviceID: %x", ioDevice->deviceID);
       
   512                         switch (ioDevice->deviceID )
       
   513                         {
       
   514                         case XA_ADAPTID_V4L2SRC:
       
   515                             DEBUG_INFO("Camera deviceID: v4l2src ");
       
   516  
       
   517                             break;
       
   518                         case XA_ADAPTID_VIDEOTESTSRC:
       
   519                             DEBUG_INFO("Camera deviceID: videotestsrc");
       
   520  
       
   521                             break;
       
   522                         default:
       
   523                         case XA_DEFAULTDEVICEID_CAMERA:
       
   524                             DEBUG_INFO("Camera deviceID:Default");
       
   525                            
       
   526                             break;
       
   527                         }
       
   528                         if ( cameraCtx )
       
   529 						{
       
   530 							gstSrc = GST_ELEMENT(cameraCtx->baseObj.bin);
       
   531 							gst_object_ref(GST_OBJECT(gstSrc));
       
   532 							*isobj = XA_BOOLEAN_TRUE;
       
   533 						}
       
   534 						else
       
   535 						{
       
   536 							DEBUG_ERR("No camera object created!");
       
   537 							return NULL;
       
   538 						}
       
   539                     }
       
   540                     break;
       
   541                 }
       
   542                 case XA_IODEVICE_RADIO:
       
   543                     DEBUG_INFO("XA_IODEVICE_RADIO");
       
   544                     if ( ioDevice->device )
       
   545                     {
       
   546                         DEBUG_INFO("Use radio pipeline as source.");
       
   547                         /* Get radio_pipeline and set it to base context */
       
   548                         radioDevice = (XARadioDeviceImpl*)(*ioDevice->device);
       
   549                         /* radio does not have actual bin, only source element*/
       
   550                         gstSrc = GST_ELEMENT(((XAAdaptationGstCtx*)radioDevice->adaptationCtx)->bin);
       
   551                         /* refcount increase is needed to keep this not being deleted after use */
       
   552                         gst_object_ref(GST_OBJECT(gstSrc));
       
   553                         /**isobj = XA_BOOLEAN_TRUE;*/
       
   554                     }
       
   555                     break;
       
   556                 default:
       
   557                 {
       
   558                     DEBUG_ERR("Unsupported IODevice.");
       
   559                     break;
       
   560                 }
       
   561             }
       
   562             break; /* XA_DATALOCATOR_IODEVICE */
       
   563 
       
   564 /*        case XA_DATALOCATOR_CONTENTPIPE:
       
   565         {
       
   566         	DEBUG_INFO("XA_DATALOCATOR_CONTENTPIPE");
       
   567         	gstSrc = gst_element_factory_make("appsrc",name);
       
   568             break;
       
   569         }*/
       
   570         case XA_DATALOCATOR_ADDRESS:
       
   571             {
       
   572                 XADataLocator_Address* address = (XADataLocator_Address*)(xaSrc->pLocator);
       
   573                 gstSrc = gst_element_factory_make("appsrc", name);
       
   574                 /* init gst buffer from datalocator */
       
   575                 if( gstSrc )
       
   576                 {
       
   577                     /* init GST buffer from XADataLocator*/
       
   578                     GstBuffer* userBuf = gst_buffer_new();
       
   579                     if( userBuf )
       
   580                     {
       
   581                         userBuf->size = address->length;
       
   582                         userBuf->data = address->pAddress;
       
   583                         /* push the whole buffer to appsrc so it is ready for preroll */
       
   584                         DEBUG_INFO("Pushing buffer");
       
   585                         gst_app_src_push_buffer( GST_APP_SRC(gstSrc), userBuf );
       
   586                         DEBUG_INFO_A1("Sent buffer at 0x%x to appsrc", userBuf );
       
   587                         gst_app_src_end_of_stream( GST_APP_SRC(gstSrc) );
       
   588                     }
       
   589                     else
       
   590                     {
       
   591                         DEBUG_ERR("Failure allocating buffer!");
       
   592                     }
       
   593                 }
       
   594                 else
       
   595                 {
       
   596                     DEBUG_ERR("Failure creating appsrc!");
       
   597                 }
       
   598             }
       
   599             break;
       
   600 
       
   601         default:
       
   602             DEBUG_ERR("Incorrect data locator for source.")
       
   603             break;
       
   604     }
       
   605 
       
   606     if ( gstSrc )
       
   607     {
       
   608         DEBUG_INFO_A1("Created gstreamer source element at %x", gstSrc);
       
   609     }
       
   610 
       
   611     DEBUG_API("<-XAAdaptationGst_CreateGstSource");
       
   612     return gstSrc;
       
   613 }
       
   614 
       
   615 
       
   616 /**
       
   617  * GstElement* XAAdaptationGst_CreateGstSink( XADataSink* xaSnk, const XAchar *name )
       
   618  * @param XADataSink* xaSnk - XADataSink defining gst sink to create
       
   619  * @param const XAchar *name - string for naming the gst element
       
   620  * @return GstElement* - return newly created gst sink element
       
   621  * Description: Create gst sink element corresponding to XA sink structure
       
   622  */
       
   623 GstElement* XAAdaptationGst_CreateGstSink( XADataSink* xaSnk, const char *name, XAboolean *isobj )
       
   624 {
       
   625     XAuint32 locType = 0;
       
   626     GstElement* gstSnk = NULL;
       
   627     XADataLocator_URI* uri = NULL;
       
   628     DEBUG_API("->XAAdaptationGst_CreateGstSink");
       
   629     if(!xaSnk || !xaSnk->pLocator)
       
   630     {
       
   631         DEBUG_INFO("Warning! No sink specified, use fakesink");
       
   632         gstSnk = gst_element_factory_make("fakesink",name);
       
   633         if(!gstSnk)
       
   634         {
       
   635             DEBUG_ERR("Cannot create sink!");
       
   636             return NULL;
       
   637         }
       
   638         g_object_set( G_OBJECT(gstSnk),"async", FALSE, NULL);
       
   639     }
       
   640     else
       
   641     {
       
   642         locType = *((XAuint32*)(xaSnk->pLocator));
       
   643         switch ( locType )
       
   644         {
       
   645             case XA_DATALOCATOR_URI:
       
   646                 DEBUG_INFO("XA_DATALOCATOR_URI");
       
   647                 uri = (XADataLocator_URI*)xaSnk->pLocator;
       
   648                 gstSnk = gst_element_factory_make("filesink",name);
       
   649                 if(!gstSnk)
       
   650                 {
       
   651                     DEBUG_ERR("Cannot create sink!");
       
   652                     return NULL;
       
   653                 }
       
   654                 if ( uri->URI != NULL )
       
   655                 {
       
   656                     XAchar *fname;
       
   657                     DEBUG_INFO_A1("URI: %s", uri->URI);
       
   658                     if(strncmp((char *)uri->URI, "file:///", 8) == 0)
       
   659                     {
       
   660                         fname = &((uri->URI)[8]);
       
   661                     }
       
   662                     else
       
   663                     {
       
   664                         fname = uri->URI;
       
   665                     }
       
   666                     DEBUG_INFO_A1("->filesystem path %s", fname);
       
   667                     g_object_set( G_OBJECT(gstSnk),"location", fname,
       
   668                                                    "async", FALSE,
       
   669                                                    "qos", FALSE,
       
   670                                                    "max-lateness", (gint64)(-1),
       
   671                                                    NULL);
       
   672                 }
       
   673                 else
       
   674                 {
       
   675                     DEBUG_ERR("No recording output uri specified.");
       
   676                     return NULL;
       
   677                 }
       
   678                 break;
       
   679             case XA_DATALOCATOR_NATIVEDISPLAY:
       
   680                 DEBUG_INFO("Sink locator type - XA_DATALOCATOR_NATIVEDISPLAY");
       
   681 #ifdef USE_NGA_SURFACES
       
   682                 gstSnk = gst_element_factory_make("devvideosink","devvideosink");
       
   683 #else
       
   684                 gstSnk = gst_element_factory_make("ximagesink",name);
       
   685 #endif /*USE_NGA_SURFACES*/
       
   686                 if(!gstSnk)
       
   687                 {
       
   688                     DEBUG_ERR("Cannot create sink!");
       
   689                     return NULL;
       
   690                 }
       
   691                 g_object_set( G_OBJECT(gstSnk), "force-aspect-ratio", TRUE,
       
   692 												"async", FALSE,
       
   693                                                "qos", FALSE,
       
   694 												"handle-events", TRUE,
       
   695 												"handle-expose", TRUE,
       
   696                                                "max-lateness", (gint64)(-1),
       
   697                                                NULL);
       
   698                 break;
       
   699             case XA_DATALOCATOR_OUTPUTMIX:
       
   700                 DEBUG_INFO("Sink locator type - XA_DATALOCATOR_OUTPUTMIX");
       
   701                 {
       
   702                     /* Get OutputMix adaptation from data locator */
       
   703                     XADataLocator_OutputMix* omix = (XADataLocator_OutputMix*)(xaSnk->pLocator);
       
   704                     if ( omix->outputMix )
       
   705                     {
       
   706                         XAOMixImpl* omixDevice = (XAOMixImpl*)(*omix->outputMix);
       
   707 
       
   708                         if(omixDevice)
       
   709                         {
       
   710                             /*TODO we had to remove this line below since adaptationCtx
       
   711                              * was  not a member of structure*/
       
   712                         
       
   713                             /*gstSnk = XAOutputMixAdapt_GetSink(omixDevice->adaptationCtx);*/
       
   714                             if(!gstSnk)
       
   715                             {
       
   716                                 DEBUG_ERR("Cannot create sink!");
       
   717                                 return NULL;
       
   718                             }
       
   719                             *isobj = XA_BOOLEAN_TRUE;
       
   720                         }
       
   721                         else
       
   722                         {
       
   723                             DEBUG_ERR("Warning - NULL outputmix object - default audio output used");
       
   724                             gstSnk = gst_element_factory_make("alsasink",name);
       
   725                         }
       
   726                     }
       
   727                     else
       
   728                     {
       
   729                         DEBUG_ERR("Warning - NULL outputmix object - default audio output used");
       
   730                         gstSnk = gst_element_factory_make("alsasink",name);
       
   731                     }
       
   732 
       
   733                 }
       
   734                 break;
       
   735 /*		 	case XA_DATALOCATOR_CONTENTPIPE:
       
   736 				DEBUG_INFO("XA_DATALOCATOR_CONTENTPIPE");
       
   737 				gstSnk = gst_element_factory_make("appsink",name);
       
   738 				break;*/
       
   739             case XA_DATALOCATOR_ADDRESS:
       
   740                 {
       
   741                     gstSnk = gst_element_factory_make("appsink", name);
       
   742                     /* Not actually object sink, but attribute used to notify recorder
       
   743                      * about appsink (no object sinks applicable in this use case)
       
   744                      **/
       
   745                     *isobj=TRUE;
       
   746                 }
       
   747                 break;
       
   748             case XA_DATALOCATOR_IODEVICE:
       
   749                 /* when only valid IOdevice sinks vibra and LED sinks implemented
       
   750                  * at adaptation level, add handling here (in this implementation,
       
   751                  * no handling needed as only dummy implementations for those)
       
   752                  **/
       
   753             default:
       
   754                 DEBUG_ERR("Incorrect data locator for sink.")
       
   755                 break;
       
   756         }
       
   757     }
       
   758     if (gstSnk )
       
   759     {
       
   760         DEBUG_INFO_A1("Created gstreamer sink element at %x", gstSnk);
       
   761     }
       
   762     DEBUG_API("<-XAAdaptationGst_CreateGstSink");
       
   763     return gstSnk;
       
   764 }
       
   765 
       
   766 /**
       
   767  * GstElement* XAAdaptationGst_CreateVideoPP( )
       
   768  * @return GstElement* - return newly created gst pipeline element
       
   769  * Description: Create video processing pipeline
       
   770  */
       
   771 GstElement* XAAdaptationGst_CreateVideoPP( )
       
   772 {
       
   773     GstElement *vpp;
       
   774     DEBUG_API("->XAAdaptationGst_CreateVideoPP");
       
   775     vpp = gst_pipeline_new("videopp");
       
   776     if( vpp )
       
   777     {
       
   778         GstPad *ghostsink, *ghostsrc;
       
   779         GstElement 	*col1,
       
   780 					*col2,
       
   781 					*rotate,
       
   782 					*mirror,
       
   783 					*box,
       
   784 					*crop,
       
   785 					*gamma,
       
   786 					*balance,
       
   787 					*scale,
       
   788 					*scale2,
       
   789 #ifdef USE_NGA_SURFACES
       
   790 					*identity,
       
   791 #endif /*USE_NGA_SURFACES*/
       
   792 					*queue;
       
   793 
       
   794 
       
   795         /* Crete ffmpegcolorspace to convert stream to correct format */
       
   796         col1 = gst_element_factory_make( "ffmpegcolorspace", "pp_colsp1");
       
   797         if(col1)
       
   798         {
       
   799             DEBUG_INFO("Created ffmpegcolorspace element");
       
   800             gst_bin_add(GST_BIN(vpp), col1);
       
   801            /* make this bin link point*/
       
   802             ghostsink = gst_element_get_static_pad(col1,"sink");
       
   803             if(ghostsink)
       
   804             {
       
   805                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_sink",ghostsink));
       
   806                 gst_object_unref(GST_OBJECT(ghostsink));
       
   807             }
       
   808         }
       
   809 
       
   810         /* create video crop, this will be sink for videoPP pipeline */
       
   811         crop = gst_element_factory_make( "videocrop", "pp_crop");
       
   812         if(crop)
       
   813         {
       
   814             DEBUG_INFO("Created crop element");
       
   815             gst_bin_add(GST_BIN(vpp), crop);
       
   816         }
       
   817 
       
   818         /* create video rotate */
       
   819         rotate = gst_element_factory_make( "videoflip", "pp_rotate");
       
   820         if(rotate)
       
   821         {
       
   822             DEBUG_INFO("Created rotate element");
       
   823             g_object_set(G_OBJECT(rotate), "method", FLIP_NONE, NULL);
       
   824             gst_bin_add(GST_BIN(vpp), rotate);
       
   825         }
       
   826 
       
   827         /* create video mirror */
       
   828         mirror = gst_element_factory_make( "videoflip", "pp_mirror");
       
   829         if(mirror)
       
   830         {
       
   831             DEBUG_INFO("Created mirror element");
       
   832             g_object_set(G_OBJECT(mirror), "method", FLIP_NONE, NULL);
       
   833             gst_bin_add(GST_BIN(vpp), mirror);
       
   834         }
       
   835 
       
   836         /* create video box */
       
   837         box = gst_element_factory_make( "videobox", "pp_box");
       
   838         if(box)
       
   839         {
       
   840             DEBUG_INFO("Created videobox element");
       
   841             gst_bin_add(GST_BIN(vpp), box);
       
   842         }
       
   843 
       
   844         /* create video balance */
       
   845         balance = gst_element_factory_make( "videobalance", "pp_balance");
       
   846         if(balance)
       
   847         {
       
   848             DEBUG_INFO("Created balance element");
       
   849             gst_bin_add(GST_BIN(vpp), balance);
       
   850         }
       
   851 
       
   852         /* create video gamma */
       
   853         gamma = gst_element_factory_make( "gamma", "pp_gamma");
       
   854         if(gamma)
       
   855         {
       
   856             DEBUG_INFO("Created gamma element");
       
   857             gst_bin_add(GST_BIN(vpp), gamma);
       
   858         }
       
   859 
       
   860         /* Create videoscale element to scale postprocessed output to correct size */
       
   861         scale = gst_element_factory_make("videoscale", "pp_scale");
       
   862         if ( scale )
       
   863         {
       
   864             DEBUG_INFO("Created videoscale element");
       
   865             gst_bin_add(GST_BIN(vpp), scale);
       
   866         }
       
   867         scale2 = gst_element_factory_make("videoscale", "pp_scale2");
       
   868 		if ( scale2 )
       
   869 		{
       
   870 			GstPad *pad = NULL;
       
   871 			GstCaps *caps = NULL;
       
   872 			DEBUG_INFO("Created videoscale element");
       
   873 			pad = gst_element_get_static_pad(scale2,"src");
       
   874 			caps = gst_caps_new_simple("video/x-raw-yuv",
       
   875 					 "width", G_TYPE_INT,0,
       
   876 					 "height", G_TYPE_INT,0,
       
   877 					 NULL);
       
   878 			gst_pad_set_caps(pad, caps);
       
   879 			gst_bin_add(GST_BIN(vpp), scale2);
       
   880 		}
       
   881 
       
   882         /* create video queue */
       
   883         queue = gst_element_factory_make( "queue", "vpp_queue");
       
   884         if(queue)
       
   885         {
       
   886             DEBUG_INFO("Created queue element");
       
   887             gst_bin_add(GST_BIN(vpp), queue);
       
   888 #ifdef USE_NGA_SURFACES
       
   889             /* make this bin link point*/
       
   890             ghostsink = gst_element_get_static_pad(queue,"sink");
       
   891             if(ghostsink)
       
   892             {
       
   893                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_src",ghostsink));
       
   894                 gst_object_unref(GST_OBJECT(ghostsink));
       
   895             }            
       
   896 #endif /*USE_NGA_SURFACES*/
       
   897         }
       
   898 
       
   899 
       
   900         /* Crete ffmpegcolorspace to convert stream to correct format */
       
   901         col2 = gst_element_factory_make( "ffmpegcolorspace", "pp_colsp2");
       
   902         if(col2)
       
   903         {
       
   904             DEBUG_INFO("Created ffmpegcolorspace element");
       
   905             gst_bin_add(GST_BIN(vpp), col2);
       
   906             /* make this bin link point*/
       
   907             ghostsrc = gst_element_get_static_pad(col2,"src");
       
   908             if(ghostsrc)
       
   909             {
       
   910                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_src",ghostsrc));
       
   911                 gst_object_unref(GST_OBJECT(ghostsrc));
       
   912             }
       
   913         }
       
   914 
       
   915 #ifdef USE_NGA_SURFACES
       
   916         //shyward
       
   917         /* create identity element */
       
   918         identity  = gst_element_factory_make( "identity", "identity" );
       
   919         if(identity)
       
   920         {
       
   921            DEBUG_INFO("Created identity element");
       
   922            gst_bin_add(GST_BIN(vpp), identity);   
       
   923            /* make this bin link point*/
       
   924            ghostsrc = gst_element_get_static_pad(identity,"src");
       
   925            if(ghostsrc)
       
   926            {
       
   927                gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_sink",ghostsrc));
       
   928                gst_object_unref(GST_OBJECT(ghostsrc));
       
   929            }                
       
   930         }        
       
   931         if( !(gst_element_link_many(queue,identity,NULL)) )
       
   932 #else
       
   933         //shyward - thins code assumes all the elements will have been created, which is not true
       
   934         if( !(gst_element_link_many(col1,
       
   935 									scale,
       
   936 									crop,
       
   937 									rotate,
       
   938 									mirror,
       
   939 									box,
       
   940 									balance,
       
   941 									gamma,
       
   942 									queue,
       
   943 									scale2,
       
   944 #ifdef USE_NGA_SURFACES
       
   945                 					identity,
       
   946 #endif /*USE_NGA_SURFACES*/
       
   947 									col2,
       
   948 									NULL)
       
   949 									) )
       
   950 #endif /*USE_NGA_SURFACES*/
       
   951         {
       
   952             DEBUG_ERR("Could not link videopp elements!!");
       
   953             gst_object_unref(vpp);
       
   954             vpp = NULL;
       
   955         }
       
   956     }
       
   957     DEBUG_API("<-XAAdaptationGst_CreateVideoPP");
       
   958     return vpp;
       
   959 }
       
   960 
       
   961 /**
       
   962  * GstElement* XAAdaptationGst_CreateFixedSizeRecordVideoPP( )
       
   963  * @return GstElement* - return newly created gst pipeline element
       
   964  * Description: Create video processing pipeline with fixed output size to TEST_VIDEO_WIDTH x TEST_VIDEO_HEIGHT
       
   965  *              experimental implementation for changing recorder output size
       
   966  */
       
   967 GstElement* XAAdaptationGst_CreateFixedSizeVideoPP( )
       
   968 {
       
   969     GstElement *vpp;
       
   970     DEBUG_API("->XAAdaptationGst_CreateFixedSizeVideoPP");
       
   971     vpp = gst_pipeline_new("videopp");
       
   972     if( vpp )
       
   973     {
       
   974         GstPad *ghostsink, *ghostsrc;
       
   975         GstElement  *col1,
       
   976                     *col2,
       
   977                     *rotate,
       
   978                     *mirror,
       
   979                     *box,
       
   980                     *crop,
       
   981                     *gamma,
       
   982                     *balance,
       
   983                     *scale,
       
   984                     *scale2,
       
   985                     *filter,
       
   986                     *queue;
       
   987 
       
   988 
       
   989         /* Crete ffmpegcolorspace to convert stream to correct format */
       
   990         col1 = gst_element_factory_make( "ffmpegcolorspace", "pp_colsp1");
       
   991         if(col1)
       
   992         {
       
   993             DEBUG_INFO("Created ffmpegcolorspace element");
       
   994             gst_bin_add(GST_BIN(vpp), col1);
       
   995            /* make this bin link point*/
       
   996             ghostsink = gst_element_get_static_pad(col1,"sink");
       
   997             if(ghostsink)
       
   998             {
       
   999                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_sink",ghostsink));
       
  1000                 gst_object_unref(GST_OBJECT(ghostsink));
       
  1001             }
       
  1002         }
       
  1003 
       
  1004         /* create video crop, this will be sink for videoPP pipeline */
       
  1005         crop = gst_element_factory_make( "videocrop", "pp_crop");
       
  1006         if(crop)
       
  1007         {
       
  1008             DEBUG_INFO("Created crop element");
       
  1009             gst_bin_add(GST_BIN(vpp), crop);
       
  1010         }
       
  1011 
       
  1012         /* create video rotate */
       
  1013         rotate = gst_element_factory_make( "videoflip", "pp_rotate");
       
  1014         if(rotate)
       
  1015         {
       
  1016             DEBUG_INFO("Created rotate element");
       
  1017             g_object_set(G_OBJECT(rotate), "method", FLIP_NONE, NULL);
       
  1018             gst_bin_add(GST_BIN(vpp), rotate);
       
  1019         }
       
  1020 
       
  1021         /* create video mirror */
       
  1022         mirror = gst_element_factory_make( "videoflip", "pp_mirror");
       
  1023         if(mirror)
       
  1024         {
       
  1025             DEBUG_INFO("Created mirror element");
       
  1026             g_object_set(G_OBJECT(mirror), "method", FLIP_NONE, NULL);
       
  1027             gst_bin_add(GST_BIN(vpp), mirror);
       
  1028         }
       
  1029 
       
  1030         /* create video box */
       
  1031         box = gst_element_factory_make( "videobox", "pp_box");
       
  1032         if(box)
       
  1033         {
       
  1034             DEBUG_INFO("Created videobox element");
       
  1035             gst_bin_add(GST_BIN(vpp), box);
       
  1036         }
       
  1037 
       
  1038         /* create video balance */
       
  1039         balance = gst_element_factory_make( "videobalance", "pp_balance");
       
  1040         if(balance)
       
  1041         {
       
  1042             DEBUG_INFO("Created balance element");
       
  1043             gst_bin_add(GST_BIN(vpp), balance);
       
  1044         }
       
  1045 
       
  1046         /* create video gamma */
       
  1047         gamma = gst_element_factory_make( "gamma", "pp_gamma");
       
  1048         if(gamma)
       
  1049         {
       
  1050             DEBUG_INFO("Created gamma element");
       
  1051             gst_bin_add(GST_BIN(vpp), gamma);
       
  1052         }
       
  1053 
       
  1054         /* Create videoscale element to scale postprocessed output to correct size */
       
  1055         scale = gst_element_factory_make("videoscale", "pp_scale");
       
  1056         if ( scale )
       
  1057         {
       
  1058             DEBUG_INFO("Created videoscale element");
       
  1059             gst_bin_add(GST_BIN(vpp), scale);
       
  1060         }
       
  1061         scale2 = gst_element_factory_make("videoscale", "pp_scale2");
       
  1062         if ( scale2 )
       
  1063         {
       
  1064             GstPad *pad = NULL;
       
  1065             GstCaps *caps = NULL;
       
  1066             DEBUG_INFO("Created videoscale element");
       
  1067             pad = gst_element_get_static_pad(scale2,"src");
       
  1068             caps = gst_caps_new_simple("video/x-raw-yuv",
       
  1069                      "width", G_TYPE_INT,0,
       
  1070                      "height", G_TYPE_INT,0,
       
  1071                      NULL);
       
  1072             gst_pad_set_caps(pad, caps);
       
  1073             gst_bin_add(GST_BIN(vpp), scale2);
       
  1074         }
       
  1075 
       
  1076         /* create capsfilter for fixed video size */
       
  1077         filter = gst_element_factory_make("capsfilter", "pp_filter");
       
  1078         if ( filter )
       
  1079         {
       
  1080 
       
  1081             g_object_set( G_OBJECT(filter), "caps",
       
  1082                             gst_caps_new_simple("video/x-raw-yuv",
       
  1083                                                 "width", G_TYPE_INT, TEST_VIDEO_WIDTH,
       
  1084                                                 "height", G_TYPE_INT, TEST_VIDEO_HEIGHT, NULL)
       
  1085                                                 ,NULL );
       
  1086             gst_bin_add(GST_BIN(vpp), filter);
       
  1087         }
       
  1088 
       
  1089         /* create video queue */
       
  1090         queue = gst_element_factory_make( "queue", "vpp_queue");
       
  1091         if(queue)
       
  1092         {
       
  1093             gst_bin_add(GST_BIN(vpp), queue);
       
  1094         }
       
  1095 
       
  1096 
       
  1097         /* Crete ffmpegcolorspace to convert stream to correct format */
       
  1098         col2 = gst_element_factory_make( "ffmpegcolorspace", "pp_colsp2");
       
  1099         if(col2)
       
  1100         {
       
  1101             DEBUG_INFO("Created ffmpegcolorspace element");
       
  1102             gst_bin_add(GST_BIN(vpp), col2);
       
  1103             /* make this bin link point*/
       
  1104             ghostsrc = gst_element_get_static_pad(col2,"src");
       
  1105             if(ghostsrc)
       
  1106             {
       
  1107                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_src",ghostsrc));
       
  1108                 gst_object_unref(GST_OBJECT(ghostsrc));
       
  1109             }
       
  1110         }
       
  1111         if( !(gst_element_link_many(col1,
       
  1112                                     scale,
       
  1113                                     crop,
       
  1114                                     rotate,
       
  1115                                     mirror,
       
  1116                                     box,
       
  1117                                     balance,
       
  1118                                     gamma,
       
  1119                                     queue,
       
  1120                                     scale2,
       
  1121                                     filter,
       
  1122                                     col2,
       
  1123                                     NULL)
       
  1124                                     ) )
       
  1125         {
       
  1126             DEBUG_ERR("Could not link videopp elements!!");
       
  1127             gst_object_unref(vpp);
       
  1128             vpp = NULL;
       
  1129         }
       
  1130     }
       
  1131     DEBUG_API("<-XAAdaptationGst_CreateFixedSizeVideoPP");
       
  1132     return vpp;
       
  1133 }
       
  1134 
       
  1135 
       
  1136 
       
  1137 /**
       
  1138  * GstElement* XAAdaptationGst_CreateVideoPPBlackScr( )
       
  1139  * @return GstElement* - return newly created gst pipeline element
       
  1140  * Description: Create video processing pipeline for black screen
       
  1141  */
       
  1142 GstElement* XAAdaptationGst_CreateVideoPPBlackScr( )
       
  1143 {
       
  1144     GstElement *vppBScr;
       
  1145     DEBUG_API("->XAAdaptationGst_CreateVideoPPBlackScr");
       
  1146     vppBScr = gst_pipeline_new("videoppBScr");
       
  1147     if( vppBScr )
       
  1148     {
       
  1149         GstPad *ghostsrc=NULL;
       
  1150         GstElement *testVideo=NULL, *scale=NULL;
       
  1151         GstElement *ffmpegcolorspace=NULL;
       
  1152 
       
  1153         testVideo = gst_element_factory_make( "videotestsrc", "videotest");
       
  1154         if(testVideo)
       
  1155         {
       
  1156             DEBUG_INFO("Created videotestsrc element");
       
  1157 
       
  1158             g_object_set(G_OBJECT(testVideo), "pattern", (gint)2, "num-buffers", (gint)1, NULL);
       
  1159             gst_bin_add(GST_BIN(vppBScr), testVideo);
       
  1160         }
       
  1161 
       
  1162         scale = gst_element_factory_make("videoscale", "BSrc_scale");
       
  1163         if(scale)
       
  1164         {
       
  1165             DEBUG_INFO("Created videoscale element");
       
  1166             gst_bin_add(GST_BIN(vppBScr), scale);
       
  1167             /* make this bin link point*/
       
  1168             ghostsrc = gst_element_get_static_pad(scale,"src");
       
  1169             if(ghostsrc)
       
  1170             {
       
  1171                 gst_element_add_pad(vppBScr, gst_ghost_pad_new("videoppBSrc_src",ghostsrc));
       
  1172                 gst_object_unref(GST_OBJECT(ghostsrc));
       
  1173             }
       
  1174         }
       
  1175         ffmpegcolorspace = gst_element_factory_make("ffmpegcolorspace", "BlackScrFfmpeg");
       
  1176         gst_bin_add(GST_BIN(vppBScr), ffmpegcolorspace);
       
  1177         if( !(gst_element_link_many(testVideo, ffmpegcolorspace, scale, NULL)) )
       
  1178         {
       
  1179             DEBUG_ERR("Could not link videoppBSrc elements!!");
       
  1180             gst_object_unref(vppBScr);
       
  1181             vppBScr = NULL;
       
  1182         }
       
  1183     }
       
  1184     DEBUG_API("<-XAAdaptationGst_CreateVideoPPBlackScr");
       
  1185     return vppBScr;
       
  1186 }
       
  1187 
       
  1188 /**
       
  1189  * GstElement* XAAdaptationGst_CreateInputSelector( )
       
  1190  * @return GstElement* - return newly created input selector
       
  1191  * Description: Create input selector to processing between black screen and video screen
       
  1192  */
       
  1193 GstElement* XAAdaptationGst_CreateInputSelector( )
       
  1194 {
       
  1195     GstElement *inputSelector;
       
  1196     DEBUG_API("->XAAdaptationGst_CreateInputSelector");
       
  1197     inputSelector = gst_element_factory_make("input-selector", "input-selector");
       
  1198     if( inputSelector )
       
  1199     {
       
  1200         g_object_set(G_OBJECT(inputSelector), "select-all", TRUE, NULL);
       
  1201     }
       
  1202     DEBUG_API("<-XAAdaptationGst_CreateInputSelector");
       
  1203     return inputSelector;
       
  1204 }
       
  1205 
       
  1206 /**
       
  1207  * GstElement* XAAdaptationGst_CreateAudioPP( )
       
  1208  * @return GstElement* - return newly created gst pipeline element
       
  1209  * Description: Create video processing pipeline
       
  1210  */
       
  1211 GstElement* XAAdaptationGst_CreateAudioPP( )
       
  1212 {
       
  1213     GstElement *app;
       
  1214     gboolean ok = TRUE;
       
  1215     DEBUG_API("->XAAdaptationGst_CreateAudioPP");
       
  1216     app = gst_pipeline_new("audiopp");
       
  1217     if( app )
       
  1218     {
       
  1219         GstPad *ghostsink, *ghostsrc;
       
  1220         GstElement *ac,*vol,*eq,*queue,*pan, *ac2;
       
  1221 
       
  1222         /* first and last elements should be audioconverts to match sink and encoder formats */
       
  1223         ac = gst_element_factory_make( "audioconvert", "pp_ac");
       
  1224         if (ac)
       
  1225         {
       
  1226             ok = gst_bin_add(GST_BIN(app), ac);
       
  1227             /* make this bin link point*/
       
  1228             if (ok)
       
  1229             {
       
  1230                 ghostsink = gst_element_get_static_pad(ac,"sink");
       
  1231                 ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1232                 gst_object_unref(GST_OBJECT(ghostsink));
       
  1233             }
       
  1234         }
       
  1235         ac2 = gst_element_factory_make( "audioconvert", "pp_ac2");
       
  1236         if (ac2 && ok)
       
  1237         {
       
  1238             ok = gst_bin_add(GST_BIN(app), ac2);
       
  1239             /* make this bin link point*/
       
  1240             if (ok)
       
  1241             {
       
  1242                 ghostsrc = gst_element_get_static_pad(ac2,"src");
       
  1243                 ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1244                 gst_object_unref(GST_OBJECT(ghostsrc));
       
  1245             }
       
  1246         }
       
  1247 
       
  1248         vol = gst_element_factory_make( "volume", "pp_vol");
       
  1249         /* create volume controller */
       
  1250         if (vol && ok)
       
  1251         {
       
  1252             ok = gst_bin_add(GST_BIN(app), vol);
       
  1253             g_object_set( G_OBJECT(vol), "volume", (gdouble)1, NULL );
       
  1254         }
       
  1255         /* create 10-band equalizer */
       
  1256         eq = gst_element_factory_make( "equalizer-10bands", "pp_equ");
       
  1257         if (eq && ok)
       
  1258         {
       
  1259             ok = gst_bin_add(GST_BIN(app), eq);
       
  1260         }
       
  1261         /* create audio queue */
       
  1262         queue = gst_element_factory_make( "queue", "app_queue");
       
  1263         if(queue && ok)
       
  1264         {
       
  1265             ok = gst_bin_add(GST_BIN(app), queue);
       
  1266             g_object_set (G_OBJECT (queue), "max-size-buffers", 2, NULL);
       
  1267         }
       
  1268         /* create audio pan effect */
       
  1269         pan = gst_element_factory_make( "audiopanorama", "pp_pan");
       
  1270         if (pan && ok)
       
  1271         {
       
  1272             ok = gst_bin_add(GST_BIN(app), pan);
       
  1273         }
       
  1274 
       
  1275         if (ac && ok)
       
  1276         {
       
  1277             if (queue)
       
  1278             {
       
  1279                 ok = gst_element_link(ac, queue);
       
  1280             }
       
  1281             else if (vol)
       
  1282             {
       
  1283                 ok = gst_element_link(ac, vol);
       
  1284             }
       
  1285             else if (pan)
       
  1286             {
       
  1287                 ok = gst_element_link(ac, pan);
       
  1288             }
       
  1289             else if (eq)
       
  1290             {
       
  1291                 ok = gst_element_link(ac, eq);
       
  1292             }
       
  1293             else if (ac2)
       
  1294             {
       
  1295                 ok = gst_element_link(ac, ac2);
       
  1296             }
       
  1297         }
       
  1298         if (queue && ok)
       
  1299         {
       
  1300             if (vol)
       
  1301             {
       
  1302                 ok = gst_element_link(queue, vol);
       
  1303             }
       
  1304             else if (pan)
       
  1305             {
       
  1306                 ok = gst_element_link(queue, pan);
       
  1307             }
       
  1308             else if (eq)
       
  1309             {
       
  1310                 ok = gst_element_link(queue, eq);
       
  1311             }
       
  1312             else if (ac2)
       
  1313             {
       
  1314                 ok = gst_element_link(queue, ac2);
       
  1315             }
       
  1316         }
       
  1317         if (vol && ok)
       
  1318         {
       
  1319             if (pan)
       
  1320             {
       
  1321                 ok = gst_element_link(vol, pan);
       
  1322             }
       
  1323             else if (eq)
       
  1324             {
       
  1325                 ok = gst_element_link(vol, eq);
       
  1326             }
       
  1327             else if (ac2)
       
  1328             {
       
  1329                 ok = gst_element_link(vol, ac2);
       
  1330             }
       
  1331         }
       
  1332         if (pan && ok)
       
  1333         {
       
  1334             if (eq)
       
  1335             {
       
  1336                 ok = gst_element_link(pan, eq);
       
  1337             }
       
  1338             else if (ac2)
       
  1339             {
       
  1340                 ok = gst_element_link(pan, ac2);
       
  1341             }
       
  1342         }
       
  1343         if (eq && ok)
       
  1344         {
       
  1345             if (ac2)
       
  1346             {
       
  1347                 ok = gst_element_link(eq, ac2);
       
  1348             }
       
  1349         }
       
  1350         
       
  1351         if (ac)
       
  1352         {
       
  1353             // ghost sink above
       
  1354         }
       
  1355         else if (queue && ok)
       
  1356         {
       
  1357             /* make this bin link point*/
       
  1358             ghostsink = gst_element_get_static_pad(queue,"sink");
       
  1359             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1360             gst_object_unref(GST_OBJECT(ghostsink));
       
  1361         }
       
  1362         else if (vol && ok)
       
  1363         {
       
  1364             /* make this bin link point*/
       
  1365             ghostsink = gst_element_get_static_pad(vol,"sink");
       
  1366             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1367             gst_object_unref(GST_OBJECT(ghostsink));
       
  1368         }
       
  1369         else if (pan && ok)
       
  1370         {
       
  1371             /* make this bin link point*/
       
  1372             ghostsink = gst_element_get_static_pad(pan,"sink");
       
  1373             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1374             gst_object_unref(GST_OBJECT(ghostsink));
       
  1375         }
       
  1376         else if (eq && ok)
       
  1377         {
       
  1378             /* make this bin link point*/
       
  1379             ghostsink = gst_element_get_static_pad(eq,"sink");
       
  1380             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1381             gst_object_unref(GST_OBJECT(ghostsink));
       
  1382         }
       
  1383         else if (ac2 && ok)
       
  1384         {
       
  1385             /* make this bin link point*/
       
  1386             ghostsink = gst_element_get_static_pad(ac2,"sink");
       
  1387             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1388             gst_object_unref(GST_OBJECT(ghostsink));
       
  1389         }
       
  1390         
       
  1391         if (ac2)
       
  1392         {
       
  1393             // ghost src above
       
  1394         }
       
  1395         else if (eq && ok)
       
  1396         {
       
  1397             /* make this bin link point*/
       
  1398             ghostsrc = gst_element_get_static_pad(eq,"src");
       
  1399             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1400             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1401         }
       
  1402         else if (pan && ok)
       
  1403         {
       
  1404             /* make this bin link point*/
       
  1405             ghostsrc = gst_element_get_static_pad(pan,"src");
       
  1406             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1407             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1408         }
       
  1409         else if (vol && ok)
       
  1410         {
       
  1411             /* make this bin link point*/
       
  1412             ghostsrc = gst_element_get_static_pad(vol,"src");
       
  1413             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1414             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1415         }
       
  1416         else if (queue && ok)
       
  1417         {
       
  1418             /* make this bin link point*/
       
  1419             ghostsrc = gst_element_get_static_pad(queue,"src");
       
  1420             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1421             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1422         }
       
  1423         else if (ac && ok)
       
  1424         {
       
  1425             /* make this bin link point*/
       
  1426             ghostsrc = gst_element_get_static_pad(ac,"src");
       
  1427             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1428             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1429         }
       
  1430             
       
  1431 //        if( !(gst_element_link_many(ac, queue, vol, ac2, NULL)) )
       
  1432 //        if( !(gst_element_link_many(ac, queue, vol, pan, eq, ac2, NULL)) )
       
  1433         if (!ok)
       
  1434         {
       
  1435             DEBUG_ERR("Could not link audiopp elements!!");
       
  1436             gst_object_unref(app);
       
  1437             app = NULL;
       
  1438         }
       
  1439     }
       
  1440 
       
  1441     DEBUG_API("<-XAAdaptationGst_CreateAudioPP");
       
  1442     return app;
       
  1443 }
       
  1444 
       
  1445 /* called when pad is actually blocking/ gets unblocked*/
       
  1446 void XAAdaptationGst_PadBlockCb(GstPad *pad, gboolean blocked, gpointer user_data)
       
  1447 {
       
  1448     DEBUG_API_A2("->XAAdaptationGst_PadBlockCb   pad \"%s\" of \"%s\" ",
       
  1449                         GST_OBJECT_NAME(pad),
       
  1450                         GST_OBJECT_NAME(gst_pad_get_parent_element(pad)) );
       
  1451     DEBUG_API_A1("<-XAAdaptationGst_PadBlockCb   blocked:%d",blocked);
       
  1452 }
       
  1453 
       
  1454 /* utility to set same fields for all media types in caps */
       
  1455 void XAAdaptationGst_SetAllCaps (GstCaps * caps, char *field, ...)
       
  1456 {
       
  1457     GstStructure *structure;
       
  1458     va_list var_args;
       
  1459     int i;
       
  1460 
       
  1461     for (i = 0; i < gst_caps_get_size (caps); i++)
       
  1462     {
       
  1463         structure = gst_caps_get_structure (caps, i);
       
  1464         va_start (var_args, field);
       
  1465         gst_structure_set_valist (structure, field, var_args);
       
  1466         va_end (var_args);
       
  1467     }
       
  1468 }
       
  1469 
       
  1470