oggmux: fix deadlock when not pulling a buffer from collectpads
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Wed, 17 Dec 2014 12:17:09 +0000 (12:17 +0000)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Fri, 3 Apr 2015 14:52:54 +0000 (15:52 +0100)
oggmux keeps a cached buffer per pad, and pulls buffers from
collectpads to this cached buffer for all pads before processing
the best pad. In some cases, the move from collectpads buffer
to cached buffer is delayed till next call. However, when there
is only one pad, this can't be delayed till next call as there
will be a deadlock since collectpads has no other pad to push to.

https://bugzilla.gnome.org/show_bug.cgi?id=740565

ext/ogg/gstoggmux.c

index ded27a2..f4bf959 100644 (file)
@@ -1663,7 +1663,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
     if (next_buf) {
       ogg_mux->pulling->eos = FALSE;
       gst_buffer_unref (next_buf);
-    } else {
+    } else if (!ogg_mux->pulling->map.is_sparse) {
       GST_DEBUG_OBJECT (ogg_mux->pulling->collect.pad, "setting eos to true");
       ogg_mux->pulling->eos = TRUE;
     }
@@ -1676,7 +1676,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
     if (next_buf) {
       best->eos = FALSE;
       gst_buffer_unref (next_buf);
-    } else {
+    } else if (!best->map.is_sparse) {
       GST_DEBUG_OBJECT (best->collect.pad, "setting eos to true");
       best->eos = TRUE;
     }
@@ -2044,6 +2044,14 @@ gst_ogg_mux_collected (GstCollectPads * pads, GstOggMux * ogg_mux)
   if (best->eos && all_pads_eos (pads))
     goto eos;
 
+  /* We might have used up a cached pad->buffer. If all streams
+   * have a buffer ready in collectpads, collectpads will block at
+   * next chain, and will never call collected again. So we make a
+   * last call to _queue_pads now, to ensure that collectpads can
+   * push to at least one pad (mostly for streams with a single
+   * logical stream). */
+  gst_ogg_mux_queue_pads (ogg_mux, &popped);
+
   return ret;
 
 eos: