2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000,2005 Wim Taymans <wim@fluendo.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
25 * @short_description: Base class for getrange based source elements
26 * @see_also: #GstBaseTransform, #GstBaseSink
28 * This class is mostly useful for elements that do byte based
29 * access to a random access resource, like files.
30 * If random access is not possible, the live-mode should be set
34 * <listitem><para>one source pad</para></listitem>
35 * <listitem><para>handles state changes</para></listitem>
36 * <listitem><para>does flushing</para></listitem>
37 * <listitem><para>preroll with optional preview</para></listitem>
38 * <listitem><para>pull/push mode</para></listitem>
39 * <listitem><para>EOS handling</para></listitem>
50 #include "gstbasesrc.h"
51 #include "gsttypefindhelper.h"
52 #include <gst/gstmarshal.h>
54 #define DEFAULT_BLOCKSIZE 4096
55 #define DEFAULT_NUM_BUFFERS -1
57 GST_DEBUG_CATEGORY_STATIC (gst_base_src_debug);
58 #define GST_CAT_DEFAULT gst_base_src_debug
60 /* BaseSrc signals and args */
74 static GstElementClass *parent_class = NULL;
76 static void gst_base_src_base_init (gpointer g_class);
77 static void gst_base_src_class_init (GstBaseSrcClass * klass);
78 static void gst_base_src_init (GstBaseSrc * src, gpointer g_class);
79 static void gst_base_src_finalize (GObject * object);
83 gst_base_src_get_type (void)
85 static GType base_src_type = 0;
88 static const GTypeInfo base_src_info = {
89 sizeof (GstBaseSrcClass),
90 (GBaseInitFunc) gst_base_src_base_init,
92 (GClassInitFunc) gst_base_src_class_init,
97 (GInstanceInitFunc) gst_base_src_init,
100 base_src_type = g_type_register_static (GST_TYPE_ELEMENT,
101 "GstBaseSrc", &base_src_info, G_TYPE_FLAG_ABSTRACT);
103 return base_src_type;
105 static GstCaps *gst_base_src_getcaps (GstPad * pad);
106 static gboolean gst_base_src_setcaps (GstPad * pad, GstCaps * caps);
108 static gboolean gst_base_src_activate_push (GstPad * pad, gboolean active);
109 static gboolean gst_base_src_activate_pull (GstPad * pad, gboolean active);
110 static void gst_base_src_set_property (GObject * object, guint prop_id,
111 const GValue * value, GParamSpec * pspec);
112 static void gst_base_src_get_property (GObject * object, guint prop_id,
113 GValue * value, GParamSpec * pspec);
114 static gboolean gst_base_src_event_handler (GstPad * pad, GstEvent * event);
116 static gboolean gst_base_src_query (GstPad * pad, GstQuery * query);
118 static gboolean gst_base_src_default_negotiate (GstBaseSrc * basesrc);
119 static gboolean gst_base_src_default_newsegment (GstBaseSrc * src);
121 static gboolean gst_base_src_unlock (GstBaseSrc * basesrc);
122 static gboolean gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size);
123 static gboolean gst_base_src_start (GstBaseSrc * basesrc);
124 static gboolean gst_base_src_stop (GstBaseSrc * basesrc);
126 static GstStateChangeReturn gst_base_src_change_state (GstElement * element,
127 GstStateChange transition);
129 static void gst_base_src_loop (GstPad * pad);
130 static gboolean gst_base_src_check_get_range (GstPad * pad);
131 static GstFlowReturn gst_base_src_get_range (GstPad * pad, guint64 offset,
132 guint length, GstBuffer ** buf);
135 gst_base_src_base_init (gpointer g_class)
137 GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
141 gst_base_src_class_init (GstBaseSrcClass * klass)
143 GObjectClass *gobject_class;
144 GstElementClass *gstelement_class;
146 gobject_class = (GObjectClass *) klass;
147 gstelement_class = (GstElementClass *) klass;
149 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
151 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_base_src_finalize);
152 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_base_src_set_property);
153 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_base_src_get_property);
155 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BLOCKSIZE,
156 g_param_spec_ulong ("blocksize", "Block size",
157 "Size in bytes to read per buffer", 1, G_MAXULONG, DEFAULT_BLOCKSIZE,
160 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_NUM_BUFFERS,
161 g_param_spec_int ("num-buffers", "num-buffers",
162 "Number of buffers to output before sending EOS", -1, G_MAXINT,
163 DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE));
165 gstelement_class->change_state =
166 GST_DEBUG_FUNCPTR (gst_base_src_change_state);
168 klass->negotiate = gst_base_src_default_negotiate;
169 klass->newsegment = gst_base_src_default_newsegment;
173 gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
176 GstPadTemplate *pad_template;
178 basesrc->is_live = FALSE;
179 basesrc->live_lock = g_mutex_new ();
180 basesrc->live_cond = g_cond_new ();
181 basesrc->num_buffers = DEFAULT_NUM_BUFFERS;
182 basesrc->num_buffers_left = -1;
184 basesrc->can_activate_push = TRUE;
185 basesrc->pad_mode = GST_ACTIVATE_NONE;
188 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
189 g_return_if_fail (pad_template != NULL);
191 GST_DEBUG_OBJECT (basesrc, "creating src pad");
192 pad = gst_pad_new_from_template (pad_template, "src");
194 GST_DEBUG_OBJECT (basesrc, "setting functions on src pad");
195 gst_pad_set_activatepush_function (pad,
196 GST_DEBUG_FUNCPTR (gst_base_src_activate_push));
197 gst_pad_set_activatepull_function (pad,
198 GST_DEBUG_FUNCPTR (gst_base_src_activate_pull));
199 gst_pad_set_event_function (pad,
200 GST_DEBUG_FUNCPTR (gst_base_src_event_handler));
201 gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_query));
202 gst_pad_set_checkgetrange_function (pad,
203 GST_DEBUG_FUNCPTR (gst_base_src_check_get_range));
204 gst_pad_set_getrange_function (pad,
205 GST_DEBUG_FUNCPTR (gst_base_src_get_range));
206 gst_pad_set_getcaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_getcaps));
207 gst_pad_set_setcaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_setcaps));
209 /* hold pointer to pad */
210 basesrc->srcpad = pad;
211 GST_DEBUG_OBJECT (basesrc, "adding src pad");
212 gst_element_add_pad (GST_ELEMENT (basesrc), pad);
214 basesrc->segment_start = -1;
215 basesrc->segment_end = -1;
216 basesrc->need_newsegment = TRUE;
217 basesrc->blocksize = DEFAULT_BLOCKSIZE;
218 basesrc->clock_id = NULL;
220 GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
222 GST_DEBUG_OBJECT (basesrc, "init done");
226 gst_base_src_finalize (GObject * object)
230 basesrc = GST_BASE_SRC (object);
232 g_mutex_free (basesrc->live_lock);
233 g_cond_free (basesrc->live_cond);
235 G_OBJECT_CLASS (parent_class)->finalize (object);
239 * gst_base_src_set_live:
240 * @src: base source instance
241 * @live: new live-mode
243 * If the element listens to a live source, the @livemode should
244 * be set to %TRUE. This declares that this source can't seek.
247 gst_base_src_set_live (GstBaseSrc * src, gboolean live)
251 GST_LIVE_UNLOCK (src);
255 * gst_base_src_is_live:
256 * @src: base source instance
258 * Check if an element is in live mode.
260 * Returns: %TRUE if element is in live mode.
263 gst_base_src_is_live (GstBaseSrc * src)
268 result = src->is_live;
269 GST_LIVE_UNLOCK (src);
275 gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
277 GstBaseSrcClass *bclass;
281 bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
282 bclass = GST_BASE_SRC_GET_CLASS (bsrc);
284 if (bclass->set_caps)
285 res = bclass->set_caps (bsrc, caps);
291 gst_base_src_getcaps (GstPad * pad)
293 GstBaseSrcClass *bclass;
295 GstCaps *caps = NULL;
297 bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
298 bclass = GST_BASE_SRC_GET_CLASS (bsrc);
299 if (bclass->get_caps)
300 caps = bclass->get_caps (bsrc);
303 GstPadTemplate *pad_template;
306 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
307 if (pad_template != NULL) {
308 caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
315 gst_base_src_query (GstPad * pad, GstQuery * query)
322 src = GST_BASE_SRC (GST_PAD_PARENT (pad));
324 switch (GST_QUERY_TYPE (query)) {
325 case GST_QUERY_POSITION:
329 gst_query_parse_position (query, &format, NULL);
331 case GST_FORMAT_DEFAULT:
332 case GST_FORMAT_BYTES:
333 gst_query_set_position (query, GST_FORMAT_BYTES, src->offset);
335 case GST_FORMAT_PERCENT:
336 b = gst_base_src_get_size (src, &ui64);
337 i64 = GST_FORMAT_PERCENT_MAX;
339 i64 *= gst_guint64_to_gdouble (src->offset)
340 / gst_guint64_to_gdouble (ui64);
341 gst_query_set_position (query, GST_FORMAT_PERCENT, i64);
347 case GST_QUERY_DURATION:
351 gst_query_parse_duration (query, &format, NULL);
353 case GST_FORMAT_DEFAULT:
354 case GST_FORMAT_BYTES:
355 b = gst_base_src_get_size (src, &ui64);
356 /* better to make get_size take an int64 */
357 i64 = b ? (gint64) ui64 : -1;
358 gst_query_set_duration (query, GST_FORMAT_BYTES, i64);
360 case GST_FORMAT_PERCENT:
361 gst_query_set_duration (query, GST_FORMAT_PERCENT,
362 GST_FORMAT_PERCENT_MAX);
369 case GST_QUERY_SEEKING:
370 gst_query_set_seeking (query, GST_FORMAT_BYTES,
371 src->seekable, src->segment_start, src->segment_end);
374 case GST_QUERY_FORMATS:
375 gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
376 GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
379 case GST_QUERY_LATENCY:
380 case GST_QUERY_JITTER:
382 case GST_QUERY_CONVERT:
384 return gst_pad_query_default (pad, query);
389 gst_base_src_default_newsegment (GstBaseSrc * src)
393 GST_DEBUG_OBJECT (src, "Sending newsegment from %" G_GINT64_FORMAT
394 " to %" G_GINT64_FORMAT, (gint64) src->segment_start,
395 (gint64) src->segment_end);
396 event = gst_event_new_newsegment (FALSE, 1.0,
398 (gint64) src->segment_start, (gint64) src->segment_end, (gint64) 0);
400 return gst_pad_push_event (src->srcpad, event);
404 gst_base_src_newsegment (GstBaseSrc * src)
406 GstBaseSrcClass *bclass;
407 gboolean result = FALSE;
409 bclass = GST_BASE_SRC_GET_CLASS (src);
411 if (bclass->newsegment)
412 result = bclass->newsegment (src);
418 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
423 GstSeekType cur_type, stop_type;
426 gst_event_parse_seek (event, &rate, &format, &flags,
427 &cur_type, &cur, &stop_type, &stop);
429 /* get seek format */
430 if (format == GST_FORMAT_DEFAULT)
431 format = GST_FORMAT_BYTES;
432 /* we can only seek bytes */
433 if (format != GST_FORMAT_BYTES)
436 /* get seek positions */
437 src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
439 /* send flush start */
440 gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
442 /* unblock streaming thread */
443 gst_base_src_unlock (src);
445 /* grab streaming lock */
446 GST_STREAM_LOCK (src->srcpad);
448 /* send flush stop */
449 gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
451 /* perform the seek */
453 case GST_SEEK_TYPE_NONE:
455 case GST_SEEK_TYPE_SET:
458 src->offset = MIN (cur, src->size);
459 src->segment_start = src->offset;
461 case GST_SEEK_TYPE_CUR:
462 src->offset = CLAMP (src->offset + cur, 0, src->size);
463 src->segment_start = src->offset;
465 case GST_SEEK_TYPE_END:
468 src->offset = MAX (0, src->size + cur);
469 src->segment_start = src->offset;
476 case GST_SEEK_TYPE_NONE:
478 case GST_SEEK_TYPE_SET:
481 src->segment_end = MIN (stop, src->size);
483 case GST_SEEK_TYPE_CUR:
484 src->segment_end = CLAMP (src->segment_end + stop, 0, src->size);
486 case GST_SEEK_TYPE_END:
489 src->segment_end = src->size + stop;
495 GST_DEBUG_OBJECT (src, "seek pending for segment from %" G_GINT64_FORMAT
496 " to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
498 /* now make sure the newsegment will be send */
499 src->need_newsegment = TRUE;
501 /* and restart the task */
502 gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
504 GST_STREAM_UNLOCK (src->srcpad);
506 gst_event_unref (event);
513 GST_DEBUG_OBJECT (src, "seek error");
514 GST_STREAM_UNLOCK (src->srcpad);
515 gst_event_unref (event);
521 gst_base_src_event_handler (GstPad * pad, GstEvent * event)
524 GstBaseSrcClass *bclass;
527 src = GST_BASE_SRC (GST_PAD_PARENT (pad));
528 bclass = GST_BASE_SRC_GET_CLASS (src);
531 result = bclass->event (src, event);
533 switch (GST_EVENT_TYPE (event)) {
535 if (!src->seekable) {
536 gst_event_unref (event);
539 return gst_base_src_do_seek (src, event);
540 case GST_EVENT_FLUSH_START:
541 /* cancel any blocking getrange */
542 gst_base_src_unlock (src);
544 case GST_EVENT_FLUSH_STOP:
549 gst_event_unref (event);
555 gst_base_src_set_property (GObject * object, guint prop_id,
556 const GValue * value, GParamSpec * pspec)
560 src = GST_BASE_SRC (object);
564 src->blocksize = g_value_get_ulong (value);
566 case PROP_NUM_BUFFERS:
567 src->num_buffers = g_value_get_int (value);
570 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
576 gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
581 src = GST_BASE_SRC (object);
585 g_value_set_ulong (value, src->blocksize);
587 case PROP_NUM_BUFFERS:
588 g_value_set_int (value, src->num_buffers);
591 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
597 gst_base_src_get_range (GstPad * pad, guint64 offset, guint length,
602 GstBaseSrcClass *bclass;
604 src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
605 bclass = GST_BASE_SRC_GET_CLASS (src);
609 while (!src->live_running) {
610 GST_DEBUG ("live source signal waiting");
611 GST_LIVE_SIGNAL (src);
612 GST_DEBUG ("live source waiting for running state");
614 GST_DEBUG ("live source unlocked");
617 GST_LIVE_UNLOCK (src);
620 if (GST_PAD_IS_FLUSHING (pad))
624 if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED))
630 GST_DEBUG_OBJECT (src,
631 "reading offset %" G_GUINT64_FORMAT ", length %u, size %"
632 G_GINT64_FORMAT, offset, length, src->size);
635 if (src->size != -1) {
636 if (offset > src->size)
637 goto unexpected_length;
639 if (offset + length > src->size) {
640 if (bclass->get_size)
641 bclass->get_size (src, &src->size);
643 if (offset + length > src->size) {
644 length = src->size - offset;
649 goto unexpected_length;
651 if (src->num_buffers_left == 0) {
652 goto reached_num_buffers;
654 if (src->num_buffers_left > 0)
655 src->num_buffers_left--;
658 ret = bclass->create (src, offset, length, buf);
665 GST_DEBUG_OBJECT (src, "pad is flushing");
667 return GST_FLOW_WRONG_STATE;
671 GST_DEBUG_OBJECT (src, "getrange but not started");
672 return GST_FLOW_WRONG_STATE;
676 GST_DEBUG_OBJECT (src, "no create function");
677 return GST_FLOW_ERROR;
681 GST_DEBUG_OBJECT (src, "unexpected length %u (offset=%" G_GUINT64_FORMAT
682 ", size=%" G_GUINT64_FORMAT ")", length, offset, src->size);
683 return GST_FLOW_UNEXPECTED;
687 GST_DEBUG_OBJECT (src, "sent all buffers");
688 return GST_FLOW_UNEXPECTED;
693 gst_base_src_check_get_range (GstPad * pad)
697 src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
699 if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
700 gst_base_src_start (src);
701 gst_base_src_stop (src);
704 return src->seekable;
708 gst_base_src_loop (GstPad * pad)
711 GstBuffer *buf = NULL;
714 src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
716 if (src->need_newsegment) {
717 /* now send newsegment */
718 gst_base_src_newsegment (src);
719 src->need_newsegment = FALSE;
722 ret = gst_base_src_get_range (pad, src->offset, src->blocksize, &buf);
723 if (ret != GST_FLOW_OK)
729 src->offset += GST_BUFFER_SIZE (buf);
731 ret = gst_pad_push (pad, buf);
732 if (ret != GST_FLOW_OK)
739 GST_DEBUG_OBJECT (src, "going to EOS");
740 gst_pad_pause_task (pad);
741 gst_pad_push_event (pad, gst_event_new_eos ());
746 GST_DEBUG_OBJECT (src, "pausing task");
747 gst_pad_pause_task (pad);
748 if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
749 /* for fatal errors we post an error message */
750 GST_ELEMENT_ERROR (src, STREAM, STOPPED,
751 ("streaming stopped, reason %s", gst_flow_get_name (ret)),
752 ("streaming stopped, reason %s", gst_flow_get_name (ret)));
753 gst_pad_push_event (pad, gst_event_new_eos ());
759 GST_ELEMENT_ERROR (src, STREAM, STOPPED,
760 ("internal: element returned NULL buffer"),
761 ("internal: element returned NULL buffer"));
762 gst_pad_pause_task (pad);
763 gst_pad_push_event (pad, gst_event_new_eos ());
768 /* this will always be called between start() and stop(). So you can rely on
769 resources allocated by start() and freed from stop(). This needs to be added
770 to the docs at some point. */
772 gst_base_src_unlock (GstBaseSrc * basesrc)
774 GstBaseSrcClass *bclass;
775 gboolean result = FALSE;
777 GST_DEBUG ("unlock");
778 /* unblock whatever the subclass is doing */
779 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
781 result = bclass->unlock (basesrc);
783 GST_DEBUG ("unschedule clock");
784 /* and unblock the clock as well, if any */
786 if (basesrc->clock_id) {
787 gst_clock_id_unschedule (basesrc->clock_id);
789 GST_UNLOCK (basesrc);
791 GST_DEBUG ("unlock done");
797 gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size)
799 GstBaseSrcClass *bclass;
800 gboolean result = FALSE;
802 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
803 if (bclass->get_size)
804 result = bclass->get_size (basesrc, size);
807 basesrc->size = *size;
813 gst_base_src_is_seekable (GstBaseSrc * basesrc)
815 GstBaseSrcClass *bclass;
817 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
819 /* check if we can seek */
820 if (bclass->is_seekable)
821 basesrc->seekable = bclass->is_seekable (basesrc);
823 basesrc->seekable = FALSE;
825 GST_DEBUG_OBJECT (basesrc, "is seekable: %d", basesrc->seekable);
827 return basesrc->seekable;
831 gst_base_src_default_negotiate (GstBaseSrc * basesrc)
834 GstCaps *caps = NULL;
835 GstCaps *peercaps = NULL;
836 gboolean result = FALSE;
838 thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));
839 GST_DEBUG ("caps of src: %" GST_PTR_FORMAT, thiscaps);
840 if (thiscaps == NULL || gst_caps_is_any (thiscaps))
843 peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
844 GST_DEBUG ("caps of peer: %" GST_PTR_FORMAT, peercaps);
848 icaps = gst_caps_intersect (thiscaps, peercaps);
849 GST_DEBUG ("intersect: %" GST_PTR_FORMAT, icaps);
850 gst_caps_unref (thiscaps);
851 gst_caps_unref (peercaps);
853 caps = gst_caps_copy_nth (icaps, 0);
854 gst_caps_unref (icaps);
860 caps = gst_caps_make_writable (caps);
861 gst_caps_truncate (caps);
863 gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
864 GST_DEBUG ("fixated to: %" GST_PTR_FORMAT, caps);
866 if (gst_caps_is_any (caps)) {
867 gst_caps_unref (caps);
869 } else if (gst_caps_is_fixed (caps)) {
870 gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
871 gst_caps_unref (caps);
879 GST_DEBUG ("no negotiation needed");
881 gst_caps_unref (thiscaps);
887 gst_base_src_negotiate (GstBaseSrc * basesrc)
889 GstBaseSrcClass *bclass;
890 gboolean result = TRUE;
892 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
894 if (bclass->negotiate)
895 result = bclass->negotiate (basesrc);
901 gst_base_src_start (GstBaseSrc * basesrc)
903 GstBaseSrcClass *bclass;
906 if (GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
909 GST_DEBUG_OBJECT (basesrc, "starting source");
911 basesrc->num_buffers_left = basesrc->num_buffers;
913 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
915 result = bclass->start (basesrc);
920 goto could_not_start;
922 GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_STARTED);
924 /* start in the beginning */
927 /* figure out the size */
928 if (bclass->get_size) {
929 result = bclass->get_size (basesrc, &basesrc->size);
937 GST_DEBUG ("size %d %lld", result, basesrc->size);
939 /* we always run to the end */
940 basesrc->segment_start = 0;
941 basesrc->segment_end = basesrc->size;
942 basesrc->need_newsegment = TRUE;
944 /* check if we can seek, updates ->seekable */
945 gst_base_src_is_seekable (basesrc);
949 if (basesrc->seekable) {
952 caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
953 gst_pad_set_caps (basesrc->srcpad, caps);
954 gst_caps_unref (caps);
958 if (!gst_base_src_negotiate (basesrc))
959 goto could_not_negotiate;
966 GST_DEBUG_OBJECT (basesrc, "could not start");
971 GST_DEBUG_OBJECT (basesrc, "could not negotiate, stopping");
972 GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
973 ("Could not connect source to pipeline"),
974 ("Check your filtered caps, if any"));
975 gst_base_src_stop (basesrc);
981 gst_base_src_stop (GstBaseSrc * basesrc)
983 GstBaseSrcClass *bclass;
984 gboolean result = TRUE;
986 if (!GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
989 GST_DEBUG_OBJECT (basesrc, "stopping source");
991 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
993 result = bclass->stop (basesrc);
996 GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
1002 gst_base_src_deactivate (GstBaseSrc * basesrc, GstPad * pad)
1006 GST_LIVE_LOCK (basesrc);
1007 basesrc->live_running = TRUE;
1008 GST_LIVE_SIGNAL (basesrc);
1009 GST_LIVE_UNLOCK (basesrc);
1011 /* step 1, unblock clock sync (if any) */
1012 gst_base_src_unlock (basesrc);
1014 /* step 2, make sure streaming finishes */
1015 result = gst_pad_stop_task (pad);
1021 gst_base_src_activate_push (GstPad * pad, gboolean active)
1023 GstBaseSrc *basesrc;
1025 basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1027 /* prepare subclass first */
1029 GST_DEBUG_OBJECT (basesrc, "Activating in push mode");
1031 if (!basesrc->can_activate_push)
1032 goto no_push_activation;
1034 if (!gst_base_src_start (basesrc))
1037 return gst_pad_start_task (pad, (GstTaskFunction) gst_base_src_loop, pad);
1039 GST_DEBUG_OBJECT (basesrc, "Deactivating in push mode");
1040 return gst_base_src_deactivate (basesrc, pad);
1045 GST_DEBUG_OBJECT (basesrc, "Subclass disabled push-mode activation");
1050 gst_base_src_stop (basesrc);
1051 GST_DEBUG_OBJECT (basesrc, "Failed to start in push mode");
1057 gst_base_src_activate_pull (GstPad * pad, gboolean active)
1059 GstBaseSrc *basesrc;
1061 basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1063 /* prepare subclass first */
1065 GST_DEBUG_OBJECT (basesrc, "Activating in pull mode");
1066 if (!gst_base_src_start (basesrc))
1069 if (!basesrc->seekable) {
1070 gst_base_src_stop (basesrc);
1076 GST_DEBUG_OBJECT (basesrc, "Deactivating in pull mode");
1078 if (!gst_base_src_stop (basesrc))
1081 return gst_base_src_deactivate (basesrc, pad);
1086 gst_base_src_stop (basesrc);
1087 GST_DEBUG_OBJECT (basesrc, "Failed to start in pull mode");
1092 GST_DEBUG_OBJECT (basesrc, "Failed to stop in pull mode");
1097 static GstStateChangeReturn
1098 gst_base_src_change_state (GstElement * element, GstStateChange transition)
1100 GstBaseSrc *basesrc;
1101 GstStateChangeReturn result;
1102 gboolean no_preroll = FALSE;
1104 basesrc = GST_BASE_SRC (element);
1107 switch (transition) {
1108 case GST_STATE_CHANGE_NULL_TO_READY:
1110 case GST_STATE_CHANGE_READY_TO_PAUSED:
1111 GST_LIVE_LOCK (element);
1112 if (basesrc->is_live) {
1114 basesrc->live_running = FALSE;
1116 GST_LIVE_UNLOCK (element);
1118 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1119 GST_LIVE_LOCK (element);
1120 if (basesrc->is_live) {
1121 basesrc->live_running = TRUE;
1122 GST_LIVE_SIGNAL (element);
1124 GST_LIVE_UNLOCK (element);
1131 GST_ELEMENT_CLASS (parent_class)->change_state (element,
1132 transition)) == GST_STATE_CHANGE_FAILURE)
1135 switch (transition) {
1136 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1137 GST_LIVE_LOCK (element);
1138 if (basesrc->is_live) {
1140 basesrc->live_running = FALSE;
1142 GST_LIVE_UNLOCK (element);
1144 case GST_STATE_CHANGE_PAUSED_TO_READY:
1145 if (!gst_base_src_stop (basesrc))
1146 result = GST_STATE_CHANGE_FAILURE;
1148 case GST_STATE_CHANGE_READY_TO_NULL:
1154 if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)
1155 return GST_STATE_CHANGE_NO_PREROLL;
1162 gst_base_src_stop (basesrc);