commit f108a93e47d79926774b83f205bf83fe109d84b6
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Tue Nov 16 12:20:37 2010 +0100

    basesink: also preroll after a flush with async=false
    
    Make sure to preroll after a flush even when we are async=false.
    Add unit test.
    
    Fixes #634965

diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c
index 951940e..6369769 100644
--- a/libs/gst/base/gstbasesink.c
+++ b/libs/gst/base/gstbasesink.c
@@ -3202,7 +3202,6 @@ gst_base_sink_flush_start (GstBaseSink * basesink, GstPad * pad)
     gst_element_lost_state (GST_ELEMENT_CAST (basesink));
   } else {
     basesink->priv->have_latency = TRUE;
-    basesink->need_preroll = FALSE;
   }
   gst_base_sink_set_last_buffer (basesink, NULL);
   GST_PAD_STREAM_UNLOCK (pad);
diff --git a/tests/check/generic/sinks.c b/tests/check/generic/sinks.c
index 8fe4c81..472ed3a 100644
--- a/tests/check/generic/sinks.c
+++ b/tests/check/generic/sinks.c
@@ -1245,6 +1245,86 @@ GST_START_TEST (test_async_done_eos)
 
 GST_END_TEST;
 
+static GMutex *preroll_lock;
+static GCond *preroll_cond;
+
+static void
+test_async_false_seek_preroll (GstElement * elem, GstBuffer * buf,
+    GstPad * pad, gpointer data)
+{
+  g_mutex_lock (preroll_lock);
+  GST_DEBUG ("Got preroll buffer %p", buf);
+  g_cond_signal (preroll_cond);
+  g_mutex_unlock (preroll_lock);
+}
+
+static void
+test_async_false_seek_handoff (GstElement * elem, GstBuffer * buf,
+    GstPad * pad, gpointer data)
+{
+  /* should never be reached, we never go to PLAYING */
+  GST_DEBUG ("Got handoff buffer %p", buf);
+  fail_unless (FALSE);
+}
+
+GST_START_TEST (test_async_false_seek)
+{
+  GstElement *pipeline, *source, *sink;
+
+  preroll_lock = g_mutex_new ();
+  preroll_cond = g_cond_new ();
+
+  /* Create gstreamer elements */
+  pipeline = gst_pipeline_new ("test-pipeline");
+  source = gst_element_factory_make ("fakesrc", "file-source");
+  sink = gst_element_factory_make ("fakesink", "audio-output");
+
+  g_object_set (G_OBJECT (sink), "async", FALSE, NULL);
+  g_object_set (G_OBJECT (sink), "num-buffers", 10, NULL);
+  g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
+
+  g_signal_connect (sink, "handoff", G_CALLBACK (test_async_false_seek_handoff),
+      NULL);
+  g_signal_connect (sink, "preroll-handoff",
+      G_CALLBACK (test_async_false_seek_preroll), NULL);
+
+  /* we add all elements into the pipeline */
+  gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
+
+  /* we link the elements together */
+  gst_element_link (source, sink);
+
+  GST_DEBUG ("Now pausing");
+  g_mutex_lock (preroll_lock);
+  gst_element_set_state (pipeline, GST_STATE_PAUSED);
+
+  /* wait for preroll */
+  GST_DEBUG ("wait for preroll");
+  g_cond_wait (preroll_cond, preroll_lock);
+  g_mutex_unlock (preroll_lock);
+
+  g_mutex_lock (preroll_lock);
+  GST_DEBUG ("Seeking");
+  fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_BYTES,
+          GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, -1));
+
+  GST_DEBUG ("wait for new preroll");
+  /* this either prerolls or fails */
+  g_cond_wait (preroll_cond, preroll_lock);
+  g_mutex_unlock (preroll_lock);
+
+  GST_DEBUG ("bring pipe to state NULL");
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+
+  GST_DEBUG ("Deleting pipeline");
+  gst_object_unref (GST_OBJECT (pipeline));
+
+  g_mutex_free (preroll_lock);
+  g_cond_free (preroll_cond);
+}
+
+GST_END_TEST;
+
 /* test: try changing state of sinks */
 static Suite *
 gst_sinks_suite (void)
@@ -1278,6 +1358,7 @@ gst_sinks_suite (void)
   tcase_add_test (tc_chain, test_fake_eos);
   tcase_add_test (tc_chain, test_async_done);
   tcase_add_test (tc_chain, test_async_done_eos);
+  tcase_add_test (tc_chain, test_async_false_seek);
 
   return s;
 }
