mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-03 04:52:28 +00:00
splitmuxsink: Don't crash on EOS without buffer
Fix a case where upstream pushed EOS without buffers. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2753>
This commit is contained in:
parent
450116eafb
commit
c5c149086e
2 changed files with 81 additions and 2 deletions
|
@ -2805,14 +2805,34 @@ handle_mq_input (GstPad * pad, GstPadProbeInfo * info, MqStreamCtx * ctx)
|
||||||
splitmux->input_state = SPLITMUX_INPUT_STATE_WAITING_GOP_COLLECT;
|
splitmux->input_state = SPLITMUX_INPUT_STATE_WAITING_GOP_COLLECT;
|
||||||
/* Wake up other input pads to collect this GOP */
|
/* Wake up other input pads to collect this GOP */
|
||||||
GST_SPLITMUX_BROADCAST_INPUT (splitmux);
|
GST_SPLITMUX_BROADCAST_INPUT (splitmux);
|
||||||
check_completed_gop (splitmux, ctx);
|
if (g_queue_is_empty (&splitmux->pending_input_gops)) {
|
||||||
|
GST_WARNING_OBJECT (splitmux,
|
||||||
|
"EOS with no buffers received on the reference pad");
|
||||||
|
|
||||||
|
/* - child muxer and sink might be still locked state
|
||||||
|
* (see gst_splitmux_reset_elements()) so should be unlocked
|
||||||
|
* for state change of splitmuxsink to be applied to child
|
||||||
|
* - would need to post async done message
|
||||||
|
* - location on sink element is still null then it will post
|
||||||
|
* error message on bus (muxer will produce something, header
|
||||||
|
* data for example)
|
||||||
|
*
|
||||||
|
* Calls start_next_fragment() here, the method will address
|
||||||
|
* everything the above mentioned one */
|
||||||
|
ret = start_next_fragment (splitmux, ctx);
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
goto beach;
|
||||||
|
} else {
|
||||||
|
check_completed_gop (splitmux, ctx);
|
||||||
|
}
|
||||||
} else if (splitmux->input_state ==
|
} else if (splitmux->input_state ==
|
||||||
SPLITMUX_INPUT_STATE_WAITING_GOP_COLLECT) {
|
SPLITMUX_INPUT_STATE_WAITING_GOP_COLLECT) {
|
||||||
/* If we are waiting for a GOP to be completed (ie, for aux
|
/* If we are waiting for a GOP to be completed (ie, for aux
|
||||||
* pads to catch up), then this pad is complete, so check
|
* pads to catch up), then this pad is complete, so check
|
||||||
* if the whole GOP is.
|
* if the whole GOP is.
|
||||||
*/
|
*/
|
||||||
check_completed_gop (splitmux, ctx);
|
if (!g_queue_is_empty (&splitmux->pending_input_gops))
|
||||||
|
check_completed_gop (splitmux, ctx);
|
||||||
}
|
}
|
||||||
GST_SPLITMUX_UNLOCK (splitmux);
|
GST_SPLITMUX_UNLOCK (splitmux);
|
||||||
break;
|
break;
|
||||||
|
@ -3181,6 +3201,15 @@ handle_mq_input (GstPad * pad, GstPadProbeInfo * info, MqStreamCtx * ctx)
|
||||||
|
|
||||||
GST_LOG_OBJECT (pad,
|
GST_LOG_OBJECT (pad,
|
||||||
"Collected last packet of GOP. Checking other pads");
|
"Collected last packet of GOP. Checking other pads");
|
||||||
|
|
||||||
|
if (g_queue_is_empty (&splitmux->pending_input_gops)) {
|
||||||
|
GST_WARNING_OBJECT (pad,
|
||||||
|
"Reference was closed without GOP, dropping");
|
||||||
|
GST_SPLITMUX_UNLOCK (splitmux);
|
||||||
|
GST_PAD_PROBE_INFO_FLOW_RETURN (info) = GST_FLOW_EOS;
|
||||||
|
return GST_PAD_PROBE_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
check_completed_gop (splitmux, ctx);
|
check_completed_gop (splitmux, ctx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -663,6 +663,55 @@ GST_START_TEST (test_splitmuxsink_muxer_pad_map)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_eos_pipeline (guint num_video_buf, guint num_audio_buf,
|
||||||
|
gboolean configure_audio)
|
||||||
|
{
|
||||||
|
GstMessage *msg;
|
||||||
|
GstElement *pipeline;
|
||||||
|
gchar *dest_pattern;
|
||||||
|
gchar *pipeline_str;
|
||||||
|
gchar *audio_branch = NULL;
|
||||||
|
|
||||||
|
dest_pattern = g_build_filename (tmpdir, "out%05d.mp4", NULL);
|
||||||
|
|
||||||
|
if (configure_audio) {
|
||||||
|
audio_branch = g_strdup_printf ("audiotestsrc num-buffers=%d ! "
|
||||||
|
"splitsink.audio_0", num_audio_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline_str = g_strdup_printf ("splitmuxsink name=splitsink location=%s "
|
||||||
|
"muxer-factory=qtmux videotestsrc num-buffers=%d ! jpegenc ! splitsink. "
|
||||||
|
"%s", dest_pattern, num_video_buf, audio_branch ? audio_branch : "");
|
||||||
|
pipeline = gst_parse_launch (pipeline_str, NULL);
|
||||||
|
g_free (dest_pattern);
|
||||||
|
g_free (audio_branch);
|
||||||
|
g_free (pipeline_str);
|
||||||
|
|
||||||
|
fail_if (pipeline == NULL);
|
||||||
|
|
||||||
|
msg = run_pipeline (pipeline);
|
||||||
|
|
||||||
|
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR)
|
||||||
|
dump_error (msg);
|
||||||
|
fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
|
||||||
|
gst_message_unref (msg);
|
||||||
|
|
||||||
|
gst_object_unref (pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (test_splitmuxsink_eos_without_buffer)
|
||||||
|
{
|
||||||
|
/* below pipelines will create non-playable files but at least we should not
|
||||||
|
* crash */
|
||||||
|
run_eos_pipeline (0, 0, FALSE);
|
||||||
|
run_eos_pipeline (0, 0, TRUE);
|
||||||
|
run_eos_pipeline (1, 0, TRUE);
|
||||||
|
run_eos_pipeline (0, 1, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static GstPadProbeReturn
|
static GstPadProbeReturn
|
||||||
count_upstrea_fku (GstPad * pad, GstPadProbeInfo * info,
|
count_upstrea_fku (GstPad * pad, GstPadProbeInfo * info,
|
||||||
guint * upstream_fku_count)
|
guint * upstream_fku_count)
|
||||||
|
@ -863,6 +912,7 @@ splitmuxsink_suite (void)
|
||||||
tcase_add_checked_fixture (tc_chain_mp4_jpeg, tempdir_setup,
|
tcase_add_checked_fixture (tc_chain_mp4_jpeg, tempdir_setup,
|
||||||
tempdir_cleanup);
|
tempdir_cleanup);
|
||||||
tcase_add_test (tc_chain_mp4_jpeg, test_splitmuxsink_muxer_pad_map);
|
tcase_add_test (tc_chain_mp4_jpeg, test_splitmuxsink_muxer_pad_map);
|
||||||
|
tcase_add_test (tc_chain_mp4_jpeg, test_splitmuxsink_eos_without_buffer);
|
||||||
} else {
|
} else {
|
||||||
GST_INFO ("Skipping tests, missing plugins: jpegenc or mp4mux");
|
GST_INFO ("Skipping tests, missing plugins: jpegenc or mp4mux");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue