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