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
24 #include <sys/ioctl.h>
31 #include <gst/gstutils.h>
32 //#include <mm_debug.h>
34 #include <sys/time.h> /*gettimeofday*/
37 #include "gstavsysaudiosrc.h"
42 * _ENABLE_FAKE_READ: enable fake read instead of avsys_audio_read(). (default: 0)
44 #define _ENABLE_FAKE_READ 0
48 #define _MIN_RATE 8000
49 #define _MAX_RATE 48000
50 #define _MIN_CHANNEL 1
51 #define _MAX_CHANNEL 2
54 #define DEFAULT_GPT8_FREQ 26
57 static long g_delay_time;
60 #define DEFAULT_MEDIACALL_MODE AVSYS_AUDIO_ECHO_MODE_NONE
61 #define DEFAULT_AUDIO_LATENCY AVSYSAUDIOSRC_LATENCY_MID
63 GST_DEBUG_CATEGORY_EXTERN (avsystem_src_debug);
64 #define GST_CAT_DEFAULT avsystem_src_debug
66 /* elementfactory information */
67 static const GstElementDetails gst_avsysaudiosrc_details =
68 GST_ELEMENT_DETAILS ("AV system source",
70 "Read from a AV system audio in",
71 "Samsung Electronics co., ltd.");
77 #if !defined(I386_SIMULATOR)
78 PROP_AUDIO_MEDIA_CALL,
90 gst_avsysaudiosrc_audio_latency_get_type (void)
92 static GType capture_audio_latency_type = 0;
93 static const GEnumValue capture_audio_latency[] = {
94 {AVSYSAUDIOSRC_LATENCY_LOW, "Set capture latency as low", "low"},
95 {AVSYSAUDIOSRC_LATENCY_MID, "Set capture latency as mid", "mid"},
96 {AVSYSAUDIOSRC_LATENCY_HIGH, "Set capture latency as high", "high"},
100 if (!capture_audio_latency_type) {
101 capture_audio_latency_type =
102 g_enum_register_static ("GstAvsysAudioSrcAudioLatency", capture_audio_latency);
104 return capture_audio_latency_type;
108 GST_BOILERPLATE (GstAvsysAudioSrc, gst_avsysaudiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC);
110 #if _ENABLE_FAKE_READ
111 static unsigned long fake_delay (unsigned long usec);
114 static guint gst_avsysaudiosrc_delay (GstAudioSrc *asrc);
116 static void gst_avsysaudiosrc_finalize (GObject * object);
117 static void gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
118 static void gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
120 static GstCaps* gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc);
122 static gboolean gst_avsysaudiosrc_open (GstAudioSrc * asrc);
123 static gboolean gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec);
124 static gboolean gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc);
125 static gboolean gst_avsysaudiosrc_close (GstAudioSrc * asrc);
126 static guint gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length);
127 static void gst_avsysaudiosrc_reset (GstAudioSrc * asrc);
128 static gboolean gst_avsysaudiosrc_avsys_close (GstAvsysAudioSrc *src);
129 static gboolean gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *src);
130 static gboolean gst_avsysaudiosrc_avsys_cork (GstAvsysAudioSrc *avsysaudiosrc, int cork);
131 static gboolean gst_avsysaudiosrc_avsys_start (GstAvsysAudioSrc *src);
132 static gboolean gst_avsysaudiosrc_avsys_stop (GstAvsysAudioSrc *src);
133 #if defined(_USE_CAPS_)
134 static GstCaps *gst_avsysaudiosrc_detect_rates (GstObject * obj, avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps);
135 static GstCaps *gst_avsysaudiosrc_detect_channels (GstObject * obj,avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps);
136 static GstCaps *gst_avsysaudiosrc_detect_formats (GstObject * obj,avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps);
137 static GstCaps *gst_avsysaudiosrc_probe_supported_formats (GstObject * obj, avsys_handle_t handle, const GstCaps * template_caps);
139 static GstStateChangeReturn gst_avsys_src_change_state (GstElement * element, GstStateChange transition) ;
143 /* AvsysAudioSrc signals and args */
148 # define AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS "LITTLE_ENDIAN"
150 static GstStaticPadTemplate avsysaudiosrc_src_factory =
151 GST_STATIC_PAD_TEMPLATE ("src",
156 "endianness = (int) { " AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS " }, "
157 "signed = (boolean) { TRUE }, "
160 "rate = (int) [ 8000, 48000 ], "
161 "channels = (int) [ 1, 2 ]; "
163 "signed = (boolean) { FALSE }, "
166 "rate = (int) [ 8000, 48000 ], "
167 "channels = (int) [ 1, 2 ]")
170 static inline guint _time_to_sample(GstAvsysAudioSrc *avsyssrc, GstClockTime diff)
173 // sample rate : asrc->audio_param.samplerate
174 result =(GST_TIME_AS_USECONDS(diff) * avsyssrc->audio_param.samplerate)/1000000;
180 gst_avsysaudiosrc_finalize (GObject * object)
182 GstAvsysAudioSrc *src = NULL;
185 src = GST_AVSYS_AUDIO_SRC (object);
186 g_mutex_free (src->avsysaudio_lock);
188 G_OBJECT_CLASS (parent_class)->finalize (object);
192 gst_avsysaudiosrc_base_init (gpointer g_class)
194 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
196 gst_element_class_set_details (element_class, &gst_avsysaudiosrc_details);
198 gst_element_class_add_pad_template (element_class,
199 gst_static_pad_template_get (&avsysaudiosrc_src_factory));
203 gst_avsysaudiosrc_class_init (GstAvsysAudioSrcClass * klass)
205 GObjectClass *gobject_class;
206 GstElementClass *gstelement_class;
207 GstBaseSrcClass *gstbasesrc_class;
208 GstBaseAudioSrcClass *gstbaseaudiosrc_class;
209 GstAudioSrcClass *gstaudiosrc_class;
211 gobject_class = (GObjectClass *) klass;
212 gstelement_class = (GstElementClass *) klass;
213 gstbasesrc_class = (GstBaseSrcClass *) klass;
214 gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
215 gstaudiosrc_class = (GstAudioSrcClass *) klass;
217 gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_avsys_src_change_state);
219 parent_class = g_type_class_peek_parent (klass);
221 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_finalize);
222 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_get_property);
223 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_set_property);
224 #if defined(_USE_CAPS_)
225 gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_getcaps);
227 gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_open);
228 gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_prepare);
229 gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_unprepare);
230 gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_close);
231 gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_read);
232 gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_delay);
233 gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_reset);
235 g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY,
236 g_param_spec_enum("latency", "Audio Latency",
238 GST_AVSYS_AUDIO_SRC_LATENCY, DEFAULT_AUDIO_LATENCY,
239 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
245 *@note useful range 0 - 1000000 microsecond
247 #if _ENABLE_FAKE_READ
249 fake_delay (unsigned long usec)
251 struct timeval s_time;
252 struct timeval c_time;
259 unsigned long total_usec = 0UL;
260 unsigned long t = 0UL;
268 if (gettimeofday ((struct timeval *)&s_time, NULL) == 0) {
269 s_sec = s_time.tv_sec;
270 s_usec = s_time.tv_usec;
277 if (gettimeofday ((struct timeval *)&c_time, NULL) == 0) {
278 c_sec = c_time.tv_sec;
279 c_usec = c_time.tv_usec;
285 t_sec = c_sec - s_sec;
288 if ((s_usec) > (c_usec)) {
289 t_usec = 1000000L - (s_usec) + (c_usec);
292 t_usec = (c_usec) - (s_usec);
295 /*get total elapsed time*/
296 total_usec = (t_sec * 1000000UL) + t_usec;
298 t = usec - total_usec;
300 if (total_usec >= usec) {
304 /*this function does not work in precision*/
315 gst_avsysaudiosrc_delay (GstAudioSrc *asrc)
317 GstAvsysAudioSrc *avsys_audio = NULL;
321 avsys_audio = GST_AVSYS_AUDIO_SRC (asrc);
322 if(AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay))
331 gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
333 GstAvsysAudioSrc *src = NULL;
334 // gint getvalue = 0;
335 src = GST_AVSYS_AUDIO_SRC (object);
337 if (src->cached_caps == NULL)
341 case PROP_AUDIO_LATENCY:
342 src->latency = g_value_get_enum(value);
345 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
352 gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
354 GstAvsysAudioSrc *src;
356 src = GST_AVSYS_AUDIO_SRC (object);
360 case PROP_AUDIO_LATENCY:
361 g_value_set_enum(value, src->latency);
364 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
370 gst_avsysaudiosrc_init (GstAvsysAudioSrc * avsysaudiosrc, GstAvsysAudioSrcClass * g_class)
372 GST_DEBUG_OBJECT (avsysaudiosrc, "initializing");
374 avsysaudiosrc->cached_caps = NULL;
375 avsysaudiosrc->audio_handle = (avsys_handle_t)-1;
376 avsysaudiosrc->buffer_size = 0;
377 avsysaudiosrc->avsysaudio_lock = g_mutex_new ();
378 avsysaudiosrc->latency = DEFAULT_AUDIO_LATENCY;
381 #if defined(_USE_CAPS_)
383 gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc)
385 GstElementClass *element_class;
386 GstPadTemplate *pad_template;
387 GstAvsysAudioSrc *src;
388 GstCaps *caps = NULL;
390 src = GST_AVSYS_AUDIO_SRC (bsrc);
392 if(src->audio_handle==(avsys_handle_t)-1){
393 GST_DEBUG_OBJECT(src,"device not open, using template caps");
397 if (src->cached_caps)
399 GST_LOG_OBJECT (src, "Returning cached caps");
400 return gst_caps_ref(src->cached_caps);
402 element_class = GST_ELEMENT_GET_CLASS (src);
403 pad_template = gst_element_class_get_pad_template (element_class, "src");
404 g_return_val_if_fail (pad_template != NULL, NULL);
406 caps = gst_avsysaudiosrc_probe_supported_formats (GST_OBJECT (src), src->audio_handle,
407 gst_pad_template_get_caps (pad_template));
410 src->cached_caps = gst_caps_ref (caps);
413 GST_INFO_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
419 gst_avsysaudiosrc_open (GstAudioSrc * asrc)
425 avsysaudiosrc_parse_spec (GstAvsysAudioSrc *avsys_audio, GstRingBufferSpec * spec)
428 if (spec->type != GST_BUFTYPE_LINEAR ||
429 spec->channels > 2 || spec->channels < 1 ||
430 !(spec->format == GST_S8 || spec->format == GST_S16_LE) )
436 avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT;
437 avsys_audio->bytes_per_sample = 1;
440 avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT;
441 avsys_audio->bytes_per_sample = 2;
444 GST_DEBUG_OBJECT(avsys_audio, "Only support S8, S16LE format");
448 // set audio parameter for avsys audio open
450 switch(avsys_audio->latency)
452 case AVSYSAUDIOSRC_LATENCY_LOW:
453 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY;
455 case AVSYSAUDIOSRC_LATENCY_MID:
456 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT;
458 case AVSYSAUDIOSRC_LATENCY_HIGH:
459 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY;
465 avsys_audio->audio_param.priority = 0;
466 avsys_audio->audio_param.samplerate = spec->rate;
467 avsys_audio->audio_param.channels = spec->channels;
469 if(spec->channels == 2)
470 avsys_audio->bytes_per_sample *= 2;
471 else if(spec->channels > 2)
473 GST_ERROR_OBJECT(avsys_audio,"Unsupported channel number %d", spec->channels);
481 gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
483 GstAvsysAudioSrc *avsysaudiosrc = NULL;
484 guint p_time = 0, b_time = 0;
486 avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
488 if (!avsysaudiosrc_parse_spec(avsysaudiosrc, spec))
490 GST_ERROR("avsysaudiosrc_parse_spec failed");
495 if (!gst_avsysaudiosrc_avsys_open (avsysaudiosrc))
497 GST_ERROR("gst_avsysaudiosrc_avsys_open failed");
501 /* Ring buffer size */
502 if (AVSYS_STATE_SUCCESS ==
503 avsys_audio_get_period_buffer_time(avsysaudiosrc->audio_handle, &p_time, &b_time))
505 if(p_time == 0 || b_time == 0)
508 spec->latency_time = (guint64)p_time;
509 spec->buffer_time = (guint64)b_time;
515 spec->segsize = avsysaudiosrc->buffer_size;
516 spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0);
519 GST_INFO_OBJECT(avsysaudiosrc, "audio buffer spec : latency_time(%llu), buffer_time(%llu), segtotal(%d), segsize(%d)\n",
520 spec->latency_time, spec->buffer_time, spec->segtotal, spec->segsize);
527 gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc)
529 GstAvsysAudioSrc *avsysaudiosrc = NULL;
532 avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
535 GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
537 if(!gst_avsysaudiosrc_avsys_close(avsysaudiosrc))
539 GST_ERROR_OBJECT(avsysaudiosrc, "gst_avsysaudiosrc_avsys_close failed");
542 GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
550 gst_avsysaudiosrc_close (GstAudioSrc * asrc)
552 GstAvsysAudioSrc *avsysaudiosrc = NULL;
554 avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
555 gst_caps_replace (&avsysaudiosrc->cached_caps, NULL);
561 gst_avsysaudiosrc_reset (GstAudioSrc * asrc)
563 GstAvsysAudioSrc *avsys_audio = NULL;
565 avsys_audio = GST_AVSYS_AUDIO_SRC (asrc);
566 GST_AVSYS_AUDIO_SRC_LOCK (asrc);
568 if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle))
570 GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: ");
573 GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
579 static GstStateChangeReturn
580 gst_avsys_src_change_state (GstElement * element, GstStateChange transition)
582 GstAvsysAudioSrc *avsys = NULL;
583 GstStateChangeReturn ret ;
585 avsys = GST_AVSYS_AUDIO_SRC (element);
586 GST_DEBUG("gst_avsys_src_change_state");
590 case GST_STATE_CHANGE_NULL_TO_READY:
592 GST_DEBUG ("GST_STATE_CHANGE_NULL_TO_READY\n") ;
595 case GST_STATE_CHANGE_READY_TO_PAUSED:
597 GST_DEBUG ("GST_STATE_CHANGE_READY_TO_PAUSED\n") ;
600 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
602 GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_PLAYING\n") ;
604 if (!gst_avsysaudiosrc_avsys_start (avsys)) {
605 GST_ERROR("gst_avsysaudiosrc_avsys_start failed");
613 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
615 GST_DEBUG ("After parent_class->change_state...\n") ;
618 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
620 GST_DEBUG ("GST_STATE_CHANGE_PLAYING_TO_PAUSED\n") ;
622 if (!gst_avsysaudiosrc_avsys_stop (avsys)) {
623 GST_ERROR("gst_avsysaudiosrc_avsys_stop failed");
627 case GST_STATE_CHANGE_PAUSED_TO_READY:
629 GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_READY\n") ;
632 case GST_STATE_CHANGE_READY_TO_NULL:
634 GST_DEBUG ("GST_STATE_CHANGE_READY_TO_NULL\n") ;
647 gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
649 GstAvsysAudioSrc *avsysaudiosrc = NULL;
652 guint used_length = 0;
654 avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
658 GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
659 #if _ENABLE_FAKE_READ
660 readed = avsysaudiosrc->buffer_size;
661 memset (ptr, 10, avsysaudiosrc->buffer_size); /*maybe can't hear*/
662 fake_delay (1000000UL / g_delay_time);
665 readed = avsys_audio_read (avsysaudiosrc->audio_handle, ptr, length);
668 #endif //_ENABLE_FAKE_READ
669 GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
675 GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
676 return length; /* skip one period */
681 gst_avsysaudiosrc_avsys_cork (GstAvsysAudioSrc *avsysaudiosrc, int cork)
683 int avsys_result = avsys_audio_cork (avsysaudiosrc->audio_handle, cork);
684 if (avsys_result != AVSYS_STATE_SUCCESS) {
685 GST_ERROR_OBJECT(avsysaudiosrc, "avsys_audio_cork() error. [0x%x]\n", avsys_result);
692 gst_avsysaudiosrc_avsys_start (GstAvsysAudioSrc *avsysaudiosrc)
696 GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
697 result = gst_avsysaudiosrc_avsys_cork(avsysaudiosrc, CAPTURE_UNCORK);
698 GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
704 gst_avsysaudiosrc_avsys_stop (GstAvsysAudioSrc *avsysaudiosrc)
708 GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
709 result = gst_avsysaudiosrc_avsys_cork(avsysaudiosrc, CAPTURE_CORK);
710 GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
716 gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *avsysaudiosrc)
718 int avsys_result = 0;
720 GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
722 avsys_result = avsys_audio_open(&avsysaudiosrc->audio_param, &avsysaudiosrc->audio_handle, &avsysaudiosrc->buffer_size);
724 if (avsys_result != AVSYS_STATE_SUCCESS) {
725 GST_ERROR_OBJECT(avsysaudiosrc, "avsys_audio_open() error. [0x%x]\n", avsys_result);
726 GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
730 #if _ENABLE_FAKE_READ
731 g_delay_time = (unsigned long)((avsysaudiosrc->samplerate * (avsysaudiosrc->format / 8) * avsysaudiosrc->channels) / avsysaudiosrc->buffer_size);
734 GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
739 gst_avsysaudiosrc_avsys_close(GstAvsysAudioSrc *src)
743 if (src->audio_handle != (avsys_handle_t)-1)
745 /*close avsys audio*/
746 ret = avsys_audio_close (src->audio_handle);
749 GST_ERROR_OBJECT(src, "avsys_audio_close() error 0x%x", ret);
752 src->audio_handle = (avsys_handle_t)-1;
753 GST_DEBUG_OBJECT(src, "AVsys audio handle closed");
757 GST_WARNING_OBJECT(src,"avsys audio handle has already closed");
762 #if defined(_USE_CAPS_)
764 gst_avsysaudiosrc_detect_rates(GstObject *obj,
765 avsys_pcm_hw_params_t *hw_params, GstCaps *in_caps)
769 gint err, dir, min_rate, max_rate, i;
771 GST_LOG_OBJECT(obj, "probing sample rates ...");
773 if ((err = avsys_pcm_hw_params_get_rate_min(hw_params, &min, &dir)) < 0)
776 if ((err = avsys_pcm_hw_params_get_rate_max(hw_params, &max, &dir)) < 0)
782 if (min_rate < _MIN_RATE)
783 min_rate = _MIN_RATE; /* random 'sensible minimum' */
786 max_rate = _MAX_RATE; /* or maybe just use 192400 or so? */
787 else if (max_rate > 0 && max_rate < _MIN_RATE)
788 max_rate = MAX (_MIN_RATE, min_rate);
790 GST_DEBUG_OBJECT(obj, "Min. rate = %u (%d)", min_rate, min);
791 GST_DEBUG_OBJECT(obj, "Max. rate = %u (%d)", max_rate, max);
793 caps = gst_caps_make_writable(in_caps);
795 for (i = 0; i < gst_caps_get_size(caps); ++i)
799 s = gst_caps_get_structure(caps, i);
800 if (min_rate == max_rate)
802 gst_structure_set(s, "rate", G_TYPE_INT, min_rate, NULL);
806 gst_structure_set(s, "rate", GST_TYPE_INT_RANGE, min_rate,
815 GST_ERROR_OBJECT(obj, "failed to query minimum sample rate");
816 gst_caps_unref(in_caps);
821 GST_ERROR_OBJECT(obj, "failed to query maximum sample rate");
822 gst_caps_unref(in_caps);
829 gst_avsysaudiosrc_detect_formats(GstObject * obj,
830 avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps)
832 avsys_pcm_format_mask_t *mask;
837 avsys_pcm_format_mask_malloc(&mask);
838 avsys_pcm_hw_params_get_format_mask(hw_params, mask);
840 caps = gst_caps_new_empty();
842 for (i = 0; i < gst_caps_get_size(in_caps); ++i)
846 gint width = 0, depth = 0;
849 s = gst_caps_get_structure(in_caps, i);
850 if (!gst_structure_has_name(s, "audio/x-raw-int"))
852 GST_WARNING_OBJECT(obj, "skipping non-int format");
855 if (!gst_structure_get_int(s, "width", &width)
856 || !gst_structure_get_int(s, "depth", &depth))
859 GST_DEBUG_OBJECT(obj, "width = %d height = %d", width, depth);
861 sndformat = 0;//SND_PCM_FORMAT_S8
864 sndformat = 2; //SND_PCM_FORMAT_S16_LE
865 if (avsys_pcm_format_mask_test(mask, sndformat))
866 { //must be implemented
867 /* template contains { true, false } or just one, leave it as it is */
868 scopy = gst_structure_copy(s);
877 /* TODO: proper endianness detection, for now it's CPU endianness only */
878 gst_structure_set(scopy, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
879 gst_structure_set(scopy, "endianness", G_TYPE_INT, G_BYTE_ORDER,
881 gst_caps_append_structure(caps, scopy);
886 avsys_pcm_format_mask_free(mask);
887 gst_caps_unref(in_caps);
893 gst_avsysaudiosrc_detect_channels(GstObject * obj,
894 avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps)
898 gint err, min_channel, max_channel, i;
901 GST_LOG_OBJECT(obj, "probing sample rates ...");
903 if ((err = avsys_pcm_hw_params_get_channels_min(hw_params, &min)) < 0)
906 if ((err = avsys_pcm_hw_params_get_channels_max(hw_params, &max)) < 0)
912 if (min_channel < _MIN_CHANNEL)
913 min_channel = _MIN_CHANNEL; /* random 'sensible minimum' */
915 if (max_channel <= 0)
916 max_channel = _MAX_CHANNEL; /* or maybe just use 192400 or so? */
917 else if (max_channel > 0 && max_channel < _MIN_CHANNEL)
918 max_channel = MAX (_MAX_CHANNEL, min_channel);
920 GST_DEBUG_OBJECT(obj, "Min. channel = %u (%d)", min_channel, min);
921 GST_DEBUG_OBJECT(obj, "Max. channel = %u (%d)", max_channel, max);
923 caps = gst_caps_make_writable(in_caps);
925 for (i = 0; i < gst_caps_get_size(caps); ++i)
929 s = gst_caps_get_structure(caps, i);
930 if (min_channel == max_channel)
932 gst_structure_set(s, "channels", G_TYPE_INT, _MIN_CHANNEL, NULL);
936 gst_structure_set(s, "channels", GST_TYPE_INT_RANGE, min_channel,
946 GST_ERROR_OBJECT(obj, "failed to query minimum sample rate");
947 gst_caps_unref(in_caps);
952 GST_ERROR_OBJECT(obj, "failed to query maximum sample rate:");
953 gst_caps_unref(in_caps);
959 * gst_avsys_probe_supported_formats:
961 * Takes the template caps and returns the subset which is actually
962 * supported by this device.
967 gst_avsysaudiosrc_probe_supported_formats(GstObject * obj,
968 avsys_handle_t handle, const GstCaps * template_caps)
971 avsys_pcm_hw_params_t *hw_params;
975 avsys_pcm_hw_params_malloc(&hw_params);
976 if ((err = avsys_pcm_hw_params_any(handle, hw_params)) < 0)
979 caps = gst_caps_copy(template_caps);
981 if (!(caps = gst_avsysaudiosrc_detect_formats(obj, hw_params, caps)))
982 goto subroutine_error;
984 if (!(caps = gst_avsysaudiosrc_detect_rates(obj, hw_params, caps)))
985 goto subroutine_error;
987 if (!(caps = gst_avsysaudiosrc_detect_channels(obj, hw_params, caps)))
988 goto subroutine_error;
990 avsys_pcm_hw_params_free(hw_params);
996 GST_ERROR_OBJECT(obj, "failed to query formats");
1001 GST_ERROR_OBJECT(obj, "failed to query formats");