From d8868c633900a77139ea263b4bfe26970991d8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Wed, 15 Feb 2017 14:48:58 -0500 Subject: [PATCH] splitmuxsink: Change files on incompatible caps https://bugzilla.gnome.org/show_bug.cgi?id=761761 --- gst/multifile/gstsplitmuxsink.c | 55 +++++++++++++++++++++++++++++++-- gst/multifile/gstsplitmuxsink.h | 1 + 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/gst/multifile/gstsplitmuxsink.c b/gst/multifile/gstsplitmuxsink.c index 4f8865bd41..5d8c974f5b 100644 --- a/gst/multifile/gstsplitmuxsink.c +++ b/gst/multifile/gstsplitmuxsink.c @@ -612,6 +612,9 @@ send_eos (GstSplitMuxSink * splitmux, MqStreamCtx * ctx) static void complete_or_wait_on_out (GstSplitMuxSink * splitmux, MqStreamCtx * ctx) { + if (ctx->caps_change) + return; + do { /* When first starting up, the reference stream has to output * the first buffer to prepare the muxer and sink */ @@ -895,6 +898,43 @@ handle_mq_output (GstPad * pad, GstPadProbeInfo * info, MqStreamCtx * ctx) GST_SPLITMUX_UNLOCK (splitmux); return GST_PAD_PROBE_DROP; } + case GST_EVENT_CAPS:{ + GstPad *peer; + + if (!ctx->is_reference) + break; + + peer = gst_pad_get_peer (pad); + if (peer) { + gboolean ok = gst_pad_send_event (peer, gst_event_ref (event)); + + gst_object_unref (peer); + + if (ok) + break; + } else { + break; + } + /* This is in the case the muxer doesn't allow this change of caps */ + + GST_SPLITMUX_LOCK (splitmux); + locked = TRUE; + ctx->caps_change = TRUE; + splitmux->ready_for_output = FALSE; + + if (splitmux->output_state != SPLITMUX_OUTPUT_STATE_START_NEXT_FILE) { + + if (ctx->out_eos == FALSE) { + send_eos (splitmux, ctx); + } + splitmux->output_state = SPLITMUX_OUTPUT_STATE_START_NEXT_FILE; + } + + /* Lets it fall through, if it fails again, then the muxer just can't + * support this format, but at least we have a closed file. + */ + break; + } default: break; } @@ -907,7 +947,14 @@ handle_mq_output (GstPad * pad, GstPadProbeInfo * info, MqStreamCtx * ctx) complete_or_wait_on_out (splitmux, ctx); GST_SPLITMUX_UNLOCK (splitmux); - return GST_PAD_PROBE_PASS; + /* Don't try to forward sticky events before the next buffer is there + * because it would cause a new file to be created without the first + * buffer being available. + */ + if (ctx->caps_change && GST_EVENT_IS_STICKY (event)) + return GST_PAD_PROBE_DROP; + else + return GST_PAD_PROBE_PASS; } /* Allow everything through until the configured next stopping point */ @@ -930,6 +977,8 @@ handle_mq_output (GstPad * pad, GstPadProbeInfo * info, MqStreamCtx * ctx) " size %" G_GUINT64_FORMAT, pad, GST_STIME_ARGS (ctx->out_running_time), buf_info->buf_size); + ctx->caps_change = FALSE; + complete_or_wait_on_out (splitmux, ctx); splitmux->muxed_out_bytes += buf_info->buf_size; @@ -1015,7 +1064,9 @@ start_next_fragment (GstSplitMuxSink * splitmux, MqStreamCtx * ctx) gst_element_set_state (sink, GST_STATE_NULL); GST_SPLITMUX_LOCK (splitmux); - set_next_filename (splitmux, ctx); + if (splitmux->muxed_out_bytes > 0 || splitmux->fragment_id == 0) + set_next_filename (splitmux, ctx); + splitmux->muxed_out_bytes = 0; GST_SPLITMUX_UNLOCK (splitmux); gst_element_set_state (sink, GST_STATE_TARGET (splitmux)); diff --git a/gst/multifile/gstsplitmuxsink.h b/gst/multifile/gstsplitmuxsink.h index a0599fbc8b..31e50f6273 100644 --- a/gst/multifile/gstsplitmuxsink.h +++ b/gst/multifile/gstsplitmuxsink.h @@ -82,6 +82,7 @@ typedef struct _MqStreamCtx gboolean in_eos; gboolean out_eos; gboolean need_unblock; + gboolean caps_change; GstSegment in_segment; GstSegment out_segment;