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, NULL);
331 case GST_FORMAT_DEFAULT:
332 case GST_FORMAT_BYTES:
333 b = gst_base_src_get_size (src, &ui64);
334 /* better to make get_size take an int64 */
335 i64 = b ? (gint64) ui64 : -1;
336 gst_query_set_position (query, GST_FORMAT_BYTES, src->offset, i64);
338 case GST_FORMAT_PERCENT:
339 b = gst_base_src_get_size (src, &ui64);
340 i64 = GST_FORMAT_PERCENT_MAX;
341 i64 *= b ? (src->offset / gst_guint64_to_gdouble (ui64)) : 1.0;
342 gst_query_set_position (query, GST_FORMAT_PERCENT,
343 i64, GST_FORMAT_PERCENT_MAX);
350 case GST_QUERY_SEEKING:
351 gst_query_set_seeking (query, GST_FORMAT_BYTES,
352 src->seekable, src->segment_start, src->segment_end);
355 case GST_QUERY_FORMATS:
356 gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
357 GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
360 case GST_QUERY_LATENCY:
361 case GST_QUERY_JITTER:
363 case GST_QUERY_CONVERT:
365 return gst_pad_query_default (pad, query);
370 gst_base_src_default_newsegment (GstBaseSrc * src)
374 GST_DEBUG_OBJECT (src, "Sending newsegment from %" G_GINT64_FORMAT
375 " to %" G_GINT64_FORMAT, (gint64) src->segment_start,
376 (gint64) src->segment_end);
377 event = gst_event_new_newsegment (FALSE, 1.0,
379 (gint64) src->segment_start, (gint64) src->segment_end, (gint64) 0);
381 return gst_pad_push_event (src->srcpad, event);
385 gst_base_src_newsegment (GstBaseSrc * src)
387 GstBaseSrcClass *bclass;
388 gboolean result = FALSE;
390 bclass = GST_BASE_SRC_GET_CLASS (src);
392 if (bclass->newsegment)
393 result = bclass->newsegment (src);
399 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
404 GstSeekType cur_type, stop_type;
407 gst_event_parse_seek (event, &rate, &format, &flags,
408 &cur_type, &cur, &stop_type, &stop);
410 /* get seek format */
411 if (format == GST_FORMAT_DEFAULT)
412 format = GST_FORMAT_BYTES;
413 /* we can only seek bytes */
414 if (format != GST_FORMAT_BYTES)
417 /* get seek positions */
418 src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
420 /* send flush start */
421 gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
423 /* unblock streaming thread */
424 gst_base_src_unlock (src);
426 /* grab streaming lock */
427 GST_STREAM_LOCK (src->srcpad);
429 /* send flush stop */
430 gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
432 /* perform the seek */
434 case GST_SEEK_TYPE_NONE:
436 case GST_SEEK_TYPE_SET:
439 src->offset = MIN (cur, src->size);
440 src->segment_start = src->offset;
442 case GST_SEEK_TYPE_CUR:
443 src->offset = CLAMP (src->offset + cur, 0, src->size);
444 src->segment_start = src->offset;
446 case GST_SEEK_TYPE_END:
449 src->offset = MAX (0, src->size + cur);
450 src->segment_start = src->offset;
457 case GST_SEEK_TYPE_NONE:
459 case GST_SEEK_TYPE_SET:
462 src->segment_end = MIN (stop, src->size);
464 case GST_SEEK_TYPE_CUR:
465 src->segment_end = CLAMP (src->segment_end + stop, 0, src->size);
467 case GST_SEEK_TYPE_END:
470 src->segment_end = src->size + stop;
476 GST_DEBUG_OBJECT (src, "seek pending for segment from %" G_GINT64_FORMAT
477 " to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
479 /* now make sure the newsegment will be send */
480 src->need_newsegment = TRUE;
482 /* and restart the task */
483 gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
485 GST_STREAM_UNLOCK (src->srcpad);
487 gst_event_unref (event);
494 GST_DEBUG_OBJECT (src, "seek error");
495 GST_STREAM_UNLOCK (src->srcpad);
496 gst_event_unref (event);
502 gst_base_src_event_handler (GstPad * pad, GstEvent * event)
505 GstBaseSrcClass *bclass;
508 src = GST_BASE_SRC (GST_PAD_PARENT (pad));
509 bclass = GST_BASE_SRC_GET_CLASS (src);
512 result = bclass->event (src, event);
514 switch (GST_EVENT_TYPE (event)) {
516 if (!src->seekable) {
517 gst_event_unref (event);
520 return gst_base_src_do_seek (src, event);
521 case GST_EVENT_FLUSH_START:
522 /* cancel any blocking getrange */
523 gst_base_src_unlock (src);
525 case GST_EVENT_FLUSH_STOP:
530 gst_event_unref (event);
536 gst_base_src_set_property (GObject * object, guint prop_id,
537 const GValue * value, GParamSpec * pspec)
541 src = GST_BASE_SRC (object);
545 src->blocksize = g_value_get_ulong (value);
547 case PROP_NUM_BUFFERS:
548 src->num_buffers = g_value_get_int (value);
551 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
557 gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
562 src = GST_BASE_SRC (object);
566 g_value_set_ulong (value, src->blocksize);
568 case PROP_NUM_BUFFERS:
569 g_value_set_int (value, src->num_buffers);
572 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
578 gst_base_src_get_range (GstPad * pad, guint64 offset, guint length,
583 GstBaseSrcClass *bclass;
585 src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
586 bclass = GST_BASE_SRC_GET_CLASS (src);
590 while (!src->live_running) {
591 GST_DEBUG ("live source signal waiting");
592 GST_LIVE_SIGNAL (src);
593 GST_DEBUG ("live source waiting for running state");
595 GST_DEBUG ("live source unlocked");
598 GST_LIVE_UNLOCK (src);
601 if (GST_PAD_IS_FLUSHING (pad))
605 if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED))
611 GST_DEBUG_OBJECT (src,
612 "reading offset %" G_GUINT64_FORMAT ", length %u, size %"
613 G_GUINT64_FORMAT, offset, length, src->size);
616 if (src->size != -1) {
617 if (offset > src->size)
618 goto unexpected_length;
620 if (offset + length > src->size) {
621 if (bclass->get_size)
622 bclass->get_size (src, &src->size);
624 if (offset + length > src->size) {
625 length = src->size - offset;
630 goto unexpected_length;
632 if (src->num_buffers_left == 0) {
633 goto reached_num_buffers;
635 if (src->num_buffers_left > 0)
636 src->num_buffers_left--;
639 ret = bclass->create (src, offset, length, buf);
646 GST_DEBUG_OBJECT (src, "pad is flushing");
648 return GST_FLOW_WRONG_STATE;
652 GST_DEBUG_OBJECT (src, "getrange but not started");
653 return GST_FLOW_WRONG_STATE;
657 GST_DEBUG_OBJECT (src, "no create function");
658 return GST_FLOW_ERROR;
662 GST_DEBUG_OBJECT (src, "unexpected length %u (offset=%" G_GUINT64_FORMAT
663 ", size=%" G_GUINT64_FORMAT ")", length, offset, src->size);
664 return GST_FLOW_UNEXPECTED;
668 GST_DEBUG_OBJECT (src, "sent all buffers");
669 return GST_FLOW_UNEXPECTED;
674 gst_base_src_check_get_range (GstPad * pad)
678 src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
680 if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
681 gst_base_src_start (src);
682 gst_base_src_stop (src);
685 return src->seekable;
689 gst_base_src_loop (GstPad * pad)
692 GstBuffer *buf = NULL;
695 src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
697 if (src->need_newsegment) {
698 /* now send newsegment */
699 gst_base_src_newsegment (src);
700 src->need_newsegment = FALSE;
703 ret = gst_base_src_get_range (pad, src->offset, src->blocksize, &buf);
704 if (ret != GST_FLOW_OK)
710 src->offset += GST_BUFFER_SIZE (buf);
712 ret = gst_pad_push (pad, buf);
713 if (ret != GST_FLOW_OK)
720 GST_DEBUG_OBJECT (src, "going to EOS");
721 gst_pad_pause_task (pad);
722 gst_pad_push_event (pad, gst_event_new_eos ());
727 GST_DEBUG_OBJECT (src, "pausing task");
728 gst_pad_pause_task (pad);
729 if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
730 /* for fatal errors we post an error message */
731 GST_ELEMENT_ERROR (src, STREAM, STOPPED,
732 ("streaming stopped, reason %s", gst_flow_get_name (ret)),
733 ("streaming stopped, reason %s", gst_flow_get_name (ret)));
734 gst_pad_push_event (pad, gst_event_new_eos ());
740 GST_ELEMENT_ERROR (src, STREAM, STOPPED,
741 ("internal: element returned NULL buffer"),
742 ("internal: element returned NULL buffer"));
743 gst_pad_pause_task (pad);
744 gst_pad_push_event (pad, gst_event_new_eos ());
749 /* this will always be called between start() and stop(). So you can rely on
750 resources allocated by start() and freed from stop(). This needs to be added
751 to the docs at some point. */
753 gst_base_src_unlock (GstBaseSrc * basesrc)
755 GstBaseSrcClass *bclass;
756 gboolean result = FALSE;
758 GST_DEBUG ("unlock");
759 /* unblock whatever the subclass is doing */
760 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
762 result = bclass->unlock (basesrc);
764 GST_DEBUG ("unschedule clock");
765 /* and unblock the clock as well, if any */
767 if (basesrc->clock_id) {
768 gst_clock_id_unschedule (basesrc->clock_id);
770 GST_UNLOCK (basesrc);
772 GST_DEBUG ("unlock done");
778 gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size)
780 GstBaseSrcClass *bclass;
781 gboolean result = FALSE;
783 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
784 if (bclass->get_size)
785 result = bclass->get_size (basesrc, size);
788 basesrc->size = *size;
794 gst_base_src_is_seekable (GstBaseSrc * basesrc)
796 GstBaseSrcClass *bclass;
798 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
800 /* check if we can seek */
801 if (bclass->is_seekable)
802 basesrc->seekable = bclass->is_seekable (basesrc);
804 basesrc->seekable = FALSE;
806 GST_DEBUG_OBJECT (basesrc, "is seekable: %d", basesrc->seekable);
808 return basesrc->seekable;
812 gst_base_src_default_negotiate (GstBaseSrc * basesrc)
815 GstCaps *caps = NULL;
816 GstCaps *peercaps = NULL;
817 gboolean result = FALSE;
819 thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));
820 GST_DEBUG ("caps of src: %" GST_PTR_FORMAT, thiscaps);
821 if (thiscaps == NULL || gst_caps_is_any (thiscaps))
824 peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
825 GST_DEBUG ("caps of peer: %" GST_PTR_FORMAT, peercaps);
829 icaps = gst_caps_intersect (thiscaps, peercaps);
830 GST_DEBUG ("intersect: %" GST_PTR_FORMAT, icaps);
831 gst_caps_unref (thiscaps);
832 gst_caps_unref (peercaps);
834 caps = gst_caps_copy_nth (icaps, 0);
835 gst_caps_unref (icaps);
841 caps = gst_caps_make_writable (caps);
842 gst_caps_truncate (caps);
844 gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
845 GST_DEBUG ("fixated to: %" GST_PTR_FORMAT, caps);
847 if (gst_caps_is_any (caps)) {
848 gst_caps_unref (caps);
850 } else if (gst_caps_is_fixed (caps)) {
851 gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
852 gst_caps_unref (caps);
860 GST_DEBUG ("no negotiation needed");
862 gst_caps_unref (thiscaps);
868 gst_base_src_negotiate (GstBaseSrc * basesrc)
870 GstBaseSrcClass *bclass;
871 gboolean result = TRUE;
873 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
875 if (bclass->negotiate)
876 result = bclass->negotiate (basesrc);
882 gst_base_src_start (GstBaseSrc * basesrc)
884 GstBaseSrcClass *bclass;
887 if (GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
890 GST_DEBUG_OBJECT (basesrc, "starting source");
892 basesrc->num_buffers_left = basesrc->num_buffers;
894 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
896 result = bclass->start (basesrc);
901 goto could_not_start;
903 GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_STARTED);
905 /* start in the beginning */
908 /* figure out the size */
909 if (bclass->get_size) {
910 result = bclass->get_size (basesrc, &basesrc->size);
918 GST_DEBUG ("size %d %lld", result, basesrc->size);
920 /* we always run to the end */
921 basesrc->segment_start = 0;
922 basesrc->segment_end = basesrc->size;
923 basesrc->need_newsegment = TRUE;
925 /* check if we can seek, updates ->seekable */
926 gst_base_src_is_seekable (basesrc);
930 if (basesrc->seekable) {
933 caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
934 gst_pad_set_caps (basesrc->srcpad, caps);
935 gst_caps_unref (caps);
939 if (!gst_base_src_negotiate (basesrc))
940 goto could_not_negotiate;
947 GST_DEBUG_OBJECT (basesrc, "could not start");
952 GST_DEBUG_OBJECT (basesrc, "could not negotiate, stopping");
953 GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
954 ("Could not connect source to pipeline"),
955 ("Check your filtered caps, if any"));
956 gst_base_src_stop (basesrc);
962 gst_base_src_stop (GstBaseSrc * basesrc)
964 GstBaseSrcClass *bclass;
965 gboolean result = TRUE;
967 if (!GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
970 GST_DEBUG_OBJECT (basesrc, "stopping source");
972 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
974 result = bclass->stop (basesrc);
977 GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
983 gst_base_src_deactivate (GstBaseSrc * basesrc, GstPad * pad)
987 GST_LIVE_LOCK (basesrc);
988 basesrc->live_running = TRUE;
989 GST_LIVE_SIGNAL (basesrc);
990 GST_LIVE_UNLOCK (basesrc);
992 /* step 1, unblock clock sync (if any) */
993 gst_base_src_unlock (basesrc);
995 /* step 2, make sure streaming finishes */
996 result = gst_pad_stop_task (pad);
1002 gst_base_src_activate_push (GstPad * pad, gboolean active)
1004 GstBaseSrc *basesrc;
1006 basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1008 /* prepare subclass first */
1010 GST_DEBUG_OBJECT (basesrc, "Activating in push mode");
1012 if (!basesrc->can_activate_push)
1013 goto no_push_activation;
1015 if (!gst_base_src_start (basesrc))
1018 return gst_pad_start_task (pad, (GstTaskFunction) gst_base_src_loop, pad);
1020 GST_DEBUG_OBJECT (basesrc, "Deactivating in push mode");
1021 return gst_base_src_deactivate (basesrc, pad);
1026 GST_DEBUG_OBJECT (basesrc, "Subclass disabled push-mode activation");
1031 gst_base_src_stop (basesrc);
1032 GST_DEBUG_OBJECT (basesrc, "Failed to start in push mode");
1038 gst_base_src_activate_pull (GstPad * pad, gboolean active)
1040 GstBaseSrc *basesrc;
1042 basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1044 /* prepare subclass first */
1046 GST_DEBUG_OBJECT (basesrc, "Activating in pull mode");
1047 if (!gst_base_src_start (basesrc))
1050 if (!basesrc->seekable) {
1051 gst_base_src_stop (basesrc);
1057 GST_DEBUG_OBJECT (basesrc, "Deactivating in pull mode");
1059 if (!gst_base_src_stop (basesrc))
1062 return gst_base_src_deactivate (basesrc, pad);
1067 gst_base_src_stop (basesrc);
1068 GST_DEBUG_OBJECT (basesrc, "Failed to start in pull mode");
1073 GST_DEBUG_OBJECT (basesrc, "Failed to stop in pull mode");
1078 static GstStateChangeReturn
1079 gst_base_src_change_state (GstElement * element, GstStateChange transition)
1081 GstBaseSrc *basesrc;
1082 GstStateChangeReturn result;
1083 gboolean no_preroll = FALSE;
1085 basesrc = GST_BASE_SRC (element);
1088 switch (transition) {
1089 case GST_STATE_CHANGE_NULL_TO_READY:
1091 case GST_STATE_CHANGE_READY_TO_PAUSED:
1092 GST_LIVE_LOCK (element);
1093 if (basesrc->is_live) {
1095 basesrc->live_running = FALSE;
1097 GST_LIVE_UNLOCK (element);
1099 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1100 GST_LIVE_LOCK (element);
1101 if (basesrc->is_live) {
1102 basesrc->live_running = TRUE;
1103 GST_LIVE_SIGNAL (element);
1105 GST_LIVE_UNLOCK (element);
1112 GST_ELEMENT_CLASS (parent_class)->change_state (element,
1113 transition)) == GST_STATE_CHANGE_FAILURE)
1116 switch (transition) {
1117 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1118 GST_LIVE_LOCK (element);
1119 if (basesrc->is_live) {
1121 basesrc->live_running = FALSE;
1123 GST_LIVE_UNLOCK (element);
1125 case GST_STATE_CHANGE_PAUSED_TO_READY:
1126 if (!gst_base_src_stop (basesrc))
1127 result = GST_STATE_CHANGE_FAILURE;
1129 case GST_STATE_CHANGE_READY_TO_NULL:
1135 if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)
1136 return GST_STATE_CHANGE_NO_PREROLL;
1143 gst_base_src_stop (basesrc);