1 |
|
2 #include <gst/gst_global.h> |
|
3 #include <stdlib.h> |
|
4 #include <gst/gst.h> |
|
5 #include <gst/gstelement.h> |
|
6 #include <string.h> |
|
7 #define LOG_FILE "c:\\logs\\amr_record_logs.txt" |
|
8 #include "std_log_result.h" |
|
9 #include <gst/interfaces/gstspeechencoderconfig.h> |
|
10 #define LOG_FILENAME_LINE __FILE__, __LINE__ |
|
11 #define LOG_FILENAME_LEN 256 |
|
12 #define _DEBUG 1 |
|
13 |
|
14 static char log_filename[LOG_FILENAME_LEN]; |
|
15 |
|
16 static guint bitrate = 0; |
|
17 static guint record_duration = 10000; |
|
18 static guint _enable_logs = 0; |
|
19 |
|
20 static GstSpeechEncoderConfigIntfc* iface; |
|
21 |
|
22 |
|
23 #define ENABLE_LOGS |
|
24 |
|
25 #ifdef ENABLE_LOGS |
|
26 #define RET_GST_ERR_STR(var, level, str) \ |
|
27 if ( level == var )\ |
|
28 return str; |
|
29 |
|
30 static inline const char* _gst_err_cat( GstDebugLevel level) |
|
31 { |
|
32 |
|
33 RET_GST_ERR_STR(level,GST_LEVEL_NONE,""); |
|
34 RET_GST_ERR_STR(level,GST_LEVEL_ERROR,"E "); |
|
35 RET_GST_ERR_STR(level,GST_LEVEL_WARNING,"W "); |
|
36 RET_GST_ERR_STR(level,GST_LEVEL_INFO,"I "); |
|
37 RET_GST_ERR_STR(level,GST_LEVEL_DEBUG,"D "); |
|
38 RET_GST_ERR_STR(level,GST_LEVEL_LOG, "L "); |
|
39 RET_GST_ERR_STR(level,GST_LEVEL_FIXME, "F "); |
|
40 RET_GST_ERR_STR(level,GST_LEVEL_MEMDUMP, "M "); |
|
41 return ""; |
|
42 } |
|
43 |
|
44 static FILE* log_fp = 0; |
|
45 |
|
46 static void open_log_fp() |
|
47 { |
|
48 if (!log_fp) |
|
49 { |
|
50 snprintf(log_filename, LOG_FILENAME_LEN, "C:\\logs\\testframework\\gst_amr_br%d.log", bitrate); |
|
51 |
|
52 log_fp = fopen(log_filename, "w"); |
|
53 if (!log_fp) |
|
54 return; |
|
55 } |
|
56 } |
|
57 |
|
58 |
|
59 static void _gstLogFunction (GstDebugCategory *category, |
|
60 GstDebugLevel level, |
|
61 const gchar *file, |
|
62 const gchar *function, |
|
63 gint line, |
|
64 GObject *object, |
|
65 GstDebugMessage *message, |
|
66 gpointer data) |
|
67 { |
|
68 open_log_fp(); |
|
69 |
|
70 fprintf(log_fp, "%s : %s \n", _gst_err_cat(level), gst_debug_message_get(message)); |
|
71 fflush(log_fp); |
|
72 |
|
73 } |
|
74 #endif // ENABLE_LOGS |
|
75 |
|
76 static void parse_args(int argc, char** argv) |
|
77 { |
|
78 |
|
79 gint cur = 1; |
|
80 while ( argv[cur] && cur < argc ) |
|
81 { |
|
82 GST_WARNING("br:%d, record_duration:%d \n",bitrate,record_duration); |
|
83 if( !strcmp(argv[cur],"-br") ) bitrate = atoi(argv[cur+1]); |
|
84 else if( !strcmp(argv[cur],"-l") ) _enable_logs = atoi(argv[cur+1]); |
|
85 else if( !strcmp(argv[cur],"-d") ) record_duration = atoi(argv[cur+1]); |
|
86 |
|
87 cur+=2; |
|
88 } |
|
89 } |
|
90 |
|
91 |
|
92 GstElement *pipeline, *source, *amrmux,*sink; |
|
93 GstBus *bus; |
|
94 GMainLoop *loop; |
|
95 |
|
96 static gboolean |
|
97 bus_call (GstBus *bus, |
|
98 GstMessage *msg, |
|
99 gpointer data) |
|
100 { |
|
101 #ifdef ENABLE_LOGS |
|
102 if(_enable_logs) |
|
103 { |
|
104 open_log_fp(); |
|
105 fprintf(log_fp,"[msg] %s from %s\n", GST_MESSAGE_TYPE_NAME(msg), GST_MESSAGE_SRC_NAME (msg)); |
|
106 } |
|
107 #endif |
|
108 |
|
109 switch (GST_MESSAGE_TYPE (msg)) { |
|
110 case GST_MESSAGE_EOS: |
|
111 gst_element_set_state (pipeline, GST_STATE_NULL); |
|
112 g_main_loop_quit(loop); |
|
113 gst_object_unref (GST_OBJECT (pipeline)); |
|
114 break; |
|
115 |
|
116 case GST_MESSAGE_ERROR: { |
|
117 gchar *debug; |
|
118 GError *err; |
|
119 gst_message_parse_error (msg, &err, &debug); |
|
120 g_free (debug); |
|
121 g_print ("Error: %s\n", err->message); |
|
122 g_error_free (err); |
|
123 break; |
|
124 } |
|
125 default: |
|
126 break; |
|
127 } |
|
128 |
|
129 return TRUE; |
|
130 } |
|
131 |
|
132 static gboolean |
|
133 quit_loop (gpointer data) |
|
134 { |
|
135 GST_WARNING("Sending EOS\n"); |
|
136 gst_element_send_event (pipeline, gst_event_new_eos ()); |
|
137 return TRUE; |
|
138 } |
|
139 |
|
140 int main (int argc, char *argv[]) |
|
141 { |
|
142 char filename[1024]; |
|
143 GstCaps* caps; |
|
144 #ifdef ENABLE_LOGS |
|
145 if ( _enable_logs ) |
|
146 setenv("GST_DEBUG","2",1); |
|
147 #endif // ENABLE_LOGS |
|
148 |
|
149 parse_args(argc,argv); |
|
150 |
|
151 gst_init (&argc, &argv); |
|
152 #ifdef ENABLE_LOGS |
|
153 if ( _enable_logs ) |
|
154 gst_debug_add_log_function( _gstLogFunction, 0); |
|
155 #endif // ENABLE_LOGS |
|
156 |
|
157 loop = g_main_loop_new (NULL, FALSE); |
|
158 |
|
159 /* create elements */ |
|
160 pipeline = gst_pipeline_new ("audio-player"); |
|
161 source = gst_element_factory_make ("devsoundsrc", "audio-source"); |
|
162 amrmux = gst_element_factory_make ("amrmux", "amrmux"); |
|
163 sink = gst_element_factory_make ("filesink", "sink"); |
|
164 |
|
165 if (!pipeline || !source || !amrmux || !sink) { |
|
166 g_print ("One element could not be created\n"); |
|
167 GST_ERROR("One element could not be created\n"); |
|
168 return -1; |
|
169 } |
|
170 if(bitrate > 0) |
|
171 { |
|
172 snprintf(filename, 1024, "C:\\data\\amr_record_%d.amr", bitrate ); |
|
173 } |
|
174 else |
|
175 { |
|
176 snprintf(filename, 1024, "C:\\data\\amr_record.amr" ); |
|
177 } |
|
178 |
|
179 /* set filename property on the file source. Also add a message handler. */ |
|
180 g_object_set (G_OBJECT (sink), "location", filename, NULL); |
|
181 /* put all elements in a bin */ |
|
182 gst_bin_add_many (GST_BIN (pipeline),source, amrmux,sink, NULL); |
|
183 |
|
184 caps = gst_caps_new_simple ("audio/amr", |
|
185 "width", G_TYPE_INT, 8, |
|
186 "depth", G_TYPE_INT, 8, |
|
187 "signed",G_TYPE_BOOLEAN, TRUE, |
|
188 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
189 "rate", G_TYPE_INT, 8000, |
|
190 "channels", G_TYPE_INT, 1, NULL); |
|
191 |
|
192 if(!gst_element_link_filtered (source, amrmux, caps)) |
|
193 { |
|
194 GST_ERROR("Linking source, amrmux failed\n"); |
|
195 return -1; |
|
196 } |
|
197 |
|
198 if(!gst_element_link (amrmux, sink)) |
|
199 { |
|
200 GST_ERROR("Linking amrmux,sink failed\n"); |
|
201 return -1; |
|
202 } |
|
203 |
|
204 gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)), bus_call, loop); |
|
205 iface = GST_SPEECH_ENCODER_CONFIG_GET_IFACE(source); |
|
206 if(!iface) |
|
207 { |
|
208 GST_ERROR("Speech Encoder Interface NULL \n"); |
|
209 return -1; |
|
210 } |
|
211 if (bitrate > 0) |
|
212 { |
|
213 GST_WARNING("Setting bitrate %d \n",bitrate); |
|
214 iface->SetBitrate(bitrate); |
|
215 } |
|
216 |
|
217 /* Now set to playing and iterate. */ |
|
218 g_print ("Setting to PLAYING\n"); |
|
219 GST_WARNING("Setting to Playing \n"); |
|
220 gst_element_set_state (pipeline, GST_STATE_PLAYING); |
|
221 iface->GetBitrate(&bitrate); |
|
222 |
|
223 g_timeout_add (record_duration, quit_loop, loop); |
|
224 |
|
225 g_main_loop_run (loop); |
|
226 /* clean up nicely */ |
|
227 GST_WARNING("Returned, stopping playback\n"); |
|
228 |
|
229 gst_element_set_state (pipeline, GST_STATE_NULL); |
|
230 gst_object_unref (GST_OBJECT (pipeline)); |
|
231 |
|
232 #ifdef ENABLE_LOGS |
|
233 if ( _enable_logs ) |
|
234 fclose(log_fp); |
|
235 #endif // ENABLE_LOGS |
|
236 |
|
237 g_print ("completed playing audio\n"); |
|
238 return 0; |
|
239 } |
|
240 |
|