docs/libs/gstreamer-libs-sections.txt: Add new function:
[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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, 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 #define FAILING_TESTS
31
32 #include "test_transform.c"
33
34 static gboolean buffer_alloc_pt1_called;
35
36 static GstFlowReturn
37 buffer_alloc_pt1 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
38     GstBuffer ** buf)
39 {
40   GST_DEBUG_OBJECT (pad, "buffer_alloc called %" G_GUINT64_FORMAT ", %u, %"
41       GST_PTR_FORMAT, offset, size, caps);
42
43   buffer_alloc_pt1_called = TRUE;
44
45   *buf = gst_buffer_new_and_alloc (size);
46   gst_buffer_set_caps (*buf, caps);
47
48   return GST_FLOW_OK;
49 }
50
51 static gboolean set_caps_pt1_called;
52
53 static gboolean
54 set_caps_pt1 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
55 {
56   GST_DEBUG_OBJECT (trans, "set_caps called");
57
58   set_caps_pt1_called = TRUE;
59
60   return TRUE;
61 }
62
63 /* basic passthrough, we don't have any transform functions so we can only
64  * perform passthrough. We also don't have caps, which is fine */
65 GST_START_TEST (basetransform_chain_pt1)
66 {
67   TestTransData *trans;
68   GstBuffer *buffer;
69   GstFlowReturn res;
70   GstCaps *caps;
71
72   klass_set_caps = set_caps_pt1;
73   trans = gst_test_trans_new ();
74   trans->buffer_alloc = buffer_alloc_pt1;
75
76   GST_DEBUG_OBJECT (trans, "buffer without caps, size 20");
77
78   buffer = gst_buffer_new_and_alloc (20);
79
80   buffer_alloc_pt1_called = FALSE;
81   set_caps_pt1_called = FALSE;;
82   res = gst_test_trans_push (trans, buffer);
83   fail_unless (res == GST_FLOW_OK);
84 #ifdef FAILING_TESTS
85   /* FIXME, passthough without pad-alloc, do pad-alloc on the srcpad */
86   fail_unless (buffer_alloc_pt1_called == TRUE);
87 #endif
88   fail_unless (set_caps_pt1_called == FALSE);
89
90   buffer = gst_test_trans_pop (trans);
91   fail_unless (buffer != NULL);
92   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
93   /* caps should not have been set */
94   fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
95
96   gst_buffer_unref (buffer);
97
98   GST_DEBUG_OBJECT (trans, "buffer without caps, size 10");
99
100   buffer = gst_buffer_new_and_alloc (10);
101   buffer_alloc_pt1_called = FALSE;
102   set_caps_pt1_called = FALSE;;
103   res = gst_test_trans_push (trans, buffer);
104   fail_unless (res == GST_FLOW_OK);
105 #ifdef FAILING_TESTS
106   /* FIXME, passthough without pad-alloc, do pad-alloc on the srcpad */
107   fail_unless (buffer_alloc_pt1_called == TRUE);
108 #endif
109   fail_unless (set_caps_pt1_called == FALSE);
110
111   buffer = gst_test_trans_pop (trans);
112   fail_unless (buffer != NULL);
113   fail_unless (GST_BUFFER_SIZE (buffer) == 10);
114   /* caps should not have been set */
115   fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
116
117   gst_buffer_unref (buffer);
118
119   /* proxy buffer-alloc without caps */
120   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
121
122   buffer_alloc_pt1_called = FALSE;
123   set_caps_pt1_called = FALSE;;
124   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
125   fail_unless (res == GST_FLOW_OK);
126   fail_unless (buffer_alloc_pt1_called == TRUE);
127   fail_unless (set_caps_pt1_called == FALSE);
128   gst_buffer_unref (buffer);
129
130   /* with caps buffer */
131   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
132
133   caps = gst_caps_new_simple ("foo/x-bar", NULL);
134   buffer_alloc_pt1_called = FALSE;
135   set_caps_pt1_called = FALSE;;
136   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, caps, &buffer);
137   fail_unless (res == GST_FLOW_OK);
138   fail_unless (buffer_alloc_pt1_called == TRUE);
139   fail_unless (set_caps_pt1_called == FALSE);
140   gst_buffer_unref (buffer);
141
142   /* once more */
143   buffer_alloc_pt1_called = FALSE;
144   set_caps_pt1_called = FALSE;;
145   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, caps, &buffer);
146   fail_unless (res == GST_FLOW_OK);
147   fail_unless (buffer_alloc_pt1_called == TRUE);
148   fail_unless (set_caps_pt1_called == FALSE);
149   gst_buffer_unref (buffer);
150
151   gst_caps_unref (caps);
152
153   gst_test_trans_free (trans);
154 }
155
156 GST_END_TEST;
157
158 static gboolean set_caps_pt2_called;
159
160 static gboolean
161 set_caps_pt2 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
162 {
163   GST_DEBUG_OBJECT (trans, "set_caps called");
164
165   set_caps_pt2_called = TRUE;
166
167   fail_unless (gst_caps_is_equal (incaps, outcaps));
168
169   return TRUE;
170 }
171
172 /* basic passthrough, we don't have any transform functions so we can only
173  * perform passthrough with same caps */
174 GST_START_TEST (basetransform_chain_pt2)
175 {
176   TestTransData *trans;
177   GstBuffer *buffer;
178   GstCaps *caps;
179   GstFlowReturn res;
180
181   klass_set_caps = set_caps_pt2;
182   trans = gst_test_trans_new ();
183   trans->buffer_alloc = buffer_alloc_pt1;
184
185   /* first buffer */
186   caps = gst_caps_new_simple ("foo/x-bar", NULL);
187
188   GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
189
190   buffer = gst_buffer_new_and_alloc (20);
191   gst_buffer_set_caps (buffer, caps);
192
193   buffer_alloc_pt1_called = FALSE;
194   set_caps_pt2_called = FALSE;
195   res = gst_test_trans_push (trans, buffer);
196   fail_unless (res == GST_FLOW_OK);
197 #ifdef FAILING_TESTS
198   /* FIXME, passthough without pad-alloc, do pad-alloc on the srcpad */
199   fail_unless (buffer_alloc_pt1_called == TRUE);
200 #endif
201   fail_unless (set_caps_pt2_called == TRUE);
202
203   buffer = gst_test_trans_pop (trans);
204   fail_unless (buffer != NULL);
205   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
206 #if OPTIMIZED
207   fail_unless (GST_BUFFER_CAPS (buffer) == caps);
208 #else
209   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
210 #endif
211
212   gst_buffer_unref (buffer);
213
214   /* with caps buffer */
215   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
216
217   buffer_alloc_pt1_called = FALSE;
218   set_caps_pt2_called = FALSE;;
219   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, caps, &buffer);
220   fail_unless (res == GST_FLOW_OK);
221   fail_unless (buffer_alloc_pt1_called == TRUE);
222   fail_unless (set_caps_pt2_called == FALSE);
223   gst_buffer_unref (buffer);
224
225   gst_caps_unref (caps);
226
227   /* second buffer, renegotiates, keeps extra type arg in caps */
228   caps = gst_caps_new_simple ("foo/x-bar", "type", G_TYPE_INT, 1, NULL);
229
230   GST_DEBUG_OBJECT (trans, "buffer with caps, size 10");
231
232   buffer = gst_buffer_new_and_alloc (10);
233   gst_buffer_set_caps (buffer, caps);
234
235   buffer_alloc_pt1_called = FALSE;
236   set_caps_pt2_called = FALSE;
237   res = gst_test_trans_push (trans, buffer);
238   fail_unless (res == GST_FLOW_OK);
239 #ifdef FAILING_TESTS
240   /* FIXME, passthough without pad-alloc, do pad-alloc on the srcpad */
241   fail_unless (buffer_alloc_pt1_called == TRUE);
242 #endif
243   fail_unless (set_caps_pt2_called == TRUE);
244
245   buffer = gst_test_trans_pop (trans);
246   fail_unless (buffer != NULL);
247   fail_unless (GST_BUFFER_SIZE (buffer) == 10);
248 #if OPTIMIZED
249   fail_unless (GST_BUFFER_CAPS (buffer) == caps);
250 #else
251   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
252 #endif
253
254   gst_buffer_unref (buffer);
255
256   /* with caps buffer */
257   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
258
259   buffer_alloc_pt1_called = FALSE;
260   set_caps_pt2_called = FALSE;;
261   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, caps, &buffer);
262   fail_unless (res == GST_FLOW_OK);
263   fail_unless (buffer_alloc_pt1_called == TRUE);
264   fail_unless (set_caps_pt2_called == FALSE);
265   gst_buffer_unref (buffer);
266
267   gst_caps_unref (caps);
268
269   /* with caps that is a superset */
270   caps = gst_caps_new_simple ("foo/x-bar", NULL);
271
272   GST_DEBUG_OBJECT (trans, "alloc with superset caps, size 20");
273
274   buffer_alloc_pt1_called = FALSE;
275   set_caps_pt2_called = FALSE;;
276   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, caps, &buffer);
277   fail_unless (res == GST_FLOW_OK);
278   fail_unless (buffer_alloc_pt1_called == TRUE);
279   fail_unless (set_caps_pt2_called == FALSE);
280   gst_buffer_unref (buffer);
281
282   gst_caps_unref (caps);
283
284   gst_test_trans_free (trans);
285 }
286
287 GST_END_TEST;
288
289 static gboolean transform_ip_1_called;
290 static gboolean transform_ip_1_writable;
291
292 static GstFlowReturn
293 transform_ip_1 (GstBaseTransform * trans, GstBuffer * buf)
294 {
295   GST_DEBUG_OBJECT (trans, "transform called");
296
297   transform_ip_1_called = TRUE;
298   transform_ip_1_writable = gst_buffer_is_writable (buf);
299
300   GST_DEBUG_OBJECT (trans, "writable: %d", transform_ip_1_writable);
301
302   return GST_FLOW_OK;
303 }
304
305 /* basic in-place, check if the _ip function is called, buffer should
306  * be writable. no setcaps is set */
307 GST_START_TEST (basetransform_chain_ip1)
308 {
309   TestTransData *trans;
310   GstBuffer *buffer;
311   GstFlowReturn res;
312
313   klass_transform_ip = transform_ip_1;
314   trans = gst_test_trans_new ();
315   trans->buffer_alloc = buffer_alloc_pt1;
316
317   GST_DEBUG_OBJECT (trans, "buffer without caps, size 20");
318
319   buffer = gst_buffer_new_and_alloc (20);
320
321   transform_ip_1_called = FALSE;;
322   transform_ip_1_writable = TRUE;;
323   buffer_alloc_pt1_called = FALSE;
324   res = gst_test_trans_push (trans, buffer);
325   fail_unless (res == GST_FLOW_OK);
326   fail_unless (transform_ip_1_called == TRUE);
327   fail_unless (transform_ip_1_writable == TRUE);
328 #ifdef FAILING_TESTS
329   /* FIXME, in-place without pad-alloc, do pad-alloc on the srcpad */
330   fail_unless (buffer_alloc_pt1_called == TRUE);
331 #endif
332
333   buffer = gst_test_trans_pop (trans);
334   fail_unless (buffer != NULL);
335   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
336   gst_buffer_unref (buffer);
337
338   GST_DEBUG_OBJECT (trans, "buffer without caps extra ref, size 20");
339
340   buffer = gst_buffer_new_and_alloc (20);
341   /* take additional ref to make it non-writable */
342   gst_buffer_ref (buffer);
343
344   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
345
346   transform_ip_1_called = FALSE;;
347   transform_ip_1_writable = FALSE;;
348   buffer_alloc_pt1_called = FALSE;
349   res = gst_test_trans_push (trans, buffer);
350   fail_unless (res == GST_FLOW_OK);
351   fail_unless (transform_ip_1_called == TRUE);
352   /* copy should have been taken with pad-alloc */
353   fail_unless (transform_ip_1_writable == TRUE);
354   fail_unless (buffer_alloc_pt1_called == TRUE);
355   /* after push, get rid of the final ref we had */
356   gst_buffer_unref (buffer);
357
358   buffer = gst_test_trans_pop (trans);
359   fail_unless (buffer != NULL);
360   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
361
362   /* output buffer has refcount 1 */
363   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
364   gst_buffer_unref (buffer);
365
366   /* with caps buffer */
367   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
368
369   buffer_alloc_pt1_called = FALSE;
370   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
371   fail_unless (res == GST_FLOW_OK);
372   fail_unless (buffer_alloc_pt1_called == TRUE);
373   gst_buffer_unref (buffer);
374
375   gst_test_trans_free (trans);
376 }
377
378 GST_END_TEST;
379
380 static gboolean set_caps_1_called;
381
382 static gboolean
383 set_caps_1 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
384 {
385   GstCaps *caps;
386
387   GST_DEBUG_OBJECT (trans, "set_caps called");
388
389   set_caps_1_called = TRUE;
390
391   caps = gst_caps_new_simple ("foo/x-bar", NULL);
392
393   fail_unless (gst_caps_is_equal (incaps, caps));
394   fail_unless (gst_caps_is_equal (outcaps, caps));
395
396   gst_caps_unref (caps);
397
398   return TRUE;
399 }
400
401 /* basic in-place, check if the _ip function is called, buffer should be
402  * writable. we also set a setcaps function and see if it's called. */
403 GST_START_TEST (basetransform_chain_ip2)
404 {
405   TestTransData *trans;
406   GstBuffer *buffer;
407   GstFlowReturn res;
408   GstCaps *caps;
409
410   klass_transform_ip = transform_ip_1;
411   klass_set_caps = set_caps_1;
412
413   trans = gst_test_trans_new ();
414   trans->buffer_alloc = buffer_alloc_pt1;
415
416   /* with caps buffer */
417   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
418
419   buffer_alloc_pt1_called = FALSE;
420   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
421   fail_unless (res == GST_FLOW_OK);
422   fail_unless (buffer_alloc_pt1_called == TRUE);
423   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
424   fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
425   gst_buffer_unref (buffer);
426
427   caps = gst_caps_new_simple ("foo/x-bar", NULL);
428
429   /* with caps buffer */
430   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
431
432   buffer_alloc_pt1_called = FALSE;
433   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, caps, &buffer);
434   fail_unless (res == GST_FLOW_OK);
435   fail_unless (buffer_alloc_pt1_called == TRUE);
436   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
437   fail_unless (GST_BUFFER_CAPS (buffer) == caps);
438   gst_buffer_unref (buffer);
439
440   /* first try to push a buffer without caps, this should fail */
441   buffer = gst_buffer_new_and_alloc (20);
442
443   GST_DEBUG_OBJECT (trans, "buffer without caps, size 20");
444
445   transform_ip_1_called = FALSE;;
446   transform_ip_1_writable = FALSE;;
447   buffer_alloc_pt1_called = FALSE;
448   set_caps_1_called = FALSE;;
449   res = gst_test_trans_push (trans, buffer);
450   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
451   fail_unless (transform_ip_1_called == FALSE);
452   fail_unless (transform_ip_1_writable == FALSE);
453   fail_unless (set_caps_1_called == FALSE);
454   fail_unless (buffer_alloc_pt1_called == FALSE);
455
456   /* try to push a buffer with caps */
457   GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
458
459   buffer = gst_buffer_new_and_alloc (20);
460   gst_buffer_set_caps (buffer, caps);
461
462   transform_ip_1_called = FALSE;
463   transform_ip_1_writable = FALSE;
464   set_caps_1_called = FALSE;;
465   buffer_alloc_pt1_called = FALSE;
466   res = gst_test_trans_push (trans, buffer);
467   fail_unless (res == GST_FLOW_OK);
468   fail_unless (transform_ip_1_called == TRUE);
469   fail_unless (transform_ip_1_writable == TRUE);
470   fail_unless (set_caps_1_called == TRUE);
471 #ifdef FAILING_TESTS
472   /* FIXME, in-place without pad-alloc, do pad-alloc on the srcpad */
473   fail_unless (buffer_alloc_pt1_called == TRUE);
474 #endif
475
476   buffer = gst_test_trans_pop (trans);
477   fail_unless (buffer != NULL);
478   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
479 #if OPTIMIZED
480   fail_unless (GST_BUFFER_CAPS (buffer) == caps);
481 #else
482   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
483 #endif
484   gst_buffer_unref (buffer);
485
486   /* with caps buffer */
487   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
488
489   buffer_alloc_pt1_called = FALSE;
490   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, caps, &buffer);
491   fail_unless (res == GST_FLOW_OK);
492   fail_unless (buffer_alloc_pt1_called == TRUE);
493   gst_buffer_unref (buffer);
494
495   GST_DEBUG_OBJECT (trans, "buffer with caps extra ref, size 20");
496
497   buffer = gst_buffer_new_and_alloc (20);
498   gst_buffer_set_caps (buffer, caps);
499   /* take additional ref to make it non-writable */
500   gst_buffer_ref (buffer);
501
502   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
503
504   transform_ip_1_called = FALSE;;
505   transform_ip_1_writable = FALSE;;
506   buffer_alloc_pt1_called = FALSE;
507   res = gst_test_trans_push (trans, buffer);
508   fail_unless (res == GST_FLOW_OK);
509   fail_unless (transform_ip_1_called == TRUE);
510   fail_unless (transform_ip_1_writable == TRUE);
511   fail_unless (buffer_alloc_pt1_called == TRUE);
512   /* after push, get rid of the final ref we had */
513   gst_buffer_unref (buffer);
514
515   buffer = gst_test_trans_pop (trans);
516   fail_unless (buffer != NULL);
517   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
518 #if OPTIMIZED
519   fail_unless (GST_BUFFER_CAPS (buffer) == caps);
520 #else
521   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
522 #endif
523
524   /* output buffer has refcount 1 */
525   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
526   gst_buffer_unref (buffer);
527
528   /* with caps buffer */
529   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
530
531   buffer_alloc_pt1_called = FALSE;
532   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, caps, &buffer);
533   fail_unless (res == GST_FLOW_OK);
534   fail_unless (buffer_alloc_pt1_called == TRUE);
535   gst_buffer_unref (buffer);
536
537   gst_caps_unref (caps);
538
539   gst_test_trans_free (trans);
540 }
541
542 GST_END_TEST;
543
544 static GstStaticPadTemplate sink_template_ct1 = GST_STATIC_PAD_TEMPLATE ("sink",
545     GST_PAD_SINK,
546     GST_PAD_ALWAYS,
547     GST_STATIC_CAPS ("baz/x-foo")
548     );
549
550 static gboolean set_caps_ct1_called;
551
552 static gboolean
553 set_caps_ct1 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
554 {
555   GstCaps *caps1, *caps2;
556
557   GST_DEBUG_OBJECT (trans, "set_caps called");
558
559   caps1 = gst_caps_new_simple ("baz/x-foo", NULL);
560   caps2 = gst_caps_new_simple ("foo/x-bar", NULL);
561
562   fail_unless (gst_caps_is_equal (incaps, caps1));
563   fail_unless (gst_caps_is_equal (outcaps, caps2));
564
565   set_caps_ct1_called = TRUE;;
566
567   gst_caps_unref (caps1);
568   gst_caps_unref (caps2);
569
570   return TRUE;
571 }
572
573 static gboolean transform_ct1_called;
574 static gboolean transform_ct1_writable;
575
576 static GstFlowReturn
577 transform_ct1 (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
578 {
579   transform_ct1_called = TRUE;
580   transform_ct1_writable = gst_buffer_is_writable (out);
581
582   GST_DEBUG_OBJECT (trans, "writable: %d", transform_ct1_writable);
583
584   return GST_FLOW_OK;
585 }
586
587 static GstCaps *
588 transform_caps_ct1 (GstBaseTransform * trans, GstPadDirection dir,
589     GstCaps * caps)
590 {
591   GstCaps *res;
592
593   if (dir == GST_PAD_SINK) {
594     res = gst_caps_new_simple ("foo/x-bar", NULL);
595   } else {
596     res = gst_caps_new_simple ("baz/x-foo", NULL);
597   }
598   return res;
599 }
600
601 static gboolean
602 transform_size_ct1 (GstBaseTransform * trans, GstPadDirection direction,
603     GstCaps * caps, guint size, GstCaps * othercaps, guint * othersize)
604 {
605   if (direction == GST_PAD_SINK) {
606     *othersize = size * 2;
607   } else {
608     *othersize = size / 2;
609   }
610
611   return TRUE;
612 }
613
614 gboolean buffer_alloc_ct1_called;
615
616 static GstFlowReturn
617 buffer_alloc_ct1 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
618     GstBuffer ** buf)
619 {
620   GstCaps *outcaps;
621
622   GST_DEBUG_OBJECT (pad, "buffer_alloc called %" G_GUINT64_FORMAT ", %u, %"
623       GST_PTR_FORMAT, offset, size, caps);
624
625   buffer_alloc_ct1_called = TRUE;
626
627   outcaps = gst_caps_new_simple ("foo/x-bar", NULL);
628   fail_unless (gst_caps_is_equal (outcaps, caps));
629   gst_caps_unref (outcaps);
630
631   *buf = gst_buffer_new_and_alloc (size);
632   gst_buffer_set_caps (*buf, caps);
633
634   return GST_FLOW_OK;
635 }
636
637 /* basic copy-transform, check if the transform function is called,
638  * buffer should be writable. we also set a setcaps function and
639  * see if it's called. */
640 GST_START_TEST (basetransform_chain_ct1)
641 {
642   TestTransData *trans;
643   GstBuffer *buffer;
644   GstFlowReturn res;
645   GstCaps *incaps, *outcaps;
646
647   sink_template = &sink_template_ct1;
648   klass_transform = transform_ct1;
649   klass_set_caps = set_caps_ct1;
650   klass_transform_caps = transform_caps_ct1;
651   klass_transform_size = transform_size_ct1;
652
653   trans = gst_test_trans_new ();
654   trans->buffer_alloc = buffer_alloc_ct1;
655
656   incaps = gst_caps_new_simple ("baz/x-foo", NULL);
657   outcaps = gst_caps_new_simple ("foo/x-bar", NULL);
658
659 #if 0
660   /* without caps buffer, I think this should fail */
661   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
662
663   buffer_alloc_ct1_called = FALSE;
664   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
665   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
666   /* should not call pad-alloc because the caps and sizes are different */
667   fail_unless (buffer_alloc_ct1_called == FALSE);
668 #endif
669
670   /* with wrong (unsupported) caps */
671   GST_DEBUG_OBJECT (trans, "alloc with wrong caps, size 20");
672
673   buffer_alloc_ct1_called = FALSE;
674   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, outcaps, &buffer);
675   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
676 #ifdef FAILING_TESTS
677   /* FIXME, why would this call the alloc function? we try to alloc something
678    * with caps that are not supported on the sinkpad */
679   fail_unless (buffer_alloc_ct1_called == FALSE);
680 #endif
681
682   /* with caps buffer */
683   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
684
685   buffer_alloc_ct1_called = FALSE;
686   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, incaps, &buffer);
687   fail_unless (res == GST_FLOW_OK);
688   /* should not call pad-alloc because the caps and sizes are different */
689   fail_unless (buffer_alloc_ct1_called == FALSE);
690   gst_buffer_unref (buffer);
691
692   /* first try to push a buffer without caps, this should fail */
693   buffer = gst_buffer_new_and_alloc (20);
694
695   GST_DEBUG_OBJECT (trans, "buffer without caps");
696
697   transform_ct1_called = FALSE;;
698   transform_ct1_writable = FALSE;;
699   set_caps_ct1_called = FALSE;;
700   buffer_alloc_ct1_called = FALSE;
701   res = gst_test_trans_push (trans, buffer);
702   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
703   fail_unless (transform_ct1_called == FALSE);
704   fail_unless (transform_ct1_writable == FALSE);
705   fail_unless (set_caps_ct1_called == FALSE);
706   fail_unless (buffer_alloc_ct1_called == FALSE);
707
708   /* try to push a buffer with caps */
709   buffer = gst_buffer_new_and_alloc (20);
710   gst_buffer_set_caps (buffer, incaps);
711
712   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
713
714   transform_ct1_called = FALSE;
715   transform_ct1_writable = FALSE;
716   set_caps_ct1_called = FALSE;;
717   buffer_alloc_ct1_called = FALSE;
718   res = gst_test_trans_push (trans, buffer);
719   fail_unless (res == GST_FLOW_OK);
720   fail_unless (transform_ct1_called == TRUE);
721   fail_unless (transform_ct1_writable == TRUE);
722   fail_unless (set_caps_ct1_called == TRUE);
723   fail_unless (buffer_alloc_ct1_called == TRUE);
724
725   buffer = gst_test_trans_pop (trans);
726   fail_unless (buffer != NULL);
727   fail_unless (GST_BUFFER_SIZE (buffer) == 40);
728   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
729   gst_buffer_unref (buffer);
730
731   buffer = gst_buffer_new_and_alloc (20);
732   gst_buffer_set_caps (buffer, incaps);
733   /* take additional ref to make it non-writable */
734   gst_buffer_ref (buffer);
735
736   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
737
738   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
739
740   transform_ct1_called = FALSE;;
741   transform_ct1_writable = FALSE;;
742   buffer_alloc_ct1_called = FALSE;
743   res = gst_test_trans_push (trans, buffer);
744   fail_unless (res == GST_FLOW_OK);
745   fail_unless (transform_ct1_called == TRUE);
746   fail_unless (transform_ct1_writable == TRUE);
747   fail_unless (buffer_alloc_ct1_called == TRUE);
748   /* after push, get rid of the final ref we had */
749   gst_buffer_unref (buffer);
750
751   buffer = gst_test_trans_pop (trans);
752   fail_unless (buffer != NULL);
753   fail_unless (GST_BUFFER_SIZE (buffer) == 40);
754   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
755
756   /* output buffer has refcount 1 */
757   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
758   gst_buffer_unref (buffer);
759
760   /* with caps buffer */
761   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
762
763   buffer_alloc_ct1_called = FALSE;
764   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, incaps, &buffer);
765   fail_unless (res == GST_FLOW_OK);
766 #ifdef FAILING_TESTS
767   /* should not call pad-alloc because the caps and sizes are different, it
768    * currently still calls the pad alloc for no reason and then throws away the
769    * buffer. */
770   fail_unless (buffer_alloc_ct1_called == FALSE);
771 #endif
772   fail_unless (GST_BUFFER_SIZE (buffer) == 10);
773   gst_buffer_unref (buffer);
774
775   /* with caps buffer */
776   GST_DEBUG_OBJECT (trans, "alloc with wrong caps, size 10");
777
778   buffer_alloc_ct1_called = FALSE;
779   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, outcaps, &buffer);
780   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
781 #ifdef FAILING_TESTS
782   /* should not call the pad-alloc function */
783   fail_unless (buffer_alloc_ct1_called == FALSE);
784 #endif
785
786   gst_caps_unref (incaps);
787   gst_caps_unref (outcaps);
788
789   gst_test_trans_free (trans);
790 }
791
792 GST_END_TEST;
793
794 static GstStaticPadTemplate src_template_ct2 = GST_STATIC_PAD_TEMPLATE ("src",
795     GST_PAD_SRC,
796     GST_PAD_ALWAYS,
797     GST_STATIC_CAPS ("baz/x-foo; foo/x-bar")
798     );
799
800 static gint set_caps_ct2_case;
801 static gboolean set_caps_ct2_called;
802
803 static gboolean
804 set_caps_ct2 (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps)
805 {
806   GstCaps *caps1, *caps2;
807
808   GST_DEBUG_OBJECT (trans, "set_caps called");
809
810   caps1 = gst_caps_new_simple ("foo/x-bar", NULL);
811
812   if (set_caps_ct2_case == 1)
813     caps2 = gst_caps_copy (caps1);
814   else
815     caps2 = gst_caps_new_simple ("baz/x-foo", NULL);
816
817   fail_unless (gst_caps_is_equal (incaps, caps1));
818   fail_unless (gst_caps_is_equal (outcaps, caps2));
819
820   set_caps_ct2_called = TRUE;;
821
822   gst_caps_unref (caps1);
823   gst_caps_unref (caps2);
824
825   return TRUE;
826 }
827
828 static gboolean transform_ct2_called;
829 static gboolean transform_ct2_writable;
830
831 static GstFlowReturn
832 transform_ct2 (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
833 {
834   transform_ct2_called = TRUE;
835   transform_ct2_writable = gst_buffer_is_writable (out);
836
837   GST_DEBUG_OBJECT (trans, "writable: %d", transform_ct2_writable);
838
839   return GST_FLOW_OK;
840 }
841
842 static GstCaps *
843 transform_caps_ct2 (GstBaseTransform * trans, GstPadDirection dir,
844     GstCaps * caps)
845 {
846   GstCaps *res;
847
848   if (dir == GST_PAD_SINK) {
849     /* everything on the sinkpad can be transformed to the output formats */
850     res = gst_caps_from_string ("foo/x-bar;baz/x-foo");
851   } else {
852     /* all on the srcpad can be transformed to the format of the sinkpad */
853     res = gst_caps_new_simple ("foo/x-bar", NULL);
854   }
855   return res;
856 }
857
858 static gboolean
859 transform_size_ct2 (GstBaseTransform * trans, GstPadDirection direction,
860     GstCaps * caps, guint size, GstCaps * othercaps, guint * othersize)
861 {
862   if (gst_caps_is_equal (caps, othercaps)) {
863     *othersize = size;
864   } else {
865     if (direction == GST_PAD_SINK) {
866       *othersize = size * 2;
867     } else {
868       *othersize = size / 2;
869     }
870   }
871
872   return TRUE;
873 }
874
875 static gint buffer_alloc_ct2_case;
876 static gboolean buffer_alloc_ct2_called;
877 static gboolean buffer_alloc_ct2_suggest;
878
879 static GstFlowReturn
880 buffer_alloc_ct2 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
881     GstBuffer ** buf)
882 {
883   GstCaps *incaps, *outcaps;
884
885   GST_DEBUG_OBJECT (pad, "buffer_alloc called %" G_GUINT64_FORMAT ", %u, %"
886       GST_PTR_FORMAT, offset, size, caps);
887
888   buffer_alloc_ct2_called = TRUE;
889
890   if (buffer_alloc_ct2_case == 1) {
891     incaps = gst_caps_new_simple ("foo/x-bar", NULL);
892     if (buffer_alloc_ct2_suggest) {
893       outcaps = gst_caps_new_simple ("baz/x-foo", NULL);
894       size *= 2;
895     } else
896       outcaps = gst_caps_ref (incaps);
897   } else {
898     incaps = gst_caps_new_simple ("baz/x-foo", NULL);
899     if (buffer_alloc_ct2_suggest) {
900       outcaps = gst_caps_new_simple ("foo/x-bar", NULL);
901       size /= 2;
902     } else
903       outcaps = gst_caps_ref (incaps);
904   }
905   GST_DEBUG_OBJECT (pad, "expect %" GST_PTR_FORMAT, incaps);
906
907   fail_unless (gst_caps_is_equal (caps, incaps));
908
909   *buf = gst_buffer_new_and_alloc (size);
910   gst_buffer_set_caps (*buf, outcaps);
911
912   GST_DEBUG_OBJECT (pad, "return buffer of size %u, caps %" GST_PTR_FORMAT,
913       size, outcaps);
914
915   gst_caps_unref (outcaps);
916   gst_caps_unref (incaps);
917
918   return GST_FLOW_OK;
919 }
920
921 /* basic copy-transform, check if the transform function is called,
922  * buffer should be writable. we also set a setcaps function and
923  * see if it's called. */
924 GST_START_TEST (basetransform_chain_ct2)
925 {
926   TestTransData *trans;
927   GstBuffer *buffer;
928   GstFlowReturn res;
929   GstCaps *incaps, *outcaps;
930
931   src_template = &src_template_ct2;
932   klass_transform = transform_ct2;
933   klass_set_caps = set_caps_ct2;
934   klass_transform_caps = transform_caps_ct2;
935   klass_transform_size = transform_size_ct2;
936
937   trans = gst_test_trans_new ();
938   trans->buffer_alloc = buffer_alloc_ct2;
939
940   incaps = gst_caps_new_simple ("foo/x-bar", NULL);
941   outcaps = gst_caps_new_simple ("baz/x-foo", NULL);
942
943 #if 0
944   /* without caps buffer, I think this should fail */
945   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
946
947   buffer_alloc_ct2_called = FALSE;
948   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
949   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
950   /* should not call pad-alloc because the caps and sizes are different */
951   fail_unless (buffer_alloc_ct2_called == FALSE);
952 #endif
953
954   /* with passthrough caps */
955   GST_DEBUG_OBJECT (trans, "alloc size 20, with passthrough caps %"
956       GST_PTR_FORMAT, incaps);
957
958   buffer_alloc_ct2_case = 1;
959   buffer_alloc_ct2_called = FALSE;
960   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, incaps, &buffer);
961   fail_unless (res == GST_FLOW_OK);
962   fail_unless (buffer_alloc_ct2_called == TRUE);
963   gst_buffer_unref (buffer);
964
965   /* with caps buffer */
966   GST_DEBUG_OBJECT (trans, "alloc size 20, with wrong caps %" GST_PTR_FORMAT,
967       outcaps);
968
969   buffer_alloc_ct2_case = 2;
970   buffer_alloc_ct2_called = FALSE;
971   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, outcaps, &buffer);
972   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
973 #ifdef FAILING_TESTS
974   /* should not call pad-alloc because the caps and sizes are different */
975   fail_unless (buffer_alloc_ct2_called == FALSE);
976 #endif
977
978   /* first try to push a buffer without caps, this should fail */
979   buffer = gst_buffer_new_and_alloc (20);
980
981   GST_DEBUG_OBJECT (trans, "buffer without caps");
982
983   transform_ct2_called = FALSE;;
984   transform_ct2_writable = FALSE;;
985   set_caps_ct2_called = FALSE;;
986   buffer_alloc_ct2_called = FALSE;
987   res = gst_test_trans_push (trans, buffer);
988   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
989   fail_unless (transform_ct2_called == FALSE);
990   fail_unless (transform_ct2_writable == FALSE);
991   fail_unless (set_caps_ct2_called == FALSE);
992   fail_unless (buffer_alloc_ct2_called == FALSE);
993
994   /* try to push a buffer with caps */
995   buffer = gst_buffer_new_and_alloc (20);
996   gst_buffer_set_caps (buffer, incaps);
997
998   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
999
1000   buffer_alloc_ct2_case = 1;
1001   set_caps_ct2_case = 1;
1002   transform_ct2_called = FALSE;
1003   transform_ct2_writable = FALSE;
1004   set_caps_ct2_called = FALSE;;
1005   buffer_alloc_ct2_called = FALSE;
1006   res = gst_test_trans_push (trans, buffer);
1007   fail_unless (res == GST_FLOW_OK);
1008   fail_unless (transform_ct2_called == TRUE);
1009   fail_unless (transform_ct2_writable == TRUE);
1010   fail_unless (set_caps_ct2_called == TRUE);
1011   fail_unless (buffer_alloc_ct2_called == TRUE);
1012
1013   buffer = gst_test_trans_pop (trans);
1014   fail_unless (buffer != NULL);
1015   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
1016   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
1017   gst_buffer_unref (buffer);
1018
1019   buffer = gst_buffer_new_and_alloc (20);
1020   gst_buffer_set_caps (buffer, incaps);
1021   /* take additional ref to make it non-writable */
1022   gst_buffer_ref (buffer);
1023
1024   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
1025
1026   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
1027
1028   transform_ct2_called = FALSE;;
1029   transform_ct2_writable = FALSE;;
1030   buffer_alloc_ct2_called = FALSE;
1031   res = gst_test_trans_push (trans, buffer);
1032   fail_unless (res == GST_FLOW_OK);
1033   fail_unless (transform_ct2_called == TRUE);
1034   fail_unless (transform_ct2_writable == TRUE);
1035   fail_unless (buffer_alloc_ct2_called == TRUE);
1036   /* after push, get rid of the final ref we had */
1037   gst_buffer_unref (buffer);
1038
1039   buffer = gst_test_trans_pop (trans);
1040   fail_unless (buffer != NULL);
1041   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
1042   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
1043
1044   /* output buffer has refcount 1 */
1045   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
1046   gst_buffer_unref (buffer);
1047
1048   /* with caps buffer */
1049   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
1050
1051   buffer_alloc_ct2_case = 1;
1052   buffer_alloc_ct2_called = FALSE;
1053   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, incaps, &buffer);
1054   fail_unless (res == GST_FLOW_OK);
1055   fail_unless (buffer_alloc_ct2_called == TRUE);
1056   fail_unless (GST_BUFFER_SIZE (buffer) == 10);
1057   gst_buffer_unref (buffer);
1058
1059   /* with caps buffer */
1060   GST_DEBUG_OBJECT (trans, "alloc with wrong caps, size 10");
1061
1062   buffer_alloc_ct2_case = 2;
1063   buffer_alloc_ct2_called = FALSE;
1064   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, outcaps, &buffer);
1065   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
1066 #ifdef FAILING_TESTS
1067   /* should not call the pad-alloc function */
1068   fail_unless (buffer_alloc_ct2_called == FALSE);
1069 #endif
1070
1071   gst_caps_unref (incaps);
1072   gst_caps_unref (outcaps);
1073
1074   gst_test_trans_free (trans);
1075 }
1076
1077 GST_END_TEST;
1078
1079 /* basic copy-transform, we work in passthrough here. */
1080 GST_START_TEST (basetransform_chain_ct3)
1081 {
1082   TestTransData *trans;
1083   GstBuffer *buffer;
1084   GstFlowReturn res;
1085   GstCaps *incaps, *outcaps;
1086
1087   src_template = &src_template_ct2;
1088   klass_passthrough_on_same_caps = TRUE;
1089   klass_transform = transform_ct2;
1090   klass_set_caps = set_caps_ct2;
1091   klass_transform_caps = transform_caps_ct2;
1092   klass_transform_size = transform_size_ct2;
1093
1094   trans = gst_test_trans_new ();
1095   trans->buffer_alloc = buffer_alloc_ct2;
1096
1097   incaps = gst_caps_new_simple ("foo/x-bar", NULL);
1098   outcaps = gst_caps_new_simple ("baz/x-foo", NULL);
1099
1100 #if 0
1101   /* without caps buffer, I think this should fail */
1102   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
1103
1104   buffer_alloc_ct2_called = FALSE;
1105   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
1106   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
1107   /* should not call pad-alloc because the caps and sizes are different */
1108   fail_unless (buffer_alloc_ct2_called == FALSE);
1109 #endif
1110
1111   /* with passthrough caps */
1112   GST_DEBUG_OBJECT (trans, "alloc size 20, with passthrough caps %"
1113       GST_PTR_FORMAT, incaps);
1114
1115   buffer_alloc_ct2_case = 1;
1116   buffer_alloc_ct2_called = FALSE;
1117   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, incaps, &buffer);
1118   fail_unless (res == GST_FLOW_OK);
1119   fail_unless (buffer_alloc_ct2_called == TRUE);
1120   gst_buffer_unref (buffer);
1121
1122   /* with caps buffer */
1123   GST_DEBUG_OBJECT (trans, "alloc size 20, with wrong caps %" GST_PTR_FORMAT,
1124       outcaps);
1125
1126   buffer_alloc_ct2_case = 2;
1127   buffer_alloc_ct2_called = FALSE;
1128   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, outcaps, &buffer);
1129   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
1130 #ifdef FAILING_TESTS
1131   /* should not call pad-alloc because the caps and sizes are different */
1132   fail_unless (buffer_alloc_ct2_called == FALSE);
1133 #endif
1134
1135   /* first try to push a buffer without caps, this should fail */
1136   buffer = gst_buffer_new_and_alloc (20);
1137
1138   GST_DEBUG_OBJECT (trans, "buffer without caps");
1139
1140   transform_ct2_called = FALSE;;
1141   transform_ct2_writable = FALSE;;
1142   set_caps_ct2_called = FALSE;;
1143   buffer_alloc_ct2_called = FALSE;
1144   res = gst_test_trans_push (trans, buffer);
1145   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
1146   fail_unless (transform_ct2_called == FALSE);
1147   fail_unless (transform_ct2_writable == FALSE);
1148   fail_unless (set_caps_ct2_called == FALSE);
1149   fail_unless (buffer_alloc_ct2_called == FALSE);
1150
1151   /* try to push a buffer with caps */
1152   buffer = gst_buffer_new_and_alloc (20);
1153   gst_buffer_set_caps (buffer, incaps);
1154
1155   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
1156
1157   buffer_alloc_ct2_case = 1;
1158   set_caps_ct2_case = 1;
1159   transform_ct2_called = FALSE;
1160   set_caps_ct2_called = FALSE;;
1161   buffer_alloc_ct2_called = FALSE;
1162   res = gst_test_trans_push (trans, buffer);
1163   fail_unless (res == GST_FLOW_OK);
1164   fail_unless (transform_ct2_called == FALSE);
1165   fail_unless (set_caps_ct2_called == TRUE);
1166 #ifdef FAILING_TESTS
1167   fail_unless (buffer_alloc_ct2_called == TRUE);
1168 #endif
1169
1170   buffer = gst_test_trans_pop (trans);
1171   fail_unless (buffer != NULL);
1172   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
1173   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
1174   gst_buffer_unref (buffer);
1175
1176   buffer = gst_buffer_new_and_alloc (20);
1177   gst_buffer_set_caps (buffer, incaps);
1178   /* take additional ref to make it non-writable */
1179   gst_buffer_ref (buffer);
1180
1181   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 2);
1182
1183   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
1184
1185   transform_ct2_called = FALSE;;
1186   buffer_alloc_ct2_called = FALSE;
1187   res = gst_test_trans_push (trans, buffer);
1188   fail_unless (res == GST_FLOW_OK);
1189   fail_unless (transform_ct2_called == FALSE);
1190 #ifdef FAILING_TESTS
1191   fail_unless (buffer_alloc_ct2_called == TRUE);
1192 #endif
1193   /* after push, get rid of the final ref we had */
1194   gst_buffer_unref (buffer);
1195
1196   buffer = gst_test_trans_pop (trans);
1197   fail_unless (buffer != NULL);
1198   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
1199   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
1200
1201   /* output buffer has refcount 1 */
1202   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
1203   gst_buffer_unref (buffer);
1204
1205   /* with caps buffer */
1206   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
1207
1208   buffer_alloc_ct2_case = 1;
1209   buffer_alloc_ct2_called = FALSE;
1210   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, incaps, &buffer);
1211   fail_unless (res == GST_FLOW_OK);
1212   fail_unless (buffer_alloc_ct2_called == TRUE);
1213   fail_unless (GST_BUFFER_SIZE (buffer) == 10);
1214   gst_buffer_unref (buffer);
1215
1216   /* with caps buffer */
1217   GST_DEBUG_OBJECT (trans, "alloc with wrong caps, size 10");
1218
1219   buffer_alloc_ct2_case = 2;
1220   buffer_alloc_ct2_called = FALSE;
1221   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, outcaps, &buffer);
1222   fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
1223 #ifdef FAILING_TESTS
1224   /* FIXME should not call the pad-alloc function but it currently does */
1225   fail_unless (buffer_alloc_ct2_called == FALSE);
1226 #endif
1227
1228   /* change the return value of the buffer-alloc function */
1229   GST_DEBUG_OBJECT (trans, "switching transform output");
1230   buffer_alloc_ct2_suggest = TRUE;
1231
1232   GST_DEBUG_OBJECT (trans,
1233       "buffer with in passthrough with caps %" GST_PTR_FORMAT, incaps);
1234   buffer = gst_buffer_new_and_alloc (10);
1235   gst_buffer_set_caps (buffer, incaps);
1236
1237   /* don't suggest anything else */
1238   buffer_alloc_ct2_case = 1;
1239   set_caps_ct2_case = 2;
1240   transform_ct2_called = FALSE;;
1241   buffer_alloc_ct2_called = FALSE;
1242   res = gst_test_trans_push (trans, buffer);
1243   fail_unless (res == GST_FLOW_OK);
1244   fail_unless (transform_ct2_called == TRUE);
1245 #ifdef FAILING_TESTS
1246   /* FIXME, pad alloc must be called to get the new caps, because we don't call
1247    * pad alloc */
1248   fail_unless (buffer_alloc_ct2_called == TRUE);
1249 #endif
1250
1251   buffer = gst_test_trans_pop (trans);
1252   fail_unless (buffer != NULL);
1253 #ifdef FAILING_TESTS
1254   /* FIXME changing src caps should produce converted buffer */
1255   GST_DEBUG_OBJECT (trans, "received caps %" GST_PTR_FORMAT,
1256       GST_BUFFER_CAPS (buffer));
1257   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
1258   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
1259 #endif
1260
1261   /* output buffer has refcount 1 */
1262   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
1263   gst_buffer_unref (buffer);
1264
1265   /* with caps buffer */
1266   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
1267
1268   set_caps_ct2_case = 0;
1269   buffer_alloc_ct2_case = 1;
1270   buffer_alloc_ct2_called = FALSE;
1271   set_caps_ct2_called = FALSE;;
1272   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, incaps, &buffer);
1273   fail_unless (res == GST_FLOW_OK);
1274   fail_unless (buffer_alloc_ct2_called == TRUE);
1275 #ifdef FAILING_TESTS
1276   /* FIXME a buffer alloc should never set caps */
1277   fail_unless (set_caps_ct2_called == FALSE);
1278 #endif
1279   fail_unless (GST_BUFFER_SIZE (buffer) == 10);
1280 #ifdef FAILING_TESTS
1281   /* FIXME, ideally we want to reuse these caps */
1282   fail_unless (GST_BUFFER_CAPS (buffer) == incaps);
1283 #endif
1284   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
1285   gst_buffer_unref (buffer);
1286
1287   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
1288   buffer = gst_buffer_new_and_alloc (10);
1289   gst_buffer_set_caps (buffer, incaps);
1290
1291   /* don't suggest anything else */
1292   buffer_alloc_ct2_suggest = FALSE;
1293   buffer_alloc_ct2_case = 0;
1294   transform_ct2_called = FALSE;;
1295   buffer_alloc_ct2_called = FALSE;
1296   res = gst_test_trans_push (trans, buffer);
1297   fail_unless (res == GST_FLOW_OK);
1298   fail_unless (transform_ct2_called == TRUE);
1299   fail_unless (buffer_alloc_ct2_called == TRUE);
1300   /* after push, get rid of the final ref we had */
1301
1302   buffer = gst_test_trans_pop (trans);
1303   fail_unless (buffer != NULL);
1304   fail_unless (GST_BUFFER_SIZE (buffer) == 20);
1305   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
1306
1307   /* output buffer has refcount 1 */
1308   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
1309   gst_buffer_unref (buffer);
1310
1311   gst_caps_unref (incaps);
1312   gst_caps_unref (outcaps);
1313
1314   gst_test_trans_free (trans);
1315 }
1316
1317 GST_END_TEST;
1318
1319 static Suite *
1320 gst_basetransform_suite (void)
1321 {
1322   Suite *s = suite_create ("GstBaseTransform");
1323   TCase *tc = tcase_create ("general");
1324
1325   suite_add_tcase (s, tc);
1326   tcase_add_test (tc, basetransform_chain_pt1);
1327   tcase_add_test (tc, basetransform_chain_pt2);
1328   tcase_add_test (tc, basetransform_chain_ip1);
1329   tcase_add_test (tc, basetransform_chain_ip2);
1330   tcase_add_test (tc, basetransform_chain_ct1);
1331   tcase_add_test (tc, basetransform_chain_ct2);
1332   tcase_add_test (tc, basetransform_chain_ct3);
1333
1334   return s;
1335 }
1336
1337 GST_CHECK_MAIN (gst_basetransform);