[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