[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