summaryrefslogtreecommitdiffstats
path: root/gst/matroska/ebml-read.c
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>2004-10-01 08:42:56 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2004-10-01 08:42:56 +0000
commita8afe5f5b387fe1585525e58eafcf31f7d17c5f6 (patch)
tree9544f8c25be518d06fb08ae2d7d70398bdb7fc1a /gst/matroska/ebml-read.c
parent815d511c8acf1d015d4609832251491499d7b115 (diff)
ext/dvdread/dvdreadsrc.c: Fix. Don't do one big huge loop around the whole DVD, that will cache all data and thus eat...
Original commit message from CVS: * 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.
Diffstat (limited to 'gst/matroska/ebml-read.c')
-rw-r--r--gst/matroska/ebml-read.c127
1 files changed, 77 insertions, 50 deletions
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)