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
This commit is contained in:
Julien Isorce 2017-08-29 09:47:51 +01:00
parent c134a3c21b
commit 68518acb53
2 changed files with 43 additions and 8 deletions

View file

@ -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);

View file

@ -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;
}