appsink: unref preroll buffer upon pull
authorJulien Isorce <jisorce@oblong.com>
Tue, 29 Aug 2017 08:47:51 +0000 (09:47 +0100)
committerJulien Isorce <jisorce@oblong.com>
Wed, 13 Sep 2017 13:11:27 +0000 (14:11 +0100)
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
tests/check/elements/appsink.c

index 379b5fb0259d9ae5c4a18b8c8334ede5b3b5c289..539d9b05b655f6407af513834ccbf698c59f10c1 100644 (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);
 
index a5b2c8240f8dbbf010cff3c468e03e8009951a39..84a9f829ced8c6e07c513ad0e3c7dae66af7074a 100644 (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;
 }