summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog40
-rw-r--r--gst/matroska/ebml-read.c127
2 files changed, 117 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 9ba7d02e..7e15ebf3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2004-10-01 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+
+ * ext/dvdread/dvdreadsrc.c: (dvdreadsrc_class_init),
+ (dvdreadsrc_init), (dvdreadsrc_dispose), (dvdreadsrc_set_property),
+ (dvdreadsrc_get_property), (_open), (_seek), (_read),
+ (dvdreadsrc_get), (dvdreadsrc_open_file),
+ (dvdreadsrc_change_state):
+ Fix. Don't do one big huge loop around the whole DVD, that will
+ cache all data and thus eat sizeof(dvd) (several GB) before we
+ see something.
+ * gst-libs/gst/riff/riff-read.c: (gst_riff_read_seek):
+ Actually NULL'ify event after using it.
+ * gst/matroska/ebml-read.c: (gst_ebml_read_use_event),
+ (gst_ebml_read_handle_event), (gst_ebml_read_element_id),
+ (gst_ebml_read_element_length), (gst_ebml_read_element_data),
+ (gst_ebml_read_seek), (gst_ebml_read_skip):
+ Handle events.
+ * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_base_init),
+ (gst_dvd_demux_init), (gst_dvd_demux_get_audio_stream),
+ (gst_dvd_demux_get_subpicture_stream), (gst_dvd_demux_plugin_init):
+ Fix timing (this will probably break if I seek using menus, but
+ I didn't get there yet). VOBs and normal DVDs should now work.
+ Add a mpeg2-only pad with high rank so this get autoplugged for
+ MPEG-2 movies.
+ * gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_base_init),
+ (gst_mpeg_demux_class_init), (gst_mpeg_demux_init),
+ (gst_mpeg_demux_new_output_pad), (gst_mpeg_demux_get_video_stream),
+ (gst_mpeg_demux_get_audio_stream),
+ (gst_mpeg_demux_get_private_stream), (gst_mpeg_demux_parse_packet),
+ (gst_mpeg_demux_parse_pes), (gst_mpeg_demux_plugin_init):
+ Use this as second rank for MPEG-1 and MPEG-2. Still use this for
+ MPEG-1 but use dvddemux for MPEG-2.
+ * gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_class_init),
+ (gst_mpeg_parse_init), (gst_mpeg_parse_new_pad),
+ (gst_mpeg_parse_parse_packhead):
+ Timing. Only add pad template if it exists. Add sink template from
+ class and not from ourselves. This means we will always use the
+ correct sink template even if it is not the one defined in this
+ file.
+
2004-09-29 Wim Taymans <wim@fluendo.com>
* gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_parse_packet),
diff --git a/gst/matroska/ebml-read.c b/gst/matroska/ebml-read.c
index 6face5ad..0ec5aac3 100644
--- a/gst/matroska/ebml-read.c
+++ b/gst/matroska/ebml-read.c
@@ -115,6 +115,64 @@ gst_ebml_read_change_state (GstElement * element)
}
/*
+ * 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_ebml_read_use_event (GstEbmlRead * ebml, GstEvent * event)
+{
+ if (!event) {
+ GST_ELEMENT_ERROR (ebml, RESOURCE, READ, (NULL), (NULL));
+ return FALSE;
+ }
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_EOS:
+ gst_pad_event_default (ebml->sinkpad, event);
+ return FALSE;
+
+ case GST_EVENT_INTERRUPT:
+ gst_event_unref (event);
+ return FALSE;
+
+ case GST_EVENT_DISCONTINUOUS:
+ GST_WARNING_OBJECT (ebml, "Unexected discont - might lose sync");
+ gst_pad_event_default (ebml->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 (ebml->sinkpad, event);
+ return FALSE;
+ }
+
+ /* happy */
+ g_assert_not_reached ();
+ return FALSE;
+}
+
+static gboolean
+gst_ebml_read_handle_event (GstEbmlRead * ebml)
+{
+ GstEvent *event = NULL;
+ guint32 remaining;
+
+ gst_bytestream_get_status (ebml->bs, &remaining, &event);
+
+ return gst_ebml_read_use_event (ebml, event);
+}
+
+/*
* Return: the amount of levels in the hierarchy that the
* current element lies higher than the previous one.
* The opposite isn't done - that's auto-done using master
@@ -155,25 +213,8 @@ gst_ebml_read_element_id (GstEbmlRead * ebml, guint32 * id, guint * level_up)
guint32 total;
while (gst_bytestream_peek_bytes (ebml->bs, &data, 1) != 1) {
- GstEvent *event = NULL;
- guint32 remaining;
-
- /* Here, we might encounter EOS */
- gst_bytestream_get_status (ebml->bs, &remaining, &event);
- if (event && GST_IS_EVENT (event)) {
- gboolean eos = (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
-
- gst_pad_event_default (ebml->sinkpad, event);
- if (eos)
- return FALSE;
- } else {
- guint64 pos = gst_bytestream_tell (ebml->bs);
-
- gst_event_unref (event);
- GST_ELEMENT_ERROR (ebml, RESOURCE, READ, (NULL),
- ("Read error at position %llu (0x%llx)", pos, pos));
+ if (!gst_ebml_read_handle_event (ebml))
return -1;
- }
}
total = data[0];
while (read <= 4 && !(total & len_mask)) {
@@ -189,12 +230,9 @@ gst_ebml_read_element_id (GstEbmlRead * ebml, guint32 * id, guint * level_up)
return -1;
}
- if (gst_bytestream_peek_bytes (ebml->bs, &data, read) != read) {
- guint64 pos = gst_bytestream_tell (ebml->bs);
-
- GST_ELEMENT_ERROR (ebml, RESOURCE, READ, (NULL),
- ("Read error at position %llu (0x%llx)", pos, pos));
- return -1;
+ while (gst_bytestream_peek_bytes (ebml->bs, &data, read) != read) {
+ if (!gst_ebml_read_handle_event (ebml))
+ return -1;
}
while (n < read)
total = (total << 8) | data[n++];
@@ -220,12 +258,9 @@ gst_ebml_read_element_length (GstEbmlRead * ebml, guint64 * length)
gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
guint64 total;
- if (gst_bytestream_peek_bytes (ebml->bs, &data, 1) != 1) {
- guint64 pos = gst_bytestream_tell (ebml->bs);
-
- GST_ELEMENT_ERROR (ebml, RESOURCE, READ, (NULL),
- ("Read error at position %llu (0x%llx)", pos, pos));
- return -1;
+ while (gst_bytestream_peek_bytes (ebml->bs, &data, 1) != 1) {
+ if (!gst_ebml_read_handle_event (ebml))
+ return -1;
}
total = data[0];
while (read <= 8 && !(total & len_mask)) {
@@ -243,12 +278,9 @@ gst_ebml_read_element_length (GstEbmlRead * ebml, guint64 * length)
if ((total &= (len_mask - 1)) == len_mask - 1)
num_ffs++;
- if (gst_bytestream_peek_bytes (ebml->bs, &data, read) != read) {
- guint64 pos = gst_bytestream_tell (ebml->bs);
-
- GST_ELEMENT_ERROR (ebml, RESOURCE, READ, (NULL),
- ("Read error at position %llu (0x%llx)", pos, pos));
- return -1;
+ while (gst_bytestream_peek_bytes (ebml->bs, &data, read) != read) {
+ if (!gst_ebml_read_handle_event (ebml))
+ return -1;
}
while (n < read) {
if (data[n] == 0xff)
@@ -276,13 +308,8 @@ gst_ebml_read_element_data (GstEbmlRead * ebml, guint64 length)
GstBuffer *buf = NULL;
if (gst_bytestream_peek (ebml->bs, &buf, length) != length) {
- guint64 pos = gst_bytestream_tell (ebml->bs);
-
- GST_ELEMENT_ERROR (ebml, RESOURCE, READ, (NULL),
- ("Read error at position %llu (0x%llx)", pos, pos));
- if (buf)
- gst_buffer_unref (buf);
- return NULL;
+ if (!gst_ebml_read_handle_event (ebml))
+ return NULL;
}
gst_bytestream_flush_fast (ebml->bs, length);
@@ -323,8 +350,10 @@ gst_ebml_read_seek (GstEbmlRead * ebml, guint64 offset)
/* first, flush remaining buffers */
gst_bytestream_get_status (ebml->bs, &remaining, &event);
if (event) {
- g_warning ("Unexpected event before seek");
- gst_event_unref (event);
+ GST_WARNING ("Unexpected event before seek");
+ if (!gst_ebml_read_use_event (ebml, event))
+ return NULL;
+ event = NULL;
}
if (remaining)
gst_bytestream_flush_fast (ebml->bs, remaining);
@@ -350,10 +379,7 @@ gst_ebml_read_seek (GstEbmlRead * ebml, 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 (ebml->sinkpad, event);
- if (type == GST_EVENT_EOS || type == GST_EVENT_INTERRUPT)
+ if (!gst_ebml_read_use_event (ebml, event))
return NULL;
event = NULL;
}
@@ -386,7 +412,8 @@ gst_ebml_read_skip (GstEbmlRead * ebml)
gst_bytestream_get_status (ebml->bs, &remaining, &event);
if (event) {
g_warning ("Unexpected event before skip");
- gst_event_unref (event);
+ if (!gst_ebml_read_use_event (ebml, event))
+ return FALSE;
}
if (remaining >= length)