gst_plugins_symbian/gst/AudioRecordBin/src/GstAudioRecordBin.cpp
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
       
     3 *
       
     4 * This library is free software; you can redistribute it and/or
       
     5 * modify it under the terms of the GNU Lesser General Public
       
     6 * License as published by the Free Software Foundation; either
       
     7 * version 2 of the License, or (at your option) any later version.
       
     8 *
       
     9 * This library is distributed in the hope that it will be useful,
       
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12 * Lesser General Public License for more details.
       
    13 *
       
    14 * You should have received a copy of the GNU Lesser General Public
       
    15 * License along with this library; if not, write to the
       
    16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    17 * Boston, MA 02111-1307, USA.
       
    18 *
       
    19 * Description:
       
    20 *
       
    21 */
       
    22 
       
    23 //  Include Files  
       
    24 
       
    25 #include "GstAudioRecordBin.h"
       
    26 #include "gstfactorylists.h"
       
    27 #include <gst/gst.h>
       
    28 #include <string.h>
       
    29 #include <stdlib.h>
       
    30 
       
    31 GST_DEBUG_CATEGORY_STATIC (aud_recbin_cat);     // define category (statically)
       
    32 #ifdef GST_CAT_DEFAULT
       
    33 #undef GST_CAT_DEFAULT
       
    34 #endif
       
    35 
       
    36 #define GST_CAT_DEFAULT aud_recbin_cat     // set as default
       
    37 
       
    38 /** Macro to enable weak ref monitoring, used to track
       
    39  * ref / unref problems. 
       
    40  * NOTE : DO NOT USE IN HARDWARE, can be used in EMULATOR ONLY */
       
    41 //#define WEAK_REF
       
    42 #ifdef WEAK_REF
       
    43 #define MONITOR_REF(gobj) if( G_IS_OBJECT(gobj) ) g_object_weak_ref( G_OBJECT(gobj), sWeakNotify, (gpointer) #gobj)
       
    44 /** Weak Ref callback */
       
    45 static void sWeakNotify (gpointer  data, GObject  *where_the_object_was);
       
    46 #else
       
    47 #define MONITOR_REF(gobj) /* NOP */
       
    48 #endif // WEAK_REF
       
    49 
       
    50 /** Enable the caps filter */
       
    51 //#define ENABLE_CAPS_FILTER
       
    52 
       
    53 /** The struct used to indicated the filter criteria for gst plugin factory */
       
    54 typedef struct
       
    55 {
       
    56     /** The type of the factory */
       
    57     GstFactoryListType type;
       
    58     /** The caps expected to be supported by a sink pad */
       
    59     GstCaps* sinkCaps;
       
    60     /** The caps expected to be supported by a src pad */
       
    61     GstCaps* srcCaps;
       
    62 } FilterData;
       
    63 #ifdef ENABLE_CAPS_FILTER
       
    64 /** Create the capability filter */
       
    65 static GstElement* sCreateCapsFilter( GstCaps* encCaps);
       
    66 #endif
       
    67 
       
    68 /** Creates the element , which accepts \a sinkcaps and 
       
    69  * provides \a srccaps on the src pad */
       
    70 GstElement* sCreateCompatibleFilter(GstFactoryListType type,
       
    71         const gchar* name, GstCaps* sinkcaps, GstCaps* srccaps);
       
    72 
       
    73 
       
    74 /** Utility function to create the caps depending on the mimetype, fills in the default
       
    75  * values
       
    76  * */
       
    77 static GstCaps* sCreateCaps( const char* mimetype );
       
    78 
       
    79 /**
       
    80  * Checks if a given element \a factory can accpet the \a caps on a pad
       
    81  * of given \a direction.
       
    82  */
       
    83 gboolean gst_element_factory_can_accept_caps (GstElementFactory * factory,
       
    84     const GstCaps * caps, GstPadDirection direction )
       
    85 {
       
    86   GList *templates;
       
    87 
       
    88   g_return_val_if_fail (factory != NULL, FALSE);
       
    89   g_return_val_if_fail (caps != NULL, FALSE);
       
    90 
       
    91   templates = factory->staticpadtemplates;
       
    92 
       
    93   while (templates) {
       
    94     GstStaticPadTemplate *template1 = (GstStaticPadTemplate *) templates->data;
       
    95 
       
    96     if (template1->direction == direction ) {
       
    97       if (gst_caps_is_subset( caps, gst_static_caps_get(&template1->static_caps)))
       
    98         return TRUE;
       
    99     }
       
   100     templates = g_list_next (templates);
       
   101   }
       
   102 
       
   103   return FALSE;
       
   104 }
       
   105 /**
       
   106  * Checks if the element factory has the \a klass_type and checks if the filter data
       
   107  * criteria ( accepts sinkCaps & srcCaps ) is met.
       
   108  */
       
   109 static inline gboolean element_klass_filter (GstElementFactory * factory, const gchar *klass_type, FilterData* pData)
       
   110 {
       
   111     const gchar *klass = NULL;
       
   112     gboolean sink_caps_supported = FALSE;
       
   113     gboolean src_caps_supported = FALSE;
       
   114 
       
   115     klass = gst_element_factory_get_klass (factory);
       
   116     GST_DEBUG("klass = %s\n", klass);
       
   117 
       
   118     if (strstr (klass, klass_type) != NULL)
       
   119     {
       
   120         sink_caps_supported = gst_element_factory_can_accept_caps( factory, pData->sinkCaps, GST_PAD_SINK );               
       
   121     
       
   122         src_caps_supported = gst_element_factory_can_accept_caps( factory, pData->srcCaps, GST_PAD_SRC );
       
   123 
       
   124         GST_INFO("%s fact name = %s, can sink %d can src %d \n",
       
   125                 klass_type,
       
   126                 GST_PLUGIN_FEATURE_NAME(factory),
       
   127                 sink_caps_supported, src_caps_supported
       
   128                 );
       
   129 
       
   130         return TRUE && sink_caps_supported && src_caps_supported;
       
   131     }
       
   132 
       
   133     return FALSE;
       
   134 }
       
   135 
       
   136 /**
       
   137  * gst_factory_list_is_type:
       
   138  * @factory: a #GstElementFactory
       
   139  * @type: a #GstFactoryListType
       
   140  *
       
   141  * Check if @factory if of the given types.
       
   142  *
       
   143  * Returns: %TRUE if @factory is of @type.
       
   144  */
       
   145 gboolean gst_factory_list_is_type (GstElementFactory * factory, FilterData * pData)
       
   146 {
       
   147     gboolean res = FALSE;
       
   148     const char* encoder_klass_str = "Encoder";
       
   149     const char* muxer_klass_str = "Muxer";
       
   150 
       
   151     /* NOTE : GST_FACTORY_LIST_SINK, GST_FACTORY_LIST_DECODER, GST_FACTORY_LIST_SRC
       
   152      * ignored.
       
   153      */
       
   154     if (!res && (pData->type & GST_FACTORY_LIST_ENCODER))
       
   155         res = element_klass_filter (factory,encoder_klass_str, pData);
       
   156     if (!res && (pData->type & GST_FACTORY_LIST_MUXER))
       
   157         res = element_klass_filter (factory,muxer_klass_str, pData);
       
   158 
       
   159     return res;
       
   160 }
       
   161 
       
   162 /** The element filter used along with gst registry feature filter;
       
   163  * The filter criteria is indicated in \a pData. */ 
       
   164 static gboolean element_filter (GstPluginFeature * feature, FilterData * pData)
       
   165 {
       
   166     gboolean res;
       
   167 
       
   168     /* we only care about element factories */
       
   169     if (G_UNLIKELY (!GST_IS_ELEMENT_FACTORY (feature)))
       
   170         return FALSE;
       
   171 
       
   172     res = gst_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (feature), pData);
       
   173 
       
   174     return res;
       
   175 }
       
   176 
       
   177 /* function used to sort element features, by comparing the ranks.
       
   178  * If ranks are same, then the plugin name is used. */
       
   179 static gint compare_ranks(GstPluginFeature * f1, GstPluginFeature * f2)
       
   180 {
       
   181   gint diff;
       
   182   const gchar *rname1, *rname2;
       
   183 
       
   184   diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
       
   185   if (diff != 0)
       
   186     return diff;
       
   187 
       
   188   rname1 = gst_plugin_feature_get_name (f1);
       
   189   rname2 = gst_plugin_feature_get_name (f2);
       
   190 
       
   191   diff = strcmp (rname2, rname1);
       
   192 
       
   193   return diff;
       
   194 }
       
   195 
       
   196 /** Returns a GList of factory elements, of a given \a type and which accpets \a sinkCaps and
       
   197  * and provides \a srcCaps.
       
   198  * */
       
   199 GList* gst_factory_list_get_elements (GstFactoryListType type, GstCaps* sinkCaps, GstCaps* srcCaps)
       
   200 {
       
   201     FilterData* pData = NULL;
       
   202     GList *list = NULL;
       
   203 
       
   204     // construct the data
       
   205     pData = (FilterData*) calloc(sizeof(FilterData), 1);
       
   206     pData->sinkCaps = sinkCaps;
       
   207     pData->srcCaps = srcCaps;
       
   208     pData->type = type;
       
   209 
       
   210     /* get the feature list using the filter */
       
   211     list = gst_default_registry_feature_filter ((GstPluginFeatureFilter)
       
   212             element_filter, FALSE, pData);
       
   213 
       
   214     free( pData );
       
   215     
       
   216     // sort depending on the ranks
       
   217     if ( list )
       
   218         list = g_list_sort( list, (GCompareFunc) compare_ranks );
       
   219 
       
   220     GST_INFO("sort list done");
       
   221 
       
   222     return list;
       
   223 
       
   224 }
       
   225 /** Gets the pad depending on th pad template. */
       
   226 static GstPad * gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
       
   227 {
       
   228     GstPad *ret = NULL;
       
   229     GstPadPresence presence;
       
   230 
       
   231     /* If this function is ever exported, we need check the validity of `element'
       
   232      * and `templ', and to make sure the template actually belongs to the
       
   233      * element. */
       
   234 
       
   235     presence = GST_PAD_TEMPLATE_PRESENCE (templ);
       
   236 
       
   237     switch (presence) {
       
   238         case GST_PAD_ALWAYS:
       
   239         case GST_PAD_SOMETIMES:
       
   240             GST_INFO("presence : always/sometimes");
       
   241             ret = gst_element_get_static_pad (element, templ->name_template);
       
   242             if (!ret && presence == GST_PAD_ALWAYS)
       
   243                 g_warning
       
   244                     ("Element %s has an ALWAYS template %s, but no pad of the same name",
       
   245                      GST_OBJECT_NAME (element), templ->name_template);
       
   246             break;
       
   247 
       
   248         case GST_PAD_REQUEST:
       
   249             GST_INFO("presence : request audio_1");
       
   250             //ret = gst_element_request_pad (element, templ, NULL);
       
   251             ret = gst_element_get_request_pad( element, "audio_%d");
       
   252             break;
       
   253     }
       
   254 
       
   255     return ret;
       
   256 }
       
   257 
       
   258 /* Finds compatible muxer sink pad, for a given \a encoder \ref GstElement */
       
   259 static inline GstPad * get_compatible_muxer_sink_pad (GstElement * muxer, GstElement * encoder) //pass in the right arguments here
       
   260 {
       
   261     GstPad *srcpad = 0, *sinkpad = 0;
       
   262     GstPadTemplate *srctempl = 0;
       
   263     GstPadTemplate *sinktempl = 0;
       
   264 
       
   265     srcpad = gst_element_get_static_pad (encoder, "src");
       
   266 
       
   267     srctempl = gst_pad_get_pad_template (srcpad);
       
   268 
       
   269     GST_DEBUG (
       
   270             "Attempting to find pad from muxer %s compatible with %s:%s",
       
   271             GST_ELEMENT_NAME (muxer), GST_DEBUG_PAD_NAME (srcpad));
       
   272     
       
   273     gst_object_unref( srcpad );
       
   274 
       
   275     sinktempl = gst_element_get_compatible_pad_template (muxer, srctempl);
       
   276     if (G_UNLIKELY (sinktempl == NULL))
       
   277         goto no_template;
       
   278 
       
   279     sinkpad = gst_element_get_pad_from_template (muxer, sinktempl);
       
   280     
       
   281     return sinkpad;
       
   282 
       
   283 no_template:
       
   284     {
       
   285         GST_ERROR ("No compatible pad available on muxer");
       
   286         return NULL;
       
   287     }
       
   288 }
       
   289 
       
   290 
       
   291 /**
       
   292  * Creates the encoder bin.
       
   293  * If the function is successful, A encoder bin with a ghost sink pad 
       
   294  * which accepts the \a encCaps and a ghost source pad which gives
       
   295  * \a muxCaps type is available.
       
   296  * 
       
   297  * Algo:
       
   298  * 
       
   299  * 1. Check if any pads of src give out encCaps
       
   300  * 1.1 If yes, 
       
   301  *      -> Create a list of muxers available in the gst plugin repository and select the appropriate muxer
       
   302  *      -> connect src -> muxer, create encbin.
       
   303  * 1.2 If no,
       
   304  *      -> Create a list of encoders availabe in the gst plugin repo and  select a appropriate enc
       
   305  *      -> connect src -> capsfilter (optional) -> enc -> muxer and return encbin
       
   306  *      
       
   307  * 
       
   308  * \param [in] src The source gst element
       
   309  * \param [in] encCaps The capability of the encoder being created.
       
   310  * \param [in] muxCaps The capability type of the muxer to create.
       
   311  * 
       
   312  * \return On successful the ptr to encoder bin gst element is returned, else NULL.
       
   313  */
       
   314 EXPORT_C GstElement* CreateAudioRecordBin( GstElement* src, GstCaps* encCaps, GstCaps* muxCaps)
       
   315 {
       
   316     GstElement *encbin = NULL; // The top level encoder bin
       
   317     GstPad *ghostsrc = NULL, *ghostsink = NULL; // Ghost src, sink pads of the enc bin
       
   318     GstElement *muxer = NULL; // The muxer
       
   319     GstElement *encoder = NULL; // The encoder
       
   320 #ifdef ENABLE_CAPS_FILTER
       
   321     GstElement * audiofilter = NULL; // Audio filter
       
   322 #endif // ENABLE_CAPS_FILTER
       
   323     GstPad* src_pad = 0;
       
   324     gboolean accept_src_pad = 0;
       
   325     GstCaps* src_caps = 0;
       
   326     
       
   327     if ( !src || !encCaps || !muxCaps )
       
   328     {
       
   329     		GST_ERROR("invalid args");
       
   330     		return NULL;
       
   331     }    
       
   332 
       
   333     /* gst initialization */
       
   334     if ( FALSE == gst_init_check(NULL, NULL,NULL) )
       
   335     {
       
   336         GST_ERROR("gst_init_check FAIL");
       
   337         return NULL;
       
   338     }
       
   339 
       
   340     /* Initialize the debug category */
       
   341     GST_DEBUG_CATEGORY_INIT (aud_recbin_cat, "AudioRecordBin",
       
   342             0, "Audio record bin plugin");
       
   343 
       
   344 
       
   345     /* 1. Create the bin */
       
   346     encbin = gst_bin_new("encbin");
       
   347     if ( !encbin )
       
   348     {
       
   349         GST_ERROR("encbin creation FAIL");
       
   350         return NULL;
       
   351     }
       
   352     MONITOR_REF(encbin);
       
   353 
       
   354     /* 2. Get the src pad, of the source element */
       
   355     src_pad = gst_element_get_pad (src, "src");
       
   356 
       
   357     src_caps = gst_pad_get_caps( src_pad );
       
   358 
       
   359     /* 2.1 Check if the src gst element can directly give the encCaps */
       
   360     accept_src_pad = gst_caps_is_subset( encCaps ,src_caps);   
       
   361 
       
   362     GST_INFO(" accept caps %d ", accept_src_pad );
       
   363     gst_object_unref (src_pad);
       
   364     gst_caps_unref( src_caps );
       
   365 
       
   366     if ( !accept_src_pad )
       
   367     {
       
   368         GstCaps* enc_in_caps = 0;
       
   369 
       
   370         /* The src pad does not directly give the encoded format,
       
   371          * fallback to x-raw-int / x-raw-float and construct the pipeline
       
   372          * */
       
   373         enc_in_caps = sCreateCaps("audio/x-raw-int");
       
   374 
       
   375         encoder = sCreateCompatibleFilter( GST_FACTORY_LIST_ENCODER, "encoder", enc_in_caps, encCaps);
       
   376         if (!encoder )
       
   377         {
       
   378             GST_ERROR("encoder creation FAIL");
       
   379             gst_caps_unref( enc_in_caps );
       
   380             goto CLEANUP;
       
   381         }
       
   382         
       
   383 #ifdef ENABLE_CAPS_FILTER
       
   384         audiofilter = sCreateCapsFilter(enc_in_caps);
       
   385 #endif // ENABLE_CAPS_FILTER
       
   386         
       
   387         gst_caps_unref( enc_in_caps );
       
   388 
       
   389         // add elements to the enc bin
       
   390         if (gst_bin_add(GST_BIN(encbin), encoder))
       
   391         {
       
   392             GST_INFO("Added encoder to bin");
       
   393         }
       
   394         else
       
   395         {
       
   396             GST_ERROR("Could not add encoder to bin");
       
   397             goto CLEANUP;
       
   398         }
       
   399 
       
   400     }
       
   401 
       
   402     /* construct the muxer which can accept the encCaps and give out muxCaps */
       
   403 #ifdef ENABLE_CAPS_FILTER
       
   404     /* Add a caps filter, if not created above */
       
   405     if ( !audiofilter )
       
   406         audiofilter = sCreateCapsFilter(encCaps);
       
   407 
       
   408     if ( !audiofilter)
       
   409     {
       
   410         GST_ERROR("audio filter creation FAIL ");
       
   411         goto CLEANUP;
       
   412     }
       
   413     MONITOR_REF(audiofilter);
       
   414     
       
   415     // add elements to the enc bin
       
   416     if (gst_bin_add(GST_BIN(encbin), audiofilter))
       
   417     {
       
   418         GST_INFO("Added audio filter to bin");
       
   419     }
       
   420     else
       
   421     {
       
   422         GST_ERROR("Could not add audio filter to bin");
       
   423         goto CLEANUP;
       
   424     }
       
   425 #endif // ENABLE_CAPS_FILTER
       
   426 
       
   427 
       
   428     // Create the muxer 
       
   429     muxer = sCreateCompatibleFilter( GST_FACTORY_LIST_MUXER, "muxer", encCaps, muxCaps );
       
   430 
       
   431     if ( !muxer )
       
   432     {
       
   433         GST_ERROR("no suitable muxer found");
       
   434         goto CLEANUP;
       
   435     }
       
   436 
       
   437     MONITOR_REF(muxer);
       
   438 
       
   439     if (gst_bin_add(GST_BIN(encbin), muxer))
       
   440     {
       
   441         GST_INFO("Added muxer to bin");
       
   442     }
       
   443     else
       
   444     {
       
   445         GST_ERROR("Could not add muxer to bin");
       
   446         goto CLEANUP;
       
   447     }
       
   448 
       
   449     // link the added elements.
       
   450     // If encoder is present, then the bin will have,
       
   451     // capsfilter -> encoder -> muxer
       
   452     // or else
       
   453     // capsfilter -> muxer.
       
   454     // Note that caps filter is optionally controlled by macro ENABLE_CAPS_FILTER
       
   455     if ( encoder )
       
   456     {
       
   457         GstPad* srcpad      = 0;
       
   458         GstPad* muxerpad    = 0;
       
   459 #ifdef ENABLE_CAPS_FILTER
       
   460         GST_INFO("audiofilter -> encoder");
       
   461         if(!gst_element_link(audiofilter, encoder))
       
   462         {
       
   463             GST_ERROR("Could not link audiofilter -> encoder!!");
       
   464             goto CLEANUP;
       
   465         }
       
   466 #endif //ENABLE_CAPS_FILTER
       
   467         
       
   468         // get the src pad
       
   469         srcpad = gst_element_get_static_pad (encoder, "src");
       
   470         
       
   471         // get the sink pad of muxer
       
   472         GST_INFO("get compatible mux sink pad ... ");
       
   473         muxerpad = get_compatible_muxer_sink_pad (muxer, encoder);
       
   474 
       
   475         // link 
       
   476         if (G_UNLIKELY (gst_pad_link (srcpad, muxerpad) != GST_PAD_LINK_OK))
       
   477         {
       
   478             GST_ERROR("gst_pad_link fail");
       
   479             goto CLEANUP;
       
   480         }
       
   481         gst_object_unref( srcpad );
       
   482         gst_object_unref( muxerpad );
       
   483         GST_INFO("gst_pad_link successful");
       
   484 
       
   485     }
       
   486 #ifdef ENABLE_CAPS_FILTER
       
   487     else 
       
   488     {
       
   489         GST_INFO("audiofilter -> muxer ");
       
   490         if(!gst_element_link(audiofilter, muxer))
       
   491         {
       
   492             GST_ERROR("Could not link audiofilter to muxer!!");
       
   493             goto CLEANUP;
       
   494         }
       
   495     }
       
   496 #endif //ENABLE_CAPS_FILTER
       
   497     GST_INFO("linking complete");
       
   498 
       
   499     // create the ghost pads
       
   500     // The ghost src pad is provided by the muxer
       
   501     ghostsrc = gst_element_get_static_pad(muxer, "src");
       
   502     // The ghost sink pad is determined by the availability
       
   503     // of audiofilter, encoder.
       
   504 #ifdef ENABLE_CAPS_FILTER
       
   505     ghostsink = gst_element_get_static_pad(audiofilter, "sink");
       
   506 #else
       
   507     if ( encoder )
       
   508         ghostsink = gst_element_get_static_pad(encoder, "sink");
       
   509     else
       
   510         ghostsink = gst_element_get_static_pad(muxer, "sink");
       
   511 #endif //ENABLE_CAPS_FILTER
       
   512 
       
   513     MONITOR_REF( ghostsrc );
       
   514     MONITOR_REF( ghostsink );
       
   515 
       
   516     if(ghostsrc)
       
   517     {
       
   518         gst_element_add_pad(encbin, gst_ghost_pad_new("src",ghostsrc));
       
   519         gst_object_unref(GST_OBJECT(ghostsrc));
       
   520         GST_INFO("+ghost src");
       
   521     }
       
   522     if(ghostsink)
       
   523     {
       
   524         gst_element_add_pad(encbin, gst_ghost_pad_new("sink",ghostsink));
       
   525         gst_object_unref(GST_OBJECT(ghostsink));
       
   526         GST_INFO("+ghost sink");
       
   527     }
       
   528     return encbin;
       
   529 CLEANUP:
       
   530     // release only if the gst element has not been added to the bin;
       
   531     // when added to a bin, the bin ( i.e the parent ) takes care of
       
   532     // releasing.
       
   533     if ( encoder && !gst_element_get_parent(encoder) )
       
   534         gst_object_unref( encoder );
       
   535     if ( muxer && !gst_element_get_parent(muxer))
       
   536         gst_object_unref( muxer );
       
   537     #ifdef ENABLE_CAPS_FILTER
       
   538     if ( audiofilter && !gst_element_get_parent(audiofilter))
       
   539         gst_object_unref( audiofilter );
       
   540     #endif //ENABLE_CAPS_FILTER
       
   541     if ( encbin )
       
   542         gst_object_unref( encbin );
       
   543     return NULL;
       
   544 }
       
   545 #ifdef ENABLE_CAPS_FILTER
       
   546 /** Create the caps filter */
       
   547 GstElement* sCreateCapsFilter( GstCaps* encCaps)
       
   548 {
       
   549     GstElement* audiofilter = NULL;
       
   550 
       
   551     audiofilter = gst_element_factory_make("capsfilter", "audiofilter");
       
   552     if( !audiofilter )
       
   553     {
       
   554         return NULL;
       
   555     }
       
   556 
       
   557     g_object_set( G_OBJECT(audiofilter), "caps",encCaps,NULL);
       
   558 
       
   559     return audiofilter;
       
   560 }
       
   561 #endif
       
   562 /** Create a filter, which accepts \a encCaps on sink pad and 
       
   563  * provides \a muxCaps on the src pad */
       
   564 GstElement* sCreateCompatibleFilter(GstFactoryListType type,
       
   565         const gchar* name, GstCaps* sinkcaps, GstCaps* srccaps)
       
   566 {
       
   567 
       
   568     GList* factory_lst = NULL;
       
   569     GstElementFactory * factory = NULL;
       
   570     GstElement* element = NULL;
       
   571     guint nFactory = 0;
       
   572     
       
   573     GST_DEBUG("before gst_factory_list_get_elements");
       
   574 
       
   575     factory_lst = gst_factory_list_get_elements(type, sinkcaps, srccaps);
       
   576     
       
   577     GST_DEBUG("gst_factory_list_get_elements");
       
   578     
       
   579     nFactory = g_list_length ( factory_lst );   
       
   580     
       
   581     if ( !nFactory )
       
   582     {
       
   583         GST_ERROR("no matching %s found", name );
       
   584         return NULL;
       
   585     }
       
   586     GST_INFO("nElement %d", nFactory);
       
   587 
       
   588     // The first element factory in the sorted list is chosen
       
   589     factory = (GstElementFactory*) g_list_nth_data (factory_lst, 0);
       
   590     if ( factory )
       
   591     {
       
   592         GST_INFO("%s selected = %s can sink %d src %d ", 
       
   593                 name,
       
   594                 GST_PLUGIN_FEATURE_NAME(factory),
       
   595                 gst_element_factory_can_sink_caps(factory,sinkcaps),
       
   596                 gst_element_factory_can_src_caps(factory,srccaps)
       
   597                 );
       
   598 
       
   599         element =  gst_element_factory_create(factory, name);
       
   600         if (!element)
       
   601         {
       
   602             g_print("could not create element!");
       
   603         }
       
   604     }
       
   605 
       
   606     // free the muxers list
       
   607     gst_plugin_feature_list_free( factory_lst );
       
   608 
       
   609     return element;
       
   610 }
       
   611 
       
   612 
       
   613 /** Utility function to create the caps depending on the mimetype, fills in the default
       
   614  * values
       
   615  * */
       
   616 static GstCaps* sCreateCaps( const char* mimetype )
       
   617 {
       
   618     GstCaps* caps = NULL;
       
   619     GST_INFO( "inside sCreateCaps");
       
   620     if ( !strcmp(mimetype, "audio/x-raw-int") ||
       
   621             !strcmp(mimetype, "audio/x-raw-float") )
       
   622     {
       
   623         caps = gst_caps_new_simple(mimetype,
       
   624                 "width", G_TYPE_INT, 16,
       
   625                 "depth", G_TYPE_INT, 16,
       
   626                 "signed",G_TYPE_BOOLEAN, TRUE,
       
   627                 "endianness",G_TYPE_INT, G_BYTE_ORDER,
       
   628                 "rate", G_TYPE_INT, 16000,
       
   629                 "channels", G_TYPE_INT, 1, 
       
   630                 NULL);
       
   631     }
       
   632     else
       
   633     {
       
   634         // fallback to default 
       
   635         GST_INFO("fallback");
       
   636         caps = gst_caps_new_simple(mimetype, NULL);
       
   637         
       
   638     }
       
   639     return caps;
       
   640 } 
       
   641 
       
   642 #ifdef WEAK_REF
       
   643 void sWeakNotify (gpointer  data, GObject  *where_the_object_was)
       
   644 {
       
   645     GST_DEBUG("__release__ %s", (const char*) data );
       
   646 }
       
   647 #endif // WEAK_REF
       
   648 
       
   649 
       
   650 //  Exported Functions
       
   651 
       
   652 #ifndef EKA2 // for EKA1 only
       
   653 EXPORT_C TInt E32Dll(TDllReason /*aReason*/)
       
   654     // Called when the DLL is loaded and unloaded. Note: have to define
       
   655     // epoccalldllentrypoints in MMP file to get this called in THUMB.
       
   656 {
       
   657     return KErrNone;
       
   658 }
       
   659 #endif
       
   660 
       
   661