oggdemux: fix hang on small truncated files
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Tue, 10 Jan 2012 16:14:29 +0000 (16:14 +0000)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Tue, 10 Jan 2012 16:20:23 +0000 (16:20 +0000)
A first hang was happening when trying to locate a page backwards,
where we'd sync forever on the same page.
With that fixed, a second hang would happen after preparing an EOS
event, but with no chain created yet to send it to, the pipeline
would stay idle forever.
An element error is now emitted for this case.

ext/ogg/gstoggdemux.c

index a06aec8..f54ab95 100644 (file)
@@ -2371,6 +2371,8 @@ gst_ogg_demux_get_prev_page (GstOggDemux * ogg, ogg_page * og, gint64 * offset)
       if (ret == GST_FLOW_UNEXPECTED) {
         new_offset = 0;
         GST_LOG_OBJECT (ogg, "got unexpected");
+        /* We hit EOS. */
+        goto beach;
       } else if (ret != GST_FLOW_OK) {
         GST_LOG_OBJECT (ogg, "got error %d", ret);
         return ret;
@@ -2398,6 +2400,7 @@ gst_ogg_demux_get_prev_page (GstOggDemux * ogg, ogg_page * og, gint64 * offset)
   if (offset)
     *offset = cur_offset;
 
+beach:
   return ret;
 }
 
@@ -4466,8 +4469,17 @@ pause:
      * e.g. because of a flushing seek.
      */
     if (event) {
-      gst_event_set_seqnum (event, ogg->seqnum);
-      gst_ogg_demux_send_event (ogg, event);
+      /* guard against corrupt/truncated files, where one can hit EOS
+         before prerolling is done and a chain created. If we have no
+         chain to send the event to, error out. */
+      if (ogg->current_chain || ogg->building_chain) {
+        gst_event_set_seqnum (event, ogg->seqnum);
+        gst_ogg_demux_send_event (ogg, event);
+      } else {
+        gst_event_unref (event);
+        GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, (NULL),
+            ("EOS before finding a chain"));
+      }
     }
     return;
   }