summaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/swfdec/gstswfdec.c103
-rw-r--r--ext/swfdec/gstswfdec.h3
2 files changed, 98 insertions, 8 deletions
diff --git a/ext/swfdec/gstswfdec.c b/ext/swfdec/gstswfdec.c
index b589be8c..c4714ad3 100644
--- a/ext/swfdec/gstswfdec.c
+++ b/ext/swfdec/gstswfdec.c
@@ -49,7 +49,7 @@ GST_STATIC_PAD_TEMPLATE (
"video_00",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB)
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)
);
static GstStaticPadTemplate audio_template_factory =
@@ -158,6 +158,78 @@ gst_swfdec_class_init(GstSwfdecClass *klass)
gstelement_class->change_state = gst_swfdec_change_state;
}
+static GstCaps *
+gst_swfdec_video_getcaps (GstPad *pad)
+{
+ GstSwfdec *swfdec;
+ GstCaps *caps;
+
+ swfdec = GST_SWFDEC (gst_pad_get_parent (pad));
+
+ caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+ if (swfdec->have_format) {
+ gst_caps_set_simple (caps,
+ "framerate", G_TYPE_DOUBLE, swfdec->frame_rate,
+ NULL);
+ }
+
+ return caps;
+}
+
+static GstPadLinkReturn
+gst_swfdec_video_link (GstPad *pad, const GstCaps *caps)
+{
+ GstSwfdec *swfdec;
+ GstStructure *structure;
+ int width, height;
+ int ret;
+
+ swfdec = GST_SWFDEC (gst_pad_get_parent (pad));
+
+ if (!swfdec->have_format) {
+ return GST_PAD_LINK_DELAYED;
+ }
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ gst_structure_get_int (structure, "width", &width);
+ gst_structure_get_int (structure, "height", &height);
+
+ if (swfdec->height == height && swfdec->width == width) {
+ return GST_PAD_LINK_OK;
+ }
+
+ ret = swfdec_decoder_set_image_size (swfdec->state, width, height);
+ if (ret == SWF_OK) {
+ swfdec->width = width;
+ swfdec->height = height;
+
+ return GST_PAD_LINK_OK;
+ }
+
+ return GST_PAD_LINK_REFUSED;
+}
+
+static void
+copy_image (void *dest, void *src, int width, int height)
+{
+ guint8 *d = dest;
+ guint8 *s = src;
+ int x,y;
+
+ for(y=0;y<height;y++){
+ for(x=0;x<width;x++){
+ d[0] = s[2];
+ d[1] = s[1];
+ d[2] = s[0];
+ d[3] = 0;
+ d+=4;
+ s+=3;
+ }
+ }
+
+}
+
static void
gst_swfdec_loop(GstElement *element)
{
@@ -197,6 +269,7 @@ gst_swfdec_loop(GstElement *element)
if(ret==SWF_CHANGE){
GstCaps *caps;
+ GstPadLinkReturn link_ret;
swfdec_decoder_get_image_size(swfdec->state,
&swfdec->width, &swfdec->height);
@@ -205,12 +278,20 @@ gst_swfdec_loop(GstElement *element)
caps = gst_caps_copy (gst_pad_get_pad_template_caps (
swfdec->videopad));
+ swfdec_decoder_get_rate (swfdec->state, &swfdec->frame_rate);
gst_caps_set_simple (caps,
- "framerate", G_TYPE_DOUBLE, (double)swfdec->frame_rate,
+ "framerate", G_TYPE_DOUBLE, swfdec->frame_rate,
"height",G_TYPE_INT,swfdec->height,
"width",G_TYPE_INT,swfdec->width,
NULL);
- gst_pad_set_explicit_caps(swfdec->videopad, caps);
+ link_ret = gst_pad_try_set_caps (swfdec->videopad, caps);
+ if (GST_PAD_LINK_SUCCESSFUL (link_ret)){
+ /* good */
+ } else {
+ gst_element_error (swfdec, CORE, NEGOTIATION, NULL, NULL);
+ return;
+ }
+ swfdec->have_format = TRUE;
return;
}
@@ -221,11 +302,17 @@ gst_swfdec_loop(GstElement *element)
int len;
/* video stuff */
- newbuf = gst_buffer_new();
- GST_BUFFER_SIZE(newbuf) = swfdec->width * swfdec->height * 3;
+ //newbuf = gst_buffer_new();
+ //GST_BUFFER_SIZE(newbuf) = swfdec->width * swfdec->height * 3;
+
+ newbuf = gst_pad_alloc_buffer (swfdec->videopad, GST_BUFFER_OFFSET_NONE,
+ swfdec->width * 4 * swfdec->height);
swfdec_decoder_get_image(swfdec->state, &data);
- GST_BUFFER_DATA(newbuf) = data;
+ copy_image (GST_BUFFER_DATA (newbuf), data, swfdec->width,
+ swfdec->height);
+ free (data);
+ //GST_BUFFER_DATA(newbuf) = data;
swfdec->timestamp += swfdec->interval;
GST_BUFFER_TIMESTAMP(newbuf) = swfdec->timestamp;
@@ -267,7 +354,8 @@ gst_swfdec_init (GstSwfdec *swfdec)
"video_00");
gst_pad_set_query_function (swfdec->videopad,
GST_DEBUG_FUNCPTR (gst_swfdec_src_query));
- gst_pad_use_explicit_caps (swfdec->videopad);
+ gst_pad_set_getcaps_function (swfdec->videopad, gst_swfdec_video_getcaps);
+ gst_pad_set_link_function (swfdec->videopad, gst_swfdec_video_link);
gst_element_add_pad(GST_ELEMENT(swfdec), swfdec->videopad);
swfdec->audiopad = gst_pad_new_from_template(
@@ -530,6 +618,7 @@ gst_swfdec_change_state (GstElement *element)
swfdec->closed = FALSE;
/* reset the initial video state */
+ swfdec->have_format = FALSE;
swfdec->format = -1;
swfdec->width = -1;
swfdec->height = -1;
diff --git a/ext/swfdec/gstswfdec.h b/ext/swfdec/gstswfdec.h
index 5ee2a3b5..05015682 100644
--- a/ext/swfdec/gstswfdec.h
+++ b/ext/swfdec/gstswfdec.h
@@ -57,11 +57,12 @@ struct _GstSwfdec {
/* the timestamp of the next frame */
gboolean first;
+ gboolean have_format;
double rate;
gint64 timestamp;
gint64 interval;
- gfloat frame_rate;
+ double frame_rate;
/* video state */
gint format;