[Swfdec] 10 commits - libswfdec/swfdec_flv_decoder.c
libswfdec/swfdec_flv_decoder.h libswfdec/swfdec_js_global.c
libswfdec/swfdec_js_movie.c libswfdec/swfdec_js_net_stream.c
libswfdec/swfdec_loader.c libswfdec/swfdec_loader.h
libswfdec/swfdec_loadertarget.c libswfdec/swfdec_net_stream.c
libswfdec/swfdec_net_stream.h test/trace
Benjamin Otte
company at kemper.freedesktop.org
Wed Mar 14 13:12:35 PDT 2007
libswfdec/swfdec_flv_decoder.c | 43 +++++
libswfdec/swfdec_flv_decoder.h | 10 +
libswfdec/swfdec_js_global.c | 2
libswfdec/swfdec_js_movie.c | 3
libswfdec/swfdec_js_net_stream.c | 18 ++
libswfdec/swfdec_loader.c | 44 +++--
libswfdec/swfdec_loader.h | 2
libswfdec/swfdec_loadertarget.c | 8 -
libswfdec/swfdec_net_stream.c | 184 +++++++++++++++++------
libswfdec/swfdec_net_stream.h | 7
test/trace/Makefile.am | 10 +
test/trace/README | 40 +++--
test/trace/netstream-onstatus-notfound.as | 14 +
test/trace/netstream-onstatus-notfound.swf |binary
test/trace/netstream-onstatus-notfound.swf.trace | 6
test/trace/netstream-onstatus.c | 44 +++++
test/trace/netstream-onstatus.swf |binary
test/trace/netstream-onstatus.swf.trace | 12 +
test/trace/setinterval-arguments.as | 4
test/trace/setinterval-arguments.swf |binary
test/trace/setinterval-arguments.swf.trace | 4
test/trace/trace.c | 15 +
test/trace/video.flv |binary
23 files changed, 383 insertions(+), 87 deletions(-)
New commits:
diff-tree dedf24e3a36c463b0fa40d83e5b80ff36024baa3 (from 10dd6dc219da2fa309574ecc7e8cbf266aa1433b)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 20:35:37 2007 +0100
update the README to include information about source files
diff --git a/test/trace/README b/test/trace/README
index f6ae935..730ec0c 100644
--- a/test/trace/README
+++ b/test/trace/README
@@ -14,6 +14,23 @@ written to a file named "tmp". The retur
failure if at least one test failed.
+What are all the other files?
+
+Some test files are created with Open Source tools. In that case, the sources
+used for creating them are included and named $FILE.$TOOL-EXTENSION. Every
+one of those files includes the command that were used for creating the test
+files.
+
+
+Why don't you autogenerate the SWF files from sources but include them?
+
+An important thing to note is that this testsuite is supposed to test the
+correct handling of SWF files, so the reference file must be an SWF file. Since
+Open Source tools could produce different SWF files depending on version, we
+the testsuite could end up testing different files. This is something that is
+definitely not wanted. Consider the source files annotations only.
+
+
How do I run my new test?
Create a file to test, say "test.swf", and put the expected output in the
@@ -33,7 +50,8 @@ Unfortunately this requires access to th
How do I add a test to the testsuite?
-Just put the file and its trace file into this directory and add both to
-EXTRA_DIST in Makefile.am. It should appear in the output when running
-make check. (Note that the order of files tested during make check is pretty
-much random.)
+Just put the file, its trace file and if you have them, source files used for
+creating the file into this directory and add all of them to EXTRA_DIST in
+Makefile.am. The file should appear in the output when running make check.
+(Note that the order of files tested during make check is pretty much random.)
+
diff-tree 10dd6dc219da2fa309574ecc7e8cbf266aa1433b (from 2f64500b40e8735c34ff65811ff8661f59621a22)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 20:27:13 2007 +0100
add 2 tests for onStatus messages
This includes a video only FLV file for use in tests including video.
Please reuse it.
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 3b50bae..20e4684 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -113,6 +113,12 @@ EXTRA_DIST = \
names.swf.trace \
netconnection.swf \
netconnection.swf.trace \
+ netstream-onstatus.c \
+ netstream-onstatus.swf \
+ netstream-onstatus.trace \
+ netstream-onstatus-notfound.as \
+ netstream-onstatus-notfound.swf \
+ netstream-onstatus-notfound.swf.trace \
number.swf \
number.swf.trace \
object-math-5.swf \
@@ -161,6 +167,7 @@ EXTRA_DIST = \
undefined2-6.swf.trace \
undefined2-7.swf \
undefined2-7.swf.trace \
+ video.flv \
xscale.swf \
xscale.swf.trace
diff --git a/test/trace/netstream-onstatus-notfound.as b/test/trace/netstream-onstatus-notfound.as
new file mode 100644
index 0000000..1cd5983
--- /dev/null
+++ b/test/trace/netstream-onstatus-notfound.as
@@ -0,0 +1,14 @@
+// makeswf -v 7 -s 200x150 -r 1 -o netstream-onstatus-notfound.swf netstream-onstatus-notfound.as
+
+trace ("Test onStatus emission for nonexisting movies");
+nc = new NetConnection ();
+nc.connect (null);
+ns = new NetStream (nc);
+ns.onStatus = function (info) {
+ trace ("NetStream onStatus called");
+ trace (info.code);
+ trace (info.level);
+};
+trace ("Calling play");
+ns.play ("doesnotexist.flv");
+trace ("done calling play");
diff --git a/test/trace/netstream-onstatus-notfound.swf b/test/trace/netstream-onstatus-notfound.swf
new file mode 100644
index 0000000..ecdd844
Binary files /dev/null and b/test/trace/netstream-onstatus-notfound.swf differ
diff --git a/test/trace/netstream-onstatus-notfound.swf.trace b/test/trace/netstream-onstatus-notfound.swf.trace
new file mode 100644
index 0000000..d24b102
--- /dev/null
+++ b/test/trace/netstream-onstatus-notfound.swf.trace
@@ -0,0 +1,6 @@
+Test onStatus emission for nonexisting movies
+Calling play
+done calling play
+NetStream onStatus called
+NetStream.Play.StreamNotFound
+error
diff --git a/test/trace/netstream-onstatus.c b/test/trace/netstream-onstatus.c
new file mode 100644
index 0000000..37c4ad5
--- /dev/null
+++ b/test/trace/netstream-onstatus.c
@@ -0,0 +1,44 @@
+/* gcc `pkg-config --libs --cflags libming` netstream-onstatus.c -o netstream-onstatus && ./netstream-onstatus
+ */
+
+#include <ming.h>
+
+int
+main (int argc, char **argv)
+{
+ SWFMovie movie;
+ SWFVideoStream video;
+ SWFDisplayItem item;
+ SWFAction action;
+
+ if (Ming_init ())
+ return 1;
+ Ming_useSWFVersion (7);
+
+ movie = newSWFMovie();
+ SWFMovie_setRate (movie, 1);
+ SWFMovie_setDimension (movie, 200, 150);
+ video = newSWFVideoStream ();
+ SWFVideoStream_setDimension (video, 200, 150);
+ item = SWFMovie_add (movie, (SWFBlock) video);
+ SWFDisplayItem_setName (item, "video");
+ action = compileSWFActionCode (""
+ "trace (\"Test what onStatus messages exist in an average movie.\");"
+ "nc = new NetConnection ();"
+ "nc.connect (null);"
+ "ns = new NetStream (nc);"
+ "ns.onStatus = function (info) {"
+ " trace (\"NetStream onStatus called\");"
+ " trace (info.code);"
+ " trace (info.level);"
+ "};"
+ "video.attachVideo (ns);"
+ "ns.setBufferTime (5);"
+ "trace (\"Calling play\");"
+ "ns.play (\"video.flv\");"
+ "trace (\"done calling play\");"
+ "");
+ SWFMovie_add (movie, (SWFBlock) action);
+ SWFMovie_save (movie, "netstream-onstatus.swf");
+ return 0;
+}
diff --git a/test/trace/netstream-onstatus.swf b/test/trace/netstream-onstatus.swf
new file mode 100644
index 0000000..dc9e39a
Binary files /dev/null and b/test/trace/netstream-onstatus.swf differ
diff --git a/test/trace/netstream-onstatus.swf.trace b/test/trace/netstream-onstatus.swf.trace
new file mode 100644
index 0000000..c343359
--- /dev/null
+++ b/test/trace/netstream-onstatus.swf.trace
@@ -0,0 +1,12 @@
+Test what onStatus messages exist in an average movie.
+Calling play
+done calling play
+NetStream onStatus called
+NetStream.Play.Start
+status
+NetStream onStatus called
+NetStream.Buffer.Flush
+status
+NetStream onStatus called
+NetStream.Play.Stop
+status
diff --git a/test/trace/video.flv b/test/trace/video.flv
new file mode 100644
index 0000000..7ce58aa
Binary files /dev/null and b/test/trace/video.flv differ
diff-tree 2f64500b40e8735c34ff65811ff8661f59621a22 (from ae8e75b794793b72bc11ab4da2212eed26473618)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 20:22:22 2007 +0100
implement NetStream.setBufferTime
diff --git a/libswfdec/swfdec_js_net_stream.c b/libswfdec/swfdec_js_net_stream.c
index f92634c..46cb1dc 100644
--- a/libswfdec/swfdec_js_net_stream.c
+++ b/libswfdec/swfdec_js_net_stream.c
@@ -43,8 +43,24 @@ swfdec_js_net_stream_play (JSContext *cx
return JS_TRUE;
}
+static JSBool
+swfdec_js_net_stream_set_buffer_time (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ SwfdecNetStream *stream;
+ double d;
+
+ stream = swfdec_scriptable_from_object (cx, obj, SWFDEC_TYPE_NET_STREAM);
+ if (stream == NULL)
+ return JS_TRUE;
+ if (!JS_ValueToNumber (cx, argv[0], &d))
+ return JS_FALSE;
+ swfdec_net_stream_set_buffer_time (stream, d);
+ return JS_TRUE;
+}
+
static JSFunctionSpec net_stream_methods[] = {
- { "play", swfdec_js_net_stream_play, 1, 0, 0 },
+ { "play", swfdec_js_net_stream_play, 1, 0, 0 },
+ { "setBufferTime", swfdec_js_net_stream_set_buffer_time, 1, 0, 0 },
{0,0,0,0,0}
};
diff-tree ae8e75b794793b72bc11ab4da2212eed26473618 (from 06365380f68f96b17964c770cdca0600932b0805)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 20:21:27 2007 +0100
implement onStatus events
includes quite a bit of refactoring in SwfdecNetStream and buffer time support
diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index da311d4..530915d 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -424,6 +424,29 @@ swfdec_flv_decoder_get_video (SwfdecFlvD
return tag->buffer;
}
+gboolean
+swfdec_flv_decoder_get_video_info (SwfdecFlvDecoder *flv,
+ guint *first_timestamp, guint *last_timestamp)
+{
+ g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), FALSE);
+
+ if (flv->video == NULL)
+ return FALSE;
+
+ if (flv->video->len == 0) {
+ if (first_timestamp)
+ *first_timestamp = 0;
+ if (last_timestamp)
+ *last_timestamp = 0;
+ return TRUE;
+ }
+ if (first_timestamp)
+ *first_timestamp = g_array_index (flv->video, SwfdecFlvVideoTag, 0).timestamp;
+ if (last_timestamp)
+ *last_timestamp = g_array_index (flv->video, SwfdecFlvVideoTag, flv->video->len - 1).timestamp;
+ return TRUE;
+}
+
SwfdecBuffer *
swfdec_flv_decoder_get_audio (SwfdecFlvDecoder *flv, guint timestamp,
SwfdecAudioFormat *codec_format, gboolean *width, SwfdecAudioOut *format,
@@ -489,6 +512,22 @@ notify_initialized (SwfdecPlayer *player
swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
}
+gboolean
+swfdec_flv_decoder_is_eof (SwfdecFlvDecoder *flv)
+{
+ g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), TRUE);
+
+ return flv->state == SWFDEC_STATE_EOF;
+}
+
+void
+swfdec_flv_decoder_eof (SwfdecFlvDecoder *flv)
+{
+ g_return_if_fail (SWFDEC_IS_FLV_DECODER (flv));
+
+ flv->state = SWFDEC_STATE_EOF;
+}
+
SwfdecMovie *
swfdec_flv_decoder_add_movie (SwfdecFlvDecoder *flv, SwfdecMovie *parent)
{
@@ -511,10 +550,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);
- if (!swfdec_loader_target_set_decoder (SWFDEC_LOADER_TARGET (stream), SWFDEC_DECODER (flv))) {
- g_assert_not_reached ();
- }
swfdec_video_movie_set_input (SWFDEC_VIDEO_MOVIE (movie), &stream->input);
swfdec_net_stream_set_playing (stream, TRUE);
g_object_unref (conn);
diff --git a/libswfdec/swfdec_flv_decoder.h b/libswfdec/swfdec_flv_decoder.h
index d3c5e0b..9163058 100644
--- a/libswfdec/swfdec_flv_decoder.h
+++ b/libswfdec/swfdec_flv_decoder.h
@@ -52,14 +52,18 @@ struct _SwfdecFlvDecoderClass {
GType swfdec_flv_decoder_get_type (void);
-SwfdecMovie * swfdec_flv_decoder_add_movie (SwfdecFlvDecoder * flv,
- SwfdecMovie * parent);
+gboolean swfdec_flv_decoder_is_eof (SwfdecFlvDecoder * flv);
+void swfdec_flv_decoder_eof (SwfdecFlvDecoder * flv);
+
SwfdecBuffer * swfdec_flv_decoder_get_video (SwfdecFlvDecoder * flv,
guint timestamp,
gboolean keyframe,
SwfdecVideoFormat * format,
guint * real_timestamp,
guint * next_timestamp);
+gboolean swfdec_flv_decoder_get_video_info (SwfdecFlvDecoder * flv,
+ guint * first_timestamp,
+ guint * last_timestamp);
SwfdecBuffer * swfdec_flv_decoder_get_audio (SwfdecFlvDecoder * flv,
guint timestamp,
SwfdecAudioFormat * codec_format,
@@ -68,6 +72,8 @@ SwfdecBuffer * swfdec_flv_decoder_get_au
guint * real_timestamp,
guint * next_timestamp);
+SwfdecMovie * swfdec_flv_decoder_add_movie (SwfdecFlvDecoder * flv,
+ SwfdecMovie * parent);
G_END_DECLS
#endif
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index b524725..32651ad 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -26,8 +26,39 @@
#include "swfdec_debug.h"
#include "swfdec_loader_internal.h"
#include "swfdec_loadertarget.h"
+#include "js/jsapi.h"
static void
+swfdec_net_stream_onstatus (SwfdecNetStream *stream, const char *code, const char *level)
+{
+ jsval val;
+ JSString *string;
+ JSObject *object;
+ JSContext *cx;
+
+ cx = stream->player->jscx;
+ object = JS_NewObject (cx, NULL, NULL, NULL);
+ if (!object)
+ return;
+ string = JS_NewStringCopyZ (cx, code);
+ if (!string)
+ return;
+ val = STRING_TO_JSVAL (string);
+ if (!JS_SetProperty (cx, object, "code", &val))
+ return;
+ string = JS_NewStringCopyZ (cx, level);
+ if (!string)
+ return;
+ val = STRING_TO_JSVAL (string);
+ if (!JS_SetProperty (cx, object, "level", &val))
+ return;
+
+ val = OBJECT_TO_JSVAL (object);
+ swfdec_scriptable_execute (SWFDEC_SCRIPTABLE (stream), "onStatus", 1, &val);
+}
+
+static void swfdec_net_stream_update_playing (SwfdecNetStream *stream);
+static void
swfdec_net_stream_video_goto (SwfdecNetStream *stream, guint timestamp)
{
SwfdecBuffer *buffer;
@@ -76,6 +107,15 @@ swfdec_net_stream_video_goto (SwfdecNetS
}
}
}
+ if (stream->next_time <= stream->current_time) {
+ if (swfdec_flv_decoder_is_eof (stream->flvdecoder)) {
+ swfdec_net_stream_onstatus (stream, "NetStream.Play.Stop", "status");
+ } else {
+ stream->buffering = TRUE;
+ swfdec_net_stream_onstatus (stream, "NetStream.Buffer.Empty", "status");
+ }
+ swfdec_net_stream_update_playing (stream);
+ }
}
static void
@@ -84,13 +124,13 @@ swfdec_net_stream_timeout (SwfdecTimeout
SwfdecNetStream *stream = SWFDEC_NET_STREAM ((guchar *) timeout - G_STRUCT_OFFSET (SwfdecNetStream, timeout));
SWFDEC_LOG ("timeout fired");
+ stream->timeout.callback = NULL;
swfdec_net_stream_video_goto (stream, stream->next_time);
if (stream->next_time > stream->current_time) {
SWFDEC_LOG ("readding timeout");
stream->timeout.timestamp += SWFDEC_MSECS_TO_TICKS (stream->next_time - stream->current_time);
+ stream->timeout.callback = swfdec_net_stream_timeout;
swfdec_player_add_timeout (stream->player, &stream->timeout);
- } else {
- stream->timeout.callback = NULL;
}
}
@@ -100,8 +140,9 @@ swfdec_net_stream_update_playing (Swfdec
gboolean should_play;
should_play = stream->playing;
+ should_play &= !stream->buffering;
should_play &= stream->flvdecoder != NULL;
- should_play &= stream->next_time > stream->current_time;
+ //should_play &= stream->next_time > stream->current_time;
if (should_play && stream->timeout.callback == NULL) {
SWFDEC_DEBUG ("starting playback");
stream->timeout.callback = swfdec_net_stream_timeout;
@@ -135,58 +176,89 @@ swfdec_net_stream_loader_target_get_play
return SWFDEC_NET_STREAM (target)->player;
}
-static SwfdecDecoder *
-swfdec_net_stream_loader_target_get_decoder (SwfdecLoaderTarget *target)
-{
- return SWFDEC_DECODER (SWFDEC_NET_STREAM (target)->flvdecoder);
-}
-
-static gboolean
-swfdec_net_stream_loader_target_set_decoder (SwfdecLoaderTarget *target,
- SwfdecDecoder *decoder)
+static void
+swfdec_net_stream_loader_target_parse (SwfdecLoaderTarget *target,
+ SwfdecLoader *loader)
{
SwfdecNetStream *stream = SWFDEC_NET_STREAM (target);
+ SwfdecDecoderClass *klass;
+ gboolean recheck = FALSE;
+
+ if (loader->error) {
+ if (stream->flvdecoder == NULL)
+ swfdec_net_stream_onstatus (stream, "NetStream.Play.StreamNotFound", "error");
+ return;
+ }
+ if (!loader->eof && swfdec_buffer_queue_get_depth (loader->queue) == 0) {
+ SWFDEC_WARNING ("nothing to parse?!");
+ return;
+ }
+ if (stream->flvdecoder == NULL) {
+ /* FIXME: add mp3 support */
+ stream->flvdecoder = g_object_new (SWFDEC_TYPE_FLV_DECODER, NULL);
+ SWFDEC_DECODER (stream->flvdecoder)->player = stream->player;
+ SWFDEC_DECODER (stream->flvdecoder)->queue = loader->queue;
+ swfdec_net_stream_onstatus (stream, "NetStream.Play.Start", "status");
+ }
+ klass = SWFDEC_DECODER_GET_CLASS (stream->flvdecoder);
+ g_return_if_fail (klass->parse);
- if (!SWFDEC_IS_FLV_DECODER (decoder)) {
- g_object_unref (decoder);
- return FALSE;
+ while (TRUE) {
+ SwfdecStatus status = klass->parse (SWFDEC_DECODER (stream->flvdecoder));
+ switch (status) {
+ case SWFDEC_STATUS_OK:
+ break;
+ case SWFDEC_STATUS_INIT:
+ /* HACK for native flv playback */
+ swfdec_player_initialize (stream->player,
+ SWFDEC_DECODER (stream->flvdecoder)->rate,
+ SWFDEC_DECODER (stream->flvdecoder)->width,
+ SWFDEC_DECODER (stream->flvdecoder)->height);
+ case SWFDEC_STATUS_IMAGE:
+ recheck = TRUE;
+ break;
+ case SWFDEC_STATUS_ERROR:
+ case SWFDEC_STATUS_NEEDBITS:
+ goto out;
+ case SWFDEC_STATUS_EOF:
+ /* the flv decoder never emits this */
+ default:
+ g_assert_not_reached ();
+ return;
+ }
+ }
+out:
+ if (loader->eof) {
+ swfdec_flv_decoder_eof (stream->flvdecoder);
+ recheck = TRUE;
+ swfdec_net_stream_onstatus (stream, "NetStream.Buffer.Flush", "status");
+ swfdec_net_stream_video_goto (stream, stream->current_time);
+ stream->buffering = FALSE;
+ }
+ 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, "NetStream.Buffer.Full", "status");
+ }
+ } else {
+ SWFDEC_ERROR ("no video stream, how do we update buffering?");
+ }
+ }
+ swfdec_net_stream_update_playing (stream);
}
- stream->flvdecoder = SWFDEC_FLV_DECODER (decoder);
- swfdec_net_stream_update_playing (stream);
- return TRUE;
}
-static gboolean
-swfdec_net_stream_loader_target_image (SwfdecLoaderTarget *target)
-{
- SwfdecNetStream *stream = SWFDEC_NET_STREAM (target);
- guint current, next;
- SwfdecBuffer *buffer;
- SwfdecVideoFormat format;
-
- if (!stream->playing)
- return TRUE;
-
- buffer = swfdec_flv_decoder_get_video (stream->flvdecoder,
- stream->current_time, FALSE, &format, ¤t, &next);
- if (format != stream->format ||
- stream->current_time != current ||
- stream->next_time != next)
- swfdec_net_stream_video_goto (stream, current);
- swfdec_net_stream_update_playing (stream);
-
- return TRUE;
-}
static void
swfdec_net_stream_loader_target_init (SwfdecLoaderTargetInterface *iface)
{
iface->get_player = swfdec_net_stream_loader_target_get_player;
- iface->get_decoder = swfdec_net_stream_loader_target_get_decoder;
- iface->set_decoder = swfdec_net_stream_loader_target_set_decoder;
-
- iface->init = swfdec_net_stream_loader_target_image;
- iface->image = swfdec_net_stream_loader_target_image;
+ iface->parse = swfdec_net_stream_loader_target_parse;
}
/*** SWFDEC VIDEO MOVIE INPUT ***/
@@ -251,6 +323,8 @@ swfdec_net_stream_init (SwfdecNetStream
{
stream->input.connect = swfdec_net_stream_input_connect;
stream->input.disconnect = swfdec_net_stream_input_disconnect;
+
+ stream->buffer_time = 100; /* msecs */
}
SwfdecNetStream *
@@ -264,6 +338,7 @@ swfdec_net_stream_new (SwfdecPlayer *pla
stream = g_object_new (SWFDEC_TYPE_NET_STREAM, NULL);
stream->player = player;
stream->conn = conn;
+ SWFDEC_SCRIPTABLE (stream)->jscx = player->jscx;
g_object_ref (conn);
return stream;
@@ -295,6 +370,7 @@ swfdec_net_stream_set_loader (SwfdecNetS
stream->flvdecoder = NULL;
}
stream->loader = loader;
+ stream->buffering = TRUE;
if (loader) {
g_object_ref (loader);
swfdec_loader_set_target (loader, SWFDEC_LOADER_TARGET (stream));
@@ -321,3 +397,23 @@ swfdec_net_stream_get_playing (SwfdecNet
return stream->playing;
}
+void
+swfdec_net_stream_set_buffer_time (SwfdecNetStream *stream, double secs)
+{
+ g_return_if_fail (SWFDEC_IS_NET_STREAM (stream));
+
+ /* FIXME: is this correct? */
+ if (secs <= 0)
+ return;
+
+ stream->buffer_time = secs * 1000;
+}
+
+double
+swfdec_net_stream_get_buffer_time (SwfdecNetStream *stream)
+{
+ g_return_val_if_fail (SWFDEC_IS_NET_STREAM (stream), 0.1);
+
+ return (double) stream->buffer_time / 1000.0;
+}
+
diff --git a/libswfdec/swfdec_net_stream.h b/libswfdec/swfdec_net_stream.h
index ce22330..c36c45a 100644
--- a/libswfdec/swfdec_net_stream.h
+++ b/libswfdec/swfdec_net_stream.h
@@ -48,8 +48,12 @@ struct _SwfdecNetStream
SwfdecLoader * loader; /* input stream */
SwfdecFlvDecoder * flvdecoder; /* flv decoder */
gboolean playing; /* TRUE if this stream is playing */
+ gboolean buffering; /* TRUE if we're waiting for more input data */
gboolean error; /* in error */
+ /* properties */
+ guint buffer_time; /* buffering time in msecs */
+
/* video decoding */
guint current_time; /* current playback timestamp */
guint next_time; /* next video image at this timestamp */
@@ -82,6 +86,9 @@ void swfdec_net_stream_set_loader (Swf
void swfdec_net_stream_set_playing (SwfdecNetStream * stream,
gboolean playing);
gboolean swfdec_net_stream_get_playing (SwfdecNetStream * stream);
+void swfdec_net_stream_set_buffer_time (SwfdecNetStream * stream,
+ double secs);
+double swfdec_net_stream_get_buffer_time (SwfdecNetStream * stream);
G_END_DECLS
diff-tree 06365380f68f96b17964c770cdca0600932b0805 (from db754a85ebcee98643d8d4d40998d759bdb7b01a)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 19:42:27 2007 +0100
Fix crash when setInterval is used with arguments
diff --git a/libswfdec/swfdec_js_global.c b/libswfdec/swfdec_js_global.c
index bab231a..02e9a55 100644
--- a/libswfdec/swfdec_js_global.c
+++ b/libswfdec/swfdec_js_global.c
@@ -139,7 +139,7 @@ swfdec_js_global_setInterval (JSContext
interval->msecs = msecs;
interval->vals[0] = fun;
interval->vals[1] = OBJECT_TO_JSVAL (object);
- memcpy (&interval->vals[2], &argv[first_arg], n_args);
+ memcpy (&interval->vals[2], &argv[first_arg], n_args * sizeof (jsval));
for (i = 0; i < n_args + 2; i++) {
if (!JS_AddRoot (cx, &interval->vals[i])) {
/* FIXME: is it save roots that weren't added before? */
diff-tree db754a85ebcee98643d8d4d40998d759bdb7b01a (from be5455d2287e0d4c7b6ee2770ce72b3022a840c6)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 19:40:19 2007 +0100
add currently crashing test
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index ed2582f..3b50bae 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -141,6 +141,9 @@ EXTRA_DIST = \
setinterval.swf.trace
setinterval2.swf \
setinterval2.swf.trace \
+ setinterval-arguments.as \
+ setinterval-arguments.swf \
+ setinterval-arguments.swf.trace \
setinterval-clear.swf \
setinterval-clear.swf.trace \
setvariable.swf \
diff --git a/test/trace/setinterval-arguments.as b/test/trace/setinterval-arguments.as
new file mode 100644
index 0000000..7d88ef1
--- /dev/null
+++ b/test/trace/setinterval-arguments.as
@@ -0,0 +1,4 @@
+// makeswf -v 7 -s 200x150 -r 1 -o setinterval-arguments.swf setinterval-arguments.as
+
+trace ("Check arguments to setInterval work");
+setInterval (function (a, b, c) { trace (a); trace (b); trace (c); }, 7000, 1, 42, "hi");
diff --git a/test/trace/setinterval-arguments.swf b/test/trace/setinterval-arguments.swf
new file mode 100644
index 0000000..2ba1086
Binary files /dev/null and b/test/trace/setinterval-arguments.swf differ
diff --git a/test/trace/setinterval-arguments.swf.trace b/test/trace/setinterval-arguments.swf.trace
new file mode 100644
index 0000000..827154e
--- /dev/null
+++ b/test/trace/setinterval-arguments.swf.trace
@@ -0,0 +1,4 @@
+Check arguments to setInterval work
+1
+42
+hi
diff-tree be5455d2287e0d4c7b6ee2770ce72b3022a840c6 (from 97490d426827b5adbb2205f904c83f51ab836223)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 17:14:54 2007 +0100
use the movie's JSClass
this makes Video::attachVideo work again
diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index e0f3f54..1504e3d 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -1248,7 +1248,8 @@ swfdec_js_movie_create_jsobject (SwfdecM
(fun = swfdec_js_movie_lookup_class (SWFDEC_SPRITE_MOVIE (movie))) != JSVAL_NULL) {
swfdec_js_construct_object (script->jscx, &movieclip_class, fun, &script->jsobj);
} else {
- script->jsobj = JS_NewObject (script->jscx, &movieclip_class,
+ SwfdecScriptableClass *klass = SWFDEC_SCRIPTABLE_GET_CLASS (movie);
+ script->jsobj = JS_NewObject (script->jscx, klass->jsclass,
NULL, NULL);
}
if (!script->jsobj ||
diff-tree 97490d426827b5adbb2205f904c83f51ab836223 (from 318f367d0a5fe8efaff7861b06baaaebbc9dd7db)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 15:46:20 2007 +0100
change sematics of trace test slightly
Instead of advancing 10 times, the movie advances until 10 / rate seconds have passed.
No test needs to be changed for this.
diff --git a/test/trace/README b/test/trace/README
index 1593365..f6ae935 100644
--- a/test/trace/README
+++ b/test/trace/README
@@ -5,13 +5,13 @@ How does it work?
./trace [FILE1 [FILE2 [...]]]
The program trace in this directory takes all files on the command line or all
files in the current directory and runs them. Running consists of instancing a
-SwfdecPlayer and iterating $FILE 10 times. Everytime the trace function is
-invoked by that player, its output is appended to a buffer. After this the
-captured output is compared to the file $FILE.trace. If the output matches, the
-test succeeded for the given file, otherwise it failed. In this case a diff is
-produced and dumped to stdout. The captured trace output is written to a file
-named "tmp". The return value is 0 if all tests passed, or failure if at least
-one test failed.
+SwfdecPlayer and iterating $FILE until 10 frames have passed. Everytime the
+trace function is invoked by that player, its output is appended to a buffer.
+Finally the captured output is compared to the file $FILE.trace. If the output
+matches, the test succeeded for the given file, otherwise it failed. In this
+case a diff is produced and dumped to stdout. The captured trace output is
+written to a file named "tmp". The return value is 0 if all tests passed, or
+failure if at least one test failed.
How do I run my new test?
diff --git a/test/trace/trace.c b/test/trace/trace.c
index d2fee65..9a5a841 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -1,6 +1,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <math.h>
#include <string.h>
#include <libswfdec/swfdec.h>
@@ -16,7 +17,7 @@ run_test (const char *filename)
SwfdecLoader *loader;
SwfdecPlayer *player;
SwfdecBuffer *buffer;
- guint i;
+ guint time_left;
GError *error = NULL;
char *str;
GString *string;
@@ -31,12 +32,22 @@ run_test (const char *filename)
player = swfdec_player_new ();
g_signal_connect (player, "trace", G_CALLBACK (trace_cb), string);
swfdec_player_set_loader (player, loader);
+ if (!swfdec_player_is_initialized (player)) {
+ g_print (" ERROR: player is not initialized\n");
+ g_object_unref (player);
+ return FALSE;
+ }
+ time_left = ceil (10000 / swfdec_player_get_rate (player));
/* FIXME: Make the number of iterations configurable? */
- for (i = 0; i < 10; i++) {
+ while (TRUE) {
/* FIXME: will not do 10 iterations if there's other stuff loaded */
guint advance = swfdec_player_get_next_event (player);
+
+ if (advance > time_left)
+ break;
swfdec_player_advance (player, advance);
+ time_left -= advance;
}
g_signal_handlers_disconnect_by_func (player, trace_cb, string);
g_object_unref (player);
diff-tree 318f367d0a5fe8efaff7861b06baaaebbc9dd7db (from cfd5a7fd62cf9b2ccb30338e1ce22da5e6a04840)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 14:48:30 2007 +0100
Don't return immediately in swfdec_loader_target_parse if the loader is in error
Also update the hack for native FLV loading to call swfdec_loader_target_parse
when the loader changed instead of just cninuing. This allows different parse
functions in different targets.
diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c
index 3212fc8..40ad26f 100644
--- a/libswfdec/swfdec_loadertarget.c
+++ b/libswfdec/swfdec_loadertarget.c
@@ -97,7 +97,11 @@ swfdec_loader_target_parse_default (Swfd
swfdec_loader_error_locked (loader, "Internal error");
return;
}
- target = loader->target;
+ /* HACK for flv playback */
+ if (target != loader->target) {
+ swfdec_loader_target_parse (loader->target, loader);
+ return;
+ }
}
klass = SWFDEC_DECODER_GET_CLASS (dec);
g_return_if_fail (klass->parse);
@@ -150,8 +154,6 @@ swfdec_loader_target_parse (SwfdecLoader
SWFDEC_LOG ("parsing %p%s%s", loader,
loader->error ? " ERROR" : "", loader->eof ? " EOF" : "");
- if (loader->error)
- return;
iface = SWFDEC_LOADER_TARGET_GET_INTERFACE (target);
if (iface->parse == NULL) {
diff-tree cfd5a7fd62cf9b2ccb30338e1ce22da5e6a04840 (from 467707141d1d5daa08fe9ebff8bcdfb7ed0abac1)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 14 14:47:00 2007 +0100
change the way swfdec_loader_load works.
swfdec_loader_load now always returns a loader. If there was an error creating
the loader, the loader will have been put in the error state on creation.
diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index 22f418b..4334562 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -191,17 +191,16 @@ swfdec_file_loader_load (SwfdecLoader *l
/* FIXME: need to rework seperators on windows? */
real_path = g_build_filename (SWFDEC_FILE_LOADER (loader)->dir, url, NULL);
buffer = swfdec_buffer_new_from_file (real_path, &error);
- if (buffer == NULL) {
- SWFDEC_ERROR ("Couldn't load \"%s\": %s", real_path, error->message);
- g_free (real_path);
- g_error_free (error);
- return NULL;
- }
ret = g_object_new (SWFDEC_TYPE_FILE_LOADER, NULL);
ret->url = real_path;
SWFDEC_FILE_LOADER (ret)->dir = g_strdup (SWFDEC_FILE_LOADER (loader)->dir);
- swfdec_loader_push (ret, buffer);
- swfdec_loader_eof (ret);
+ if (buffer == NULL) {
+ swfdec_loader_error (ret, error->message);
+ g_error_free (error);
+ } else {
+ swfdec_loader_push (ret, buffer);
+ swfdec_loader_eof (ret);
+ }
return ret;
}
@@ -227,6 +226,7 @@ swfdec_file_loader_init (SwfdecFileLoade
SwfdecLoader *
swfdec_loader_load (SwfdecLoader *loader, const char *url)
{
+ SwfdecLoader *ret;
SwfdecLoaderClass *klass;
g_return_val_if_fail (SWFDEC_IS_LOADER (loader), NULL);
@@ -234,7 +234,9 @@ swfdec_loader_load (SwfdecLoader *loader
klass = SWFDEC_LOADER_GET_CLASS (loader);
g_return_val_if_fail (klass->load != NULL, NULL);
- return klass->load (loader, url);
+ ret = klass->load (loader, url);
+ g_assert (ret != NULL);
+ return ret;
}
void
@@ -321,15 +323,20 @@ swfdec_loader_error (SwfdecLoader *loade
g_return_if_fail (SWFDEC_IS_LOADER (loader));
g_return_if_fail (error != NULL);
- SWFDEC_ERROR ("error in loader %p: %s", loader, error);
- if (loader->error)
+ if (loader->error) {
+ SWFDEC_ERROR ("another error in loader %p: %s", loader, error);
return;
+ }
- player = swfdec_loader_target_get_player (loader->target);
- swfdec_player_lock (player);
- swfdec_loader_error_locked (loader, error);
- swfdec_player_perform_actions (player);
- swfdec_player_unlock (player);
+ if (loader->target) {
+ player = swfdec_loader_target_get_player (loader->target);
+ swfdec_player_lock (player);
+ swfdec_loader_error_locked (loader, error);
+ swfdec_player_perform_actions (player);
+ swfdec_player_unlock (player);
+ } else {
+ swfdec_loader_error_locked (loader, error);
+ }
}
void
@@ -338,10 +345,11 @@ swfdec_loader_error_locked (SwfdecLoader
if (loader->error)
return;
- SWFDEC_ERROR ("error in loader %p: %s", loader, error);
+ SWFDEC_WARNING ("error in %s %p: %s", G_OBJECT_TYPE_NAME (loader), loader, error);
loader->error = g_strdup (error);
g_object_notify (G_OBJECT (loader), "error");
- swfdec_loader_target_parse (loader->target, loader);
+ if (loader->target)
+ swfdec_loader_target_parse (loader->target, loader);
}
void
diff --git a/libswfdec/swfdec_loader.h b/libswfdec/swfdec_loader.h
index 87153b4..c6bc678 100644
--- a/libswfdec/swfdec_loader.h
+++ b/libswfdec/swfdec_loader.h
@@ -52,7 +52,7 @@ struct _SwfdecLoaderClass
{
GObjectClass object_class;
- /* FIXME: better error reporting? */
+ /* loads the given URL. Must return a loader, the loader can be in the error state */
SwfdecLoader * (* load) (SwfdecLoader * loader,
const char * url);
};
More information about the Swfdec
mailing list