Initialize Tizen 2.3
[framework/multimedia/gst-plugins-base0.10.git] / mobile / tests / examples / playrec / playrec.c
1 /* GStreamer
2  *
3  * Copyright (C) 2010 Wim Taymans <wim.taymans@collabora.co.uk>
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., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /* An example of synchronized playback and recording.
22  * The trick is to wait for the playback pipeline to preroll before starting
23  * playback and recording.
24  */
25 #include <string.h>
26
27 #include <gst/gst.h>
28
29 /* Define to run the asynchronous version. This requires 0.10.31 of the
30  * GStreamer core. The async version has the benefit that it doesn't block the
31  * main thread but it produces slightly less clear code. */
32 #define ASYNC_VERSION
33
34 static GMainLoop *loop;
35 static GstElement *pipeline = NULL;
36 static GstElement *play_bin, *play_source, *play_sink;
37 static GstElement *rec_bin, *rec_source, *rec_sink;
38
39 static gboolean
40 message_handler (GstBus * bus, GstMessage * message, gpointer user_data)
41 {
42
43   switch (GST_MESSAGE_TYPE (message)) {
44 #ifdef ASYNC_VERSION
45     case GST_MESSAGE_ELEMENT:{
46       const GstStructure *str;
47
48       str = gst_message_get_structure (message);
49
50       if (gst_structure_has_name (str, "GstBinForwarded")) {
51         GstMessage *orig;
52
53         /* unwrap the element message */
54         gst_structure_get (str, "message", GST_TYPE_MESSAGE, &orig, NULL);
55         g_assert (orig);
56
57         switch (GST_MESSAGE_TYPE (orig)) {
58           case GST_MESSAGE_ASYNC_DONE:
59             g_print ("ASYNC done %s\n", GST_MESSAGE_SRC_NAME (orig));
60             if (GST_MESSAGE_SRC (orig) == GST_OBJECT_CAST (play_bin)) {
61               g_print
62                   ("prerolled, starting synchronized playback and recording\n");
63               /* returns ASYNC because the sink linked to the live source is not
64                * prerolled */
65               g_assert (gst_element_set_state (pipeline,
66                       GST_STATE_PLAYING) == GST_STATE_CHANGE_ASYNC);
67             }
68             break;
69           default:
70             break;
71         }
72       }
73       break;
74     }
75 #endif
76     case GST_MESSAGE_EOS:
77       g_print ("EOS\n");
78       g_main_loop_quit (loop);
79       break;
80     case GST_MESSAGE_ERROR:{
81       GError *err = NULL;
82
83       gst_message_parse_error (message, &err, NULL);
84       g_print ("error: %s\n", err->message);
85       g_clear_error (&err);
86
87       g_main_loop_quit (loop);
88       break;
89     }
90     default:
91       break;
92   }
93
94   return TRUE;
95 }
96
97 int
98 main (int argc, char *argv[])
99 {
100   GstBus *bus;
101   gint watch_id;
102
103   gst_init (NULL, NULL);
104
105   loop = g_main_loop_new (NULL, TRUE);
106
107   pipeline = gst_pipeline_new ("pipeline");
108 #ifdef ASYNC_VERSION
109   /* this enables messages of individual elements inside the pipeline */
110   g_object_set (pipeline, "message-forward", TRUE, NULL);
111 #endif
112
113   /* make a bin with the playback elements this is a non-live pipeline */
114   play_bin = gst_bin_new ("play_bin");
115   play_source = gst_element_factory_make ("audiotestsrc", "play_source");
116   play_sink = gst_element_factory_make ("autoaudiosink", "play_sink");
117
118   gst_bin_add (GST_BIN (play_bin), play_source);
119   gst_bin_add (GST_BIN (play_bin), play_sink);
120
121   gst_element_link (play_source, play_sink);
122
123   /* make bin with the record elements, this is a live pipeline */
124   rec_bin = gst_bin_new ("rec_bin");
125   rec_source = gst_element_factory_make ("autoaudiosrc", "rec_source");
126   rec_sink = gst_element_factory_make ("fakesink", "rec_sink");
127
128   gst_bin_add (GST_BIN (rec_bin), rec_source);
129   gst_bin_add (GST_BIN (rec_bin), rec_sink);
130
131   gst_element_link (rec_source, rec_sink);
132
133   gst_bin_add (GST_BIN (pipeline), play_bin);
134   gst_bin_add (GST_BIN (pipeline), rec_bin);
135
136   bus = gst_element_get_bus (pipeline);
137   watch_id = gst_bus_add_watch (bus, message_handler, NULL);
138   gst_object_unref (bus);
139
140   g_print ("going to PAUSED\n");
141   /* returns NO_PREROLL because we have a live element */
142   g_assert (gst_element_set_state (pipeline,
143           GST_STATE_PAUSED) == GST_STATE_CHANGE_NO_PREROLL);
144
145   g_print ("waiting for playback preroll\n");
146 #ifndef ASYNC_VERSION
147   /* sync wait for preroll on the playback bin and then go to PLAYING */
148   g_assert (gst_element_get_state (play_bin, NULL, NULL,
149           GST_CLOCK_TIME_NONE) == GST_STATE_CHANGE_SUCCESS);
150   g_print ("prerolled, starting synchronized playback and recording\n");
151   /* returns ASYNC because the sink linked to the live source is not
152    * prerolled */
153   g_assert (gst_element_set_state (pipeline,
154           GST_STATE_PLAYING) == GST_STATE_CHANGE_ASYNC);
155 #endif
156
157   g_main_loop_run (loop);
158
159   g_source_remove (watch_id);
160   gst_element_set_state (pipeline, GST_STATE_NULL);
161   gst_object_unref (pipeline);
162
163   g_main_loop_unref (loop);
164
165   return 0;
166 }