diff options
author | Benjamin Otte <otte@gnome.org> | 2008-12-10 12:44:29 +0100 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2008-12-16 21:38:15 +0100 |
commit | 4d1e0e4db4c6db9db0710f2a2cee7e3bff95c7ca (patch) | |
tree | 0f156fe1f3cfbc572b5011aea4c03e9073fa7407 | |
parent | 673db3e51dfa13fde8f11f7305c6c8d9d7517dee (diff) |
handle Buffer.Full and Buffer.Empty messages
-rw-r--r-- | swfdec/swfdec_net_stream.c | 12 | ||||
-rw-r--r-- | swfdec/swfdec_net_stream_video.c | 45 | ||||
-rw-r--r-- | swfdec/swfdec_net_stream_video.h | 3 |
3 files changed, 53 insertions, 7 deletions
diff --git a/swfdec/swfdec_net_stream.c b/swfdec/swfdec_net_stream.c index 5d79cdaf..9fd98d02 100644 --- a/swfdec/swfdec_net_stream.c +++ b/swfdec/swfdec_net_stream.c @@ -177,6 +177,14 @@ swfdec_net_stream_mark (SwfdecGcObject *object) } static void +swfdec_net_stream_video_buffer_status (SwfdecNetStreamVideo *video, GParamSpec *pspec, + SwfdecNetStream* stream) +{ + swfdec_net_stream_onstatus (stream, video->playing ? + SWFDEC_AS_STR_NetStream_Buffer_Full : SWFDEC_AS_STR_NetStream_Buffer_Empty); +} + +static void swfdec_net_stream_dispose (GObject *object) { SwfdecNetStream *stream = SWFDEC_NET_STREAM (object); @@ -185,6 +193,8 @@ swfdec_net_stream_dispose (GObject *object) swfdec_rtmp_rpc_free (stream->rpc); stream->rpc = NULL; } + g_signal_handlers_disconnect_by_func (stream->video, + swfdec_net_stream_video_buffer_status, stream); G_OBJECT_CLASS (swfdec_net_stream_parent_class)->dispose (object); } @@ -288,6 +298,8 @@ swfdec_net_stream_construct (SwfdecAsContext *cx, SwfdecAsObject *object, stream->conn = conn; stream->rpc = swfdec_rtmp_rpc_new (conn, SWFDEC_AS_RELAY (stream)); stream->video = swfdec_net_stream_video_new (SWFDEC_PLAYER (cx)); + g_signal_connect (stream->video, "notify::playing", + G_CALLBACK (swfdec_net_stream_video_buffer_status), stream); swfdec_as_context_get_time (cx, &stream->rpc->last_send); swfdec_as_object_set_relay (o, SWFDEC_AS_RELAY (stream)); } diff --git a/swfdec/swfdec_net_stream_video.c b/swfdec/swfdec_net_stream_video.c index 8f725609..13fd14fb 100644 --- a/swfdec/swfdec_net_stream_video.c +++ b/swfdec/swfdec_net_stream_video.c @@ -75,10 +75,31 @@ swfdec_net_stream_video_video_provider_init (SwfdecVideoProviderInterface *iface /*** SWFDEC_NET_STREAM_VIDEO ***/ +enum { + PROP_0, + PROP_PLAYING +}; + G_DEFINE_TYPE_WITH_CODE (SwfdecNetStreamVideo, swfdec_net_stream_video, SWFDEC_TYPE_GC_OBJECT, G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_VIDEO_PROVIDER, swfdec_net_stream_video_video_provider_init)) static void +swfdec_net_stream_video_get_property (GObject *object, guint param_id, GValue *value, + GParamSpec * pspec) +{ + SwfdecNetStreamVideo *video = SWFDEC_NET_STREAM_VIDEO (object); + + switch (param_id) { + case PROP_PLAYING: + g_value_set_boolean (value, video->playing); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void swfdec_net_stream_video_dispose (GObject *object) { SwfdecNetStreamVideo *video = SWFDEC_NET_STREAM_VIDEO (object); @@ -106,11 +127,17 @@ swfdec_net_stream_video_class_init (SwfdecNetStreamVideoClass * g_class) GObjectClass *object_class = G_OBJECT_CLASS (g_class); object_class->dispose = swfdec_net_stream_video_dispose; + object_class->get_property = swfdec_net_stream_video_get_property; + + g_object_class_install_property (object_class, PROP_PLAYING, + g_param_spec_boolean ("playing", "playing", "TRUE when the video is playing", + FALSE, G_PARAM_READABLE)); } static void swfdec_net_stream_video_init (SwfdecNetStreamVideo *video) { + video->buffer_time = 100; video->next = g_queue_new (); } @@ -221,8 +248,11 @@ swfdec_net_stream_video_decode (SwfdecNetStreamVideo *video) for (;;) { packet = g_queue_pop_head (video->next); - if (packet == NULL) + if (packet == NULL) { + video->playing = FALSE; + g_object_notify (G_OBJECT (video), "playing"); return; + } video->timeout.timestamp += SWFDEC_TICKS_PER_SECOND * packet->header.timestamp / 1000; if (player->priv->time < video->timeout.timestamp) { g_queue_push_head (video->next, packet); @@ -231,6 +261,7 @@ swfdec_net_stream_video_decode (SwfdecNetStreamVideo *video) return; } swfdec_net_stream_video_decode_one (video, packet->buffer); + video->next_length -= packet->header.timestamp; swfdec_rtmp_packet_free (packet); } } @@ -238,7 +269,9 @@ swfdec_net_stream_video_decode (SwfdecNetStreamVideo *video) static void swfdec_net_stream_video_start (SwfdecNetStreamVideo *video) { + video->playing = TRUE; video->timeout.timestamp = SWFDEC_PLAYER (swfdec_gc_object_get_context (video))->priv->time; + g_object_notify (G_OBJECT (video), "playing"); } void @@ -252,13 +285,11 @@ swfdec_net_stream_video_push (SwfdecNetStreamVideo *video, packet = swfdec_rtmp_packet_new (header->channel, header->stream, header->type, header->timestamp, buffer); - if (g_queue_is_empty (video->next)) { - g_queue_push_tail (video->next, packet); - if (video->decoder == NULL) - swfdec_net_stream_video_start (video); + g_queue_push_tail (video->next, packet); + video->next_length += header->timestamp; + if (!video->playing && video->next_length >= video->buffer_time) { + swfdec_net_stream_video_start (video); swfdec_net_stream_video_decode (video); - } else { - g_queue_push_tail (video->next, packet); } } diff --git a/swfdec/swfdec_net_stream_video.h b/swfdec/swfdec_net_stream_video.h index ddd1ece9..163d048b 100644 --- a/swfdec/swfdec_net_stream_video.h +++ b/swfdec/swfdec_net_stream_video.h @@ -41,7 +41,10 @@ typedef struct _SwfdecNetStreamVideoClass SwfdecNetStreamVideoClass; struct _SwfdecNetStreamVideo { SwfdecGcObject object; + gulong buffer_time; /* time to buffer before starting to play */ GQueue * next; /* queue of pending packets */ + gulong next_length; /* number of milliseconds in the next queue */ + gboolean playing; /* TRUE if we're currently playing */ SwfdecTimeout timeout; /* time the next image should be decoded */ SwfdecVideoDecoder * decoder; /* the current decoder */ }; |