avidemux: push mode; cater for unusual chunk sizes

This commit is contained in:
Mark Nauwelaerts 2009-08-08 21:54:00 +02:00
parent a74c385b7b
commit bb2b02c5b7
2 changed files with 32 additions and 17 deletions

View file

@ -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)) { if (!gst_avi_demux_peek_chunk_info (avi, tag, size)) {
return FALSE; return FALSE;
} }
/* FIXME: shouldn't this check go to gst_avi_demux_peek_chunk_info() already */
if (!(*size) || (*size) == -1) { /* size 0 -> empty data buffer would surprise most callers,
GST_INFO ("Invalid chunk size %d for tag %" GST_FOURCC_FORMAT, * 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)); *size, GST_FOURCC_ARGS (*tag));
/* chain should give up */
avi->abort_buffering = TRUE;
return FALSE; return FALSE;
} }
peek_size = (*size + 1) & ~1; peek_size = (*size + 1) & ~1;
@ -4182,15 +4188,13 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
GST_LOG ("Chunk ok"); GST_LOG ("Chunk ok");
} else if ((tag & 0xffff) == (('x' << 8) | 'i')) { } else if ((tag & 0xffff) == (('x' << 8) | 'i')) {
GST_DEBUG ("Found sub-index tag"); GST_DEBUG ("Found sub-index tag");
if (gst_avi_demux_peek_chunk (avi, &tag, &size)) { if (gst_avi_demux_peek_chunk (avi, &tag, &size) || size == 0) {
if ((size > 0) && (size != -1)) { /* accept 0 size buffer here */
GST_DEBUG (" skipping %d bytes for now", size); avi->abort_buffering = FALSE;
gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size)); GST_DEBUG (" skipping %d bytes for now", size);
} gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
} }
return GST_FLOW_OK; return GST_FLOW_OK;
} else if (tag == GST_RIFF_TAG_JUNK) {
GST_DEBUG ("JUNK chunk, skipping");
} else if (tag == GST_RIFF_TAG_idx1) { } else if (tag == GST_RIFF_TAG_idx1) {
GST_DEBUG ("Found index tag, stream done"); GST_DEBUG ("Found index tag, stream done");
avi->have_eos = TRUE; avi->have_eos = TRUE;
@ -4206,12 +4210,11 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
} else if (tag == GST_RIFF_TAG_JUNK) { } else if (tag == GST_RIFF_TAG_JUNK) {
/* rec list might contain JUNK chunks */ /* rec list might contain JUNK chunks */
GST_DEBUG ("Found JUNK tag"); GST_DEBUG ("Found JUNK tag");
if (gst_avi_demux_peek_chunk (avi, &tag, &size)) { if (gst_avi_demux_peek_chunk (avi, &tag, &size) || size == 0) {
if ((size > 0) && (size != -1)) { /* accept 0 size buffer here */
GST_DEBUG (" skipping %d bytes for now", size); avi->abort_buffering = FALSE;
gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size)); GST_DEBUG (" skipping %d bytes for now", size);
continue; gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
}
} }
return GST_FLOW_OK; return GST_FLOW_OK;
} else { } else {
@ -4221,8 +4224,13 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
} }
if (G_UNLIKELY (!gst_avi_demux_peek_chunk (avi, &tag, &size))) { 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); gst_adapter_flush (avi->adapter, 8);
}
return GST_FLOW_OK; return GST_FLOW_OK;
} }
GST_DEBUG ("chunk ID %" GST_FOURCC_FORMAT ", size %u", 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_DEBUG_OBJECT (avi, "state: %d res:%s", avi->state,
gst_flow_get_name (res)); 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; return res;
} }

View file

@ -132,6 +132,7 @@ typedef struct _GstAviDemux {
GstAviDemuxState state; GstAviDemuxState state;
GstAviDemuxHeaderState header_state; GstAviDemuxHeaderState header_state;
guint64 offset; guint64 offset;
gboolean abort_buffering;
/* index */ /* index */
gst_avi_index_entry *index_entries; gst_avi_index_entry *index_entries;