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