From 68518acb53d4808cf8352ed4fd1cb8b331553559 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Tue, 29 Aug 2017 09:47:51 +0100 Subject: [PATCH] appsink: unref preroll buffer upon pull There is no reason for appsink to hang onto the preroll buffer. If needed, the application can just keep a ref on this buffer after calling gst_app_sink_try_pull_preroll. Also added unit test 'test_pull_preroll' make elements/appsink.check https://bugzilla.gnome.org/show_bug.cgi?id=786740 --- gst-libs/gst/app/gstappsink.c | 25 +++++++++++++++++-------- tests/check/elements/appsink.c | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/app/gstappsink.c b/gst-libs/gst/app/gstappsink.c index 379b5fb025..539d9b05b6 100644 --- a/gst-libs/gst/app/gstappsink.c +++ b/gst-libs/gst/app/gstappsink.c @@ -302,13 +302,15 @@ gst_app_sink_class_init (GstAppSinkClass * klass) * @appsink: the appsink element to emit this signal on * * Get the last preroll sample in @appsink. This was the sample that caused the - * appsink to preroll in the PAUSED state. This sample can be pulled many times - * and remains available to the application even after EOS. + * appsink to preroll in the PAUSED state. * * This function is typically used when dealing with a pipeline in the PAUSED * state. Calling this function after doing a seek will give the sample right * after the seek position. * + * Calling this function will clear the internal reference to the preroll + * buffer. + * * Note that the preroll sample will also be returned as the first sample * when calling gst_app_sink_pull_sample() or the "pull-sample" action signal. * @@ -355,13 +357,15 @@ gst_app_sink_class_init (GstAppSinkClass * klass) * @timeout: the maximum amount of time to wait for the preroll sample * * Get the last preroll sample in @appsink. This was the sample that caused the - * appsink to preroll in the PAUSED state. This sample can be pulled many times - * and remains available to the application even after EOS. + * appsink to preroll in the PAUSED state. * * This function is typically used when dealing with a pipeline in the PAUSED * state. Calling this function after doing a seek will give the sample right * after the seek position. * + * Calling this function will clear the internal reference to the preroll + * buffer. + * * Note that the preroll sample will also be returned as the first sample * when calling gst_app_sink_pull_sample() or the "pull-sample" action signal. * @@ -1357,13 +1361,15 @@ gst_app_sink_get_wait_on_eos (GstAppSink * appsink) * @appsink: a #GstAppSink * * Get the last preroll sample in @appsink. This was the sample that caused the - * appsink to preroll in the PAUSED state. This sample can be pulled many times - * and remains available to the application even after EOS. + * appsink to preroll in the PAUSED state. * * This function is typically used when dealing with a pipeline in the PAUSED * state. Calling this function after doing a seek will give the sample right * after the seek position. * + * Calling this function will clear the internal reference to the preroll + * buffer. + * * Note that the preroll sample will also be returned as the first sample * when calling gst_app_sink_pull_sample(). * @@ -1413,13 +1419,15 @@ gst_app_sink_pull_sample (GstAppSink * appsink) * @timeout: the maximum amount of time to wait for the preroll sample * * Get the last preroll sample in @appsink. This was the sample that caused the - * appsink to preroll in the PAUSED state. This sample can be pulled many times - * and remains available to the application even after EOS. + * appsink to preroll in the PAUSED state. * * This function is typically used when dealing with a pipeline in the PAUSED * state. Calling this function after doing a seek will give the sample right * after the seek position. * + * Calling this function will clear the internal reference to the preroll + * buffer. + * * Note that the preroll sample will also be returned as the first sample * when calling gst_app_sink_pull_sample(). * @@ -1478,6 +1486,7 @@ gst_app_sink_try_pull_preroll (GstAppSink * appsink, GstClockTime timeout) sample = gst_sample_new (priv->preroll_buffer, priv->preroll_caps, &priv->preroll_segment, NULL); + gst_buffer_replace (&priv->preroll_buffer, NULL); GST_DEBUG_OBJECT (appsink, "we have the preroll sample %p", sample); g_mutex_unlock (&priv->mutex); diff --git a/tests/check/elements/appsink.c b/tests/check/elements/appsink.c index a5b2c8240f..84a9f829ce 100644 --- a/tests/check/elements/appsink.c +++ b/tests/check/elements/appsink.c @@ -503,6 +503,31 @@ GST_START_TEST (test_pull_with_timeout) GST_END_TEST; +GST_START_TEST (test_pull_preroll) +{ + GstElement *sink = NULL; + GstBuffer *buffer = NULL; + GstSample *pulled_preroll = NULL; + + sink = setup_appsink (); + + ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); + + buffer = gst_buffer_new_and_alloc (4); + fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK); + + pulled_preroll = gst_app_sink_pull_preroll (GST_APP_SINK (sink)); + fail_unless (pulled_preroll); + gst_sample_unref (pulled_preroll); + + fail_if (gst_app_sink_try_pull_preroll (GST_APP_SINK (sink), 0)); + + ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); + cleanup_appsink (sink); +} + +GST_END_TEST; + static Suite * appsink_suite (void) { @@ -520,6 +545,7 @@ appsink_suite (void) tcase_add_test (tc_chain, test_buffer_list_signal); tcase_add_test (tc_chain, test_segment); tcase_add_test (tc_chain, test_pull_with_timeout); + tcase_add_test (tc_chain, test_pull_preroll); return s; }