Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / libs / gst / base / gstpushsrc.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *               2000,2005 Wim Taymans <wim@fluendo.com>
4  *
5  * gstpushsrc.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:gstpushsrc
25  * @short_description: Base class for push based source elements
26  * @see_also: #GstBaseSrc
27  *
28  * This class is mostly useful for elements that cannot do
29  * random access, or at least very slowly. The source usually
30  * prefers to push out a fixed size buffer.
31  *
32  * Subclasses usually operate in a format that is different from the
33  * default GST_FORMAT_BYTES format of #GstBaseSrc.
34  *
35  * Classes extending this base class will usually be scheduled
36  * in a push based mode. If the peer accepts to operate without
37  * offsets and within the limits of the allowed block size, this
38  * class can operate in getrange based mode automatically. To make
39  * this possible, the subclass should implement and override the
40  * SCHEDULING query.
41  *
42  * The subclass should extend the methods from the baseclass in
43  * addition to the ::create method.
44  *
45  * Seeking, flushing, scheduling and sync is all handled by this
46  * base class.
47  *
48  * Last reviewed on 2006-07-04 (0.10.9)
49  */
50
51 #ifdef HAVE_CONFIG_H
52 #  include "config.h"
53 #endif
54
55 #include <stdlib.h>
56 #include <string.h>
57
58 #include "gstpushsrc.h"
59 #include "gsttypefindhelper.h"
60 #include <gst/gstmarshal.h>
61
62 GST_DEBUG_CATEGORY_STATIC (gst_push_src_debug);
63 #define GST_CAT_DEFAULT gst_push_src_debug
64
65 #define _do_init \
66     GST_DEBUG_CATEGORY_INIT (gst_push_src_debug, "pushsrc", 0, \
67         "pushsrc element");
68
69 #define gst_push_src_parent_class parent_class
70 G_DEFINE_TYPE_WITH_CODE (GstPushSrc, gst_push_src, GST_TYPE_BASE_SRC, _do_init);
71
72 static gboolean gst_push_src_query (GstBaseSrc * src, GstQuery * query);
73 static GstFlowReturn gst_push_src_create (GstBaseSrc * bsrc, guint64 offset,
74     guint length, GstBuffer ** ret);
75 static GstFlowReturn gst_push_src_alloc (GstBaseSrc * bsrc, guint64 offset,
76     guint length, GstBuffer ** ret);
77 static GstFlowReturn gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset,
78     guint length, GstBuffer * ret);
79
80 static void
81 gst_push_src_class_init (GstPushSrcClass * klass)
82 {
83   GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
84
85   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_push_src_create);
86   gstbasesrc_class->alloc = GST_DEBUG_FUNCPTR (gst_push_src_alloc);
87   gstbasesrc_class->fill = GST_DEBUG_FUNCPTR (gst_push_src_fill);
88   gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_push_src_query);
89 }
90
91 static void
92 gst_push_src_init (GstPushSrc * pushsrc)
93 {
94   /* nop */
95 }
96
97 static gboolean
98 gst_push_src_query (GstBaseSrc * src, GstQuery * query)
99 {
100   gboolean ret;
101
102   switch (GST_QUERY_TYPE (query)) {
103     case GST_QUERY_SCHEDULING:
104     {
105       /* a pushsrc can by default never operate in pull mode override
106        * if you want something different. */
107       gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEQUENTIAL, 1, -1,
108           0);
109       gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
110
111       ret = TRUE;
112       break;
113     }
114     default:
115       ret = GST_BASE_SRC_CLASS (parent_class)->query (src, query);
116       break;
117   }
118   return ret;
119 }
120
121
122 static GstFlowReturn
123 gst_push_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
124     GstBuffer ** ret)
125 {
126   GstFlowReturn fret;
127   GstPushSrc *src;
128   GstPushSrcClass *pclass;
129
130   src = GST_PUSH_SRC (bsrc);
131   pclass = GST_PUSH_SRC_GET_CLASS (src);
132   if (pclass->create)
133     fret = pclass->create (src, ret);
134   else
135     fret =
136         GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, ret);
137
138   return fret;
139 }
140
141 static GstFlowReturn
142 gst_push_src_alloc (GstBaseSrc * bsrc, guint64 offset, guint length,
143     GstBuffer ** ret)
144 {
145   GstFlowReturn fret;
146   GstPushSrc *src;
147   GstPushSrcClass *pclass;
148
149   src = GST_PUSH_SRC (bsrc);
150   pclass = GST_PUSH_SRC_GET_CLASS (src);
151   if (pclass->alloc)
152     fret = pclass->alloc (src, ret);
153   else
154     fret = GST_BASE_SRC_CLASS (parent_class)->alloc (bsrc, offset, length, ret);
155
156   return fret;
157 }
158
159 static GstFlowReturn
160 gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset, guint length,
161     GstBuffer * ret)
162 {
163   GstFlowReturn fret;
164   GstPushSrc *src;
165   GstPushSrcClass *pclass;
166
167   src = GST_PUSH_SRC (bsrc);
168   pclass = GST_PUSH_SRC_GET_CLASS (src);
169   if (pclass->fill)
170     fret = pclass->fill (src, ret);
171   else
172     fret = GST_BASE_SRC_CLASS (parent_class)->fill (bsrc, offset, length, ret);
173
174   return fret;
175 }