[Swfdec] 9 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame_internal.h libswfdec/swfdec_as_object.c libswfdec/swfdec_codec_gst.c test/trace

Benjamin Otte company at kemper.freedesktop.org
Sun Oct 28 07:47:24 PDT 2007


 libswfdec/swfdec_as_context.c          |   14 -
 libswfdec/swfdec_as_frame.c            |   19 ++
 libswfdec/swfdec_as_frame_internal.h   |    1 
 libswfdec/swfdec_as_object.c           |    4 
 libswfdec/swfdec_codec_gst.c           |  281 +++++++++------------------------
 test/trace/Makefile.am                 |    7 
 test/trace/catch-in-caller-6.swf       |binary
 test/trace/catch-in-caller-6.swf.trace |    3 
 test/trace/catch-in-caller-7.swf       |binary
 test/trace/catch-in-caller-7.swf.trace |    3 
 test/trace/catch-in-caller-8.swf       |binary
 test/trace/catch-in-caller-8.swf.trace |    3 
 test/trace/catch-in-caller.as          |   16 +
 13 files changed, 140 insertions(+), 211 deletions(-)

New commits:
commit 6e1490dedda306bdd385d9490ecc6737d07b7099
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Oct 28 15:46:55 2007 +0100

    we need to check_block(), not pop_block()

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 2c3fdbd..c902406 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -799,7 +799,7 @@ swfdec_as_frame_handle_exception (SwfdecAsFrame *frame)
 
   /* pop blocks in the hope that we are inside a Try block */
   while (cx->exception && frame->blocks->len) {
-    swfdec_as_frame_pop_block (frame);
+    swfdec_as_frame_check_block (frame);
   }
   /* exit frame, nothing caught the exception */
   if (cx->exception) {
commit a696fb3a36815396e9bfcf3eaeaff078e9c44713
Merge: bdc9305... c591a9e...
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Oct 28 15:27:26 2007 +0100

    Merge branch 'master' of ssh://company@git.freedesktop.org/git/swfdec/swfdec
    
    Conflicts:
    
    	libswfdec/swfdec_as_context.c

diff --cc libswfdec/swfdec_as_context.c
index c47e984,8fcd976..f83632f
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@@ -856,16 -856,16 +856,12 @@@ start
    check_block = TRUE;
  
    while (context->state < SWFDEC_AS_CONTEXT_ABORTED) {
-     while (context->exception && frame->blocks->len > 0) {
-       frame->pc = frame->block_end;
-       swfdec_as_frame_check_block (frame);
-       pc = frame->pc;
-     }
 -    // in case of an exception, skip blocks until exception is cleared or we
 -    // run out of blocks
 -    while (context->exception && frame->blocks->len > 0) {
 -      frame->pc = frame->block_end;
 -      swfdec_as_frame_check_block (frame);
 -      pc = frame->pc;
 -    }
      if (context->exception) {
 -      SWFDEC_ERROR ("Unhandled exception");
 -      goto error;
 +      swfdec_as_frame_handle_exception (frame);
 +      if (frame != context->frame)
 +	goto start;
++      pc = frame->pc;
 +      continue;
      }
      if (check_block && (pc < frame->block_start || pc >= frame->block_end)) {
        SWFDEC_LOG ("code exited block");
commit bdc93056cf0231c876bc5942daf1a05d7feac4ea
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Oct 28 15:25:12 2007 +0100

    test catching outside the throwing function

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 2ff2699..739279c 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -248,6 +248,13 @@ EXTRA_DIST = \
 	cast-7.swf.trace \
 	cast-8.swf \
 	cast-8.swf.trace \
+	catch-in-caller.as \
+	catch-in-caller-6.swf \
+	catch-in-caller-6.swf.trace \
+	catch-in-caller-7.swf \
+	catch-in-caller-7.swf.trace \
+	catch-in-caller-8.swf \
+	catch-in-caller-8.swf.trace \
 	charat.as \
 	charat-5.swf \
 	charat-5.swf.trace \
diff --git a/test/trace/catch-in-caller-6.swf b/test/trace/catch-in-caller-6.swf
new file mode 100644
index 0000000..e1a90af
Binary files /dev/null and b/test/trace/catch-in-caller-6.swf differ
diff --git a/test/trace/catch-in-caller-6.swf.trace b/test/trace/catch-in-caller-6.swf.trace
new file mode 100644
index 0000000..ed03e81
--- /dev/null
+++ b/test/trace/catch-in-caller-6.swf.trace
@@ -0,0 +1,3 @@
+Throw inside a function and catch outside of that function
+hi
+done
diff --git a/test/trace/catch-in-caller-7.swf b/test/trace/catch-in-caller-7.swf
new file mode 100644
index 0000000..4de1513
Binary files /dev/null and b/test/trace/catch-in-caller-7.swf differ
diff --git a/test/trace/catch-in-caller-7.swf.trace b/test/trace/catch-in-caller-7.swf.trace
new file mode 100644
index 0000000..ed03e81
--- /dev/null
+++ b/test/trace/catch-in-caller-7.swf.trace
@@ -0,0 +1,3 @@
+Throw inside a function and catch outside of that function
+hi
+done
diff --git a/test/trace/catch-in-caller-8.swf b/test/trace/catch-in-caller-8.swf
new file mode 100644
index 0000000..b9c3751
Binary files /dev/null and b/test/trace/catch-in-caller-8.swf differ
diff --git a/test/trace/catch-in-caller-8.swf.trace b/test/trace/catch-in-caller-8.swf.trace
new file mode 100644
index 0000000..ed03e81
--- /dev/null
+++ b/test/trace/catch-in-caller-8.swf.trace
@@ -0,0 +1,3 @@
+Throw inside a function and catch outside of that function
+hi
+done
diff --git a/test/trace/catch-in-caller.as b/test/trace/catch-in-caller.as
new file mode 100644
index 0000000..acdcce1
--- /dev/null
+++ b/test/trace/catch-in-caller.as
@@ -0,0 +1,16 @@
+// makeswf -v 7 -s 200x150 -r 1 -o movie23.swf movie23.as
+
+trace ("Throw inside a function and catch outside of that function");
+
+function foo () {
+  throw "hi";
+};
+
+try {
+  foo ();
+} catch (e) {
+  trace (e);
+};
+trace ("done");
+
+loadMovie ("FSCommand:quit", "");
commit c896bd95809ce52619ca47a11fbbeb1a9014bd43
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Oct 28 15:22:22 2007 +0100

    fix exception catching code, when the catch() is in a function further up

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 663a15c..c47e984 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -856,17 +856,16 @@ start:
   check_block = TRUE;
 
   while (context->state < SWFDEC_AS_CONTEXT_ABORTED) {
-    // in case of an exception, skip blocks until exception is cleared or we
-    // run out of blocks
     while (context->exception && frame->blocks->len > 0) {
       frame->pc = frame->block_end;
       swfdec_as_frame_check_block (frame);
       pc = frame->pc;
     }
     if (context->exception) {
-      SWFDEC_ERROR ("Unhandled exception: %s",
-	  swfdec_as_value_to_string (context, &context->exception_value));
-      goto error;
+      swfdec_as_frame_handle_exception (frame);
+      if (frame != context->frame)
+	goto start;
+      continue;
     }
     if (check_block && (pc < frame->block_start || pc >= frame->block_end)) {
       SWFDEC_LOG ("code exited block");
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 841f438..2c3fdbd 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -788,6 +788,25 @@ out:
   }
 }
 
+void
+swfdec_as_frame_handle_exception (SwfdecAsFrame *frame)
+{
+  SwfdecAsContext *cx;
+
+  g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
+  cx = SWFDEC_AS_OBJECT (frame)->context;
+  g_return_if_fail (cx->exception);
+
+  /* pop blocks in the hope that we are inside a Try block */
+  while (cx->exception && frame->blocks->len) {
+    swfdec_as_frame_pop_block (frame);
+  }
+  /* exit frame, nothing caught the exception */
+  if (cx->exception) {
+    swfdec_as_frame_return (frame, NULL);
+  }
+}
+
 /**
  * swfdec_as_frame_get_next:
  * @frame: a #SwfdecAsFrame
diff --git a/libswfdec/swfdec_as_frame_internal.h b/libswfdec/swfdec_as_frame_internal.h
index b09fb9c..1e2075d 100644
--- a/libswfdec/swfdec_as_frame_internal.h
+++ b/libswfdec/swfdec_as_frame_internal.h
@@ -105,6 +105,7 @@ void		swfdec_as_frame_push_block	(SwfdecAsFrame *	frame,
 						 GDestroyNotify		destroy);
 void		swfdec_as_frame_pop_block	(SwfdecAsFrame *	frame);
 void		swfdec_as_frame_check_block	(SwfdecAsFrame *	frame);
+void		swfdec_as_frame_handle_exception(SwfdecAsFrame *	frame);
 
 
 G_END_DECLS
commit 2068cff060c579a7b11aaffd36f7f1613a828934
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Oct 28 15:19:51 2007 +0100

    don't crash when the context was aborted

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index a5f7866..cc6be1a 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -1113,6 +1113,8 @@ swfdec_as_object_call_with_security (SwfdecAsObject *object, SwfdecSecurity *sec
   if (!SWFDEC_IS_AS_FUNCTION (fun))
     return;
   swfdec_as_function_call (fun, object, argc, argv, return_value ? return_value : &tmp);
+  if (swfdec_as_context_is_aborted (object->context))
+    return;
   swfdec_as_frame_set_security (object->context->frame, sec);
   swfdec_as_context_run (object->context);
 }
commit 59f5e77bc3cd708f7e4417d534c0b7fb5195689c
Merge: d41b6eb... 27e0f57...
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Oct 28 14:21:50 2007 +0100

    Merge branch 'master' of ssh://company@git.freedesktop.org/git/swfdec/swfdec

commit d41b6eb0a9a32f16c2a6fd6f05ca9ef0f59be76c
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat Oct 27 00:11:51 2007 +0200

    typo in docs

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 2ae087b..a5f7866 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -67,7 +67,7 @@
  * SwfdecAsVariableFlag:
  * @SWFDEC_AS_VARIABLE_HIDDEN: Do not include variable in enumerations and
  *                                swfdec_as_object_foreach().
- * @SWFDEC_AS_VARIABLE_PERMANENT: Do not all swfdec_as_object_delete_variable()
+ * @SWFDEC_AS_VARIABLE_PERMANENT: Do not alloe swfdec_as_object_delete_variable()
  *                                to delete this variable.
  * @SWFDEC_AS_VARIABLE_CONSTANT: Do not allow changing the value with
  *                               swfdec_as_object_set_variable().
commit de08174d082b4ed91fbfb22859aa3d563023bce6
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Oct 26 21:47:26 2007 +0200

    only set caps if there are none set yet

diff --git a/libswfdec/swfdec_codec_gst.c b/libswfdec/swfdec_codec_gst.c
index cd2d02e..b449533 100644
--- a/libswfdec/swfdec_codec_gst.c
+++ b/libswfdec/swfdec_codec_gst.c
@@ -272,7 +272,16 @@ static gboolean
 swfdec_gst_decoder_push (SwfdecGstDecoder *dec, GstBuffer *buffer)
 {
   GstFlowReturn ret;
-  gst_buffer_set_caps (buffer, GST_PAD_CAPS (dec->src));
+  GstCaps *caps;
+
+  /* set caps if none set yet */
+  caps = gst_buffer_get_caps (buffer);
+  if (caps) {
+    gst_caps_unref (caps);
+  } else {
+    gst_buffer_set_caps (buffer, GST_PAD_CAPS (dec->src));
+  }
+
   ret = gst_pad_push (dec->src, buffer);
   if (GST_FLOW_IS_SUCCESS (ret))
     return TRUE;
commit a80f28771abeed57f6af38b7512ca69f45c9a198
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Oct 26 21:42:50 2007 +0200

    make Gst video use the same output method

diff --git a/libswfdec/swfdec_codec_gst.c b/libswfdec/swfdec_codec_gst.c
index bd8f95a..cd2d02e 100644
--- a/libswfdec/swfdec_codec_gst.c
+++ b/libswfdec/swfdec_codec_gst.c
@@ -271,7 +271,13 @@ swfdec_gst_decoder_finish (SwfdecGstDecoder *dec)
 static gboolean
 swfdec_gst_decoder_push (SwfdecGstDecoder *dec, GstBuffer *buffer)
 {
-  return GST_FLOW_IS_SUCCESS (gst_pad_push (dec->src, buffer));
+  GstFlowReturn ret;
+  gst_buffer_set_caps (buffer, GST_PAD_CAPS (dec->src));
+  ret = gst_pad_push (dec->src, buffer);
+  if (GST_FLOW_IS_SUCCESS (ret))
+    return TRUE;
+  SWFDEC_ERROR ("error %d pushing data", (int) ret);
+  return FALSE;
 }
 
 static void
@@ -412,65 +418,27 @@ error:
 
 /*** VIDEO ***/
 
-#if 0
-#define swfdec_cond_wait(cond, mutex) G_STMT_START { \
-  g_print ("waiting at %s\n", G_STRLOC); \
-  g_cond_wait (cond, mutex); \
-  g_print ("   done at %s\n", G_STRLOC); \
-}G_STMT_END
-#else
-#define swfdec_cond_wait g_cond_wait
-#endif
-
+/* NB: We don't put a colorspace tansform here, we just assume that the codecs
+ * in GStreamer decode to the native format that we enforce. */
 typedef struct _SwfdecGstVideo SwfdecGstVideo;
 struct _SwfdecGstVideo {
   SwfdecVideoDecoder	decoder;
 
-  GMutex *	  	mutex;		/* mutex that blocks everything below (NB: locked by default) */
-  GCond *		cond;		/* cond used to signal when stuff below changes */
-  volatile int		refcount;	/* refcount (d'oh) */
-
-  GstElement *		pipeline;	/* pipeline that is playing or NULL when done */
-  SwfdecBuffer *	in;		/* next input buffer or NULL */
-  GstBuffer *		out;		/* available output or NULL */
-  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 */
+  gboolean		error;
+  SwfdecGstDecoder	dec;		/* the decoder element */
+  GstBuffer *		last;		/* last decoded buffer */
 };
 
 static void
-swfdec_gst_video_unref (gpointer data, GObject *unused)
-{
-  SwfdecGstVideo *player = data;
-
-  if (!g_atomic_int_dec_and_test (&player->refcount))
-    return;
-  g_cond_free (player->cond);
-  g_mutex_free (player->mutex);
-  gst_caps_unref (player->srccaps);
-  if (player->in)
-    swfdec_buffer_unref (player->in);
-  if (player->out)
-    gst_buffer_unref (player->out);
-  g_slice_free (SwfdecGstVideo, player);
-}
-
-static void
 swfdec_video_decoder_gst_free (SwfdecVideoDecoder *dec)
 {
   SwfdecGstVideo *player = (SwfdecGstVideo *) dec;
-  GstElement *pipeline;
 
-  pipeline = player->pipeline;
-  player->pipeline = NULL;
-  g_cond_signal (player->cond);
-  g_mutex_unlock (player->mutex);
-  gst_element_set_state (pipeline, GST_STATE_NULL);
-  g_object_unref (pipeline);
+  swfdec_gst_decoder_finish (&player->dec);
+  if (player->last)
+    gst_buffer_unref (player->last);
 
-  swfdec_gst_video_unref (player, NULL);
+  g_slice_free (SwfdecGstVideo, player);
 }
 
 static gboolean
@@ -479,117 +447,66 @@ swfdec_video_decoder_gst_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer,
 {
   SwfdecGstVideo *player = (SwfdecGstVideo *) dec;
 #define ALIGN(x, n) (((x) + (n) - 1) & (~((n) - 1)))
+  GstBuffer *buf;
+  GstCaps *caps;
+  GstStructure *structure;
+
+  if (player->error)
+    return FALSE;
+  if (player->last) {
+    gst_buffer_unref (player->last);
+    player->last = NULL;
+  }
 
-  while (player->in != NULL && !player->error) {
-    swfdec_cond_wait (player->cond, player->mutex);
+  buf = swfdec_gst_buffer_new (swfdec_buffer_ref (buffer));
+  if (!swfdec_gst_decoder_push (&player->dec, buf)) {
+    SWFDEC_ERROR ("failed to push buffer");
+    player->error = TRUE;
+    return FALSE;
+  }
+
+  player->last = swfdec_gst_decoder_pull (&player->dec);
+  if (player->last == NULL) {
+    SWFDEC_ERROR ("failed to pull decoded buffer");
+    player->error = TRUE;
+    return FALSE;
   }
-  player->in = swfdec_buffer_ref (buffer);
-  g_cond_signal (player->cond);
-  if (player->out) {
-    gst_buffer_unref (player->out);
-    player->out = NULL;
+  while ((buf = swfdec_gst_decoder_pull (&player->dec))) {
+    SWFDEC_WARNING ("too many output buffers!");
   }
-  while (player->out == NULL && !player->error) {
-    swfdec_cond_wait (player->cond, player->mutex);
+  caps = gst_buffer_get_caps (player->last);
+  if (caps == NULL) {
+    SWFDEC_ERROR ("no caps on decoded buffer");
+    player->error = TRUE;
+    return FALSE;
   }
-  if (player->error)
+  structure = gst_caps_get_structure (caps, 0);
+  if (!gst_structure_get_int (structure, "width", (int *) &image->width) ||
+      !gst_structure_get_int (structure, "height", (int *) &image->height)) {
+    SWFDEC_ERROR ("invalid caps on decoded buffer");
+    player->error = TRUE;
     return FALSE;
-  image->width = player->width;
-  image->height = player->height;
+  }
   image->mask = NULL;
+  buf = player->last;
   switch (swfdec_video_codec_get_format (dec->codec)) {
     case SWFDEC_VIDEO_FORMAT_RGBA:
-      image->plane[0] = player->out->data;
-      image->rowstride[0] = player->width * 4;
+      image->plane[0] = buf->data;
+      image->rowstride[0] = image->width * 4;
       break;
     case SWFDEC_VIDEO_FORMAT_I420:
-      image->plane[0] = player->out->data;
-      image->rowstride[0] = ALIGN (player->width, 4);
-      image->plane[1] = image->plane[0] + image->rowstride[0] * ALIGN (player->height, 2);
-      image->rowstride[1] = ALIGN (player->width, 8) / 2;
-      image->plane[2] = image->plane[1] + image->rowstride[1] * ALIGN (player->height, 2) / 2;
+      image->plane[0] = buf->data;
+      image->rowstride[0] = ALIGN (image->width, 4);
+      image->plane[1] = image->plane[0] + image->rowstride[0] * ALIGN (image->height, 2);
+      image->rowstride[1] = ALIGN (image->width, 8) / 2;
+      image->plane[2] = image->plane[1] + image->rowstride[1] * ALIGN (image->height, 2) / 2;
       image->rowstride[2] = image->rowstride[1];
-      g_assert (image->plane[2] + image->rowstride[2] * ALIGN (player->height, 2) / 2 == image->plane[0] + player->out->size);
+      g_assert (image->plane[2] + image->rowstride[2] * ALIGN (image->height, 2) / 2 == image->plane[0] + buf->size);
       break;
   }
   return TRUE;
 }
 
-static void
-swfdec_video_decoder_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;
-  }
-  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);
-  swfdec_buffer_unref (player->in);
-  player->in = NULL;
-  player->out_next = TRUE;
-  g_cond_signal (player->cond);
-  g_mutex_unlock (player->mutex);
-}
-
-static void
-swfdec_video_decoder_gst_fakesink_handoff (GstElement *fakesrc, GstBuffer *buf, 
-    GstPad *pad, SwfdecGstVideo *player)
-{
-  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);
-    if (!gst_structure_get_int (structure, "width", &player->width) ||
-        !gst_structure_get_int (structure, "height", &player->height)) {
-      player->width = 0;
-      player->height = 0;
-    }
-    gst_caps_unref (caps);
-  }
-  if (player->pipeline == NULL) {
-    g_mutex_unlock (player->mutex);
-    return;
-  }
-  if (player->out != NULL)
-    gst_buffer_unref (player->out);
-  player->out = gst_buffer_ref (buf);
-  player->out_next = FALSE;
-  g_cond_signal (player->cond);
-  g_mutex_unlock (player->mutex);
-}
-
-static void
-swfdec_video_decoder_gst_link (GstElement *src, GstPad *pad, GstElement *sink)
-{
-  GstCaps *caps;
-  
-  caps = g_object_get_data (G_OBJECT (sink), "swfdec-caps");
-  g_assert (caps);
-  if (!gst_element_link_filtered (src, sink, caps)) {
-    SWFDEC_ERROR ("no delayed link");
-  }
-}
-
 static GstCaps *
 swfdec_video_decoder_get_sink_caps (SwfdecVideoCodec codec)
 {
@@ -613,84 +530,37 @@ SwfdecVideoDecoder *
 swfdec_video_decoder_gst_new (SwfdecVideoCodec codec)
 {
   SwfdecGstVideo *player;
-  GstElement *fakesrc, *fakesink, *decoder;
-  GstCaps *caps;
+  GstCaps *srccaps, *sinkcaps;
 
   if (!gst_init_check (NULL, NULL, NULL))
     return NULL;
 
   switch (codec) {
     case SWFDEC_VIDEO_CODEC_H263:
-      caps = gst_caps_from_string ("video/x-flash-video");
+      srccaps = gst_caps_from_string ("video/x-flash-video");
       break;
     case SWFDEC_VIDEO_CODEC_VP6:
-      caps = gst_caps_from_string ("video/x-vp6-flash");
+      srccaps = gst_caps_from_string ("video/x-vp6-flash");
       break;
     default:
       return NULL;
   }
-  g_assert (caps);
+  g_assert (srccaps);
+  sinkcaps = swfdec_video_decoder_get_sink_caps (codec);
 
-  player = g_slice_new0 (SwfdecGstVideo);
+  player = g_slice_new (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 ();
-  g_mutex_lock (player->mutex);
-  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_video_decoder_gst_free (&player->decoder);
-    return NULL;
-  }
-  g_object_set (fakesrc, "signal-handoffs", TRUE, 
-      "can-activate-pull", FALSE, NULL);
-  g_signal_connect (fakesrc, "handoff", 
-      G_CALLBACK (swfdec_video_decoder_gst_fakesrc_handoff), player);
-  g_atomic_int_inc (&player->refcount);
-  g_object_weak_ref (G_OBJECT (fakesrc), swfdec_gst_video_unref, player);
-  gst_bin_add (GST_BIN (player->pipeline), fakesrc);
-  fakesink = gst_element_factory_make ("fakesink", NULL);
-  if (fakesink == NULL) {
-    SWFDEC_ERROR ("failed to create fakesink");
-    swfdec_video_decoder_gst_free (&player->decoder);
-    return NULL;
-  }
-  g_object_set (fakesink, "signal-handoffs", TRUE, NULL);
-  g_signal_connect (fakesink, "handoff", 
-      G_CALLBACK (swfdec_video_decoder_gst_fakesink_handoff), player);
-  caps = swfdec_video_decoder_get_sink_caps (codec);
-  g_assert (caps);
-  g_object_set_data_full (G_OBJECT (fakesink), "swfdec-caps", caps, 
-      (GDestroyNotify) gst_caps_unref);
-  g_atomic_int_inc (&player->refcount);
-  g_object_weak_ref (G_OBJECT (fakesink), swfdec_gst_video_unref, player);
-  gst_bin_add (GST_BIN (player->pipeline), fakesink);
-  decoder = gst_element_factory_make ("decodebin", NULL);
-  if (decoder == NULL) {
-    SWFDEC_ERROR ("failed to create decoder");
-    swfdec_video_decoder_gst_free (&player->decoder);
-    return NULL;
-  }
-  gst_bin_add (GST_BIN (player->pipeline), decoder);
-  g_signal_connect (decoder, "pad-added", 
-      G_CALLBACK (swfdec_video_decoder_gst_link), fakesink);
 
-  if (!gst_element_link_filtered (fakesrc, decoder, player->srccaps)) {
-    SWFDEC_ERROR ("linking failed");
-    swfdec_video_decoder_gst_free (&player->decoder);
-    return NULL;
-  }
-  if (gst_element_set_state (player->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
-    SWFDEC_ERROR ("failed to change sate");
+  if (!swfdec_gst_decoder_init (&player->dec, NULL, srccaps, sinkcaps)) {
     swfdec_video_decoder_gst_free (&player->decoder);
+    gst_caps_unref (srccaps);
+    gst_caps_unref (sinkcaps);
     return NULL;
   }
 
+  gst_caps_unref (srccaps);
+  gst_caps_unref (sinkcaps);
   return &player->decoder;
 }
 


More information about the Swfdec mailing list