tests: wasapi: check PLAYING -> READY -> PLAYING
[platform/upstream/gstreamer.git] / tests / check / elements / wasapi.c
1 /* GStreamer unit test for wasapi plugin
2  *
3  * Copyright (C) 2021 Jakub Janků <janku.jakub.jj@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <gst/gst.h>
26 #include <gst/check/gstcheck.h>
27
28 typedef struct
29 {
30   GMainLoop *loop;
31   GstElement *pipe;
32   guint rem_st_changes;
33 } SinkPlayReadyTData;
34
35 static gboolean
36 bus_watch_cb (GstBus * bus, GstMessage * message, gpointer user_data)
37 {
38   fail_unless (message->type != GST_MESSAGE_ERROR);
39   return G_SOURCE_CONTINUE;
40 }
41
42 static gboolean
43 state_timer_cb (gpointer user_data)
44 {
45   SinkPlayReadyTData *tdata = user_data;
46   GstState nxt_st = tdata->rem_st_changes % 2 == 1 ?
47       GST_STATE_READY : GST_STATE_PLAYING;
48
49   ASSERT_SET_STATE (tdata->pipe, nxt_st, GST_STATE_CHANGE_SUCCESS);
50   tdata->rem_st_changes--;
51
52   if (tdata->rem_st_changes == 0) {
53     g_main_loop_quit (tdata->loop);
54     return G_SOURCE_REMOVE;
55   }
56   return G_SOURCE_CONTINUE;
57 }
58
59 /* Test that the wasapisink can survive the state change
60  * from PLAYING to READY and then back to PLAYING */
61 GST_START_TEST (test_sink_play_ready)
62 {
63   SinkPlayReadyTData tdata;
64   GstBus *bus;
65
66   tdata.pipe = gst_parse_launch ("audiotestsrc ! wasapisink async=false", NULL);
67   fail_unless (tdata.pipe != NULL);
68   bus = gst_element_get_bus (tdata.pipe);
69   fail_unless (bus != NULL);
70   gst_bus_add_watch (bus, bus_watch_cb, NULL);
71
72   ASSERT_SET_STATE (tdata.pipe, GST_STATE_PLAYING, GST_STATE_CHANGE_SUCCESS);
73   tdata.rem_st_changes = 3;     /* -> READY -> PLAYING -> QUIT */
74   g_timeout_add_seconds (1, state_timer_cb, &tdata);
75
76   tdata.loop = g_main_loop_new (NULL, FALSE);
77   g_main_loop_run (tdata.loop);
78
79   g_main_loop_unref (tdata.loop);
80   gst_bus_remove_watch (bus);
81   gst_object_unref (bus);
82   gst_object_unref (tdata.pipe);
83 }
84
85 GST_END_TEST;
86
87 static gboolean
88 device_is_available (const gchar * factory_name)
89 {
90   GstElement *elem;
91   gboolean avail;
92
93   elem = gst_element_factory_make (factory_name, NULL);
94   if (elem == NULL) {
95     GST_INFO ("%s: not available", factory_name);
96     return FALSE;
97   }
98
99   avail = gst_element_set_state (elem, GST_STATE_READY)
100       == GST_STATE_CHANGE_SUCCESS;
101   if (!avail) {
102     GST_INFO ("%s: cannot change state to ready", factory_name);
103   }
104
105   gst_element_set_state (elem, GST_STATE_NULL);
106   gst_object_unref (elem);
107
108   return avail;
109 }
110
111 static Suite *
112 wasapi_suite (void)
113 {
114   Suite *suite = suite_create ("wasapi");
115   TCase *tc_sink = tcase_create ("sink");
116
117   suite_add_tcase (suite, tc_sink);
118
119   if (device_is_available ("wasapisink")) {
120     tcase_add_test (tc_sink, test_sink_play_ready);
121   } else {
122     GST_INFO ("Sink not available, skipping sink tests");
123   }
124
125   return suite;
126 }
127
128 GST_CHECK_MAIN (wasapi)