Merge remote-tracking branch 'origin/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
61 GST_DEBUG_CATEGORY_STATIC (gst_push_src_debug);
62 #define GST_CAT_DEFAULT gst_push_src_debug
63
64 #define _do_init \
65     GST_DEBUG_CATEGORY_INIT (gst_push_src_debug, "pushsrc", 0, \
66         "pushsrc element");
67
68 #define gst_push_src_parent_class parent_class
69 G_DEFINE_TYPE_WITH_CODE (GstPushSrc, gst_push_src, GST_TYPE_BASE_SRC, _do_init);
70
71 static gboolean gst_push_src_query (GstBaseSrc * src, GstQuery * query);
72 static GstFlowReturn gst_push_src_create (GstBaseSrc * bsrc, guint64 offset,
73     guint length, GstBuffer ** ret);
74 static GstFlowReturn gst_push_src_alloc (GstBaseSrc * bsrc, guint64 offset,
75     guint length, GstBuffer ** ret);
76 static GstFlowReturn gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset,
77     guint length, GstBuffer * ret);
78
79 static void
80 gst_push_src_class_init (GstPushSrcClass * klass)
81 {
82   GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
83
84   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_push_src_create);
85   gstbasesrc_class->alloc = GST_DEBUG_FUNCPTR (gst_push_src_alloc);
86   gstbasesrc_class->fill = GST_DEBUG_FUNCPTR (gst_push_src_fill);
87   gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_push_src_query);
88 }
89
90 static void
91 gst_push_src_init (GstPushSrc * pushsrc)
92 {
93   /* nop */
94 }
95
96 static gboolean
97 gst_push_src_query (GstBaseSrc * src, GstQuery * query)
98 {
99   gboolean ret;
100
101   switch (GST_QUERY_TYPE (query)) {
102     case GST_QUERY_SCHEDULING:
103     {
104       /* a pushsrc can by default never operate in pull mode override
105        * if you want something different. */
106       gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEQUENTIAL, 1, -1,
107           0);
108       gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
109
110       ret = TRUE;
111       break;
112     }
113     default:
114       ret = GST_BASE_SRC_CLASS (parent_class)->query (src, query);
115       break;
116   }
117   return ret;
118 }
119
120
121 static GstFlowReturn
122 gst_push_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
123     GstBuffer ** ret)
124 {
125   GstFlowReturn fret;
126   GstPushSrc *src;
127   GstPushSrcClass *pclass;
128
129   src = GST_PUSH_SRC (bsrc);
130   pclass = GST_PUSH_SRC_GET_CLASS (src);
131   if (pclass->create)
132     fret = pclass->create (src, ret);
133   else
134     fret =
135         GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, ret);
136
137   return fret;
138 }
139
140 static GstFlowReturn
141 gst_push_src_alloc (GstBaseSrc * bsrc, guint64 offset, guint length,
142     GstBuffer ** ret)
143 {
144   GstFlowReturn fret;
145   GstPushSrc *src;
146   GstPushSrcClass *pclass;
147
148   src = GST_PUSH_SRC (bsrc);
149   pclass = GST_PUSH_SRC_GET_CLASS (src);
150   if (pclass->alloc)
151     fret = pclass->alloc (src, ret);
152   else
153     fret = GST_BASE_SRC_CLASS (parent_class)->alloc (bsrc, offset, length, ret);
154
155   return fret;
156 }
157
158 static GstFlowReturn
159 gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset, guint length,
160     GstBuffer * ret)
161 {
162   GstFlowReturn fret;
163   GstPushSrc *src;
164   GstPushSrcClass *pclass;
165
166   src = GST_PUSH_SRC (bsrc);
167   pclass = GST_PUSH_SRC_GET_CLASS (src);
168   if (pclass->fill)
169     fret = pclass->fill (src, ret);
170   else
171     fret = GST_BASE_SRC_CLASS (parent_class)->fill (bsrc, offset, length, ret);
172
173   return fret;
174 }