[Swfdec] 3 commits - libswfdec-gtk/swfdec_gtk_loader.c libswfdec/Makefile.am libswfdec/swfdec_codec.c libswfdec/swfdec_codec_ffmpeg.c libswfdec/swfdec_codec_gst.c libswfdec/swfdec_codec.h libswfdec/swfdec_codec_screen.c libswfdec/swfdec_codec_video.c libswfdec/swfdec_codec_video.h libswfdec/swfdec_flv_decoder.c libswfdec/swfdec_flv_decoder.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_net_stream.h libswfdec/swfdec_video.c libswfdec/swfdec_video.h libswfdec/swfdec_video_movie.c libswfdec/swfdec_video_movie.h player/Makefile.am player/swfplay.c

Benjamin Otte company at kemper.freedesktop.org
Fri Apr 6 06:45:56 PDT 2007


 libswfdec-gtk/swfdec_gtk_loader.c |   10 --
 libswfdec/Makefile.am             |    2 
 libswfdec/swfdec_codec.c          |   39 --------
 libswfdec/swfdec_codec.h          |   26 -----
 libswfdec/swfdec_codec_ffmpeg.c   |   98 ++++++++-------------
 libswfdec/swfdec_codec_gst.c      |  174 +++++++++++++++++++-------------------
 libswfdec/swfdec_codec_screen.c   |   60 +++++--------
 libswfdec/swfdec_codec_video.c    |  151 ++++++++++++++++++++++++++++++++
 libswfdec/swfdec_codec_video.h    |   57 ++++++++++++
 libswfdec/swfdec_flv_decoder.c    |   22 +---
 libswfdec/swfdec_flv_decoder.h    |    1 
 libswfdec/swfdec_net_stream.c     |   37 ++------
 libswfdec/swfdec_net_stream.h     |    4 
 libswfdec/swfdec_video.c          |   29 ------
 libswfdec/swfdec_video.h          |    9 -
 libswfdec/swfdec_video_movie.c    |    9 -
 libswfdec/swfdec_video_movie.h    |    4 
 player/Makefile.am                |    4 
 player/swfplay.c                  |   10 ++
 19 files changed, 418 insertions(+), 328 deletions(-)

New commits:
diff-tree f9ed2528c36837320c94bb1fec2313445c85c886 (from 25c390688e91b470212ae7eade090d28d0546a00)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Apr 6 15:45:20 2007 +0200

    revamp the video decoding API
    
    lots of code saved, and VP6 with GStreamer works now

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 0ad15c5..fa1abb6 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -35,6 +35,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_codec_adpcm.c \
 	$(CODECS) \
 	swfdec_codec_screen.c \
+	swfdec_codec_video.c \
 	swfdec_color.c \
 	swfdec_connection.c \
 	swfdec_debug.c \
@@ -122,6 +123,7 @@ noinst_HEADERS = \
 	swfdec_cached.h \
 	swfdec_character.h \
 	swfdec_codec.h \
+	swfdec_codec_video.h \
 	swfdec_color.h \
 	swfdec_connection.h \
 	swfdec_debug.h \
diff --git a/libswfdec/swfdec_codec.c b/libswfdec/swfdec_codec.c
index 8affa1c..32ad9cc 100644
--- a/libswfdec/swfdec_codec.c
+++ b/libswfdec/swfdec_codec.c
@@ -27,7 +27,6 @@
 /*** DECODER LIST ***/
 
 extern const SwfdecAudioCodec swfdec_codec_adpcm;
-extern const SwfdecVideoCodec swfdec_codec_screen;
 
 #ifdef HAVE_MAD
 extern const SwfdecAudioCodec swfdec_codec_mad;
@@ -35,11 +34,8 @@ extern const SwfdecAudioCodec swfdec_cod
 
 #ifdef HAVE_FFMPEG
 extern const SwfdecAudioCodec swfdec_codec_ffmpeg_audio;
-extern const SwfdecVideoCodec swfdec_codec_ffmpeg_video;
 #endif
 
-extern const SwfdecVideoCodec swfdec_codec_gst_video;
-
 /*** UNCOMPRESSED SOUND ***/
 
 #define U8_FLAG (0x10000)
@@ -144,38 +140,3 @@ swfdec_codec_get_audio (SwfdecAudioForma
   }
 }
 
-const SwfdecVideoCodec *
-swfdec_codec_get_video (SwfdecVideoFormat format)
-{
-  switch (format) {
-    case SWFDEC_VIDEO_FORMAT_SCREEN:
-      return &swfdec_codec_screen;
-#ifdef HAVE_FFMPEG
-      return &swfdec_codec_ffmpeg_video;
-#endif
-      SWFDEC_ERROR ("Screen video requires ffmpeg");
-      return NULL;
-    case SWFDEC_VIDEO_FORMAT_H263:
-#ifdef HAVE_GST
-      return &swfdec_codec_gst_video;
-#else
-#ifdef HAVE_FFMPEG
-      return &swfdec_codec_ffmpeg_video;
-#else
-      SWFDEC_ERROR ("H263 video requires ffmpeg or GStreamer");
-      return NULL;
-#endif
-#endif
-    case SWFDEC_VIDEO_FORMAT_VP6:
-#ifdef HAVE_GST
-      return &swfdec_codec_gst_video;
-#else
-      SWFDEC_ERROR ("VP6 video requires ffmpeg or GStreamer");
-      return NULL;
-#endif
-    default:
-      SWFDEC_ERROR ("video codec %u not implemented yet", (guint) format);
-      return NULL;
-  }
-}
-
diff --git a/libswfdec/swfdec_codec.h b/libswfdec/swfdec_codec.h
index a248170..1920e03 100644
--- a/libswfdec/swfdec_codec.h
+++ b/libswfdec/swfdec_codec.h
@@ -25,7 +25,6 @@
 #include <libswfdec/swfdec_buffer.h>
 
 typedef struct _SwfdecAudioCodec SwfdecAudioCodec;
-typedef struct _SwfdecVideoCodec SwfdecVideoCodec;
 
 typedef enum {
   SWFDEC_AUDIO_FORMAT_UNDEFINED = 0,
@@ -36,15 +35,6 @@ typedef enum {
   SWFDEC_AUDIO_FORMAT_NELLYMOSER = 6
 } SwfdecAudioFormat;
 
-typedef enum {
-  SWFDEC_VIDEO_FORMAT_UNDEFINED = 0,
-  SWFDEC_VIDEO_FORMAT_H263 = 2,
-  SWFDEC_VIDEO_FORMAT_SCREEN = 3,
-  SWFDEC_VIDEO_FORMAT_VP6 = 4,
-  SWFDEC_VIDEO_FORMAT_VP6_ALPHA = 5,
-  SWFDEC_VIDEO_FORMAT_SCREEN2 = 6
-} SwfdecVideoFormat;
-
 struct _SwfdecAudioCodec {
   gpointer		(* init)	(SwfdecAudioFormat	type,
 					 gboolean		width,
@@ -56,29 +46,13 @@ struct _SwfdecAudioCodec {
   SwfdecBuffer *	(* finish)	(gpointer		codec_data);
 };
 
-struct _SwfdecVideoCodec {
-  gpointer		(* init)	(SwfdecVideoFormat	type);
-  gboolean	    	(* get_size)	(gpointer		codec_data,
-					 guint *		width,
-					 guint *		height);
-  SwfdecBuffer *	(* decode)	(gpointer		codec_data,
-					 SwfdecBuffer *		buffer);
-  void			(* finish)	(gpointer		codec_data);
-};
-
 const SwfdecAudioCodec *   	swfdec_codec_get_audio		(SwfdecAudioFormat	format);
-const SwfdecVideoCodec *  	swfdec_codec_get_video		(SwfdecVideoFormat	format);
 
 #define swfdec_audio_codec_init(codec,type,width,format) (codec)->init (type, width, format)
 #define swfdec_audio_codec_get_format(codec, codec_data) (codec)->get_format (codec_data)
 #define swfdec_audio_codec_decode(codec, codec_data, buffer) (codec)->decode (codec_data, buffer)
 #define swfdec_audio_codec_finish(codec, codec_data) (codec)->finish (codec_data)
 
-#define swfdec_video_codec_init(codec,type) (codec)->init (type)
-#define swfdec_video_codec_get_size(codec, codec_data, width, height) (codec)->get_size (codec_data, width, height)
-#define swfdec_video_codec_decode(codec, codec_data, buffer) (codec)->decode (codec_data, buffer)
-#define swfdec_video_codec_finish(codec, codec_data) (codec)->finish (codec_data)
-
 
 G_END_DECLS
 #endif
diff --git a/libswfdec/swfdec_codec_ffmpeg.c b/libswfdec/swfdec_codec_ffmpeg.c
index 5f2dcaf..08b9c34 100644
--- a/libswfdec/swfdec_codec_ffmpeg.c
+++ b/libswfdec/swfdec_codec_ffmpeg.c
@@ -24,6 +24,7 @@
 #include <avcodec.h>
 
 #include "swfdec_codec.h"
+#include "swfdec_codec_video.h"
 #include "swfdec_debug.h"
 
 /*** GENERAL ***/
@@ -201,60 +202,16 @@ const SwfdecAudioCodec swfdec_codec_ffmp
 /*** VIDEO ***/
 
 typedef struct {
+  SwfdecVideoDecoder	decoder;
   AVCodecContext *	ctx;		/* out context (d'oh) */
   AVFrame *		frame;		/* the frame we use for decoding */
-} SwfdecCodecFFMpegVideo;
-
-static gpointer
-swfdec_codec_ffmpeg_video_init (SwfdecVideoFormat type)
-{
-  SwfdecCodecFFMpegVideo *codec;
-  AVCodecContext *ctx;
-  enum CodecID id;
-
-  switch (type) {
-    case SWFDEC_VIDEO_FORMAT_H263:
-      id = CODEC_ID_FLV1;
-      break;
-    case SWFDEC_VIDEO_FORMAT_SCREEN:
-      id = CODEC_ID_FLASHSV;
-      break;
-    default:
-      g_assert_not_reached ();
-      id = 0;
-      break;
-  }
-  ctx = swfdec_codec_ffmpeg_init (id);
-
-  if (ctx == NULL)
-    return NULL;
-  codec = g_new (SwfdecCodecFFMpegVideo, 1);
-  codec->ctx = ctx;
-  codec->frame = avcodec_alloc_frame ();
-
-  return codec;
-}
-
-static gboolean
-swfdec_codec_ffmpeg_video_get_size (gpointer codec_data,
-    guint *width, guint *height)
-{
-  SwfdecCodecFFMpegVideo *codec = codec_data;
-  AVCodecContext *ctx = codec->ctx;
-
-  if (ctx->width <= 0 || ctx->height <= 0)
-    return FALSE;
-
-  *width = ctx->width;
-  *height = ctx->height;
-
-  return TRUE;
-}
+} SwfdecVideoDecoderFFMpeg;
 
 SwfdecBuffer *
-swfdec_codec_ffmpeg_video_decode (gpointer codec_data, SwfdecBuffer *buffer)
+swfdec_video_decoder_ffmpeg_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer,
+    guint *width, guint *height, guint *rowstride)
 {
-  SwfdecCodecFFMpegVideo *codec = codec_data;
+  SwfdecVideoDecoderFFMpeg *codec = (SwfdecVideoDecoderFFMpeg *) dec;
   int got_image;
   SwfdecBuffer *ret;
   AVPicture picture;
@@ -270,23 +227,50 @@ swfdec_codec_ffmpeg_video_decode (gpoint
   img_convert (&picture, PIX_FMT_RGB32, 
       (AVPicture *) codec->frame, codec->ctx->pix_fmt,
       codec->ctx->width, codec->ctx->height);
+  *width = codec->ctx->width;
+  *height = codec->ctx->height;
+  *rowstride = codec->ctx->width * 4;
   return ret;
 }
 
 static void
-swfdec_codec_ffmpeg_video_finish (gpointer codec_data)
+swfdec_video_decoder_ffmpeg_free (SwfdecVideoDecoder *dec)
 {
-  SwfdecCodecFFMpegVideo *codec = codec_data;
+  SwfdecVideoDecoderFFMpeg *codec = (SwfdecVideoDecoderFFMpeg *) dec;
+
   avcodec_close (codec->ctx);
   av_free (codec->ctx);
   av_free (codec->frame);
+  g_free (codec);
 }
 
+SwfdecVideoDecoder *
+swfdec_video_decoder_ffmpeg_new (SwfdecVideoFormat type)
+{
+  SwfdecVideoDecoderFFMpeg *codec;
+  AVCodecContext *ctx;
+  enum CodecID id;
 
-const SwfdecVideoCodec swfdec_codec_ffmpeg_video = {
-  swfdec_codec_ffmpeg_video_init,
-  swfdec_codec_ffmpeg_video_get_size,
-  swfdec_codec_ffmpeg_video_decode,
-  swfdec_codec_ffmpeg_video_finish
-};
+  switch (type) {
+    case SWFDEC_VIDEO_FORMAT_H263:
+      id = CODEC_ID_FLV1;
+      break;
+    case SWFDEC_VIDEO_FORMAT_SCREEN:
+      id = CODEC_ID_FLASHSV;
+      break;
+    default:
+      return NULL;
+  }
+  ctx = swfdec_codec_ffmpeg_init (id);
+
+  if (ctx == NULL)
+    return NULL;
+  codec = g_new (SwfdecVideoDecoderFFMpeg, 1);
+  codec->decoder.decode = swfdec_video_decoder_ffmpeg_decode;
+  codec->decoder.free = swfdec_video_decoder_ffmpeg_free;
+  codec->ctx = ctx;
+  codec->frame = avcodec_alloc_frame ();
+
+  return &codec->decoder;
+}
 
diff --git a/libswfdec/swfdec_codec_gst.c b/libswfdec/swfdec_codec_gst.c
index c10a201..cd4f517 100644
--- a/libswfdec/swfdec_codec_gst.c
+++ b/libswfdec/swfdec_codec_gst.c
@@ -23,10 +23,10 @@
 #include <string.h>
 #include <gst/gst.h>
 
-#include "swfdec_codec.h"
+#include "swfdec_codec_video.h"
 #include "swfdec_debug.h"
 
-#if 1
+#if 0
 #define swfdec_cond_wait(cond, mutex) G_STMT_START { \
   g_print ("waiting at %s\n", G_STRLOC); \
   g_cond_wait (cond, mutex); \
@@ -38,6 +38,8 @@
 
 typedef struct _SwfdecGstVideo SwfdecGstVideo;
 struct _SwfdecGstVideo {
+  SwfdecVideoDecoder	decoder;
+
   GMutex *	  	mutex;		/* mutex that blocks everything below */
   GCond *		cond;		/* cond used to signal when stuff below changes */
   volatile int		refcount;	/* refcount (d'oh) */
@@ -48,6 +50,8 @@ struct _SwfdecGstVideo {
   int			width;		/* width of last output buffer */
   int			height;		/* height of last output buffer */
   GstCaps *		srccaps;	/* caps to set on buffers */
+  gboolean		out_next;	/* wether the pipeline expects input or output */
+  gboolean		error;		/* we're in an error state */
 };
 
 static void
@@ -68,9 +72,9 @@ swfdec_gst_video_unref (gpointer data, G
 }
 
 static void
-swfdec_codec_gst_video_finish (gpointer codec_data)
+swfdec_video_decoder_gst_free (SwfdecVideoDecoder *dec)
 {
-  SwfdecGstVideo *player = codec_data;
+  SwfdecGstVideo *player = (SwfdecGstVideo *) dec;
   GstElement *pipeline;
 
   g_mutex_lock (player->mutex);
@@ -84,22 +88,57 @@ swfdec_codec_gst_video_finish (gpointer 
   swfdec_gst_video_unref (player, NULL);
 }
 
+SwfdecBuffer *
+swfdec_video_decoder_gst_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer,
+    guint *width, guint *height, guint *rowstride)
+{
+  SwfdecGstVideo *player = (SwfdecGstVideo *) dec;
+
+  g_mutex_lock (player->mutex);
+  while (player->in != NULL && !player->error) {
+    swfdec_cond_wait (player->cond, player->mutex);
+  }
+  player->in = buffer;
+  g_cond_signal (player->cond);
+  while (player->out == NULL && !player->error) {
+    swfdec_cond_wait (player->cond, player->mutex);
+  }
+  if (player->error) {
+    g_mutex_unlock (player->mutex);
+    return NULL;
+  }
+  buffer = player->out;
+  player->out = NULL;
+  *width = player->width;
+  *height = player->height;
+  *rowstride = player->width * 4;
+  g_mutex_unlock (player->mutex);
+  return buffer;
+}
+
 static void
 swfdec_codec_gst_fakesrc_handoff (GstElement *fakesrc, GstBuffer *buf, 
     GstPad *pad, SwfdecGstVideo *player)
 {
   g_mutex_lock (player->mutex);
+  if (player->out_next) {
+    player->error = TRUE;
+    g_cond_signal (player->cond);
+    g_mutex_unlock (player->mutex);
+    return;
+  }
   while (player->pipeline != NULL && player->in == NULL)
     swfdec_cond_wait (player->cond, player->mutex);
   if (player->pipeline == NULL) {
     g_mutex_unlock (player->mutex);
     return;
   }
-  g_print ("got one\n");
   buf->data = g_memdup (player->in->data, player->in->length);
+  buf->malloc_data = buf->data;
   buf->size = player->in->length;
   gst_buffer_set_caps (buf, player->srccaps);
   player->in = NULL;
+  player->out_next = TRUE;
   g_cond_signal (player->cond);
   g_mutex_unlock (player->mutex);
 }
@@ -111,6 +150,12 @@ swfdec_codec_gst_fakesink_handoff (GstEl
   GstCaps *caps;
 
   g_mutex_lock (player->mutex);
+  if (!player->out_next) {
+    player->error = TRUE;
+    g_cond_signal (player->cond);
+    g_mutex_unlock (player->mutex);
+    return;
+  }
   caps = gst_buffer_get_caps (buf);
   if (caps) {
     GstStructure *structure = gst_caps_get_structure (caps, 0);
@@ -123,57 +168,60 @@ swfdec_codec_gst_fakesink_handoff (GstEl
   }
   while (player->pipeline != NULL && player->out != NULL)
     swfdec_cond_wait (player->cond, player->mutex);
-  if (player->pipeline == NULL)
+  if (player->pipeline == NULL) {
+    g_mutex_unlock (player->mutex);
     return;
-  g_print ("put one\n");
-  player->out = swfdec_buffer_new ();
-  player->out->data = g_memdup (buf->data, buf->size);
-  player->out->length = buf->size;
+  }
+  player->out = swfdec_buffer_new_for_data (
+      g_memdup (buf->data, buf->size), buf->size);
+  player->out_next = FALSE;
   g_cond_signal (player->cond);
   g_mutex_unlock (player->mutex);
 }
 
 static void
-do_the_link (GstElement *src, GstPad *pad, GstElement *sink)
+swfdec_codec_gst_do_link (GstElement *src, GstPad *pad, GstElement *sink)
 {
-  g_print ("link!\n");
   if (!gst_element_link (src, sink)) {
     SWFDEC_ERROR ("no delayed link");
   }
 }
 
-static gpointer
-swfdec_codec_gst_video_init (SwfdecVideoFormat type)
+SwfdecVideoDecoder *
+swfdec_video_decoder_gst_new (SwfdecVideoFormat type)
 {
   SwfdecGstVideo *player;
   GstElement *fakesrc, *fakesink, *decoder, *csp;
-  GstCaps *sinkcaps;
+  GstCaps *caps;
 
   if (!gst_init_check (NULL, NULL, NULL))
-    return FALSE;
+    return NULL;
 
-  player = g_slice_new0 (SwfdecGstVideo);
-  player->pipeline = gst_pipeline_new ("pipeline");
-  player->refcount = 1;
-  g_assert (player->pipeline);
-  player->mutex = g_mutex_new ();
-  player->cond = g_cond_new ();
   switch (type) {
     case SWFDEC_VIDEO_FORMAT_H263:
-      player->srccaps = gst_caps_from_string ("video/x-flash-video");
+      caps = gst_caps_from_string ("video/x-flash-video");
       break;
     case SWFDEC_VIDEO_FORMAT_VP6:
-      player->srccaps = gst_caps_from_string ("video/x-vp6-flash");
+      caps = gst_caps_from_string ("video/x-vp6-flash");
       break;
     default:
-      g_assert_not_reached ();
-      break;
+      return NULL;
   }
-  g_assert (player->srccaps);
+  g_assert (caps);
+
+  player = g_slice_new0 (SwfdecGstVideo);
+  player->decoder.decode = swfdec_video_decoder_gst_decode;
+  player->decoder.free = swfdec_video_decoder_gst_free;
+  player->pipeline = gst_pipeline_new ("pipeline");
+  player->refcount = 1;
+  g_assert (player->pipeline);
+  player->mutex = g_mutex_new ();
+  player->cond = g_cond_new ();
+  player->srccaps = caps;
   fakesrc = gst_element_factory_make ("fakesrc", NULL);
   if (fakesrc == NULL) {
     SWFDEC_ERROR ("failed to create fakesrc");
-    swfdec_codec_gst_video_finish (player);
+    swfdec_video_decoder_gst_free (&player->decoder);
     return NULL;
   }
   g_object_set (fakesrc, "signal-handoffs", TRUE, 
@@ -186,7 +234,7 @@ swfdec_codec_gst_video_init (SwfdecVideo
   fakesink = gst_element_factory_make ("fakesink", NULL);
   if (fakesink == NULL) {
     SWFDEC_ERROR ("failed to create fakesink");
-    swfdec_codec_gst_video_finish (player);
+    swfdec_video_decoder_gst_free (&player->decoder);
     return NULL;
   }
   g_object_set (fakesink, "signal-handoffs", TRUE, NULL);
@@ -198,85 +246,41 @@ swfdec_codec_gst_video_init (SwfdecVideo
   decoder = gst_element_factory_make ("decodebin", NULL);
   if (decoder == NULL) {
     SWFDEC_ERROR ("failed to create decoder");
-    swfdec_codec_gst_video_finish (player);
+    swfdec_video_decoder_gst_free (&player->decoder);
     return NULL;
   }
   gst_bin_add (GST_BIN (player->pipeline), decoder);
   csp = gst_element_factory_make ("ffmpegcolorspace", NULL);
   if (csp == NULL) {
     SWFDEC_ERROR ("failed to create colorspace");
-    swfdec_codec_gst_video_finish (player);
+    swfdec_video_decoder_gst_free (&player->decoder);
     return NULL;
   }
   gst_bin_add (GST_BIN (player->pipeline), csp);
-  g_signal_connect (decoder, "pad-added", G_CALLBACK (do_the_link), csp);
+  g_signal_connect (decoder, "pad-added", 
+      G_CALLBACK (swfdec_codec_gst_do_link), csp);
 
 #if G_BYTE_ORDER == G_BIG_ENDIAN
-  sinkcaps = gst_caps_from_string ("video/x-raw-rgb, bpp=32, endianness=4321, depth=24, "
+  caps = gst_caps_from_string ("video/x-raw-rgb, bpp=32, endianness=4321, depth=24, "
       "red_mask=16711680, green_mask=65280, blue_mask=255");
 #else
-  sinkcaps = gst_caps_from_string ("video/x-raw-rgb, bpp=32, endianness=4321, depth=24, "
+  caps = gst_caps_from_string ("video/x-raw-rgb, bpp=32, endianness=4321, depth=24, "
       "red_mask=65280, green_mask=16711680, blue_mask=-16777216");
 #endif
-  g_assert (sinkcaps);
+  g_assert (caps);
   if (!gst_element_link_filtered (fakesrc, decoder, player->srccaps) ||
-#if 0
-      !gst_element_link (decoder, csp) ||
-#endif
-      !gst_element_link_filtered (csp, fakesink, sinkcaps)) {
+      !gst_element_link_filtered (csp, fakesink, caps)) {
     SWFDEC_ERROR ("linking failed");
-    swfdec_codec_gst_video_finish (player);
+    swfdec_video_decoder_gst_free (&player->decoder);
     return NULL;
   }
-  gst_caps_unref (sinkcaps);
+  gst_caps_unref (caps);
   if (gst_element_set_state (player->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
     SWFDEC_ERROR ("failed to change sate");
-    swfdec_codec_gst_video_finish (player);
+    swfdec_video_decoder_gst_free (&player->decoder);
     return NULL;
   }
 
-  return player;
-}
-
-static gboolean
-swfdec_codec_gst_video_get_size (gpointer codec_data,
-    guint *width, guint *height)
-{
-  SwfdecGstVideo *player = codec_data;
-
-  g_mutex_lock (player->mutex);
-  if (player->width == 0 || player->height == 0) {
-    g_mutex_unlock (player->mutex);
-    return FALSE;
-  }
-  *width = player->width;
-  *height = player->height;
-  g_mutex_unlock (player->mutex);
-  return TRUE;
-}
-
-SwfdecBuffer *
-swfdec_codec_gst_video_decode (gpointer codec_data, SwfdecBuffer *buffer)
-{
-  SwfdecGstVideo *player = codec_data;
-
-  g_mutex_lock (player->mutex);
-  g_assert (player->in == NULL);
-  player->in = buffer;
-  g_cond_signal (player->cond);
-  while (player->out == NULL) {
-    swfdec_cond_wait (player->cond, player->mutex);
-  }
-  buffer = player->out;
-  player->out = NULL;
-  g_mutex_unlock (player->mutex);
-  return buffer;
+  return &player->decoder;
 }
 
-const SwfdecVideoCodec swfdec_codec_gst_video = {
-  swfdec_codec_gst_video_init,
-  swfdec_codec_gst_video_get_size,
-  swfdec_codec_gst_video_decode,
-  swfdec_codec_gst_video_finish
-};
-
diff --git a/libswfdec/swfdec_codec_screen.c b/libswfdec/swfdec_codec_screen.c
index 6c88696..369ff88 100644
--- a/libswfdec/swfdec_codec_screen.c
+++ b/libswfdec/swfdec_codec_screen.c
@@ -25,44 +25,24 @@
 #include <zlib.h>
 #include <liboil/liboil.h>
 
-#include "swfdec_codec.h"
+#include "swfdec_codec_video.h"
 #include "swfdec_bits.h"
 #include "swfdec_debug.h"
 
 typedef struct _SwfdecCodecScreen SwfdecCodecScreen;
 
 struct _SwfdecCodecScreen {
+  SwfdecVideoDecoder	decoder;	/* the decoder */
   gulong		width;		/* width of last image */
   gulong		height;		/* height of last image */
   SwfdecBuffer *	buffer;		/* buffer containing last decoded image */
 };
 
-static gpointer
-swfdec_codec_screen_init (SwfdecVideoFormat type)
-{
-  SwfdecCodecScreen *screen = g_new0 (SwfdecCodecScreen, 1);
-
-  return screen;
-}
-
-static gboolean
-swfdec_codec_screen_get_size (gpointer codec_data,
-    guint *width, guint *height)
-{
-  SwfdecCodecScreen *screen = codec_data;
-
-  if (screen->width == 0 || screen->height == 0)
-    return FALSE;
-
-  *width = screen->width;
-  *height = screen->height;
-  return TRUE;
-}
-#include <unistd.h>
 static SwfdecBuffer *
-swfdec_codec_screen_decode (gpointer codec_data, SwfdecBuffer *buffer)
+swfdec_video_decoder_screen_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer,
+    guint *width, guint *height, guint *rowstride)
 {
-  SwfdecCodecScreen *screen = codec_data;
+  SwfdecCodecScreen *screen = (SwfdecCodecScreen *) dec;
   SwfdecBuffer *ret;
   SwfdecBits bits;
   gulong i, j, w, h, bw, bh, stride;
@@ -82,7 +62,7 @@ swfdec_codec_screen_decode (gpointer cod
   } else if (screen->width != w || screen->height != h) {
     SWFDEC_ERROR ("width or height differ from original: was %lux%lu, is %lux%lu",
 	screen->width, screen->height, w, h);
-    /* FIXME: this is was ffmpeg does, should we be more forgiving? */
+    /* FIXME: this is what ffmpeg does, should we be more forgiving? */
     return NULL;
   }
   if (screen->buffer && screen->buffer->ref_count == 1) {
@@ -127,22 +107,34 @@ swfdec_codec_screen_decode (gpointer cod
       }
     }
   }
+  *width = screen->width;
+  *height = screen->height;
+  *rowstride = stride;
   return ret;
 }
 
 static void
-swfdec_codec_screen_finish (gpointer codec_data)
+swfdec_video_decoder_screen_free (SwfdecVideoDecoder *dec)
 {
-  SwfdecCodecScreen *screen = codec_data;
+  SwfdecCodecScreen *screen = (SwfdecCodecScreen *) dec;
 
   if (screen->buffer)
     swfdec_buffer_unref (screen->buffer);
   g_free (screen);
 }
 
-const SwfdecVideoCodec swfdec_codec_screen = {
-  swfdec_codec_screen_init,
-  swfdec_codec_screen_get_size,
-  swfdec_codec_screen_decode,
-  swfdec_codec_screen_finish
-};
+SwfdecVideoDecoder *
+swfdec_video_decoder_screen_new (SwfdecVideoFormat type)
+{
+  SwfdecCodecScreen *screen;
+  
+  if (type != SWFDEC_VIDEO_FORMAT_SCREEN)
+    return NULL;
+  
+  screen = g_new0 (SwfdecCodecScreen, 1);
+  screen->decoder.decode = swfdec_video_decoder_screen_decode;
+  screen->decoder.free = swfdec_video_decoder_screen_free;
+
+  return &screen->decoder;
+}
+
diff --git a/libswfdec/swfdec_codec_video.c b/libswfdec/swfdec_codec_video.c
new file mode 100644
index 0000000..b6a7185
--- /dev/null
+++ b/libswfdec/swfdec_codec_video.c
@@ -0,0 +1,151 @@
+/* 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec_codec_video.h"
+#include "swfdec_debug.h"
+
+extern SwfdecVideoDecoderNewFunc swfdec_video_decoder_screen_new;
+#ifdef HAVE_FFMPEG
+extern SwfdecVideoDecoderNewFunc swfdec_video_decoder_ffmpeg_new;
+#endif
+#ifdef HAVE_GST
+extern SwfdecVideoDecoderNewFunc swfdec_video_decoder_gst_new;
+#endif
+
+/**
+ * swfdec_video_decoder_new:
+ * @format: #SwfdecVideoFormat to create the #SwfdecVideoDecoder for
+ *
+ * Creates a new decoder to decode videos of type @format. If no suitable
+ * decoder could be created, %NULL is returned.
+ *
+ * Returns:
+ **/
+SwfdecVideoDecoder *
+swfdec_video_decoder_new (SwfdecVideoFormat format)
+{
+  SwfdecVideoDecoder *ret;
+
+  ret = swfdec_video_decoder_screen_new (format);
+#ifdef HAVE_FFMPEG
+  if (ret == NULL)
+    ret = swfdec_video_decoder_ffmpeg_new (format);
+#endif
+#ifdef HAVE_GST
+  if (ret == NULL)
+    ret = swfdec_video_decoder_gst_new (format);
+#endif
+
+  if (ret != NULL) {
+    ret->format = format;
+    g_return_val_if_fail (ret->decode, ret);
+    g_return_val_if_fail (ret->free, ret);
+  } else {
+    SWFDEC_WARNING ("no decoder found for codec %u\n", (guint) format);
+  }
+  return ret;
+}
+
+/**
+ * swfdec_video_decoder_free:
+ * @decoder: a #SwfdecVideoDecoder
+ *
+ * Frees the given @decoder and all associated ressources.
+ **/
+void
+swfdec_video_decoder_free (SwfdecVideoDecoder *decoder)
+{
+  g_return_if_fail (decoder);
+
+  decoder->free (decoder);
+}
+
+static void
+foo (gpointer data)
+{
+  //g_print ("boom baby %u\n", ((SwfdecBuffer *) data)->ref_count);
+  swfdec_buffer_unref (data);
+}
+/**
+ * swfdec_video_decoder_decode:
+ * @decoder: a #SwfdecVideoDecoder
+ * @buffer: buffer to decode
+ *
+ * Decodes the given buffer into an image surface.
+ *
+ * Returns: a new cairo image surface or %NULL on error.
+ **/
+cairo_surface_t *
+swfdec_video_decoder_decode (SwfdecVideoDecoder *decoder, SwfdecBuffer *buffer)
+{
+  static const cairo_user_data_key_t key;
+  cairo_surface_t *surface;
+  guint width, height, rowstride;
+
+  g_return_val_if_fail (decoder != NULL, NULL);
+  g_return_val_if_fail (buffer != NULL, NULL);
+
+  if (decoder->format == SWFDEC_VIDEO_FORMAT_VP6) {
+    guint wsub, hsub;
+    SwfdecBuffer *tmp;
+    wsub = *buffer->data;
+    hsub = wsub & 0xF;
+    wsub >>= 4;
+    tmp = swfdec_buffer_new_subbuffer (buffer, 1, buffer->length - 1);
+    buffer = decoder->decode (decoder, tmp, &width, &height, &rowstride);
+    swfdec_buffer_unref (tmp);
+    if (wsub >= width || hsub >= height) {
+      SWFDEC_ERROR ("size subtraction too big");
+      if (buffer)
+	swfdec_buffer_unref (buffer);
+      return NULL;
+    }
+    width -= wsub;
+    height -= hsub;
+  } else {
+    buffer = decoder->decode (decoder, buffer, &width, &height, &rowstride);
+  }
+  if (buffer == NULL) {
+    SWFDEC_ERROR ("failed to decode video");
+    return NULL;
+  }
+  if (width == 0 || height == 0 || rowstride < width * 4) {
+    SWFDEC_ERROR ("invalid image size");
+    swfdec_buffer_unref (buffer);
+    return NULL;
+  }
+  surface = cairo_image_surface_create_for_data (buffer->data, CAIRO_FORMAT_RGB24,
+      width, height, rowstride);
+  if (cairo_surface_status (surface)) {
+    SWFDEC_ERROR ("failed to create surface: %s", 
+	cairo_status_to_string (cairo_surface_status (surface)));
+    cairo_surface_destroy (surface);
+    swfdec_buffer_unref (buffer);
+    return NULL;
+  }
+  cairo_surface_set_user_data (surface, &key, buffer, 
+      foo);
+      //(cairo_destroy_func_t) swfdec_buffer_unref);
+  return surface;
+}
+
diff --git a/libswfdec/swfdec_codec_video.h b/libswfdec/swfdec_codec_video.h
new file mode 100644
index 0000000..010fe02
--- /dev/null
+++ b/libswfdec/swfdec_codec_video.h
@@ -0,0 +1,57 @@
+/* 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_CODEC_VIDEO_H_
+#define _SWFDEC_CODEC_VIDEO_H_
+
+#include <glib.h>
+#include <cairo.h>
+#include <libswfdec/swfdec_buffer.h>
+
+typedef enum {
+  SWFDEC_VIDEO_FORMAT_UNDEFINED = 0,
+  SWFDEC_VIDEO_FORMAT_H263 = 2,
+  SWFDEC_VIDEO_FORMAT_SCREEN = 3,
+  SWFDEC_VIDEO_FORMAT_VP6 = 4,
+  SWFDEC_VIDEO_FORMAT_VP6_ALPHA = 5,
+  SWFDEC_VIDEO_FORMAT_SCREEN2 = 6
+} SwfdecVideoFormat;
+
+typedef struct _SwfdecVideoDecoder SwfdecVideoDecoder;
+typedef SwfdecVideoDecoder * (SwfdecVideoDecoderNewFunc) (SwfdecVideoFormat format);
+
+struct _SwfdecVideoDecoder {
+  SwfdecVideoFormat	format;
+  SwfdecBuffer *	(* decode)	(SwfdecVideoDecoder *	decoder,
+					 SwfdecBuffer *		buffer,
+					 guint *		width,
+					 guint *		height,
+					 guint *		rowstride);
+  void			(* free)	(SwfdecVideoDecoder *	decoder);
+};
+
+SwfdecVideoDecoder *	swfdec_video_decoder_new      	(SwfdecVideoFormat	format);
+void			swfdec_video_decoder_free	(SwfdecVideoDecoder *   decoder);
+
+cairo_surface_t *     	swfdec_video_decoder_decode	(SwfdecVideoDecoder *	decoder,
+							 SwfdecBuffer *		buffer);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index ac644e2..b6dfff0 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -269,23 +269,19 @@ swfdec_flv_decoder_parse_video_tag (Swfd
   }
   if (dec->width == 0 && dec->height == 0) {
     SwfdecFlvVideoTag *tag = &g_array_index (flv->video, SwfdecFlvVideoTag, 0);
-    const SwfdecVideoCodec *codec = swfdec_codec_get_video (tag->format);
-    gpointer decoder;
-    SwfdecBuffer *ignore;
+    SwfdecVideoDecoder *decoder;
+    cairo_surface_t *surface;
 
-    if (codec == NULL)
-      return SWFDEC_STATUS_OK;
-    decoder = swfdec_video_codec_init (codec, tag->format);
+    /* nice hack... */
+    decoder = swfdec_video_decoder_new (tag->format);
     if (decoder == NULL)
       return SWFDEC_STATUS_OK;
-    ignore = swfdec_video_codec_decode (codec, decoder, tag->buffer);
-    if (ignore)
-      swfdec_buffer_unref (ignore);
-    if (!swfdec_video_codec_get_size (codec, decoder, &dec->width, &dec->height)) {
-      swfdec_video_codec_finish (codec, decoder);
+    surface = swfdec_video_decoder_decode (decoder, tag->buffer);
+    if (surface == NULL)
       return SWFDEC_STATUS_OK;
-    }
-    swfdec_video_codec_finish (codec, decoder);
+    dec->width = cairo_image_surface_get_width (surface);
+    dec->height = cairo_image_surface_get_height (surface);
+    swfdec_video_decoder_free (decoder);
     return SWFDEC_STATUS_INIT;
   } else {
     return SWFDEC_STATUS_IMAGE;
diff --git a/libswfdec/swfdec_flv_decoder.h b/libswfdec/swfdec_flv_decoder.h
index 7bb9c72..c26b169 100644
--- a/libswfdec/swfdec_flv_decoder.h
+++ b/libswfdec/swfdec_flv_decoder.h
@@ -21,6 +21,7 @@
 #define __SWFDEC_FLV_DECODER_H__
 
 #include <libswfdec/swfdec_codec.h>
+#include <libswfdec/swfdec_codec_video.h>
 #include <libswfdec/swfdec_decoder.h>
 
 G_BEGIN_DECLS
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 7e16631..d0ab3e6 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -85,32 +85,17 @@ swfdec_net_stream_video_goto (SwfdecNetS
   } else {
     if (format != stream->format) {
       if (stream->decoder)
-	swfdec_video_codec_finish (stream->codec, stream->decoder);
+	swfdec_video_decoder_free (stream->decoder);
       stream->format = format;
-      stream->codec = swfdec_codec_get_video (format);
-      if (stream->codec)
-	stream->decoder = swfdec_video_codec_init (stream->codec, format);
-      else
-	stream->decoder = NULL;
+      stream->decoder = swfdec_video_decoder_new (format);
     }
     if (stream->decoder) {
-      SwfdecBuffer *decoded = swfdec_video_codec_decode (stream->codec, stream->decoder, buffer);
-      if (decoded) {
-	static const cairo_user_data_key_t key;
-	guint w, h;
-	if (!swfdec_video_codec_get_size (stream->codec, stream->decoder, &w, &h)) {
-	    g_assert_not_reached ();
-	}
-	stream->surface = cairo_image_surface_create_for_data (decoded->data, 
-	    CAIRO_FORMAT_RGB24, w, h, w * 4);
-	cairo_surface_set_user_data (stream->surface, &key, 
-	    decoded, (cairo_destroy_func_t) swfdec_buffer_unref);
-	if (old != stream->surface) {
-	  GList *walk;
-	  for (walk = stream->movies; walk; walk = walk->next) {
-	    swfdec_video_movie_new_image (walk->data, stream->surface, w, h);
-	  }
-	}
+      stream->surface = swfdec_video_decoder_decode (stream->decoder, buffer);
+    }
+    if (stream->surface) {
+      GList *walk;
+      for (walk = stream->movies; walk; walk = walk->next) {
+	swfdec_video_movie_new_image (walk->data, stream->surface);
       }
     }
   }
@@ -336,8 +321,10 @@ swfdec_net_stream_dispose (GObject *obje
     cairo_surface_destroy (stream->surface);
     stream->surface = NULL;
   }
-  if (stream->decoder)
-    swfdec_video_codec_finish (stream->codec, stream->decoder);
+  if (stream->decoder) {
+    swfdec_video_decoder_free (stream->decoder);
+    stream->decoder = NULL;
+  }
   swfdec_net_stream_set_loader (stream, NULL);
   g_object_unref (stream->conn);
   stream->conn = NULL;
diff --git a/libswfdec/swfdec_net_stream.h b/libswfdec/swfdec_net_stream.h
index 7973b5f..9a1ff11 100644
--- a/libswfdec/swfdec_net_stream.h
+++ b/libswfdec/swfdec_net_stream.h
@@ -21,6 +21,7 @@
 #define _SWFDEC_NET_STREAM_H_
 
 #include <libswfdec/swfdec.h>
+#include <libswfdec/swfdec_codec_video.h>
 #include <libswfdec/swfdec_connection.h>
 #include <libswfdec/swfdec_flv_decoder.h>
 #include <libswfdec/swfdec_player_internal.h>
@@ -58,8 +59,7 @@ struct _SwfdecNetStream
   guint			current_time;	/* current playback timestamp */
   guint			next_time;	/* next video image at this timestamp */
   SwfdecVideoFormat	format;		/* current format */
-  const SwfdecVideoCodec *codec;	/* codec used to decode the video */
-  gpointer		decoder;	/* decoder used for decoding */
+  SwfdecVideoDecoder *	decoder;	/* decoder used for decoding */
   cairo_surface_t *	surface;	/* current image */
   SwfdecTimeout		timeout;	/* timeout to advance to */
   SwfdecVideoMovieInput	input;		/* used when attaching to a video movie */
diff --git a/libswfdec/swfdec_video.c b/libswfdec/swfdec_video.c
index 70afa13..eb682b1 100644
--- a/libswfdec/swfdec_video.c
+++ b/libswfdec/swfdec_video.c
@@ -70,8 +70,6 @@ swfdec_video_input_iterate (SwfdecVideoM
 {
   SwfdecVideoInput *input = (SwfdecVideoInput *) input_;
   SwfdecBuffer *buffer;
-  static const cairo_user_data_key_t key;
-  guint w, h;
   cairo_surface_t *surface;
 
   input->current_frame = (input->current_frame + 1) % input->video->n_frames;
@@ -81,17 +79,8 @@ swfdec_video_input_iterate (SwfdecVideoM
   if (buffer == NULL)
     return;
 
-  buffer = swfdec_video_codec_decode (input->video->codec, input->decoder, buffer);
-  if (buffer == NULL)
-    return;
-  if (!swfdec_video_codec_get_size (input->video->codec, input->decoder, &w, &h)) {
-      g_assert_not_reached ();
-  }
-  surface = cairo_image_surface_create_for_data (buffer->data, 
-      CAIRO_FORMAT_RGB24, w, h, w * 4);
-  cairo_surface_set_user_data (surface, &key, 
-      buffer, (cairo_destroy_func_t) swfdec_buffer_unref);
-  swfdec_video_movie_new_image (input->movie, surface, w, h);
+  surface = swfdec_video_decoder_decode (input->decoder, buffer);
+  swfdec_video_movie_new_image (input->movie, surface);
   cairo_surface_destroy (surface);
 }
 
@@ -111,7 +100,7 @@ swfdec_video_input_disconnect (SwfdecVid
 
   g_assert (input->movie == movie);
   if (input->decoder)
-    swfdec_video_codec_finish (input->video->codec, input->decoder);
+    swfdec_video_decoder_free (input->decoder);
   g_object_unref (input->video);
   g_free (input);
 }
@@ -123,11 +112,8 @@ swfdec_video_input_new (SwfdecVideo *vid
   
   if (video->n_frames == 0)
     return NULL;
-  if (video->codec == NULL)
-    return NULL;
   input = g_new0 (SwfdecVideoInput, 1);
-  if (video->codec)
-    input->decoder = swfdec_video_codec_init (video->codec, video->format);
+  input->decoder = swfdec_video_decoder_new (video->format);
   if (input->decoder == NULL) {
     g_free (input);
     return NULL;
@@ -214,13 +200,6 @@ tag_func_define_video (SwfdecSwfDecoder 
   SWFDEC_LOG ("  deblocking: %d", deblocking);
   SWFDEC_LOG ("  smoothing: %d", smoothing);
   SWFDEC_LOG ("  format: %d", (int) video->format);
-  if (video->format != SWFDEC_VIDEO_FORMAT_UNDEFINED) {
-    video->codec = swfdec_codec_get_video (video->format);
-    if (video->codec == NULL) {
-      SWFDEC_WARNING ("no codec for format %d", (int) video->format);
-      return SWFDEC_STATUS_OK;
-    }
-  }
   return SWFDEC_STATUS_OK;
 }
 
diff --git a/libswfdec/swfdec_video.h b/libswfdec/swfdec_video.h
index 97c997f..a64065b 100644
--- a/libswfdec/swfdec_video.h
+++ b/libswfdec/swfdec_video.h
@@ -21,7 +21,7 @@
 #define _SWFDEC_VIDEO_H_
 
 #include <libswfdec/swfdec_graphic.h>
-#include <libswfdec/swfdec_codec.h>
+#include <libswfdec/swfdec_codec_video.h>
 
 G_BEGIN_DECLS
 
@@ -37,13 +37,12 @@ typedef struct _SwfdecVideoClass SwfdecV
 struct _SwfdecVideo {
   SwfdecGraphic			graphic;
 
-  guint			width;		/* width in pixels */
-  guint			height;		/* height in pixels */
-  guint			n_frames;	/* length of movie */
+  guint				width;		/* width in pixels */
+  guint				height;		/* height in pixels */
+  guint				n_frames;	/* length of movie */
   GArray *			images;		/* actual images of the movie */
   
   SwfdecVideoFormat		format;		/* format in use */
-  const SwfdecVideoCodec *	codec;		/* codec for this video (can be NULL) */
 };
 
 struct _SwfdecVideoClass {
diff --git a/libswfdec/swfdec_video_movie.c b/libswfdec/swfdec_video_movie.c
index cf74a92..6c94d73 100644
--- a/libswfdec/swfdec_video_movie.c
+++ b/libswfdec/swfdec_video_movie.c
@@ -142,20 +142,17 @@ swfdec_video_movie_clear (SwfdecVideoMov
 }
 
 void
-swfdec_video_movie_new_image (SwfdecVideoMovie *movie, cairo_surface_t *image,
-    guint width, guint height)
+swfdec_video_movie_new_image (SwfdecVideoMovie *movie, cairo_surface_t *image)
 {
   g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
   g_return_if_fail (image != NULL);
-  g_return_if_fail (width > 0);
-  g_return_if_fail (height > 0);
 
   if (movie->image)
     cairo_surface_destroy (movie->image);
   cairo_surface_reference (image);
   movie->image = image;
-  movie->image_width = width;
-  movie->image_height = height;
+  movie->image_width = cairo_image_surface_get_width (image);
+  movie->image_height = cairo_image_surface_get_height (image);
   swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
 }
 
diff --git a/libswfdec/swfdec_video_movie.h b/libswfdec/swfdec_video_movie.h
index 87ee9c9..9ba9f1a 100644
--- a/libswfdec/swfdec_video_movie.h
+++ b/libswfdec/swfdec_video_movie.h
@@ -70,9 +70,7 @@ void		swfdec_video_movie_set_input		(Swf
 void		swfdec_video_movie_clear	      	(SwfdecVideoMovie *	movie);
 /* API for SwfdecVideoMovieInput */
 void		swfdec_video_movie_new_image		(SwfdecVideoMovie *	movie,
-							 cairo_surface_t *	surface,
-							 guint			width,
-							 guint			height);
+							 cairo_surface_t *	surface);
 
 G_END_DECLS
 #endif
diff-tree 25c390688e91b470212ae7eade090d28d0546a00 (from 9df37a6370130977093126a74e1d2341e07399d5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Apr 6 15:44:43 2007 +0200

    fix gnome-vfs integratrion to use the right conversion func
    
    I hope this was the last time...

diff --git a/player/Makefile.am b/player/Makefile.am
index d22e527..11c0b56 100644
--- a/player/Makefile.am
+++ b/player/Makefile.am
@@ -24,8 +24,8 @@ noinst_HEADERS = \
 	swfdec_player_manager.h \
 	swfdec_slow_loader.h
 
-swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS)
-swfplay_LDFLAGS = $(GTK_LIBS) $(SWFDEC_GTK_LIBS)
+swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS) $(GNOMEVFS_CFLAGS)
+swfplay_LDFLAGS = $(GTK_LIBS) $(SWFDEC_GTK_LIBS) $(GNOMEVFS_LIBS)
 
 swfdebug_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js
 swfdebug_LDFLAGS = $(GTK_LIBS) $(SWFDEC_GTK_LIBS)
diff --git a/player/swfplay.c b/player/swfplay.c
index 78c5c48..7cc4dbe 100644
--- a/player/swfplay.c
+++ b/player/swfplay.c
@@ -25,6 +25,9 @@
 #include <libswfdec/swfdec.h>
 
 #include <libswfdec-gtk/swfdec-gtk.h>
+#if HAVE_GNOMEVFS
+#include <libgnomevfs/gnome-vfs.h>
+#endif
 
 #include "swfdec_slow_loader.h"
 
@@ -76,6 +79,7 @@ main (int argc, char *argv[])
   gboolean trace = FALSE;
   char *variables = NULL;
   GtkWidget *window;
+  char *s;
 
   GOptionEntry options[] = {
     { "delay", 'd', 0, G_OPTION_ARG_INT, &delay, "make loading of resources take time", "SECS" },
@@ -109,7 +113,13 @@ main (int argc, char *argv[])
     return 1;
   }
 
+#if HAVE_GNOMEVFS
+  s = gnome_vfs_make_uri_from_shell_arg (argv[1]);
+  loader = swfdec_gtk_loader_new (s);
+  g_free (s);
+#else
   loader = swfdec_gtk_loader_new (argv[1]);
+#endif
   if (loader->error) {
     g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], loader->error);
     g_object_unref (loader);
diff-tree 9df37a6370130977093126a74e1d2341e07399d5 (from bb03d104fbecb67c43dd6822288f57a73e6897c3)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Apr 6 13:58:50 2007 +0200

    back out calling gnome_vfs_make_uri_from_input()
    
    LEt the user do this and document that it's a good idea

diff --git a/libswfdec-gtk/swfdec_gtk_loader.c b/libswfdec-gtk/swfdec_gtk_loader.c
index f0e8c40..1247a30 100644
--- a/libswfdec-gtk/swfdec_gtk_loader.c
+++ b/libswfdec-gtk/swfdec_gtk_loader.c
@@ -225,8 +225,9 @@ swfdec_gtk_loader_init (SwfdecGtkLoader 
  *
  * Creates a new loader for the given URI using gnome-vfs (or using the local
  * file backend, if compiled without gnome-vfs support). The uri must be valid
- * UTF-8. If using gnome-vfs, gnome_vfs_make_uri_from_input() will be called on
- * @uri.
+ * UTF-8. If using gnome-vfs, you might want to use 
+ * gnome_vfs_make_uri_from_shell_arg() or gnome_vfs_make_uri_from_input() on
+ * the @uri prior to calling this function.
  *
  * Returns: a new #SwfdecLoader using gnome-vfs.
  **/
@@ -234,14 +235,11 @@ SwfdecLoader *
 swfdec_gtk_loader_new (const char *uri)
 {
   GnomeVFSURI *guri;
-  char *s;
 
   g_return_val_if_fail (uri != NULL, NULL);
 
   gnome_vfs_init ();
-  s = gnome_vfs_make_uri_from_input (uri);
-  guri = gnome_vfs_uri_new (s);
-  g_free (s);
+  guri = gnome_vfs_uri_new (uri);
   return swfdec_gtk_loader_new_from_uri (guri);
 }
 


More information about the Swfdec mailing list