gst/: API change fix.
[platform/upstream/gstreamer.git] / libs / gst / base / gstbasesrc.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *               2000,2005 Wim Taymans <wim@fluendo.com>
4  *
5  * gstbasesrc.c:
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 /**
24  * SECTION:gstbasesrc
25  * @short_description: Base class for getrange based source elements
26  * @see_also: #GstBaseTransform, #GstBaseSink
27  *
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
31  * to TRUE.
32  *
33  * <itemizedlist>
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>
40  * </itemizedlist>
41  */
42
43 #include <stdlib.h>
44 #include <string.h>
45
46 #ifdef HAVE_CONFIG_H
47 #  include "config.h"
48 #endif
49
50 #include "gstbasesrc.h"
51 #include "gsttypefindhelper.h"
52 #include <gst/gstmarshal.h>
53
54 #define DEFAULT_BLOCKSIZE       4096
55 #define DEFAULT_NUM_BUFFERS     -1
56
57 GST_DEBUG_CATEGORY_STATIC (gst_base_src_debug);
58 #define GST_CAT_DEFAULT gst_base_src_debug
59
60 /* BaseSrc signals and args */
61 enum
62 {
63   /* FILL ME */
64   LAST_SIGNAL
65 };
66
67 enum
68 {
69   PROP_0,
70   PROP_BLOCKSIZE,
71   PROP_NUM_BUFFERS,
72 };
73
74 static GstElementClass *parent_class = NULL;
75
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);
80
81
82 GType
83 gst_base_src_get_type (void)
84 {
85   static GType base_src_type = 0;
86
87   if (!base_src_type) {
88     static const GTypeInfo base_src_info = {
89       sizeof (GstBaseSrcClass),
90       (GBaseInitFunc) gst_base_src_base_init,
91       NULL,
92       (GClassInitFunc) gst_base_src_class_init,
93       NULL,
94       NULL,
95       sizeof (GstBaseSrc),
96       0,
97       (GInstanceInitFunc) gst_base_src_init,
98     };
99
100     base_src_type = g_type_register_static (GST_TYPE_ELEMENT,
101         "GstBaseSrc", &base_src_info, G_TYPE_FLAG_ABSTRACT);
102   }
103   return base_src_type;
104 }
105 static GstCaps *gst_base_src_getcaps (GstPad * pad);
106 static gboolean gst_base_src_setcaps (GstPad * pad, GstCaps * caps);
107
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);
115
116 static gboolean gst_base_src_query (GstPad * pad, GstQuery * query);
117
118 static gboolean gst_base_src_default_negotiate (GstBaseSrc * basesrc);
119 static gboolean gst_base_src_default_newsegment (GstBaseSrc * src);
120
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);
125
126 static GstStateChangeReturn gst_base_src_change_state (GstElement * element,
127     GstStateChange transition);
128
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);
133
134 static void
135 gst_base_src_base_init (gpointer g_class)
136 {
137   GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
138 }
139
140 static void
141 gst_base_src_class_init (GstBaseSrcClass * klass)
142 {
143   GObjectClass *gobject_class;
144   GstElementClass *gstelement_class;
145
146   gobject_class = (GObjectClass *) klass;
147   gstelement_class = (GstElementClass *) klass;
148
149   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
150
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);
154
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,
158           G_PARAM_READWRITE));
159
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));
164
165   gstelement_class->change_state =
166       GST_DEBUG_FUNCPTR (gst_base_src_change_state);
167
168   klass->negotiate = gst_base_src_default_negotiate;
169   klass->newsegment = gst_base_src_default_newsegment;
170 }
171
172 static void
173 gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
174 {
175   GstPad *pad;
176   GstPadTemplate *pad_template;
177
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;
183
184   basesrc->can_activate_push = TRUE;
185   basesrc->pad_mode = GST_ACTIVATE_NONE;
186
187   pad_template =
188       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
189   g_return_if_fail (pad_template != NULL);
190
191   GST_DEBUG_OBJECT (basesrc, "creating src pad");
192   pad = gst_pad_new_from_template (pad_template, "src");
193
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));
208
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);
213
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;
219
220   GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
221
222   GST_DEBUG_OBJECT (basesrc, "init done");
223 }
224
225 static void
226 gst_base_src_finalize (GObject * object)
227 {
228   GstBaseSrc *basesrc;
229
230   basesrc = GST_BASE_SRC (object);
231
232   g_mutex_free (basesrc->live_lock);
233   g_cond_free (basesrc->live_cond);
234
235   G_OBJECT_CLASS (parent_class)->finalize (object);
236 }
237
238 /**
239  * gst_base_src_set_live:
240  * @src: base source instance
241  * @live: new live-mode
242  *
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.
245  */
246 void
247 gst_base_src_set_live (GstBaseSrc * src, gboolean live)
248 {
249   GST_LIVE_LOCK (src);
250   src->is_live = live;
251   GST_LIVE_UNLOCK (src);
252 }
253
254 /**
255  * gst_base_src_is_live:
256  * @src: base source instance
257  *
258  * Check if an element is in live mode.
259  *
260  * Returns: %TRUE if element is in live mode.
261  */
262 gboolean
263 gst_base_src_is_live (GstBaseSrc * src)
264 {
265   gboolean result;
266
267   GST_LIVE_LOCK (src);
268   result = src->is_live;
269   GST_LIVE_UNLOCK (src);
270
271   return result;
272 }
273
274 static gboolean
275 gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
276 {
277   GstBaseSrcClass *bclass;
278   GstBaseSrc *bsrc;
279   gboolean res = TRUE;
280
281   bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
282   bclass = GST_BASE_SRC_GET_CLASS (bsrc);
283
284   if (bclass->set_caps)
285     res = bclass->set_caps (bsrc, caps);
286
287   return res;
288 }
289
290 static GstCaps *
291 gst_base_src_getcaps (GstPad * pad)
292 {
293   GstBaseSrcClass *bclass;
294   GstBaseSrc *bsrc;
295   GstCaps *caps = NULL;
296
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);
301
302   if (caps == NULL) {
303     GstPadTemplate *pad_template;
304
305     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));
309     }
310   }
311   return caps;
312 }
313
314 static gboolean
315 gst_base_src_query (GstPad * pad, GstQuery * query)
316 {
317   gboolean b;
318   guint64 ui64;
319   gint64 i64;
320   GstBaseSrc *src;
321
322   src = GST_BASE_SRC (GST_PAD_PARENT (pad));
323
324   switch (GST_QUERY_TYPE (query)) {
325     case GST_QUERY_POSITION:
326     {
327       GstFormat format;
328
329       gst_query_parse_position (query, &format, NULL);
330       switch (format) {
331         case GST_FORMAT_DEFAULT:
332         case GST_FORMAT_BYTES:
333           gst_query_set_position (query, GST_FORMAT_BYTES, src->offset);
334           return TRUE;
335         case GST_FORMAT_PERCENT:
336           b = gst_base_src_get_size (src, &ui64);
337           i64 = GST_FORMAT_PERCENT_MAX;
338           if (b)
339             i64 *= gst_guint64_to_gdouble (src->offset)
340                 / gst_guint64_to_gdouble (ui64);
341           gst_query_set_position (query, GST_FORMAT_PERCENT, i64);
342           return TRUE;
343         default:
344           return FALSE;
345       }
346     }
347     case GST_QUERY_DURATION:
348     {
349       GstFormat format;
350
351       gst_query_parse_duration (query, &format, NULL);
352       switch (format) {
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);
359           return TRUE;
360         case GST_FORMAT_PERCENT:
361           gst_query_set_duration (query, GST_FORMAT_PERCENT,
362               GST_FORMAT_PERCENT_MAX);
363           return TRUE;
364         default:
365           return FALSE;
366       }
367     }
368
369     case GST_QUERY_SEEKING:
370       gst_query_set_seeking (query, GST_FORMAT_BYTES,
371           src->seekable, src->segment_start, src->segment_end);
372       return TRUE;
373
374     case GST_QUERY_FORMATS:
375       gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
376           GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
377       return TRUE;
378
379     case GST_QUERY_LATENCY:
380     case GST_QUERY_JITTER:
381     case GST_QUERY_RATE:
382     case GST_QUERY_CONVERT:
383     default:
384       return gst_pad_query_default (pad, query);
385   }
386 }
387
388 static gboolean
389 gst_base_src_default_newsegment (GstBaseSrc * src)
390 {
391   GstEvent *event;
392
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,
397       GST_FORMAT_BYTES,
398       (gint64) src->segment_start, (gint64) src->segment_end, (gint64) 0);
399
400   return gst_pad_push_event (src->srcpad, event);
401 }
402
403 static gboolean
404 gst_base_src_newsegment (GstBaseSrc * src)
405 {
406   GstBaseSrcClass *bclass;
407   gboolean result = FALSE;
408
409   bclass = GST_BASE_SRC_GET_CLASS (src);
410
411   if (bclass->newsegment)
412     result = bclass->newsegment (src);
413
414   return result;
415 }
416
417 static gboolean
418 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
419 {
420   gdouble rate;
421   GstFormat format;
422   GstSeekFlags flags;
423   GstSeekType cur_type, stop_type;
424   gint64 cur, stop;
425
426   gst_event_parse_seek (event, &rate, &format, &flags,
427       &cur_type, &cur, &stop_type, &stop);
428
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)
434     return FALSE;
435
436   /* get seek positions */
437   src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
438
439   /* send flush start */
440   gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
441
442   /* unblock streaming thread */
443   gst_base_src_unlock (src);
444
445   /* grab streaming lock */
446   GST_STREAM_LOCK (src->srcpad);
447
448   /* send flush stop */
449   gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
450
451   /* perform the seek */
452   switch (cur_type) {
453     case GST_SEEK_TYPE_NONE:
454       break;
455     case GST_SEEK_TYPE_SET:
456       if (cur < 0)
457         goto error;
458       src->offset = MIN (cur, src->size);
459       src->segment_start = src->offset;
460       break;
461     case GST_SEEK_TYPE_CUR:
462       src->offset = CLAMP (src->offset + cur, 0, src->size);
463       src->segment_start = src->offset;
464       break;
465     case GST_SEEK_TYPE_END:
466       if (cur > 0)
467         goto error;
468       src->offset = MAX (0, src->size + cur);
469       src->segment_start = src->offset;
470       break;
471     default:
472       goto error;
473   }
474
475   switch (stop_type) {
476     case GST_SEEK_TYPE_NONE:
477       break;
478     case GST_SEEK_TYPE_SET:
479       if (stop < 0)
480         goto error;
481       src->segment_end = MIN (stop, src->size);
482       break;
483     case GST_SEEK_TYPE_CUR:
484       src->segment_end = CLAMP (src->segment_end + stop, 0, src->size);
485       break;
486     case GST_SEEK_TYPE_END:
487       if (stop > 0)
488         goto error;
489       src->segment_end = src->size + stop;
490       break;
491     default:
492       goto error;
493   }
494
495   GST_DEBUG_OBJECT (src, "seek pending for segment from %" G_GINT64_FORMAT
496       " to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
497
498   /* now make sure the newsegment will be send */
499   src->need_newsegment = TRUE;
500
501   /* and restart the task */
502   gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
503       src->srcpad);
504   GST_STREAM_UNLOCK (src->srcpad);
505
506   gst_event_unref (event);
507
508   return TRUE;
509
510   /* ERROR */
511 error:
512   {
513     GST_DEBUG_OBJECT (src, "seek error");
514     GST_STREAM_UNLOCK (src->srcpad);
515     gst_event_unref (event);
516     return FALSE;
517   }
518 }
519
520 static gboolean
521 gst_base_src_event_handler (GstPad * pad, GstEvent * event)
522 {
523   GstBaseSrc *src;
524   GstBaseSrcClass *bclass;
525   gboolean result;
526
527   src = GST_BASE_SRC (GST_PAD_PARENT (pad));
528   bclass = GST_BASE_SRC_GET_CLASS (src);
529
530   if (bclass->event)
531     result = bclass->event (src, event);
532
533   switch (GST_EVENT_TYPE (event)) {
534     case GST_EVENT_SEEK:
535       if (!src->seekable) {
536         gst_event_unref (event);
537         return FALSE;
538       }
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);
543       break;
544     case GST_EVENT_FLUSH_STOP:
545       break;
546     default:
547       break;
548   }
549   gst_event_unref (event);
550
551   return TRUE;
552 }
553
554 static void
555 gst_base_src_set_property (GObject * object, guint prop_id,
556     const GValue * value, GParamSpec * pspec)
557 {
558   GstBaseSrc *src;
559
560   src = GST_BASE_SRC (object);
561
562   switch (prop_id) {
563     case PROP_BLOCKSIZE:
564       src->blocksize = g_value_get_ulong (value);
565       break;
566     case PROP_NUM_BUFFERS:
567       src->num_buffers = g_value_get_int (value);
568       break;
569     default:
570       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
571       break;
572   }
573 }
574
575 static void
576 gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
577     GParamSpec * pspec)
578 {
579   GstBaseSrc *src;
580
581   src = GST_BASE_SRC (object);
582
583   switch (prop_id) {
584     case PROP_BLOCKSIZE:
585       g_value_set_ulong (value, src->blocksize);
586       break;
587     case PROP_NUM_BUFFERS:
588       g_value_set_int (value, src->num_buffers);
589       break;
590     default:
591       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
592       break;
593   }
594 }
595
596 static GstFlowReturn
597 gst_base_src_get_range (GstPad * pad, guint64 offset, guint length,
598     GstBuffer ** buf)
599 {
600   GstFlowReturn ret;
601   GstBaseSrc *src;
602   GstBaseSrcClass *bclass;
603
604   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
605   bclass = GST_BASE_SRC_GET_CLASS (src);
606
607   GST_LIVE_LOCK (src);
608   if (src->is_live) {
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");
613       GST_LIVE_WAIT (src);
614       GST_DEBUG ("live source unlocked");
615     }
616   }
617   GST_LIVE_UNLOCK (src);
618
619   GST_LOCK (pad);
620   if (GST_PAD_IS_FLUSHING (pad))
621     goto flushing;
622   GST_UNLOCK (pad);
623
624   if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED))
625     goto not_started;
626
627   if (!bclass->create)
628     goto no_function;
629
630   GST_DEBUG_OBJECT (src,
631       "reading offset %" G_GUINT64_FORMAT ", length %u, size %"
632       G_GINT64_FORMAT, offset, length, src->size);
633
634   /* check size */
635   if (src->size != -1) {
636     if (offset > src->size)
637       goto unexpected_length;
638
639     if (offset + length > src->size) {
640       if (bclass->get_size)
641         bclass->get_size (src, &src->size);
642
643       if (offset + length > src->size) {
644         length = src->size - offset;
645       }
646     }
647   }
648   if (length == 0)
649     goto unexpected_length;
650
651   if (src->num_buffers_left == 0) {
652     goto reached_num_buffers;
653   } else {
654     if (src->num_buffers_left > 0)
655       src->num_buffers_left--;
656   }
657
658   ret = bclass->create (src, offset, length, buf);
659
660   return ret;
661
662   /* ERROR */
663 flushing:
664   {
665     GST_DEBUG_OBJECT (src, "pad is flushing");
666     GST_UNLOCK (pad);
667     return GST_FLOW_WRONG_STATE;
668   }
669 not_started:
670   {
671     GST_DEBUG_OBJECT (src, "getrange but not started");
672     return GST_FLOW_WRONG_STATE;
673   }
674 no_function:
675   {
676     GST_DEBUG_OBJECT (src, "no create function");
677     return GST_FLOW_ERROR;
678   }
679 unexpected_length:
680   {
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;
684   }
685 reached_num_buffers:
686   {
687     GST_DEBUG_OBJECT (src, "sent all buffers");
688     return GST_FLOW_UNEXPECTED;
689   }
690 }
691
692 static gboolean
693 gst_base_src_check_get_range (GstPad * pad)
694 {
695   GstBaseSrc *src;
696
697   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
698
699   if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
700     gst_base_src_start (src);
701     gst_base_src_stop (src);
702   }
703
704   return src->seekable;
705 }
706
707 static void
708 gst_base_src_loop (GstPad * pad)
709 {
710   GstBaseSrc *src;
711   GstBuffer *buf = NULL;
712   GstFlowReturn ret;
713
714   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
715
716   if (src->need_newsegment) {
717     /* now send newsegment */
718     gst_base_src_newsegment (src);
719     src->need_newsegment = FALSE;
720   }
721
722   ret = gst_base_src_get_range (pad, src->offset, src->blocksize, &buf);
723   if (ret != GST_FLOW_OK)
724     goto eos;
725
726   if (buf == NULL)
727     goto error;
728
729   src->offset += GST_BUFFER_SIZE (buf);
730
731   ret = gst_pad_push (pad, buf);
732   if (ret != GST_FLOW_OK)
733     goto pause;
734
735   return;
736
737 eos:
738   {
739     GST_DEBUG_OBJECT (src, "going to EOS");
740     gst_pad_pause_task (pad);
741     gst_pad_push_event (pad, gst_event_new_eos ());
742     return;
743   }
744 pause:
745   {
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 ());
754     }
755     return;
756   }
757 error:
758   {
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 ());
764     return;
765   }
766 }
767
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. */
771 static gboolean
772 gst_base_src_unlock (GstBaseSrc * basesrc)
773 {
774   GstBaseSrcClass *bclass;
775   gboolean result = FALSE;
776
777   GST_DEBUG ("unlock");
778   /* unblock whatever the subclass is doing */
779   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
780   if (bclass->unlock)
781     result = bclass->unlock (basesrc);
782
783   GST_DEBUG ("unschedule clock");
784   /* and unblock the clock as well, if any */
785   GST_LOCK (basesrc);
786   if (basesrc->clock_id) {
787     gst_clock_id_unschedule (basesrc->clock_id);
788   }
789   GST_UNLOCK (basesrc);
790
791   GST_DEBUG ("unlock done");
792
793   return result;
794 }
795
796 static gboolean
797 gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size)
798 {
799   GstBaseSrcClass *bclass;
800   gboolean result = FALSE;
801
802   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
803   if (bclass->get_size)
804     result = bclass->get_size (basesrc, size);
805
806   if (result)
807     basesrc->size = *size;
808
809   return result;
810 }
811
812 static gboolean
813 gst_base_src_is_seekable (GstBaseSrc * basesrc)
814 {
815   GstBaseSrcClass *bclass;
816
817   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
818
819   /* check if we can seek */
820   if (bclass->is_seekable)
821     basesrc->seekable = bclass->is_seekable (basesrc);
822   else
823     basesrc->seekable = FALSE;
824
825   GST_DEBUG_OBJECT (basesrc, "is seekable: %d", basesrc->seekable);
826
827   return basesrc->seekable;
828 }
829
830 static gboolean
831 gst_base_src_default_negotiate (GstBaseSrc * basesrc)
832 {
833   GstCaps *thiscaps;
834   GstCaps *caps = NULL;
835   GstCaps *peercaps = NULL;
836   gboolean result = FALSE;
837
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))
841     goto no_nego_needed;
842
843   peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
844   GST_DEBUG ("caps of peer: %" GST_PTR_FORMAT, peercaps);
845   if (peercaps) {
846     GstCaps *icaps;
847
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);
852     if (icaps) {
853       caps = gst_caps_copy_nth (icaps, 0);
854       gst_caps_unref (icaps);
855     }
856   } else {
857     caps = thiscaps;
858   }
859   if (caps) {
860     caps = gst_caps_make_writable (caps);
861     gst_caps_truncate (caps);
862
863     gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
864     GST_DEBUG ("fixated to: %" GST_PTR_FORMAT, caps);
865
866     if (gst_caps_is_any (caps)) {
867       gst_caps_unref (caps);
868       result = TRUE;
869     } else if (gst_caps_is_fixed (caps)) {
870       gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
871       gst_caps_unref (caps);
872       result = TRUE;
873     }
874   }
875   return result;
876
877 no_nego_needed:
878   {
879     GST_DEBUG ("no negotiation needed");
880     if (thiscaps)
881       gst_caps_unref (thiscaps);
882     return TRUE;
883   }
884 }
885
886 static gboolean
887 gst_base_src_negotiate (GstBaseSrc * basesrc)
888 {
889   GstBaseSrcClass *bclass;
890   gboolean result = TRUE;
891
892   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
893
894   if (bclass->negotiate)
895     result = bclass->negotiate (basesrc);
896
897   return result;
898 }
899
900 static gboolean
901 gst_base_src_start (GstBaseSrc * basesrc)
902 {
903   GstBaseSrcClass *bclass;
904   gboolean result;
905
906   if (GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
907     return TRUE;
908
909   GST_DEBUG_OBJECT (basesrc, "starting source");
910
911   basesrc->num_buffers_left = basesrc->num_buffers;
912
913   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
914   if (bclass->start)
915     result = bclass->start (basesrc);
916   else
917     result = TRUE;
918
919   if (!result)
920     goto could_not_start;
921
922   GST_OBJECT_FLAG_SET (basesrc, GST_BASE_SRC_STARTED);
923
924   /* start in the beginning */
925   basesrc->offset = 0;
926
927   /* figure out the size */
928   if (bclass->get_size) {
929     result = bclass->get_size (basesrc, &basesrc->size);
930     if (result == FALSE)
931       basesrc->size = -1;
932   } else {
933     result = FALSE;
934     basesrc->size = -1;
935   }
936
937   GST_DEBUG ("size %d %lld", result, basesrc->size);
938
939   /* we always run to the end */
940   basesrc->segment_start = 0;
941   basesrc->segment_end = basesrc->size;
942   basesrc->need_newsegment = TRUE;
943
944   /* check if we can seek, updates ->seekable */
945   gst_base_src_is_seekable (basesrc);
946
947   /* run typefind */
948 #if 0
949   if (basesrc->seekable) {
950     GstCaps *caps;
951
952     caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
953     gst_pad_set_caps (basesrc->srcpad, caps);
954     gst_caps_unref (caps);
955   }
956 #endif
957
958   if (!gst_base_src_negotiate (basesrc))
959     goto could_not_negotiate;
960
961   return TRUE;
962
963   /* ERROR */
964 could_not_start:
965   {
966     GST_DEBUG_OBJECT (basesrc, "could not start");
967     return FALSE;
968   }
969 could_not_negotiate:
970   {
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);
976     return FALSE;
977   }
978 }
979
980 static gboolean
981 gst_base_src_stop (GstBaseSrc * basesrc)
982 {
983   GstBaseSrcClass *bclass;
984   gboolean result = TRUE;
985
986   if (!GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
987     return TRUE;
988
989   GST_DEBUG_OBJECT (basesrc, "stopping source");
990
991   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
992   if (bclass->stop)
993     result = bclass->stop (basesrc);
994
995   if (result)
996     GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
997
998   return result;
999 }
1000
1001 static gboolean
1002 gst_base_src_deactivate (GstBaseSrc * basesrc, GstPad * pad)
1003 {
1004   gboolean result;
1005
1006   GST_LIVE_LOCK (basesrc);
1007   basesrc->live_running = TRUE;
1008   GST_LIVE_SIGNAL (basesrc);
1009   GST_LIVE_UNLOCK (basesrc);
1010
1011   /* step 1, unblock clock sync (if any) */
1012   gst_base_src_unlock (basesrc);
1013
1014   /* step 2, make sure streaming finishes */
1015   result = gst_pad_stop_task (pad);
1016
1017   return result;
1018 }
1019
1020 static gboolean
1021 gst_base_src_activate_push (GstPad * pad, gboolean active)
1022 {
1023   GstBaseSrc *basesrc;
1024
1025   basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1026
1027   /* prepare subclass first */
1028   if (active) {
1029     GST_DEBUG_OBJECT (basesrc, "Activating in push mode");
1030
1031     if (!basesrc->can_activate_push)
1032       goto no_push_activation;
1033
1034     if (!gst_base_src_start (basesrc))
1035       goto error_start;
1036
1037     return gst_pad_start_task (pad, (GstTaskFunction) gst_base_src_loop, pad);
1038   } else {
1039     GST_DEBUG_OBJECT (basesrc, "Deactivating in push mode");
1040     return gst_base_src_deactivate (basesrc, pad);
1041   }
1042
1043 no_push_activation:
1044   {
1045     GST_DEBUG_OBJECT (basesrc, "Subclass disabled push-mode activation");
1046     return FALSE;
1047   }
1048 error_start:
1049   {
1050     gst_base_src_stop (basesrc);
1051     GST_DEBUG_OBJECT (basesrc, "Failed to start in push mode");
1052     return FALSE;
1053   }
1054 }
1055
1056 static gboolean
1057 gst_base_src_activate_pull (GstPad * pad, gboolean active)
1058 {
1059   GstBaseSrc *basesrc;
1060
1061   basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1062
1063   /* prepare subclass first */
1064   if (active) {
1065     GST_DEBUG_OBJECT (basesrc, "Activating in pull mode");
1066     if (!gst_base_src_start (basesrc))
1067       goto error_start;
1068
1069     if (!basesrc->seekable) {
1070       gst_base_src_stop (basesrc);
1071       return FALSE;
1072     }
1073
1074     return TRUE;
1075   } else {
1076     GST_DEBUG_OBJECT (basesrc, "Deactivating in pull mode");
1077
1078     if (!gst_base_src_stop (basesrc))
1079       goto error_stop;
1080
1081     return gst_base_src_deactivate (basesrc, pad);
1082   }
1083
1084 error_start:
1085   {
1086     gst_base_src_stop (basesrc);
1087     GST_DEBUG_OBJECT (basesrc, "Failed to start in pull mode");
1088     return FALSE;
1089   }
1090 error_stop:
1091   {
1092     GST_DEBUG_OBJECT (basesrc, "Failed to stop in pull mode");
1093     return FALSE;
1094   }
1095 }
1096
1097 static GstStateChangeReturn
1098 gst_base_src_change_state (GstElement * element, GstStateChange transition)
1099 {
1100   GstBaseSrc *basesrc;
1101   GstStateChangeReturn result;
1102   gboolean no_preroll = FALSE;
1103
1104   basesrc = GST_BASE_SRC (element);
1105
1106
1107   switch (transition) {
1108     case GST_STATE_CHANGE_NULL_TO_READY:
1109       break;
1110     case GST_STATE_CHANGE_READY_TO_PAUSED:
1111       GST_LIVE_LOCK (element);
1112       if (basesrc->is_live) {
1113         no_preroll = TRUE;
1114         basesrc->live_running = FALSE;
1115       }
1116       GST_LIVE_UNLOCK (element);
1117       break;
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);
1123       }
1124       GST_LIVE_UNLOCK (element);
1125       break;
1126     default:
1127       break;
1128   }
1129
1130   if ((result =
1131           GST_ELEMENT_CLASS (parent_class)->change_state (element,
1132               transition)) == GST_STATE_CHANGE_FAILURE)
1133     goto failure;
1134
1135   switch (transition) {
1136     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1137       GST_LIVE_LOCK (element);
1138       if (basesrc->is_live) {
1139         no_preroll = TRUE;
1140         basesrc->live_running = FALSE;
1141       }
1142       GST_LIVE_UNLOCK (element);
1143       break;
1144     case GST_STATE_CHANGE_PAUSED_TO_READY:
1145       if (!gst_base_src_stop (basesrc))
1146         result = GST_STATE_CHANGE_FAILURE;
1147       break;
1148     case GST_STATE_CHANGE_READY_TO_NULL:
1149       break;
1150     default:
1151       break;
1152   }
1153
1154   if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)
1155     return GST_STATE_CHANGE_NO_PREROLL;
1156   else
1157     return result;
1158
1159   /* ERRORS */
1160 failure:
1161   {
1162     gst_base_src_stop (basesrc);
1163     return result;
1164   }
1165 }