summaryrefslogtreecommitdiffstats
path: root/gst/avi
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2009-08-08 21:54:00 +0200
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2009-08-31 16:50:00 +0200
commitbb2b02c5b7584e70fb3736b242115e7097b0edb2 (patch)
treee8dd0599fde41ae5d49ca4deb9a3875cf426b7e1 /gst/avi
parenta74c385b7b7d12d0a312de6e59c845ed25836c6e (diff)
avidemux: push mode; cater for unusual chunk sizes
Diffstat (limited to 'gst/avi')
-rw-r--r--gst/avi/gstavidemux.c48
-rw-r--r--gst/avi/gstavidemux.h1
2 files changed, 32 insertions, 17 deletions
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index 4c7d4dc3..6ff01fd1 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -821,10 +821,16 @@ gst_avi_demux_peek_chunk (GstAviDemux * avi, guint32 * tag, guint32 * size)
if (!gst_avi_demux_peek_chunk_info (avi, tag, size)) {
return FALSE;
}
- /* FIXME: shouldn't this check go to gst_avi_demux_peek_chunk_info() already */
- if (!(*size) || (*size) == -1) {
- GST_INFO ("Invalid chunk size %d for tag %" GST_FOURCC_FORMAT,
+
+ /* size 0 -> empty data buffer would surprise most callers,
+ * large size -> do not bother trying to squeeze that into adapter,
+ * so we throw poor man's exception, which can be caught if caller really
+ * wants to handle 0 size chunk */
+ if (!(*size) || (*size) >= (1 << 30)) {
+ GST_INFO ("Invalid/unexpected chunk size %d for tag %" GST_FOURCC_FORMAT,
*size, GST_FOURCC_ARGS (*tag));
+ /* chain should give up */
+ avi->abort_buffering = TRUE;
return FALSE;
}
peek_size = (*size + 1) & ~1;
@@ -4182,15 +4188,13 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
GST_LOG ("Chunk ok");
} else if ((tag & 0xffff) == (('x' << 8) | 'i')) {
GST_DEBUG ("Found sub-index tag");
- if (gst_avi_demux_peek_chunk (avi, &tag, &size)) {
- if ((size > 0) && (size != -1)) {
- GST_DEBUG (" skipping %d bytes for now", size);
- gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
- }
+ if (gst_avi_demux_peek_chunk (avi, &tag, &size) || size == 0) {
+ /* accept 0 size buffer here */
+ avi->abort_buffering = FALSE;
+ GST_DEBUG (" skipping %d bytes for now", size);
+ gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
}
return GST_FLOW_OK;
- } else if (tag == GST_RIFF_TAG_JUNK) {
- GST_DEBUG ("JUNK chunk, skipping");
} else if (tag == GST_RIFF_TAG_idx1) {
GST_DEBUG ("Found index tag, stream done");
avi->have_eos = TRUE;
@@ -4206,12 +4210,11 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
} else if (tag == GST_RIFF_TAG_JUNK) {
/* rec list might contain JUNK chunks */
GST_DEBUG ("Found JUNK tag");
- if (gst_avi_demux_peek_chunk (avi, &tag, &size)) {
- if ((size > 0) && (size != -1)) {
- GST_DEBUG (" skipping %d bytes for now", size);
- gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
- continue;
- }
+ if (gst_avi_demux_peek_chunk (avi, &tag, &size) || size == 0) {
+ /* accept 0 size buffer here */
+ avi->abort_buffering = FALSE;
+ GST_DEBUG (" skipping %d bytes for now", size);
+ gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
}
return GST_FLOW_OK;
} else {
@@ -4221,8 +4224,13 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
}
if (G_UNLIKELY (!gst_avi_demux_peek_chunk (avi, &tag, &size))) {
- if ((size == 0) || (size == -1))
+ /* supposedly one hopes to catch a nicer chunk later on ... */
+ /* FIXME ?? give up here rather than possibly ending up going
+ * through the whole file */
+ if (avi->abort_buffering) {
+ avi->abort_buffering = FALSE;
gst_adapter_flush (avi->adapter, 8);
+ }
return GST_FLOW_OK;
}
GST_DEBUG ("chunk ID %" GST_FOURCC_FORMAT ", size %u",
@@ -4496,6 +4504,12 @@ gst_avi_demux_chain (GstPad * pad, GstBuffer * buf)
GST_DEBUG_OBJECT (avi, "state: %d res:%s", avi->state,
gst_flow_get_name (res));
+ if (G_UNLIKELY (avi->abort_buffering)) {
+ avi->abort_buffering = FALSE;
+ res = GST_FLOW_ERROR;
+ GST_ELEMENT_ERROR (avi, STREAM, DEMUX, NULL, ("unhandled buffer size"));
+ }
+
return res;
}
diff --git a/gst/avi/gstavidemux.h b/gst/avi/gstavidemux.h
index 1537f915..95b57d5a 100644
--- a/gst/avi/gstavidemux.h
+++ b/gst/avi/gstavidemux.h
@@ -132,6 +132,7 @@ typedef struct _GstAviDemux {
GstAviDemuxState state;
GstAviDemuxHeaderState header_state;
guint64 offset;
+ gboolean abort_buffering;
/* index */
gst_avi_index_entry *index_entries;