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