Revision: 201007
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Mar 2010 09:35:09 +0200
changeset 7 71e347f905f2
parent 2 5505e8908944
child 8 4a7fac7dd34a
Revision: 201007 Kit: 201011
data/Create_GStreamer_STUB_SIS.bat
data/Gstreamer_Stub.pkg
gst_plugins_good/group/gstcamerabin.mmp
gst_plugins_good/group/gstphotography.mmp
gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp
gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.h
gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.cpp
gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.h
gst_plugins_symbian/gst/devsound/gstdevsoundsink.c
gst_plugins_symbian/gst/devsound/gstdevsoundsink.h
gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c
gst_plugins_symbian/gst/devsound/gstdevsoundsrc.h
gstreamer_core/gst/gstinterface.h
gstregistrygenerator/group/gstregistrygenerator.mmp
--- a/data/Create_GStreamer_STUB_SIS.bat	Fri Jan 22 09:59:59 2010 +0200
+++ b/data/Create_GStreamer_STUB_SIS.bat	Fri Mar 19 09:35:09 2010 +0200
@@ -1,16 +1,21 @@
 rem
-rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-rem All rights reserved.
-rem This component and the accompanying materials are made available
-rem under the terms of the License "Symbian Foundation License v1.0"
-rem which accompanies this distribution, and is available
-rem at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+rem
+rem This library is free software; you can redistribute it and/or
+rem modify it under the terms of the GNU Lesser General Public
+rem License as published by the Free Software Foundation; either
+rem version 2 of the License, or (at your option) any later version.
 rem
-rem Initial Contributors:
-rem Nokia Corporation - initial contribution.
+rem This library is distributed in the hope that it will be useful,
+rem but WITHOUT ANY WARRANTY; without even the implied warranty of
+rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+rem Lesser General Public License for more details.
 rem
-rem Contributors:
-rem
+rem You should have received a copy of the GNU Lesser General Public
+rem License along with this library; if not, write to the
+rem Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+rem Boston, MA 02111-1307, USA.
+rem 
 rem Description: PKG for GStreamer
 rem
 
--- a/data/Gstreamer_Stub.pkg	Fri Jan 22 09:59:59 2010 +0200
+++ b/data/Gstreamer_Stub.pkg	Fri Mar 19 09:35:09 2010 +0200
@@ -1,15 +1,20 @@
 ;
-; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-; All rights reserved.
-; This component and the accompanying materials are made available
-; under the terms of the License "Symbian Foundation License v1.0"
-; which accompanies this distribution, and is available
-; at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+;
+; This library is free software; you can redistribute it and/or
+; modify it under the terms of the GNU Lesser General Public
+; License as published by the Free Software Foundation; either
+; version 2 of the License, or (at your option) any later version.
 ;
-; Initial Contributors:
-; Nokia Corporation - initial contribution.
+; 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
+; Lesser General Public License for more details.
 ;
-; Contributors:
+; You should have received a copy of the GNU Lesser 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.
 ;
 ; Description: GStreamer multimedia framework
 ;
--- a/gst_plugins_good/group/gstcamerabin.mmp	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_good/group/gstcamerabin.mmp	Fri Mar 19 09:35:09 2010 +0200
@@ -1,16 +1,25 @@
 // Gstreamer.MMP
 /*
- *  Copyright © 2008 Nokia Corporation.
- *  This material, including documentation and any related
- *  computer progrs, is protected by copyright controlled by
- *  Nokia Corporation. All rights are reserved. Copying,
- *  including reproducing, storing, adapting or translating, any
- *  or all of this material requires the prior written consent of
- *  Nokia Corporation. This material also contains confidential
- *  information which may not be disclosed to others without the
- *  prior written consent of Nokia Corporation.
- * ============================================================================
- */
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser 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.
+*
+* Description:
+*
+*/
 
 #include <platform_paths.hrh>                                                            
 
--- a/gst_plugins_good/group/gstphotography.mmp	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_good/group/gstphotography.mmp	Fri Mar 19 09:35:09 2010 +0200
@@ -1,16 +1,24 @@
-// Gstreamer.MMP
 /*
- *  Copyright © 2008 Nokia Corporation.
- *  This material, including documentation and any related
- *  computer progrs, is protected by copyright controlled by
- *  Nokia Corporation. All rights are reserved. Copying,
- *  including reproducing, storing, adapting or translating, any
- *  or all of this material requires the prior written consent of
- *  Nokia Corporation. This material also contains confidential
- *  information which may not be disclosed to others without the
- *  prior written consent of Nokia Corporation.
- * ============================================================================
- */
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser 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.
+*
+* Description:
+*
+*/
 
 #include <platform_paths.hrh>                                                            
 
--- a/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp	Fri Mar 19 09:35:09 2010 +0200
@@ -93,7 +93,7 @@
     {
     TRequestStatus* stat = &(AL->iStatus);
     User::RequestComplete(stat, aError);
-    iCallbackError = aError;
+    iCallbackError = 0;
     }
 /*******************************************************/
 void DevSoundWrapper::BufferToBeEmptied(CMMFBuffer* /*aBuffer*/)
@@ -244,6 +244,41 @@
 
 /************************************************************/
 
+int pause_devsound(GstDevsoundSink *ds)
+    {
+    TRACE_PRN_FN_ENT;
+    DevSoundWrapper* handle = (DevSoundWrapper*) ds->handle;
+    if(handle->dev_sound->IsResumeSupported())
+        {
+        handle->dev_sound->Pause();
+        }
+    else
+        {
+        handle->iSamplesPlayed = handle->dev_sound->SamplesPlayed();
+        handle->dev_sound->Stop();
+        }
+    TRACE_PRN_FN_EXT;
+    return 0;
+    }
+
+int resume_devsound(GstDevsoundSink *ds)
+    {
+    TRACE_PRN_FN_ENT;
+    DevSoundWrapper* handle = (DevSoundWrapper*) ds->handle;
+    if(handle->dev_sound->IsResumeSupported())
+        {
+        handle->dev_sound->Resume();
+        }
+    else
+        {
+        playinit(handle);
+        initproperties(ds);
+        }
+    TRACE_PRN_FN_EXT;
+    return 0;
+    }
+
+
 int close_devsound(GstDevsoundSink *ds)
     {
     TRACE_PRN_FN_ENT;
@@ -560,6 +595,19 @@
     {
     return handle->iCallbackError;
     }
+
+#ifdef AV_SYNC
+gboolean  is_timeplayed_supported(DevSoundWrapper *handle)
+    {
+    gboolean retVal = FALSE;
+    if (handle->dev_sound && (handle->dev_sound)->IsGetTimePlayedSupported())
+        {
+        retVal = TRUE;
+        }
+    return retVal;
+    }
+#endif /*AV_SYNC*/
+
 /*******************************************************************/
 
 int playinit(DevSoundWrapper *handle)
@@ -569,7 +617,7 @@
     ((handle)->AL)->InitialiseActiveListener();
     handle->eosReceived = false;
 
-        TRAP(handle->iCallbackError,(handle->dev_sound)->PlayInitL());
+    TRAP(handle->iCallbackError,(handle->dev_sound)->PlayInitL());
     if (handle->iCallbackError == KErrNone)
         {
         ((handle)->AL)->StartActiveScheduler();
@@ -715,7 +763,19 @@
     {
     TRACE_PRN_FN_ENT;
     DevSoundWrapper* dsPtr = STATIC_CAST(DevSoundWrapper*, ds->handle);
-    ds->samplesplayed = (dsPtr->dev_sound)->SamplesPlayed();
+#ifdef AV_SYNC
+    if (dsPtr->dev_sound->IsGetTimePlayedSupported())
+        {
+        TTimeIntervalMicroSeconds timePlayedInMS = 0;
+        (dsPtr->dev_sound)->GetTimePlayed(timePlayedInMS);
+        /* store value in nano seconds */
+        ds->time_or_samples_played = timePlayedInMS.Int64() * 1000;
+        }
+    else
+        {
+        ds->time_or_samples_played += (dsPtr->dev_sound)->SamplesPlayed();
+        }
+#endif /*AV_SYNC*/
     get_outputdevice(dsPtr,&ds->output);
     TRACE_PRN_FN_EXT;
     }
@@ -725,9 +785,6 @@
     TRACE_PRN_FN_ENT;
     DevSoundWrapper* dsPtr=  STATIC_CAST(DevSoundWrapper*, ds->handle);
     ds->maxvolume     = (dsPtr->dev_sound)->MaxVolume();
-    ds->volume        = (dsPtr->dev_sound)->Volume();
-    framemode_rqrd_for_ec(dsPtr,&ds->framemodereq);   
-    get_cng(dsPtr,&ds->g711cng);
-    get_ilbccng(dsPtr,&ds->ilbccng);
+    ds->volume        = (dsPtr->dev_sound)->Volume();    
     TRACE_PRN_FN_EXT;    
     }
--- a/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.h	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.h	Fri Mar 19 09:35:09 2010 +0200
@@ -96,6 +96,7 @@
   	int dev_count;
   	TInt iCallbackError;
   	TUint32 fourcc;
+  	TUint32 iSamplesPlayed;
   	bool eosReceived;
   	//sem_t mutex;
   	//RArray<TFourCC> supportedtypes;
@@ -142,10 +143,14 @@
 	int open_devsound(DevSoundWrapper **handle);
 	int open_device(DevSoundWrapper **handle);
     int initialize_devsound(GstDevsoundSink* sink);
+    int pause_devsound(GstDevsoundSink *ds);
+    int resume_devsound(GstDevsoundSink *ds);
     int close_devsound(GstDevsoundSink *ds);
     int check_if_device_open(DevSoundWrapper *handle) ;
-
 	int get_ds_cb_error(DevSoundWrapper *handle);
+#ifdef AV_SYNC
+    gboolean is_timeplayed_supported(DevSoundWrapper *handle);
+#endif /*AV_SYNC*/
 
 	//Error Concealment custom interface
     void conceal_error_for_next_buffer(DevSoundWrapper *handle);
@@ -175,7 +180,6 @@
 	int pre_init_setconf(GstDevsoundSink *ds);
 	void getsupporteddatatypes(GstDevsoundSink *ds);
 
-
 #ifdef __cplusplus
 }//extern c
 #endif
--- a/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.cpp	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.cpp	Fri Mar 19 09:35:09 2010 +0200
@@ -212,6 +212,49 @@
     }
 /*********************************************************/
 
+int stop_devsound(GstDevsoundSrc *ds)
+    {
+    TRACE_PRN_FN_ENT;
+    DevSoundWrapperSrc* handle = (DevSoundWrapperSrc*) ds->handle;
+    handle->dev_sound->Stop();
+    TRACE_PRN_FN_EXT;
+    return 0;
+    }
+
+int pause_devsound(GstDevsoundSrc *ds)
+    {
+    TRACE_PRN_FN_ENT;
+    DevSoundWrapperSrc* handle = (DevSoundWrapperSrc*) ds->handle;
+    if(handle->dev_sound->IsResumeSupported())
+        {
+        handle->dev_sound->Pause();
+        }
+    else
+        {
+        handle->iSamplesRecorded = handle->dev_sound->SamplesRecorded();
+        handle->dev_sound->Stop();
+        }
+    TRACE_PRN_FN_EXT;
+    return 0;
+    }
+
+int resume_devsound(GstDevsoundSrc *ds)
+    {
+    TRACE_PRN_FN_ENT;
+    DevSoundWrapperSrc* handle = (DevSoundWrapperSrc*) ds->handle;
+    if(handle->dev_sound->IsResumeSupported())
+        {
+        handle->dev_sound->Resume();
+        }
+    else
+        {
+        recordinit(handle);
+        initproperties(ds);
+        }
+    TRACE_PRN_FN_EXT;
+    return 0;
+    }
+
 int open_device(DevSoundWrapperSrc **handle)
     {
     int retcode = KErrNone;
@@ -538,11 +581,13 @@
 void set_rate(DevSoundWrapperSrc *handle, int rate)
     {
     handle->caps.iRate = rate;
+    TRACE_PRN_N1(_L("set_rate %d"),rate);
     }
 /******************************************************************/
 void set_channels(DevSoundWrapperSrc *handle, int channels)
     {
     handle->caps.iChannels = channels;
+    TRACE_PRN_N1(_L("set_channels %d"),channels);
     }
 /****************************************************************/
 void set_encoding(DevSoundWrapperSrc *handle, int encoding)
@@ -557,7 +602,10 @@
 /*****************************************************************/
 void set_fourcc(DevSoundWrapperSrc *handle, int fourcc)
     {
+    TRACE_PRN_FN_ENT;
     handle->fourcc = fourcc;
+    TRACE_PRN_N1(_L("set_fourcc %d"),fourcc);
+    TRACE_PRN_FN_EXT;
     }
 
 /*******************************************************************/
--- a/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.h	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.h	Fri Mar 19 09:35:09 2010 +0200
@@ -97,6 +97,7 @@
   	TUint32 fourcc;
   	int bufferreadpos;
   	guint* supportedbitrates;
+  	int iSamplesRecorded;
     CSpeechEncoderConfig* iSpeechEncoderConfig;
     CG711EncoderIntfc*    iG711EncoderIntfc;
     CG729EncoderIntfc*    iG729EncoderIntfc;
@@ -141,6 +142,9 @@
 	int open_devsound(DevSoundWrapperSrc **handle);
     int open_device(DevSoundWrapperSrc **handle);
     int initialize_devsound(GstDevsoundSrc* ds);
+    int pause_devsound(GstDevsoundSrc *ds);
+    int stop_devsound(GstDevsoundSrc *ds);
+    int resume_devsound(GstDevsoundSrc *ds);
 	int close_devsound(GstDevsoundSrc* ds);
 
 	int SetConfigurations(DevSoundWrapperSrc *handle);
--- a/gst_plugins_symbian/gst/devsound/gstdevsoundsink.c	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsink.c	Fri Mar 19 09:35:09 2010 +0200
@@ -32,6 +32,10 @@
 #include "gstilbcdecoderinterface.h"
 #include "string.h"
 #include <glib_global.h>
+#ifdef AV_SYNC
+#include <gst/audio/gstaudioclock.h>
+#endif /*AV_SYNC*/
+
 
 GST_DEBUG_CATEGORY_EXTERN (devsound_debug);
 #define GST_CAT_DEFAULT devsound_debug
@@ -59,12 +63,21 @@
 static GstCaps *gst_devsound_sink_getcaps(GstBaseSink * bsink);
 static gboolean gst_devsound_sink_setcaps(GstBaseSink *bsink, GstCaps *caps);
 
+static gboolean gst_devsound_sink_event(GstBaseSink * asink, GstEvent * event);
+#ifdef AV_SYNC
+static void gst_devsound_sink_get_times(GstBaseSink * bsink, GstBuffer * buffer,
+    GstClockTime * start, GstClockTime * end);
+static GstClock *gst_devsound_sink_provide_clock (GstElement * element);
+static GstClockTime gst_devsound_sink_get_time (GstClock * clock,
+    gpointer user_data);
+#endif /*AV_SYNC*/
 
-static gboolean gst_devsound_sink_event(GstBaseSink * asink, GstEvent * event);
+static GstStateChangeReturn gst_devsound_sink_change_state (GstElement * element,
+    GstStateChange transition);
+
 
 static void *StartDevSoundThread(void *threadid);
 
-
 //Error concealment interface impl
 static void gst_error_concealment_handler_init (gpointer g_iface,
     gpointer iface_data);
@@ -97,6 +110,7 @@
 static gint gst_SetIlbcDecoderMode(enum TIlbcDecodeMode aDecodeMode);
 static void  gst_Apply_Ilbc_Decoder_Update(GstDevsoundSink* dssink );
 
+static void get_PopulateIntfcProperties(GstDevsoundSink* dssink);
 
 static gboolean gst_sink_start (GstBaseSink * sink);
 static gboolean gst_sink_stop (GstBaseSink * sink);
@@ -160,23 +174,26 @@
     VOLUME,
     MAXVOLUME,
     VOLUMERAMP,
-    CHANNELS,
+/*    CHANNELS,*/
     LEFTBALANCE,
     RIGHTBALANCE,
-    RATE,
+/*    RATE,*/
     PRIORITY,
     PREFERENCE,
-    SAMPLESPLAYED,
-    FOURCC, //FOURCC is not needed
-    MIMETYPE,
+/*    SAMPLESPLAYED,*/
+/*    FOURCC, //FOURCC is not needed*/
+/*    MIMETYPE,*/
     OUTPUTDEVICE
     };
 
 enum command_to_consumer_thread_enum
     {
     OPEN = 2,
-    WRITEDATA,
+    PLAYING,
+    PAUSE,
+    RESUME,
     /*UPDATE,*/
+    WAIT,
     CLOSE
     };
 enum command_to_consumer_thread_enum cmd;
@@ -185,33 +202,14 @@
     GST_STATIC_PAD_TEMPLATE ("sink",
         GST_PAD_SINK,
         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, "
-                //"width = (int) 8, "
-                //"depth = (int) 8, "
-                "rate = (int) 8000, "
-                "channels = (int) 1 ; "
-                "audio/x-alaw, "
-                "rate = (int) [ 8000, 48000 ], "
-                "channels = (int) [ 1, 2 ]; "
-                "audio/g729, "
-                "rate = (int) [ 8000, 48000 ], "
-                "channels = (int) [ 1, 2 ]; "
-                "audio/mp3, "
-                "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 ]")
+        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, " "channels = (int) 1 ; "
+                "audio/AMR, " "rate = (int) 8000, " "channels = (int) 1 ; "
+                "audio/x-alaw, " "rate = (int) [ 8000, 48000 ], " "channels = (int) [ 1, 2 ]; "
+                "audio/g729, " "rate = (int) [ 8000, 48000 ], " "channels = (int) [ 1, 2 ]; "
+                "audio/mp3, " "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;
@@ -284,14 +282,20 @@
 
 static void gst_devsound_sink_dispose(GObject * object)
     {
-    GstDevsoundSink *devsoundsink= GST_DEVSOUND_SINK (object);
+    GstDevsoundSink *devsoundsink = GST_DEVSOUND_SINK (object);
 
     if (devsoundsink->probed_caps)
         {
         gst_caps_unref(devsoundsink->probed_caps);
         devsoundsink->probed_caps = NULL;
         }
-
+#ifdef AV_SYNC
+    if (devsoundsink->clock)
+        {
+        gst_object_unref (devsoundsink->clock);
+        }
+    devsoundsink->clock = NULL;
+#endif /*AV_SYNC*/
     G_OBJECT_CLASS (parent_class)->dispose (object);
     }
 
@@ -324,7 +328,10 @@
     gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_devsound_sink_finalise);
     gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_devsound_sink_get_property);
     gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_devsound_sink_set_property);
-
+    
+    
+    gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_devsound_sink_change_state);
+    
     g_object_class_install_property(gobject_class, PROP_DEVICE,
             g_param_spec_string("device", "Device", "Devsound device ",
             DEFAULT_DEVICE, G_PARAM_READWRITE));
@@ -348,11 +355,11 @@
     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, SAMPLESPLAYED,
                       g_param_spec_int("samplesplayed", "Samples Played", "Samples Played",
                               -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,
@@ -362,7 +369,7 @@
             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,
@@ -372,12 +379,16 @@
             g_param_spec_int("channels", "Channels", "Channels ", -1,
                     G_MAXINT, -1,
                     G_PARAM_READWRITE));
-
+*/
     g_object_class_install_property(gobject_class, OUTPUTDEVICE,
              g_param_spec_int("outputdevice", "Output Device", "Output Device ", -1,
                      G_MAXINT, -1,
                      G_PARAM_READWRITE));
     
+#ifdef AV_SYNC
+    gstelement_class->provide_clock = GST_DEBUG_FUNCPTR (gst_devsound_sink_provide_clock);
+#endif /*AV_SYNC*/
+
     gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_sink_start);
     gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_sink_stop);
     gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_sink_render);
@@ -385,35 +396,47 @@
     gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_devsound_sink_getcaps);
     gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_devsound_sink_setcaps);
     gstbasesink_class->event    = GST_DEBUG_FUNCPTR (gst_devsound_sink_event);
+#ifdef AV_SYNC
+    gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_devsound_sink_get_times);
+#endif /*AV_SYNC*/
     }
 
-static void gst_devsound_sink_init(GstDevsoundSink * devsoundsink)
+static void gst_devsound_sink_init(GstDevsoundSink * dssink)
     {
-    GST_DEBUG_OBJECT(devsoundsink, "initializing devsoundsink");
-    devsoundsink->device = g_strdup(DEFAULT_DEVICE);
-    devsoundsink->handle = NULL;
-    devsoundsink->preference = 0; //default=>EMdaPriorityPreferenceNone;
-    devsoundsink->priority = 0;   //default=>EMdaPriorityNormal;
+    GST_DEBUG_OBJECT(dssink, "initializing devsoundsink");
+    dssink->device = g_strdup(DEFAULT_DEVICE);
+    dssink->handle = NULL;
+    dssink->preference = 0; //default=>EMdaPriorityPreferenceNone;
+    dssink->priority = 0;   //default=>EMdaPriorityNormal;
+#ifdef AV_SYNC
+    dssink->time_or_samples_played = 0;
+    dssink->timeplayedavailable = FALSE;
+    /* Create the provided clock. */
+    dssink->clock = gst_audio_clock_new ("clock", gst_devsound_sink_get_time, dssink);
+#endif /*AV_SYNC*/
     pthread_mutex_init(&ds_mutex, NULL);
     pthread_cond_init(&ds_condition, NULL);
     }
 
 static void *StartDevSoundThread(void *threadarg)
     {
-
-    GstDevsoundSink *devsound;
+    GstDevsoundSink *dssink;
 
     gint remainingDataLen = 0;
     GstBuffer *buffer = NULL;
     gboolean lastBufferSet=FALSE;
-    devsound = (GstDevsoundSink*) threadarg;
+    dssink = (GstDevsoundSink*) threadarg;
 
-    open_devsound(&(devsound->handle));
+    // TODO handle error here
+    open_devsound(&(dssink->handle));
+#ifdef AV_SYNC
+    dssink->timeplayedavailable = is_timeplayed_supported(dssink->handle);
+#endif /*AV_SYNC*/
 
 
     //get supported (in/out)put datatypes
     //from devsound to build caps
-    getsupporteddatatypes(devsound);
+    getsupporteddatatypes(dssink);
 
     // TODO obtain mutex to update variable here???
     consumer_thread_state = CONSUMER_THREAD_INITIALIZED;
@@ -438,82 +461,94 @@
         {
         //TODO if there is preemption we have to somehow signal
         //the pipeline in the render
-        initialize_devsound(devsound);
+        initialize_devsound(dssink);
 
-        playinit(devsound->handle);
-        initproperties(devsound);
+        playinit(dssink->handle);
+        dssink->eosreceived = FALSE;
+        initproperties(dssink);
         }
     while (1)
         {
         switch (cmd)
             {
-            case WRITEDATA:
+            case PAUSE:
+                pause_devsound(dssink);
+                cmd = WAIT;
+                break;
+                
+            case RESUME:
+                resume_devsound(dssink);
+                cmd = PLAYING;
+                break;
+            
+            case WAIT:
+                pthread_mutex_lock(&ds_mutex);
+                pthread_cond_signal(&ds_condition);
+                pthread_mutex_unlock(&ds_mutex);
+                            
+                pthread_mutex_lock(&ds_mutex);
+                pthread_cond_wait(&ds_condition, &ds_mutex);
+                pthread_mutex_unlock(&ds_mutex);
+                break;
+                
+            case PLAYING:
                 {
-                pre_init_setconf(devsound);
-                gst_Apply_ErrorConcealment_Update(devsound);
-                gst_Apply_G711_Decoder_Update(devsound);
-                gst_Apply_G729_Decoder_Update(devsound);
-                gst_Apply_Ilbc_Decoder_Update(devsound);
+                pre_init_setconf(dssink);
+                gst_Apply_ErrorConcealment_Update(dssink);
+                gst_Apply_G711_Decoder_Update(dssink);
+                gst_Apply_G729_Decoder_Update(dssink);
+                gst_Apply_Ilbc_Decoder_Update(dssink);
 
                 // TODO we could do this in BTBF callback
-                populateproperties(devsound);
-
-                framemodereq = devsound->framemodereq;
-                g711cng = devsound->g711cng;
-                ilbccng = devsound->ilbccng;
-                output = devsound->output;
-
+                populateproperties(dssink);
+                get_PopulateIntfcProperties(dssink);
+                
                 if(buffer_queue->length > 0)
                     {
                     if (remainingDataLen == 0)
                         {
                         // TODO enable lock and unlock
-                        GST_OBJECT_LOCK (devsound);
+                        GST_OBJECT_LOCK (dssink);
                         buffer = GST_BUFFER_CAST(g_queue_peek_head(buffer_queue));
-                        GST_OBJECT_UNLOCK(devsound);
+                        GST_OBJECT_UNLOCK(dssink);
                         remainingDataLen = GST_BUFFER_SIZE(buffer);
                         }
 
                     lastBufferSet =  GST_BUFFER_FLAG_IS_SET(buffer,GST_BUFFER_FLAG_LAST);
-                    remainingDataLen = write_data(devsound->handle,
+                    remainingDataLen = write_data(dssink->handle,
                             GST_BUFFER_DATA(buffer) + (GST_BUFFER_SIZE(buffer) - remainingDataLen),
                             remainingDataLen,
                             lastBufferSet);
 
                     if (remainingDataLen == 0)
                         {
-                        GST_OBJECT_LOCK (devsound);
+                        GST_OBJECT_LOCK (dssink);
                         buffer = GST_BUFFER_CAST(g_queue_pop_head(buffer_queue));
-                        GST_OBJECT_UNLOCK(devsound);
+                        GST_OBJECT_UNLOCK(dssink);
                         gst_buffer_unref(buffer);
                         buffer = NULL;
                         }
 
                     if (lastBufferSet && remainingDataLen == 0)
                         {
-                        // Last Buffer is already sent to DevSound
-                        // and we have received PlayError so now we exit
-                        // from the big loop next time
-/*
-                        pthread_mutex_lock(&ds_mutex);
-                        pthread_cond_signal(&ds_condition);
-                        pthread_mutex_unlock(&ds_mutex);
-*/
-                        cmd = CLOSE;
-                       }
+                        lastBufferSet = FALSE;
+                        dssink->eosreceived = FALSE;
+                        playinit(dssink->handle);
+                        initproperties(dssink);
+                        get_PopulateIntfcProperties(dssink);
+                        cmd = WAIT;
+                        }
                     }
                 else
                     {
-                    pthread_mutex_lock(&ds_mutex);
-                    pthread_cond_wait(&ds_condition, &ds_mutex);
-                    pthread_mutex_unlock(&ds_mutex);
+                    cmd = WAIT;
                     }
                 }
                 break;
             case CLOSE:
                 {
-                close_devsound(devsound);
-                devsound->handle= NULL;
+                close_devsound(dssink);
+                dssink->handle= NULL;
                 pthread_mutex_lock(&ds_mutex);
                 pthread_cond_signal(&ds_condition);
                 pthread_mutex_unlock(&ds_mutex);
@@ -537,7 +572,7 @@
 static gboolean gst_sink_start (GstBaseSink * sink)
     {
     GstBuffer *tmp_gstbuffer=NULL;
-    GstDevsoundSink *devsound = GST_DEVSOUND_SINK(sink);
+    GstDevsoundSink *dssink = GST_DEVSOUND_SINK(sink);
 
     if(buffer_queue)
         {
@@ -557,7 +592,7 @@
 
     consumer_thread_state = CONSUMER_THREAD_INITIALIZING;
     cmd = OPEN;
-    pthread_create(&ds_thread,  NULL, StartDevSoundThread, (void *)devsound);
+    pthread_create(&ds_thread,  NULL, StartDevSoundThread, (void *)dssink);
 
     // Wait until consumer thread is created
     // TODO : obtain mutex to retreive thread state?
@@ -574,7 +609,7 @@
 static gboolean gst_sink_stop (GstBaseSink * sink)
     {
     GstBuffer *tmp_gstbuffer=NULL;
-    GstDevsoundSink *devsound = GST_DEVSOUND_SINK(sink);
+    GstDevsoundSink *dssink = GST_DEVSOUND_SINK(sink);
 
     cmd = CLOSE;
 
@@ -582,7 +617,12 @@
     pthread_cond_signal(&ds_condition);
     pthread_mutex_unlock(&ds_mutex);
 
-    GST_OBJECT_LOCK(devsound);
+    pthread_mutex_lock(&ds_mutex);
+    pthread_cond_wait(&ds_condition, &ds_mutex);
+    pthread_mutex_unlock(&ds_mutex);
+    
+
+    GST_OBJECT_LOCK(dssink);
     while (buffer_queue->length)
         {
         tmp_gstbuffer = (GstBuffer*)g_queue_pop_tail(buffer_queue);
@@ -590,7 +630,7 @@
         }
     g_queue_free(buffer_queue);
     buffer_queue = NULL;
-    GST_OBJECT_UNLOCK(devsound);
+    GST_OBJECT_UNLOCK(dssink);
 
     return TRUE;
     }
@@ -598,21 +638,21 @@
 static GstFlowReturn gst_sink_render (GstBaseSink * sink,
     GstBuffer * buffer)
     {
-    GstDevsoundSink *devsound = GST_DEVSOUND_SINK(sink);
+    GstDevsoundSink *dssink = GST_DEVSOUND_SINK(sink);
     GstBuffer* tmp;
 
-    if (get_ds_cb_error(devsound->handle))
+    if (get_ds_cb_error(dssink->handle))
         {
         return GST_FLOW_CUSTOM_ERROR;
         }
         
     tmp = gst_buffer_copy(buffer);
  
-    GST_OBJECT_LOCK (devsound);
+    GST_OBJECT_LOCK (dssink);
     g_queue_push_tail (buffer_queue, tmp);
-    GST_OBJECT_UNLOCK (devsound);
+    GST_OBJECT_UNLOCK (dssink);
 
-    cmd = WRITEDATA;
+    cmd = PLAYING;
     pthread_mutex_lock(&ds_mutex);
     pthread_cond_signal(&ds_condition);
     pthread_mutex_unlock(&ds_mutex);
@@ -622,7 +662,7 @@
 
 static void gst_devsound_sink_finalise(GObject * object)
     {
-    GstDevsoundSink *devsoundsink= GST_DEVSOUND_SINK (object);
+    GstDevsoundSink *devsoundsink = GST_DEVSOUND_SINK (object);
     g_free(devsoundsink->device);
 
     }
@@ -646,7 +686,7 @@
                 sink->probed_caps = NULL;
                 }
             break;
-        case CHANNELS:
+/*        case CHANNELS:
             sink->channels = g_value_get_int(value);
             sink->pending.channelsupdate = TRUE;
             break;
@@ -656,7 +696,7 @@
             sink->rate = gst_devsound_sink_get_rate(sink->rate);
             sink->pending.rateupdate = TRUE;
             break;
-        case VOLUME:
+*/        case VOLUME:
             sink->volume = g_value_get_int(value);
             sink->pending.volumeupdate = TRUE;
             break;
@@ -680,14 +720,13 @@
             sink->preference = g_value_get_int(value);
             sink->pending.preferenceupdate = TRUE;
             break;
-        case FOURCC: //FOURCC is not needed
+/*        case FOURCC: //FOURCC is not needed
             sink->fourcc = g_value_get_int(value);
             sink->pending.fourccupdate = TRUE;
             break;
-
         case MIMETYPE:
             sink->mimetype = g_value_dup_string(value);
-            break;
+            break;*/
         case OUTPUTDEVICE:
             sink->output = g_value_get_int(value);
             sink->pending.outputupdate = TRUE;
@@ -710,21 +749,21 @@
         case PROP_DEVICE:
             g_value_set_string(value, sink->device);
             break;
-        case CHANNELS:
+/*        case CHANNELS:
             g_value_set_int(value, sink->channels);
             break;
         case RATE:
             g_value_set_int(value, sink->rate);
-            break;
+            break;*/
         case VOLUME:
             g_value_set_int(value, sink->volume);
             break;
         case MAXVOLUME:
             g_value_set_int(value, sink->maxvolume);
             break;
-        case SAMPLESPLAYED:
+/*        case SAMPLESPLAYED:
               g_value_set_int(value, sink->samplesplayed);
-              break;
+              break;*/
         case OUTPUTDEVICE:
               g_value_set_int(value, sink->output);
               break;
@@ -923,14 +962,14 @@
 
 static gboolean gst_devsound_sink_event(GstBaseSink *asink, GstEvent *event)
     {
-    GstDevsoundSink *sink= GST_DEVSOUND_SINK (asink);
+    GstDevsoundSink *sink = GST_DEVSOUND_SINK (asink);
     GstBuffer* lastBuffer = NULL;
     switch (GST_EVENT_TYPE (event))
         {
         case GST_EVENT_EOS:
             // end-of-stream, we should close down all stream leftovers here
             //reset_devsound(sink->handle);
-
+            sink->eosreceived = TRUE;
             if(buffer_queue->length)
                 {
                 GST_OBJECT_LOCK(sink);
@@ -945,7 +984,7 @@
                 GST_OBJECT_LOCK(sink);
                 g_queue_push_tail(buffer_queue,lastBuffer);
                 GST_OBJECT_UNLOCK(sink);
-                cmd = WRITEDATA;
+                cmd = PLAYING;
                 pthread_mutex_lock(&ds_mutex);
                 pthread_cond_signal(&ds_condition);
                 pthread_mutex_unlock(&ds_mutex);
@@ -962,6 +1001,103 @@
     return TRUE;
     }
 
+#ifdef AV_SYNC
+static void gst_devsound_sink_get_times (GstBaseSink * bsink, GstBuffer * buffer,
+    GstClockTime * start, GstClockTime * end)
+    {
+    /* Like GstBaseAudioSink, we set these to NONE */
+    *start = GST_CLOCK_TIME_NONE;
+    *end = GST_CLOCK_TIME_NONE;
+    }
+
+static GstClock *gst_devsound_sink_provide_clock (GstElement * element)
+    {
+    GstDevsoundSink *sink = GST_DEVSOUND_SINK (element);
+    return GST_CLOCK (gst_object_ref (sink->clock));
+    }
+
+static GstClockTime gst_devsound_sink_get_time (GstClock * clock, gpointer user_data)
+    {
+    GstClockTime result = 0;
+    GstDevsoundSink *sink = GST_DEVSOUND_SINK (user_data);
+
+    /* The value returned must be in nano seconds. 1 sec = 1000000000 nano seconds (9 zeros)*/
+    /*If time played is available from DevSound (a3f devsound onwards) get it*/
+    if (sink->timeplayedavailable)
+        {
+        result = sink->time_or_samples_played;
+        }
+    else if ((sink->time_or_samples_played > 0 ) && (sink->rate > 0 ))/*This is a pre-a3f devsound. So calculate times played based on samples played*/
+        { /*GST_SECOND = 1000000000*/
+        result = gst_util_uint64_scale_int (sink->time_or_samples_played, GST_SECOND, sink->rate);
+        }
+    GST_LOG_OBJECT (sink, "Time: %" GST_TIME_FORMAT, GST_TIME_ARGS (result));
+    return result;
+    }
+#endif /*AV_SYNC*/
+
+static GstStateChangeReturn gst_devsound_sink_change_state (GstElement * element, GstStateChange transition)
+    {
+    GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+    GstDevsoundSink *sink= GST_DEVSOUND_SINK (element);
+    
+    switch (transition)
+        {
+        case GST_STATE_CHANGE_NULL_TO_READY:
+            {
+#ifdef AV_SYNC
+            sink->time_or_samples_played = 0;
+#endif /*AV_SYNC*/			
+            }
+            break;
+
+        case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+            if(cmd == WAIT)
+                {
+                cmd = RESUME;
+                pthread_mutex_lock(&ds_mutex);
+                pthread_cond_signal(&ds_condition);
+                pthread_mutex_unlock(&ds_mutex);
+                
+                pthread_mutex_lock(&ds_mutex);
+                pthread_cond_wait(&ds_condition, &ds_mutex);
+                pthread_mutex_unlock(&ds_mutex);
+                }
+            break;
+        default:
+            break;
+        }
+
+    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+      if (G_UNLIKELY (ret == GST_STATE_CHANGE_FAILURE))
+        goto activate_failed;
+
+      switch (transition) {
+          
+          case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+              cmd = PAUSE;
+              pthread_mutex_lock(&ds_mutex);
+              pthread_cond_signal(&ds_condition);
+              pthread_mutex_unlock(&ds_mutex);
+              
+              pthread_mutex_lock(&ds_mutex);
+              pthread_cond_wait(&ds_condition, &ds_mutex);
+              pthread_mutex_unlock(&ds_mutex);
+              break;
+          default:
+              break;
+          }
+      
+      return ret;
+    
+    activate_failed:
+      {
+        GST_DEBUG_OBJECT (sink,
+            "element failed to change states -- activation problem?");
+        return GST_STATE_CHANGE_FAILURE;
+      }    
+    }
+
 
 /************************************
 * Error Concealment Interface begins
@@ -1142,3 +1278,13 @@
         customInfaceUpdate.ilbcdecodermodeupdate = FALSE;
         }
     }
+
+static void get_PopulateIntfcProperties(GstDevsoundSink* dssink)
+    {
+    framemode_rqrd_for_ec(dssink->handle,&framemodereq);   
+
+    get_cng(dssink->handle,&g711cng);
+    
+    get_ilbccng(dssink->handle,&ilbccng);
+    }
+	
--- a/gst_plugins_symbian/gst/devsound/gstdevsoundsink.h	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsink.h	Fri Mar 19 09:35:09 2010 +0200
@@ -28,7 +28,6 @@
 #ifndef __GST_DEVSOUNDSINK_H__
 #define __GST_DEVSOUNDSINK_H__
 
-
 #include <gst/gst.h>
 #include <gst/base/gstbasesink.h>
 
@@ -41,7 +40,7 @@
 #define GST_IS_DEVSOUND_SINK(obj)       (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DEVSOUND_SINK))
 #define GST_IS_DEVSOUND_SINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DEVSOUND_SINK))
 
-
+//#define AV_SYNC
 
 typedef struct _GstDevsoundSink GstDevsoundSink;
 typedef struct _GstDevsoundSinkClass GstDevsoundSinkClass;
@@ -49,51 +48,55 @@
 typedef struct _GstDevsoundUpdate GstDevsoundUpdate;
 
 struct _GstDevsoundUpdate{
-gboolean  channelsupdate;
-gboolean  rateupdate;
-gboolean  volumeupdate;
-gboolean  volumerampupdate;
-gboolean  leftbalanceupdate;
-gboolean  rightbalanceupdate;
-gboolean  preferenceupdate;
-gboolean  priorityupdate;
-gboolean  fourccupdate;
-gboolean  outputupdate;
+    gboolean  channelsupdate;
+    gboolean  rateupdate;
+    gboolean  volumeupdate;
+    gboolean  volumerampupdate;
+    gboolean  leftbalanceupdate;
+    gboolean  rightbalanceupdate;
+    gboolean  preferenceupdate;
+    gboolean  priorityupdate;
+    gboolean  fourccupdate;
+    gboolean  outputupdate;
 };
 
 struct _GstDevsoundSink {
-  GstBaseSink    sink;	
-  
-  void *handle;	
-  void *dataptr;
-  gchar *device;
-  gint   bytes_per_sample;
-  GstCaps *probed_caps;
+    GstBaseSink    sink;	
 
-  GstDevsoundUpdate pending;
+    void *handle;	
+    void *dataptr;
+    gchar *device;
+    gint   bytes_per_sample;
+    GstCaps *probed_caps;
+
+    GstDevsoundUpdate pending;
 
-  //properties
-  gint   channels;
-  gint   rate;
-  gint   volume;
-  gint   volumeramp;
-  gint   maxvolume;
-  gint   leftbalance;
-  gint   rightbalance;
-  gint   priority;
-  gint   preference;
-  gint   samplesplayed;
-  gint   output;
-  gulong fourcc;
-  gchar  *mimetype;
-  GList   *fmt;
-  gboolean framemodereq;
-  gboolean g711cng;
-  gboolean ilbccng;  
+    //properties
+    gint   channels;
+    gint   rate;
+    gint   volume;
+    gint   volumeramp;
+    gint   maxvolume;
+    gint   leftbalance;
+    gint   rightbalance;
+    gint   priority;
+    gint   preference;
+    gint   output;
+    gulong fourcc;
+    gchar  *mimetype;
+    GList   *fmt;
+
+    gboolean eosreceived;
+    
+#ifdef AV_SYNC
+    gboolean timeplayedavailable;
+    gulong time_or_samples_played;
+    GstClock *clock;		/* The clock for this element. */
+#endif /*AV_SYNC*/
 };
 
 struct _GstDevsoundSinkClass {
-  GstBaseSinkClass parent_class;
+    GstBaseSinkClass parent_class;
 };
 
 GType gst_devsound_sink_get_type(void);
@@ -101,3 +104,4 @@
 G_END_DECLS
 
 #endif /* __GST_DEVSOUNDSINK_H__ */
+
--- a/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c	Fri Mar 19 09:35:09 2010 +0200
@@ -71,6 +71,11 @@
         guint size, GstBuffer **buf);
 static void *StartDevSoundThread(void *threadid);
 
+static gboolean gst_devsound_src_event(GstBaseSrc * asrc, GstEvent * event);
+
+static GstStateChangeReturn gst_devsound_src_change_state (GstElement * element,
+    GstStateChange transition);
+
 /*********************************
  * Speech Encoder Config Interface
  * ******************************/
@@ -164,7 +169,10 @@
 enum command_to_consumer_thread_enum
     {
     OPEN = 2,
-    READDATA,
+    RECORDING,
+    PAUSE,
+    RESUME,
+    STOP,
     /*UPDATE,*/
     CLOSE
     };
@@ -319,6 +327,8 @@
     gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_devsound_src_get_property);
     gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_devsound_src_set_property);
 
+    gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_devsound_src_change_state);
+    
     g_object_class_install_property(gobject_class, PROP_DEVICE,
             g_param_spec_string("device", "Device", "Devsound device ",
                     DEFAULT_DEVICE, G_PARAM_READWRITE));
@@ -362,17 +372,19 @@
             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->event = GST_DEBUG_FUNCPTR (gst_devsound_src_event);
     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_base_src_set_live(GST_BASE_SRC(devsoundsrc), TRUE);
     //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;
@@ -423,71 +435,50 @@
         recordinit(devsoundsrc->handle);
         initproperties(devsoundsrc);
         }
-    //cmd = READDATA;
-    while (1)
+
+    while (TRUE)
         {
-        //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:
+            case PAUSE:
+                pause_devsound(devsoundsrc);
+                break;
+                
+            case RESUME:
+                resume_devsound(devsoundsrc);
+                break;
+            
+            case STOP:
+                stop_devsound(devsoundsrc);
+                break;
+                
+            case RECORDING:
                 {
+                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;
+
+                buffersize = get_databuffer_size(devsoundsrc->handle);
+                get_databuffer(devsoundsrc->handle, &gBuffer);
+                pushBuffer = gst_buffer_new_and_alloc(buffersize);
+                memcpy(GST_BUFFER_DATA(pushBuffer),gBuffer,buffersize);
+                
+                GST_OBJECT_LOCK(devsoundsrc);
+                g_queue_push_head (dataqueue,pushBuffer);
+                GST_OBJECT_UNLOCK(devsoundsrc);
+                
                 record_data(devsoundsrc->handle);
                 }
                 break;
@@ -502,21 +493,25 @@
                 pthread_mutex_lock(&(create_mutex1));
                 pthread_cond_signal(&(create_condition1));
                 pthread_mutex_unlock(&(create_mutex1));
-				// TODO obtain mutex here
+                // 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;			
+                consumer_thread_state = CONSUMER_THREAD_UNINITIALIZED;          
                 pthread_exit(NULL);
                 break;
             }
+        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);
         }
-    // 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,
@@ -692,7 +687,7 @@
 
     if(dataqueue)
         {
-        while (dataqueue->length)
+        while (g_queue_get_length(dataqueue))
             {
             tmp_gstbuffer = (GstBuffer*)g_queue_pop_tail(dataqueue);
             gst_buffer_unref(tmp_gstbuffer);
@@ -731,6 +726,9 @@
     //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "gst_devsound_src_stop ENTER ");
     cmd = CLOSE;
 
+    pthread_mutex_lock(&(create_mutex1));
+    pthread_cond_signal(&(create_condition1));
+    pthread_mutex_unlock(&(create_mutex1));
     //GST_OBJECT_LOCK (src);
     pthread_mutex_lock(&(create_mutex1));
     pthread_cond_wait(&(create_condition1), &(create_mutex1));
@@ -746,7 +744,7 @@
     //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)
+    while (g_queue_get_length(dataqueue))
         {
         //gst_debug_log(devsound_debug, GST_LEVEL_LOG, "", "", 0, (GObject *) src, "Removing DATAQUEUE elements ENTER ");
         popBuffer = (GstBuffer*)g_queue_pop_tail(dataqueue);
@@ -764,7 +762,6 @@
     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;
@@ -794,6 +791,16 @@
     {
     GstDevsoundSrc *dsrc= GST_DEVSOUND_SRC(src);
     int bufferpos=0;
+    
+    if(!g_queue_get_length(dataqueue) && (dsrc->eosreceived == TRUE))
+        {
+        pthread_mutex_lock(&(create_mutex1));
+        pthread_cond_signal(&(create_condition1));
+        pthread_mutex_unlock(&(create_mutex1));
+        
+        return GST_FLOW_UNEXPECTED;
+        }
+    
     //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);
@@ -839,26 +846,36 @@
 
             // 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)
+            if (!g_queue_get_length(dataqueue))
                 {
                 //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));
+                if(dsrc->eosreceived == TRUE)
+                    {
+                    return GST_FLOW_UNEXPECTED;
+                    }
+                else
+                    {
+                    cmd = RECORDING;
+                    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);
-
+            if(!popBuffer)
+                {
+                return GST_FLOW_UNEXPECTED;
+                }
             // 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
@@ -893,6 +910,63 @@
     return GST_FLOW_OK;
     }
 
+
+static GstStateChangeReturn gst_devsound_src_change_state (GstElement * element,
+    GstStateChange transition)
+    {
+    GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+    GstDevsoundSrc *src= GST_DEVSOUND_SRC (element);
+    
+    switch (transition) {
+        
+        case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+            if(cmd == PAUSE)
+                {
+                cmd = RESUME;
+                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);
+                }
+            break;
+        default:
+            break;
+        }
+
+    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+      if (G_UNLIKELY (ret == GST_STATE_CHANGE_FAILURE))
+        goto activate_failed;
+
+      switch (transition) {
+          
+          case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+              cmd = PAUSE;
+              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);
+              break;
+          default:
+              break;
+          }
+      
+      return ret;
+    
+    activate_failed:
+      {
+        GST_DEBUG_OBJECT (src,
+            "element failed to change states -- activation problem?");
+        return GST_STATE_CHANGE_FAILURE;
+      }    
+    }
+
+
 static gboolean gst_devsound_src_is_seekable(GstBaseSrc * bsrc)
     {
     GstDevsoundSrc *src= GST_DEVSOUND_SRC(bsrc);
@@ -1137,3 +1211,40 @@
 
     }
 
+static gboolean gst_devsound_src_event(GstBaseSrc *asrc, GstEvent *event)
+    {
+    int retValue = FALSE;
+    GstDevsoundSrc *src = GST_DEVSOUND_SRC(asrc);
+    switch (GST_EVENT_TYPE (event))
+        {
+        case GST_EVENT_EOS:
+            // end-of-stream, we should close down all stream leftovers here
+            //reset_devsound(sink->handle);
+            src->eosreceived = TRUE;
+            cmd = STOP;
+            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);
+            
+            if(g_queue_get_length(dataqueue))
+                {
+                pthread_mutex_lock(&create_mutex1);
+                pthread_cond_wait(&create_condition1, &create_mutex1);
+                pthread_mutex_unlock(&create_mutex1);
+                }
+            
+            gst_pad_push_event (asrc->srcpad, gst_event_new_eos ());
+            retValue = TRUE;
+            break;
+        default:
+            retValue = FALSE;
+            break;
+        }
+    
+    return retValue;
+    }
+	
--- a/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.h	Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.h	Fri Mar 19 09:35:09 2010 +0200
@@ -77,6 +77,7 @@
   gint   samplesrecorded; 
   GList*  fmt;
   GList*  supportedbitrates;
+  gboolean eosreceived;
   
   guint speechbitrate;
   gboolean speechvadmode;
--- a/gstreamer_core/gst/gstinterface.h	Fri Jan 22 09:59:59 2010 +0200
+++ b/gstreamer_core/gst/gstinterface.h	Fri Mar 19 09:35:09 2010 +0200
@@ -71,6 +71,9 @@
 #define GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_TYPE(obj, type) \
   (gst_implements_interface_check ((obj), (type)))
 
+#ifdef __SYMBIAN32__
+IMPORT_C
+#endif
 GType	 gst_implements_interface_get_type    (void);
 
 /* wrapper functions to check for functionality implementation */
--- a/gstregistrygenerator/group/gstregistrygenerator.mmp	Fri Jan 22 09:59:59 2010 +0200
+++ b/gstregistrygenerator/group/gstregistrygenerator.mmp	Fri Mar 19 09:35:09 2010 +0200
@@ -38,6 +38,8 @@
 SOURCEPATH	  ../src
 SOURCE		  gstregistrygenerator.cpp
 
+STATICLIBRARY    libcrt0.lib
+
 LIBRARY         libc.lib
 LIBRARY         libpthread.lib
 LIBRARY         libdl.lib
@@ -52,6 +54,8 @@
 LIBRARY			libgstbase.lib
 LIBRARY			libgstcontroller.lib
 
+LIBRARY			euser.lib
+
 #ifdef ENABLE_ABIV2_MODE
   DEBUGGABLE_UDEBONLY
 #endif