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