properly exit when hitting a stack overflow (fixes #13491)
[swfdec.git] / player / swfdec_slow_loader.c
blob4261800718a006719fa2895f6c499e82bee5d64c
1 /* Swfdec
2 * Copyright (C) 2006 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "swfdec_slow_loader.h"
25 #include <libswfdec-gtk/swfdec-gtk.h>
27 /*** SwfdecSlowLoader ***/
29 G_DEFINE_TYPE (SwfdecSlowLoader, swfdec_slow_loader, SWFDEC_TYPE_LOADER)
31 static void
32 swfdec_slow_loader_notify_cb (SwfdecLoader *child, GParamSpec *pspec, SwfdecLoader *loader)
34 if (g_str_equal (pspec->name, "size")) {
35 swfdec_loader_set_size (loader, swfdec_loader_get_size (child));
39 static void
40 swfdec_slow_loader_dispose (GObject *object)
42 SwfdecSlowLoader *slow = SWFDEC_SLOW_LOADER (object);
44 g_signal_handlers_disconnect_by_func (slow->loader, swfdec_slow_loader_notify_cb, slow);
45 g_object_unref (slow->loader);
46 if (slow->timeout_id) {
47 g_source_remove (slow->timeout_id);
48 slow->timeout_id = 0;
51 G_OBJECT_CLASS (swfdec_slow_loader_parent_class)->dispose (object);
54 static gboolean
55 swfdec_slow_loader_tick (gpointer data)
57 SwfdecSlowLoader *slow = data;
58 SwfdecBuffer *buffer;
59 guint total, amount;
61 amount = swfdec_buffer_queue_get_depth (slow->loader->queue);
62 if (amount > 0) {
63 total = swfdec_buffer_queue_get_offset (slow->loader->queue);
64 total += amount;
65 total *= slow->tick_time;
66 total += slow->duration - 1; /* rounding */
67 amount = MIN (amount, total / slow->duration);
68 buffer = swfdec_buffer_queue_pull (slow->loader->queue, amount);
69 #if 0
70 g_print ("pushing %u bytes (%u/%u total)\n",
71 amount, swfdec_buffer_queue_get_offset (slow->loader->queue),
72 swfdec_buffer_queue_get_offset (slow->loader->queue) +
73 swfdec_buffer_queue_get_depth (slow->loader->queue));
74 #endif
75 swfdec_loader_push (SWFDEC_LOADER (slow), buffer);
76 if (swfdec_buffer_queue_get_depth (slow->loader->queue) > 0)
77 return TRUE;
80 if (slow->loader->error) {
81 swfdec_loader_error (SWFDEC_LOADER (slow), slow->loader->error);
82 slow->timeout_id = 0;
83 return FALSE;
84 } else {
85 gboolean eof;
86 g_object_get (slow->loader, "eof", &eof, NULL);
87 if (eof) {
88 swfdec_loader_eof (SWFDEC_LOADER (slow));
89 slow->timeout_id = 0;
90 return FALSE;
91 } else {
92 return TRUE;
97 static void
98 swfdec_slow_loader_initialize (SwfdecSlowLoader *slow, SwfdecLoader *loader, guint duration)
100 glong size;
102 slow->tick_time = 100;
103 slow->duration = duration * 1000;
104 slow->loader = loader;
105 g_signal_connect (loader, "notify", G_CALLBACK (swfdec_slow_loader_notify_cb), slow);
106 size = swfdec_loader_get_size (loader);
107 if (size >= 0)
108 swfdec_loader_set_size (SWFDEC_LOADER (slow), size);
109 slow->timeout_id = g_timeout_add (slow->tick_time, swfdec_slow_loader_tick, slow);
110 swfdec_loader_open (SWFDEC_LOADER (slow), 0);
113 static void
114 swfdec_slow_loader_load (SwfdecLoader *loader, SwfdecLoader *parent,
115 SwfdecLoaderRequest request, const char *data, gsize data_len)
117 SwfdecSlowLoader *slow = SWFDEC_SLOW_LOADER (loader);
118 SwfdecLoader *new;
120 /* FIXME: include request and data */
121 new = swfdec_gtk_loader_new (swfdec_url_get_url (swfdec_loader_get_url (loader)));
122 swfdec_slow_loader_initialize (slow, new, SWFDEC_SLOW_LOADER (parent)->duration / 1000);
125 static void
126 swfdec_slow_loader_class_init (SwfdecSlowLoaderClass *klass)
128 GObjectClass *object_class = G_OBJECT_CLASS (klass);
129 SwfdecLoaderClass *loader_class = SWFDEC_LOADER_CLASS (klass);
131 object_class->dispose = swfdec_slow_loader_dispose;
133 loader_class->load = swfdec_slow_loader_load;
136 static void
137 swfdec_slow_loader_init (SwfdecSlowLoader *slow_loader)
141 SwfdecLoader *
142 swfdec_slow_loader_new (SwfdecLoader *loader, guint duration)
144 SwfdecSlowLoader *ret;
146 g_return_val_if_fail (SWFDEC_IS_LOADER (loader), NULL);
147 g_return_val_if_fail (duration > 0, NULL);
149 ret = g_object_new (SWFDEC_TYPE_SLOW_LOADER, "url", loader->url, NULL);
150 swfdec_slow_loader_initialize (ret, loader, duration);
151 return SWFDEC_LOADER (ret);