160 #ifdef __SYMBIAN32__ |
159 #ifdef __SYMBIAN32__ |
161 static void gst_app_sink_class_init (GstAppSinkClass * klass); |
160 static void gst_app_sink_class_init (GstAppSinkClass * klass); |
162 static void gst_app_sink_init (GstAppSink * appsink, GstAppSinkClass * klass); |
161 static void gst_app_sink_init (GstAppSink * appsink, GstAppSinkClass * klass); |
163 static void gst_app_sink_base_init (gpointer g_class); |
162 static void gst_app_sink_base_init (gpointer g_class); |
164 #endif |
163 #endif |
|
164 |
165 static void gst_app_sink_set_property (GObject * object, guint prop_id, |
165 static void gst_app_sink_set_property (GObject * object, guint prop_id, |
166 const GValue * value, GParamSpec * pspec); |
166 const GValue * value, GParamSpec * pspec); |
167 static void gst_app_sink_get_property (GObject * object, guint prop_id, |
167 static void gst_app_sink_get_property (GObject * object, guint prop_id, |
168 GValue * value, GParamSpec * pspec); |
168 GValue * value, GParamSpec * pspec); |
169 |
169 |
172 static gboolean gst_app_sink_start (GstBaseSink * psink); |
172 static gboolean gst_app_sink_start (GstBaseSink * psink); |
173 static gboolean gst_app_sink_stop (GstBaseSink * psink); |
173 static gboolean gst_app_sink_stop (GstBaseSink * psink); |
174 static gboolean gst_app_sink_event (GstBaseSink * sink, GstEvent * event); |
174 static gboolean gst_app_sink_event (GstBaseSink * sink, GstEvent * event); |
175 static GstFlowReturn gst_app_sink_preroll (GstBaseSink * psink, |
175 static GstFlowReturn gst_app_sink_preroll (GstBaseSink * psink, |
176 GstBuffer * buffer); |
176 GstBuffer * buffer); |
177 static GstFlowReturn gst_app_sink_render_common (GstBaseSink * psink, |
|
178 GstMiniObject * data, gboolean is_list); |
|
179 static GstFlowReturn gst_app_sink_render (GstBaseSink * psink, |
177 static GstFlowReturn gst_app_sink_render (GstBaseSink * psink, |
180 GstBuffer * buffer); |
178 GstBuffer * buffer); |
181 static GstFlowReturn gst_app_sink_render_list (GstBaseSink * psink, |
|
182 GstBufferList * list); |
|
183 static GstCaps *gst_app_sink_getcaps (GstBaseSink * psink); |
179 static GstCaps *gst_app_sink_getcaps (GstBaseSink * psink); |
184 static GstMiniObject *gst_app_sink_pull_object (GstAppSink * appsink); |
|
185 |
180 |
186 static guint gst_app_sink_signals[LAST_SIGNAL] = { 0 }; |
181 static guint gst_app_sink_signals[LAST_SIGNAL] = { 0 }; |
187 |
182 |
188 static void |
183 static void |
189 _do_init (GType filesrc_type) |
184 _do_init (GType filesrc_type) |
294 gobject_class->get_property = gst_app_sink_get_property; |
290 gobject_class->get_property = gst_app_sink_get_property; |
295 |
291 |
296 g_object_class_install_property (gobject_class, PROP_CAPS, |
292 g_object_class_install_property (gobject_class, PROP_CAPS, |
297 g_param_spec_boxed ("caps", "Caps", |
293 g_param_spec_boxed ("caps", "Caps", |
298 "The allowed caps for the sink pad", GST_TYPE_CAPS, |
294 "The allowed caps for the sink pad", GST_TYPE_CAPS, |
299 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
295 G_PARAM_READWRITE)); |
300 |
296 |
301 g_object_class_install_property (gobject_class, PROP_EOS, |
297 g_object_class_install_property (gobject_class, PROP_EOS, |
302 g_param_spec_boolean ("eos", "EOS", |
298 g_param_spec_boolean ("eos", "EOS", |
303 "Check if the sink is EOS or not started", DEFAULT_PROP_EOS, |
299 "Check if the sink is EOS or not started", DEFAULT_PROP_EOS, |
304 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); |
300 G_PARAM_READABLE)); |
305 |
301 |
306 g_object_class_install_property (gobject_class, PROP_EMIT_SIGNALS, |
302 g_object_class_install_property (gobject_class, PROP_EMIT_SIGNALS, |
307 g_param_spec_boolean ("emit-signals", "Emit signals", |
303 g_param_spec_boolean ("emit-signals", "Emit signals", |
308 "Emit new-preroll and new-buffer signals", DEFAULT_PROP_EMIT_SIGNALS, |
304 "Emit new-preroll and new-buffer signals", DEFAULT_PROP_EMIT_SIGNALS, |
309 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
305 G_PARAM_READWRITE)); |
310 |
306 |
311 g_object_class_install_property (gobject_class, PROP_MAX_BUFFERS, |
307 g_object_class_install_property (gobject_class, PROP_MAX_BUFFERS, |
312 g_param_spec_uint ("max-buffers", "Max Buffers", |
308 g_param_spec_uint ("max-buffers", "Max Buffers", |
313 "The maximum number of buffers to queue internally (0 = unlimited)", |
309 "The maximum number of buffers to queue internally (0 = unlimited)", |
314 0, G_MAXUINT, DEFAULT_PROP_MAX_BUFFERS, |
310 0, G_MAXUINT, DEFAULT_PROP_MAX_BUFFERS, |
315 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
311 G_PARAM_READWRITE)); |
316 |
312 |
317 g_object_class_install_property (gobject_class, PROP_DROP, |
313 g_object_class_install_property (gobject_class, PROP_DROP, |
318 g_param_spec_boolean ("drop", "Drop", |
314 g_param_spec_boolean ("drop", "Drop", |
319 "Drop old buffers when the buffer queue is filled", DEFAULT_PROP_DROP, |
315 "Drop old buffers when the buffer queue is filled", DEFAULT_PROP_DROP, |
320 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
316 G_PARAM_READWRITE)); |
321 |
317 |
322 /** |
318 /** |
323 * GstAppSink::eos: |
319 * GstAppSink::eos: |
324 * @appsink: the appsink element that emited the signal |
320 * @appsink: the appsink element that emited the signal |
325 * |
321 * |
368 */ |
364 */ |
369 gst_app_sink_signals[SIGNAL_NEW_BUFFER] = |
365 gst_app_sink_signals[SIGNAL_NEW_BUFFER] = |
370 g_signal_new ("new-buffer", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, |
366 g_signal_new ("new-buffer", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, |
371 G_STRUCT_OFFSET (GstAppSinkClass, new_buffer), |
367 G_STRUCT_OFFSET (GstAppSinkClass, new_buffer), |
372 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); |
368 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); |
373 /** |
|
374 * GstAppSink::new-buffer-list: |
|
375 * @appsink: the appsink element that emited the signal |
|
376 * |
|
377 * Signal that a new bufferlist is available. |
|
378 * |
|
379 * This signal is emited from the steaming thread and only when the |
|
380 * "emit-signals" property is %TRUE. |
|
381 * |
|
382 * The new buffer can be retrieved with the "pull-buffer-list" action |
|
383 * signal or gst_app_sink_pull_buffe_listr() either from this signal callback |
|
384 * or from any other thread. |
|
385 * |
|
386 * Note that this signal is only emited when the "emit-signals" property is |
|
387 * set to %TRUE, which it is not by default for performance reasons. |
|
388 */ |
|
389 gst_app_sink_signals[SIGNAL_NEW_BUFFER_LIST] = |
|
390 g_signal_new ("new-buffer-list", G_TYPE_FROM_CLASS (klass), |
|
391 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstAppSinkClass, new_buffer_list), |
|
392 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); |
|
393 |
369 |
394 /** |
370 /** |
395 * GstAppSink::pull-preroll: |
371 * GstAppSink::pull-preroll: |
396 * @appsink: the appsink element to emit this signal on |
372 * @appsink: the appsink element to emit this signal on |
397 * |
373 * |
443 gst_app_sink_signals[SIGNAL_PULL_BUFFER] = |
419 gst_app_sink_signals[SIGNAL_PULL_BUFFER] = |
444 g_signal_new ("pull-buffer", G_TYPE_FROM_CLASS (klass), |
420 g_signal_new ("pull-buffer", G_TYPE_FROM_CLASS (klass), |
445 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass, |
421 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass, |
446 pull_buffer), NULL, NULL, gst_app_marshal_BUFFER__VOID, |
422 pull_buffer), NULL, NULL, gst_app_marshal_BUFFER__VOID, |
447 GST_TYPE_BUFFER, 0, G_TYPE_NONE); |
423 GST_TYPE_BUFFER, 0, G_TYPE_NONE); |
448 /** |
|
449 * GstAppSink::pull-buffer-list: |
|
450 * @appsink: the appsink element to emit this signal on |
|
451 * |
|
452 * This function blocks until a buffer list or EOS becomes available or the appsink |
|
453 * element is set to the READY/NULL state. |
|
454 * |
|
455 * This function will only return bufferlists when the appsink is in the PLAYING |
|
456 * state. All rendered bufferlists will be put in a queue so that the application |
|
457 * can pull bufferlists at its own rate. |
|
458 * |
|
459 * Note that when the application does not pull bufferlists fast enough, the |
|
460 * queued bufferlists could consume a lot of memory, especially when dealing with |
|
461 * raw video frames. It's possible to control the behaviour of the queue with |
|
462 * the "drop" and "max-buffers" properties. |
|
463 * |
|
464 * If an EOS event was received before any buffers, this function returns |
|
465 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition. |
|
466 * |
|
467 * Returns: a #GstBufferList or NULL when the appsink is stopped or EOS. |
|
468 */ |
|
469 gst_app_sink_signals[SIGNAL_PULL_BUFFER_LIST] = |
|
470 g_signal_new ("pull-buffer-list", G_TYPE_FROM_CLASS (klass), |
|
471 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass, |
|
472 pull_buffer_list), NULL, NULL, gst_app_marshal_BUFFER__VOID, |
|
473 GST_TYPE_BUFFER_LIST, 0, G_TYPE_NONE); |
|
474 |
424 |
475 basesink_class->unlock = gst_app_sink_unlock_start; |
425 basesink_class->unlock = gst_app_sink_unlock_start; |
476 basesink_class->unlock_stop = gst_app_sink_unlock_stop; |
426 basesink_class->unlock_stop = gst_app_sink_unlock_stop; |
477 basesink_class->start = gst_app_sink_start; |
427 basesink_class->start = gst_app_sink_start; |
478 basesink_class->stop = gst_app_sink_stop; |
428 basesink_class->stop = gst_app_sink_stop; |
479 basesink_class->event = gst_app_sink_event; |
429 basesink_class->event = gst_app_sink_event; |
480 basesink_class->preroll = gst_app_sink_preroll; |
430 basesink_class->preroll = gst_app_sink_preroll; |
481 basesink_class->render = gst_app_sink_render; |
431 basesink_class->render = gst_app_sink_render; |
482 basesink_class->render_list = gst_app_sink_render_list; |
|
483 basesink_class->get_caps = gst_app_sink_getcaps; |
432 basesink_class->get_caps = gst_app_sink_getcaps; |
484 |
433 |
485 klass->pull_preroll = gst_app_sink_pull_preroll; |
434 klass->pull_preroll = gst_app_sink_pull_preroll; |
486 klass->pull_buffer = gst_app_sink_pull_buffer; |
435 klass->pull_buffer = gst_app_sink_pull_buffer; |
487 klass->pull_buffer_list = gst_app_sink_pull_buffer_list; |
|
488 |
436 |
489 g_type_class_add_private (klass, sizeof (GstAppSinkPrivate)); |
437 g_type_class_add_private (klass, sizeof (GstAppSinkPrivate)); |
490 } |
438 } |
491 |
439 |
492 static void |
440 static void |
748 return GST_FLOW_WRONG_STATE; |
696 return GST_FLOW_WRONG_STATE; |
749 } |
697 } |
750 } |
698 } |
751 |
699 |
752 static GstFlowReturn |
700 static GstFlowReturn |
753 gst_app_sink_render_common (GstBaseSink * psink, GstMiniObject * data, |
701 gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer) |
754 gboolean is_list) |
702 { |
755 { |
703 GstFlowReturn res = GST_FLOW_OK; |
756 GstAppSink *appsink = GST_APP_SINK (psink); |
704 GstAppSink *appsink = GST_APP_SINK (psink); |
757 gboolean emit; |
705 gboolean emit; |
758 |
706 |
759 g_mutex_lock (appsink->priv->mutex); |
707 g_mutex_lock (appsink->priv->mutex); |
760 if (appsink->priv->flushing) |
708 if (appsink->priv->flushing) |
761 goto flushing; |
709 goto flushing; |
762 |
710 |
763 GST_DEBUG_OBJECT (appsink, "pushing render buffer%s %p on queue (%d)", |
711 GST_DEBUG_OBJECT (appsink, "pushing render buffer %p on queue (%d)", |
764 is_list ? " list" : "", data, appsink->priv->queue->length); |
712 buffer, appsink->priv->queue->length); |
765 |
713 |
766 while (appsink->priv->max_buffers > 0 && |
714 while (appsink->priv->max_buffers > 0 && |
767 appsink->priv->queue->length >= appsink->priv->max_buffers) { |
715 appsink->priv->queue->length >= appsink->priv->max_buffers) { |
768 if (appsink->priv->drop) { |
716 if (appsink->priv->drop) { |
769 GstMiniObject *obj; |
717 GstBuffer *buf; |
770 |
718 |
771 /* we need to drop the oldest buffer/list and try again */ |
719 /* we need to drop the oldest buffer and try again */ |
772 obj = g_queue_pop_head (appsink->priv->queue); |
720 buf = g_queue_pop_head (appsink->priv->queue); |
773 GST_DEBUG_OBJECT (appsink, "dropping old buffer/list %p", obj); |
721 GST_DEBUG_OBJECT (appsink, "dropping old buffer %p", buf); |
774 gst_mini_object_unref (obj); |
722 gst_buffer_unref (buf); |
775 } else { |
723 } else { |
776 GST_DEBUG_OBJECT (appsink, "waiting for free space, length %d >= %d", |
724 GST_DEBUG_OBJECT (appsink, "waiting for free space, length %d >= %d", |
777 appsink->priv->queue->length, appsink->priv->max_buffers); |
725 appsink->priv->queue->length, appsink->priv->max_buffers); |
778 /* wait for a buffer to be removed or flush */ |
726 /* wait for a buffer to be removed or flush */ |
779 g_cond_wait (appsink->priv->cond, appsink->priv->mutex); |
727 g_cond_wait (appsink->priv->cond, appsink->priv->mutex); |
780 if (appsink->priv->flushing) |
728 if (appsink->priv->flushing) |
781 goto flushing; |
729 goto flushing; |
782 } |
730 } |
783 } |
731 } |
784 /* we need to ref the buffer when pushing it in the queue */ |
732 /* we need to ref the buffer when pushing it in the queue */ |
785 g_queue_push_tail (appsink->priv->queue, gst_mini_object_ref (data)); |
733 g_queue_push_tail (appsink->priv->queue, gst_buffer_ref (buffer)); |
|
734 |
786 g_cond_signal (appsink->priv->cond); |
735 g_cond_signal (appsink->priv->cond); |
787 emit = appsink->priv->emit_signals; |
736 emit = appsink->priv->emit_signals; |
788 g_mutex_unlock (appsink->priv->mutex); |
737 g_mutex_unlock (appsink->priv->mutex); |
789 |
738 |
790 if (is_list) { |
739 if (appsink->priv->callbacks.new_buffer) |
791 if (appsink->priv->callbacks.new_buffer_list) |
740 res = |
792 appsink->priv->callbacks.new_buffer_list (appsink, |
741 appsink->priv->callbacks.new_buffer (appsink, appsink->priv->user_data); |
793 appsink->priv->user_data); |
742 else if (emit) |
794 } else { |
743 g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_BUFFER], 0); |
795 if (appsink->priv->callbacks.new_buffer) |
744 |
796 appsink->priv->callbacks.new_buffer (appsink, appsink->priv->user_data); |
745 return res; |
797 else if (emit) |
|
798 g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_BUFFER], 0); |
|
799 } |
|
800 return GST_FLOW_OK; |
|
801 |
746 |
802 flushing: |
747 flushing: |
803 { |
748 { |
804 GST_DEBUG_OBJECT (appsink, "we are flushing"); |
749 GST_DEBUG_OBJECT (appsink, "we are flushing"); |
805 g_mutex_unlock (appsink->priv->mutex); |
750 g_mutex_unlock (appsink->priv->mutex); |
806 return GST_FLOW_WRONG_STATE; |
751 return GST_FLOW_WRONG_STATE; |
807 } |
752 } |
808 } |
753 } |
809 |
754 |
810 static GstFlowReturn |
|
811 gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer) |
|
812 { |
|
813 return gst_app_sink_render_common (psink, GST_MINI_OBJECT_CAST (buffer), |
|
814 FALSE); |
|
815 } |
|
816 |
|
817 static GstFlowReturn |
|
818 gst_app_sink_render_list (GstBaseSink * psink, GstBufferList * list) |
|
819 { |
|
820 return gst_app_sink_render_common (psink, GST_MINI_OBJECT_CAST (list), TRUE); |
|
821 } |
|
822 |
|
823 static GstCaps * |
755 static GstCaps * |
824 gst_app_sink_getcaps (GstBaseSink * psink) |
756 gst_app_sink_getcaps (GstBaseSink * psink) |
825 { |
757 { |
826 GstCaps *caps; |
758 GstCaps *caps; |
827 |
759 |
832 gst_caps_ref (caps); |
764 gst_caps_ref (caps); |
833 GST_DEBUG_OBJECT (appsink, "got caps %" GST_PTR_FORMAT, caps); |
765 GST_DEBUG_OBJECT (appsink, "got caps %" GST_PTR_FORMAT, caps); |
834 GST_OBJECT_UNLOCK (appsink); |
766 GST_OBJECT_UNLOCK (appsink); |
835 |
767 |
836 return caps; |
768 return caps; |
837 } |
|
838 |
|
839 static GstMiniObject * |
|
840 gst_app_sink_pull_object (GstAppSink * appsink) |
|
841 { |
|
842 GstMiniObject *obj = NULL; |
|
843 |
|
844 g_return_val_if_fail (appsink != NULL, NULL); |
|
845 g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL); |
|
846 |
|
847 g_mutex_lock (appsink->priv->mutex); |
|
848 |
|
849 while (TRUE) { |
|
850 GST_DEBUG_OBJECT (appsink, "trying to grab a buffer/list"); |
|
851 if (!appsink->priv->started) |
|
852 goto not_started; |
|
853 |
|
854 if (!g_queue_is_empty (appsink->priv->queue)) |
|
855 break; |
|
856 |
|
857 if (appsink->priv->is_eos) |
|
858 goto eos; |
|
859 |
|
860 /* nothing to return, wait */ |
|
861 GST_DEBUG_OBJECT (appsink, "waiting for a buffer/list"); |
|
862 g_cond_wait (appsink->priv->cond, appsink->priv->mutex); |
|
863 } |
|
864 obj = g_queue_pop_head (appsink->priv->queue); |
|
865 GST_DEBUG_OBJECT (appsink, "we have a buffer/list %p", obj); |
|
866 g_cond_signal (appsink->priv->cond); |
|
867 g_mutex_unlock (appsink->priv->mutex); |
|
868 |
|
869 return obj; |
|
870 |
|
871 /* special conditions */ |
|
872 eos: |
|
873 { |
|
874 GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL"); |
|
875 g_mutex_unlock (appsink->priv->mutex); |
|
876 return NULL; |
|
877 } |
|
878 not_started: |
|
879 { |
|
880 GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL"); |
|
881 g_mutex_unlock (appsink->priv->mutex); |
|
882 return NULL; |
|
883 } |
|
884 } |
769 } |
885 |
770 |
886 /* external API */ |
771 /* external API */ |
887 |
772 |
888 /** |
773 /** |
1224 * |
1109 * |
1225 * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS. |
1110 * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS. |
1226 * |
1111 * |
1227 * Since: 0.10.22 |
1112 * Since: 0.10.22 |
1228 */ |
1113 */ |
1229 |
|
1230 EXPORT_C GstBuffer * |
1114 EXPORT_C GstBuffer * |
1231 gst_app_sink_pull_buffer (GstAppSink * appsink) |
1115 gst_app_sink_pull_buffer (GstAppSink * appsink) |
1232 { |
1116 { |
1233 GST_DEBUG_OBJECT (appsink, "pull a buffer"); |
1117 GstBuffer *buf = NULL; |
1234 return GST_BUFFER_CAST (gst_app_sink_pull_object (appsink)); |
1118 |
1235 } |
1119 g_return_val_if_fail (appsink != NULL, NULL); |
1236 |
1120 g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL); |
1237 /** |
1121 |
1238 * gst_app_sink_pull_buffer_list: |
1122 g_mutex_lock (appsink->priv->mutex); |
1239 * @appsink: a #GstAppSink |
1123 |
1240 * |
1124 while (TRUE) { |
1241 * This function blocks until a buffer list or EOS becomes available or the |
1125 GST_DEBUG_OBJECT (appsink, "trying to grab a buffer"); |
1242 * appsink element is set to the READY/NULL state. |
1126 if (!appsink->priv->started) |
1243 * |
1127 goto not_started; |
1244 * This function will only return buffer lists when the appsink is in the |
1128 |
1245 * PLAYING state. All rendered buffer lists will be put in a queue so that |
1129 if (!g_queue_is_empty (appsink->priv->queue)) |
1246 * the application can pull buffer lists at its own rate. Note that when |
1130 break; |
1247 * the application does not pull buffer lists fast enough, the queued buffer |
1131 |
1248 * lists could consume a lot of memory, especially when dealing with raw |
1132 if (appsink->priv->is_eos) |
1249 * video frames. |
1133 goto eos; |
1250 * |
1134 |
1251 * If an EOS event was received before any buffer lists, this function returns |
1135 /* nothing to return, wait */ |
1252 * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition. |
1136 GST_DEBUG_OBJECT (appsink, "waiting for a buffer"); |
1253 * |
1137 g_cond_wait (appsink->priv->cond, appsink->priv->mutex); |
1254 * Returns: a #GstBufferList or NULL when the appsink is stopped or EOS. |
1138 } |
1255 */ |
1139 buf = g_queue_pop_head (appsink->priv->queue); |
1256 EXPORT_C GstBufferList * |
1140 GST_DEBUG_OBJECT (appsink, "we have a buffer %p", buf); |
1257 gst_app_sink_pull_buffer_list (GstAppSink * appsink) |
1141 g_cond_signal (appsink->priv->cond); |
1258 { |
1142 g_mutex_unlock (appsink->priv->mutex); |
1259 GST_DEBUG_OBJECT (appsink, "pull a buffer list"); |
1143 |
1260 return GST_BUFFER_LIST_CAST (gst_app_sink_pull_object (appsink)); |
1144 return buf; |
|
1145 |
|
1146 /* special conditions */ |
|
1147 eos: |
|
1148 { |
|
1149 GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL"); |
|
1150 g_mutex_unlock (appsink->priv->mutex); |
|
1151 return NULL; |
|
1152 } |
|
1153 not_started: |
|
1154 { |
|
1155 GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL"); |
|
1156 g_mutex_unlock (appsink->priv->mutex); |
|
1157 return NULL; |
|
1158 } |
1261 } |
1159 } |
1262 |
1160 |
1263 /** |
1161 /** |
1264 * gst_app_sink_set_callbacks: |
1162 * gst_app_sink_set_callbacks: |
1265 * @appsink: a #GstAppSink |
1163 * @appsink: a #GstAppSink |