summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2008-12-14 21:25:50 +0100
committerBenjamin Otte <otte@gnome.org>2008-12-16 21:38:18 +0100
commit41dd7becc52a391b55cabd020cba9340c2335279 (patch)
tree42f33150fffdcdbbd6ca8112b2423567c3bdb854
parenta9bbc0a515517498a7defcfb78de2db3667cd635 (diff)
implement swfdec_net_stream_clear()
-rw-r--r--swfdec/swfdec_audio.c25
-rw-r--r--swfdec/swfdec_audio_internal.h2
-rw-r--r--swfdec/swfdec_audio_stream.c19
-rw-r--r--swfdec/swfdec_net_stream.c10
-rw-r--r--swfdec/swfdec_net_stream_audio.c22
-rw-r--r--swfdec/swfdec_net_stream_video.c19
-rw-r--r--swfdec/swfdec_net_stream_video.h1
7 files changed, 96 insertions, 2 deletions
diff --git a/swfdec/swfdec_audio.c b/swfdec/swfdec_audio.c
index 0722feba..c2f5ebd8 100644
--- a/swfdec/swfdec_audio.c
+++ b/swfdec/swfdec_audio.c
@@ -78,6 +78,12 @@ swfdec_audio_dispose (GObject *object)
}
static void
+swfdec_audio_do_clear (SwfdecAudio *audio)
+{
+ g_signal_emit (audio, signals[CHANGED], 0);
+}
+
+static void
swfdec_audio_class_init (SwfdecAudioClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -106,6 +112,8 @@ swfdec_audio_class_init (SwfdecAudioClass *klass)
G_TYPE_NONE, 0);
object_class->dispose = swfdec_audio_dispose;
+
+ klass->clear = swfdec_audio_do_clear;
}
static void
@@ -404,3 +412,20 @@ swfdec_audio_format_get_bytes_per_sample (SwfdecAudioFormat format)
return bps [format & 0x3];
}
+/**
+ * swfdec_audio_clear:
+ * @audio: the audio to clear
+ *
+ * Clears all caches of the given @audio output to prepare it for using with
+ * a different audio stream. This is useful i.e. after a seek.
+ **/
+void
+swfdec_audio_clear (SwfdecAudio *audio)
+{
+ SwfdecAudioClass *klass;
+
+ g_return_if_fail (SWFDEC_IS_AUDIO (audio));
+
+ klass = SWFDEC_AUDIO_GET_CLASS (audio);
+ klass->clear (audio);
+}
diff --git a/swfdec/swfdec_audio_internal.h b/swfdec/swfdec_audio_internal.h
index d225d719..21ac48f6 100644
--- a/swfdec/swfdec_audio_internal.h
+++ b/swfdec/swfdec_audio_internal.h
@@ -48,6 +48,7 @@ struct _SwfdecAudio {
struct _SwfdecAudioClass {
GObjectClass object_class;
+ void (* clear) (SwfdecAudio * audio);
gsize (* iterate) (SwfdecAudio * audio,
gsize n_samples);
gsize (* render) (SwfdecAudio * audio,
@@ -59,6 +60,7 @@ struct _SwfdecAudioClass {
void swfdec_audio_add (SwfdecAudio * audio,
SwfdecPlayer * player);
void swfdec_audio_remove (SwfdecAudio * audio);
+void swfdec_audio_clear (SwfdecAudio * audio);
void swfdec_audio_set_actor (SwfdecAudio * audio,
SwfdecActor * actor);
void swfdec_audio_set_matrix (SwfdecAudio * audio,
diff --git a/swfdec/swfdec_audio_stream.c b/swfdec/swfdec_audio_stream.c
index 5eb0bfc2..4b2d5fa3 100644
--- a/swfdec/swfdec_audio_stream.c
+++ b/swfdec/swfdec_audio_stream.c
@@ -33,6 +33,24 @@
G_DEFINE_TYPE (SwfdecAudioStream, swfdec_audio_stream, SWFDEC_TYPE_AUDIO)
static void
+swfdec_audio_stream_clear (SwfdecAudio *audio)
+{
+ SwfdecAudioStream *stream = SWFDEC_AUDIO_STREAM (audio);
+
+ if (stream->decoder) {
+ /* FIXME: don't discard the decoder for smoother sounding seeks? */
+ g_object_unref (stream->decoder);
+ stream->decoder = NULL;
+ }
+ g_queue_foreach (stream->queue, (GFunc) swfdec_buffer_unref, NULL);
+ g_queue_clear (stream->queue);
+ stream->done = FALSE;
+ stream->buffering = FALSE;
+
+ SWFDEC_AUDIO_CLASS (swfdec_audio_stream_parent_class)->clear (audio);
+}
+
+static void
swfdec_audio_stream_dispose (GObject *object)
{
SwfdecAudioStream *stream = SWFDEC_AUDIO_STREAM (object);
@@ -178,6 +196,7 @@ swfdec_audio_stream_class_init (SwfdecAudioStreamClass *klass)
object_class->dispose = swfdec_audio_stream_dispose;
+ audio_class->clear = swfdec_audio_stream_clear;
audio_class->iterate = swfdec_audio_stream_iterate;
audio_class->render = swfdec_audio_stream_render;
}
diff --git a/swfdec/swfdec_net_stream.c b/swfdec/swfdec_net_stream.c
index 4f7599cb..ab641355 100644
--- a/swfdec/swfdec_net_stream.c
+++ b/swfdec/swfdec_net_stream.c
@@ -149,9 +149,12 @@ swfdec_net_stream_rtmp_stream_flush (SwfdecRtmpStream *rtmp_stream)
}
static void
-swfdec_net_stream_rtmp_stream_clear (SwfdecRtmpStream *stream)
+swfdec_net_stream_rtmp_stream_clear (SwfdecRtmpStream *rtmp_stream)
{
- SWFDEC_FIXME ("implement");
+ SwfdecNetStream *stream = SWFDEC_NET_STREAM (rtmp_stream);
+
+ swfdec_net_stream_video_clear (stream->video);
+ swfdec_audio_clear (SWFDEC_AUDIO (stream->audio));
}
static void
@@ -187,8 +190,11 @@ swfdec_net_stream_video_buffer_status (SwfdecNetStreamVideo *video, GParamSpec *
{
if (video->playing) {
swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Full);
+ swfdec_audio_add (SWFDEC_AUDIO (stream->audio),
+ SWFDEC_PLAYER (swfdec_gc_object_get_context (stream)));
} else {
swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Empty);
+ swfdec_audio_remove (SWFDEC_AUDIO (stream->audio));
}
}
diff --git a/swfdec/swfdec_net_stream_audio.c b/swfdec/swfdec_net_stream_audio.c
index a28f4ead..da1d8a1d 100644
--- a/swfdec/swfdec_net_stream_audio.c
+++ b/swfdec/swfdec_net_stream_audio.c
@@ -47,6 +47,19 @@ swfdec_net_stream_audio_dispose (GObject *object)
G_OBJECT_CLASS (swfdec_net_stream_audio_parent_class)->dispose (object);
}
+static void
+swfdec_net_stream_audio_clear (SwfdecAudio *audio)
+{
+ SwfdecNetStreamAudio *stream = SWFDEC_NET_STREAM_AUDIO (audio);
+
+ /* pop eventual NULL buffer indicating end of data */
+ if (g_queue_peek_tail (stream->queue) == NULL)
+ g_queue_pop_tail (stream->queue);
+ g_queue_foreach (stream->queue, (GFunc) swfdec_buffer_unref, NULL);
+
+ SWFDEC_AUDIO_CLASS (swfdec_net_stream_audio_parent_class)->clear (audio);
+}
+
static SwfdecBuffer *
swfdec_net_stream_audio_pull (SwfdecAudioStream *audio)
{
@@ -78,10 +91,13 @@ static void
swfdec_net_stream_audio_class_init (SwfdecNetStreamAudioClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ SwfdecAudioClass *audio_class = SWFDEC_AUDIO_CLASS (klass);
SwfdecAudioStreamClass *stream_class = SWFDEC_AUDIO_STREAM_CLASS (klass);
object_class->dispose = swfdec_net_stream_audio_dispose;
+ audio_class->clear = swfdec_net_stream_audio_clear;
+
stream_class->pull = swfdec_net_stream_audio_pull;
}
@@ -113,5 +129,11 @@ swfdec_net_stream_audio_push (SwfdecNetStreamAudio *audio, SwfdecBuffer *buffer)
swfdec_buffer_unref (buffer);
return;
};
+ if (!g_queue_is_empty (audio->queue) && g_queue_peek_tail (audio->queue) == NULL) {
+ SWFDEC_ERROR ("pushing data onto an audio stream that is done. Ignoring.");
+ if (buffer)
+ swfdec_buffer_unref (buffer);
+ return;
+ }
g_queue_push_tail (audio->queue, buffer);
}
diff --git a/swfdec/swfdec_net_stream_video.c b/swfdec/swfdec_net_stream_video.c
index ccfddde7..faf4a6fc 100644
--- a/swfdec/swfdec_net_stream_video.c
+++ b/swfdec/swfdec_net_stream_video.c
@@ -116,6 +116,7 @@ swfdec_net_stream_video_dispose (GObject *object)
if (video->timeout.callback) {
swfdec_player_remove_timeout (SWFDEC_PLAYER (swfdec_gc_object_get_context (video)),
&video->timeout);
+ video->timeout.callback = NULL;
}
G_OBJECT_CLASS (swfdec_net_stream_video_parent_class)->dispose (object);
@@ -153,6 +154,24 @@ swfdec_net_stream_video_new (SwfdecPlayer *player)
return ret;
}
+void
+swfdec_net_stream_video_clear (SwfdecNetStreamVideo *video)
+{
+ g_return_if_fail (SWFDEC_IS_NET_STREAM_VIDEO (video));
+
+ video->time = 0;
+ g_queue_foreach (video->next, (GFunc) swfdec_rtmp_packet_free, NULL);
+ g_queue_clear (video->next);
+ video->next_length = 0;
+ video->playing = FALSE;
+ if (video->timeout.callback) {
+ swfdec_player_remove_timeout (SWFDEC_PLAYER (swfdec_gc_object_get_context (video)),
+ &video->timeout);
+ video->timeout.callback = NULL;
+ }
+ /* FIXME: clear decoder, too? currently it's needed for getting the current image */
+}
+
static void
swfdec_net_stream_video_decode_one (SwfdecNetStreamVideo *video, SwfdecBuffer *buffer)
{
diff --git a/swfdec/swfdec_net_stream_video.h b/swfdec/swfdec_net_stream_video.h
index 2aa51456..1e7cdfd1 100644
--- a/swfdec/swfdec_net_stream_video.h
+++ b/swfdec/swfdec_net_stream_video.h
@@ -58,6 +58,7 @@ GType swfdec_net_stream_video_get_type (void);
SwfdecNetStreamVideo * swfdec_net_stream_video_new (SwfdecPlayer * player);
+void swfdec_net_stream_video_clear (SwfdecNetStreamVideo * video);
void swfdec_net_stream_video_push (SwfdecNetStreamVideo * video,
const SwfdecRtmpHeader *header,
SwfdecBuffer * buffer);