[Swfdec] Branch 'as' - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_player.c

Benjamin Otte company at kemper.freedesktop.org
Sun May 20 12:49:21 PDT 2007


 libswfdec/swfdec_as_context.c   |   25 +++++++++++++++++++++++++
 libswfdec/swfdec_as_context.h   |    8 +++++++-
 libswfdec/swfdec_as_interpret.c |   21 +++++++++++++--------
 libswfdec/swfdec_player.c       |   10 ++++++++++
 4 files changed, 55 insertions(+), 9 deletions(-)

New commits:
diff-tree 210bee663edb435f5f15cd5e8e9649faecd982d9 (from 91444350cb32843ed2aa0ea386df0ba983a7aec6)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun May 20 21:51:40 2007 +0200

    implement GetTime and functionality to get the "current" time
    
    I want to be able to overwrite g_get_current_time() on a  per-player basis to
    allow stuff such as faster or slower playback. So the context has a vfunc for
    getting the time.

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 9f07f55..1bca426 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -316,6 +316,7 @@ swfdec_as_context_init (SwfdecAsContext 
   g_assert (*s == 0);
   context->global = swfdec_as_object_new (context);
   context->rand = g_rand_new ();
+  g_get_current_time (&context->start_time);
 }
 
 /*** STRINGS ***/
@@ -359,6 +360,30 @@ swfdec_as_context_new (void)
   return g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL);
 }
 
+/**
+ * swfdec_as_context_get_time:
+ * @context: a #SwfdecAsContext
+ * @tv: a #GTimeVal to be set to the context's time
+ *
+ * This function queries the time to be used inside this context. By default,
+ * this is the same as g_get_current_time(), but it may be overwriten to allow
+ * things such as slower or faster playback.
+ **/
+void
+swfdec_as_context_get_time (SwfdecAsContext *context, GTimeVal *tv)
+{
+  SwfdecAsContextClass *klass;
+
+  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+  g_return_if_fail (tv != NULL);
+
+  klass = SWFDEC_AS_CONTEXT_GET_CLASS (context);
+  if (klass->get_time)
+    klass->get_time (context, tv);
+  else
+    g_get_current_time (tv);
+}
+
 void
 swfdec_as_context_run (SwfdecAsContext *context)
 {
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index a7b0312..88c6c6f 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -50,6 +50,7 @@ struct _SwfdecAsContext {
   SwfdecAsContextState	state;		/* our current state */
   SwfdecAsObject *	global;		/* the global object */
   GRand *		rand;		/* random number generator */
+  GTimeVal		start_time;   	/* time this movie started (for GetTime action) */
 
   /* bookkeeping for GC */
   gsize			memory;		/* memory currently in use */
@@ -75,8 +76,11 @@ struct _SwfdecAsContextClass {
 
   /* mark all objects that should not be collected */
   void			(* mark)		(SwfdecAsContext *	context);
-  /* call this function before executing a bytecode if non-NULL */
+  /* debugging: call this function before executing a bytecode if non-NULL */
   void			(* step)		(SwfdecAsContext *	context);
+  /* overwrite if you want to report a different time than gettimeofday */
+  void			(* get_time)		(SwfdecAsContext *      context,
+						 GTimeVal *		tv);
 };
 
 GType		swfdec_as_context_get_type	(void);
@@ -85,6 +89,8 @@ SwfdecAsContext *swfdec_as_context_new		
 void		swfdec_as_context_startup     	(SwfdecAsContext *	context,
 						 guint			version);
 
+void		swfdec_as_context_get_time	(SwfdecAsContext *	context,
+						 GTimeVal *		tv);
 const char *	swfdec_as_context_get_string	(SwfdecAsContext *	context,
 						 const char *		string);
 
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index acdfb74..886dae6 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1632,16 +1632,23 @@ swfdec_action_type_of (SwfdecAsContext *
   SWFDEC_AS_VALUE_SET_STRING (val, type);
 }
 
-#if 0
 static void
 swfdec_action_get_time (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecPlayer *player = JS_GetContextPrivate (cx);
+  GTimeVal tv;
+  gulong diff;
+
+  swfdec_as_context_get_time (cx, &tv);
+  /* we assume here that swfdec_as_context_get_time always returns a tv > start_time */
+  diff = tv.tv_sec - cx->start_time.tv_sec;
+  if (diff > G_MAXULONG / 1000 - 1) {
+    SWFDEC_ERROR ("FIXME: time overflow");
+  }
+  diff *= 1000;
+  diff = diff + (tv.tv_usec - cx->start_time.tv_usec) / 1000;
 
-  *cx->fp->sp++ = INT_TO_JSVAL ((int) SWFDEC_TICKS_TO_MSECS (player->time));
-  return JS_TRUE;
+  SWFDEC_AS_VALUE_SET_INT (swfdec_as_stack_push (cx->frame->stack), diff);
 }
-#endif
 
 static void
 swfdec_action_extends (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
@@ -2070,9 +2077,7 @@ const SwfdecActionSpec swfdec_as_actions
   [SWFDEC_AS_ACTION_MB_STRING_LENGTH] = { "MBStringLength", NULL },
   [SWFDEC_AS_ACTION_CHAR_TO_ASCII] = { "CharToAscii", NULL },
   [SWFDEC_AS_ACTION_ASCII_TO_CHAR] = { "AsciiToChar", NULL },
-#if 0
-  [0x34] = { "GetTime", NULL, 0, 1, { NULL, swfdec_action_get_time, swfdec_action_get_time, swfdec_action_get_time, swfdec_action_get_time } },
-#endif
+  [SWFDEC_AS_ACTION_GET_TIME] = { "GetTime", NULL, 0, 1, { NULL, swfdec_action_get_time, swfdec_action_get_time, swfdec_action_get_time, swfdec_action_get_time } },
   [SWFDEC_AS_ACTION_MB_STRING_EXTRACT] = { "MBStringExtract", NULL },
   [SWFDEC_AS_ACTION_MB_CHAR_TO_ASCII] = { "MBCharToAscii", NULL },
   [SWFDEC_AS_ACTION_MB_ASCII_TO_CHAR] = { "MBAsciiToChar", NULL },
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 146d304..ec783b7 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -788,6 +788,15 @@ swfdec_player_mark (SwfdecAsContext *con
 }
 
 static void
+swfdec_player_get_time (SwfdecAsContext *context, GTimeVal *tv)
+{
+  *tv = context->start_time;
+
+  /* FIXME: what granularity do we want? Currently it's milliseconds */
+  g_time_val_add (tv, SWFDEC_TICKS_TO_MSECS (SWFDEC_PLAYER (context)->time) * 1000);
+}
+
+static void
 swfdec_player_class_init (SwfdecPlayerClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -897,6 +906,7 @@ swfdec_player_class_init (SwfdecPlayerCl
       G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
 
   context_class->mark = swfdec_player_mark;
+  context_class->get_time = swfdec_player_get_time;
 
   klass->advance = swfdec_player_do_advance;
   klass->handle_mouse = swfdec_player_do_handle_mouse;


More information about the Swfdec mailing list