1 /* GStreamer
2 *
3 * unit test for jpegenc
4 *
5 * Copyright (C) <2010> Thiago Santos <thiago.sousa.santos@collabora.co.uk>
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 #include <unistd.h>
24
25 #include <gst/check/gstcheck.h>
26 #include <gst/app/gstappsink.h>
27
28 /* For ease of programming we use globals to keep refs for our floating
29 * sink pads we create; otherwise we always have to do get_pad,
30 * get_peer, and then remove references in every test function */
31 static GstPad *mysinkpad;
32 static GstPad *mysrcpad;
33
34 #define JPEG_CAPS_STRING "image/jpeg"
35
36 #define JPEG_CAPS_RESTRICTIVE "image/jpeg, " \
37 "width = (int) [100, 200], " \
38 "framerate = (fraction) 25/1, " \
39 "extraparameter = (string) { abc, def }"
40
41 static GstStaticPadTemplate jpeg_sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
42 GST_PAD_SINK,
43 GST_PAD_ALWAYS,
44 GST_STATIC_CAPS (JPEG_CAPS_STRING));
45
46 static GstStaticPadTemplate any_sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
47 GST_PAD_SINK,
48 GST_PAD_ALWAYS,
49 GST_STATIC_CAPS_ANY);
50
51 static GstStaticPadTemplate jpeg_restrictive_sinktemplate =
52 GST_STATIC_PAD_TEMPLATE ("sink",
53 GST_PAD_SINK,
54 GST_PAD_ALWAYS,
55 GST_STATIC_CAPS (JPEG_CAPS_RESTRICTIVE));
56
57 static GstStaticPadTemplate any_srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
58 GST_PAD_SRC,
59 GST_PAD_ALWAYS,
60 GST_STATIC_CAPS_ANY);
61
62
63 static GstElement *
setup_jpegenc(GstStaticPadTemplate * sinktemplate)64 setup_jpegenc (GstStaticPadTemplate * sinktemplate)
65 {
66 GstElement *jpegenc;
67
68 GST_DEBUG ("setup_jpegenc");
69 jpegenc = gst_check_setup_element ("jpegenc");
70 mysinkpad = gst_check_setup_sink_pad (jpegenc, sinktemplate);
71 mysrcpad = gst_check_setup_src_pad (jpegenc, &any_srctemplate);
72 gst_pad_set_active (mysrcpad, TRUE);
73 gst_pad_set_active (mysinkpad, TRUE);
74
75 return jpegenc;
76 }
77
78 static void
cleanup_jpegenc(GstElement * jpegenc)79 cleanup_jpegenc (GstElement * jpegenc)
80 {
81 GST_DEBUG ("cleanup_jpegenc");
82 gst_element_set_state (jpegenc, GST_STATE_NULL);
83
84 gst_check_drop_buffers ();
85 gst_pad_set_active (mysrcpad, FALSE);
86 gst_pad_set_active (mysinkpad, FALSE);
87 gst_check_teardown_sink_pad (jpegenc);
88 gst_check_teardown_src_pad (jpegenc);
89 gst_check_teardown_element (jpegenc);
90 }
91
92 static GstBuffer *
create_video_buffer(GstCaps * caps)93 create_video_buffer (GstCaps * caps)
94 {
95 GstElement *pipeline;
96 GstElement *cf;
97 GstElement *sink;
98 GstSample *sample;
99 GstBuffer *buffer;
100
101 pipeline =
102 gst_parse_launch
103 ("videotestsrc num-buffers=1 ! capsfilter name=cf ! appsink name=sink",
104 NULL);
105 g_assert (pipeline != NULL);
106
107 cf = gst_bin_get_by_name (GST_BIN (pipeline), "cf");
108 sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
109
110 g_object_set (G_OBJECT (cf), "caps", caps, NULL);
111
112 gst_element_set_state (pipeline, GST_STATE_PLAYING);
113
114 sample = gst_app_sink_pull_sample (GST_APP_SINK (sink));
115
116 gst_element_set_state (pipeline, GST_STATE_NULL);
117 gst_object_unref (pipeline);
118 gst_object_unref (sink);
119 gst_object_unref (cf);
120
121 buffer = gst_sample_get_buffer (sample);
122 gst_buffer_ref (buffer);
123
124 gst_sample_unref (sample);
125
126 return buffer;
127 }
128
129
GST_START_TEST(test_jpegenc_getcaps)130 GST_START_TEST (test_jpegenc_getcaps)
131 {
132 GstElement *jpegenc;
133 GstPad *sinkpad;
134 GstCaps *caps;
135 GstStructure *structure;
136 gint fps_n;
137 gint fps_d;
138 const GValue *value;
139
140 /* we are going to do some get caps to confirm it doesn't return non-subset
141 * caps */
142
143 jpegenc = setup_jpegenc (&any_sinktemplate);
144 sinkpad = gst_element_get_static_pad (jpegenc, "sink");
145 /* this should assert if non-subset */
146 caps = gst_pad_query_caps (sinkpad, NULL);
147 gst_caps_unref (caps);
148 gst_object_unref (sinkpad);
149 cleanup_jpegenc (jpegenc);
150
151 jpegenc = setup_jpegenc (&jpeg_sinktemplate);
152 sinkpad = gst_element_get_static_pad (jpegenc, "sink");
153 /* this should assert if non-subset */
154 caps = gst_pad_query_caps (sinkpad, NULL);
155 gst_caps_unref (caps);
156 gst_object_unref (sinkpad);
157 cleanup_jpegenc (jpegenc);
158
159 /* now use a more restricted one and check the resulting caps */
160 jpegenc = setup_jpegenc (&jpeg_restrictive_sinktemplate);
161 sinkpad = gst_element_get_static_pad (jpegenc, "sink");
162 /* this should assert if non-subset */
163 caps = gst_pad_query_caps (sinkpad, NULL);
164 structure = gst_caps_get_structure (caps, 0);
165
166 /* check the width */
167 value = gst_structure_get_value (structure, "width");
168 fail_unless (gst_value_get_int_range_min (value) == 100);
169 fail_unless (gst_value_get_int_range_max (value) == 200);
170
171 fail_unless (gst_structure_get_fraction (structure, "framerate", &fps_n,
172 &fps_d));
173 fail_unless (fps_n == 25);
174 fail_unless (fps_d == 1);
175
176 gst_caps_unref (caps);
177 gst_object_unref (sinkpad);
178 cleanup_jpegenc (jpegenc);
179 }
180
181 GST_END_TEST;
182
183
GST_START_TEST(test_jpegenc_different_caps)184 GST_START_TEST (test_jpegenc_different_caps)
185 {
186 GstElement *jpegenc;
187 GstBuffer *buffer;
188 GstCaps *caps;
189 GstCaps *allowed_caps;
190
191 /* now use a more restricted one and check the resulting caps */
192 jpegenc = setup_jpegenc (&any_sinktemplate);
193 gst_element_set_state (jpegenc, GST_STATE_PLAYING);
194
195 /* push first buffer with 800x600 resolution */
196 caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
197 800, "height", G_TYPE_INT, 600, "framerate",
198 GST_TYPE_FRACTION, 1, 1, "format", G_TYPE_STRING, "I420", NULL);
199 gst_check_setup_events (mysrcpad, jpegenc, caps, GST_FORMAT_TIME);
200 fail_unless ((buffer = create_video_buffer (caps)) != NULL);
201 gst_caps_unref (caps);
202 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
203
204 /* check the allowed caps to see if a second buffer with a different
205 * caps could be negotiated */
206 allowed_caps = gst_pad_get_allowed_caps (mysrcpad);
207
208 /* the caps we want to negotiate to */
209 caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
210 640, "height", G_TYPE_INT, 480, "framerate",
211 GST_TYPE_FRACTION, 1, 1, "format", G_TYPE_STRING, "I420", NULL);
212 fail_unless (gst_caps_can_intersect (allowed_caps, caps));
213 fail_unless (gst_pad_set_caps (mysrcpad, caps));
214
215 /* push second buffer with 640x480 resolution */
216 buffer = create_video_buffer (caps);
217 gst_caps_unref (caps);
218 fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
219
220 gst_caps_unref (allowed_caps);
221 gst_element_set_state (jpegenc, GST_STATE_NULL);
222 cleanup_jpegenc (jpegenc);
223 }
224
225 GST_END_TEST;
226
227 static Suite *
jpegenc_suite(void)228 jpegenc_suite (void)
229 {
230 Suite *s = suite_create ("jpegenc");
231 TCase *tc_chain = tcase_create ("general");
232
233 suite_add_tcase (s, tc_chain);
234 tcase_add_test (tc_chain, test_jpegenc_getcaps);
235 tcase_add_test (tc_chain, test_jpegenc_different_caps);
236
237 return s;
238 }
239
240 GST_CHECK_MAIN (jpegenc);
241