1 /* GStreamer
2 * Copyright (C) 2014 Song Bing <b06498@freescale.com>
3 *
4 * streamsynchronizer.c: Unit test for streamsynchronizer
5 *
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.
10 *
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.
15 *
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.
20 */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <gst/check/gstcheck.h>
26
27 static gboolean have_group_id = FALSE;
28 static guint group_id_pre;
29 static GMutex test_mutex;
30
31 static GstPadProbeReturn
event_probe(GstPad * pad,GstPadProbeInfo * info,gpointer udata)32 event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
33 {
34 GstPadProbeReturn ret = GST_PAD_PROBE_OK;
35 GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
36
37 switch (GST_EVENT_TYPE (event)) {
38 case GST_EVENT_STREAM_START:{
39 guint group_id;
40
41 g_mutex_lock (&test_mutex);
42 fail_unless (gst_event_parse_group_id (event, &group_id));
43
44 if (have_group_id) {
45 if (group_id_pre != group_id) {
46 event = gst_event_copy (event);
47 gst_event_set_group_id (event, group_id_pre);
48 gst_event_replace ((GstEvent **) & info->data, event);
49 gst_event_unref (event);
50 }
51 } else {
52 group_id_pre = group_id;
53 have_group_id = TRUE;
54 }
55 g_mutex_unlock (&test_mutex);
56 break;
57 }
58 default:
59 break;
60 }
61
62 return ret;
63 }
64
65 static void
run_streamsynchronizer_handle_eos(const gchar * launch_line)66 run_streamsynchronizer_handle_eos (const gchar * launch_line)
67 {
68 GstElement *pipeline;
69 GstElement *audiosrc;
70 GstElement *videosrc;
71 GstMessage *msg;
72 GstPad *pad;
73 GstBus *bus;
74
75 pipeline = gst_parse_launch (launch_line, NULL);
76 fail_unless (pipeline != NULL);
77
78 videosrc = gst_bin_get_by_name (GST_BIN (pipeline), "videosrc");
79 fail_unless (videosrc != NULL);
80
81 pad = gst_element_get_static_pad (videosrc, "src");
82 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, event_probe,
83 videosrc, NULL);
84 gst_object_unref (pad);
85 gst_object_unref (videosrc);
86
87 audiosrc = gst_bin_get_by_name (GST_BIN (pipeline), "audiosrc");
88 fail_unless (audiosrc != NULL);
89
90 pad = gst_element_get_static_pad (audiosrc, "src");
91 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, event_probe,
92 audiosrc, NULL);
93 gst_object_unref (pad);
94 gst_object_unref (audiosrc);
95
96 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
97
98 fail_unless (gst_element_set_state (pipeline, GST_STATE_PLAYING) !=
99 GST_STATE_CHANGE_FAILURE);
100
101 msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
102 GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
103
104 fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ASYNC_DONE);
105 gst_message_unref (msg);
106
107 fail_unless_equals_int (gst_element_get_state (pipeline, NULL, NULL,
108 GST_CLOCK_TIME_NONE), GST_STATE_CHANGE_SUCCESS);
109
110 fail_unless (gst_element_set_state (pipeline, GST_STATE_PAUSED) !=
111 GST_STATE_CHANGE_FAILURE);
112
113 /* can't ensure can received async-done message when call state change very quickly. */
114 fail_unless_equals_int (gst_element_get_state (pipeline, NULL, NULL,
115 GST_CLOCK_TIME_NONE), GST_STATE_CHANGE_SUCCESS);
116
117 fail_unless (gst_element_set_state (pipeline, GST_STATE_PLAYING) !=
118 GST_STATE_CHANGE_FAILURE);
119
120 fail_unless_equals_int (gst_element_get_state (pipeline, NULL, NULL,
121 GST_CLOCK_TIME_NONE), GST_STATE_CHANGE_SUCCESS);
122
123 gst_element_set_state (pipeline, GST_STATE_NULL);
124
125 gst_object_unref (bus);
126 gst_object_unref (pipeline);
127 }
128
GST_START_TEST(test_streamsynchronizer_normal)129 GST_START_TEST (test_streamsynchronizer_normal)
130 {
131 run_streamsynchronizer_handle_eos ("videotestsrc name=videosrc ! "
132 "streamsynchronizer name=streamsync audiotestsrc name=audiosrc ! "
133 "streamsync. streamsync. ! fakesink sync=true streamsync. ! fakesink sync=true");
134 }
135
136 GST_END_TEST;
137
GST_START_TEST(test_streamsynchronizer_track_with_less_data)138 GST_START_TEST (test_streamsynchronizer_track_with_less_data)
139 {
140 run_streamsynchronizer_handle_eos ("videotestsrc name=videosrc ! "
141 "streamsynchronizer name=streamsync audiotestsrc name=audiosrc num-buffers=1 ! "
142 "streamsync. streamsync. ! fakesink sync=true streamsync. ! fakesink sync=true");
143 }
144
145 GST_END_TEST;
146
GST_START_TEST(test_streamsynchronizer_track_without_data)147 GST_START_TEST (test_streamsynchronizer_track_without_data)
148 {
149 run_streamsynchronizer_handle_eos ("videotestsrc name=videosrc ! "
150 "streamsynchronizer name=streamsync audiotestsrc name=audiosrc num-buffers=0 ! "
151 "streamsync. streamsync. ! fakesink sync=true streamsync. ! fakesink sync=true");
152 }
153
154 GST_END_TEST;
155
156 static Suite *
streamsynchronizer_handle_eos_suite(void)157 streamsynchronizer_handle_eos_suite (void)
158 {
159 Suite *s = suite_create ("streamsynchronizer");
160 TCase *tc_chain = tcase_create ("general");
161
162 suite_add_tcase (s, tc_chain);
163 tcase_add_test (tc_chain, test_streamsynchronizer_normal);
164 tcase_add_test (tc_chain, test_streamsynchronizer_track_with_less_data);
165 tcase_add_test (tc_chain, test_streamsynchronizer_track_without_data);
166 return s;
167 }
168
169 GST_CHECK_MAIN (streamsynchronizer_handle_eos);
170