tests: transform1: make test work with CK_FORK=no
[platform/upstream/gstreamer.git] / tests / check / libs / transform1.c
1 /* GStreamer
2  *
3  * some unit tests for GstBaseTransform
4  *
5  * Copyright (C) 2008 Wim Taymans <wim.taymans@gmail.com>
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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #include <gst/gst.h>
27 #include <gst/check/gstcheck.h>
28 #include <gst/base/gstbasetransform.h>
29
30 #include "test_transform.c"
31
32 static gboolean set_caps_pt1_called;
33
34 static gboolean
35 set_caps_pt1 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
36 {
37   GST_DEBUG_OBJECT (trans, "set_caps called");
38
39   set_caps_pt1_called = TRUE;
40
41   return TRUE;
42 }
43
44 /* basic passthrough, we don't have any transform functions so we can only
45  * perform passthrough. We also don't have caps, which is fine */
46 GST_START_TEST (basetransform_chain_pt1)
47 {
48   TestTransData *trans;
49   GstBuffer *buffer;
50   GstFlowReturn res;
51   GstCaps *caps;
52
53   klass_set_caps = set_caps_pt1;
54   trans = gst_test_trans_new ();
55
56   gst_test_trans_push_segment (trans);
57
58   GST_DEBUG_OBJECT (trans, "buffer without caps, size 20");
59
60   buffer = gst_buffer_new_and_alloc (20);
61
62   set_caps_pt1_called = FALSE;
63   res = gst_test_trans_push (trans, buffer);
64   fail_unless (res == GST_FLOW_OK);
65   fail_unless (set_caps_pt1_called == FALSE);
66
67   buffer = gst_test_trans_pop (trans);
68   fail_unless (buffer != NULL);
69   fail_unless (gst_buffer_get_size (buffer) == 20);
70
71   gst_buffer_unref (buffer);
72
73   GST_DEBUG_OBJECT (trans, "buffer without caps, size 10");
74
75   buffer = gst_buffer_new_and_alloc (10);
76   set_caps_pt1_called = FALSE;
77   res = gst_test_trans_push (trans, buffer);
78   fail_unless (res == GST_FLOW_OK);
79   fail_unless (set_caps_pt1_called == FALSE);
80
81   buffer = gst_test_trans_pop (trans);
82   fail_unless (buffer != NULL);
83   fail_unless (gst_buffer_get_size (buffer) == 10);
84
85   gst_buffer_unref (buffer);
86
87   gst_pad_push_event (trans->srcpad, gst_event_new_flush_start ());
88   gst_pad_push_event (trans->srcpad, gst_event_new_flush_stop (TRUE));
89
90   caps = gst_caps_new_empty_simple ("foo/x-bar");
91   set_caps_pt1_called = FALSE;
92   gst_test_trans_setcaps (trans, caps);
93   fail_unless (set_caps_pt1_called == TRUE);
94   gst_caps_unref (caps);
95
96   gst_test_trans_push_segment (trans);
97
98   gst_test_trans_free (trans);
99
100   klass_transform_ip = NULL;
101   klass_transform = NULL;
102   klass_transform_caps = NULL;
103   klass_transform_size = NULL;
104   klass_set_caps = NULL;
105   klass_submit_input_buffer = NULL;
106   klass_generate_output = NULL;
107 }
108
109 GST_END_TEST;
110
111 static gboolean set_caps_pt2_called;
112
113 static gboolean
114 set_caps_pt2 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
115 {
116   GST_DEBUG_OBJECT (trans, "set_caps called");
117
118   set_caps_pt2_called = TRUE;
119
120   fail_unless (gst_caps_is_equal (incaps, outcaps));
121
122   return TRUE;
123 }
124
125 /* basic passthrough, we don't have any transform functions so we can only
126  * perform passthrough with same caps */
127 GST_START_TEST (basetransform_chain_pt2)
128 {
129   TestTransData *trans;
130   GstBuffer *buffer;
131   GstCaps *caps;
132   GstFlowReturn res;
133
134   klass_set_caps = set_caps_pt2;
135   trans = gst_test_trans_new ();
136
137   /* first buffer */
138   set_caps_pt2_called = FALSE;
139   caps = gst_caps_new_empty_simple ("foo/x-bar");
140   gst_test_trans_setcaps (trans, caps);
141   gst_test_trans_push_segment (trans);
142
143   GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
144
145   buffer = gst_buffer_new_and_alloc (20);
146
147   res = gst_test_trans_push (trans, buffer);
148   fail_unless (res == GST_FLOW_OK);
149   fail_unless (set_caps_pt2_called == TRUE);
150
151   buffer = gst_test_trans_pop (trans);
152   fail_unless (buffer != NULL);
153   fail_unless (gst_buffer_get_size (buffer) == 20);
154
155   gst_buffer_unref (buffer);
156
157   gst_caps_unref (caps);
158
159   /* second buffer, renegotiates, keeps extra type arg in caps */
160   caps = gst_caps_new_simple ("foo/x-bar", "type", G_TYPE_INT, 1, NULL);
161   set_caps_pt2_called = FALSE;
162   gst_test_trans_setcaps (trans, caps);
163
164   GST_DEBUG_OBJECT (trans, "buffer with caps, size 10");
165
166   buffer = gst_buffer_new_and_alloc (10);
167
168   res = gst_test_trans_push (trans, buffer);
169   fail_unless (res == GST_FLOW_OK);
170   fail_unless (set_caps_pt2_called == TRUE);
171
172   buffer = gst_test_trans_pop (trans);
173   fail_unless (buffer != NULL);
174   fail_unless (gst_buffer_get_size (buffer) == 10);
175
176   gst_buffer_unref (buffer);
177
178   gst_caps_unref (caps);
179
180   /* with caps that is a superset */
181   caps = gst_caps_new_empty_simple ("foo/x-bar");
182   set_caps_pt2_called = FALSE;
183   gst_test_trans_setcaps (trans, caps);
184
185   GST_DEBUG_OBJECT (trans, "buffer with caps, size 10");
186
187   buffer = gst_buffer_new_and_alloc (10);
188
189   res = gst_test_trans_push (trans, buffer);
190   fail_unless (res == GST_FLOW_OK);
191   fail_unless (set_caps_pt2_called == TRUE);
192
193   buffer = gst_test_trans_pop (trans);
194   fail_unless (buffer != NULL);
195   fail_unless (gst_buffer_get_size (buffer) == 10);
196
197   gst_buffer_unref (buffer);
198
199   gst_caps_unref (caps);
200
201   gst_test_trans_free (trans);
202 }
203
204 GST_END_TEST;
205
206 static gboolean transform_ip_1_called;
207 static gboolean transform_ip_1_writable;
208
209 static GstFlowReturn
210 transform_ip_1 (GstBaseTransform * trans, GstBuffer * buf)
211 {
212   GST_DEBUG_OBJECT (trans, "transform called");
213
214   transform_ip_1_called = TRUE;
215   transform_ip_1_writable = gst_buffer_is_writable (buf);
216
217   GST_DEBUG_OBJECT (trans, "writable: %d", transform_ip_1_writable);
218
219   return GST_FLOW_OK;
220 }
221
222 /* basic in-place, check if the _ip function is called, buffer should
223  * be writable. no setcaps is set */
224 GST_START_TEST (basetransform_chain_ip1)
225 {
226   TestTransData *trans;
227   GstBuffer *buffer;
228   GstFlowReturn res;
229
230   klass_transform_ip = transform_ip_1;
231   trans = gst_test_trans_new ();
232
233   gst_test_trans_push_segment (trans);
234
235   GST_DEBUG_OBJECT (trans, "buffer without caps, size 20");
236
237   buffer = gst_buffer_new_and_alloc (20);
238
239   transform_ip_1_called = FALSE;
240   transform_ip_1_writable = TRUE;
241   res = gst_test_trans_push (trans, buffer);
242   fail_unless (res == GST_FLOW_OK);
243   fail_unless (transform_ip_1_called == TRUE);
244   fail_unless (transform_ip_1_writable == TRUE);
245
246   buffer = gst_test_trans_pop (trans);
247   fail_unless (buffer != NULL);
248   fail_unless (gst_buffer_get_size (buffer) == 20);
249   gst_buffer_unref (buffer);
250
251   GST_DEBUG_OBJECT (trans, "buffer without caps extra ref, size 20");
252
253   buffer = gst_buffer_new_and_alloc (20);
254   /* take additional ref to make it non-writable */
255   gst_buffer_ref (buffer);
256
257   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
258
259   transform_ip_1_called = FALSE;
260   transform_ip_1_writable = FALSE;
261   res = gst_test_trans_push (trans, buffer);
262   fail_unless (res == GST_FLOW_OK);
263   fail_unless (transform_ip_1_called == TRUE);
264   /* copy should have been taken with pad-alloc */
265   fail_unless (transform_ip_1_writable == TRUE);
266   /* after push, get rid of the final ref we had */
267   gst_buffer_unref (buffer);
268
269   buffer = gst_test_trans_pop (trans);
270   fail_unless (buffer != NULL);
271   fail_unless (gst_buffer_get_size (buffer) == 20);
272
273   /* output buffer has refcount 1 */
274   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
275   gst_buffer_unref (buffer);
276
277   /* with caps buffer */
278   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
279
280   gst_test_trans_free (trans);
281 }
282
283 GST_END_TEST;
284
285 static gboolean set_caps_1_called;
286
287 static gboolean
288 set_caps_1 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
289 {
290   GstCaps *caps;
291
292   GST_DEBUG_OBJECT (trans, "set_caps called");
293
294   set_caps_1_called = TRUE;
295
296   caps = gst_caps_new_empty_simple ("foo/x-bar");
297
298   fail_unless (gst_caps_is_equal (incaps, caps));
299   fail_unless (gst_caps_is_equal (outcaps, caps));
300
301   gst_caps_unref (caps);
302
303   return TRUE;
304 }
305
306 /* basic in-place, check if the _ip function is called, buffer should be
307  * writable. we also set a setcaps function and see if it's called. */
308 GST_START_TEST (basetransform_chain_ip2)
309 {
310   TestTransData *trans;
311   GstBuffer *buffer;
312   GstFlowReturn res;
313   GstCaps *caps;
314
315   klass_transform_ip = transform_ip_1;
316   klass_set_caps = set_caps_1;
317
318   trans = gst_test_trans_new ();
319
320   caps = gst_caps_new_empty_simple ("foo/x-bar");
321   gst_test_trans_push_segment (trans);
322
323   /* first try to push a buffer without caps, this should fail */
324   buffer = gst_buffer_new_and_alloc (20);
325
326   GST_DEBUG_OBJECT (trans, "buffer without caps, size 20");
327
328   transform_ip_1_called = FALSE;
329   transform_ip_1_writable = FALSE;
330   set_caps_1_called = FALSE;
331   res = gst_test_trans_push (trans, buffer);
332   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
333   fail_unless (transform_ip_1_called == FALSE);
334   fail_unless (transform_ip_1_writable == FALSE);
335   fail_unless (set_caps_1_called == FALSE);
336
337   /* try to push a buffer with caps */
338   gst_pad_push_event (trans->srcpad, gst_event_new_flush_start ());
339   gst_pad_push_event (trans->srcpad, gst_event_new_flush_stop (TRUE));
340
341   set_caps_1_called = FALSE;
342   gst_test_trans_setcaps (trans, caps);
343   gst_test_trans_push_segment (trans);
344
345   GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
346
347   buffer = gst_buffer_new_and_alloc (20);
348
349   transform_ip_1_called = FALSE;
350   transform_ip_1_writable = FALSE;
351   res = gst_test_trans_push (trans, buffer);
352   fail_unless (res == GST_FLOW_OK);
353   fail_unless (transform_ip_1_called == TRUE);
354   fail_unless (transform_ip_1_writable == TRUE);
355   fail_unless (set_caps_1_called == TRUE);
356
357   buffer = gst_test_trans_pop (trans);
358   fail_unless (buffer != NULL);
359   fail_unless (gst_buffer_get_size (buffer) == 20);
360   gst_buffer_unref (buffer);
361
362   GST_DEBUG_OBJECT (trans, "buffer with caps extra ref, size 20");
363
364   buffer = gst_buffer_new_and_alloc (20);
365   /* take additional ref to make it non-writable */
366   gst_buffer_ref (buffer);
367
368   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
369
370   transform_ip_1_called = FALSE;
371   transform_ip_1_writable = FALSE;
372   res = gst_test_trans_push (trans, buffer);
373   fail_unless (res == GST_FLOW_OK);
374   fail_unless (transform_ip_1_called == TRUE);
375   fail_unless (transform_ip_1_writable == TRUE);
376   /* after push, get rid of the final ref we had */
377   gst_buffer_unref (buffer);
378
379   buffer = gst_test_trans_pop (trans);
380   fail_unless (buffer != NULL);
381   fail_unless (gst_buffer_get_size (buffer) == 20);
382
383   /* output buffer has refcount 1 */
384   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
385   gst_buffer_unref (buffer);
386
387   gst_caps_unref (caps);
388
389   gst_test_trans_free (trans);
390 }
391
392 GST_END_TEST;
393
394 static GstStaticPadTemplate sink_template_ct1 = GST_STATIC_PAD_TEMPLATE ("sink",
395     GST_PAD_SINK,
396     GST_PAD_ALWAYS,
397     GST_STATIC_CAPS ("baz/x-foo")
398     );
399
400 static gboolean set_caps_ct1_called;
401
402 static gboolean
403 set_caps_ct1 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
404 {
405   GstCaps *caps1, *caps2;
406
407   GST_DEBUG_OBJECT (trans, "set_caps called");
408
409   caps1 = gst_caps_new_empty_simple ("baz/x-foo");
410   caps2 = gst_caps_new_empty_simple ("foo/x-bar");
411
412   fail_unless (gst_caps_is_equal (incaps, caps1));
413   fail_unless (gst_caps_is_equal (outcaps, caps2));
414
415   set_caps_ct1_called = TRUE;
416
417   gst_caps_unref (caps1);
418   gst_caps_unref (caps2);
419
420   return TRUE;
421 }
422
423 static gboolean transform_ct1_called;
424 static gboolean transform_ct1_writable;
425
426 static GstFlowReturn
427 transform_ct1 (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
428 {
429   transform_ct1_called = TRUE;
430   transform_ct1_writable = gst_buffer_is_writable (out);
431
432   GST_DEBUG_OBJECT (trans, "writable: %d", transform_ct1_writable);
433
434   return GST_FLOW_OK;
435 }
436
437 static GstCaps *
438 transform_caps_ct1 (GstBaseTransform * trans, GstPadDirection dir,
439     GstCaps * caps, GstCaps * filter)
440 {
441   GstCaps *res;
442
443   if (dir == GST_PAD_SINK) {
444     res = gst_caps_new_empty_simple ("foo/x-bar");
445   } else {
446     res = gst_caps_new_empty_simple ("baz/x-foo");
447   }
448
449   if (filter) {
450     GstCaps *temp =
451         gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
452     gst_caps_unref (res);
453     res = temp;
454   }
455
456   return res;
457 }
458
459 static gboolean
460 transform_size_ct1 (GstBaseTransform * trans, GstPadDirection direction,
461     GstCaps * caps, gsize size, GstCaps * othercaps, gsize * othersize)
462 {
463   if (direction == GST_PAD_SINK) {
464     *othersize = size * 2;
465   } else {
466     *othersize = size / 2;
467   }
468
469   return TRUE;
470 }
471
472 /* basic copy-transform, check if the transform function is called,
473  * buffer should be writable. we also set a setcaps function and
474  * see if it's called. */
475 GST_START_TEST (basetransform_chain_ct1)
476 {
477   TestTransData *trans;
478   GstBuffer *buffer;
479   GstFlowReturn res;
480   GstCaps *incaps, *outcaps;
481
482   sink_template = &sink_template_ct1;
483   klass_transform = transform_ct1;
484   klass_set_caps = set_caps_ct1;
485   klass_transform_caps = transform_caps_ct1;
486   klass_transform_size = transform_size_ct1;
487
488   trans = gst_test_trans_new ();
489
490   incaps = gst_caps_new_empty_simple ("baz/x-foo");
491   outcaps = gst_caps_new_empty_simple ("foo/x-bar");
492   gst_test_trans_push_segment (trans);
493
494   /* first try to push a buffer without caps, this should fail */
495   buffer = gst_buffer_new_and_alloc (20);
496
497   GST_DEBUG_OBJECT (trans, "buffer without caps");
498
499   transform_ct1_called = FALSE;
500   transform_ct1_writable = FALSE;
501   set_caps_ct1_called = FALSE;
502   res = gst_test_trans_push (trans, buffer);
503   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
504   fail_unless (transform_ct1_called == FALSE);
505   fail_unless (transform_ct1_writable == FALSE);
506   fail_unless (set_caps_ct1_called == FALSE);
507
508   /* try to push a buffer with caps */
509   gst_pad_push_event (trans->srcpad, gst_event_new_flush_start ());
510   gst_pad_push_event (trans->srcpad, gst_event_new_flush_stop (TRUE));
511
512   set_caps_ct1_called = FALSE;
513   gst_test_trans_setcaps (trans, incaps);
514   gst_test_trans_push_segment (trans);
515
516   buffer = gst_buffer_new_and_alloc (20);
517
518   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
519
520   transform_ct1_called = FALSE;
521   transform_ct1_writable = FALSE;
522   res = gst_test_trans_push (trans, buffer);
523   fail_unless (res == GST_FLOW_OK);
524   fail_unless (transform_ct1_called == TRUE);
525   fail_unless (transform_ct1_writable == TRUE);
526   fail_unless (set_caps_ct1_called == TRUE);
527
528   buffer = gst_test_trans_pop (trans);
529   fail_unless (buffer != NULL);
530   fail_unless (gst_buffer_get_size (buffer) == 40);
531   gst_buffer_unref (buffer);
532
533   buffer = gst_buffer_new_and_alloc (20);
534   /* take additional ref to make it non-writable */
535   gst_buffer_ref (buffer);
536
537   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
538
539   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
540
541   transform_ct1_called = FALSE;
542   transform_ct1_writable = FALSE;
543   res = gst_test_trans_push (trans, buffer);
544   fail_unless (res == GST_FLOW_OK);
545   fail_unless (transform_ct1_called == TRUE);
546   fail_unless (transform_ct1_writable == TRUE);
547   /* after push, get rid of the final ref we had */
548   gst_buffer_unref (buffer);
549
550   buffer = gst_test_trans_pop (trans);
551   fail_unless (buffer != NULL);
552   fail_unless (gst_buffer_get_size (buffer) == 40);
553
554   /* output buffer has refcount 1 */
555   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
556   gst_buffer_unref (buffer);
557
558   gst_caps_unref (incaps);
559   gst_caps_unref (outcaps);
560
561   gst_test_trans_free (trans);
562 }
563
564 GST_END_TEST;
565
566 static GstStaticPadTemplate src_template_ct2 = GST_STATIC_PAD_TEMPLATE ("src",
567     GST_PAD_SRC,
568     GST_PAD_ALWAYS,
569     GST_STATIC_CAPS ("baz/x-foo; foo/x-bar")
570     );
571
572 static gint set_caps_ct2_case;
573 static gboolean set_caps_ct2_called;
574
575 static gboolean
576 set_caps_ct2 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
577 {
578   GstCaps *caps1, *caps2;
579
580   GST_DEBUG_OBJECT (trans, "set_caps called");
581
582   caps1 = gst_caps_new_empty_simple ("foo/x-bar");
583
584   if (set_caps_ct2_case == 1)
585     caps2 = gst_caps_copy (caps1);
586   else
587     caps2 = gst_caps_new_empty_simple ("baz/x-foo");
588
589   fail_unless (gst_caps_is_equal (incaps, caps1));
590   fail_unless (gst_caps_is_equal (outcaps, caps2));
591
592   set_caps_ct2_called = TRUE;
593
594   gst_caps_unref (caps1);
595   gst_caps_unref (caps2);
596
597   return TRUE;
598 }
599
600 static gboolean transform_ct2_called;
601 static gboolean transform_ct2_writable;
602
603 static GstFlowReturn
604 transform_ct2 (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
605 {
606   transform_ct2_called = TRUE;
607   transform_ct2_writable = gst_buffer_is_writable (out);
608
609   GST_DEBUG_OBJECT (trans, "writable: %d", transform_ct2_writable);
610
611   return GST_FLOW_OK;
612 }
613
614 static GstCaps *
615 transform_caps_ct2 (GstBaseTransform * trans, GstPadDirection dir,
616     GstCaps * caps, GstCaps * filter)
617 {
618   GstCaps *res;
619
620   if (dir == GST_PAD_SINK) {
621     /* everything on the sinkpad can be transformed to the output formats */
622     if (set_caps_ct2_case == 1)
623       res = gst_caps_new_empty_simple ("foo/x-bar");
624     else
625       res = gst_caps_new_empty_simple ("baz/x-foo");
626   } else {
627     /* all on the srcpad can be transformed to the format of the sinkpad */
628     res = gst_caps_new_empty_simple ("foo/x-bar");
629   }
630
631   if (filter) {
632     GstCaps *temp =
633         gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
634     gst_caps_unref (res);
635     res = temp;
636   }
637
638   return res;
639 }
640
641 static gboolean
642 transform_size_ct2 (GstBaseTransform * trans, GstPadDirection direction,
643     GstCaps * caps, gsize size, GstCaps * othercaps, gsize * othersize)
644 {
645   if (gst_caps_is_equal (caps, othercaps)) {
646     *othersize = size;
647   } else {
648     if (direction == GST_PAD_SINK) {
649       *othersize = size * 2;
650     } else {
651       *othersize = size / 2;
652     }
653   }
654
655   return TRUE;
656 }
657
658 /* basic copy-transform, check if the transform function is called,
659  * buffer should be writable. we also set a setcaps function and
660  * see if it's called. */
661 GST_START_TEST (basetransform_chain_ct2)
662 {
663   TestTransData *trans;
664   GstBuffer *buffer;
665   GstFlowReturn res;
666   GstCaps *incaps, *outcaps;
667
668   src_template = &src_template_ct2;
669   klass_transform = transform_ct2;
670   klass_set_caps = set_caps_ct2;
671   klass_transform_caps = transform_caps_ct2;
672   klass_transform_size = transform_size_ct2;
673
674   trans = gst_test_trans_new ();
675
676   incaps = gst_caps_new_empty_simple ("foo/x-bar");
677   outcaps = gst_caps_new_empty_simple ("baz/x-foo");
678
679   gst_test_trans_push_segment (trans);
680
681   /* first try to push a buffer without caps, this should fail */
682   buffer = gst_buffer_new_and_alloc (20);
683
684   GST_DEBUG_OBJECT (trans, "buffer without caps");
685
686   transform_ct2_called = FALSE;
687   transform_ct2_writable = FALSE;
688   set_caps_ct2_called = FALSE;
689   res = gst_test_trans_push (trans, buffer);
690   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
691   fail_unless (transform_ct2_called == FALSE);
692   fail_unless (transform_ct2_writable == FALSE);
693   fail_unless (set_caps_ct2_called == FALSE);
694
695
696   /* try to push a buffer with caps */
697   gst_pad_push_event (trans->srcpad, gst_event_new_flush_start ());
698   gst_pad_push_event (trans->srcpad, gst_event_new_flush_stop (TRUE));
699
700   set_caps_ct2_case = 1;
701   set_caps_ct2_called = FALSE;
702   gst_test_trans_setcaps (trans, incaps);
703   gst_test_trans_push_segment (trans);
704
705   buffer = gst_buffer_new_and_alloc (20);
706
707   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
708
709   transform_ct2_called = FALSE;
710   transform_ct2_writable = FALSE;
711   res = gst_test_trans_push (trans, buffer);
712   fail_unless (res == GST_FLOW_OK);
713   fail_unless (transform_ct2_called == TRUE);
714   fail_unless (transform_ct2_writable == TRUE);
715   fail_unless (set_caps_ct2_called == TRUE);
716
717   buffer = gst_test_trans_pop (trans);
718   fail_unless (buffer != NULL);
719   fail_unless (gst_buffer_get_size (buffer) == 20);
720   gst_buffer_unref (buffer);
721
722   buffer = gst_buffer_new_and_alloc (20);
723   /* take additional ref to make it non-writable */
724   gst_buffer_ref (buffer);
725
726   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
727
728   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
729
730   transform_ct2_called = FALSE;
731   transform_ct2_writable = FALSE;
732   res = gst_test_trans_push (trans, buffer);
733   fail_unless (res == GST_FLOW_OK);
734   fail_unless (transform_ct2_called == TRUE);
735   fail_unless (transform_ct2_writable == TRUE);
736   /* after push, get rid of the final ref we had */
737   gst_buffer_unref (buffer);
738
739   buffer = gst_test_trans_pop (trans);
740   fail_unless (buffer != NULL);
741   fail_unless (gst_buffer_get_size (buffer) == 20);
742
743   /* output buffer has refcount 1 */
744   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
745   gst_buffer_unref (buffer);
746
747   gst_caps_unref (incaps);
748   gst_caps_unref (outcaps);
749
750   gst_test_trans_free (trans);
751 }
752
753 GST_END_TEST;
754
755 /* basic copy-transform, we work in passthrough here. */
756 GST_START_TEST (basetransform_chain_ct3)
757 {
758   TestTransData *trans;
759   GstBuffer *buffer;
760   GstFlowReturn res;
761   GstCaps *incaps, *outcaps;
762
763   src_template = &src_template_ct2;
764   klass_passthrough_on_same_caps = TRUE;
765   klass_transform = transform_ct2;
766   klass_set_caps = set_caps_ct2;
767   klass_transform_caps = transform_caps_ct2;
768   klass_transform_size = transform_size_ct2;
769
770   trans = gst_test_trans_new ();
771
772   incaps = gst_caps_new_empty_simple ("foo/x-bar");
773   outcaps = gst_caps_new_empty_simple ("baz/x-foo");
774
775   /* with passthrough caps */
776   gst_test_trans_push_segment (trans);
777   GST_DEBUG_OBJECT (trans, "alloc size 20, with passthrough caps %"
778       GST_PTR_FORMAT, incaps);
779
780   /* first try to push a buffer without caps, this should fail */
781   buffer = gst_buffer_new_and_alloc (20);
782
783   GST_DEBUG_OBJECT (trans, "buffer without caps");
784
785   transform_ct2_called = FALSE;
786   transform_ct2_writable = FALSE;
787   set_caps_ct2_called = FALSE;
788   res = gst_test_trans_push (trans, buffer);
789   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
790   fail_unless (transform_ct2_called == FALSE);
791   fail_unless (transform_ct2_writable == FALSE);
792   fail_unless (set_caps_ct2_called == FALSE);
793
794   /* try to push a buffer with caps */
795   buffer = gst_buffer_new_and_alloc (20);
796
797   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
798
799   gst_pad_push_event (trans->srcpad, gst_event_new_flush_start ());
800   gst_pad_push_event (trans->srcpad, gst_event_new_flush_stop (TRUE));
801
802   set_caps_ct2_case = 1;
803   set_caps_ct2_called = FALSE;
804   gst_test_trans_setcaps (trans, incaps);
805   gst_test_trans_push_segment (trans);
806
807   transform_ct2_called = FALSE;
808   res = gst_test_trans_push (trans, buffer);
809   fail_unless (res == GST_FLOW_OK);
810   fail_unless (transform_ct2_called == FALSE);
811   fail_unless (set_caps_ct2_called == TRUE);
812
813   buffer = gst_test_trans_pop (trans);
814   fail_unless (buffer != NULL);
815   fail_unless (gst_buffer_get_size (buffer) == 20);
816   gst_buffer_unref (buffer);
817
818   buffer = gst_buffer_new_and_alloc (20);
819   /* take additional ref to make it non-writable */
820   gst_buffer_ref (buffer);
821
822   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
823
824   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
825
826   transform_ct2_called = FALSE;
827   res = gst_test_trans_push (trans, buffer);
828   fail_unless (res == GST_FLOW_OK);
829   fail_unless (transform_ct2_called == FALSE);
830   /* after push, get rid of the final ref we had */
831   gst_buffer_unref (buffer);
832
833   buffer = gst_test_trans_pop (trans);
834   fail_unless (buffer != NULL);
835   fail_unless (gst_buffer_get_size (buffer) == 20);
836
837   /* output buffer has refcount 1 */
838   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
839   gst_buffer_unref (buffer);
840
841   /* change the return value of the buffer-alloc function */
842   GST_DEBUG_OBJECT (trans, "switching transform output");
843
844   GST_DEBUG_OBJECT (trans,
845       "buffer with in passthrough with caps %" GST_PTR_FORMAT, incaps);
846   buffer = gst_buffer_new_and_alloc (10);
847
848   /* don't suggest anything else */
849   set_caps_ct2_case = 2;
850   gst_pad_push_event (trans->sinkpad, gst_event_new_reconfigure ());
851   transform_ct2_called = FALSE;
852   res = gst_test_trans_push (trans, buffer);
853   fail_unless (res == GST_FLOW_OK);
854   fail_unless (transform_ct2_called == TRUE);
855
856   buffer = gst_test_trans_pop (trans);
857   fail_unless (buffer != NULL);
858   fail_unless (gst_buffer_get_size (buffer) == 20);
859
860   /* output buffer has refcount 1 */
861   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
862   gst_buffer_unref (buffer);
863
864   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
865   buffer = gst_buffer_new_and_alloc (10);
866
867   /* don't suggest anything else */
868   transform_ct2_called = FALSE;
869   res = gst_test_trans_push (trans, buffer);
870   fail_unless (res == GST_FLOW_OK);
871   fail_unless (transform_ct2_called == TRUE);
872   /* after push, get rid of the final ref we had */
873
874   buffer = gst_test_trans_pop (trans);
875   fail_unless (buffer != NULL);
876   fail_unless (gst_buffer_get_size (buffer) == 20);
877
878   /* output buffer has refcount 1 */
879   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
880   gst_buffer_unref (buffer);
881
882   gst_caps_unref (incaps);
883   gst_caps_unref (outcaps);
884
885   gst_test_trans_free (trans);
886 }
887
888 GST_END_TEST;
889
890 static void
891 transform1_setup (void)
892 {
893   sink_template = &gst_test_trans_sink_template;
894   src_template = &gst_test_trans_src_template;
895 }
896
897 static void
898 transform1_teardown (void)
899 {
900   /* reset global state */
901   klass_transform_ip = NULL;
902   klass_transform = NULL;
903   klass_transform_caps = NULL;
904   klass_transform_size = NULL;
905   klass_set_caps = NULL;
906   klass_submit_input_buffer = NULL;
907   klass_generate_output = NULL;
908 }
909
910 static Suite *
911 gst_basetransform_suite (void)
912 {
913   Suite *s = suite_create ("GstBaseTransform");
914   TCase *tc = tcase_create ("general");
915
916   suite_add_tcase (s, tc);
917   tcase_add_checked_fixture (tc, transform1_setup, transform1_teardown);
918
919   /* pass through */
920   tcase_add_test (tc, basetransform_chain_pt1);
921   tcase_add_test (tc, basetransform_chain_pt2);
922   /* in place */
923   tcase_add_test (tc, basetransform_chain_ip1);
924   tcase_add_test (tc, basetransform_chain_ip2);
925   /* copy transform */
926   tcase_add_test (tc, basetransform_chain_ct1);
927   tcase_add_test (tc, basetransform_chain_ct2);
928   tcase_add_test (tc, basetransform_chain_ct3);
929
930   return s;
931 }
932
933 GST_CHECK_MAIN (gst_basetransform);