summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gst/modplug/gstmodplug.cc191
-rw-r--r--gst/modplug/gstmodplug.h2
2 files changed, 138 insertions, 55 deletions
diff --git a/gst/modplug/gstmodplug.cc b/gst/modplug/gstmodplug.cc
index cc7bf5be..0b1cbd29 100644
--- a/gst/modplug/gstmodplug.cc
+++ b/gst/modplug/gstmodplug.cc
@@ -30,7 +30,7 @@
#include "gstmodplug.h"
-#include <gst/audio/audio.h>
+#include <gst/gst.h>
#include <stdlib.h>
GstElementDetails modplug_details = {
@@ -105,9 +105,12 @@ static void gst_modplug_class_init (GstModPlugClass *klass);
static void gst_modplug_init (GstModPlug *filter);
static void gst_modplug_set_property (GObject *object, guint id, const GValue *value, GParamSpec *pspec );
static void gst_modplug_get_property (GObject *object, guint id, GValue *value, GParamSpec *pspec );
-static void gst_modplug_loop (GstElement *element);
+static void gst_modplug_loop (GstElement *element);
static void gst_modplug_setup (GstModPlug *modplug);
-static GstElementStateReturn gst_modplug_change_state (GstElement *element);
+static gboolean gst_modplug_src_event (GstPad *pad, GstEvent *event);
+static gboolean gst_modplug_src_query (GstPad *pad, GstPadQueryType type, GstFormat *format, gint64 *value);
+static GstElementStateReturn
+ gst_modplug_change_state (GstElement *element);
static GstElementClass *parent_class = NULL;
@@ -237,6 +240,8 @@ gst_modplug_init (GstModPlug *modplug)
gst_element_add_pad(GST_ELEMENT(modplug),modplug->sinkpad);
gst_element_add_pad(GST_ELEMENT(modplug),modplug->srcpad);
+ gst_pad_set_event_function (modplug->srcpad, (GstPadEventFunction)GST_DEBUG_FUNCPTR(gst_modplug_src_event));
+ gst_pad_set_query_function (modplug->srcpad, gst_modplug_src_query);
gst_element_set_loop_function (GST_ELEMENT (modplug), gst_modplug_loop);
modplug->Buffer = NULL;
@@ -282,7 +287,83 @@ gst_modplug_setup (GstModPlug *modplug)
modplug->mSoundFile->SetReverbParameters( modplug->reverb_depth, modplug->reverb_delay );
}
-
+
+
+static gboolean
+gst_modplug_src_query (GstPad *pad, GstPadQueryType type,
+ GstFormat *format, gint64 *value)
+{
+ gboolean res = TRUE;
+ GstModPlug *modplug;
+ float tmp;
+
+ modplug = GST_MODPLUG (gst_pad_get_parent (pad));
+
+ switch (type) {
+ case GST_PAD_QUERY_TOTAL:
+ switch (*format) {
+ case GST_FORMAT_DEFAULT:
+ *format = GST_FORMAT_TIME;
+ case GST_FORMAT_TIME:
+ *value=(gint64)modplug->mSoundFile->GetSongTime() * 1000000000LL;
+ break;
+ default:
+ res = FALSE;
+ break;
+ }
+ break;
+ case GST_PAD_QUERY_POSITION:
+ switch (*format) {
+ case GST_FORMAT_DEFAULT:
+ *format = GST_FORMAT_TIME;
+ default:
+ tmp = ((float)( modplug->mSoundFile->GetSongTime() * modplug->mSoundFile->GetCurrentPos() ) / (float)modplug->mSoundFile->GetMaxPosition() );
+ *value=(gint64)(tmp * 1000000000LL);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return res;
+}
+
+
+
+
+static gboolean
+gst_modplug_src_event (GstPad *pad, GstEvent *event)
+{
+ gboolean res = TRUE;
+ GstModPlug *modplug;
+
+ modplug = GST_MODPLUG (gst_pad_get_parent (pad));
+
+ switch (GST_EVENT_TYPE (event)) {
+ /* the all-formats seek logic */
+ case GST_EVENT_SEEK:
+ {
+ gboolean flush;
+ GstFormat format;
+
+ format = GST_FORMAT_TIME;
+
+ /* shave off the flush flag, we'll need it later */
+ flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH;
+
+ /* assume the worst */
+ res = FALSE;
+
+ modplug->seek_at = GST_EVENT_SEEK_OFFSET (event);
+ }
+ default:
+ res = FALSE;
+ break;
+ }
+
+ return res;
+}
+
static void
@@ -291,7 +372,8 @@ gst_modplug_loop (GstElement *element)
GstModPlug *modplug;
GstBuffer *buffer_in, *buffer_out;
gint mode16bits;
- guint64 total_samples, sync_point;
+ guint64 total_samples, sync_point;
+ float temp;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_MODPLUG (element));
@@ -322,11 +404,6 @@ gst_modplug_loop (GstElement *element)
else
mode16bits = 8;
-/* CSoundFile::SetWaveConfig ( modplug->frequency, mode16bits, modplug->channel );
- CSoundFile::SetWaveConfigEx ( modplug->surround, !modplug->oversamp, modplug->reverb, true, modplug->megabass, modplug->noise_reduction, false );
- CSoundFile::SetResamplingMode ( SRCMODE_SPLINE );
- CSoundFile::SetSurroundParameters( 30, 100 );*/
-
gst_modplug_setup( modplug );
modplug->mSoundFile = new CSoundFile;
@@ -357,6 +434,30 @@ gst_modplug_loop (GstElement *element)
sync_point = 0;
do {
+ if ( modplug->seek_at != 0 )
+ {
+ GstEvent *discont;
+ GstClockTime time;
+ int seek_to_pos;
+ gint64 total;
+
+ total = modplug->mSoundFile->GetSongTime() * 1000000000LL;
+
+ temp = (float) total / modplug->seek_at;
+ seek_to_pos = (int)( modplug->mSoundFile->GetMaxPosition() / temp );
+
+ modplug->mSoundFile->SetCurrentPos( seek_to_pos );
+ modplug->seek_at = 0;
+
+ /* get stream stats */
+ time = (gint64) (total * modplug->mSoundFile->GetCurrentPos() ) / modplug->mSoundFile->GetMaxPosition();
+ discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time, NULL );
+
+ gst_pad_push (modplug->srcpad, GST_BUFFER (discont));
+ }
+
+
+
if( modplug->mSoundFile->Read ( modplug->audiobuffer, modplug->length ) != 0 )
{
buffer_out = gst_buffer_new();
@@ -364,14 +465,14 @@ gst_modplug_loop (GstElement *element)
GST_BUFFER_SIZE( buffer_out ) = modplug->length;
total_samples+=1152;
- GST_BUFFER_TIMESTAMP( buffer_out ) = total_samples * GST_SECOND / modplug->frequency;
+ GST_BUFFER_TIMESTAMP( buffer_out ) = total_samples * GST_SECOND / modplug->frequency;
- gst_pad_push( srcpad, buffer_out );
- gst_element_yield (element);
+ gst_pad_push( srcpad, buffer_out );
+ gst_element_yield (element);
}
else
{
- free( modplug->audiobuffer );
+ free( modplug->audiobuffer );
gst_element_set_eos (GST_ELEMENT (modplug));
gst_pad_push (modplug->srcpad, GST_BUFFER (gst_event_new (GST_EVENT_EOS)));
}
@@ -383,54 +484,34 @@ gst_modplug_loop (GstElement *element)
static GstElementStateReturn
gst_modplug_change_state (GstElement *element)
{
-GstModPlug *modplug;
-
- g_return_val_if_fail (GST_IS_MODPLUG (element), GST_STATE_FAILURE);
-
- modplug = GST_MODPLUG (element);
+ GstModPlug *modplug;
- GST_DEBUG (0,"state pending %d", GST_STATE_PENDING (element));
+ modplug = GST_MODPLUG( element );
- /* if going down into NULL state, close the file if it's open */
-/* if (GST_STATE_PENDING (element) == GST_STATE_READY)
- {
- gst_modplug_setup(modplug);
-
- if ( Player_Active() )
- {
- Player_TogglePause();
- Player_SetPosition( 0 );
- }
-
- }
-
- if (GST_STATE_PENDING (element) == GST_STATE_PLAYING)
- {
- if ( Player_Active() && Player_Paused() )
- Player_TogglePause();
- else
- if ( ! Player_Active() )
- Player_Start(module);
-
+ switch (GST_STATE_TRANSITION (element)) {
+ case GST_STATE_NULL_TO_READY:
+// modplug->mSoundFile = new CSoundFile;
+ break;
+ case GST_STATE_READY_TO_PAUSED:
+ break;
+ case GST_STATE_PAUSED_TO_PLAYING:
+ break;
+ case GST_STATE_PLAYING_TO_PAUSED:
+ break;
+ case GST_STATE_PAUSED_TO_READY:
+// modplug->mSoundFile->SetCurrentPos( 0 );
+ break;
+ case GST_STATE_READY_TO_NULL:
+ free( modplug->audiobuffer );
+ modplug->mSoundFile->Destroy();
+ break;
}
-
- if (GST_STATE_PENDING (element) == GST_STATE_PAUSED)
- if ( Player_Active() && ! Player_Paused() )
- Player_TogglePause();
-
- if (GST_STATE_PENDING (element) == GST_STATE_NULL)
- ModPlug_Exit();
- */
-
- /* if we haven't failed already, give the parent class a chance to ;-) */
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+ parent_class->change_state (element);
+
return GST_STATE_SUCCESS;
}
-
-
static void
gst_modplug_set_property (GObject *object, guint id, const GValue *value, GParamSpec *pspec )
{
diff --git a/gst/modplug/gstmodplug.h b/gst/modplug/gstmodplug.h
index 56badeee..87efb7ff 100644
--- a/gst/modplug/gstmodplug.h
+++ b/gst/modplug/gstmodplug.h
@@ -63,6 +63,8 @@ struct _GstModPlug {
guchar *audiobuffer;
gint32 length;
+ gboolean restart;
+ gint64 seek_at;
CSoundFile *mSoundFile;
};