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");
198 gst_object_unref (pad_template);
200 GST_DEBUG_OBJECT (basesrc, "setting functions on src pad");
201 gst_pad_set_activatepush_function (pad,
202 GST_DEBUG_FUNCPTR (gst_base_src_activate_push));
203 gst_pad_set_activatepull_function (pad,
204 GST_DEBUG_FUNCPTR (gst_base_src_activate_pull));
205 gst_pad_set_event_function (pad,
206 GST_DEBUG_FUNCPTR (gst_base_src_event_handler));
207 gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_query));
208 gst_pad_set_checkgetrange_function (pad,
209 GST_DEBUG_FUNCPTR (gst_base_src_check_get_range));
210 gst_pad_set_getrange_function (pad,
211 GST_DEBUG_FUNCPTR (gst_base_src_pad_get_range));
212 gst_pad_set_getcaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_getcaps));
213 gst_pad_set_setcaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_setcaps));
215 /* hold pointer to pad */
216 basesrc->srcpad = pad;
217 GST_DEBUG_OBJECT (basesrc, "adding src pad");
218 gst_element_add_pad (GST_ELEMENT (basesrc), pad);
220 basesrc->blocksize = DEFAULT_BLOCKSIZE;
221 basesrc->clock_id = NULL;
222 basesrc->segment_start = 0;
223 basesrc->segment_end = -1;
225 GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
227 GST_DEBUG_OBJECT (basesrc, "init done");
231 gst_base_src_finalize (GObject * object)
235 basesrc = GST_BASE_SRC (object);
237 g_mutex_free (basesrc->live_lock);
238 g_cond_free (basesrc->live_cond);
240 G_OBJECT_CLASS (parent_class)->finalize (object);
244 * gst_base_src_set_live:
245 * @src: base source instance
246 * @live: new live-mode
248 * If the element listens to a live source, the @livemode should
249 * be set to %TRUE. This declares that this source can't seek.
252 gst_base_src_set_live (GstBaseSrc * src, gboolean live)
256 GST_LIVE_UNLOCK (src);
260 * gst_base_src_is_live:
261 * @src: base source instance
263 * Check if an element is in live mode.
265 * Returns: %TRUE if element is in live mode.
268 gst_base_src_is_live (GstBaseSrc * src)
273 result = src->is_live;
274 GST_LIVE_UNLOCK (src);
280 gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
282 GstBaseSrcClass *bclass;
286 bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
287 bclass = GST_BASE_SRC_GET_CLASS (bsrc);
289 if (bclass->set_caps)
290 res = bclass->set_caps (bsrc, caps);
296 gst_base_src_getcaps (GstPad * pad)
298 GstBaseSrcClass *bclass;
300 GstCaps *caps = NULL;
302 bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
303 bclass = GST_BASE_SRC_GET_CLASS (bsrc);
304 if (bclass->get_caps)
305 caps = bclass->get_caps (bsrc);
308 GstPadTemplate *pad_template;
311 gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
312 if (pad_template != NULL) {
313 caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
320 gst_base_src_query (GstPad * pad, GstQuery * query)
325 src = GST_BASE_SRC (gst_pad_get_parent (pad));
327 switch (GST_QUERY_TYPE (query)) {
328 case GST_QUERY_POSITION:
332 gst_query_parse_position (query, &format, NULL);
334 case GST_FORMAT_DEFAULT:
335 case GST_FORMAT_BYTES:
336 gst_query_set_position (query, GST_FORMAT_BYTES, src->offset);
339 case GST_FORMAT_PERCENT:
345 b = gst_base_src_get_size (src, &ui64);
346 if (b && src->offset > ui64)
347 i64 = gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX, src->offset,
350 i64 = GST_FORMAT_PERCENT_MAX;
352 gst_query_set_position (query, GST_FORMAT_PERCENT, i64);
362 case GST_QUERY_DURATION:
366 gst_query_parse_duration (query, &format, NULL);
368 case GST_FORMAT_DEFAULT:
369 case GST_FORMAT_BYTES:
375 b = gst_base_src_get_size (src, &ui64);
376 /* better to make get_size take an int64 */
377 i64 = b ? (gint64) ui64 : -1;
378 gst_query_set_duration (query, GST_FORMAT_BYTES, i64);
382 case GST_FORMAT_PERCENT:
383 gst_query_set_duration (query, GST_FORMAT_PERCENT,
384 GST_FORMAT_PERCENT_MAX);
394 case GST_QUERY_SEEKING:
395 gst_query_set_seeking (query, GST_FORMAT_BYTES,
396 src->seekable, 0, src->size);
400 case GST_QUERY_SEGMENT:
404 start = src->segment_start;
405 /* no end segment configured, current size then */
406 if ((stop = src->segment_end) == -1)
409 /* FIXME, we can't report our rate as we did not store it, d'oh!.
410 * Also, subclasses might want to support other formats. */
411 gst_query_set_segment (query, 1.0, GST_FORMAT_BYTES, start, stop);
416 case GST_QUERY_FORMATS:
417 gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
418 GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
422 case GST_QUERY_LATENCY:
423 case GST_QUERY_JITTER:
425 case GST_QUERY_CONVERT:
427 res = gst_pad_query_default (pad, query);
431 gst_object_unref (src);
436 gst_base_src_default_newsegment (GstBaseSrc * src)
440 GST_DEBUG_OBJECT (src, "Sending newsegment from %" G_GINT64_FORMAT
441 " to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
443 event = gst_event_new_newsegment (FALSE, 1.0,
444 GST_FORMAT_BYTES, src->segment_start, src->segment_end,
447 return gst_pad_push_event (src->srcpad, event);
451 gst_base_src_newsegment (GstBaseSrc * src)
453 GstBaseSrcClass *bclass;
454 gboolean result = FALSE;
456 bclass = GST_BASE_SRC_GET_CLASS (src);
458 if (bclass->newsegment)
459 result = bclass->newsegment (src);
464 /* based on the event parameters configure the segment_start/stop
465 * times. Called with STREAM_LOCK.
468 gst_base_src_configure_segment (GstBaseSrc * src, GstEvent * event)
473 GstSeekType cur_type, stop_type;
475 gboolean update_stop, update_start;
477 gst_event_parse_seek (event, &rate, &format, &flags,
478 &cur_type, &cur, &stop_type, &stop);
480 /* parse the loop flag */
481 /* FIXME, need to store other flags and rate too */
482 src->segment_loop = (flags & GST_SEEK_FLAG_SEGMENT) != 0;
484 /* assume we'll update both start and stop values */
488 /* perform the seek, segment_start is never invalid */
490 case GST_SEEK_TYPE_NONE:
491 /* no update to segment */
492 cur = src->segment_start;
493 update_start = FALSE;
495 case GST_SEEK_TYPE_SET:
496 /* cur holds desired position */
498 case GST_SEEK_TYPE_CUR:
499 /* add cur to currently configure segment */
500 cur = src->segment_start + cur;
502 case GST_SEEK_TYPE_END:
503 /* add cur to total length */
504 cur = src->size + cur;
507 /* bring in sane range */
509 cur = CLAMP (cur, 0, src->size);
513 /* segment_end can be -1 if we have not configured a stop. */
515 case GST_SEEK_TYPE_NONE:
516 stop = src->segment_end;
519 case GST_SEEK_TYPE_SET:
520 /* stop folds required value */
522 case GST_SEEK_TYPE_CUR:
523 if (src->segment_end != -1)
524 stop = src->segment_end + stop;
528 case GST_SEEK_TYPE_END:
530 stop = src->size + stop;
536 /* if we have a valid stop time, make sure it is clipped */
539 stop = CLAMP (stop, 0, src->size);
541 stop = MAX (stop, 0);
544 src->segment_start = cur;
545 src->segment_end = stop;
547 /* update our offset if it was updated */
551 GST_DEBUG_OBJECT (src, "segment configured from %" G_GINT64_FORMAT
552 " to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
557 /* this code implements the seeking. It is a good example
558 * handling all cases (modulo the FIXMEs).
560 * A seek updates the currently configured segment_start
561 * and segment_stop values based on the SEEK_TYPE. If the
562 * segment_start value is updated, a seek to this new position
563 * should be performed.
565 * The seek can only be executed when we are not currently
566 * streaming any data, to make sure that this is the case, we
567 * acquire the STREAM_LOCK which is taken when we are in the
568 * _loop() function or when a getrange() is called. Normally
569 * we will not receive a seek if we are operating in pull mode
572 * When we are in the loop() function, we might be in the middle
573 * of pushing a buffer, which might block in a sink. To make sure
574 * that the push gets unblocked we push out a FLUSH_START event.
575 * Our loop function will get a WRONG_STATE return value from
576 * the push and will pause, effectively releasing the STREAM_LOCK.
578 * For a non-flushing seek, we pause the task, which might eventually
579 * release the STREAM_LOCK. We say eventually because when the sink
580 * blocks on the sample we might wait a very long time until the sink
581 * unblocks the sample. In any case we acquire the STREAM_LOCK and
582 * can continue the seek. A non-flushing seek is normally done in a
583 * running pipeline to perform seamless playback.
585 * After updating the segment_start/stop values, we prepare for
586 * streaming again. We push out a FLUSH_STOP to make the peer pad
587 * accept data again and we start our task again.
589 * A segment seek posts a message on the bus saying that the playback
590 * of the segment started. We store the segment flag internally because
591 * when we reach the segment_stop we have to post a segment_done
592 * instead of EOS when doing a segment seek.
595 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
602 gst_event_parse_seek (event, &rate, &format, &flags, NULL, NULL, NULL, NULL);
604 /* FIXME subclasses should be able to provide other formats */
605 /* get seek format */
606 if (format == GST_FORMAT_DEFAULT)
607 format = GST_FORMAT_BYTES;
608 /* we can only seek bytes */
609 if (format != GST_FORMAT_BYTES)
610 goto unsupported_seek;
612 flush = flags & GST_SEEK_FLAG_FLUSH;
614 /* send flush start */
616 gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
618 gst_pad_pause_task (src->srcpad);
620 /* unblock streaming thread */
621 gst_base_src_unlock (src);
623 /* grab streaming lock, this should eventually be possible, either
624 * because the task is paused or out streaming thread stopped
625 * because our peer is flushing. */
626 GST_STREAM_LOCK (src->srcpad);
628 /* now configure the segment */
629 gst_base_src_configure_segment (src, event);
631 /* and prepare to continue streaming */
633 /* send flush stop, peer will accept data and events again. We
634 * are not yet providing data as we still have the STREAM_LOCK. */
635 gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
637 /* now make sure the newsegment will be send from the streaming
638 * thread. We could opt to send it here too. */
639 src->need_newsegment = TRUE;
641 if (src->segment_loop) {
642 /* FIXME subclasses should be able to provide other formats */
643 gst_element_post_message (GST_ELEMENT (src),
644 gst_message_new_segment_start (GST_OBJECT (src), GST_FORMAT_BYTES,
645 src->segment_start));
648 /* and restart the task in case it got paused explicitely or by
649 * the FLUSH_START event we pushed out. */
650 gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
653 /* and release the lock again so we can continue streaming */
654 GST_STREAM_UNLOCK (src->srcpad);
661 GST_DEBUG_OBJECT (src, "invalid format, seek aborted.");
667 /* all events send to this element directly
670 gst_base_src_send_event (GstElement * element, GstEvent * event)
675 src = GST_BASE_SRC (element);
677 switch (GST_EVENT_TYPE (event)) {
679 result = gst_base_src_configure_segment (src, event);
690 gst_base_src_event_handler (GstPad * pad, GstEvent * event)
693 GstBaseSrcClass *bclass;
696 src = GST_BASE_SRC (gst_pad_get_parent (pad));
697 bclass = GST_BASE_SRC_GET_CLASS (src);
700 if (!(result = bclass->event (src, event)))
701 goto subclass_failed;
704 switch (GST_EVENT_TYPE (event)) {
706 /* is normally called when in push mode */
710 result = gst_base_src_do_seek (src, event);
712 case GST_EVENT_FLUSH_START:
713 /* cancel any blocking getrange, is normally called
714 * when in pull mode. */
715 result = gst_base_src_unlock (src);
717 case GST_EVENT_FLUSH_STOP:
722 gst_event_unref (event);
723 gst_object_unref (src);
730 GST_DEBUG_OBJECT (src, "subclass refused event");
731 gst_object_unref (src);
732 gst_event_unref (event);
737 GST_DEBUG_OBJECT (src, "is not seekable");
738 gst_object_unref (src);
739 gst_event_unref (event);
745 gst_base_src_set_property (GObject * object, guint prop_id,
746 const GValue * value, GParamSpec * pspec)
750 src = GST_BASE_SRC (object);
754 src->blocksize = g_value_get_ulong (value);
756 case PROP_NUM_BUFFERS:
757 src->num_buffers = g_value_get_int (value);
760 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
766 gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
771 src = GST_BASE_SRC (object);
775 g_value_set_ulong (value, src->blocksize);
777 case PROP_NUM_BUFFERS:
778 g_value_set_int (value, src->num_buffers);
781 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
786 /* with STREAM_LOCK and LOCK*/
787 static GstClockReturn
788 gst_base_src_wait (GstBaseSrc * basesrc, GstClockTime time)
794 if ((clock = GST_ELEMENT_CLOCK (basesrc)) == NULL)
797 /* clock_id should be NULL outside of this function */
798 g_assert (basesrc->clock_id == NULL);
799 g_assert (GST_CLOCK_TIME_IS_VALID (time));
801 id = gst_clock_new_single_shot_id (clock, time);
803 basesrc->clock_id = id;
804 /* release the object lock while waiting */
805 GST_UNLOCK (basesrc);
807 ret = gst_clock_id_wait (id, NULL);
810 gst_clock_id_unref (id);
811 basesrc->clock_id = NULL;
817 /* perform synchronisation on a buffer
819 static GstClockReturn
820 gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
822 GstClockReturn result = GST_CLOCK_OK;
823 GstClockTime start, end;
824 GstBaseSrcClass *bclass;
825 gboolean start_valid;
826 GstClockTime base_time;
828 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
831 if (bclass->get_times)
832 bclass->get_times (basesrc, buffer, &start, &end);
834 start_valid = GST_CLOCK_TIME_IS_VALID (start);
836 /* if we don't have a timestamp, we don't sync */
838 GST_DEBUG_OBJECT (basesrc, "get_times returned invalid start");
842 GST_DEBUG_OBJECT (basesrc, "got times start: %" GST_TIME_FORMAT
843 ", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
845 /* now do clocking */
847 base_time = GST_ELEMENT_CAST (basesrc)->base_time;
849 GST_LOG_OBJECT (basesrc,
850 "waiting for clock, base time %" GST_TIME_FORMAT
851 ", stream_start %" GST_TIME_FORMAT,
852 GST_TIME_ARGS (base_time), GST_TIME_ARGS (start));
854 result = gst_base_src_wait (basesrc, start + base_time);
855 GST_UNLOCK (basesrc);
857 GST_LOG_OBJECT (basesrc, "clock entry done: %d", result);
865 gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
869 GstBaseSrcClass *bclass;
871 GstClockReturn status;
873 bclass = GST_BASE_SRC_GET_CLASS (src);
877 while (!src->live_running) {
878 GST_DEBUG ("live source signal waiting");
879 GST_LIVE_SIGNAL (src);
880 GST_DEBUG ("live source waiting for running state");
882 GST_DEBUG ("live source unlocked");
884 /* FIXME, use another variable to signal stopping */
885 GST_LOCK (src->srcpad);
886 if (GST_PAD_IS_FLUSHING (src->srcpad))
888 GST_UNLOCK (src->srcpad);
890 GST_LIVE_UNLOCK (src);
892 if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED))
895 if (G_UNLIKELY (!bclass->create))
898 /* the max amount of bytes to read is the total size or
899 * up to the segment_end if present. */
900 if (src->segment_end != -1)
901 maxsize = MIN (src->size, src->segment_end);
905 GST_DEBUG_OBJECT (src,
906 "reading offset %" G_GUINT64_FORMAT ", length %u, size %" G_GINT64_FORMAT
907 ", segment_end %" G_GINT64_FORMAT ", maxsize %" G_GINT64_FORMAT, offset,
908 length, src->size, src->segment_end, maxsize);
912 if (offset > maxsize)
913 goto unexpected_length;
915 if (offset + length > maxsize) {
916 /* see if length of the file changed */
917 if (bclass->get_size)
918 bclass->get_size (src, &src->size);
920 if (src->segment_end != -1)
921 maxsize = MIN (src->size, src->segment_end);
925 if (offset + length > maxsize) {
926 length = maxsize - offset;
931 goto unexpected_length;
933 if (src->num_buffers_left == 0) {
934 goto reached_num_buffers;
936 if (src->num_buffers_left > 0)
937 src->num_buffers_left--;
940 ret = bclass->create (src, offset, length, buf);
941 if (ret != GST_FLOW_OK)
944 /* now sync before pushing the buffer */
945 status = gst_base_src_do_sync (src, *buf);
947 case GST_CLOCK_EARLY:
948 GST_DEBUG_OBJECT (src, "buffer too late!, returning anyway");
951 GST_DEBUG_OBJECT (src, "buffer ok");
954 GST_DEBUG_OBJECT (src, "clock returned %d, not returning", status);
955 gst_buffer_unref (*buf);
957 ret = GST_FLOW_WRONG_STATE;
966 GST_DEBUG_OBJECT (src, "pad is flushing");
967 GST_UNLOCK (src->srcpad);
968 GST_LIVE_UNLOCK (src);
969 return GST_FLOW_WRONG_STATE;
973 GST_DEBUG_OBJECT (src, "getrange but not started");
974 return GST_FLOW_WRONG_STATE;
978 GST_DEBUG_OBJECT (src, "no create function");
979 return GST_FLOW_ERROR;
983 GST_DEBUG_OBJECT (src, "unexpected length %u (offset=%" G_GUINT64_FORMAT
984 ", size=%" G_GUINT64_FORMAT ")", length, offset, src->size);
985 return GST_FLOW_UNEXPECTED;
989 GST_DEBUG_OBJECT (src, "sent all buffers");
990 return GST_FLOW_UNEXPECTED;
995 gst_base_src_pad_get_range (GstPad * pad, guint64 offset, guint length,
1001 src = GST_BASE_SRC (gst_pad_get_parent (pad));
1003 res = gst_base_src_get_range (src, offset, length, buf);
1005 gst_object_unref (src);
1011 gst_base_src_check_get_range (GstPad * pad)
1015 src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1017 if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
1018 gst_base_src_start (src);
1019 gst_base_src_stop (src);
1022 return src->seekable;
1026 gst_base_src_loop (GstPad * pad)
1029 GstBuffer *buf = NULL;
1032 src = GST_BASE_SRC (gst_pad_get_parent (pad));
1034 /* only send segments when operating in push mode */
1035 if (G_UNLIKELY (src->need_newsegment)) {
1036 /* now send newsegment */
1037 gst_base_src_newsegment (src);
1038 src->need_newsegment = FALSE;
1041 ret = gst_base_src_get_range (src, src->offset, src->blocksize, &buf);
1042 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1043 if (ret == GST_FLOW_UNEXPECTED)
1048 if (G_UNLIKELY (buf == NULL))
1051 src->offset += GST_BUFFER_SIZE (buf);
1053 ret = gst_pad_push (pad, buf);
1054 if (G_UNLIKELY (ret != GST_FLOW_OK))
1057 gst_object_unref (src);
1063 GST_DEBUG_OBJECT (src, "going to EOS, getrange returned UNEXPECTED");
1064 gst_pad_pause_task (pad);
1065 if (src->segment_loop) {
1066 /* FIXME, subclass might want to use another format */
1067 gst_element_post_message (GST_ELEMENT (src),
1068 gst_message_new_segment_done (GST_OBJECT (src),
1069 GST_FORMAT_BYTES, src->segment_end));
1071 gst_pad_push_event (pad, gst_event_new_eos ());
1074 gst_object_unref (src);
1079 const gchar *reason = gst_flow_get_name (ret);
1081 GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
1082 gst_pad_pause_task (pad);
1083 if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
1084 /* for fatal errors we post an error message */
1085 GST_ELEMENT_ERROR (src, STREAM, FAILED,
1086 (_("Internal data flow error.")),
1087 ("streaming task paused, reason %s", reason));
1088 gst_pad_push_event (pad, gst_event_new_eos ());
1090 gst_object_unref (src);
1095 GST_ELEMENT_ERROR (src, STREAM, FAILED,
1096 (_("Internal data flow error.")), ("element returned NULL buffer"));
1097 gst_pad_pause_task (pad);
1098 gst_pad_push_event (pad, gst_event_new_eos ());
1100 gst_object_unref (src);
1105 /* this will always be called between start() and stop(). So you can rely on
1106 resources allocated by start() and freed from stop(). This needs to be added
1107 to the docs at some point. */
1109 gst_base_src_unlock (GstBaseSrc * basesrc)
1111 GstBaseSrcClass *bclass;
1112 gboolean result = TRUE;
1114 GST_DEBUG ("unlock");
1115 /* unblock whatever the subclass is doing */
1116 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1118 result = bclass->unlock (basesrc);
1120 GST_DEBUG ("unschedule clock");
1121 /* and unblock the clock as well, if any */
1123 if (basesrc->clock_id) {
1124 gst_clock_id_unschedule (basesrc->clock_id);
1126 GST_UNLOCK (basesrc);
1128 GST_DEBUG ("unlock done");
1134 gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size)
1136 GstBaseSrcClass *bclass;
1137 gboolean result = FALSE;
1139 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1140 if (bclass->get_size)
1141 result = bclass->get_size (basesrc, size);
1144 basesrc->size = *size;
1150 gst_base_src_is_seekable (GstBaseSrc * basesrc)
1152 GstBaseSrcClass *bclass;
1154 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1156 /* check if we can seek */
1157 if (bclass->is_seekable)
1158 basesrc->seekable = bclass->is_seekable (basesrc);
1160 basesrc->seekable = FALSE;
1162 GST_DEBUG_OBJECT (basesrc, "is seekable: %d", basesrc->seekable);
1164 return basesrc->seekable;
1167 /* default negotiation code */
1169 gst_base_src_default_negotiate (GstBaseSrc * basesrc)
1172 GstCaps *caps = NULL;
1173 GstCaps *peercaps = NULL;
1174 gboolean result = FALSE;
1176 /* first see what is possible on our source pad */
1177 thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));
1178 GST_DEBUG ("caps of src: %" GST_PTR_FORMAT, thiscaps);
1179 /* nothing or anything is allowed, we're done */
1180 if (thiscaps == NULL || gst_caps_is_any (thiscaps))
1181 goto no_nego_needed;
1183 /* get the peer caps */
1184 peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
1185 GST_DEBUG ("caps of peer: %" GST_PTR_FORMAT, peercaps);
1189 /* get intersection */
1190 icaps = gst_caps_intersect (thiscaps, peercaps);
1191 GST_DEBUG ("intersect: %" GST_PTR_FORMAT, icaps);
1192 gst_caps_unref (thiscaps);
1193 gst_caps_unref (peercaps);
1195 /* take first (and best) possibility */
1196 caps = gst_caps_copy_nth (icaps, 0);
1197 gst_caps_unref (icaps);
1200 /* no peer, work with our own caps then */
1204 caps = gst_caps_make_writable (caps);
1205 gst_caps_truncate (caps);
1208 gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
1209 GST_DEBUG ("fixated to: %" GST_PTR_FORMAT, caps);
1211 if (gst_caps_is_any (caps)) {
1212 /* hmm, still anything, so element can do anything and
1213 * nego is not needed */
1214 gst_caps_unref (caps);
1216 } else if (gst_caps_is_fixed (caps)) {
1217 /* yay, fixed caps, use those then */
1218 gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
1219 gst_caps_unref (caps);
1227 GST_DEBUG ("no negotiation needed");
1229 gst_caps_unref (thiscaps);
1235 gst_base_src_negotiate (GstBaseSrc * basesrc)
1237 GstBaseSrcClass *bclass;
1238 gboolean result = TRUE;
1240 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1242 if (bclass->negotiate)
1243 result = bclass->negotiate (basesrc);
1249 gst_base_src_start (GstBaseSrc * basesrc)
1251 GstBaseSrcClass *bclass;
1254 if (GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
1257 GST_DEBUG_OBJECT (basesrc, "starting source");
1259 basesrc->num_buffers_left = basesrc->num_buffers;
1261 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1263 result = bclass->start (basesrc);
1268 goto could_not_start;
1270 GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_STARTED);
1272 /* figure out the size */
1273 if (bclass->get_size) {
1274 result = bclass->get_size (basesrc, &basesrc->size);
1275 if (result == FALSE)
1282 GST_DEBUG ("size %d %lld", result, basesrc->size);
1284 /* check if we can seek, updates ->seekable */
1285 gst_base_src_is_seekable (basesrc);
1287 basesrc->need_newsegment = TRUE;
1291 if (basesrc->seekable) {
1294 caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
1295 gst_pad_set_caps (basesrc->srcpad, caps);
1296 gst_caps_unref (caps);
1300 if (!gst_base_src_negotiate (basesrc))
1301 goto could_not_negotiate;
1308 GST_DEBUG_OBJECT (basesrc, "could not start");
1311 could_not_negotiate:
1313 GST_DEBUG_OBJECT (basesrc, "could not negotiate, stopping");
1314 GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
1315 ("Could not connect source to pipeline"),
1316 ("Check your filtered caps, if any"));
1317 gst_base_src_stop (basesrc);
1323 gst_base_src_stop (GstBaseSrc * basesrc)
1325 GstBaseSrcClass *bclass;
1326 gboolean result = TRUE;
1328 if (!GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
1331 GST_DEBUG_OBJECT (basesrc, "stopping source");
1333 bclass = GST_BASE_SRC_GET_CLASS (basesrc);
1335 result = bclass->stop (basesrc);
1338 GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
1344 gst_base_src_deactivate (GstBaseSrc * basesrc, GstPad * pad)
1348 GST_LIVE_LOCK (basesrc);
1349 basesrc->live_running = TRUE;
1350 GST_LIVE_SIGNAL (basesrc);
1351 GST_LIVE_UNLOCK (basesrc);
1353 /* step 1, unblock clock sync (if any) */
1354 result = gst_base_src_unlock (basesrc);
1356 /* step 2, make sure streaming finishes */
1357 result &= gst_pad_stop_task (pad);
1363 gst_base_src_activate_push (GstPad * pad, gboolean active)
1365 GstBaseSrc *basesrc;
1368 basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1370 /* prepare subclass first */
1372 GST_DEBUG_OBJECT (basesrc, "Activating in push mode");
1374 if (!basesrc->can_activate_push)
1375 goto no_push_activation;
1377 if (!gst_base_src_start (basesrc))
1380 res = gst_pad_start_task (pad, (GstTaskFunction) gst_base_src_loop, pad);
1382 GST_DEBUG_OBJECT (basesrc, "Deactivating in push mode");
1383 res = gst_base_src_deactivate (basesrc, pad);
1390 GST_DEBUG_OBJECT (basesrc, "Subclass disabled push-mode activation");
1395 gst_base_src_stop (basesrc);
1396 GST_DEBUG_OBJECT (basesrc, "Failed to start in push mode");
1402 gst_base_src_activate_pull (GstPad * pad, gboolean active)
1404 GstBaseSrc *basesrc;
1406 basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1408 /* prepare subclass first */
1410 GST_DEBUG_OBJECT (basesrc, "Activating in pull mode");
1411 if (!gst_base_src_start (basesrc))
1414 if (!basesrc->seekable) {
1415 gst_base_src_stop (basesrc);
1421 GST_DEBUG_OBJECT (basesrc, "Deactivating in pull mode");
1423 if (!gst_base_src_stop (basesrc))
1426 return gst_base_src_deactivate (basesrc, pad);
1431 gst_base_src_stop (basesrc);
1432 GST_DEBUG_OBJECT (basesrc, "Failed to start in pull mode");
1437 GST_DEBUG_OBJECT (basesrc, "Failed to stop in pull mode");
1442 static GstStateChangeReturn
1443 gst_base_src_change_state (GstElement * element, GstStateChange transition)
1445 GstBaseSrc *basesrc;
1446 GstStateChangeReturn result;
1447 gboolean no_preroll = FALSE;
1449 basesrc = GST_BASE_SRC (element);
1451 switch (transition) {
1452 case GST_STATE_CHANGE_NULL_TO_READY:
1454 case GST_STATE_CHANGE_READY_TO_PAUSED:
1455 GST_LIVE_LOCK (element);
1456 if (basesrc->is_live) {
1458 basesrc->live_running = FALSE;
1460 GST_LIVE_UNLOCK (element);
1462 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1463 GST_LIVE_LOCK (element);
1464 if (basesrc->is_live) {
1465 basesrc->live_running = TRUE;
1466 GST_LIVE_SIGNAL (element);
1468 GST_LIVE_UNLOCK (element);
1475 GST_ELEMENT_CLASS (parent_class)->change_state (element,
1476 transition)) == GST_STATE_CHANGE_FAILURE)
1479 switch (transition) {
1480 case GST_STATE_CHANGE_NULL_TO_READY:
1481 /* we always run from start to end when in READY, after putting
1482 * the element to READY a seek can be done on the element to
1483 * configure the segment when going to PAUSED. */
1484 basesrc->segment_loop = FALSE;
1485 basesrc->segment_start = 0;
1486 basesrc->segment_end = -1;
1487 basesrc->offset = 0;
1489 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1490 GST_LIVE_LOCK (element);
1491 if (basesrc->is_live) {
1493 basesrc->live_running = FALSE;
1495 GST_LIVE_UNLOCK (element);
1497 case GST_STATE_CHANGE_PAUSED_TO_READY:
1498 if (!gst_base_src_stop (basesrc))
1500 /* we always run from start to end when in READY */
1501 basesrc->segment_loop = FALSE;
1502 basesrc->segment_start = 0;
1503 basesrc->segment_end = -1;
1504 basesrc->offset = 0;
1506 case GST_STATE_CHANGE_READY_TO_NULL:
1512 if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)
1513 result = GST_STATE_CHANGE_NO_PREROLL;
1520 GST_DEBUG_OBJECT (basesrc, "parent failed state change");
1521 gst_base_src_stop (basesrc);
1526 GST_DEBUG_OBJECT (basesrc, "Failed to stop");
1527 return GST_STATE_CHANGE_FAILURE;