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
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,
74 gst_avsysaudiosink_audio_mute_get_type (void)
76 static GType avaudio_mute_type = 0;
77 static const GEnumValue avaudio_mute[] = {
78 {AVSYSAUDIOSINK_AUDIO_UNMUTE, "Unmute", "unmute"},
79 {AVSYSAUDIOSINK_AUDIO_MUTE, "Mute immediately", "mute"},
80 {AVSYSAUDIOSINK_AUDIO_MUTE_WITH_FADEDOWN_EFFECT, "Mute with fadedown effect", "fadedown"},
84 if (!avaudio_mute_type) {
86 g_enum_register_static ("GstAvsysAudioSinkAudioMute", avaudio_mute);
88 return avaudio_mute_type;
92 gst_avsysaudiosink_user_route_get_type (void)
94 static GType user_route_type = 0;
95 static const GEnumValue user_route[] = {
96 {AVSYSAUDIOSINK_USERROUTE_AUTO, "Route automatically", "auto"},
97 {AVSYSAUDIOSINK_USERROUTE_PHONE, "Route to phone only", "phone"},
101 if (!user_route_type) {
103 g_enum_register_static ("GstAvsysAudioSinkUserRoutePolicy",user_route);
105 return user_route_type;
109 gst_avsysaudiosink_audio_route_get_type (void)
111 static GType playback_audio_route_type = 0;
112 static const GEnumValue playback_audio_route[] = {
113 {AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING, "Use external sound path", "external"},
114 {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_NORMAL, "Auto change between speaker & earphone", "normal"},
115 {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_ALERT, "Play via both speaker & earphone", "alert"},
116 {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_HEADSET_ONLY, "Play via earphone only", "headset"},
120 if (!playback_audio_route_type) {
121 playback_audio_route_type =
122 g_enum_register_static ("GstAvsysAudioSinkAudioRoutePolicy", playback_audio_route);
124 return playback_audio_route_type;
129 gst_avsysaudiosink_volume_table_get_type (void)
131 static GType avsysaudio_volume_table_type = 0;
132 static const GEnumValue avsysaudio_volume_table[] = {
133 {AVSYS_AUDIO_VOLUME_TYPE_SYSTEM, "System Volume", "system"},
134 {AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION, "Notification Volume", "notification"},
135 {AVSYS_AUDIO_VOLUME_TYPE_ALARM, "Alarm Volume", "alarm"},
136 {AVSYS_AUDIO_VOLUME_TYPE_RINGTONE, "Ringtone Volume", "ringtone"},
137 {AVSYS_AUDIO_VOLUME_TYPE_MEDIA, "Media Volume", "media"},
138 {AVSYS_AUDIO_VOLUME_TYPE_CALL, "Call Volume", "call"},
139 {AVSYS_AUDIO_VOLUME_TYPE_FIXED, "Fixed Volume", "fixed"},
140 {AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA, "Java Volume", "java"},
144 if (!avsysaudio_volume_table_type) {
145 avsysaudio_volume_table_type =
146 g_enum_register_static ("GstAvsysAudioSinkVolumeTable", avsysaudio_volume_table);
148 return avsysaudio_volume_table_type;
152 gst_avsysaudiosink_latency_get_type (void)
154 static GType avsysaudio_latency_type = 0;
155 static const GEnumValue avsysaudio_latency[] = {
156 {AVSYSAUDIOSINK_LATENCY_LOW, "Low latency", "low"},
157 {AVSYSAUDIOSINK_LATENCY_MID, "Mid latency", "mid"},
158 {AVSYSAUDIOSINK_LATENCY_HIGH, "High latency", "high"},
162 if (!avsysaudio_latency_type) {
163 avsysaudio_latency_type =
164 g_enum_register_static ("GstAvsysAudioSinkLatency", avsysaudio_latency);
166 return avsysaudio_latency_type;
169 static void gst_avsysaudiosink_init_interfaces (GType type);
171 //#define GST_BOILERPLATE_FULL(type, type_as_function, parent_type, parent_type_macro, additional_initializations)
173 GST_BOILERPLATE_FULL (GstAvsysAudioSink, gst_avsysaudiosink, GstAudioSink,
174 GST_TYPE_AUDIO_SINK, gst_avsysaudiosink_init_interfaces);
177 static void gst_avsysaudiosink_finalise (GObject * object);
178 static void gst_avsysaudiosink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
179 static void gst_avsysaudiosink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
181 static GstCaps *gst_avsysaudiosink_getcaps (GstBaseSink * bsink);
184 static gboolean gst_avsysaudiosink_avsys_close(GstAvsysAudioSink *avsys_audio);
185 static gboolean gst_avsysaudiosink_avsys_open(GstAvsysAudioSink *avsys_audio);
187 static gboolean gst_avsysaudiosink_open (GstAudioSink * asink);
188 static gboolean gst_avsysaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec);
189 static gboolean gst_avsysaudiosink_unprepare (GstAudioSink * asink);
190 static gboolean gst_avsysaudiosink_close (GstAudioSink * asink);
191 static guint gst_avsysaudiosink_write (GstAudioSink * asink, gpointer data, guint length);
192 static guint gst_avsysaudiosink_delay (GstAudioSink * asink);
193 static void gst_avsysaudiosink_reset (GstAudioSink * asink);
194 static gboolean avsysaudiosink_post_message(GstAvsysAudioSink* self,int errorcode);
197 #define AVSYS_AUDIO_FACTORY_ENDIANNESS "LITTLE_ENDIAN"
200 static GstStaticPadTemplate avsysaudiosink_sink_factory =
201 GST_STATIC_PAD_TEMPLATE ("sink",
204 GST_STATIC_CAPS ("audio/x-raw-int, "
205 "endianness = (int) { " AVSYS_AUDIO_FACTORY_ENDIANNESS " }, "
206 "signed = (boolean) { TRUE }, "
209 "rate = (int) [ 1, MAX ], "
210 "channels = (int) [ 1, 2 ]; "
212 "signed = (boolean) { FALSE }, "
215 "rate = (int) [ 1, MAX ], "
216 "channels = (int) [ 1, 2 ] "
220 static inline guint _time_to_sample(GstAvsysAudioSink * asink, GstClockTime diff)
223 result =(GST_TIME_AS_USECONDS(diff) * asink->audio_param.samplerate)/1000000;
229 gst_avsysaudiosink_finalise (GObject * object)
231 GstAvsysAudioSink *sink = NULL;
233 sink = GST_AVSYS_AUDIO_SINK (object);
234 gst_avsysaudiosink_avsys_close(sink);
235 g_mutex_free (sink->avsys_audio_lock);
236 g_mutex_free (sink->avsys_audio_reset_lock);
238 G_OBJECT_CLASS (parent_class)->finalize (object);
242 gst_avsysaudiosink_init_interfaces (GType type)
248 gst_avsysaudiosink_base_init (gpointer g_class)
250 GstElementClass *element_class = NULL;
252 element_class = GST_ELEMENT_CLASS (g_class);
253 gst_element_class_set_details (element_class, &gst_avsysaudiosink_details);
254 gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&avsysaudiosink_sink_factory));
257 static GstStateChangeReturn
258 gst_avsyssudiosink_change_state (GstElement *element, GstStateChange transition);
262 gst_avsysaudiosink_class_init (GstAvsysAudioSinkClass * klass)
264 GObjectClass *gobject_class;
265 GstElementClass *gstelement_class;
266 GstBaseSinkClass *gstbasesink_class;
267 GstBaseAudioSinkClass *gstbaseaudiosink_class;
268 GstAudioSinkClass *gstaudiosink_class;
270 gobject_class = (GObjectClass *) klass;
271 gstelement_class = (GstElementClass *) klass;
272 gstbasesink_class = (GstBaseSinkClass *) klass;
273 gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
274 gstaudiosink_class = (GstAudioSinkClass *) klass;
276 parent_class = g_type_class_peek_parent (klass);
277 gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_avsyssudiosink_change_state);
279 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_finalise);
280 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_get_property);
281 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_set_property);
283 // gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_getcaps);
285 gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_open);
286 gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_prepare);
287 gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_unprepare);
288 gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_close);
289 gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_write);
290 gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_delay);
291 gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_reset);
293 g_object_class_install_property ( gobject_class, PROP_AUDIO_VOLUME_TYPE,
294 g_param_spec_enum ("volumetype", "Avsystem Volume Type",
295 "Select avsystem audio software volume type",
296 GST_AVSYS_AUDIO_SINK_VOLUME_TYPE, DEFAULT_VOLUME_TYPE,
297 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
299 g_object_class_install_property ( gobject_class, PROP_AUDIO_PRIORITY,
300 g_param_spec_int ("priority", "Avsystem Sound Priority", "Avsystem sound priority",
301 AVSYS_AUDIO_PRIORITY_NORMAL, AVSYS_AUDIO_PRIORITY_SOLO_WITH_TRANSITION_EFFECT,
302 AVSYS_AUDIO_PRIORITY_NORMAL, G_PARAM_READWRITE));
304 g_object_class_install_property ( gobject_class, PROP_AUDIO_HANDLE,
305 g_param_spec_pointer("audio-handle", "Avsystem handle",
306 "Avsystem audio handle",
309 g_object_class_install_property ( gobject_class, PROP_AUDIO_CALLBACK,
310 g_param_spec_pointer("audio-callback", "Avsystem callback",
311 "Avsystem audio callback",
314 g_object_class_install_property (gobject_class, PROP_AUDIO_FADEUPVOLUME,
315 g_param_spec_boolean ("fadeup", "Avsystem fadeup volume",
316 "Enable avsystem audio fadeup volume when pause to play",
317 DEFAULT_FADEUP_VOLUME, G_PARAM_READWRITE));
319 g_object_class_install_property (gobject_class ,PROP_AUDIO_MUTE,
320 g_param_spec_enum("mute", "Avsystem mute",
321 "Avsystem audio mute",
322 GST_AVSYS_AUDIO_SINK_MUTE, DEFAULT_AUDIO_MUTE,
323 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
325 g_object_class_install_property (gobject_class ,PROP_AUDIO_ROUTE_POLICY,
326 g_param_spec_enum("audio-route", "Audio Route Policy",
327 "Audio route policy of system",
328 GST_AVSYS_AUDIO_SINK_AUDIO_ROUTE, DEFAULT_AUDIO_ROUTE,
329 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
331 g_object_class_install_property (gobject_class ,PROP_AUDIO_USER_ROUTE,
332 g_param_spec_enum("user-route", "User Route Policy",
334 GST_AVSYS_AUDIO_SINK_USER_ROUTE, DEFAULT_USER_ROUTE,
335 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
337 g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY,
338 g_param_spec_enum("latency", "Audio Backend Latency",
339 "Audio backend latency",
340 GST_AVSYS_AUDIO_SINK_LATENCY_TYPE, DEFAULT_AUDIO_LATENCY,
341 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
345 gst_avsysaudiosink_set_property (GObject * object, guint prop_id,
346 const GValue * value, GParamSpec * pspec)
348 GstAvsysAudioSink *sink = NULL;
350 gboolean nbool = FALSE;
352 sink = GST_AVSYS_AUDIO_SINK (object);
356 case PROP_AUDIO_HANDLE:
357 sink->cbHandle = g_value_get_pointer(value);
359 case PROP_AUDIO_CALLBACK:
360 sink->audio_stream_cb = g_value_get_pointer(value);
363 case PROP_AUDIO_VOLUME_TYPE:
364 nvalue = g_value_get_enum(value);
365 sink->volume_type = nvalue;
368 case PROP_AUDIO_PRIORITY:
369 nvalue = g_value_get_int(value);
370 sink->sound_priority = nvalue;
373 case PROP_AUDIO_MUTE:
374 nvalue = g_value_get_enum(value);
375 if(sink->audio_handle != (avsys_handle_t)-1)
377 if(AVSYS_SUCCESS(avsys_audio_set_mute_fadedown(sink->audio_handle)))
385 case PROP_AUDIO_FADEUPVOLUME:
386 nbool = g_value_get_boolean(value);
387 sink->use_fadeup_volume = nbool;
390 case PROP_AUDIO_ROUTE_POLICY:
391 nvalue = g_value_get_enum(value);
392 sink->audio_route_policy = nvalue;
393 switch(sink->audio_route_policy)
395 case AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING:
396 GST_INFO_OBJECT(sink, "use external audio route setting");
399 g_print("AVSYSAUDIOSINK :: Unknown audio route option %d\n", sink->audio_route_policy);
400 GST_ERROR_OBJECT(sink, "Unknown audio route option %d", sink->audio_route_policy);
404 case PROP_AUDIO_USER_ROUTE:
405 nvalue = g_value_get_enum(value);
406 sink->user_route_policy = nvalue;
408 case PROP_AUDIO_LATENCY:
409 nvalue = g_value_get_enum(value);
410 sink->latency = nvalue;
413 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
419 gst_avsysaudiosink_get_property (GObject * object, guint prop_id,
420 GValue * value, GParamSpec * pspec)
422 GstAvsysAudioSink *sink = NULL;
424 sink = GST_AVSYS_AUDIO_SINK (object);
427 case PROP_AUDIO_VOLUME_TYPE:
428 g_value_set_enum(value, sink->volume_type);
430 case PROP_AUDIO_PRIORITY:
431 g_value_set_int(value, sink->sound_priority);
433 case PROP_AUDIO_MUTE:
434 g_value_set_enum(value, sink->mute);
436 case PROP_AUDIO_FADEUPVOLUME:
437 g_value_set_boolean(value, sink->use_fadeup_volume);
440 case PROP_AUDIO_ROUTE_POLICY:
441 g_value_set_enum(value, sink->audio_route_policy);
443 case PROP_AUDIO_USER_ROUTE:
444 g_value_set_enum(value, sink->user_route_policy);
446 case PROP_AUDIO_LATENCY:
447 g_value_set_enum(value, sink->latency);
451 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
457 gst_avsysaudiosink_init (GstAvsysAudioSink * avsysaudiosink, GstAvsysAudioSinkClass * g_class)
459 GST_DEBUG_OBJECT (avsysaudiosink, "initializing avsysaudiosink");
461 avsysaudiosink->audio_handle = (avsys_handle_t)-1;
462 avsysaudiosink->cached_caps = NULL;
463 avsysaudiosink->avsys_audio_lock = g_mutex_new ();
464 avsysaudiosink->avsys_audio_reset_lock = g_mutex_new ();
465 avsysaudiosink->volume_type = DEFAULT_VOLUME_TYPE;
466 avsysaudiosink->sound_priority = AVSYS_AUDIO_PRIORITY_NORMAL;
467 avsysaudiosink->mute = DEFAULT_AUDIO_MUTE;
468 avsysaudiosink->use_fadeup_volume = DEFAULT_FADEUP_VOLUME;
469 avsysaudiosink->latency = DEFAULT_AUDIO_LATENCY;
470 avsysaudiosink->audio_route_policy = DEFAULT_AUDIO_ROUTE;
471 avsysaudiosink->bytes_per_sample = 1;
472 #if defined (LPCM_DUMP_SUPPORT)
473 avsysaudiosink->dumpFp = NULL;
479 gst_avsysaudiosink_getcaps (GstBaseSink * bsink)
481 GstElementClass *element_class = NULL;
482 GstPadTemplate *pad_template = NULL;
483 GstAvsysAudioSink *sink = GST_AVSYS_AUDIO_SINK (bsink);
488 sink = GST_AVSYS_AUDIO_SINK (bsink);
489 if (sink->audio_handle == -1)
491 GST_DEBUG_OBJECT (sink, "avsystem audio not open, using template caps");
492 return NULL; /* base class will get template caps for us */
495 if (sink->cached_caps)
497 GST_LOG_OBJECT (sink, "Returning cached caps");
498 return gst_caps_ref (sink->cached_caps);
501 element_class = GST_ELEMENT_GET_CLASS (sink);
502 pad_template = gst_element_class_get_pad_template (element_class, "sink");
503 g_return_val_if_fail (pad_template != NULL, NULL);
505 // todo : get supported format.
506 //caps = gst_avsysaudio_probe_supported_formats (GST_OBJECT (sink), sink->,
507 //gst_pad_template_get_caps (pad_template));
510 //sink->cached_caps = gst_caps_ref (caps);
513 GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps);
520 avsysaudiosink_parse_spec (GstAvsysAudioSink * avsys_audio, GstRingBufferSpec * spec)
523 if (spec->type != GST_BUFTYPE_LINEAR ||
524 spec->channels > 2 || spec->channels < 1 ||
525 !(spec->format == GST_S8 || spec->format == GST_S16_LE) )
531 avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT;
532 avsys_audio->bytes_per_sample = 1;
535 avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT;
536 avsys_audio->bytes_per_sample = 2;
542 /// set audio parameter for avsys audio open
543 switch(avsys_audio->latency)
545 case AVSYSAUDIOSINK_LATENCY_LOW:
546 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT_VIDEO;
548 case AVSYSAUDIOSINK_LATENCY_MID:
549 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT;
551 case AVSYSAUDIOSINK_LATENCY_HIGH:
552 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT_CLOCK;
558 avsys_audio->audio_param.priority = 0;
559 avsys_audio->audio_param.samplerate = spec->rate;
560 avsys_audio->audio_param.channels = spec->channels;
562 if(spec->channels == 2)
563 avsys_audio->bytes_per_sample *= 2;
564 else if(spec->channels > 2)
566 GST_ERROR_OBJECT(avsys_audio,"Unsupported channel number %d", spec->channels);
570 /* set software volume table type */
571 avsys_audio->audio_param.vol_type = avsys_audio->volume_type;
572 avsys_audio->audio_param.priority = avsys_audio->sound_priority;
573 avsys_audio->audio_param.handle_route = avsys_audio->user_route_policy;
579 gst_avsysaudiosink_open (GstAudioSink * asink)
585 gst_avsysaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
587 GstAvsysAudioSink *avsys_audio = NULL;
588 guint p_time = 0, b_time = 0;
590 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
592 // set avsys audio param
593 if (!avsysaudiosink_parse_spec (avsys_audio, spec))
596 if (gst_avsysaudiosink_avsys_open(avsys_audio) == FALSE)
598 GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_open() failed");
603 /* Ring buffer size */
604 if (AVSYS_STATE_SUCCESS ==
605 avsys_audio_get_period_buffer_time(avsys_audio->audio_handle, &p_time, &b_time))
607 if(p_time == 0 || b_time == 0)
610 spec->latency_time = (guint64)p_time;
611 spec->buffer_time = (guint64)b_time;
617 spec->segsize = avsys_audio->avsys_size; /* '/16' see avsys_audio_open */
618 spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0);
621 GST_WARNING_OBJECT (avsys_audio, "latency time %u, buffer time %u, seg total %u\n",
622 (unsigned int)(spec->latency_time/1000), (unsigned int)(spec->buffer_time/1000), spec->segtotal);
627 GST_ELEMENT_ERROR (avsys_audio, RESOURCE, SETTINGS, (NULL),
628 ("Setting of swparams failed: " ));
634 gst_avsysaudiosink_unprepare (GstAudioSink * asink)
636 GstAvsysAudioSink *avsys_audio = NULL;
637 gboolean result = TRUE;
638 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
640 if(!gst_avsysaudiosink_avsys_close(avsys_audio))
642 GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_close() failed");
650 gst_avsysaudiosink_close (GstAudioSink * asink)
652 GstAvsysAudioSink *avsys_audio = NULL;
654 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
655 gst_caps_replace (&avsys_audio->cached_caps, NULL);
662 * Underrun and suspend recovery
666 gst_avsysaudiosink_write (GstAudioSink * asink, gpointer data, guint length)
668 GstAvsysAudioSink *avsys_audio = NULL;
671 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
672 GST_AVSYS_AUDIO_SINK_LOCK (asink);
674 if(avsys_audio->audio_stream_cb == NULL)
676 write_len = avsys_audio_write(avsys_audio->audio_handle, data, length);
678 #if defined (LPCM_DUMP_SUPPORT)
679 fwrite(data, 1, write_len, avsys_audio->dumpFp); //This is for original data (no volume convert)
681 if(write_len != length)
686 GST_AVSYS_AUDIO_SINK_UNLOCK (asink);
691 GST_AVSYS_AUDIO_SINK_UNLOCK (asink);
693 if(AVSYS_FAIL(write_len))
695 GST_ERROR_OBJECT(avsys_audio, "avsys_audio_write() failed with %d\n", write_len);
697 return length; /* skip one period */
704 result = avsys_audio->audio_stream_cb(data, length, avsys_audio->cbHandle);
707 GST_ERROR_OBJECT(avsys_audio,"auido stream callback failed\n");
709 GST_AVSYS_AUDIO_SINK_UNLOCK (asink);
715 gst_avsysaudiosink_delay (GstAudioSink * asink)
717 GstAvsysAudioSink *avsys_audio = NULL;
721 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
722 GST_AVSYS_AUDIO_SINK_RESET_LOCK (asink);
723 if((int)avsys_audio->audio_handle != -1) {
724 if(AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay)) {
728 GST_AVSYS_AUDIO_SINK_RESET_UNLOCK (asink);
733 gst_avsysaudiosink_reset (GstAudioSink * asink)
735 GstAvsysAudioSink *avsys_audio = NULL;
736 int avsys_result = AVSYS_STATE_SUCCESS;
738 GST_AVSYS_AUDIO_SINK_LOCK (asink);
739 avsys_audio = GST_AVSYS_AUDIO_SINK (asink);
741 #if defined(__REPLACE_RESET_WITH_CLOSE_AND_REOPEN__)
742 GST_AVSYS_AUDIO_SINK_RESET_LOCK (asink);
743 avsys_result = avsys_audio_close (avsys_audio->audio_handle);
744 if(AVSYS_FAIL(avsys_result))
746 GST_ERROR_OBJECT (avsys_audio, "avsys_audio_close: internal error: ");
750 avsys_audio->audio_handle =(avsys_handle_t) -1;
752 GST_AVSYS_AUDIO_SINK_RESET_UNLOCK (asink);
754 if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle))
756 GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: ");
760 GST_AVSYS_AUDIO_SINK_UNLOCK (asink);
767 gst_avsysaudiosink_avsys_open(GstAvsysAudioSink *avsys_audio)
771 GST_AVSYS_AUDIO_SINK_LOCK(avsys_audio);
772 if(avsys_audio->audio_handle == (avsys_handle_t)-1) {
774 GST_LOG_OBJECT (avsys_audio, "avsys_audio_open() with user policy [%d] ", avsys_audio->user_route_policy);
776 avsys_result = avsys_audio_open(&avsys_audio->audio_param, &avsys_audio->audio_handle, &avsys_audio->avsys_size);
777 if(avsys_result != AVSYS_STATE_SUCCESS)
779 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
780 avsysaudiosink_post_message(avsys_audio, avsys_result);
784 GST_LOG_OBJECT (avsys_audio, "Opened av system ");
786 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
790 GST_WARNING_OBJECT(avsys_audio, "audio handle has already opened");
791 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
794 #if defined (LPCM_DUMP_SUPPORT)
795 if(avsys_audio->dumpFp == NULL)
797 avsys_audio->dumpFp = fopen("/root/dump.lpcm","w");
804 gst_avsysaudiosink_avsys_close(GstAvsysAudioSink *avsys_audio)
806 int avsys_result = AVSYS_STATE_SUCCESS;
808 GST_AVSYS_AUDIO_SINK_LOCK (avsys_audio);
810 if(avsys_audio->audio_handle != (avsys_handle_t)-1 )
812 avsys_result = avsys_audio_close(avsys_audio->audio_handle);
814 if (AVSYS_FAIL(avsys_result))
816 GST_ERROR_OBJECT(avsys_audio,
817 "avsys_audio_close() failed with 0x%x", avsys_result);
818 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
823 avsys_audio->audio_handle = (avsys_handle_t) -1;
824 GST_INFO_OBJECT(avsys_audio, "avsys_audio_close() success");
827 GST_LOG_OBJECT (avsys_audio, "Closed av system ");
831 GST_WARNING_OBJECT(avsys_audio, "audio handle has already closed");
834 GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio);
835 #if defined (LPCM_DUMP_SUPPORT)
836 if(avsys_audio->dumpFp != NULL)
838 fclose(avsys_audio->dumpFp);
839 avsys_audio->dumpFp = NULL;
845 static GstStateChangeReturn
846 gst_avsyssudiosink_change_state (GstElement *element, GstStateChange transition)
848 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
849 GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (element);
851 int avsys_result = AVSYS_STATE_SUCCESS;
855 case GST_STATE_CHANGE_NULL_TO_READY:
857 case GST_STATE_CHANGE_READY_TO_PAUSED:
859 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
860 #if defined(_ALSA_DAPM_)
861 switch(avsys_audio->audio_route_policy)
863 case AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING:
864 GST_INFO_OBJECT(avsys_audio, "audio route uses external setting");
867 GST_ERROR_OBJECT(avsys_audio, "Unknown audio route option %d\n", avsys_audio->audio_route_policy);
871 #if defined(__REPLACE_RESET_WITH_CLOSE_AND_REOPEN__)
872 if(avsys_audio->audio_handle == (avsys_handle_t)-1)
874 avsys_result = avsys_audio_open(&avsys_audio->audio_param, &avsys_audio->audio_handle, &avsys_audio->avsys_size);
875 if(AVSYS_FAIL(avsys_result))
877 GST_ERROR_OBJECT (avsys_audio, "avsys_audio_open: internal error: ");
878 return GST_STATE_CHANGE_FAILURE;
883 if(avsys_audio->use_fadeup_volume) {
884 GST_INFO_OBJECT(avsys_audio, "Set fadeup volume");
885 avsys_audio_set_volume_fadeup(avsys_audio->audio_handle);
888 if(AVSYS_STATE_SUCCESS != avsys_audio_set_mute(avsys_audio->audio_handle, CONVERT_MUTE_VALUE(avsys_audio->mute)))
890 GST_ERROR_OBJECT(avsys_audio, "Set mute failed %d", CONVERT_MUTE_VALUE(avsys_audio->mute));
896 ret = GST_ELEMENT_CLASS(parent_class)->change_state (element, transition);
897 if (ret == GST_STATE_CHANGE_FAILURE)
903 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
905 case GST_STATE_CHANGE_PAUSED_TO_READY:
907 case GST_STATE_CHANGE_READY_TO_NULL:
917 avsysaudiosink_post_message(GstAvsysAudioSink* self,int errorcode)
919 GST_DEBUG("avsysaudiosink_post_message\n");
921 GstMessage *Msg = NULL;
923 gboolean status = FALSE;
924 GError *error = NULL;
928 error_code = errorcode;
930 error_code = GST_STREAM_ERROR_TYPE_NOT_FOUND; */
931 error_code = GST_RESOURCE_ERROR_FAILED;
932 domain = gst_resource_error_quark();
933 error = g_error_new (domain, error_code, "AVSYSAUDIOSINK_RESOURCE_ERROR");
934 Msg = gst_message_new_error(GST_ELEMENT(self), error, "AVSYSAUDIOSINK_ERROR");
935 status = gst_element_post_message (GST_ELEMENT(self), Msg);
938 GST_ERROR("Error in posting message on the bus ...\n");