mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
avidemux: push mode; cater for unusual chunk sizes
This commit is contained in:
parent
a74c385b7b
commit
bb2b02c5b7
2 changed files with 32 additions and 17 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue