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