[Swfdec-commits] 9 commits - swfdec-gtk/swfdec_playback_alsa.c swfdec/swfdec_button.c swfdec/swfdec_button_movie.c swfdec/swfdec_cached.c swfdec/swfdec_decoder.c swfdec/swfdec_decoder.h swfdec/swfdec_event.c swfdec/swfdec_event.h swfdec/swfdec_filter.c swfdec/swfdec_filter.h swfdec/swfdec_flv_decoder.c swfdec/swfdec_image.c swfdec/swfdec_net_stream.c swfdec/swfdec_player.c swfdec/swfdec_player.h swfdec/swfdec_player_internal.h swfdec/swfdec_resource.c swfdec/swfdec_sound.c swfdec/swfdec_sprite.c swfdec/swfdec_sprite.h swfdec/swfdec_sprite_movie.c swfdec/swfdec_sprite_movie.h swfdec/swfdec_video.c test/image

Benjamin Otte company at kemper.freedesktop.org
Thu Apr 10 13:57:54 PDT 2008


 swfdec-gtk/swfdec_playback_alsa.c           |   49 ++++++++++--
 swfdec/swfdec_button.c                      |    6 -
 swfdec/swfdec_button_movie.c                |    2 
 swfdec/swfdec_cached.c                      |    2 
 swfdec/swfdec_decoder.c                     |   59 +++++++++++++-
 swfdec/swfdec_decoder.h                     |   14 ++-
 swfdec/swfdec_event.c                       |    7 -
 swfdec/swfdec_event.h                       |    2 
 swfdec/swfdec_filter.c                      |    3 
 swfdec/swfdec_filter.h                      |    3 
 swfdec/swfdec_flv_decoder.c                 |    4 -
 swfdec/swfdec_image.c                       |  111 +++++++---------------------
 swfdec/swfdec_net_stream.c                  |    5 +
 swfdec/swfdec_player.c                      |  101 ++-----------------------
 swfdec/swfdec_player.h                      |    5 -
 swfdec/swfdec_player_internal.h             |   10 --
 swfdec/swfdec_resource.c                    |    7 +
 swfdec/swfdec_sound.c                       |    4 -
 swfdec/swfdec_sprite.c                      |   20 -----
 swfdec/swfdec_sprite.h                      |    1 
 swfdec/swfdec_sprite_movie.c                |   22 +++++
 swfdec/swfdec_sprite_movie.h                |    2 
 swfdec/swfdec_video.c                       |    2 
 test/image/Makefile.am                      |   12 +++
 test/image/definebits-palette-5.swf         |binary
 test/image/definebits-palette-5.swf.org.png |binary
 test/image/definebits-palette-5.swf.png     |binary
 test/image/definebits-palette-6.swf         |binary
 test/image/definebits-palette-6.swf.org.png |binary
 test/image/definebits-palette-6.swf.png     |binary
 test/image/definebits-palette-7.swf         |binary
 test/image/definebits-palette-7.swf.png     |binary
 test/image/definebits-palette-8.swf         |binary
 test/image/definebits-palette-8.swf.png     |binary
 test/image/definebits-palette-base64.c      |   94 +++++++++++++++++++++++
 test/image/definebits-palette.xml           |   93 +++++++++++++++++++++++
 36 files changed, 392 insertions(+), 248 deletions(-)

New commits:
commit 89945b80c199b4ee9641352dc4c84e339f927443
Merge: d3d6f90... 0d78b94...
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 22:46:32 2008 +0200

    Merge branch '0.6'

diff --cc swfdec/swfdec_image.c
index ccf43d1,fc54511..47fd185
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@@ -29,18 -29,27 +29,15 @@@
  
  #include "jpeg.h"
  #include "swfdec_image.h"
 -#include "swfdec_cache.h"
 +#include "swfdec_cached_image.h"
  #include "swfdec_debug.h"
 +#include "swfdec_renderer_internal.h"
  #include "swfdec_swf_decoder.h"
  
 -static const cairo_user_data_key_t key;
 -
  static void merge_alpha (SwfdecImage * image, unsigned char *image_data,
      unsigned char *alpha);
- static void swfdec_image_colormap_decode (SwfdecImage * image,
-     unsigned char *dest,
-     unsigned char *src, unsigned char *colormap, int colormap_len);
  
 -G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CACHED)
 -
 -static void
 -swfdec_image_unload (SwfdecCached *cached)
 -{
 -  SwfdecImage *image = SWFDEC_IMAGE (cached);
 -
 -  if (image->surface) {
 -    cairo_surface_destroy (image->surface);
 -    image->surface = NULL;
 -  }
 -}
 +G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CHARACTER)
  
  static void
  swfdec_image_dispose (GObject *object)
@@@ -310,11 -314,10 +307,10 @@@ merge_alpha (SwfdecImage * image, unsig
    }
  }
  
 -static void
 -swfdec_image_lossless_load (SwfdecImage *image)
 +static cairo_surface_t *
 +swfdec_image_lossless_load (SwfdecImage *image, SwfdecRenderer *renderer)
  {
    int format;
-   guint color_table_size;
    unsigned char *ptr;
    SwfdecBits bits;
    guint8 *data;
@@@ -337,10 -335,10 +328,9 @@@
    SWFDEC_LOG ("format = %d", format);
    SWFDEC_LOG ("width = %d", image->width);
    SWFDEC_LOG ("height = %d", image->height);
-   SWFDEC_LOG ("color_table_size = %d", color_table_size);
  
    if (image->width == 0 || image->height == 0)
 -    return;
 -  swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
 +    return NULL;
  
    if (format == 3) {
      SwfdecBuffer *buffer;
commit 0d78b94f47a5535731eb076a5a02137cd28d6fa2
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 22:46:09 2008 +0200

    add testcase for latest fix

diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index 8349615..f33ab90 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -46,6 +46,18 @@ EXTRA_DIST = \
 	color-transform-add80-alpha.swf.png \
 	default.stas \
 	default.sts \
+	definebits-palette-5.swf \
+	definebits-palette-5.swf.org.png \
+	definebits-palette-5.swf.png \
+	definebits-palette-6.swf \
+	definebits-palette-6.swf.org.png \
+	definebits-palette-6.swf.png \
+	definebits-palette-7.swf \
+	definebits-palette-7.swf.png \
+	definebits-palette-8.swf \
+	definebits-palette-8.swf.png \
+	definebits-palette-base64.c \
+	definebits-palette.xml \
 	duplicate-depth.c \
 	duplicate-depth-5.swf \
 	duplicate-depth-5.swf.png \
diff --git a/test/image/definebits-palette-5.swf b/test/image/definebits-palette-5.swf
new file mode 100644
index 0000000..829d8e0
Binary files /dev/null and b/test/image/definebits-palette-5.swf differ
diff --git a/test/image/definebits-palette-5.swf.org.png b/test/image/definebits-palette-5.swf.org.png
new file mode 100644
index 0000000..ac7db19
Binary files /dev/null and b/test/image/definebits-palette-5.swf.org.png differ
diff --git a/test/image/definebits-palette-5.swf.png b/test/image/definebits-palette-5.swf.png
new file mode 100644
index 0000000..c1dba49
Binary files /dev/null and b/test/image/definebits-palette-5.swf.png differ
diff --git a/test/image/definebits-palette-6.swf b/test/image/definebits-palette-6.swf
new file mode 100644
index 0000000..c25cbdc
Binary files /dev/null and b/test/image/definebits-palette-6.swf differ
diff --git a/test/image/definebits-palette-6.swf.org.png b/test/image/definebits-palette-6.swf.org.png
new file mode 100644
index 0000000..1dc05e2
Binary files /dev/null and b/test/image/definebits-palette-6.swf.org.png differ
diff --git a/test/image/definebits-palette-6.swf.png b/test/image/definebits-palette-6.swf.png
new file mode 100644
index 0000000..c1dba49
Binary files /dev/null and b/test/image/definebits-palette-6.swf.png differ
diff --git a/test/image/definebits-palette-7.swf b/test/image/definebits-palette-7.swf
new file mode 100644
index 0000000..4fa202d
Binary files /dev/null and b/test/image/definebits-palette-7.swf differ
diff --git a/test/image/definebits-palette-7.swf.png b/test/image/definebits-palette-7.swf.png
new file mode 100644
index 0000000..c1dba49
Binary files /dev/null and b/test/image/definebits-palette-7.swf.png differ
diff --git a/test/image/definebits-palette-8.swf b/test/image/definebits-palette-8.swf
new file mode 100644
index 0000000..e7ec025
Binary files /dev/null and b/test/image/definebits-palette-8.swf differ
diff --git a/test/image/definebits-palette-8.swf.png b/test/image/definebits-palette-8.swf.png
new file mode 100644
index 0000000..a6d104f
Binary files /dev/null and b/test/image/definebits-palette-8.swf.png differ
diff --git a/test/image/definebits-palette-base64.c b/test/image/definebits-palette-base64.c
new file mode 100644
index 0000000..c2d6072
--- /dev/null
+++ b/test/image/definebits-palette-base64.c
@@ -0,0 +1,94 @@
+/* gcc `pkg-config --libs --cflags libming glib-2.0 -lz` movie21.c -o movie21 && ./movie21
+ */
+
+#include <string.h>
+#include <zlib.h>
+#include <glib.h>
+
+static const guint32 palette[5] = { 0xFF0000FF, 0xCF00CF00, 0x9F9F0000, 0x6F006F6F, 0x3F3F003F };
+
+static const guint8 indexes[9 * 11] = {
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 1, 1, 1, 1, 1, 1, 1, 0, 
+  0, 1, 2, 2, 2, 2, 2, 1, 0, 
+  0, 1, 2, 3, 3, 3, 2, 1, 0, 
+  0, 1, 2, 3, 4, 3, 2, 1, 0, 
+  0, 1, 2, 3, 4, 3, 2, 1, 0, 
+  0, 1, 2, 3, 4, 3, 2, 1, 0, 
+  0, 1, 2, 3, 3, 3, 2, 1, 0, 
+  0, 1, 2, 2, 2, 2, 2, 1, 0, 
+  0, 1, 1, 1, 1, 1, 1, 1, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 
+};
+
+#define SWFDEC_COLOR_COMBINE(r,g,b,a)	(((a)<<24) | ((r)<<16) | ((g)<<8) | (b))
+#define SWFDEC_COLOR_A(x)		(((x)>>24)&0xff)
+#define SWFDEC_COLOR_R(x)		(((x)>>16)&0xff)
+#define SWFDEC_COLOR_G(x)		(((x)>>8)&0xff)
+#define SWFDEC_COLOR_B(x)		((x)&0xff)
+
+gsize
+create_palletized (guint8 *data, gboolean alpha)
+{
+  guint i;
+  guint8 *start = data;
+
+  if (!alpha)
+    *data++ = G_N_ELEMENTS (palette) - 1;
+  for (i = 0; i < G_N_ELEMENTS (palette); i++) {
+    *data++ = SWFDEC_COLOR_R (palette[i]);
+    *data++ = SWFDEC_COLOR_G (palette[i]);
+    *data++ = SWFDEC_COLOR_B (palette[i]);
+    if (alpha)
+      *data++ = SWFDEC_COLOR_A (palette[i]);
+  }
+  for (i = 0; i < 11; i++) {
+    memcpy (data, &indexes[9 * i], 9);
+    data += 12;
+  }
+  return data - start;
+}
+
+static void
+run (int format, gboolean alpha)
+{
+  guint8 data[2000] = { 0, };
+  guint8 compressed[2000] = { 0, };
+  gsize len; 
+  gulong clen;
+  int ret;
+  char *s;
+
+  switch (format) {
+    case 3:
+      len = create_palletized (data, alpha);
+      g_print ("%u\n", len);
+      break;
+    default:
+      g_assert_not_reached ();
+      return;
+  }
+  
+  if (alpha) {
+    clen = sizeof (compressed);
+    ret = compress2 (compressed, &clen, data, len, 9);
+  } else {
+    clen = sizeof (compressed) - 1;
+    ret = compress2 (compressed + 1, &clen, data + 1, len - 1, 9);
+    compressed[0] = data[0];
+  }
+  g_assert (ret == Z_OK);
+
+  s = g_base64_encode (compressed, clen + 1);
+  g_print ("%s\n\n", s);
+  g_free (s);
+}
+
+int
+main (int argc, char **argv)
+{
+  run (3, FALSE);
+  run (3, TRUE);
+
+  return 0;
+}
diff --git a/test/image/definebits-palette.xml b/test/image/definebits-palette.xml
new file mode 100644
index 0000000..736760e
--- /dev/null
+++ b/test/image/definebits-palette.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+  <Header framerate="31" frames="27">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+
+      <DefineBitsLossless objectID="1" format="3" width="9" height="11">
+        <data>
+	  <data>BHjaY2D4D4YMDP//Q2gIcNq3nYERAhjkvgHZTCDACJZjZGJmZgayZcDizCwgNt8VBBuqBsxewsIBVw8Rh5gjvmY/3HxksPDbdgDX3xLS</data>
+        </data>
+      </DefineBitsLossless>
+      <DefineShape objectID="2">
+        <bounds>
+          <Rectangle left="0" right="180" top="0" bottom="220"/>
+        </bounds>
+        <styles>
+          <StyleList>
+            <fillStyles>
+              <ClippedBitmap objectID="1">
+                <matrix>
+                  <Transform scaleX="20.00000000000000" scaleY="20.00000000000000" transX="0" transY="0"/>
+                </matrix>
+              </ClippedBitmap>
+            </fillStyles>
+            <lineStyles/>
+          </StyleList>
+        </styles>
+        <shapes>
+          <Shape>
+            <edges>
+              <ShapeSetup fillStyle1="1"/>
+              <LineTo x="180" y="0"/>
+              <LineTo x="0" y="220"/>
+              <LineTo x="-180" y="0"/>
+              <LineTo x="0" y="-220"/>
+              <ShapeSetup/>
+            </edges>
+          </Shape>
+        </shapes>
+      </DefineShape>
+      <PlaceObject2 replace="0" depth="1" objectID="2">
+	<transform>
+	  <Transform transX="500" transY="500"/>
+	</transform>
+      </PlaceObject2>
+
+      <DefineBitsLossless2 objectID="3" format="3" width="9" height="11" n_colormap="4">
+        <data>
+	  <data>eNpjYPj/n+E8w/n5DAzzGfLz8+0Z7O0ZkAEjBEDYTCAAYzMzMyPYLESwkdQjmYNkPhIAAP04B1kA</data>
+	</data>
+      </DefineBitsLossless2>
+      <DefineShape objectID="4">
+        <bounds>
+          <Rectangle left="0" right="180" top="0" bottom="220"/>
+        </bounds>
+        <styles>
+          <StyleList>
+            <fillStyles>
+              <ClippedBitmap objectID="3">
+                <matrix>
+                  <Transform scaleX="20.00000000000000" scaleY="20.00000000000000" transX="0" transY="0"/>
+                </matrix>
+              </ClippedBitmap>
+            </fillStyles>
+            <lineStyles/>
+          </StyleList>
+        </styles>
+        <shapes>
+          <Shape>
+            <edges>
+              <ShapeSetup fillStyle1="1"/>
+              <LineTo x="180" y="0"/>
+              <LineTo x="0" y="220"/>
+              <LineTo x="-180" y="0"/>
+              <LineTo x="0" y="-220"/>
+              <ShapeSetup/>
+            </edges>
+          </Shape>
+        </shapes>
+      </DefineShape>
+      <PlaceObject2 replace="0" depth="2" objectID="4">
+	<transform>
+	  <Transform transX="1000" transY="500"/>
+	</transform>
+      </PlaceObject2>
+
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
commit a126ae9d57e0729ac758b76b4dba415a04a9221f
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 22:41:32 2008 +0200

    fix memory overwrite error that could lead to segfaults
    
    https://bugzilla.redhat.com/show_bug.cgi?id=441614

diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index b4bff6c..fc54511 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -37,9 +37,6 @@ static const cairo_user_data_key_t key;
 
 static void merge_alpha (SwfdecImage * image, unsigned char *image_data,
     unsigned char *alpha);
-static void swfdec_image_colormap_decode (SwfdecImage * image,
-    unsigned char *dest,
-    unsigned char *src, unsigned char *colormap, int colormap_len);
 
 G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CACHED)
 
@@ -321,7 +318,6 @@ static void
 swfdec_image_lossless_load (SwfdecImage *image)
 {
   int format;
-  guint color_table_size;
   unsigned char *ptr;
   SwfdecBits bits;
   guint8 *data;
@@ -335,16 +331,10 @@ swfdec_image_lossless_load (SwfdecImage *image)
   SWFDEC_LOG ("  width = %d", image->width);
   image->height = swfdec_bits_get_u16 (&bits);
   SWFDEC_LOG ("  height = %d", image->height);
-  if (format == 3) {
-    color_table_size = swfdec_bits_get_u8 (&bits) + 1;
-  } else {
-    color_table_size = 0;
-  }
 
   SWFDEC_LOG ("format = %d", format);
   SWFDEC_LOG ("width = %d", image->width);
   SWFDEC_LOG ("height = %d", image->height);
-  SWFDEC_LOG ("color_table_size = %d", color_table_size);
 
   if (image->width == 0 || image->height == 0)
     return;
@@ -352,63 +342,55 @@ swfdec_image_lossless_load (SwfdecImage *image)
 
   if (format == 3) {
     SwfdecBuffer *buffer;
-    unsigned char *indexed_data;
-    guint i;
+    guchar *indexed_data;
+    guint32 palette[256], *pixels;
+    guint i, j;
+    guint palette_size;
     guint rowstride = (image->width + 3) & ~3;
 
+    palette_size = swfdec_bits_get_u8 (&bits) + 1;
+    SWFDEC_LOG ("palette_size = %d", palette_size);
+
     data = g_malloc (4 * image->width * image->height);
 
     if (have_alpha) {
-      buffer = swfdec_bits_decompress (&bits, -1, color_table_size * 4 + rowstride * image->height);
+      buffer = swfdec_bits_decompress (&bits, -1, palette_size * 4 + rowstride * image->height);
       if (buffer == NULL) {
 	SWFDEC_ERROR ("failed to decompress data");
 	memset (data, 0, 4 * image->width * image->height);
 	goto out;
       }
       ptr = buffer->data;
-      for (i = 0; i < color_table_size; i++) {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-	guint8 tmp = ptr[i * 4 + 0];
-        ptr[i * 4 + 0] = ptr[i * 4 + 2];
-        ptr[i * 4 + 2] = tmp;
-#else
-        guint8 tmp = ptr[i * 4 + 3];
-        ptr[i * 4 + 3] = ptr[i * 4 + 2];
-        ptr[i * 4 + 2] = ptr[i * 4 + 1];
-        ptr[i * 4 + 1] = ptr[i * 4 + 0];
-        ptr[i * 4 + 0] = tmp;
-#endif
+      for (i = 0; i < palette_size; i++) {
+	palette[i] = SWFDEC_COLOR_COMBINE (ptr[i * 4 + 0], ptr[i * 4 + 1],
+	    ptr[i * 4 + 2], ptr[i * 4 + 3]);
       }
-      indexed_data = ptr + color_table_size * 4;
+      indexed_data = ptr + palette_size * 4;
     } else {
-      buffer = swfdec_bits_decompress (&bits, -1, color_table_size * 3 + rowstride * image->height);
+      buffer = swfdec_bits_decompress (&bits, -1, palette_size * 3 + rowstride * image->height);
       if (buffer == NULL) {
 	SWFDEC_ERROR ("failed to decompress data");
 	memset (data, 0, 4 * image->width * image->height);
 	goto out;
       }
       ptr = buffer->data;
-      for (i = color_table_size - 1; i < color_table_size; i--) {
-	guint8 color[3];
-	color[0] = ptr[i * 3 + 0];
-	color[1] = ptr[i * 3 + 1];
-	color[2] = ptr[i * 3 + 2];
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-        ptr[i * 4 + 0] = color[2];
-        ptr[i * 4 + 1] = color[1];
-	ptr[i * 4 + 2] = color[0];
-        ptr[i * 4 + 3] = 255;
-#else
-        ptr[i * 4 + 0] = 255;
-        ptr[i * 4 + 1] = color[0];
-        ptr[i * 4 + 2] = color[1];
-        ptr[i * 4 + 3] = color[2];
-#endif
+      for (i = 0; i < palette_size; i++) {
+	palette[i] = SWFDEC_COLOR_COMBINE (ptr[i * 3 + 0],
+	    ptr[i * 3 + 1], ptr[i * 3 + 2], 0xFF);
+      }
+      indexed_data = ptr + palette_size * 3;
+    }
+    if (palette_size < 256)
+      memset (palette + palette_size, 0, (256 - palette_size) * 4);
+
+    pixels = (guint32 *) data;
+    for (j = 0; j < (guint) image->height; j++) {
+      for (i = 0; i < (guint) image->width; i++) {
+	*pixels = palette[indexed_data[i]];
+	pixels++;
       }
-      indexed_data = ptr + color_table_size * 3;
+      indexed_data += rowstride;
     }
-    swfdec_image_colormap_decode (image, data, indexed_data,
-	ptr, color_table_size);
 
     swfdec_buffer_unref (buffer);
   } else if (format == 4) {
@@ -525,43 +507,6 @@ tag_func_define_bits_lossless_2 (SwfdecSwfDecoder * s, guint tag)
   return SWFDEC_STATUS_OK;
 }
 
-static void
-swfdec_image_colormap_decode (SwfdecImage * image,
-    unsigned char *dest,
-    unsigned char *src, unsigned char *colormap, int colormap_len)
-{
-  int c;
-  int i;
-  int j;
-  int rowstride;
-
-  rowstride = (image->width + 3) & ~0x3;
-  SWFDEC_DEBUG ("rowstride %d", rowstride);
-
-  for (j = 0; j < image->height; j++) {
-    for (i = 0; i < image->width; i++) {
-      c = src[i];
-      if (colormap_len < 256 && c == 255) {
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = 0;
-        dest[3] = 0;
-      } else if (c >= colormap_len) {
-        SWFDEC_ERROR ("colormap index out of range (%d>=%d) (%d,%d)",
-            c, colormap_len, i, j);
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = 0;
-        dest[3] = 0;
-      } else {
-	memmove (dest, &colormap[c*4], 4);
-      }
-      dest += 4;
-    }
-    src += rowstride;
-  }
-}
-
 static cairo_status_t
 swfdec_image_png_read (void *bitsp, unsigned char *data, unsigned int length)
 {
commit d3d6f904d5fae9946c7cff572a41f4bebe722b18
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 18:41:24 2008 +0200

    rewrite background handling
    
    This gets rid of a property that is useless.
    
    I used to think that the ability to set bgcolor on a Flash file changed the
    background of a Flash file. Turns out this isn't true, but it's a real attribute
    of the embed tag.

diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index b12d22f..92f4480 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -651,7 +651,6 @@ enum {
   PROP_RATE,
   PROP_MOUSE_CURSOR,
   PROP_NEXT_EVENT,
-  PROP_BACKGROUND_COLOR,
   PROP_WIDTH,
   PROP_HEIGHT,
   PROP_ALIGNMENT,
@@ -726,9 +725,6 @@ swfdec_player_get_property (GObject *object, guint param_id, GValue *value,
   SwfdecPlayerPrivate *priv = player->priv;
   
   switch (param_id) {
-    case PROP_BACKGROUND_COLOR:
-      g_value_set_uint (value, swfdec_player_get_background_color (player));
-      break;
     case PROP_CACHE_SIZE:
       g_value_set_ulong (value, swfdec_cache_get_max_cache_size (priv->cache));
       break;
@@ -876,9 +872,6 @@ swfdec_player_set_property (GObject *object, guint param_id, const GValue *value
   SwfdecPlayerPrivate *priv = player->priv;
 
   switch (param_id) {
-    case PROP_BACKGROUND_COLOR:
-      swfdec_player_set_background_color (player, g_value_get_uint (value));
-      break;
     case PROP_CACHE_SIZE:
       swfdec_cache_set_max_cache_size (priv->cache, g_value_get_ulong (value));
       break;
@@ -1973,9 +1966,6 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
   g_object_class_install_property (object_class, PROP_CACHE_SIZE,
       g_param_spec_ulong ("cache-size", "cache size", "maximum cache size in bytes",
 	  0, G_MAXULONG, 50 * 1024 * 1024, G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_BACKGROUND_COLOR,
-      g_param_spec_uint ("background-color", "background color", "ARGB color used to draw the background",
-	  0, G_MAXUINT, SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF), G_PARAM_READWRITE));
   g_object_class_install_property (object_class, PROP_WIDTH,
       g_param_spec_int ("width", "width", "current width of the movie",
 	  -1, G_MAXINT, -1, G_PARAM_READWRITE));
@@ -2203,7 +2193,6 @@ swfdec_player_init (SwfdecPlayer *player)
   }
   priv->external_actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerExternalAction, 8);
   priv->cache = swfdec_cache_new (16 * 1024 * 1024);
-  priv->bgcolor = SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF);
   priv->socket_type = SWFDEC_TYPE_SOCKET;
 
   priv->runtime = g_timer_new ();
@@ -2890,8 +2879,6 @@ swfdec_player_render_with_renderer (SwfdecPlayer *player, cairo_t *cr,
   /* convert the cairo matrix */
   cairo_translate (cr, priv->offset_x, priv->offset_y);
   cairo_scale (cr, priv->scale_x / SWFDEC_TWIPS_SCALE_FACTOR, priv->scale_y / SWFDEC_TWIPS_SCALE_FACTOR);
-  swfdec_color_set_source (cr, priv->bgcolor);
-  cairo_paint (cr);
 
   for (walk = priv->roots; walk; walk = walk->next) {
     swfdec_movie_render (walk->data, cr, &trans, &real);
@@ -3124,50 +3111,6 @@ swfdec_player_get_audio (SwfdecPlayer *	player)
 }
 
 /**
- * swfdec_player_get_background_color:
- * @player: a #SwfdecPlayer
- *
- * Gets the current background color. The color will be an ARGB-quad, with the 
- * MSB being the alpha value.
- *
- * Returns: the background color as an ARGB value
- **/
-guint
-swfdec_player_get_background_color (SwfdecPlayer *player)
-{
-  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF));
-
-  return player->priv->bgcolor;
-}
-
-/**
- * swfdec_player_set_background_color:
- * @player: a #SwfdecPlayer
- * @color: new color to use as background color
- *
- * Sets a new background color as an ARGB value. To get transparency, set the 
- * value to 0. To get a black beackground, use 0xFF000000.
- **/
-void
-swfdec_player_set_background_color (SwfdecPlayer *player, guint color)
-{
-  SwfdecPlayerPrivate *priv;
-
-  g_return_if_fail (SWFDEC_IS_PLAYER (player));
-
-  priv = player->priv;
-  priv->bgcolor_set = TRUE;
-  if (priv->bgcolor == color)
-    return;
-  priv->bgcolor = color;
-  g_object_notify (G_OBJECT (player), "background-color");
-  if (swfdec_player_is_initialized (player)) {
-    g_signal_emit (player, signals[INVALIDATE], 0, 0.0, 0.0, 
-	(double) priv->width, (double) priv->height);
-  }
-}
-
-/**
  * swfdec_player_get_scale_mode:
  * @player: a #SwfdecPlayer
  *
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index 49cfe39..c259895 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -115,11 +115,6 @@ void		swfdec_player_get_size		(SwfdecPlayer *	player,
 void		swfdec_player_set_size		(SwfdecPlayer *	player,
 						 int		width,
 						 int		height);
-guint		swfdec_player_get_background_color 
-						(SwfdecPlayer *	player);
-void		swfdec_player_set_background_color 
-						(SwfdecPlayer *	player,
-						 guint	color);
 SwfdecScaleMode	swfdec_player_get_scale_mode	(SwfdecPlayer *		player);
 void		swfdec_player_set_scale_mode	(SwfdecPlayer *		player,
 						 SwfdecScaleMode	mode);
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index ef96cd5..94b9a98 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -70,8 +70,6 @@ struct _SwfdecPlayerPrivate
   guint			height;			/* height of movie */
   GList *		roots;			/* all the root movies */
   SwfdecCache *		cache;			/* player cache */
-  gboolean		bgcolor_set;		/* TRUE if the background color has been set */
-  SwfdecColor		bgcolor;		/* background color */
   SwfdecResource *	resource;		/* initial resource loaded */
   char *		variables;		/* variables to set on the player */
   SwfdecURL *		url;			/* url or NULL if not set yet */
diff --git a/swfdec/swfdec_sprite.c b/swfdec/swfdec_sprite.c
index a6759eb..cf639fe 100644
--- a/swfdec/swfdec_sprite.c
+++ b/swfdec/swfdec_sprite.c
@@ -125,27 +125,7 @@ swfdec_sprite_get_action (SwfdecSprite *sprite, guint n, guint *tag, SwfdecBuffe
 int
 tag_func_set_background_color (SwfdecSwfDecoder * s, guint tag)
 {
-  SWFDEC_FIXME ("fix background color handling");
-#if 0
-  SwfdecPlayer *player = SWFDEC_DECODER (s)->player;
-  SwfdecPlayerPrivate *priv = player->priv;
-  SwfdecColor color = swfdec_bits_get_color (&s->b);
-
-  if (priv->bgcolor_set) {
-    /* only an INFO because it can be set by user, should be error if we check duplication of tag */
-    SWFDEC_INFO ("background color has been set to %X already, setting to %X ignored",
-	priv->bgcolor, color);
-  } else {
-    SWFDEC_LOG ("setting background color to %X", color);
-    /* can't use swfdec_player_set_background_color() here, because the player is locked and doesn't emit signals */
-    priv->bgcolor = color;
-    priv->bgcolor_set = TRUE;
-    priv->invalid_extents = priv->stage;
-    g_array_set_size (priv->invalidations, 1);
-    g_array_index (priv->invalidations, SwfdecRectangle, 0) = priv->stage;
-    g_object_notify (G_OBJECT (player), "background-color");
-  }
-#endif
+  s->parse_sprite->bgcolor = swfdec_bits_get_color (&s->b);
 
   return SWFDEC_STATUS_OK;
 }
@@ -157,6 +137,7 @@ swfdec_sprite_create_movie (SwfdecGraphic *graphic, gsize *size)
 
   ret->sprite = SWFDEC_SPRITE (graphic);
   ret->n_frames = ret->sprite->n_frames;
+  ret->bgcolor = ret->sprite->bgcolor;
   *size = sizeof (SwfdecSpriteMovie);
 
   return SWFDEC_MOVIE (ret);
diff --git a/swfdec/swfdec_sprite.h b/swfdec/swfdec_sprite.h
index cbca787..1559642 100644
--- a/swfdec/swfdec_sprite.h
+++ b/swfdec/swfdec_sprite.h
@@ -69,6 +69,7 @@ struct _SwfdecSprite
   guint			n_frames;	/* number of frames in this sprite */
   SwfdecScript *	init_action;	/* action to run when initializing this sprite */
   GArray *		actions;      	/* SwfdecSpriteAction in execution order */
+  SwfdecColor		bgcolor;	/* background color for this sprite */
 
   /* parse state */
   guint			parse_frame;	/* frame we're currently parsing. == n_frames if done parsing */
diff --git a/swfdec/swfdec_sprite_movie.c b/swfdec/swfdec_sprite_movie.c
index 2255982..f62b6a4 100644
--- a/swfdec/swfdec_sprite_movie.c
+++ b/swfdec/swfdec_sprite_movie.c
@@ -760,6 +760,23 @@ swfdec_sprite_movie_finish_movie (SwfdecMovie *mov)
 }
 
 static void
+swfdec_sprite_movie_render (SwfdecMovie *mov, cairo_t *cr,
+    const SwfdecColorTransform *trans, const SwfdecRect *inval)
+{
+  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
+
+  if (movie->bgcolor) {
+    cairo_rectangle (cr, mov->original_extents.x0, mov->original_extents.y0,
+	mov->original_extents.x1, mov->original_extents.y1);
+    swfdec_color_set_source (cr, movie->bgcolor);
+    cairo_fill (cr);
+  }
+
+  SWFDEC_MOVIE_CLASS (swfdec_sprite_movie_parent_class)->render (mov,
+      cr, trans, inval);
+}
+
+static void
 swfdec_sprite_movie_mark (SwfdecAsObject *object)
 {
   GList *walk;
@@ -788,6 +805,7 @@ swfdec_sprite_movie_class_init (SwfdecSpriteMovieClass * g_class)
 
   movie_class->init_movie = swfdec_sprite_movie_init_movie;
   movie_class->finish_movie = swfdec_sprite_movie_finish_movie;
+  movie_class->render = swfdec_sprite_movie_render;
   
   actor_class->iterate_start = swfdec_sprite_movie_iterate;
   actor_class->iterate_end = swfdec_sprite_movie_iterate_end;
diff --git a/swfdec/swfdec_sprite_movie.h b/swfdec/swfdec_sprite_movie.h
index aa409e8..967b530 100644
--- a/swfdec/swfdec_sprite_movie.h
+++ b/swfdec/swfdec_sprite_movie.h
@@ -50,7 +50,7 @@ struct _SwfdecSpriteMovie
   gboolean		playing;	/* TRUE if the movie automatically advances */
 
   /* color information */
-  SwfdecColor		bg_color;	/* background color (only used on main sprite) */
+  SwfdecColor		bgcolor;	/* background color (only used on main sprite) */
 
   /* audio stream handling */
   guint			sound_frame;	/* current sound frame */
commit 0317535619fb939b57262df9848305dd4017958e
Merge: 218dc6f... 3c743af...
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 18:37:40 2008 +0200

    Merge branch '0.6'

commit 3c743afcb529963d4f8da2bdd826c62aa915c0e1
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 17:47:32 2008 +0200

    add snd_pcm_write support to make PA work via ALSA

diff --git a/swfdec-gtk/swfdec_playback_alsa.c b/swfdec-gtk/swfdec_playback_alsa.c
index bddd189..9d1a8f7 100644
--- a/swfdec-gtk/swfdec_playback_alsa.c
+++ b/swfdec-gtk/swfdec_playback_alsa.c
@@ -47,14 +47,16 @@ struct _SwfdecPlayback {
   GMainContext *	context;	/* context we work in */
 };
 
-typedef struct {
+typedef struct _Stream Stream;
+struct _Stream {
   SwfdecPlayback *     	sound;		/* reference to sound object */
   SwfdecAudio *		audio;		/* the audio we play back */
   snd_pcm_t *		pcm;		/* the pcm we play back to */
   GSource **		sources;	/* sources for writing data */
   guint			n_sources;	/* number of sources */
   guint			offset;		/* offset into sound */
-} Stream;
+  gboolean		(* write)	(Stream *);
+};
 
 #define ALSA_TRY(func,msg) G_STMT_START{ \
   int err = func; \
@@ -90,7 +92,7 @@ write_player (Stream *stream, const snd_pcm_channel_area_t *dst,
 }
 
 static gboolean
-try_write (Stream *stream)
+try_write_mmap (Stream *stream)
 {
   snd_pcm_sframes_t avail_result;
   snd_pcm_uframes_t offset, avail;
@@ -117,6 +119,31 @@ try_write (Stream *stream)
   return TRUE;
 }
 
+static gboolean
+try_write_so_pa_gets_it (Stream *stream)
+{
+#define STEP 1024
+  snd_pcm_sframes_t avail, step;
+  avail = snd_pcm_avail_update (stream->pcm);
+  ALSA_ERROR (avail, "snd_pcm_avail_update failed", FALSE);
+
+  while (avail > 0) {
+    gint16 data[2 * STEP] = { 0, };
+
+    step = MIN (avail, STEP);
+    swfdec_audio_render (stream->audio, data, stream->offset, step);
+    step = snd_pcm_writei (stream->pcm, data, step);
+    ALSA_ERROR (step, "snd_pcm_writei failed", FALSE);
+    avail -= step;
+    stream->offset += step;
+  }
+
+  return TRUE;
+#undef STEP
+}
+
+#define try_write(stream) ((stream)->write (stream))
+
 static void
 swfdec_playback_stream_remove_handlers (Stream *stream)
 {
@@ -141,10 +168,10 @@ handle_stream (GIOChannel *source, GIOCondition cond, gpointer data)
   state = snd_pcm_state (stream->pcm);
   if (state != SND_PCM_STATE_RUNNING) {
     swfdec_playback_stream_start (stream);
+    return TRUE;
   } else {
-    try_write (stream);
+    return try_write (stream);
   }
-  return TRUE;
 }
 
 static void
@@ -185,7 +212,9 @@ swfdec_playback_stream_start (Stream *stream)
       stream->offset = 0;
       //g_print ("offset: %u (delay: %ld)\n", sound->offset, delay);
       if (try_write (stream)) {
-	ALSA_ERROR (snd_pcm_start (stream->pcm), "error starting",);
+	if (stream->write == try_write_mmap) {
+	  ALSA_ERROR (snd_pcm_start (stream->pcm), "error starting",);
+	}
 	swfdec_playback_stream_install_handlers (stream);
       }
       break;
@@ -208,6 +237,7 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
   snd_pcm_hw_params_t *hw_params;
   guint rate;
   snd_pcm_uframes_t uframes;
+  gboolean (* try_write) (Stream *);
 
   /* "default" uses dmix, and dmix ticks way slow, so this thingy here stutters */
   ALSA_ERROR (snd_pcm_open (&ret, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK),
@@ -218,7 +248,11 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
     g_printerr ("No sound format available\n");
     return;
   }
-  if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) {
+  if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) >= 0) {
+    try_write = try_write_mmap;
+  } else if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED) >= 0) {
+    try_write = try_write_so_pa_gets_it;
+  } else {
     g_printerr ("Failed setting access\n");
     goto fail;
   }
@@ -252,6 +286,7 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
   }
 #endif
   stream = g_new0 (Stream, 1);
+  stream->write = try_write;
   stream->sound = sound;
   stream->audio = g_object_ref (audio);
   stream->pcm = ret;
commit 218dc6f8a86ef5c1b52af6dace285cce0c4b4681
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 16:21:00 2008 +0200

    reinstate missing codecs support
    
    we now go via a signal emitted by the decoder

diff --git a/swfdec/swfdec_decoder.c b/swfdec/swfdec_decoder.c
index e5b3e9a..81e4c22 100644
--- a/swfdec/swfdec_decoder.c
+++ b/swfdec/swfdec_decoder.c
@@ -22,6 +22,9 @@
 #endif
 
 #include <string.h>
+
+#include "swfdec_codec_audio.h"
+#include "swfdec_codec_video.h"
 #include "swfdec_decoder.h"
 #include "swfdec_debug.h"
 #include "swfdec_decoder.h"
@@ -29,12 +32,29 @@
 #include "swfdec_image_decoder.h"
 #include "swfdec_swf_decoder.h"
 
+enum {
+  MISSING_PLUGINS,
+  LAST_SIGNAL
+};
 
 G_DEFINE_ABSTRACT_TYPE (SwfdecDecoder, swfdec_decoder, G_TYPE_OBJECT)
+static guint signals[LAST_SIGNAL] = { 0, };
 
 static void
 swfdec_decoder_class_init (SwfdecDecoderClass *klass)
 {
+  /**
+   * SwfdecDecoder::missing-plugin:
+   * @player: the #SwfdecPlayer missing plugins
+   * @details: the detail string for the missing plugins
+   *
+   * Emitted whenever a missing plugin is detected.
+   */
+  signals[MISSING_PLUGINS] = g_signal_new ("missing-plugin", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwfdecDecoderClass, missing_plugins),
+      NULL, NULL, g_cclosure_marshal_VOID__STRING,
+      G_TYPE_NONE, 1, G_TYPE_STRING);
+
 }
 
 static void
@@ -91,3 +111,36 @@ swfdec_decoder_eof (SwfdecDecoder *decoder)
   return klass->eof (decoder);
 }
 
+void
+swfdec_decoder_use_audio_codec (SwfdecDecoder *decoder, guint codec, 
+    SwfdecAudioFormat format)
+{
+  char *detail;
+
+  g_return_if_fail (SWFDEC_IS_DECODER (decoder));
+
+  swfdec_audio_decoder_prepare (codec, format, &detail);
+  if (detail == NULL)
+    return;
+
+  SWFDEC_INFO ("missing audio plugin: %s\n", detail);
+  g_signal_emit (decoder, signals[MISSING_PLUGINS], 0, detail);
+  g_free (detail);
+}
+
+void
+swfdec_decoder_use_video_codec (SwfdecDecoder *decoder, guint codec)
+{
+  char *detail;
+
+  g_return_if_fail (SWFDEC_IS_DECODER (decoder));
+
+  detail = swfdec_video_decoder_prepare (codec);
+  if (detail == NULL)
+    return;
+
+  SWFDEC_INFO ("missing video plugin: %s\n", detail);
+  g_signal_emit (decoder, signals[MISSING_PLUGINS], 0, detail);
+  g_free (detail);
+}
+
diff --git a/swfdec/swfdec_decoder.h b/swfdec/swfdec_decoder.h
index 2e454dd..fad1b5b 100644
--- a/swfdec/swfdec_decoder.h
+++ b/swfdec/swfdec_decoder.h
@@ -21,6 +21,7 @@
 #define _SWFDEC_DECODER_H_
 
 #include <glib-object.h>
+#include <swfdec/swfdec_audio_internal.h>
 #include <swfdec/swfdec_buffer.h>
 #include <swfdec/swfdec_loader.h>
 #include <swfdec/swfdec_player.h>
@@ -75,6 +76,10 @@ struct _SwfdecDecoderClass
   SwfdecStatus		(* parse)		(SwfdecDecoder *	decoder,
 						 SwfdecBuffer *		buffer);
   SwfdecStatus		(* eof)			(SwfdecDecoder *	decoder);
+
+  /* signals */
+  void			(* missing_plugins)	(SwfdecDecoder *	dec,
+						 const char **		details);
 };
 
 GType		swfdec_decoder_get_type		(void);
@@ -86,6 +91,11 @@ SwfdecStatus	swfdec_decoder_parse		(SwfdecDecoder *	decoder,
 						 SwfdecBuffer * 	buffer);
 SwfdecStatus	swfdec_decoder_eof		(SwfdecDecoder *	decoder);
 
+void		swfdec_decoder_use_audio_codec	(SwfdecDecoder *	decoder,
+						 guint			codec, 
+						 SwfdecAudioFormat	format);
+void		swfdec_decoder_use_video_codec	(SwfdecDecoder *	decoder,
+						 guint			codec);
 
 G_END_DECLS
 #endif
diff --git a/swfdec/swfdec_flv_decoder.c b/swfdec/swfdec_flv_decoder.c
index fe64cde..30f32a6 100644
--- a/swfdec/swfdec_flv_decoder.c
+++ b/swfdec/swfdec_flv_decoder.c
@@ -253,7 +253,7 @@ swfdec_flv_decoder_parse_video_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
   }
   if (flv->video->len == 0) {
     g_array_append_val (flv->video, tag);
-    //swfdec_player_use_video_codec (SWFDEC_DECODER (flv)->player, tag.format);
+    swfdec_decoder_use_video_codec (SWFDEC_DECODER (flv), tag.format);
     return SWFDEC_STATUS_INIT;
   } else if (g_array_index (flv->video, SwfdecFlvVideoTag, 
 	flv->video->len - 1).timestamp < tag.timestamp) {
@@ -292,7 +292,7 @@ swfdec_flv_decoder_parse_audio_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
   }
   if (flv->audio->len == 0) {
     g_array_append_val (flv->audio, tag);
-    //swfdec_player_use_audio_codec (SWFDEC_DECODER (flv)->player, tag.format, tag.original_format);
+    swfdec_decoder_use_audio_codec (SWFDEC_DECODER (flv), tag.format, tag.original_format);
     return SWFDEC_STATUS_INIT;
   } else if (g_array_index (flv->audio, SwfdecFlvAudioTag, 
 	flv->audio->len - 1).timestamp < tag.timestamp) {
diff --git a/swfdec/swfdec_net_stream.c b/swfdec/swfdec_net_stream.c
index 9b67804..25d3c1e 100644
--- a/swfdec/swfdec_net_stream.c
+++ b/swfdec/swfdec_net_stream.c
@@ -269,6 +269,8 @@ swfdec_net_stream_stream_target_parse (SwfdecStreamTarget *target,
   if (ns->flvdecoder == NULL) {
     /* FIXME: add mp3 support */
     ns->flvdecoder = g_object_new (SWFDEC_TYPE_FLV_DECODER, NULL);
+    g_signal_connect_swapped (ns->flvdecoder, "missing-plugin", 
+	G_CALLBACK (swfdec_player_add_missing_plugin), SWFDEC_AS_OBJECT (ns)->context);
     swfdec_net_stream_onstatus (ns, SWFDEC_AS_STR_NetStream_Play_Start,
 	SWFDEC_AS_STR_status);
     swfdec_loader_set_data_type (SWFDEC_LOADER (stream), SWFDEC_LOADER_DATA_FLV);
@@ -571,6 +573,8 @@ swfdec_net_stream_set_loader (SwfdecNetStream *stream, SwfdecLoader *loader)
     g_object_unref (lstream);
   }
   if (stream->flvdecoder) {
+    g_signal_handlers_disconnect_by_func (stream->flvdecoder,
+	  swfdec_player_add_missing_plugin, SWFDEC_AS_OBJECT (stream)->context);
     g_object_unref (stream->flvdecoder);
     stream->flvdecoder = NULL;
   }
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 29ca9f8..b12d22f 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -2165,8 +2165,11 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
   /**
    * SwfdecPlayer::missing-plugins:
    * @player: the #SwfdecPlayer missing plugins
-   * @details: the details strigs for all missing plugins
+   * @details: the details strings for all missing plugins
    *
+   * Emitted whenever a plugin is detected that GStreamer cannot currently 
+   * handle because it is missing plugins to do so. You should use 
+   * gst_install_plugins_async() to install those plugins.
    */
   signals[MISSING_PLUGINS] = g_signal_new ("missing-plugins", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwfdecPlayerClass, missing_plugins),
@@ -2562,48 +2565,19 @@ swfdec_player_load (SwfdecPlayer *player, const char *url,
 }
 
 void
-swfdec_player_use_audio_codec (SwfdecPlayer *player, guint codec, 
-    SwfdecAudioFormat format)
+swfdec_player_add_missing_plugin (SwfdecPlayer *player, const char *detail)
 {
   SwfdecPlayerPrivate *priv;
-  char *detail;
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
-
-  swfdec_audio_decoder_prepare (codec, format, &detail);
-  if (detail == NULL)
-    return;
+  g_return_if_fail (detail != NULL);
 
   priv = player->priv;
-  if (g_slist_find_custom (priv->missing_plugins, detail, (GCompareFunc) strcmp)) {
-    g_free (detail);
+  if (g_slist_find_custom (priv->missing_plugins, detail, (GCompareFunc) strcmp))
     return;
-  }
-
-  SWFDEC_INFO ("missing audio plugin: %s\n", detail);
-  priv->missing_plugins = g_slist_prepend (priv->missing_plugins, detail);
-}
-
-void
-swfdec_player_use_video_codec (SwfdecPlayer *player, guint codec)
-{
-  SwfdecPlayerPrivate *priv;
-  char *detail;
-
-  g_return_if_fail (SWFDEC_IS_PLAYER (player));
-
-  detail = swfdec_video_decoder_prepare (codec);
-  if (detail == NULL)
-    return;
-
-  priv = player->priv;
-  if (g_slist_find_custom (priv->missing_plugins, detail, (GCompareFunc) strcmp)) {
-    g_free (detail);
-    return;
-  }
 
-  SWFDEC_INFO ("missing video plugin: %s\n", detail);
-  priv->missing_plugins = g_slist_prepend (priv->missing_plugins, detail);
+  SWFDEC_INFO ("adding missing plugin: %s\n", detail);
+  priv->missing_plugins = g_slist_prepend (priv->missing_plugins, g_strdup (detail));
 }
 
 /** PUBLIC API ***/
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index 7b9dd54..ef96cd5 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -22,7 +22,6 @@
 
 #include <swfdec/swfdec_player.h>
 #include <swfdec/swfdec_audio.h>
-#include <swfdec/swfdec_audio_internal.h>
 #include <swfdec/swfdec_cache.h>
 #include <swfdec/swfdec_event.h>
 #include <swfdec/swfdec_function_list.h>
@@ -256,12 +255,9 @@ void		swfdec_player_global_to_stage	(SwfdecPlayer *		player,
 						 double *		x,
 						 double *		y);
 void		swfdec_player_update_scale	(SwfdecPlayer *		player);
+void		swfdec_player_add_missing_plugin(SwfdecPlayer *		player,
+						 const char *		detail);
 
-void		swfdec_player_use_audio_codec	(SwfdecPlayer *		player,
-						 guint			codec, 
-						 SwfdecAudioFormat	format);
-void		swfdec_player_use_video_codec	(SwfdecPlayer *		player,
-						 guint			codec);
 /* in swfdec_policy_file.c */
 gboolean	swfdec_player_allow_now		(SwfdecPlayer *		player,
 						 const SwfdecURL *	url);
diff --git a/swfdec/swfdec_resource.c b/swfdec/swfdec_resource.c
index 210b7d2..4285b02 100644
--- a/swfdec/swfdec_resource.c
+++ b/swfdec/swfdec_resource.c
@@ -274,6 +274,8 @@ swfdec_resource_stream_target_parse (SwfdecStreamTarget *target, SwfdecStream *s
     } else {
       glong total;
       resource->decoder = dec;
+      g_signal_connect_swapped (dec, "missing-plugin", 
+	  G_CALLBACK (swfdec_player_add_missing_plugin), SWFDEC_AS_OBJECT (resource)->context);
       total = swfdec_loader_get_size (loader);
       if (total >= 0)
 	dec->bytes_total = total;
@@ -418,6 +420,8 @@ swfdec_resource_dispose (GObject *object)
     resource->loader = NULL;
   }
   if (resource->decoder) {
+    g_signal_handlers_disconnect_by_func (resource->decoder,
+	  swfdec_player_add_missing_plugin, SWFDEC_AS_OBJECT (resource)->context);
     g_object_unref (resource->decoder);
     resource->decoder = NULL;
   }
diff --git a/swfdec/swfdec_sound.c b/swfdec/swfdec_sound.c
index 53fe2c1..4a46030 100644
--- a/swfdec/swfdec_sound.c
+++ b/swfdec/swfdec_sound.c
@@ -146,7 +146,7 @@ tag_func_define_sound (SwfdecSwfDecoder * s, guint tag)
   }
   sound->n_samples *= swfdec_audio_format_get_granularity (sound->format);
 
-  //swfdec_player_use_audio_codec (SWFDEC_DECODER (s)->player, sound->codec, sound->format);
+  swfdec_decoder_use_audio_codec (SWFDEC_DECODER (s), sound->codec, sound->format);
 
   return SWFDEC_STATUS_OK;
 }
@@ -272,7 +272,7 @@ tag_func_sound_stream_head (SwfdecSwfDecoder * s, guint tag)
       sound->codec = SWFDEC_AUDIO_CODEC_UNDEFINED;
   }
 
-  //swfdec_player_use_audio_codec (SWFDEC_DECODER (s)->player, sound->codec, sound->format);
+  swfdec_decoder_use_audio_codec (SWFDEC_DECODER (s), sound->codec, sound->format);
 
   return SWFDEC_STATUS_OK;
 }
diff --git a/swfdec/swfdec_video.c b/swfdec/swfdec_video.c
index 210813e..b75649c 100644
--- a/swfdec/swfdec_video.c
+++ b/swfdec/swfdec_video.c
@@ -240,7 +240,7 @@ tag_func_define_video (SwfdecSwfDecoder *s, guint tag)
   SWFDEC_LOG ("  deblocking: %d", deblocking);
   SWFDEC_LOG ("  smoothing: %d", smoothing);
   SWFDEC_LOG ("  format: %d", (int) video->format);
-  //swfdec_player_use_video_codec (SWFDEC_DECODER (s)->player, video->format);
+  swfdec_decoder_use_video_codec (SWFDEC_DECODER (s), video->format);
   return SWFDEC_STATUS_OK;
 }
 
commit 086097438e93215dffaf9fc8b21d7ab343ab820c
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 16:20:52 2008 +0200

    signals should be const

diff --git a/swfdec/swfdec_cached.c b/swfdec/swfdec_cached.c
index 173868e..5920385 100644
--- a/swfdec/swfdec_cached.c
+++ b/swfdec/swfdec_cached.c
@@ -38,7 +38,7 @@ enum {
   LAST_SIGNAL
 };
 
-guint signals[LAST_SIGNAL] = { 0, };
+static guint signals[LAST_SIGNAL] = { 0, };
 
 static void
 swfdec_cached_get_property (GObject *object, guint param_id, GValue *value,
commit 14dd3ce09d71d41b7f603b15c9914e3a88865bfc
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 10 15:16:59 2008 +0200

    get rid of SwfdecDecoder.player
    
    When we don't store a reference to the player in the decoder, we have a
    better seperation of data (SwfdecDecoder, SwfdecCharacter, ...) and runtime
    (SwfdecPlayer, SwfdecMovie, ...)
    
    open issues:
    - backgrounds (but we handle those wrong anyway)
    - codec detection

diff --git a/swfdec/swfdec_button.c b/swfdec/swfdec_button.c
index a0e32ed..26215ae 100644
--- a/swfdec/swfdec_button.c
+++ b/swfdec/swfdec_button.c
@@ -180,7 +180,7 @@ tag_func_define_button_2 (SwfdecSwfDecoder * s, guint tag)
     swfdec_bits_get_color_transform (&bits, &ctrans);
 
     if (has_filters) {
-      GSList *list = swfdec_filter_parse (SWFDEC_DECODER (s)->player, &bits);
+      GSList *list = swfdec_filter_parse (&bits);
       g_slist_free (list);
     }
     if (has_blend_mode) {
@@ -226,7 +226,7 @@ tag_func_define_button_2 (SwfdecSwfDecoder * s, guint tag)
     SWFDEC_LOG (" length = %d", length);
 
     if (button->events == NULL)
-      button->events = swfdec_event_list_new (SWFDEC_DECODER (s)->player);
+      button->events = swfdec_event_list_new ();
     SWFDEC_LOG ("  new event for condition %u (key %u)", condition, key);
     swfdec_event_list_parse (button->events, &bits, s->version, condition, key,
 	script_name);
@@ -285,7 +285,7 @@ tag_func_define_button (SwfdecSwfDecoder * s, guint tag)
 
   if (swfdec_bits_peek_u8 (&s->b)) {
     char *script_name = g_strdup_printf ("Button%u", id);
-    button->events = swfdec_event_list_new (SWFDEC_DECODER (s)->player);
+    button->events = swfdec_event_list_new ();
     SWFDEC_LOG ("  event for button press");
     swfdec_event_list_parse (button->events, &s->b, s->version, 1 << SWFDEC_EVENT_RELEASE, 
 	0, script_name);
diff --git a/swfdec/swfdec_button_movie.c b/swfdec/swfdec_button_movie.c
index 5b14015..90364f3 100644
--- a/swfdec/swfdec_button_movie.c
+++ b/swfdec/swfdec_button_movie.c
@@ -85,7 +85,7 @@ swfdec_button_movie_perform_place (SwfdecButtonMovie *button, SwfdecBits *bits)
       blend_mode = 0;
     }
     if (has_filters) {
-      GSList *filters = swfdec_filter_parse (player, bits);
+      GSList *filters = swfdec_filter_parse (bits);
       g_slist_free (filters);
     }
   } else {
diff --git a/swfdec/swfdec_decoder.c b/swfdec/swfdec_decoder.c
index f3a3289..e5b3e9a 100644
--- a/swfdec/swfdec_decoder.c
+++ b/swfdec/swfdec_decoder.c
@@ -43,12 +43,11 @@ swfdec_decoder_init (SwfdecDecoder *decoder)
 }
 
 SwfdecDecoder *
-swfdec_decoder_new (SwfdecPlayer *player, const SwfdecBuffer *buffer)
+swfdec_decoder_new (const SwfdecBuffer *buffer)
 {
   guchar *data;
   SwfdecDecoder *retval;
   
-  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
   g_return_val_if_fail (buffer != NULL, NULL);
 
   if (buffer->length < SWFDEC_DECODER_DETECT_LENGTH)
@@ -64,9 +63,6 @@ swfdec_decoder_new (SwfdecPlayer *player, const SwfdecBuffer *buffer)
   } else {
     retval = NULL;
   }
-  if (retval) {
-    retval->player = player;
-  }
   return retval;
 }
 
diff --git a/swfdec/swfdec_decoder.h b/swfdec/swfdec_decoder.h
index 1dc762c..2e454dd 100644
--- a/swfdec/swfdec_decoder.h
+++ b/swfdec/swfdec_decoder.h
@@ -58,7 +58,6 @@ struct _SwfdecDecoder
 {
   GObject		object;
 
-  SwfdecPlayer *	player;		/* FIXME: only needed to get the JS Context, I want it gone */
   SwfdecLoaderDataType	data_type;	/* type of the data we provide or UNKNOWN if not known yet */
   guint			rate;		/* rate per second in 256th */
   guint			width;		/* width of stream */
@@ -81,8 +80,7 @@ struct _SwfdecDecoderClass
 GType		swfdec_decoder_get_type		(void);
 
 #define SWFDEC_DECODER_DETECT_LENGTH 4
-SwfdecDecoder *	swfdec_decoder_new		(SwfdecPlayer *		player,
-						 const SwfdecBuffer *	buffer);
+SwfdecDecoder *	swfdec_decoder_new		(const SwfdecBuffer *	buffer);
 
 SwfdecStatus	swfdec_decoder_parse		(SwfdecDecoder *	decoder,
 						 SwfdecBuffer * 	buffer);
diff --git a/swfdec/swfdec_event.c b/swfdec/swfdec_event.c
index 876390e..136f4cd 100644
--- a/swfdec/swfdec_event.c
+++ b/swfdec/swfdec_event.c
@@ -24,7 +24,6 @@
 #include "swfdec_as_internal.h"
 #include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
-#include "swfdec_player_internal.h"
 #include "swfdec_script_internal.h"
 
 typedef struct _SwfdecEvent SwfdecEvent;
@@ -36,7 +35,6 @@ struct _SwfdecEvent {
 };
 
 struct _SwfdecEventList {
-  SwfdecPlayer *	player;
   guint			refcount;
   GArray *		events;
 };
@@ -103,14 +101,11 @@ swfdec_event_type_get_name (SwfdecEventType type)
 }
 
 SwfdecEventList *
-swfdec_event_list_new (SwfdecPlayer *player)
+swfdec_event_list_new (void)
 {
   SwfdecEventList *list;
 
-  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
-
   list = g_new0 (SwfdecEventList, 1);
-  list->player = player;
   list->refcount = 1;
   list->events = g_array_new (FALSE, FALSE, sizeof (SwfdecEvent));
 
diff --git a/swfdec/swfdec_event.h b/swfdec/swfdec_event.h
index 8d4ba68..ef69df3 100644
--- a/swfdec/swfdec_event.h
+++ b/swfdec/swfdec_event.h
@@ -56,7 +56,7 @@ typedef enum _SwfdecEventType {
 
 const char *		swfdec_event_type_get_name	(SwfdecEventType      type);
 
-SwfdecEventList *	swfdec_event_list_new		(SwfdecPlayer *	      player);
+SwfdecEventList *	swfdec_event_list_new		(void);
 SwfdecEventList *	swfdec_event_list_copy		(SwfdecEventList *    list);
 void			swfdec_event_list_free		(SwfdecEventList *    list);
 
diff --git a/swfdec/swfdec_filter.c b/swfdec/swfdec_filter.c
index b51561b..8bff38c 100644
--- a/swfdec/swfdec_filter.c
+++ b/swfdec/swfdec_filter.c
@@ -54,12 +54,11 @@ swfdec_filter_apply (SwfdecFilter *filter, cairo_pattern_t *pattern)
 }
 
 GSList *
-swfdec_filter_parse (SwfdecPlayer *player, SwfdecBits *bits)
+swfdec_filter_parse (SwfdecBits *bits)
 {
   GSList *filters = NULL;
   guint i, n_filters, filter_id;
 
-  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
   g_return_val_if_fail (bits != NULL, NULL);
 
   n_filters = swfdec_bits_get_u8 (bits);
diff --git a/swfdec/swfdec_filter.h b/swfdec/swfdec_filter.h
index ff0ce72..b15b9f7 100644
--- a/swfdec/swfdec_filter.h
+++ b/swfdec/swfdec_filter.h
@@ -52,8 +52,7 @@ GType			swfdec_filter_get_type	(void);
 
 cairo_pattern_t *	swfdec_filter_apply	(SwfdecFilter *		filter,
 						 cairo_pattern_t *	pattern);
-GSList *		swfdec_filter_parse	(SwfdecPlayer *		player,
-						 SwfdecBits *		bits);
+GSList *		swfdec_filter_parse	(SwfdecBits *		bits);
 
 
 G_END_DECLS
diff --git a/swfdec/swfdec_flv_decoder.c b/swfdec/swfdec_flv_decoder.c
index 35d9760..fe64cde 100644
--- a/swfdec/swfdec_flv_decoder.c
+++ b/swfdec/swfdec_flv_decoder.c
@@ -253,7 +253,7 @@ swfdec_flv_decoder_parse_video_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
   }
   if (flv->video->len == 0) {
     g_array_append_val (flv->video, tag);
-    swfdec_player_use_video_codec (SWFDEC_DECODER (flv)->player, tag.format);
+    //swfdec_player_use_video_codec (SWFDEC_DECODER (flv)->player, tag.format);
     return SWFDEC_STATUS_INIT;
   } else if (g_array_index (flv->video, SwfdecFlvVideoTag, 
 	flv->video->len - 1).timestamp < tag.timestamp) {
@@ -292,7 +292,7 @@ swfdec_flv_decoder_parse_audio_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
   }
   if (flv->audio->len == 0) {
     g_array_append_val (flv->audio, tag);
-    swfdec_player_use_audio_codec (SWFDEC_DECODER (flv)->player, tag.format, tag.original_format);
+    //swfdec_player_use_audio_codec (SWFDEC_DECODER (flv)->player, tag.format, tag.original_format);
     return SWFDEC_STATUS_INIT;
   } else if (g_array_index (flv->audio, SwfdecFlvAudioTag, 
 	flv->audio->len - 1).timestamp < tag.timestamp) {
diff --git a/swfdec/swfdec_net_stream.c b/swfdec/swfdec_net_stream.c
index 5db95d8..9b67804 100644
--- a/swfdec/swfdec_net_stream.c
+++ b/swfdec/swfdec_net_stream.c
@@ -269,7 +269,6 @@ swfdec_net_stream_stream_target_parse (SwfdecStreamTarget *target,
   if (ns->flvdecoder == NULL) {
     /* FIXME: add mp3 support */
     ns->flvdecoder = g_object_new (SWFDEC_TYPE_FLV_DECODER, NULL);
-    SWFDEC_DECODER (ns->flvdecoder)->player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (ns)->context);
     swfdec_net_stream_onstatus (ns, SWFDEC_AS_STR_NetStream_Play_Start,
 	SWFDEC_AS_STR_status);
     swfdec_loader_set_data_type (SWFDEC_LOADER (stream), SWFDEC_LOADER_DATA_FLV);
diff --git a/swfdec/swfdec_resource.c b/swfdec/swfdec_resource.c
index 4316359..210b7d2 100644
--- a/swfdec/swfdec_resource.c
+++ b/swfdec/swfdec_resource.c
@@ -267,8 +267,7 @@ swfdec_resource_stream_target_parse (SwfdecStreamTarget *target, SwfdecStream *s
     if (swfdec_buffer_queue_get_depth (queue) < SWFDEC_DECODER_DETECT_LENGTH)
       return FALSE;
     buffer = swfdec_buffer_queue_peek (queue, 4);
-    dec =
-      swfdec_decoder_new (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (resource)->context), buffer);
+    dec = swfdec_decoder_new (buffer);
     swfdec_buffer_unref (buffer);
     if (dec == NULL) {
       SWFDEC_ERROR ("no decoder found for format");
diff --git a/swfdec/swfdec_sound.c b/swfdec/swfdec_sound.c
index 76e21fc..53fe2c1 100644
--- a/swfdec/swfdec_sound.c
+++ b/swfdec/swfdec_sound.c
@@ -146,7 +146,7 @@ tag_func_define_sound (SwfdecSwfDecoder * s, guint tag)
   }
   sound->n_samples *= swfdec_audio_format_get_granularity (sound->format);
 
-  swfdec_player_use_audio_codec (SWFDEC_DECODER (s)->player, sound->codec, sound->format);
+  //swfdec_player_use_audio_codec (SWFDEC_DECODER (s)->player, sound->codec, sound->format);
 
   return SWFDEC_STATUS_OK;
 }
@@ -272,7 +272,7 @@ tag_func_sound_stream_head (SwfdecSwfDecoder * s, guint tag)
       sound->codec = SWFDEC_AUDIO_CODEC_UNDEFINED;
   }
 
-  swfdec_player_use_audio_codec (SWFDEC_DECODER (s)->player, sound->codec, sound->format);
+  //swfdec_player_use_audio_codec (SWFDEC_DECODER (s)->player, sound->codec, sound->format);
 
   return SWFDEC_STATUS_OK;
 }
diff --git a/swfdec/swfdec_sprite.c b/swfdec/swfdec_sprite.c
index f7bc576..a6759eb 100644
--- a/swfdec/swfdec_sprite.c
+++ b/swfdec/swfdec_sprite.c
@@ -125,6 +125,8 @@ swfdec_sprite_get_action (SwfdecSprite *sprite, guint n, guint *tag, SwfdecBuffe
 int
 tag_func_set_background_color (SwfdecSwfDecoder * s, guint tag)
 {
+  SWFDEC_FIXME ("fix background color handling");
+#if 0
   SwfdecPlayer *player = SWFDEC_DECODER (s)->player;
   SwfdecPlayerPrivate *priv = player->priv;
   SwfdecColor color = swfdec_bits_get_color (&s->b);
@@ -143,6 +145,7 @@ tag_func_set_background_color (SwfdecSwfDecoder * s, guint tag)
     g_array_index (priv->invalidations, SwfdecRectangle, 0) = priv->stage;
     g_object_notify (G_OBJECT (player), "background-color");
   }
+#endif
 
   return SWFDEC_STATUS_OK;
 }
diff --git a/swfdec/swfdec_sprite_movie.c b/swfdec/swfdec_sprite_movie.c
index 34104dc..2255982 100644
--- a/swfdec/swfdec_sprite_movie.c
+++ b/swfdec/swfdec_sprite_movie.c
@@ -247,7 +247,7 @@ swfdec_sprite_movie_perform_place (SwfdecSpriteMovie *movie, SwfdecBits *bits, g
   }
 
   if (has_filter) {
-    GSList *filters = swfdec_filter_parse (player, bits);
+    GSList *filters = swfdec_filter_parse (bits);
     g_slist_free (filters);
   }
 
@@ -262,7 +262,7 @@ swfdec_sprite_movie_perform_place (SwfdecSpriteMovie *movie, SwfdecBits *bits, g
     int reserved, clip_event_flags, event_flags, key_code;
     char *script_name;
 
-    events = swfdec_event_list_new (player);
+    events = swfdec_event_list_new ();
     reserved = swfdec_bits_get_u16 (bits);
     clip_event_flags = swfdec_get_clipeventflags (mov, bits);
 
diff --git a/swfdec/swfdec_video.c b/swfdec/swfdec_video.c
index 215c6dd..210813e 100644
--- a/swfdec/swfdec_video.c
+++ b/swfdec/swfdec_video.c
@@ -240,7 +240,7 @@ tag_func_define_video (SwfdecSwfDecoder *s, guint tag)
   SWFDEC_LOG ("  deblocking: %d", deblocking);
   SWFDEC_LOG ("  smoothing: %d", smoothing);
   SWFDEC_LOG ("  format: %d", (int) video->format);
-  swfdec_player_use_video_codec (SWFDEC_DECODER (s)->player, video->format);
+  //swfdec_player_use_video_codec (SWFDEC_DECODER (s)->player, video->format);
   return SWFDEC_STATUS_OK;
 }
 


More information about the Swfdec-commits mailing list