2 * Copyright (C) 2007 David Schleef <ds@schleef.org>
3 * (C) 2008 Wim Taymans <wim.taymans@gmail.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * SECTION:element-appsink
24 * Appsink is a sink plugin that supports many different methods for making
25 * the application get a handle on the GStreamer data in a pipeline. Unlike
26 * most GStreamer elements, Appsink provides external API functions.
28 * For the documentation of the API, please see the
29 * <link linkend="gst-plugins-base-libs-appsink">libgstapp</link> section in
30 * the GStreamer Plugins Base Libraries documentation.
37 * @see_also: #GstBaseSink, appsrc
39 * Appsink is a sink plugin that supports many different methods for making
40 * the application get a handle on the GStreamer data in a pipeline. Unlike
41 * most GStreamer elements, Appsink provides external API functions.
43 * appsink can be used by linking to the gstappsink.h header file to access the
44 * methods or by using the appsink action signals and properties.
46 * The normal way of retrieving buffers from appsink is by using the
47 * gst_app_sink_pull_buffer() and gst_app_sink_pull_preroll() methods.
48 * These methods block until a buffer becomes available in the sink or when the
49 * sink is shut down or reaches EOS.
51 * Appsink will internally use a queue to collect buffers from the streaming
52 * thread. If the application is not pulling buffers fast enough, this queue
53 * will consume a lot of memory over time. The "max-buffers" property can be
54 * used to limit the queue size. The "drop" property controls whether the
55 * streaming thread blocks or if older buffers are dropped when the maximum
56 * queue size is reached. Note that blocking the streaming thread can negatively
57 * affect real-time performance and should be avoided.
59 * If a blocking behaviour is not desirable, setting the "emit-signals" property
60 * to %TRUE will make appsink emit the "new-buffer" and "new-preroll" signals
61 * when a buffer can be pulled without blocking.
63 * The "caps" property on appsink can be used to control the formats that
64 * appsink can receive. This property can contain non-fixed caps, the format of
65 * the pulled buffers can be obtained by getting the buffer caps.
67 * If one of the pull-preroll or pull-buffer methods return %NULL, the appsink
68 * is stopped or in the EOS state. You can check for the EOS state with the
69 * "eos" property or with the gst_app_sink_is_eos() method.
71 * The eos signal can also be used to be informed when the EOS state is reached
74 * Last reviewed on 2008-12-17 (0.10.10)
82 #include <gst/base/gstbasesink.h>
83 #include <gst/gstbuffer.h>
87 #include "gstappsink.h"
90 GST_DEBUG_CATEGORY (app_sink_debug);
91 #define GST_CAT_DEFAULT app_sink_debug
93 static const GstElementDetails app_sink_details =
94 GST_ELEMENT_DETAILS ("AppSink",
96 "Allow the application to get access to raw buffer",
97 "David Schleef <ds@schleef.org>, Wim Taymans <wim.taymans@gmail.com>");
113 #define DEFAULT_PROP_EOS TRUE
114 #define DEFAULT_PROP_EMIT_SIGNALS FALSE
115 #define DEFAULT_PROP_MAX_BUFFERS 0
116 #define DEFAULT_PROP_DROP FALSE
129 static GstStaticPadTemplate gst_app_sink_template =
130 GST_STATIC_PAD_TEMPLATE ("sink",
133 GST_STATIC_CAPS_ANY);
135 static void gst_app_sink_dispose (GObject * object);
136 static void gst_app_sink_finalize (GObject * object);
138 static void gst_app_sink_set_property (GObject * object, guint prop_id,
139 const GValue * value, GParamSpec * pspec);
140 static void gst_app_sink_get_property (GObject * object, guint prop_id,
141 GValue * value, GParamSpec * pspec);
143 static gboolean gst_app_sink_unlock_start (GstBaseSink * bsink);
144 static gboolean gst_app_sink_unlock_stop (GstBaseSink * bsink);
145 static gboolean gst_app_sink_start (GstBaseSink * psink);
146 static gboolean gst_app_sink_stop (GstBaseSink * psink);
147 static gboolean gst_app_sink_event (GstBaseSink * sink, GstEvent * event);
148 static GstFlowReturn gst_app_sink_preroll (GstBaseSink * psink,
150 static GstFlowReturn gst_app_sink_render (GstBaseSink * psink,
152 static GstCaps *gst_app_sink_getcaps (GstBaseSink * psink);
154 static guint gst_app_sink_signals[LAST_SIGNAL] = { 0 };
156 GST_BOILERPLATE (GstAppSink, gst_app_sink, GstBaseSink, GST_TYPE_BASE_SINK);
159 gst_app_marshal_OBJECT__VOID (GClosure * closure,
160 GValue * return_value,
161 guint n_param_values,
162 const GValue * param_values,
163 gpointer invocation_hint, gpointer marshal_data)
165 typedef GstBuffer *(*GMarshalFunc_OBJECT__VOID) (gpointer data1,
167 register GMarshalFunc_OBJECT__VOID callback;
168 register GCClosure *cc = (GCClosure *) closure;
169 register gpointer data1, data2;
172 g_return_if_fail (return_value != NULL);
173 g_return_if_fail (n_param_values == 1);
175 if (G_CCLOSURE_SWAP_DATA (closure)) {
176 data1 = closure->data;
177 data2 = g_value_peek_pointer (param_values + 0);
179 data1 = g_value_peek_pointer (param_values + 0);
180 data2 = closure->data;
183 (GMarshalFunc_OBJECT__VOID) (marshal_data ? marshal_data : cc->callback);
185 v_return = callback (data1, data2);
187 gst_value_take_buffer (return_value, v_return);
191 gst_app_sink_base_init (gpointer g_class)
193 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
195 GST_DEBUG_CATEGORY_INIT (app_sink_debug, "appsink", 0, "appsink element");
197 gst_element_class_set_details (element_class, &app_sink_details);
199 gst_element_class_add_pad_template (element_class,
200 gst_static_pad_template_get (&gst_app_sink_template));
204 gst_app_sink_class_init (GstAppSinkClass * klass)
206 GObjectClass *gobject_class = (GObjectClass *) klass;
207 GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
209 gobject_class->dispose = gst_app_sink_dispose;
210 gobject_class->finalize = gst_app_sink_finalize;
212 gobject_class->set_property = gst_app_sink_set_property;
213 gobject_class->get_property = gst_app_sink_get_property;
215 g_object_class_install_property (gobject_class, PROP_CAPS,
216 g_param_spec_boxed ("caps", "Caps",
217 "The allowed caps for the sink pad", GST_TYPE_CAPS,
218 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
220 g_object_class_install_property (gobject_class, PROP_EOS,
221 g_param_spec_boolean ("eos", "EOS",
222 "Check if the sink is EOS or not started", DEFAULT_PROP_EOS,
223 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
225 g_object_class_install_property (gobject_class, PROP_EMIT_SIGNALS,
226 g_param_spec_boolean ("emit-signals", "Emit signals",
227 "Emit new-preroll and new-buffer signals", DEFAULT_PROP_EMIT_SIGNALS,
228 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
230 g_object_class_install_property (gobject_class, PROP_MAX_BUFFERS,
231 g_param_spec_uint ("max-buffers", "Max Buffers",
232 "The maximum number of buffers to queue internally (0 = unlimited)",
233 0, G_MAXUINT, DEFAULT_PROP_MAX_BUFFERS,
234 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
236 g_object_class_install_property (gobject_class, PROP_DROP,
237 g_param_spec_boolean ("drop", "Drop",
238 "Drop old buffers when the buffer queue is filled", DEFAULT_PROP_DROP,
239 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
243 * @appsink: the appsink element that emited the signal
245 * Signal that the end-of-stream has been reached. This signal is emited from
246 * the steaming thread.
248 gst_app_sink_signals[SIGNAL_EOS] =
249 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
250 G_STRUCT_OFFSET (GstAppSinkClass, eos),
251 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
253 * GstAppSink::new-preroll:
254 * @appsink: the appsink element that emited the signal
256 * Signal that a new preroll buffer is available.
258 * This signal is emited from the steaming thread and only when the
259 * "emit-signals" property is %TRUE.
261 * The new preroll buffer can be retrieved with the "pull-preroll" action
262 * signal or gst_app_sink_pull_preroll() either from this signal callback
263 * or from any other thread.
265 * Note that this signal is only emited when the "emit-signals" property is
266 * set to %TRUE, which it is not by default for performance reasons.
268 gst_app_sink_signals[SIGNAL_NEW_PREROLL] =
269 g_signal_new ("new-preroll", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
270 G_STRUCT_OFFSET (GstAppSinkClass, new_preroll),
271 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
273 * GstAppSink::new-buffer:
274 * @appsink: the appsink element that emited the signal
276 * Signal that a new buffer is available.
278 * This signal is emited from the steaming thread and only when the
279 * "emit-signals" property is %TRUE.
281 * The new buffer can be retrieved with the "pull-buffer" action
282 * signal or gst_app_sink_pull_buffer() either from this signal callback
283 * or from any other thread.
285 * Note that this signal is only emited when the "emit-signals" property is
286 * set to %TRUE, which it is not by default for performance reasons.
288 gst_app_sink_signals[SIGNAL_NEW_BUFFER] =
289 g_signal_new ("new-buffer", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
290 G_STRUCT_OFFSET (GstAppSinkClass, new_buffer),
291 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
294 * GstAppSink::pull-preroll:
295 * @appsink: the appsink element to emit this signal on
297 * Get the last preroll buffer in @appsink. This was the buffer that caused the
298 * appsink to preroll in the PAUSED state. This buffer can be pulled many times
299 * and remains available to the application even after EOS.
301 * This function is typically used when dealing with a pipeline in the PAUSED
302 * state. Calling this function after doing a seek will give the buffer right
303 * after the seek position.
305 * Note that the preroll buffer will also be returned as the first buffer
306 * when calling gst_app_sink_pull_buffer() or the "pull-buffer" action signal.
308 * If an EOS event was received before any buffers, this function returns
309 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
311 * This function blocks until a preroll buffer or EOS is received or the appsink
312 * element is set to the READY/NULL state.
314 * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS.
316 gst_app_sink_signals[SIGNAL_PULL_PREROLL] =
317 g_signal_new ("pull-preroll", G_TYPE_FROM_CLASS (klass),
318 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass,
319 pull_preroll), NULL, NULL, gst_app_marshal_OBJECT__VOID,
320 GST_TYPE_BUFFER, 0, G_TYPE_NONE);
322 * GstAppSink::pull-buffer:
323 * @appsink: the appsink element to emit this signal on
325 * This function blocks until a buffer or EOS becomes available or the appsink
326 * element is set to the READY/NULL state.
328 * This function will only return buffers when the appsink is in the PLAYING
329 * state. All rendered buffers will be put in a queue so that the application
330 * can pull buffers at its own rate.
332 * Note that when the application does not pull buffers fast enough, the
333 * queued buffers could consume a lot of memory, especially when dealing with
334 * raw video frames. It's possible to control the behaviour of the queue with
335 * the "drop" and "max-buffers" properties.
337 * If an EOS event was received before any buffers, this function returns
338 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
340 * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS.
342 gst_app_sink_signals[SIGNAL_PULL_PREROLL] =
343 g_signal_new ("pull-buffer", G_TYPE_FROM_CLASS (klass),
344 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass,
345 pull_buffer), NULL, NULL, gst_app_marshal_OBJECT__VOID,
346 GST_TYPE_BUFFER, 0, G_TYPE_NONE);
348 basesink_class->unlock = gst_app_sink_unlock_start;
349 basesink_class->unlock_stop = gst_app_sink_unlock_stop;
350 basesink_class->start = gst_app_sink_start;
351 basesink_class->stop = gst_app_sink_stop;
352 basesink_class->event = gst_app_sink_event;
353 basesink_class->preroll = gst_app_sink_preroll;
354 basesink_class->render = gst_app_sink_render;
355 basesink_class->get_caps = gst_app_sink_getcaps;
357 klass->pull_preroll = gst_app_sink_pull_preroll;
358 klass->pull_buffer = gst_app_sink_pull_buffer;
362 gst_app_sink_init (GstAppSink * appsink, GstAppSinkClass * klass)
364 appsink->mutex = g_mutex_new ();
365 appsink->cond = g_cond_new ();
366 appsink->queue = g_queue_new ();
368 appsink->emit_signals = DEFAULT_PROP_EMIT_SIGNALS;
369 appsink->max_buffers = DEFAULT_PROP_MAX_BUFFERS;
370 appsink->drop = DEFAULT_PROP_DROP;
374 gst_app_sink_dispose (GObject * obj)
376 GstAppSink *appsink = GST_APP_SINK (obj);
379 GST_OBJECT_LOCK (appsink);
381 gst_caps_unref (appsink->caps);
382 appsink->caps = NULL;
384 GST_OBJECT_UNLOCK (appsink);
386 g_mutex_lock (appsink->mutex);
387 if (appsink->preroll) {
388 gst_buffer_unref (appsink->preroll);
389 appsink->preroll = NULL;
391 while ((buffer = g_queue_pop_head (appsink->queue)))
392 gst_buffer_unref (buffer);
393 g_mutex_unlock (appsink->mutex);
395 G_OBJECT_CLASS (parent_class)->dispose (obj);
399 gst_app_sink_finalize (GObject * obj)
401 GstAppSink *appsink = GST_APP_SINK (obj);
403 g_mutex_free (appsink->mutex);
404 g_cond_free (appsink->cond);
405 g_queue_free (appsink->queue);
407 G_OBJECT_CLASS (parent_class)->finalize (obj);
411 gst_app_sink_set_property (GObject * object, guint prop_id,
412 const GValue * value, GParamSpec * pspec)
414 GstAppSink *appsink = GST_APP_SINK (object);
418 gst_app_sink_set_caps (appsink, gst_value_get_caps (value));
420 case PROP_EMIT_SIGNALS:
421 gst_app_sink_set_emit_signals (appsink, g_value_get_boolean (value));
423 case PROP_MAX_BUFFERS:
424 gst_app_sink_set_max_buffers (appsink, g_value_get_uint (value));
427 gst_app_sink_set_drop (appsink, g_value_get_boolean (value));
430 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
436 gst_app_sink_get_property (GObject * object, guint prop_id, GValue * value,
439 GstAppSink *appsink = GST_APP_SINK (object);
446 caps = gst_app_sink_get_caps (appsink);
447 gst_value_set_caps (value, caps);
449 gst_caps_unref (caps);
453 g_value_set_boolean (value, gst_app_sink_is_eos (appsink));
455 case PROP_EMIT_SIGNALS:
456 g_value_set_boolean (value, gst_app_sink_get_emit_signals (appsink));
458 case PROP_MAX_BUFFERS:
459 g_value_set_uint (value, gst_app_sink_get_max_buffers (appsink));
462 g_value_set_boolean (value, gst_app_sink_get_drop (appsink));
465 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
471 gst_app_sink_unlock_start (GstBaseSink * bsink)
473 GstAppSink *appsink = GST_APP_SINK (bsink);
475 g_mutex_lock (appsink->mutex);
476 GST_DEBUG_OBJECT (appsink, "unlock start");
477 appsink->flushing = TRUE;
478 g_cond_signal (appsink->cond);
479 g_mutex_unlock (appsink->mutex);
485 gst_app_sink_unlock_stop (GstBaseSink * bsink)
487 GstAppSink *appsink = GST_APP_SINK (bsink);
489 g_mutex_lock (appsink->mutex);
490 GST_DEBUG_OBJECT (appsink, "unlock stop");
491 appsink->flushing = FALSE;
492 g_cond_signal (appsink->cond);
493 g_mutex_unlock (appsink->mutex);
499 gst_app_sink_flush_unlocked (GstAppSink * appsink)
503 GST_DEBUG_OBJECT (appsink, "flush stop appsink");
504 appsink->is_eos = FALSE;
505 gst_buffer_replace (&appsink->preroll, NULL);
506 while ((buffer = g_queue_pop_head (appsink->queue)))
507 gst_buffer_unref (buffer);
508 g_cond_signal (appsink->cond);
512 gst_app_sink_start (GstBaseSink * psink)
514 GstAppSink *appsink = GST_APP_SINK (psink);
516 g_mutex_lock (appsink->mutex);
517 GST_DEBUG_OBJECT (appsink, "starting");
518 appsink->started = TRUE;
519 g_mutex_unlock (appsink->mutex);
525 gst_app_sink_stop (GstBaseSink * psink)
527 GstAppSink *appsink = GST_APP_SINK (psink);
529 g_mutex_lock (appsink->mutex);
530 GST_DEBUG_OBJECT (appsink, "stopping");
531 appsink->flushing = TRUE;
532 appsink->started = FALSE;
533 gst_app_sink_flush_unlocked (appsink);
534 g_mutex_unlock (appsink->mutex);
540 gst_app_sink_event (GstBaseSink * sink, GstEvent * event)
542 GstAppSink *appsink = GST_APP_SINK (sink);
544 switch (event->type) {
547 g_mutex_lock (appsink->mutex);
548 GST_DEBUG_OBJECT (appsink, "receiving EOS");
549 appsink->is_eos = TRUE;
550 g_cond_signal (appsink->cond);
551 g_mutex_unlock (appsink->mutex);
554 g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_EOS], 0);
556 case GST_EVENT_FLUSH_START:
557 /* we don't have to do anything here, the base class will call unlock
558 * which will make sure we exit the _render method */
559 GST_DEBUG_OBJECT (appsink, "received FLUSH_START");
561 case GST_EVENT_FLUSH_STOP:
562 g_mutex_lock (appsink->mutex);
563 GST_DEBUG_OBJECT (appsink, "received FLUSH_STOP");
564 gst_app_sink_flush_unlocked (appsink);
565 g_mutex_unlock (appsink->mutex);
574 gst_app_sink_preroll (GstBaseSink * psink, GstBuffer * buffer)
576 GstAppSink *appsink = GST_APP_SINK (psink);
579 g_mutex_lock (appsink->mutex);
580 if (appsink->flushing)
583 GST_DEBUG_OBJECT (appsink, "setting preroll buffer %p", buffer);
584 gst_buffer_replace (&appsink->preroll, buffer);
585 g_cond_signal (appsink->cond);
586 emit = appsink->emit_signals;
587 g_mutex_unlock (appsink->mutex);
590 g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_PREROLL], 0);
596 GST_DEBUG_OBJECT (appsink, "we are flushing");
597 g_mutex_unlock (appsink->mutex);
598 return GST_FLOW_WRONG_STATE;
603 gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer)
605 GstAppSink *appsink = GST_APP_SINK (psink);
608 g_mutex_lock (appsink->mutex);
609 if (appsink->flushing)
612 GST_DEBUG_OBJECT (appsink, "pushing render buffer %p on queue (%d)",
613 buffer, appsink->queue->length);
615 while (appsink->max_buffers > 0 &&
616 appsink->queue->length >= appsink->max_buffers) {
620 /* we need to drop the oldest buffer and try again */
621 buf = g_queue_pop_head (appsink->queue);
622 GST_DEBUG_OBJECT (appsink, "dropping old buffer %p", buf);
623 gst_buffer_unref (buf);
625 GST_DEBUG_OBJECT (appsink, "waiting for free space, length %d >= %d",
626 appsink->queue->length, appsink->max_buffers);
627 /* wait for a buffer to be removed or flush */
628 g_cond_wait (appsink->cond, appsink->mutex);
629 if (appsink->flushing)
633 /* we need to ref the buffer when pushing it in the queue */
634 g_queue_push_tail (appsink->queue, gst_buffer_ref (buffer));
635 g_cond_signal (appsink->cond);
636 emit = appsink->emit_signals;
637 g_mutex_unlock (appsink->mutex);
640 g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_BUFFER], 0);
646 GST_DEBUG_OBJECT (appsink, "we are flushing");
647 g_mutex_unlock (appsink->mutex);
648 return GST_FLOW_WRONG_STATE;
653 gst_app_sink_getcaps (GstBaseSink * psink)
657 GstAppSink *appsink = GST_APP_SINK (psink);
659 GST_OBJECT_LOCK (appsink);
660 if ((caps = appsink->caps))
662 GST_DEBUG_OBJECT (appsink, "got caps %" GST_PTR_FORMAT, caps);
663 GST_OBJECT_UNLOCK (appsink);
671 * gst_app_sink_set_caps:
672 * @appsink: a #GstAppSink
675 * Set the capabilities on the appsink element. This function takes
676 * a copy of the caps structure. After calling this method, the sink will only
677 * accept caps that match @caps. If @caps is non-fixed, you must check the caps
678 * on the buffers to get the actual used caps.
681 gst_app_sink_set_caps (GstAppSink * appsink, const GstCaps * caps)
685 g_return_if_fail (appsink != NULL);
686 g_return_if_fail (GST_IS_APP_SINK (appsink));
688 GST_OBJECT_LOCK (appsink);
689 GST_DEBUG_OBJECT (appsink, "setting caps to %" GST_PTR_FORMAT, caps);
690 if ((old = appsink->caps) != caps) {
692 appsink->caps = gst_caps_copy (caps);
694 appsink->caps = NULL;
696 gst_caps_unref (old);
698 GST_OBJECT_UNLOCK (appsink);
702 * gst_app_sink_get_caps:
703 * @appsink: a #GstAppSink
705 * Get the configured caps on @appsink.
707 * Returns: the #GstCaps accepted by the sink. gst_caps_unref() after usage.
710 gst_app_sink_get_caps (GstAppSink * appsink)
714 g_return_val_if_fail (appsink != NULL, NULL);
715 g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
717 GST_OBJECT_LOCK (appsink);
718 if ((caps = appsink->caps))
720 GST_DEBUG_OBJECT (appsink, "getting caps of %" GST_PTR_FORMAT, caps);
721 GST_OBJECT_UNLOCK (appsink);
727 * gst_app_sink_is_eos:
728 * @appsink: a #GstAppSink
730 * Check if @appsink is EOS, which is when no more buffers can be pulled because
731 * an EOS event was received.
733 * This function also returns %TRUE when the appsink is not in the PAUSED or
736 * Returns: %TRUE if no more buffers can be pulled and the appsink is EOS.
739 gst_app_sink_is_eos (GstAppSink * appsink)
743 g_return_val_if_fail (appsink != NULL, FALSE);
744 g_return_val_if_fail (GST_IS_APP_SINK (appsink), FALSE);
746 g_mutex_lock (appsink->mutex);
747 if (!appsink->started)
750 if (appsink->is_eos && g_queue_is_empty (appsink->queue)) {
751 GST_DEBUG_OBJECT (appsink, "we are EOS and the queue is empty");
754 GST_DEBUG_OBJECT (appsink, "we are not yet EOS");
757 g_mutex_unlock (appsink->mutex);
763 GST_DEBUG_OBJECT (appsink, "we are stopped, return TRUE");
764 g_mutex_unlock (appsink->mutex);
770 * gst_app_sink_set_emit_signals:
771 * @appsink: a #GstAppSink
772 * @emit: the new state
774 * Make appsink emit the "new-preroll" and "new-buffer" signals. This option is
775 * by default disabled because signal emission is expensive and unneeded when
776 * the application prefers to operate in pull mode.
779 gst_app_sink_set_emit_signals (GstAppSink * appsink, gboolean emit)
781 g_return_if_fail (GST_IS_APP_SINK (appsink));
783 g_mutex_lock (appsink->mutex);
784 appsink->emit_signals = emit;
785 g_mutex_unlock (appsink->mutex);
789 * gst_app_sink_get_emit_signals:
790 * @appsink: a #GstAppSink
792 * Check if appsink will emit the "new-preroll" and "new-buffer" signals.
794 * Returns: %TRUE if @appsink is emiting the "new-preroll" and "new-buffer"
798 gst_app_sink_get_emit_signals (GstAppSink * appsink)
802 g_return_val_if_fail (GST_IS_APP_SINK (appsink), FALSE);
804 g_mutex_lock (appsink->mutex);
805 result = appsink->emit_signals;
806 g_mutex_unlock (appsink->mutex);
812 * gst_app_sink_set_max_buffers:
813 * @appsink: a #GstAppSink
814 * @max: the maximum number of buffers to queue
816 * Set the maximum amount of buffers that can be queued in @appsink. After this
817 * amount of buffers are queued in appsink, any more buffers will block upstream
818 * elements until a buffer is pulled from @appsink.
821 gst_app_sink_set_max_buffers (GstAppSink * appsink, guint max)
823 g_return_if_fail (GST_IS_APP_SINK (appsink));
825 g_mutex_lock (appsink->mutex);
826 if (max != appsink->max_buffers) {
827 appsink->max_buffers = max;
828 /* signal the change */
829 g_cond_signal (appsink->cond);
831 g_mutex_unlock (appsink->mutex);
835 * gst_app_sink_get_max_buffers:
836 * @appsink: a #GstAppSink
838 * Get the maximum amount of buffers that can be queued in @appsink.
840 * Returns: The maximum amount of buffers that can be queued.
843 gst_app_sink_get_max_buffers (GstAppSink * appsink)
847 g_return_val_if_fail (GST_IS_APP_SINK (appsink), 0);
849 g_mutex_lock (appsink->mutex);
850 result = appsink->max_buffers;
851 g_mutex_unlock (appsink->mutex);
857 * gst_app_sink_set_drop:
858 * @appsink: a #GstAppSink
859 * @drop: the new state
861 * Instruct @appsink to drop old buffers when the maximum amount of queued
862 * buffers is reached.
865 gst_app_sink_set_drop (GstAppSink * appsink, gboolean drop)
867 g_return_if_fail (GST_IS_APP_SINK (appsink));
869 g_mutex_lock (appsink->mutex);
870 if (appsink->drop != drop) {
871 appsink->drop = drop;
872 /* signal the change */
873 g_cond_signal (appsink->cond);
875 g_mutex_unlock (appsink->mutex);
879 * gst_app_sink_get_drop:
880 * @appsink: a #GstAppSink
882 * Check if @appsink will drop old buffers when the maximum amount of queued
883 * buffers is reached.
885 * Returns: %TRUE if @appsink is dropping old buffers when the queue is
889 gst_app_sink_get_drop (GstAppSink * appsink)
893 g_return_val_if_fail (GST_IS_APP_SINK (appsink), FALSE);
895 g_mutex_lock (appsink->mutex);
896 result = appsink->drop;
897 g_mutex_unlock (appsink->mutex);
903 * gst_app_sink_pull_preroll:
904 * @appsink: a #GstAppSink
906 * Get the last preroll buffer in @appsink. This was the buffer that caused the
907 * appsink to preroll in the PAUSED state. This buffer can be pulled many times
908 * and remains available to the application even after EOS.
910 * This function is typically used when dealing with a pipeline in the PAUSED
911 * state. Calling this function after doing a seek will give the buffer right
912 * after the seek position.
914 * Note that the preroll buffer will also be returned as the first buffer
915 * when calling gst_app_sink_pull_buffer().
917 * If an EOS event was received before any buffers, this function returns
918 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
920 * This function blocks until a preroll buffer or EOS is received or the appsink
921 * element is set to the READY/NULL state.
923 * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS.
926 gst_app_sink_pull_preroll (GstAppSink * appsink)
928 GstBuffer *buf = NULL;
930 g_return_val_if_fail (appsink != NULL, NULL);
931 g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
933 g_mutex_lock (appsink->mutex);
936 GST_DEBUG_OBJECT (appsink, "trying to grab a buffer");
937 if (!appsink->started)
940 if (appsink->preroll != NULL)
946 /* nothing to return, wait */
947 GST_DEBUG_OBJECT (appsink, "waiting for the preroll buffer");
948 g_cond_wait (appsink->cond, appsink->mutex);
950 buf = gst_buffer_ref (appsink->preroll);
951 GST_DEBUG_OBJECT (appsink, "we have the preroll buffer %p", buf);
952 g_mutex_unlock (appsink->mutex);
956 /* special conditions */
959 GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL");
960 g_mutex_unlock (appsink->mutex);
965 GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL");
966 g_mutex_unlock (appsink->mutex);
972 * gst_app_sink_pull_buffer:
973 * @appsink: a #GstAppSink
975 * This function blocks until a buffer or EOS becomes available or the appsink
976 * element is set to the READY/NULL state.
978 * This function will only return buffers when the appsink is in the PLAYING
979 * state. All rendered buffers will be put in a queue so that the application
980 * can pull buffers at its own rate. Note that when the application does not
981 * pull buffers fast enough, the queued buffers could consume a lot of memory,
982 * especially when dealing with raw video frames.
984 * If an EOS event was received before any buffers, this function returns
985 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
987 * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS.
990 gst_app_sink_pull_buffer (GstAppSink * appsink)
992 GstBuffer *buf = NULL;
994 g_return_val_if_fail (appsink != NULL, NULL);
995 g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
997 g_mutex_lock (appsink->mutex);
1000 GST_DEBUG_OBJECT (appsink, "trying to grab a buffer");
1001 if (!appsink->started)
1004 if (!g_queue_is_empty (appsink->queue))
1007 if (appsink->is_eos)
1010 /* nothing to return, wait */
1011 GST_DEBUG_OBJECT (appsink, "waiting for a buffer");
1012 g_cond_wait (appsink->cond, appsink->mutex);
1014 buf = g_queue_pop_head (appsink->queue);
1015 GST_DEBUG_OBJECT (appsink, "we have a buffer %p", buf);
1016 g_cond_signal (appsink->cond);
1017 g_mutex_unlock (appsink->mutex);
1021 /* special conditions */
1024 GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL");
1025 g_mutex_unlock (appsink->mutex);
1030 GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL");
1031 g_mutex_unlock (appsink->mutex);