# HG changeset patch # User hgs # Date 1269471338 18000 # Node ID 32e421e6175ce0918d1aa4320dd6de493c950056 # Parent 5505e89089447d368cbe9331bfdcfde389f6c9b6 201005 diff -r 5505e8908944 -r 32e421e6175c gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp --- a/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp Fri Jan 22 09:59:59 2010 +0200 +++ b/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.cpp Wed Mar 24 17:55:38 2010 -0500 @@ -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; } diff -r 5505e8908944 -r 32e421e6175c gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.h --- a/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.h Fri Jan 22 09:59:59 2010 +0200 +++ b/gst_plugins_symbian/gst/devsound/devsoundsinkwrapper.h Wed Mar 24 17:55:38 2010 -0500 @@ -96,6 +96,7 @@ int dev_count; TInt iCallbackError; TUint32 fourcc; + TUint32 iSamplesPlayed; bool eosReceived; //sem_t mutex; //RArray 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 diff -r 5505e8908944 -r 32e421e6175c gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.cpp --- a/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.cpp Fri Jan 22 09:59:59 2010 +0200 +++ b/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.cpp Wed Mar 24 17:55:38 2010 -0500 @@ -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; } /*******************************************************************/ diff -r 5505e8908944 -r 32e421e6175c gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.h --- a/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.h Fri Jan 22 09:59:59 2010 +0200 +++ b/gst_plugins_symbian/gst/devsound/devsoundsrcwrapper.h Wed Mar 24 17:55:38 2010 -0500 @@ -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); diff -r 5505e8908944 -r 32e421e6175c gst_plugins_symbian/gst/devsound/gstdevsoundsink.c --- a/gst_plugins_symbian/gst/devsound/gstdevsoundsink.c Fri Jan 22 09:59:59 2010 +0200 +++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsink.c Wed Mar 24 17:55:38 2010 -0500 @@ -32,6 +32,10 @@ #include "gstilbcdecoderinterface.h" #include "string.h" #include +#ifdef AV_SYNC +#include +#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); + } + diff -r 5505e8908944 -r 32e421e6175c gst_plugins_symbian/gst/devsound/gstdevsoundsink.h --- a/gst_plugins_symbian/gst/devsound/gstdevsoundsink.h Fri Jan 22 09:59:59 2010 +0200 +++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsink.h Wed Mar 24 17:55:38 2010 -0500 @@ -28,7 +28,6 @@ #ifndef __GST_DEVSOUNDSINK_H__ #define __GST_DEVSOUNDSINK_H__ - #include #include @@ -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__ */ + diff -r 5505e8908944 -r 32e421e6175c gst_plugins_symbian/gst/devsound/gstdevsoundsrc.c --- 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; + } + diff -r 5505e8908944 -r 32e421e6175c gst_plugins_symbian/gst/devsound/gstdevsoundsrc.h --- a/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.h Fri Jan 22 09:59:59 2010 +0200 +++ b/gst_plugins_symbian/gst/devsound/gstdevsoundsrc.h Wed Mar 24 17:55:38 2010 -0500 @@ -77,6 +77,7 @@ gint samplesrecorded; GList* fmt; GList* supportedbitrates; + gboolean eosreceived; guint speechbitrate; gboolean speechvadmode; diff -r 5505e8908944 -r 32e421e6175c gstreamer_core/gst/gstinterface.h --- a/gstreamer_core/gst/gstinterface.h Fri Jan 22 09:59:59 2010 +0200 +++ b/gstreamer_core/gst/gstinterface.h Wed Mar 24 17:55:38 2010 -0500 @@ -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 */ diff -r 5505e8908944 -r 32e421e6175c internal/gstplayer/data/gstplayer.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/gstplayer/data/gstplayer.rss Wed Mar 24 17:55:38 2010 -0500 @@ -0,0 +1,349 @@ +/* +* 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: +* +*/ +/* +* ============================================================================== +* Name : GSTPlayer.rss +* Part of : GSTPlayer +* Interface : +* Description : +* Version : +* + +* ============================================================================== +*/ + +// RESOURCE IDENTIFIER +NAME HEWB // 4 letter ID + + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "GSTPlayer.hrh" +#include "GSTPlayer.rls" + +#define KWidth 176 +#define KHeight 100 +#define KMaxLength 256 + +// RESOURCE DEFINITIONS +// ----------------------------------------------------------------------------- +// +// Define the resource file signature +// This resource should be empty. +// +// ----------------------------------------------------------------------------- +// +RESOURCE RSS_SIGNATURE + { + } + +// ----------------------------------------------------------------------------- +// +// Default Document Name +// +// ----------------------------------------------------------------------------- +// +RESOURCE TBUF r_default_document_name + { + buf="HEWB"; + } + +// ----------------------------------------------------------------------------- +// +// Define default menu and CBA key. +// +// ----------------------------------------------------------------------------- +// +RESOURCE EIK_APP_INFO + { + menubar = r_gstplayer_menubar; + cba = R_AVKON_SOFTKEYS_OPTIONS_EXIT; + } + + +// ----------------------------------------------------------------------------- +// +// r_helloworldbasic_menubar +// Menubar for HelloWorldBasic example +// +// ----------------------------------------------------------------------------- +// +RESOURCE MENU_BAR r_gstplayer_menubar + { + titles = + { + MENU_TITLE { menu_pane = r_gstplayer_menu; } + }; + } + +RESOURCE MENU_PANE r_play_cmd + { + items= + { + MENU_ITEM{command = EGSTPlayerNewSong;txt = "New Song";}, + MENU_ITEM{command = EGSTPlayerPlay;txt = "Play";}, + MENU_ITEM{command = EGSTPlayerSamplesPlayed; txt = "Samples Played"; }, + MENU_ITEM{command = EGSTPlayerSkPadCaps;txt = "Sink Pad Caps";cascade=r_sinkpad_caps;}, + MENU_ITEM{command = EGSTPlayerVolume;txt = "Volume"; cascade=r_volume_cmds;} + }; + } + +RESOURCE MENU_PANE r_record_cmd + { + items= + { + MENU_ITEM{command = EGSTPlayerRecordWav;txt = "Record WAV";}, + MENU_ITEM{command = EGSTPlayerRecordRaw;txt = "Record RAW";}, + MENU_ITEM{command = EGSTPlayerRecordAmr;txt = "Record AMR";}, + MENU_ITEM{command = EGSTPlayerRecordG711;txt = "Record G711";}, + MENU_ITEM{command = EGSTPlayerRecordG729;txt = "Record G729";}, + MENU_ITEM{command = EGSTPlayerRecordIlbc;txt = "Record ILBC";}, + MENU_ITEM { command = EGSTPlayerSamplesRecorded; txt = "Samples Recorded"; }, + MENU_ITEM{command = EGSTPlayerSourcePadCaps;txt = "Source Pad Caps";cascade=r_srcpad_caps;}, + MENU_ITEM{command = EGSTPlayerGain;txt = "Gain"; cascade=r_gain_cmds;} + }; + } + +RESOURCE MENU_PANE r_volume_cmds + { + items= + { + MENU_ITEM { command = EGSTPlayerCurrentVolume; txt = "Current Volume"; }, + MENU_ITEM { command = EGSTPlayerMaxVolume; txt = "Max Volume"; }, + MENU_ITEM { command = EGSTPlayerVolumeUp; txt = "Volume up"; }, + MENU_ITEM { command = EGSTPlayerVolumeDown; txt = "Volume down"; }, + MENU_ITEM { command = EGSTPlayerRightBalance; txt = "Right Balance"; }, + MENU_ITEM { command = EGSTPlayerLeftBalance; txt = "Left Balance"; } + }; + } + +RESOURCE MENU_PANE r_gain_cmds + { + items= + { + MENU_ITEM { command = EGSTPlayerCurrentGain; txt = "Current Gain"; }, + MENU_ITEM { command = EGSTPlayerMaxGain; txt = "Max Gain"; }, + MENU_ITEM { command = EGSTPlayerGainUp; txt = "Gain up"; }, + MENU_ITEM { command = EGSTPlayerGainDown; txt = "Gain down"; } + // MENU_ITEM { command = EGSTPlayerRightBalance; txt = "Right Balance"; }, + // MENU_ITEM { command = EGSTPlayerLeftBalance; txt = "Left Balance"; } + }; + } +RESOURCE MENU_PANE r_sinkpad_caps + { + items= + { + MENU_ITEM { command = EGSTPlayerSinkPadCaps; txt = "DevSound sinkpad caps"; }, + MENU_ITEM { command = EGSTPlayerNegotiatedSinkCaps; txt = "Negotiated Sink Caps"; } + }; + } + +RESOURCE MENU_PANE r_srcpad_caps + { + items= + { + MENU_ITEM { command = EGSTPlayerSrcPadCaps; txt = "DevSound srcpad caps"; }, + MENU_ITEM { command = EGSTPlayerNegotiatedSrcCaps; txt = "Negotiated Src Caps"; } + }; + } + +RESOURCE MENU_PANE r_sample_info + { + items= + { + MENU_ITEM { command = EGSTPlayerSamplesPlayed; txt = "Samples Played"; }, + MENU_ITEM { command = EGSTPlayerSamplesRecorded; txt = "Samples Recorded"; }//, + //MENU_ITEM { command = EGSTPlayerTimePlayed; txt = "Time Played"; } + }; + } + +// ----------------------------------------------------------------------------- +// +// r_helloworldbasic_menu +// Menu for "Options" +// +// ----------------------------------------------------------------------------- +// +RESOURCE MENU_PANE r_gstplayer_menu + { + items = + { + // added the new Options menu command here + MENU_ITEM + { + command = EGSTPlayerPlayerTest; + txt = "Play"; + cascade=r_play_cmd; + }, + MENU_ITEM + { + command = EGSTPlayerRecordTest; + txt = "Record"; + cascade=r_record_cmd; + }, + MENU_ITEM + { + command = EGSTPlayerStop; + txt = "Stop"; + }, + MENU_ITEM + { + command = EGSTPlayerPause; + txt = "Pause"; + }, + MENU_ITEM + { + command = EGSTRecorderStop; + txt = "Record Stop"; + }, + MENU_ITEM + { + command = EGSTPlayerResume; + txt = "Resume"; + }, + /* MENU_ITEM + { + command = EGSTPlayerVolume; + txt = "Volume"; + cascade=r_volume_cmds; + }, + */ + /* MENU_ITEM + { + command = EGSTPlayerSamplesInfo; + txt = "Sample info"; + cascade=r_sample_info; + }, + */ + /* MENU_ITEM + { + command = EGSTPlayerPadCaps; + txt = "Pad Caps"; + cascade=r_pad_caps; + }, + */ + MENU_ITEM + { + command = EAknSoftkeyExit; + txt = "Exit"; + } + }; + } + +// ----------------------------------------------------------------------------- +// +// Resources for messages. +// +// ----------------------------------------------------------------------------- +// +RESOURCE TBUF32 r_hewb_command1_text { buf="Select mp3/wav/raw file."; } +RESOURCE TBUF32 r_hewb_command2_text { buf="Select mp3/wav/raw New Song!"; } +RESOURCE TBUF32 r_hewb_caption_string { buf="GSTPlayer"; } + + +// ---------------------------------------------------------------------------- +// +// r_helloworldbasic_localisable_app_info +// +// ---------------------------------------------------------------------------- +// +RESOURCE LOCALISABLE_APP_INFO r_gstplayer_localisable_app_info + { + short_caption = "GSTPlayer"; + caption_and_icon = + CAPTION_AND_ICON_INFO + { + caption = "GSTPlayer"; + + number_of_icons = 1; + icon_file = "\\resource\\apps\\gstplayer_aif.mif"; + }; + } + +/* RESOURCE DIALOG r_res_id_for_a_dialog +{ + flags = EAknDialogSelectionList; + buttons = R_AVKON_SOFTKEYS_OK_CANCEL; + items = + { + DLG_LINE + { + type = EAknCtSingleListBox; + id = ESelectionListControl; + control = LISTBOX + { + flags = EAknListBoxSelectionList; + }; + } + }; +} + + + +RESOURCE MENU_BAR r_res_id_for_a_menubar +{ + titles = + { + MENU_TITLE { menu_pane = R_AVKON_MENUPANE_SETTING_LIST ; } + }; +}*/ + +RESOURCE RTXTED r_richtexteditor_rich_text_editor + { + width = KWidth; + height = KHeight; + textlimit = KMaxLength; + flags = EEikEdwinReadOnly | EEikEdwinAvkonDisableCursor; + avkon_flags = EAknEditorFlagEnableScrollBars; + } +// --------------------------------------------------------- +// +// r_musicshop_memory_selection_dialog +// +// --------------------------------------------------------- +// +RESOURCE MEMORYSELECTIONDIALOG r_musicshop_memory_selection_dialog + { + softkey_1 = text_softkey_select; + locations = + { + LOCATION { root_path = text_phone_memory_root_path; }, + LOCATION { root_path = text_memory_card_root_path; } + }; + } + +// End of File + diff -r 5505e8908944 -r 32e421e6175c internal/gstplayer/group/gstplayer.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/gstplayer/group/gstplayer.mmp Wed Mar 24 17:55:38 2010 -0500 @@ -0,0 +1,118 @@ +/* +* 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: +* +*/ +/* +* ============================================================================== +* Name : gstplayer.mmp +* Part of : GSTPlayer +* Interface : +* Description : +* Version : +* +* ============================================================================== +*/ + +#include + +TARGET GSTPlayer.exe +TARGETTYPE exe +UID 0x100039CE 0xA000017F +LANG SC +VENDORID VID_DEFAULT +CAPABILITY All -tcb + +SECUREID 0xA000017F +EPOCSTACKSIZE 0x8000 +EPOCHEAPSIZE 0x1000000 0x1000000 + +SOURCEPATH ../src +SOURCE GSTPlayer.cpp +SOURCE GSTPlayerApplication.cpp +SOURCE GSTPlayerAppView.cpp +SOURCE GSTPlayerAppUi.cpp +SOURCE GSTPlayerDocument.cpp +SOURCE RichTextEditor.cpp +SOURCE GlibEventHandler.cpp +SOURCE SymGstreamer.cpp + +SOURCEPATH ../data + +START RESOURCE GSTPlayer.rss +HEADER +TARGETPATH resource/apps +END //RESOURCE + +START RESOURCE GSTPlayer_reg.rss +DEPENDS gstplayer.rsg +#ifdef WINSCW +TARGETPATH /private/10003a3f/apps +#else +TARGETPATH /private/10003a3f/import/apps +#endif +END //RESOURCE + +USERINCLUDE ../inc + +MW_LAYER_SYSTEMINCLUDE +OS_LAYER_LIBC_SYSTEMINCLUDE +OS_LAYER_GLIB_SYSTEMINCLUDE +USERINCLUDE ../../../include/gstreamer +USERINCLUDE ../../../include/gstreamer/gst +USERINCLUDE ../../../include/gstreamer/gst/base +USERINCLUDE ../../../include/gstreamer/gst/controller +USERINCLUDE ../../../include/gstreamer/gst/dataprotocol +USERINCLUDE ../../../include/gstreamer/gst/net + +LIBRARY euser.lib +LIBRARY apparc.lib +LIBRARY cone.lib +LIBRARY eikcore.lib +LIBRARY avkon.lib +LIBRARY commonengine.lib +LIBRARY efsrv.lib +LIBRARY estor.lib +LIBRARY PlatformEnv.lib +LIBRARY CommonDialogs.lib +LIBRARY eikctl.lib +LIBRARY eikcoctl.lib +LIBRARY etext.lib +LIBRARY ws32.lib +LIBRARY libc.lib +LIBRARY libpthread.lib +LIBRARY libdl.lib +LIBRARY libm.lib +LIBRARY libglib.lib +LIBRARY libgmodule.lib +LIBRARY libgobject.lib +LIBRARY libgthread.lib +LIBRARY glibbackend.lib +//LIBRARY libpopt.lib +LIBRARY libz.lib +//LIBRARY pavFeedsLibXml2.lib +LIBRARY libgstreamer.lib +//LIBRARY libgsterrorconcealment.lib +//LIBRARY libgstg711decoderinterface.lib +LIBRARY libgstdevsoundext.lib +LIBRARY MMFDevSound.lib + +// End of File + +SMPSAFE diff -r 5505e8908944 -r 32e421e6175c internal/gstplayer/inc/gstplayer.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/gstplayer/inc/gstplayer.hrh Wed Mar 24 17:55:38 2010 -0500 @@ -0,0 +1,83 @@ +/* +* 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: +* +*/ +/* +* ============================================================================== +* Name : helloworldbasic.hrh +* Part of : Helloworldbasic +* Interface : +* Description : +* Version : +* + +* ============================================================================== +*/ + +#ifndef __GSTPLAYER_HRH__ +#define __GSTPLAYER_HRH__ + +// GSTPlayer enumerate command codes +enum TGSTPlayerIds + { + EGSTPlayerNewSong = 0x6001, // start value must not be 0 + EGSTPlayerPlayerTest, + EGSTPlayerRecordTest, + EGSTPlayerPlay, + EGSTPlayerStop, + EGSTRecorderStop, + EGSTPlayerPause, + EGSTPlayerResume, + EGSTPlayerRecordRaw, + EGSTPlayerRecordWav, + EGSTPlayerRecordAmr, + EGSTPlayerRecordG711, + EGSTPlayerRecordG729, + EGSTPlayerRecordIlbc, + EGSTPlayerVolume, + EGSTPlayerCurrentVolume, + EGSTPlayerMaxVolume, + EGSTPlayerVolumeUp, + EGSTPlayerVolumeDown, + EGSTPlayerRightBalance, + EGSTPlayerLeftBalance, + EGSTPlayerGain, + EGSTPlayerCurrentGain, + EGSTPlayerMaxGain, + EGSTPlayerGainUp, + EGSTPlayerGainDown, + EGSTPlayerSamplesPlayed, + EGSTPlayerSamplesRecorded, + EGSTPlayerSamplesInfo, + EGSTPlayerTimePlayed, + + EGSTPlayerSkPadCaps, + EGSTPlayerSourcePadCaps, + + EGSTPlayerSinkPadCaps, + EGSTPlayerSrcPadCaps, + + EGSTPlayerNegotiatedSinkCaps, + EGSTPlayerNegotiatedSrcCaps + + + }; + +#endif // __HELLOWORLDBASIC_HRH__ diff -r 5505e8908944 -r 32e421e6175c internal/gstplayer/src/GSTPlayerappui.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/gstplayer/src/GSTPlayerappui.cpp Wed Mar 24 17:55:38 2010 -0500 @@ -0,0 +1,447 @@ +/* +* 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: +* +*/ +/* +* ============================================================================== +* Name : gstplayerappui.cpp +* Part of : gstplayer +* Interface : +* Description : +* Version : +* + +* ============================================================================== +*/ + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GSTPlayer.pan" +#include "GSTPlayerAppUi.h" +#include "GSTPlayerAppView.h" +#include "GSTPlayer.hrh" + +#include "GlibEventHandler.h" +#include "gstreamer.h" + +TFileName fileName; + +_LIT( KHelloFileName, "\\private\\A000017F\\Hello.txt" ); +_LIT( KHelloText, "HELLO WORLD!"); + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// CGSTPlayerAppUi::ConstructL() +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CGSTPlayerAppUi::ConstructL() + { + // Initialise app UI with standard value. + BaseConstructL(CAknAppUi::EAknEnableSkin); + // Here the Hello.txt file can be created, if it is not copied automatically. + /* + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + + RFile file; + + // Create a file to write the text to + if ( file.Replace(fsSession, KHelloFileName, EFileWrite ) != KErrNone ) + { + return; + } + CleanupClosePushL( file ); + + RFileWriteStream outputFileStream( file ); + CleanupClosePushL( outputFileStream ); + outputFileStream << KHelloText; + + CleanupStack::PopAndDestroy(2); // file, outputFileStream + + fsSession.Close(); + */ + + // Create view object + iAppView = CGSTPlayerAppView::NewL(ClientRect() ); + + iGstView = iAppView; + + } +// ----------------------------------------------------------------------------- +// CGSTPlayerAppUi::CGSTPlayerAppUi() +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +CGSTPlayerAppUi::CGSTPlayerAppUi() + { + // No implementation required + } + +// ----------------------------------------------------------------------------- +// CGSTPlayerAppUi::~CGSTPlayerAppUi() +// Destructor. +// ----------------------------------------------------------------------------- +// +CGSTPlayerAppUi::~CGSTPlayerAppUi() + { + + if (iAppView) + { + delete iAppView; + iAppView = NULL; + } + + } + +// ----------------------------------------------------------------------------- +// CGSTPlayerAppUi::HandleCommandL() +// Takes care of command handling. +// ----------------------------------------------------------------------------- +// +void CGSTPlayerAppUi::HandleCommandL(TInt aCommand) + { + switch (aCommand) + { + case EEikCmdExit: + case EAknSoftkeyExit: + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + gst_object_unref(GST_OBJECT (pipeline)); + + } + Exit(); + break; + + case EGSTPlayerNewSong: + { + /*TDes& aPath; + TBool aMemoryCardStorageAllowed;*/ + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + gst_object_unref(GST_OBJECT (pipeline)); + + } + CAknMemorySelectionDialog* memoryDialog = + CAknMemorySelectionDialog::NewL(ECFDDialogTypeSave, + R_MUSICSHOP_MEMORY_SELECTION_DIALOG, EFalse); + CleanupStack::PushL(memoryDialog); + + CAknMemorySelectionDialog::TMemory + mem(CAknMemorySelectionDialog::EPhoneMemory); + TFileName ignore; + //TFileName path; + if (! (memoryDialog->ExecuteL(mem, &fileName, &ignore) )) + { + // User dnt select the memory location. + // retVal = EFalse; + } + else + { + //aPath.Copy( path ); + } + CleanupStack::PopAndDestroy(); // memoryDialog + + + //if user has pressed cancel button, then just return + if (!ShowDirListL(fileName)) + { + return; + } //end if + if (GstreamerNew(fileName) == -1) + { + // Load a string from the resource file and display it + HBufC* textResource = + StringLoader::LoadLC( R_HEWB_COMMAND1_TEXT); + CAknInformationNote* informationNote; + + informationNote = new ( ELeave ) CAknInformationNote; + + // Show the information Note with + // textResource loaded with StringLoader. + informationNote->ExecuteLD( *textResource); + + // Pop HBuf from CleanUpStack and Destroy it. + CleanupStack::PopAndDestroy(textResource); + + } + + } + break; + case EGSTPlayerPlay: + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + if (GstreamerNew(fileName) == -1) + { + // Load a string from the resource file and display it + HBufC* textResource = + StringLoader::LoadLC( R_HEWB_COMMAND2_TEXT); + CAknInformationNote* informationNote; + + informationNote = new ( ELeave ) CAknInformationNote; + + // Show the information Note with + // textResource loaded with StringLoader. + informationNote->ExecuteLD( *textResource); + + // Pop HBuf from CleanUpStack and Destroy it. + CleanupStack::PopAndDestroy(textResource); + + } + + break; + case EGSTPlayerStop: + if (pipeline!=NULL) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (pipeline)); + pipeline = NULL; + } + break; + case EGSTRecorderStop: + if (pipeline!=NULL) + { + gst_element_send_event (pipeline, gst_event_new_eos ()); + } + break; + + case EGSTPlayerPause: + if (pipeline!=NULL ) + { + + gst_element_set_state(pipeline, GST_STATE_PAUSED); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + break; + + case EGSTPlayerResume: + if (pipeline!=NULL) + { + + gst_element_set_state(pipeline, GST_STATE_PLAYING); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + break; + + case EGSTPlayerRecordWav: + { + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + gst_record_wav(); + } + break; + + case EGSTPlayerRecordRaw: + { + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + gst_record_raw(); + } + break; + + case EGSTPlayerRecordAmr: + { + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + gst_record_amr(); + } + break; + + case EGSTPlayerRecordG711: + { + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + gst_record_g711(); + } + break; + case EGSTPlayerRecordG729: + { + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + gst_record_g729(); + } + break; + case EGSTPlayerRecordIlbc: + { + if (pipeline!=NULL && pipeline ->current_state + == GST_STATE_PLAYING) + { + + gst_element_set_state(pipeline, GST_STATE_NULL); + //gst_object_unref (GST_OBJECT (pipeline)); + + } + gst_record_ilbc(); + } + break; + + case EGSTPlayerCurrentVolume: + gst_current_volume(); + break; + case EGSTPlayerMaxVolume: + gst_max_volume(); + break; + case EGSTPlayerVolumeUp: + gst_volume_up(); + break; + case EGSTPlayerVolumeDown: + gst_volume_down(); + break; + case EGSTPlayerLeftBalance: + case EGSTPlayerRightBalance: + gst_balance(); + break; + case EGSTPlayerCurrentGain: + gst_current_gain(); + break; + case EGSTPlayerMaxGain: + gst_max_gain(); + break; + case EGSTPlayerGainUp: + gst_gain_up(); + break; + case EGSTPlayerGainDown: + gst_gain_down(); + break; + case EGSTPlayerSamplesPlayed: + samplesplayed(); + break; + case EGSTPlayerSamplesRecorded: + samplesrecorded(); + break; + case EGSTPlayerSinkPadCaps: + getsinkpadcaps(); + break; + case EGSTPlayerSrcPadCaps: + getsrcpadcaps(); + break; + case EGSTPlayerNegotiatedSinkCaps: + negotiatedsinkcaps(); + break; + case EGSTPlayerNegotiatedSrcCaps: + negotiatedsrccaps(); + break; + default: + Panic(EGSTPlayerUi); + break; + } + } +// ----------------------------------------------------------------------------- +// Called by the framework when the application status pane +// size is changed. Passes the new client rectangle to the +// AppView +// ----------------------------------------------------------------------------- +// +void CGSTPlayerAppUi::HandleStatusPaneSizeChange() + { + iAppView->SetRect(ClientRect() ); + + } + +TBool CGSTPlayerAppUi::ShowDirListL(TFileName &filePath) + { + + _LIT(KDialogTitle, "Select File"); + + TBool ret = CAknFileSelectionDialog::RunDlgLD(filePath, // on return, contains the selected file's name + PathInfo::PhoneMemoryRootPath(), // default root path for browsing + KDialogTitle, // Dialog's title + 0 // Pointer to class implementing + // MAknFileSelectionObserver. OkToExitL is called + // when user has selected an file. + ); + + return ret; + + } + +void ShowNoteL() + { + // Load a string from the resource file and display it + HBufC* textResource = StringLoader::LoadLC( R_HEWB_COMMAND1_TEXT); + CAknInformationNote* informationNote; + + informationNote = new ( ELeave ) CAknInformationNote; + + // Show the information Note with + // textResource loaded with StringLoader. + informationNote->ExecuteLD( *textResource); + + // Pop HBuf from CleanUpStack and Destroy it. + CleanupStack::PopAndDestroy(textResource); + } +// End of File + diff -r 5505e8908944 -r 32e421e6175c internal/gstplayer/src/SymGstreamer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/gstplayer/src/SymGstreamer.cpp Wed Mar 24 17:55:38 2010 -0500 @@ -0,0 +1,1189 @@ +/* +* 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 "gstreamer.h" +#include "GlibEventHandler.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gstplayerappview.h" + +GstElement *pipeline, *source, *wavparse,*sink,*decoder,*conv,*resample,*record,*fakesink,*filesink,*encoder,*filter,*wavenc; +GstBus *bus; +GstCaps* caps; +GstState current,pending; +char carray[1024]; + +CGSTPlayerAppView *iGstView; + +GstPad *dssinkpad; +GstCaps *dssinkcap; +GstPad *dssrcpad; +GstCaps *dssrccap; +GstStructure *str; + +gboolean negcaps = FALSE; + +static gboolean print_field (GQuark field, const GValue *value, gpointer pfx); +static void print_caps (const GstCaps *caps, const gchar *pfx); + + + +static void +cb_raw_playback_handoff (GstElement *src, GstBuffer *buffer, GstPad *pad, + gpointer user_data) + { + static gint readbytes = 0; + static gboolean eofReached = FALSE; + + size_t readsize; + gint size; + FILE *f; + GstCaps *bufCaps; + if ( eofReached == TRUE ) + { + //gst_element_set_state (pipeline, GST_STATE_NULL); + // gst_object_unref (GST_OBJECT (pipeline)); + if ( gst_element_send_event (src, gst_event_new_eos ()) == TRUE ) + { + g_print ("posted eos"); + } + + else + { + //g_print ("unable to post eos"); + } + return; + } + + readsize = 0; + f = fopen (carray, "r"); + eofReached = TRUE; + if ( fseek(f, readbytes, 0) == 0 ) + { + readsize = fread (GST_BUFFER_DATA (buffer),1,GST_BUFFER_SIZE (buffer),f); + eofReached = FALSE; + GST_BUFFER_SIZE (buffer) = readsize; + } + fclose(f); + + size = GST_BUFFER_SIZE (buffer); + readbytes += readsize; + if ( (readsize < size) || (readsize == 0) ) + { + eofReached = TRUE; + } + + bufCaps = gst_caps_new_simple ("audio/x-raw-int", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + gst_buffer_set_caps(buffer,bufCaps); + + } + +static void +cb_play_mp3_handoff (GstElement *fakesrc, + GstBuffer *buffer, + GstPad *pad, + gpointer user_data) +{ +GstCaps *bufCaps; + static gint readbytes = 0; + size_t readsize = 0; + int size = GST_BUFFER_SIZE (buffer); + + FILE *f = fopen (carray, "r"); + fseek(f,readbytes,0); + readsize = fread(GST_BUFFER_DATA (buffer),1,GST_BUFFER_SIZE (buffer),f); + readbytes += readsize; + GST_BUFFER_SIZE (buffer) = readsize; + if(readsize == 0) + { + gst_element_send_event(fakesrc,gst_event_new_eos()); + } + fclose(f); + +} +static void +cb_record_raw_handoff (GstElement *fakesrc, + GstBuffer *buffer, + GstPad *pad, + gpointer user_data) +{ + int size = GST_BUFFER_SIZE (buffer); + //g_print ("[%u]", size); + FILE *f = fopen (carray, "a"); + fwrite(GST_BUFFER_DATA (buffer),1,GST_BUFFER_SIZE (buffer),f); + fclose(f); +} + + +static gboolean +bus_call (GstBus *bus, + GstMessage *msg, + gpointer data) +{ + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_EOS: + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (pipeline)); + break; + case GST_MESSAGE_ERROR: { + gchar *debug; + GError *err; + gst_message_parse_error (msg, &err, &debug); + g_free (debug); + g_print ("Error: %s\n", err->message); + g_error_free (err); + break; + } + default: + break; + } + + return TRUE; +} + + +static void +new_pad_cb (GstElement *wavparse, GstPad *new_pad, gpointer pipeline) + { + //GstElement *sink,*conv,*resample; + gst_element_set_state ((_GstElement *)pipeline, GST_STATE_PAUSED); + sink = gst_element_factory_make ("devsoundsink", "sink"); + conv = gst_element_factory_make ("audioconvert", "audioconvert"); + if (!conv) { + g_print ("could not create \"audioconvert\" element!"); + return; + } + resample = gst_element_factory_make ("audioresample", "audioresample"); + if (!resample) { + g_print ("could not create \"audioresample\" element!"); + return ; + } + gst_bin_add_many(GST_BIN (pipeline), conv, resample, sink, NULL); + + // if (!gst_element_link (wavparse, sink)) + // g_error ("link(wavparse, sink) failed!\n"); + + if(! gst_element_link_many (wavparse,conv, resample, sink, NULL)) + g_print ("link(wavparse,conv,remaple sink) failed!\n"); + + gst_element_set_state ((_GstElement *)pipeline, GST_STATE_PLAYING); + } + + #define FILENAME 1024 + int GstreamerNew(TFileName filename) + { + size_t ret; + + ret = wcstombs(carray, (const wchar_t *)filename.PtrZ(), FILENAME); + int file_type=0; + + + + char *p; + p = strrchr(carray, '.'); + + if ((p != NULL) && (strcmp(p, ".mp3") == 0)) + { + file_type=2; + } + else if ((p != NULL) && (strcmp(p, ".wav") == 0)) + { + file_type=1; + } + else if ((p != NULL) && (strcmp(p, ".raw") == 0)) + { + file_type=3; + } + else if ((p != NULL) && (strcmp(p, ".amr") == 0)) + { + file_type=4; + } + else if ((p != NULL) && (strcmp(p, ".g711") == 0)) + { + file_type=5; + } + else if ((p != NULL) && (strcmp(p, ".g729") == 0)) + { + file_type=6; + } + else if ((p != NULL) && (strcmp(p, ".lbc") == 0)) + { + file_type=7; + } + else + return -1; + + if(file_type==1) + { + gst_play_wave(); + } + else if(file_type==2) + { + gst_play_mp3(); + } + else if(file_type==3) + { + gst_play_raw(); + } + else if(file_type==4) + { + gst_play_amr(); + } + else if(file_type==5) + { + gst_play_g711(); + } + else if(file_type==6) + { + gst_play_g729(); + } + else if(file_type==7) + { + gst_play_ilbc(); + } + + else + { + return 0; + } + } + + +int gst_play_mp3() +{ + /* create elements */ + gboolean link_ok; + + pipeline = gst_pipeline_new ("pipeline"); + source = gst_element_factory_make ("filesrc", "filesrc"); + //sink = gst_element_factory_make ("fakesink", "sink"); + sink = gst_element_factory_make ("devsoundsink", "sink"); + + caps = gst_caps_new_simple ("audio/mp3", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 16000, + "channels", G_TYPE_INT, 2, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch( bus, bus_call, NULL); + gst_object_unref (bus); + + g_object_set (G_OBJECT (source), "location", carray, NULL); + + gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); + + //gst_element_link (source, sink); + link_ok = gst_element_link_filtered (source, sink, caps); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; +} + + + int gst_play_wave() + { + /* create elements */ + if(!pipeline) + { + pipeline = gst_pipeline_new ("pipeline"); + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, bus_call, NULL); + gst_object_unref (bus); + } + + if(!source) + { + source = gst_element_factory_make ("filesrc", "pavsrc"); + g_object_set (G_OBJECT (source), "location", carray, NULL); + gst_bin_add (GST_BIN (pipeline), source); + } + + if(!wavparse) + { + wavparse = gst_element_factory_make ("wavparse", "parse"); + gst_bin_add (GST_BIN (pipeline), wavparse ); + g_signal_connect (wavparse, "pad-added", G_CALLBACK (new_pad_cb),pipeline); + } + + /* set filename property on the file source */ + if (!gst_element_link (source, wavparse)) + { + g_print("could not link elements!"); + return -1; + } + + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + return 0; + } + + int gst_record_wav() + { + + /* create a new bin to hold the elements */ + pipeline = gst_pipeline_new("pipeline"); + + record = gst_element_factory_make("devsoundsrc", "record_audio"); + if (!record) + { + g_print("could not create \"record\" element!"); + return -1; + } + + filesink = gst_element_factory_make("filesink", "filesink"); + if (!filesink) + { + g_print("could not create \"filesink\" element!"); + return -1; + } + + wavenc = gst_element_factory_make("wavenc", "wavencoder"); + if (!wavenc) + { + g_print("could not create \"wavenc\" element!"); + return -1; + } + + _LIT(KFILENAME,"c:\\data\\test.wav"); + TFileName fn; + fn.Append(KFILENAME); + TInt ret; + // char carray[FILENAME]; + ret = wcstombs(carray, (const wchar_t *)fn.PtrZ(), FILENAME); + + g_object_set(G_OBJECT (filesink), "location", carray, NULL); + bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline)); + gst_bus_add_watch(bus, bus_call, NULL); + gst_object_unref(bus); + + /* add objects to the main pipeline */ + gst_bin_add_many(GST_BIN (pipeline),record,wavenc,filesink, NULL); + + /* link the elements */ + //gst_element_link_many(record, wavenc,filesink, NULL); + caps = gst_caps_new_simple ("audio/x-raw-int", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 16000, + "channels", G_TYPE_INT, 1, NULL); + + gst_element_link_filtered (record, wavenc, caps); + gst_element_link (wavenc, filesink); + gst_caps_unref (caps); + + /* start recording */ + gst_element_set_state(pipeline, GST_STATE_PLAYING); + + return 0; + } + + int gst_record_amr() + { + iGstView->DrawText(_L("Recording AMR"),KRgbRed); + + /* create a new bin to hold the elements */ + pipeline = gst_pipeline_new ("pipeline"); + + //g_print ("pipeline created"); + record = gst_element_factory_make ("devsoundsrc", "record_audio"); + // encoder = gst_element_factory_make ("wavenc", NULL); + if (!record) { + g_print ("could not create \"record\" element!"); + iGstView->DrawText(_L("Devsound src not available"),KRgbRed); + return -1; + } + + filesink = gst_element_factory_make("filesink", "filesink"); + if (!filesink) + { + g_print("could not create \"filesink\" element!"); + return -1; + } + + caps = gst_caps_new_simple ("audio/amr", + "width", G_TYPE_INT, 8, + "depth", G_TYPE_INT, 8, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + + g_object_set (G_OBJECT (record), + "blocksize", 1280, + NULL); + + _LIT(KFILENAME,"c:\\data\\recordtest.amr"); + TFileName fn; + fn.Append(KFILENAME); + TInt ret; + ret = wcstombs(carray, (const wchar_t *)fn.PtrZ(), FILENAME); + g_object_set(G_OBJECT (filesink), "location", carray, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, bus_call, NULL); + gst_object_unref (bus); + + + /* add objects to the main pipeline */ + gst_bin_add_many(GST_BIN (pipeline),record,filesink , NULL); + /* link the elements */ + gst_element_link_filtered (record, filesink, caps); + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; + } + + int gst_record_g711() + { + /* create a new bin to hold the elements */ + pipeline = gst_pipeline_new ("pipeline"); + + //g_print ("pipeline created"); + record = gst_element_factory_make ("devsoundsrc", "record_audio"); + // encoder = gst_element_factory_make ("wavenc", NULL); + if (!record) { + g_print ("could not create \"record\" element!"); + return -1; + } + + filesink = gst_element_factory_make("filesink", "filesink"); + if (!filesink) + { + g_print("could not create \"filesink\" element!"); + return -1; + } + + caps = gst_caps_new_simple ("audio/x-alaw", + "width", G_TYPE_INT, 8, + "depth", G_TYPE_INT, 8, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + g_object_set (G_OBJECT (record), + "blocksize", 1280, + NULL); + + _LIT(KFILENAME,"c:\\data\\recordtest.g711"); + TFileName fn; + fn.Append(KFILENAME); + TInt ret; + ret = wcstombs(carray, (const wchar_t *)fn.PtrZ(), FILENAME); + g_object_set(G_OBJECT (filesink), "location", carray, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, bus_call, NULL); + gst_object_unref (bus); + + + /* add objects to the main pipeline */ + gst_bin_add_many(GST_BIN (pipeline),record,filesink , NULL); + /* link the elements */ + gst_element_link_filtered (record, filesink, caps); + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; + } + + int gst_record_g729() + { + /* create a new bin to hold the elements */ + pipeline = gst_pipeline_new ("pipeline"); + + record = gst_element_factory_make ("devsoundsrc", "record_audio"); + if (!record) { + g_print ("could not create \"record\" element!"); + return -1; + } + + filesink = gst_element_factory_make("filesink", "filesink"); + if (!filesink) + { + g_print("could not create \"filesink\" element!"); + return -1; + } + + caps = gst_caps_new_simple ("audio/g729", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + g_object_set (G_OBJECT (record), + "blocksize", 1280, + NULL); + + _LIT(KFILENAME,"c:\\data\\recordtest.g729"); + TFileName fn; + fn.Append(KFILENAME); + TInt ret; + ret = wcstombs(carray, (const wchar_t *)fn.PtrZ(), FILENAME); + g_object_set(G_OBJECT (filesink), "location", carray, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, bus_call, NULL); + gst_object_unref (bus); + + + /* add objects to the main pipeline */ + gst_bin_add_many(GST_BIN (pipeline),record,filesink , NULL); + /* link the elements */ + gst_element_link_filtered (record, filesink, caps); + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; + } + + int gst_record_ilbc() + { + /* create a new bin to hold the elements */ + pipeline = gst_pipeline_new ("pipeline"); + + record = gst_element_factory_make ("devsoundsrc", "record_audio"); + if (!record) { + g_print ("could not create \"record\" element!"); + return -1; + } + + filesink = gst_element_factory_make("filesink", "filesink"); + if (!filesink) + { + g_print("could not create \"filesink\" element!"); + return -1; + } + + caps = gst_caps_new_simple ("audio/ilbc", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + g_object_set (G_OBJECT (record), + "blocksize", 1280, + NULL); + + _LIT(KFILENAME,"c:\\data\\recordtest.lbc"); + TFileName fn; + fn.Append(KFILENAME); + TInt ret; + ret = wcstombs(carray, (const wchar_t *)fn.PtrZ(), FILENAME); + g_object_set(G_OBJECT (filesink), "location", carray, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, bus_call, NULL); + gst_object_unref (bus); + + + /* add objects to the main pipeline */ + gst_bin_add_many(GST_BIN (pipeline),record,filesink , NULL); + /* link the elements */ + gst_element_link_filtered (record, filesink, caps); + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; + } + + int gst_record_raw() + { + + /* create a new bin to hold the elements */ + pipeline = gst_pipeline_new ("pipeline"); + + //g_print ("pipeline created"); + record = gst_element_factory_make ("devsoundsrc", "record_audio"); + // encoder = gst_element_factory_make ("wavenc", NULL); + if (!record) { + g_print ("could not create \"record\" element!"); + return -1; + } + //g_print ("record created"); + + filesink = gst_element_factory_make("filesink", "filesink"); + if (!filesink) + { + g_print("could not create \"filesink\" element!"); + return -1; + } + //GstRingBufferSpec + //g_print ("sink created"); + caps = gst_caps_new_simple ("audio/x-raw-int", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + //g_print ("caps created"); + g_object_set (G_OBJECT (record), + //"signal-handoffs", TRUE, + "blocksize", 1280, + // "gain",10000, + NULL); + + /*g_object_set (G_OBJECT (fakesink), + "signal-handoffs", TRUE, + "sizemax", 4096, + "sizetype", 2, NULL);*/ + + _LIT(KFILENAME,"c:\\data\\test.raw"); + TFileName fn; + fn.Append(KFILENAME); + TInt ret; + //char carray[FILENAME]; + carray[0]='\0'; + ret = wcstombs(carray, (const wchar_t *)fn.PtrZ(), FILENAME); + + + g_object_set (G_OBJECT (filesink), "location", carray,"buffer-size",1280, NULL); + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch (bus, bus_call, NULL); + gst_object_unref (bus); + + + /* add objects to the main pipeline */ + gst_bin_add_many(GST_BIN (pipeline),record,filesink , NULL); + //g_print ("added to pipe"); + /* link the elements */ + //gst_element_link(record,/*encoder,*/ fakesink/*audiosink*/); + gst_element_link_filtered (record, filesink, caps); + //g_signal_connect (fakesink, "handoff", G_CALLBACK (cb_record_raw_handoff), NULL); + /* start recording */ + // g_print ("start pipe"); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; + } + + + int gst_play_raw() + { + /* create elements */ + gboolean link_ok; + + pipeline = gst_pipeline_new ("pipeline"); + source = gst_element_factory_make ("filesrc", "filesrc"); + //sink = gst_element_factory_make ("fakesink", "sink"); + sink = gst_element_factory_make ("devsoundsink", "sink"); + +caps = gst_caps_new_simple ("audio/x-raw-int", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch( bus, bus_call, NULL); + gst_object_unref (bus); + + /*g_object_set (G_OBJECT(source), + "signal-handoffs", TRUE, + //"num-buffers", 4, + "sizemax", 4096, + "sizetype", 2, + NULL);*/ + + g_object_set (G_OBJECT (source), "location", carray, NULL); +// g_signal_connect (source, "handoff", G_CALLBACK (cb_raw_playback_handoff), NULL); + + gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); + + //gst_element_link (source, sink); + link_ok = gst_element_link_filtered (source, sink, caps); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + +while (caps->refcount > 1) + { + gst_caps_unref (caps); + } + gst_caps_unref (caps); + + + return 0; + } + + int gst_play_amr() + { + /* create elements */ + gboolean link_ok; + + pipeline = gst_pipeline_new ("pipeline"); + source = gst_element_factory_make ("filesrc", "filesrc"); + //sink = gst_element_factory_make ("fakesink", "sink"); + sink = gst_element_factory_make ("devsoundsink", "sink"); + + caps = gst_caps_new_simple ("audio/amr", + "width", G_TYPE_INT, 8, + "depth", G_TYPE_INT, 8, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch( bus, bus_call, NULL); + gst_object_unref (bus); + + g_object_set (G_OBJECT (source), "location", carray, NULL); + + gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); + + link_ok = gst_element_link_filtered (source, sink, caps); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; + } + + int gst_play_g711() + { + /* create elements */ + gboolean link_ok; + + pipeline = gst_pipeline_new ("pipeline"); + source = gst_element_factory_make ("filesrc", "filesrc"); + sink = gst_element_factory_make ("devsoundsink", "sink"); + + caps = gst_caps_new_simple ("audio/x-alaw", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch( bus, bus_call, NULL); + gst_object_unref (bus); + + g_object_set (G_OBJECT (source), "location", carray, NULL); + gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); + + link_ok = gst_element_link_filtered (source, sink, caps); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; + } + int gst_play_g729() + { + /* create elements */ + gboolean link_ok; + + pipeline = gst_pipeline_new ("pipeline"); + source = gst_element_factory_make ("filesrc", "filesrc"); + sink = gst_element_factory_make ("devsoundsink", "sink"); + + caps = gst_caps_new_simple ("audio/g729", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch( bus, bus_call, NULL); + gst_object_unref (bus); + + g_object_set (G_OBJECT (source), "location", carray, NULL); + + gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); + + link_ok = gst_element_link_filtered (source, sink, caps); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + return 0; + } + int gst_play_ilbc() + { + /* create elements */ + gboolean link_ok; + + pipeline = gst_pipeline_new ("pipeline"); + source = gst_element_factory_make ("filesrc", "filesrc"); + sink = gst_element_factory_make ("devsoundsink", "sink"); + + caps = gst_caps_new_simple ("audio/ilbc", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed",G_TYPE_BOOLEAN, TRUE, + "endianness",G_TYPE_INT, G_BYTE_ORDER, + "rate", G_TYPE_INT, 8000, + "channels", G_TYPE_INT, 1, NULL); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + gst_bus_add_watch( bus, bus_call, NULL); + gst_object_unref (bus); + + g_object_set (G_OBJECT (source), "location", carray, NULL); + + gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); + + link_ok = gst_element_link_filtered (source, sink, caps); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + return 0; + } + + + //****** + int gst_current_volume() + { + if(!sink) + { + iGstView->DrawText(_L("Devsound sink not available"),KRgbRed); + return -1; + } + int vol; + TBuf<25> currentvolume(_L("current volume ")); + g_object_get(G_OBJECT(sink), + "volume",&vol,NULL); + + currentvolume.AppendNum(vol); + + iGstView->DrawText(currentvolume,KRgbBlack); + return 0; + } + + int gst_max_volume() + { + if(!sink) + { + iGstView->DrawText(_L("Devsound sink not available"),KRgbRed); + return -1; + } + + int maxvol; + TBuf<25> maxvolume(_L("max volume ")); + + g_object_get(G_OBJECT(sink), + "maxvolume",&maxvol,NULL); + + maxvolume.AppendNum(maxvol); + + iGstView->DrawText(maxvolume,KRgbBlack); + return 0; + + } + int gst_volume_up() + { + + if(!sink) + { + iGstView->DrawText(_L("Devsound sink not available"),KRgbRed); + return -1; + } + iGstView->DrawText(_L("volume up"),KRgbBlack); + int maxvol; + g_object_get(G_OBJECT(sink), + "maxvolume",&maxvol,NULL); + g_object_set (G_OBJECT (sink), + "volume", maxvol, NULL); + return 0; + } + + int gst_volume_down() + { + if(!sink) + { + iGstView->DrawText(_L("Devsound sink not available"),KRgbRed); + return -1; + } + + iGstView->DrawText(_L("volume down"),KRgbBlack); + int maxvol; + g_object_get(G_OBJECT(sink), + "maxvolume",&maxvol,NULL); + g_object_set (G_OBJECT (sink), + "volume", maxvol/2, NULL); + return 0; + } + + int gst_current_gain() + { + if(!record) + { + iGstView->DrawText(_L("Devsound source not available"),KRgbRed); + return -1; + } + int gain; + TBuf<25> currentgain(_L("current gain ")); + g_object_get(G_OBJECT(record), + "gain",&gain,NULL); + + currentgain.AppendNum(gain); + + iGstView->DrawText(currentgain,KRgbBlack); + return 0; + } + + int gst_max_gain() + { + if(!record) + { + iGstView->DrawText(_L("Devsound source not available"),KRgbRed); + return -1; + } + + int max; + TBuf<25> maxgain(_L("max gain ")); + + g_object_get(G_OBJECT(record), + "maxgain",&max,NULL); + + maxgain.AppendNum(max); + + iGstView->DrawText(maxgain,KRgbBlack); + return 0; + + } + int gst_gain_up() + { + + if(!record) + { + iGstView->DrawText(_L("Devsound source not available"),KRgbRed); + return -1; + } + int max; + g_object_get(G_OBJECT(record), + "maxgain",&max,NULL); + + iGstView->DrawText(_L("gain up"),KRgbBlack); + g_object_set (G_OBJECT (record), + "gain", max, NULL); + return 0; + } + + int gst_gain_down() + { + if(!record) + { + iGstView->DrawText(_L("Devsound source not available"),KRgbRed); + return -1; + } + int max; + g_object_get(G_OBJECT(record), + "maxgain",&max,NULL); + iGstView->DrawText(_L("gain down"),KRgbBlack); + g_object_set (G_OBJECT (sink), + "gain", max/2, NULL); + return 0; + } + + + + int gst_balance() + { + if(!sink) + { + iGstView->DrawText(_L("Devsound sink not available"),KRgbRed); + return -1; + } + + iGstView->DrawText(_L("balance"),KRgbBlack); + /* g_object_set (G_OBJECT (sink), + "left balance", 5000, + "right balance",5000,NULL); + */ + return 0; + } + + void samplesplayed() + { + if(!sink) + { + iGstView->DrawText(_L("Devsound sink not available"),KRgbRed); + } + int samples; + TBuf<25> samplesplayed(_L("samples played ")); + g_object_get (G_OBJECT (sink), + "samples played", &samples, NULL); + + samplesplayed.AppendNum(samples); + iGstView->DrawText(samplesplayed,KRgbBlack); + } + + void samplesrecorded() + { + if(!record) + { + iGstView->DrawText(_L("Devsound src not available"),KRgbRed); + } + int samples; + TBuf<25> samplesrecorded(_L("samples recorded ")); + g_object_get (G_OBJECT (record), + "samples recorded", &samples, NULL); + + samplesrecorded.AppendNum(samples); + iGstView->DrawText(samplesrecorded,KRgbBlack); + } + + static gboolean print_field (GQuark field, const GValue *value, gpointer pfx) + { + gchar *str = gst_value_serialize (value); + + const gchar* c; + + RDebug::Printf("%s %15s: %s\n", (gchar *) pfx, c = g_quark_to_string (field), str); + + if(negcaps) + { + TPtrC8 property((const TText8*)c); + TPtrC8 val((const TText8*)str); + TBuf<10> appdval; + appdval.Copy(val); + + TBuf<25> name; + name.Copy(property); + name.Append(':'); + name.Append(appdval); + + iGstView->DrawText(name,KRgbBlack); + } + g_free (str); + return TRUE; + } + + static void print_caps (const GstCaps *caps, const gchar *pfx) + { + guint i; + + g_return_if_fail (caps != NULL); + + if (gst_caps_is_any (caps)) { + RDebug::Printf("%sANY\n", pfx); + return; + } + if (gst_caps_is_empty (caps)) { + RDebug::Printf("%sEMPTY\n", pfx); + return; + } + const gchar *c; + for (i = 0; i < gst_caps_get_size (caps); i++) { + GstStructure *structure = gst_caps_get_structure (caps, i); + + RDebug::Printf("%s%s\n", pfx,c = gst_structure_get_name (structure)); + + TPtrC8 fmt((const TText8*)c); + + TBuf<25> name; + name.Copy(fmt); + + iGstView->DrawText(name,KRgbBlack); + + gst_structure_foreach (structure, print_field, (gpointer) pfx); + } + } + + void getsinkpadcaps() + { + RDebug::Print(_L("Devsound Pad Caps")); + if(!sink) + { + iGstView->DrawText(_L("Devsound sink not available"),KRgbRed); + return; + } + negcaps = FALSE; + dssinkpad = gst_element_get_pad (sink, "sink"); + dssinkcap = gst_pad_get_caps (dssinkpad); + + print_caps (dssinkcap, " "); + } + + void negotiatedsinkcaps() + { + RDebug::Print(_L("Negotiated caps")); + if(!sink) + { + iGstView->DrawText(_L("Devsound sink not available"),KRgbRed); + return; + } + negcaps = TRUE; + dssinkpad = gst_element_get_pad (sink, "sink"); + dssinkcap = gst_pad_get_negotiated_caps (dssinkpad); + + print_caps (dssinkcap, " "); + } + + void getsrcpadcaps() + { + RDebug::Print(_L("Devsound Source Pad Caps")); + if(!record) + { + iGstView->DrawText(_L("Devsound src not available"),KRgbRed); + return; + } + negcaps = FALSE; + dssrcpad = gst_element_get_pad (record, "src"); + dssrccap = gst_pad_get_caps (dssrcpad); + + print_caps (dssrccap, " "); + } + + void negotiatedsrccaps() + { + RDebug::Print(_L("Negotiated src caps")); + if(!record) + { + iGstView->DrawText(_L("Devsound src not available"),KRgbRed); + return; + } + negcaps = TRUE; + dssrcpad = gst_element_get_pad (record, "src"); + dssrccap = gst_pad_get_negotiated_caps (dssrcpad); + + print_caps (dssrccap, " "); + + }