mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-05-18 00:12:46 +00:00
Merge branch 'sink-preroll-object' into 'main'
basesink, appsink: Add an API to basesink to notify preroll object and unblock pull-preroll on GAP event See merge request gstreamer/gstreamer!861
This commit is contained in:
commit
e47f6b0135
|
@ -152,10 +152,18 @@ If an EOS event was received before any buffers, this function returns
|
|||
%NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
|
||||
|
||||
This function blocks until a preroll sample or EOS is received or the appsink
|
||||
element is set to the READY/NULL state.</doc>
|
||||
element is set to the READY/NULL state.
|
||||
|
||||
As of 1.24, gst_app_sink_pull_preroll() will be unblocked if the appsink
|
||||
is prerolled via GAP event, then this function will return %NULL.
|
||||
And if #GstBufferList support was enabled via
|
||||
gst_app_sink_set_buffer_list_support(), returned #GstSample will contain
|
||||
#GstBufferList instead of #GstBuffer when the preroll object is
|
||||
#GstBufferList</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.h"/>
|
||||
<return-value transfer-ownership="full" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is stopped or EOS.
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is
|
||||
stopped, EOS, or preroll object is GAP event.
|
||||
Call gst_sample_unref() after usage.</doc>
|
||||
<type name="Gst.Sample" c:type="GstSample*"/>
|
||||
</return-value>
|
||||
|
@ -247,10 +255,18 @@ this function returns %NULL. Use gst_app_sink_is_eos () to check for the EOS
|
|||
condition.
|
||||
|
||||
This function blocks until a preroll sample or EOS is received, the appsink
|
||||
element is set to the READY/NULL state, or the timeout expires.</doc>
|
||||
element is set to the READY/NULL state, or the timeout expires.
|
||||
|
||||
As of 1.24, gst_app_sink_try_pull_preroll() will be unblocked if the appsink
|
||||
is prerolled via GAP event, then this function will return %NULL.
|
||||
And if #GstBufferList support was enabled via
|
||||
gst_app_sink_set_buffer_list_support(), returned #GstSample will contain
|
||||
#GstBufferList instead of #GstBuffer when the preroll object is
|
||||
#GstBufferList</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.h"/>
|
||||
<return-value transfer-ownership="full" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is stopped or EOS or the timeout expires.
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is
|
||||
stopped, EOS, or preroll object is GAP event or the timeout expires.
|
||||
Call gst_sample_unref() after usage.</doc>
|
||||
<type name="Gst.Sample" c:type="GstSample*"/>
|
||||
</return-value>
|
||||
|
@ -481,10 +497,18 @@ If an EOS event was received before any buffers, this function returns
|
|||
%NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
|
||||
|
||||
This function blocks until a preroll sample or EOS is received or the appsink
|
||||
element is set to the READY/NULL state.</doc>
|
||||
element is set to the READY/NULL state.
|
||||
|
||||
As of 1.24, gst_app_sink_pull_preroll() will be unblocked if the appsink
|
||||
is prerolled via GAP event, then this function will return %NULL.
|
||||
And if #GstBufferList support was enabled via
|
||||
gst_app_sink_set_buffer_list_support(), returned #GstSample will contain
|
||||
#GstBufferList instead of #GstBuffer when the preroll object is
|
||||
#GstBufferList</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.h"/>
|
||||
<return-value transfer-ownership="full" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is stopped or EOS.
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is
|
||||
stopped, EOS, or preroll object is GAP event.
|
||||
Call gst_sample_unref() after usage.</doc>
|
||||
<type name="Gst.Sample" c:type="GstSample*"/>
|
||||
</return-value>
|
||||
|
@ -763,10 +787,18 @@ this function returns %NULL. Use gst_app_sink_is_eos () to check for the EOS
|
|||
condition.
|
||||
|
||||
This function blocks until a preroll sample or EOS is received, the appsink
|
||||
element is set to the READY/NULL state, or the timeout expires.</doc>
|
||||
element is set to the READY/NULL state, or the timeout expires.
|
||||
|
||||
As of 1.24, gst_app_sink_try_pull_preroll() will be unblocked if the appsink
|
||||
is prerolled via GAP event, then this function will return %NULL.
|
||||
And if #GstBufferList support was enabled via
|
||||
gst_app_sink_set_buffer_list_support(), returned #GstSample will contain
|
||||
#GstBufferList instead of #GstBuffer when the preroll object is
|
||||
#GstBufferList</doc>
|
||||
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.h"/>
|
||||
<return-value transfer-ownership="full" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is stopped or EOS or the timeout expires.
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is
|
||||
stopped, EOS, or preroll object is GAP event or the timeout expires.
|
||||
Call gst_sample_unref() after usage.</doc>
|
||||
<type name="Gst.Sample" c:type="GstSample*"/>
|
||||
</return-value>
|
||||
|
@ -1211,7 +1243,8 @@ gst_app_sink_set_callbacks().</doc>
|
|||
<callback name="pull_preroll">
|
||||
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.h"/>
|
||||
<return-value transfer-ownership="full" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is stopped or EOS.
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is
|
||||
stopped, EOS, or preroll object is GAP event.
|
||||
Call gst_sample_unref() after usage.</doc>
|
||||
<type name="Gst.Sample" c:type="GstSample*"/>
|
||||
</return-value>
|
||||
|
@ -1243,7 +1276,8 @@ gst_app_sink_set_callbacks().</doc>
|
|||
<callback name="try_pull_preroll">
|
||||
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.h"/>
|
||||
<return-value transfer-ownership="full" nullable="1">
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is stopped or EOS or the timeout expires.
|
||||
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/app/gstappsink.c">a #GstSample or NULL when the appsink is
|
||||
stopped, EOS, or preroll object is GAP event or the timeout expires.
|
||||
Call gst_sample_unref() after usage.</doc>
|
||||
<type name="Gst.Sample" c:type="GstSample*"/>
|
||||
</return-value>
|
||||
|
|
|
@ -4141,6 +4141,26 @@ with non-synchronized streams or sparse streams.</doc>
|
|||
</parameter>
|
||||
</parameters>
|
||||
</virtual-method>
|
||||
<virtual-method name="preroll_object" version="1.24">
|
||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/libs/gst/base/gstbasesink.h">Optional. Called to notify subclass of preroll object which can be
|
||||
#GstBuffer, #GstBufferList, or #GstEvent (EOS or GAP).
|
||||
This method will be called additionally after the
|
||||
#GstBaseSinkClass::preroll</doc>
|
||||
<source-position filename="../subprojects/gstreamer/libs/gst/base/gstbasesink.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<type name="Gst.FlowReturn" c:type="GstFlowReturn"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<instance-parameter name="sink" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/libs/gst/base/gstbasesink.h">a #GstBaseSink</doc>
|
||||
<type name="BaseSink" c:type="GstBaseSink*"/>
|
||||
</instance-parameter>
|
||||
<parameter name="object" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/libs/gst/base/gstbasesink.h">a #GstMiniObject</doc>
|
||||
<type name="Gst.MiniObject" c:type="GstMiniObject*"/>
|
||||
</parameter>
|
||||
</parameters>
|
||||
</virtual-method>
|
||||
<virtual-method name="propose_allocation">
|
||||
<source-position filename="../subprojects/gstreamer/libs/gst/base/gstbasesink.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
|
@ -5333,8 +5353,26 @@ output/present buffers.</doc>
|
|||
</parameters>
|
||||
</callback>
|
||||
</field>
|
||||
<field name="preroll_object">
|
||||
<callback name="preroll_object">
|
||||
<source-position filename="../subprojects/gstreamer/libs/gst/base/gstbasesink.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
<type name="Gst.FlowReturn" c:type="GstFlowReturn"/>
|
||||
</return-value>
|
||||
<parameters>
|
||||
<parameter name="sink" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/libs/gst/base/gstbasesink.h">a #GstBaseSink</doc>
|
||||
<type name="BaseSink" c:type="GstBaseSink*"/>
|
||||
</parameter>
|
||||
<parameter name="object" transfer-ownership="none">
|
||||
<doc xml:space="preserve" filename="../subprojects/gstreamer/libs/gst/base/gstbasesink.h">a #GstMiniObject</doc>
|
||||
<type name="Gst.MiniObject" c:type="GstMiniObject*"/>
|
||||
</parameter>
|
||||
</parameters>
|
||||
</callback>
|
||||
</field>
|
||||
<field name="_gst_reserved" readable="0" private="1">
|
||||
<array zero-terminated="0" fixed-size="20">
|
||||
<array zero-terminated="0" fixed-size="19">
|
||||
<type name="gpointer" c:type="gpointer"/>
|
||||
</array>
|
||||
</field>
|
||||
|
|
|
@ -124,7 +124,7 @@ struct _GstAppSinkPrivate
|
|||
GCond cond;
|
||||
GMutex mutex;
|
||||
GstQueueArray *queue;
|
||||
GstBuffer *preroll_buffer;
|
||||
GstMiniObject *preroll_object;
|
||||
GstCaps *preroll_caps;
|
||||
GstCaps *last_caps;
|
||||
GstSegment preroll_segment;
|
||||
|
@ -209,8 +209,8 @@ static gboolean gst_app_sink_start (GstBaseSink * psink);
|
|||
static gboolean gst_app_sink_stop (GstBaseSink * psink);
|
||||
static gboolean gst_app_sink_event (GstBaseSink * sink, GstEvent * event);
|
||||
static gboolean gst_app_sink_query (GstBaseSink * bsink, GstQuery * query);
|
||||
static GstFlowReturn gst_app_sink_preroll (GstBaseSink * psink,
|
||||
GstBuffer * buffer);
|
||||
static GstFlowReturn gst_app_sink_preroll_object (GstBaseSink * psink,
|
||||
GstMiniObject * object);
|
||||
static GstFlowReturn gst_app_sink_render_common (GstBaseSink * psink,
|
||||
GstMiniObject * data, gboolean is_list);
|
||||
static GstFlowReturn gst_app_sink_render (GstBaseSink * psink,
|
||||
|
@ -591,7 +591,7 @@ gst_app_sink_class_init (GstAppSinkClass * klass)
|
|||
basesink_class->start = gst_app_sink_start;
|
||||
basesink_class->stop = gst_app_sink_stop;
|
||||
basesink_class->event = gst_app_sink_event;
|
||||
basesink_class->preroll = gst_app_sink_preroll;
|
||||
basesink_class->preroll_object = gst_app_sink_preroll_object;
|
||||
basesink_class->render = gst_app_sink_render;
|
||||
basesink_class->render_list = gst_app_sink_render_list;
|
||||
basesink_class->get_caps = gst_app_sink_getcaps;
|
||||
|
@ -648,7 +648,7 @@ gst_app_sink_dispose (GObject * obj)
|
|||
callbacks = g_steal_pointer (&priv->callbacks);
|
||||
while ((queue_obj = gst_queue_array_pop_head (priv->queue)))
|
||||
gst_mini_object_unref (queue_obj);
|
||||
gst_buffer_replace (&priv->preroll_buffer, NULL);
|
||||
gst_clear_mini_object (&priv->preroll_object);
|
||||
gst_caps_replace (&priv->preroll_caps, NULL);
|
||||
gst_caps_replace (&priv->last_caps, NULL);
|
||||
if (priv->sample) {
|
||||
|
@ -799,7 +799,7 @@ gst_app_sink_flush_unlocked (GstAppSink * appsink)
|
|||
|
||||
GST_DEBUG_OBJECT (appsink, "flush stop appsink");
|
||||
priv->is_eos = FALSE;
|
||||
gst_buffer_replace (&priv->preroll_buffer, NULL);
|
||||
gst_clear_mini_object (&priv->preroll_object);
|
||||
while ((obj = gst_queue_array_pop_head (priv->queue)))
|
||||
gst_mini_object_unref (obj);
|
||||
|
||||
|
@ -844,7 +844,7 @@ gst_app_sink_stop (GstBaseSink * psink)
|
|||
priv->started = FALSE;
|
||||
priv->wait_status = NOONE_WAITING;
|
||||
gst_app_sink_flush_unlocked (appsink);
|
||||
gst_buffer_replace (&priv->preroll_buffer, NULL);
|
||||
gst_clear_mini_object (&priv->preroll_object);
|
||||
gst_caps_replace (&priv->preroll_caps, NULL);
|
||||
gst_caps_replace (&priv->last_caps, NULL);
|
||||
gst_segment_init (&priv->preroll_segment, GST_FORMAT_UNDEFINED);
|
||||
|
@ -871,7 +871,7 @@ gst_app_sink_setcaps (GstBaseSink * sink, GstCaps * caps)
|
|||
gst_queue_array_push_tail (priv->queue, gst_event_new_caps (caps));
|
||||
gst_queue_status_info_push_event (&priv->queue_status_info);
|
||||
|
||||
if (!priv->preroll_buffer)
|
||||
if (!priv->preroll_object)
|
||||
gst_caps_replace (&priv->preroll_caps, caps);
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
|
||||
|
@ -890,7 +890,7 @@ gst_app_sink_event (GstBaseSink * sink, GstEvent * event)
|
|||
case GST_EVENT_SEGMENT:
|
||||
g_mutex_lock (&priv->mutex);
|
||||
GST_DEBUG_OBJECT (appsink, "receiving SEGMENT");
|
||||
if (!priv->preroll_buffer)
|
||||
if (!priv->preroll_object)
|
||||
gst_event_copy_segment (event, &priv->preroll_segment);
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
break;
|
||||
|
@ -1004,7 +1004,7 @@ gst_app_sink_event (GstBaseSink * sink, GstEvent * event)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_app_sink_preroll (GstBaseSink * psink, GstBuffer * buffer)
|
||||
gst_app_sink_preroll_object (GstBaseSink * psink, GstMiniObject * object)
|
||||
{
|
||||
GstFlowReturn res;
|
||||
GstAppSink *appsink = GST_APP_SINK_CAST (psink);
|
||||
|
@ -1016,8 +1016,8 @@ gst_app_sink_preroll (GstBaseSink * psink, GstBuffer * buffer)
|
|||
if (priv->flushing)
|
||||
goto flushing;
|
||||
|
||||
GST_DEBUG_OBJECT (appsink, "setting preroll buffer %p", buffer);
|
||||
gst_buffer_replace (&priv->preroll_buffer, buffer);
|
||||
GST_DEBUG_OBJECT (appsink, "setting preroll object %" GST_PTR_FORMAT, object);
|
||||
gst_mini_object_replace (&priv->preroll_object, object);
|
||||
|
||||
if ((priv->wait_status & APP_WAITING))
|
||||
g_cond_signal (&priv->cond);
|
||||
|
@ -1284,7 +1284,7 @@ gst_app_sink_query (GstBaseSink * bsink, GstQuery * query)
|
|||
{
|
||||
g_mutex_lock (&priv->mutex);
|
||||
GST_DEBUG_OBJECT (appsink, "waiting buffers to be consumed");
|
||||
while (priv->queue_status_info.queued_buffers > 0 || priv->preroll_buffer) {
|
||||
while (priv->queue_status_info.queued_buffers > 0 || priv->preroll_object) {
|
||||
if (priv->unlock) {
|
||||
/* we are asked to unlock, call the wait_preroll method */
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
|
@ -1804,7 +1804,15 @@ gst_app_sink_get_wait_on_eos (GstAppSink * appsink)
|
|||
* This function blocks until a preroll sample or EOS is received or the appsink
|
||||
* element is set to the READY/NULL state.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a #GstSample or NULL when the appsink is stopped or EOS.
|
||||
* As of 1.24, gst_app_sink_pull_preroll() will be unblocked if the appsink
|
||||
* is prerolled via GAP event, then this function will return %NULL.
|
||||
* And if #GstBufferList support was enabled via
|
||||
* gst_app_sink_set_buffer_list_support(), returned #GstSample will contain
|
||||
* #GstBufferList instead of #GstBuffer when the preroll object is
|
||||
* #GstBufferList
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a #GstSample or NULL when the appsink is
|
||||
* stopped, EOS, or preroll object is GAP event.
|
||||
* Call gst_sample_unref() after usage.
|
||||
*/
|
||||
GstSample *
|
||||
|
@ -1898,7 +1906,15 @@ gst_app_sink_pull_object (GstAppSink * appsink)
|
|||
* This function blocks until a preroll sample or EOS is received, the appsink
|
||||
* element is set to the READY/NULL state, or the timeout expires.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a #GstSample or NULL when the appsink is stopped or EOS or the timeout expires.
|
||||
* As of 1.24, gst_app_sink_try_pull_preroll() will be unblocked if the appsink
|
||||
* is prerolled via GAP event, then this function will return %NULL.
|
||||
* And if #GstBufferList support was enabled via
|
||||
* gst_app_sink_set_buffer_list_support(), returned #GstSample will contain
|
||||
* #GstBufferList instead of #GstBuffer when the preroll object is
|
||||
* #GstBufferList
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a #GstSample or NULL when the appsink is
|
||||
* stopped, EOS, or preroll object is GAP event or the timeout expires.
|
||||
* Call gst_sample_unref() after usage.
|
||||
*
|
||||
* Since: 1.10
|
||||
|
@ -1928,7 +1944,7 @@ gst_app_sink_try_pull_preroll (GstAppSink * appsink, GstClockTime timeout)
|
|||
if (!priv->started)
|
||||
goto not_started;
|
||||
|
||||
if (priv->preroll_buffer != NULL)
|
||||
if (priv->preroll_object != NULL)
|
||||
break;
|
||||
|
||||
if (priv->is_eos)
|
||||
|
@ -1945,11 +1961,31 @@ gst_app_sink_try_pull_preroll (GstAppSink * appsink, GstClockTime timeout)
|
|||
}
|
||||
priv->wait_status &= ~APP_WAITING;
|
||||
}
|
||||
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);
|
||||
|
||||
if (GST_IS_BUFFER (priv->preroll_object)) {
|
||||
sample =
|
||||
gst_sample_new (GST_BUFFER_CAST (priv->preroll_object),
|
||||
priv->preroll_caps, &priv->preroll_segment, NULL);
|
||||
} else if (GST_IS_BUFFER_LIST (priv->preroll_object)) {
|
||||
GstBufferList *buffer_list = GST_BUFFER_LIST_CAST (priv->preroll_object);
|
||||
|
||||
sample = gst_sample_new (NULL, priv->preroll_caps, &priv->preroll_segment,
|
||||
NULL);
|
||||
|
||||
if (appsink->priv->buffer_lists_supported) {
|
||||
gst_sample_set_buffer_list (sample, buffer_list);
|
||||
} else {
|
||||
gst_sample_set_buffer (sample, gst_buffer_list_get (buffer_list, 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (sample) {
|
||||
GST_DEBUG_OBJECT (appsink, "we have the preroll sample %p", sample);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (appsink, "preroll object is not buffer or buffer list");
|
||||
}
|
||||
|
||||
gst_clear_mini_object (&priv->preroll_object);
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
|
||||
return sample;
|
||||
|
@ -2066,7 +2102,7 @@ gst_app_sink_try_pull_object (GstAppSink * appsink, GstClockTime timeout)
|
|||
priv = appsink->priv;
|
||||
|
||||
g_mutex_lock (&priv->mutex);
|
||||
gst_buffer_replace (&priv->preroll_buffer, NULL);
|
||||
gst_clear_mini_object (&priv->preroll_object);
|
||||
|
||||
while (TRUE) {
|
||||
GST_DEBUG_OBJECT (appsink, "trying to grab an object");
|
||||
|
|
|
@ -550,6 +550,66 @@ GST_START_TEST (test_pull_preroll)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_pull_preroll_with_gap)
|
||||
{
|
||||
GstElement *sink = NULL;
|
||||
GstSample *pulled_preroll = NULL;
|
||||
GstEvent *gap;
|
||||
|
||||
sink = setup_appsink ();
|
||||
|
||||
ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
|
||||
|
||||
gap = gst_event_new_gap (0, GST_SECOND);
|
||||
fail_unless (gst_pad_push_event (mysrcpad, gap));
|
||||
|
||||
pulled_preroll = gst_app_sink_pull_preroll (GST_APP_SINK (sink));
|
||||
fail_if (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;
|
||||
|
||||
GST_START_TEST (test_pull_preroll_with_buffer_list_support)
|
||||
{
|
||||
GstElement *sink = NULL;
|
||||
GstSample *pulled_preroll = NULL;
|
||||
GstBufferList *list, *list_in_sample;
|
||||
GstBuffer *buffer;
|
||||
|
||||
sink = setup_appsink ();
|
||||
|
||||
g_object_set (sink, "buffer-list", TRUE, NULL);
|
||||
|
||||
ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
|
||||
|
||||
list = create_buffer_list ();
|
||||
fail_unless (gst_pad_push_list (mysrcpad, list) == GST_FLOW_OK);
|
||||
|
||||
pulled_preroll = gst_app_sink_pull_preroll (GST_APP_SINK (sink));
|
||||
fail_unless (pulled_preroll);
|
||||
|
||||
buffer = gst_sample_get_buffer (pulled_preroll);
|
||||
fail_if (buffer);
|
||||
|
||||
list_in_sample = gst_sample_get_buffer_list (pulled_preroll);
|
||||
fail_unless (GST_IS_BUFFER_LIST (list_in_sample));
|
||||
|
||||
/* unmodified buffer list is expected */
|
||||
fail_unless (list == list_in_sample);
|
||||
|
||||
gst_sample_unref (pulled_preroll);
|
||||
|
||||
ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
|
||||
cleanup_appsink (sink);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_do_not_care_preroll)
|
||||
{
|
||||
GstElement *sink = NULL;
|
||||
|
@ -1261,6 +1321,8 @@ appsink_suite (void)
|
|||
tcase_add_test (tc_chain, test_pull_with_timeout);
|
||||
tcase_add_test (tc_chain, test_query_drain);
|
||||
tcase_add_test (tc_chain, test_pull_preroll);
|
||||
tcase_add_test (tc_chain, test_pull_preroll_with_gap);
|
||||
tcase_add_test (tc_chain, test_pull_preroll_with_buffer_list_support);
|
||||
tcase_add_test (tc_chain, test_do_not_care_preroll);
|
||||
tcase_add_test (tc_chain, test_pull_sample_refcounts);
|
||||
tcase_add_test (tc_chain, test_event_callback);
|
||||
|
|
|
@ -2146,7 +2146,14 @@ again:
|
|||
}
|
||||
} else {
|
||||
/* else do buffer sync code */
|
||||
GstBuffer *buffer = GST_BUFFER_CAST (obj);
|
||||
GstBuffer *buffer;
|
||||
|
||||
/* empty buffer list must be handled already at
|
||||
* gst_base_sink_chain_unlocked() */
|
||||
if (GST_IS_BUFFER_LIST (obj))
|
||||
buffer = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
|
||||
else
|
||||
buffer = GST_BUFFER_CAST (obj);
|
||||
|
||||
/* just get the times to see if we need syncing, if the retuned start is -1
|
||||
* we don't sync. */
|
||||
|
@ -2487,7 +2494,7 @@ gst_base_sink_do_preroll (GstBaseSink * sink, GstMiniObject * obj)
|
|||
|
||||
/* if it's a buffer, we need to call the preroll method */
|
||||
if (sink->priv->call_preroll) {
|
||||
GstBaseSinkClass *bclass;
|
||||
GstBaseSinkClass *bclass = GST_BASE_SINK_GET_CLASS (sink);
|
||||
GstBuffer *buf;
|
||||
|
||||
if (GST_IS_BUFFER_LIST (obj)) {
|
||||
|
@ -2508,8 +2515,6 @@ gst_base_sink_do_preroll (GstBaseSink * sink, GstMiniObject * obj)
|
|||
GST_DEBUG_OBJECT (sink, "preroll buffer %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
|
||||
|
||||
bclass = GST_BASE_SINK_GET_CLASS (sink);
|
||||
|
||||
if (bclass->prepare)
|
||||
if ((ret = bclass->prepare (sink, buf)) != GST_FLOW_OK)
|
||||
goto prepare_canceled;
|
||||
|
@ -2520,6 +2525,15 @@ gst_base_sink_do_preroll (GstBaseSink * sink, GstMiniObject * obj)
|
|||
|
||||
sink->priv->call_preroll = FALSE;
|
||||
}
|
||||
|
||||
if (bclass->preroll_object) {
|
||||
if ((ret = bclass->preroll_object (sink, obj)) != GST_FLOW_OK) {
|
||||
sink->priv->call_preroll = TRUE;
|
||||
goto preroll_canceled;
|
||||
}
|
||||
|
||||
sink->priv->call_preroll = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* commit state */
|
||||
|
@ -3115,8 +3129,8 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
|
|||
if (max_lateness == -1)
|
||||
goto no_drop;
|
||||
|
||||
/* only check for buffers */
|
||||
if (G_UNLIKELY (!GST_IS_BUFFER (obj)))
|
||||
/* only check for buffers or buffer lists */
|
||||
if (G_UNLIKELY (!GST_IS_BUFFER (obj) && !GST_IS_BUFFER_LIST (obj)))
|
||||
goto not_buffer;
|
||||
|
||||
/* can't do check if we don't have a timestamp */
|
||||
|
@ -3923,8 +3937,7 @@ again:
|
|||
|
||||
/* synchronize this object, non syncable objects return OK
|
||||
* immediately. */
|
||||
ret = gst_base_sink_do_sync (basesink, GST_MINI_OBJECT_CAST (sync_buf),
|
||||
&late, &step_end);
|
||||
ret = gst_base_sink_do_sync (basesink, obj, &late, &step_end);
|
||||
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
||||
goto sync_failed;
|
||||
|
||||
|
|
|
@ -223,8 +223,22 @@ struct _GstBaseSinkClass {
|
|||
/* Render a BufferList */
|
||||
GstFlowReturn (*render_list) (GstBaseSink *sink, GstBufferList *buffer_list);
|
||||
|
||||
/**
|
||||
* GstBaseSinkClass::preroll_object:
|
||||
* @sink: a #GstBaseSink
|
||||
* @object: (transfer none): a #GstMiniObject
|
||||
*
|
||||
* Optional. Called to notify subclass of preroll object which can be
|
||||
* #GstBuffer, #GstBufferList, or #GstEvent (EOS or GAP).
|
||||
* This method will be called additionally after the
|
||||
* #GstBaseSinkClass::preroll
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GstFlowReturn (*preroll_object) (GstBaseSink *sink, GstMiniObject * object);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE - 1];
|
||||
};
|
||||
|
||||
GST_BASE_API
|
||||
|
|
Loading…
Reference in a new issue