df1256ceb529ad48e4eb39aa9dab025bc4c6ede4
[platform/upstream/gstreamer.git] / sys / audioflingersink / gstaudioflingersink.c
1 /* GStreamer
2  * Copyright (C) <2009> Prajnashi S <prajnashi@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /**
21  * SECTION:element-audioflindersink
22  *
23  * This element lets you output sound using the Audio Flinger system in Android
24  *
25  * Note that you should almost always use generic audio conversion elements
26  * like audioconvert and audioresample in front of an audiosink to make sure
27  * your pipeline works under all circumstances (those conversion elements will
28  * act in passthrough-mode if no conversion is necessary).
29  */
30
31 #ifdef HAVE_CONFIG_H
32 //#include "config.h"
33 #endif
34 #include "gstaudioflingersink.h"
35 #include <utils/Log.h>
36
37
38
39 #define LOG_NDEBUG 0
40
41 #undef LOG_TAG
42 #define LOG_TAG "GstAudioFlingerSink"
43
44
45 #define DEFAULT_BUFFERTIME (500*GST_MSECOND) / (GST_USECOND)
46 #define DEFAULT_LATENCYTIME (50*GST_MSECOND) / (GST_USECOND)
47 #define DEFAULT_VOLUME 10.0
48 #define DEFAULT_MUTE FALSE
49 #define DEFAULT_EXPORT_SYSTEM_AUDIO_CLOCK TRUE
50
51 /*
52  * PROPERTY_ID
53  */
54 enum
55 {
56   PROP_NULL,
57   PROP_VOLUME,
58   PROP_MUTE,
59   PROP_AUDIO_SINK,
60 };
61
62 GST_DEBUG_CATEGORY_STATIC (audioflinger_debug);
63 #define GST_CAT_DEFAULT audioflinger_debug
64
65 /* elementfactory information */
66 static const GstElementDetails gst_audioflinger_sink_details =
67 GST_ELEMENT_DETAILS ("Audio Sink (AudioFlinger)",
68     "Sink/Audio",
69     "Output to android's AudioFlinger",
70     "Prajnashi S <prajnashi@gmail.com>, "
71     "Alessandro Decina <alessandro.decina@collabora.co.uk>");
72
73 #define GST_TYPE_ANDROID_AUDIORING_BUFFER        \
74         (gst_android_audioringbuffer_get_type())
75 #define GST_ANDROID_AUDIORING_BUFFER(obj)        \
76         (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ANDROID_AUDIORING_BUFFER,GstAndroidAudioRingBuffer))
77 #define GST_ANDROID_AUDIORING_BUFFER_CLASS(klass) \
78         (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ANDROID_AUDIORING_BUFFER,GstAndroidAudioRingBufferClass))
79 #define GST_ANDROID_AUDIORING_BUFFER_GET_CLASS(obj) \
80         (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ANDROID_AUDIORING_BUFFER, GstAndroidAudioRingBufferClass))
81 #define GST_ANDROID_AUDIORING_BUFFER_CAST(obj)        \
82         ((GstAndroidAudioRingBuffer *)obj)
83 #define GST_IS_ANDROID_AUDIORING_BUFFER(obj)     \
84         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ANDROID_AUDIORING_BUFFER))
85 #define GST_IS_ANDROID_AUDIORING_BUFFER_CLASS(klass)\
86         (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ANDROID_AUDIORING_BUFFER))
87
88 typedef struct _GstAndroidAudioRingBuffer GstAndroidAudioRingBuffer;
89 typedef struct _GstAndroidAudioRingBufferClass GstAndroidAudioRingBufferClass;
90
91 #define GST_ANDROID_AUDIORING_BUFFER_GET_COND(buf) (((GstAndroidAudioRingBuffer *)buf)->cond)
92 #define GST_ANDROID_AUDIORING_BUFFER_WAIT(buf)     (g_cond_wait (GST_ANDROID_ANDROID_AUDIORING_BUFFER_GET_COND (buf), GST_OBJECT_GET_LOCK (buf)))
93 #define GST_ANDROID_AUDIORING_BUFFER_SIGNAL(buf)   (g_cond_signal (GST_ANDROID_ANDROID_AUDIORING_BUFFER_GET_COND (buf)))
94 #define GST_ANDROID_AUDIORING_BUFFER_BROADCAST(buf)(g_cond_broadcast (GST_ANDROID_ANDROID_AUDIORING_BUFFER_GET_COND (buf)))
95
96 struct _GstAndroidAudioRingBuffer
97 {
98   GstRingBuffer object;
99
100   gboolean running;
101   gint queuedseg;
102
103   GCond *cond;
104 };
105
106 struct _GstAndroidAudioRingBufferClass
107 {
108   GstRingBufferClass parent_class;
109 };
110
111 static void
112 gst_android_audioringbuffer_class_init (GstAndroidAudioRingBufferClass * klass);
113 static void gst_android_audioringbuffer_init (GstAndroidAudioRingBuffer *
114     ringbuffer, GstAndroidAudioRingBufferClass * klass);
115 static void gst_android_audioringbuffer_dispose (GObject * object);
116 static void gst_android_audioringbuffer_finalize (GObject * object);
117
118 static GstRingBufferClass *ring_parent_class = NULL;
119
120 static gboolean gst_android_audioringbuffer_open_device (GstRingBuffer * buf);
121 static gboolean gst_android_audioringbuffer_close_device (GstRingBuffer * buf);
122 static gboolean gst_android_audioringbuffer_acquire (GstRingBuffer * buf,
123     GstRingBufferSpec * spec);
124 static gboolean gst_android_audioringbuffer_release (GstRingBuffer * buf);
125 static gboolean gst_android_audioringbuffer_start (GstRingBuffer * buf);
126 static gboolean gst_android_audioringbuffer_pause (GstRingBuffer * buf);
127 static gboolean gst_android_audioringbuffer_stop (GstRingBuffer * buf);
128 static gboolean gst_android_audioringbuffer_activate (GstRingBuffer * buf,
129     gboolean active);
130 static void gst_android_audioringbuffer_clear (GstRingBuffer * buf);
131 static guint gst_android_audioringbuffer_commit (GstRingBuffer * buf,
132     guint64 * sample, guchar * data, gint in_samples, gint out_samples,
133     gint * accum);
134
135 static void gst_audioflinger_sink_base_init (gpointer g_class);
136 static void gst_audioflinger_sink_class_init (GstAudioFlingerSinkClass * klass);
137 static void gst_audioflinger_sink_init (GstAudioFlingerSink *
138     audioflinger_sink);
139
140 static void gst_audioflinger_sink_dispose (GObject * object);
141 static void gst_audioflinger_sink_finalise (GObject * object);
142
143 static void gst_audioflinger_sink_get_property (GObject * object, guint prop_id,
144     GValue * value, GParamSpec * pspec);
145 static void gst_audioflinger_sink_set_property (GObject * object, guint prop_id,
146     const GValue * value, GParamSpec * pspec);
147
148 static GstCaps *gst_audioflinger_sink_getcaps (GstBaseSink * bsink);
149
150 static gboolean gst_audioflinger_sink_open (GstAudioFlingerSink * asink);
151 static gboolean gst_audioflinger_sink_close (GstAudioFlingerSink * asink);
152 static gboolean gst_audioflinger_sink_prepare (GstAudioFlingerSink * asink,
153     GstRingBufferSpec * spec);
154 static gboolean gst_audioflinger_sink_unprepare (GstAudioFlingerSink * asink);
155 static void gst_audioflinger_sink_reset (GstAudioFlingerSink * asink,
156     gboolean create_clock);
157 static void gst_audioflinger_sink_set_mute (GstAudioFlingerSink *
158     audioflinger_sink, gboolean mute);
159 static void gst_audioflinger_sink_set_volume (GstAudioFlingerSink *
160     audioflinger_sink, float volume);
161 static gboolean gst_audioflinger_sink_event (GstBaseSink * bsink,
162     GstEvent * event);
163 static GstRingBuffer *gst_audioflinger_sink_create_ringbuffer (GstBaseAudioSink
164     * sink);
165 static GstClockTime gst_audioflinger_sink_get_time (GstClock * clock,
166     gpointer user_data);
167 static GstFlowReturn gst_audioflinger_sink_preroll (GstBaseSink * bsink,
168     GstBuffer * buffer);
169 static GstClockTime gst_audioflinger_sink_system_audio_clock_get_time (GstClock
170     * clock, gpointer user_data);
171 static GstClock *gst_audioflinger_sink_provide_clock (GstElement * elem);
172 static GstStateChangeReturn gst_audioflinger_sink_change_state (GstElement *
173     element, GstStateChange transition);
174
175 static GstStaticPadTemplate audioflingersink_sink_factory =
176     GST_STATIC_PAD_TEMPLATE ("sink",
177     GST_PAD_SINK,
178     GST_PAD_ALWAYS,
179     GST_STATIC_CAPS ("audio/x-raw-int, "
180         "endianness = (int) { " G_STRINGIFY (G_BYTE_ORDER) " }, "
181         "signed = (boolean) { TRUE }, "
182         "width = (int) 16, "
183         "depth = (int) 16, "
184         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; ")
185     );
186
187 static GType
188 gst_android_audioringbuffer_get_type (void)
189 {
190   static GType ringbuffer_type = 0;
191
192   if (!ringbuffer_type) {
193     static const GTypeInfo ringbuffer_info = {
194       sizeof (GstAndroidAudioRingBufferClass),
195       NULL,
196       NULL,
197       (GClassInitFunc) gst_android_audioringbuffer_class_init,
198       NULL,
199       NULL,
200       sizeof (GstAndroidAudioRingBuffer),
201       0,
202       (GInstanceInitFunc) gst_android_audioringbuffer_init,
203       NULL
204     };
205
206     ringbuffer_type =
207         g_type_register_static (GST_TYPE_RING_BUFFER,
208         "GstAndroidAudioSinkRingBuffer", &ringbuffer_info, 0);
209   }
210   return ringbuffer_type;
211 }
212
213 static void
214 gst_android_audioringbuffer_class_init (GstAndroidAudioRingBufferClass * klass)
215 {
216   GObjectClass *gobject_class;
217   GstRingBufferClass *gstringbuffer_class;
218
219   gobject_class = G_OBJECT_CLASS (klass);
220   gstringbuffer_class = GST_RING_BUFFER_CLASS (klass);
221
222   ring_parent_class = g_type_class_peek_parent (klass);
223
224   gobject_class->dispose = gst_android_audioringbuffer_dispose;
225   gobject_class->finalize = gst_android_audioringbuffer_finalize;
226
227   gstringbuffer_class->open_device =
228       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_open_device);
229   gstringbuffer_class->close_device =
230       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_close_device);
231   gstringbuffer_class->acquire =
232       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_acquire);
233   gstringbuffer_class->release =
234       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_release);
235   gstringbuffer_class->start =
236       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_start);
237   gstringbuffer_class->pause =
238       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_pause);
239   gstringbuffer_class->resume =
240       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_start);
241   gstringbuffer_class->stop =
242       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_stop);
243   gstringbuffer_class->clear_all =
244       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_clear);
245   gstringbuffer_class->commit =
246       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_commit);
247
248 #if 0
249   gstringbuffer_class->delay =
250       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_delay);
251 #endif
252   gstringbuffer_class->activate =
253       GST_DEBUG_FUNCPTR (gst_android_audioringbuffer_activate);
254 }
255
256 static void
257 gst_android_audioringbuffer_init (G_GNUC_UNUSED GstAndroidAudioRingBuffer *
258     ringbuffer, G_GNUC_UNUSED GstAndroidAudioRingBufferClass * g_class)
259 {
260 }
261
262 static void
263 gst_android_audioringbuffer_dispose (GObject * object)
264 {
265   G_OBJECT_CLASS (ring_parent_class)->dispose (object);
266 }
267
268 static void
269 gst_android_audioringbuffer_finalize (GObject * object)
270 {
271   G_OBJECT_CLASS (ring_parent_class)->finalize (object);
272 }
273
274 static gboolean
275 gst_android_audioringbuffer_open_device (GstRingBuffer * buf)
276 {
277   GstAudioFlingerSink *sink;
278   gboolean result = TRUE;
279   LOGD (">gst_android_audioringbuffer_open_device");
280   sink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (buf));
281   result = gst_audioflinger_sink_open (sink);
282
283   if (!result)
284     goto could_not_open;
285
286   return result;
287
288 could_not_open:
289   {
290     GST_DEBUG_OBJECT (sink, "could not open device");
291     LOGE ("could not open device");
292     return FALSE;
293   }
294 }
295
296 static gboolean
297 gst_android_audioringbuffer_close_device (GstRingBuffer * buf)
298 {
299   GstAudioFlingerSink *sink;
300   gboolean result = TRUE;
301
302   LOGD (">gst_android_audioringbuffer_close_device");
303
304   sink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (buf));
305
306   result = gst_audioflinger_sink_close (sink);
307
308   if (!result)
309     goto could_not_close;
310
311   return result;
312
313 could_not_close:
314   {
315     GST_DEBUG_OBJECT (sink, "could not close device");
316     LOGE ("could not close device");
317     return FALSE;
318   }
319 }
320
321 static gboolean
322 gst_android_audioringbuffer_acquire (GstRingBuffer * buf,
323     GstRingBufferSpec * spec)
324 {
325   GstAudioFlingerSink *sink;
326   gboolean result = FALSE;
327
328   LOGD (">gst_android_audioringbuffer_acquire");
329
330   sink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (buf));
331
332   result = gst_audioflinger_sink_prepare (sink, spec);
333
334   if (!result)
335     goto could_not_prepare;
336
337   return TRUE;
338
339   /* ERRORS */
340 could_not_prepare:
341   {
342     GST_DEBUG_OBJECT (sink, "could not prepare device");
343     LOGE ("could not close device");
344     return FALSE;
345   }
346 }
347
348 static gboolean
349 gst_android_audioringbuffer_activate (G_GNUC_UNUSED GstRingBuffer * buf,
350     G_GNUC_UNUSED gboolean active)
351 {
352   return TRUE;
353 }
354
355 /* function is called with LOCK */
356 static gboolean
357 gst_android_audioringbuffer_release (GstRingBuffer * buf)
358 {
359   GstAudioFlingerSink *sink;
360   gboolean result = FALSE;
361   LOGD (">gst_android_audioringbuffer_release");
362
363   sink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (buf));
364
365   result = gst_audioflinger_sink_unprepare (sink);
366
367   if (!result)
368     goto could_not_unprepare;
369
370   GST_DEBUG_OBJECT (sink, "unprepared");
371   LOGD ("unprepared");
372
373   return result;
374
375 could_not_unprepare:
376   {
377     GST_DEBUG_OBJECT (sink, "could not unprepare device");
378     LOGE ("could not unprepare device");
379     return FALSE;
380   }
381 }
382
383 static gboolean
384 gst_android_audioringbuffer_start (GstRingBuffer * buf)
385 {
386   GstAudioFlingerSink *asink;
387   GstAndroidAudioRingBuffer *abuf;
388
389   abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf);
390   asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf));
391
392   GST_INFO_OBJECT (buf, "starting ringbuffer");
393   LOGD ("starting ringbuffer");
394
395   audioflinger_device_start (asink->audioflinger_device);
396
397   return TRUE;
398 }
399
400 static gboolean
401 gst_android_audioringbuffer_pause (GstRingBuffer * buf)
402 {
403   GstAudioFlingerSink *asink;
404   GstAndroidAudioRingBuffer *abuf;
405
406   abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf);
407   asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf));
408
409   GST_INFO_OBJECT (buf, "pausing ringbuffer");
410   LOGD ("pausing ringbuffer");
411
412   audioflinger_device_pause (asink->audioflinger_device);
413
414   return TRUE;
415 }
416
417 static gboolean
418 gst_android_audioringbuffer_stop (GstRingBuffer * buf)
419 {
420   GstAudioFlingerSink *asink;
421   GstAndroidAudioRingBuffer *abuf;
422
423   abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf);
424   asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf));
425
426   GST_INFO_OBJECT (buf, "stopping ringbuffer");
427   LOGD ("stopping ringbuffer");
428
429   audioflinger_device_stop (asink->audioflinger_device);
430
431   return TRUE;
432 }
433
434 #if 0
435 static guint
436 gst_android_audioringbuffer_delay (GstRingBuffer * buf)
437 {
438   return 0;
439 }
440 #endif
441
442 static void
443 gst_android_audioringbuffer_clear (GstRingBuffer * buf)
444 {
445   GstAudioFlingerSink *asink;
446   GstAndroidAudioRingBuffer *abuf;
447
448   abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf);
449   asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf));
450
451   GST_INFO_OBJECT (buf, "clearing ringbuffer");
452   LOGD ("clearing ringbuffer");
453
454   if (asink->audioflinger_device == NULL)
455     return;
456
457   GST_INFO_OBJECT (asink, "resetting clock");
458   gst_audio_clock_reset (GST_AUDIO_CLOCK (asink->audio_clock), 0);
459
460   audioflinger_device_flush (asink->audioflinger_device);
461 }
462
463 #define FWD_SAMPLES(s,se,d,de)                  \
464 G_STMT_START {                                  \
465   /* no rate conversion */                      \
466   guint towrite = MIN (se + bps - s, de - d);   \
467   /* simple copy */                             \
468   if (!skip)                                    \
469     memcpy (d, s, towrite);                     \
470   in_samples -= towrite / bps;                  \
471   out_samples -= towrite / bps;                 \
472   s += towrite;                                 \
473   GST_LOG ("copy %u bytes", towrite);           \
474 } G_STMT_END
475
476 /* in_samples >= out_samples, rate > 1.0 */
477 #define FWD_UP_SAMPLES(s,se,d,de)               \
478 G_STMT_START {                                  \
479   guint8 *sb = s, *db = d;                      \
480   while (s <= se && d < de) {                   \
481     if (!skip)                                  \
482       memcpy (d, s, bps);                       \
483     s += bps;                                   \
484     *accum += outr;                             \
485     if ((*accum << 1) >= inr) {                 \
486       *accum -= inr;                            \
487       d += bps;                                 \
488     }                                           \
489   }                                             \
490   in_samples -= (s - sb)/bps;                   \
491   out_samples -= (d - db)/bps;                  \
492   GST_DEBUG ("fwd_up end %d/%d",*accum,*toprocess);     \
493 } G_STMT_END
494
495 /* out_samples > in_samples, for rates smaller than 1.0 */
496 #define FWD_DOWN_SAMPLES(s,se,d,de)             \
497 G_STMT_START {                                  \
498   guint8 *sb = s, *db = d;                      \
499   while (s <= se && d < de) {                   \
500     if (!skip)                                  \
501       memcpy (d, s, bps);                       \
502     d += bps;                                   \
503     *accum += inr;                              \
504     if ((*accum << 1) >= outr) {                \
505       *accum -= outr;                           \
506       s += bps;                                 \
507     }                                           \
508   }                                             \
509   in_samples -= (s - sb)/bps;                   \
510   out_samples -= (d - db)/bps;                  \
511   GST_DEBUG ("fwd_down end %d/%d",*accum,*toprocess);   \
512 } G_STMT_END
513
514 #define REV_UP_SAMPLES(s,se,d,de)               \
515 G_STMT_START {                                  \
516   guint8 *sb = se, *db = d;                     \
517   while (s <= se && d < de) {                   \
518     if (!skip)                                  \
519       memcpy (d, se, bps);                      \
520     se -= bps;                                  \
521     *accum += outr;                             \
522     while (d < de && (*accum << 1) >= inr) {    \
523       *accum -= inr;                            \
524       d += bps;                                 \
525     }                                           \
526   }                                             \
527   in_samples -= (sb - se)/bps;                  \
528   out_samples -= (d - db)/bps;                  \
529   GST_DEBUG ("rev_up end %d/%d",*accum,*toprocess);     \
530 } G_STMT_END
531
532 #define REV_DOWN_SAMPLES(s,se,d,de)             \
533 G_STMT_START {                                  \
534   guint8 *sb = se, *db = d;                     \
535   while (s <= se && d < de) {                   \
536     if (!skip)                                  \
537       memcpy (d, se, bps);                      \
538     d += bps;                                   \
539     *accum += inr;                              \
540     while (s <= se && (*accum << 1) >= outr) {  \
541       *accum -= outr;                           \
542       se -= bps;                                \
543     }                                           \
544   }                                             \
545   in_samples -= (sb - se)/bps;                  \
546   out_samples -= (d - db)/bps;                  \
547   GST_DEBUG ("rev_down end %d/%d",*accum,*toprocess);   \
548 } G_STMT_END
549
550 static guint
551 gst_android_audioringbuffer_commit (GstRingBuffer * buf, guint64 * sample,
552     guchar * data, gint in_samples, gint out_samples, gint * accum)
553 {
554   GstBaseAudioSink *baseaudiosink;
555   GstAudioFlingerSink *asink;
556   GstAndroidAudioRingBuffer *abuf;
557   guint result;
558   guint8 *data_end;
559   gboolean reverse;
560   gint *toprocess;
561   gint inr, outr, bps;
562   guint bufsize;
563   gboolean skip = FALSE;
564   guint32 position;
565   gboolean slaved;
566   guint64 corrected_sample;
567   gboolean sync;
568
569   abuf = GST_ANDROID_AUDIORING_BUFFER_CAST (buf);
570   asink = GST_AUDIOFLINGERSINK (GST_OBJECT_PARENT (abuf));
571   baseaudiosink = GST_BASE_AUDIO_SINK (asink);
572   sync = gst_base_sink_get_sync (GST_BASE_SINK_CAST (asink));
573
574   GST_LOG_OBJECT (asink, "entering commit");
575
576   /* make sure the ringbuffer is started */
577   if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
578           GST_RING_BUFFER_STATE_STARTED)) {
579     /* see if we are allowed to start it */
580     if (G_UNLIKELY (g_atomic_int_get (&buf->abidata.ABI.may_start) == FALSE))
581       goto no_start;
582
583     GST_LOG_OBJECT (buf, "start!");
584     LOGD ("start!");
585     if (!gst_ring_buffer_start (buf))
586       goto start_failed;
587   }
588
589   slaved = GST_ELEMENT_CLOCK (baseaudiosink) != asink->exported_clock;
590   if (asink->last_resync_sample == -1 ||
591       (gint64) baseaudiosink->next_sample == -1) {
592     if (slaved) {
593       /* we're writing a discont buffer. Disable slaving for a while in order to
594        * fill the initial buffer needed by the audio mixer thread. This avoids
595        * some cases where audioflinger removes us from the list of active tracks
596        * because we aren't writing enough data.
597        */
598       GST_INFO_OBJECT (asink, "no previous sample, now %" G_GINT64_FORMAT
599           " disabling slaving", *sample);
600       LOGD ("no previous sample, now %ld disabling slaving", *sample);
601
602       asink->last_resync_sample = *sample;
603       g_object_set (asink, "slave-method", GST_BASE_AUDIO_SINK_SLAVE_NONE,
604           NULL);
605       asink->slaving_disabled = TRUE;
606     } else {
607 /* Trace displayed too much time : remove it
608       GST_INFO_OBJECT (asink, "no previous sample but not slaved");
609       LOGD("no previous sample but not slaved");
610 */
611     }
612   }
613
614   if (slaved && asink->slaving_disabled) {
615     guint64 threshold;
616
617     threshold = gst_util_uint64_scale_int (buf->spec.rate, 5, 1);
618     threshold += asink->last_resync_sample;
619
620     if (*sample >= threshold) {
621       GST_INFO_OBJECT (asink, "last sync %" G_GINT64_FORMAT
622           " reached sample %" G_GINT64_FORMAT ", enabling slaving",
623           asink->last_resync_sample, *sample);
624       g_object_set (asink, "slave-method", GST_BASE_AUDIO_SINK_SLAVE_SKEW,
625           NULL);
626       asink->slaving_disabled = FALSE;
627     }
628   }
629
630   bps = buf->spec.bytes_per_sample;
631   bufsize = buf->spec.segsize * buf->spec.segtotal;
632
633   /* our toy resampler for trick modes */
634   reverse = out_samples < 0;
635   out_samples = ABS (out_samples);
636
637   if (in_samples >= out_samples)
638     toprocess = &in_samples;
639   else
640     toprocess = &out_samples;
641
642   inr = in_samples - 1;
643   outr = out_samples - 1;
644
645   GST_LOG_OBJECT (asink, "in %d, out %d reverse %d sync %d", inr, outr,
646       reverse, sync);
647
648   /* data_end points to the last sample we have to write, not past it. This is
649    * needed to properly handle reverse playback: it points to the last sample. */
650   data_end = data + (bps * inr);
651
652   while (*toprocess > 0) {
653     if (sync) {
654       size_t avail;
655       guint towrite;
656       gint err;
657       guint8 *d, *d_end;
658       gpointer buffer_handle;
659
660       position = audioflinger_device_get_position (asink->audioflinger_device);
661       avail = out_samples;
662       buffer_handle = NULL;
663       GST_LOG_OBJECT (asink, "calling obtain buffer, position %d"
664           " offset %" G_GINT64_FORMAT " samples %" G_GSSIZE_FORMAT,
665           position, *sample, avail);
666       err = audioflinger_device_obtain_buffer (asink->audioflinger_device,
667           &buffer_handle, (int8_t **) & d, &avail, *sample);
668       GST_LOG_OBJECT (asink, "obtain buffer returned");
669       if (err < 0) {
670         GST_LOG_OBJECT (asink, "obtain buffer error %d, state %d",
671             err, buf->state);
672         LOGD ("obtain buffer error 0x%x, state %d", err, buf->state);
673
674         if (err == LATE)
675           skip = TRUE;
676         else if (buf->state != GST_RING_BUFFER_STATE_STARTED)
677           goto done;
678         else
679           goto obtain_buffer_failed;
680       }
681
682       towrite = avail * bps;
683       d_end = d + towrite;
684
685       GST_LOG_OBJECT (asink, "writing %u samples at offset %" G_GUINT64_FORMAT,
686           (guint) avail, *sample);
687
688       if (G_LIKELY (inr == outr && !reverse)) {
689         FWD_SAMPLES (data, data_end, d, d_end);
690       } else if (!reverse) {
691         if (inr >= outr) {
692           /* forward speed up */
693           FWD_UP_SAMPLES (data, data_end, d, d_end);
694         } else {
695           /* forward slow down */
696           FWD_DOWN_SAMPLES (data, data_end, d, d_end);
697         }
698       } else {
699         if (inr >= outr)
700           /* reverse speed up */
701           REV_UP_SAMPLES (data, data_end, d, d_end);
702         else
703           /* reverse slow down */
704           REV_DOWN_SAMPLES (data, data_end, d, d_end);
705       }
706
707       *sample += avail;
708
709       if (buffer_handle)
710         audioflinger_device_release_buffer (asink->audioflinger_device,
711             buffer_handle);
712     } else {
713       gint written;
714
715       written = audioflinger_device_write (asink->audioflinger_device, data,
716           *toprocess * bps);
717       if (written > 0) {
718         *toprocess -= written / bps;
719         data += written;
720       } else {
721         LOGE ("Error to write buffer(error=%d)", written);
722         GST_LOG_OBJECT (asink, "Error to write buffer(error=%d)", written);
723         goto start_failed;
724       }
725     }
726   }
727 skip:
728   /* we consumed all samples here */
729   data = data_end + bps;
730
731 done:
732   result = inr - ((data_end - data) / bps);
733   GST_LOG_OBJECT (asink, "wrote %d samples", result);
734
735   return result;
736
737   /* ERRORS */
738 no_start:
739   {
740     GST_LOG_OBJECT (asink, "we can not start");
741     LOGE ("we can not start");
742     return 0;
743   }
744 start_failed:
745   {
746     GST_LOG_OBJECT (asink, "failed to start the ringbuffer");
747     LOGE ("failed to start the ringbuffer");
748     return 0;
749   }
750 obtain_buffer_failed:
751   {
752     GST_ELEMENT_ERROR (asink, RESOURCE, FAILED,
753         ("obtain_buffer failed"), (NULL));
754     LOGE ("obtain_buffer failed");
755     return -1;
756   }
757 }
758
759 static GstElementClass *parent_class = NULL;
760
761 GType
762 gst_audioflinger_sink_get_type (void)
763 {
764   static GType audioflingersink_type = 0;
765
766   if (!audioflingersink_type) {
767     static const GTypeInfo audioflingersink_info = {
768       sizeof (GstAudioFlingerSinkClass),
769       gst_audioflinger_sink_base_init,
770       NULL,
771       (GClassInitFunc) gst_audioflinger_sink_class_init,
772       NULL,
773       NULL,
774       sizeof (GstAudioFlingerSink),
775       0,
776       (GInstanceInitFunc) gst_audioflinger_sink_init,
777     };
778
779     audioflingersink_type =
780         g_type_register_static (GST_TYPE_AUDIO_SINK, "GstAudioFlingerSink",
781         &audioflingersink_info, 0);
782   }
783
784   return audioflingersink_type;
785 }
786
787 static void
788 gst_audioflinger_sink_dispose (GObject * object)
789 {
790   GstAudioFlingerSink *audioflinger_sink = GST_AUDIOFLINGERSINK (object);
791
792   if (audioflinger_sink->probed_caps) {
793     gst_caps_unref (audioflinger_sink->probed_caps);
794     audioflinger_sink->probed_caps = NULL;
795   }
796
797   G_OBJECT_CLASS (parent_class)->dispose (object);
798 }
799
800 static void
801 gst_audioflinger_sink_base_init (gpointer g_class)
802 {
803   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
804
805   gst_element_class_set_details (element_class, &gst_audioflinger_sink_details);
806
807   gst_element_class_add_pad_template (element_class,
808       gst_static_pad_template_get (&audioflingersink_sink_factory));
809   GST_DEBUG_CATEGORY_INIT (audioflinger_debug, "audioflingersink", 0,
810       "audioflinger sink trace");
811 }
812
813 static void
814 gst_audioflinger_sink_class_init (GstAudioFlingerSinkClass * klass)
815 {
816   GObjectClass *gobject_class;
817   GstElementClass *gstelement_class;
818   GstBaseSinkClass *gstbasesink_class;
819   GstBaseAudioSinkClass *gstbaseaudiosink_class;
820   GstAudioSinkClass *gstaudiosink_class;
821
822   gobject_class = (GObjectClass *) klass;
823   gstelement_class = (GstElementClass *) klass;
824   gstbasesink_class = (GstBaseSinkClass *) klass;
825   gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
826   gstaudiosink_class = (GstAudioSinkClass *) klass;
827
828   parent_class = g_type_class_peek_parent (klass);
829
830   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_audioflinger_sink_dispose);
831   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_audioflinger_sink_finalise);
832   gobject_class->get_property =
833       GST_DEBUG_FUNCPTR (gst_audioflinger_sink_get_property);
834   gobject_class->set_property =
835       GST_DEBUG_FUNCPTR (gst_audioflinger_sink_set_property);
836
837   gstelement_class->provide_clock =
838       GST_DEBUG_FUNCPTR (gst_audioflinger_sink_provide_clock);
839   gstelement_class->change_state =
840       GST_DEBUG_FUNCPTR (gst_audioflinger_sink_change_state);
841
842   gstbasesink_class->get_caps =
843       GST_DEBUG_FUNCPTR (gst_audioflinger_sink_getcaps);
844
845   gstbaseaudiosink_class->create_ringbuffer =
846       GST_DEBUG_FUNCPTR (gst_audioflinger_sink_create_ringbuffer);
847
848   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_audioflinger_sink_event);
849   gstbasesink_class->preroll =
850       GST_DEBUG_FUNCPTR (gst_audioflinger_sink_preroll);
851
852   /* Install properties */
853   g_object_class_install_property (gobject_class, PROP_MUTE,
854       g_param_spec_boolean ("mute", "Mute",
855           "Mute output", DEFAULT_MUTE, G_PARAM_READWRITE));
856   g_object_class_install_property (gobject_class, PROP_VOLUME,
857       g_param_spec_double ("volume", "Volume",
858           "control volume size", 0.0, 10.0, DEFAULT_VOLUME, G_PARAM_READWRITE));
859   g_object_class_install_property (gobject_class, PROP_AUDIO_SINK,
860       g_param_spec_pointer ("audiosink", "AudioSink",
861           "The pointer of MediaPlayerBase::AudioSink", G_PARAM_WRITABLE));
862 }
863
864 static void
865 gst_audioflinger_sink_init (GstAudioFlingerSink * audioflinger_sink)
866 {
867   GST_DEBUG_OBJECT (audioflinger_sink, "initializing audioflinger_sink");
868   LOGD ("initializing audioflinger_sink");
869
870   audioflinger_sink->audio_clock = NULL;
871   audioflinger_sink->system_clock = NULL;
872   audioflinger_sink->system_audio_clock = NULL;
873   audioflinger_sink->exported_clock = NULL;
874   audioflinger_sink->export_system_audio_clock =
875       DEFAULT_EXPORT_SYSTEM_AUDIO_CLOCK;
876   gst_audioflinger_sink_reset (audioflinger_sink, TRUE);
877 }
878
879 static void
880 gst_audioflinger_sink_reset (GstAudioFlingerSink * sink, gboolean create_clocks)
881 {
882
883   if (sink->audioflinger_device != NULL) {
884     audioflinger_device_release (sink->audioflinger_device);
885     sink->audioflinger_device = NULL;
886   }
887
888   sink->audioflinger_device = NULL;
889   sink->m_volume = DEFAULT_VOLUME;
890   sink->m_mute = DEFAULT_MUTE;
891   sink->m_init = FALSE;
892   sink->m_audiosink = NULL;
893   sink->eos = FALSE;
894   sink->may_provide_clock = TRUE;
895   sink->last_resync_sample = -1;
896
897   if (sink->system_clock) {
898     GstClock *clock = sink->system_clock;
899
900     GST_INFO_OBJECT (sink, "destroying system_clock %d",
901         GST_OBJECT_REFCOUNT (sink->system_clock));
902     gst_clock_set_master (sink->system_clock, NULL);
903     gst_object_replace ((GstObject **) & sink->system_clock, NULL);
904     GST_INFO_OBJECT (sink, "destroyed system_clock");
905     GST_INFO_OBJECT (sink, "destroying system_audio_clock %d",
906         GST_OBJECT_REFCOUNT (sink->system_audio_clock));
907     gst_object_replace ((GstObject **) & sink->system_audio_clock, NULL);
908     GST_INFO_OBJECT (sink, "destroyed system_audio_clock");
909   }
910
911   if (sink->audio_clock) {
912     GST_INFO_OBJECT (sink, "destroying audio clock %d",
913         GST_OBJECT_REFCOUNT (sink->audio_clock));
914
915     gst_object_replace ((GstObject **) & sink->audio_clock, NULL);
916   }
917
918   if (sink->exported_clock) {
919     GST_INFO_OBJECT (sink, "destroying exported clock %d",
920         GST_OBJECT_REFCOUNT (sink->exported_clock));
921     gst_object_replace ((GstObject **) & sink->exported_clock, NULL);
922     GST_INFO_OBJECT (sink, "destroyed exported clock");
923   }
924
925   if (create_clocks) {
926     GstClockTime external, internal;
927
928     /* create the audio clock that uses the ringbuffer as its audio source */
929     sink->audio_clock = gst_audio_clock_new ("GstAudioFlingerSinkClock",
930         gst_audioflinger_sink_get_time, sink);
931
932     /* always set audio_clock as baseaudiosink's provided_clock */
933     gst_object_replace ((GstObject **) &
934         GST_BASE_AUDIO_SINK (sink)->provided_clock,
935         GST_OBJECT (sink->audio_clock));
936
937     /* create the system_audio_clock, which is an *audio clock* that uses an
938      * instance of the system clock as its time source */
939     sink->system_audio_clock =
940         gst_audio_clock_new ("GstAudioFlingerSystemAudioClock",
941         gst_audioflinger_sink_system_audio_clock_get_time, sink);
942
943     /* create an instance of the system clock, that we slave to
944      * sink->audio_clock to have an audio clock with an higher resolution than
945      * the segment size (50ms) */
946     sink->system_clock = g_object_new (GST_TYPE_SYSTEM_CLOCK,
947         "name", "GstAudioFlingerSystemClock", NULL);
948
949     /* calibrate the clocks */
950     external = gst_clock_get_time (sink->audio_clock);
951     internal = gst_clock_get_internal_time (sink->system_clock);
952     gst_clock_set_calibration (sink->system_clock, internal, external, 1, 1);
953
954     /* slave the system clock to the audio clock */
955     GST_OBJECT_FLAG_SET (sink->system_clock, GST_CLOCK_FLAG_CAN_SET_MASTER);
956     g_object_set (sink->system_clock, "timeout", 50 * GST_MSECOND, NULL);
957     gst_clock_set_master (sink->system_clock, sink->audio_clock);
958   }
959
960 }
961
962 static void
963 gst_audioflinger_sink_finalise (GObject * object)
964 {
965   GstAudioFlingerSink *audioflinger_sink = GST_AUDIOFLINGERSINK (object);
966
967   GST_INFO_OBJECT (object, "finalize");
968
969   gst_audioflinger_sink_reset (audioflinger_sink, FALSE);
970
971   G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (object));
972 }
973
974 static GstRingBuffer *
975 gst_audioflinger_sink_create_ringbuffer (GstBaseAudioSink * sink)
976 {
977   GstRingBuffer *buffer;
978
979   GST_DEBUG_OBJECT (sink, "creating ringbuffer");
980   LOGD ("creating ringbuffer");
981   buffer = g_object_new (GST_TYPE_ANDROID_AUDIORING_BUFFER, NULL);
982   GST_DEBUG_OBJECT (sink, "created ringbuffer @%p", buffer);
983   LOGD ("created ringbuffer @%p", buffer);
984
985   return buffer;
986 }
987
988 static void
989 gst_audioflinger_sink_get_property (GObject * object, guint prop_id,
990     GValue * value, GParamSpec * pspec)
991 {
992   GstAudioFlingerSink *audioflinger_sink;
993
994   audioflinger_sink = GST_AUDIOFLINGERSINK (object);
995   g_return_if_fail (audioflinger_sink != NULL);
996
997   switch (prop_id) {
998     case PROP_MUTE:
999       g_value_set_boolean (value, audioflinger_sink->m_mute);
1000       GST_DEBUG_OBJECT (audioflinger_sink, "get mute: %d",
1001           audioflinger_sink->m_mute);
1002       LOGD ("get mute: %d", audioflinger_sink->m_mute);
1003       break;
1004     case PROP_VOLUME:
1005       g_value_set_double (value, audioflinger_sink->m_volume);
1006       GST_DEBUG_OBJECT (audioflinger_sink, "get volume: %f",
1007           audioflinger_sink->m_volume);
1008       LOGD ("get volume: %f", audioflinger_sink->m_volume);
1009       break;
1010     case PROP_AUDIO_SINK:
1011       GST_ERROR_OBJECT (audioflinger_sink, "Shall not go here!");
1012       LOGD ("Shall not go here!");
1013       break;
1014     default:
1015       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1016       break;
1017   }
1018 }
1019
1020 static void
1021 gst_audioflinger_sink_set_property (GObject * object, guint prop_id,
1022     const GValue * value, GParamSpec * pspec)
1023 {
1024   GstAudioFlingerSink *audioflinger_sink;
1025   audioflinger_sink = GST_AUDIOFLINGERSINK (object);
1026
1027   g_return_if_fail (audioflinger_sink != NULL);
1028   GST_OBJECT_LOCK (audioflinger_sink);
1029   switch (prop_id) {
1030     case PROP_MUTE:
1031       audioflinger_sink->m_mute = g_value_get_boolean (value);
1032       GST_DEBUG_OBJECT (audioflinger_sink, "set mute: %d",
1033           audioflinger_sink->m_mute);
1034       LOGD ("set mute: %d", audioflinger_sink->m_mute);
1035       /* set device if it's initialized */
1036       if (audioflinger_sink->audioflinger_device && audioflinger_sink->m_init)
1037         gst_audioflinger_sink_set_mute (audioflinger_sink,
1038             (int) (audioflinger_sink->m_mute));
1039       break;
1040     case PROP_VOLUME:
1041       audioflinger_sink->m_volume = g_value_get_double (value);
1042       GST_DEBUG_OBJECT (audioflinger_sink, "set volume: %f",
1043           audioflinger_sink->m_volume);
1044       LOGD ("set volume: %f", audioflinger_sink->m_volume);
1045       /* set device if it's initialized */
1046       if (audioflinger_sink->audioflinger_device && audioflinger_sink->m_init)
1047         gst_audioflinger_sink_set_volume (audioflinger_sink,
1048             (float) audioflinger_sink->m_volume);
1049       break;
1050     case PROP_AUDIO_SINK:
1051       audioflinger_sink->m_audiosink = g_value_get_pointer (value);
1052       GST_DEBUG_OBJECT (audioflinger_sink, "set audiosink: %p",
1053           audioflinger_sink->m_audiosink);
1054       LOGD ("set audiosink: %p", audioflinger_sink->m_audiosink);
1055       break;
1056     default:
1057       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1058       break;
1059   }
1060   GST_OBJECT_UNLOCK (audioflinger_sink);
1061 }
1062
1063 static GstCaps *
1064 gst_audioflinger_sink_getcaps (GstBaseSink * bsink)
1065 {
1066   GstAudioFlingerSink *audioflinger_sink;
1067   GstCaps *caps;
1068
1069   audioflinger_sink = GST_AUDIOFLINGERSINK (bsink);
1070   GST_DEBUG_OBJECT (audioflinger_sink, "enter,%p",
1071       audioflinger_sink->audioflinger_device);
1072   LOGD ("gst_audioflinger_sink_getcaps,%p",
1073       audioflinger_sink->audioflinger_device);
1074   if (audioflinger_sink->audioflinger_device == NULL
1075       || audioflinger_sink->m_init == FALSE) {
1076     caps =
1077         gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD
1078             (bsink)));
1079   } else if (audioflinger_sink->probed_caps) {
1080     caps = gst_caps_copy (audioflinger_sink->probed_caps);
1081   } else {
1082     caps = gst_caps_new_any ();
1083     if (caps && !gst_caps_is_empty (caps)) {
1084       audioflinger_sink->probed_caps = gst_caps_copy (caps);
1085     }
1086   }
1087
1088   return caps;
1089 }
1090
1091 static gboolean
1092 gst_audioflinger_sink_open (GstAudioFlingerSink * audioflinger)
1093 {
1094   GstBaseAudioSink *baseaudiosink = (GstBaseAudioSink *) audioflinger;
1095
1096   GST_DEBUG_OBJECT (audioflinger, "enter");
1097   LOGD ("gst_audioflinger_sink_open");
1098   g_return_val_if_fail (audioflinger != NULL, FALSE);
1099
1100   baseaudiosink->buffer_time = DEFAULT_BUFFERTIME;
1101   baseaudiosink->latency_time = DEFAULT_LATENCYTIME;
1102
1103   if (audioflinger->audioflinger_device == NULL) {
1104     if (audioflinger->m_audiosink) {
1105       if (!(audioflinger->audioflinger_device =
1106               audioflinger_device_open (audioflinger->m_audiosink)))
1107         goto failed_creation;
1108       GST_DEBUG_OBJECT (audioflinger, "open an existed flinger, %p",
1109           audioflinger->audioflinger_device);
1110       LOGD ("open an existed flinger, %p", audioflinger->audioflinger_device);
1111     } else {
1112       if (!(audioflinger->audioflinger_device = audioflinger_device_create ()))
1113         goto failed_creation;
1114       GST_DEBUG_OBJECT (audioflinger, "create a new flinger, %p",
1115           audioflinger->audioflinger_device);
1116       LOGD ("create a new flinger, %p", audioflinger->audioflinger_device);
1117     }
1118   }
1119   return TRUE;
1120
1121   /* ERRORS */
1122 failed_creation:
1123   {
1124     GST_ELEMENT_ERROR (audioflinger, RESOURCE, SETTINGS, (NULL),
1125         ("Failed to create AudioFlinger"));
1126     LOGE ("Failed to create AudioFlinger");
1127     return FALSE;
1128   }
1129 }
1130
1131 static gboolean
1132 gst_audioflinger_sink_close (GstAudioFlingerSink * audioflinger)
1133 {
1134   GST_DEBUG_OBJECT (audioflinger, "enter");
1135   LOGD ("gst_audioflinger_sink_close");
1136
1137   if (audioflinger->audioflinger_device != NULL) {
1138     GST_DEBUG_OBJECT (audioflinger, "release flinger device");
1139     LOGD ("release flinger device");
1140     audioflinger_device_stop (audioflinger->audioflinger_device);
1141     audioflinger_device_release (audioflinger->audioflinger_device);
1142     audioflinger->audioflinger_device = NULL;
1143   }
1144   return TRUE;
1145 }
1146
1147 static gboolean
1148 gst_audioflinger_sink_prepare (GstAudioFlingerSink * audioflinger,
1149     GstRingBufferSpec * spec)
1150 {
1151   GST_DEBUG_OBJECT (audioflinger, "enter");
1152   LOGD ("gst_audioflinger_sink_prepare");
1153
1154   /* FIXME: 
1155    * 
1156    * Pipeline crashes in audioflinger_device_set(), after releasing audio
1157    * flinger device and creating it again. In most cases, it will happen when
1158    * playing the same audio again.
1159    *
1160    * It seems the root cause is we create and release audio flinger sink in
1161    * different thread in playbin2. Till now, I haven't found way to
1162    * create/release device in the same thread. Fortunately, it will not effect
1163    * the gst-launch usage 
1164    */
1165   if (audioflinger_device_set (audioflinger->audioflinger_device,
1166           3, spec->channels, spec->rate, spec->segsize) == -1)
1167     goto failed_creation;
1168
1169   audioflinger->m_init = TRUE;
1170 //  gst_audioflinger_sink_set_volume (audioflinger, audioflinger->m_volume);
1171 //  gst_audioflinger_sink_set_mute (audioflinger, audioflinger->m_mute);
1172   spec->bytes_per_sample = (spec->width / 8) * spec->channels;
1173   audioflinger->bytes_per_sample = spec->bytes_per_sample;
1174
1175   spec->segsize =
1176       audioflinger_device_frameCount (audioflinger->audioflinger_device);
1177
1178   GST_DEBUG_OBJECT (audioflinger,
1179       "channels: %d, rate: %d, width: %d, got segsize: %d, segtotal: %d, "
1180       "frame count: %d, frame size: %d",
1181       spec->channels, spec->rate, spec->width, spec->segsize, spec->segtotal,
1182       audioflinger_device_frameCount (audioflinger->audioflinger_device),
1183       audioflinger_device_frameSize (audioflinger->audioflinger_device)
1184       );
1185   LOGD ("channels: %d, rate: %d, width: %d, got segsize: %d, segtotal: %d, "
1186       "frame count: %d, frame size: %d",
1187       spec->channels, spec->rate, spec->width, spec->segsize, spec->segtotal,
1188       audioflinger_device_frameCount (audioflinger->audioflinger_device),
1189       audioflinger_device_frameSize (audioflinger->audioflinger_device)
1190       );
1191
1192 #if 0
1193   GST_DEBUG_OBJECT (audioflinger, "pause device");
1194   LOGD ("pause device");
1195   audioflinger_device_pause (audioflinger->audioflinger_device);
1196 #endif
1197
1198   return TRUE;
1199
1200   /* ERRORS */
1201 failed_creation:
1202   {
1203     GST_ELEMENT_ERROR (audioflinger, RESOURCE, SETTINGS, (NULL),
1204         ("Failed to create AudioFlinger for format %d", spec->format));
1205     LOGE ("Failed to create AudioFlinger for format %d", spec->format);
1206     return FALSE;
1207   }
1208 dodgy_width:
1209   {
1210     GST_ELEMENT_ERROR (audioflinger, RESOURCE, SETTINGS, (NULL),
1211         ("Unhandled width %d", spec->width));
1212     LOGE ("Unhandled width %d", spec->width);
1213     return FALSE;
1214   }
1215 }
1216
1217 static gboolean
1218 gst_audioflinger_sink_unprepare (GstAudioFlingerSink * audioflinger)
1219 {
1220   GST_DEBUG_OBJECT (audioflinger, "enter");
1221   LOGD ("gst_audioflinger_sink_unprepare");
1222
1223   if (audioflinger->audioflinger_device != NULL) {
1224     GST_DEBUG_OBJECT (audioflinger, "release flinger device");
1225     LOGD ("release flinger device");
1226     audioflinger_device_stop (audioflinger->audioflinger_device);
1227     audioflinger->m_init = FALSE;
1228   }
1229
1230   return TRUE;
1231 }
1232
1233 static void
1234 gst_audioflinger_sink_set_mute (GstAudioFlingerSink * audioflinger_sink,
1235     gboolean mute)
1236 {
1237   GST_DEBUG_OBJECT (audioflinger_sink, "set PROP_MUTE = %d\n", mute);
1238   LOGD ("set PROP_MUTE = %d\n", mute);
1239
1240   if (audioflinger_sink->audioflinger_device)
1241     audioflinger_device_mute (audioflinger_sink->audioflinger_device, mute);
1242   audioflinger_sink->m_mute = mute;
1243 }
1244
1245 static void
1246 gst_audioflinger_sink_set_volume (GstAudioFlingerSink * audioflinger_sink,
1247     float volume)
1248 {
1249   GST_DEBUG_OBJECT (audioflinger_sink, "set PROP_VOLUME = %f\n", volume);
1250   LOGD ("set PROP_VOLUME = %f\n", volume);
1251
1252   if (audioflinger_sink->audioflinger_device != NULL) {
1253     audioflinger_device_set_volume (audioflinger_sink->audioflinger_device,
1254         volume, volume);
1255   }
1256 }
1257
1258 gboolean
1259 gst_audioflinger_sink_plugin_init (GstPlugin * plugin)
1260 {
1261   return gst_element_register (plugin, "audioflingersink", GST_RANK_PRIMARY,
1262       GST_TYPE_AUDIOFLINGERSINK);
1263 }
1264
1265 /*
1266 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "audioflingersink",
1267     "audioflinger sink audio", plugin_init, VERSION, "LGPL", "GStreamer",
1268     "http://gstreamer.net/")
1269     */
1270
1271 static GstClock *
1272 gst_audioflinger_sink_provide_clock (GstElement * elem)
1273 {
1274   GstBaseAudioSink *sink;
1275   GstAudioFlingerSink *asink;
1276   GstClock *clock;
1277
1278   sink = GST_BASE_AUDIO_SINK (elem);
1279   asink = GST_AUDIOFLINGERSINK (elem);
1280
1281   /* we have no ringbuffer (must be NULL state) */
1282   if (sink->ringbuffer == NULL)
1283     goto wrong_state;
1284
1285   if (!gst_ring_buffer_is_acquired (sink->ringbuffer))
1286     goto wrong_state;
1287
1288   GST_OBJECT_LOCK (sink);
1289   if (!asink->may_provide_clock)
1290     goto already_playing;
1291
1292   if (!sink->provide_clock)
1293     goto clock_disabled;
1294
1295   clock = GST_CLOCK_CAST (gst_object_ref (asink->exported_clock));
1296   GST_INFO_OBJECT (asink, "providing clock %p %s", clock,
1297       clock == NULL ? NULL : GST_OBJECT_NAME (clock));
1298   GST_OBJECT_UNLOCK (sink);
1299
1300   return clock;
1301
1302   /* ERRORS */
1303 wrong_state:
1304   {
1305     GST_DEBUG_OBJECT (sink, "ringbuffer not acquired");
1306     LOGD ("ringbuffer not acquired");
1307     return NULL;
1308   }
1309 already_playing:
1310   {
1311     GST_INFO_OBJECT (sink, "we went to playing already");
1312     GST_OBJECT_UNLOCK (sink);
1313     return NULL;
1314   }
1315 clock_disabled:
1316   {
1317     GST_DEBUG_OBJECT (sink, "clock provide disabled");
1318     LOGD ("clock provide disabled");
1319     GST_OBJECT_UNLOCK (sink);
1320     return NULL;
1321   }
1322 }
1323
1324 static GstStateChangeReturn
1325 gst_audioflinger_sink_change_state (GstElement * element,
1326     GstStateChange transition)
1327 {
1328   GstStateChangeReturn ret;
1329   GstClockTime time;
1330   GstAudioFlingerSink *sink = GST_AUDIOFLINGERSINK (element);
1331
1332   switch (transition) {
1333     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1334       sink->may_provide_clock = FALSE;
1335       if (sink->exported_clock == sink->system_audio_clock) {
1336         GstClockTime cinternal, cexternal, crate_num, crate_denom;
1337
1338         /* take the slave lock to make sure that the slave_callback doesn't run
1339          * while we're moving sink->audio_clock forward, causing
1340          * sink->system_clock to jump as well */
1341         GST_CLOCK_SLAVE_LOCK (sink->system_clock);
1342         gst_clock_get_calibration (sink->audio_clock, NULL, NULL,
1343             &crate_num, &crate_denom);
1344         cinternal = gst_clock_get_internal_time (sink->audio_clock);
1345         cexternal = gst_clock_get_time (GST_ELEMENT_CLOCK (sink));
1346         gst_clock_set_calibration (sink->audio_clock, cinternal, cexternal,
1347             crate_num, crate_denom);
1348         /* reset observations */
1349         sink->system_clock->filling = TRUE;
1350         sink->system_clock->time_index = 0;
1351         GST_CLOCK_SLAVE_UNLOCK (sink->system_clock);
1352
1353         time = gst_clock_get_time (sink->audio_clock);
1354         GST_INFO_OBJECT (sink, "PAUSED_TO_PLAYING,"
1355             " base_time %" GST_TIME_FORMAT
1356             " after %" GST_TIME_FORMAT
1357             " internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT,
1358             GST_TIME_ARGS (GST_ELEMENT (sink)->base_time),
1359             GST_TIME_ARGS (time),
1360             GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal));
1361       }
1362       break;
1363     default:
1364       break;
1365   }
1366
1367   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1368
1369   switch (transition) {
1370     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1371       break;
1372     default:
1373       break;
1374   }
1375   return ret;
1376 }
1377
1378 static GstFlowReturn
1379 gst_audioflinger_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
1380 {
1381   GstFlowReturn ret;
1382   gboolean us_live = FALSE;
1383   GstQuery *query;
1384   GstAudioFlingerSink *asink = GST_AUDIOFLINGERSINK (bsink);
1385   GstBaseAudioSink *baseaudiosink = GST_BASE_AUDIO_SINK (bsink);
1386   GstClock *clock;
1387
1388   GST_INFO_OBJECT (bsink, "preroll");
1389
1390   ret = GST_BASE_SINK_CLASS (parent_class)->preroll (bsink, buffer);
1391   if (ret != GST_FLOW_OK)
1392     goto done;
1393
1394   if (asink->exported_clock != NULL) {
1395     GST_INFO_OBJECT (bsink, "clock already exported");
1396     goto done;
1397   }
1398
1399   query = gst_query_new_latency ();
1400
1401   /* ask the peer for the latency */
1402   if (gst_pad_peer_query (bsink->sinkpad, query)) {
1403     /* get upstream min and max latency */
1404     gst_query_parse_latency (query, &us_live, NULL, NULL);
1405     GST_INFO_OBJECT (bsink, "query result live: %d", us_live);
1406   } else {
1407     GST_WARNING_OBJECT (bsink, "latency query failed");
1408   }
1409   gst_query_unref (query);
1410
1411   if (!us_live && asink->export_system_audio_clock) {
1412     clock = asink->system_audio_clock;
1413     /* set SLAVE_NONE so that baseaudiosink doesn't try to slave audio_clock to
1414      * system_audio_clock
1415      */
1416     g_object_set (asink, "slave-method", GST_BASE_AUDIO_SINK_SLAVE_NONE, NULL);
1417   } else {
1418     clock = asink->audio_clock;
1419   }
1420
1421   GST_INFO_OBJECT (bsink, "using %s clock",
1422       clock == asink->audio_clock ? "audio" : "system_audio");
1423   gst_object_replace ((GstObject **) & asink->exported_clock,
1424       GST_OBJECT (clock));
1425   GST_OBJECT_UNLOCK (asink);
1426
1427 done:
1428   return ret;
1429 }
1430
1431 static gboolean
1432 gst_audioflinger_sink_event (GstBaseSink * bsink, GstEvent * event)
1433 {
1434   GstAudioFlingerSink *asink = GST_AUDIOFLINGERSINK (bsink);
1435   GstBaseAudioSink *baseaudiosink = GST_BASE_AUDIO_SINK (bsink);
1436   GstRingBuffer *ringbuf = baseaudiosink->ringbuffer;
1437
1438   switch (GST_EVENT_TYPE (event)) {
1439     case GST_EVENT_EOS:
1440       GST_INFO_OBJECT (asink, "got EOS");
1441       asink->eos = TRUE;
1442
1443       if (baseaudiosink->next_sample) {
1444         guint64 next_sample, sample;
1445         gint sps;
1446         GstFlowReturn ret;
1447         GstBuffer *buf;
1448
1449         sps = ringbuf->spec.segsize / ringbuf->spec.bytes_per_sample;
1450         sample = baseaudiosink->next_sample;
1451         next_sample = baseaudiosink->next_sample / sps;
1452         if (next_sample < ringbuf->spec.segsize) {
1453           gint samples, out_samples, accum, size;
1454           GstClockTime timestamp, before, after;
1455           guchar *data, *data_start;
1456           gint64 drift_tolerance;
1457           guint written;
1458           gint64 offset;
1459
1460           samples = (ringbuf->spec.segsize - next_sample) * 4;
1461
1462           size = samples * ringbuf->spec.bytes_per_sample;
1463
1464           timestamp = gst_util_uint64_scale_int (baseaudiosink->next_sample,
1465               GST_SECOND, ringbuf->spec.rate);
1466
1467           before = gst_clock_get_internal_time (asink->audio_clock);
1468           GST_INFO_OBJECT (asink, "%" G_GINT64_FORMAT " < %d, "
1469               "padding with silence, samples %d size %d ts %" GST_TIME_FORMAT,
1470               next_sample, ringbuf->spec.segsize, samples, size,
1471               GST_TIME_ARGS (timestamp));
1472           LOGD ("PADDING");
1473
1474           data_start = data = g_malloc0 (size);
1475           offset = baseaudiosink->next_sample;
1476           out_samples = samples;
1477
1478           GST_STATE_LOCK (bsink);
1479           do {
1480             written =
1481                 gst_ring_buffer_commit_full (ringbuf, &offset, data, samples,
1482                 out_samples, &accum);
1483
1484             GST_DEBUG_OBJECT (bsink, "wrote %u of %u", written, samples);
1485             /* if we wrote all, we're done */
1486             if (written == samples)
1487               break;
1488
1489             /* else something interrupted us and we wait for preroll. */
1490             if ((ret = gst_base_sink_wait_preroll (bsink)) != GST_FLOW_OK)
1491               break;
1492
1493             /* update the output samples. FIXME, this will just skip them when pausing
1494              * during trick mode */
1495             if (out_samples > written) {
1496               out_samples -= written;
1497               accum = 0;
1498             } else
1499               break;
1500
1501             samples -= written;
1502             data += written * ringbuf->spec.bytes_per_sample;
1503           } while (TRUE);
1504
1505
1506           GST_STATE_UNLOCK (bsink);
1507
1508           g_free (data_start);
1509           after = gst_clock_get_internal_time (asink->audio_clock);
1510
1511           GST_INFO_OBJECT (asink, "padded, left %d before %" GST_TIME_FORMAT
1512               " after %" GST_TIME_FORMAT, samples,
1513               GST_TIME_ARGS (before), GST_TIME_ARGS (after));
1514
1515
1516         } else {
1517           LOGD ("NOT PADDING 1");
1518         }
1519       } else {
1520         LOGD ("NOT PADDING 2");
1521       }
1522
1523       break;
1524     case GST_EVENT_BUFFERING_START:
1525       GST_INFO_OBJECT (asink, "buffering start");
1526       break;
1527     case GST_EVENT_BUFFERING_STOP:
1528     {
1529       gboolean slaved;
1530       GstClockTime cinternal, cexternal, crate_num, crate_denom;
1531       GstClockTime before, after;
1532
1533       gst_clock_get_calibration (asink->audio_clock, &cinternal, &cexternal,
1534           &crate_num, &crate_denom);
1535
1536       before = gst_clock_get_time (asink->audio_clock);
1537
1538       cinternal = gst_clock_get_internal_time (asink->audio_clock);
1539       cexternal = gst_clock_get_time (GST_ELEMENT_CLOCK (asink));
1540       gst_clock_set_calibration (asink->audio_clock, cinternal,
1541           cexternal, crate_num, crate_denom);
1542
1543       after = gst_clock_get_time (asink->audio_clock);
1544
1545       GST_INFO_OBJECT (asink, "buffering stopped, clock recalibrated"
1546           " before %" GST_TIME_FORMAT " after %" GST_TIME_FORMAT,
1547           GST_TIME_ARGS (before), GST_TIME_ARGS (after));
1548
1549       /* force baseaudiosink to resync from the next buffer */
1550       GST_BASE_AUDIO_SINK (asink)->next_sample = -1;
1551
1552       /* reset this so we allow some time before enabling slaving again */
1553       asink->last_resync_sample = -1;
1554       slaved = GST_ELEMENT_CLOCK (asink) != asink->exported_clock;
1555       if (slaved) {
1556         GST_INFO_OBJECT (asink, "disabling slaving");
1557         g_object_set (asink, "slave-method", GST_BASE_AUDIO_SINK_SLAVE_NONE,
1558             NULL);
1559         asink->slaving_disabled = TRUE;
1560       }
1561
1562       g_object_set (asink, "drift-tolerance", 200 * GST_MSECOND, NULL);
1563       break;
1564     }
1565     default:
1566       break;
1567   }
1568
1569   return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
1570 }
1571
1572 static GstClockTime
1573 gst_audioflinger_sink_get_time (GstClock * clock, gpointer user_data)
1574 {
1575   GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (user_data);
1576   uint32_t position = -1;
1577   GstAudioFlingerSink *asink = GST_AUDIOFLINGERSINK (sink);
1578   GstClockTime time = GST_CLOCK_TIME_NONE;
1579   GstClockTime ptime = GST_CLOCK_TIME_NONE;
1580   GstClockTime system_audio_clock_time = GST_CLOCK_TIME_NONE;
1581   GstClockTime offset = GST_CLOCK_TIME_NONE;
1582   GstClockTime adjusted_time = GST_CLOCK_TIME_NONE;
1583   GstClockTime cinternal, cexternal, crate_num, crate_denom;
1584
1585   gst_clock_get_calibration (clock, &cinternal, &cexternal,
1586       &crate_num, &crate_denom);
1587
1588   if (!asink->audioflinger_device || !asink->m_init) {
1589     GST_DEBUG_OBJECT (sink, "device not created yet");
1590
1591     goto out;
1592   }
1593
1594   if (!asink->audioflinger_device || !asink->m_init) {
1595     GST_DEBUG_OBJECT (sink, "device not created yet");
1596
1597     goto out;
1598   }
1599
1600   if (!sink->ringbuffer) {
1601     GST_DEBUG_OBJECT (sink, "NULL ringbuffer");
1602
1603     goto out;
1604   }
1605
1606   if (!sink->ringbuffer->acquired) {
1607     GST_DEBUG_OBJECT (sink, "ringbuffer not acquired");
1608
1609     goto out;
1610   }
1611
1612   position = audioflinger_device_get_position (asink->audioflinger_device);
1613   if (position == -1)
1614     goto out;
1615
1616   time = gst_util_uint64_scale_int (position, GST_SECOND,
1617       sink->ringbuffer->spec.rate);
1618
1619   offset = gst_audio_clock_adjust (GST_CLOCK (clock), 0);
1620   adjusted_time = gst_audio_clock_adjust (GST_CLOCK (clock), time);
1621
1622   if (asink->system_audio_clock)
1623     system_audio_clock_time = gst_clock_get_time (asink->system_audio_clock);
1624
1625   if (GST_ELEMENT_CLOCK (asink)
1626       && asink->audio_clock != GST_ELEMENT_CLOCK (asink))
1627     ptime = gst_clock_get_time (GST_ELEMENT_CLOCK (asink));
1628
1629 out:
1630   GST_DEBUG_OBJECT (sink,
1631       "clock %s processed samples %" G_GINT32_FORMAT " offset %" GST_TIME_FORMAT
1632       " time %" GST_TIME_FORMAT " pipeline time %" GST_TIME_FORMAT
1633       " system audio clock %" GST_TIME_FORMAT " adjusted_time %" GST_TIME_FORMAT
1634       " cinternal %" GST_TIME_FORMAT " cexternal %" GST_TIME_FORMAT,
1635       GST_OBJECT_NAME (clock), position, GST_TIME_ARGS (offset),
1636       GST_TIME_ARGS (time), GST_TIME_ARGS (ptime),
1637       GST_TIME_ARGS (system_audio_clock_time), GST_TIME_ARGS (adjusted_time),
1638       GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal));
1639
1640   return time;
1641 }
1642
1643 static GstClockTime
1644 gst_audioflinger_sink_system_audio_clock_get_time (GstClock * clock,
1645     gpointer user_data)
1646 {
1647   GstClockTime time, offset;
1648   GstAudioFlingerSink *sink = GST_AUDIOFLINGERSINK (user_data);
1649
1650   time = gst_clock_get_time (sink->system_clock);
1651   offset = gst_audio_clock_adjust (clock, (GstClockTime) 0);
1652   time -= offset;
1653
1654   return time;
1655 }