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 * @short_description: Easy way for applications to extract samples from a
24 * @see_also: #GstSample, #GstBaseSink, appsrc
26 * Appsink is a sink plugin that supports many different methods for making
27 * the application get a handle on the GStreamer data in a pipeline. Unlike
28 * most GStreamer elements, Appsink provides external API functions.
30 * appsink can be used by linking to the gstappsink.h header file to access the
31 * methods or by using the appsink action signals and properties.
33 * The normal way of retrieving samples from appsink is by using the
34 * gst_app_sink_pull_sample() and gst_app_sink_pull_preroll() methods.
35 * These methods block until a sample becomes available in the sink or when the
36 * sink is shut down or reaches EOS.
38 * Appsink will internally use a queue to collect buffers from the streaming
39 * thread. If the application is not pulling samples fast enough, this queue
40 * will consume a lot of memory over time. The "max-buffers" property can be
41 * used to limit the queue size. The "drop" property controls whether the
42 * streaming thread blocks or if older buffers are dropped when the maximum
43 * queue size is reached. Note that blocking the streaming thread can negatively
44 * affect real-time performance and should be avoided.
46 * If a blocking behaviour is not desirable, setting the "emit-signals" property
47 * to %TRUE will make appsink emit the "new-sample" and "new-preroll" signals
48 * when a sample can be pulled without blocking.
50 * The "caps" property on appsink can be used to control the formats that
51 * appsink can receive. This property can contain non-fixed caps, the format of
52 * the pulled samples can be obtained by getting the sample caps.
54 * If one of the pull-preroll or pull-sample methods return %NULL, the appsink
55 * is stopped or in the EOS state. You can check for the EOS state with the
56 * "eos" property or with the gst_app_sink_is_eos() method.
58 * The eos signal can also be used to be informed when the EOS state is reached
61 * Last reviewed on 2008-12-17 (0.10.22)
71 #include <gst/base/gstbasesink.h>
72 #include <gst/gstbuffer.h>
76 #include "gstapp-marshal.h"
77 #include "gstappsink.h"
79 #include "gst/glib-compat-private.h"
81 struct _GstAppSinkPrivate
84 gboolean emit_signals;
93 GstCaps *preroll_caps;
95 GstSegment last_segment;
101 GstAppSinkCallbacks callbacks;
103 GDestroyNotify notify;
106 GST_DEBUG_CATEGORY_STATIC (app_sink_debug);
107 #define GST_CAT_DEFAULT app_sink_debug
123 #define DEFAULT_PROP_EOS TRUE
124 #define DEFAULT_PROP_EMIT_SIGNALS FALSE
125 #define DEFAULT_PROP_MAX_BUFFERS 0
126 #define DEFAULT_PROP_DROP FALSE
139 static GstStaticPadTemplate gst_app_sink_template =
140 GST_STATIC_PAD_TEMPLATE ("sink",
143 GST_STATIC_CAPS_ANY);
145 static void gst_app_sink_uri_handler_init (gpointer g_iface,
146 gpointer iface_data);
148 static void gst_app_sink_dispose (GObject * object);
149 static void gst_app_sink_finalize (GObject * object);
151 static void gst_app_sink_set_property (GObject * object, guint prop_id,
152 const GValue * value, GParamSpec * pspec);
153 static void gst_app_sink_get_property (GObject * object, guint prop_id,
154 GValue * value, GParamSpec * pspec);
156 static gboolean gst_app_sink_unlock_start (GstBaseSink * bsink);
157 static gboolean gst_app_sink_unlock_stop (GstBaseSink * bsink);
158 static gboolean gst_app_sink_start (GstBaseSink * psink);
159 static gboolean gst_app_sink_stop (GstBaseSink * psink);
160 static gboolean gst_app_sink_event (GstBaseSink * sink, GstEvent * event);
161 static GstFlowReturn gst_app_sink_preroll (GstBaseSink * psink,
163 static GstFlowReturn gst_app_sink_render (GstBaseSink * psink,
165 static gboolean gst_app_sink_setcaps (GstBaseSink * sink, GstCaps * caps);
166 static GstCaps *gst_app_sink_getcaps (GstBaseSink * psink, GstCaps * filter);
168 static guint gst_app_sink_signals[LAST_SIGNAL] = { 0 };
170 #define gst_app_sink_parent_class parent_class
171 G_DEFINE_TYPE_WITH_CODE (GstAppSink, gst_app_sink, GST_TYPE_BASE_SINK,
172 G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
173 gst_app_sink_uri_handler_init));
176 gst_app_sink_class_init (GstAppSinkClass * klass)
178 GObjectClass *gobject_class = (GObjectClass *) klass;
179 GstElementClass *element_class = (GstElementClass *) klass;
180 GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
182 GST_DEBUG_CATEGORY_INIT (app_sink_debug, "appsink", 0, "appsink element");
184 gobject_class->dispose = gst_app_sink_dispose;
185 gobject_class->finalize = gst_app_sink_finalize;
187 gobject_class->set_property = gst_app_sink_set_property;
188 gobject_class->get_property = gst_app_sink_get_property;
190 g_object_class_install_property (gobject_class, PROP_CAPS,
191 g_param_spec_boxed ("caps", "Caps",
192 "The allowed caps for the sink pad", GST_TYPE_CAPS,
193 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
195 g_object_class_install_property (gobject_class, PROP_EOS,
196 g_param_spec_boolean ("eos", "EOS",
197 "Check if the sink is EOS or not started", DEFAULT_PROP_EOS,
198 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
200 g_object_class_install_property (gobject_class, PROP_EMIT_SIGNALS,
201 g_param_spec_boolean ("emit-signals", "Emit signals",
202 "Emit new-preroll, new-buffer and new-buffer-list signals",
203 DEFAULT_PROP_EMIT_SIGNALS,
204 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
206 g_object_class_install_property (gobject_class, PROP_MAX_BUFFERS,
207 g_param_spec_uint ("max-buffers", "Max Buffers",
208 "The maximum number of buffers to queue internally (0 = unlimited)",
209 0, G_MAXUINT, DEFAULT_PROP_MAX_BUFFERS,
210 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
212 g_object_class_install_property (gobject_class, PROP_DROP,
213 g_param_spec_boolean ("drop", "Drop",
214 "Drop old buffers when the buffer queue is filled", DEFAULT_PROP_DROP,
215 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
219 * @appsink: the appsink element that emitted the signal
221 * Signal that the end-of-stream has been reached. This signal is emitted from
222 * the steaming thread.
224 gst_app_sink_signals[SIGNAL_EOS] =
225 g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
226 G_STRUCT_OFFSET (GstAppSinkClass, eos),
227 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
229 * GstAppSink::new-preroll:
230 * @appsink: the appsink element that emitted the signal
232 * Signal that a new preroll sample is available.
234 * This signal is emitted from the steaming thread and only when the
235 * "emit-signals" property is %TRUE.
237 * The new preroll sample can be retrieved with the "pull-preroll" action
238 * signal or gst_app_sink_pull_preroll() either from this signal callback
239 * or from any other thread.
241 * Note that this signal is only emitted when the "emit-signals" property is
242 * set to %TRUE, which it is not by default for performance reasons.
244 gst_app_sink_signals[SIGNAL_NEW_PREROLL] =
245 g_signal_new ("new-preroll", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
246 G_STRUCT_OFFSET (GstAppSinkClass, new_preroll),
247 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
249 * GstAppSink::new-sample:
250 * @appsink: the appsink element that emited the signal
252 * Signal that a new sample is available.
254 * This signal is emitted from the steaming thread and only when the
255 * "emit-signals" property is %TRUE.
257 * The new sample can be retrieved with the "pull-sample" action
258 * signal or gst_app_sink_pull_sample() either from this signal callback
259 * or from any other thread.
261 * Note that this signal is only emitted when the "emit-signals" property is
262 * set to %TRUE, which it is not by default for performance reasons.
264 gst_app_sink_signals[SIGNAL_NEW_SAMPLE] =
265 g_signal_new ("new-sample", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
266 G_STRUCT_OFFSET (GstAppSinkClass, new_sample),
267 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
270 * GstAppSink::pull-preroll:
271 * @appsink: the appsink element to emit this signal on
273 * Get the last preroll sample in @appsink. This was the sample that caused the
274 * appsink to preroll in the PAUSED state. This sample can be pulled many times
275 * and remains available to the application even after EOS.
277 * This function is typically used when dealing with a pipeline in the PAUSED
278 * state. Calling this function after doing a seek will give the sample right
279 * after the seek position.
281 * Note that the preroll sample will also be returned as the first sample
282 * when calling gst_app_sink_pull_sample() or the "pull-sample" action signal.
284 * If an EOS event was received before any buffers, this function returns
285 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
287 * This function blocks until a preroll sample or EOS is received or the appsink
288 * element is set to the READY/NULL state.
290 * Returns: a #GstSample or NULL when the appsink is stopped or EOS.
292 gst_app_sink_signals[SIGNAL_PULL_PREROLL] =
293 g_signal_new ("pull-preroll", G_TYPE_FROM_CLASS (klass),
294 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass,
295 pull_preroll), NULL, NULL, __gst_app_marshal_BOXED__VOID,
296 GST_TYPE_SAMPLE, 0, G_TYPE_NONE);
298 * GstAppSink::pull-sample:
299 * @appsink: the appsink element to emit this signal on
301 * This function blocks until a sample or EOS becomes available or the appsink
302 * element is set to the READY/NULL state.
304 * This function will only return samples when the appsink is in the PLAYING
305 * state. All rendered samples will be put in a queue so that the application
306 * can pull samples at its own rate.
308 * Note that when the application does not pull samples fast enough, the
309 * queued samples could consume a lot of memory, especially when dealing with
310 * raw video frames. It's possible to control the behaviour of the queue with
311 * the "drop" and "max-buffers" properties.
313 * If an EOS event was received before any buffers, this function returns
314 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
316 * Returns: a #GstSample or NULL when the appsink is stopped or EOS.
318 gst_app_sink_signals[SIGNAL_PULL_SAMPLE] =
319 g_signal_new ("pull-sample", G_TYPE_FROM_CLASS (klass),
320 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass,
321 pull_sample), NULL, NULL, __gst_app_marshal_BOXED__VOID,
322 GST_TYPE_SAMPLE, 0, G_TYPE_NONE);
324 gst_element_class_set_details_simple (element_class, "AppSink",
325 "Generic/Sink", "Allow the application to get access to raw buffer",
326 "David Schleef <ds@schleef.org>, Wim Taymans <wim.taymans@gmail.com>");
328 gst_element_class_add_pad_template (element_class,
329 gst_static_pad_template_get (&gst_app_sink_template));
331 basesink_class->unlock = gst_app_sink_unlock_start;
332 basesink_class->unlock_stop = gst_app_sink_unlock_stop;
333 basesink_class->start = gst_app_sink_start;
334 basesink_class->stop = gst_app_sink_stop;
335 basesink_class->event = gst_app_sink_event;
336 basesink_class->preroll = gst_app_sink_preroll;
337 basesink_class->render = gst_app_sink_render;
338 basesink_class->get_caps = gst_app_sink_getcaps;
339 basesink_class->set_caps = gst_app_sink_setcaps;
341 klass->pull_preroll = gst_app_sink_pull_preroll;
342 klass->pull_sample = gst_app_sink_pull_sample;
344 g_type_class_add_private (klass, sizeof (GstAppSinkPrivate));
348 gst_app_sink_init (GstAppSink * appsink)
350 GstAppSinkPrivate *priv;
352 priv = appsink->priv =
353 G_TYPE_INSTANCE_GET_PRIVATE (appsink, GST_TYPE_APP_SINK,
356 priv->mutex = g_mutex_new ();
357 priv->cond = g_cond_new ();
358 priv->queue = g_queue_new ();
360 priv->emit_signals = DEFAULT_PROP_EMIT_SIGNALS;
361 priv->max_buffers = DEFAULT_PROP_MAX_BUFFERS;
362 priv->drop = DEFAULT_PROP_DROP;
366 gst_app_sink_dispose (GObject * obj)
368 GstAppSink *appsink = GST_APP_SINK_CAST (obj);
369 GstAppSinkPrivate *priv = appsink->priv;
370 GstMiniObject *queue_obj;
372 GST_OBJECT_LOCK (appsink);
374 gst_caps_unref (priv->caps);
378 priv->notify (priv->user_data);
380 priv->user_data = NULL;
383 GST_OBJECT_UNLOCK (appsink);
385 g_mutex_lock (priv->mutex);
386 while ((queue_obj = g_queue_pop_head (priv->queue)))
387 gst_mini_object_unref (queue_obj);
388 gst_buffer_replace (&priv->preroll, NULL);
389 gst_caps_replace (&priv->preroll_caps, NULL);
390 gst_caps_replace (&priv->last_caps, NULL);
391 g_mutex_unlock (priv->mutex);
393 G_OBJECT_CLASS (parent_class)->dispose (obj);
397 gst_app_sink_finalize (GObject * obj)
399 GstAppSink *appsink = GST_APP_SINK_CAST (obj);
400 GstAppSinkPrivate *priv = appsink->priv;
402 g_mutex_free (priv->mutex);
403 g_cond_free (priv->cond);
404 g_queue_free (priv->queue);
406 G_OBJECT_CLASS (parent_class)->finalize (obj);
410 gst_app_sink_set_property (GObject * object, guint prop_id,
411 const GValue * value, GParamSpec * pspec)
413 GstAppSink *appsink = GST_APP_SINK_CAST (object);
417 gst_app_sink_set_caps (appsink, gst_value_get_caps (value));
419 case PROP_EMIT_SIGNALS:
420 gst_app_sink_set_emit_signals (appsink, g_value_get_boolean (value));
422 case PROP_MAX_BUFFERS:
423 gst_app_sink_set_max_buffers (appsink, g_value_get_uint (value));
426 gst_app_sink_set_drop (appsink, g_value_get_boolean (value));
429 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
435 gst_app_sink_get_property (GObject * object, guint prop_id, GValue * value,
438 GstAppSink *appsink = GST_APP_SINK_CAST (object);
445 caps = gst_app_sink_get_caps (appsink);
446 gst_value_set_caps (value, caps);
448 gst_caps_unref (caps);
452 g_value_set_boolean (value, gst_app_sink_is_eos (appsink));
454 case PROP_EMIT_SIGNALS:
455 g_value_set_boolean (value, gst_app_sink_get_emit_signals (appsink));
457 case PROP_MAX_BUFFERS:
458 g_value_set_uint (value, gst_app_sink_get_max_buffers (appsink));
461 g_value_set_boolean (value, gst_app_sink_get_drop (appsink));
464 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
470 gst_app_sink_unlock_start (GstBaseSink * bsink)
472 GstAppSink *appsink = GST_APP_SINK_CAST (bsink);
473 GstAppSinkPrivate *priv = appsink->priv;
475 g_mutex_lock (priv->mutex);
476 GST_DEBUG_OBJECT (appsink, "unlock start");
478 g_cond_signal (priv->cond);
479 g_mutex_unlock (priv->mutex);
485 gst_app_sink_unlock_stop (GstBaseSink * bsink)
487 GstAppSink *appsink = GST_APP_SINK_CAST (bsink);
488 GstAppSinkPrivate *priv = appsink->priv;
490 g_mutex_lock (priv->mutex);
491 GST_DEBUG_OBJECT (appsink, "unlock stop");
492 priv->unlock = FALSE;
493 g_cond_signal (priv->cond);
494 g_mutex_unlock (priv->mutex);
500 gst_app_sink_flush_unlocked (GstAppSink * appsink)
503 GstAppSinkPrivate *priv = appsink->priv;
505 GST_DEBUG_OBJECT (appsink, "flush stop appsink");
506 priv->is_eos = FALSE;
507 gst_buffer_replace (&priv->preroll, NULL);
508 while ((obj = g_queue_pop_head (priv->queue)))
509 gst_mini_object_unref (obj);
510 priv->num_buffers = 0;
511 g_cond_signal (priv->cond);
515 gst_app_sink_start (GstBaseSink * psink)
517 GstAppSink *appsink = GST_APP_SINK_CAST (psink);
518 GstAppSinkPrivate *priv = appsink->priv;
520 g_mutex_lock (priv->mutex);
521 GST_DEBUG_OBJECT (appsink, "starting");
522 priv->flushing = FALSE;
523 priv->started = TRUE;
524 gst_segment_init (&priv->last_segment, GST_FORMAT_TIME);
525 g_mutex_unlock (priv->mutex);
531 gst_app_sink_stop (GstBaseSink * psink)
533 GstAppSink *appsink = GST_APP_SINK_CAST (psink);
534 GstAppSinkPrivate *priv = appsink->priv;
536 g_mutex_lock (priv->mutex);
537 GST_DEBUG_OBJECT (appsink, "stopping");
538 priv->flushing = TRUE;
539 priv->started = FALSE;
540 gst_app_sink_flush_unlocked (appsink);
541 gst_caps_replace (&priv->preroll_caps, NULL);
542 gst_caps_replace (&priv->last_caps, NULL);
543 g_mutex_unlock (priv->mutex);
549 gst_app_sink_setcaps (GstBaseSink * sink, GstCaps * caps)
551 GstAppSink *appsink = GST_APP_SINK_CAST (sink);
552 GstAppSinkPrivate *priv = appsink->priv;
554 g_mutex_lock (priv->mutex);
555 GST_DEBUG_OBJECT (appsink, "receiving CAPS");
556 g_queue_push_tail (priv->queue, gst_event_new_caps (caps));
557 gst_caps_replace (&priv->preroll_caps, caps);
558 g_mutex_unlock (priv->mutex);
564 gst_app_sink_event (GstBaseSink * sink, GstEvent * event)
566 GstAppSink *appsink = GST_APP_SINK_CAST (sink);
567 GstAppSinkPrivate *priv = appsink->priv;
569 switch (event->type) {
570 case GST_EVENT_SEGMENT:
571 g_mutex_lock (priv->mutex);
572 GST_DEBUG_OBJECT (appsink, "receiving SEGMENT");
573 g_queue_push_tail (priv->queue, gst_event_ref (event));
574 g_mutex_unlock (priv->mutex);
577 g_mutex_lock (priv->mutex);
578 GST_DEBUG_OBJECT (appsink, "receiving EOS");
580 g_cond_signal (priv->cond);
581 g_mutex_unlock (priv->mutex);
584 if (priv->callbacks.eos)
585 priv->callbacks.eos (appsink, priv->user_data);
587 g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_EOS], 0);
590 case GST_EVENT_FLUSH_START:
591 /* we don't have to do anything here, the base class will call unlock
592 * which will make sure we exit the _render method */
593 GST_DEBUG_OBJECT (appsink, "received FLUSH_START");
595 case GST_EVENT_FLUSH_STOP:
596 g_mutex_lock (priv->mutex);
597 GST_DEBUG_OBJECT (appsink, "received FLUSH_STOP");
598 gst_app_sink_flush_unlocked (appsink);
599 g_mutex_unlock (priv->mutex);
604 return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
608 gst_app_sink_preroll (GstBaseSink * psink, GstBuffer * buffer)
610 GstFlowReturn res = GST_FLOW_OK;
611 GstAppSink *appsink = GST_APP_SINK_CAST (psink);
612 GstAppSinkPrivate *priv = appsink->priv;
615 g_mutex_lock (priv->mutex);
619 GST_DEBUG_OBJECT (appsink, "setting preroll buffer %p", buffer);
620 gst_buffer_replace (&priv->preroll, buffer);
622 g_cond_signal (priv->cond);
623 emit = priv->emit_signals;
624 g_mutex_unlock (priv->mutex);
626 if (priv->callbacks.new_preroll)
627 res = priv->callbacks.new_preroll (appsink, priv->user_data);
629 g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_PREROLL], 0);
635 GST_DEBUG_OBJECT (appsink, "we are flushing");
636 g_mutex_unlock (priv->mutex);
637 return GST_FLOW_FLUSHING;
642 dequeue_buffer (GstAppSink * appsink)
644 GstAppSinkPrivate *priv = appsink->priv;
650 obj = g_queue_pop_head (priv->queue);
652 if (GST_IS_BUFFER (obj)) {
653 buffer = GST_BUFFER_CAST (obj);
654 GST_DEBUG_OBJECT (appsink, "dequeued buffer %p", buffer);
657 } else if (GST_IS_EVENT (obj)) {
658 GstEvent *event = GST_EVENT_CAST (obj);
660 switch (GST_EVENT_TYPE (obj)) {
665 gst_event_parse_caps (event, &caps);
666 GST_DEBUG_OBJECT (appsink, "activating caps %" GST_PTR_FORMAT, caps);
667 gst_caps_replace (&priv->last_caps, caps);
670 case GST_EVENT_SEGMENT:
671 gst_event_copy_segment (event, &priv->last_segment);
672 GST_DEBUG_OBJECT (appsink, "activated segment %" GST_SEGMENT_FORMAT,
673 &priv->last_segment);
678 gst_mini_object_unref (obj);
686 gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer)
689 GstAppSink *appsink = GST_APP_SINK_CAST (psink);
690 GstAppSinkPrivate *priv = appsink->priv;
694 g_mutex_lock (priv->mutex);
698 GST_DEBUG_OBJECT (appsink, "pushing render buffer %p on queue (%d)",
699 buffer, priv->num_buffers);
701 while (priv->max_buffers > 0 && priv->num_buffers >= priv->max_buffers) {
705 /* we need to drop the oldest buffer and try again */
706 if ((old = dequeue_buffer (appsink))) {
707 GST_DEBUG_OBJECT (appsink, "dropping old buffer %p", old);
708 gst_buffer_unref (old);
711 GST_DEBUG_OBJECT (appsink, "waiting for free space, length %d >= %d",
712 priv->num_buffers, priv->max_buffers);
715 /* we are asked to unlock, call the wait_preroll method */
716 g_mutex_unlock (priv->mutex);
717 if ((ret = gst_base_sink_wait_preroll (psink)) != GST_FLOW_OK)
720 /* we are allowed to continue now */
724 /* wait for a buffer to be removed or flush */
725 g_cond_wait (priv->cond, priv->mutex);
730 /* we need to ref the buffer when pushing it in the queue */
731 g_queue_push_tail (priv->queue, gst_buffer_ref (buffer));
733 g_cond_signal (priv->cond);
734 emit = priv->emit_signals;
735 g_mutex_unlock (priv->mutex);
737 if (priv->callbacks.new_sample)
738 priv->callbacks.new_sample (appsink, priv->user_data);
740 g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_SAMPLE], 0);
746 GST_DEBUG_OBJECT (appsink, "we are flushing");
747 g_mutex_unlock (priv->mutex);
748 return GST_FLOW_FLUSHING;
752 GST_DEBUG_OBJECT (appsink, "we are stopping");
758 gst_app_sink_getcaps (GstBaseSink * psink, GstCaps * filter)
761 GstAppSink *appsink = GST_APP_SINK_CAST (psink);
762 GstAppSinkPrivate *priv = appsink->priv;
764 GST_OBJECT_LOCK (appsink);
765 if ((caps = priv->caps)) {
767 caps = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
771 GST_DEBUG_OBJECT (appsink, "got caps %" GST_PTR_FORMAT, caps);
772 GST_OBJECT_UNLOCK (appsink);
780 * gst_app_sink_set_caps:
781 * @appsink: a #GstAppSink
784 * Set the capabilities on the appsink element. This function takes
785 * a copy of the caps structure. After calling this method, the sink will only
786 * accept caps that match @caps. If @caps is non-fixed, you must check the caps
787 * on the buffers to get the actual used caps.
792 gst_app_sink_set_caps (GstAppSink * appsink, const GstCaps * caps)
795 GstAppSinkPrivate *priv;
797 g_return_if_fail (GST_IS_APP_SINK (appsink));
799 priv = appsink->priv;
801 GST_OBJECT_LOCK (appsink);
802 GST_DEBUG_OBJECT (appsink, "setting caps to %" GST_PTR_FORMAT, caps);
803 if ((old = priv->caps) != caps) {
805 priv->caps = gst_caps_copy (caps);
809 gst_caps_unref (old);
811 GST_OBJECT_UNLOCK (appsink);
815 * gst_app_sink_get_caps:
816 * @appsink: a #GstAppSink
818 * Get the configured caps on @appsink.
820 * Returns: the #GstCaps accepted by the sink. gst_caps_unref() after usage.
825 gst_app_sink_get_caps (GstAppSink * appsink)
828 GstAppSinkPrivate *priv;
830 g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
832 priv = appsink->priv;
834 GST_OBJECT_LOCK (appsink);
835 if ((caps = priv->caps))
837 GST_DEBUG_OBJECT (appsink, "getting caps of %" GST_PTR_FORMAT, caps);
838 GST_OBJECT_UNLOCK (appsink);
844 * gst_app_sink_is_eos:
845 * @appsink: a #GstAppSink
847 * Check if @appsink is EOS, which is when no more samples can be pulled because
848 * an EOS event was received.
850 * This function also returns %TRUE when the appsink is not in the PAUSED or
853 * Returns: %TRUE if no more samples can be pulled and the appsink is EOS.
858 gst_app_sink_is_eos (GstAppSink * appsink)
861 GstAppSinkPrivate *priv;
863 g_return_val_if_fail (GST_IS_APP_SINK (appsink), FALSE);
865 priv = appsink->priv;
867 g_mutex_lock (priv->mutex);
871 if (priv->is_eos && priv->num_buffers == 0) {
872 GST_DEBUG_OBJECT (appsink, "we are EOS and the queue is empty");
875 GST_DEBUG_OBJECT (appsink, "we are not yet EOS");
878 g_mutex_unlock (priv->mutex);
884 GST_DEBUG_OBJECT (appsink, "we are stopped, return TRUE");
885 g_mutex_unlock (priv->mutex);
891 * gst_app_sink_set_emit_signals:
892 * @appsink: a #GstAppSink
893 * @emit: the new state
895 * Make appsink emit the "new-preroll" and "new-sample" signals. This option is
896 * by default disabled because signal emission is expensive and unneeded when
897 * the application prefers to operate in pull mode.
902 gst_app_sink_set_emit_signals (GstAppSink * appsink, gboolean emit)
904 GstAppSinkPrivate *priv;
906 g_return_if_fail (GST_IS_APP_SINK (appsink));
908 priv = appsink->priv;
910 g_mutex_lock (priv->mutex);
911 priv->emit_signals = emit;
912 g_mutex_unlock (priv->mutex);
916 * gst_app_sink_get_emit_signals:
917 * @appsink: a #GstAppSink
919 * Check if appsink will emit the "new-preroll" and "new-sample" signals.
921 * Returns: %TRUE if @appsink is emiting the "new-preroll" and "new-sample"
927 gst_app_sink_get_emit_signals (GstAppSink * appsink)
930 GstAppSinkPrivate *priv;
932 g_return_val_if_fail (GST_IS_APP_SINK (appsink), FALSE);
934 priv = appsink->priv;
936 g_mutex_lock (priv->mutex);
937 result = priv->emit_signals;
938 g_mutex_unlock (priv->mutex);
944 * gst_app_sink_set_max_buffers:
945 * @appsink: a #GstAppSink
946 * @max: the maximum number of buffers to queue
948 * Set the maximum amount of buffers that can be queued in @appsink. After this
949 * amount of buffers are queued in appsink, any more buffers will block upstream
950 * elements until a sample is pulled from @appsink.
955 gst_app_sink_set_max_buffers (GstAppSink * appsink, guint max)
957 GstAppSinkPrivate *priv;
959 g_return_if_fail (GST_IS_APP_SINK (appsink));
961 priv = appsink->priv;
963 g_mutex_lock (priv->mutex);
964 if (max != priv->max_buffers) {
965 priv->max_buffers = max;
966 /* signal the change */
967 g_cond_signal (priv->cond);
969 g_mutex_unlock (priv->mutex);
973 * gst_app_sink_get_max_buffers:
974 * @appsink: a #GstAppSink
976 * Get the maximum amount of buffers that can be queued in @appsink.
978 * Returns: The maximum amount of buffers that can be queued.
983 gst_app_sink_get_max_buffers (GstAppSink * appsink)
986 GstAppSinkPrivate *priv;
988 g_return_val_if_fail (GST_IS_APP_SINK (appsink), 0);
990 priv = appsink->priv;
992 g_mutex_lock (priv->mutex);
993 result = priv->max_buffers;
994 g_mutex_unlock (priv->mutex);
1000 * gst_app_sink_set_drop:
1001 * @appsink: a #GstAppSink
1002 * @drop: the new state
1004 * Instruct @appsink to drop old buffers when the maximum amount of queued
1005 * buffers is reached.
1010 gst_app_sink_set_drop (GstAppSink * appsink, gboolean drop)
1012 GstAppSinkPrivate *priv;
1014 g_return_if_fail (GST_IS_APP_SINK (appsink));
1016 priv = appsink->priv;
1018 g_mutex_lock (priv->mutex);
1019 if (priv->drop != drop) {
1021 /* signal the change */
1022 g_cond_signal (priv->cond);
1024 g_mutex_unlock (priv->mutex);
1028 * gst_app_sink_get_drop:
1029 * @appsink: a #GstAppSink
1031 * Check if @appsink will drop old buffers when the maximum amount of queued
1032 * buffers is reached.
1034 * Returns: %TRUE if @appsink is dropping old buffers when the queue is
1040 gst_app_sink_get_drop (GstAppSink * appsink)
1043 GstAppSinkPrivate *priv;
1045 g_return_val_if_fail (GST_IS_APP_SINK (appsink), FALSE);
1047 priv = appsink->priv;
1049 g_mutex_lock (priv->mutex);
1050 result = priv->drop;
1051 g_mutex_unlock (priv->mutex);
1057 * gst_app_sink_pull_preroll:
1058 * @appsink: a #GstAppSink
1060 * Get the last preroll sample in @appsink. This was the sample that caused the
1061 * appsink to preroll in the PAUSED state. This sample can be pulled many times
1062 * and remains available to the application even after EOS.
1064 * This function is typically used when dealing with a pipeline in the PAUSED
1065 * state. Calling this function after doing a seek will give the sample right
1066 * after the seek position.
1068 * Note that the preroll sample will also be returned as the first sample
1069 * when calling gst_app_sink_pull_sample().
1071 * If an EOS event was received before any buffers, this function returns
1072 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
1074 * This function blocks until a preroll sample or EOS is received or the appsink
1075 * element is set to the READY/NULL state.
1077 * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS.
1082 gst_app_sink_pull_preroll (GstAppSink * appsink)
1084 GstSample *sample = NULL;
1085 GstAppSinkPrivate *priv;
1087 g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
1089 priv = appsink->priv;
1091 g_mutex_lock (priv->mutex);
1094 GST_DEBUG_OBJECT (appsink, "trying to grab a buffer");
1098 if (priv->preroll != NULL)
1104 /* nothing to return, wait */
1105 GST_DEBUG_OBJECT (appsink, "waiting for the preroll buffer");
1106 g_cond_wait (priv->cond, priv->mutex);
1109 gst_sample_new (priv->preroll, priv->preroll_caps, &priv->last_segment,
1111 GST_DEBUG_OBJECT (appsink, "we have the preroll sample %p", sample);
1112 g_mutex_unlock (priv->mutex);
1116 /* special conditions */
1119 GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL");
1120 g_mutex_unlock (priv->mutex);
1125 GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL");
1126 g_mutex_unlock (priv->mutex);
1132 * gst_app_sink_pull_sample:
1133 * @appsink: a #GstAppSink
1135 * This function blocks until a sample or EOS becomes available or the appsink
1136 * element is set to the READY/NULL state.
1138 * This function will only return samples when the appsink is in the PLAYING
1139 * state. All rendered buffers will be put in a queue so that the application
1140 * can pull samples at its own rate. Note that when the application does not
1141 * pull samples fast enough, the queued buffers could consume a lot of memory,
1142 * especially when dealing with raw video frames.
1144 * If an EOS event was received before any buffers, this function returns
1145 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition.
1147 * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS.
1153 gst_app_sink_pull_sample (GstAppSink * appsink)
1155 GstSample *sample = NULL;
1157 GstAppSinkPrivate *priv;
1159 g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
1161 priv = appsink->priv;
1163 g_mutex_lock (priv->mutex);
1166 GST_DEBUG_OBJECT (appsink, "trying to grab a buffer");
1170 if (priv->num_buffers > 0)
1176 /* nothing to return, wait */
1177 GST_DEBUG_OBJECT (appsink, "waiting for a buffer");
1178 g_cond_wait (priv->cond, priv->mutex);
1180 buffer = dequeue_buffer (appsink);
1181 GST_DEBUG_OBJECT (appsink, "we have a buffer %p", buffer);
1182 sample = gst_sample_new (buffer, priv->last_caps, &priv->last_segment, NULL);
1183 gst_buffer_unref (buffer);
1185 g_cond_signal (priv->cond);
1186 g_mutex_unlock (priv->mutex);
1190 /* special conditions */
1193 GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL");
1194 g_mutex_unlock (priv->mutex);
1199 GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL");
1200 g_mutex_unlock (priv->mutex);
1206 * gst_app_sink_set_callbacks:
1207 * @appsink: a #GstAppSink
1208 * @callbacks: the callbacks
1209 * @user_data: a user_data argument for the callbacks
1210 * @notify: a destroy notify function
1212 * Set callbacks which will be executed for each new preroll, new sample and eos.
1213 * This is an alternative to using the signals, it has lower overhead and is thus
1214 * less expensive, but also less flexible.
1216 * If callbacks are installed, no signals will be emitted for performance
1222 gst_app_sink_set_callbacks (GstAppSink * appsink,
1223 GstAppSinkCallbacks * callbacks, gpointer user_data, GDestroyNotify notify)
1225 GDestroyNotify old_notify;
1226 GstAppSinkPrivate *priv;
1228 g_return_if_fail (GST_IS_APP_SINK (appsink));
1229 g_return_if_fail (callbacks != NULL);
1231 priv = appsink->priv;
1233 GST_OBJECT_LOCK (appsink);
1234 old_notify = priv->notify;
1239 old_data = priv->user_data;
1241 priv->user_data = NULL;
1242 priv->notify = NULL;
1243 GST_OBJECT_UNLOCK (appsink);
1245 old_notify (old_data);
1247 GST_OBJECT_LOCK (appsink);
1249 priv->callbacks = *callbacks;
1250 priv->user_data = user_data;
1251 priv->notify = notify;
1252 GST_OBJECT_UNLOCK (appsink);
1255 /*** GSTURIHANDLER INTERFACE *************************************************/
1258 gst_app_sink_uri_get_type (GType type)
1260 return GST_URI_SINK;
1263 static const gchar *const *
1264 gst_app_sink_uri_get_protocols (GType type)
1266 static const gchar *protocols[] = { "appsink", NULL };
1272 gst_app_sink_uri_get_uri (GstURIHandler * handler)
1274 return g_strdup ("appsink");
1278 gst_app_sink_uri_set_uri (GstURIHandler * handler, const gchar * uri,
1281 /* GstURIHandler checks the protocol for us */
1286 gst_app_sink_uri_handler_init (gpointer g_iface, gpointer iface_data)
1288 GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
1290 iface->get_type = gst_app_sink_uri_get_type;
1291 iface->get_protocols = gst_app_sink_uri_get_protocols;
1292 iface->get_uri = gst_app_sink_uri_get_uri;
1293 iface->set_uri = gst_app_sink_uri_set_uri;