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>
53 #include <gst/gst-i18n-lib.h>
55 #define DEFAULT_BLOCKSIZE 4096
56 #define DEFAULT_NUM_BUFFERS -1
58 GST_DEBUG_CATEGORY_STATIC (gst_base_src_debug);
59 #define GST_CAT_DEFAULT gst_base_src_debug
61 /* BaseSrc signals and args */
75 static GstElementClass *parent_class = NULL;
77 static void gst_base_src_base_init (gpointer g_class);
78 static void gst_base_src_class_init (GstBaseSrcClass * klass);
79 static void gst_base_src_init (GstBaseSrc * src, gpointer g_class);
80 static void gst_base_src_finalize (GObject * object);
84 gst_base_src_get_type (void)
86 static GType base_src_type = 0;
89 static const GTypeInfo base_src_info = {
90 sizeof (GstBaseSrcClass),
91 (GBaseInitFunc) gst_base_src_base_init,
93 (GClassInitFunc) gst_base_src_class_init,
98 (GInstanceInitFunc) gst_base_src_init,
101 base_src_type = g_type_register_static (GST_TYPE_ELEMENT,
102 "GstBaseSrc", &base_src_info, G_TYPE_FLAG_ABSTRACT);
104 return base_src_type;
106 static GstCaps *gst_base_src_getcaps (GstPad * pad);
107 static gboolean gst_base_src_setcaps (GstPad * pad, GstCaps * caps);
109 static gboolean gst_base_src_activate_push (GstPad * pad, gboolean active);
110 static gboolean gst_base_src_activate_pull (GstPad * pad, gboolean active);
111 static void gst_base_src_set_property (GObject * object, guint prop_id,
112 const GValue * value, GParamSpec * pspec);
113 static void gst_base_src_get_property (GObject * object, guint prop_id,
114 GValue * value, GParamSpec * pspec);
115 static gboolean gst_base_src_event_handler (GstPad * pad, GstEvent * event);
116 static gboolean gst_base_src_send_event (GstElement * elem, GstEvent * event);
118 static gboolean gst_base_src_query (GstPad * pad, GstQuery * query);
120 static gboolean gst_base_src_default_negotiate (GstBaseSrc * basesrc);
121 static gboolean gst_base_src_default_newsegment (GstBaseSrc * src);
123 static gboolean gst_base_src_unlock (GstBaseSrc * basesrc);
124 static gboolean gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size);
125 static gboolean gst_base_src_start (GstBaseSrc * basesrc);
126 static gboolean gst_base_src_stop (GstBaseSrc * basesrc);
128 static GstStateChangeReturn gst_base_src_change_state (GstElement * element,
129 GstStateChange transition);
131 static void gst_base_src_loop (GstPad * pad);
132 static gboolean gst_base_src_check_get_range (GstPad * pad);
133 static GstFlowReturn gst_base_src_pad_get_range (GstPad * pad, guint64 offset,
134 guint length, GstBuffer ** buf);
135 static GstFlowReturn gst_base_src_get_range (GstBaseSrc * src, guint64 offset,
136 guint length, GstBuffer ** buf);
139 gst_base_src_base_init (gpointer g_class)
141 GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
145 gst_base_src_class_init (GstBaseSrcClass * klass)
147 GObjectClass *gobject_class;
148 GstElementClass *gstelement_class;
150 gobject_class = (GObjectClass *) klass;
151 gstelement_class = (GstElementClass *) klass;
153 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
155 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_base_src_finalize);
156 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_base_src_set_property);
157 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_base_src_get_property);
159 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BLOCKSIZE,
160 g_param_spec_ulong ("blocksize", "Block size",
161 "Size in bytes to read per buffer", 1, G_MAXULONG, DEFAULT_BLOCKSIZE,
164 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_NUM_BUFFERS,
165 g_param_spec_int ("num-buffers", "num-buffers",
166 "Number of buffers to output before sending EOS", -1, G_MAXINT,
167 DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE));
169 gstelement_class->change_state =
170 GST_DEBUG_FUNCPTR (gst_base_src_change_state);
171 gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_base_src_send_event);
173 klass->negotiate = gst_base_src_default_negotiate;
174 klass->newsegment = gst_base_src_default_newsegment;
178 gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
181 GstPadTemplate *pad_template;
183 basesrc->is_live = FALSE;
184 basesrc->live_lock = g_mutex_new ();
185 basesrc->live_cond = g_cond_new ();
186 basesrc->num_buffers = DEFAULT_NUM_BUFFERS;
187 basesrc->num_buffers_left = -1;
189 basesrc->can_activate_push = TRUE;
190 basesrc->pad_mode = GST_ACTIVATE_NONE;
193 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
194 g_return_if_fail (pad_template != NULL);
196 GST_DEBUG_OBJECT (basesrc, "creating src pad");
197 pad = gst_pad_new_from_template (pad_template, "src");
199 GST_DEBUG_OBJECT (basesrc, "setting functions on src pad");
200 gst_pad_set_activatepush_function (pad,
201 GST_DEBUG_FUNCPTR (gst_base_src_activate_push));
202 gst_pad_set_activatepull_function (pad,
203 GST_DEBUG_FUNCPTR (gst_base_src_activate_pull));
204 gst_pad_set_event_function (pad,
205 GST_DEBUG_FUNCPTR (gst_base_src_event_handler));
206 gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_query));
207 gst_pad_set_checkgetrange_function (pad,
208 GST_DEBUG_FUNCPTR (gst_base_src_check_get_range));
209 gst_pad_set_getrange_function (pad,
210 GST_DEBUG_FUNCPTR (gst_base_src_pad_get_range));
211 gst_pad_set_getcaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_getcaps));
212 gst_pad_set_setcaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_setcaps));
214 /* hold pointer to pad */
215 basesrc->srcpad = pad;
216 GST_DEBUG_OBJECT (basesrc, "adding src pad");
217 gst_element_add_pad (GST_ELEMENT (basesrc), pad);
219 basesrc->blocksize = DEFAULT_BLOCKSIZE;
220 basesrc->clock_id = NULL;
221 basesrc->segment_start = 0;
222 basesrc->segment_end = -1;
224 GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
226 GST_DEBUG_OBJECT (basesrc, "init done");
230 gst_base_src_finalize (GObject * object)
234 basesrc = GST_BASE_SRC (object);
236 g_mutex_free (basesrc->live_lock);
237 g_cond_free (basesrc->live_cond);
239 G_OBJECT_CLASS (parent_class)->finalize (object);
243 * gst_base_src_set_live:
244 * @src: base source instance
245 * @live: new live-mode
247 * If the element listens to a live source, the @livemode should
248 * be set to %TRUE. This declares that this source can't seek.
251 gst_base_src_set_live (GstBaseSrc * src, gboolean live)
255 GST_LIVE_UNLOCK (src);
259 * gst_base_src_is_live:
260 * @src: base source instance
262 * Check if an element is in live mode.
264 * Returns: %TRUE if element is in live mode.
267 gst_base_src_is_live (GstBaseSrc * src)
272 result = src->is_live;
273 GST_LIVE_UNLOCK (src);
279 gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
281 GstBaseSrcClass *bclass;
285 bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
286 bclass = GST_BASE_SRC_GET_CLASS (bsrc);
288 if (bclass->set_caps)
289 res = bclass->set_caps (bsrc, caps);
295 gst_base_src_getcaps (GstPad * pad)
297 GstBaseSrcClass *bclass;
299 GstCaps *caps = NULL;
301 bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
302 bclass = GST_BASE_SRC_GET_CLASS (bsrc);
303 if (bclass->get_caps)
304 caps = bclass->get_caps (bsrc);
307 GstPadTemplate *pad_template;
310 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
311 if (pad_template != NULL) {
312 caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
319 gst_base_src_query (GstPad * pad, GstQuery * query)
324 src = GST_BASE_SRC (gst_pad_get_parent (pad));
326 switch (GST_QUERY_TYPE (query)) {
327 case GST_QUERY_POSITION:
331 gst_query_parse_position (query, &format, NULL);
333 case GST_FORMAT_DEFAULT:
334 case GST_FORMAT_BYTES:
335 gst_query_set_position (query, GST_FORMAT_BYTES, src->offset);
338 case GST_FORMAT_PERCENT:
344 b = gst_base_src_get_size (src, &ui64);
345 if (b && src->offset > ui64)
346 i64 = gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX, src->offset,
349 i64 = GST_FORMAT_PERCENT_MAX;
351 gst_query_set_position (query, GST_FORMAT_PERCENT, i64);
361 case GST_QUERY_DURATION:
365 gst_query_parse_duration (query, &format, NULL);
367 case GST_FORMAT_DEFAULT:
368 case GST_FORMAT_BYTES:
374 b = gst_base_src_get_size (src, &ui64);
375 /* better to make get_size take an int64 */
376 i64 = b ? (gint64) ui64 : -1;
377 gst_query_set_duration (query, GST_FORMAT_BYTES, i64);
381 case GST_FORMAT_PERCENT:
382 gst_query_set_duration (query, GST_FORMAT_PERCENT,
383 GST_FORMAT_PERCENT_MAX);
393 case GST_QUERY_SEEKING:
394 gst_query_set_seeking (query, GST_FORMAT_BYTES,
395 src->seekable, 0, src->size);
399 case GST_QUERY_SEGMENT:
403 start = src->segment_start;
404 /* no end segment configured, current size then */
405 if ((stop = src->segment_end) == -1)
408 /* FIXME, we can't report our rate as we did not store it, d'oh!.
409 * Also, subclasses might want to support other formats. */
410 gst_query_set_segment (query, 1.0, GST_FORMAT_BYTES, start, stop);
415 case GST_QUERY_FORMATS:
416 gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
417 GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
421 case GST_QUERY_LATENCY:
422 case GST_QUERY_JITTER:
424 case GST_QUERY_CONVERT:
426 res = gst_pad_query_default (pad, query);
430 gst_object_unref (src);
435 gst_base_src_default_newsegment (GstBaseSrc * src)
439 GST_DEBUG_OBJECT (src, "Sending newsegment from %" G_GINT64_FORMAT
440 " to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
442 event = gst_event_new_newsegment (FALSE, 1.0,
443 GST_FORMAT_BYTES, src->segment_start, src->segment_end,
446 return gst_pad_push_event (src->srcpad, event);
450 gst_base_src_newsegment (GstBaseSrc * src)
452 GstBaseSrcClass *bclass;
453 gboolean result = FALSE;
455 bclass = GST_BASE_SRC_GET_CLASS (src);
457 if (bclass->newsegment)
458 result = bclass->newsegment (src);
463 /* based on the event parameters configure the segment_start/stop
464 * times. Called with STREAM_LOCK.
467 gst_base_src_configure_segment (GstBaseSrc * src, GstEvent * event)
472 GstSeekType cur_type, stop_type;
474 gboolean update_stop, update_start;
476 gst_event_parse_seek (event, &rate, &format, &flags,
477 &cur_type, &cur, &stop_type, &stop);
479 /* parse the loop flag */
480 /* FIXME, need to store other flags and rate too */
481 src->segment_loop = (flags & GST_SEEK_FLAG_SEGMENT) != 0;
483 /* assume we'll update both start and stop values */
487 /* perform the seek, segment_start is never invalid */
489 case GST_SEEK_TYPE_NONE:
490 /* no update to segment */
491 cur = src->segment_start;
492 update_start = FALSE;
494 case GST_SEEK_TYPE_SET:
495 /* cur holds desired position */
497 case GST_SEEK_TYPE_CUR:
498 /* add cur to currently configure segment */
499 cur = src->segment_start + cur;
501 case GST_SEEK_TYPE_END:
502 /* add cur to total length */
503 cur = src->size + cur;
506 /* bring in sane range */
508 cur = CLAMP (cur, 0, src->size);
512 /* segment_end can be -1 if we have not configured a stop. */
514 case GST_SEEK_TYPE_NONE:
515 stop = src->segment_end;
518 case GST_SEEK_TYPE_SET:
519 /* stop folds required value */
521 case GST_SEEK_TYPE_CUR:
522 if (src->segment_end != -1)
523 stop = src->segment_end + stop;
527 case GST_SEEK_TYPE_END:
529 stop = src->size + stop;
535 /* if we have a valid stop time, make sure it is clipped */
538 stop = CLAMP (stop, 0, src->size);
540 stop = MAX (stop, 0);
543 src->segment_start = cur;
544 src->segment_end = stop;
546 /* update our offset if it was updated */
550 GST_DEBUG_OBJECT (src, "segment configured from %" G_GINT64_FORMAT
551 " to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
556 /* this code implements the seeking. It is a good example
557 * handling all cases (modulo the FIXMEs).
559 * A seek updates the currently configured segment_start
560 * and segment_stop values based on the SEEK_TYPE. If the
561 * segment_start value is updated, a seek to this new position
562 * should be performed.
564 * The seek can only be executed when we are not currently
565 * streaming any data, to make sure that this is the case, we
566 * acquire the STREAM_LOCK which is taken when we are in the
567 * _loop() function or when a getrange() is called. Normally
568 * we will not receive a seek if we are operating in pull mode
571 * When we are in the loop() function, we might be in the middle
572 * of pushing a buffer, which might block in a sink. To make sure
573 * that the push gets unblocked we push out a FLUSH_START event.
574 * Our loop function will get a WRONG_STATE return value from
575 * the push and will pause, effectively releasing the STREAM_LOCK.
577 * For a non-flushing seek, we pause the task, which might eventually
578 * release the STREAM_LOCK. We say eventually because when the sink
579 * blocks on the sample we might wait a very long time until the sink
580 * unblocks the sample. In any case we acquire the STREAM_LOCK and
581 * can continue the seek. A non-flushing seek is normally done in a
582 * running pipeline to perform seamless playback.
584 * After updating the segment_start/stop values, we prepare for
585 * streaming again. We push out a FLUSH_STOP to make the peer pad
586 * accept data again and we start our task again.
588 * A segment seek posts a message on the bus saying that the playback
589 * of the segment started. We store the segment flag internally because
590 * when we reach the segment_stop we have to post a segment_done
591 * instead of EOS when doing a segment seek.
594 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
601 gst_event_parse_seek (event, &rate, &format, &flags, NULL, NULL, NULL, NULL);
603 /* FIXME subclasses should be able to provide other formats */
604 /* get seek format */
605 if (format == GST_FORMAT_DEFAULT)
606 format = GST_FORMAT_BYTES;
607 /* we can only seek bytes */
608 if (format != GST_FORMAT_BYTES)
609 goto unsupported_seek;
611 flush = flags & GST_SEEK_FLAG_FLUSH;
613 /* send flush start */
615 gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
617 gst_pad_pause_task (src->srcpad);
619 /* unblock streaming thread */
620 gst_base_src_unlock (src);
622 /* grab streaming lock, this should eventually be possible, either
623 * because the task is paused or out streaming thread stopped
624 * because our peer is flushing. */
625 GST_STREAM_LOCK (src->srcpad);
627 /* now configure the segment */
628 gst_base_src_configure_segment (src, event);
630 /* and prepare to continue streaming */
632 /* send flush stop, peer will accept data and events again. We
633 * are not yet providing data as we still have the STREAM_LOCK. */
634 gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
636 /* now make sure the newsegment will be send from the streaming
637 * thread. We could opt to send it here too. */
638 src->need_newsegment = TRUE;
640 if (src->segment_loop) {
641 /* FIXME subclasses should be able to provide other formats */
642 gst_element_post_message (GST_ELEMENT (src),
643 gst_message_new_segment_start (GST_OBJECT (src), GST_FORMAT_BYTES,
644 src->segment_start));
647 /* and restart the task in case it got paused explicitely or by
648 * the FLUSH_START event we pushed out. */
649 gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
652 /* and release the lock again so we can continue streaming */
653 GST_STREAM_UNLOCK (src->srcpad);
660 GST_DEBUG_OBJECT (src, "invalid format, seek aborted.");
666 /* all events send to this element directly
669 gst_base_src_send_event (GstElement * element, GstEvent * event)
674 src = GST_BASE_SRC (element);
676 switch (GST_EVENT_TYPE (event)) {
678 result = gst_base_src_configure_segment (src, event);
689 gst_base_src_event_handler (GstPad * pad, GstEvent * event)
692 GstBaseSrcClass *bclass;
695 src = GST_BASE_SRC (gst_pad_get_parent (pad));
696 bclass = GST_BASE_SRC_GET_CLASS (src);
699 if (!(result = bclass->event (src, event)))
700 goto subclass_failed;
703 switch (GST_EVENT_TYPE (event)) {
705 /* is normally called when in push mode */
709 result = gst_base_src_do_seek (src, event);
711 case GST_EVENT_FLUSH_START:
712 /* cancel any blocking getrange, is normally called
713 * when in pull mode. */
714 result = gst_base_src_unlock (src);
716 case GST_EVENT_FLUSH_STOP:
721 gst_event_unref (event);
722 gst_object_unref (src);
729 GST_DEBUG_OBJECT (src, "subclass refused event");
730 gst_object_unref (src);
731 gst_event_unref (event);
736 GST_DEBUG_OBJECT (src, "is not seekable");
737 gst_object_unref (src);
738 gst_event_unref (event);
744 gst_base_src_set_property (GObject * object, guint prop_id,
745 const GValue * value, GParamSpec * pspec)
749 src = GST_BASE_SRC (object);
753 src->blocksize = g_value_get_ulong (value);
755 case PROP_NUM_BUFFERS:
756 src->num_buffers = g_value_get_int (value);
759 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
765 gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
770 src = GST_BASE_SRC (object);
774 g_value_set_ulong (value, src->blocksize);
776 case PROP_NUM_BUFFERS:
777 g_value_set_int (value, src->num_buffers);
780 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
785 /* with STREAM_LOCK and LOCK*/
786 static GstClockReturn
787 gst_base_src_wait (GstBaseSrc * basesrc, GstClockTime time)
793 if ((clock = GST_ELEMENT_CLOCK (basesrc)) == NULL)
796 /* clock_id should be NULL outside of this function */
797 g_assert (basesrc->clock_id == NULL);
798 g_assert (GST_CLOCK_TIME_IS_VALID (time));
800 id = gst_clock_new_single_shot_id (clock, time);
802 basesrc->clock_id = id;
803 /* release the object lock while waiting */
804 GST_UNLOCK (basesrc);
806 ret = gst_clock_id_wait (id, NULL);
809 gst_clock_id_unref (id);
810 basesrc->clock_id = NULL;
816 /* perform synchronisation on a buffer
818 static GstClockReturn
819 gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
821 GstClockReturn result = GST_CLOCK_OK;
822 GstClockTime start, end;
823 GstBaseSrcClass *bclass;
824 gboolean start_valid;
825 GstClockTime base_time;
827 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
830 if (bclass->get_times)
831 bclass->get_times (basesrc, buffer, &start, &end);
833 start_valid = GST_CLOCK_TIME_IS_VALID (start);
835 /* if we don't have a timestamp, we don't sync */
837 GST_DEBUG_OBJECT (basesrc, "get_times returned invalid start");
841 GST_DEBUG_OBJECT (basesrc, "got times start: %" GST_TIME_FORMAT
842 ", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
844 /* now do clocking */
846 base_time = GST_ELEMENT_CAST (basesrc)->base_time;
848 GST_LOG_OBJECT (basesrc,
849 "waiting for clock, base time %" GST_TIME_FORMAT
850 ", stream_start %" GST_TIME_FORMAT,
851 GST_TIME_ARGS (base_time), GST_TIME_ARGS (start));
853 result = gst_base_src_wait (basesrc, start + base_time);
854 GST_UNLOCK (basesrc);
856 GST_LOG_OBJECT (basesrc, "clock entry done: %d", result);
864 gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
868 GstBaseSrcClass *bclass;
870 GstClockReturn status;
872 bclass = GST_BASE_SRC_GET_CLASS (src);
876 while (!src->live_running) {
877 GST_DEBUG ("live source signal waiting");
878 GST_LIVE_SIGNAL (src);
879 GST_DEBUG ("live source waiting for running state");
881 GST_DEBUG ("live source unlocked");
883 /* FIXME, use another variable to signal stopping */
884 GST_LOCK (src->srcpad);
885 if (GST_PAD_IS_FLUSHING (src->srcpad))
887 GST_UNLOCK (src->srcpad);
889 GST_LIVE_UNLOCK (src);
891 if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED))
894 if (G_UNLIKELY (!bclass->create))
897 /* the max amount of bytes to read is the total size or
898 * up to the segment_end if present. */
899 if (src->segment_end != -1)
900 maxsize = MIN (src->size, src->segment_end);
904 GST_DEBUG_OBJECT (src,
905 "reading offset %" G_GUINT64_FORMAT ", length %u, size %" G_GINT64_FORMAT
906 ", segment_end %" G_GINT64_FORMAT ", maxsize %" G_GINT64_FORMAT, offset,
907 length, src->size, src->segment_end, maxsize);
911 if (offset > maxsize)
912 goto unexpected_length;
914 if (offset + length > maxsize) {
915 /* see if length of the file changed */
916 if (bclass->get_size)
917 bclass->get_size (src, &src->size);
919 if (src->segment_end != -1)
920 maxsize = MIN (src->size, src->segment_end);
924 if (offset + length > maxsize) {
925 length = maxsize - offset;
930 goto unexpected_length;
932 if (src->num_buffers_left == 0) {
933 goto reached_num_buffers;
935 if (src->num_buffers_left > 0)
936 src->num_buffers_left--;
939 ret = bclass->create (src, offset, length, buf);
940 if (ret != GST_FLOW_OK)
943 /* now sync before pushing the buffer */
944 status = gst_base_src_do_sync (src, *buf);
946 case GST_CLOCK_EARLY:
947 GST_DEBUG_OBJECT (src, "buffer too late!, returning anyway");
950 GST_DEBUG_OBJECT (src, "buffer ok");
953 GST_DEBUG_OBJECT (src, "clock returned %d, not returning", status);
954 gst_buffer_unref (*buf);
956 ret = GST_FLOW_WRONG_STATE;
965 GST_DEBUG_OBJECT (src, "pad is flushing");
966 GST_UNLOCK (src->srcpad);
967 GST_LIVE_UNLOCK (src);
968 return GST_FLOW_WRONG_STATE;
972 GST_DEBUG_OBJECT (src, "getrange but not started");
973 return GST_FLOW_WRONG_STATE;
977 GST_DEBUG_OBJECT (src, "no create function");
978 return GST_FLOW_ERROR;
982 GST_DEBUG_OBJECT (src, "unexpected length %u (offset=%" G_GUINT64_FORMAT
983 ", size=%" G_GUINT64_FORMAT ")", length, offset, src->size);
984 return GST_FLOW_UNEXPECTED;
988 GST_DEBUG_OBJECT (src, "sent all buffers");
989 return GST_FLOW_UNEXPECTED;
994 gst_base_src_pad_get_range (GstPad * pad, guint64 offset, guint length,
1000 src = GST_BASE_SRC (gst_pad_get_parent (pad));
1002 res = gst_base_src_get_range (src, offset, length, buf);
1004 gst_object_unref (src);
1010 gst_base_src_check_get_range (GstPad * pad)
1014 src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1016 if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
1017 gst_base_src_start (src);
1018 gst_base_src_stop (src);
1021 return src->seekable;
1025 gst_base_src_loop (GstPad * pad)
1028 GstBuffer *buf = NULL;
1031 src = GST_BASE_SRC (gst_pad_get_parent (pad));
1033 /* only send segments when operating in push mode */
1034 if (G_UNLIKELY (src->need_newsegment)) {
1035 /* now send newsegment */
1036 gst_base_src_newsegment (src);
1037 src->need_newsegment = FALSE;
1040 ret = gst_base_src_get_range (src, src->offset, src->blocksize, &buf);
1041 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1042 if (ret == GST_FLOW_UNEXPECTED)
1047 if (G_UNLIKELY (buf == NULL))
1050 src->offset += GST_BUFFER_SIZE (buf);
1052 ret = gst_pad_push (pad, buf);
1053 if (G_UNLIKELY (ret != GST_FLOW_OK))
1056 gst_object_unref (src);
1062 GST_DEBUG_OBJECT (src, "going to EOS, getrange returned UNEXPECTED");
1063 gst_pad_pause_task (pad);
1064 if (src->segment_loop) {
1065 /* FIXME, subclass might want to use another format */
1066 gst_element_post_message (GST_ELEMENT (src),
1067 gst_message_new_segment_done (GST_OBJECT (src),
1068 GST_FORMAT_BYTES, src->segment_end));
1070 gst_pad_push_event (pad, gst_event_new_eos ());
1073 gst_object_unref (src);
1078 const gchar *reason = gst_flow_get_name (ret);
1080 GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
1081 gst_pad_pause_task (pad);
1082 if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
1083 /* for fatal errors we post an error message */
1084 GST_ELEMENT_ERROR (src, STREAM, FAILED,
1085 (_("Internal data flow error.")),
1086 ("streaming task paused, reason %s", reason));
1087 gst_pad_push_event (pad, gst_event_new_eos ());
1089 gst_object_unref (src);
1094 GST_ELEMENT_ERROR (src, STREAM, FAILED,
1095 (_("Internal data flow error.")), ("element returned NULL buffer"));
1096 gst_pad_pause_task (pad);
1097 gst_pad_push_event (pad, gst_event_new_eos ());
1099 gst_object_unref (src);
1104 /* this will always be called between start() and stop(). So you can rely on
1105 resources allocated by start() and freed from stop(). This needs to be added
1106 to the docs at some point. */
1108 gst_base_src_unlock (GstBaseSrc * basesrc)
1110 GstBaseSrcClass *bclass;
1111 gboolean result = TRUE;
1113 GST_DEBUG ("unlock");
1114 /* unblock whatever the subclass is doing */
1115 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1117 result = bclass->unlock (basesrc);
1119 GST_DEBUG ("unschedule clock");
1120 /* and unblock the clock as well, if any */
1122 if (basesrc->clock_id) {
1123 gst_clock_id_unschedule (basesrc->clock_id);
1125 GST_UNLOCK (basesrc);
1127 GST_DEBUG ("unlock done");
1133 gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size)
1135 GstBaseSrcClass *bclass;
1136 gboolean result = FALSE;
1138 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1139 if (bclass->get_size)
1140 result = bclass->get_size (basesrc, size);
1143 basesrc->size = *size;
1149 gst_base_src_is_seekable (GstBaseSrc * basesrc)
1151 GstBaseSrcClass *bclass;
1153 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1155 /* check if we can seek */
1156 if (bclass->is_seekable)
1157 basesrc->seekable = bclass->is_seekable (basesrc);
1159 basesrc->seekable = FALSE;
1161 GST_DEBUG_OBJECT (basesrc, "is seekable: %d", basesrc->seekable);
1163 return basesrc->seekable;
1166 /* default negotiation code */
1168 gst_base_src_default_negotiate (GstBaseSrc * basesrc)
1171 GstCaps *caps = NULL;
1172 GstCaps *peercaps = NULL;
1173 gboolean result = FALSE;
1175 /* first see what is possible on our source pad */
1176 thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));
1177 GST_DEBUG ("caps of src: %" GST_PTR_FORMAT, thiscaps);
1178 /* nothing or anything is allowed, we're done */
1179 if (thiscaps == NULL || gst_caps_is_any (thiscaps))
1180 goto no_nego_needed;
1182 /* get the peer caps */
1183 peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
1184 GST_DEBUG ("caps of peer: %" GST_PTR_FORMAT, peercaps);
1188 /* get intersection */
1189 icaps = gst_caps_intersect (thiscaps, peercaps);
1190 GST_DEBUG ("intersect: %" GST_PTR_FORMAT, icaps);
1191 gst_caps_unref (thiscaps);
1192 gst_caps_unref (peercaps);
1194 /* take first (and best) possibility */
1195 caps = gst_caps_copy_nth (icaps, 0);
1196 gst_caps_unref (icaps);
1199 /* no peer, work with our own caps then */
1203 caps = gst_caps_make_writable (caps);
1204 gst_caps_truncate (caps);
1207 gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
1208 GST_DEBUG ("fixated to: %" GST_PTR_FORMAT, caps);
1210 if (gst_caps_is_any (caps)) {
1211 /* hmm, still anything, so element can do anything and
1212 * nego is not needed */
1213 gst_caps_unref (caps);
1215 } else if (gst_caps_is_fixed (caps)) {
1216 /* yay, fixed caps, use those then */
1217 gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
1218 gst_caps_unref (caps);
1226 GST_DEBUG ("no negotiation needed");
1228 gst_caps_unref (thiscaps);
1234 gst_base_src_negotiate (GstBaseSrc * basesrc)
1236 GstBaseSrcClass *bclass;
1237 gboolean result = TRUE;
1239 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1241 if (bclass->negotiate)
1242 result = bclass->negotiate (basesrc);
1248 gst_base_src_start (GstBaseSrc * basesrc)
1250 GstBaseSrcClass *bclass;
1253 if (GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
1256 GST_DEBUG_OBJECT (basesrc, "starting source");
1258 basesrc->num_buffers_left = basesrc->num_buffers;
1260 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1262 result = bclass->start (basesrc);
1267 goto could_not_start;
1269 GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_STARTED);
1271 /* figure out the size */
1272 if (bclass->get_size) {
1273 result = bclass->get_size (basesrc, &basesrc->size);
1274 if (result == FALSE)
1281 GST_DEBUG ("size %d %lld", result, basesrc->size);
1283 /* check if we can seek, updates ->seekable */
1284 gst_base_src_is_seekable (basesrc);
1286 basesrc->need_newsegment = TRUE;
1290 if (basesrc->seekable) {
1293 caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
1294 gst_pad_set_caps (basesrc->srcpad, caps);
1295 gst_caps_unref (caps);
1299 if (!gst_base_src_negotiate (basesrc))
1300 goto could_not_negotiate;
1307 GST_DEBUG_OBJECT (basesrc, "could not start");
1310 could_not_negotiate:
1312 GST_DEBUG_OBJECT (basesrc, "could not negotiate, stopping");
1313 GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
1314 ("Could not connect source to pipeline"),
1315 ("Check your filtered caps, if any"));
1316 gst_base_src_stop (basesrc);
1322 gst_base_src_stop (GstBaseSrc * basesrc)
1324 GstBaseSrcClass *bclass;
1325 gboolean result = TRUE;
1327 if (!GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
1330 GST_DEBUG_OBJECT (basesrc, "stopping source");
1332 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1334 result = bclass->stop (basesrc);
1337 GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
1343 gst_base_src_deactivate (GstBaseSrc * basesrc, GstPad * pad)
1347 GST_LIVE_LOCK (basesrc);
1348 basesrc->live_running = TRUE;
1349 GST_LIVE_SIGNAL (basesrc);
1350 GST_LIVE_UNLOCK (basesrc);
1352 /* step 1, unblock clock sync (if any) */
1353 result = gst_base_src_unlock (basesrc);
1355 /* step 2, make sure streaming finishes */
1356 result &= gst_pad_stop_task (pad);
1362 gst_base_src_activate_push (GstPad * pad, gboolean active)
1364 GstBaseSrc *basesrc;
1367 basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1369 /* prepare subclass first */
1371 GST_DEBUG_OBJECT (basesrc, "Activating in push mode");
1373 if (!basesrc->can_activate_push)
1374 goto no_push_activation;
1376 if (!gst_base_src_start (basesrc))
1379 res = gst_pad_start_task (pad, (GstTaskFunction) gst_base_src_loop, pad);
1381 GST_DEBUG_OBJECT (basesrc, "Deactivating in push mode");
1382 res = gst_base_src_deactivate (basesrc, pad);
1389 GST_DEBUG_OBJECT (basesrc, "Subclass disabled push-mode activation");
1394 gst_base_src_stop (basesrc);
1395 GST_DEBUG_OBJECT (basesrc, "Failed to start in push mode");
1401 gst_base_src_activate_pull (GstPad * pad, gboolean active)
1403 GstBaseSrc *basesrc;
1405 basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1407 /* prepare subclass first */
1409 GST_DEBUG_OBJECT (basesrc, "Activating in pull mode");
1410 if (!gst_base_src_start (basesrc))
1413 if (!basesrc->seekable) {
1414 gst_base_src_stop (basesrc);
1420 GST_DEBUG_OBJECT (basesrc, "Deactivating in pull mode");
1422 if (!gst_base_src_stop (basesrc))
1425 return gst_base_src_deactivate (basesrc, pad);
1430 gst_base_src_stop (basesrc);
1431 GST_DEBUG_OBJECT (basesrc, "Failed to start in pull mode");
1436 GST_DEBUG_OBJECT (basesrc, "Failed to stop in pull mode");
1441 static GstStateChangeReturn
1442 gst_base_src_change_state (GstElement * element, GstStateChange transition)
1444 GstBaseSrc *basesrc;
1445 GstStateChangeReturn result;
1446 gboolean no_preroll = FALSE;
1448 basesrc = GST_BASE_SRC (element);
1450 switch (transition) {
1451 case GST_STATE_CHANGE_NULL_TO_READY:
1453 case GST_STATE_CHANGE_READY_TO_PAUSED:
1454 GST_LIVE_LOCK (element);
1455 if (basesrc->is_live) {
1457 basesrc->live_running = FALSE;
1459 GST_LIVE_UNLOCK (element);
1461 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1462 GST_LIVE_LOCK (element);
1463 if (basesrc->is_live) {
1464 basesrc->live_running = TRUE;
1465 GST_LIVE_SIGNAL (element);
1467 GST_LIVE_UNLOCK (element);
1474 GST_ELEMENT_CLASS (parent_class)->change_state (element,
1475 transition)) == GST_STATE_CHANGE_FAILURE)
1478 switch (transition) {
1479 case GST_STATE_CHANGE_NULL_TO_READY:
1480 /* we always run from start to end when in READY, after putting
1481 * the element to READY a seek can be done on the element to
1482 * configure the segment when going to PAUSED. */
1483 basesrc->segment_loop = FALSE;
1484 basesrc->segment_start = 0;
1485 basesrc->segment_end = -1;
1486 basesrc->offset = 0;
1488 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1489 GST_LIVE_LOCK (element);
1490 if (basesrc->is_live) {
1492 basesrc->live_running = FALSE;
1494 GST_LIVE_UNLOCK (element);
1496 case GST_STATE_CHANGE_PAUSED_TO_READY:
1497 if (!gst_base_src_stop (basesrc))
1499 /* we always run from start to end when in READY */
1500 basesrc->segment_loop = FALSE;
1501 basesrc->segment_start = 0;
1502 basesrc->segment_end = -1;
1503 basesrc->offset = 0;
1505 case GST_STATE_CHANGE_READY_TO_NULL:
1511 if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)
1512 result = GST_STATE_CHANGE_NO_PREROLL;
1519 GST_DEBUG_OBJECT (basesrc, "parent failed state change");
1520 gst_base_src_stop (basesrc);
1525 GST_DEBUG_OBJECT (basesrc, "Failed to stop");
1526 return GST_STATE_CHANGE_FAILURE;