tests: transform1: make test work with CK_FORK=no
[platform/upstream/gstreamer.git] / tests / check / libs / test_transform.c
1
2 #include <gst/base/gstbasetransform.h>
3
4 typedef struct
5 {
6   GstPad *srcpad;
7   GstPad *sinkpad;
8   GList *events;
9   GList *buffers;
10   GstElement *trans;
11   GstBaseTransformClass *klass;
12 } TestTransData;
13
14 static GstStaticPadTemplate gst_test_trans_src_template =
15 GST_STATIC_PAD_TEMPLATE ("src",
16     GST_PAD_SRC,
17     GST_PAD_ALWAYS,
18     GST_STATIC_CAPS ("foo/x-bar")
19     );
20
21 static GstStaticPadTemplate gst_test_trans_sink_template =
22 GST_STATIC_PAD_TEMPLATE ("sink",
23     GST_PAD_SINK,
24     GST_PAD_ALWAYS,
25     GST_STATIC_CAPS ("foo/x-bar")
26     );
27
28 typedef struct _GstTestTrans GstTestTrans;
29 typedef struct _GstTestTransClass GstTestTransClass;
30
31 #define GST_TEST_TRANS(obj) ((GstTestTrans *)(obj))
32
33 struct _GstTestTrans
34 {
35   GstBaseTransform element;
36
37   TestTransData *data;
38 };
39
40 struct _GstTestTransClass
41 {
42   GstBaseTransformClass parent_class;
43 };
44
45 static GstFlowReturn (*klass_transform) (GstBaseTransform * trans,
46     GstBuffer * inbuf, GstBuffer * outbuf) = NULL;
47 static GstFlowReturn (*klass_transform_ip) (GstBaseTransform * trans,
48     GstBuffer * buf) = NULL;
49 static gboolean (*klass_set_caps) (GstBaseTransform * trans, GstCaps * incaps,
50     GstCaps * outcaps) = NULL;
51 static GstCaps *(*klass_transform_caps) (GstBaseTransform * trans,
52     GstPadDirection direction, GstCaps * caps, GstCaps * filter) = NULL;
53 static gboolean (*klass_transform_size) (GstBaseTransform * trans,
54     GstPadDirection direction, GstCaps * caps, gsize size, GstCaps * othercaps,
55     gsize * othersize) = NULL;
56 static gboolean klass_passthrough_on_same_caps = FALSE;
57 GstFlowReturn (*klass_submit_input_buffer) (GstBaseTransform * trans,
58     gboolean is_discont, GstBuffer * input) = NULL;
59 GstFlowReturn (*klass_generate_output) (GstBaseTransform * trans,
60     GstBuffer ** outbuf) = NULL;
61
62 static GstStaticPadTemplate *sink_template = &gst_test_trans_sink_template;
63 static GstStaticPadTemplate *src_template = &gst_test_trans_src_template;
64
65 static void
66 gst_test_trans_class_init (GstTestTransClass * klass)
67 {
68   GstElementClass *element_class;
69   GstBaseTransformClass *trans_class;
70
71   element_class = (GstElementClass *) klass;
72   trans_class = (GstBaseTransformClass *) klass;
73
74   gst_element_class_set_metadata (element_class, "TestTrans",
75       "Filter/Test", "Test transform", "Wim Taymans <wim.taymans@gmail.com>");
76
77   gst_element_class_add_static_pad_template (element_class, sink_template);
78   gst_element_class_add_static_pad_template (element_class, src_template);
79
80   GST_INFO ("setting up %s", g_type_name (((GTypeClass *) klass)->g_type));
81
82   trans_class->passthrough_on_same_caps = klass_passthrough_on_same_caps;
83   if (klass_transform_ip != NULL)
84     trans_class->transform_ip = klass_transform_ip;
85   if (klass_transform != NULL)
86     trans_class->transform = klass_transform;
87   if (klass_transform_caps != NULL)
88     trans_class->transform_caps = klass_transform_caps;
89   if (klass_transform_size != NULL)
90     trans_class->transform_size = klass_transform_size;
91   if (klass_set_caps != NULL)
92     trans_class->set_caps = klass_set_caps;
93   if (klass_submit_input_buffer != NULL)
94     trans_class->submit_input_buffer = klass_submit_input_buffer;
95   if (klass_generate_output)
96     trans_class->generate_output = klass_generate_output;
97 }
98
99 static void
100 gst_test_trans_init (GstTestTrans * this)
101 {
102 }
103
104 static void
105 gst_test_trans_set_data (GstTestTrans * this, TestTransData * data)
106 {
107   this->data = data;
108 }
109
110 static GstFlowReturn
111 result_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
112 {
113   TestTransData *data;
114
115   data = gst_pad_get_element_private (pad);
116
117   data->buffers = g_list_append (data->buffers, buffer);
118
119   return GST_FLOW_OK;
120 }
121
122 #if 0
123 static GstFlowReturn
124 result_buffer_alloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
125     GstBuffer ** buf)
126 {
127   GstFlowReturn res;
128   TestTransData *data;
129
130   data = gst_pad_get_element_private (pad);
131
132   *buf = gst_buffer_new_and_alloc (size);
133   gst_buffer_set_caps (*buf, caps);
134   res = GST_FLOW_OK;
135
136   return res;
137 }
138 #endif
139
140 static TestTransData *
141 gst_test_trans_new (void)
142 {
143   TestTransData *res;
144   GstPad *tmp;
145   GstPadTemplate *templ;
146   GType type;
147
148   /* we register a new sub-class for every test-run, so the class init
149    * function is called for every test run and can be set up properly
150    * even with CK_FORK=no */
151   {
152     static gint counter = 0;
153     gchar name[100];
154
155     g_snprintf (name, sizeof (name), "GstTestTrans%d", ++counter);
156
157     type = g_type_register_static_simple (GST_TYPE_BASE_TRANSFORM, name,
158         sizeof (GstTestTransClass), (GClassInitFunc) gst_test_trans_class_init,
159         sizeof (GstTestTrans), (GInstanceInitFunc) gst_test_trans_init, 0);
160   }
161
162   res = g_new0 (TestTransData, 1);
163   res->trans = g_object_new (type, NULL);
164
165   templ = gst_static_pad_template_get (sink_template);
166   templ->direction = GST_PAD_SRC;
167   res->srcpad = gst_pad_new_from_template (templ, "src");
168   gst_object_unref (templ);
169
170   templ = gst_static_pad_template_get (src_template);
171   templ->direction = GST_PAD_SINK;
172   res->sinkpad = gst_pad_new_from_template (templ, "sink");
173   gst_object_unref (templ);
174
175   res->klass = GST_BASE_TRANSFORM_GET_CLASS (res->trans);
176
177   gst_test_trans_set_data (GST_TEST_TRANS (res->trans), res);
178   gst_pad_set_element_private (res->sinkpad, res);
179
180   gst_pad_set_chain_function (res->sinkpad, result_sink_chain);
181
182   tmp = gst_element_get_static_pad (res->trans, "sink");
183   gst_pad_link (res->srcpad, tmp);
184   gst_object_unref (tmp);
185
186   tmp = gst_element_get_static_pad (res->trans, "src");
187   gst_pad_link (tmp, res->sinkpad);
188   gst_object_unref (tmp);
189
190   gst_pad_set_active (res->sinkpad, TRUE);
191   gst_element_set_state (res->trans, GST_STATE_PAUSED);
192   gst_pad_set_active (res->srcpad, TRUE);
193
194   gst_pad_push_event (res->srcpad, gst_event_new_stream_start ("test"));
195
196   return res;
197 }
198
199 static void
200 gst_test_trans_free (TestTransData * data)
201 {
202   GstPad *tmp;
203
204   gst_pad_set_active (data->sinkpad, FALSE);
205   gst_element_set_state (data->trans, GST_STATE_NULL);
206   gst_pad_set_active (data->srcpad, FALSE);
207
208   tmp = gst_element_get_static_pad (data->trans, "src");
209   gst_pad_unlink (tmp, data->sinkpad);
210   gst_object_unref (tmp);
211
212   tmp = gst_element_get_static_pad (data->trans, "sink");
213   gst_pad_link (data->srcpad, tmp);
214   gst_object_unref (tmp);
215
216   gst_object_unref (data->srcpad);
217   gst_object_unref (data->sinkpad);
218   gst_object_unref (data->trans);
219
220   g_free (data);
221 }
222
223 static GstFlowReturn
224 gst_test_trans_push (TestTransData * data, GstBuffer * buffer)
225 {
226   GstFlowReturn ret;
227
228   ret = gst_pad_push (data->srcpad, buffer);
229
230   return ret;
231 }
232
233 static GstBuffer *
234 gst_test_trans_pop (TestTransData * data)
235 {
236   GstBuffer *ret;
237
238   if (data->buffers) {
239     ret = data->buffers->data;
240     data->buffers = g_list_delete_link (data->buffers, data->buffers);
241   } else {
242     ret = NULL;
243   }
244   return ret;
245 }
246
247 static gboolean
248 gst_test_trans_setcaps (TestTransData * data, GstCaps * caps)
249 {
250   return gst_pad_set_caps (data->srcpad, caps);
251 }
252
253 static gboolean
254 gst_test_trans_push_segment (TestTransData * data)
255 {
256   GstSegment segment;
257
258   gst_segment_init (&segment, GST_FORMAT_TIME);
259
260   return gst_pad_push_event (data->srcpad, gst_event_new_segment (&segment));
261 }