diff options
author | Benjamin Otte <otte@gnome.org> | 2008-12-14 21:25:50 +0100 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2008-12-16 21:38:18 +0100 |
commit | 41dd7becc52a391b55cabd020cba9340c2335279 (patch) | |
tree | 42f33150fffdcdbbd6ca8112b2423567c3bdb854 | |
parent | a9bbc0a515517498a7defcfb78de2db3667cd635 (diff) |
implement swfdec_net_stream_clear()
-rw-r--r-- | swfdec/swfdec_audio.c | 25 | ||||
-rw-r--r-- | swfdec/swfdec_audio_internal.h | 2 | ||||
-rw-r--r-- | swfdec/swfdec_audio_stream.c | 19 | ||||
-rw-r--r-- | swfdec/swfdec_net_stream.c | 10 | ||||
-rw-r--r-- | swfdec/swfdec_net_stream_audio.c | 22 | ||||
-rw-r--r-- | swfdec/swfdec_net_stream_video.c | 19 | ||||
-rw-r--r-- | swfdec/swfdec_net_stream_video.h | 1 |
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); |