summaryrefslogtreecommitdiffstats
path: root/gst/amrparse
diff options
context:
space:
mode:
authorRené Stadler <mail@renestadler.de>2009-04-05 03:50:19 +0300
committerRené Stadler <mail@renestadler.de>2009-04-05 05:26:09 +0300
commit0293f54d06916b3fca1d8dd526b25b92e2ee5f37 (patch)
treeeb937c99fb0a50d7b2498a233ae2cee20acf4846 /gst/amrparse
parent9c6e21d1f66366a9e22538b1aec3a842bd194fea (diff)
downloadgst-plugins-bad-0293f54d06916b3fca1d8dd526b25b92e2ee5f37.tar.gz
gst-plugins-bad-0293f54d06916b3fca1d8dd526b25b92e2ee5f37.tar.bz2
gst-plugins-bad-0293f54d06916b3fca1d8dd526b25b92e2ee5f37.zip
baseparse: Fix push mode seeking (aacparse, amrparse)
Sending the flush-start event forward before taking the stream lock actually works, in contrast to deadlocking in downstream preroll_wait (hunk 1). After that we get the chain function being stuck in a busy loop. This is fixed by updating the minimum frame size inside the synchronization loop because the subclass asks for more data in this way (hunk 2). Finally, this leads to a very probable crash because the subclass can find a valid frame with a size greater than the currently available data in the adapter. This makes the subsequent gst_adapter_take_buffer call return NULL, which is not expected (hunk 3).
Diffstat (limited to 'gst/amrparse')
-rw-r--r--gst/amrparse/gstbaseparse.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/gst/amrparse/gstbaseparse.c b/gst/amrparse/gstbaseparse.c
index b06b9bec..7de3c93f 100644
--- a/gst/amrparse/gstbaseparse.c
+++ b/gst/amrparse/gstbaseparse.c
@@ -605,10 +605,11 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
case GST_EVENT_FLUSH_START:
parse->priv->flushing = TRUE;
+ handled = gst_pad_push_event (parse->srcpad, event);
/* Wait for _chain() to exit by taking the srcpad STREAM_LOCK */
GST_PAD_STREAM_LOCK (parse->srcpad);
- handled = gst_pad_push_event (parse->srcpad, event);
GST_PAD_STREAM_UNLOCK (parse->srcpad);
+
break;
case GST_EVENT_FLUSH_STOP:
@@ -896,12 +897,12 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
while (!parse->priv->flushing) {
tmpbuf = gst_buffer_new ();
- GST_BASE_PARSE_LOCK (parse);
- min_size = parse->priv->min_frame_size;
- GST_BASE_PARSE_UNLOCK (parse);
-
/* Synchronization loop */
for (;;) {
+ GST_BASE_PARSE_LOCK (parse);
+ min_size = parse->priv->min_frame_size;
+ GST_BASE_PARSE_UNLOCK (parse);
+
/* Collect at least min_frame_size bytes */
if (gst_adapter_available (parse->adapter) < min_size) {
GST_DEBUG_OBJECT (parse, "not enough data available (only %d bytes)",
@@ -923,6 +924,12 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
skip = -1;
if (bclass->check_valid_frame (parse, tmpbuf, &fsize, &skip)) {
+ if (gst_adapter_available (parse->adapter) < fsize) {
+ GST_DEBUG_OBJECT (parse,
+ "found valid frame but not enough data available (only %d bytes)",
+ gst_adapter_available (parse->adapter));
+ goto done;
+ }
break;
}
if (skip > 0) {