4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>
8 * This library is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License as published by the
10 * Free Software Foundation; either version 2.1 of the License, or (at your option)
13 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 * License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software Foundation, Inc., 51
20 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <gst/gstutils.h>
31 #include "gstavsysaudiosink.h"
34 #define __REPLACE_RESET_WITH_CLOSE_AND_REOPEN__
36 #define CONVERT_MUTE_VALUE(_mute) ((_mute) ? AVSYS_AUDIO_MUTE : AVSYS_AUDIO_UNMUTE)
38 GST_DEBUG_CATEGORY_EXTERN (avsystem_sink_debug);
39 #define GST_CAT_DEFAULT avsystem_sink_debug
41 #define DEFAULT_USER_ROUTE AVSYSAUDIOSINK_USERROUTE_AUTO
42 #define DEFAULT_AUDIO_ROUTE AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING
43 #define DEFAULT_VOLUME_TYPE AVSYS_AUDIO_VOLUME_TYPE_MEDIA
44 #define DEFAULT_MEDIACALL_MODE AVSYS_AUDIO_ECHO_MODE_NONE
45 #define DEFAULT_FADEUP_VOLUME FALSE
46 #define DEFAULT_AUDIO_MUTE AVSYSAUDIOSINK_AUDIO_UNMUTE
47 #define DEFAULT_AUDIO_LATENCY AVSYSAUDIOSINK_LATENCY_MID
48 #define DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE FALSE
50 //GST_DEBUG_CATEGORY_STATIC (gst_avsystemsink_debug);
52 /* element factory information */
53 static const GstElementDetails gst_avsysaudiosink_details =
54 GST_ELEMENT_DETAILS ("AV-system Audio OUT",
56 "Output to AV System",
57 "Samsung Electronics co., ltd");
63 PROP_AUDIO_VOLUME_TYPE,
65 PROP_AUDIO_FADEUPVOLUME,
66 PROP_AUDIO_ROUTE_POLICY,
67 PROP_AUDIO_USER_ROUTE,
71 PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE,
75 gst_avsysaudiosink_audio_mute_get_type (void)
77 static GType avaudio_mute_type = 0;
78 static const GEnumValue avaudio_mute[] = {
79 {AVSYSAUDIOSINK_AUDIO_UNMUTE, "Unmute", "unmute"},
80 {AVSYSAUDIOSINK_AUDIO_MUTE, "Mute immediately", "mute"},
81 {AVSYSAUDIOSINK_AUDIO_MUTE_WITH_FADEDOWN_EFFECT, "Mute with fadedown effect", "fadedown"},
85 if (!avaudio_mute_type) {
87 g_enum_register_static ("GstAvsysAudioSinkAudioMute", avaudio_mute);
89 return avaudio_mute_type;
93 gst_avsysaudiosink_user_route_get_type (void)
95 static GType user_route_type = 0;
96 static const GEnumValue user_route[] = {
97 {AVSYSAUDIOSINK_USERROUTE_AUTO, "Route automatically", "auto"},
98 {AVSYSAUDIOSINK_USERROUTE_PHONE, "Route to phone only", "phone"},
102 if (!user_route_type) {
104 g_enum_register_static ("GstAvsysAudioSinkUserRoutePolicy",user_route);
106 return user_route_type;
110 gst_avsysaudiosink_audio_route_get_type (void)
112 static GType playback_audio_route_type = 0;
113 static const GEnumValue playback_audio_route[] = {
114 {AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING, "Use external sound path", "external"},
115 {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_NORMAL, "Auto change between speaker & earphone", "normal"},
116 {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_ALERT, "Play via both speaker & earphone", "alert"},
117 {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_HEADSET_ONLY, "Play via earphone only", "headset"},
121 if (!playback_audio_route_type) {
122 playback_audio_route_type =
123 g_enum_register_static ("GstAvsysAudioSinkAudioRoutePolicy", playback_audio_route);
125 return playback_audio_route_type;
129 gst_avsysaudiosink_latency_get_type (void)
131 static GType avsysaudio_latency_type = 0;
132 static const GEnumValue avsysaudio_latency[] = {
133 {AVSYSAUDIOSINK_LATENCY_LOW, "Low latency", "low"},
134 {AVSYSAUDIOSINK_LATENCY_MID, "Mid latency", "mid"},
135 {AVSYSAUDIOSINK_LATENCY_HIGH, "High latency", "high"},
139 if (!avsysaudio_latency_type) {
140 avsysaudio_latency_type =
141 g_enum_register_static ("GstAvsysAudioSinkLatency", avsysaudio_latency);
143 return avsysaudio_latency_type;
146 static void gst_avsysaudiosink_init_interfaces (GType type);
148 //#define GST_BOILERPLATE_FULL(type, type_as_function, parent_type, parent_type_macro, additional_initializations)
150 GST_BOILERPLATE_FULL (GstAvsysAudioSink, gst_avsysaudiosink, GstAudioSink,
151 GST_TYPE_AUDIO_SINK, gst_avsysaudiosink_init_interfaces);
154 static void gst_avsysaudiosink_finalise (GObject * object);
155 static void gst_avsysaudiosink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
156 static void gst_avsysaudiosink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
158 static GstCaps *gst_avsysaudiosink_getcaps (GstBaseSink * bsink);
161 static gboolean gst_avsysaudiosink_avsys_close(GstAvsysAudioSink *avsys_audio);
162 static gboolean gst_avsysaudiosink_avsys_open(GstAvsysAudioSink *avsys_audio);
164 static gboolean gst_avsysaudiosink_open (GstAudioSink * asink);
165 static gboolean gst_avsysaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec);
166 static gboolean gst_avsysaudiosink_unprepare (GstAudioSink * asink);
167 static gboolean gst_avsysaudiosink_close (GstAudioSink * asink);
168 static guint gst_avsysaudiosink_write (GstAudioSink * asink, gpointer data, guint length);
169 static guint gst_avsysaudiosink_delay (GstAudioSink * asink);
170 static void gst_avsysaudiosink_reset (GstAudioSink * asink);
171 static gboolean avsysaudiosink_post_message(GstAvsysAudioSink* self,int errorcode);
174 #define AVSYS_AUDIO_FACTORY_ENDIANNESS "LITTLE_ENDIAN"
177 static GstStaticPadTemplate avsysaudiosink_sink_factory =
178 GST_STATIC_PAD_TEMPLATE ("sink",
181 GST_STATIC_CAPS ("audio/x-raw-int, "
182 "endianness = (int) { " AVSYS_AUDIO_FACTORY_ENDIANNESS " }, "
183 "signed = (boolean) { TRUE }, "
186 "rate = (int) 44100, "
187 "channels = (int) [ 1, 6 ]; "
189 "signed = (boolean) { FALSE }, "
192 "rate = (int) 44100, "
193 "channels = (int) [ 1, 6 ] "
197 static inline guint _time_to_sample(GstAvsysAudioSink * asink, GstClockTime diff)
200 result =(GST_TIME_AS_USECONDS(diff) * asink->audio_param.samplerate)/1000000;
206 gst_avsysaudiosink_finalise (GObject * object)
208 GstAvsysAudioSink *sink = NULL;
210 sink = GST_AVSYS_AUDIO_SINK (object);
211 gst_avsysaudiosink_avsys_close(sink);
212 g_mutex_free (sink->avsys_audio_lock);
213 g_mutex_free (sink->avsys_audio_reset_lock);
215 G_OBJECT_CLASS (parent_class)->finalize (object);
219 gst_avsysaudiosink_init_interfaces (GType type)
225 gst_avsysaudiosink_base_init (gpointer g_class)
227 GstElementClass *element_class = NULL;
229 element_class = GST_ELEMENT_CLASS (g_class);
230 gst_element_class_set_details (element_class, &gst_avsysaudiosink_details);
231 gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&avsysaudiosink_sink_factory));
234 static GstStateChangeReturn
235 gst_avsyssudiosink_change_state (GstElement *element, GstStateChange transition);
239 gst_avsysaudiosink_class_init (GstAvsysAudioSinkClass * klass)
241 GObjectClass *gobject_class;
242 GstElementClass *gstelement_class;
243 GstBaseSinkClass *gstbasesink_class;
244 GstBaseAudioSinkClass *gstbaseaudiosink_class;
245 GstAudioSinkClass *gstaudiosink_class;
247 gobject_class = (GObjectClass *) klass;
248 gstelement_class = (GstElementClass *) klass;
249 gstbasesink_class = (GstBaseSinkClass *) klass;
250 gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
251 gstaudiosink_class = (GstAudioSinkClass *) klass;
253 parent_class = g_type_class_peek_parent (klass);
254 gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_avsyssudiosink_change_state);
256 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_finalise);
257 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_get_property);
258 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_set_property);
260 // gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_getcaps);
262 gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_open);
263 gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_prepare);
264 gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_unprepare);
265 gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_close);
266 gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_write);
267 gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_delay);
268 gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_reset);
270 g_object_class_install_property ( gobject_class, PROP_AUDIO_VOLUME_TYPE,
271 g_param_spec_int ("volumetype", "Avsystem Volume Type",
272 "Select avsystem audio software volume type", 0, G_MAXINT,
273 DEFAULT_VOLUME_TYPE, G_PARAM_READWRITE));
275 g_object_class_install_property ( gobject_class, PROP_AUDIO_PRIORITY,
276 g_param_spec_int ("priority", "Avsystem Sound Priority", "Avsystem sound priority",
277 AVSYS_AUDIO_PRIORITY_NORMAL, AVSYS_AUDIO_PRIORITY_SOLO_WITH_TRANSITION_EFFECT,
278 AVSYS_AUDIO_PRIORITY_NORMAL, G_PARAM_READWRITE));
280 g_object_class_install_property ( gobject_class, PROP_AUDIO_HANDLE,
281 g_param_spec_pointer("audio-handle", "Avsystem handle",
282 "Avsystem audio handle",
285 g_object_class_install_property ( gobject_class, PROP_AUDIO_CALLBACK,
286 g_param_spec_pointer("audio-callback", "Avsystem callback",
287 "Avsystem audio callback",
290 g_object_class_install_property (gobject_class, PROP_AUDIO_FADEUPVOLUME,
291 g_param_spec_boolean ("fadeup", "Avsystem fadeup volume",
292 "Enable avsystem audio fadeup volume when pause to play",
293 DEFAULT_FADEUP_VOLUME, G_PARAM_READWRITE));
295 g_object_class_install_property (gobject_class ,PROP_AUDIO_MUTE,
296 g_param_spec_enum("mute", "Avsystem mute",
297 "Avsystem audio mute",
298 GST_AVSYS_AUDIO_SINK_MUTE, DEFAULT_AUDIO_MUTE,
299 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
301 g_object_class_install_property (gobject_class ,PROP_AUDIO_ROUTE_POLICY,
302 g_param_spec_enum("audio-route", "Audio Route Policy",
303 "Audio route policy of system",
304 GST_AVSYS_AUDIO_SINK_AUDIO_ROUTE, DEFAULT_AUDIO_ROUTE,
305 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
307 g_object_class_install_property (gobject_class ,PROP_AUDIO_USER_ROUTE,
308 g_param_spec_enum("user-route", "User Route Policy",
310 GST_AVSYS_AUDIO_SINK_USER_ROUTE, DEFAULT_USER_ROUTE,
311 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
313 g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY,
314 g_param_spec_enum("latency", "Audio Backend Latency",
315 "Audio backend latency",
316 GST_AVSYS_AUDIO_SINK_LATENCY_TYPE, DEFAULT_AUDIO_LATENCY,
317 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
319 g_object_class_install_property (gobject_class, PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE,
320 g_param_spec_boolean ("close-handle-on-prepare", "Close Handle on Prepare",
321 "Close Handle on Prepare",
322 DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE, G_PARAM_READWRITE));
326 gst_avsysaudiosink_set_property (GObject * object, guint prop_id,
327 const GValue * value, GParamSpec * pspec)
329 GstAvsysAudioSink *sink = NULL;
331 gboolean nbool = FALSE;
333 sink = GST_AVSYS_AUDIO_SINK (object);
336 case PROP_AUDIO_HANDLE:
337 sink->cbHandle = g_value_get_pointer(value);
339 case PROP_AUDIO_CALLBACK:
340 sink->audio_stream_cb = g_value_get_pointer(value);
342 case PROP_AUDIO_VOLUME_TYPE:
343 nvalue = g_value_get_int(value);
344 sink->volume_type = nvalue;
345 if (sink->audio_handle != (avsys_handle_t)-1) {
346 avsys_audio_update_volume_config(sink->audio_handle, sink->volume_type);
349 case PROP_AUDIO_PRIORITY:
350 nvalue = g_value_get_int(value);
351 sink->sound_priority = nvalue;
353 case PROP_AUDIO_MUTE:
354 nvalue = g_value_get_enum(value);
355 if (sink->audio_handle != (avsys_handle_t)-1) {
356 if(AVSYS_SUCCESS(avsys_audio_set_mute_fadedown(sink->audio_handle)))
362 case PROP_AUDIO_FADEUPVOLUME:
363 nbool = g_value_get_boolean(value);
364 sink->use_fadeup_volume = nbool;
366 case PROP_AUDIO_ROUTE_POLICY:
367 nvalue = g_value_get_enum(value);
368 sink->audio_route_policy = nvalue;
369 switch (sink->audio_route_policy) {
370 case AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING:
371 GST_INFO_OBJECT(sink, "use external audio route setting");
374 g_print("AVSYSAUDIOSINK :: Unknown audio route option %d\n", sink->audio_route_policy);
375 GST_ERROR_OBJECT(sink, "Unknown audio route option %d", sink->audio_route_policy);
379 case PROP_AUDIO_USER_ROUTE:
380 nvalue = g_value_get_enum(value);
381 sink->user_route_policy = nvalue;
383 case PROP_AUDIO_LATENCY:
384 nvalue = g_value_get_enum(value);
385 sink->latency = nvalue;
387 case PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE:
388 nbool = g_value_get_boolean(value);
389 sink->close_handle_on_prepare = nbool;
392 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
398 gst_avsysaudiosink_get_property (GObject * object, guint prop_id,
399 GValue * value, GParamSpec * pspec)
401 GstAvsysAudioSink *sink = NULL;
403 sink = GST_AVSYS_AUDIO_SINK (object);
406 case PROP_AUDIO_VOLUME_TYPE:
407 g_value_set_int(value, sink->volume_type);
409 case PROP_AUDIO_PRIORITY:
410 g_value_set_int(value, sink->sound_priority);
412 case PROP_AUDIO_MUTE:
413 g_value_set_enum(value, sink->mute);
415 case PROP_AUDIO_FADEUPVOLUME:
416 g_value_set_boolean(value, sink->use_fadeup_volume);
418 case PROP_AUDIO_ROUTE_POLICY:
419 g_value_set_enum(value, sink->audio_route_policy);
421 case PROP_AUDIO_USER_ROUTE:
422 g_value_set_enum(value, sink->user_route_policy);
424 case PROP_AUDIO_LATENCY:
425 g_value_set_enum(value, sink->latency);
427 case PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE:
428 g_value_set_boolean(value, sink->close_handle_on_prepare);
432 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
438 gst_avsysaudiosink_init (GstAvsysAudioSink * avsysaudiosink, GstAvsysAudioSinkClass * g_class)
440 GST_DEBUG_OBJECT (avsysaudiosink, "initializing avsysaudiosink");
442 avsysaudiosink->audio_handle = (avsys_handle_t)-1;
443 avsysaudiosink->cached_caps = NULL;
444 avsysaudiosink->avsys_audio_lock = g_mutex_new ();
445 avsysaudiosink->avsys_audio_reset_lock = g_mutex_new ();
446 avsysaudiosink->volume_type = DEFAULT_VOLUME_TYPE;
447 avsysaudiosink->sound_priority = AVSYS_AUDIO_PRIORITY_NORMAL;
448 avsysaudiosink->mute = DEFAULT_AUDIO_MUTE;
449 avsysaudiosink->use_fadeup_volume = DEFAULT_FADEUP_VOLUME;
450 avsysaudiosink->latency = DEFAULT_AUDIO_LATENCY;
451 avsysaudiosink->audio_route_policy = DEFAULT_AUDIO_ROUTE;
452 avsysaudiosink->bytes_per_sample = 1;
453 avsysaudiosink->close_handle_on_prepare = DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE;
454 #if defined (LPCM_DUMP_SUPPORT)
455 avsysaudiosink->dumpFp = NULL;
461 gst_avsysaudiosink_getcaps (GstBaseSink * bsink)
463 GstElementClass *element_class = NULL;
464 GstPadTemplate *pad_template = NULL;
465 GstAvsysAudioSink *sink = GST_AVSYS_AUDIO_SINK (bsink);
470 sink = GST_AVSYS_AUDIO_SINK (bsink);
471 if (sink->audio_handle == -1)
473 GST_DEBUG_OBJECT (sink, "avsystem audio not open, using template caps");
474 return NULL; /* base class will get template caps for us */
477 if (sink->cached_caps)
479 GST_LOG_OBJECT (sink, "Returning cached caps");
480 return gst_caps_ref (sink->cached_caps);
483 element_class = GST_ELEMENT_GET_CLASS (sink);
484 pad_template = gst_element_class_get_pad_template (element_class, "sink");
485 g_return_val_if_fail (pad_template != NULL, NULL);
487 // todo : get supported format.
488 //caps = gst_avsysaudio_probe_supported_formats (GST_OBJECT (sink), sink->,
489 //gst_pad_template_get_caps (pad_template));
492 //sink->cached_caps = gst_caps_ref (caps);
495 GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps);
502 avsysaudiosink_parse_spec (GstAvsysAudioSink * avsys_audio, GstRingBufferSpec * spec)
505 if (spec->type != GST_BUFTYPE_LINEAR ||
506 spec->channels > 6 || spec->channels < 1 ||
507 !(spec->format == GST_S8 || spec->format == GST_S16_LE) )
510 switch (spec->format) {
512 avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT;
513 avsys_audio->bytes_per_sample = 1;
516 avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT;
517 avsys_audio->bytes_per_sample = 2;
523 /// set audio parameter for avsys audio open
524 switch (avsys_audio->latency) {
525 case AVSYSAUDIOSINK_LATENCY_LOW:
526 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT_VIDEO;
528 case AVSYSAUDIOSINK_LATENCY_MID:
529 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT;
531 case AVSYSAUDIOSINK_LATENCY_HIGH:
532 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT_CLOCK;
536 avsys_audio->audio_param.priority = 0;
537 avsys_audio->audio_param.samplerate = spec->rate;
538 avsys_audio->audio_param.channels = spec->channels;
539 avsys_audio->bytes_per_sample *= spec->channels;
541 /* set software volume table type */
542 avsys_audio->audio_param.vol_type = avsys_audio->volume_type;
543 avsys_audio->audio_param.priority = avsys_audio->sound_priority;
544 avsys_audio->audio_param.handle_route = avsys_audio->user_route_policy;
550 gst_avsysaudiosink_open (GstAudioSink * asink)
556 gst_avsysaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
558 GstAvsysAudioSink *avsys_audio = NULL;
559 guint p_time = 0, b_time = 0;
561 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
563 GST_WARNING("Start");
565 // set avsys audio param
566 if (!avsysaudiosink_parse_spec (avsys_audio, spec))
569 if (gst_avsysaudiosink_avsys_open(avsys_audio) == FALSE) {
570 GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_open() failed");
574 /* Ring buffer size */
575 if (AVSYS_STATE_SUCCESS ==
576 avsys_audio_get_period_buffer_time(avsys_audio->audio_handle, &p_time, &b_time)) {
577 if(p_time == 0 || b_time == 0)
580 spec->latency_time = (guint64)p_time;
581 spec->buffer_time = (guint64)b_time;
583 GST_WARNING_OBJECT(avsys_audio, "");
586 spec->segsize = avsys_audio->avsys_size; /* '/16' see avsys_audio_open */
587 spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0);
590 if (avsys_audio->close_handle_on_prepare) {
591 if (gst_avsysaudiosink_avsys_close(avsys_audio) == FALSE) {
592 GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_close() failed");
598 GST_WARNING_OBJECT (avsys_audio, "latency time %u, buffer time %u, seg total %u\n",
599 (unsigned int)(spec->latency_time/1000), (unsigned int)(spec->buffer_time/1000), spec->segtotal);
604 GST_ELEMENT_ERROR (avsys_audio, RESOURCE, SETTINGS, (NULL),
605 ("Setting of swparams failed: " ));
610 avsysaudiosink_post_message(avsys_audio, GST_RESOURCE_ERROR_OPEN_READ);
615 gst_avsysaudiosink_unprepare (GstAudioSink * asink)
617 GstAvsysAudioSink *avsys_audio = NULL;
618 gboolean result = TRUE;
619 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
621 GST_WARNING("Start");
622 if(!gst_avsysaudiosink_avsys_close(avsys_audio))
624 GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_close() failed");
633 gst_avsysaudiosink_close (GstAudioSink * asink)
635 GstAvsysAudioSink *avsys_audio = NULL;
637 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
638 gst_caps_replace (&avsys_audio->cached_caps, NULL);
645 * Underrun and suspend recovery
649 gst_avsysaudiosink_write (GstAudioSink * asink, gpointer data, guint length)
651 GstAvsysAudioSink *avsys_audio = NULL;
654 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
655 GST_AVSYS_AUDIO_SINK_LOCK (asink);
657 if (avsys_audio->audio_stream_cb == NULL) {
658 write_len = avsys_audio_write(avsys_audio->audio_handle, data, length);
660 #if defined (LPCM_DUMP_SUPPORT)
661 fwrite(data, 1, write_len, avsys_audio->dumpFp); //This is for original data (no volume convert)
663 if(write_len != length)
668 GST_AVSYS_AUDIO_SINK_UNLOCK (asink);
673 GST_AVSYS_AUDIO_SINK_UNLOCK (asink);
675 if(AVSYS_FAIL(write_len))
677 GST_ERROR_OBJECT(avsys_audio, "avsys_audio_write() failed with %d\n", write_len);
679 return length; /* skip one period */
683 result = avsys_audio->audio_stream_cb(data, length, avsys_audio->cbHandle);
686 GST_ERROR_OBJECT(avsys_audio,"auido stream callback failed\n");
688 GST_AVSYS_AUDIO_SINK_UNLOCK (asink);
694 gst_avsysaudiosink_delay (GstAudioSink * asink)
696 GstAvsysAudioSink *avsys_audio = NULL;
700 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
701 GST_AVSYS_AUDIO_SINK_RESET_LOCK (asink);
702 if ((int)avsys_audio->audio_handle != -1) {
703 if (AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay)) {
707 GST_AVSYS_AUDIO_SINK_RESET_UNLOCK (asink);
712 gst_avsysaudiosink_reset (GstAudioSink * asink)
714 GstAvsysAudioSink *avsys_audio = NULL;
715 int avsys_result = AVSYS_STATE_SUCCESS;
717 GST_WARNING("Start");
718 GST_AVSYS_AUDIO_SINK_LOCK (asink);
719 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
721 #if defined(__REPLACE_RESET_WITH_CLOSE_AND_REOPEN__)
722 GST_AVSYS_AUDIO_SINK_RESET_LOCK (asink);
723 avsys_result = avsys_audio_close (avsys_audio->audio_handle);
724 if(AVSYS_FAIL(avsys_result)) {
725 GST_ERROR_OBJECT (avsys_audio, "avsys_audio_close: internal error: ");
727 avsys_audio->audio_handle =(avsys_handle_t) -1;
729 GST_AVSYS_AUDIO_SINK_RESET_UNLOCK (asink);
731 if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle)) {
732 GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: ");
736 GST_AVSYS_AUDIO_SINK_UNLOCK (asink);
744 gst_avsysaudiosink_avsys_open(GstAvsysAudioSink *avsys_audio)
748 GST_AVSYS_AUDIO_SINK_LOCK(avsys_audio);
749 if (avsys_audio->audio_handle == (avsys_handle_t)-1) {
751 GST_LOG_OBJECT (avsys_audio, "avsys_audio_open() with user policy [%d] ", avsys_audio->user_route_policy);
753 avsys_result = avsys_audio_open(&avsys_audio->audio_param, &avsys_audio->audio_handle, &avsys_audio->avsys_size);
754 if (avsys_result != AVSYS_STATE_SUCCESS) {
755 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
756 avsysaudiosink_post_message(avsys_audio, GST_RESOURCE_ERROR_OPEN_READ);
760 GST_LOG_OBJECT (avsys_audio, "Opened av system ");
762 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
764 GST_WARNING_OBJECT(avsys_audio, "audio handle has already opened");
765 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
768 #if defined (LPCM_DUMP_SUPPORT)
769 if (avsys_audio->dumpFp == NULL) {
770 avsys_audio->dumpFp = fopen("/root/dump.lpcm","w");
777 gst_avsysaudiosink_avsys_close(GstAvsysAudioSink *avsys_audio)
779 int avsys_result = AVSYS_STATE_SUCCESS;
781 GST_AVSYS_AUDIO_SINK_LOCK (avsys_audio);
783 if (avsys_audio->audio_handle != (avsys_handle_t)-1 ) {
784 avsys_result = avsys_audio_close(avsys_audio->audio_handle);
786 if (AVSYS_FAIL(avsys_result))
788 GST_ERROR_OBJECT(avsys_audio,
789 "avsys_audio_close() failed with 0x%x", avsys_result);
790 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
793 avsys_audio->audio_handle = (avsys_handle_t) -1;
794 GST_INFO_OBJECT(avsys_audio, "avsys_audio_close() success");
797 GST_LOG_OBJECT (avsys_audio, "Closed av system ");
799 GST_WARNING_OBJECT(avsys_audio, "audio handle has already closed");
802 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
803 #if defined (LPCM_DUMP_SUPPORT)
804 if(avsys_audio->dumpFp != NULL)
806 fclose(avsys_audio->dumpFp);
807 avsys_audio->dumpFp = NULL;
813 static GstStateChangeReturn
814 gst_avsyssudiosink_change_state (GstElement *element, GstStateChange transition)
816 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
817 GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (element);
819 int avsys_result = AVSYS_STATE_SUCCESS;
821 switch (transition) {
822 case GST_STATE_CHANGE_NULL_TO_READY:
824 case GST_STATE_CHANGE_READY_TO_PAUSED:
826 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
827 #if defined(_ALSA_DAPM_)
828 switch(avsys_audio->audio_route_policy) {
829 case AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING:
830 GST_INFO_OBJECT(avsys_audio, "audio route uses external setting");
833 GST_ERROR_OBJECT(avsys_audio, "Unknown audio route option %d\n", avsys_audio->audio_route_policy);
837 #if defined(__REPLACE_RESET_WITH_CLOSE_AND_REOPEN__)
838 if (avsys_audio->audio_handle == (avsys_handle_t)-1) {
839 avsys_result = avsys_audio_open(&avsys_audio->audio_param, &avsys_audio->audio_handle, &avsys_audio->avsys_size);
840 if (AVSYS_FAIL(avsys_result)) {
841 GST_ERROR_OBJECT (avsys_audio, "avsys_audio_open: internal error: ");
842 return GST_STATE_CHANGE_FAILURE;
847 if (avsys_audio->use_fadeup_volume) {
848 GST_INFO_OBJECT(avsys_audio, "Set fadeup volume");
849 avsys_audio_set_volume_fadeup(avsys_audio->audio_handle);
852 if(AVSYS_STATE_SUCCESS != avsys_audio_set_mute(avsys_audio->audio_handle, CONVERT_MUTE_VALUE(avsys_audio->mute)))
854 GST_ERROR_OBJECT(avsys_audio, "Set mute failed %d", CONVERT_MUTE_VALUE(avsys_audio->mute));
860 ret = GST_ELEMENT_CLASS(parent_class)->change_state (element, transition);
861 if (ret == GST_STATE_CHANGE_FAILURE) {
864 switch (transition) {
865 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
867 case GST_STATE_CHANGE_PAUSED_TO_READY:
869 case GST_STATE_CHANGE_READY_TO_NULL:
879 avsysaudiosink_post_message(GstAvsysAudioSink* self,int errorcode)
881 GST_DEBUG("avsysaudiosink_post_message\n");
883 GstMessage *Msg = NULL;
885 gboolean status = FALSE;
886 GError *error = NULL;
890 error_code = errorcode;
892 error_code = GST_STREAM_ERROR_TYPE_NOT_FOUND; */
893 error_code = errorcode;
894 domain = gst_resource_error_quark();
895 error = g_error_new (domain, error_code, "AVSYSAUDIOSINK_RESOURCE_ERROR");
896 Msg = gst_message_new_error(GST_ELEMENT(self), error, "AVSYSAUDIOSINK_ERROR");
897 status = gst_element_post_message (GST_ELEMENT(self), Msg);
900 GST_ERROR("Error in posting message on the bus ...\n");