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,
85 gst_avsysaudiosrc_audio_latency_get_type (void)
87 static GType capture_audio_latency_type = 0;
88 static const GEnumValue capture_audio_latency[] = {
89 {AVSYSAUDIOSRC_LATENCY_LOW, "Set capture latency as low", "low"},
90 {AVSYSAUDIOSRC_LATENCY_MID, "Set capture latency as mid", "mid"},
91 {AVSYSAUDIOSRC_LATENCY_HIGH, "Set capture latency as high", "high"},
95 if (!capture_audio_latency_type) {
96 capture_audio_latency_type =
97 g_enum_register_static ("GstAvsysAudioSrcAudioLatency", capture_audio_latency);
99 return capture_audio_latency_type;
103 GST_BOILERPLATE (GstAvsysAudioSrc, gst_avsysaudiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC);
105 #if _ENABLE_FAKE_READ
106 static unsigned long fake_delay (unsigned long usec);
109 static guint gst_avsysaudiosrc_delay (GstAudioSrc *asrc);
111 static void gst_avsysaudiosrc_finalize (GObject * object);
112 static void gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
113 static void gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
115 static GstCaps* gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc);
117 static gboolean gst_avsysaudiosrc_open (GstAudioSrc * asrc);
118 static gboolean gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec);
119 static gboolean gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc);
120 static gboolean gst_avsysaudiosrc_close (GstAudioSrc * asrc);
121 static guint gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length);
122 static void gst_avsysaudiosrc_reset (GstAudioSrc * asrc);
123 static gboolean gst_avsysaudiosrc_avsys_close (GstAvsysAudioSrc *src);
124 static gboolean gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *src);
125 #if defined(_USE_CAPS_)
126 static GstCaps *gst_avsysaudiosrc_detect_rates (GstObject * obj, avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps);
127 static GstCaps *gst_avsysaudiosrc_detect_channels (GstObject * obj,avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps);
128 static GstCaps *gst_avsysaudiosrc_detect_formats (GstObject * obj,avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps);
129 static GstCaps *gst_avsysaudiosrc_probe_supported_formats (GstObject * obj, avsys_handle_t handle, const GstCaps * template_caps);
131 static GstStateChangeReturn gst_avsys_src_change_state (GstElement * element, GstStateChange transition) ;
135 /* AvsysAudioSrc signals and args */
140 # define AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS "LITTLE_ENDIAN"
142 static GstStaticPadTemplate avsysaudiosrc_src_factory =
143 GST_STATIC_PAD_TEMPLATE ("src",
148 "endianness = (int) { " AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS " }, "
149 "signed = (boolean) { TRUE }, "
152 "rate = (int) [ 8000, 48000 ], "
153 "channels = (int) [ 1, 2 ]; "
155 "signed = (boolean) { FALSE }, "
158 "rate = (int) [ 8000, 48000 ], "
159 "channels = (int) [ 1, 2 ]")
162 static inline guint _time_to_sample(GstAvsysAudioSrc *avsyssrc, GstClockTime diff)
165 // sample rate : asrc->audio_param.samplerate
166 result =(GST_TIME_AS_USECONDS(diff) * avsyssrc->audio_param.samplerate)/1000000;
172 gst_avsysaudiosrc_finalize (GObject * object)
174 GstAvsysAudioSrc *src = NULL;
177 src = GST_AVSYS_AUDIO_SRC (object);
178 g_mutex_free (src->avsysaudio_lock);
180 G_OBJECT_CLASS (parent_class)->finalize (object);
184 gst_avsysaudiosrc_base_init (gpointer g_class)
186 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
188 gst_element_class_set_details (element_class, &gst_avsysaudiosrc_details);
190 gst_element_class_add_pad_template (element_class,
191 gst_static_pad_template_get (&avsysaudiosrc_src_factory));
195 gst_avsysaudiosrc_class_init (GstAvsysAudioSrcClass * klass)
197 GObjectClass *gobject_class;
198 GstElementClass *gstelement_class;
199 GstBaseSrcClass *gstbasesrc_class;
200 GstBaseAudioSrcClass *gstbaseaudiosrc_class;
201 GstAudioSrcClass *gstaudiosrc_class;
203 gobject_class = (GObjectClass *) klass;
204 gstelement_class = (GstElementClass *) klass;
205 gstbasesrc_class = (GstBaseSrcClass *) klass;
206 gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
207 gstaudiosrc_class = (GstAudioSrcClass *) klass;
209 gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_avsys_src_change_state);
211 parent_class = g_type_class_peek_parent (klass);
213 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_finalize);
214 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_get_property);
215 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_set_property);
216 #if defined(_USE_CAPS_)
217 gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_getcaps);
219 gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_open);
220 gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_prepare);
221 gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_unprepare);
222 gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_close);
223 gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_read);
224 gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_delay);
225 gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_reset);
227 g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY,
228 g_param_spec_enum("latency", "Audio Latency",
230 GST_AVSYS_AUDIO_SRC_LATENCY, DEFAULT_AUDIO_LATENCY,
231 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
237 *@note useful range 0 - 1000000 microsecond
239 #if _ENABLE_FAKE_READ
241 fake_delay (unsigned long usec)
243 struct timeval s_time;
244 struct timeval c_time;
251 unsigned long total_usec = 0UL;
252 unsigned long t = 0UL;
260 if (gettimeofday ((struct timeval *)&s_time, NULL) == 0) {
261 s_sec = s_time.tv_sec;
262 s_usec = s_time.tv_usec;
269 if (gettimeofday ((struct timeval *)&c_time, NULL) == 0) {
270 c_sec = c_time.tv_sec;
271 c_usec = c_time.tv_usec;
277 t_sec = c_sec - s_sec;
280 if ((s_usec) > (c_usec)) {
281 t_usec = 1000000L - (s_usec) + (c_usec);
284 t_usec = (c_usec) - (s_usec);
287 /*get total elapsed time*/
288 total_usec = (t_sec * 1000000UL) + t_usec;
290 t = usec - total_usec;
292 if (total_usec >= usec) {
296 /*this function does not work in precision*/
307 gst_avsysaudiosrc_delay (GstAudioSrc *asrc)
309 GstAvsysAudioSrc *avsys_audio = NULL;
313 avsys_audio = GST_AVSYS_AUDIO_SRC (asrc);
314 if(AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay))
323 gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
325 GstAvsysAudioSrc *src = NULL;
326 // gint getvalue = 0;
327 src = GST_AVSYS_AUDIO_SRC (object);
329 if (src->cached_caps == NULL)
333 case PROP_AUDIO_LATENCY:
334 src->latency = g_value_get_enum(value);
337 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
344 gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
346 GstAvsysAudioSrc *src;
348 src = GST_AVSYS_AUDIO_SRC (object);
352 case PROP_AUDIO_LATENCY:
353 g_value_set_enum(value, src->latency);
356 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
362 gst_avsysaudiosrc_init (GstAvsysAudioSrc * avsysaudiosrc, GstAvsysAudioSrcClass * g_class)
364 GST_DEBUG_OBJECT (avsysaudiosrc, "initializing");
366 avsysaudiosrc->cached_caps = NULL;
367 avsysaudiosrc->audio_handle = (avsys_handle_t)-1;
368 avsysaudiosrc->buffer_size = 0;
369 avsysaudiosrc->avsysaudio_lock = g_mutex_new ();
370 avsysaudiosrc->latency = DEFAULT_AUDIO_LATENCY;
373 #if defined(_USE_CAPS_)
375 gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc)
377 GstElementClass *element_class;
378 GstPadTemplate *pad_template;
379 GstAvsysAudioSrc *src;
380 GstCaps *caps = NULL;
382 src = GST_AVSYS_AUDIO_SRC (bsrc);
384 if(src->audio_handle==(avsys_handle_t)-1){
385 GST_DEBUG_OBJECT(src,"device not open, using template caps");
389 if (src->cached_caps)
391 GST_LOG_OBJECT (src, "Returning cached caps");
392 return gst_caps_ref(src->cached_caps);
394 element_class = GST_ELEMENT_GET_CLASS (src);
395 pad_template = gst_element_class_get_pad_template (element_class, "src");
396 g_return_val_if_fail (pad_template != NULL, NULL);
398 caps = gst_avsysaudiosrc_probe_supported_formats (GST_OBJECT (src), src->audio_handle,
399 gst_pad_template_get_caps (pad_template));
402 src->cached_caps = gst_caps_ref (caps);
405 GST_INFO_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
411 gst_avsysaudiosrc_open (GstAudioSrc * asrc)
417 avsysaudiosrc_parse_spec (GstAvsysAudioSrc *avsys_audio, GstRingBufferSpec * spec)
420 if (spec->type != GST_BUFTYPE_LINEAR ||
421 spec->channels > 2 || spec->channels < 1 ||
422 !(spec->format == GST_S8 || spec->format == GST_S16_LE) )
428 avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT;
429 avsys_audio->bytes_per_sample = 1;
432 avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT;
433 avsys_audio->bytes_per_sample = 2;
436 GST_DEBUG_OBJECT(avsys_audio, "Only support S8, S16LE format");
440 // set audio parameter for avsys audio open
442 switch(avsys_audio->latency)
444 case AVSYSAUDIOSRC_LATENCY_LOW:
445 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY;
447 case AVSYSAUDIOSRC_LATENCY_MID:
448 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT;
450 case AVSYSAUDIOSRC_LATENCY_HIGH:
451 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY;
457 avsys_audio->audio_param.priority = 0;
458 avsys_audio->audio_param.samplerate = spec->rate;
459 avsys_audio->audio_param.channels = spec->channels;
461 if(spec->channels == 2)
462 avsys_audio->bytes_per_sample *= 2;
463 else if(spec->channels > 2)
465 GST_ERROR_OBJECT(avsys_audio,"Unsupported channel number %d", spec->channels);
473 gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
475 GstAvsysAudioSrc *avsysaudiosrc = NULL;
476 guint p_time = 0, b_time = 0;
477 // gint avsys_result = 0;
479 avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
481 if (!avsysaudiosrc_parse_spec(avsysaudiosrc, spec))
483 GST_ERROR("avsysaudiosrc_parse_spec failed");
486 //g_print("AVSYSAUDIOSRC :: avsysaudiosrc_parse_spec() success\n");
489 if (!gst_avsysaudiosrc_avsys_open (avsysaudiosrc))
491 GST_ERROR("gst_avsysaudiosrc_avsys_open failed");
495 /* Ring buffer size */
496 if (AVSYS_STATE_SUCCESS ==
497 avsys_audio_get_period_buffer_time(avsysaudiosrc->audio_handle, &p_time, &b_time))
499 if(p_time == 0 || b_time == 0)
502 spec->latency_time = (guint64)p_time;
503 spec->buffer_time = (guint64)b_time;
509 spec->segsize = avsysaudiosrc->buffer_size;
510 spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0);
513 GST_INFO_OBJECT(avsysaudiosrc, "audio buffer spec : latency_time(%llu), buffer_time(%llu), segtotal(%d), segsize(%d)\n",
514 spec->latency_time, spec->buffer_time, spec->segtotal, spec->segsize);
521 gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc)
523 GstAvsysAudioSrc *avsysaudiosrc = NULL;
526 avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
529 GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
531 if(!gst_avsysaudiosrc_avsys_close(avsysaudiosrc))
533 GST_ERROR_OBJECT(avsysaudiosrc, "gst_avsysaudiosrc_avsys_close failed");
536 GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
544 gst_avsysaudiosrc_close (GstAudioSrc * asrc)
546 GstAvsysAudioSrc *avsysaudiosrc = NULL;
548 avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
549 gst_caps_replace (&avsysaudiosrc->cached_caps, NULL);
555 gst_avsysaudiosrc_reset (GstAudioSrc * asrc)
557 GstAvsysAudioSrc *avsys_audio = NULL;
559 avsys_audio = GST_AVSYS_AUDIO_SRC (asrc);
560 GST_AVSYS_AUDIO_SRC_LOCK (asrc);
562 if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle))
564 GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: ");
567 GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
573 static GstStateChangeReturn
574 gst_avsys_src_change_state (GstElement * element, GstStateChange transition)
576 GstAvsysAudioSrc *avsys = NULL;
577 GstStateChangeReturn ret ;
579 avsys = GST_AVSYS_AUDIO_SRC (element);
580 GST_DEBUG("gst_avsys_src_change_state");
584 case GST_STATE_CHANGE_NULL_TO_READY:
586 GST_DEBUG ("GST_STATE_CHANGE_NULL_TO_READY\n") ;
589 case GST_STATE_CHANGE_READY_TO_PAUSED:
591 GST_DEBUG ("GST_STATE_CHANGE_READY_TO_PAUSED\n") ;
594 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
596 GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_PLAYING\n") ;
603 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
605 GST_DEBUG ("After parent_class->change_state...\n") ;
608 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
610 GST_DEBUG ("GST_STATE_CHANGE_PLAYING_TO_PAUSED\n") ;
613 case GST_STATE_CHANGE_PAUSED_TO_READY:
615 GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_READY\n") ;
618 case GST_STATE_CHANGE_READY_TO_NULL:
620 GST_DEBUG ("GST_STATE_CHANGE_READY_TO_NULL\n") ;
633 gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
635 GstAvsysAudioSrc *avsysaudiosrc = NULL;
638 guint used_length = 0;
640 avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
644 GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
645 #if _ENABLE_FAKE_READ
646 readed = avsysaudiosrc->buffer_size;
647 memset (ptr, 10, avsysaudiosrc->buffer_size); /*maybe can't hear*/
648 fake_delay (1000000UL / g_delay_time);
651 readed = avsys_audio_read (avsysaudiosrc->audio_handle, ptr, length);
654 #endif //_ENABLE_FAKE_READ
655 GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
661 GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
662 return length; /* skip one period */
667 gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *avsysaudiosrc)
669 int avsys_result = 0;
671 GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
673 avsys_result = avsys_audio_open(&avsysaudiosrc->audio_param, &avsysaudiosrc->audio_handle, &avsysaudiosrc->buffer_size);
675 if (avsys_result != AVSYS_STATE_SUCCESS) {
676 GST_ERROR_OBJECT(avsysaudiosrc, "avsys_audio_open() error. [0x%x]\n", avsys_result);
677 GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
681 #if _ENABLE_FAKE_READ
682 g_delay_time = (unsigned long)((avsysaudiosrc->samplerate * (avsysaudiosrc->format / 8) * avsysaudiosrc->channels) / avsysaudiosrc->buffer_size);
685 GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
690 gst_avsysaudiosrc_avsys_close(GstAvsysAudioSrc *src)
694 if (src->audio_handle != (avsys_handle_t)-1)
696 /*close avsys audio*/
697 ret = avsys_audio_close (src->audio_handle);
700 GST_ERROR_OBJECT(src, "avsys_audio_close() error 0x%x", ret);
703 src->audio_handle = (avsys_handle_t)-1;
704 GST_DEBUG_OBJECT(src, "AVsys audio handle closed");
708 GST_WARNING_OBJECT(src,"avsys audio handle has already closed");
713 #if defined(_USE_CAPS_)
715 gst_avsysaudiosrc_detect_rates(GstObject *obj,
716 avsys_pcm_hw_params_t *hw_params, GstCaps *in_caps)
720 gint err, dir, min_rate, max_rate, i;
722 GST_LOG_OBJECT(obj, "probing sample rates ...");
724 if ((err = avsys_pcm_hw_params_get_rate_min(hw_params, &min, &dir)) < 0)
727 if ((err = avsys_pcm_hw_params_get_rate_max(hw_params, &max, &dir)) < 0)
733 if (min_rate < _MIN_RATE)
734 min_rate = _MIN_RATE; /* random 'sensible minimum' */
737 max_rate = _MAX_RATE; /* or maybe just use 192400 or so? */
738 else if (max_rate > 0 && max_rate < _MIN_RATE)
739 max_rate = MAX (_MIN_RATE, min_rate);
741 GST_DEBUG_OBJECT(obj, "Min. rate = %u (%d)", min_rate, min);
742 GST_DEBUG_OBJECT(obj, "Max. rate = %u (%d)", max_rate, max);
744 caps = gst_caps_make_writable(in_caps);
746 for (i = 0; i < gst_caps_get_size(caps); ++i)
750 s = gst_caps_get_structure(caps, i);
751 if (min_rate == max_rate)
753 gst_structure_set(s, "rate", G_TYPE_INT, min_rate, NULL);
757 gst_structure_set(s, "rate", GST_TYPE_INT_RANGE, min_rate,
766 GST_ERROR_OBJECT(obj, "failed to query minimum sample rate");
767 gst_caps_unref(in_caps);
772 GST_ERROR_OBJECT(obj, "failed to query maximum sample rate");
773 gst_caps_unref(in_caps);
780 gst_avsysaudiosrc_detect_formats(GstObject * obj,
781 avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps)
783 avsys_pcm_format_mask_t *mask;
788 avsys_pcm_format_mask_malloc(&mask);
789 avsys_pcm_hw_params_get_format_mask(hw_params, mask);
791 caps = gst_caps_new_empty();
793 for (i = 0; i < gst_caps_get_size(in_caps); ++i)
797 gint width = 0, depth = 0;
800 s = gst_caps_get_structure(in_caps, i);
801 if (!gst_structure_has_name(s, "audio/x-raw-int"))
803 GST_WARNING_OBJECT(obj, "skipping non-int format");
806 if (!gst_structure_get_int(s, "width", &width)
807 || !gst_structure_get_int(s, "depth", &depth))
810 GST_DEBUG_OBJECT(obj, "width = %d height = %d", width, depth);
812 sndformat = 0;//SND_PCM_FORMAT_S8
815 sndformat = 2; //SND_PCM_FORMAT_S16_LE
816 if (avsys_pcm_format_mask_test(mask, sndformat))
817 { //must be implemented
818 /* template contains { true, false } or just one, leave it as it is */
819 scopy = gst_structure_copy(s);
828 /* TODO: proper endianness detection, for now it's CPU endianness only */
829 gst_structure_set(scopy, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
830 gst_structure_set(scopy, "endianness", G_TYPE_INT, G_BYTE_ORDER,
832 gst_caps_append_structure(caps, scopy);
837 avsys_pcm_format_mask_free(mask);
838 gst_caps_unref(in_caps);
844 gst_avsysaudiosrc_detect_channels(GstObject * obj,
845 avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps)
849 gint err, min_channel, max_channel, i;
852 GST_LOG_OBJECT(obj, "probing sample rates ...");
854 if ((err = avsys_pcm_hw_params_get_channels_min(hw_params, &min)) < 0)
857 if ((err = avsys_pcm_hw_params_get_channels_max(hw_params, &max)) < 0)
863 if (min_channel < _MIN_CHANNEL)
864 min_channel = _MIN_CHANNEL; /* random 'sensible minimum' */
866 if (max_channel <= 0)
867 max_channel = _MAX_CHANNEL; /* or maybe just use 192400 or so? */
868 else if (max_channel > 0 && max_channel < _MIN_CHANNEL)
869 max_channel = MAX (_MAX_CHANNEL, min_channel);
871 GST_DEBUG_OBJECT(obj, "Min. channel = %u (%d)", min_channel, min);
872 GST_DEBUG_OBJECT(obj, "Max. channel = %u (%d)", max_channel, max);
874 caps = gst_caps_make_writable(in_caps);
876 for (i = 0; i < gst_caps_get_size(caps); ++i)
880 s = gst_caps_get_structure(caps, i);
881 if (min_channel == max_channel)
883 gst_structure_set(s, "channels", G_TYPE_INT, _MIN_CHANNEL, NULL);
887 gst_structure_set(s, "channels", GST_TYPE_INT_RANGE, min_channel,
897 GST_ERROR_OBJECT(obj, "failed to query minimum sample rate");
898 gst_caps_unref(in_caps);
903 GST_ERROR_OBJECT(obj, "failed to query maximum sample rate:");
904 gst_caps_unref(in_caps);
910 * gst_avsys_probe_supported_formats:
912 * Takes the template caps and returns the subset which is actually
913 * supported by this device.
918 gst_avsysaudiosrc_probe_supported_formats(GstObject * obj,
919 avsys_handle_t handle, const GstCaps * template_caps)
922 avsys_pcm_hw_params_t *hw_params;
926 avsys_pcm_hw_params_malloc(&hw_params);
927 if ((err = avsys_pcm_hw_params_any(handle, hw_params)) < 0)
930 caps = gst_caps_copy(template_caps);
932 if (!(caps = gst_avsysaudiosrc_detect_formats(obj, hw_params, caps)))
933 goto subroutine_error;
935 if (!(caps = gst_avsysaudiosrc_detect_rates(obj, hw_params, caps)))
936 goto subroutine_error;
938 if (!(caps = gst_avsysaudiosrc_detect_channels(obj, hw_params, caps)))
939 goto subroutine_error;
941 avsys_pcm_hw_params_free(hw_params);
947 GST_ERROR_OBJECT(obj, "failed to query formats");
952 GST_ERROR_OBJECT(obj, "failed to query formats");