gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c
changeset 0 0e761a78d257
child 7 71e347f905f2
child 29 567bb019e3e3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c	Thu Dec 17 08:53:32 2009 +0200
@@ -0,0 +1,1139 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *               2000,2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gstdevsoundsrc.c:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gqueue.h>
+#include "common.h"
+#include "gstdevsoundsrc.h"
+
+#include <glib_global.h>
+#include "gstg711encoderinterface.h"
+#include "gstspeechencoderconfig.h"
+#include "gstg729encoderinterface.h"
+#include "gstilbcencoderinterface.h"
+#include "string.h"
+
+GST_DEBUG_CATEGORY_EXTERN (devsoundsrc_debug);
+#define GST_CAT_DEFAULT devsoundsrc_debug
+
+/* elementfactory information */
+static const GstElementDetails gst_devsound_src_details=
+GST_ELEMENT_DETAILS ("Audio Src (DEVSOUND)",
+        "Src/Audio",
+        "Record via Devsound",
+        " "
+);
+
+static void gst_devsound_src_base_init(gpointer g_class);
+static void gst_devsound_src_class_init(GstDevsoundSrcClass * klass);
+static void gst_devsound_src_init(GstDevsoundSrc * devsoundsrc);
+
+static void gst_devsound_src_dispose(GObject * object);
+
+static void gst_devsound_src_get_property(GObject * object, guint prop_id,
+        GValue * value, GParamSpec * pspec);
+static void gst_devsound_src_set_property(GObject * object, guint prop_id,
+        const GValue * value, GParamSpec * pspec);
+
+static GstCaps *gst_devsound_src_getcaps(GstBaseSrc * bsrc);
+static gboolean gst_devsound_src_setcaps(GstBaseSrc *bsrc, GstCaps *caps);
+
+static gboolean gst_devsound_src_start(GstBaseSrc * bsrc);
+static gboolean gst_devsound_src_stop(GstBaseSrc * bsrc);
+static gboolean gst_devsound_src_unlock(GstBaseSrc * bsrc);
+static gboolean gst_devsound_src_unlock_stop(GstBaseSrc * bsrc);
+static gboolean gst_devsound_src_is_seekable(GstBaseSrc * bsrc);
+static gboolean gst_devsound_src_get_size(GstBaseSrc * src, guint64 * size);
+
+static GstFlowReturn gst_devsound_src_create(GstBaseSrc *src, guint64 offset,
+        guint size, GstBuffer **buf);
+static void *StartDevSoundThread(void *threadid);
+
+/*********************************
+ * Speech Encoder Config Interface
+ * ******************************/
+static void gst_speech_encoder_config_handler_init(gpointer g_iface,
+        gpointer iface_data);
+static gint gst_get_speech_encoder_bit_rate(guint* aBitrate);
+static gint gst_get_speech_encoder_supported_bit_rates(
+        GList** aSupportedBitrates);
+static gint gst_get_speech_encoder_vad_mode(gboolean* aVadMode);
+static gint gst_set_speech_encoder_bit_rate(guint aBitrate);
+static gint gst_set_speech_encoder_vad_mode(gboolean aVadMode);
+static void gst_Apply_SpeechEncoder_Update(GstDevsoundSrc *devsoundsrc );
+
+
+/*************************
+ * G711 Encoder Interface
+ * ***********************/
+static void gst_g711_encoder_handler_init(gpointer g_iface,
+        gpointer iface_data);
+static gint gst_get_g711_encoder_vad_mode(gboolean* aVadMode);
+static gint gst_set_g711_encoder_mode(enum TG711EncodeMode aEncodeMode);
+static gint gst_set_g711_vad_mode(gboolean aVadMode);
+static void gst_Apply_G711Encoder_Update(GstDevsoundSrc *devsoundsrc );
+
+
+/*************************
+ * 729 Encoder Interface
+ * ***********************/
+static void gst_g729_encoder_handler_init(gpointer g_iface,
+        gpointer iface_data);
+static gint gst_set_g729_vad_mode(TBool aVadMode);
+static gint gst_get_g729_vad_mode(TBool* aVadMode);
+static void gst_Apply_G729Encoder_Update(GstDevsoundSrc *devsoundsrc );
+
+
+/*************************
+ * ilbc Encoder Interface
+ * ***********************/
+static void gst_ilbc_encoder_handler_init(gpointer g_iface,
+        gpointer iface_data);
+static gint gst_set_ilbc_encoder_mode(enum TIlbcEncodeMode aEncodeMode);
+static gint gst_set_ilbc_vad_mode(gboolean aVadMode);
+static gint gst_get_ilbc_vad_mode(gboolean* aVadMode);
+static void gst_Apply_IlbcEncoder_Update(GstDevsoundSrc *devsoundsrc );
+
+
+static gint gst_devsound_src_get_rate(gint rate);
+
+
+typedef struct _GstCustomIfaceUpdate GstCustomIfaceUpdate;
+
+struct _GstCustomIfaceUpdate{
+gboolean  speechbitrateupdate;
+gboolean  speechvadmodeupdate;
+gboolean  g711encodermodeupdate;
+gboolean  g711vadmodeupdate;
+gboolean  g729vadmodeupdate;
+gboolean  ilbcencodermodeupdate;
+gboolean  ilbcvadmodeupdate;
+};
+GstCustomIfaceUpdate customInfaceUpdate = {0,0,0,0,0,0,0};
+
+guint speechbitrate;
+gboolean speechvadmode;
+enum TG711EncodeMode g711encodemode;
+gboolean g711vadmode;
+GList* supportedbitrates;
+gint numofbitrates;
+gboolean g729vadmode;
+enum TIlbcEncodeMode ilbcencodemode;
+gboolean ilbcvadmode;
+
+pthread_t ds_thread;
+pthread_mutex_t create_mutex1;
+pthread_cond_t create_condition1;
+
+enum consumer_thread_state_enum {
+   CONSUMER_THREAD_UNINITIALIZED,
+   CONSUMER_THREAD_INITIALIZING,
+   CONSUMER_THREAD_INITIALIZED
+};
+enum consumer_thread_state_enum consumer_thread_state;
+
+
+
+GQueue* dataqueue= NULL;
+GstBuffer* popBuffer= NULL;
+int dataleft = 0;
+int dataCopied = 0;
+
+enum command_to_consumer_thread_enum
+    {
+    OPEN = 2,
+    READDATA,
+    /*UPDATE,*/
+    CLOSE
+    };
+enum command_to_consumer_thread_enum cmd;
+
+enum
+    {
+    LAST_SIGNAL
+    };
+
+#define DEFAULT_DEVICE  "default"
+
+enum
+    {
+    PROP_0,
+    PROP_DEVICE,
+    GAIN,
+    MAXGAIN,
+    CHANNELS,
+    LEFTBALANCE,
+    RIGHTBALANCE,
+    RATE,
+    PRIORITY,
+    PREFERENCE,
+    SAMPLESRECORDED
+    };
+
+static GstStaticPadTemplate devsound_src_factory=
+    GST_STATIC_PAD_TEMPLATE ("src",
+        GST_PAD_SRC,
+        GST_PAD_ALWAYS,
+        GST_STATIC_CAPS ("audio/x-raw-int, "
+                "endianness = (int) { " G_STRINGIFY (G_BYTE_ORDER) " }, "
+                "signed = (boolean) TRUE, "
+                "width = (int) 16, "
+                "depth = (int) 16, "
+                "rate = (int) [ 8000, 48000 ],"
+                "channels = (int) [ 1, 2 ]; "
+                "audio/amr, "
+                "rate = (int) [ 8000, 48000 ], "
+                "channels = (int) [ 1, 2 ]; "
+                "audio/x-alaw, "
+                "rate = (int) [ 8000, 48000 ], "
+                "channels = (int) [ 1, 2 ]; "
+                "audio/g729, "
+                "rate = (int) [ 8000, 48000 ], "
+                "channels = (int) [ 1, 2 ]; "
+                "audio/ilbc, "
+                "rate = (int) [ 8000, 48000 ], "
+                "channels = (int) [ 1, 2 ]; "
+                "audio/x-mulaw, "
+                "rate = (int) [ 8000, 48000 ], "
+                "channels = (int) [ 1, 2 ]")
+                );
+
+static GstElementClass *parent_class= NULL;
+
+static void gst_devsound_src_base_init(gpointer g_class)
+    {
+    GstElementClass *element_class= GST_ELEMENT_CLASS (g_class);
+
+    gst_element_class_set_details(element_class, &gst_devsound_src_details);
+
+    gst_element_class_add_pad_template(element_class,
+            gst_static_pad_template_get(&devsound_src_factory));
+    }
+
+GType gst_devsound_src_get_type(void)
+    {
+    static GType devsoundsrc_type = 0;
+
+    if (!devsoundsrc_type)
+        {
+        static const GTypeInfo devsoundsrc_info =
+            {
+            sizeof(GstDevsoundSrcClass), gst_devsound_src_base_init, NULL,
+                    (GClassInitFunc) gst_devsound_src_class_init, NULL, NULL,
+                    sizeof(GstDevsoundSrc), 0,
+                    (GInstanceInitFunc) gst_devsound_src_init
+,        };
+
+    static const GInterfaceInfo speech_encoder_config_info =
+        {
+        gst_speech_encoder_config_handler_init,
+        NULL,
+        NULL
+        };
+
+    static const GInterfaceInfo g711_encoder_info =
+        {
+        gst_g711_encoder_handler_init,
+        NULL,
+        NULL
+        };
+
+    static const GInterfaceInfo g729_encoder_info =
+         {
+         gst_g729_encoder_handler_init,
+         NULL,
+         NULL
+         };
+
+    static const GInterfaceInfo ilbc_encoder_info =
+         {
+         gst_ilbc_encoder_handler_init,
+         NULL,
+         NULL
+         };
+
+    devsoundsrc_type =
+    g_type_register_static (GST_TYPE_PUSH_SRC, "GstDevsoundSrc",
+            &devsoundsrc_info, 0);
+
+    g_type_add_interface_static (devsoundsrc_type, GST_TYPE_SPEECH_ENCODER_CONFIG,
+            &speech_encoder_config_info);
+
+    g_type_add_interface_static (devsoundsrc_type, GST_TYPE_G711_ENCODER,
+            &g711_encoder_info);
+
+    g_type_add_interface_static (devsoundsrc_type, GST_TYPE_G729_ENCODER,
+              &g729_encoder_info);
+
+    g_type_add_interface_static (devsoundsrc_type, GST_TYPE_ILBC_ENCODER,
+              &ilbc_encoder_info);
+
+    }
+
+return devsoundsrc_type;
+}
+
+static void gst_devsound_src_dispose(GObject * object)
+    {
+    GstDevsoundSrc *devsoundsrc= GST_DEVSOUND_SRC (object);
+    G_OBJECT_CLASS (parent_class)->dispose (object);
+    }
+
+static void gst_devsound_src_class_init(GstDevsoundSrcClass * klass)
+    {
+    GObjectClass *gobject_class;
+    GstElementClass *gstelement_class;
+    GstBaseSrcClass *gstbasesrc_class;
+    GstPushSrcClass *gstpushsrc_class;
+
+    gobject_class = (GObjectClass *) klass;
+    gstelement_class = (GstElementClass *) klass;
+    gstbasesrc_class = (GstBaseSrcClass *) klass;
+    gstpushsrc_class = (GstPushSrcClass *) klass;
+
+    parent_class = g_type_class_peek_parent(klass);
+
+    gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_devsound_src_dispose);
+    gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_devsound_src_get_property);
+    gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_devsound_src_set_property);
+
+    g_object_class_install_property(gobject_class, PROP_DEVICE,
+            g_param_spec_string("device", "Device", "Devsound device ",
+                    DEFAULT_DEVICE, G_PARAM_READWRITE));
+
+    g_object_class_install_property(gobject_class, GAIN, g_param_spec_int(
+            "gain", "Gain", "Devsound src gain", -1, G_MAXINT, -1,
+            G_PARAM_READWRITE));
+
+    g_object_class_install_property(gobject_class, MAXGAIN, g_param_spec_int(
+            "maxgain", "MaxGain", "Devsound src max gain", -1, G_MAXINT, -1,
+            G_PARAM_READABLE));
+
+    g_object_class_install_property(gobject_class, LEFTBALANCE,
+            g_param_spec_int("leftbalance", "Left Balance", "Left Balance",
+                    -1, G_MAXINT, -1, G_PARAM_READWRITE));
+
+    g_object_class_install_property(gobject_class, RIGHTBALANCE,
+            g_param_spec_int("rightbalance", "Right Balance",
+                    "Right Balance", -1, G_MAXINT, -1, G_PARAM_READWRITE));
+
+    g_object_class_install_property(gobject_class, SAMPLESRECORDED,
+            g_param_spec_int("samplesrecorded", "Samples Recorded",
+                    "Samples Recorded", -1, G_MAXINT, -1, G_PARAM_READABLE));
+
+    g_object_class_install_property(gobject_class, PRIORITY,
+            g_param_spec_int("priority", "Priority", "Priority ", -1,
+            G_MAXINT, -1,
+            G_PARAM_READWRITE));
+
+    g_object_class_install_property(gobject_class, PREFERENCE,
+            g_param_spec_int("preference", "Preference", "Preference ", -1,
+            G_MAXINT, -1,
+            G_PARAM_READWRITE));
+
+    g_object_class_install_property(gobject_class, RATE,
+            g_param_spec_int("rate", "Rate", "Rate ", -1,
+                    G_MAXINT, -1,
+                    G_PARAM_READWRITE));
+
+    g_object_class_install_property(gobject_class, CHANNELS,
+            g_param_spec_int("channels", "Channels", "Channels ", -1,
+                    G_MAXINT, -1,
+                    G_PARAM_READWRITE));
+    gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_devsound_src_start);
+    gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_devsound_src_stop);
+    gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_devsound_src_getcaps);
+    gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_devsound_src_setcaps);
+
+    gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_devsound_src_create);
+    }
+
+static void gst_devsound_src_init(GstDevsoundSrc * devsoundsrc)
+    {
+    GST_DEBUG_OBJECT(devsoundsrc, "initializing devsoundsrc");
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "gst_devsound_src_init ENTER ",NULL);
+    devsoundsrc->device = g_strdup(DEFAULT_DEVICE);
+    devsoundsrc->handle=NULL;
+    devsoundsrc->preference = 0; //default=>EMdaPriorityPreferenceNone;
+    devsoundsrc->priority = 0;   //default=>EMdaPriorityNormal;
+    pthread_mutex_init(&create_mutex1, NULL);
+    pthread_cond_init(&create_condition1, NULL);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "gst_devsound_src_init EXIT ",NULL);
+    }
+
+static void *StartDevSoundThread(void *threadarg)
+    {
+    GstDevsoundSrc *devsoundsrc= GST_DEVSOUND_SRC (threadarg);
+    int buffersize;
+    TUint8* gBuffer;
+    GstBuffer* pushBuffer= NULL;
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "StartDevSoundThread ",NULL);
+    open_devsound(&(devsoundsrc->handle));
+
+    getsupporteddatatypes(devsoundsrc);
+
+// TODO obtain mutex to update variable here???
+    consumer_thread_state = CONSUMER_THREAD_INITIALIZED;
+	
+    //pre_init_setconf(devsoundsrc);
+
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "After Record Init ",NULL);
+
+    pthread_mutex_lock(&(create_mutex1));
+    pthread_cond_signal(&(create_condition1));
+    pthread_mutex_unlock(&(create_mutex1));
+
+    // Wait until we receive a command from the main thread
+    // TODO obtain mutex to read variable here???
+    while ( cmd == OPEN )
+        {
+        pthread_mutex_lock(&create_mutex1);
+        pthread_cond_wait(&create_condition1, &create_mutex1);
+        pthread_mutex_unlock(&create_mutex1);
+        }
+
+    // This could happen if client creates sink and deletes it
+    // without putting it to play state
+    if ( cmd != CLOSE )
+        {
+        initialize_devsound(devsoundsrc);
+    
+        recordinit(devsoundsrc->handle);
+        initproperties(devsoundsrc);
+        }
+    //cmd = READDATA;
+    while (1)
+        {
+        //set/get properties
+        //***************************************
+        pre_init_setconf(devsoundsrc);
+        gst_Apply_SpeechEncoder_Update(devsoundsrc);
+        gst_Apply_G711Encoder_Update(devsoundsrc);
+        gst_Apply_G729Encoder_Update(devsoundsrc );
+        gst_Apply_IlbcEncoder_Update(devsoundsrc );
+
+        populateproperties(devsoundsrc);
+
+        supportedbitrates = devsoundsrc->supportedbitrates;
+        //numofbitrates = devsoundsrc->numofbitrates;
+        speechbitrate = devsoundsrc->speechbitrate;
+        speechvadmode = devsoundsrc->speechvadmode;
+        g711vadmode = devsoundsrc->g711vadmode;
+        g729vadmode  = devsoundsrc->g729vadmode;
+        ilbcvadmode = devsoundsrc->ilbcvadmode;
+
+
+        //****************************************
+        //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "Before Buffer Alloc ",NULL);
+        buffersize = get_databuffer_size(devsoundsrc->handle);
+        get_databuffer(devsoundsrc->handle, &gBuffer);
+        pushBuffer = gst_buffer_new_and_alloc(buffersize);
+        //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "After Buffer Alloc ",NULL);
+        if (GST_BUFFER_DATA(pushBuffer))
+            {
+            memcpy(GST_BUFFER_DATA(pushBuffer),gBuffer,buffersize);
+            }
+        else
+            {
+            //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "Push buffer alloc failed ",NULL);
+            }
+
+        if (dataqueue)
+            {
+            GST_OBJECT_LOCK(devsoundsrc);
+            g_queue_push_head (dataqueue,pushBuffer);
+            GST_OBJECT_UNLOCK(devsoundsrc);
+            //signalmutex_create(devsoundsrc->handle);
+            if(dataqueue->length == 1 && (cmd != CLOSE))
+                {
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "Before signal in DevSoundt ",NULL);
+                pthread_mutex_lock(&(create_mutex1));
+                pthread_cond_signal(&(create_condition1));
+                pthread_mutex_unlock(&(create_mutex1));
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "After signal in DevSoundt ",NULL);
+                }
+            //cmd = READDATA;
+            //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "Before DevSnd Wait ",NULL);
+            //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "After DevSnd Wait ",NULL);
+           }
+        else
+            {
+            //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "dataqueue is NULL, CLOSE now ",NULL);
+            cmd = CLOSE;
+            }
+
+        switch (cmd)
+            {
+            case READDATA:
+                {
+                record_data(devsoundsrc->handle);
+                }
+                break;
+            case CLOSE:
+                {
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "Before Close DevSound ",NULL);
+                close_devsound(devsoundsrc);
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "After Close DevSound ",NULL);
+                devsoundsrc->handle= NULL;
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "After handle NULL ",NULL);
+
+                pthread_mutex_lock(&(create_mutex1));
+                pthread_cond_signal(&(create_condition1));
+                pthread_mutex_unlock(&(create_mutex1));
+				// TODO obtain mutex here
+                consumer_thread_state = CONSUMER_THREAD_UNINITIALIZED;
+                pthread_exit(NULL);
+                }
+                break;
+            default:
+                // TODO obtain mutex here
+                consumer_thread_state = CONSUMER_THREAD_UNINITIALIZED;			
+                pthread_exit(NULL);
+                break;
+            }
+        }
+    // TODO obtain mutex here
+    consumer_thread_state = CONSUMER_THREAD_UNINITIALIZED;
+    pthread_exit(NULL);
+    }
+
+static void gst_devsound_src_set_property(GObject * object, guint prop_id,
+        const GValue * value, GParamSpec * pspec)
+    {
+    GstDevsoundSrc *src;
+
+    src = GST_DEVSOUND_SRC (object);
+
+    switch (prop_id)
+        {
+        case PROP_DEVICE:
+            if (src->device)
+                g_free(src->device);
+            src->device = g_value_dup_string(value);
+            if (src->probed_caps)
+                {
+                gst_caps_unref(src->probed_caps);
+                src->probed_caps = NULL;
+                }
+            break;
+        case CHANNELS:
+            src->channels = g_value_get_int(value);
+            src->pending.channelsupdate = TRUE;
+            break;
+        case RATE:
+            src->rate = g_value_get_int(value);
+            //Convert rate to something devsound understands
+            src->rate = gst_devsound_src_get_rate(src->rate);
+            src->pending.rateupdate = TRUE;
+            break;
+        case GAIN:
+            src->gain = g_value_get_int(value);
+            src->pending.gainupdate = TRUE;
+            break;
+        case LEFTBALANCE:
+            src->leftbalance = g_value_get_int(value);
+            src->pending.leftbalanceupdate = TRUE;
+            break;
+        case RIGHTBALANCE:
+            src->rightbalance = g_value_get_int(value);
+            src->pending.rightbalanceupdate = TRUE;
+            break;
+        case PRIORITY:
+            src->priority = g_value_get_int(value);
+            src->pending.priorityupdate = TRUE;
+            break;
+        case PREFERENCE:
+            src->preference = g_value_get_int(value);
+            src->pending.preferenceupdate = TRUE;
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+        }
+    }
+
+static void gst_devsound_src_get_property(GObject * object, guint prop_id,
+        GValue * value, GParamSpec * pspec)
+    {
+    GstDevsoundSrc *src;
+
+    src = GST_DEVSOUND_SRC (object);
+
+    switch (prop_id)
+        {
+        case PROP_DEVICE:
+            g_value_set_string(value, src->device);
+            break;
+        case CHANNELS:
+            g_value_set_int(value, src->channels);
+            break;
+        case RATE:
+            g_value_set_int(value, src->rate);
+            break;
+        case GAIN:
+            g_value_set_int(value, src->gain);
+            break;
+        case MAXGAIN:
+            g_value_set_int(value, src->maxgain);
+            break;
+        case SAMPLESRECORDED:
+            g_value_set_int(value, src->samplesrecorded);
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+        }
+    }
+
+static gboolean gst_devsound_src_setcaps(GstBaseSrc *bsrc, GstCaps *caps)
+    {
+    GstDevsoundSrc *devsoundsrc;
+    GstStructure *structure;
+    const gchar *mimetype;
+    int rate;
+    int channel;
+
+    devsoundsrc = GST_DEVSOUND_SRC (bsrc);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "gst_devsound_src_setcaps ENTER ",NULL);
+    structure = gst_caps_get_structure(caps, 0);
+    mimetype = gst_structure_get_name(structure);
+
+    gst_structure_get_int(structure, "rate", &rate);
+    gst_structure_get_int(structure, "channels", &channel);
+
+    devsoundsrc->rate = gst_devsound_src_get_rate(rate);
+    devsoundsrc->channels = channel;
+
+    set_channels(devsoundsrc->handle, devsoundsrc->channels);
+
+    set_rate(devsoundsrc->handle, devsoundsrc->rate);
+
+    if (!strncmp(mimetype, "audio/x-raw-int", 15))
+        {
+        devsoundsrc->fourcc = 0x36315020; //KMMFFourCCCodePCM16
+        }
+    else if (!strncmp(mimetype, "audio/amr", 9))
+        {
+        devsoundsrc->fourcc = 0x524d4120; //KMMFFourCCCodeAMR
+        }
+    else if (!strncmp(mimetype, "audio/x-mulaw", 13)||
+             !strncmp(mimetype,"audio/x-alaw", 12))
+        {
+        devsoundsrc->fourcc = 0x31313747; //KMccFourCCIdG711
+        }
+    else if (!strncmp(mimetype, "audio/ilbc", 10))
+        {
+        devsoundsrc->fourcc = 0x43424c49; //KMccFourCCIdILBC
+        }
+    else if (!strncmp(mimetype, "audio/g729", 10))
+        {
+        devsoundsrc->fourcc = 0x39323747; //KMccFourCCIdG729
+        }
+    else
+        {
+        devsoundsrc->fourcc = 0x36315020; //KMMFFourCCCodePCM16
+        }
+
+    set_fourcc(devsoundsrc->handle, devsoundsrc->fourcc);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "Before Signal DevSound from STOP",NULL);
+    pthread_mutex_lock(&(create_mutex1));
+    pthread_cond_signal(&(create_condition1));
+    pthread_mutex_unlock(&(create_mutex1));
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "After Signal DevSound from STOP ",NULL);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) devsoundsrc, "gst_devsound_src_setcaps EXIT ",NULL);
+    return TRUE;
+    }
+
+static GstCaps * gst_devsound_src_getcaps(GstBaseSrc * bsrc)
+    {
+    GstDevsoundSrc *devsoundsrc;
+    GstCaps *caps;
+    GstPadTemplate *pad_template;
+
+    devsoundsrc = GST_DEVSOUND_SRC (bsrc);
+
+    GST_DEBUG_OBJECT(devsoundsrc, "getcaps called");
+
+    pad_template = gst_static_pad_template_get(&devsound_src_factory);
+    caps = gst_caps_copy(gst_pad_template_get_caps(pad_template));
+
+    gst_object_unref(pad_template);
+
+    return caps;
+    }
+
+static gboolean gst_devsound_src_start(GstBaseSrc * bsrc)
+    {
+    GstBuffer *tmp_gstbuffer=NULL;	
+    GstDevsoundSrc *src= GST_DEVSOUND_SRC(bsrc);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "gst_devsound_src_start ENTER ",NULL);
+
+    if(dataqueue)
+        {
+        while (dataqueue->length)
+            {
+            tmp_gstbuffer = (GstBuffer*)g_queue_pop_tail(dataqueue);
+            gst_buffer_unref(tmp_gstbuffer);
+            }
+        g_queue_free(dataqueue);
+        dataqueue = NULL;
+        }
+    
+    if(dataqueue == NULL)
+          {
+          dataqueue = g_queue_new();
+          }
+
+    consumer_thread_state = CONSUMER_THREAD_INITIALIZING;
+    cmd = OPEN;
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "Before Thread Create ",NULL);
+    pthread_create(&ds_thread, NULL, StartDevSoundThread, (void *)src);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "After Thread Create ",NULL);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "Before Mutex Wait in START ",NULL);
+    if (consumer_thread_state == CONSUMER_THREAD_INITIALIZING)
+        {
+        pthread_mutex_lock(&create_mutex1);
+        pthread_cond_wait(&create_condition1, &create_mutex1);
+        pthread_mutex_unlock(&create_mutex1);
+        }
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "AFter Mutex Wait in START ",NULL);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "gst_devsound_src_start EXIT ",NULL);
+    return TRUE;
+    /* ERRORS */
+    }
+
+static gboolean gst_devsound_src_stop(GstBaseSrc * bsrc)
+    {
+	
+    GstDevsoundSrc *src= GST_DEVSOUND_SRC(bsrc);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "gst_devsound_src_stop ENTER ");
+    cmd = CLOSE;
+
+    //GST_OBJECT_LOCK (src);
+    pthread_mutex_lock(&(create_mutex1));
+    pthread_cond_wait(&(create_condition1), &(create_mutex1));
+    pthread_mutex_unlock(&(create_mutex1));
+    //GST_OBJECT_UNLOCK (src);
+
+    if (popBuffer)
+        {
+        gst_buffer_unref(popBuffer);
+        popBuffer = NULL;
+        dataleft = 0;   //Arun'S changes
+        }
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "Before QUEUE Lock in STOP ");
+    GST_OBJECT_LOCK(src);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "After QUEUE Lock in STOP ");
+    while (dataqueue->length)
+        {
+        //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "Removing DATAQUEUE elements ENTER ");
+        popBuffer = (GstBuffer*)g_queue_pop_tail(dataqueue);
+        gst_buffer_unref(popBuffer);
+        popBuffer = NULL;
+        dataleft = 0; //Arun'S changes
+        //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "Removing DATAQUEUE elements EXIT ");
+        }
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "Before Queue FREE ");
+    g_queue_free(dataqueue);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "After Queue FREE ");
+    dataqueue = NULL;
+    GST_OBJECT_UNLOCK(src);
+
+    pthread_mutex_destroy(&create_mutex1);
+    pthread_cond_destroy(&(create_condition1));
+
+
+    g_free(src->device);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "gst_devsound_src_stop EXIT ");
+    return TRUE;
+    }
+
+static gboolean gst_devsound_src_unlock(GstBaseSrc * bsrc)
+    {
+    GstDevsoundSrc *src= GST_DEVSOUND_SRC(bsrc);
+
+    GST_LOG_OBJECT(src, "Flushing");
+    GST_OBJECT_LOCK (src);
+    GST_OBJECT_UNLOCK (src);
+
+    return TRUE;
+    }
+
+static gboolean gst_devsound_src_unlock_stop(GstBaseSrc * bsrc)
+    {
+    GstDevsoundSrc *src= GST_DEVSOUND_SRC(bsrc);
+
+    GST_LOG_OBJECT(src, "No longer flushing");
+    return TRUE;
+    }
+
+static GstFlowReturn gst_devsound_src_create(GstBaseSrc *src, guint64 offset,
+        guint size, GstBuffer **buf)
+    {
+    GstDevsoundSrc *dsrc= GST_DEVSOUND_SRC(src);
+    int bufferpos=0;
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "gst_devsound_src_create ENTER ");
+
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "Before Buffer Alloc in CREATE ",NULL);
+    *buf = gst_buffer_try_new_and_alloc(size);
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "AFter Buffer Alloc in CREATE ",NULL);
+
+    while (size > 0)
+        {
+        if (dataleft >= size)
+            {
+            // if there is some data left in the popped buffer previously whose size
+            // is more then the buffer which is incoming fresh to get filled, fill it
+            //here. and if the data left in the popped buffer is 0, then unref it
+            //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "dataleft >=size in CREATE ", NULL);
+            memcpy(GST_BUFFER_DATA(*buf)+bufferpos,GST_BUFFER_DATA(popBuffer)+dataCopied,size);
+            bufferpos+=size;
+            dataCopied += size;
+            dataleft = GST_BUFFER_SIZE(popBuffer) - dataCopied;
+            size = 0;
+            if (dataleft == 0)
+                {
+                dataCopied = 0;
+                gst_buffer_unref(popBuffer);
+                popBuffer = NULL;
+                }
+            }
+        else
+            {
+            // if the dataleft in the popped buffer is greater then 0 and  less then
+            // the size of data needed for the fresh buffer. copy the remaining data
+            // from the popped buffer and then unref it.
+            if (dataleft > 0)
+                {
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "dataleft >0 in CREATE ",NULL);
+                memcpy(GST_BUFFER_DATA(*buf)+bufferpos,GST_BUFFER_DATA(popBuffer)+dataCopied,dataleft);
+                size -= dataleft;
+                bufferpos += dataleft;
+                dataCopied = 0;
+                dataleft = 0;
+                gst_buffer_unref(popBuffer);
+                popBuffer = NULL;
+                }
+
+            // we wait here if the dataqueue length is 0 and we need data
+            // to be filled in the queue from the DevSound Thread
+            if (!dataqueue->length)
+                {
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "Before WAIT in CREATE ",NULL);
+                cmd = READDATA;
+                pthread_mutex_lock(&(create_mutex1));
+                pthread_cond_signal(&(create_condition1));
+                pthread_mutex_unlock(&(create_mutex1));
+                
+                pthread_mutex_lock(&(create_mutex1));
+                pthread_cond_wait(&(create_condition1), &(create_mutex1));
+                pthread_mutex_unlock(&(create_mutex1));
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "AFTER WAIT in CREATE ",NULL);
+                }
+
+            //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "Before POP in CREATE ",NULL);
+            GST_OBJECT_LOCK(dsrc);
+            popBuffer = (GstBuffer*)g_queue_pop_tail(dataqueue);
+            GST_OBJECT_UNLOCK(dsrc);
+            //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "AFTER POP in CREATE ",NULL);
+
+            // copy the data from the popped buffer based on how much of the incoming
+            //buffer size is left to fill. we might have filled the fresh buffer somewhat
+            // where the size of the fresh buffer is more then the data remaining in the
+            // popped buffer.
+            if (size < GST_BUFFER_SIZE(popBuffer))
+                {
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "SIZE < POPBUFFER CREATE ",NULL);
+                memcpy(GST_BUFFER_DATA(*buf)+ bufferpos,GST_BUFFER_DATA(popBuffer),size);
+                bufferpos+=size;
+                dataCopied = size;
+                dataleft = GST_BUFFER_SIZE(popBuffer) - dataCopied;
+                size = 0;
+                }
+            else
+                {
+                //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "SIZE >= POPBUFFER CREATE ",NULL);
+                memcpy(GST_BUFFER_DATA(*buf)+ bufferpos,GST_BUFFER_DATA(popBuffer),GST_BUFFER_SIZE(popBuffer));
+                bufferpos+=GST_BUFFER_SIZE(popBuffer);
+                dataCopied = 0;
+                dataleft = 0;
+                size = size - GST_BUFFER_SIZE(popBuffer);
+                }
+
+            if (!dataleft)
+                {
+                gst_buffer_unref(popBuffer);
+                popBuffer = NULL;
+                }
+            }
+        }
+    //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) dsrc, "gst_devsound_src_create EXIT ",NULL);
+    return GST_FLOW_OK;
+    }
+
+static gboolean gst_devsound_src_is_seekable(GstBaseSrc * bsrc)
+    {
+    GstDevsoundSrc *src= GST_DEVSOUND_SRC(bsrc);
+    return FALSE;
+    }
+
+static gboolean gst_devsound_src_get_size(GstBaseSrc * bsrc, guint64 * size)
+    {
+    GstDevsoundSrc *src= GST_DEVSOUND_SRC(bsrc);
+    return TRUE;
+    }
+
+static void gst_speech_encoder_config_handler_init(gpointer g_iface,
+        gpointer iface_data)
+    {
+    GstSpeechEncoderConfigIntfc *iface =
+            (GstSpeechEncoderConfigIntfc *) g_iface;
+
+    iface->GetBitrate = gst_get_speech_encoder_bit_rate;
+    iface->GetSupportedBitrates = gst_get_speech_encoder_supported_bit_rates;
+    iface->GetVadMode = gst_get_speech_encoder_vad_mode;
+    iface->SetBitrate = gst_set_speech_encoder_bit_rate;
+    iface->SetVadMode = gst_set_speech_encoder_vad_mode;
+
+    }
+
+static gint gst_get_speech_encoder_bit_rate(guint* aBitrate)
+    {
+    *aBitrate = speechbitrate;
+    return 0;
+    }
+static gint gst_get_speech_encoder_supported_bit_rates(
+        GList** aSupportedBitrate)
+    {
+    *aSupportedBitrate = supportedbitrates;
+    return 0;
+    }
+static gint gst_get_speech_encoder_vad_mode(gboolean* aVadMode)
+    {
+    *aVadMode = speechvadmode;
+    return 0;
+    }
+static gint gst_set_speech_encoder_bit_rate(guint aBitrate)
+    {
+    speechbitrate = aBitrate;
+    customInfaceUpdate.speechbitrateupdate = TRUE;
+    return 0;
+    }
+
+static gint gst_set_speech_encoder_vad_mode(gboolean aVadMode)
+    {
+    speechvadmode = aVadMode;
+    customInfaceUpdate.speechvadmodeupdate = TRUE;
+    return 0;
+    }
+
+
+static void gst_Apply_SpeechEncoder_Update(GstDevsoundSrc *devsoundsrc )
+    {
+    if(customInfaceUpdate.speechbitrateupdate == TRUE)
+        {
+        set_speech_encoder_bit_rate(devsoundsrc->handle,speechbitrate);
+        customInfaceUpdate.speechbitrateupdate = FALSE;
+        }
+    if(customInfaceUpdate.speechvadmodeupdate == TRUE)
+        {
+        set_speech_encoder_vad_mode(devsoundsrc->handle,speechvadmode);
+        customInfaceUpdate.speechvadmodeupdate = FALSE;
+        }
+    }
+
+static void gst_g711_encoder_handler_init(gpointer g_iface,
+        gpointer iface_data)
+    {
+    GstG711EncoderIntfc *iface = (GstG711EncoderIntfc *) g_iface;
+
+    iface->GetVadMode = gst_get_g711_encoder_vad_mode;
+    iface->SetEncoderMode = gst_set_g711_encoder_mode;
+    iface->SetVadMode = gst_set_g711_vad_mode;
+
+    }
+
+static gint gst_get_g711_encoder_vad_mode(gboolean* aVadMode)
+    {
+    *aVadMode = g711vadmode;
+    return 0;
+    }
+
+static gint gst_set_g711_encoder_mode(enum TG711EncodeMode aEncodeMode)
+    {
+    g711encodemode = aEncodeMode;
+    customInfaceUpdate.g711encodermodeupdate = TRUE;
+    return 0;
+    }
+static gint gst_set_g711_vad_mode(gboolean aVadMode)
+    {
+    g711vadmode = aVadMode;
+    customInfaceUpdate.g711vadmodeupdate = TRUE;
+    return 0;
+    }
+
+
+static void gst_Apply_G711Encoder_Update(GstDevsoundSrc *devsoundsrc )
+    {
+
+    if(customInfaceUpdate.g711encodermodeupdate == TRUE)
+        {
+        set_g711_encoder_mode(devsoundsrc->handle,g711encodemode);
+        customInfaceUpdate.g711encodermodeupdate = FALSE;
+        }
+    if(customInfaceUpdate.g711vadmodeupdate == TRUE)
+        {
+        set_g711_vad_mode(devsoundsrc->handle,g711vadmode);
+        customInfaceUpdate.g711vadmodeupdate = FALSE;
+        }
+    }
+
+static void gst_g729_encoder_handler_init(gpointer g_iface,
+        gpointer iface_data)
+    {
+
+    GstG729EncoderIntfc *iface = (GstG729EncoderIntfc *) g_iface;
+
+    iface->GetVadMode = gst_get_g729_vad_mode;
+    iface->SetVadMode = gst_set_g729_vad_mode;
+
+    }
+
+static gint gst_set_g729_vad_mode(TBool aVadMode)
+    {
+    g729vadmode = aVadMode;
+    customInfaceUpdate.g729vadmodeupdate = TRUE;
+    return 0;
+    }
+
+static gint gst_get_g729_vad_mode(TBool* aVadMode)
+    {
+    *aVadMode = g729vadmode;
+    return 0;
+    }
+static void gst_Apply_G729Encoder_Update(GstDevsoundSrc *devsoundsrc )
+    {
+    if(customInfaceUpdate.g729vadmodeupdate)
+        {
+        set_g729_vad_mode(devsoundsrc->handle,g729vadmode);
+        customInfaceUpdate.g729vadmodeupdate = FALSE;
+        }
+
+    }
+
+static void gst_ilbc_encoder_handler_init(gpointer g_iface,
+        gpointer iface_data)
+    {
+    GstIlbcEncoderIntfc *iface = (GstIlbcEncoderIntfc *) g_iface;
+
+    iface->GetVadMode = gst_get_ilbc_vad_mode;
+    iface->SetEncoderMode = gst_set_ilbc_encoder_mode;
+    iface->SetVadMode = gst_set_ilbc_vad_mode;
+    }
+
+static gint gst_set_ilbc_encoder_mode(enum TIlbcEncodeMode aEncodeMode)
+    {
+    ilbcencodemode = aEncodeMode;
+    return 0;
+    }
+
+static gint gst_set_ilbc_vad_mode(gboolean aVadMode)
+    {
+    ilbcvadmode = aVadMode;
+    return 0;
+    }
+
+static gint gst_get_ilbc_vad_mode(gboolean* aVadMode)
+    {
+    *aVadMode = ilbcvadmode;
+    return 0;
+    }
+
+static void gst_Apply_IlbcEncoder_Update(GstDevsoundSrc *devsoundsrc )
+    {
+    if(customInfaceUpdate.ilbcencodermodeupdate)
+        {
+        set_ilbc_encoder_mode(devsoundsrc->handle,ilbcencodemode);
+        customInfaceUpdate.ilbcencodermodeupdate = FALSE;
+        }
+    if(customInfaceUpdate.ilbcvadmodeupdate)
+         {
+         set_ilbc_vad_mode(devsoundsrc->handle,ilbcvadmode);
+         customInfaceUpdate.ilbcvadmodeupdate = FALSE;
+         }
+
+    }
+
+static gint gst_devsound_src_get_rate(gint rate)
+    {
+    gint result;
+
+    switch (rate)
+        {
+        case 8000:
+            result=0x00000001;//EMMFSampleRate8000Hz;
+            break;
+        case 11025:
+            result=0x00000002;//EMMFSampleRate11025Hz;
+            break;
+        case 16000:
+            result=0x00000004;//EMMFSampleRate16000Hz;
+            break;
+        case 22050:
+            result=0x00000008;//EMMFSampleRate22050Hz;
+            break;
+        case 32000:
+            result=0x00000010;//EMMFSampleRate32000Hz;
+            break;
+        case 44100:
+            result=0x00000020;//EMMFSampleRate44100Hz;
+            break;
+        case 48000:
+            result=0x00000040;//EMMFSampleRate48000Hz;
+            break;
+        case 88200:
+            result=0x00000080;//EMMFSampleRate88200Hz;
+            break;
+        case 96000:
+            result= 0x00000100;//EMMFSampleRate96000Hz;
+            break;
+        case 12000:
+            result=0x00000200;//EMMFSampleRate12000Hz;
+            break;
+        case 24000:
+            result=0x00000400;//EMMFSampleRate24000Hz;
+            break;
+        case 64000:
+            result=0x00000800; //EMMFSampleRate64000Hz;
+            break;
+        default:
+            result=0x00000001;//EMMFSampleRate8000Hz;
+            break;
+
+        }
+    return result;
+
+    }
+