1 | /* |
---|
2 | * test for tee element |
---|
3 | * this tests for proxying of caps from tee sink to src's in various situations |
---|
4 | * it also tests if you get a good, unique pad when requesting a third one |
---|
5 | * which shows a bug in 0.3.2 : |
---|
6 | * request pad, get 0 |
---|
7 | * request pad, get 1 |
---|
8 | * remove pad 0, |
---|
9 | * request pad, get 1 (number of pads), already exists, assert fail |
---|
10 | * |
---|
11 | * thomas@apestaart.org |
---|
12 | * originally written for 0.3.2 |
---|
13 | */ |
---|
14 | |
---|
15 | #include <gst/gst.h> |
---|
16 | #include <property.h> |
---|
17 | |
---|
18 | GstElement * |
---|
19 | element_create (char *name, char *element) |
---|
20 | /* |
---|
21 | * create the element |
---|
22 | * print an error if it can't be created |
---|
23 | * return NULL if it couldn't be created |
---|
24 | * return element if it did work |
---|
25 | */ |
---|
26 | { |
---|
27 | GstElement *el = NULL; |
---|
28 | |
---|
29 | el = (GstElement *) gst_element_factory_make (element, name); |
---|
30 | if (el == NULL) { |
---|
31 | fprintf (stderr, "Could not create element %s (%s) !\n", name, element); |
---|
32 | return NULL; |
---|
33 | } else |
---|
34 | return el; |
---|
35 | } |
---|
36 | |
---|
37 | int |
---|
38 | main (int argc, char *argv[]) |
---|
39 | { |
---|
40 | GstElement *pipeline = NULL; |
---|
41 | GstElement *tee, *src, *sink1, *sink2; |
---|
42 | GstPad *tee_src1, *tee_src2; |
---|
43 | |
---|
44 | #if 0 |
---|
45 | GstCaps *src_caps = NULL; |
---|
46 | GstCaps *sink_caps = NULL; |
---|
47 | GstStructure *structure = NULL; |
---|
48 | GstPad *pad = NULL; |
---|
49 | #endif |
---|
50 | |
---|
51 | /* init */ |
---|
52 | gst_init (&argc, &argv); |
---|
53 | |
---|
54 | /* create */ |
---|
55 | g_print ("Creating pipeline\n"); |
---|
56 | pipeline = gst_pipeline_new ("pipeline"); |
---|
57 | |
---|
58 | g_print ("Connecting signals to pipeline\n"); |
---|
59 | g_signal_connect (pipeline, "deep_notify", |
---|
60 | G_CALLBACK (property_change_callback), NULL); |
---|
61 | |
---|
62 | g_print ("Creating elements\n"); |
---|
63 | if (!(tee = element_create ("tee", "tee"))) |
---|
64 | return 1; |
---|
65 | if (!(src = element_create ("src", "fakesrc"))) |
---|
66 | return 1; |
---|
67 | g_object_set (G_OBJECT (src), "sizetype", 2, NULL); |
---|
68 | if (!(sink1 = element_create ("sink1", "fakesink"))) |
---|
69 | return 1; |
---|
70 | if (!(sink2 = element_create ("sink2", "fakesink"))) |
---|
71 | return 1; |
---|
72 | |
---|
73 | /* add */ |
---|
74 | g_print ("Adding elements to bin\n"); |
---|
75 | gst_bin_add (GST_BIN (pipeline), src); |
---|
76 | gst_bin_add (GST_BIN (pipeline), tee); |
---|
77 | |
---|
78 | /* link input part */ |
---|
79 | g_print ("Linking input elements\n"); |
---|
80 | gst_pad_link (gst_element_get_pad (src, "src"), |
---|
81 | gst_element_get_pad (tee, "sink")); |
---|
82 | |
---|
83 | /* request one pad from tee */ |
---|
84 | g_print ("Requesting first pad\n"); |
---|
85 | tee_src1 = gst_element_get_request_pad (tee, "src%d"); |
---|
86 | gst_bin_add (GST_BIN (pipeline), sink1); |
---|
87 | gst_pad_link (tee_src1, gst_element_get_pad (sink1, "sink")); |
---|
88 | |
---|
89 | /* set to play */ |
---|
90 | g_print ("Doing 1 iteration\n"); |
---|
91 | gst_element_set_state (pipeline, GST_STATE_PLAYING); |
---|
92 | gst_bin_iterate (GST_BIN (pipeline)); |
---|
93 | |
---|
94 | /* pause and request another pad */ |
---|
95 | g_print ("Requesting second pad\n"); |
---|
96 | gst_element_set_state (pipeline, GST_STATE_PAUSED); |
---|
97 | tee_src2 = gst_element_get_request_pad (tee, "src%d"); |
---|
98 | gst_bin_add (GST_BIN (pipeline), sink2); |
---|
99 | gst_pad_link (tee_src2, gst_element_get_pad (sink2, "sink")); |
---|
100 | |
---|
101 | /* now we have two fakesinks linked, iterate */ |
---|
102 | g_print ("Doing 1 iteration\n"); |
---|
103 | gst_element_set_state (pipeline, GST_STATE_PLAYING); |
---|
104 | gst_bin_iterate (GST_BIN (pipeline)); |
---|
105 | |
---|
106 | /* We don't allow apps to call gst_pad_try_set_caps(). */ |
---|
107 | #if 0 |
---|
108 | /* now we try setting caps on the src pad */ |
---|
109 | /* FIXME: should we set to pause here ? */ |
---|
110 | src_caps = gst_caps_from_string ("audio/raw, format=(s)\"int\", " |
---|
111 | "rate=(i)44100"); |
---|
112 | |
---|
113 | g_assert (src_caps != NULL); |
---|
114 | g_print ("Setting caps on fakesrc's src pad\n"); |
---|
115 | pad = gst_element_get_pad (src, "src"); |
---|
116 | if ((gst_pad_try_set_caps (pad, src_caps)) <= 0) { |
---|
117 | g_print ("Could not set caps !\n"); |
---|
118 | } |
---|
119 | |
---|
120 | /* now iterate and see if it proxies caps ok */ |
---|
121 | gst_bin_iterate (GST_BIN (pipeline)); |
---|
122 | sink_caps = gst_pad_get_caps (gst_element_get_pad (sink1, "sink")); |
---|
123 | if (sink_caps && gst_caps_is_fixed (sink_caps)) { |
---|
124 | structure = gst_caps_get_structure (sink_caps, 0); |
---|
125 | } else { |
---|
126 | structure = NULL; |
---|
127 | g_print ("sink_caps is not fixed\n"); |
---|
128 | } |
---|
129 | if (structure == NULL || !(gst_structure_has_field (structure, "rate"))) { |
---|
130 | g_print ("Hm, rate has not been propagated to sink1.\n"); |
---|
131 | return 1; |
---|
132 | } else { |
---|
133 | int rate; |
---|
134 | |
---|
135 | gst_structure_get_int (structure, "rate", &rate); |
---|
136 | g_print ("Rate of pad on sink1 : %d\n", rate); |
---|
137 | } |
---|
138 | sink_caps = gst_pad_get_caps (gst_element_get_pad (sink2, "sink")); |
---|
139 | structure = gst_caps_get_structure (sink_caps, 0); |
---|
140 | if (structure != NULL && !(gst_structure_has_field (structure, "rate"))) { |
---|
141 | g_print ("Hm, rate has not been propagated to sink2.\n"); |
---|
142 | return 1; |
---|
143 | } else { |
---|
144 | int rate; |
---|
145 | |
---|
146 | gst_structure_get_int (structure, "rate", &rate); |
---|
147 | g_print ("Rate of pad on sink2 : %d\n", rate); |
---|
148 | } |
---|
149 | #endif |
---|
150 | |
---|
151 | /* remove the first one, iterate */ |
---|
152 | g_print ("Removing first sink\n"); |
---|
153 | gst_element_set_state (pipeline, GST_STATE_PAUSED); |
---|
154 | gst_pad_unlink (tee_src1, gst_element_get_pad (sink1, "sink")); |
---|
155 | gst_bin_remove (GST_BIN (pipeline), sink1); |
---|
156 | |
---|
157 | /* only second fakesink linked, iterate */ |
---|
158 | g_print ("Doing 1 iteration\n"); |
---|
159 | gst_element_set_state (pipeline, GST_STATE_PLAYING); |
---|
160 | gst_bin_iterate (GST_BIN (pipeline)); |
---|
161 | |
---|
162 | /* request another pad */ |
---|
163 | g_print ("Requesting third pad\n"); |
---|
164 | gst_element_set_state (pipeline, GST_STATE_PAUSED); |
---|
165 | /* in 0.3.2 the next statement gives an assert error */ |
---|
166 | tee_src1 = gst_element_get_request_pad (tee, "src%d"); |
---|
167 | |
---|
168 | gst_element_set_state (pipeline, GST_STATE_NULL); |
---|
169 | |
---|
170 | g_print ("Done !\n"); |
---|
171 | return 0; |
---|
172 | } |
---|