UVC H264 plugin
[platform/upstream/gstreamer.git] / tests / check / elements / uvch264demux.c
1 /* GStreamer
2  *
3  * unit test for uvch264_demux
4  *
5  * Copyright (C) <2012> Collabora Ltd.
6  *   Author: Youness Alaoui <youness.alaoui@collabora.co.uk>
7  * Copyright (C) <2008> Sebastian Dröge <sebastian.droege@collabora.co.uk>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include <gst/check/gstcheck.h>
26 #include <string.h>
27
28 static GstElement *demux;
29 static GstPad *mjpg_pad, *h264_pad, *yuy2_pad, *nv12_pad, *jpg_pad;
30 static gboolean have_h264_eos, have_yuy2_eos, have_nv12_eos, have_jpg_eos;
31 static GstBuffer *buffer_h264, *buffer_yuy2, *buffer_nv12, *buffer_jpg;
32 static GError *gerror;
33 static gchar *error_debug;
34
35 static GstStaticPadTemplate mjpg_template =
36 GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
37     GST_STATIC_CAPS ("image/jpeg, width=640, height=480, framerate=15/1"));
38
39 static GstStaticPadTemplate sink_template =
40 GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
41     GST_STATIC_CAPS_ANY);
42
43 #define STRINGIFY_(x) #x
44 #define STRINGIFY(x) STRINGIFY_ (x)
45 #define DATADIR STRINGIFY (UVCH264DEMUX_DATADIR)
46 #define VALID_H264_JPG_MJPG_FILENAME  DATADIR "/valid_h264_jpg.mjpg"
47 #define VALID_H264_JPG_JPG_FILENAME   DATADIR "/valid_h264_jpg.jpg"
48 #define VALID_H264_JPG_H264_FILENAME  DATADIR "/valid_h264_jpg.h264"
49 #define VALID_H264_YUY2_MJPG_FILENAME DATADIR "/valid_h264_yuy2.mjpg"
50 #define VALID_H264_YUY2_YUY2_FILENAME DATADIR "/valid_h264_yuy2.yuy2"
51 #define VALID_H264_YUY2_H264_FILENAME DATADIR "/valid_h264_yuy2.h264"
52
53 #define _sink_chain_func(type)                                          \
54 static GstFlowReturn                                                    \
55  _sink_##type##_chain (GstPad * pad, GstBuffer * buffer)                \
56 {                                                                       \
57   fail_unless (GST_BUFFER_CAPS (buffer) != NULL);                       \
58                                                                         \
59   buffer_##type = buffer;                                               \
60                                                                         \
61   return GST_FLOW_OK;                                                   \
62 }
63
64 #define _sink_event_func(type)                          \
65 static gboolean                                         \
66  _sink_##type##_event (GstPad * pad, GstEvent * event)  \
67 {                                                       \
68   if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)          \
69     have_##type##_eos = TRUE;                           \
70                                                         \
71   gst_event_unref (event);                              \
72                                                         \
73   return TRUE;                                          \
74 }
75
76
77 _sink_chain_func (h264);
78 _sink_chain_func (yuy2);
79 _sink_chain_func (nv12);
80 _sink_chain_func (jpg);
81
82 _sink_event_func (h264);
83 _sink_event_func (yuy2);
84 _sink_event_func (nv12);
85 _sink_event_func (jpg);
86
87
88 static GstBusSyncReply
89 _bus_sync_handler (GstBus * bus, GstMessage * message, gpointer data)
90 {
91   if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
92     fail_unless (gerror == NULL && error_debug == NULL);
93     fail_unless (GST_MESSAGE_SRC (message) == GST_OBJECT (demux));
94     gst_message_parse_error (message, &gerror, &error_debug);
95   }
96   return GST_BUS_PASS;
97 }
98
99 static void
100 _teardown_test (void)
101 {
102   GstBus *bus;
103   gst_element_set_state (demux, GST_STATE_NULL);
104
105   bus = GST_ELEMENT_BUS (demux);
106   gst_bus_set_flushing (bus, TRUE);
107   gst_object_unref (bus);
108
109   gst_pad_set_active (mjpg_pad, FALSE);
110   gst_object_unref (mjpg_pad);
111   if (h264_pad) {
112     gst_pad_set_active (h264_pad, FALSE);
113     gst_object_unref (h264_pad);
114   }
115   if (yuy2_pad) {
116     gst_pad_set_active (yuy2_pad, FALSE);
117     gst_object_unref (yuy2_pad);
118   }
119   if (nv12_pad) {
120     gst_pad_set_active (nv12_pad, FALSE);
121     gst_object_unref (nv12_pad);
122   }
123   if (jpg_pad) {
124     gst_pad_set_active (jpg_pad, FALSE);
125     gst_object_unref (jpg_pad);
126   }
127   if (gerror) {
128     g_error_free (gerror);
129     gerror = NULL;
130   }
131   if (error_debug) {
132     g_free (error_debug);
133     error_debug = NULL;
134   }
135
136   gst_object_unref (demux);
137   mjpg_pad = h264_pad = yuy2_pad = nv12_pad = jpg_pad = NULL;
138   demux = NULL;
139 }
140
141 static void
142 _setup_test (gboolean link_h264, gboolean link_yuy2, gboolean link_nv12,
143     gboolean link_jpg)
144 {
145   GstBus *bus = gst_bus_new ();
146   GstPad *sinkpad, *h264pad, *yuy2pad, *nv12pad, *jpgpad;
147
148   have_h264_eos = have_yuy2_eos = have_nv12_eos = have_jpg_eos = FALSE;
149   buffer_h264 = buffer_yuy2 = buffer_nv12 = buffer_jpg = NULL;
150
151   demux = gst_element_factory_make ("uvch264_mjpgdemux", NULL);
152   fail_unless (demux != NULL);
153
154   gst_element_set_bus (demux, bus);
155   gst_bus_set_sync_handler (bus, _bus_sync_handler, NULL);
156
157   mjpg_pad = gst_pad_new_from_static_template (&mjpg_template, "src");
158   fail_unless (mjpg_pad != NULL);
159   sinkpad = gst_element_get_static_pad (demux, "sink");
160   fail_unless (sinkpad != NULL);
161   fail_unless (gst_pad_link (mjpg_pad, sinkpad) == GST_PAD_LINK_OK);
162   gst_object_unref (sinkpad);
163
164   gst_pad_set_active (mjpg_pad, TRUE);
165
166   if (link_h264) {
167     h264pad = gst_element_get_static_pad (demux, "h264");
168     fail_unless (h264pad != NULL);
169
170     h264_pad = gst_pad_new_from_static_template (&sink_template, "h264");
171     fail_unless (h264_pad != NULL);
172     gst_pad_set_chain_function (h264_pad, _sink_h264_chain);
173     gst_pad_set_event_function (h264_pad, _sink_h264_event);
174
175     fail_unless (gst_pad_link (h264pad, h264_pad) == GST_PAD_LINK_OK);
176     gst_object_unref (h264pad);
177
178     gst_pad_set_active (h264_pad, TRUE);
179   }
180   if (link_yuy2) {
181     yuy2pad = gst_element_get_static_pad (demux, "yuy2");
182     fail_unless (yuy2pad != NULL);
183
184     yuy2_pad = gst_pad_new_from_static_template (&sink_template, "yuy2");
185     fail_unless (yuy2_pad != NULL);
186     gst_pad_set_chain_function (yuy2_pad, _sink_yuy2_chain);
187     gst_pad_set_event_function (yuy2_pad, _sink_yuy2_event);
188
189     fail_unless (gst_pad_link (yuy2pad, yuy2_pad) == GST_PAD_LINK_OK);
190     gst_object_unref (yuy2pad);
191
192     gst_pad_set_active (yuy2_pad, TRUE);
193   }
194   if (link_nv12) {
195     nv12pad = gst_element_get_static_pad (demux, "nv12");
196     fail_unless (nv12pad != NULL);
197
198     nv12_pad = gst_pad_new_from_static_template (&sink_template, "nv12");
199     fail_unless (nv12_pad != NULL);
200     gst_pad_set_chain_function (nv12_pad, _sink_nv12_chain);
201     gst_pad_set_event_function (nv12_pad, _sink_nv12_event);
202
203     fail_unless (gst_pad_link (nv12pad, nv12_pad) == GST_PAD_LINK_OK);
204     gst_object_unref (nv12pad);
205     gst_pad_set_active (nv12_pad, TRUE);
206   }
207   if (link_jpg) {
208     jpgpad = gst_element_get_static_pad (demux, "jpeg");
209     fail_unless (jpgpad != NULL);
210
211     jpg_pad = gst_pad_new_from_static_template (&sink_template, "jpeg");
212     fail_unless (jpg_pad != NULL);
213     gst_pad_set_chain_function (jpg_pad, _sink_jpg_chain);
214     gst_pad_set_event_function (jpg_pad, _sink_jpg_event);
215
216     fail_unless (gst_pad_link (jpgpad, jpg_pad) == GST_PAD_LINK_OK);
217     gst_object_unref (jpgpad);
218
219     gst_pad_set_active (jpg_pad, TRUE);
220   }
221
222   gst_element_set_state (demux, GST_STATE_PLAYING);
223 }
224
225 static GstBuffer *
226 _buffer_from_file (const gchar * filename)
227 {
228   GstBuffer *buffer = gst_buffer_new ();
229   gchar *contents = NULL;
230   gsize length = 0;
231
232   fail_unless (g_file_get_contents (filename, &contents, &length, NULL));
233
234   GST_BUFFER_MALLOCDATA (buffer) = (guint8 *) contents;
235   GST_BUFFER_DATA (buffer) = (guint8 *) contents;
236   GST_BUFFER_SIZE (buffer) = length;
237   GST_BUFFER_OFFSET (buffer) = 0;
238
239   return buffer;
240 }
241
242 GST_START_TEST (test_valid_h264_jpg)
243 {
244   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
245   GstCaps *h264_caps;
246   GstBuffer *buffer;
247   gchar *h264_data, *jpg_data;
248   gsize h264_size, jpg_size;
249
250   _setup_test (TRUE, TRUE, TRUE, TRUE);
251
252   h264_caps = gst_caps_new_simple ("video/x-h264",
253       "width", G_TYPE_INT, 640, "height", G_TYPE_INT, 480,
254       "framerate", GST_TYPE_FRACTION, 15, 1, NULL);
255   buffer = _buffer_from_file (VALID_H264_JPG_MJPG_FILENAME);
256   gst_buffer_set_caps (buffer, mjpg_caps);
257   fail_unless (g_file_get_contents (VALID_H264_JPG_H264_FILENAME,
258           &h264_data, &h264_size, NULL));
259   fail_unless (g_file_get_contents (VALID_H264_JPG_JPG_FILENAME,
260           &jpg_data, &jpg_size, NULL));
261
262   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_OK);
263   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
264
265   fail_unless (have_h264_eos);
266   fail_unless (have_yuy2_eos);
267   fail_unless (have_nv12_eos);
268   fail_unless (have_jpg_eos);
269   fail_unless (buffer_h264 != NULL);
270   fail_unless (buffer_jpg != NULL);
271   fail_unless (buffer_nv12 == NULL);
272   fail_unless (buffer_yuy2 == NULL);
273   fail_unless (gerror == NULL && error_debug == NULL);
274   fail_unless (gst_caps_is_always_compatible (GST_BUFFER_CAPS (buffer_h264),
275           h264_caps));
276   fail_unless (gst_caps_is_always_compatible (GST_BUFFER_CAPS (buffer_jpg),
277           mjpg_caps));
278   fail_unless (GST_BUFFER_SIZE (buffer_h264) == h264_size);
279   fail_unless (GST_BUFFER_SIZE (buffer_jpg) == jpg_size);
280   fail_unless (memcmp (GST_BUFFER_DATA (buffer_h264), h264_data,
281           h264_size) == 0);
282   fail_unless (memcmp (GST_BUFFER_DATA (buffer_jpg), jpg_data, jpg_size) == 0);
283
284   gst_caps_unref (mjpg_caps);
285   gst_caps_unref (h264_caps);
286   g_free (h264_data);
287   g_free (jpg_data);
288   gst_buffer_unref (buffer_h264);
289   gst_buffer_unref (buffer_jpg);
290   _teardown_test ();
291 }
292
293 GST_END_TEST;
294
295 GST_START_TEST (test_valid_h264_yuy2)
296 {
297   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
298   GstCaps *h264_caps;
299   GstCaps *yuy2_caps;
300   GstBuffer *buffer;
301   gchar *h264_data, *yuy2_data;
302   gsize h264_size, yuy2_size;
303
304   _setup_test (TRUE, TRUE, TRUE, TRUE);
305
306   h264_caps = gst_caps_new_simple ("video/x-h264",
307       "width", G_TYPE_INT, 640, "height", G_TYPE_INT, 480,
308       "framerate", GST_TYPE_FRACTION, 15, 1, NULL);
309   yuy2_caps = gst_caps_new_simple ("video/x-raw-yuv",
310       "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
311       "width", G_TYPE_INT, 160, "height", G_TYPE_INT, 90,
312       "framerate", GST_TYPE_FRACTION, 15, 1, NULL);
313   buffer = _buffer_from_file (VALID_H264_YUY2_MJPG_FILENAME);
314   gst_buffer_set_caps (buffer, mjpg_caps);
315   fail_unless (g_file_get_contents (VALID_H264_YUY2_H264_FILENAME,
316           &h264_data, &h264_size, NULL));
317   fail_unless (g_file_get_contents (VALID_H264_YUY2_YUY2_FILENAME,
318           &yuy2_data, &yuy2_size, NULL));
319
320   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_OK);
321   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
322
323   fail_unless (have_h264_eos);
324   fail_unless (have_yuy2_eos);
325   fail_unless (have_nv12_eos);
326   fail_unless (have_jpg_eos);
327   fail_unless (buffer_h264 != NULL);
328   fail_unless (buffer_jpg == NULL);
329   fail_unless (buffer_nv12 == NULL);
330   fail_unless (buffer_yuy2 != NULL);
331   fail_unless (gerror == NULL && error_debug == NULL);
332   fail_unless (gst_caps_is_always_compatible (GST_BUFFER_CAPS (buffer_h264),
333           h264_caps));
334   fail_unless (gst_caps_is_always_compatible (GST_BUFFER_CAPS (buffer_yuy2),
335           yuy2_caps));
336   fail_unless (GST_BUFFER_SIZE (buffer_h264) == h264_size);
337   fail_unless (GST_BUFFER_SIZE (buffer_yuy2) == yuy2_size);
338   fail_unless (memcmp (GST_BUFFER_DATA (buffer_h264), h264_data,
339           h264_size) == 0);
340   fail_unless (memcmp (GST_BUFFER_DATA (buffer_yuy2), yuy2_data,
341           yuy2_size) == 0);
342
343   gst_caps_unref (mjpg_caps);
344   gst_caps_unref (yuy2_caps);
345   gst_caps_unref (h264_caps);
346   g_free (h264_data);
347   g_free (yuy2_data);
348   gst_buffer_unref (buffer_h264);
349   gst_buffer_unref (buffer_yuy2);
350   _teardown_test ();
351 }
352
353 GST_END_TEST;
354
355 GST_START_TEST (test_no_data)
356 {
357   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
358   GstBuffer *buffer = gst_buffer_new ();
359
360   _setup_test (TRUE, TRUE, TRUE, TRUE);
361
362   gst_buffer_set_caps (buffer, mjpg_caps);
363   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_OK);
364   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
365
366   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
367   fail_unless (buffer_h264 == NULL && buffer_jpg != NULL);
368   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
369   fail_unless (gerror == NULL && error_debug == NULL);
370
371   _teardown_test ();
372 }
373
374 GST_END_TEST;
375
376 GST_START_TEST (test_data_zero)
377 {
378   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
379   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
380
381   _setup_test (TRUE, TRUE, TRUE, TRUE);
382
383   memset (GST_BUFFER_DATA (buffer), 0, 1024);
384   GST_BUFFER_SIZE (buffer) = 1024;
385   gst_buffer_set_caps (buffer, mjpg_caps);
386   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_OK);
387   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
388
389   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
390   fail_unless (buffer_h264 == NULL && buffer_jpg == NULL);
391   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
392
393   _teardown_test ();
394 }
395
396 GST_END_TEST;
397
398 GST_START_TEST (test_no_marker_size)
399 {
400   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
401   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
402   const guchar data[] = {
403     0xff, 0xd8, 0xff, 0xe4, 0x00
404   };
405
406   _setup_test (TRUE, TRUE, TRUE, TRUE);
407
408   memcpy (GST_BUFFER_DATA (buffer), data, sizeof (data));
409   GST_BUFFER_SIZE (buffer) = sizeof (data);
410   gst_buffer_set_caps (buffer, mjpg_caps);
411   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_ERROR);
412   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
413
414   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
415   fail_unless (buffer_h264 == NULL && buffer_jpg == NULL);
416   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
417   fail_unless (gerror != NULL);
418   fail_unless (gerror->domain == GST_STREAM_ERROR);
419   fail_unless (gerror->code == GST_STREAM_ERROR_DEMUX);
420   fail_unless (memcmp (gerror->message,
421           "Not enough data to read marker size",
422           strlen (gerror->message)) == 0);
423
424   _teardown_test ();
425 }
426
427 GST_END_TEST;
428
429 GST_START_TEST (test_not_enough_data)
430 {
431   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
432   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
433   const guchar data[] = {
434     0xff, 0xd8, 0xff, 0xe4, 0x00, 0xff, 0x00, 0x00
435   };
436
437   _setup_test (TRUE, TRUE, TRUE, TRUE);
438
439   memcpy (GST_BUFFER_DATA (buffer), data, sizeof (data));
440   GST_BUFFER_SIZE (buffer) = sizeof (data);
441   gst_buffer_set_caps (buffer, mjpg_caps);
442   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_ERROR);
443   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
444
445   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
446   fail_unless (buffer_h264 == NULL && buffer_jpg == NULL);
447   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
448   fail_unless (gerror != NULL);
449   fail_unless (gerror->domain == GST_STREAM_ERROR);
450   fail_unless (gerror->code == GST_STREAM_ERROR_DEMUX);
451   fail_unless (memcmp (gerror->message,
452           "Not enough data to read marker content",
453           strlen (gerror->message)) == 0);
454
455   _teardown_test ();
456 }
457
458 GST_END_TEST;
459
460 GST_START_TEST (test_no_aux_header)
461 {
462   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
463   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
464   const guchar data[] = {
465     0xff, 0xd8, 0xff, 0xe4, 0x00, 0x02, 0x00, 0x00,
466     0xff, 0xd9
467   };
468
469   _setup_test (TRUE, TRUE, TRUE, TRUE);
470
471   memcpy (GST_BUFFER_DATA (buffer), data, sizeof (data));
472   GST_BUFFER_SIZE (buffer) = sizeof (data);
473   gst_buffer_set_caps (buffer, mjpg_caps);
474   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_ERROR);
475   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
476
477   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
478   fail_unless (buffer_h264 == NULL && buffer_jpg == NULL);
479   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
480   fail_unless (gerror != NULL);
481   fail_unless (gerror->domain == GST_STREAM_ERROR);
482   fail_unless (gerror->code == GST_STREAM_ERROR_DEMUX);
483   fail_unless (memcmp (gerror->message,
484           "Not enough data to read aux header", strlen (gerror->message)) == 0);
485
486   _teardown_test ();
487 }
488
489 GST_END_TEST;
490
491 GST_START_TEST (test_empty_aux_data)
492 {
493   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
494   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
495   const guchar data[] = {
496     0xff, 0xd8, 0xff, 0xe4, 0x00, 0x1C, 0x00, 0x01,
497     0x16, 0x00, 0x48, 0x32, 0x36, 0x34, 0x80, 0x07,
498     0x38, 0x04, 0x2a, 0x2c, 0x0a, 0x00, 0x1b, 0x00,
499     0x40, 0x62, 0xcb, 0x0a, 0x00, 0x00, 0x00, 0x00,
500     0xff, 0xd9
501   };
502
503   _setup_test (TRUE, TRUE, TRUE, TRUE);
504
505   memcpy (GST_BUFFER_DATA (buffer), data, sizeof (data));
506   GST_BUFFER_SIZE (buffer) = sizeof (data);
507   gst_buffer_set_caps (buffer, mjpg_caps);
508   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_OK);
509   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
510
511   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
512   fail_unless (buffer_h264 == NULL && buffer_jpg == NULL);
513   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
514   fail_unless (gerror == NULL);
515
516   _teardown_test ();
517 }
518
519 GST_END_TEST;
520
521 GST_START_TEST (test_unknown_fcc)
522 {
523   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
524   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
525   const guchar data[] = {
526     0xff, 0xd8, 0xff, 0xe4, 0x00, 0x2C, 0x00, 0x01,
527     0x16, 0x00, 0x48, 0x30, 0x30, 0x30, 0x80, 0x07,
528     0x38, 0x04, 0x2a, 0x2c, 0x0a, 0x00, 0x1b, 0x00,
529     0x40, 0x62, 0xcb, 0x0a, 0x10, 0x00, 0x00, 0x00,
530     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532     0xff, 0xd9
533   };
534
535   _setup_test (TRUE, TRUE, TRUE, TRUE);
536
537   memcpy (GST_BUFFER_DATA (buffer), data, sizeof (data));
538   GST_BUFFER_SIZE (buffer) = sizeof (data);
539   gst_buffer_set_caps (buffer, mjpg_caps);
540   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_ERROR);
541   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
542
543   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
544   fail_unless (buffer_h264 == NULL && buffer_jpg == NULL);
545   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
546   fail_unless (gerror != NULL);
547   fail_unless (gerror->domain == GST_STREAM_ERROR);
548   fail_unless (gerror->code == GST_STREAM_ERROR_DEMUX);
549   fail_unless (memcmp (gerror->message,
550           "Unknown auxiliary stream format : H000",
551           strlen (gerror->message)) == 0);
552
553   _teardown_test ();
554 }
555
556 GST_END_TEST;
557
558 GST_START_TEST (test_not_enough_aux_data)
559 {
560   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
561   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
562   const guchar data[] = {
563     0xff, 0xd8, 0xff, 0xe4, 0x00, 0x1C, 0x00, 0x01,
564     0x16, 0x00, 0x48, 0x32, 0x36, 0x34, 0x80, 0x07,
565     0x38, 0x04, 0x2a, 0x2c, 0x0a, 0x00, 0x1b, 0x00,
566     0x40, 0x62, 0xcb, 0x0a, 0x10, 0x00, 0x00, 0x00,
567     0xff, 0xd9
568   };
569
570   _setup_test (TRUE, TRUE, TRUE, TRUE);
571
572   memcpy (GST_BUFFER_DATA (buffer), data, sizeof (data));
573   GST_BUFFER_SIZE (buffer) = sizeof (data);
574   gst_buffer_set_caps (buffer, mjpg_caps);
575   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_ERROR);
576   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
577
578   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
579   fail_unless (buffer_h264 == NULL && buffer_jpg == NULL);
580   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
581   fail_unless (gerror != NULL);
582   fail_unless (gerror->domain == GST_STREAM_ERROR);
583   fail_unless (gerror->code == GST_STREAM_ERROR_DEMUX);
584   fail_unless (memcmp (gerror->message,
585           "Incomplete auxiliary stream. 16 bytes missing",
586           strlen (gerror->message)) == 0);
587
588   _teardown_test ();
589 }
590
591 GST_END_TEST;
592
593 GST_START_TEST (test_too_much_aux_data)
594 {
595   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
596   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
597   const guchar data[] = {
598     0xff, 0xd8, 0xff, 0xe4, 0x00, 0x3C, 0x00, 0x01,
599     0x16, 0x00, 0x48, 0x32, 0x36, 0x34, 0x80, 0x07,
600     0x38, 0x04, 0x2a, 0x2c, 0x0a, 0x00, 0x1b, 0x00,
601     0x40, 0x62, 0xcb, 0x0a, 0x10, 0x00, 0x00, 0x00,
602     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606     0xff, 0xd9
607   };
608
609   _setup_test (TRUE, TRUE, TRUE, TRUE);
610
611   memcpy (GST_BUFFER_DATA (buffer), data, sizeof (data));
612   GST_BUFFER_SIZE (buffer) = sizeof (data);
613   gst_buffer_set_caps (buffer, mjpg_caps);
614   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_ERROR);
615   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
616
617   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
618   fail_unless (buffer_h264 == NULL && buffer_jpg == NULL);
619   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
620   fail_unless (gerror != NULL);
621   fail_unless (gerror->domain == GST_STREAM_ERROR);
622   fail_unless (gerror->code == GST_STREAM_ERROR_DEMUX);
623   fail_unless (memcmp (gerror->message,
624           "Expected 16 auxiliary data, got 32 bytes",
625           strlen (gerror->message)) == 0);
626
627   _teardown_test ();
628 }
629
630 GST_END_TEST;
631
632
633 GST_START_TEST (test_no_sos_marker)
634 {
635   GstCaps *mjpg_caps = gst_static_pad_template_get_caps (&mjpg_template);
636   GstBuffer *buffer = gst_buffer_new_and_alloc (1024);
637   const guchar data[] = {
638     0xff, 0xd8, 0xff, 0xe4, 0x00, 0x2C, 0x00, 0x01,
639     0x16, 0x00, 0x48, 0x32, 0x36, 0x34, 0x80, 0x07,
640     0x38, 0x04, 0x2a, 0x2c, 0x0a, 0x00, 0x1b, 0x00,
641     0x40, 0x62, 0xcb, 0x0a, 0x10, 0x00, 0x00, 0x00,
642     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644     0xff, 0xd9
645   };
646   const guchar h264_data[] = {
647     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
649   };
650
651   _setup_test (TRUE, TRUE, TRUE, TRUE);
652
653   memcpy (GST_BUFFER_DATA (buffer), data, sizeof (data));
654   GST_BUFFER_SIZE (buffer) = sizeof (data);
655   gst_buffer_set_caps (buffer, mjpg_caps);
656   fail_unless (gst_pad_push (mjpg_pad, buffer) == GST_FLOW_OK);
657   fail_unless (gst_pad_push_event (mjpg_pad, gst_event_new_eos ()));
658
659   fail_unless (have_h264_eos && have_yuy2_eos && have_nv12_eos && have_jpg_eos);
660   fail_unless (buffer_h264 != NULL && buffer_jpg == NULL);
661   fail_unless (buffer_nv12 == NULL && buffer_yuy2 == NULL);
662   fail_unless (gerror == NULL);
663   fail_unless (GST_BUFFER_SIZE (buffer_h264) == sizeof (h264_data));
664   fail_unless (memcmp (GST_BUFFER_DATA (buffer_h264), h264_data,
665           sizeof (h264_data)) == 0);
666
667   _teardown_test ();
668 }
669
670 GST_END_TEST;
671
672 static Suite *
673 uvch264demux_suite (void)
674 {
675   Suite *s = suite_create ("uvch264demux");
676   TCase *tc_chain = tcase_create ("general");
677
678   suite_add_tcase (s, tc_chain);
679   tcase_set_timeout (tc_chain, 180);
680   tcase_add_test (tc_chain, test_valid_h264_jpg);
681   tcase_add_test (tc_chain, test_valid_h264_yuy2);
682   tcase_add_test (tc_chain, test_no_data);
683   tcase_add_test (tc_chain, test_data_zero);
684   tcase_add_test (tc_chain, test_no_marker_size);
685   tcase_add_test (tc_chain, test_not_enough_data);
686   tcase_add_test (tc_chain, test_no_aux_header);
687   tcase_add_test (tc_chain, test_empty_aux_data);
688   tcase_add_test (tc_chain, test_unknown_fcc);
689   tcase_add_test (tc_chain, test_no_sos_marker);
690   tcase_add_test (tc_chain, test_not_enough_aux_data);
691   tcase_add_test (tc_chain, test_too_much_aux_data);
692
693   return s;
694 }
695
696 GST_CHECK_MAIN (uvch264demux);