summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-08-10 16:52:40 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-08-10 16:52:40 +0000
commitc36202dfe2d761ad8dc97b2944dcc79a5e2c2071 (patch)
tree366b42a30ec589a858d5856cef665e632384f579
parentc1e93adda88cd2f329414fb96de8776048a711f5 (diff)
ext/gdk_pixbuf/gstgdkpixbuf.c: Support various image formats (e.g. RGBA). Makes gif images work.
Original commit message from CVS: * ext/gdk_pixbuf/gstgdkpixbuf.c: (gst_gdk_pixbuf_chain): Support various image formats (e.g. RGBA). Makes gif images work. * gst/qtdemux/qtdemux.c: (gst_qtdemux_loop_header), (gst_qtdemux_add_stream), (qtdemux_parse_trak): Some workarounds for odd behaviour I found while crawling through apple.com/trailers. For one, if you load single-image (still-image) trailers containing gif images, they will have an infinite framerate since there is no duration. Capping framerate makes negotiation work. Also, some movies don't actually have size markers, since they only contain a single chunk of data (or so? I don't understand quicktime at all, I guess), so throwing the whole binary blob from the offset to end-of-file to the decoder makes at least something display (yes, this actually works :) ). Lastly, for some reason, one redirect URI movies caused an assertion because it read a negative size (immediate return) and tried to flush it (guint, signflip), leading to odd stuff and subsequent crashes.
-rw-r--r--ChangeLog19
-rw-r--r--ext/gdk_pixbuf/gstgdkpixbuf.c27
-rw-r--r--gst/qtdemux/qtdemux.c13
3 files changed, 48 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index f8ef94956..5a6c1a6f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
2005-08-10 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * ext/gdk_pixbuf/gstgdkpixbuf.c: (gst_gdk_pixbuf_chain):
+ Support various image formats (e.g. RGBA). Makes gif images work.
+ * gst/qtdemux/qtdemux.c: (gst_qtdemux_loop_header),
+ (gst_qtdemux_add_stream), (qtdemux_parse_trak):
+ Some workarounds for odd behaviour I found while crawling through
+ apple.com/trailers. For one, if you load single-image (still-image)
+ trailers containing gif images, they will have an infinite framerate
+ since there is no duration. Capping framerate makes negotiation work.
+ Also, some movies don't actually have size markers, since they only
+ contain a single chunk of data (or so? I don't understand quicktime
+ at all, I guess), so throwing the whole binary blob from the offset
+ to end-of-file to the decoder makes at least something display (yes,
+ this actually works :) ). Lastly, for some reason, one redirect URI
+ movies caused an assertion because it read a negative size (immediate
+ return) and tried to flush it (guint, signflip), leading to odd
+ stuff and subsequent crashes.
+
+2005-08-10 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+
* ext/gnomevfs/gstgnomevfssrc.c: (gst_gnomevfssrc_get):
Fix premature EOS. This causes issues when reading ID3v1 tags using
gnomevfssrc instead of filesrc; after ID3v1 tag typefinding, the
diff --git a/ext/gdk_pixbuf/gstgdkpixbuf.c b/ext/gdk_pixbuf/gstgdkpixbuf.c
index 361f08cdb..200105d93 100644
--- a/ext/gdk_pixbuf/gstgdkpixbuf.c
+++ b/ext/gdk_pixbuf/gstgdkpixbuf.c
@@ -78,10 +78,10 @@ static GstStaticPadTemplate gst_gdk_pixbuf_sink_template =
);
static GstStaticPadTemplate gst_gdk_pixbuf_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
+ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB)
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB "; " GST_VIDEO_CAPS_RGBA)
);
gboolean pixbufscale_init (GstPlugin * plugin);
@@ -298,12 +298,12 @@ gst_gdk_pixbuf_chain (GstPad * pad, GstData * _data)
GError *error = NULL;
if (!gdk_pixbuf_loader_close (filter->pixbuf_loader, &error)) {
- GST_ELEMENT_ERROR (filter, LIBRARY, SHUTDOWN, (NULL), (error->message));
+ GST_ERROR_OBJECT (filter, error->message);
g_error_free (error);
- return;
}
- pixbuf = gdk_pixbuf_loader_get_pixbuf (filter->pixbuf_loader);
+ if (!(pixbuf = gdk_pixbuf_loader_get_pixbuf (filter->pixbuf_loader)))
+ goto next;
if (filter->image_size == 0) {
GstCaps *caps;
@@ -313,14 +313,24 @@ gst_gdk_pixbuf_chain (GstPad * pad, GstData * _data)
/* gdk_pixbuf likes to pad rowstride to 4 byte boundaries which we can't do
* at the moment
*/
- filter->rowstride = filter->width * 3;
+ filter->rowstride = gdk_pixbuf_get_rowstride (pixbuf);
filter->image_size = filter->rowstride * filter->height;
- caps = gst_caps_copy (gst_pad_get_pad_template_caps (filter->srcpad));
+ if (gdk_pixbuf_get_rowstride (pixbuf) / filter->width == 4) {
+ caps = gst_caps_from_string (GST_VIDEO_CAPS_RGBA);
+ } else if (gdk_pixbuf_get_rowstride (pixbuf) / filter->width == 3) {
+ caps = gst_caps_from_string (GST_VIDEO_CAPS_RGB);
+ } else {
+ GST_ELEMENT_ERROR (filter, CORE, NEGOTIATION, (NULL),
+ ("Bpp %d not supported",
+ gdk_pixbuf_get_bits_per_sample (pixbuf)));
+ return;
+ }
gst_caps_set_simple (caps,
"width", G_TYPE_INT, filter->width,
"height", G_TYPE_INT, filter->height,
"framerate", G_TYPE_DOUBLE, filter->framerate, NULL);
+ GST_DEBUG ("Set size to %dx%d", filter->width, filter->height);
gst_pad_set_explicit_caps (filter->srcpad, caps);
}
@@ -347,6 +357,7 @@ gst_gdk_pixbuf_chain (GstPad * pad, GstData * _data)
}
}
+ GST_DEBUG ("pushing...");
gst_pad_push (filter->srcpad, GST_DATA (outbuf));
g_object_unref (G_OBJECT (filter->pixbuf_loader));
@@ -362,7 +373,7 @@ gst_gdk_pixbuf_chain (GstPad * pad, GstData * _data)
filter->pixbuf_loader = NULL;
}
}
-
+next:
if (GST_IS_BUFFER (_data)) {
if (filter->pixbuf_loader == NULL) {
filter->pixbuf_loader = gdk_pixbuf_loader_new ();
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index c92c2a9b2..be75424f0 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -730,14 +730,12 @@ gst_qtdemux_loop_header (GstElement * element)
min_time = G_MAXUINT64;
for (i = 0; i < qtdemux->n_streams; i++) {
stream = qtdemux->streams[i];
-
if (stream->sample_index < stream->n_samples &&
stream->samples[stream->sample_index].timestamp < min_time) {
min_time = stream->samples[stream->sample_index].timestamp;
index = i;
}
}
-
if (index == -1) {
qtdemux->state = QTDEMUX_STATE_SEEKING_EOS;
return;
@@ -790,7 +788,8 @@ gst_qtdemux_loop_header (GstElement * element)
break;
}
} while (TRUE);
- gst_bytestream_flush_fast (qtdemux->bs, size);
+ if (size > 0)
+ gst_bytestream_flush_fast (qtdemux->bs, size);
qtdemux->offset += size;
if (buf) {
@@ -864,6 +863,10 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
(&gst_qtdemux_videosrc_template), name);
g_free (name);
stream->fps = 1. * GST_SECOND / stream->samples[0].duration;
+ if (stream->fps < 1)
+ stream->fps = 1;
+ else if (stream->fps > 100)
+ stream->fps = 100;
if (stream->caps) {
gst_caps_set_simple (stream->caps,
"width", G_TYPE_INT, stream->width,
@@ -2417,6 +2420,10 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
samples[j].size =
samples_per_chunk * stream->bytes_per_frame /
stream->samples_per_packet / stream->compression;
+ else if (n_samples == 1 && j == 0 &&
+ gst_bytestream_length (qtdemux->bs) > samples[j].offset)
+ samples[j].size =
+ gst_bytestream_length (qtdemux->bs) - samples[j].offset;
else
samples[j].size = stream->bytes_per_frame;
samples[j].duration =