summaryrefslogtreecommitdiffstats
path: root/gst/matroska/ebml-read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/matroska/ebml-read.c')
-rw-r--r--gst/matroska/ebml-read.c127
1 files changed, 101 insertions, 26 deletions
diff --git a/gst/matroska/ebml-read.c b/gst/matroska/ebml-read.c
index a6b9225d..67b9b5f3 100644
--- a/gst/matroska/ebml-read.c
+++ b/gst/matroska/ebml-read.c
@@ -157,7 +157,20 @@ gst_ebml_read_element_id (GstEbmlRead *ebml,
guint32 total;
if (gst_bytestream_peek_bytes (ebml->bs, &data, 1) != 1) {
- /*gst_element_error (GST_ELEMENT (ebml), "Read error");*/
+ GstEvent *event = NULL;
+ guint32 remaining;
+
+ /* Here, we might encounter EOS */
+ gst_bytestream_get_status (ebml->bs, &remaining, &event);
+ if (event && GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
+ gst_pad_event_default (ebml->sinkpad, event);
+ } else {
+ guint64 pos = gst_bytestream_tell (ebml->bs);
+ gst_event_unref (event);
+ gst_element_error (GST_ELEMENT (ebml),
+ "Read error at position %llu (0x%llx)",
+ pos, pos);
+ }
return -1;
}
total = data[0];
@@ -166,13 +179,18 @@ gst_ebml_read_element_id (GstEbmlRead *ebml,
len_mask >>= 1;
}
if (read > 4) {
+ guint64 pos = gst_bytestream_tell (ebml->bs);
gst_element_error (GST_ELEMENT (ebml),
- "Invalid EBML ID size tag (0x%x)", data[0]);
+ "Invalid EBML ID size tag (0x%x) at position %llu (0x%llx)",
+ data[0], pos, pos);
return -1;
}
if (gst_bytestream_peek_bytes (ebml->bs, &data, read) != read) {
- /*gst_element_error (GST_ELEMENT (ebml), "Read error");*/
+ guint64 pos = gst_bytestream_tell (ebml->bs);
+ gst_element_error (GST_ELEMENT (ebml),
+ "Read error at position %llu (0x%llx)",
+ pos, pos);
return -1;
}
while (n < read)
@@ -201,7 +219,10 @@ gst_ebml_read_element_length (GstEbmlRead *ebml,
guint64 total;
if (gst_bytestream_peek_bytes (ebml->bs, &data, 1) != 1) {
- /*gst_element_error (GST_ELEMENT (ebml), "Read error");*/
+ guint64 pos = gst_bytestream_tell (ebml->bs);
+ gst_element_error (GST_ELEMENT (ebml),
+ "Read error at position %llu (0x%llx)",
+ pos, pos);
return -1;
}
total = data[0];
@@ -210,15 +231,20 @@ gst_ebml_read_element_length (GstEbmlRead *ebml,
len_mask >>= 1;
}
if (read > 8) {
+ guint64 pos = gst_bytestream_tell (ebml->bs);
gst_element_error (GST_ELEMENT (ebml),
- "Invalid EBML length size tag (0x%x)", data[0]);
+ "Invalid EBML length size tag (0x%x) at position %llu (0x%llx)",
+ data[0], pos, pos);
return -1;
}
if ((total &= (len_mask - 1)) == len_mask - 1)
num_ffs++;
if (gst_bytestream_peek_bytes (ebml->bs, &data, read) != read) {
- /*gst_element_error (GST_ELEMENT (ebml), "Read error");*/
+ guint64 pos = gst_bytestream_tell (ebml->bs);
+ gst_element_error (GST_ELEMENT (ebml),
+ "Read error at position %llu (0x%llx)",
+ pos, pos);
return -1;
}
while (n < read) {
@@ -228,12 +254,6 @@ gst_ebml_read_element_length (GstEbmlRead *ebml,
n++;
}
- if (!total) {
- gst_element_error (GST_ELEMENT (ebml),
- "Invalid length 0");
- return -1;
- }
-
if (read == num_ffs)
*length = G_MAXUINT64;
else
@@ -254,7 +274,10 @@ gst_ebml_read_element_data (GstEbmlRead *ebml,
GstBuffer *buf = NULL;
if (gst_bytestream_peek (ebml->bs, &buf, length) != length) {
- /*gst_element_error (GST_ELEMENT (ebml), "Read error");*/
+ guint64 pos = gst_bytestream_tell (ebml->bs);
+ gst_element_error (GST_ELEMENT (ebml),
+ "Read error at position %llu (0x%llx)",
+ pos, pos);
if (buf)
gst_buffer_unref (buf);
return NULL;
@@ -276,16 +299,12 @@ gst_ebml_peek_id (GstEbmlRead *ebml,
guint *level_up)
{
guint32 id;
- guint my_level_up;
- g_return_val_if_fail (level_up != NULL, 0);
+ g_assert (level_up);
- if (gst_ebml_read_element_id (ebml, &id, &my_level_up) < 0)
+ if (gst_ebml_read_element_id (ebml, &id, level_up) < 0)
return 0;
- if (level_up)
- *level_up = my_level_up;
-
return id;
}
@@ -293,11 +312,47 @@ gst_ebml_peek_id (GstEbmlRead *ebml,
* Seek to a given offset.
*/
-void
+GstEvent *
gst_ebml_read_seek (GstEbmlRead *ebml,
guint64 offset)
{
- gst_bytestream_seek (ebml->bs, offset, GST_SEEK_METHOD_SET);
+ guint32 remaining;
+ GstEvent *event;
+ guchar *data;
+
+ /* first, flush remaining buffers */
+ gst_bytestream_get_status (ebml->bs, &remaining, &event);
+ if (event) {
+ g_warning ("Unexpected event before seek");
+ gst_event_unref (event);
+ }
+ if (remaining)
+ gst_bytestream_flush_fast (ebml->bs, remaining);
+
+ /* now seek */
+ if (!gst_bytestream_seek (ebml->bs, offset, GST_SEEK_METHOD_SET)) {
+ gst_element_error (GST_ELEMENT (ebml),
+ "Seek to position %llu (0x%llx) failed",
+ offset, offset);
+ return NULL;
+ }
+
+ /* and now, peek a new byte. This will fail because there's a
+ * pending event. Then, take the event and return it. */
+ if (gst_bytestream_peek_bytes (ebml->bs, &data, 1))
+ g_warning ("Unexpected data after seek");
+
+ /* get the discont event and return */
+ gst_bytestream_get_status (ebml->bs, &remaining, &event);
+ if (!event || GST_EVENT_TYPE (event) != GST_EVENT_DISCONTINUOUS) {
+ gst_element_error (GST_ELEMENT (ebml),
+ "No discontinuity event after seek");
+ if (event)
+ gst_event_unref (event);
+ return NULL;
+ }
+
+ return event;
}
/*
@@ -308,8 +363,9 @@ gboolean
gst_ebml_read_skip (GstEbmlRead *ebml)
{
gint bytes;
- guint32 id;
+ guint32 id, remaining;
guint64 length;
+ GstEvent *event;
if ((bytes = gst_ebml_read_element_id (ebml, &id, NULL)) < 0)
return FALSE;
@@ -319,7 +375,23 @@ gst_ebml_read_skip (GstEbmlRead *ebml)
return FALSE;
gst_bytestream_flush_fast (ebml->bs, bytes);
- return gst_bytestream_flush (ebml->bs, length);
+ /* do we have enough bytes left to skip? */
+ gst_bytestream_get_status (ebml->bs, &remaining, &event);
+ if (event) {
+ g_warning ("Unexpected event before skip");
+ gst_event_unref (event);
+ }
+
+ if (remaining >= length)
+ return gst_bytestream_flush (ebml->bs, length);
+
+ if (!(event = gst_ebml_read_seek (ebml,
+ gst_bytestream_tell (ebml->bs) + length)))
+ return FALSE;
+
+ gst_event_unref (event);
+
+ return TRUE;
}
/*
@@ -365,7 +437,8 @@ gst_ebml_read_uint (GstEbmlRead *ebml,
size = GST_BUFFER_SIZE (buf);
if (size < 1 || size > 8) {
gst_element_error (GST_ELEMENT (ebml),
- "Invalid integer element size %d", size);
+ "Invalid integer element size %d at position %llu (0x%llu)",
+ size, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET (buf));
gst_buffer_unref (buf);
return FALSE;
}
@@ -400,7 +473,8 @@ gst_ebml_read_sint (GstEbmlRead *ebml,
size = GST_BUFFER_SIZE (buf);
if (size < 1 || size > 8) {
gst_element_error (GST_ELEMENT (ebml),
- "Invalid integer element size %d", size);
+ "Invalid integer element size %d at position %llu (0x%llx)",
+ size, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET (buf));
gst_buffer_unref (buf);
return FALSE;
}
@@ -439,7 +513,8 @@ gst_ebml_read_float (GstEbmlRead *ebml,
if (size != 4 && size != 8 && size != 10) {
gst_element_error (GST_ELEMENT (ebml),
- "Invalid float element size %d", size);
+ "Invalid float element size %d at position %llu (0x%llx)",
+ size, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET (buf));
gst_buffer_unref (buf);
return FALSE;
}