[Swfdec] 3 commits - libswfdec/Makefile.am libswfdec/swfdec_amf.c libswfdec/swfdec_amf.h libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_net_stream.c

Benjamin Otte company at kemper.freedesktop.org
Tue Mar 20 05:58:56 PDT 2007


 libswfdec/Makefile.am         |    2 
 libswfdec/swfdec_amf.c        |  230 ++++++++++++++++++++++++++++++++++++++++++
 libswfdec/swfdec_amf.h        |   59 ++++++++++
 libswfdec/swfdec_bits.c       |   22 ++++
 libswfdec/swfdec_bits.h       |    1 
 libswfdec/swfdec_net_stream.c |   24 ++++
 6 files changed, 338 insertions(+)

New commits:
diff-tree 82bed9c9883df0ea0d012b8c59a8d4986175c671 (from 6e035c9fca2f71563f5fc1a4561fedaa04600f3f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Mar 20 13:58:19 2007 +0100

    handle data tags by calling a function on the NEtStream object using the AMF-decoded data.

diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index b722095..e9b251a 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "swfdec_net_stream.h"
+#include "swfdec_amf.h"
 #include "swfdec_audio_flv.h"
 #include "swfdec_debug.h"
 #include "swfdec_loader_internal.h"
@@ -65,8 +66,12 @@ swfdec_net_stream_video_goto (SwfdecNetS
   SwfdecBuffer *buffer;
   SwfdecVideoFormat format;
   cairo_surface_t *old;
+  gboolean process_events;
+  guint process_events_from;
 
   SWFDEC_LOG ("goto %ums", timestamp);
+  process_events = timestamp == stream->next_time;
+  process_events_from = MIN (stream->next_time, stream->current_time + 1);
   buffer = swfdec_flv_decoder_get_video (stream->flvdecoder, timestamp,
       FALSE, &format, &stream->current_time, &stream->next_time);
   old = stream->surface;
@@ -117,6 +122,25 @@ swfdec_net_stream_video_goto (SwfdecNetS
     }
     swfdec_net_stream_update_playing (stream);
   }
+  if (process_events) {
+    while (process_events_from <= stream->current_time) {
+      jsval name, value;
+      SwfdecBits bits;
+      SwfdecBuffer *event = swfdec_flv_decoder_get_data (stream->flvdecoder, process_events_from, &process_events_from);
+      if (!event)
+	break;
+      SWFDEC_LOG ("processing event from timestamp %u", process_events_from);
+      process_events_from++; /* increase so we get the next event next time */
+      swfdec_bits_init (&bits, event);
+      if (swfdec_amf_parse (SWFDEC_SCRIPTABLE (stream)->jscx, &bits, 2, 
+	    SWFDEC_AMF_STRING, &name, SWFDEC_AMF_MIXED_ARRAY, &value) != 2) {
+	SWFDEC_ERROR ("could not parse data tag");
+      } else {
+	swfdec_scriptable_execute (SWFDEC_SCRIPTABLE (stream), 
+	    JS_GetStringBytes (JSVAL_TO_STRING (name)), 1, &value);
+      }
+    }
+  }
 }
 
 static void
diff-tree 6e035c9fca2f71563f5fc1a4561fedaa04600f3f (from e4e0c60341b918ffb5637502afd157cd2bfbd366)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Mar 20 13:57:42 2007 +0100

    add initial support for handling AMF encoded data

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index ecd16aa..1270262 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -16,6 +16,7 @@ lib_LTLIBRARIES = libswfdec- at SWFDEC_MAJO
 js_cflags = -I$(srcdir)/js/ -I./js -DXP_UNIX -DDEBUG
 
 libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES = \
+	swfdec_amf.c \
 	swfdec_audio.c \
 	swfdec_audio_event.c \
 	swfdec_audio_flv.c \
@@ -105,6 +106,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@includedir 
 libswfdec_ at SWFDEC_MAJORMINOR@include_HEADERS = $(public_headers) swfdec_enums.h
 
 noinst_HEADERS = \
+	swfdec_amf.h \
 	swfdec_audio_internal.h \
 	swfdec_audio_event.h \
 	swfdec_audio_flv.h \
diff --git a/libswfdec/swfdec_amf.c b/libswfdec/swfdec_amf.c
new file mode 100644
index 0000000..e1ac8ba
--- /dev/null
+++ b/libswfdec/swfdec_amf.c
@@ -0,0 +1,230 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec_amf.h"
+#include "swfdec_bits.h"
+#include "swfdec_debug.h"
+#include "js/jsapi.h"
+
+typedef gboolean (* SwfdecAmfParseFunc) (JSContext *cx, SwfdecBits *bits, jsval *val);
+extern const SwfdecAmfParseFunc parse_funcs[SWFDEC_AMF_N_TYPES];
+
+static gboolean
+swfdec_amf_parse_boolean (JSContext *cx, SwfdecBits *bits, jsval *val)
+{
+  *val = swfdec_bits_get_u8 (bits) ? JSVAL_TRUE : JSVAL_FALSE;
+  return TRUE;
+}
+
+static gboolean
+swfdec_amf_parse_number (JSContext *cx, SwfdecBits *bits, jsval *val)
+{
+  double d = swfdec_bits_get_bdouble (bits);
+
+  if (!JS_NewNumberValue (cx, d, val))
+    return FALSE;
+  return TRUE;
+}
+
+static gboolean
+swfdec_amf_parse_string (JSContext *cx, SwfdecBits *bits, jsval *val)
+{
+  guint len = swfdec_bits_get_bu16 (bits);
+  char *s;
+  JSString *string;
+  
+  s = swfdec_bits_get_string_length (bits, len);
+  if (s == NULL)
+    return FALSE;
+
+  string = JS_NewStringCopyZ (cx, s);
+  g_free (s);
+  if (!string)
+    return FALSE;
+  *val = STRING_TO_JSVAL (string);
+  return TRUE;
+}
+static gboolean
+swfdec_amf_parse_properties (JSContext *cx, SwfdecBits *bits, jsval *val)
+{
+  guint type;
+  SwfdecAmfParseFunc func;
+  JSObject *object;
+
+  g_assert (JSVAL_IS_OBJECT (*val));
+  object = JSVAL_TO_OBJECT (*val);
+
+  while (swfdec_bits_left (bits)) {
+    jsval id, val;
+    if (!swfdec_amf_parse_string (cx, bits, &id))
+      return FALSE;
+    type = swfdec_bits_get_u8 (bits);
+    if (type == SWFDEC_AMF_END_OBJECT)
+      return TRUE;
+    if (type >= SWFDEC_AMF_N_TYPES ||
+	(func = parse_funcs[type]) == NULL) {
+      SWFDEC_ERROR ("no parse func for AMF type %u", type);
+      return FALSE;
+    }
+    if (!func (cx, bits, &val))
+      return FALSE;
+    if (!JS_SetProperty (cx, object, JS_GetStringBytes (JSVAL_TO_STRING (id)), &val))
+      return FALSE;
+  }
+  /* no more bytes seems to end automatically */
+  return TRUE;
+}
+
+static gboolean
+swfdec_amf_parse_object (JSContext *cx, SwfdecBits *bits, jsval *val)
+{
+  JSObject *object;
+  
+  object = JS_NewObject (cx, NULL, NULL, NULL);
+  if (object == NULL)
+    return FALSE;
+
+  *val = OBJECT_TO_JSVAL (object);
+  return swfdec_amf_parse_properties (cx, bits, val);
+}
+
+static gboolean
+swfdec_amf_parse_mixed_array (JSContext *cx, SwfdecBits *bits, jsval *val)
+{
+  guint len;
+  JSObject *object;
+  
+  len = swfdec_bits_get_bu32 (bits);
+  object = JS_NewArrayObject (cx, len, NULL);
+  if (object == NULL)
+    return FALSE;
+
+  *val = OBJECT_TO_JSVAL (object);
+  return swfdec_amf_parse_properties (cx, bits, val);
+}
+
+static gboolean
+swfdec_amf_parse_array (JSContext *cx, SwfdecBits *bits, jsval *val)
+{
+  guint i, len;
+  JSObject *object;
+  jsval *vector;
+  guint type;
+  SwfdecAmfParseFunc func;
+  
+  len = swfdec_bits_get_bu32 (bits);
+  vector = g_try_new (jsval, len);
+  if (vector == NULL)
+    return FALSE;
+  for (i = 0; i < len; i++) {
+    type = swfdec_bits_get_u8 (bits);
+    if (type >= SWFDEC_AMF_N_TYPES ||
+	(func = parse_funcs[type]) == NULL) {
+      SWFDEC_ERROR ("no parse func for AMF type %u", type);
+      goto fail;
+    }
+    if (!func (cx, bits, &vector[i]))
+      goto fail;
+  }
+  object = JS_NewArrayObject (cx, len, vector);
+  if (object == NULL)
+    goto fail;
+
+  *val = OBJECT_TO_JSVAL (object);
+  g_free (vector);
+  return TRUE;
+
+fail:
+  g_free (vector);
+  return FALSE;
+}
+
+const SwfdecAmfParseFunc parse_funcs[SWFDEC_AMF_N_TYPES] = {
+  [SWFDEC_AMF_NUMBER] = swfdec_amf_parse_number,
+  [SWFDEC_AMF_BOOLEAN] = swfdec_amf_parse_boolean,
+  [SWFDEC_AMF_STRING] = swfdec_amf_parse_string,
+  [SWFDEC_AMF_OBJECT] = swfdec_amf_parse_object,
+  [SWFDEC_AMF_MIXED_ARRAY] = swfdec_amf_parse_mixed_array,
+  [SWFDEC_AMF_ARRAY] = swfdec_amf_parse_array,
+#if 0
+  SWFDEC_AMF_MOVIECLIP = 4,
+  SWFDEC_AMF_NULL = 5,
+  SWFDEC_AMF_UNDEFINED = 6,
+  SWFDEC_AMF_REFERENCE = 7,
+  SWFDEC_AMF_END_OBJECT = 9,
+  SWFDEC_AMF_ARRAY = 10,
+  SWFDEC_AMF_DATE = 11,
+  SWFDEC_AMF_BIG_STRING = 12,
+  SWFDEC_AMF_RECORDSET = 14,
+  SWFDEC_AMF_XML = 15,
+  SWFDEC_AMF_CLASS = 16,
+  SWFDEC_AMF_FLASH9 = 17,
+#endif
+};
+
+gboolean
+swfdec_amf_parse_one (JSContext *cx, SwfdecBits *bits, SwfdecAmfType expected_type, 
+    jsval *rval)
+{
+  SwfdecAmfParseFunc func;
+  guint type;
+
+  g_return_val_if_fail (cx != NULL, FALSE);
+  g_return_val_if_fail (bits != NULL, FALSE);
+  g_return_val_if_fail (rval != NULL, FALSE);
+  g_return_val_if_fail (expected_type < SWFDEC_AMF_N_TYPES, FALSE);
+
+  type = swfdec_bits_get_u8 (bits);
+  if (type != expected_type) {
+    SWFDEC_ERROR ("parse object should be type %u, but is %u", 
+	expected_type, type);
+    return FALSE;
+  }
+  if (type >= SWFDEC_AMF_N_TYPES ||
+      (func = parse_funcs[type]) == NULL) {
+    SWFDEC_ERROR ("no parse func for AMF type %u", type);
+    return FALSE;
+  }
+  return func (cx, bits, rval);
+}
+
+guint
+swfdec_amf_parse (JSContext *cx, SwfdecBits *bits, guint n_items, ...)
+{
+  va_list args;
+  guint i;
+
+  g_return_val_if_fail (cx != NULL, 0);
+  g_return_val_if_fail (bits != NULL, 0);
+
+  va_start (args, n_items);
+  for (i = 0; i < n_items; i++) {
+    SwfdecAmfType type = va_arg (args, SwfdecAmfType);
+    jsval *val = va_arg (args, jsval *);
+    if (!swfdec_amf_parse_one (cx, bits, type, val))
+      break;
+  }
+  va_end (args);
+  return i;
+}
+
diff --git a/libswfdec/swfdec_amf.h b/libswfdec/swfdec_amf.h
new file mode 100644
index 0000000..564fbb5
--- /dev/null
+++ b/libswfdec/swfdec_amf.h
@@ -0,0 +1,59 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef __SWFDEC_AMF_H__
+#define __SWFDEC_AMF_H__
+
+#include <libswfdec/js/jspubtd.h>
+#include <libswfdec/swfdec_bits.h>
+
+typedef enum {
+  SWFDEC_AMF_NUMBER = 0,
+  SWFDEC_AMF_BOOLEAN = 1,
+  SWFDEC_AMF_STRING = 2,
+  SWFDEC_AMF_OBJECT = 3,
+  SWFDEC_AMF_MOVIECLIP = 4,
+  SWFDEC_AMF_NULL = 5,
+  SWFDEC_AMF_UNDEFINED = 6,
+  SWFDEC_AMF_REFERENCE = 7,
+  SWFDEC_AMF_MIXED_ARRAY = 8,
+  SWFDEC_AMF_END_OBJECT = 9,
+  SWFDEC_AMF_ARRAY = 10,
+  SWFDEC_AMF_DATE = 11,
+  SWFDEC_AMF_BIG_STRING = 12,
+  /* what is 13? */
+  SWFDEC_AMF_RECORDSET = 14,
+  SWFDEC_AMF_XML = 15,
+  SWFDEC_AMF_CLASS = 16,
+  SWFDEC_AMF_FLASH9 = 17,
+  /* add more items here */
+  SWFDEC_AMF_N_TYPES
+} SwfdecAmfType;
+
+gboolean	swfdec_amf_parse_one		(JSContext *	cx, 
+						 SwfdecBits *	bits,
+						 SwfdecAmfType	expected_type,
+						 jsval *	rval);
+guint		swfdec_amf_parse		(JSContext *	cx, 
+						 SwfdecBits *	bits,
+						 guint		n_items,
+						 ...);
+
+
+#endif
diff-tree e4e0c60341b918ffb5637502afd157cd2bfbd366 (from 9395d4ef15746d3e1d7070a13f6da03a91c67b54)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Mar 20 13:56:52 2007 +0100

    add swfdec_bits_get_bdouble for querying big endian doubles

diff --git a/libswfdec/swfdec_bits.c b/libswfdec/swfdec_bits.c
index 860d2c4..19b1dcd 100644
--- a/libswfdec/swfdec_bits.c
+++ b/libswfdec/swfdec_bits.c
@@ -322,6 +322,28 @@ swfdec_bits_get_double (SwfdecBits * b)
   return d;
 }
 
+double
+swfdec_bits_get_bdouble (SwfdecBits * b)
+{
+  double d;
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+  guint64 tmp;
+#endif
+
+  SWFDEC_BYTES_CHECK (b, 8);
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+  d = *((double *) b->ptr);
+#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
+  tmp = *((guint64 *) b->ptr);
+  tmp = GUINT64_FROM_BE (tmp);
+  d = *((double *) &tmp);
+#endif
+  b->ptr += 8;
+
+  return d;
+}
+
 void
 swfdec_bits_syncbits (SwfdecBits * b)
 {
diff --git a/libswfdec/swfdec_bits.h b/libswfdec/swfdec_bits.h
index d568dd8..ac07746 100644
--- a/libswfdec/swfdec_bits.h
+++ b/libswfdec/swfdec_bits.h
@@ -53,6 +53,7 @@ unsigned int swfdec_bits_get_bu24 (Swfde
 unsigned int swfdec_bits_get_bu32 (SwfdecBits *b);
 float swfdec_bits_get_float (SwfdecBits * b);
 double swfdec_bits_get_double (SwfdecBits * b);
+double swfdec_bits_get_bdouble (SwfdecBits * b);
 void swfdec_bits_syncbits (SwfdecBits * b);
 
 void swfdec_bits_get_color_transform (SwfdecBits * bits,


More information about the Swfdec mailing list