[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