1 /* GStreamer unit tests for flvdemux
3 * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
4 * Copyright (C) 2016 Havard Graff <havard@pexip.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #include <gst/check/gstcheck.h>
23 #include <gst/check/gstharness.h>
26 #include <gst/tag/tag.h>
29 pad_added_cb (GstElement * flvdemux, GstPad * pad, GstBin * pipeline)
33 sink = gst_bin_get_by_name (pipeline, "fakesink");
34 fail_unless (gst_element_link (flvdemux, sink));
35 gst_object_unref (sink);
37 gst_element_set_state (sink, GST_STATE_PAUSED);
40 static GstBusSyncReply
41 error_cb (GstBus * bus, GstMessage * msg, gpointer user_data)
43 if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
44 const gchar *file = (const gchar *) user_data;
48 gst_message_parse_error (msg, &err, &dbg);
49 g_error ("ERROR for %s: %s\n%s\n", file, err->message, dbg);
56 handoff_cb (GstElement * element, GstBuffer * buf, GstPad * pad,
60 GST_LOG ("counter = %d", *p_counter);
64 process_file (const gchar * file, gboolean push_mode, gint repeat,
67 GstElement *src, *sep, *sink, *flvdemux, *pipeline;
72 pipeline = gst_pipeline_new ("pipeline");
73 fail_unless (pipeline != NULL, "Failed to create pipeline!");
75 bus = gst_element_get_bus (pipeline);
77 /* kids, don't use a sync handler for this at home, really; we do because
78 * we just want to abort and nothing else */
79 gst_bus_set_sync_handler (bus, error_cb, (gpointer) file, NULL);
81 src = gst_element_factory_make ("filesrc", "filesrc");
82 fail_unless (src != NULL, "Failed to create 'filesrc' element!");
85 sep = gst_element_factory_make ("queue", "queue");
86 fail_unless (sep != NULL, "Failed to create 'queue' element");
88 sep = gst_element_factory_make ("identity", "identity");
89 fail_unless (sep != NULL, "Failed to create 'identity' element");
92 flvdemux = gst_element_factory_make ("flvdemux", "flvdemux");
93 fail_unless (flvdemux != NULL, "Failed to create 'flvdemux' element!");
95 sink = gst_element_factory_make ("fakesink", "fakesink");
96 fail_unless (sink != NULL, "Failed to create 'fakesink' element!");
98 g_object_set (sink, "signal-handoffs", TRUE, NULL);
99 g_signal_connect (sink, "handoff", G_CALLBACK (handoff_cb), &counter);
101 gst_bin_add_many (GST_BIN (pipeline), src, sep, flvdemux, sink, NULL);
103 fail_unless (gst_element_link (src, sep));
104 fail_unless (gst_element_link (sep, flvdemux));
106 /* can't link flvdemux and sink yet, do that later */
107 g_signal_connect (flvdemux, "pad-added", G_CALLBACK (pad_added_cb), pipeline);
109 path = g_build_filename (GST_TEST_FILES_PATH, file, NULL);
110 GST_LOG ("processing file '%s'", path);
111 g_object_set (src, "location", path, NULL);
114 GstStateChangeReturn state_ret;
117 GST_LOG ("repeat=%d", repeat);
121 state_ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
122 fail_unless (state_ret != GST_STATE_CHANGE_FAILURE);
124 if (state_ret == GST_STATE_CHANGE_ASYNC) {
125 GST_LOG ("waiting for pipeline to reach PAUSED state");
126 state_ret = gst_element_get_state (pipeline, NULL, NULL, -1);
127 fail_unless_equals_int (state_ret, GST_STATE_CHANGE_SUCCESS);
130 GST_LOG ("PAUSED, let's read all of it");
132 state_ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
133 fail_unless (state_ret != GST_STATE_CHANGE_FAILURE);
135 msg = gst_bus_poll (bus, GST_MESSAGE_EOS, -1);
136 fail_unless (msg != NULL, "Expected EOS message on bus! (%s)", file);
138 gst_message_unref (msg);
140 if (num_buffers >= 0) {
141 fail_unless_equals_int (counter, num_buffers);
144 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
145 GST_STATE_CHANGE_SUCCESS);
148 } while (repeat > 0);
150 gst_object_unref (bus);
151 gst_object_unref (pipeline);
156 GST_START_TEST (test_reuse_pull)
158 process_file ("pcm16sine.flv", FALSE, 3, 129);
159 gst_task_cleanup_all ();
164 GST_START_TEST (test_reuse_push)
166 process_file ("pcm16sine.flv", TRUE, 3, 129);
167 gst_task_cleanup_all ();
173 create_buffer (guint8 * data, gsize size)
175 GstBuffer *buf = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
176 data, size, 0, size, NULL, NULL);
177 GST_BUFFER_PTS (buf) = GST_CLOCK_TIME_NONE;
178 GST_BUFFER_DTS (buf) = GST_CLOCK_TIME_NONE;
179 GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
180 GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
181 GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
186 flvdemux_pad_added (GstElement * flvdemux, GstPad * srcpad, GstHarness * h)
191 caps = gst_pad_get_current_caps (srcpad);
192 fail_unless (caps != NULL);
193 gst_caps_unref (caps);
194 gst_harness_add_element_src_pad (h, srcpad);
197 GST_START_TEST (test_speex)
199 guint8 flv_header0[] = {
200 0x46, 0x4c, 0x56, 0x01, 0x04, 0x00, 0x00, 0x00,
201 0x09, 0x00, 0x00, 0x00, 0x00
204 guint8 flv_header1[] = {
205 0x12, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x6f, 0x6e,
207 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61,
208 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x61,
209 0x75, 0x64, 0x69, 0x6f, 0x63, 0x6f, 0x64, 0x65,
210 0x63, 0x69, 0x64, 0x00, 0x40, 0x26, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x6d, 0x65,
212 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x63, 0x72,
213 0x65, 0x61, 0x74, 0x6f, 0x72, 0x02, 0x00, 0x13,
214 0x47, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65,
215 0x72, 0x20, 0x46, 0x4c, 0x56, 0x20, 0x6d, 0x75,
216 0x78, 0x65, 0x72, 0x00, 0x0c, 0x63, 0x72, 0x65,
217 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74,
218 0x65, 0x02, 0x00, 0x18, 0x57, 0x65, 0x64, 0x20,
219 0x53, 0x65, 0x70, 0x20, 0x32, 0x33, 0x20, 0x31,
220 0x30, 0x3a, 0x34, 0x39, 0x3a, 0x35, 0x36, 0x20,
221 0x32, 0x30, 0x31, 0x35, 0x00, 0x00, 0x09, 0x00,
225 guint8 speex_header0[] = {
226 0x08, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0xb2, 0x53, 0x70, 0x65, 0x65,
228 0x78, 0x20, 0x20, 0x20, 0x31, 0x2e, 0x32, 0x72,
229 0x63, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
232 0x80, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
233 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
234 0xff, 0xff, 0xff, 0xff, 0x40, 0x01, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
240 guint8 speex_header1[] = {
241 0x08, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0xb2, 0x1f, 0x00, 0x00, 0x00,
243 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20,
244 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x53, 0x74,
245 0x72, 0x65, 0x61, 0x6d, 0x65, 0x72, 0x20, 0x53,
246 0x70, 0x65, 0x65, 0x78, 0x65, 0x6e, 0x63, 0x00,
247 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34,
251 0x08, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0xb2, 0x36, 0x9d, 0x1b, 0x9a,
253 0x20, 0x00, 0x01, 0x68, 0xe8, 0xe8, 0xe8, 0xe8,
254 0xe8, 0xe8, 0xe8, 0x84, 0x00, 0xb4, 0x74, 0x74,
255 0x74, 0x74, 0x74, 0x74, 0x74, 0x42, 0x00, 0x5a,
256 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x21,
257 0x00, 0x2d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
258 0x1d, 0x1b, 0x3b, 0x60, 0xab, 0xab, 0xab, 0xab,
259 0xab, 0x0a, 0xba, 0xba, 0xba, 0xba, 0xb0, 0xab,
260 0xab, 0xab, 0xab, 0xab, 0x0a, 0xba, 0xba, 0xba,
261 0xba, 0xb7, 0x00, 0x00, 0x00, 0x52,
264 GstHarness *h = gst_harness_new_with_padnames ("flvdemux", "sink", NULL);
265 gst_harness_set_src_caps_str (h, "video/x-flv");
267 g_signal_connect (h->element, "pad-added",
268 G_CALLBACK (flvdemux_pad_added), h);
270 gst_harness_push (h, create_buffer (flv_header0, sizeof (flv_header0)));
271 gst_harness_push (h, create_buffer (flv_header1, sizeof (flv_header1)));
272 gst_harness_push (h, create_buffer (speex_header0, sizeof (speex_header0)));
273 gst_harness_push (h, create_buffer (speex_header1, sizeof (speex_header1)));
274 gst_harness_push (h, create_buffer (buffer, sizeof (buffer)));
278 const GstStructure *s;
279 const GValue *streamheader;
280 const GValue *header;
281 const GValue *vorbiscomment;
287 caps = gst_pad_get_current_caps (h->sinkpad);
288 s = gst_caps_get_structure (caps, 0);
290 fail_unless (gst_structure_has_name (s, "audio/x-speex"));
292 streamheader = gst_structure_get_value (s, "streamheader");
293 fail_unless (streamheader != NULL);
294 fail_unless (G_VALUE_HOLDS (streamheader, GST_TYPE_ARRAY));
295 fail_unless_equals_int (2, gst_value_array_get_size (streamheader));
297 header = gst_value_array_get_value (streamheader, 0);
298 fail_unless (header != NULL);
299 fail_unless (G_VALUE_HOLDS (header, GST_TYPE_BUFFER));
300 buf = gst_value_get_buffer (header);
302 vorbiscomment = gst_value_array_get_value (streamheader, 1);
303 fail_unless (header != NULL);
304 fail_unless (G_VALUE_HOLDS (header, GST_TYPE_BUFFER));
305 buf = gst_value_get_buffer (vorbiscomment);
306 list = gst_tag_list_from_vorbiscomment_buffer (buf, NULL, 0, NULL);
307 fail_unless (list != NULL);
308 gst_tag_list_unref (list);
310 gst_structure_get_int (s, "rate", &rate);
311 fail_unless_equals_int (16000, rate);
313 gst_structure_get_int (s, "channels", &channels);
314 fail_unless_equals_int (1, channels);
316 gst_caps_unref (caps);
319 /* we should have gotten 2x speex-headers, and one encoded buffer */
320 fail_unless_equals_int (3, gst_harness_buffers_in_queue (h));
322 gst_harness_teardown (h);
328 GST_START_TEST (test_aac)
330 guint8 flv_header[] = {
331 0x46, 0x4c, 0x56, 0x01, 0x04, 0x00, 0x00, 0x00,
332 0x09, 0x00, 0x00, 0x00, 0x00,
333 0x12, 0x00, 0x00, 0x2d, /* script tag */
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
335 0x00, 0x0a, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61,
336 0x44, 0x61, 0x74, 0x61, 0x03, 0x00, 0x06, 0x53,
337 0x65, 0x72, 0x76, 0x65, 0x72, 0x02, 0x00, 0x11,
338 0x50, 0x65, 0x78, 0x69, 0x70, 0x20, 0x52, 0x54,
339 0x4d, 0x50, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65,
340 0x72, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x38,
343 guint8 aac_header[] = {
344 0x08, 0x00, 0x00, 0x04, /* audio tag */
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf,
346 0x00, 0x13, 0x10, 0x00, 0x00, 0x00, 0x0f,
349 guint8 aac_buffer[] = {
350 0x08, 0x00, 0x01, 0x57, /* audio tag */
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf,
352 0x01, 0x21, 0x21, 0x45, 0x00, 0x14, 0x50, 0x01,
353 0x46, 0xf0, 0x4d, 0xfb, 0x01, 0x3c, 0x08, 0x40,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x07, 0x0e, 0x00, 0x0d, 0xff, 0xe2, 0x14,
356 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
357 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
358 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
359 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
360 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
361 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
362 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
363 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
364 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
365 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
366 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
367 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
368 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
369 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
370 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
371 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
372 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
373 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
374 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
375 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
376 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
377 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
378 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
379 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
380 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
381 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
382 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
383 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
384 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
385 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
386 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
387 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
388 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
389 0xb4, 0xb4, 0xb4, 0xbb, 0xc6, 0x84, 0x29, 0x69,
390 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
391 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
392 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
393 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
394 0x69, 0x69, 0x69, 0x69, 0x69, 0x78, 0x00, 0x00,
398 GstHarness *h = gst_harness_new_with_padnames ("flvdemux", "sink", NULL);
399 gst_harness_set_src_caps_str (h, "video/x-flv");
401 g_signal_connect (h->element, "pad-added",
402 G_CALLBACK (flvdemux_pad_added), h);
404 gst_harness_push (h, create_buffer (flv_header, sizeof (flv_header)));
405 gst_harness_push (h, create_buffer (aac_header, sizeof (aac_header)));
406 gst_harness_push (h, create_buffer (aac_buffer, sizeof (aac_buffer)));
410 const GstStructure *s;
413 const gchar *stream_format;
416 const GValue *codec_data;
418 caps = gst_pad_get_current_caps (h->sinkpad);
419 s = gst_caps_get_structure (caps, 0);
421 fail_unless (gst_structure_has_name (s, "audio/mpeg"));
423 gst_structure_get_int (s, "mpegversion", &mpegversion);
424 fail_unless_equals_int (4, mpegversion);
426 gst_structure_get_boolean (s, "framed", &framed);
427 fail_unless (framed == TRUE);
429 stream_format = gst_structure_get_string (s, "stream-format");
430 fail_unless_equals_string ("raw", stream_format);
432 gst_structure_get_int (s, "rate", &rate);
433 fail_unless_equals_int (24000, rate);
435 gst_structure_get_int (s, "channels", &channels);
436 fail_unless_equals_int (2, channels);
438 codec_data = gst_structure_get_value (s, "codec_data");
439 fail_unless (codec_data != NULL);
440 fail_unless (G_VALUE_HOLDS (codec_data, GST_TYPE_BUFFER));
442 gst_caps_unref (caps);
445 /* we should have gotten one encoded buffer */
446 fail_unless_equals_int (1, gst_harness_buffers_in_queue (h));
448 gst_harness_teardown (h);
453 GST_START_TEST (test_aac_not_support_rate_channels)
455 guint8 flv_header[] = {
456 0x46, 0x4c, 0x56, 0x01, 0x04, 0x00, 0x00, 0x00,
457 0x09, 0x00, 0x00, 0x00, 0x00,
458 0x12, 0x00, 0x00, 0x44, /* script tag */
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
460 0x00, 0x0a, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61,
461 0x44, 0x61, 0x74, 0x61, 0x08, 0x00, 0x00, 0x00,
462 0x04, 0x00, 0x0c, 0x61, 0x75, 0x64, 0x69, 0x6f,
463 0x63, 0x6f, 0x64, 0x65, 0x63, 0x69, 0x64, 0x00,
464 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x00, 0x0d, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x64,
466 0x61, 0x74, 0x61, 0x72, 0x61, 0x74, 0x65, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4f,
471 guint8 aac_header[] = {
472 0x08, 0x00, 0x00, 0x04, /* audio tag */
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf,
474 0x00, 0x13, 0x88, 0x00, 0x00, 0x00, 0x0f,
477 guint8 aac_buffer[] = {
478 0x08, 0x00, 0x01, 0x57, /* audio tag */
479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf,
480 0x01, 0x21, 0x21, 0x45, 0x00, 0x14, 0x50, 0x01,
481 0x46, 0xf0, 0x4d, 0xfb, 0x01, 0x3c, 0x08, 0x40,
482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483 0x00, 0x07, 0x0e, 0x00, 0x0d, 0xff, 0xe2, 0x14,
484 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
485 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
486 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
487 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
488 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
489 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
490 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
491 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
492 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
493 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
494 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
495 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
496 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
497 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
498 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
499 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
500 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
501 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
502 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
503 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
504 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
505 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
506 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
507 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
508 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
509 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
510 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
511 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
512 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
513 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
514 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
515 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
516 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
517 0xb4, 0xb4, 0xb4, 0xbb, 0xc6, 0x84, 0x29, 0x69,
518 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
519 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
520 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
521 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
522 0x69, 0x69, 0x69, 0x69, 0x69, 0x78, 0x00, 0x00,
526 GstHarness *h = gst_harness_new_with_padnames ("flvdemux", "sink", NULL);
527 gst_harness_set_src_caps_str (h, "video/x-flv");
529 g_signal_connect (h->element, "pad-added",
530 G_CALLBACK (flvdemux_pad_added), h);
532 gst_harness_push (h, create_buffer (flv_header, sizeof (flv_header)));
533 gst_harness_push (h, create_buffer (aac_header, sizeof (aac_header)));
534 gst_harness_push (h, create_buffer (aac_buffer, sizeof (aac_buffer)));
538 const GstStructure *s;
541 const gchar *stream_format;
544 const GValue *codec_data;
546 caps = gst_pad_get_current_caps (h->sinkpad);
547 s = gst_caps_get_structure (caps, 0);
549 fail_unless (gst_structure_has_name (s, "audio/mpeg"));
551 gst_structure_get_int (s, "mpegversion", &mpegversion);
552 fail_unless_equals_int (4, mpegversion);
554 gst_structure_get_boolean (s, "framed", &framed);
555 fail_unless (framed == TRUE);
557 stream_format = gst_structure_get_string (s, "stream-format");
558 fail_unless_equals_string ("raw", stream_format);
560 gst_structure_get_int (s, "rate", &rate);
561 fail_unless_equals_int (22050, rate);
563 gst_structure_get_int (s, "channels", &channels);
564 fail_unless_equals_int (1, channels);
566 codec_data = gst_structure_get_value (s, "codec_data");
567 fail_unless (codec_data != NULL);
568 fail_unless (G_VALUE_HOLDS (codec_data, GST_TYPE_BUFFER));
570 gst_caps_unref (caps);
573 /* we should have gotten one encoded buffer */
574 fail_unless_equals_int (1, gst_harness_buffers_in_queue (h));
576 gst_harness_teardown (h);
581 GST_START_TEST (test_h264)
583 guint8 flv_header[] = {
584 0x46, 0x4c, 0x56, 0x01, 0x01, 0x00, 0x00, 0x00,
585 0x09, 0x00, 0x00, 0x00, 0x00,
586 0x12, 0x00, 0x00, 0x2d, /* script tag */
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
588 0x00, 0x0a, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61,
589 0x44, 0x61, 0x74, 0x61, 0x03, 0x00, 0x06, 0x53,
590 0x65, 0x72, 0x76, 0x65, 0x72, 0x02, 0x00, 0x11,
591 0x50, 0x65, 0x78, 0x69, 0x70, 0x20, 0x52, 0x54,
592 0x4d, 0x50, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65,
593 0x72, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x38,
596 guint8 h264_packet0[] = {
597 0x09, 0x00, 0x00, 0x1e, /* video tag */
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
599 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0xc0, 0x1e,
600 0xff, 0xe1, 0x00, 0x0a, 0x67, 0x42, 0xc0, 0x1e,
601 0x95, 0xa0, 0x28, 0x0b, 0xde, 0x54, 0x01, 0x00,
602 0x04, 0x68, 0xce, 0x3c, 0x80, 0x00, 0x00, 0x00,
606 guint8 h264_packet1[] = {
607 0x09, 0x00, 0x00, 0x1b, /* video tag */
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
609 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
610 0x67, 0x42, 0xc0, 0x1e, 0x95, 0xa0, 0x28, 0x0b,
611 0xde, 0x54, 0x00, 0x00, 0x00, 0x04, 0x68, 0xce,
612 0x3c, 0x80, 0x00, 0x00, 0x00, 0x26
615 GstHarness *h = gst_harness_new_with_padnames ("flvdemux", "sink", NULL);
616 gst_harness_set_src_caps_str (h, "video/x-flv");
618 g_signal_connect (h->element, "pad-added",
619 G_CALLBACK (flvdemux_pad_added), h);
621 gst_harness_push (h, create_buffer (flv_header, sizeof (flv_header)));
622 gst_harness_push (h, create_buffer (h264_packet0, sizeof (h264_packet0)));
623 gst_harness_push (h, create_buffer (h264_packet1, sizeof (h264_packet1)));
627 const GstStructure *s;
628 const gchar *stream_format;
629 const GValue *codec_data;
631 caps = gst_pad_get_current_caps (h->sinkpad);
632 s = gst_caps_get_structure (caps, 0);
634 fail_unless (gst_structure_has_name (s, "video/x-h264"));
636 stream_format = gst_structure_get_string (s, "stream-format");
637 fail_unless_equals_string ("avc", stream_format);
639 codec_data = gst_structure_get_value (s, "codec_data");
640 fail_unless (codec_data != NULL);
641 fail_unless (G_VALUE_HOLDS (codec_data, GST_TYPE_BUFFER));
643 gst_caps_unref (caps);
646 /* we should have gotten one encoded buffer */
647 fail_unless_equals_int (1, gst_harness_buffers_in_queue (h));
649 gst_harness_teardown (h);
656 flvdemux_suite (void)
658 Suite *s = suite_create ("flvdemux");
659 TCase *tc_chain = tcase_create ("general");
661 suite_add_tcase (s, tc_chain);
662 tcase_add_test (tc_chain, test_reuse_push);
663 tcase_add_test (tc_chain, test_reuse_pull);
665 tcase_add_test (tc_chain, test_speex);
666 tcase_add_test (tc_chain, test_aac);
667 tcase_add_test (tc_chain, test_h264);
668 tcase_add_test (tc_chain, test_aac_not_support_rate_channels);
673 GST_CHECK_MAIN (flvdemux)