--- a/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c Fri Jan 22 09:59:59 2010 +0200
+++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c Wed Mar 24 17:55:38 2010 -0500
@@ -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;
+ }
+