[Swfdec] 4 commits - libswfdec/swfdec_flv_decoder.c
libswfdec/swfdec_flv_decoder.h libswfdec/swfdec_movie.c test/trace
Benjamin Otte
company at kemper.freedesktop.org
Tue Mar 20 03:22:30 PDT 2007
libswfdec/swfdec_flv_decoder.c | 108 +++++++++++++++++++++++++++++++-
libswfdec/swfdec_flv_decoder.h | 4 +
libswfdec/swfdec_movie.c | 2
test/trace/Makefile.am | 3
test/trace/onload-childparent.c | 38 +++++++++++
test/trace/onload-childparent.swf |binary
test/trace/onload-childparent.swf.trace | 3
7 files changed, 156 insertions(+), 2 deletions(-)
New commits:
diff-tree 9395d4ef15746d3e1d7070a13f6da03a91c67b54 (from c1dade098152d072a1e1acb571a7deae7d3e950d)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 20 11:21:54 2007 +0100
add test that checks child/parent onLoad order
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index c72b19b..32583ec 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -134,6 +134,9 @@ EXTRA_DIST = \
object-math-6.swf.trace \
object-math-7.swf \
object-math-7.swf.trace \
+ onload-childparent.c \
+ onload-childparent.swf \
+ onload-childparent.swf.trace \
order.swf \
order.swf.trace \
parent-root.swf \
diff --git a/test/trace/onload-childparent.c b/test/trace/onload-childparent.c
new file mode 100644
index 0000000..44e2ce3
--- /dev/null
+++ b/test/trace/onload-childparent.c
@@ -0,0 +1,38 @@
+/* gcc `pkg-config --libs --cflags libming` onload-childparent.c -o onload-childparent && ./onload-childparent
+ */
+
+#include <ming.h>
+
+int
+main (int argc, char **argv)
+{
+ SWFMovie movie;
+ SWFMovieClip parent, child;
+ SWFDisplayItem item;
+
+ if (Ming_init ())
+ return 1;
+ Ming_useSWFVersion (7);
+
+ movie = newSWFMovie();
+ SWFMovie_setRate (movie, 1);
+ SWFMovie_setDimension (movie, 200, 150);
+ SWFMovie_add (movie, (SWFBlock) compileSWFActionCode (""
+ " trace (\"Check that the parent onLoad event happens before the child's onLoad\");"
+ ""));
+ parent = newSWFMovieClip ();
+ child = newSWFMovieClip ();
+ item = SWFMovieClip_add (parent, (SWFBlock) child);
+ SWFDisplayItem_addAction (item, compileSWFActionCode (""
+ " trace (\"child\");"
+ ""), SWFACTION_ONLOAD);
+ SWFMovieClip_nextFrame (parent);
+ item = SWFMovie_add (movie, (SWFBlock) parent);
+ SWFDisplayItem_addAction (item, compileSWFActionCode (""
+ " trace (\"parent\");"
+ ""), SWFACTION_ONLOAD);
+ SWFMovie_nextFrame (movie);
+
+ SWFMovie_save (movie, "onload-childparent.swf");
+ return 0;
+}
diff --git a/test/trace/onload-childparent.swf b/test/trace/onload-childparent.swf
new file mode 100644
index 0000000..b51d895
Binary files /dev/null and b/test/trace/onload-childparent.swf differ
diff --git a/test/trace/onload-childparent.swf.trace b/test/trace/onload-childparent.swf.trace
new file mode 100644
index 0000000..3439819
--- /dev/null
+++ b/test/trace/onload-childparent.swf.trace
@@ -0,0 +1,3 @@
+Check that the parent onLoad event happens before the child's onLoad
+parent
+child
diff-tree c1dade098152d072a1e1acb571a7deae7d3e950d (from 8b7d05d276bf0a66216443bdb8de15707b75d984)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 20 11:21:00 2007 +0100
parent onLoad events happen before child onLoad events
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 4c4ec47..17e2217 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -748,9 +748,9 @@ swfdec_movie_set_parent (SwfdecMovie *mo
}
if (SWFDEC_IS_DEBUGGER (player))
g_signal_emit_by_name (player, "movie-added", movie);
+ swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);
if (klass->init_movie)
klass->init_movie (movie);
- swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);
}
static void
diff-tree 8b7d05d276bf0a66216443bdb8de15707b75d984 (from f0b43bf7ca0fa81ad5b8a3ade399b9c242e08328)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 20 11:10:24 2007 +0100
set the decoder after setting the loader
setting the laoder resets the decoder, so a new one would get created
diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index 21e2ff8..7615225 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -656,8 +656,8 @@ swfdec_flv_decoder_add_movie (SwfdecFlvD
/* set up the playback stream */
conn = swfdec_connection_new (SWFDEC_ROOT_MOVIE (parent)->player->jscx);
stream = swfdec_net_stream_new (SWFDEC_ROOT_MOVIE (parent)->player, conn);
- stream->flvdecoder = flv;
swfdec_net_stream_set_loader (stream, SWFDEC_ROOT_MOVIE (parent)->loader);
+ stream->flvdecoder = flv;
swfdec_video_movie_set_input (SWFDEC_VIDEO_MOVIE (movie), &stream->input);
swfdec_net_stream_set_playing (stream, TRUE);
g_object_unref (conn);
diff-tree f0b43bf7ca0fa81ad5b8a3ade399b9c242e08328 (from 72e2c95e9fbd6cdebc5755652ee3a8bb0b6af6b3)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 20 11:07:44 2007 +0100
handle data tags
diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index 530915d..21e2ff8 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -36,6 +36,7 @@ enum {
typedef struct _SwfdecFlvVideoTag SwfdecFlvVideoTag;
typedef struct _SwfdecFlvAudioTag SwfdecFlvAudioTag;
+typedef struct _SwfdecFlvDataTag SwfdecFlvDataTag;
struct _SwfdecFlvVideoTag {
guint timestamp; /* milliseconds */
@@ -52,6 +53,11 @@ struct _SwfdecFlvAudioTag {
SwfdecBuffer * buffer; /* buffer for this data */
};
+struct _SwfdecFlvDataTag {
+ guint timestamp; /* milliseconds */
+ SwfdecBuffer * buffer; /* buffer containing raw AMF data */
+};
+
G_DEFINE_TYPE (SwfdecFlvDecoder, swfdec_flv_decoder, SWFDEC_TYPE_DECODER)
static void
@@ -76,6 +82,15 @@ swfdec_flv_decoder_dispose (GObject *obj
g_array_free (flv->video, TRUE);
flv->video = NULL;
}
+ if (flv->data) {
+ for (i = 0; i < flv->data->len; i++) {
+ SwfdecFlvDataTag *tag = &g_array_index (flv->data, SwfdecFlvDataTag, i);
+ swfdec_buffer_unref (tag->buffer);
+ }
+ g_array_free (flv->data, TRUE);
+ flv->data = NULL;
+ }
+
G_OBJECT_CLASS (swfdec_flv_decoder_parent_class)->dispose (object);
}
@@ -197,6 +212,27 @@ swfdec_flv_decoder_find_audio (SwfdecFlv
return min;
}
+static guint
+swfdec_flv_decoder_find_data (SwfdecFlvDecoder *flv, guint timestamp)
+{
+ guint min, max;
+
+ g_assert (flv->data);
+
+ min = 0;
+ max = flv->data->len;
+ while (max - min > 1) {
+ guint cur = (max + min) / 2;
+ SwfdecFlvDataTag *tag = &g_array_index (flv->data, SwfdecFlvDataTag, cur);
+ if (tag->timestamp > timestamp) {
+ max = cur;
+ } else {
+ min = cur;
+ }
+ }
+ return min;
+}
+
static SwfdecStatus
swfdec_flv_decoder_parse_video_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, guint timestamp)
{
@@ -297,6 +333,36 @@ swfdec_flv_decoder_parse_audio_tag (Swfd
}
}
+static void
+swfdec_flv_decoder_parse_data_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, guint timestamp)
+{
+ SwfdecFlvDataTag tag;
+
+ if (flv->data == NULL) {
+ flv->data = g_array_new (FALSE, FALSE, sizeof (SwfdecFlvDataTag));
+ }
+
+ tag.timestamp = timestamp;
+ tag.buffer = swfdec_bits_get_buffer (bits, -1);
+ if (tag.buffer == NULL) {
+ SWFDEC_WARNING ("no buffer, ignoring");
+ return;
+ }
+ if (flv->data->len == 0) {
+ g_array_append_val (flv->data, tag);
+ } else if (g_array_index (flv->data, SwfdecFlvDataTag,
+ flv->data->len - 1).timestamp < tag.timestamp) {
+ g_array_append_val (flv->data, tag);
+ } else {
+ guint idx;
+ SWFDEC_WARNING ("timestamps of data buffers not increasing (last was %u, now %u)",
+ g_array_index (flv->data, SwfdecFlvDataTag, flv->data->len - 1).timestamp,
+ tag.timestamp);
+ idx = swfdec_flv_decoder_find_data (flv, tag.timestamp);
+ g_array_insert_val (flv->data, idx, tag);
+ }
+}
+
static SwfdecStatus
swfdec_flv_decoder_parse_tag (SwfdecFlvDecoder *flv)
{
@@ -334,6 +400,9 @@ swfdec_flv_decoder_parse_tag (SwfdecFlvD
case 9:
ret = swfdec_flv_decoder_parse_video_tag (flv, &bits, timestamp);
break;
+ case 18:
+ swfdec_flv_decoder_parse_data_tag (flv, &bits, timestamp);
+ break;
default:
SWFDEC_WARNING ("unknown tag (type %u)", type);
break;
@@ -492,6 +561,43 @@ swfdec_flv_decoder_get_audio (SwfdecFlvD
return tag->buffer;
}
+/**
+ * swfdec_flv_decoder_get_data:
+ * @flv: a #SwfdecFlvDecoder
+ * @timestamp: timestamp to look for
+ * @real_timestamp: the timestamp of the returned buffer, if any
+ *
+ * Finds the next data event with a timestamp of at least @timestamp. If one
+ * exists, it is returned, and its real timestamp put into @real_timestamp.
+ * Otherwise, %NULL is returned.
+ *
+ * Returns: a #SwfdecBuffer containing the next data or NULL if none
+ **/
+SwfdecBuffer *
+swfdec_flv_decoder_get_data (SwfdecFlvDecoder *flv, guint timestamp, guint *real_timestamp)
+{
+ guint id;
+ SwfdecFlvDataTag *tag;
+
+ g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), NULL);
+
+ if (flv->data == NULL ||
+ flv->data->len == 0)
+ return NULL;
+
+ id = swfdec_flv_decoder_find_data (flv, timestamp);
+ tag = &g_array_index (flv->data, SwfdecFlvDataTag, id);
+ while (tag->timestamp < timestamp) {
+ id++;
+ if (id >= flv->data->len)
+ return NULL;
+ tag++;
+ }
+ if (real_timestamp)
+ *real_timestamp = tag->timestamp;
+ return tag->buffer;
+}
+
/*** HACK ***/
/* This is a hack to allow native FLV playback IN SwfdecPlayer */
diff --git a/libswfdec/swfdec_flv_decoder.h b/libswfdec/swfdec_flv_decoder.h
index 9163058..7bb9c72 100644
--- a/libswfdec/swfdec_flv_decoder.h
+++ b/libswfdec/swfdec_flv_decoder.h
@@ -44,6 +44,7 @@ struct _SwfdecFlvDecoder
int state; /* parsing state we're in */
GArray * audio; /* audio tags */
GArray * video; /* video tags */
+ GArray * data; /* data tags (if any) */
};
struct _SwfdecFlvDecoderClass {
@@ -71,6 +72,9 @@ SwfdecBuffer * swfdec_flv_decoder_get_au
SwfdecAudioOut * format,
guint * real_timestamp,
guint * next_timestamp);
+SwfdecBuffer * swfdec_flv_decoder_get_data (SwfdecFlvDecoder * flv,
+ guint timestamp,
+ guint * real_timestamp);
SwfdecMovie * swfdec_flv_decoder_add_movie (SwfdecFlvDecoder * flv,
SwfdecMovie * parent);
More information about the Swfdec
mailing list