summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog45
-rw-r--r--gst-libs/gst/riff/riff-read.c136
-rw-r--r--gst/flx/gstflxdec.c34
-rw-r--r--gst/modplug/gstmodplug.cc6
4 files changed, 149 insertions, 72 deletions
diff --git a/ChangeLog b/ChangeLog
index 75b76db6..a38fdd04 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+2004-09-29 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+
+ * ext/flac/gstflacdec.c: (gst_flacdec_src_query):
+ Only return true if we actually filled something in. Prevents
+ player applications from showing a random length for flac files.
+ * gst-libs/gst/riff/riff-read.c: (gst_riff_read_class_init),
+ (gst_riff_read_use_event), (gst_riff_read_handle_event),
+ (gst_riff_read_seek), (gst_riff_read_skip), (gst_riff_read_strh),
+ (gst_riff_read_strf_vids_with_data),
+ (gst_riff_read_strf_auds_with_data), (gst_riff_read_strf_iavs):
+ OK, ok, so I implemented event handling. Apparently it's normal
+ that we receive random events at random points without asking
+ for it.
+ * gst/avi/gstavidemux.c: (gst_avi_demux_reset),
+ (gst_avi_demux_src_convert), (gst_avi_demux_handle_src_query),
+ (gst_avi_demux_handle_src_event), (gst_avi_demux_stream_index),
+ (gst_avi_demux_sync), (gst_avi_demux_stream_scan),
+ (gst_avi_demux_massage_index), (gst_avi_demux_stream_header),
+ (gst_avi_demux_handle_seek), (gst_avi_demux_process_next_entry),
+ (gst_avi_demux_stream_data), (gst_avi_demux_loop):
+ * gst/avi/gstavidemux.h:
+ Implement non-lineair chunk handling and subchunk processing.
+ The first solves playback of AVI files where the audio and video
+ data of individual buffers that we read are not synchronized.
+ This should not happen according to the wonderful AVI specs, but
+ of course it does happen in reality. It is also a prerequisite for
+ the second. Subchunk processing allows us to cut chunks in small
+ pieces and process each of these pieces separately. This is
+ required because I've seen several AVI files with incredibly large
+ audio chunks, even some files with only one audio chunk for the
+ whole file. This allows for proper playback including seeking.
+ This patch is supposed to fix all AVI A/V sync issues.
+ * gst/flx/gstflxdec.c: (gst_flxdec_class_init),
+ (flx_decode_chunks), (flx_decode_color), (gst_flxdec_loop):
+ Work.
+ * gst/modplug/gstmodplug.cc:
+ Proper return value setting for the query() function.
+ * gst/playback/gstplaybasebin.c: (setup_source):
+ Being in non-playing state (after, e.g., EOS) is not necessarily
+ a bad thing. Allow for that. This fixes playback of short files.
+ They don't actually playback fully now, because the clock already
+ runs. This means that small files (<500kB) with a small length
+ (<2sec) will still not or barely play. Other files, such as mod
+ or flx, will work correctly, however.
+
2004-09-28 Wim Taymans <wim@fluendo.com>
* ext/speex/gstspeex.c: (plugin_init):
diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c
index d81f6ada..a400c7aa 100644
--- a/gst-libs/gst/riff/riff-read.c
+++ b/gst-libs/gst/riff/riff-read.c
@@ -29,6 +29,9 @@
#include "riff-ids.h"
#include "riff-read.h"
+GST_DEBUG_CATEGORY_STATIC (riffread_debug);
+#define GST_CAT_DEFAULT riffread_debug
+
enum
{
ARG_0,
@@ -76,6 +79,9 @@ gst_riff_read_class_init (GstRiffReadClass * klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ GST_DEBUG_CATEGORY_INIT (riffread_debug, "riffread",
+ 0, "RIFF stream helper class");
+
gstelement_class->change_state = gst_riff_read_change_state;
}
@@ -146,6 +152,64 @@ gst_riff_read_element_level_up (GstRiffRead * riff)
}
/*
+ * Event handler. Basic:
+ * - EOS: end-of-file, stop processing, forward EOS.
+ * - Interrupt: stop processing.
+ * - Discont: shouldn't be handled here but in the seek handler. Error.
+ * - Flush: ignore, since we check for flush flags manually. Don't forward.
+ * - Others: warn, ignore.
+ * Return value indicates whether to continue processing.
+ */
+
+static gboolean
+gst_riff_read_use_event (GstRiffRead * riff, GstEvent * event)
+{
+ if (!event) {
+ GST_ELEMENT_ERROR (riff, RESOURCE, READ, (NULL), (NULL));
+ return FALSE;
+ }
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_EOS:
+ gst_pad_event_default (riff->sinkpad, event);
+ return FALSE;
+
+ case GST_EVENT_INTERRUPT:
+ gst_event_unref (event);
+ return FALSE;
+
+ case GST_EVENT_DISCONTINUOUS:
+ GST_WARNING_OBJECT (riff, "Unexected discont - might lose sync");
+ gst_pad_event_default (riff->sinkpad, event);
+ return TRUE;
+
+ case GST_EVENT_FLUSH:
+ gst_event_unref (event);
+ return TRUE;
+
+ default:
+ GST_WARNING ("don't know how to handle event %d", GST_EVENT_TYPE (event));
+ gst_pad_event_default (riff->sinkpad, event);
+ return FALSE;
+ }
+
+ /* happy */
+ g_assert_not_reached ();
+ return FALSE;
+}
+
+static gboolean
+gst_riff_read_handle_event (GstRiffRead * riff)
+{
+ GstEvent *event = NULL;
+ guint32 remaining;
+
+ gst_bytestream_get_status (riff->bs, &remaining, &event);
+
+ return gst_riff_read_use_event (riff, event);
+}
+
+/*
* Read the next tag plus length (may be NULL). Return
* TRUE on success or FALSE on failure.
*/
@@ -174,21 +238,8 @@ gst_riff_peek_head (GstRiffRead * riff,
/* read */
while (gst_bytestream_peek_bytes (riff->bs, &data, 8) != 8) {
- GstEvent *event = NULL;
- guint32 remaining;
-
- /* Here, we might encounter EOS */
- gst_bytestream_get_status (riff->bs, &remaining, &event);
- if (event && GST_IS_EVENT (event)) {
- gboolean eos = (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
-
- gst_pad_event_default (riff->sinkpad, event);
- if (eos)
- return FALSE;
- } else {
- GST_ELEMENT_ERROR (riff, RESOURCE, READ, (NULL), (NULL));
+ if (!gst_riff_read_handle_event (riff))
return FALSE;
- }
}
/* parse tag + length (if wanted) */
@@ -215,33 +266,10 @@ gst_riff_read_element_data (GstRiffRead * riff, guint length, guint * got_bytes)
guint32 got;
while ((got = gst_bytestream_peek (riff->bs, &buf, length)) != length) {
- /*GST_ELEMENT_ERROR (riff, RESOURCE, READ, (NULL), (NULL)); */
- GstEvent *event = NULL;
- guint32 remaining;
-
- gst_bytestream_get_status (riff->bs, &remaining, &event);
- if (event && GST_IS_EVENT (event)) {
- gst_pad_event_default (riff->sinkpad, event);
- if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
-
- if (buf)
- gst_buffer_unref (buf);
-
- if (got_bytes)
- *got_bytes = got;
-
- return NULL;
- }
- } else {
- GST_ELEMENT_ERROR (riff, RESOURCE, READ, (NULL), (NULL));
- if (buf)
- gst_buffer_unref (buf);
-
- if (got_bytes)
- *got_bytes = got;
-
+ if (buf)
+ gst_buffer_unref (buf);
+ if (!gst_riff_read_handle_event (riff))
return NULL;
- }
}
/* we need 16-bit alignment */
@@ -275,7 +303,9 @@ gst_riff_read_seek (GstRiffRead * riff, guint64 offset)
/* first, flush remaining buffers */
gst_bytestream_get_status (riff->bs, &remaining, &event);
if (event) {
- g_warning ("Unexpected event before seek");
+ GST_WARNING ("Unexpected event before seek");
+ if (!gst_riff_read_use_event (riff, event))
+ return NULL;
}
if (remaining)
@@ -301,10 +331,7 @@ gst_riff_read_seek (GstRiffRead * riff, guint64 offset)
GST_WARNING ("No discontinuity event after seek - seek failed");
break;
} else if (GST_EVENT_TYPE (event) != GST_EVENT_DISCONTINUOUS) {
- GstEventType type = GST_EVENT_TYPE (event);
-
- gst_pad_event_default (riff->sinkpad, event);
- if (type == GST_EVENT_EOS || type == GST_EVENT_INTERRUPT)
+ if (!gst_riff_read_use_event (riff, event))
return NULL;
event = NULL;
}
@@ -361,7 +388,7 @@ gboolean
gst_riff_read_skip (GstRiffRead * riff)
{
guint32 tag, length;
- GstEvent *event;
+ GstEvent *event = NULL;
guint32 remaining;
if (!gst_riff_peek_head (riff, &tag, &length, NULL))
@@ -376,12 +403,9 @@ gst_riff_read_skip (GstRiffRead * riff)
/* see if we have that much data available */
gst_bytestream_get_status (riff->bs, &remaining, &event);
- if (event && GST_IS_EVENT (event)) {
- gboolean eos = (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
-
- g_warning ("Unexpected event in skip");
- gst_pad_event_default (riff->sinkpad, event);
- if (eos)
+ if (event) {
+ GST_WARNING ("Unexpected event in skip");
+ if (!gst_riff_read_use_event (riff, event))
return FALSE;
}
@@ -458,7 +482,7 @@ gst_riff_read_strh (GstRiffRead * riff, gst_riff_strh ** header)
return FALSE;
}
if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strh)) {
- g_warning ("Too small strh (%d available, %d needed)",
+ GST_WARNING ("Too small strh (%d available, %d needed)",
GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_strh));
gst_buffer_unref (buf);
return FALSE;
@@ -526,7 +550,7 @@ gst_riff_read_strf_vids_with_data (GstRiffRead * riff,
return FALSE;
}
if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_vids)) {
- g_warning ("Too small strf_vids (%d available, %d needed)",
+ GST_WARNING ("Too small strf_vids (%d available, %d needed)",
GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_strf_vids));
gst_buffer_unref (buf);
return FALSE;
@@ -620,7 +644,7 @@ gst_riff_read_strf_auds_with_data (GstRiffRead * riff,
return FALSE;
}
if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_auds)) {
- g_warning ("Too small strf_auds (%d available, %d needed)",
+ GST_WARNING ("Too small strf_auds (%d available, %d needed)",
GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_strf_auds));
gst_buffer_unref (buf);
return FALSE;
@@ -702,7 +726,7 @@ gst_riff_read_strf_iavs (GstRiffRead * riff, gst_riff_strf_iavs ** header)
return FALSE;
}
if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_iavs)) {
- g_warning ("Too small strf_iavs (%d available, %d needed)",
+ GST_WARNING ("Too small strf_iavs (%d available, %d needed)",
GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_strf_iavs));
gst_buffer_unref (buf);
return FALSE;
diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c
index b2694962..3323ca0a 100644
--- a/gst/flx/gstflxdec.c
+++ b/gst/flx/gstflxdec.c
@@ -28,6 +28,9 @@
#define JIFFIE (GST_SECOND/70)
+GST_DEBUG_CATEGORY_STATIC (flxdec_debug);
+#define GST_CAT_DEFAULT flxdec_debug
+
/* flx element information */
static GstElementDetails flxdec_details = {
"FLX Decoder",
@@ -133,6 +136,8 @@ gst_flxdec_class_init (GstFlxDecClass * klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ GST_DEBUG_CATEGORY_INIT (flxdec_debug, "flxdec", 0, "FLX video decoder");
+
gobject_class->set_property = gst_flxdec_set_property;
gobject_class->get_property = gst_flxdec_get_property;
@@ -206,9 +211,8 @@ flx_decode_chunks (GstFlxDec * flxdec, gulong count, gchar * data, gchar * dest)
break;
default:
- g_print ("GstFlxDec: Unimplented chunk type: 0x%02x size: %d\n",
+ GST_WARNING ("Unimplented chunk type: 0x%02x size: %d - skipping",
hdr->id, hdr->size);
- g_print ("GstFlxDec: Skipping...\n");
data += rndalign (hdr->size) - FlxFrameChunkSize;
break;
}
@@ -228,7 +232,7 @@ flx_decode_color (GstFlxDec * flxdec, guchar * data, guchar * dest, gint scale)
data += 2;
indx = 0;
- g_print ("GstFlxDec: cmap packs: %d\n", packs);
+ GST_LOG ("GstFlxDec: cmap packs: %d", packs);
while (packs--) {
/* color map index + skip count */
indx += *data++;
@@ -238,7 +242,7 @@ flx_decode_color (GstFlxDec * flxdec, guchar * data, guchar * dest, gint scale)
if (count == 0)
count = 256;
- g_print ("GstFlxDec: cmap count: %d (indx: %d)\n", count, indx);
+ GST_LOG ("GstFlxDec: cmap count: %d (indx: %d)\n", count, indx);
flx_set_palette_vector (flxdec->converter, indx, count, data, scale);
data += (count * 3);
@@ -449,7 +453,7 @@ gst_flxdec_loop (GstElement * element)
databuf = flx_get_data (flxdec, FlxHeaderSize);
if (!databuf) {
- g_print ("empty buffer\n");
+ GST_LOG ("empty buffer");
return;
}
@@ -470,12 +474,12 @@ gst_flxdec_loop (GstElement * element)
}
- g_print ("GstFlxDec: size : %d\n", flxh->size);
- g_print ("GstFlxDec: frames : %d\n", flxh->frames);
- g_print ("GstFlxDec: width : %d\n", flxh->width);
- g_print ("GstFlxDec: height : %d\n", flxh->height);
- g_print ("GstFlxDec: depth : %d\n", flxh->depth);
- g_print ("GstFlxDec: speed : %d\n", flxh->speed);
+ GST_LOG ("size : %d\n", flxh->size);
+ GST_LOG ("frames : %d\n", flxh->frames);
+ GST_LOG ("width : %d\n", flxh->width);
+ GST_LOG ("height : %d\n", flxh->height);
+ GST_LOG ("depth : %d\n", flxh->depth);
+ GST_LOG ("speed : %d\n", flxh->speed);
flxdec->next_time = 0;
@@ -496,10 +500,10 @@ gst_flxdec_loop (GstElement * element)
flx_colorspace_converter_new (flxh->width, flxh->height);
if (flxh->type == FLX_MAGICHDR_FLC || flxh->type == FLX_MAGICHDR_FLX) {
- g_print ("GstFlxDec: (FLC) aspect_dx : %d\n", flxh->aspect_dx);
- g_print ("GstFlxDec: (FLC) aspect_dy : %d\n", flxh->aspect_dy);
- g_print ("GstFlxDec: (FLC) oframe1 : 0x%08x\n", flxh->oframe1);
- g_print ("GstFlxDec: (FLC) oframe2 : 0x%08x\n", flxh->oframe2);
+ GST_LOG ("(FLC) aspect_dx : %d\n", flxh->aspect_dx);
+ GST_LOG ("(FLC) aspect_dy : %d\n", flxh->aspect_dy);
+ GST_LOG ("(FLC) oframe1 : 0x%08x\n", flxh->oframe1);
+ GST_LOG ("(FLC) oframe2 : 0x%08x\n", flxh->oframe2);
}
flxdec->size = (flxh->width * flxh->height);
diff --git a/gst/modplug/gstmodplug.cc b/gst/modplug/gstmodplug.cc
index 8e8b6efd..c5a2fa82 100644
--- a/gst/modplug/gstmodplug.cc
+++ b/gst/modplug/gstmodplug.cc
@@ -346,15 +346,19 @@ gst_modplug_src_query (GstPad * pad, GstQueryType type,
break;
case GST_QUERY_POSITION:
switch (*format) {
- default:
+ case GST_FORMAT_TIME:
tmp =
((float) (modplug->mSoundFile->GetSongTime () *
modplug->mSoundFile->GetCurrentPos ()) /
(float) modplug->mSoundFile->GetMaxPosition ());
*value = (gint64) (tmp * GST_SECOND);
break;
+ default:
+ res = FALSE;
+ break;
}
default:
+ res = FALSE;
break;
}