mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +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/2174>
This commit is contained in:
parent
6066e913ee
commit
b233df3537
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;
|
||||
/* Wake up other input pads to collect this GOP */
|
||||
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 ==
|
||||
SPLITMUX_INPUT_STATE_WAITING_GOP_COLLECT) {
|
||||
/* If we are waiting for a GOP to be completed (ie, for aux
|
||||
* pads to catch up), then this pad is complete, so check
|
||||
* 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);
|
||||
break;
|
||||
|
@ -3178,6 +3198,15 @@ handle_mq_input (GstPad * pad, GstPadProbeInfo * info, MqStreamCtx * ctx)
|
|||
|
||||
GST_LOG_OBJECT (pad,
|
||||
"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);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -663,6 +663,55 @@ GST_START_TEST (test_splitmuxsink_muxer_pad_map)
|
|||
|
||||
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
|
||||
count_upstrea_fku (GstPad * pad, GstPadProbeInfo * info,
|
||||
guint * upstream_fku_count)
|
||||
|
@ -863,6 +912,7 @@ splitmuxsink_suite (void)
|
|||
tcase_add_checked_fixture (tc_chain_mp4_jpeg, tempdir_setup,
|
||||
tempdir_cleanup);
|
||||
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 {
|
||||
GST_INFO ("Skipping tests, missing plugins: jpegenc or mp4mux");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue