docs/gst/gstreamer-sections.txt: made some defines private
[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 #if 0
380 static const GstEventMask *
381 gst_base_src_get_event_mask (GstPad * pad)
382 {
383   static const GstEventMask masks[] = {
384     {GST_EVENT_SEEK, GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_SET |
385           GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH |
386           GST_SEEK_FLAG_SEGMENT_LOOP},
387     {GST_EVENT_FLUSH, 0},
388     {GST_EVENT_SIZE, 0},
389     {0, 0},
390   };
391   return masks;
392 }
393 #endif
394
395 static gboolean
396 gst_base_src_send_discont (GstBaseSrc * src)
397 {
398   GstEvent *event;
399
400   event = gst_event_new_newsegment (1.0,
401       GST_FORMAT_BYTES,
402       (gint64) src->segment_start, (gint64) src->segment_end, (gint64) 0);
403
404   return gst_pad_push_event (src->srcpad, event);
405 }
406
407 static gboolean
408 gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
409 {
410   gdouble rate;
411   GstFormat format;
412   GstSeekFlags flags;
413   GstSeekType cur_type, stop_type;
414   gint64 cur, stop;
415
416   gst_event_parse_seek (event, &rate, &format, &flags,
417       &cur_type, &cur, &stop_type, &stop);
418
419   /* get seek format */
420   if (format == GST_FORMAT_DEFAULT)
421     format = GST_FORMAT_BYTES;
422   /* we can only seek bytes */
423   if (format != GST_FORMAT_BYTES)
424     return FALSE;
425
426   /* get seek positions */
427   src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
428
429   /* send flush start */
430   gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
431
432   /* unblock streaming thread */
433   gst_base_src_unlock (src);
434
435   /* grab streaming lock */
436   GST_STREAM_LOCK (src->srcpad);
437
438   /* send flush stop */
439   gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
440
441   /* perform the seek */
442   switch (cur_type) {
443     case GST_SEEK_TYPE_SET:
444       if (cur < 0)
445         goto error;
446       src->offset = MIN (cur, src->size);
447       src->segment_start = src->offset;
448       src->segment_end = MIN (stop, src->size);
449       GST_DEBUG_OBJECT (src, "seek set pending to %" G_GINT64_FORMAT,
450           src->offset);
451       break;
452     case GST_SEEK_TYPE_CUR:
453       cur += src->offset;
454       src->offset = CLAMP (cur, 0, src->size);
455       src->segment_start = src->offset;
456       src->segment_end = stop;
457       GST_DEBUG_OBJECT (src, "seek cur pending to %" G_GINT64_FORMAT,
458           src->offset);
459       break;
460     case GST_SEEK_TYPE_END:
461       if (cur > 0)
462         goto error;
463       cur = src->size + cur;
464       src->offset = MAX (0, cur);
465       src->segment_start = src->offset;
466       src->segment_end = stop;
467       GST_DEBUG_OBJECT (src, "seek end pending to %" G_GINT64_FORMAT,
468           src->offset);
469       break;
470     default:
471       goto error;
472   }
473
474   /* now make sure the discont will be send */
475   src->need_discont = TRUE;
476
477   /* and restart the task */
478   gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
479       src->srcpad);
480   GST_STREAM_UNLOCK (src->srcpad);
481
482   gst_event_unref (event);
483
484   return TRUE;
485
486   /* ERROR */
487 error:
488   {
489     GST_DEBUG_OBJECT (src, "seek error");
490     GST_STREAM_UNLOCK (src->srcpad);
491     gst_event_unref (event);
492     return FALSE;
493   }
494 }
495
496 static gboolean
497 gst_base_src_event_handler (GstPad * pad, GstEvent * event)
498 {
499   GstBaseSrc *src;
500   GstBaseSrcClass *bclass;
501   gboolean result;
502
503   src = GST_BASE_SRC (GST_PAD_PARENT (pad));
504   bclass = GST_BASE_SRC_GET_CLASS (src);
505
506   if (bclass->event)
507     result = bclass->event (src, event);
508
509   switch (GST_EVENT_TYPE (event)) {
510     case GST_EVENT_SEEK:
511       return gst_base_src_do_seek (src, event);
512     case GST_EVENT_FLUSH_START:
513       /* cancel any blocking getrange */
514       gst_base_src_unlock (src);
515       break;
516     case GST_EVENT_FLUSH_STOP:
517       break;
518     default:
519       break;
520   }
521   gst_event_unref (event);
522
523   return TRUE;
524 }
525
526 static void
527 gst_base_src_set_property (GObject * object, guint prop_id,
528     const GValue * value, GParamSpec * pspec)
529 {
530   GstBaseSrc *src;
531
532   src = GST_BASE_SRC (object);
533
534   switch (prop_id) {
535     case PROP_BLOCKSIZE:
536       src->blocksize = g_value_get_ulong (value);
537       break;
538     case PROP_HAS_LOOP:
539       src->has_loop = g_value_get_boolean (value);
540       gst_base_src_set_dataflow_funcs (src);
541       break;
542     case PROP_HAS_GETRANGE:
543       src->has_getrange = g_value_get_boolean (value);
544       gst_base_src_set_dataflow_funcs (src);
545       break;
546     case PROP_NUM_BUFFERS:
547       src->num_buffers = g_value_get_int (value);
548       break;
549     default:
550       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
551       break;
552   }
553 }
554
555 static void
556 gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
557     GParamSpec * pspec)
558 {
559   GstBaseSrc *src;
560
561   src = GST_BASE_SRC (object);
562
563   switch (prop_id) {
564     case PROP_BLOCKSIZE:
565       g_value_set_ulong (value, src->blocksize);
566       break;
567     case PROP_HAS_LOOP:
568       g_value_set_boolean (value, src->has_loop);
569       break;
570     case PROP_HAS_GETRANGE:
571       g_value_set_boolean (value, src->has_getrange);
572       break;
573     case PROP_NUM_BUFFERS:
574       g_value_set_int (value, src->num_buffers);
575       break;
576     default:
577       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
578       break;
579   }
580 }
581
582 static GstFlowReturn
583 gst_base_src_get_range (GstPad * pad, guint64 offset, guint length,
584     GstBuffer ** buf)
585 {
586   GstFlowReturn ret;
587   GstBaseSrc *src;
588   GstBaseSrcClass *bclass;
589
590   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
591   bclass = GST_BASE_SRC_GET_CLASS (src);
592
593   GST_LIVE_LOCK (src);
594   if (src->is_live) {
595     while (!src->live_running) {
596       GST_DEBUG ("live source signal waiting");
597       GST_LIVE_SIGNAL (src);
598       GST_DEBUG ("live source waiting for running state");
599       GST_LIVE_WAIT (src);
600       GST_DEBUG ("live source unlocked");
601     }
602   }
603   GST_LIVE_UNLOCK (src);
604
605   GST_LOCK (pad);
606   if (GST_PAD_IS_FLUSHING (pad))
607     goto flushing;
608   GST_UNLOCK (pad);
609
610   if (!GST_FLAG_IS_SET (src, GST_BASE_SRC_STARTED))
611     goto not_started;
612
613   if (!bclass->create)
614     goto no_function;
615
616   /* check size */
617   if (src->size != -1) {
618     if (offset > src->size)
619       goto unexpected_length;
620
621     if (offset + length > src->size) {
622       if (bclass->get_size)
623         bclass->get_size (src, &src->size);
624
625       if (offset + length > src->size) {
626         length = src->size - offset;
627       }
628     }
629   }
630   if (length == 0)
631     goto unexpected_length;
632
633   if (src->num_buffers_left == 0) {
634     goto reached_num_buffers;
635   } else {
636     if (src->num_buffers_left > 0)
637       src->num_buffers_left--;
638   }
639
640   ret = bclass->create (src, offset, length, buf);
641
642   return ret;
643
644   /* ERROR */
645 flushing:
646   {
647     GST_DEBUG_OBJECT (src, "pad is flushing");
648     GST_UNLOCK (pad);
649     return GST_FLOW_WRONG_STATE;
650   }
651 not_started:
652   {
653     GST_DEBUG_OBJECT (src, "getrange but not started");
654     return GST_FLOW_WRONG_STATE;
655   }
656 no_function:
657   {
658     GST_DEBUG_OBJECT (src, "no create function");
659     return GST_FLOW_ERROR;
660   }
661 unexpected_length:
662   {
663     GST_DEBUG_OBJECT (src, "unexpected length %u", length);
664     return GST_FLOW_UNEXPECTED;
665   }
666 reached_num_buffers:
667   {
668     GST_DEBUG_OBJECT (src, "sent all buffers");
669     return GST_FLOW_UNEXPECTED;
670   }
671 }
672
673 static gboolean
674 gst_base_src_check_get_range (GstPad * pad)
675 {
676   GstBaseSrc *src;
677
678   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
679
680   if (!GST_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
681     gst_base_src_start (src);
682     gst_base_src_stop (src);
683   }
684
685   return src->seekable;
686 }
687
688 static void
689 gst_base_src_loop (GstPad * pad)
690 {
691   GstBaseSrc *src;
692   GstBuffer *buf = NULL;
693   GstFlowReturn ret;
694
695   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
696
697   if (src->need_discont) {
698     /* now send discont */
699     gst_base_src_send_discont (src);
700     src->need_discont = FALSE;
701   }
702
703   ret = gst_base_src_get_range (pad, src->offset, src->blocksize, &buf);
704   if (ret != GST_FLOW_OK)
705     goto eos;
706
707   if (buf == NULL)
708     goto error;
709
710   src->offset += GST_BUFFER_SIZE (buf);
711
712   ret = gst_pad_push (pad, buf);
713   if (ret != GST_FLOW_OK)
714     goto pause;
715
716   return;
717
718 eos:
719   {
720     GST_DEBUG_OBJECT (src, "going to EOS");
721     gst_pad_pause_task (pad);
722     gst_pad_push_event (pad, gst_event_new_eos ());
723     return;
724   }
725 pause:
726   {
727     GST_DEBUG_OBJECT (src, "pausing task");
728     gst_pad_pause_task (pad);
729     if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
730       /* for fatal errors we post an error message */
731       GST_ELEMENT_ERROR (src, STREAM, STOPPED,
732           ("streaming stopped, reason %s", gst_flow_get_name (ret)),
733           ("streaming stopped, reason %s", gst_flow_get_name (ret)));
734       gst_pad_push_event (pad, gst_event_new_eos ());
735     }
736     return;
737   }
738 error:
739   {
740     GST_ELEMENT_ERROR (src, STREAM, STOPPED,
741         ("internal: element returned NULL buffer"),
742         ("internal: element returned NULL buffer"));
743     gst_pad_pause_task (pad);
744     gst_pad_push_event (pad, gst_event_new_eos ());
745     return;
746   }
747 }
748
749 static gboolean
750 gst_base_src_unlock (GstBaseSrc * basesrc)
751 {
752   GstBaseSrcClass *bclass;
753   gboolean result = FALSE;
754
755   GST_DEBUG ("unlock");
756   /* unblock whatever the subclass is doing */
757   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
758   if (bclass->unlock)
759     result = bclass->unlock (basesrc);
760
761   GST_DEBUG ("unschedule clock");
762   /* and unblock the clock as well, if any */
763   GST_LOCK (basesrc);
764   if (basesrc->clock_id) {
765     gst_clock_id_unschedule (basesrc->clock_id);
766   }
767   GST_UNLOCK (basesrc);
768
769   GST_DEBUG ("unlock done");
770
771   return result;
772 }
773
774 static gboolean
775 gst_base_src_get_size (GstBaseSrc * basesrc, guint64 * size)
776 {
777   GstBaseSrcClass *bclass;
778   gboolean result = FALSE;
779
780   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
781   if (bclass->get_size)
782     result = bclass->get_size (basesrc, size);
783
784   if (result)
785     basesrc->size = *size;
786
787   return result;
788 }
789
790 static gboolean
791 gst_base_src_is_seekable (GstBaseSrc * basesrc)
792 {
793   GstBaseSrcClass *bclass;
794
795   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
796
797   /* check if we can seek */
798   if (bclass->is_seekable)
799     basesrc->seekable = bclass->is_seekable (basesrc);
800   else
801     basesrc->seekable = FALSE;
802
803   return basesrc->seekable;
804 }
805
806 static gboolean
807 gst_base_src_default_negotiate (GstBaseSrc * basesrc)
808 {
809   GstCaps *thiscaps;
810   GstCaps *caps = NULL;
811   GstCaps *peercaps = NULL;
812   gboolean result = FALSE;
813
814   thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc));
815   GST_DEBUG ("caps of src: %" GST_PTR_FORMAT, thiscaps);
816   if (thiscaps == NULL || gst_caps_is_any (thiscaps))
817     goto no_nego_needed;
818
819   peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
820   GST_DEBUG ("caps of peer: %" GST_PTR_FORMAT, peercaps);
821   if (peercaps) {
822     GstCaps *icaps;
823
824     icaps = gst_caps_intersect (thiscaps, peercaps);
825     GST_DEBUG ("intersect: %" GST_PTR_FORMAT, icaps);
826     gst_caps_unref (thiscaps);
827     gst_caps_unref (peercaps);
828     if (icaps) {
829       caps = gst_caps_copy_nth (icaps, 0);
830       gst_caps_unref (icaps);
831     }
832   } else {
833     caps = thiscaps;
834   }
835   if (caps) {
836     caps = gst_caps_make_writable (caps);
837     gst_caps_truncate (caps);
838
839     gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
840     GST_DEBUG ("fixated to: %" GST_PTR_FORMAT, caps);
841
842     if (gst_caps_is_any (caps)) {
843       gst_caps_unref (caps);
844       result = TRUE;
845     } else if (gst_caps_is_fixed (caps)) {
846       gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
847       gst_caps_unref (caps);
848       result = TRUE;
849     }
850   }
851   return result;
852
853 no_nego_needed:
854   {
855     GST_DEBUG ("no negotiation needed");
856     if (thiscaps)
857       gst_caps_unref (thiscaps);
858     return TRUE;
859   }
860 }
861
862 static gboolean
863 gst_base_src_negotiate (GstBaseSrc * basesrc)
864 {
865   GstBaseSrcClass *bclass;
866   gboolean result = TRUE;
867
868   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
869
870   if (bclass->negotiate)
871     result = bclass->negotiate (basesrc);
872
873   return result;
874 }
875
876 static gboolean
877 gst_base_src_start (GstBaseSrc * basesrc)
878 {
879   GstBaseSrcClass *bclass;
880   gboolean result;
881
882   if (GST_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
883     return TRUE;
884
885   basesrc->num_buffers_left = basesrc->num_buffers;
886
887   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
888   if (bclass->start)
889     result = bclass->start (basesrc);
890   else
891     result = TRUE;
892
893   if (!result)
894     goto could_not_start;
895
896   GST_FLAG_SET (basesrc, GST_BASE_SRC_STARTED);
897
898   /* start in the beginning */
899   basesrc->offset = 0;
900
901   /* figure out the size */
902   if (bclass->get_size) {
903     result = bclass->get_size (basesrc, &basesrc->size);
904     if (result == FALSE)
905       basesrc->size = -1;
906   } else {
907     result = FALSE;
908     basesrc->size = -1;
909   }
910
911   GST_DEBUG ("size %d %lld", result, basesrc->size);
912
913   /* we always run to the end */
914   basesrc->segment_start = 0;
915   basesrc->segment_end = basesrc->size;
916   basesrc->need_discont = TRUE;
917
918   /* check if we can seek, updates ->seekable */
919   gst_base_src_is_seekable (basesrc);
920
921   /* run typefind */
922 #if 0
923   if (basesrc->seekable) {
924     GstCaps *caps;
925
926     caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
927     gst_pad_set_caps (basesrc->srcpad, caps);
928     gst_caps_unref (caps);
929   }
930 #endif
931
932   if (!gst_base_src_negotiate (basesrc))
933     goto could_not_negotiate;
934
935   return TRUE;
936
937   /* ERROR */
938 could_not_start:
939   {
940     GST_DEBUG_OBJECT (basesrc, "could not start");
941     return FALSE;
942   }
943 could_not_negotiate:
944   {
945     GST_DEBUG_OBJECT (basesrc, "could not negotiate, stopping");
946     GST_ELEMENT_ERROR (basesrc, STREAM, FORMAT,
947         ("Could not connect source to pipeline"),
948         ("Check your filtered caps, if any"));
949     gst_base_src_stop (basesrc);
950     return FALSE;
951   }
952 }
953
954 static gboolean
955 gst_base_src_stop (GstBaseSrc * basesrc)
956 {
957   GstBaseSrcClass *bclass;
958   gboolean result = TRUE;
959
960   if (!GST_FLAG_IS_SET (basesrc, GST_BASE_SRC_STARTED))
961     return TRUE;
962
963   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
964   if (bclass->stop)
965     result = bclass->stop (basesrc);
966
967   if (result)
968     GST_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
969
970   return result;
971 }
972
973 static gboolean
974 gst_base_src_deactivate (GstBaseSrc * basesrc, GstPad * pad)
975 {
976   gboolean result;
977
978   GST_LIVE_LOCK (basesrc);
979   basesrc->live_running = TRUE;
980   GST_LIVE_SIGNAL (basesrc);
981   GST_LIVE_UNLOCK (basesrc);
982
983   /* step 1, unblock clock sync (if any) */
984   gst_base_src_unlock (basesrc);
985
986   /* step 2, make sure streaming finishes */
987   result = gst_pad_stop_task (pad);
988
989   return result;
990 }
991
992 static gboolean
993 gst_base_src_activate_push (GstPad * pad, gboolean active)
994 {
995   GstBaseSrc *basesrc;
996
997   basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
998
999   /* prepare subclass first */
1000   if (active) {
1001     if (!gst_base_src_start (basesrc))
1002       goto error_start;
1003
1004     return gst_pad_start_task (pad, (GstTaskFunction) gst_base_src_loop, pad);
1005   } else {
1006     return gst_base_src_deactivate (basesrc, pad);
1007   }
1008
1009 error_start:
1010   {
1011     GST_DEBUG_OBJECT (basesrc, "failed to start");
1012     return FALSE;
1013   }
1014 }
1015
1016 static gboolean
1017 gst_base_src_activate_pull (GstPad * pad, gboolean active)
1018 {
1019   GstBaseSrc *basesrc;
1020
1021   basesrc = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
1022
1023   /* prepare subclass first */
1024   if (active) {
1025     if (!gst_base_src_start (basesrc))
1026       goto error_start;
1027
1028     if (!basesrc->seekable) {
1029       gst_base_src_stop (basesrc);
1030       return FALSE;
1031     }
1032
1033     return TRUE;
1034   } else {
1035     return gst_base_src_deactivate (basesrc, pad);
1036   }
1037
1038 error_start:
1039   {
1040     GST_DEBUG_OBJECT (basesrc, "failed to start");
1041     return FALSE;
1042   }
1043 }
1044
1045 static GstElementStateReturn
1046 gst_base_src_change_state (GstElement * element)
1047 {
1048   GstBaseSrc *basesrc;
1049   GstElementStateReturn result = GST_STATE_SUCCESS;
1050   GstElementStateReturn presult;
1051   GstElementState transition;
1052
1053   basesrc = GST_BASE_SRC (element);
1054
1055   transition = GST_STATE_TRANSITION (element);
1056
1057   switch (transition) {
1058     case GST_STATE_NULL_TO_READY:
1059       break;
1060     case GST_STATE_READY_TO_PAUSED:
1061       GST_LIVE_LOCK (element);
1062       if (basesrc->is_live) {
1063         result = GST_STATE_NO_PREROLL;
1064         basesrc->live_running = FALSE;
1065       }
1066       GST_LIVE_UNLOCK (element);
1067       break;
1068     case GST_STATE_PAUSED_TO_PLAYING:
1069       GST_LIVE_LOCK (element);
1070       if (basesrc->is_live) {
1071         basesrc->live_running = TRUE;
1072         GST_LIVE_SIGNAL (element);
1073       }
1074       GST_LIVE_UNLOCK (element);
1075       break;
1076     default:
1077       break;
1078   }
1079
1080   if ((presult = GST_ELEMENT_CLASS (parent_class)->change_state (element)) !=
1081       GST_STATE_SUCCESS)
1082     return presult;
1083
1084   switch (transition) {
1085     case GST_STATE_PLAYING_TO_PAUSED:
1086       GST_LIVE_LOCK (element);
1087       if (basesrc->is_live) {
1088         result = GST_STATE_NO_PREROLL;
1089         basesrc->live_running = FALSE;
1090       }
1091       GST_LIVE_UNLOCK (element);
1092       break;
1093     case GST_STATE_PAUSED_TO_READY:
1094       if (!gst_base_src_stop (basesrc))
1095         result = GST_STATE_FAILURE;
1096       break;
1097     case GST_STATE_READY_TO_NULL:
1098       break;
1099     default:
1100       break;
1101   }
1102
1103   return result;
1104 }