2
/* Ekiga -- A VoIP and Video-Conferencing application
3
* Copyright (C) 2000-2009 Damien Sandras <dsandras@seconix.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program 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
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20
* Ekiga is licensed under the GPL license and as a special exception,
21
* you have permission to link or otherwise combine this program with the
22
* programs OPAL, OpenH323 and PWLIB, and distribute the combination,
23
* without applying the requirements of the GNU GPL to the OPAL, OpenH323
24
* and PWLIB programs, as long as you do follow the requirements of the
25
* GNU GPL for all the rest of the software thus combined.
30
* gst-audiooutput.cpp - description
31
* ------------------------------------
32
* begin : Sat 27 September 2008
33
* copyright : (C) 2008 by Julien Puydt
34
* description : Gstreamer audio output code
38
#include <glib/gi18n.h>
40
#include "gst-audiooutput.h"
42
#include <gst/interfaces/propertyprobe.h>
43
#include <gst/app/gstappsrc.h>
44
#include <gst/app/gstappbuffer.h>
49
pipeline_cleaner (GstBus* /*bus*/,
55
if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS
56
&& GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (pipeline)) {
59
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
60
g_object_unref (pipeline);
67
GST::AudioOutputManager::AudioOutputManager ():
68
already_detected_devices(false)
72
GST::AudioOutputManager::~AudioOutputManager ()
77
GST::AudioOutputManager::get_devices (std::vector<Ekiga::AudioOutputDevice>& devices)
81
for (std::map<std::pair<std::string, std::string>, std::string>::const_iterator iter
82
= devices_by_name.begin ();
83
iter != devices_by_name.end ();
86
Ekiga::AudioOutputDevice device;
87
device.type = "GStreamer";
88
device.source = iter->first.first;
89
device.name = iter->first.second;
90
devices.push_back (device);
95
GST::AudioOutputManager::set_device (Ekiga::AudioOutputPS ps,
96
const Ekiga::AudioOutputDevice& device)
100
if ( !already_detected_devices)
103
if (device.type == "GStreamer"
104
&& devices_by_name.find (std::pair<std::string,std::string>(device.source, device.name)) != devices_by_name.end ()) {
106
unsigned ii = (ps == Ekiga::primary)?0:1;
107
current_state[ii].opened = false;
108
current_state[ii].device = device;
115
GST::AudioOutputManager::open (Ekiga::AudioOutputPS ps,
118
unsigned bits_per_sample)
121
unsigned ii = (ps == Ekiga::primary)?0:1;
122
gchar* command = NULL;
123
GError* error = NULL;
126
if ( !already_detected_devices)
129
command = g_strdup_printf ("appsrc is-live=true name=ekiga_src"
135
",signed=true,endianness=1234"
137
samplerate, channels, bits_per_sample, bits_per_sample,
138
devices_by_name[std::pair<std::string,std::string>(current_state[ii].device.source, current_state[ii].device.name)].c_str ());
139
//g_print ("Pipeline: %s\n", command);
140
pipeline[ii] = gst_parse_launch (command, &error);
144
(void)gst_element_set_state (pipeline[ii], GST_STATE_PLAYING);
146
// this will make us wait so we can return the right value...
147
(void)gst_element_get_state (pipeline[ii],
152
if ( !(current == GST_STATE_PLAYING
153
|| current == GST_STATE_PAUSED)) {
155
gst_element_set_state (pipeline[ii], GST_STATE_NULL);
156
gst_object_unref (GST_OBJECT (pipeline[ii]));
161
Ekiga::AudioOutputSettings settings;
162
GstElement* volume = NULL;
165
volume = gst_bin_get_by_name (GST_BIN (pipeline[ii]), "ekiga_volume");
166
if (volume != NULL) {
168
g_object_get (G_OBJECT (volume),
171
settings.volume = (unsigned)(255*val);
172
settings.modifyable = true;
173
g_object_unref (volume);
176
settings.modifyable = false;
178
current_state[ii].channels = channels;
179
current_state[ii].samplerate = samplerate;
180
current_state[ii].bits_per_sample = bits_per_sample;
181
device_opened (ps, current_state[ii].device, settings);
187
g_error_free (error);
193
current_state[ii].opened = result;
195
// std::cout << __PRETTY_FUNCTION__
198
// std::cout << "TRUE";
200
// std::cout << "FALSE";
201
// std::cout << std::endl;
207
GST::AudioOutputManager::close (Ekiga::AudioOutputPS ps)
209
unsigned ii = (ps == Ekiga::primary)?0:1;
210
if (pipeline[ii] != NULL) {
212
GstElement* src = gst_bin_get_by_name (GST_BIN (pipeline[ii]), "ekiga_src");
216
gst_app_src_end_of_stream (GST_APP_SRC (src));
217
GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline[ii]));
218
gst_bus_add_watch (bus, pipeline_cleaner, pipeline[ii]);
219
gst_object_unref (bus);
220
gst_element_set_state (pipeline[ii], GST_STATE_NULL);
222
device_closed (ps, current_state[ii].device);
225
current_state[ii].opened = false;
229
GST::AudioOutputManager::set_buffer_size (Ekiga::AudioOutputPS ps,
230
unsigned buffer_size,
231
unsigned /*num_buffers*/)
233
unsigned ii = (ps == Ekiga::primary)?0:1;
234
GstElement* src = NULL;
236
src = gst_bin_get_by_name (GST_BIN (pipeline[ii]), "ekiga_src");
240
g_object_set (G_OBJECT (src),
241
"blocksize", buffer_size,
243
g_object_unref (src);
248
GST::AudioOutputManager::set_frame_data (Ekiga::AudioOutputPS ps,
254
unsigned ii = (ps == Ekiga::primary)?0:1;
256
GstBuffer* buffer = NULL;
257
GstElement* src = NULL;
261
g_return_val_if_fail (GST_IS_BIN (pipeline[ii]), false);
263
src = gst_bin_get_by_name (GST_BIN (pipeline[ii]), "ekiga_src");
267
tmp = (gchar*)g_malloc0 (size);
268
memcpy (tmp, data, size);
269
buffer = gst_app_buffer_new (tmp, size,
270
(GstAppBufferFinalizeFunc)g_free, tmp);
271
gst_app_src_push_buffer (GST_APP_SRC (src), buffer);
274
g_object_unref (src);
281
GST::AudioOutputManager::set_volume (Ekiga::AudioOutputPS ps,
284
unsigned ii = (ps == Ekiga::primary)?0:1;
285
GstElement* volume = NULL;
290
volume = gst_bin_get_by_name (GST_BIN (pipeline[ii]), "ekiga_volume");
291
if (volume != NULL) {
293
g_object_set (G_OBJECT (volume),
296
g_object_unref (volume);
301
GST::AudioOutputManager::has_device (const std::string& source,
302
const std::string& device_name,
303
Ekiga::AudioOutputDevice& /*device*/)
305
return (devices_by_name.find (std::pair<std::string,std::string>(source, device_name)) != devices_by_name.end ());
309
GST::AudioOutputManager::detect_devices ()
311
devices_by_name.clear ();
312
detect_fakesink_devices ();
313
detect_alsasink_devices ();
314
detect_pulsesink_devices ();
315
detect_sdlsink_devices ();
316
devices_by_name[std::pair<std::string,std::string>("FILE","/tmp/sound.wav")] = "volume name=ekiga_volume ! filesink location=/tmp/sound.wav";
320
GST::AudioOutputManager::detect_fakesink_devices ()
322
GstElement* elt = NULL;
324
elt = gst_element_factory_make ("fakesink", "fakesinkpresencetest");
328
devices_by_name[std::pair<std::string,std::string>(_("Silent"), _("Silent"))] = "fakesink";
329
gst_object_unref (GST_OBJECT (elt));
334
GST::AudioOutputManager::detect_alsasink_devices ()
336
GstElement* elt = NULL;
338
elt = gst_element_factory_make ("alsasink", "alsasinkpresencetest");
342
GstPropertyProbe* probe = NULL;
343
const GParamSpec* pspec = NULL;
344
GValueArray* array = NULL;
346
gst_element_set_state (elt, GST_STATE_PAUSED);
347
probe = GST_PROPERTY_PROBE (elt);
348
pspec = gst_property_probe_get_property (probe, "device");
350
array = gst_property_probe_probe_and_get_values (probe, pspec);
353
for (guint index = 0; index < array->n_values; index++) {
355
GValue* device = NULL;
359
device = g_value_array_get_nth (array, index);
360
g_object_set_property (G_OBJECT (elt), "device", device);
361
g_object_get (G_OBJECT (elt), "device-name", &name, NULL);
362
descr = g_strdup_printf ("volume name=ekiga_volume ! alsasink device=%s",
363
g_value_get_string (device));
367
devices_by_name[std::pair<std::string,std::string>("ALSA", name)] = descr;
372
g_value_array_free (array);
375
devices_by_name[std::pair<std::string,std::string>("ALSA","---")] = "volume name=ekiga_volume ! alsasink";
377
gst_element_set_state (elt, GST_STATE_NULL);
378
gst_object_unref (GST_OBJECT (elt));
383
GST::AudioOutputManager::detect_pulsesink_devices ()
385
GstElement* elt = NULL;
387
elt = gst_element_factory_make ("pulsesink", "pulsesinkpresencetest");
391
GstPropertyProbe* probe = NULL;
392
const GParamSpec* pspec = NULL;
393
GValueArray* array = NULL;
395
gst_element_set_state (elt, GST_STATE_PAUSED);
396
probe = GST_PROPERTY_PROBE (elt);
397
pspec = gst_property_probe_get_property (probe, "device");
399
array = gst_property_probe_probe_and_get_values (probe, pspec);
402
for (guint index = 0; index < array->n_values; index++) {
404
GValue* device = NULL;
408
device = g_value_array_get_nth (array, index);
409
g_object_set_property (G_OBJECT (elt), "device", device);
410
g_object_get (G_OBJECT (elt), "device-name", &name, NULL);
411
descr = g_strdup_printf ("volume name=ekiga_volume ! pulsesink device=%s",
412
g_value_get_string (device));
416
devices_by_name[std::pair<std::string,std::string>("PULSEAUDIO", name)] = descr;
422
g_value_array_free (array);
425
gst_element_set_state (elt, GST_STATE_NULL);
426
gst_object_unref (GST_OBJECT (elt));
431
GST::AudioOutputManager::detect_sdlsink_devices ()
434
descr = g_strdup_printf ("volume name=ekiga_volume ! sdlaudiosink");
435
devices_by_name[std::pair<std::string,std::string>("SDL", "Default")] = descr;