[Swfdec] 9 commits - doc/swfdec-sections.txt libswfdec/swfdec_as_frame.c libswfdec/swfdec_loader.c libswfdec/swfdec_loader.h libswfdec/swfdec_loader_internal.h libswfdec/swfdec_loadertarget.c libswfdec/swfdec_loadertarget.h libswfdec/swfdec_movie.c libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_swf_instance.c libswfdec/swfdec_url.c libswfdec/swfdec_xml.c player/swfdec_slow_loader.c
Benjamin Otte
company at kemper.freedesktop.org
Wed Aug 1 08:08:58 PDT 2007
doc/swfdec-sections.txt | 5 +
libswfdec/swfdec_as_frame.c | 10 ++
libswfdec/swfdec_loader.c | 173 ++++++++++++++++++++++---------------
libswfdec/swfdec_loader.h | 8 +
libswfdec/swfdec_loader_internal.h | 12 +-
libswfdec/swfdec_loadertarget.c | 52 ++++++++++-
libswfdec/swfdec_loadertarget.h | 17 +++
libswfdec/swfdec_movie.c | 1
libswfdec/swfdec_net_stream.c | 96 ++++++++++++--------
libswfdec/swfdec_player.c | 94 +++++++++++++++++++-
libswfdec/swfdec_player_internal.h | 11 ++
libswfdec/swfdec_swf_instance.c | 19 ++--
libswfdec/swfdec_url.c | 2
libswfdec/swfdec_xml.c | 71 ++++++++-------
player/swfdec_slow_loader.c | 15 ++-
15 files changed, 420 insertions(+), 166 deletions(-)
New commits:
diff-tree e24deaade92d1c0b55dd2fda9c422a9759e2aa18 (from 2253157314bf1e420b56212989d09b6c50d46e9c)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 17:06:53 2007 +0200
document swfdec_as_frame_init_arguments()
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 612ed70..4608b0a 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -62,6 +62,16 @@
* allocated on the stack. All of its members are private.
*/
+/**
+ * swfdec_as_stack_iterator_init_arguments:
+ * @iter: iterator to be initialized
+ * @frame: the frame to initialize from
+ *
+ * Initializes a stack iterator to walk the arguments passed to the given @frame. See
+ * swfdec_as_stack_iterator_init() about suggested iterator usage.
+ *
+ * Returns: The value of the first argument
+ **/
SwfdecAsValue *
swfdec_as_stack_iterator_init_arguments (SwfdecAsStackIterator *iter, SwfdecAsFrame *frame)
{
diff-tree 2253157314bf1e420b56212989d09b6c50d46e9c (from 8c33c1d42b579e7897fd0353e6e549543d289fa7)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 17:02:59 2007 +0200
fix up docs build
diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index ccb76d4..a250b3a 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -19,9 +19,11 @@ SWFDEC_AUDIO_GET_CLASS
<TITLE>SwfdecLoader</TITLE>
SwfdecLoader
swfdec_loader_new_from_file
+swfdec_loader_open
swfdec_loader_push
swfdec_loader_eof
swfdec_loader_error
+swfdec_loader_get_url
swfdec_loader_set_size
swfdec_loader_get_size
swfdec_loader_get_loaded
@@ -52,6 +54,7 @@ swfdec_url_get_url
swfdec_url_new
swfdec_url_new_relative
<SUBSECTION Standard>
+SWFDEC_TYPE_URL
swfdec_url_get_type
</SECTION>
@@ -116,7 +119,9 @@ swfdec_buffer_queue_pull
swfdec_buffer_queue_pull_buffer
swfdec_buffer_queue_peek
<SUBSECTION Standard>
+SWFDEC_TYPE_BUFFER
swfdec_buffer_get_type
+SWFDEC_TYPE_BUFFER_QUEUE
swfdec_buffer_queue_get_type
</SECTION>
diff-tree 8c33c1d42b579e7897fd0353e6e549543d289fa7 (from d0e4e10c1aa96552bcf2aa96af5949650870926b)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 16:54:05 2007 +0200
make it compile (it doesn't work yet)
diff --git a/player/swfdec_slow_loader.c b/player/swfdec_slow_loader.c
index c568316..603627a 100644
--- a/player/swfdec_slow_loader.c
+++ b/player/swfdec_slow_loader.c
@@ -81,12 +81,16 @@ swfdec_slow_loader_tick (gpointer data)
swfdec_loader_error (SWFDEC_LOADER (slow), slow->loader->error);
slow->timeout_id = 0;
return FALSE;
- } else if (slow->loader->eof) {
- swfdec_loader_eof (SWFDEC_LOADER (slow));
- slow->timeout_id = 0;
- return FALSE;
} else {
- return TRUE;
+ gboolean eof;
+ g_object_get (slow->loader, "eof", &eof, NULL);
+ if (eof) {
+ swfdec_loader_eof (SWFDEC_LOADER (slow));
+ slow->timeout_id = 0;
+ return FALSE;
+ } else {
+ return TRUE;
+ }
}
}
@@ -103,6 +107,7 @@ swfdec_slow_loader_initialize (SwfdecSlo
if (size)
swfdec_loader_set_size (SWFDEC_LOADER (slow), size);
slow->timeout_id = g_timeout_add (slow->tick_time, swfdec_slow_loader_tick, slow);
+ swfdec_loader_open (SWFDEC_LOADER (slow), 0);
}
static void
diff-tree d0e4e10c1aa96552bcf2aa96af5949650870926b (from 5b36ea83a867d29e554cd2cfc1170f056c0fa52f)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 16:34:36 2007 +0200
remove hack for loader actions
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index b4df554..ab9d34a 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -633,8 +633,6 @@ swfdec_player_dispose (GObject *object)
while (player->roots)
swfdec_movie_destroy (player->roots->data);
- swfdec_player_remove_all_actions (player, player); /* HACK to allow non-removable actions */
-
/* we do this here so references to GC'd objects get freed */
G_OBJECT_CLASS (swfdec_player_parent_class)->dispose (object);
diff-tree 5b36ea83a867d29e554cd2cfc1170f056c0fa52f (from de8205950a51b5bf5ad7645fb67eb9b9c21a0b4e)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 16:33:57 2007 +0200
step 2 in loading reorg: SwfdecLoaderTarget
SwfdecLoaderTarget now has 3 vfuncs: open, parse, eof and error.
They are queued to be called whenever they were called on the loader.
diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index 285ffc2..cddbe10 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -244,11 +244,27 @@ swfdec_file_loader_init (SwfdecFileLoade
static void
swfdec_loader_perform_open (gpointer loaderp, gpointer unused)
{
- SWFDEC_FIXME ("add vfunc for open to SwfdecLoaderTarget");
+ SwfdecLoader *loader = loaderp;
+
+ swfdec_loader_target_open (loader->target, loader, loader->open_status);
+}
+
+static void
+swfdec_loader_perform_eof (gpointer loaderp, gpointer unused)
+{
+ SwfdecLoader *loader = loaderp;
+
+ swfdec_loader_target_eof (loader->target, loader);
+}
+
+static void
+swfdec_loader_perform_error (gpointer loaderp, gpointer unused)
+{
+ SwfdecLoader *loader = loaderp;
+
+ swfdec_loader_target_error (loader->target, loader);
}
-#define swfdec_loader_perform_error swfdec_loader_perform_push
-#define swfdec_loader_perform_eof swfdec_loader_perform_push
static void
swfdec_loader_perform_push (gpointer loaderp, gpointer unused)
{
diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c
index aa939b7..a6723b1 100644
--- a/libswfdec/swfdec_loadertarget.c
+++ b/libswfdec/swfdec_loadertarget.c
@@ -76,6 +76,21 @@ swfdec_loader_target_get_player (SwfdecL
}
void
+swfdec_loader_target_open (SwfdecLoaderTarget *target, SwfdecLoader *loader, guint status)
+{
+ SwfdecLoaderTargetInterface *iface;
+
+ g_return_if_fail (SWFDEC_IS_LOADER_TARGET (target));
+ g_return_if_fail (SWFDEC_IS_LOADER (loader));
+
+ SWFDEC_LOG ("opening %p (state %u)", loader, loader->state);
+
+ iface = SWFDEC_LOADER_TARGET_GET_INTERFACE (target);
+ if (iface->open)
+ iface->open (target, loader, status);
+}
+
+void
swfdec_loader_target_parse (SwfdecLoaderTarget *target, SwfdecLoader *loader)
{
SwfdecLoaderTargetInterface *iface;
@@ -86,7 +101,37 @@ swfdec_loader_target_parse (SwfdecLoader
SWFDEC_LOG ("parsing %p (state %u)", loader, loader->state);
iface = SWFDEC_LOADER_TARGET_GET_INTERFACE (target);
- g_return_if_fail (iface->parse != NULL);
- iface->parse (target, loader);
+ if (iface->parse)
+ iface->parse (target, loader);
+}
+
+void
+swfdec_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loader)
+{
+ SwfdecLoaderTargetInterface *iface;
+
+ g_return_if_fail (SWFDEC_IS_LOADER_TARGET (target));
+ g_return_if_fail (SWFDEC_IS_LOADER (loader));
+
+ SWFDEC_LOG ("eof on %p (state %u)", loader, loader->state);
+
+ iface = SWFDEC_LOADER_TARGET_GET_INTERFACE (target);
+ if (iface->eof)
+ iface->eof (target, loader);
+}
+
+void
+swfdec_loader_target_error (SwfdecLoaderTarget *target, SwfdecLoader *loader)
+{
+ SwfdecLoaderTargetInterface *iface;
+
+ g_return_if_fail (SWFDEC_IS_LOADER_TARGET (target));
+ g_return_if_fail (SWFDEC_IS_LOADER (loader));
+
+ SWFDEC_LOG ("error on %p (state %u)", loader, loader->state);
+
+ iface = SWFDEC_LOADER_TARGET_GET_INTERFACE (target);
+ if (iface->error)
+ iface->error (target, loader);
}
diff --git a/libswfdec/swfdec_loadertarget.h b/libswfdec/swfdec_loadertarget.h
index 2d99869..81178c5 100644
--- a/libswfdec/swfdec_loadertarget.h
+++ b/libswfdec/swfdec_loadertarget.h
@@ -36,17 +36,32 @@ typedef struct _SwfdecLoaderTargetInterf
struct _SwfdecLoaderTargetInterface {
GTypeInterface parent;
- /* mandatory vfuncs */
+ /* mandatory vfunc */
SwfdecPlayer * (* get_player) (SwfdecLoaderTarget * target);
+ /* optional vfuncs */
+ void (* open) (SwfdecLoaderTarget * target,
+ SwfdecLoader * loader,
+ guint status);
void (* parse) (SwfdecLoaderTarget * target,
SwfdecLoader * loader);
+ void (* eof) (SwfdecLoaderTarget * target,
+ SwfdecLoader * loader);
+ void (* error) (SwfdecLoaderTarget * target,
+ SwfdecLoader * loader);
};
GType swfdec_loader_target_get_type (void) G_GNUC_CONST;
SwfdecPlayer * swfdec_loader_target_get_player (SwfdecLoaderTarget * target);
+void swfdec_loader_target_open (SwfdecLoaderTarget * target,
+ SwfdecLoader * loader,
+ guint status);
void swfdec_loader_target_parse (SwfdecLoaderTarget * target,
SwfdecLoader * loader);
+void swfdec_loader_target_eof (SwfdecLoaderTarget * target,
+ SwfdecLoader * loader);
+void swfdec_loader_target_error (SwfdecLoaderTarget * target,
+ SwfdecLoader * loader);
G_END_DECLS
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 2734ec6..6f266b7 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -193,6 +193,37 @@ swfdec_net_stream_loader_target_get_play
}
static void
+swfdec_net_stream_loader_target_error (SwfdecLoaderTarget *target,
+ SwfdecLoader *loader)
+{
+ SwfdecNetStream *stream = SWFDEC_NET_STREAM (target);
+
+ if (stream->flvdecoder == NULL)
+ swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Play_StreamNotFound,
+ SWFDEC_AS_STR_error);
+}
+
+static void
+swfdec_net_stream_loader_target_recheck (SwfdecNetStream *stream)
+{
+ if (stream->buffering) {
+ guint first, last;
+ if (swfdec_flv_decoder_get_video_info (stream->flvdecoder, &first, &last)) {
+ guint current = MAX (first, stream->current_time);
+ if (current + stream->buffer_time <= last) {
+ swfdec_net_stream_video_goto (stream, current);
+ stream->buffering = FALSE;
+ swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Full,
+ SWFDEC_AS_STR_status);
+ }
+ } else {
+ SWFDEC_ERROR ("no video stream, how do we update buffering?");
+ }
+ }
+ swfdec_net_stream_update_playing (stream);
+}
+
+static void
swfdec_net_stream_loader_target_parse (SwfdecLoaderTarget *target,
SwfdecLoader *loader)
{
@@ -200,12 +231,6 @@ swfdec_net_stream_loader_target_parse (S
SwfdecDecoderClass *klass;
gboolean recheck = FALSE;
- if (loader->error) {
- if (stream->flvdecoder == NULL)
- swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Play_StreamNotFound,
- SWFDEC_AS_STR_error);
- return;
- }
if (loader->state != SWFDEC_LOADER_STATE_EOF && swfdec_buffer_queue_get_depth (loader->queue) == 0) {
SWFDEC_INFO ("nothing to do");
return;
@@ -246,45 +271,37 @@ swfdec_net_stream_loader_target_parse (S
}
}
out:
- if (loader->state == SWFDEC_LOADER_STATE_EOF) {
- guint first, last;
- swfdec_flv_decoder_eof (stream->flvdecoder);
- recheck = TRUE;
- swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Flush,
+ if (recheck)
+ swfdec_net_stream_loader_target_recheck (stream);
+}
+
+static void
+swfdec_net_stream_loader_target_eof (SwfdecLoaderTarget *target,
+ SwfdecLoader *loader)
+{
+ SwfdecNetStream *stream = SWFDEC_NET_STREAM (target);
+ guint first, last;
+
+ swfdec_flv_decoder_eof (stream->flvdecoder);
+ swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Flush,
+ SWFDEC_AS_STR_status);
+ swfdec_net_stream_video_goto (stream, stream->current_time);
+ stream->buffering = FALSE;
+ if (swfdec_flv_decoder_get_video_info (stream->flvdecoder, &first, &last) &&
+ stream->current_time + stream->buffer_time <= last) {
+ swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Full,
SWFDEC_AS_STR_status);
- swfdec_net_stream_video_goto (stream, stream->current_time);
- stream->buffering = FALSE;
- if (swfdec_flv_decoder_get_video_info (stream->flvdecoder, &first, &last) &&
- stream->current_time + stream->buffer_time <= last) {
- swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Full,
- SWFDEC_AS_STR_status);
- }
- }
- if (recheck) {
- if (stream->buffering) {
- guint first, last;
- if (swfdec_flv_decoder_get_video_info (stream->flvdecoder, &first, &last)) {
- guint current = MAX (first, stream->current_time);
- if (current + stream->buffer_time <= last) {
- swfdec_net_stream_video_goto (stream, current);
- stream->buffering = FALSE;
- swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NetStream_Buffer_Full,
- SWFDEC_AS_STR_status);
- }
- } else {
- SWFDEC_ERROR ("no video stream, how do we update buffering?");
- }
- }
- swfdec_net_stream_update_playing (stream);
}
+ swfdec_net_stream_loader_target_recheck (stream);
}
-
static void
swfdec_net_stream_loader_target_init (SwfdecLoaderTargetInterface *iface)
{
iface->get_player = swfdec_net_stream_loader_target_get_player;
iface->parse = swfdec_net_stream_loader_target_parse;
+ iface->eof = swfdec_net_stream_loader_target_eof;
+ iface->error = swfdec_net_stream_loader_target_error;
}
/*** SWFDEC VIDEO MOVIE INPUT ***/
diff --git a/libswfdec/swfdec_swf_instance.c b/libswfdec/swfdec_swf_instance.c
index e21baf8..7f82971 100644
--- a/libswfdec/swfdec_swf_instance.c
+++ b/libswfdec/swfdec_swf_instance.c
@@ -79,8 +79,6 @@ swfdec_swf_instance_loader_target_parse
SwfdecDecoder *dec = instance->decoder;
SwfdecDecoderClass *klass;
- if (loader->error)
- return;
if (dec == NULL) {
if (!swfdec_decoder_can_detect (loader->queue))
return;
diff --git a/libswfdec/swfdec_xml.c b/libswfdec/swfdec_xml.c
index 1db087e..c418ca4 100644
--- a/libswfdec/swfdec_xml.c
+++ b/libswfdec/swfdec_xml.c
@@ -52,43 +52,49 @@ swfdec_xml_ondata (SwfdecXml *xml)
}
static void
-swfdec_xml_loader_target_parse (SwfdecLoaderTarget *target, SwfdecLoader *loader)
+swfdec_xml_loader_target_error (SwfdecLoaderTarget *target, SwfdecLoader *loader)
{
SwfdecXml *xml = SWFDEC_XML (target);
- if (xml->loader != loader || loader->state <= SWFDEC_LOADER_STATE_READING)
- return;
+ /* break reference to the loader */
+ swfdec_loader_set_target (loader, NULL);
+ xml->loader = NULL;
+ g_object_unref (loader);
+ /* emit onData */
+ swfdec_xml_ondata (xml);
+}
+
+static void
+swfdec_xml_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loader)
+{
+ SwfdecXml *xml = SWFDEC_XML (target);
+ guint size;
/* get the text from the loader */
- if (loader->state == SWFDEC_LOADER_STATE_ERROR) {
- /* nothing to do here */
- } else {
- guint size;
- g_assert (loader->state == SWFDEC_LOADER_STATE_EOF);
- swfdec_loader_set_data_type (loader, SWFDEC_LOADER_DATA_TEXT);
- size = swfdec_buffer_queue_get_depth (loader->queue);
- xml->text = g_try_malloc (size + 1);
- if (xml->text) {
- SwfdecBuffer *buffer;
- guint i = 0;
- while ((buffer = swfdec_buffer_queue_pull_buffer (loader->queue))) {
- memcpy (xml->text + i, buffer->data, buffer->length);
- i += buffer->length;
- swfdec_buffer_unref (buffer);
- }
- g_assert (i == size);
- xml->text[size] = '\0';
- /* FIXME: validate otherwise? */
- if (!g_utf8_validate (xml->text, size, NULL)) {
- SWFDEC_ERROR ("downloaded data is not valid utf-8");
- g_free (xml->text);
- xml->text = NULL;
- }
- } else {
- SWFDEC_ERROR ("not enough memory to copy %u bytes", size);
+ size = swfdec_buffer_queue_get_depth (loader->queue);
+ xml->text = g_try_malloc (size + 1);
+ if (xml->text) {
+ SwfdecBuffer *buffer;
+ guint i = 0;
+ while ((buffer = swfdec_buffer_queue_pull_buffer (loader->queue))) {
+ memcpy (xml->text + i, buffer->data, buffer->length);
+ i += buffer->length;
+ swfdec_buffer_unref (buffer);
}
+ g_assert (i == size);
+ xml->text[size] = '\0';
+ /* FIXME: validate otherwise? */
+ if (!g_utf8_validate (xml->text, size, NULL)) {
+ SWFDEC_ERROR ("downloaded data is not valid utf-8");
+ g_free (xml->text);
+ xml->text = NULL;
+ }
+ } else {
+ SWFDEC_ERROR ("not enough memory to copy %u bytes", size);
}
+
/* break reference to the loader */
+ swfdec_loader_set_target (loader, NULL);
xml->loader = NULL;
g_object_unref (loader);
/* emit onData */
@@ -99,7 +105,8 @@ static void
swfdec_xml_loader_target_init (SwfdecLoaderTargetInterface *iface)
{
iface->get_player = swfdec_xml_loader_target_get_player;
- iface->parse = swfdec_xml_loader_target_parse;
+ iface->eof = swfdec_xml_loader_target_eof;
+ iface->error = swfdec_xml_loader_target_error;
}
/*** SWFDEC_XML ***/
@@ -166,4 +173,5 @@ swfdec_xml_load (SwfdecXml *xml, const c
swfdec_xml_reset (xml);
xml->loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (xml)->context), url);
swfdec_loader_set_target (xml->loader, SWFDEC_LOADER_TARGET (xml));
+ swfdec_loader_set_data_type (xml->loader, SWFDEC_LOADER_DATA_TEXT);
}
diff-tree de8205950a51b5bf5ad7645fb67eb9b9c21a0b4e (from 262fa2409436f429658cf14f03169bf0ebf277bf)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 15:59:45 2007 +0200
s/g_print/SWFDEC_DEBUG/
diff --git a/libswfdec/swfdec_url.c b/libswfdec/swfdec_url.c
index d1ec4ec..47b7142 100644
--- a/libswfdec/swfdec_url.c
+++ b/libswfdec/swfdec_url.c
@@ -80,7 +80,7 @@ swfdec_url_new (const char *string)
g_return_val_if_fail (string != NULL, NULL);
- g_print ("%s\n", string);
+ SWFDEC_DEBUG ("new url: %s", string);
url = g_slice_new0 (SwfdecURL);
url->url = g_strdup (string);
s = strstr (string, "://");
diff-tree 262fa2409436f429658cf14f03169bf0ebf277bf (from 49edc7f46d99b2f9da859511a0272dd63268c24d)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 15:59:06 2007 +0200
first step in loader handling reord
Loaders don't execute their code immediately now but instead call
swfdec_player_add_external_action() to queue actions for later.
diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index 3ee70e4..285ffc2 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -105,7 +105,7 @@ swfdec_loader_get_property (GObject *obj
g_value_set_string (value, loader->error);
break;
case PROP_EOF:
- g_value_set_boolean (value, loader->eof);
+ g_value_set_boolean (value, loader->state == SWFDEC_LOADER_STATE_EOF);
break;
case PROP_DATA_TYPE:
g_value_set_enum (value, loader->data_type);
@@ -132,10 +132,6 @@ swfdec_loader_set_property (GObject *obj
case PROP_ERROR:
swfdec_loader_error (loader, g_value_get_string (value));
break;
- case PROP_EOF:
- if (g_value_get_boolean (value) && !loader->eof)
- swfdec_loader_eof (loader);
- break;
case PROP_SIZE:
if (loader->size == 0 && g_value_get_ulong (value) > 0)
swfdec_loader_set_size (loader, g_value_get_ulong (value));
@@ -224,6 +220,7 @@ swfdec_file_loader_load (SwfdecLoader *l
g_error_free (error);
} else {
swfdec_loader_set_size (loader, buffer->length);
+ swfdec_loader_open (loader, 0);
swfdec_loader_push (loader, buffer);
swfdec_loader_eof (loader);
}
@@ -244,6 +241,22 @@ swfdec_file_loader_init (SwfdecFileLoade
/*** INTERNAL API ***/
+static void
+swfdec_loader_perform_open (gpointer loaderp, gpointer unused)
+{
+ SWFDEC_FIXME ("add vfunc for open to SwfdecLoaderTarget");
+}
+
+#define swfdec_loader_perform_error swfdec_loader_perform_push
+#define swfdec_loader_perform_eof swfdec_loader_perform_push
+static void
+swfdec_loader_perform_push (gpointer loaderp, gpointer unused)
+{
+ SwfdecLoader *loader = loaderp;
+
+ swfdec_loader_target_parse (loader->target, loader);
+}
+
SwfdecLoader *
swfdec_loader_load (SwfdecLoader *loader, const char *url,
SwfdecLoaderRequest request, const char *data, gsize data_len)
@@ -276,29 +289,40 @@ swfdec_loader_set_target (SwfdecLoader *
loader->target = target;
if (target) {
loader->player = swfdec_loader_target_get_player (target);
+ switch (loader->state) {
+ case SWFDEC_LOADER_STATE_NEW:
+ break;
+ case SWFDEC_LOADER_STATE_OPEN:
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_open, NULL);
+ break;
+ case SWFDEC_LOADER_STATE_READING:
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_open, NULL);
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_push, NULL);
+ break;
+ case SWFDEC_LOADER_STATE_EOF:
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_open, NULL);
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_push, NULL);
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_eof, NULL);
+ break;
+ case SWFDEC_LOADER_STATE_ERROR:
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_error, NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
} else {
loader->player = NULL;
}
}
-static void
-swfdec_loader_do_parse (gpointer empty, gpointer loaderp)
-{
- SwfdecLoader *loader = SWFDEC_LOADER (loaderp);
-
- swfdec_loader_target_parse (loader->target, loader);
-}
-
-void
-swfdec_loader_queue_parse (SwfdecLoader *loader)
-{
- g_return_if_fail (SWFDEC_IS_LOADER (loader));
- g_return_if_fail (loader->target != NULL);
-
- /* HACK: using player as action object makes them get auto-removed */
- swfdec_player_add_action (loader->player, loader->player, swfdec_loader_do_parse, loader);
-}
-
/** PUBLIC API ***/
/**
@@ -346,6 +370,7 @@ swfdec_loader_new_from_file (const char
g_error_free (error);
} else {
swfdec_loader_set_size (loader, buf->length);
+ swfdec_loader_open (loader, 0);
swfdec_loader_push (loader, buf);
swfdec_loader_eof (loader);
}
@@ -372,40 +397,33 @@ swfdec_loader_error (SwfdecLoader *loade
return;
}
- if (loader->target) {
- swfdec_player_lock (loader->player);
- swfdec_loader_error_locked (loader, error);
- swfdec_player_perform_actions (loader->player);
- swfdec_player_unlock (loader->player);
- } else {
- swfdec_loader_error_locked (loader, error);
- }
-}
-
-void
-swfdec_loader_error_locked (SwfdecLoader *loader, const char *error)
-{
- if (loader->error)
- return;
-
- SWFDEC_WARNING ("error in %s %p: %s", G_OBJECT_TYPE_NAME (loader), loader, error);
+ loader->state = SWFDEC_LOADER_STATE_ERROR;
loader->error = g_strdup (error);
- g_object_notify (G_OBJECT (loader), "error");
if (loader->target)
- swfdec_loader_target_parse (loader->target, loader);
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_error, NULL);
}
+/**
+ * swfdec_loader_open:
+ * @loader: a #SwfdecLoader
+ * @status: HTTP state code when opening the connection or 0 if unknown or not
+ * a HTTP connection.
+ *
+ * Call this function when your loader opened the resulting file. For HTTP this
+ * is when having received the headers. You must call this function before
+ * swfdec_laoder_push() can be called.
+ **/
void
-swfdec_loader_parse (SwfdecLoader *loader)
+swfdec_loader_open (SwfdecLoader *loader, guint status)
{
- if (loader->target == NULL ||
- loader->error)
- return;
+ g_return_if_fail (SWFDEC_IS_LOADER (loader));
+ g_return_if_fail (loader->state == SWFDEC_LOADER_STATE_NEW);
- swfdec_player_lock (loader->player);
- swfdec_loader_target_parse (loader->target, loader);
- swfdec_player_perform_actions (loader->player);
- swfdec_player_unlock (loader->player);
+ loader->state = SWFDEC_LOADER_STATE_OPEN;
+ loader->open_status = status;
+ if (loader->player)
+ swfdec_player_add_external_action (loader->player, loader, swfdec_loader_perform_open, NULL);
}
/**
@@ -414,40 +432,46 @@ swfdec_loader_parse (SwfdecLoader *loade
* @buffer: new data to make available. The loader takes the reference
* to the buffer.
*
- * Makes the data in @buffer available to @loader and processes it.
+ * Makes the data in @buffer available to @loader and processes it. The @loader
+ * must be open.
**/
void
swfdec_loader_push (SwfdecLoader *loader, SwfdecBuffer *buffer)
{
g_return_if_fail (SWFDEC_IS_LOADER (loader));
- g_return_if_fail (loader->eof == FALSE);
+ g_return_if_fail (loader->state == SWFDEC_LOADER_STATE_OPEN || loader->state == SWFDEC_LOADER_STATE_READING);
g_return_if_fail (buffer != NULL);
swfdec_buffer_queue_push (loader->queue, buffer);
g_object_notify (G_OBJECT (loader), "loaded");
- swfdec_loader_parse (loader);
+ loader->state = SWFDEC_LOADER_STATE_READING;
+ if (loader->player)
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_push, NULL);
}
/**
* swfdec_loader_eof:
* @loader: a #SwfdecLoader
*
- * Indicates to @loader that no more data will follow.
+ * Indicates to @loader that no more data will follow. The loader must be open.
**/
void
swfdec_loader_eof (SwfdecLoader *loader)
{
g_return_if_fail (SWFDEC_IS_LOADER (loader));
- g_return_if_fail (loader->eof == FALSE);
+ g_return_if_fail (loader->state == SWFDEC_LOADER_STATE_OPEN || loader->state == SWFDEC_LOADER_STATE_READING);
- loader->eof = TRUE;
if (loader->size == 0) {
gulong bytes = swfdec_loader_get_loaded (loader);
if (bytes)
swfdec_loader_set_size (loader, bytes);
}
g_object_notify (G_OBJECT (loader), "eof");
- swfdec_loader_parse (loader);
+ loader->state = SWFDEC_LOADER_STATE_EOF;
+ if (loader->player)
+ swfdec_player_add_external_action (loader->player, loader,
+ swfdec_loader_perform_eof, NULL);
}
/**
diff --git a/libswfdec/swfdec_loader.h b/libswfdec/swfdec_loader.h
index 4ccc1fb..6bed2d2 100644
--- a/libswfdec/swfdec_loader.h
+++ b/libswfdec/swfdec_loader.h
@@ -56,10 +56,11 @@ struct _SwfdecLoader
GObject object;
/*< private >*/
+ guint state; /* SwfdecLoaderState the loader is currently in */
SwfdecURL * url; /* the URL for this loader in UTF-8 - must be set on creation */
+ guint open_status; /* HTTP status when opening or 0 if unknown */
gulong size; /* number of bytes in stream or 0 if unknown */
- gboolean eof; /* if we're in EOF already */
- char * error; /* if there's an error (from parsing the loader) */
+ char * error; /* error message if in error state or NULL */
gpointer target; /* SwfdecLoaderTarget that gets notified about loading progress */
gpointer player; /* SwfdecPlayer belonging to target or %NULL */
SwfdecBufferQueue * queue; /* SwfdecBufferQueue managing the input buffers */
@@ -81,6 +82,8 @@ GType swfdec_loader_get_type (void);
SwfdecLoader * swfdec_loader_new_from_file (const char * filename);
+void swfdec_loader_open (SwfdecLoader * loader,
+ guint status);
void swfdec_loader_push (SwfdecLoader * loader,
SwfdecBuffer * buffer);
void swfdec_loader_eof (SwfdecLoader * loader);
diff --git a/libswfdec/swfdec_loader_internal.h b/libswfdec/swfdec_loader_internal.h
index 0b1840f..a6a477f 100644
--- a/libswfdec/swfdec_loader_internal.h
+++ b/libswfdec/swfdec_loader_internal.h
@@ -25,6 +25,14 @@
G_BEGIN_DECLS
+typedef enum {
+ SWFDEC_LOADER_STATE_NEW = 0, /* loader is new and has not been opened yet */
+ SWFDEC_LOADER_STATE_OPEN, /* loader is opened and has got the HTTP headers */
+ SWFDEC_LOADER_STATE_READING, /* loader has read some bytes of data and is still reading */
+ SWFDEC_LOADER_STATE_EOF, /* swfdec_loader_eof() has been called */
+ SWFDEC_LOADER_STATE_ERROR /* loader is in error state */
+} SwfdecLoaderState;
+
typedef struct _SwfdecFileLoader SwfdecFileLoader;
typedef struct _SwfdecFileLoaderClass SwfdecFileLoaderClass;
@@ -52,14 +60,10 @@ SwfdecLoader * swfdec_loader_load (Swf
SwfdecLoaderRequest request,
const char * data,
gsize data_len);
-void swfdec_loader_parse (SwfdecLoader * loader);
-void swfdec_loader_queue_parse (SwfdecLoader * loader);
void swfdec_loader_set_target (SwfdecLoader * loader,
SwfdecLoaderTarget * target);
void swfdec_loader_set_data_type (SwfdecLoader * loader,
SwfdecLoaderDataType type);
-void swfdec_loader_error_locked (SwfdecLoader * loader,
- const char * error);
gboolean swfdec_urldecode_one (const char * string,
char ** name,
diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c
index f702f99..aa939b7 100644
--- a/libswfdec/swfdec_loadertarget.c
+++ b/libswfdec/swfdec_loadertarget.c
@@ -83,8 +83,7 @@ swfdec_loader_target_parse (SwfdecLoader
g_return_if_fail (SWFDEC_IS_LOADER_TARGET (target));
g_return_if_fail (SWFDEC_IS_LOADER (loader));
- SWFDEC_LOG ("parsing %p%s%s", loader,
- loader->error ? " ERROR" : "", loader->eof ? " EOF" : "");
+ SWFDEC_LOG ("parsing %p (state %u)", loader, loader->state);
iface = SWFDEC_LOADER_TARGET_GET_INTERFACE (target);
g_return_if_fail (iface->parse != NULL);
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 3a2980d..a696967 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -1113,7 +1113,6 @@ swfdec_movie_load (SwfdecMovie *movie, c
request, data, data_len);
g_assert (loader);
swfdec_player_add_level_from_loader (player, depth, loader, NULL);
- swfdec_loader_queue_parse (loader);
}
} else {
SWFDEC_ERROR ("%s does not specify a valid level", target);
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 9addf77..2734ec6 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -206,7 +206,7 @@ swfdec_net_stream_loader_target_parse (S
SWFDEC_AS_STR_error);
return;
}
- if (!loader->eof && swfdec_buffer_queue_get_depth (loader->queue) == 0) {
+ if (loader->state != SWFDEC_LOADER_STATE_EOF && swfdec_buffer_queue_get_depth (loader->queue) == 0) {
SWFDEC_INFO ("nothing to do");
return;
}
@@ -246,7 +246,7 @@ swfdec_net_stream_loader_target_parse (S
}
}
out:
- if (loader->eof) {
+ if (loader->state == SWFDEC_LOADER_STATE_EOF) {
guint first, last;
swfdec_flv_decoder_eof (stream->flvdecoder);
recheck = TRUE;
@@ -462,7 +462,6 @@ swfdec_net_stream_set_loader (SwfdecNetS
if (loader) {
g_object_ref (loader);
swfdec_loader_set_target (loader, SWFDEC_LOADER_TARGET (stream));
- swfdec_loader_queue_parse (loader);
}
swfdec_net_stream_set_playing (stream, TRUE);
}
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index ef998f7..b4df554 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -650,6 +650,8 @@ swfdec_player_dispose (GObject *object)
swfdec_ring_buffer_free (player->actions);
g_assert (player->movies == NULL);
g_assert (player->audio == NULL);
+ if (player->external_timeout.callback)
+ swfdec_player_remove_timeout (player, &player->external_timeout);
if (player->rate) {
swfdec_player_remove_timeout (player, &player->iterate_timeout);
}
@@ -950,6 +952,7 @@ swfdec_player_do_advance (SwfdecPlayer *
swfdec_player_lock (player);
swfdec_player_perform_external_actions (player);
+ swfdec_player_perform_actions (player);
target_time = player->time + SWFDEC_MSECS_TO_TICKS (msecs);
SWFDEC_DEBUG ("advancing %u msecs (%u audio frames)", msecs, audio_samples);
@@ -1522,10 +1525,13 @@ swfdec_player_set_loader_with_variables
g_return_if_fail (player->roots == NULL);
g_return_if_fail (SWFDEC_IS_LOADER (loader));
+ swfdec_player_lock (player);
player->loader = loader;
g_object_ref (loader);
swfdec_player_add_level_from_loader (player, 0, loader, variables);
- swfdec_loader_parse (loader);
+ swfdec_player_perform_external_actions (player);
+ swfdec_player_perform_actions (player);
+ swfdec_player_unlock (player);
}
/**
diff --git a/libswfdec/swfdec_swf_instance.c b/libswfdec/swfdec_swf_instance.c
index e79ed95..e21baf8 100644
--- a/libswfdec/swfdec_swf_instance.c
+++ b/libswfdec/swfdec_swf_instance.c
@@ -86,7 +86,8 @@ swfdec_swf_instance_loader_target_parse
return;
dec = swfdec_decoder_new (player, loader->queue);
if (dec == NULL) {
- swfdec_loader_error_locked (loader, "Unknown format");
+ SWFDEC_ERROR ("no decoder found");
+ swfdec_loader_set_target (loader, NULL);
return;
}
@@ -99,7 +100,7 @@ swfdec_swf_instance_loader_target_parse
} else {
SWFDEC_FIXME ("implement handling of %s", G_OBJECT_TYPE_NAME (dec));
g_object_unref (dec);
- swfdec_loader_error_locked (loader, "Unknown format");
+ swfdec_loader_set_target (loader, NULL);
return;
}
/* HACK for flv playback */
@@ -114,7 +115,8 @@ swfdec_swf_instance_loader_target_parse
SwfdecStatus status = klass->parse (dec);
switch (status) {
case SWFDEC_STATUS_ERROR:
- swfdec_loader_error_locked (loader, "parsing error");
+ SWFDEC_ERROR ("parsing error");
+ swfdec_loader_set_target (loader, NULL);
return;
case SWFDEC_STATUS_OK:
break;
diff --git a/libswfdec/swfdec_xml.c b/libswfdec/swfdec_xml.c
index a5b9e62..1db087e 100644
--- a/libswfdec/swfdec_xml.c
+++ b/libswfdec/swfdec_xml.c
@@ -56,16 +56,15 @@ swfdec_xml_loader_target_parse (SwfdecLo
{
SwfdecXml *xml = SWFDEC_XML (target);
- if (xml->loader != loader ||
- (!loader->eof && !loader->error))
+ if (xml->loader != loader || loader->state <= SWFDEC_LOADER_STATE_READING)
return;
/* get the text from the loader */
- if (loader->error) {
+ if (loader->state == SWFDEC_LOADER_STATE_ERROR) {
/* nothing to do here */
} else {
guint size;
- g_assert (loader->eof);
+ g_assert (loader->state == SWFDEC_LOADER_STATE_EOF);
swfdec_loader_set_data_type (loader, SWFDEC_LOADER_DATA_TEXT);
size = swfdec_buffer_queue_get_depth (loader->queue);
xml->text = g_try_malloc (size + 1);
@@ -167,5 +166,4 @@ swfdec_xml_load (SwfdecXml *xml, const c
swfdec_xml_reset (xml);
xml->loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (xml)->context), url);
swfdec_loader_set_target (xml->loader, SWFDEC_LOADER_TARGET (xml));
- swfdec_loader_queue_parse (xml->loader);
}
diff-tree 49edc7f46d99b2f9da859511a0272dd63268c24d (from 2cbd14d42891bafe6319ca535c8dd0a9b0ac838e)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 04:06:52 2007 +0200
refactor loader handling
- require unsetting of target before disposing loader
- make loader keep track of its player (so it can add actions there)
diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index 65081d5..3ee70e4 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -151,6 +151,8 @@ swfdec_loader_dispose (GObject *object)
{
SwfdecLoader *loader = SWFDEC_LOADER (object);
+ /* targets are supposed to keep a reference around */
+ g_assert (loader->target == NULL);
swfdec_buffer_queue_unref (loader->queue);
swfdec_url_free (loader->url);
g_free (loader->error);
@@ -268,7 +270,15 @@ swfdec_loader_set_target (SwfdecLoader *
g_return_if_fail (SWFDEC_IS_LOADER (loader));
g_return_if_fail (target == NULL || SWFDEC_IS_LOADER_TARGET (target));
+ if (loader->target) {
+ swfdec_player_remove_all_external_actions (loader->player, loader);
+ }
loader->target = target;
+ if (target) {
+ loader->player = swfdec_loader_target_get_player (target);
+ } else {
+ loader->player = NULL;
+ }
}
static void
@@ -282,14 +292,11 @@ swfdec_loader_do_parse (gpointer empty,
void
swfdec_loader_queue_parse (SwfdecLoader *loader)
{
- SwfdecPlayer *player;
-
g_return_if_fail (SWFDEC_IS_LOADER (loader));
g_return_if_fail (loader->target != NULL);
- player = swfdec_loader_target_get_player (loader->target);
/* HACK: using player as action object makes them get auto-removed */
- swfdec_player_add_action (player, player, swfdec_loader_do_parse, loader);
+ swfdec_player_add_action (loader->player, loader->player, swfdec_loader_do_parse, loader);
}
/** PUBLIC API ***/
@@ -357,8 +364,6 @@ swfdec_loader_new_from_file (const char
void
swfdec_loader_error (SwfdecLoader *loader, const char *error)
{
- SwfdecPlayer *player;
-
g_return_if_fail (SWFDEC_IS_LOADER (loader));
g_return_if_fail (error != NULL);
@@ -368,11 +373,10 @@ swfdec_loader_error (SwfdecLoader *loade
}
if (loader->target) {
- player = swfdec_loader_target_get_player (loader->target);
- swfdec_player_lock (player);
+ swfdec_player_lock (loader->player);
swfdec_loader_error_locked (loader, error);
- swfdec_player_perform_actions (player);
- swfdec_player_unlock (player);
+ swfdec_player_perform_actions (loader->player);
+ swfdec_player_unlock (loader->player);
} else {
swfdec_loader_error_locked (loader, error);
}
@@ -394,17 +398,14 @@ swfdec_loader_error_locked (SwfdecLoader
void
swfdec_loader_parse (SwfdecLoader *loader)
{
- SwfdecPlayer *player;
-
if (loader->target == NULL ||
loader->error)
return;
- player = swfdec_loader_target_get_player (loader->target);
- swfdec_player_lock (player);
+ swfdec_player_lock (loader->player);
swfdec_loader_target_parse (loader->target, loader);
- swfdec_player_perform_actions (player);
- swfdec_player_unlock (player);
+ swfdec_player_perform_actions (loader->player);
+ swfdec_player_unlock (loader->player);
}
/**
diff --git a/libswfdec/swfdec_loader.h b/libswfdec/swfdec_loader.h
index 9cc0a4e..4ccc1fb 100644
--- a/libswfdec/swfdec_loader.h
+++ b/libswfdec/swfdec_loader.h
@@ -61,6 +61,7 @@ struct _SwfdecLoader
gboolean eof; /* if we're in EOF already */
char * error; /* if there's an error (from parsing the loader) */
gpointer target; /* SwfdecLoaderTarget that gets notified about loading progress */
+ gpointer player; /* SwfdecPlayer belonging to target or %NULL */
SwfdecBufferQueue * queue; /* SwfdecBufferQueue managing the input buffers */
SwfdecLoaderDataType data_type; /* type this stream is in (identified by swfdec) */
};
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 2f993c3..9addf77 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -449,8 +449,10 @@ swfdec_net_stream_set_loader (SwfdecNetS
g_return_if_fail (SWFDEC_IS_NET_STREAM (stream));
g_return_if_fail (loader == NULL || SWFDEC_IS_LOADER (loader));
- if (stream->loader)
+ if (stream->loader) {
+ swfdec_loader_set_target (stream->loader, NULL);
g_object_unref (stream->loader);
+ }
if (stream->flvdecoder) {
g_object_unref (stream->flvdecoder);
stream->flvdecoder = NULL;
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 15caea0..ef998f7 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -323,7 +323,7 @@ swfdec_player_perform_external_actions (
/* we need to query the number of current actions so newly added ones aren't
* executed in here */
- for (i = swfdec_ring_buffer_get_size (player->external_actions); i > 0; i--) {
+ for (i = swfdec_ring_buffer_get_n_elements (player->external_actions); i > 0; i--) {
action = swfdec_ring_buffer_pop (player->external_actions);
g_assert (action != NULL);
/* skip removed actions */
diff --git a/libswfdec/swfdec_swf_instance.c b/libswfdec/swfdec_swf_instance.c
index b45ef43..e79ed95 100644
--- a/libswfdec/swfdec_swf_instance.c
+++ b/libswfdec/swfdec_swf_instance.c
@@ -149,6 +149,7 @@ swfdec_swf_instance_dispose (GObject *ob
{
SwfdecSwfInstance *instance = SWFDEC_SWF_INSTANCE (object);
+ swfdec_loader_set_target (instance->loader, NULL);
g_object_unref (instance->loader);
if (instance->decoder) {
g_object_unref (instance->decoder);
@@ -186,12 +187,14 @@ swfdec_swf_instance_new (SwfdecSpriteMov
mov = SWFDEC_MOVIE (movie);
swf = g_object_new (SWFDEC_TYPE_SWF_INSTANCE, NULL);
- swf->loader = g_object_ref (loader);
- swfdec_loader_set_target (loader, SWFDEC_LOADER_TARGET (swf));
+ /* set important variables */
+ swf->movie = movie;
if (mov->swf)
g_object_unref (mov->swf);
mov->swf = swf;
- swf->movie = movie;
+ /* set loader (that depends on those vars) */
+ swf->loader = g_object_ref (loader);
+ swfdec_loader_set_target (loader, SWFDEC_LOADER_TARGET (swf));
return swf;
}
diff --git a/libswfdec/swfdec_xml.c b/libswfdec/swfdec_xml.c
index 404ec38..a5b9e62 100644
--- a/libswfdec/swfdec_xml.c
+++ b/libswfdec/swfdec_xml.c
@@ -112,6 +112,7 @@ static void
swfdec_xml_reset (SwfdecXml *xml)
{
if (xml->loader) {
+ swfdec_loader_set_target (xml->loader, NULL);
g_object_unref (xml->loader);
xml->loader = NULL;
}
diff-tree 2cbd14d42891bafe6319ca535c8dd0a9b0ac838e (from e9b685648bc358610b38344ba67897401670f46c)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Aug 1 03:48:41 2007 +0200
add support for "external actions"
external actions are supposed to be actions that are initiated by outside
happenings, such as resizing or data being pushed to the player. By queueing
them inside the player instead of executing them immediately, we can get
around infinite loops (loading error causing a new load causing a loading
error causing...) as well as having a lot less entry points to the script
engine. This makes it easier to call functions from callbacks, in particular
from within debugger breakpoints.
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index f0e448f..15caea0 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -315,6 +315,88 @@ swfdec_player_do_action (SwfdecPlayer *p
return TRUE;
}
+static void
+swfdec_player_perform_external_actions (SwfdecPlayer *player)
+{
+ SwfdecPlayerAction *action;
+ guint i;
+
+ /* we need to query the number of current actions so newly added ones aren't
+ * executed in here */
+ for (i = swfdec_ring_buffer_get_size (player->external_actions); i > 0; i--) {
+ action = swfdec_ring_buffer_pop (player->external_actions);
+ g_assert (action != NULL);
+ /* skip removed actions */
+ if (action->object == NULL)
+ continue;
+ action->func (action->object, action->data);
+ }
+
+ if (player->external_timeout.callback) {
+ swfdec_player_remove_timeout (player, &player->external_timeout);
+ player->external_timeout.callback = NULL;
+ }
+}
+
+static void
+swfdec_player_trigger_external_actions (SwfdecTimeout *advance)
+{
+ SwfdecPlayer *player = SWFDEC_PLAYER ((guint8 *) advance - G_STRUCT_OFFSET (SwfdecPlayer, external_timeout));
+
+ player->external_timeout.callback = NULL;
+ swfdec_player_perform_external_actions (player);
+}
+
+void
+swfdec_player_add_external_action (SwfdecPlayer *player, gpointer object,
+ SwfdecActionFunc action_func, gpointer action_data)
+{
+ SwfdecPlayerAction *action;
+
+ g_return_if_fail (SWFDEC_IS_PLAYER (player));
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (action_func != NULL);
+
+ SWFDEC_LOG ("adding external action %p %p %p", object, action_func, action_data);
+ action = swfdec_ring_buffer_push (player->external_actions);
+ if (action == NULL) {
+ /* FIXME: limit number of actions to not get inf loops due to scripts? */
+ swfdec_ring_buffer_set_size (player->actions,
+ swfdec_ring_buffer_get_size (player->actions) + 16);
+ action = swfdec_ring_buffer_push (player->actions);
+ g_assert (action);
+ }
+ action->object = object;
+ action->func = action_func;
+ action->data = action_data;
+ if (!player->external_timeout.callback) {
+ /* trigger execution in 100 ms */
+ player->external_timeout.timestamp = player->time + SWFDEC_MSECS_TO_TICKS (100);
+ player->external_timeout.callback = swfdec_player_trigger_external_actions;
+ swfdec_player_add_timeout (player, &player->external_timeout);
+ }
+}
+
+void
+swfdec_player_remove_all_external_actions (SwfdecPlayer *player, gpointer object)
+{
+ SwfdecPlayerAction *action;
+ guint i;
+
+ g_return_if_fail (SWFDEC_IS_PLAYER (player));
+ g_return_if_fail (object != NULL);
+
+ for (i = 0; i < swfdec_ring_buffer_get_n_elements (player->external_actions); i++) {
+ action = swfdec_ring_buffer_peek_nth (player->external_actions, i);
+
+ if (action->object == object) {
+ SWFDEC_LOG ("removing external action %p %p %p",
+ action->object, action->func, action->data);
+ action->object = NULL;
+ }
+ }
+}
+
/*** SwfdecPlayer ***/
enum {
@@ -867,6 +949,7 @@ swfdec_player_do_advance (SwfdecPlayer *
guint frames_now;
swfdec_player_lock (player);
+ swfdec_player_perform_external_actions (player);
target_time = player->time + SWFDEC_MSECS_TO_TICKS (msecs);
SWFDEC_DEBUG ("advancing %u msecs (%u audio frames)", msecs, audio_samples);
@@ -1161,6 +1244,7 @@ swfdec_player_init (SwfdecPlayer *player
player->registered_classes = g_hash_table_new (g_direct_hash, g_direct_equal);
player->actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerAction, 16);
+ player->external_actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerAction, 8);
player->cache = swfdec_cache_new (50 * 1024 * 1024); /* 100 MB */
player->bgcolor = SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF);
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index 84946ff..cc9a384 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -106,6 +106,8 @@ struct _SwfdecPlayer
/* iterating */
GList * movies; /* list of all moveis that want to be iterated */
SwfdecRingBuffer * actions; /* all actions we've queued up so far */
+ SwfdecRingBuffer * external_actions; /* external actions we've queued up, like resize or loader stuff */
+ SwfdecTimeout external_timeout; /* callback for iterating */
GQueue * init_queue; /* all movies that require an init event */
GQueue * construct_queue; /* all movies that require an construct event */
};
@@ -150,12 +152,21 @@ void swfdec_player_add_timeout (SwfdecP
SwfdecTimeout * timeout);
void swfdec_player_remove_timeout (SwfdecPlayer * player,
SwfdecTimeout * timeout);
+void swfdec_player_add_external_action
+ (SwfdecPlayer * player,
+ gpointer object,
+ SwfdecActionFunc action_func,
+ gpointer action_data);
+void swfdec_player_remove_all_external_actions
+ (SwfdecPlayer * player,
+ gpointer object);
void swfdec_player_add_action (SwfdecPlayer * player,
gpointer object,
SwfdecActionFunc action_func,
gpointer action_data);
void swfdec_player_remove_all_actions (SwfdecPlayer * player,
gpointer object);
+
void swfdec_player_set_drag_movie (SwfdecPlayer * player,
SwfdecMovie * drag,
gboolean center,
More information about the Swfdec
mailing list