tizen 2.0 init
[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 enum {
85         CAPTURE_UNCORK = 0,
86         CAPTURE_CORK,
87 };
88
89 GType
90 gst_avsysaudiosrc_audio_latency_get_type (void)
91 {
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"},
97     {0, NULL, NULL},
98   };
99
100   if (!capture_audio_latency_type) {
101           capture_audio_latency_type =
102         g_enum_register_static ("GstAvsysAudioSrcAudioLatency", capture_audio_latency);
103   }
104   return capture_audio_latency_type;
105 }
106
107
108 GST_BOILERPLATE (GstAvsysAudioSrc, gst_avsysaudiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC);
109
110 #if _ENABLE_FAKE_READ
111 static unsigned long    fake_delay (unsigned long usec);
112 #endif
113
114 static guint gst_avsysaudiosrc_delay (GstAudioSrc *asrc);
115
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);
119
120 static GstCaps* gst_avsysaudiosrc_getcaps       (GstBaseSrc * bsrc);
121
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);
138 #endif
139 static GstStateChangeReturn gst_avsys_src_change_state (GstElement * element, GstStateChange transition) ;
140
141
142
143 /* AvsysAudioSrc signals and args */
144 enum {
145         LAST_SIGNAL
146 };
147
148 # define AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS   "LITTLE_ENDIAN"
149
150 static GstStaticPadTemplate avsysaudiosrc_src_factory =
151         GST_STATIC_PAD_TEMPLATE ("src",
152                                                                 GST_PAD_SRC,
153                                                                 GST_PAD_ALWAYS,
154                                                                 GST_STATIC_CAPS (
155                                                                         "audio/x-raw-int, "
156                                                                         "endianness = (int) { " AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS " }, "
157                              "signed = (boolean) { TRUE }, "
158                                                                         "width = (int) 16, "
159                                                                         "depth = (int) 16, "
160                              "rate = (int) [ 8000, 48000 ], "
161                              "channels = (int) [ 1, 2 ]; "
162                                                                         "audio/x-raw-int, "
163                              "signed = (boolean) { FALSE }, "
164                                                                         "width = (int) 8, "
165                                                                         "depth = (int) 8, "
166                              "rate = (int) [ 8000, 48000 ], "
167                              "channels = (int) [ 1, 2 ]")
168                                                         );
169
170 static inline guint _time_to_sample(GstAvsysAudioSrc *avsyssrc,  GstClockTime diff)
171 {
172         guint result = 0;
173         // sample rate : asrc->audio_param.samplerate
174         result =(GST_TIME_AS_USECONDS(diff) * avsyssrc->audio_param.samplerate)/1000000;
175         return result;
176 }
177
178
179 static void
180 gst_avsysaudiosrc_finalize (GObject * object)
181 {
182     GstAvsysAudioSrc *src = NULL;
183
184
185     src = GST_AVSYS_AUDIO_SRC (object);
186         g_mutex_free (src->avsysaudio_lock);
187
188         G_OBJECT_CLASS (parent_class)->finalize (object);
189 }
190
191 static void
192 gst_avsysaudiosrc_base_init (gpointer g_class)
193 {
194         GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
195
196         gst_element_class_set_details (element_class, &gst_avsysaudiosrc_details);
197
198         gst_element_class_add_pad_template (element_class,
199                                                                                 gst_static_pad_template_get (&avsysaudiosrc_src_factory));
200 }
201
202 static void
203 gst_avsysaudiosrc_class_init (GstAvsysAudioSrcClass * klass)
204 {
205         GObjectClass *gobject_class;
206         GstElementClass *gstelement_class;
207         GstBaseSrcClass *gstbasesrc_class;
208         GstBaseAudioSrcClass *gstbaseaudiosrc_class;
209         GstAudioSrcClass *gstaudiosrc_class;
210
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;
216
217         gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_avsys_src_change_state);
218
219     parent_class = g_type_class_peek_parent (klass);
220
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);
226 #endif
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);
234
235         g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY,
236                         g_param_spec_enum("latency", "Audio Latency",
237                                         "Audio latency",
238                                         GST_AVSYS_AUDIO_SRC_LATENCY, DEFAULT_AUDIO_LATENCY,
239                                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
240 }
241
242
243
244 /**
245  *@note useful range 0 - 1000000 microsecond
246  */
247 #if _ENABLE_FAKE_READ
248 static unsigned long
249 fake_delay (unsigned long usec)
250 {
251         struct timeval s_time;
252         struct timeval c_time;
253         long s_sec  = 0L;
254         long s_usec = 0L;
255         long c_sec  = 0L;
256         long c_usec = 0L;
257         long t_sec  = 0L;
258         long t_usec = 0L;
259         unsigned long total_usec = 0UL;
260         unsigned long t = 0UL;
261
262         if (usec == 0UL) {
263                 usleep (0);
264                 return 0;
265         }
266
267         /*get start time*/
268         if (gettimeofday ((struct timeval *)&s_time, NULL) == 0) {
269                 s_sec  = s_time.tv_sec;
270                 s_usec = s_time.tv_usec;
271         } else {
272                 return 0;
273         }
274
275         for (;;) {
276                 /*get current time*/
277                 if (gettimeofday ((struct timeval *)&c_time, NULL) == 0) {
278                         c_sec  = c_time.tv_sec;
279                         c_usec = c_time.tv_usec;
280                 } else {
281                         return 0;
282                 }
283
284                 /*get elasped sec*/
285                 t_sec = c_sec - s_sec;
286
287                 /*get elapsed usec*/
288                 if ((s_usec) > (c_usec)) {
289                         t_usec = 1000000L - (s_usec) + (c_usec);
290                         t_sec--;
291                 } else {
292                         t_usec = (c_usec) - (s_usec);
293                 }
294
295                 /*get total elapsed time*/
296                 total_usec = (t_sec * 1000000UL) + t_usec;
297
298                 t = usec - total_usec;
299
300                 if (total_usec >= usec) {
301                         break;
302                 } else {
303                         if (t > 10000UL) {
304                                 /*this function does not work in precision*/
305                                 usleep (1);
306                         }
307                 }
308         }
309
310         return total_usec;
311 }
312 #endif
313
314 static guint
315 gst_avsysaudiosrc_delay (GstAudioSrc *asrc)
316 {
317         GstAvsysAudioSrc        *avsys_audio = NULL;
318         int                                     delay;
319         guint                           retValue = 0;
320
321         avsys_audio = GST_AVSYS_AUDIO_SRC (asrc);
322         if(AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay))
323                 retValue = delay;
324
325         return retValue;
326 }
327
328
329
330 static void
331 gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
332 {
333     GstAvsysAudioSrc *src = NULL;
334 //    gint                      getvalue = 0;
335         src = GST_AVSYS_AUDIO_SRC (object);
336
337         if (src->cached_caps == NULL)
338         {
339                 switch (prop_id)
340                 {
341         case PROP_AUDIO_LATENCY:
342                 src->latency = g_value_get_enum(value);
343                         break;
344         default:
345                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
346                 break;
347                 }
348         }
349 }
350
351 static void
352 gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
353 {
354         GstAvsysAudioSrc *src;
355
356         src = GST_AVSYS_AUDIO_SRC (object);
357
358     switch (prop_id)
359     {
360         case PROP_AUDIO_LATENCY:
361                 g_value_set_enum(value, src->latency);
362                 break;
363         default:
364                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
365                 break;
366         }
367 }
368
369 static void
370 gst_avsysaudiosrc_init (GstAvsysAudioSrc * avsysaudiosrc, GstAvsysAudioSrcClass * g_class)
371 {
372         GST_DEBUG_OBJECT (avsysaudiosrc, "initializing");
373
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;
379 }
380
381 #if defined(_USE_CAPS_)
382 static GstCaps *
383 gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc)
384 {
385     GstElementClass *element_class;
386     GstPadTemplate *pad_template;
387         GstAvsysAudioSrc *src;
388     GstCaps *caps = NULL;
389
390         src = GST_AVSYS_AUDIO_SRC (bsrc);
391
392     if(src->audio_handle==(avsys_handle_t)-1){
393         GST_DEBUG_OBJECT(src,"device not open, using template caps");
394         return NULL;
395     }
396
397     if (src->cached_caps)
398         {
399                 GST_LOG_OBJECT (src, "Returning cached caps");
400             return gst_caps_ref(src->cached_caps);
401         }
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);
405
406         caps = gst_avsysaudiosrc_probe_supported_formats (GST_OBJECT (src), src->audio_handle,
407                                                                                                         gst_pad_template_get_caps (pad_template));
408
409         if (caps) {
410                 src->cached_caps = gst_caps_ref (caps);
411         }
412
413         GST_INFO_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
414
415         return caps;
416 }
417 #endif
418 static gboolean
419 gst_avsysaudiosrc_open (GstAudioSrc * asrc)
420 {
421         return TRUE;
422 }
423
424 static gboolean
425 avsysaudiosrc_parse_spec (GstAvsysAudioSrc *avsys_audio, GstRingBufferSpec * spec)
426 {
427     /* Check param */
428     if (spec->type != GST_BUFTYPE_LINEAR ||
429         spec->channels > 2 || spec->channels < 1 ||
430         !(spec->format == GST_S8 || spec->format == GST_S16_LE) )
431         return FALSE;
432
433     switch(spec->format)
434     {
435     case GST_S8:
436         avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT;
437         avsys_audio->bytes_per_sample = 1;
438         break;
439     case GST_S16_LE:
440         avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT;
441         avsys_audio->bytes_per_sample = 2;
442         break;
443     default:
444         GST_DEBUG_OBJECT(avsys_audio, "Only support S8, S16LE format");
445         return FALSE;
446     }
447
448     // set audio parameter for avsys audio open
449
450         switch(avsys_audio->latency)
451         {
452         case AVSYSAUDIOSRC_LATENCY_LOW:
453                 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY;
454                 break;
455         case AVSYSAUDIOSRC_LATENCY_MID:
456                 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT;
457                 break;
458         case AVSYSAUDIOSRC_LATENCY_HIGH:
459                 avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY;
460                 break;
461         default:
462                 break;
463         }
464
465     avsys_audio->audio_param.priority = 0;
466     avsys_audio->audio_param.samplerate = spec->rate;
467     avsys_audio->audio_param.channels = spec->channels;
468
469     if(spec->channels == 2)
470         avsys_audio->bytes_per_sample *= 2;
471     else if(spec->channels > 2)
472     {
473         GST_ERROR_OBJECT(avsys_audio,"Unsupported channel number %d", spec->channels);
474         return FALSE;
475     }
476
477     return TRUE;
478 }
479
480 static gboolean
481 gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
482 {
483     GstAvsysAudioSrc *avsysaudiosrc = NULL;
484         guint   p_time = 0, b_time = 0;
485
486         avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
487
488     if (!avsysaudiosrc_parse_spec(avsysaudiosrc, spec))
489     {
490         GST_ERROR("avsysaudiosrc_parse_spec failed");
491         return FALSE;
492     }
493
494         /*open avsys audio*/
495     if (!gst_avsysaudiosrc_avsys_open (avsysaudiosrc))
496     {
497         GST_ERROR("gst_avsysaudiosrc_avsys_open failed");
498         return FALSE;
499     }
500
501     /* Ring buffer size */
502     if (AVSYS_STATE_SUCCESS ==
503         avsys_audio_get_period_buffer_time(avsysaudiosrc->audio_handle, &p_time, &b_time))
504     {
505         if(p_time == 0 || b_time == 0)
506                 return FALSE;
507
508         spec->latency_time = (guint64)p_time;
509         spec->buffer_time = (guint64)b_time;
510         }
511         else
512         {
513          return FALSE;
514         }
515         spec->segsize = avsysaudiosrc->buffer_size;
516         spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0);
517         spec->segtotal += 2;
518
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);
521
522
523     return TRUE;
524 }
525
526 static gboolean
527 gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc)
528 {
529     GstAvsysAudioSrc *avsysaudiosrc = NULL;
530     gboolean ret = TRUE;
531
532     avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
533
534         /*close*/
535     GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
536
537     if(!gst_avsysaudiosrc_avsys_close(avsysaudiosrc))
538     {
539         GST_ERROR_OBJECT(avsysaudiosrc, "gst_avsysaudiosrc_avsys_close failed");
540         ret = FALSE;
541     }
542     GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
543
544
545
546         return ret;
547 }
548
549 static gboolean
550 gst_avsysaudiosrc_close (GstAudioSrc * asrc)
551 {
552     GstAvsysAudioSrc *avsysaudiosrc = NULL;
553
554     avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
555         gst_caps_replace (&avsysaudiosrc->cached_caps, NULL);
556
557         return TRUE;
558 }
559
560 static void
561 gst_avsysaudiosrc_reset (GstAudioSrc * asrc)
562 {
563         GstAvsysAudioSrc *avsys_audio = NULL;
564
565     avsys_audio = GST_AVSYS_AUDIO_SRC (asrc);
566     GST_AVSYS_AUDIO_SRC_LOCK (asrc);
567
568     if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle))
569     {
570         GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: ");
571     }
572
573     GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
574
575     return;
576 }
577
578
579 static GstStateChangeReturn
580 gst_avsys_src_change_state (GstElement * element, GstStateChange transition)
581 {
582         GstAvsysAudioSrc *avsys = NULL;
583         GstStateChangeReturn ret ;
584
585         avsys = GST_AVSYS_AUDIO_SRC (element);
586         GST_DEBUG("gst_avsys_src_change_state");
587
588         switch (transition)
589         {
590                 case GST_STATE_CHANGE_NULL_TO_READY:
591                 {
592                         GST_DEBUG ("GST_STATE_CHANGE_NULL_TO_READY\n") ;
593                         break ;
594                 }
595                 case GST_STATE_CHANGE_READY_TO_PAUSED:
596                 {
597                         GST_DEBUG ("GST_STATE_CHANGE_READY_TO_PAUSED\n") ;
598                         break ;
599                 }
600                 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
601                 {
602                         GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_PLAYING\n") ;
603                         /* Capture Start */
604                         if (!gst_avsysaudiosrc_avsys_start (avsys)) {
605                                 GST_ERROR("gst_avsysaudiosrc_avsys_start failed");
606                         }
607                         break ;
608                 }
609                 default:
610                         break ;
611         }
612
613         ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
614
615         GST_DEBUG ("After parent_class->change_state...\n") ;
616         switch (transition)
617         {
618                 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
619                 {
620                         GST_DEBUG ("GST_STATE_CHANGE_PLAYING_TO_PAUSED\n") ;
621                         /* Capture Stop */
622                         if (!gst_avsysaudiosrc_avsys_stop (avsys)) {
623                                 GST_ERROR("gst_avsysaudiosrc_avsys_stop failed");
624                         }
625                         break ;
626                 }
627                 case GST_STATE_CHANGE_PAUSED_TO_READY:
628                 {
629                         GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_READY\n") ;
630                         break ;
631                 }
632                 case GST_STATE_CHANGE_READY_TO_NULL:
633                 {
634                         GST_DEBUG ("GST_STATE_CHANGE_READY_TO_NULL\n") ;
635                         break ;
636                 }
637                 default:
638                         break ;
639         }
640
641         return ret;
642 }
643
644
645
646 static guint
647 gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
648 {
649     GstAvsysAudioSrc    *avsysaudiosrc = NULL;
650         gint                            readed = 0;
651         gpointer                        ptr = NULL;
652         guint                           used_length = 0;
653
654         avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc);
655
656         ptr = data;
657
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);
663 #else
664         ptr = data;
665         readed = avsys_audio_read (avsysaudiosrc->audio_handle, ptr, length);
666         if (readed < 0)
667                 goto _READ_ERROR;
668 #endif //_ENABLE_FAKE_READ
669         GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
670
671         return readed;
672
673 _READ_ERROR:
674         {
675                 GST_AVSYS_AUDIO_SRC_UNLOCK (asrc);
676                 return length;  /* skip one period */
677         }
678 }
679
680 static gboolean
681 gst_avsysaudiosrc_avsys_cork (GstAvsysAudioSrc *avsysaudiosrc, int cork)
682 {
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);
686                 return FALSE;
687         }
688         return TRUE;
689 }
690
691 static gboolean
692 gst_avsysaudiosrc_avsys_start (GstAvsysAudioSrc *avsysaudiosrc)
693 {
694         gboolean result;
695
696         GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
697         result = gst_avsysaudiosrc_avsys_cork(avsysaudiosrc, CAPTURE_UNCORK);
698         GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
699
700         return result;
701 }
702
703 static gboolean
704 gst_avsysaudiosrc_avsys_stop (GstAvsysAudioSrc *avsysaudiosrc)
705 {
706         gboolean result;
707
708         GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
709         result = gst_avsysaudiosrc_avsys_cork(avsysaudiosrc, CAPTURE_CORK);
710         GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
711
712         return result;
713 }
714
715 static gboolean
716 gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *avsysaudiosrc)
717 {
718         int avsys_result = 0;
719
720         GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc);
721
722         avsys_result = avsys_audio_open(&avsysaudiosrc->audio_param, &avsysaudiosrc->audio_handle, &avsysaudiosrc->buffer_size);
723
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);
727                 return FALSE;
728         }
729
730 #if _ENABLE_FAKE_READ
731         g_delay_time = (unsigned long)((avsysaudiosrc->samplerate * (avsysaudiosrc->format / 8) * avsysaudiosrc->channels) / avsysaudiosrc->buffer_size);
732 #endif
733
734         GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc);
735         return TRUE;
736 }
737
738 static gboolean
739 gst_avsysaudiosrc_avsys_close(GstAvsysAudioSrc *src)
740 {
741         int ret;
742
743     if (src->audio_handle != (avsys_handle_t)-1)
744     {
745                 /*close avsys audio*/
746                 ret = avsys_audio_close (src->audio_handle);
747         if (AVSYS_FAIL(ret))
748         {
749                 GST_ERROR_OBJECT(src, "avsys_audio_close() error 0x%x", ret);
750                         return FALSE;
751                 }
752         src->audio_handle = (avsys_handle_t)-1;
753         GST_DEBUG_OBJECT(src, "AVsys audio handle closed");
754         }
755     else
756     {
757         GST_WARNING_OBJECT(src,"avsys audio handle has already closed");
758     }
759
760         return TRUE;
761 }
762 #if defined(_USE_CAPS_)
763 static GstCaps *
764 gst_avsysaudiosrc_detect_rates(GstObject *obj,
765                 avsys_pcm_hw_params_t *hw_params, GstCaps *in_caps)
766 {
767         GstCaps *caps;
768         guint min, max;
769         gint err, dir, min_rate, max_rate, i;
770
771         GST_LOG_OBJECT(obj, "probing sample rates ...");
772
773         if ((err = avsys_pcm_hw_params_get_rate_min(hw_params, &min, &dir)) < 0)
774                 goto min_rate_err;
775
776         if ((err = avsys_pcm_hw_params_get_rate_max(hw_params, &max, &dir)) < 0)
777                 goto max_rate_err;
778
779         min_rate = min;
780         max_rate = max;
781
782         if (min_rate < _MIN_RATE)
783                 min_rate = _MIN_RATE; /* random 'sensible minimum' */
784
785         if (max_rate <= 0)
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);
789
790         GST_DEBUG_OBJECT(obj, "Min. rate = %u (%d)", min_rate, min);
791         GST_DEBUG_OBJECT(obj, "Max. rate = %u (%d)", max_rate, max);
792
793         caps = gst_caps_make_writable(in_caps);
794
795         for (i = 0; i < gst_caps_get_size(caps); ++i)
796         {
797                 GstStructure *s;
798
799                 s = gst_caps_get_structure(caps, i);
800                 if (min_rate == max_rate)
801                 {
802                         gst_structure_set(s, "rate", G_TYPE_INT, min_rate, NULL);
803                 }
804                 else
805                 {
806                         gst_structure_set(s, "rate", GST_TYPE_INT_RANGE, min_rate,
807                                         max_rate, NULL);
808                 }
809         }
810
811         return caps;
812         /* ERRORS */
813         min_rate_err:
814         {
815                 GST_ERROR_OBJECT(obj, "failed to query minimum sample rate");
816                 gst_caps_unref(in_caps);
817                 return NULL;
818         }
819         max_rate_err:
820         {
821                 GST_ERROR_OBJECT(obj, "failed to query maximum sample rate");
822                 gst_caps_unref(in_caps);
823                 return NULL;
824         }
825 }
826
827
828 static GstCaps *
829 gst_avsysaudiosrc_detect_formats(GstObject * obj,
830                 avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps)
831 {
832         avsys_pcm_format_mask_t *mask;
833         GstStructure *s;
834         GstCaps *caps;
835         gint i;
836
837         avsys_pcm_format_mask_malloc(&mask);
838         avsys_pcm_hw_params_get_format_mask(hw_params, mask);
839
840         caps = gst_caps_new_empty();
841
842         for (i = 0; i < gst_caps_get_size(in_caps); ++i)
843         {
844                 GstStructure *scopy;
845                 //gint w;
846                 gint width = 0, depth = 0;
847                 gint sndformat;
848
849                 s = gst_caps_get_structure(in_caps, i);
850                 if (!gst_structure_has_name(s, "audio/x-raw-int"))
851                 {
852                         GST_WARNING_OBJECT(obj, "skipping non-int format");
853                         continue;
854                 }
855                 if (!gst_structure_get_int(s, "width", &width)
856                                 || !gst_structure_get_int(s, "depth", &depth))
857                         continue;
858
859                 GST_DEBUG_OBJECT(obj, "width = %d height = %d", width, depth);
860                 if (width == 8)
861                         sndformat = 0;//SND_PCM_FORMAT_S8
862                 else
863                         //width==16
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);
869
870                 }
871                 else
872                 {
873                         scopy = NULL;
874                 }
875                 if (scopy)
876                 {
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,
880                                         NULL);
881                         gst_caps_append_structure(caps, scopy);
882                 }
883
884         }
885
886         avsys_pcm_format_mask_free(mask);
887         gst_caps_unref(in_caps);
888         return caps;
889 }
890
891
892 static GstCaps *
893 gst_avsysaudiosrc_detect_channels(GstObject * obj,
894                 avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps)
895 {
896         GstCaps *caps;
897         guint min, max;
898         gint err, min_channel, max_channel, i;
899 //      gint dir;
900
901         GST_LOG_OBJECT(obj, "probing sample rates ...");
902
903         if ((err = avsys_pcm_hw_params_get_channels_min(hw_params, &min)) < 0)
904                 goto min_chan_err;
905
906         if ((err = avsys_pcm_hw_params_get_channels_max(hw_params, &max)) < 0)
907                 goto max_chan_err;
908
909         min_channel = min;
910         max_channel = max;
911
912         if (min_channel < _MIN_CHANNEL)
913                 min_channel = _MIN_CHANNEL; /* random 'sensible minimum' */
914
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);
919
920         GST_DEBUG_OBJECT(obj, "Min. channel = %u (%d)", min_channel, min);
921         GST_DEBUG_OBJECT(obj, "Max. channel = %u (%d)", max_channel, max);
922
923         caps = gst_caps_make_writable(in_caps);
924
925         for (i = 0; i < gst_caps_get_size(caps); ++i)
926         {
927                 GstStructure *s;
928
929                 s = gst_caps_get_structure(caps, i);
930                 if (min_channel == max_channel)
931                 {
932                         gst_structure_set(s, "channels", G_TYPE_INT, _MIN_CHANNEL, NULL);
933                 }
934                 else
935                 {
936                         gst_structure_set(s, "channels", GST_TYPE_INT_RANGE, min_channel,
937                                         max_channel, NULL);
938                 }
939         }
940
941         return caps;
942
943         /* ERRORS */
944         min_chan_err:
945         {
946                 GST_ERROR_OBJECT(obj, "failed to query minimum sample rate");
947                 gst_caps_unref(in_caps);
948                 return NULL;
949         }
950         max_chan_err:
951         {
952                 GST_ERROR_OBJECT(obj, "failed to query maximum sample rate:");
953                 gst_caps_unref(in_caps);
954                 return NULL;
955         }
956 }
957
958 /*
959  * gst_avsys_probe_supported_formats:
960  *
961  * Takes the template caps and returns the subset which is actually
962  * supported by this device.
963  *
964  */
965
966 static GstCaps *
967 gst_avsysaudiosrc_probe_supported_formats(GstObject * obj,
968                 avsys_handle_t handle, const GstCaps * template_caps)
969 {
970
971         avsys_pcm_hw_params_t *hw_params;
972         GstCaps *caps;
973         gint err;
974
975         avsys_pcm_hw_params_malloc(&hw_params);
976         if ((err = avsys_pcm_hw_params_any(handle, hw_params)) < 0)
977                 goto error;
978
979         caps = gst_caps_copy(template_caps);
980
981         if (!(caps = gst_avsysaudiosrc_detect_formats(obj, hw_params, caps)))
982                 goto subroutine_error;
983
984         if (!(caps = gst_avsysaudiosrc_detect_rates(obj, hw_params, caps)))
985                 goto subroutine_error;
986
987         if (!(caps = gst_avsysaudiosrc_detect_channels(obj, hw_params, caps)))
988                 goto subroutine_error;
989
990         avsys_pcm_hw_params_free(hw_params);
991         return caps;
992
993         /* ERRORS */
994         error:
995         {
996                 GST_ERROR_OBJECT(obj, "failed to query formats");
997                 return NULL;
998         }
999         subroutine_error:
1000         {
1001                 GST_ERROR_OBJECT(obj, "failed to query formats");
1002                 return NULL;
1003         }
1004 }
1005 #endif