splitmuxsink: Take released-but-not-yet-output bytes into account
authorJan Schmidt <jan@centricular.com>
Thu, 11 Jun 2015 03:36:54 +0000 (13:36 +1000)
committerJan Schmidt <jan@centricular.com>
Thu, 11 Jun 2015 15:57:36 +0000 (01:57 +1000)
When deciding whether it's time to switch to a new file, take into
account data that's been released for pushing, but hasn't yet
been pushed - because downstream is slow or the threads haven't been
scheduled.

Fixes a race in the unit test and probably in practice - sometimes
failing to switch when it should for an extra GOP or two.

Also fix a problem in splitmuxsrc where playback sometimes
stalls at startup if types are found too quickly.

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

gst/multifile/gstsplitmuxpartreader.c
gst/multifile/gstsplitmuxsink.c
gst/multifile/gstsplitmuxsink.h

index fc87f81..6e92c71 100644 (file)
@@ -905,7 +905,7 @@ type_found (GstElement * typefind, guint probability,
 
   gst_bin_add (GST_BIN_CAST (reader), demux);
   gst_element_link_pads (reader->typefind, "src", demux, NULL);
-  gst_element_set_state (reader->demux, GST_STATE_PLAYING);
+  gst_element_sync_state_with_parent (reader->demux);
 
   /* Connect to demux signals */
   g_signal_connect (demux,
index 6da34e3..91d7fc4 100644 (file)
@@ -487,8 +487,10 @@ complete_or_wait_on_out (GstSplitMuxSink * splitmux, MqStreamCtx * ctx)
         GST_TIME_ARGS (splitmux->max_out_running_time));
 
     if (splitmux->max_out_running_time == GST_CLOCK_TIME_NONE ||
-        ctx->out_running_time < splitmux->max_out_running_time)
+        ctx->out_running_time < splitmux->max_out_running_time) {
+      splitmux->have_muxed_something = TRUE;
       return;
+    }
 
     if (ctx->flushing || splitmux->state == SPLITMUX_STATE_STOPPED)
       return;
@@ -678,10 +680,15 @@ start_next_fragment (GstSplitMuxSink * splitmux)
 
   /* Switch state and go back to processing */
   splitmux->state = SPLITMUX_STATE_COLLECTING_GOP_START;
-  if (!splitmux->video_ctx->in_eos)
+
+  if (!splitmux->video_ctx->in_eos) {
     splitmux->max_out_running_time = splitmux->video_ctx->in_running_time;
-  else
+  } else {
     splitmux->max_out_running_time = GST_CLOCK_TIME_NONE;
+    splitmux->have_muxed_something = FALSE;
+  }
+  splitmux->have_muxed_something =
+      (splitmux->video_ctx->in_running_time > splitmux->muxed_out_time);
 
   /* Store the overflow parameters as the basis for the next fragment */
   splitmux->mux_start_time = splitmux->muxed_out_time;
@@ -759,7 +766,7 @@ handle_gathered_gop (GstSplitMuxSink * splitmux)
 
   /* Check for overrun - have we output at least one byte and overrun
    * either threshold? */
-  if ((splitmux->mux_start_bytes < splitmux->muxed_out_bytes) &&
+  if (splitmux->have_muxed_something &&
       ((splitmux->threshold_bytes > 0 &&
               queued_bytes >= splitmux->threshold_bytes) ||
           (splitmux->threshold_time > 0 &&
@@ -782,6 +789,8 @@ handle_gathered_gop (GstSplitMuxSink * splitmux)
 
     /* Wake everyone up to push this one GOP, then sleep */
     splitmux->state = SPLITMUX_STATE_COLLECTING_GOP_START;
+    splitmux->have_muxed_something = TRUE;
+
     if (!splitmux->video_ctx->in_eos)
       splitmux->max_out_running_time = splitmux->video_ctx->in_running_time;
     else
index f383767..a305ed4 100644 (file)
@@ -118,6 +118,7 @@ struct _GstSplitMuxSink {
 
   GstClockTime muxed_out_time;
   gsize muxed_out_bytes;
+  gboolean have_muxed_something;
 
   GstClockTime mux_start_time;
   gsize mux_start_bytes;