| /* GStreamer |
| * |
| * unit test for streamheader handling |
| * |
| * Copyright (C) 2007 Thomas Vander Stichele <thomas at apestaart dot org> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include <glib.h> |
| |
| #ifdef G_OS_WIN32 |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <io.h> |
| #include <fcntl.h> |
| #define pipe(fds) _pipe(fds,4096,O_BINARY) |
| #else |
| #include <unistd.h> |
| #endif |
| |
| #include <gio/gio.h> |
| #include <gst/check/gstcheck.h> |
| #include <gst/check/gstbufferstraw.h> |
| |
| #ifndef GST_DISABLE_PARSE |
| |
| /* this tests a gdp-serialized tag from audiotestsrc being sent only once |
| * to clients of multifdsink */ |
| |
| static int n_tags = 0; |
| |
| static GstPadProbeReturn |
| tag_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) |
| { |
| GMainLoop *loop = user_data; |
| GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info); |
| |
| switch (GST_EVENT_TYPE (event)) { |
| case GST_EVENT_TAG: |
| { |
| ++n_tags; |
| fail_if (n_tags > 1, "More than 1 tag received"); |
| break; |
| } |
| case GST_EVENT_EOS: |
| { |
| g_main_loop_quit (loop); |
| break; |
| } |
| default: |
| break; |
| } |
| |
| return GST_PAD_PROBE_OK; |
| } |
| |
| GST_START_TEST (test_multifdsink_gdp_tag) |
| { |
| GstElement *p1, *p2; |
| GstElement *src, *sink, *depay; |
| GstPad *pad; |
| GMainLoop *loop; |
| int pfd[2]; |
| |
| loop = g_main_loop_new (NULL, FALSE); |
| |
| p1 = gst_parse_launch ("audiotestsrc num-buffers=10 ! gdppay" |
| " ! multifdsink name=p1sink", NULL); |
| fail_if (p1 == NULL); |
| p2 = gst_parse_launch ("fdsrc name=p2src ! gdpdepay name=depay" |
| " ! fakesink name=p2sink signal-handoffs=True", NULL); |
| fail_if (p2 == NULL); |
| |
| fail_if (pipe (pfd) == -1); |
| |
| gst_element_set_state (p1, GST_STATE_READY); |
| |
| sink = gst_bin_get_by_name (GST_BIN (p1), "p1sink"); |
| g_signal_emit_by_name (sink, "add", pfd[1], NULL); ///s[1] |
| gst_object_unref (sink); |
| |
| src = gst_bin_get_by_name (GST_BIN (p2), "p2src"); |
| g_object_set (G_OBJECT (src), "fd", pfd[0], NULL); |
| gst_object_unref (src); |
| |
| depay = gst_bin_get_by_name (GST_BIN (p2), "depay"); |
| fail_if (depay == NULL); |
| |
| pad = gst_element_get_static_pad (depay, "src"); |
| fail_unless (pad != NULL, "Could not get pad out of depay"); |
| gst_object_unref (depay); |
| |
| gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, |
| tag_event_probe_cb, loop, NULL); |
| |
| gst_element_set_state (p1, GST_STATE_PLAYING); |
| gst_element_set_state (p2, GST_STATE_PLAYING); |
| |
| g_main_loop_run (loop); |
| |
| assert_equals_int (n_tags, 1); |
| |
| gst_element_set_state (p1, GST_STATE_NULL); |
| gst_object_unref (p1); |
| gst_element_set_state (p2, GST_STATE_NULL); |
| gst_object_unref (p2); |
| } |
| |
| GST_END_TEST; |
| |
| #ifdef HAVE_VORBIS |
| /* this tests gdp-serialized Vorbis header pages being sent only once |
| * to clients of multifdsink; the gdp depayloader should deserialize |
| * exactly three in_caps buffers for the three header packets */ |
| |
| static int n_in_caps = 0; |
| |
| static GstPadProbeReturn |
| buffer_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) |
| { |
| GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info); |
| GstMapInfo map; |
| |
| gst_buffer_map (buffer, &map, GST_MAP_READ); |
| |
| if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_HEADER)) { |
| GstCaps *caps; |
| GstStructure *s; |
| const GValue *sh; |
| GArray *buffers; |
| GstBuffer *buf; |
| int i; |
| gboolean found = FALSE; |
| |
| n_in_caps++; |
| |
| caps = gst_pad_get_current_caps (pad); |
| s = gst_caps_get_structure (caps, 0); |
| fail_unless (gst_structure_has_field (s, "streamheader")); |
| sh = gst_structure_get_value (s, "streamheader"); |
| buffers = g_value_peek_pointer (sh); |
| assert_equals_int (buffers->len, 3); |
| |
| for (i = 0; i < 3; ++i) { |
| GValue *val; |
| GstMapInfo map2; |
| |
| val = &g_array_index (buffers, GValue, i); |
| buf = g_value_peek_pointer (val); |
| fail_unless (GST_IS_BUFFER (buf)); |
| |
| gst_buffer_map (buf, &map2, GST_MAP_READ); |
| if (map2.size == map.size) { |
| if (memcmp (map2.data, map.data, map.size) == 0) { |
| found = TRUE; |
| } |
| } |
| gst_buffer_unmap (buf, &map2); |
| } |
| fail_unless (found, "Did not find incoming HEADER buffer %p on caps", |
| buffer); |
| |
| gst_caps_unref (caps); |
| } |
| gst_buffer_unmap (buffer, &map); |
| |
| return TRUE; |
| } |
| |
| GST_START_TEST (test_multifdsink_gdp_vorbisenc) |
| { |
| GstElement *p1, *p2; |
| GstElement *src, *sink, *depay; |
| GstPad *pad; |
| GMainLoop *loop; |
| int pfd[2]; |
| |
| loop = g_main_loop_new (NULL, FALSE); |
| |
| p1 = gst_parse_launch ("audiotestsrc num-buffers=10 ! audioconvert " |
| " ! vorbisenc ! gdppay ! multifdsink name=p1sink", NULL); |
| fail_if (p1 == NULL); |
| p2 = gst_parse_launch ("fdsrc name=p2src ! gdpdepay name=depay" |
| " ! fakesink name=p2sink signal-handoffs=True", NULL); |
| fail_if (p2 == NULL); |
| |
| fail_if (pipe (pfd) == -1); |
| |
| gst_element_set_state (p1, GST_STATE_READY); |
| |
| sink = gst_bin_get_by_name (GST_BIN (p1), "p1sink"); |
| g_signal_emit_by_name (sink, "add", pfd[1], NULL); |
| gst_object_unref (sink); |
| |
| src = gst_bin_get_by_name (GST_BIN (p2), "p2src"); |
| g_object_set (G_OBJECT (src), "fd", pfd[0], NULL); |
| gst_object_unref (src); |
| |
| depay = gst_bin_get_by_name (GST_BIN (p2), "depay"); |
| fail_if (depay == NULL); |
| |
| pad = gst_element_get_static_pad (depay, "src"); |
| fail_unless (pad != NULL, "Could not get pad out of depay"); |
| gst_object_unref (depay); |
| |
| gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, |
| tag_event_probe_cb, loop, NULL); |
| gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, buffer_probe_cb, NULL, |
| NULL); |
| |
| gst_element_set_state (p1, GST_STATE_PLAYING); |
| gst_element_set_state (p2, GST_STATE_PLAYING); |
| |
| g_main_loop_run (loop); |
| |
| assert_equals_int (n_in_caps, 3); |
| |
| gst_element_set_state (p1, GST_STATE_NULL); |
| gst_object_unref (p1); |
| gst_element_set_state (p2, GST_STATE_NULL); |
| gst_object_unref (p2); |
| } |
| |
| GST_END_TEST; |
| #endif /* HAVE_VORBIS */ |
| |
| #endif /* #ifndef GST_DISABLE_PARSE */ |
| |
| static Suite * |
| streamheader_suite (void) |
| { |
| Suite *s = suite_create ("streamheader"); |
| TCase *tc_chain = tcase_create ("general"); |
| |
| suite_add_tcase (s, tc_chain); |
| #ifndef GST_DISABLE_PARSE |
| tcase_add_test (tc_chain, test_multifdsink_gdp_tag); |
| #ifdef HAVE_VORBIS |
| tcase_add_test (tc_chain, test_multifdsink_gdp_vorbisenc); |
| #endif |
| #endif |
| |
| return s; |
| } |
| |
| GST_CHECK_MAIN (streamheader); |