khronosfws/openmax_al/src/adaptation/xaadaptationcontextbase.c
changeset 16 43d09473c595
parent 14 80975da52420
child 22 128eb6a32b84
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 "XAAdaptationContextBase.h"
       
    24 #include "XAAdaptation.h"
       
    25 #include "XAObjectItf.h"
       
    26 #include "XACameraDevice.h"
       
    27 #include "XARadioDevice.h"
       
    28 #include "XAOutputMix.h"
       
    29 #include "XAStaticCapsAdaptation.h"
       
    30 #include "XAMediaPlayerAdaptCtx.h"
       
    31 
       
    32 extern XAboolean cameraRealized;
       
    33 extern XACameraAdaptationCtx_* cameraCtx;
       
    34 /*
       
    35  * XAAdaptationBaseCtx* XAAdaptationBase_Create()
       
    36  * 1st phase initialization function for Adaptation Base context structure.
       
    37  * Reserves memory for base context and initializes GStreamer FW.
       
    38  */
       
    39 XAresult XAAdaptationBase_Init( XAAdaptationBaseCtx* pSelf, XAuint32 ctxId )
       
    40 {
       
    41     DEBUG_API("->XAAdaptationBase_Init");
       
    42 
       
    43     if ( pSelf )
       
    44     {
       
    45         GError* gerror = 0;
       
    46 		pSelf->pipeSrcThr = NULL;
       
    47 		pSelf->pipeSinkThr = NULL;
       
    48 
       
    49         /* Set context id */
       
    50         pSelf->ctxId = ctxId;
       
    51         /* Add default handler for Gst-bus messages */
       
    52         pSelf->busCb = XAAdaptationBase_GstBusCb;
       
    53 
       
    54         // VASU MOD BEGINS
       
    55         pSelf->cond_mutx_inited = XA_BOOLEAN_FALSE;
       
    56         // VASU MOD ENDS
       
    57 
       
    58         pSelf->evtHdlrs = g_array_new (FALSE, FALSE, sizeof (XAAdaptEvtHdlr));
       
    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     else
       
    70     {
       
    71         DEBUG_ERR("Invalid Adaptation Base Context.")
       
    72         return XA_RESULT_PARAMETER_INVALID;
       
    73     }
       
    74 
       
    75     DEBUG_API("<-XAAdaptationBase_Init");
       
    76     return XA_RESULT_SUCCESS;
       
    77 }
       
    78 
       
    79 /*
       
    80  * XAresult XAAdaptationBase_PostInit()
       
    81  * 2nd phase initialization for Adaptation Base.
       
    82  */
       
    83 XAresult XAAdaptationBase_PostInit( XAAdaptationBaseCtx* ctx )
       
    84 {
       
    85     XAresult ret = XA_RESULT_SUCCESS;
       
    86     DEBUG_API("->XAAdaptationBase_PostInit");
       
    87     // VASU MOD BEGINS
       
    88     ctx->thread_launched = XA_BOOLEAN_FALSE;
       
    89     pthread_mutex_init(&(ctx->ds_mutex), NULL);
       
    90     pthread_cond_init(&(ctx->ds_condition), NULL);
       
    91     ctx->cond_mutx_inited = XA_BOOLEAN_TRUE;
       
    92     // VASU MOD ENDS
       
    93     DEBUG_API("<-XAAdaptationBase_PostInit");
       
    94     return ret;
       
    95 }
       
    96 
       
    97 /*
       
    98  * void XAAdaptationBase_Free( XAAdaptationBaseCtx* ctx )
       
    99  * Frees all Base context variables .
       
   100  */
       
   101 void XAAdaptationBase_Free( XAAdaptationBaseCtx* ctx )
       
   102 {
       
   103 	GstElement* fakesink = NULL;
       
   104     DEBUG_API("->XAAdaptationBase_Free");
       
   105 
       
   106     if ( ctx->bin )
       
   107     {
       
   108     	fakesink = gst_bin_get_by_name(GST_BIN(ctx->bin), "fakesink");
       
   109 		if ( fakesink )
       
   110 		{
       
   111 			gst_element_set_state( GST_ELEMENT(fakesink), GST_STATE_NULL);
       
   112 			gst_object_unref(fakesink);
       
   113 		}
       
   114 
       
   115         if ( gst_element_set_state(GST_ELEMENT(ctx->bin), GST_STATE_NULL )!=GST_STATE_CHANGE_SUCCESS )
       
   116         {   /*not much we can do*/
       
   117             DEBUG_ERR("WARNING: Failed to change to NULL state before deletion!!")
       
   118         }
       
   119     }
       
   120 
       
   121     if(ctx->asynctimer)
       
   122     {   /*cancel timer*/
       
   123         g_source_remove(ctx->asynctimer);
       
   124     }
       
   125     sem_post(&(ctx->semAsyncWait));
       
   126     sem_destroy(&(ctx->semAsyncWait));
       
   127 
       
   128     XAAdaptationBase_StopGstListener(ctx);
       
   129 
       
   130     if ( ctx->bin )
       
   131     {
       
   132         gst_object_unref(ctx->bin);
       
   133     }
       
   134 
       
   135     g_array_free(ctx->evtHdlrs, TRUE);
       
   136     // VASU MOD BEGINS
       
   137     if (ctx->cond_mutx_inited == XA_BOOLEAN_TRUE)
       
   138         {
       
   139         ctx->thread_launched = XA_BOOLEAN_FALSE;
       
   140         pthread_mutex_destroy(&(ctx->ds_mutex));
       
   141         pthread_cond_destroy(&(ctx->ds_condition));
       
   142         ctx->cond_mutx_inited = XA_BOOLEAN_FALSE;
       
   143         }
       
   144     // VASU MOD ENDS
       
   145 
       
   146     DEBUG_API("<-XAAdaptationBase_Free");
       
   147 }
       
   148 
       
   149 /*
       
   150  * XAresult XAAdaptationBase_AddEventHandler
       
   151  * Adds event handler for certain event types.
       
   152  */
       
   153 XAresult XAAdaptationBase_AddEventHandler( XAAdaptationBaseCtx* ctx, xaAdaptEventHandler evtHandler,
       
   154                                     XAuint32 evtTypes, void *pHandlerCtx )
       
   155 {
       
   156     XAuint32 i;
       
   157     XAAdaptEvtHdlr tmp;
       
   158     DEBUG_API("->XAAdaptationBase_AddEventHandler");
       
   159     if(!ctx)
       
   160     {
       
   161         DEBUG_ERR("no context");
       
   162         return XA_RESULT_PARAMETER_INVALID;
       
   163     }
       
   164     for(i=0; i<ctx->evtHdlrs->len; i++)
       
   165     {
       
   166         if( (g_array_index(ctx->evtHdlrs, XAAdaptEvtHdlr, i)).handlerfunc == evtHandler )
       
   167         {
       
   168             return XA_RESULT_PARAMETER_INVALID;
       
   169         }
       
   170     }
       
   171     tmp.handlerfunc = evtHandler;
       
   172     tmp.handlercontext = pHandlerCtx;
       
   173     tmp.eventtypes = evtTypes;
       
   174     g_array_append_val(ctx->evtHdlrs, tmp);
       
   175     DEBUG_API("<-XAAdaptationBase_AddEventHandler");
       
   176     return XA_RESULT_SUCCESS;
       
   177 }
       
   178 
       
   179 /*
       
   180  * XAresult XAAdaptationBase_RemoveEventHandler
       
   181  * Removes event handler for certain event types.
       
   182  */
       
   183 XAresult XAAdaptationBase_RemoveEventHandler( XAAdaptationBaseCtx* ctx, xaAdaptEventHandler evtHandler)
       
   184 {
       
   185     XAuint32 i;
       
   186     DEBUG_API("->XAAdaptationBase_RemoveEventHandler");
       
   187     if(!ctx)
       
   188     {
       
   189         DEBUG_ERR("no context");
       
   190         return XA_RESULT_PARAMETER_INVALID;
       
   191     }
       
   192     for(i=0; i<ctx->evtHdlrs->len; i++)
       
   193     {
       
   194         if( (g_array_index(ctx->evtHdlrs, XAAdaptEvtHdlr, i)).handlerfunc == evtHandler )
       
   195         {
       
   196             g_array_remove_index(ctx->evtHdlrs, i);
       
   197             return XA_RESULT_SUCCESS;
       
   198         }
       
   199     }
       
   200     DEBUG_API("<-XAAdaptationBase_RemoveEventHandler");
       
   201     /*did not find, return error*/
       
   202     return XA_RESULT_PARAMETER_INVALID;
       
   203 }
       
   204 
       
   205 /*
       
   206  * gboolean XAAdaptationBase_GstBusCb( GstBus *bus, GstMessage *message, gpointer data )
       
   207  * Default Gst-bus message handler (Callback)
       
   208  */
       
   209 gboolean XAAdaptationBase_GstBusCb( GstBus *bus, GstMessage *message, gpointer data )
       
   210 {
       
   211     GError *error;
       
   212     gchar *debug;
       
   213     DEBUG_API("->XAAdaptationBase_GstBusCb");
       
   214     DEBUG_INFO_A2("Received Gst callback \"%s\" from \"%s\"",
       
   215                     GST_MESSAGE_TYPE_NAME(message),
       
   216                     GST_OBJECT_NAME(GST_MESSAGE_SRC(message)));
       
   217 
       
   218     switch( GST_MESSAGE_TYPE(message))
       
   219     {
       
   220         case GST_MESSAGE_ERROR:
       
   221             gst_message_parse_error( message, &error, &debug );
       
   222             DEBUG_INFO_A1("%s", debug);
       
   223             break;
       
   224         case GST_MESSAGE_EOS:
       
   225             break;
       
   226         case GST_MESSAGE_UNKNOWN:
       
   227             break;
       
   228         case GST_MESSAGE_WARNING:
       
   229             break;
       
   230         case GST_MESSAGE_INFO:
       
   231             break;
       
   232         case GST_MESSAGE_TAG:
       
   233             break;
       
   234         case GST_MESSAGE_BUFFERING:
       
   235             break;
       
   236         case GST_MESSAGE_STATE_CHANGED:
       
   237             break;
       
   238         case GST_MESSAGE_STATE_DIRTY:
       
   239             break;
       
   240         case GST_MESSAGE_STEP_DONE:
       
   241             break;
       
   242         case GST_MESSAGE_CLOCK_PROVIDE:
       
   243             break;
       
   244         case GST_MESSAGE_CLOCK_LOST:
       
   245             break;
       
   246         case GST_MESSAGE_NEW_CLOCK:
       
   247             break;
       
   248         case GST_MESSAGE_STRUCTURE_CHANGE:
       
   249             break;
       
   250         case GST_MESSAGE_STREAM_STATUS:
       
   251             break;
       
   252         case GST_MESSAGE_APPLICATION:
       
   253             break;
       
   254         case GST_MESSAGE_ELEMENT:
       
   255             break;
       
   256         case GST_MESSAGE_SEGMENT_START:
       
   257             break;
       
   258         case GST_MESSAGE_SEGMENT_DONE:
       
   259             break;
       
   260         case GST_MESSAGE_DURATION:
       
   261             break;
       
   262         case GST_MESSAGE_LATENCY:
       
   263             break;
       
   264         case GST_MESSAGE_ASYNC_START:
       
   265             break;
       
   266         case GST_MESSAGE_ASYNC_DONE:
       
   267             break;
       
   268         case GST_MESSAGE_ANY:
       
   269             break;
       
   270         default:
       
   271             DEBUG_INFO("Unhandled Gst-Bus message");
       
   272             break;
       
   273     }
       
   274     DEBUG_API("<-XAAdaptationBase_GstBusCb");
       
   275     return TRUE;
       
   276 }
       
   277 
       
   278 XAresult XAAdaptationBase_InitGstListener(XAAdaptationBaseCtx* ctx)
       
   279 {
       
   280     int ret;
       
   281     DEBUG_API("->XAAdaptationBase_InitGstListener");
       
   282     if ( ctx->bin )
       
   283     {
       
   284         ctx->bus = gst_pipeline_get_bus( GST_PIPELINE( ctx->bin ));
       
   285     }
       
   286     if( !ctx->bus )
       
   287     {
       
   288         DEBUG_ERR("could not get gst bus!")
       
   289         return XA_RESULT_INTERNAL_ERROR;
       
   290     }
       
   291     ret = pthread_create(&(ctx->busloopThr), NULL, (XAAdaptationBase_LaunchGstListener),(void*)ctx);
       
   292     // VASU MOD BEGINS
       
   293     if ( ctx->thread_launched == XA_BOOLEAN_FALSE )
       
   294     {
       
   295         // Wait until the thread is created
       
   296         pthread_mutex_lock(&(ctx->ds_mutex));
       
   297         pthread_cond_wait(&(ctx->ds_condition), &(ctx->ds_mutex));
       
   298         pthread_mutex_unlock(&(ctx->ds_mutex));
       
   299         // VASU MOD ENDS
       
   300     }
       
   301     if(ret)
       
   302     {
       
   303         DEBUG_ERR_A1("could not create thread!! (%d)",ret)
       
   304         return XA_RESULT_INTERNAL_ERROR;
       
   305     }
       
   306     DEBUG_API("<-XAAdaptationBase_InitGstListener");
       
   307     return XA_RESULT_SUCCESS;
       
   308 }
       
   309 
       
   310 void * XAAdaptationBase_LaunchGstListener(void* args)
       
   311 {
       
   312     XAAdaptationBaseCtx* ctx = (XAAdaptationBaseCtx*)args;
       
   313     DEBUG_API("->XAAdaptationBase_LaunchGstListener");
       
   314     // VASU MOD BEGINS
       
   315     // Signal calling thread that this thread creation is completed
       
   316     ctx->thread_launched = XA_BOOLEAN_TRUE;
       
   317     pthread_mutex_lock(&(ctx->ds_mutex));
       
   318     pthread_cond_signal(&(ctx->ds_condition));
       
   319     pthread_mutex_unlock(&(ctx->ds_mutex));
       
   320     // VASU MOD ENDS
       
   321 
       
   322     ctx->busloop = g_main_loop_new( NULL, FALSE );
       
   323     if ( !ctx->busloop )
       
   324     {
       
   325         DEBUG_ERR("Glib main loop failure.")
       
   326         DEBUG_API("<-XAAdaptationBase_LaunchGstListener");
       
   327         assert(0);
       
   328     }
       
   329     else
       
   330     {
       
   331         DEBUG_INFO("Start Glib main loop")
       
   332         g_main_loop_run(ctx->busloop);
       
   333         DEBUG_INFO("Glib main loop stopped - exiting thread")
       
   334         DEBUG_API("<-XAAdaptationBase_LaunchGstListener");
       
   335         pthread_exit(NULL);
       
   336     }
       
   337    
       
   338 }
       
   339 
       
   340 void XAAdaptationBase_StopGstListener(XAAdaptationBaseCtx* ctx)
       
   341 {
       
   342     DEBUG_API("->XAAdaptationBase_StopGstListener");
       
   343     if(ctx->busloop)
       
   344     {
       
   345         g_main_loop_quit (ctx->busloop);
       
   346         g_main_loop_unref(ctx->busloop);
       
   347     }
       
   348     if(ctx->bus)
       
   349     {
       
   350         gst_object_unref(ctx->bus);
       
   351         ctx->bus = NULL;
       
   352     }
       
   353     DEBUG_API("<-XAAdaptationBase_StopGstListener");
       
   354 }
       
   355 
       
   356 void XAAdaptationBase_SendAdaptEvents(XAAdaptationBaseCtx* ctx, XAAdaptEvent* event)
       
   357 {
       
   358     XAuint32 i;
       
   359     XAAdaptEvtHdlr* tmp;
       
   360     for(i=0; i<ctx->evtHdlrs->len; i++)
       
   361     {
       
   362         tmp = &g_array_index(ctx->evtHdlrs, XAAdaptEvtHdlr, i);
       
   363         if( tmp->eventtypes & event->eventtype )
       
   364         {
       
   365             (tmp->handlerfunc)(tmp->handlercontext, event);
       
   366         }
       
   367     }
       
   368 }
       
   369 
       
   370 /*
       
   371  * ASynchronous operation managing
       
   372  **/
       
   373 
       
   374 /* NOTE: This should NOT be called from gst callbacks - danger of deadlock!!
       
   375  */
       
   376 void XAAdaptationBase_PrepareAsyncWait(XAAdaptationBaseCtx* ctx)
       
   377 {
       
   378     DEBUG_API("->XAAdaptationBase_PrepareAsyncWait");
       
   379 
       
   380     if( ctx->waitingasyncop )
       
   381     {   /*wait previous async op*/
       
   382         DEBUG_INFO("::WARNING:: previous asynch still ongoing!!!");
       
   383         DEBUG_INFO(">>>>  WAIT PREVIOUS");
       
   384         sem_wait(&(ctx->semAsyncWait));
       
   385         DEBUG_INFO("<<<<  PREVIOUS COMPLETED");
       
   386     }
       
   387     sem_init(&(ctx->semAsyncWait),0,0);
       
   388 
       
   389     ctx->waitingasyncop = XA_BOOLEAN_TRUE;
       
   390     DEBUG_API("<-XAAdaptationBase_PrepareAsyncWait");
       
   391 }
       
   392 
       
   393 void XAAdaptationBase_StartAsyncWait(XAAdaptationBaseCtx* ctx)
       
   394 {
       
   395     DEBUG_API("->XAAdaptationBase_StartAsyncWait");
       
   396 
       
   397     /* timeout to try to avoid gst freeze in rollup */
       
   398     ctx->asynctimer = g_timeout_add(XA_ADAPT_ASYNC_TIMEOUT,
       
   399                                     XAAdaptationBase_CancelAsyncWait, ctx);
       
   400     /* check flag once again if callback already happened before wait */
       
   401     if(ctx->waitingasyncop)
       
   402     {
       
   403         DEBUG_INFO(">>>>  ASYNC STARTS");
       
   404         sem_wait(&(ctx->semAsyncWait));
       
   405         DEBUG_INFO("<<<<  ASYNC COMPLETED");
       
   406     }
       
   407     else
       
   408     {
       
   409         DEBUG_INFO("<> async completed already");
       
   410     }
       
   411     /*cancel timer*/
       
   412     if(ctx->asynctimer)
       
   413     {
       
   414         g_source_remove(ctx->asynctimer);
       
   415     }
       
   416     ctx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   417 
       
   418     DEBUG_API("<-XAAdaptationBase_StartAsyncWait");
       
   419 }
       
   420 
       
   421 /* async operation timeout callback*/
       
   422 gboolean XAAdaptationBase_CancelAsyncWait(gpointer ctx)
       
   423 {
       
   424     XAAdaptationBaseCtx* bCtx = (XAAdaptationBaseCtx*)ctx;
       
   425     DEBUG_API("->XAAdaptationBase_CancelAsyncWait");
       
   426     if( bCtx->waitingasyncop )
       
   427     {
       
   428         DEBUG_ERR_A3("ASYNC TIMED OUT : current %d, gsttarget %d, wanted %d",
       
   429                       GST_STATE(bCtx->bin), GST_STATE_TARGET(bCtx->bin), bCtx->binWantedState);
       
   430         bCtx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   431         sem_post(&(bCtx->semAsyncWait));
       
   432     }
       
   433     DEBUG_API("<-XAAdaptationBase_CancelAsyncWait");
       
   434     /* return false to remove timer */
       
   435     return FALSE;
       
   436 }
       
   437 
       
   438 void XAAdaptationBase_CompleteAsyncWait(XAAdaptationBaseCtx* ctx)
       
   439 {
       
   440     DEBUG_API("->XAAdaptationBase_CompleteAsyncWait");
       
   441     if( ctx->waitingasyncop )
       
   442     {
       
   443         int i;
       
   444         ctx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   445         sem_getvalue(&(ctx->semAsyncWait),&i);
       
   446         DEBUG_INFO_A1("Asynch operation succeeded, sem value %d",i);
       
   447         if(i<=0)
       
   448         {   /* only post if locked */
       
   449             sem_post(&(ctx->semAsyncWait));
       
   450         }
       
   451         else if(i>0)
       
   452         {   /* should not be, reset semaphore */
       
   453             sem_init(&(ctx->semAsyncWait),0,0);
       
   454         }
       
   455     }
       
   456     DEBUG_API("<-XAAdaptationBase_CompleteAsyncWait");
       
   457 }
       
   458 
       
   459 XAresult XAAdaptationBase_SetCPConfiguration(XAAdaptationBaseCtx* ctx, XAConfigExtensionCpKey configValue)
       
   460 {
       
   461     XAresult res = XA_RESULT_SUCCESS;
       
   462 
       
   463     DEBUG_API("-> XAAdaptationBase_SetConfiguration");
       
   464     if( ctx )
       
   465     {
       
   466 		if ( configValue == XA_READ )
       
   467 		{
       
   468 			ctx->pipeSrcThrCtx.cpConfig = configValue;
       
   469 			res = XA_RESULT_SUCCESS;
       
   470 		}
       
   471 		else if ( configValue == XA_READBUFFER )
       
   472 		{
       
   473 		    ctx->pipeSrcThrCtx.cpConfig = configValue;
       
   474 			res = XA_RESULT_SUCCESS;
       
   475 		}
       
   476 		else if ( configValue == XA_WRITE )
       
   477         {
       
   478             ctx->pipeSinkThrCtx.cpConfig = configValue;
       
   479             res = XA_RESULT_SUCCESS;
       
   480         }
       
   481 		else if ( configValue == XA_WRITEBUFFER )
       
   482         {
       
   483             ctx->pipeSinkThrCtx.cpConfig = configValue;
       
   484             res = XA_RESULT_SUCCESS;
       
   485         }
       
   486     }
       
   487     else
       
   488     {
       
   489         res = XA_RESULT_PARAMETER_INVALID;
       
   490     }
       
   491     DEBUG_API("-> XAAdaptationBase_SetConfiguration");
       
   492     return res;
       
   493 }
       
   494 
       
   495 /**
       
   496  * GstElement* XAAdaptationBase_CreateGstSource( XADataSource* xaSrc, const XAchar *name )
       
   497  * @param XADataSource* xaSnk - XADataSource defining gst source to create
       
   498  * @param const XAchar *name - string for naming the gst element
       
   499  * @param XAboolean *isobj - (out param) is source another XA object?
       
   500  * @return GstElement* - return newly created gst source element
       
   501  * Description: Create gst source element corresponding to XA source structure
       
   502  */
       
   503 GstElement* XAAdaptationBase_CreateGstSource( XADataSource* xaSrc, const char *name, XAboolean *isobj, XAboolean *isPCM, XAboolean *isRawImage  )
       
   504 {
       
   505     XAuint32 locType = 0;
       
   506     GstElement* gstSrc = NULL;
       
   507     char* fname=NULL;
       
   508     XADataLocator_URI* uri = NULL;
       
   509     XADataLocator_IODevice* ioDevice = NULL;
       
   510     XACameraDeviceImpl* cameraDevice = NULL;
       
   511     XARadioDeviceImpl* radioDevice = NULL;
       
   512     XAObjectItfImpl* pObj = NULL;
       
   513 
       
   514     DEBUG_API("->XAAdaptationBase_CreateGstSource");
       
   515     if( !xaSrc || !xaSrc->pLocator || !isobj )
       
   516     {
       
   517         return NULL;
       
   518     }
       
   519     *isobj = XA_BOOLEAN_FALSE;
       
   520     if( xaSrc && xaSrc->pFormat && *((XAuint32*)(xaSrc->pFormat))==XA_DATAFORMAT_PCM && isPCM )
       
   521     {
       
   522         *isPCM = XA_BOOLEAN_TRUE;
       
   523     }
       
   524     if( xaSrc && xaSrc->pFormat && *((XAuint32*)(xaSrc->pFormat))==XA_DATAFORMAT_RAWIMAGE && isRawImage )
       
   525     {
       
   526         *isRawImage = XA_BOOLEAN_TRUE;
       
   527     }
       
   528     locType = *((XAuint32*)(xaSrc->pLocator));
       
   529     switch ( locType )
       
   530     {
       
   531         case XA_DATALOCATOR_URI:
       
   532             DEBUG_INFO("XA_DATALOCATOR_URI");
       
   533             uri = (XADataLocator_URI*)xaSrc->pLocator;
       
   534             gstSrc = gst_element_factory_make("filesrc",name);
       
   535             if ( uri->URI != NULL )
       
   536             {
       
   537                 DEBUG_INFO_A1("URI: %s", uri->URI);
       
   538                 if(strncmp((char *)uri->URI, "file://", 7) == 0)
       
   539                     {
       
   540                     fname = (char *)&((uri->URI)[7]);
       
   541                     }
       
   542                 else
       
   543                     {
       
   544                     fname = (char *)uri->URI;
       
   545                     }
       
   546                 DEBUG_INFO_A1("->filesystem path %s", fname);
       
   547                 g_object_set( G_OBJECT(gstSrc), "location", fname, NULL );
       
   548                 /*check for pcm - decodebin does not know how to handle raw PCM files */
       
   549                 if( isPCM && strstr(fname, ".pcm") )
       
   550                 {
       
   551                     DEBUG_INFO("PCM file detected");
       
   552                     *isPCM=XA_BOOLEAN_TRUE;
       
   553                 }
       
   554             }
       
   555             else
       
   556             {
       
   557                 DEBUG_ERR("No uri specified.");
       
   558                 return NULL;
       
   559             }
       
   560             break; /* XA_DATALOCATOR_URI */
       
   561 
       
   562 
       
   563         case XA_DATALOCATOR_IODEVICE:
       
   564             DEBUG_INFO("XA_DATALOCATOR_IODEVICE");
       
   565             ioDevice = (XADataLocator_IODevice*)(xaSrc->pLocator);
       
   566             switch ( ioDevice->deviceType )
       
   567             {
       
   568                 case XA_IODEVICE_AUDIOINPUT:
       
   569                 {
       
   570                     DEBUG_INFO("XA_IODEVICE_AUDIOINPUT");
       
   571                     DEBUG_INFO_A1("ioDevice->deviceID: %x", ioDevice->deviceID);
       
   572                     switch (ioDevice->deviceID )
       
   573                     {
       
   574                     //case XA_ADAPTID_ALSASRC: //Krishna
       
   575                     case XA_ADAPTID_DEVSOUNDSRC:
       
   576                         //DEBUG_INFO("alsasrc"); //Krishna
       
   577                         DEBUG_INFO("devsoundsrc");
       
   578                         gstSrc = gst_element_factory_make("devsoundsrc",name); //Krishna - changed to devsoundsrc
       
   579                         g_object_set (G_OBJECT (gstSrc), "num-buffers", 80, NULL);
       
   580                         break;
       
   581                     case XA_ADAPTID_AUDIOTESTSRC:
       
   582                         /*fall through*/
       
   583                     default:
       
   584                         DEBUG_INFO("audiotestsrc");
       
   585                         gstSrc = gst_element_factory_make("audiotestsrc",name);
       
   586                         break;
       
   587                     }
       
   588                     break;
       
   589                 }
       
   590                 case XA_IODEVICE_CAMERA:
       
   591                 {
       
   592                     DEBUG_INFO("XA_IODEVICE_CAMERA");
       
   593                     if ( ioDevice->device )
       
   594                     {   /*source is camera object*/
       
   595                         DEBUG_INFO("Use camerabin as source.");
       
   596                         /* Get camerabin from source object */
       
   597                         pObj = (XAObjectItfImpl*)(*ioDevice->device);
       
   598                         cameraDevice = (XACameraDeviceImpl*)(pObj);
       
   599                         gstSrc = GST_ELEMENT(cameraDevice->adaptationCtx->bin);
       
   600                         /* refcount increase is needed to keep this not being deleted after use */
       
   601                         gst_object_ref(GST_OBJECT(gstSrc));
       
   602                         *isobj = XA_BOOLEAN_TRUE;
       
   603                     }
       
   604                     else
       
   605                     {
       
   606                         DEBUG_INFO_A1("ioDevice->deviceID: %x", ioDevice->deviceID);
       
   607                         switch (ioDevice->deviceID )
       
   608                         {
       
   609                         case XA_ADAPTID_V4L2SRC:
       
   610                             DEBUG_INFO("Camera deviceID: v4l2src ");
       
   611  
       
   612                             break;
       
   613                         case XA_ADAPTID_VIDEOTESTSRC:
       
   614                             DEBUG_INFO("Camera deviceID: videotestsrc");
       
   615  
       
   616                             break;
       
   617                         default:
       
   618                         case XA_DEFAULTDEVICEID_CAMERA:
       
   619                             DEBUG_INFO("Camera deviceID:Default");
       
   620                            
       
   621                             break;
       
   622                         }
       
   623                         if ( cameraCtx )
       
   624 						{
       
   625 							gstSrc = GST_ELEMENT(cameraCtx->baseObj.bin);
       
   626 							gst_object_ref(GST_OBJECT(gstSrc));
       
   627 							*isobj = XA_BOOLEAN_TRUE;
       
   628 						}
       
   629 						else
       
   630 						{
       
   631 							DEBUG_ERR("No camera object created!");
       
   632 							return NULL;
       
   633 						}
       
   634                     }
       
   635                     break;
       
   636                 }
       
   637                 case XA_IODEVICE_RADIO:
       
   638                     DEBUG_INFO("XA_IODEVICE_RADIO");
       
   639                     if ( ioDevice->device )
       
   640                     {
       
   641                         DEBUG_INFO("Use radio pipeline as source.");
       
   642                         /* Get radio_pipeline and set it to base context */
       
   643                         radioDevice = (XARadioDeviceImpl*)(*ioDevice->device);
       
   644                         /* radio does not have actual bin, only source element*/
       
   645                         gstSrc = GST_ELEMENT(radioDevice->adaptationCtx->bin);
       
   646                         /* refcount increase is needed to keep this not being deleted after use */
       
   647                         gst_object_ref(GST_OBJECT(gstSrc));
       
   648                         /**isobj = XA_BOOLEAN_TRUE;*/
       
   649                     }
       
   650                     break;
       
   651                 default:
       
   652                 {
       
   653                     DEBUG_ERR("Unsupported IODevice.");
       
   654                     return NULL;
       
   655                     break;
       
   656                 }
       
   657             }
       
   658             break; /* XA_DATALOCATOR_IODEVICE */
       
   659 
       
   660         case XA_DATALOCATOR_CONTENTPIPE:
       
   661         {
       
   662         	DEBUG_INFO("XA_DATALOCATOR_CONTENTPIPE");
       
   663         	gstSrc = gst_element_factory_make("appsrc",name);
       
   664             break;
       
   665         }
       
   666         case XA_DATALOCATOR_ADDRESS:
       
   667             {
       
   668                 XADataLocator_Address* address = (XADataLocator_Address*)(xaSrc->pLocator);
       
   669                 gstSrc = gst_element_factory_make("appsrc", name);
       
   670                 /* init gst buffer from datalocator */
       
   671                 if( gstSrc )
       
   672                 {
       
   673                     /* init GST buffer from XADataLocator*/
       
   674                     GstBuffer* userBuf = gst_buffer_new();
       
   675                     if( userBuf )
       
   676                     {
       
   677                         userBuf->size = address->length;
       
   678                         userBuf->data = address->pAddress;
       
   679                         /* push the whole buffer to appsrc so it is ready for preroll */
       
   680                         DEBUG_INFO("Pushing buffer");
       
   681                         gst_app_src_push_buffer( GST_APP_SRC(gstSrc), userBuf );
       
   682                         DEBUG_INFO_A1("Sent buffer at 0x%x to appsrc", userBuf );
       
   683                         gst_app_src_end_of_stream( GST_APP_SRC(gstSrc) );
       
   684                     }
       
   685                     else
       
   686                     {
       
   687                         DEBUG_ERR("Failure allocating buffer!");
       
   688                     }
       
   689                 }
       
   690                 else
       
   691                 {
       
   692                     DEBUG_ERR("Failure creating appsrc!");
       
   693                 }
       
   694             }
       
   695             break;
       
   696 
       
   697         default:
       
   698             DEBUG_ERR("Incorrect data locator for source.")
       
   699             return NULL;
       
   700             break;
       
   701     }
       
   702 
       
   703     if ( gstSrc )
       
   704     {
       
   705         DEBUG_INFO_A1("Created gstreamer source element at %x", gstSrc);
       
   706     }
       
   707 
       
   708     DEBUG_API("<-XAAdaptationBase_CreateGstSource");
       
   709     return gstSrc;
       
   710 }
       
   711 
       
   712 
       
   713 /**
       
   714  * GstElement* XAAdaptationBase_CreateGstSink( XADataSink* xaSnk, const XAchar *name )
       
   715  * @param XADataSink* xaSnk - XADataSink defining gst sink to create
       
   716  * @param const XAchar *name - string for naming the gst element
       
   717  * @return GstElement* - return newly created gst sink element
       
   718  * Description: Create gst sink element corresponding to XA sink structure
       
   719  */
       
   720 GstElement* XAAdaptationBase_CreateGstSink( XADataSink* xaSnk, const char *name, XAboolean *isobj )
       
   721 {
       
   722     XAuint32 locType = 0;
       
   723     GstElement* gstSnk = NULL;
       
   724     XADataLocator_URI* uri = NULL;
       
   725     DEBUG_API("->XAAdaptationBase_CreateGstSink");
       
   726     if(!xaSnk || !xaSnk->pLocator)
       
   727     {
       
   728         DEBUG_INFO("Warning! No sink specified, use fakesink");
       
   729         gstSnk = gst_element_factory_make("fakesink",name);
       
   730         if(!gstSnk)
       
   731         {
       
   732             DEBUG_ERR("Cannot create sink!");
       
   733             return NULL;
       
   734         }
       
   735         g_object_set( G_OBJECT(gstSnk),"async", FALSE, NULL);
       
   736     }
       
   737     else
       
   738     {
       
   739         locType = *((XAuint32*)(xaSnk->pLocator));
       
   740         switch ( locType )
       
   741         {
       
   742             case XA_DATALOCATOR_URI:
       
   743                 DEBUG_INFO("XA_DATALOCATOR_URI");
       
   744                 uri = (XADataLocator_URI*)xaSnk->pLocator;
       
   745                 gstSnk = gst_element_factory_make("filesink",name);
       
   746                 if(!gstSnk)
       
   747                 {
       
   748                     DEBUG_ERR("Cannot create sink!");
       
   749                     return NULL;
       
   750                 }
       
   751                 if ( uri->URI != NULL )
       
   752                 {
       
   753                     XAchar *fname;
       
   754                     DEBUG_INFO_A1("URI: %s", uri->URI);
       
   755                     if(strncmp((char *)uri->URI, "file://", 7) == 0)
       
   756                     {
       
   757                         fname = &((uri->URI)[7]);
       
   758                     }
       
   759                     else
       
   760                     {
       
   761                         fname = uri->URI;
       
   762                     }
       
   763                     DEBUG_INFO_A1("->filesystem path %s", fname);
       
   764                     g_object_set( G_OBJECT(gstSnk),"location", fname,
       
   765                                                    "async", FALSE,
       
   766                                                    "qos", FALSE,
       
   767                                                    "max-lateness", (gint64)(-1),
       
   768                                                    NULL);
       
   769                 }
       
   770                 else
       
   771                 {
       
   772                     DEBUG_ERR("No recording output uri specified.");
       
   773                     return NULL;
       
   774                 }
       
   775                 break;
       
   776             case XA_DATALOCATOR_NATIVEDISPLAY:
       
   777                 DEBUG_INFO("Sink locator type - XA_DATALOCATOR_NATIVEDISPLAY");
       
   778 #ifdef USE_NGA_SURFACES
       
   779                 gstSnk = gst_element_factory_make("devvideosink","devvideosink");
       
   780 #else
       
   781                 gstSnk = gst_element_factory_make("ximagesink",name);
       
   782 #endif /*USE_NGA_SURFACES*/
       
   783                 if(!gstSnk)
       
   784                 {
       
   785                     DEBUG_ERR("Cannot create sink!");
       
   786                     return NULL;
       
   787                 }
       
   788                 g_object_set( G_OBJECT(gstSnk), "force-aspect-ratio", TRUE,
       
   789 												"async", FALSE,
       
   790                                                "qos", FALSE,
       
   791 												"handle-events", TRUE,
       
   792 												"handle-expose", TRUE,
       
   793                                                "max-lateness", (gint64)(-1),
       
   794                                                NULL);
       
   795                 break;
       
   796             case XA_DATALOCATOR_OUTPUTMIX:
       
   797                 DEBUG_INFO("Sink locator type - XA_DATALOCATOR_OUTPUTMIX");
       
   798                 {
       
   799                     /* Get OutputMix adaptation from data locator */
       
   800                     XADataLocator_OutputMix* omix = (XADataLocator_OutputMix*)(xaSnk->pLocator);
       
   801                     if ( omix->outputMix )
       
   802                     {
       
   803                         XAOMixImpl* omixDevice = (XAOMixImpl*)(*omix->outputMix);
       
   804 
       
   805                         if(omixDevice)
       
   806                         {
       
   807                             gstSnk = XAOutputMixAdapt_GetSink(omixDevice->adaptationCtx);
       
   808                             if(!gstSnk)
       
   809                             {
       
   810                                 DEBUG_ERR("Cannot create sink!");
       
   811                                 return NULL;
       
   812                             }
       
   813                             *isobj = XA_BOOLEAN_TRUE;
       
   814                         }
       
   815                         else
       
   816                         {
       
   817                             DEBUG_ERR("Warning - NULL outputmix object - default audio output used");
       
   818                             gstSnk = gst_element_factory_make("alsasink",name);
       
   819                         }
       
   820                     }
       
   821                     else
       
   822                     {
       
   823                         DEBUG_ERR("Warning - NULL outputmix object - default audio output used");
       
   824                         gstSnk = gst_element_factory_make("alsasink",name);
       
   825                     }
       
   826 
       
   827                 }
       
   828                 break;
       
   829 		 	case XA_DATALOCATOR_CONTENTPIPE:
       
   830 				DEBUG_INFO("XA_DATALOCATOR_CONTENTPIPE");
       
   831 				gstSnk = gst_element_factory_make("appsink",name);
       
   832 				break;
       
   833             case XA_DATALOCATOR_ADDRESS:
       
   834                 {
       
   835                     gstSnk = gst_element_factory_make("appsink", name);
       
   836                     /* Not actually object sink, but attribute used to notify recorder
       
   837                      * about appsink (no object sinks applicable in this use case)
       
   838                      **/
       
   839                     *isobj=TRUE;
       
   840                 }
       
   841                 break;
       
   842             case XA_DATALOCATOR_IODEVICE:
       
   843                 /* when only valid IOdevice sinks vibra and LED sinks implemented
       
   844                  * at adaptation level, add handling here (in this implementation,
       
   845                  * no handling needed as only dummy implementations for those)
       
   846                  **/
       
   847             default:
       
   848                 DEBUG_ERR("Incorrect data locator for sink.")
       
   849                 return NULL;
       
   850                 break;
       
   851         }
       
   852     }
       
   853     if (gstSnk )
       
   854     {
       
   855         DEBUG_INFO_A1("Created gstreamer sink element at %x", gstSnk);
       
   856     }
       
   857     DEBUG_API("<-XAAdaptationBase_CreateGstSink");
       
   858     return gstSnk;
       
   859 }
       
   860 
       
   861 /**
       
   862  * GstElement* XAAdaptationBase_CreateVideoPP( )
       
   863  * @return GstElement* - return newly created gst pipeline element
       
   864  * Description: Create video processing pipeline
       
   865  */
       
   866 GstElement* XAAdaptationBase_CreateVideoPP( )
       
   867 {
       
   868     GstElement *vpp;
       
   869     DEBUG_API("->XAAdaptationBase_CreateVideoPP");
       
   870     vpp = gst_pipeline_new("videopp");
       
   871     if( vpp )
       
   872     {
       
   873         GstPad *ghostsink, *ghostsrc;
       
   874         GstElement 	*col1,
       
   875 					*col2,
       
   876 					*rotate,
       
   877 					*mirror,
       
   878 					*box,
       
   879 					*crop,
       
   880 					*gamma,
       
   881 					*balance,
       
   882 					*scale,
       
   883 					*scale2,
       
   884 #ifdef USE_NGA_SURFACES
       
   885 					*identity,
       
   886 #endif /*USE_NGA_SURFACES*/
       
   887 					*queue;
       
   888 
       
   889 
       
   890         /* Crete ffmpegcolorspace to convert stream to correct format */
       
   891         col1 = gst_element_factory_make( "ffmpegcolorspace", "pp_colsp1");
       
   892         if(col1)
       
   893         {
       
   894             DEBUG_INFO("Created ffmpegcolorspace element");
       
   895             gst_bin_add(GST_BIN(vpp), col1);
       
   896            /* make this bin link point*/
       
   897             ghostsink = gst_element_get_static_pad(col1,"sink");
       
   898             if(ghostsink)
       
   899             {
       
   900                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_sink",ghostsink));
       
   901                 gst_object_unref(GST_OBJECT(ghostsink));
       
   902             }
       
   903         }
       
   904 
       
   905         /* create video crop, this will be sink for videoPP pipeline */
       
   906         crop = gst_element_factory_make( "videocrop", "pp_crop");
       
   907         if(crop)
       
   908         {
       
   909             DEBUG_INFO("Created crop element");
       
   910             gst_bin_add(GST_BIN(vpp), crop);
       
   911         }
       
   912 
       
   913         /* create video rotate */
       
   914         rotate = gst_element_factory_make( "videoflip", "pp_rotate");
       
   915         if(rotate)
       
   916         {
       
   917             DEBUG_INFO("Created rotate element");
       
   918             g_object_set(G_OBJECT(rotate), "method", FLIP_NONE, NULL);
       
   919             gst_bin_add(GST_BIN(vpp), rotate);
       
   920         }
       
   921 
       
   922         /* create video mirror */
       
   923         mirror = gst_element_factory_make( "videoflip", "pp_mirror");
       
   924         if(mirror)
       
   925         {
       
   926             DEBUG_INFO("Created mirror element");
       
   927             g_object_set(G_OBJECT(mirror), "method", FLIP_NONE, NULL);
       
   928             gst_bin_add(GST_BIN(vpp), mirror);
       
   929         }
       
   930 
       
   931         /* create video box */
       
   932         box = gst_element_factory_make( "videobox", "pp_box");
       
   933         if(box)
       
   934         {
       
   935             DEBUG_INFO("Created videobox element");
       
   936             gst_bin_add(GST_BIN(vpp), box);
       
   937         }
       
   938 
       
   939         /* create video balance */
       
   940         balance = gst_element_factory_make( "videobalance", "pp_balance");
       
   941         if(balance)
       
   942         {
       
   943             DEBUG_INFO("Created balance element");
       
   944             gst_bin_add(GST_BIN(vpp), balance);
       
   945         }
       
   946 
       
   947         /* create video gamma */
       
   948         gamma = gst_element_factory_make( "gamma", "pp_gamma");
       
   949         if(gamma)
       
   950         {
       
   951             DEBUG_INFO("Created gamma element");
       
   952             gst_bin_add(GST_BIN(vpp), gamma);
       
   953         }
       
   954 
       
   955         /* Create videoscale element to scale postprocessed output to correct size */
       
   956         scale = gst_element_factory_make("videoscale", "pp_scale");
       
   957         if ( scale )
       
   958         {
       
   959             DEBUG_INFO("Created videoscale element");
       
   960             gst_bin_add(GST_BIN(vpp), scale);
       
   961         }
       
   962         scale2 = gst_element_factory_make("videoscale", "pp_scale2");
       
   963 		if ( scale2 )
       
   964 		{
       
   965 			GstPad *pad = NULL;
       
   966 			GstCaps *caps = NULL;
       
   967 			DEBUG_INFO("Created videoscale element");
       
   968 			pad = gst_element_get_static_pad(scale2,"src");
       
   969 			caps = gst_caps_new_simple("video/x-raw-yuv",
       
   970 					 "width", G_TYPE_INT,0,
       
   971 					 "height", G_TYPE_INT,0,
       
   972 					 NULL);
       
   973 			gst_pad_set_caps(pad, caps);
       
   974 			gst_bin_add(GST_BIN(vpp), scale2);
       
   975 		}
       
   976 
       
   977         /* create video queue */
       
   978         queue = gst_element_factory_make( "queue", "vpp_queue");
       
   979         if(queue)
       
   980         {
       
   981             DEBUG_INFO("Created queue element");
       
   982             gst_bin_add(GST_BIN(vpp), queue);
       
   983 #ifdef USE_NGA_SURFACES
       
   984             /* make this bin link point*/
       
   985             ghostsink = gst_element_get_static_pad(queue,"sink");
       
   986             if(ghostsink)
       
   987             {
       
   988                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_src",ghostsink));
       
   989                 gst_object_unref(GST_OBJECT(ghostsink));
       
   990             }            
       
   991 #endif /*USE_NGA_SURFACES*/
       
   992         }
       
   993 
       
   994 
       
   995         /* Crete ffmpegcolorspace to convert stream to correct format */
       
   996         col2 = gst_element_factory_make( "ffmpegcolorspace", "pp_colsp2");
       
   997         if(col2)
       
   998         {
       
   999             DEBUG_INFO("Created ffmpegcolorspace element");
       
  1000             gst_bin_add(GST_BIN(vpp), col2);
       
  1001             /* make this bin link point*/
       
  1002             ghostsrc = gst_element_get_static_pad(col2,"src");
       
  1003             if(ghostsrc)
       
  1004             {
       
  1005                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_src",ghostsrc));
       
  1006                 gst_object_unref(GST_OBJECT(ghostsrc));
       
  1007             }
       
  1008         }
       
  1009 
       
  1010 #ifdef USE_NGA_SURFACES
       
  1011         //shyward
       
  1012         /* create identity element */
       
  1013         identity  = gst_element_factory_make( "identity", "identity" );
       
  1014         if(identity)
       
  1015         {
       
  1016            DEBUG_INFO("Created identity element");
       
  1017            gst_bin_add(GST_BIN(vpp), identity);   
       
  1018            /* make this bin link point*/
       
  1019            ghostsrc = gst_element_get_static_pad(identity,"src");
       
  1020            if(ghostsrc)
       
  1021            {
       
  1022                gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_sink",ghostsrc));
       
  1023                gst_object_unref(GST_OBJECT(ghostsrc));
       
  1024            }                
       
  1025         }        
       
  1026         if( !(gst_element_link_many(queue,identity,NULL)) )
       
  1027 #else
       
  1028         //shyward - thins code assumes all the elements will have been created, which is not true
       
  1029         if( !(gst_element_link_many(col1,
       
  1030 									scale,
       
  1031 									crop,
       
  1032 									rotate,
       
  1033 									mirror,
       
  1034 									box,
       
  1035 									balance,
       
  1036 									gamma,
       
  1037 									queue,
       
  1038 									scale2,
       
  1039 #ifdef USE_NGA_SURFACES
       
  1040                 					identity,
       
  1041 #endif /*USE_NGA_SURFACES*/
       
  1042 									col2,
       
  1043 									NULL)
       
  1044 									) )
       
  1045 #endif /*USE_NGA_SURFACES*/
       
  1046         {
       
  1047             DEBUG_ERR("Could not link videopp elements!!");
       
  1048             gst_object_unref(vpp);
       
  1049             vpp = NULL;
       
  1050         }
       
  1051     }
       
  1052     DEBUG_API("<-XAAdaptationBase_CreateVideoPP");
       
  1053     return vpp;
       
  1054 }
       
  1055 
       
  1056 /**
       
  1057  * GstElement* XAAdaptationBase_CreateFixedSizeRecordVideoPP( )
       
  1058  * @return GstElement* - return newly created gst pipeline element
       
  1059  * Description: Create video processing pipeline with fixed output size to TEST_VIDEO_WIDTH x TEST_VIDEO_HEIGHT
       
  1060  *              experimental implementation for changing recorder output size
       
  1061  */
       
  1062 GstElement* XAAdaptationBase_CreateFixedSizeVideoPP( )
       
  1063 {
       
  1064     GstElement *vpp;
       
  1065     DEBUG_API("->XAAdaptationBase_CreateFixedSizeVideoPP");
       
  1066     vpp = gst_pipeline_new("videopp");
       
  1067     if( vpp )
       
  1068     {
       
  1069         GstPad *ghostsink, *ghostsrc;
       
  1070         GstElement  *col1,
       
  1071                     *col2,
       
  1072                     *rotate,
       
  1073                     *mirror,
       
  1074                     *box,
       
  1075                     *crop,
       
  1076                     *gamma,
       
  1077                     *balance,
       
  1078                     *scale,
       
  1079                     *scale2,
       
  1080                     *filter,
       
  1081                     *queue;
       
  1082 
       
  1083 
       
  1084         /* Crete ffmpegcolorspace to convert stream to correct format */
       
  1085         col1 = gst_element_factory_make( "ffmpegcolorspace", "pp_colsp1");
       
  1086         if(col1)
       
  1087         {
       
  1088             DEBUG_INFO("Created ffmpegcolorspace element");
       
  1089             gst_bin_add(GST_BIN(vpp), col1);
       
  1090            /* make this bin link point*/
       
  1091             ghostsink = gst_element_get_static_pad(col1,"sink");
       
  1092             if(ghostsink)
       
  1093             {
       
  1094                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_sink",ghostsink));
       
  1095                 gst_object_unref(GST_OBJECT(ghostsink));
       
  1096             }
       
  1097         }
       
  1098 
       
  1099         /* create video crop, this will be sink for videoPP pipeline */
       
  1100         crop = gst_element_factory_make( "videocrop", "pp_crop");
       
  1101         if(crop)
       
  1102         {
       
  1103             DEBUG_INFO("Created crop element");
       
  1104             gst_bin_add(GST_BIN(vpp), crop);
       
  1105         }
       
  1106 
       
  1107         /* create video rotate */
       
  1108         rotate = gst_element_factory_make( "videoflip", "pp_rotate");
       
  1109         if(rotate)
       
  1110         {
       
  1111             DEBUG_INFO("Created rotate element");
       
  1112             g_object_set(G_OBJECT(rotate), "method", FLIP_NONE, NULL);
       
  1113             gst_bin_add(GST_BIN(vpp), rotate);
       
  1114         }
       
  1115 
       
  1116         /* create video mirror */
       
  1117         mirror = gst_element_factory_make( "videoflip", "pp_mirror");
       
  1118         if(mirror)
       
  1119         {
       
  1120             DEBUG_INFO("Created mirror element");
       
  1121             g_object_set(G_OBJECT(mirror), "method", FLIP_NONE, NULL);
       
  1122             gst_bin_add(GST_BIN(vpp), mirror);
       
  1123         }
       
  1124 
       
  1125         /* create video box */
       
  1126         box = gst_element_factory_make( "videobox", "pp_box");
       
  1127         if(box)
       
  1128         {
       
  1129             DEBUG_INFO("Created videobox element");
       
  1130             gst_bin_add(GST_BIN(vpp), box);
       
  1131         }
       
  1132 
       
  1133         /* create video balance */
       
  1134         balance = gst_element_factory_make( "videobalance", "pp_balance");
       
  1135         if(balance)
       
  1136         {
       
  1137             DEBUG_INFO("Created balance element");
       
  1138             gst_bin_add(GST_BIN(vpp), balance);
       
  1139         }
       
  1140 
       
  1141         /* create video gamma */
       
  1142         gamma = gst_element_factory_make( "gamma", "pp_gamma");
       
  1143         if(gamma)
       
  1144         {
       
  1145             DEBUG_INFO("Created gamma element");
       
  1146             gst_bin_add(GST_BIN(vpp), gamma);
       
  1147         }
       
  1148 
       
  1149         /* Create videoscale element to scale postprocessed output to correct size */
       
  1150         scale = gst_element_factory_make("videoscale", "pp_scale");
       
  1151         if ( scale )
       
  1152         {
       
  1153             DEBUG_INFO("Created videoscale element");
       
  1154             gst_bin_add(GST_BIN(vpp), scale);
       
  1155         }
       
  1156         scale2 = gst_element_factory_make("videoscale", "pp_scale2");
       
  1157         if ( scale2 )
       
  1158         {
       
  1159             GstPad *pad = NULL;
       
  1160             GstCaps *caps = NULL;
       
  1161             DEBUG_INFO("Created videoscale element");
       
  1162             pad = gst_element_get_static_pad(scale2,"src");
       
  1163             caps = gst_caps_new_simple("video/x-raw-yuv",
       
  1164                      "width", G_TYPE_INT,0,
       
  1165                      "height", G_TYPE_INT,0,
       
  1166                      NULL);
       
  1167             gst_pad_set_caps(pad, caps);
       
  1168             gst_bin_add(GST_BIN(vpp), scale2);
       
  1169         }
       
  1170 
       
  1171         /* create capsfilter for fixed video size */
       
  1172         filter = gst_element_factory_make("capsfilter", "pp_filter");
       
  1173         if ( filter )
       
  1174         {
       
  1175 
       
  1176             g_object_set( G_OBJECT(filter), "caps",
       
  1177                             gst_caps_new_simple("video/x-raw-yuv",
       
  1178                                                 "width", G_TYPE_INT, TEST_VIDEO_WIDTH,
       
  1179                                                 "height", G_TYPE_INT, TEST_VIDEO_HEIGHT, NULL)
       
  1180                                                 ,NULL );
       
  1181             gst_bin_add(GST_BIN(vpp), filter);
       
  1182         }
       
  1183 
       
  1184         /* create video queue */
       
  1185         queue = gst_element_factory_make( "queue", "vpp_queue");
       
  1186         if(queue)
       
  1187         {
       
  1188             gst_bin_add(GST_BIN(vpp), queue);
       
  1189         }
       
  1190 
       
  1191 
       
  1192         /* Crete ffmpegcolorspace to convert stream to correct format */
       
  1193         col2 = gst_element_factory_make( "ffmpegcolorspace", "pp_colsp2");
       
  1194         if(col2)
       
  1195         {
       
  1196             DEBUG_INFO("Created ffmpegcolorspace element");
       
  1197             gst_bin_add(GST_BIN(vpp), col2);
       
  1198             /* make this bin link point*/
       
  1199             ghostsrc = gst_element_get_static_pad(col2,"src");
       
  1200             if(ghostsrc)
       
  1201             {
       
  1202                 gst_element_add_pad(vpp, gst_ghost_pad_new("videopp_src",ghostsrc));
       
  1203                 gst_object_unref(GST_OBJECT(ghostsrc));
       
  1204             }
       
  1205         }
       
  1206         if( !(gst_element_link_many(col1,
       
  1207                                     scale,
       
  1208                                     crop,
       
  1209                                     rotate,
       
  1210                                     mirror,
       
  1211                                     box,
       
  1212                                     balance,
       
  1213                                     gamma,
       
  1214                                     queue,
       
  1215                                     scale2,
       
  1216                                     filter,
       
  1217                                     col2,
       
  1218                                     NULL)
       
  1219                                     ) )
       
  1220         {
       
  1221             DEBUG_ERR("Could not link videopp elements!!");
       
  1222             gst_object_unref(vpp);
       
  1223             vpp = NULL;
       
  1224         }
       
  1225     }
       
  1226     DEBUG_API("<-XAAdaptationBase_CreateFixedSizeVideoPP");
       
  1227     return vpp;
       
  1228 }
       
  1229 
       
  1230 
       
  1231 
       
  1232 /**
       
  1233  * GstElement* XAAdaptationBase_CreateVideoPPBlackScr( )
       
  1234  * @return GstElement* - return newly created gst pipeline element
       
  1235  * Description: Create video processing pipeline for black screen
       
  1236  */
       
  1237 GstElement* XAAdaptationBase_CreateVideoPPBlackScr( )
       
  1238 {
       
  1239     GstElement *vppBScr;
       
  1240     DEBUG_API("->XAAdaptationBase_CreateVideoPPBlackScr");
       
  1241     vppBScr = gst_pipeline_new("videoppBScr");
       
  1242     if( vppBScr )
       
  1243     {
       
  1244         GstPad *ghostsrc=NULL;
       
  1245         GstElement *testVideo=NULL, *scale=NULL;
       
  1246         GstElement *ffmpegcolorspace=NULL;
       
  1247 
       
  1248         testVideo = gst_element_factory_make( "videotestsrc", "videotest");
       
  1249         if(testVideo)
       
  1250         {
       
  1251             DEBUG_INFO("Created videotestsrc element");
       
  1252 
       
  1253             g_object_set(G_OBJECT(testVideo), "pattern", (gint)2, "num-buffers", (gint)1, NULL);
       
  1254             gst_bin_add(GST_BIN(vppBScr), testVideo);
       
  1255         }
       
  1256 
       
  1257         scale = gst_element_factory_make("videoscale", "BSrc_scale");
       
  1258         if(scale)
       
  1259         {
       
  1260             DEBUG_INFO("Created videoscale element");
       
  1261             gst_bin_add(GST_BIN(vppBScr), scale);
       
  1262             /* make this bin link point*/
       
  1263             ghostsrc = gst_element_get_static_pad(scale,"src");
       
  1264             if(ghostsrc)
       
  1265             {
       
  1266                 gst_element_add_pad(vppBScr, gst_ghost_pad_new("videoppBSrc_src",ghostsrc));
       
  1267                 gst_object_unref(GST_OBJECT(ghostsrc));
       
  1268             }
       
  1269         }
       
  1270         ffmpegcolorspace = gst_element_factory_make("ffmpegcolorspace", "BlackScrFfmpeg");
       
  1271         gst_bin_add(GST_BIN(vppBScr), ffmpegcolorspace);
       
  1272         if( !(gst_element_link_many(testVideo, ffmpegcolorspace, scale, NULL)) )
       
  1273         {
       
  1274             DEBUG_ERR("Could not link videoppBSrc elements!!");
       
  1275             gst_object_unref(vppBScr);
       
  1276             vppBScr = NULL;
       
  1277         }
       
  1278     }
       
  1279     DEBUG_API("<-XAAdaptationBase_CreateVideoPPBlackScr");
       
  1280     return vppBScr;
       
  1281 }
       
  1282 
       
  1283 /**
       
  1284  * GstElement* XAAdaptationBase_CreateInputSelector( )
       
  1285  * @return GstElement* - return newly created input selector
       
  1286  * Description: Create input selector to processing between black screen and video screen
       
  1287  */
       
  1288 GstElement* XAAdaptationBase_CreateInputSelector( )
       
  1289 {
       
  1290     GstElement *inputSelector;
       
  1291     DEBUG_API("->XAAdaptationBase_CreateInputSelector");
       
  1292     inputSelector = gst_element_factory_make("input-selector", "input-selector");
       
  1293     if( inputSelector )
       
  1294     {
       
  1295         g_object_set(G_OBJECT(inputSelector), "select-all", TRUE, NULL);
       
  1296     }
       
  1297     DEBUG_API("<-XAAdaptationBase_CreateInputSelector");
       
  1298     return inputSelector;
       
  1299 }
       
  1300 
       
  1301 /**
       
  1302  * GstElement* XAAdaptationBase_CreateAudioPP( )
       
  1303  * @return GstElement* - return newly created gst pipeline element
       
  1304  * Description: Create video processing pipeline
       
  1305  */
       
  1306 GstElement* XAAdaptationBase_CreateAudioPP( )
       
  1307 {
       
  1308     GstElement *app;
       
  1309     gboolean ok = TRUE;
       
  1310     DEBUG_API("->XAAdaptationBase_CreateAudioPP");
       
  1311     app = gst_pipeline_new("audiopp");
       
  1312     if( app )
       
  1313     {
       
  1314         GstPad *ghostsink, *ghostsrc;
       
  1315         GstElement *ac,*vol,*eq,*queue,*pan, *ac2;
       
  1316 
       
  1317         /* first and last elements should be audioconverts to match sink and encoder formats */
       
  1318         ac = gst_element_factory_make( "audioconvert", "pp_ac");
       
  1319         if (ac)
       
  1320         {
       
  1321             ok = gst_bin_add(GST_BIN(app), ac);
       
  1322             /* make this bin link point*/
       
  1323             if (ok)
       
  1324             {
       
  1325                 ghostsink = gst_element_get_static_pad(ac,"sink");
       
  1326                 ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1327                 gst_object_unref(GST_OBJECT(ghostsink));
       
  1328             }
       
  1329         }
       
  1330         ac2 = gst_element_factory_make( "audioconvert", "pp_ac2");
       
  1331         if (ac2 && ok)
       
  1332         {
       
  1333             ok = gst_bin_add(GST_BIN(app), ac2);
       
  1334             /* make this bin link point*/
       
  1335             if (ok)
       
  1336             {
       
  1337                 ghostsrc = gst_element_get_static_pad(ac2,"src");
       
  1338                 ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1339                 gst_object_unref(GST_OBJECT(ghostsrc));
       
  1340             }
       
  1341         }
       
  1342 
       
  1343         vol = gst_element_factory_make( "volume", "pp_vol");
       
  1344         /* create volume controller */
       
  1345         if (vol && ok)
       
  1346         {
       
  1347             ok = gst_bin_add(GST_BIN(app), vol);
       
  1348             g_object_set( G_OBJECT(vol), "volume", (gdouble)1, NULL );
       
  1349         }
       
  1350         /* create 10-band equalizer */
       
  1351         eq = gst_element_factory_make( "equalizer-10bands", "pp_equ");
       
  1352         if (eq && ok)
       
  1353         {
       
  1354             ok = gst_bin_add(GST_BIN(app), eq);
       
  1355         }
       
  1356         /* create audio queue */
       
  1357         queue = gst_element_factory_make( "queue", "app_queue");
       
  1358         if(queue && ok)
       
  1359         {
       
  1360             ok = gst_bin_add(GST_BIN(app), queue);
       
  1361             g_object_set (G_OBJECT (queue), "max-size-buffers", 2, NULL);
       
  1362         }
       
  1363         /* create audio pan effect */
       
  1364         pan = gst_element_factory_make( "audiopanorama", "pp_pan");
       
  1365         if (pan && ok)
       
  1366         {
       
  1367             ok = gst_bin_add(GST_BIN(app), pan);
       
  1368         }
       
  1369 
       
  1370         if (ac && ok)
       
  1371         {
       
  1372             if (queue)
       
  1373             {
       
  1374                 ok = gst_element_link(ac, queue);
       
  1375             }
       
  1376             else if (vol)
       
  1377             {
       
  1378                 ok = gst_element_link(ac, vol);
       
  1379             }
       
  1380             else if (pan)
       
  1381             {
       
  1382                 ok = gst_element_link(ac, pan);
       
  1383             }
       
  1384             else if (eq)
       
  1385             {
       
  1386                 ok = gst_element_link(ac, eq);
       
  1387             }
       
  1388             else if (ac2)
       
  1389             {
       
  1390                 ok = gst_element_link(ac, ac2);
       
  1391             }
       
  1392         }
       
  1393         if (queue && ok)
       
  1394         {
       
  1395             if (vol)
       
  1396             {
       
  1397                 ok = gst_element_link(queue, vol);
       
  1398             }
       
  1399             else if (pan)
       
  1400             {
       
  1401                 ok = gst_element_link(queue, pan);
       
  1402             }
       
  1403             else if (eq)
       
  1404             {
       
  1405                 ok = gst_element_link(queue, eq);
       
  1406             }
       
  1407             else if (ac2)
       
  1408             {
       
  1409                 ok = gst_element_link(queue, ac2);
       
  1410             }
       
  1411         }
       
  1412         if (vol && ok)
       
  1413         {
       
  1414             if (pan)
       
  1415             {
       
  1416                 ok = gst_element_link(vol, pan);
       
  1417             }
       
  1418             else if (eq)
       
  1419             {
       
  1420                 ok = gst_element_link(vol, eq);
       
  1421             }
       
  1422             else if (ac2)
       
  1423             {
       
  1424                 ok = gst_element_link(vol, ac2);
       
  1425             }
       
  1426         }
       
  1427         if (pan && ok)
       
  1428         {
       
  1429             if (eq)
       
  1430             {
       
  1431                 ok = gst_element_link(pan, eq);
       
  1432             }
       
  1433             else if (ac2)
       
  1434             {
       
  1435                 ok = gst_element_link(pan, ac2);
       
  1436             }
       
  1437         }
       
  1438         if (eq && ok)
       
  1439         {
       
  1440             if (ac2)
       
  1441             {
       
  1442                 ok = gst_element_link(eq, ac2);
       
  1443             }
       
  1444         }
       
  1445         
       
  1446         if (ac)
       
  1447         {
       
  1448             // ghost sink above
       
  1449         }
       
  1450         else if (queue && ok)
       
  1451         {
       
  1452             /* make this bin link point*/
       
  1453             ghostsink = gst_element_get_static_pad(queue,"sink");
       
  1454             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1455             gst_object_unref(GST_OBJECT(ghostsink));
       
  1456         }
       
  1457         else if (vol && ok)
       
  1458         {
       
  1459             /* make this bin link point*/
       
  1460             ghostsink = gst_element_get_static_pad(vol,"sink");
       
  1461             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1462             gst_object_unref(GST_OBJECT(ghostsink));
       
  1463         }
       
  1464         else if (pan && ok)
       
  1465         {
       
  1466             /* make this bin link point*/
       
  1467             ghostsink = gst_element_get_static_pad(pan,"sink");
       
  1468             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1469             gst_object_unref(GST_OBJECT(ghostsink));
       
  1470         }
       
  1471         else if (eq && ok)
       
  1472         {
       
  1473             /* make this bin link point*/
       
  1474             ghostsink = gst_element_get_static_pad(eq,"sink");
       
  1475             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1476             gst_object_unref(GST_OBJECT(ghostsink));
       
  1477         }
       
  1478         else if (ac2 && ok)
       
  1479         {
       
  1480             /* make this bin link point*/
       
  1481             ghostsink = gst_element_get_static_pad(ac2,"sink");
       
  1482             ok = gst_element_add_pad(app, gst_ghost_pad_new("sink",ghostsink));
       
  1483             gst_object_unref(GST_OBJECT(ghostsink));
       
  1484         }
       
  1485         
       
  1486         if (ac2)
       
  1487         {
       
  1488             // ghost src above
       
  1489         }
       
  1490         else if (eq && ok)
       
  1491         {
       
  1492             /* make this bin link point*/
       
  1493             ghostsrc = gst_element_get_static_pad(eq,"src");
       
  1494             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1495             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1496         }
       
  1497         else if (pan && ok)
       
  1498         {
       
  1499             /* make this bin link point*/
       
  1500             ghostsrc = gst_element_get_static_pad(pan,"src");
       
  1501             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1502             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1503         }
       
  1504         else if (vol && ok)
       
  1505         {
       
  1506             /* make this bin link point*/
       
  1507             ghostsrc = gst_element_get_static_pad(vol,"src");
       
  1508             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1509             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1510         }
       
  1511         else if (queue && ok)
       
  1512         {
       
  1513             /* make this bin link point*/
       
  1514             ghostsrc = gst_element_get_static_pad(queue,"src");
       
  1515             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1516             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1517         }
       
  1518         else if (ac && ok)
       
  1519         {
       
  1520             /* make this bin link point*/
       
  1521             ghostsrc = gst_element_get_static_pad(ac,"src");
       
  1522             ok = gst_element_add_pad(app, gst_ghost_pad_new("src",ghostsrc));
       
  1523             gst_object_unref(GST_OBJECT(ghostsrc));
       
  1524         }
       
  1525             
       
  1526 //        if( !(gst_element_link_many(ac, queue, vol, ac2, NULL)) )
       
  1527 //        if( !(gst_element_link_many(ac, queue, vol, pan, eq, ac2, NULL)) )
       
  1528         if (!ok)
       
  1529         {
       
  1530             DEBUG_ERR("Could not link audiopp elements!!");
       
  1531             gst_object_unref(app);
       
  1532             app = NULL;
       
  1533         }
       
  1534     }
       
  1535 
       
  1536     DEBUG_API("<-XAAdaptationBase_CreateAudioPP");
       
  1537     return app;
       
  1538 }
       
  1539 
       
  1540 /* called when pad is actually blocking/ gets unblocked*/
       
  1541 void XAAdaptationBase_PadBlockCb(GstPad *pad, gboolean blocked, gpointer user_data)
       
  1542 {
       
  1543     DEBUG_API_A2("->XAAdaptationBase_PadBlockCb   pad \"%s\" of \"%s\" ",
       
  1544                         GST_OBJECT_NAME(pad),
       
  1545                         GST_OBJECT_NAME(gst_pad_get_parent_element(pad)) );
       
  1546     DEBUG_API_A1("<-XAAdaptationBase_PadBlockCb   blocked:%d",blocked);
       
  1547 }
       
  1548 
       
  1549 /* utility to set same fields for all media types in caps */
       
  1550 void XAAdaptationBase_SetAllCaps (GstCaps * caps, char *field, ...)
       
  1551 {
       
  1552     GstStructure *structure;
       
  1553     va_list var_args;
       
  1554     int i;
       
  1555 
       
  1556     for (i = 0; i < gst_caps_get_size (caps); i++)
       
  1557     {
       
  1558         structure = gst_caps_get_structure (caps, i);
       
  1559         va_start (var_args, field);
       
  1560         gst_structure_set_valist (structure, field, var_args);
       
  1561         va_end (var_args);
       
  1562     }
       
  1563 }
       
  1564 
       
  1565 /*
       
  1566  * void* XAAdaptationBase_ContentPipeScrThrFunc( void* arg )
       
  1567  */
       
  1568 void* XAAdaptationBase_ContentPipeScrThrFunc( void* arg )
       
  1569 {
       
  1570 	XAAdaptCpThrCtx* thrCtx = (XAAdaptCpThrCtx*)arg;
       
  1571 	XAresult ret;
       
  1572 	CPresult cpRet;
       
  1573 	XAuint32 requestedBytes = CONTENT_PIPE_BUFFER_SIZE;
       
  1574 	CP_CHECKBYTESRESULTTYPE eResult;
       
  1575 
       
  1576 	DEBUG_API("->XAAdaptationBase_ContentPipeScrThrFunc");
       
  1577 
       
  1578 
       
  1579 	/* Wait until playstate is changed */
       
  1580 	ret = XAImpl_WaitSemaphore( thrCtx->stateSem );
       
  1581 	if ( ret != XA_RESULT_SUCCESS)
       
  1582 	{
       
  1583 	    DEBUG_ERR("Could not start semaphore");
       
  1584 	}
       
  1585 
       
  1586 	thrCtx->state = CPStateRunning;
       
  1587 
       
  1588 	do
       
  1589 	{
       
  1590 	    GstBuffer  *buffer = NULL;            /* Gstreamer buffer */
       
  1591 
       
  1592         if ( thrCtx->state == CPStatePaused )
       
  1593         {
       
  1594             /* Wait until playstate is changed */
       
  1595             ret = XAImpl_WaitSemaphore( thrCtx->stateSem );
       
  1596             if ( ret != XA_RESULT_SUCCESS)
       
  1597             {
       
  1598                 DEBUG_ERR("Could not start semaphore");
       
  1599                 thrCtx->state = CPStateError;
       
  1600                 break;
       
  1601             }
       
  1602         }
       
  1603 
       
  1604         if ( thrCtx->state == CPStateWaitForData )
       
  1605         {
       
  1606         }
       
  1607 	    /* Check do we have enough bytes in pipe */
       
  1608 	    cpRet = thrCtx->pipe->pContentPipe->CheckAvailableBytes(&(thrCtx->dataHandle), requestedBytes, &eResult);
       
  1609 	    if ( cpRet != EXIT_SUCCESS )
       
  1610 	    {
       
  1611 	        thrCtx->state = CPStateError;
       
  1612 	    }
       
  1613 
       
  1614 		if ( eResult == CP_CheckBytesOk)
       
  1615 		{ /* We have enough bytes in content pipe */
       
  1616 		    thrCtx->state = CPStateRunning;
       
  1617 		    DEBUG_API("CP_CheckBytesOk");
       
  1618 
       
  1619 			if ( thrCtx->cpConfig == XA_READ )
       
  1620 			{ /* OMX-AL implementation allocates buffers */
       
  1621 
       
  1622 			    /* Pointer to OMX-AL RI allocated data */
       
  1623 			    gpointer cpBuffer = NULL;
       
  1624 
       
  1625 			    /* Allocate new buffer with preferred size */
       
  1626 			    cpBuffer = g_malloc0(requestedBytes );
       
  1627 			    cpRet = thrCtx->pipe->pContentPipe->Read( &(thrCtx->dataHandle), (CPbyte*)cpBuffer, requestedBytes );
       
  1628 			    if ( cpRet != EXIT_SUCCESS )
       
  1629 			    {
       
  1630 			        DEBUG_ERR("Could not read data from content pipe!");
       
  1631 			        thrCtx->state = CPStateError;
       
  1632                     break;
       
  1633 			    }
       
  1634 			    else
       
  1635 			    {
       
  1636 			        DEBUG_INFO_A1("Readed %u bytes", requestedBytes );
       
  1637                     /* Create gstBuffer, GStreamer frees data  */
       
  1638 			        buffer = gst_app_buffer_new( (void*)cpBuffer, requestedBytes, g_free, cpBuffer );
       
  1639                     if ( !buffer )
       
  1640                     {
       
  1641                         DEBUG_ERR("Could not allocate buffer for content pipe source!");
       
  1642                         thrCtx->state = CPStateError;
       
  1643                         break;
       
  1644                     }
       
  1645 			    }
       
  1646 			}
       
  1647 			else
       
  1648 			{ /* Content pipe implementation allocates buffers */
       
  1649 			    gpointer pipeBuffer = NULL;
       
  1650 			    gpointer omxBuffer = NULL;
       
  1651 
       
  1652 			    cpRet = thrCtx->pipe->pContentPipe->ReadBuffer( &(thrCtx->dataHandle), (CPbyte**)&pipeBuffer, &requestedBytes, FALSE);
       
  1653                 if ( cpRet != EXIT_SUCCESS )
       
  1654                 {
       
  1655                     DEBUG_ERR("Could not read data from content pipe!");
       
  1656                     thrCtx->state = CPStateError;
       
  1657                     break;
       
  1658                 }
       
  1659                 else
       
  1660                 {
       
  1661                     DEBUG_INFO_A1("Readed %u bytes", requestedBytes );
       
  1662                     /* Copy pipe allocated data into own buffer */
       
  1663                     omxBuffer = g_malloc0(requestedBytes );
       
  1664                     memcpy( omxBuffer, pipeBuffer, requestedBytes );
       
  1665 
       
  1666                     /* Create gstBuffer, GStreamer frees data  */
       
  1667                     buffer = gst_app_buffer_new( omxBuffer, requestedBytes, g_free, omxBuffer );
       
  1668                     if ( !buffer )
       
  1669                     {
       
  1670                         DEBUG_ERR("Could not allocate buffer for content pipe source!");
       
  1671                         thrCtx->state = CPStateError;
       
  1672                         break;
       
  1673                     }
       
  1674                     /* Release readbuffer */
       
  1675                     cpRet = thrCtx->pipe->pContentPipe->ReleaseReadBuffer( &(thrCtx->dataHandle), (CPbyte*)pipeBuffer );
       
  1676                     if ( cpRet != EXIT_SUCCESS )
       
  1677                     {
       
  1678                         DEBUG_ERR("Could not release readbuffer!");
       
  1679                         thrCtx->state = CPStateError;
       
  1680                         break;
       
  1681                     }
       
  1682                     pipeBuffer = NULL;
       
  1683 
       
  1684                 }
       
  1685 			}
       
  1686 			if ( cpRet == EXIT_SUCCESS  )
       
  1687             {
       
  1688 			    if( buffer )
       
  1689 			    {
       
  1690 			    DEBUG_INFO("Pushing buffer");
       
  1691                 gst_app_src_push_buffer( GST_APP_SRC(thrCtx->appSrc), GST_BUFFER(buffer) );
       
  1692 			    }
       
  1693             }
       
  1694 		}
       
  1695 		else if ( eResult == CP_CheckBytesNotReady )
       
  1696 		{
       
  1697 			DEBUG_API("CP_CheckBytesNotReady");
       
  1698 			thrCtx->state = CPStateWaitForData;
       
  1699 		}
       
  1700 		else if ( eResult == CP_CheckBytesInsufficientBytes )
       
  1701 		{
       
  1702 			DEBUG_API("CP_CheckBytesInsufficientBytes");
       
  1703 			if ( requestedBytes > 0 )
       
  1704 			{
       
  1705 				requestedBytes = requestedBytes - 1 ;
       
  1706 			}
       
  1707 			else
       
  1708 			{
       
  1709 				thrCtx->state = CPStateError;
       
  1710 			}
       
  1711 		}
       
  1712 		else if ( eResult == CP_CheckBytesAtEndOfStream)
       
  1713 		{
       
  1714 			DEBUG_API("XAAdaptationBase_ContentPipeScrThrFunc-> CP_CheckBytesAtEndOfStream");
       
  1715 		    thrCtx->state = CPStateEOS;
       
  1716 		}
       
  1717 	}while (thrCtx->state == CPStateRunning || thrCtx->state == CPStateWaitForData || thrCtx->state == CPStatePaused );
       
  1718 
       
  1719 	if ( thrCtx->state == CPStateError )
       
  1720 	{
       
  1721 	    /* If error goto beginning of content */
       
  1722 	    cpRet = thrCtx->pipe->pContentPipe->SetPosition( &(thrCtx->dataHandle),0, CP_OriginBegin);
       
  1723 	}
       
  1724 	else if ( thrCtx->state == CPStateEOS )
       
  1725 	{
       
  1726 	    /* Send EOS to appSrc */
       
  1727 	    gst_app_src_end_of_stream( GST_APP_SRC(thrCtx->appSrc) );
       
  1728 	    /* Set position to beginning */
       
  1729 	    cpRet = thrCtx->pipe->pContentPipe->SetPosition( &(thrCtx->dataHandle),0, CP_OriginBegin);
       
  1730 	}
       
  1731 	else if ( thrCtx->state == CPStateStopped )
       
  1732 	{
       
  1733 	    cpRet = thrCtx->pipe->pContentPipe->SetPosition( &(thrCtx->dataHandle),0, CP_OriginBegin);
       
  1734 	}
       
  1735 
       
  1736 	thrCtx->state = CPStateInitialized;
       
  1737 
       
  1738    DEBUG_API("<-XAAdaptationBase_ContentPipeScrThrFunc");
       
  1739    return NULL;
       
  1740 }
       
  1741 
       
  1742 /*
       
  1743  * void* XAAdaptationBase_ContentPipeSinkThrFunc( void* arg )
       
  1744  */
       
  1745 void* XAAdaptationBase_ContentPipeSinkThrFunc( void* arg )
       
  1746 {
       
  1747     XAAdaptCpThrCtx* thrCtx = (XAAdaptCpThrCtx*)arg;
       
  1748     XAresult ret;
       
  1749     CPresult cpRet;
       
  1750     XAboolean paused;
       
  1751     XAuint32 position = 0;
       
  1752 
       
  1753     DEBUG_API("->XAAdaptationBase_ContentPipeSinkThrFunc");
       
  1754 
       
  1755     thrCtx->state = CPStateStarted;
       
  1756 
       
  1757     /* Wait until recordstate is changed */
       
  1758     ret = XAImpl_WaitSemaphore( thrCtx->stateSem );
       
  1759     if ( ret != XA_RESULT_SUCCESS)
       
  1760     {
       
  1761         DEBUG_ERR("Could not start semaphore");
       
  1762     }
       
  1763     thrCtx->state = CPStateRunning;
       
  1764 
       
  1765     do
       
  1766     {
       
  1767         GstBuffer  *buffer;
       
  1768 
       
  1769         if ( thrCtx->state == CPStatePaused )
       
  1770         {
       
  1771         	/*If paused get position from end of the file*/
       
  1772         	paused = XA_BOOLEAN_TRUE;
       
  1773         	DEBUG_API("Get New position");
       
  1774         	cpRet = thrCtx->pipe->pContentPipe->GetPosition(&(thrCtx->dataHandle), &position);
       
  1775         	cpRet = thrCtx->pipe->pContentPipe->SetPosition(&(thrCtx->dataHandle), (CPint)position, CP_OriginEnd);
       
  1776             /* Wait until playstate is changed */
       
  1777             ret = XAImpl_WaitSemaphore( thrCtx->stateSem );
       
  1778             if ( ret != XA_RESULT_SUCCESS)
       
  1779             {
       
  1780                 DEBUG_ERR("Could not start waiting content pipe state semaphore");
       
  1781                 thrCtx->state = CPStateError;
       
  1782                 break;
       
  1783             }
       
  1784         }
       
  1785 
       
  1786         buffer = gst_app_sink_pull_buffer(GST_APP_SINK(thrCtx->appSink) );
       
  1787         if ( !buffer )
       
  1788         {
       
  1789             DEBUG_INFO("No buffer in gstAppSink!")
       
  1790             if ( gst_app_sink_is_eos( thrCtx->appSink) )
       
  1791             {
       
  1792 				DEBUG_API("XAAdaptationBase_ContentPipeSinkThrFunc-> CPStateEOS")
       
  1793                 thrCtx->state = CPStateEOS;
       
  1794             }
       
  1795             continue;
       
  1796         }
       
  1797 
       
  1798         if ( thrCtx->cpConfig == XA_WRITE )
       
  1799         { /* OMX-AL implementation allocates buffers */
       
  1800 
       
  1801             /* Write data to content pipe */
       
  1802             cpRet = thrCtx->pipe->pContentPipe->Write( &(thrCtx->dataHandle), (CPbyte *)GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer) );
       
  1803             if ( cpRet != EXIT_SUCCESS )
       
  1804             {
       
  1805                 DEBUG_ERR("Could not write data to content pipe!");
       
  1806                 thrCtx->state = CPStateError;
       
  1807                 break;
       
  1808             }
       
  1809         }
       
  1810         else
       
  1811         { /* Use content pipe allocated buffers */
       
  1812 
       
  1813             gpointer cpBuffer = NULL;
       
  1814 
       
  1815             /* Request buffer from content pipe with gst-buffer size */
       
  1816             cpRet = thrCtx->pipe->pContentPipe->GetWriteBuffer( &(thrCtx->dataHandle), (CPbyte**)&cpBuffer, GST_BUFFER_SIZE(buffer) );
       
  1817             if ( cpRet != EXIT_SUCCESS )
       
  1818             {
       
  1819                 DEBUG_ERR("Could not get write buffer from content pipe!");
       
  1820                 thrCtx->state = CPStateError;
       
  1821                 break;
       
  1822             }
       
  1823 
       
  1824             /* Copy data from gst-buffer to content pipe buffer */
       
  1825             memcpy( cpBuffer,GST_BUFFER_DATA(buffer),GST_BUFFER_SIZE(buffer));
       
  1826 
       
  1827             /* Write buffer to content pipe */
       
  1828             cpRet = thrCtx->pipe->pContentPipe->WriteBuffer( &(thrCtx->dataHandle), cpBuffer, GST_BUFFER_SIZE(buffer) );
       
  1829             if ( cpRet != EXIT_SUCCESS )
       
  1830             {
       
  1831                 DEBUG_ERR("Could not write buffer to content pipe!");
       
  1832                 thrCtx->state = CPStateError;
       
  1833                 break;
       
  1834             }
       
  1835 
       
  1836             g_free(cpBuffer);
       
  1837             cpBuffer = NULL;
       
  1838         }
       
  1839 
       
  1840         if ( gst_app_sink_is_eos( thrCtx->appSink) )
       
  1841         {
       
  1842             thrCtx->state = CPStateEOS;
       
  1843         }
       
  1844 
       
  1845     }while (thrCtx->state == CPStateRunning || thrCtx->state == CPStatePaused );
       
  1846 
       
  1847     if ( thrCtx->state == CPStateError )
       
  1848     {
       
  1849         /* If error goto beginning of content */
       
  1850         cpRet = thrCtx->pipe->pContentPipe->SetPosition( &(thrCtx->dataHandle),0, CP_OriginBegin);
       
  1851     }
       
  1852     else if ( thrCtx->state == CPStateStopped )
       
  1853     {
       
  1854         cpRet = thrCtx->pipe->pContentPipe->SetPosition( &(thrCtx->dataHandle),0, CP_OriginBegin);
       
  1855     }
       
  1856 
       
  1857     DEBUG_API("<-XAAdaptationBase_ContentPipeSinkThrFunc");
       
  1858     return NULL;
       
  1859 }
       
  1860 
       
  1861 /*
       
  1862  * CPresult XAAdaptationBase_ContentPipeSrcCb(CP_EVENTTYPE eEvent, CPuint iParam)
       
  1863  * Description: Callback function for content pipe source
       
  1864  * @param: CP_EVENTTYPE eEvent - Callback event
       
  1865  * @param: CPuint iParam - Param related to event
       
  1866  *
       
  1867  *  No actual functionality can be handled in callback, since current
       
  1868  *  Content Pipe specification lacks methods of supplying client context and/or
       
  1869  *  reference to context pipe handle with CP callback.
       
  1870  *  Khronos group is in progress on proposals for extending this functionality.
       
  1871  *
       
  1872  */
       
  1873 CPresult XAAdaptationBase_ContentPipeSrcCb(CP_EVENTTYPE eEvent, CPuint iParam)
       
  1874 {
       
  1875 	XAresult ret = XA_RESULT_SUCCESS;
       
  1876 	switch (eEvent )
       
  1877 	{
       
  1878 	case CP_BytesAvailable:
       
  1879 		/* Restart reading thread */
       
  1880 		break;
       
  1881 	case CP_Overflow:
       
  1882 		/* Handle error */
       
  1883 		break;
       
  1884 	case CP_PipeDisconnected:
       
  1885 		/* Reconnect pipe */
       
  1886 	case CP_EventMax:
       
  1887 		break;
       
  1888 	default:
       
  1889 		break;
       
  1890 	}
       
  1891 	return ret;
       
  1892 }
       
  1893 
       
  1894 /*
       
  1895  * CPresult XAAdaptationBase_ContentPipeSinkCb(CP_EVENTTYPE eEvent, CPuint iParam)
       
  1896  * Description: Callback function for content pipe sink
       
  1897  * @param: CP_EVENTTYPE eEvent - Callback event
       
  1898  * @param: CPuint iParam - Param related to event
       
  1899  *
       
  1900  *  No actual functionality can be handled in callback, since current
       
  1901  *  Content Pipe specification lacks methods of supplying client context and/or
       
  1902  *  reference to context pipe handle with CP callback.
       
  1903  *  Khronos group is in progress on proposals for extending this functionality.
       
  1904  *
       
  1905  */
       
  1906 CPresult XAAdaptationBase_ContentPipeSinkCb(CP_EVENTTYPE eEvent, CPuint iParam)
       
  1907 {
       
  1908 	XAresult ret = XA_RESULT_SUCCESS;
       
  1909 	switch (eEvent )
       
  1910 	{
       
  1911 	case CP_BytesAvailable:
       
  1912 		/*Restart write thread.*/
       
  1913 		break;
       
  1914 	case CP_Overflow:
       
  1915 		/*Handle error */
       
  1916 		break;
       
  1917 	case CP_PipeDisconnected:
       
  1918 		/*Reconnect pipe */
       
  1919 	default:
       
  1920 		break;
       
  1921 	}
       
  1922 	return ret;
       
  1923 
       
  1924 }