11a0bc150c6f35fd2301d3d6d197cf6375c476d3
[framework/multimedia/gst-plugins-ext0.10.git] / avsystem / src / gstavsysaudiosrc.c
1 /*
2  * avsystem
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>
7  *
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)
11  * any later version.
12  *
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.
17  *
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
21  *
22  */
23
24 #include <sys/ioctl.h>
25 #include <fcntl.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <string.h>
29
30 #include <gst/gst.h>
31 #include <gst/gstutils.h>
32 //#include <mm_debug.h>
33
34 #include <sys/time.h>   /*gettimeofday*/
35 #include <unistd.h>
36
37 #include "gstavsysaudiosrc.h"
38
39 /**
40  * Define for Release
41  *
42  * _ENABLE_FAKE_READ:           enable fake read instead of avsys_audio_read(). (default: 0)
43  */
44 #define _ENABLE_FAKE_READ               0
45 //#define       USE_GPT8
46
47
48 #define _MIN_RATE               8000
49 #define _MAX_RATE               48000
50 #define _MIN_CHANNEL            1
51 #define _MAX_CHANNEL            2
52
53
54 #define DEFAULT_GPT8_FREQ 26
55
56 #if _ENABLE_FAKE_READ
57 static long g_delay_time;
58 #endif
59
60 #define DEFAULT_MEDIACALL_MODE  AVSYS_AUDIO_ECHO_MODE_NONE
61 #define DEFAULT_AUDIO_LATENCY   AVSYSAUDIOSRC_LATENCY_MID
62
63 GST_DEBUG_CATEGORY_EXTERN (avsystem_src_debug);
64 #define GST_CAT_DEFAULT avsystem_src_debug
65
66 /* elementfactory information */
67 static const GstElementDetails gst_avsysaudiosrc_details =
68         GST_ELEMENT_DETAILS ("AV system source",
69                                                  "Source/Audio",
70                                                  "Read from a AV system audio in",
71                                                  "Samsung Electronics co., ltd.");
72
73
74 enum {
75         PROP_0,
76 #if 0
77 #if !defined(I386_SIMULATOR)
78     PROP_AUDIO_MEDIA_CALL,
79 #endif
80 #endif
81     PROP_AUDIO_LATENCY,
82 };
83
84 GType
85 gst_avsysaudiosrc_audio_latency_get_type (void)
86 {
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"},
92     {0, NULL, NULL},
93   };
94
95   if (!capture_audio_latency_type) {
96           capture_audio_latency_type =
97         g_enum_register_static ("GstAvsysAudioSrcAudioLatency", capture_audio_latency);
98   }
99   return capture_audio_latency_type;
100 }
101
102
103 GST_BOILERPLATE (GstAvsysAudioSrc, gst_avsysaudiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC);
104
105 #if _ENABLE_FAKE_READ
106 static unsigned long    fake_delay (unsigned long usec);
107 #endif
108
109 static guint gst_avsysaudiosrc_delay (GstAudioSrc *asrc);
110
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);
114
115 static GstCaps* gst_avsysaudiosrc_getcaps       (GstBaseSrc * bsrc);
116
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);
130 #endif
131 static GstStateChangeReturn gst_avsys_src_change_state (GstElement * element, GstStateChange transition) ;
132
133
134
135 /* AvsysAudioSrc signals and args */
136 enum {
137         LAST_SIGNAL
138 };
139
140 # define AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS   "LITTLE_ENDIAN"
141
142 static GstStaticPadTemplate avsysaudiosrc_src_factory =
143         GST_STATIC_PAD_TEMPLATE ("src",
144                                                                 GST_PAD_SRC,
145                                                                 GST_PAD_ALWAYS,
146                                                                 GST_STATIC_CAPS (
147                                                                         "audio/x-raw-int, "
148                                                                         "endianness = (int) { " AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS " }, "
149                              "signed = (boolean) { TRUE }, "
150                                                                         "width = (int) 16, "
151                                                                         "depth = (int) 16, "
152                              "rate = (int) [ 8000, 48000 ], "
153                              "channels = (int) [ 1, 2 ]; "
154                                                                         "audio/x-raw-int, "
155                              "signed = (boolean) { FALSE }, "
156                                                                         "width = (int) 8, "
157                                                                         "depth = (int) 8, "
158                              "rate = (int) [ 8000, 48000 ], "
159                              "channels = (int) [ 1, 2 ]")
160                                                         );
161
162 static inline guint _time_to_sample(GstAvsysAudioSrc *avsyssrc,  GstClockTime diff)
163 {
164         guint result = 0;
165         // sample rate : asrc->audio_param.samplerate
166         result =(GST_TIME_AS_USECONDS(diff) * avsyssrc->audio_param.samplerate)/1000000;
167         return result;
168 }
169
170
171 static void
172 gst_avsysaudiosrc_finalize (GObject * object)
173 {
174     GstAvsysAudioSrc *src = NULL;
175
176
177     src = GST_AVSYS_AUDIO_SRC (object);
178         g_mutex_free (src->avsysaudio_lock);
179
180         G_OBJECT_CLASS (parent_class)->finalize (object);
181 }
182
183 static void
184 gst_avsysaudiosrc_base_init (gpointer g_class)
185 {
186         GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
187
188         gst_element_class_set_details (element_class, &gst_avsysaudiosrc_details);
189
190         gst_element_class_add_pad_template (element_class,
191                                                                                 gst_static_pad_template_get (&avsysaudiosrc_src_factory));
192 }
193
194 static void
195 gst_avsysaudiosrc_class_init (GstAvsysAudioSrcClass * klass)
196 {
197         GObjectClass *gobject_class;
198         GstElementClass *gstelement_class;
199         GstBaseSrcClass *gstbasesrc_class;
200         GstBaseAudioSrcClass *gstbaseaudiosrc_class;
201         GstAudioSrcClass *gstaudiosrc_class;
202
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;
208
209         gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_avsys_src_change_state);
210
211     parent_class = g_type_class_peek_parent (klass);
212
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);
218 #endif
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);
226
227         g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY,
228                         g_param_spec_enum("latency", "Audio Latency",
229                                         "Audio latency",
230                                         GST_AVSYS_AUDIO_SRC_LATENCY, DEFAULT_AUDIO_LATENCY,
231                                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
232 }
233
234
235
236 /**
237  *@note useful range 0 - 1000000 microsecond
238  */
239 #if _ENABLE_FAKE_READ
240 static unsigned long
241 fake_delay (unsigned long usec)
242 {
243         struct timeval s_time;
244         struct timeval c_time;
245         long s_sec  = 0L;
246         long s_usec = 0L;
247         long c_sec  = 0L;
248         long c_usec = 0L;
249         long t_sec  = 0L;
250         long t_usec = 0L;
251         unsigned long total_usec = 0UL;
252         unsigned long t = 0UL;
253
254         if (usec == 0UL) {
255                 usleep (0);
256                 return 0;
257         }
258
259         /*get start time*/
260         if (gettimeofday ((struct timeval *)&s_time, NULL) == 0) {
261                 s_sec  = s_time.tv_sec;
262                 s_usec = s_time.tv_usec;
263         } else {
264                 return 0;
265         }
266
267         for (;;) {
268                 /*get current time*/
269                 if (gettimeofday ((struct timeval *)&c_time, NULL) == 0) {
270                         c_sec  = c_time.tv_sec;
271                         c_usec = c_time.tv_usec;
272                 } else {
273                         return 0;
274                 }
275
276                 /*get elasped sec*/
277                 t_sec = c_sec - s_sec;
278
279                 /*get elapsed usec*/
280                 if ((s_usec) > (c_usec)) {
281                         t_usec = 1000000L - (s_usec) + (c_usec);
282                         t_sec--;
283                 } else {
284                         t_usec = (c_usec) - (s_usec);
285                 }
286
287                 /*get total elapsed time*/
288                 total_usec = (t_sec * 1000000UL) + t_usec;
289
290                 t = usec - total_usec;
291
292                 if (total_usec >= usec) {
293                         break;
294                 } else {
295                         if (t > 10000UL) {
296                                 /*this function does not work in precision*/
297                                 usleep (1);
298                         }
299                 }
300         }
301
302         return total_usec;
303 }
304 #endif
305
306 static guint
307 gst_avsysaudiosrc_delay (GstAudioSrc *asrc)
308 {
309         GstAvsysAudioSrc        *avsys_audio = NULL;
310         int                                     delay;
311         guint                           retValue = 0;
312
313         avsys_audio = GST_AVSYS_AUDIO_SRC (asrc);
314         if(AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay))
315                 retValue = delay;
316
317         return retValue;
318 }
319
320
321
322 static void
323 gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
324 {
325     GstAvsysAudioSrc *src = NULL;
326 //    gint                      getvalue = 0;
327         src = GST_AVSYS_AUDIO_SRC (object);
328
329         if (src->cached_caps == NULL)
330         {
331                 switch (prop_id)
332                 {
333         case PROP_AUDIO_LATENCY:
334                 src->latency = g_value_get_enum(value);
335                         break;
336         default:
337                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
338                 break;
339                 }
340         }
341 }
342
343 static void
344 gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
345 {
346         GstAvsysAudioSrc *src;
347
348         src = GST_AVSYS_AUDIO_SRC (object);
349
350     switch (prop_id)
351     {
352         case PROP_AUDIO_LATENCY:
353                 g_value_set_enum(value, src->latency);
354                 break;
355         default:
356                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
357                 break;
358         }
359 }
360
361 static void
362 gst_avsysaudiosrc_init (GstAvsysAudioSrc * avsysaudiosrc, GstAvsysAudioSrcClass * g_class)
363 {
364         GST_DEBUG_OBJECT (avsysaudiosrc, "initializing");
365
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;
371 }
372
373 #if defined(_USE_CAPS_)
374 static GstCaps *
375 gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc)
376 {
377     GstElementClass *element_class;
378     GstPadTemplate *pad_template;
379         GstAvsysAudioSrc *src;
380     GstCaps *caps = NULL;
381
382         src = GST_AVSYS_AUDIO_SRC (bsrc);
383
384     if(src->audio_handle==(avsys_handle_t)-1){
385         GST_DEBUG_OBJECT(src,"device not open, using template caps");
386         return NULL;
387     }
388
389     if (src->cached_caps)
390         {
391                 GST_LOG_OBJECT (src, "Returning cached caps");
392             return gst_caps_ref(src->cached_caps);
393         }
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);
397
398         caps = gst_avsysaudiosrc_probe_supported_formats (GST_OBJECT (src), src->audio_handle,
399                                                                                                         gst_pad_template_get_caps (pad_template));
400
401         if (caps) {
402                 src->cached_caps = gst_caps_ref (caps);
403         }
404
405         GST_INFO_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
406
407         return caps;
408 }
409 #endif
410 static gboolean
411 gst_avsysaudiosrc_open (GstAudioSrc * asrc)
412 {
413         return TRUE;
414 }
415
416 static gboolean
417 avsysaudiosrc_parse_spec (GstAvsysAudioSrc *avsys_audio, GstRingBufferSpec * spec)
418 {
419     /* Check param */
420     if (spec->type != GST_BUFTYPE_LINEAR ||
421         spec->channels > 2 || spec->channels < 1 ||
422         !(spec->format == GST_S8 || spec->format == GST_S16_LE) )
423         return FALSE;
424
425     switch(spec->format)
426     {
427     case GST_S8:
428         avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT;
429         avsys_audio->bytes_per_sample = 1;
430         break;
431     case GST_S16_LE:
432         avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT;
433         avsys_audio->bytes_per_sample = 2;
434         break;
435     default:
436         GST_DEBUG_OBJECT(avsys_audio, "Only support S8, S16LE format");
437         return FALSE;
438     }
439
440     // set audio parameter for avsys audio open
441
442         switch(avsys_audio->latency)
443         {
444         case AVSYSAUDIOSRC_LATENCY_LOW:
445                 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY;
446                 break;
447         case AVSYSAUDIOSRC_LATENCY_MID:
448                 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT;
449                 break;
450         case AVSYSAUDIOSRC_LATENCY_HIGH:
451                 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY;
452                 break;
453         default:
454                 break;
455         }
456
457     avsys_audio->audio_param.priority = 0;
458     avsys_audio->audio_param.samplerate = spec->rate;
459     avsys_audio->audio_param.channels = spec->channels;
460
461     if(spec->channels == 2)
462         avsys_audio->bytes_per_sample *= 2;
463     else if(spec->channels > 2)
464     {
465         GST_ERROR_OBJECT(avsys_audio,"Unsupported channel number %d", spec->channels);
466         return FALSE;
467     }
468
469     return TRUE;
470 }
471
472 static gboolean
473 gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
474 {
475     GstAvsysAudioSrc *avsysaudiosrc = NULL;
476         guint   p_time = 0, b_time = 0;
477 //      gint    avsys_result = 0;
478
479         avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
480
481     if (!avsysaudiosrc_parse_spec(avsysaudiosrc, spec))
482     {
483         GST_ERROR("avsysaudiosrc_parse_spec failed");
484         return FALSE;
485     }
486     //g_print("AVSYSAUDIOSRC :: avsysaudiosrc_parse_spec() success\n");
487
488         /*open avsys audio*/
489     if (!gst_avsysaudiosrc_avsys_open (avsysaudiosrc))
490     {
491         GST_ERROR("gst_avsysaudiosrc_avsys_open failed");
492         return FALSE;
493     }
494
495     /* Ring buffer size */
496     if (AVSYS_STATE_SUCCESS ==
497         avsys_audio_get_period_buffer_time(avsysaudiosrc->audio_handle, &p_time, &b_time))
498      {
499         if(p_time == 0 || b_time == 0)
500                 return FALSE;
501
502         spec->latency_time = (guint64)p_time;
503         spec->buffer_time = (guint64)b_time;
504         }
505         else
506         {
507          return FALSE;
508         }
509         spec->segsize = avsysaudiosrc->buffer_size;
510         spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0);
511         spec->segtotal += 2;
512
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);
515
516
517     return TRUE;
518 }
519
520 static gboolean
521 gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc)
522 {
523     GstAvsysAudioSrc *avsysaudiosrc = NULL;
524     gboolean ret = TRUE;
525
526     avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
527
528     /*close*/
529     GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
530
531     if(!gst_avsysaudiosrc_avsys_close(avsysaudiosrc))
532     {
533         GST_ERROR_OBJECT(avsysaudiosrc, "gst_avsysaudiosrc_avsys_close failed");
534         ret = FALSE;
535     }
536     GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
537
538
539
540         return ret;
541 }
542
543 static gboolean
544 gst_avsysaudiosrc_close (GstAudioSrc * asrc)
545 {
546     GstAvsysAudioSrc *avsysaudiosrc = NULL;
547
548     avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
549         gst_caps_replace (&avsysaudiosrc->cached_caps, NULL);
550
551         return TRUE;
552 }
553
554 static void
555 gst_avsysaudiosrc_reset (GstAudioSrc * asrc)
556 {
557         GstAvsysAudioSrc *avsys_audio = NULL;
558
559     avsys_audio = GST_AVSYS_AUDIO_SRC (asrc);
560     GST_AVSYS_AUDIO_SRC_LOCK (asrc);
561
562     if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle))
563     {
564         GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: ");
565     }
566
567     GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
568
569     return;
570 }
571
572
573 static GstStateChangeReturn
574 gst_avsys_src_change_state (GstElement * element, GstStateChange transition)
575 {
576         GstAvsysAudioSrc *avsys = NULL;
577         GstStateChangeReturn ret ;
578
579         avsys = GST_AVSYS_AUDIO_SRC (element);
580         GST_DEBUG("gst_avsys_src_change_state");
581
582         switch (transition)
583         {
584                 case GST_STATE_CHANGE_NULL_TO_READY:
585                 {
586                         GST_DEBUG ("GST_STATE_CHANGE_NULL_TO_READY\n") ;
587                         break ;
588                 }
589                 case GST_STATE_CHANGE_READY_TO_PAUSED:
590                 {
591                         GST_DEBUG ("GST_STATE_CHANGE_READY_TO_PAUSED\n") ;
592                         break ;
593                 }
594                 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
595                 {
596                         GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_PLAYING\n") ;
597                         break ;
598                 }
599                 default:
600                         break ;
601         }
602
603         ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
604
605         GST_DEBUG ("After parent_class->change_state...\n") ;
606         switch (transition)
607         {
608                 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
609                 {
610                         GST_DEBUG ("GST_STATE_CHANGE_PLAYING_TO_PAUSED\n") ;
611                         break ;
612                 }
613                 case GST_STATE_CHANGE_PAUSED_TO_READY:
614                 {
615                         GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_READY\n") ;
616                         break ;
617                 }
618                 case GST_STATE_CHANGE_READY_TO_NULL:
619                 {
620                         GST_DEBUG ("GST_STATE_CHANGE_READY_TO_NULL\n") ;
621                         break ;
622                 }
623                 default:
624                         break ;
625         }
626
627         return ret;
628 }
629
630
631
632 static guint
633 gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
634 {
635     GstAvsysAudioSrc    *avsysaudiosrc = NULL;
636         gint                            readed = 0;
637         gpointer                        ptr = NULL;
638         guint                           used_length = 0;
639
640         avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
641
642         ptr = data;
643
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);
649 #else
650         ptr = data;
651         readed = avsys_audio_read (avsysaudiosrc->audio_handle, ptr, length);
652         if (readed < 0)
653                 goto _READ_ERROR;
654 #endif //_ENABLE_FAKE_READ
655         GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
656
657         return readed;
658
659 _READ_ERROR:
660         {
661                 GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
662                 return length;  /* skip one period */
663         }
664 }
665
666 static gboolean
667 gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *avsysaudiosrc)
668 {
669         int avsys_result = 0;
670
671         GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
672
673         avsys_result = avsys_audio_open(&avsysaudiosrc->audio_param, &avsysaudiosrc->audio_handle, &avsysaudiosrc->buffer_size);
674
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);
678                 return FALSE;
679         }
680
681 #if _ENABLE_FAKE_READ
682         g_delay_time = (unsigned long)((avsysaudiosrc->samplerate * (avsysaudiosrc->format / 8) * avsysaudiosrc->channels) / avsysaudiosrc->buffer_size);
683 #endif
684
685         GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
686         return TRUE;
687 }
688
689 static gboolean
690 gst_avsysaudiosrc_avsys_close(GstAvsysAudioSrc *src)
691 {
692         int ret;
693
694     if (src->audio_handle != (avsys_handle_t)-1)
695     {
696                 /*close avsys audio*/
697                 ret = avsys_audio_close (src->audio_handle);
698         if (AVSYS_FAIL(ret))
699         {
700                 GST_ERROR_OBJECT(src, "avsys_audio_close() error 0x%x", ret);
701                         return FALSE;
702                 }
703         src->audio_handle = (avsys_handle_t)-1;
704         GST_DEBUG_OBJECT(src, "AVsys audio handle closed");
705         }
706     else
707     {
708         GST_WARNING_OBJECT(src,"avsys audio handle has already closed");
709     }
710
711         return TRUE;
712 }
713 #if defined(_USE_CAPS_)
714 static GstCaps *
715 gst_avsysaudiosrc_detect_rates(GstObject *obj,
716                 avsys_pcm_hw_params_t *hw_params, GstCaps *in_caps)
717 {
718         GstCaps *caps;
719         guint min, max;
720         gint err, dir, min_rate, max_rate, i;
721
722         GST_LOG_OBJECT(obj, "probing sample rates ...");
723
724         if ((err = avsys_pcm_hw_params_get_rate_min(hw_params, &min, &dir)) < 0)
725                 goto min_rate_err;
726
727         if ((err = avsys_pcm_hw_params_get_rate_max(hw_params, &max, &dir)) < 0)
728                 goto max_rate_err;
729
730         min_rate = min;
731         max_rate = max;
732
733         if (min_rate < _MIN_RATE)
734                 min_rate = _MIN_RATE; /* random 'sensible minimum' */
735
736         if (max_rate <= 0)
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);
740
741         GST_DEBUG_OBJECT(obj, "Min. rate = %u (%d)", min_rate, min);
742         GST_DEBUG_OBJECT(obj, "Max. rate = %u (%d)", max_rate, max);
743
744         caps = gst_caps_make_writable(in_caps);
745
746         for (i = 0; i < gst_caps_get_size(caps); ++i)
747         {
748                 GstStructure *s;
749
750                 s = gst_caps_get_structure(caps, i);
751                 if (min_rate == max_rate)
752                 {
753                         gst_structure_set(s, "rate", G_TYPE_INT, min_rate, NULL);
754                 }
755                 else
756                 {
757                         gst_structure_set(s, "rate", GST_TYPE_INT_RANGE, min_rate,
758                                         max_rate, NULL);
759                 }
760         }
761
762         return caps;
763         /* ERRORS */
764         min_rate_err:
765         {
766                 GST_ERROR_OBJECT(obj, "failed to query minimum sample rate");
767                 gst_caps_unref(in_caps);
768                 return NULL;
769         }
770         max_rate_err:
771         {
772                 GST_ERROR_OBJECT(obj, "failed to query maximum sample rate");
773                 gst_caps_unref(in_caps);
774                 return NULL;
775         }
776 }
777
778
779 static GstCaps *
780 gst_avsysaudiosrc_detect_formats(GstObject * obj,
781                 avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps)
782 {
783         avsys_pcm_format_mask_t *mask;
784         GstStructure *s;
785         GstCaps *caps;
786         gint i;
787
788         avsys_pcm_format_mask_malloc(&mask);
789         avsys_pcm_hw_params_get_format_mask(hw_params, mask);
790
791         caps = gst_caps_new_empty();
792
793         for (i = 0; i < gst_caps_get_size(in_caps); ++i)
794         {
795                 GstStructure *scopy;
796                 //gint w;
797                 gint width = 0, depth = 0;
798                 gint sndformat;
799
800                 s = gst_caps_get_structure(in_caps, i);
801                 if (!gst_structure_has_name(s, "audio/x-raw-int"))
802                 {
803                         GST_WARNING_OBJECT(obj, "skipping non-int format");
804                         continue;
805                 }
806                 if (!gst_structure_get_int(s, "width", &width)
807                                 || !gst_structure_get_int(s, "depth", &depth))
808                         continue;
809
810                 GST_DEBUG_OBJECT(obj, "width = %d height = %d", width, depth);
811                 if (width == 8)
812                         sndformat = 0;//SND_PCM_FORMAT_S8
813                 else
814                         //width==16
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);
820
821                 }
822                 else
823                 {
824                         scopy = NULL;
825                 }
826                 if (scopy)
827                 {
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,
831                                         NULL);
832                         gst_caps_append_structure(caps, scopy);
833                 }
834
835         }
836
837         avsys_pcm_format_mask_free(mask);
838         gst_caps_unref(in_caps);
839         return caps;
840 }
841
842
843 static GstCaps *
844 gst_avsysaudiosrc_detect_channels(GstObject * obj,
845                 avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps)
846 {
847         GstCaps *caps;
848         guint min, max;
849         gint err, min_channel, max_channel, i;
850 //      gint dir;
851
852         GST_LOG_OBJECT(obj, "probing sample rates ...");
853
854         if ((err = avsys_pcm_hw_params_get_channels_min(hw_params, &min)) < 0)
855                 goto min_chan_err;
856
857         if ((err = avsys_pcm_hw_params_get_channels_max(hw_params, &max)) < 0)
858                 goto max_chan_err;
859
860         min_channel = min;
861         max_channel = max;
862
863         if (min_channel < _MIN_CHANNEL)
864                 min_channel = _MIN_CHANNEL; /* random 'sensible minimum' */
865
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);
870
871         GST_DEBUG_OBJECT(obj, "Min. channel = %u (%d)", min_channel, min);
872         GST_DEBUG_OBJECT(obj, "Max. channel = %u (%d)", max_channel, max);
873
874         caps = gst_caps_make_writable(in_caps);
875
876         for (i = 0; i < gst_caps_get_size(caps); ++i)
877         {
878                 GstStructure *s;
879
880                 s = gst_caps_get_structure(caps, i);
881                 if (min_channel == max_channel)
882                 {
883                         gst_structure_set(s, "channels", G_TYPE_INT, _MIN_CHANNEL, NULL);
884                 }
885                 else
886                 {
887                         gst_structure_set(s, "channels", GST_TYPE_INT_RANGE, min_channel,
888                                         max_channel, NULL);
889                 }
890         }
891
892         return caps;
893
894         /* ERRORS */
895         min_chan_err:
896         {
897                 GST_ERROR_OBJECT(obj, "failed to query minimum sample rate");
898                 gst_caps_unref(in_caps);
899                 return NULL;
900         }
901         max_chan_err:
902         {
903                 GST_ERROR_OBJECT(obj, "failed to query maximum sample rate:");
904                 gst_caps_unref(in_caps);
905                 return NULL;
906         }
907 }
908
909 /*
910  * gst_avsys_probe_supported_formats:
911  *
912  * Takes the template caps and returns the subset which is actually
913  * supported by this device.
914  *
915  */
916
917 static GstCaps *
918 gst_avsysaudiosrc_probe_supported_formats(GstObject * obj,
919                 avsys_handle_t handle, const GstCaps * template_caps)
920 {
921
922         avsys_pcm_hw_params_t *hw_params;
923         GstCaps *caps;
924         gint err;
925
926         avsys_pcm_hw_params_malloc(&hw_params);
927         if ((err = avsys_pcm_hw_params_any(handle, hw_params)) < 0)
928                 goto error;
929
930         caps = gst_caps_copy(template_caps);
931
932         if (!(caps = gst_avsysaudiosrc_detect_formats(obj, hw_params, caps)))
933                 goto subroutine_error;
934
935         if (!(caps = gst_avsysaudiosrc_detect_rates(obj, hw_params, caps)))
936                 goto subroutine_error;
937
938         if (!(caps = gst_avsysaudiosrc_detect_channels(obj, hw_params, caps)))
939                 goto subroutine_error;
940
941         avsys_pcm_hw_params_free(hw_params);
942         return caps;
943
944         /* ERRORS */
945         error:
946         {
947                 GST_ERROR_OBJECT(obj, "failed to query formats");
948                 return NULL;
949         }
950         subroutine_error:
951         {
952                 GST_ERROR_OBJECT(obj, "failed to query formats");
953                 return NULL;
954         }
955 }
956 #endif