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