gst/base/gstbasesink.c: Remove extra parameter to debug output
[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: #GstBaseTransformc, #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 sinkpad</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_HAS_LOOP,
72   PROP_HAS_GETRANGE,
73   PROP_NUM_BUFFERS,
74 };
75
76 static GstElementClass *parent_class = NULL;
77
78 static void gst_base_src_base_init (gpointer g_class);
79 static void gst_base_src_class_init (GstBaseSrcClass * klass);
80 static void gst_base_src_init (GstBaseSrc * src, gpointer g_class);
81 static void gst_base_src_finalize (GObject * object);
82
83
84 GType
85 gst_base_src_get_type (void)
86 {
87   static GType base_src_type = 0;
88
89   if (!base_src_type) {
90     static const GTypeInfo base_src_info = {
91       sizeof (GstBaseSrcClass),
92       (GBaseInitFunc) gst_base_src_base_init,
93       NULL,
94       (GClassInitFunc) gst_base_src_class_init,
95       NULL,
96       NULL,
97       sizeof (GstBaseSrc),
98       0,
99       (GInstanceInitFunc) gst_base_src_init,
100     };
101
102     base_src_type = g_type_register_static (GST_TYPE_ELEMENT,
103         "GstBaseSrc", &base_src_info, G_TYPE_FLAG_ABSTRACT);
104   }
105   return base_src_type;
106 }
107 static GstCaps *gst_base_src_getcaps (GstPad * pad);
108 static gboolean gst_base_src_setcaps (GstPad * pad, GstCaps * caps);
109
110 static gboolean gst_base_src_activate_push (GstPad * pad, gboolean active);
111 static gboolean gst_base_src_activate_pull (GstPad * pad, gboolean active);
112 static void gst_base_src_set_property (GObject * object, guint prop_id,
113     const GValue * value, GParamSpec * pspec);
114 static void gst_base_src_get_property (GObject * object, guint prop_id,
115     GValue * value, GParamSpec * pspec);
116 static gboolean gst_base_src_event_handler (GstPad * pad, GstEvent * event);
117
118 static gboolean gst_base_src_query (GstPad * pad, GstQuery * query);
119
120 #if 0
121 static const GstEventMask *gst_base_src_get_event_mask (GstPad * pad);
122 #endif
123 static gboolean gst_base_src_default_negotiate (GstBaseSrc * basesrc);
124
125 static gboolean gst_base_src_unlock (GstBaseSrc * basesrc);
126 static gboolean gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size);
127 static gboolean gst_base_src_start (GstBaseSrc * basesrc);
128 static gboolean gst_base_src_stop (GstBaseSrc * basesrc);
129
130 static GstElementStateReturn gst_base_src_change_state (GstElement * element);
131
132 static void gst_base_src_set_dataflow_funcs (GstBaseSrc * this);
133 static void gst_base_src_loop (GstPad * pad);
134 static gboolean gst_base_src_check_get_range (GstPad * pad);
135 static GstFlowReturn gst_base_src_get_range (GstPad * pad, guint64 offset,
136     guint length, GstBuffer ** buf);
137
138 static void
139 gst_base_src_base_init (gpointer g_class)
140 {
141   GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
142 }
143
144 static void
145 gst_base_src_class_init (GstBaseSrcClass * klass)
146 {
147   GObjectClass *gobject_class;
148   GstElementClass *gstelement_class;
149
150   gobject_class = (GObjectClass *) klass;
151   gstelement_class = (GstElementClass *) klass;
152
153   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
154
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);
158
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,
162           G_PARAM_READWRITE));
163
164   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HAS_LOOP,
165       g_param_spec_boolean ("has-loop", "Has loop function",
166           "True if the element should expose a loop function", TRUE,
167           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
168
169   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HAS_GETRANGE,
170       g_param_spec_boolean ("has-getrange", "Has getrange function",
171           "True if the element should expose a getrange function", TRUE,
172           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
173
174   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_NUM_BUFFERS,
175       g_param_spec_int ("num-buffers", "num-buffers",
176           "Number of buffers to output before sending EOS", -1, G_MAXINT,
177           DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE));
178
179   gstelement_class->change_state =
180       GST_DEBUG_FUNCPTR (gst_base_src_change_state);
181
182   klass->negotiate = gst_base_src_default_negotiate;
183 }
184
185 static void
186 gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
187 {
188   GstPad *pad;
189   GstPadTemplate *pad_template;
190
191   basesrc->is_live = FALSE;
192   basesrc->live_lock = g_mutex_new ();
193   basesrc->live_cond = g_cond_new ();
194   basesrc->num_buffers = DEFAULT_NUM_BUFFERS;
195   basesrc->num_buffers_left = -1;
196
197   pad_template =
198       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
199   g_return_if_fail (pad_template != NULL);
200
201   pad = gst_pad_new_from_template (pad_template, "src");
202
203   gst_pad_set_activatepush_function (pad, gst_base_src_activate_push);
204   gst_pad_set_activatepull_function (pad, gst_base_src_activate_pull);
205   gst_pad_set_event_function (pad, gst_base_src_event_handler);
206   gst_pad_set_query_function (pad, gst_base_src_query);
207   gst_pad_set_checkgetrange_function (pad, gst_base_src_check_get_range);
208   gst_pad_set_getcaps_function (pad, gst_base_src_getcaps);
209   gst_pad_set_setcaps_function (pad, gst_base_src_setcaps);
210
211   /* hold ref to pad */
212   basesrc->srcpad = pad;
213   gst_element_add_pad (GST_ELEMENT (basesrc), pad);
214
215   basesrc->segment_start = -1;
216   basesrc->segment_end = -1;
217   basesrc->need_discont = TRUE;
218   basesrc->blocksize = DEFAULT_BLOCKSIZE;
219   basesrc->clock_id = NULL;
220
221   GST_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
222 }
223
224 static void
225 gst_base_src_finalize (GObject * object)
226 {
227   GstBaseSrc *basesrc;
228
229   basesrc = GST_BASE_SRC (object);
230
231   g_mutex_free (basesrc->live_lock);
232   g_cond_free (basesrc->live_cond);
233
234   G_OBJECT_CLASS (parent_class)->finalize (object);
235 }
236
237 /**
238  * gst_base_src_set_live:
239  * @src: base source instance
240  * @live: new live-mode
241  *
242  * If the element listens to a live source, the @livemode should
243  * be set to %TRUE. This declares that this source can't seek.
244  */
245 void
246 gst_base_src_set_live (GstBaseSrc * src, gboolean live)
247 {
248   GST_LIVE_LOCK (src);
249   src->is_live = live;
250   GST_LIVE_UNLOCK (src);
251 }
252
253 /**
254  * gst_base_src_get_live:
255  * @src: base source instance
256  *
257  * Check if an element is in live mode.
258  *
259  * Returns: %TRUE if element is in live mode.
260  */
261 gboolean
262 gst_base_src_is_live (GstBaseSrc * src)
263 {
264   gboolean result;
265
266   GST_LIVE_LOCK (src);
267   result = src->is_live;
268   GST_LIVE_UNLOCK (src);
269
270   return result;
271 }
272
273 static void
274 gst_base_src_set_dataflow_funcs (GstBaseSrc * this)
275 {
276   GST_DEBUG ("updating dataflow functions");
277
278   if (this->has_getrange)
279     gst_pad_set_getrange_function (this->srcpad, gst_base_src_get_range);
280   else
281     gst_pad_set_getrange_function (this->srcpad, NULL);
282 }
283
284 static gboolean
285 gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
286 {
287   GstBaseSrcClass *bclass;
288   GstBaseSrc *bsrc;
289   gboolean res = TRUE;
290
291   bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
292   bclass = GST_BASE_SRC_GET_CLASS (bsrc);
293
294   if (bclass->set_caps)
295     res = bclass->set_caps (bsrc, caps);
296
297   return res;
298 }
299
300 static GstCaps *
301 gst_base_src_getcaps (GstPad * pad)
302 {
303   GstBaseSrcClass *bclass;
304   GstBaseSrc *bsrc;
305   GstCaps *caps = NULL;
306
307   bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
308   bclass = GST_BASE_SRC_GET_CLASS (bsrc);
309   if (bclass->get_caps)
310     caps = bclass->get_caps (bsrc);
311
312   if (caps == NULL) {
313     GstPadTemplate *pad_template;
314
315     pad_template =
316         gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
317     if (pad_template != NULL) {
318       caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
319     }
320   }
321   return caps;
322 }
323
324 static gboolean
325 gst_base_src_query (GstPad * pad, GstQuery * query)
326 {
327   gboolean b;
328   guint64 ui64;
329   gint64 i64;
330   GstBaseSrc *src;
331
332   src = GST_BASE_SRC (GST_PAD_PARENT (pad));
333
334   switch (GST_QUERY_TYPE (query)) {
335     case GST_QUERY_POSITION:
336     {
337       GstFormat format;
338
339       gst_query_parse_position (query, &format, NULL, NULL);
340       switch (format) {
341         case GST_FORMAT_DEFAULT:
342         case GST_FORMAT_BYTES:
343           b = gst_base_src_get_size (src, &ui64);
344           /* better to make get_size take an int64 */
345           i64 = b ? (gint64) ui64 : -1;
346           gst_query_set_position (query, GST_FORMAT_BYTES, src->offset, i64);
347           return TRUE;
348         case GST_FORMAT_PERCENT:
349           b = gst_base_src_get_size (src, &ui64);
350           i64 = GST_FORMAT_PERCENT_MAX;
351           i64 *= b ? (src->offset / (gdouble) ui64) : 1.0;
352           gst_query_set_position (query, GST_FORMAT_PERCENT,
353               i64, GST_FORMAT_PERCENT_MAX);
354           return TRUE;
355         default:
356           return FALSE;
357       }
358     }
359
360     case GST_QUERY_SEEKING:
361       gst_query_set_seeking (query, GST_FORMAT_BYTES,
362           src->seekable, src->segment_start, src->segment_end);
363       return TRUE;
364
365     case GST_QUERY_FORMATS:
366       gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT,
367           GST_FORMAT_BYTES, GST_FORMAT_PERCENT);
368       return TRUE;
369
370     case GST_QUERY_LATENCY:
371     case GST_QUERY_JITTER:
372     case GST_QUERY_RATE:
373     case GST_QUERY_CONVERT:
374     default:
375       return gst_pad_query_default (pad, query);
376   }
377 }
378
379 static gboolean
380 gst_base_src_send_discont (GstBaseSrc * src)
381 {
382   GstEvent *event;
383
384   GST_DEBUG_OBJECT (src, "Sending newsegment from %" G_GINT64_FORMAT
385       " to %" G_GINT64_FORMAT, (gint64) src->segment_start,
386       (gint64) src->segment_end);
387   event = gst_event_new_newsegment (1.0,
388       GST_FORMAT_BYTES,
389       (gint64) src->segment_start, (gint64) src->segment_end, (gint64) 0);
390
391   return gst_pad_push_event (src->srcpad, event);
392 }
393
394 static gboolean
395 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
396 {
397   gdouble rate;
398   GstFormat format;
399   GstSeekFlags flags;
400   GstSeekType cur_type, stop_type;
401   gint64 cur, stop;
402
403   gst_event_parse_seek (event, &rate, &format, &flags,
404       &cur_type, &cur, &stop_type, &stop);
405
406   /* get seek format */
407   if (format == GST_FORMAT_DEFAULT)
408     format = GST_FORMAT_BYTES;
409   /* we can only seek bytes */
410   if (format != GST_FORMAT_BYTES)
411     return FALSE;
412
413   /* get seek positions */
414   src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
415
416   /* send flush start */
417   gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
418
419   /* unblock streaming thread */
420   gst_base_src_unlock (src);
421
422   /* grab streaming lock */
423   GST_STREAM_LOCK (src->srcpad);
424
425   /* send flush stop */
426   gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
427
428   /* perform the seek */
429   switch (cur_type) {
430     case GST_SEEK_TYPE_NONE:
431       break;
432     case GST_SEEK_TYPE_SET:
433       if (cur < 0)
434         goto error;
435       src->offset = MIN (cur, src->size);
436       src->segment_start = src->offset;
437       break;
438     case GST_SEEK_TYPE_CUR:
439       src->offset = CLAMP (src->offset + cur, 0, src->size);
440       src->segment_start = src->offset;
441       break;
442     case GST_SEEK_TYPE_END:
443       if (cur > 0)
444         goto error;
445       src->offset = MAX (0, src->size + cur);
446       src->segment_start = src->offset;
447       break;
448     default:
449       goto error;
450   }
451
452   switch (stop_type) {
453     case GST_SEEK_TYPE_NONE:
454       break;
455     case GST_SEEK_TYPE_SET:
456       if (stop < 0)
457         goto error;
458       src->segment_end = MIN (stop, src->size);
459       break;
460     case GST_SEEK_TYPE_CUR:
461       src->segment_end = CLAMP (src->segment_end + stop, 0, src->size);
462       break;
463     case GST_SEEK_TYPE_END:
464       if (stop > 0)
465         goto error;
466       src->segment_end = src->size + stop;
467       break;
468     default:
469       goto error;
470   }
471
472   GST_DEBUG_OBJECT (src, "seek pending for segment from %" G_GINT64_FORMAT
473       " to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
474
475   /* now make sure the discont will be send */
476   src->need_discont = TRUE;
477
478   /* and restart the task */
479   gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
480       src->srcpad);
481   GST_STREAM_UNLOCK (src->srcpad);
482
483   gst_event_unref (event);
484
485   return TRUE;
486
487   /* ERROR */
488 error:
489   {
490     GST_DEBUG_OBJECT (src, "seek error");
491     GST_STREAM_UNLOCK (src->srcpad);
492     gst_event_unref (event);
493     return FALSE;
494   }
495 }
496
497 static gboolean
498 gst_base_src_event_handler (GstPad * pad, GstEvent * event)
499 {
500   GstBaseSrc *src;
501   GstBaseSrcClass *bclass;
502   gboolean result;
503
504   src = GST_BASE_SRC (GST_PAD_PARENT (pad));
505   bclass = GST_BASE_SRC_GET_CLASS (src);
506
507   if (bclass->event)
508     result = bclass->event (src, event);
509
510   switch (GST_EVENT_TYPE (event)) {
511     case GST_EVENT_SEEK:
512       return gst_base_src_do_seek (src, event);
513     case GST_EVENT_FLUSH_START:
514       /* cancel any blocking getrange */
515       gst_base_src_unlock (src);
516       break;
517     case GST_EVENT_FLUSH_STOP:
518       break;
519     default:
520       break;
521   }
522   gst_event_unref (event);
523
524   return TRUE;
525 }
526
527 static void
528 gst_base_src_set_property (GObject * object, guint prop_id,
529     const GValue * value, GParamSpec * pspec)
530 {
531   GstBaseSrc *src;
532
533   src = GST_BASE_SRC (object);
534
535   switch (prop_id) {
536     case PROP_BLOCKSIZE:
537       src->blocksize = g_value_get_ulong (value);
538       break;
539     case PROP_HAS_LOOP:
540       src->has_loop = g_value_get_boolean (value);
541       gst_base_src_set_dataflow_funcs (src);
542       break;
543     case PROP_HAS_GETRANGE:
544       src->has_getrange = g_value_get_boolean (value);
545       gst_base_src_set_dataflow_funcs (src);
546       break;
547     case PROP_NUM_BUFFERS:
548       src->num_buffers = g_value_get_int (value);
549       break;
550     default:
551       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
552       break;
553   }
554 }
555
556 static void
557 gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
558     GParamSpec * pspec)
559 {
560   GstBaseSrc *src;
561
562   src = GST_BASE_SRC (object);
563
564   switch (prop_id) {
565     case PROP_BLOCKSIZE:
566       g_value_set_ulong (value, src->blocksize);
567       break;
568     case PROP_HAS_LOOP:
569       g_value_set_boolean (value, src->has_loop);
570       break;
571     case PROP_HAS_GETRANGE:
572       g_value_set_boolean (value, src->has_getrange);
573       break;
574     case PROP_NUM_BUFFERS:
575       g_value_set_int (value, src->num_buffers);
576       break;
577     default:
578       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
579       break;
580   }
581 }
582
583 static GstFlowReturn
584 gst_base_src_get_range (GstPad * pad, guint64 offset, guint length,
585     GstBuffer ** buf)
586 {
587   GstFlowReturn ret;
588   GstBaseSrc *src;
589   GstBaseSrcClass *bclass;
590
591   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
592   bclass = GST_BASE_SRC_GET_CLASS (src);
593
594   GST_LIVE_LOCK (src);
595   if (src->is_live) {
596     while (!src->live_running) {
597       GST_DEBUG ("live source signal waiting");
598       GST_LIVE_SIGNAL (src);
599       GST_DEBUG ("live source waiting for running state");
600       GST_LIVE_WAIT (src);
601       GST_DEBUG ("live source unlocked");
602     }
603   }
604   GST_LIVE_UNLOCK (src);
605
606   GST_LOCK (pad);
607   if (GST_PAD_IS_FLUSHING (pad))
608     goto flushing;
609   GST_UNLOCK (pad);
610
611   if (!GST_FLAG_IS_SET (src, GST_BASE_SRC_STARTED))
612     goto not_started;
613
614   if (!bclass->create)
615     goto no_function;
616
617   /* check size */
618   if (src->size != -1) {
619     if (offset > src->size)
620       goto unexpected_length;
621
622     if (offset + length > src->size) {
623       if (bclass->get_size)
624         bclass->get_size (src, &src->size);
625
626       if (offset + length > src->size) {
627         length = src->size - offset;
628       }
629     }
630   }
631   if (length == 0)
632     goto unexpected_length;
633
634   if (src->num_buffers_left == 0) {
635     goto reached_num_buffers;
636   } else {
637     if (src->num_buffers_left > 0)
638       src->num_buffers_left--;
639   }
640
641   ret = bclass->create (src, offset, length, buf);
642
643   return ret;
644
645   /* ERROR */
646 flushing:
647   {
648     GST_DEBUG_OBJECT (src, "pad is flushing");
649     GST_UNLOCK (pad);
650     return GST_FLOW_WRONG_STATE;
651   }
652 not_started:
653   {
654     GST_DEBUG_OBJECT (src, "getrange but not started");
655     return GST_FLOW_WRONG_STATE;
656   }
657 no_function:
658   {
659     GST_DEBUG_OBJECT (src, "no create function");
660     return GST_FLOW_ERROR;
661   }
662 unexpected_length:
663   {
664     GST_DEBUG_OBJECT (src, "unexpected length %u", length);
665     return GST_FLOW_UNEXPECTED;
666   }
667 reached_num_buffers:
668   {
669     GST_DEBUG_OBJECT (src, "sent all buffers");
670     return GST_FLOW_UNEXPECTED;
671   }
672 }
673
674 static gboolean
675 gst_base_src_check_get_range (GstPad * pad)
676 {
677   GstBaseSrc *src;
678
679   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
680
681   if (!GST_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
682     gst_base_src_start (src);
683     gst_base_src_stop (src);
684   }
685
686   return src->seekable;
687 }
688
689 static void
690 gst_base_src_loop (GstPad * pad)
691 {
692   GstBaseSrc *src;
693   GstBuffer *buf = NULL;
694   GstFlowReturn ret;
695
696   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
697
698   if (src->need_discont) {
699     /* now send discont */
700     gst_base_src_send_discont (src);
701     src->need_discont = FALSE;
702   }
703
704   ret = gst_base_src_get_range (pad, src->offset, src->blocksize, &buf);
705   if (ret != GST_FLOW_OK)
706     goto eos;
707
708   if (buf == NULL)
709     goto error;
710
711   src->offset += GST_BUFFER_SIZE (buf);
712
713   ret = gst_pad_push (pad, buf);
714   if (ret != GST_FLOW_OK)
715     goto pause;
716
717   return;
718
719 eos:
720   {
721     GST_DEBUG_OBJECT (src, "going to EOS");
722     gst_pad_pause_task (pad);
723     gst_pad_push_event (pad, gst_event_new_eos ());
724     return;
725   }
726 pause:
727   {
728     GST_DEBUG_OBJECT (src, "pausing task");
729     gst_pad_pause_task (pad);
730     if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
731       /* for fatal errors we post an error message */
732       GST_ELEMENT_ERROR (src, STREAM, STOPPED,
733           ("streaming stopped, reason %s", gst_flow_get_name (ret)),
734           ("streaming stopped, reason %s", gst_flow_get_name (ret)));
735       gst_pad_push_event (pad, gst_event_new_eos ());
736     }
737     return;
738   }
739 error:
740   {
741     GST_ELEMENT_ERROR (src, STREAM, STOPPED,
742         ("internal: element returned NULL buffer"),
743         ("internal: element returned NULL buffer"));
744     gst_pad_pause_task (pad);
745     gst_pad_push_event (pad, gst_event_new_eos ());
746     return;
747   }
748 }
749
750 static gboolean
751 gst_base_src_unlock (GstBaseSrc * basesrc)
752 {
753   GstBaseSrcClass *bclass;
754   gboolean result = FALSE;
755
756   GST_DEBUG ("unlock");
757   /* unblock whatever the subclass is doing */
758   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
759   if (bclass->unlock)
760     result = bclass->unlock (basesrc);
761
762   GST_DEBUG ("unschedule clock");
763   /* and unblock the clock as well, if any */
764   GST_LOCK (basesrc);
765   if (basesrc->clock_id) {
766     gst_clock_id_unschedule (basesrc->clock_id);
767   }
768   GST_UNLOCK (basesrc);
769
770   GST_DEBUG ("unlock done");
771
772   return result;
773 }
774
775 static gboolean
776 gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size)
777 {
778   GstBaseSrcClass *bclass;
779   gboolean result = FALSE;
780
781   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
782   if (bclass->get_size)
783     result = bclass->get_size (basesrc, size);
784
785   if (result)
786     basesrc->size = *size;
787
788   return result;
789 }
790
791 static gboolean
792 gst_base_src_is_seekable (GstBaseSrc * basesrc)
793 {
794   GstBaseSrcClass *bclass;
795
796   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
797
798   /* check if we can seek */
799   if (bclass->is_seekable)
800     basesrc->seekable = bclass->is_seekable (basesrc);
801   else
802     basesrc->seekable = FALSE;
803
804   return basesrc->seekable;
805 }
806
807 static gboolean
808 gst_base_src_default_negotiate (GstBaseSrc * basesrc)
809 {
810   GstCaps *thiscaps;
811   GstCaps *caps = NULL;
812   GstCaps *peercaps = NULL;
813   gboolean result = FALSE;
814
815   thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));
816   GST_DEBUG ("caps of src: %" GST_PTR_FORMAT, thiscaps);
817   if (thiscaps == NULL || gst_caps_is_any (thiscaps))
818     goto no_nego_needed;
819
820   peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
821   GST_DEBUG ("caps of peer: %" GST_PTR_FORMAT, peercaps);
822   if (peercaps) {
823     GstCaps *icaps;
824
825     icaps = gst_caps_intersect (thiscaps, peercaps);
826     GST_DEBUG ("intersect: %" GST_PTR_FORMAT, icaps);
827     gst_caps_unref (thiscaps);
828     gst_caps_unref (peercaps);
829     if (icaps) {
830       caps = gst_caps_copy_nth (icaps, 0);
831       gst_caps_unref (icaps);
832     }
833   } else {
834     caps = thiscaps;
835   }
836   if (caps) {
837     caps = gst_caps_make_writable (caps);
838     gst_caps_truncate (caps);
839
840     gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
841     GST_DEBUG ("fixated to: %" GST_PTR_FORMAT, caps);
842
843     if (gst_caps_is_any (caps)) {
844       gst_caps_unref (caps);
845       result = TRUE;
846     } else if (gst_caps_is_fixed (caps)) {
847       gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
848       gst_caps_unref (caps);
849       result = TRUE;
850     }
851   }
852   return result;
853
854 no_nego_needed:
855   {
856     GST_DEBUG ("no negotiation needed");
857     if (thiscaps)
858       gst_caps_unref (thiscaps);
859     return TRUE;
860   }
861 }
862
863 static gboolean
864 gst_base_src_negotiate (GstBaseSrc * basesrc)
865 {
866   GstBaseSrcClass *bclass;
867   gboolean result = TRUE;
868
869   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
870
871   if (bclass->negotiate)
872     result = bclass->negotiate (basesrc);
873
874   return result;
875 }
876
877 static gboolean
878 gst_base_src_start (GstBaseSrc * basesrc)
879 {
880   GstBaseSrcClass *bclass;
881   gboolean result;
882
883   if (GST_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
884     return TRUE;
885
886   GST_DEBUG_OBJECT (basesrc, "starting source");
887
888   basesrc->num_buffers_left = basesrc->num_buffers;
889
890   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
891   if (bclass->start)
892     result = bclass->start (basesrc);
893   else
894     result = TRUE;
895
896   if (!result)
897     goto could_not_start;
898
899   GST_FLAG_SET (basesrc, GST_BASE_SRC_STARTED);
900
901   /* start in the beginning */
902   basesrc->offset = 0;
903
904   /* figure out the size */
905   if (bclass->get_size) {
906     result = bclass->get_size (basesrc, &basesrc->size);
907     if (result == FALSE)
908       basesrc->size = -1;
909   } else {
910     result = FALSE;
911     basesrc->size = -1;
912   }
913
914   GST_DEBUG ("size %d %lld", result, basesrc->size);
915
916   /* we always run to the end */
917   basesrc->segment_start = 0;
918   basesrc->segment_end = basesrc->size;
919   basesrc->need_discont = TRUE;
920
921   /* check if we can seek, updates ->seekable */
922   gst_base_src_is_seekable (basesrc);
923
924   /* run typefind */
925 #if 0
926   if (basesrc->seekable) {
927     GstCaps *caps;
928
929     caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
930     gst_pad_set_caps (basesrc->srcpad, caps);
931     gst_caps_unref (caps);
932   }
933 #endif
934
935   if (!gst_base_src_negotiate (basesrc))
936     goto could_not_negotiate;
937
938   return TRUE;
939
940   /* ERROR */
941 could_not_start:
942   {
943     GST_DEBUG_OBJECT (basesrc, "could not start");
944     return FALSE;
945   }
946 could_not_negotiate:
947   {
948     GST_DEBUG_OBJECT (basesrc, "could not negotiate, stopping");
949     GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
950         ("Could not connect source to pipeline"),
951         ("Check your filtered caps, if any"));
952     gst_base_src_stop (basesrc);
953     return FALSE;
954   }
955 }
956
957 static gboolean
958 gst_base_src_stop (GstBaseSrc * basesrc)
959 {
960   GstBaseSrcClass *bclass;
961   gboolean result = TRUE;
962
963   if (!GST_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
964     return TRUE;
965
966   GST_DEBUG_OBJECT (basesrc, "stopping source");
967
968   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
969   if (bclass->stop)
970     result = bclass->stop (basesrc);
971
972   if (result)
973     GST_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
974
975   return result;
976 }
977
978 static gboolean
979 gst_base_src_deactivate (GstBaseSrc * basesrc, GstPad * pad)
980 {
981   gboolean result;
982
983   GST_LIVE_LOCK (basesrc);
984   basesrc->live_running = TRUE;
985   GST_LIVE_SIGNAL (basesrc);
986   GST_LIVE_UNLOCK (basesrc);
987
988   /* step 1, unblock clock sync (if any) */
989   gst_base_src_unlock (basesrc);
990
991   /* step 2, make sure streaming finishes */
992   result = gst_pad_stop_task (pad);
993
994   return result;
995 }
996
997 static gboolean
998 gst_base_src_activate_push (GstPad * pad, gboolean active)
999 {
1000   GstBaseSrc *basesrc;
1001
1002   basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1003
1004   /* prepare subclass first */
1005   if (active) {
1006     GST_DEBUG_OBJECT (basesrc, "Activating in push mode");
1007     if (!gst_base_src_start (basesrc))
1008       goto error_start;
1009
1010     return gst_pad_start_task (pad, (GstTaskFunction) gst_base_src_loop, pad);
1011   } else {
1012     GST_DEBUG_OBJECT (basesrc, "Deactivating in push mode");
1013     return gst_base_src_deactivate (basesrc, pad);
1014   }
1015
1016 error_start:
1017   {
1018     gst_base_src_stop (basesrc);
1019     GST_DEBUG_OBJECT (basesrc, "Failed to start in push mode");
1020     return FALSE;
1021   }
1022 }
1023
1024 static gboolean
1025 gst_base_src_activate_pull (GstPad * pad, gboolean active)
1026 {
1027   GstBaseSrc *basesrc;
1028
1029   basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1030
1031   /* prepare subclass first */
1032   if (active) {
1033     GST_DEBUG_OBJECT (basesrc, "Activating in pull mode");
1034     if (!gst_base_src_start (basesrc))
1035       goto error_start;
1036
1037     if (!basesrc->seekable) {
1038       gst_base_src_stop (basesrc);
1039       return FALSE;
1040     }
1041
1042     return TRUE;
1043   } else {
1044     GST_DEBUG_OBJECT (basesrc, "Deactivating in pull mode");
1045
1046     if (!gst_base_src_stop (basesrc))
1047       goto error_stop;
1048
1049     return gst_base_src_deactivate (basesrc, pad);
1050   }
1051
1052 error_start:
1053   {
1054     gst_base_src_stop (basesrc);
1055     GST_DEBUG_OBJECT (basesrc, "Failed to start in pull mode");
1056     return FALSE;
1057   }
1058 error_stop:
1059   {
1060     GST_DEBUG_OBJECT (basesrc, "Failed to stop in pull mode");
1061     return FALSE;
1062   }
1063 }
1064
1065 static GstElementStateReturn
1066 gst_base_src_change_state (GstElement * element)
1067 {
1068   GstBaseSrc *basesrc;
1069   GstElementStateReturn result = GST_STATE_SUCCESS;
1070   GstElementStateReturn presult;
1071   GstElementState transition;
1072
1073   basesrc = GST_BASE_SRC (element);
1074
1075   transition = GST_STATE_TRANSITION (element);
1076
1077   switch (transition) {
1078     case GST_STATE_NULL_TO_READY:
1079       break;
1080     case GST_STATE_READY_TO_PAUSED:
1081       GST_LIVE_LOCK (element);
1082       if (basesrc->is_live) {
1083         result = GST_STATE_NO_PREROLL;
1084         basesrc->live_running = FALSE;
1085       }
1086       GST_LIVE_UNLOCK (element);
1087       break;
1088     case GST_STATE_PAUSED_TO_PLAYING:
1089       GST_LIVE_LOCK (element);
1090       if (basesrc->is_live) {
1091         basesrc->live_running = TRUE;
1092         GST_LIVE_SIGNAL (element);
1093       }
1094       GST_LIVE_UNLOCK (element);
1095       break;
1096     default:
1097       break;
1098   }
1099
1100   if ((presult = GST_ELEMENT_CLASS (parent_class)->change_state (element)) !=
1101       GST_STATE_SUCCESS) {
1102     gst_base_src_stop (basesrc);
1103     return presult;
1104   }
1105
1106   switch (transition) {
1107     case GST_STATE_PLAYING_TO_PAUSED:
1108       GST_LIVE_LOCK (element);
1109       if (basesrc->is_live) {
1110         result = GST_STATE_NO_PREROLL;
1111         basesrc->live_running = FALSE;
1112       }
1113       GST_LIVE_UNLOCK (element);
1114       break;
1115     case GST_STATE_PAUSED_TO_READY:
1116       if (!gst_base_src_stop (basesrc))
1117         result = GST_STATE_FAILURE;
1118       break;
1119     case GST_STATE_READY_TO_NULL:
1120       break;
1121     default:
1122       break;
1123   }
1124
1125   return result;
1126 }