|
1 |
|
2 |
|
3 #include <stdlib.h> |
|
4 #include <string.h> |
|
5 #include <gst/gst.h> |
|
6 #include "record_play.h" |
|
7 |
|
8 |
|
9 GstElement *bin; |
|
10 extern int mCurrentState; |
|
11 |
|
12 static GstElement * |
|
13 create_video_output () |
|
14 { |
|
15 static gboolean have_video = FALSE; |
|
16 GstBin *bin; |
|
17 GstElement *queue, *sink; |
|
18 GstPad *pad; |
|
19 |
|
20 if (have_video) { |
|
21 //g_print ("Already playing a video stream. Ignoring this one\n"); |
|
22 return NULL; |
|
23 } |
|
24 |
|
25 /* create a new bin to hold the elements */ |
|
26 if((bin = (GstBin*) gst_bin_new (NULL)) == NULL) |
|
27 //bin = (GstBin*) gst_pipeline_new("pipeline"); |
|
28 return NULL; |
|
29 |
|
30 /* Queue to ensure all streams can push data */ |
|
31 queue = gst_element_factory_make ("queue", "q"); |
|
32 if(queue == NULL) |
|
33 return NULL;/* Queue should always be available */ |
|
34 /* Set the queue to buffer 1/10 of a second of raw video */ |
|
35 g_object_set (queue, "max-size-time", (GstClockTime) GST_SECOND / 10, |
|
36 "max-size-bytes", 0, "max-size-buffers", 0, NULL); |
|
37 |
|
38 // cs = gst_element_factory_make ("ffmpegcolorspace", "cs"); |
|
39 // if (!cs) |
|
40 // goto no_output; |
|
41 |
|
42 /* and a video sink */ |
|
43 sink = gst_element_factory_make ("fakesink"/*autovideosink*/, "sink"); |
|
44 if (!sink) |
|
45 goto no_output; |
|
46 |
|
47 /* add objects to the main pipeline */ |
|
48 gst_bin_add_many (GST_BIN (bin), queue, sink, NULL); |
|
49 |
|
50 /* Link the elements */ |
|
51 gst_element_link_many (queue, sink, NULL); |
|
52 |
|
53 /* Retrieve the sinkpad from the queue and 'ghost' it onto |
|
54 * the bin so that the caller can find it generically */ |
|
55 pad = gst_element_get_pad (queue, "sink"); |
|
56 gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("sink", pad)); |
|
57 gst_object_unref (pad); |
|
58 |
|
59 //have_video = TRUE; |
|
60 |
|
61 return GST_ELEMENT (bin); |
|
62 |
|
63 /* ERRORS */ |
|
64 no_output: |
|
65 { |
|
66 //g_print ("Could not create either ffmpegcolorspace or autovideosink for output"); |
|
67 return NULL; |
|
68 } |
|
69 } |
|
70 |
|
71 static GstElement * |
|
72 create_audio_output () |
|
73 { |
|
74 static gboolean have_audio = FALSE; |
|
75 GstBin *bin; |
|
76 GstElement *queue, *audioconvert,*audioresample, *sink; |
|
77 GstPad *pad; |
|
78 |
|
79 if (have_audio) { |
|
80 //g_print ("Already playing an audio stream. Ignoring this one\n"); |
|
81 return NULL; |
|
82 } |
|
83 |
|
84 /* create a new bin to hold the elements */ |
|
85 bin = (GstBin*) gst_bin_new (NULL); |
|
86 if(!bin) |
|
87 goto no_output; |
|
88 |
|
89 /* Queue to ensure all streams can push data */ |
|
90 queue = gst_element_factory_make ("queue", "q"); |
|
91 if (!queue) /* Queue should always be available */ |
|
92 goto no_output; |
|
93 /* Set the queue to buffer 1/10 of a second of raw audio */ |
|
94 g_object_set (queue, "max-size-time", (GstClockTime) GST_SECOND / 10, |
|
95 "max-size-bytes", 0, "max-size-buffers", 0, NULL); |
|
96 |
|
97 /* an audio converter to convert floating-point audio samples to int format */ |
|
98 audioconvert = gst_element_factory_make ("audioconvert", "ac"); |
|
99 if (!audioconvert) |
|
100 goto no_output; |
|
101 |
|
102 /* an audio converter to convert floating-point audio samples to int format */ |
|
103 audioresample = gst_element_factory_make ("audioresample", "audioresample"); |
|
104 if (!audioresample) |
|
105 goto no_output; |
|
106 |
|
107 /* and an audio sink */ |
|
108 sink = gst_element_factory_make ("autoaudiosink", "sink"); |
|
109 if (!sink) |
|
110 goto no_output; |
|
111 |
|
112 /* add objects to the bin */ |
|
113 gst_bin_add_many (GST_BIN (bin), queue, audioconvert,audioresample, sink, NULL); |
|
114 |
|
115 /* link the elements */ |
|
116 gst_element_link_many (queue, audioconvert,audioresample, sink, NULL); |
|
117 |
|
118 /* Retrieve the sinkpad from the queue element and 'ghost' it onto |
|
119 * the bin so that the caller can find it generically */ |
|
120 pad = gst_element_get_pad (queue, "sink"); |
|
121 gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("sink", pad)); |
|
122 gst_object_unref (pad); |
|
123 |
|
124 //have_audio = TRUE; |
|
125 |
|
126 return GST_ELEMENT (bin); |
|
127 |
|
128 /* ERRORS */ |
|
129 no_output: |
|
130 { |
|
131 //g_print ("Could not create either ffmpegcolorspace or autovideosink for output"); |
|
132 return NULL; |
|
133 } |
|
134 } |
|
135 |
|
136 static void |
|
137 new_decoded_pad (GstElement * element, GstPad * pad, gboolean last, |
|
138 GstBin *top_pipeline) |
|
139 { |
|
140 GstPad *out_pad; |
|
141 GstElement *output = NULL; |
|
142 GstCaps *caps; |
|
143 GstStructure *s; |
|
144 const gchar *stream_type; |
|
145 |
|
146 /* Decide which output we are creating based on the stream contents */ |
|
147 caps = gst_pad_get_caps (pad); |
|
148 if (caps == NULL) { |
|
149 //g_print ("Decodebin produced an unknown stream - ignoring\n"); |
|
150 return; |
|
151 } |
|
152 |
|
153 s = gst_caps_get_structure (caps, 0); |
|
154 if(s == NULL)/* Caps on a pad should always have exactly one entry */ |
|
155 return; |
|
156 |
|
157 stream_type = gst_structure_get_name (s); |
|
158 |
|
159 if (g_str_has_prefix (stream_type, "video/x-raw-")) { |
|
160 /* Is a new video stream */ |
|
161 //g_print ("Encountered a new video stream\n"); |
|
162 output = create_video_output (); |
|
163 } |
|
164 else if (g_str_has_prefix (stream_type, "audio/x-raw-")) { |
|
165 //g_print ("Encountered a new audio stream\n"); |
|
166 output = create_audio_output (); |
|
167 } |
|
168 else { |
|
169 //g_print ("Found unknown stream of type %s - ignoring\n", stream_type); |
|
170 } |
|
171 |
|
172 /* If no renderer was created, ignore this stream */ |
|
173 if (output == NULL) |
|
174 return; |
|
175 |
|
176 /* Add the output into our pipeline */ |
|
177 gst_bin_add (top_pipeline, output); |
|
178 |
|
179 /* If we created a output pipeline, retrieve the sink pad from it */ |
|
180 out_pad = gst_element_get_pad (output, "sink"); |
|
181 g_return_if_fail (out_pad != NULL); |
|
182 |
|
183 /* Attempt to link the new pad to the output */ |
|
184 if (gst_pad_link (pad, out_pad) != GST_PAD_LINK_OK) { |
|
185 //g_print ("Failed to add the rendering pipeline for this new data stream\n"); |
|
186 gst_bin_remove (top_pipeline, output); |
|
187 gst_object_unref (out_pad); |
|
188 return; |
|
189 } |
|
190 gst_object_unref (out_pad); |
|
191 |
|
192 /* New output renderer is successfully linked in the pipeline. |
|
193 * Change its state to playing so it is ready to receive data */ |
|
194 gst_element_set_state (output, GST_STATE_PLAYING); |
|
195 } |
|
196 |
|
197 static void |
|
198 print_tag (const GstTagList * list, const gchar * tag, gpointer unused) |
|
199 { |
|
200 gint i, count; |
|
201 |
|
202 count = gst_tag_list_get_tag_size (list, tag); |
|
203 |
|
204 for (i = 0; i < count; i++) { |
|
205 gchar *str; |
|
206 |
|
207 if (gst_tag_get_type (tag) == G_TYPE_STRING) { |
|
208 if (!gst_tag_list_get_string_index (list, tag, i, &str)) |
|
209 g_assert_not_reached (); |
|
210 } else { |
|
211 str = |
|
212 g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i)); |
|
213 } |
|
214 |
|
215 if (i == 0) { |
|
216 //g_print (" %15s: %s\n", gst_tag_get_nick (tag), str); |
|
217 } else { |
|
218 //g_print (" : %s\n", str); |
|
219 } |
|
220 |
|
221 g_free (str); |
|
222 } |
|
223 } |
|
224 |
|
225 |
|
226 |
|
227 static gboolean |
|
228 bus_call (GstBus *bus, |
|
229 GstMessage *message, |
|
230 gpointer data) |
|
231 { |
|
232 switch (GST_MESSAGE_TYPE (message)){ |
|
233 case GST_MESSAGE_EOS: |
|
234 gst_message_unref (message); |
|
235 gst_element_set_state (bin, GST_STATE_NULL); |
|
236 /* Unreffing the bin will clean up all its children too */ |
|
237 gst_object_unref (bin); |
|
238 mCurrentState = NONE; |
|
239 break; |
|
240 case GST_MESSAGE_ERROR:{ |
|
241 GError *gerror; |
|
242 gchar *debug; |
|
243 |
|
244 gst_message_parse_error (message, &gerror, &debug); |
|
245 gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); |
|
246 gst_message_unref (message); |
|
247 g_error_free (gerror); |
|
248 g_free (debug); |
|
249 gst_element_set_state (bin, GST_STATE_NULL); |
|
250 /* Unreffing the bin will clean up all its children too */ |
|
251 gst_object_unref (bin); |
|
252 mCurrentState = NONE; |
|
253 break; |
|
254 } |
|
255 case GST_MESSAGE_WARNING:{ |
|
256 GError *gerror; |
|
257 gchar *debug; |
|
258 |
|
259 gst_message_parse_warning (message, &gerror, &debug); |
|
260 gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); |
|
261 gst_message_unref (message); |
|
262 g_error_free (gerror); |
|
263 g_free (debug); |
|
264 break; |
|
265 } |
|
266 case GST_MESSAGE_TAG: |
|
267 { |
|
268 GstTagList *tags; |
|
269 |
|
270 gst_message_parse_tag (message, &tags); |
|
271 if (tags) { |
|
272 //g_print ("TAGS received from element \"%s\".\n", |
|
273 // GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)))); |
|
274 |
|
275 gst_tag_list_foreach (tags, print_tag, NULL); |
|
276 gst_tag_list_free (tags); |
|
277 tags = NULL; |
|
278 } |
|
279 break; |
|
280 } |
|
281 default: |
|
282 gst_message_unref (message); |
|
283 break; |
|
284 } |
|
285 return TRUE; |
|
286 } |
|
287 |
|
288 |
|
289 |
|
290 //static void |
|
291 //event_loop (GstElement * pipe) |
|
292 //{ |
|
293 // GstBus *bus; |
|
294 // GstMessage *message = NULL; |
|
295 // |
|
296 // bus = gst_element_get_bus (GST_ELEMENT (pipe)); |
|
297 // |
|
298 // while (TRUE) { |
|
299 // message = gst_bus_poll (bus, GST_MESSAGE_ANY, -1); |
|
300 // |
|
301 // g_assert (message != NULL); |
|
302 // |
|
303 // switch (message->type) { |
|
304 // case GST_MESSAGE_EOS: |
|
305 // gst_message_unref (message); |
|
306 // return; |
|
307 // case GST_MESSAGE_ERROR:{ |
|
308 // GError *gerror; |
|
309 // gchar *debug; |
|
310 // |
|
311 // gst_message_parse_error (message, &gerror, &debug); |
|
312 // gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); |
|
313 // gst_message_unref (message); |
|
314 // g_error_free (gerror); |
|
315 // g_free (debug); |
|
316 // return; |
|
317 // } |
|
318 // case GST_MESSAGE_WARNING:{ |
|
319 // GError *gerror; |
|
320 // gchar *debug; |
|
321 // |
|
322 // gst_message_parse_warning (message, &gerror, &debug); |
|
323 // gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); |
|
324 // gst_message_unref (message); |
|
325 // g_error_free (gerror); |
|
326 // g_free (debug); |
|
327 // break; |
|
328 // } |
|
329 // case GST_MESSAGE_TAG: |
|
330 // { |
|
331 // GstTagList *tags; |
|
332 // |
|
333 // gst_message_parse_tag (message, &tags); |
|
334 // if (tags) { |
|
335 // //g_print ("TAGS received from element \"%s\".\n", |
|
336 // GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)))); |
|
337 // |
|
338 // gst_tag_list_foreach (tags, print_tag, NULL); |
|
339 // gst_tag_list_free (tags); |
|
340 // tags = NULL; |
|
341 // } |
|
342 // break; |
|
343 // } |
|
344 // default: |
|
345 // gst_message_unref (message); |
|
346 // break; |
|
347 // } |
|
348 // } |
|
349 //} |
|
350 |
|
351 int |
|
352 gst_play_file (const char* file) |
|
353 { |
|
354 GstElement *filesrc, *decodebin, *sink; |
|
355 GstCaps* caps; |
|
356 //int length = strlen( file ); |
|
357 //gst_init (&argc, &argv); |
|
358 |
|
359 if (file == NULL) { |
|
360 //g_print ("file is not present"); |
|
361 goto no_output; |
|
362 } |
|
363 |
|
364 //g_print ("Constructing pipeline\n"); |
|
365 |
|
366 /* create a new bin to hold the elements */ |
|
367 bin = gst_pipeline_new ("pipeline"); |
|
368 if(!bin) |
|
369 goto no_output; |
|
370 |
|
371 /* create a disk reader */ |
|
372 filesrc = gst_element_factory_make ("filesrc", "disk_source"); |
|
373 if(!filesrc) |
|
374 goto no_output; |
|
375 |
|
376 g_object_set (G_OBJECT (filesrc), "location", file, NULL); |
|
377 |
|
378 if( g_str_has_suffix (file, "raw") ) |
|
379 { |
|
380 sink = gst_element_factory_make ("devsoundsink", "sink"); |
|
381 caps = gst_caps_new_simple ("audio/x-raw-int", |
|
382 "width", G_TYPE_INT, 16, |
|
383 "depth", G_TYPE_INT, 16, |
|
384 "signed",G_TYPE_BOOLEAN, TRUE, |
|
385 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
386 "rate", G_TYPE_INT, 8000, |
|
387 "channels", G_TYPE_INT, 1, NULL); |
|
388 gst_bin_add_many (GST_BIN (bin), filesrc, sink, NULL); |
|
389 |
|
390 gst_element_link_filtered (filesrc, sink, caps); |
|
391 } |
|
392 else if( g_str_has_suffix (file, "g711") ) |
|
393 { |
|
394 sink = gst_element_factory_make ("devsoundsink", "sink"); |
|
395 caps = gst_caps_new_simple ("audio/x-alaw", |
|
396 "width", G_TYPE_INT, 16, |
|
397 "depth", G_TYPE_INT, 16, |
|
398 "signed",G_TYPE_BOOLEAN, TRUE, |
|
399 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
400 "rate", G_TYPE_INT, 8000, |
|
401 "channels", G_TYPE_INT, 1, NULL); |
|
402 gst_bin_add_many (GST_BIN (bin), filesrc, sink, NULL); |
|
403 |
|
404 gst_element_link_filtered (filesrc, sink, caps); |
|
405 } |
|
406 else if( g_str_has_suffix (file, "g729") ) |
|
407 { |
|
408 sink = gst_element_factory_make ("devsoundsink", "sink"); |
|
409 caps = gst_caps_new_simple ("audio/g729", |
|
410 "width", G_TYPE_INT, 16, |
|
411 "depth", G_TYPE_INT, 16, |
|
412 "signed",G_TYPE_BOOLEAN, TRUE, |
|
413 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
414 "rate", G_TYPE_INT, 8000, |
|
415 "channels", G_TYPE_INT, 1, NULL); |
|
416 gst_bin_add_many (GST_BIN (bin), filesrc, sink, NULL); |
|
417 |
|
418 gst_element_link_filtered (filesrc, sink, caps); |
|
419 } |
|
420 else if( g_str_has_suffix (file, "ilbc") ) |
|
421 { |
|
422 sink = gst_element_factory_make ("devsoundsink", "sink"); |
|
423 |
|
424 caps = gst_caps_new_simple ("audio/ilbc", |
|
425 "width", G_TYPE_INT, 16, |
|
426 "depth", G_TYPE_INT, 16, |
|
427 "signed",G_TYPE_BOOLEAN, TRUE, |
|
428 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
429 "rate", G_TYPE_INT, 8000, |
|
430 "channels", G_TYPE_INT, 1, NULL); |
|
431 |
|
432 gst_bin_add_many (GST_BIN (bin), filesrc, sink, NULL); |
|
433 |
|
434 gst_element_link_filtered (filesrc, sink, caps); |
|
435 } |
|
436 else if( g_str_has_suffix (file, "amr") ) |
|
437 { |
|
438 sink = gst_element_factory_make ("devsoundsink", "sink"); |
|
439 caps = gst_caps_new_simple ("audio/amr", |
|
440 "width", G_TYPE_INT, 8, |
|
441 "depth", G_TYPE_INT, 8, |
|
442 "signed",G_TYPE_BOOLEAN, TRUE, |
|
443 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
444 "rate", G_TYPE_INT, 8000, |
|
445 "channels", G_TYPE_INT, 1, NULL); |
|
446 gst_bin_add_many (GST_BIN (bin), filesrc, sink, NULL); |
|
447 |
|
448 //gst_element_link (source, sink); |
|
449 gst_element_link_filtered (filesrc, sink, caps); |
|
450 } |
|
451 |
|
452 else |
|
453 { |
|
454 /* Create the decodebin */ |
|
455 decodebin = gst_element_factory_make ("decodebin", NULL); |
|
456 if (!decodebin) { |
|
457 //g_print ("could not find the \"decodebin\" element\n"); |
|
458 return -1; |
|
459 } |
|
460 |
|
461 /* add objects to the main pipeline */ |
|
462 gst_bin_add_many (GST_BIN (bin), filesrc, decodebin, NULL); |
|
463 |
|
464 /* link the elements. */ |
|
465 gst_element_link_many (filesrc, decodebin, NULL); |
|
466 |
|
467 /* Connect to decodebin's 'new-decoded-pad' signal to detect when it produces |
|
468 * a new stream */ |
|
469 g_signal_connect (G_OBJECT (decodebin), "new-decoded-pad", |
|
470 G_CALLBACK (new_decoded_pad), bin); |
|
471 } |
|
472 |
|
473 gst_bus_add_watch( gst_pipeline_get_bus (GST_PIPELINE (bin)), bus_call, NULL); |
|
474 //g_print ("Starting playback\n"); |
|
475 /* start playing */ |
|
476 gst_element_set_state (bin, GST_STATE_PLAYING); |
|
477 return 0; |
|
478 |
|
479 no_output: |
|
480 return -1; |
|
481 |
|
482 } |
|
483 |
|
484 |
|
485 int |
|
486 gst_record_file (int type) |
|
487 { |
|
488 GstElement *audiosrc, *filesink; |
|
489 char* carray = NULL; |
|
490 GstCaps* caps; |
|
491 //g_print ("Constructing pipeline\n"); |
|
492 |
|
493 /* switch case for recording type*/ |
|
494 switch( type ) |
|
495 { |
|
496 case RECORD_RAW: |
|
497 caps = gst_caps_new_simple ("audio/x-raw-int", |
|
498 "width", G_TYPE_INT, 16, |
|
499 "depth", G_TYPE_INT, 16, |
|
500 "signed",G_TYPE_BOOLEAN, TRUE, |
|
501 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
502 "rate", G_TYPE_INT, 8000, |
|
503 "channels", G_TYPE_INT, 1, NULL); |
|
504 |
|
505 carray = "c:\\data\\sounds\\Digital\\record.raw"; |
|
506 break; |
|
507 |
|
508 case RECORD_AMR: |
|
509 { |
|
510 return gst_record_amr(); |
|
511 } |
|
512 break; |
|
513 |
|
514 case RECORD_G711: |
|
515 |
|
516 caps = gst_caps_new_simple ("audio/x-alaw", |
|
517 "width", G_TYPE_INT, 8, |
|
518 "depth", G_TYPE_INT, 8, |
|
519 "signed",G_TYPE_BOOLEAN, TRUE, |
|
520 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
521 "rate", G_TYPE_INT, 8000, |
|
522 "channels", G_TYPE_INT, 1, NULL); |
|
523 |
|
524 carray = "c:\\data\\sounds\\Digital\\record.g711"; |
|
525 break; |
|
526 |
|
527 case RECORD_G729: // |
|
528 |
|
529 caps = gst_caps_new_simple ("audio/g729", |
|
530 "width", G_TYPE_INT, 16, |
|
531 "depth", G_TYPE_INT, 16, |
|
532 "signed",G_TYPE_BOOLEAN, TRUE, |
|
533 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
534 "rate", G_TYPE_INT, 8000, |
|
535 "channels", G_TYPE_INT, 1, NULL); |
|
536 |
|
537 carray = "c:\\data\\sounds\\Digital\\record.g729"; |
|
538 break; |
|
539 |
|
540 case RECORD_ILBC: // |
|
541 |
|
542 caps = gst_caps_new_simple ("audio/ilbc", |
|
543 "width", G_TYPE_INT, 16, |
|
544 "depth", G_TYPE_INT, 16, |
|
545 "signed",G_TYPE_BOOLEAN, TRUE, |
|
546 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
547 "rate", G_TYPE_INT, 8000, |
|
548 "channels", G_TYPE_INT, 1, NULL); |
|
549 |
|
550 carray = "c:\\data\\sounds\\Digital\\record.ilbc"; |
|
551 break; |
|
552 case RECORD_WAV: |
|
553 { |
|
554 return gst_record_wav(); |
|
555 } |
|
556 break; |
|
557 case RECORD_AAC: |
|
558 { |
|
559 return gst_record_aac(); |
|
560 } |
|
561 break; |
|
562 default: |
|
563 return -1; |
|
564 break; |
|
565 } |
|
566 /* create a new bin to hold the elements */ |
|
567 bin = gst_pipeline_new ("pipeline"); |
|
568 if(!bin) |
|
569 goto no_output; |
|
570 |
|
571 /* create a disk reader */ |
|
572 audiosrc = gst_element_factory_make ("devsoundsrc", "audio_source"); |
|
573 if(!audiosrc) |
|
574 goto no_output; |
|
575 |
|
576 /* Create the decodebin */ |
|
577 filesink = gst_element_factory_make ("filesink", NULL); |
|
578 if(!filesink) |
|
579 goto no_output; |
|
580 |
|
581 g_object_set (G_OBJECT (audiosrc), |
|
582 "blocksize", 1280, |
|
583 NULL); |
|
584 |
|
585 g_object_set (G_OBJECT (filesink), "location", carray,"buffer-size",1280, NULL); |
|
586 |
|
587 /* add objects to the main pipeline */ |
|
588 gst_bin_add_many (GST_BIN (bin), audiosrc, filesink, NULL); |
|
589 |
|
590 /* link the elements. */ |
|
591 gst_element_link_filtered (audiosrc, filesink, caps); |
|
592 //gst_element_link_many (audiosrc, filesink, NULL); |
|
593 gst_bus_add_watch( gst_pipeline_get_bus (GST_PIPELINE (bin)), bus_call, NULL); |
|
594 |
|
595 //g_print ("Starting recoring\n"); |
|
596 /* start playing */ |
|
597 gst_element_set_state (bin, GST_STATE_PLAYING); |
|
598 |
|
599 /* Run event loop listening for bus messages until EOS or ERROR */ |
|
600 //event_loop (bin); |
|
601 |
|
602 // //g_print ("Finished playback - stopping pipeline\n"); |
|
603 // |
|
604 // /* stop the bin */ |
|
605 // gst_element_set_state (bin, GST_STATE_NULL); |
|
606 // |
|
607 // /* Unreffing the bin will clean up all its children too */ |
|
608 // gst_object_unref (bin); |
|
609 // |
|
610 return 0; |
|
611 no_output: |
|
612 return -1; |
|
613 |
|
614 } |
|
615 |
|
616 |
|
617 int |
|
618 gst_record_wav () |
|
619 { |
|
620 GstElement *audiosrc, *filesink, *wavenc; |
|
621 char* carray = NULL; |
|
622 GstCaps* caps; |
|
623 |
|
624 //g_print ("Constructing pipeline\n"); |
|
625 |
|
626 /* create a new bin to hold the elements */ |
|
627 bin = gst_pipeline_new ("pipeline"); |
|
628 if(!bin) |
|
629 goto no_output; |
|
630 |
|
631 /* create a disk reader */ |
|
632 audiosrc = gst_element_factory_make ("devsoundsrc", "audio_source"); |
|
633 if(!audiosrc) |
|
634 goto no_output; |
|
635 |
|
636 /* Create the decodebin */ |
|
637 filesink = gst_element_factory_make ("filesink", NULL); |
|
638 if(!filesink) |
|
639 goto no_output; |
|
640 |
|
641 wavenc = gst_element_factory_make ("wavenc", NULL); |
|
642 if(!wavenc) |
|
643 goto no_output; |
|
644 |
|
645 caps = gst_caps_new_simple ("audio/x-raw-int", |
|
646 "width", G_TYPE_INT, 16, |
|
647 "depth", G_TYPE_INT, 16, |
|
648 "signed",G_TYPE_BOOLEAN, TRUE, |
|
649 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
650 "rate", G_TYPE_INT, 16000, |
|
651 "channels", G_TYPE_INT, 1, NULL); |
|
652 |
|
653 carray = "c:\\data\\sounds\\Digital\\record.wav"; |
|
654 |
|
655 g_object_set (G_OBJECT (audiosrc), |
|
656 "blocksize", 1280, |
|
657 NULL); |
|
658 |
|
659 g_object_set (G_OBJECT (filesink), "location", carray,"buffer-size",1280, NULL); |
|
660 |
|
661 /* add objects to the main pipeline */ |
|
662 gst_bin_add_many (GST_BIN (bin), audiosrc,wavenc, filesink, NULL); |
|
663 |
|
664 /* link the elements. */ |
|
665 gst_element_link_filtered (audiosrc, wavenc, caps); |
|
666 gst_element_link (wavenc, filesink); |
|
667 gst_bus_add_watch( gst_pipeline_get_bus (GST_PIPELINE (bin)), bus_call, NULL); |
|
668 //g_print ("Starting recoring\n"); |
|
669 /* start playing */ |
|
670 gst_element_set_state (bin, GST_STATE_PLAYING); |
|
671 |
|
672 return 0; |
|
673 |
|
674 no_output: |
|
675 return -1; |
|
676 } |
|
677 |
|
678 int gst_pause() |
|
679 { |
|
680 gst_element_set_state (bin, GST_STATE_PAUSED); |
|
681 return 0; |
|
682 } |
|
683 |
|
684 int gst_resume() |
|
685 { |
|
686 gst_element_set_state (bin, GST_STATE_PLAYING); |
|
687 return 0; |
|
688 } |
|
689 |
|
690 |
|
691 int gst_record_stop() |
|
692 { |
|
693 gst_element_send_event (bin, gst_event_new_eos ()); |
|
694 //gst_element_set_state (bin, GST_STATE_NULL); |
|
695 return 0; |
|
696 } |
|
697 |
|
698 |
|
699 int gst_seek() |
|
700 { |
|
701 // need to implement.. |
|
702 } |
|
703 |
|
704 int gst_get_events() |
|
705 { |
|
706 return g_main_context_iteration(NULL, FALSE); |
|
707 //return 0; |
|
708 } |
|
709 |
|
710 int gst_unref() |
|
711 { |
|
712 //g_print ("Finished playback - stopping pipeline\n"); |
|
713 /* stop the bin */ |
|
714 gst_element_set_state (bin, GST_STATE_NULL); |
|
715 /* Unreffing the bin will clean up all its children too */ |
|
716 gst_object_unref (bin); |
|
717 return 0; |
|
718 } |
|
719 |
|
720 int gst_record_aac() |
|
721 { |
|
722 GstElement *audiosrc,*filesink,*aacenc, *mp4mux; |
|
723 GstBus *bus; |
|
724 GstPad *mp4sinkpad,*aacencsrcpad; |
|
725 char* carray = NULL; |
|
726 GstCaps* caps; |
|
727 |
|
728 /*create a pipeline*/ |
|
729 bin = gst_pipeline_new ("pipeline"); |
|
730 if(!bin) |
|
731 goto no_output; |
|
732 /* create a disk reader */ |
|
733 audiosrc = gst_element_factory_make ("devsoundsrc", "audio_source"); |
|
734 if(!audiosrc) |
|
735 goto no_output; |
|
736 |
|
737 /* Create the decodebin */ |
|
738 filesink = gst_element_factory_make ("filesink", NULL); |
|
739 if(!filesink) |
|
740 goto no_output; |
|
741 //setting num-buffers |
|
742 //g_object_set (G_OBJECT (audiosrc), "num-buffers", 5000 , NULL); |
|
743 g_object_set (G_OBJECT (audiosrc), |
|
744 "blocksize", 1280, |
|
745 NULL); |
|
746 |
|
747 aacenc = gst_element_factory_make("nokiaaacenc", "nokiaaacenc"); |
|
748 if(!aacenc) |
|
749 goto no_output; |
|
750 mp4mux = gst_element_factory_make("mp4mux", "mp4mux"); |
|
751 if(!mp4mux) |
|
752 goto no_output; |
|
753 caps = gst_caps_new_simple("audio/x-raw-int", |
|
754 "width", G_TYPE_INT, 16, |
|
755 "depth", G_TYPE_INT, 16, |
|
756 "signed",G_TYPE_BOOLEAN, TRUE, |
|
757 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
758 "rate", G_TYPE_INT, 8000, |
|
759 "channels", G_TYPE_INT, 1, NULL); |
|
760 carray = "c:\\data\\sounds\\Digital\\record.mp4"; |
|
761 |
|
762 |
|
763 g_object_set(G_OBJECT (filesink), "location", carray, NULL); |
|
764 bus = gst_pipeline_get_bus(GST_PIPELINE (bin)); |
|
765 |
|
766 gst_bus_add_watch(bus, bus_call, NULL); |
|
767 |
|
768 gst_object_unref(bus); |
|
769 |
|
770 |
|
771 //add objects to the main pipeline |
|
772 gst_bin_add_many(GST_BIN (bin),audiosrc,aacenc,mp4mux,filesink, NULL); |
|
773 |
|
774 gst_element_link_filtered (audiosrc, aacenc, caps); |
|
775 |
|
776 mp4sinkpad = gst_element_get_request_pad( mp4mux, "audio_%d"); |
|
777 |
|
778 aacencsrcpad = gst_element_get_pad( aacenc, "src"); |
|
779 if (gst_pad_link (aacencsrcpad,mp4sinkpad) != GST_PAD_LINK_OK) { |
|
780 |
|
781 g_print("gst_pad_link (aacencsrcpad,mp4sinkpad) failed"); |
|
782 |
|
783 return -1; |
|
784 } |
|
785 //gst_element_link (aacenc, filesink); |
|
786 gst_element_link (mp4mux, filesink); |
|
787 |
|
788 gst_caps_unref (caps); |
|
789 |
|
790 |
|
791 gst_element_set_state(bin, GST_STATE_PLAYING); |
|
792 |
|
793 return 0; |
|
794 no_output: |
|
795 return -1; |
|
796 } |
|
797 |
|
798 int gst_record_amr() |
|
799 { |
|
800 GstElement *audiosrc, *filesink, *amrmux; |
|
801 GstBus *bus; |
|
802 char* carray = NULL; |
|
803 GstCaps* caps; |
|
804 /* create a new bin to hold the elements */ |
|
805 bin = gst_pipeline_new ("pipeline"); |
|
806 if(!bin) |
|
807 goto no_output; |
|
808 //g_print ("pipeline created"); |
|
809 audiosrc = gst_element_factory_make ("devsoundsrc", "audio_source"); |
|
810 // encoder = gst_element_factory_make ("wavenc", NULL); |
|
811 if(!audiosrc) |
|
812 goto no_output; |
|
813 |
|
814 amrmux = gst_element_factory_make ("amrmux", "muxer"); |
|
815 if(!amrmux) |
|
816 goto no_output; |
|
817 |
|
818 filesink = gst_element_factory_make("filesink", "filesink"); |
|
819 if(!filesink) |
|
820 goto no_output; |
|
821 |
|
822 caps = gst_caps_new_simple ("audio/amr", |
|
823 "width", G_TYPE_INT, 8, |
|
824 "depth", G_TYPE_INT, 8, |
|
825 "signed",G_TYPE_BOOLEAN, TRUE, |
|
826 "endianness",G_TYPE_INT, G_BYTE_ORDER, |
|
827 "rate", G_TYPE_INT, 8000, |
|
828 "channels", G_TYPE_INT, 1, NULL); |
|
829 carray = "c:\\data\\sounds\\Digital\\record.amr"; |
|
830 |
|
831 g_object_set (G_OBJECT (audiosrc), |
|
832 "blocksize", 1280, |
|
833 NULL); |
|
834 |
|
835 g_object_set(G_OBJECT (filesink), "location", carray, NULL); |
|
836 |
|
837 bus = gst_pipeline_get_bus (GST_PIPELINE (bin)); |
|
838 gst_bus_add_watch (bus, bus_call, NULL); |
|
839 gst_object_unref (bus); |
|
840 |
|
841 |
|
842 /* add objects to the main pipeline */ |
|
843 gst_bin_add_many(GST_BIN (bin),audiosrc,amrmux,filesink , NULL); |
|
844 /* link the elements */ |
|
845 gst_element_link_filtered (audiosrc, amrmux, caps); |
|
846 |
|
847 gst_element_link( amrmux, filesink ); |
|
848 |
|
849 gst_element_set_state (bin, GST_STATE_PLAYING); |
|
850 |
|
851 return 0; |
|
852 no_output: |
|
853 return -1; |
|
854 |
|
855 } |