audiosrc: avoid deadlock
[platform/upstream/gstreamer.git] / gst-libs / gst / audio / gstaudiosrc.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2005 Wim Taymans <wim@fluendo.com>
4  *
5  * gstaudiosrc.c: simple audio src base class
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /**
24  * SECTION:gstaudiosrc
25  * @short_description: Simple base class for audio sources
26  * @see_also: #GstBaseAudioSrc, #GstRingBuffer, #GstAudioSrc.
27  *
28  * This is the most simple base class for audio sources that only requires
29  * subclasses to implement a set of simple functions:
30  *
31  * <variablelist>
32  *   <varlistentry>
33  *     <term>open()</term>
34  *     <listitem><para>Open the device.</para></listitem>
35  *   </varlistentry>
36  *   <varlistentry>
37  *     <term>prepare()</term>
38  *     <listitem><para>Configure the device with the specified format.</para></listitem>
39  *   </varlistentry>
40  *   <varlistentry>
41  *     <term>read()</term>
42  *     <listitem><para>Read samples from the device.</para></listitem>
43  *   </varlistentry>
44  *   <varlistentry>
45  *     <term>reset()</term>
46  *     <listitem><para>Unblock reads and flush the device.</para></listitem>
47  *   </varlistentry>
48  *   <varlistentry>
49  *     <term>delay()</term>
50  *     <listitem><para>Get the number of samples in the device but not yet read.
51  *     </para></listitem>
52  *   </varlistentry>
53  *   <varlistentry>
54  *     <term>unprepare()</term>
55  *     <listitem><para>Undo operations done by prepare.</para></listitem>
56  *   </varlistentry>
57  *   <varlistentry>
58  *     <term>close()</term>
59  *     <listitem><para>Close the device.</para></listitem>
60  *   </varlistentry>
61  * </variablelist>
62  *
63  * All scheduling of samples and timestamps is done in this base class
64  * together with #GstBaseAudioSrc using a default implementation of a
65  * #GstRingBuffer that uses threads.
66  *
67  * Last reviewed on 2006-09-27 (0.10.12)
68  */
69
70 #include <string.h>
71
72 #include "gstaudiosrc.h"
73
74 GST_DEBUG_CATEGORY_STATIC (gst_audio_src_debug);
75 #define GST_CAT_DEFAULT gst_audio_src_debug
76
77 #define GST_TYPE_AUDIORING_BUFFER        \
78         (gst_audioringbuffer_get_type())
79 #define GST_AUDIORING_BUFFER(obj)        \
80         (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIORING_BUFFER,GstAudioRingBuffer))
81 #define GST_AUDIORING_BUFFER_CLASS(klass) \
82         (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIORING_BUFFER,GstAudioRingBufferClass))
83 #define GST_AUDIORING_BUFFER_GET_CLASS(obj) \
84         (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_AUDIORING_BUFFER, GstAudioRingBufferClass))
85 #define GST_IS_AUDIORING_BUFFER(obj)     \
86         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIORING_BUFFER))
87 #define GST_IS_AUDIORING_BUFFER_CLASS(klass)\
88         (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIORING_BUFFER))
89
90 typedef struct _GstAudioRingBuffer GstAudioRingBuffer;
91 typedef struct _GstAudioRingBufferClass GstAudioRingBufferClass;
92
93 #define GST_AUDIORING_BUFFER_GET_COND(buf) (((GstAudioRingBuffer *)buf)->cond)
94 #define GST_AUDIORING_BUFFER_WAIT(buf)     (g_cond_wait (GST_AUDIORING_BUFFER_GET_COND (buf), GST_OBJECT_GET_LOCK (buf)))
95 #define GST_AUDIORING_BUFFER_SIGNAL(buf)   (g_cond_signal (GST_AUDIORING_BUFFER_GET_COND (buf)))
96 #define GST_AUDIORING_BUFFER_BROADCAST(buf)(g_cond_broadcast (GST_AUDIORING_BUFFER_GET_COND (buf)))
97
98 struct _GstAudioRingBuffer
99 {
100   GstRingBuffer object;
101
102   gboolean running;
103   gint queuedseg;
104
105   GCond *cond;
106 };
107
108 struct _GstAudioRingBufferClass
109 {
110   GstRingBufferClass parent_class;
111 };
112
113 static void gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass);
114 static void gst_audioringbuffer_init (GstAudioRingBuffer * ringbuffer,
115     GstAudioRingBufferClass * klass);
116 static void gst_audioringbuffer_dispose (GObject * object);
117 static void gst_audioringbuffer_finalize (GObject * object);
118
119 static GstRingBufferClass *ring_parent_class = NULL;
120
121 static gboolean gst_audioringbuffer_open_device (GstRingBuffer * buf);
122 static gboolean gst_audioringbuffer_close_device (GstRingBuffer * buf);
123 static gboolean gst_audioringbuffer_acquire (GstRingBuffer * buf,
124     GstRingBufferSpec * spec);
125 static gboolean gst_audioringbuffer_release (GstRingBuffer * buf);
126 static gboolean gst_audioringbuffer_start (GstRingBuffer * buf);
127 static gboolean gst_audioringbuffer_stop (GstRingBuffer * buf);
128 static guint gst_audioringbuffer_delay (GstRingBuffer * buf);
129
130 /* ringbuffer abstract base class */
131 static GType
132 gst_audioringbuffer_get_type (void)
133 {
134   static GType ringbuffer_type = 0;
135
136   if (!ringbuffer_type) {
137     static const GTypeInfo ringbuffer_info = {
138       sizeof (GstAudioRingBufferClass),
139       NULL,
140       NULL,
141       (GClassInitFunc) gst_audioringbuffer_class_init,
142       NULL,
143       NULL,
144       sizeof (GstAudioRingBuffer),
145       0,
146       (GInstanceInitFunc) gst_audioringbuffer_init,
147       NULL
148     };
149
150     ringbuffer_type =
151         g_type_register_static (GST_TYPE_RING_BUFFER, "GstAudioSrcRingBuffer",
152         &ringbuffer_info, 0);
153   }
154   return ringbuffer_type;
155 }
156
157 static void
158 gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass)
159 {
160   GObjectClass *gobject_class;
161   GstRingBufferClass *gstringbuffer_class;
162
163   gobject_class = (GObjectClass *) klass;
164   gstringbuffer_class = (GstRingBufferClass *) klass;
165
166   ring_parent_class = g_type_class_peek_parent (klass);
167
168   gobject_class->dispose = gst_audioringbuffer_dispose;
169   gobject_class->finalize = gst_audioringbuffer_finalize;
170
171   gstringbuffer_class->open_device =
172       GST_DEBUG_FUNCPTR (gst_audioringbuffer_open_device);
173   gstringbuffer_class->close_device =
174       GST_DEBUG_FUNCPTR (gst_audioringbuffer_close_device);
175   gstringbuffer_class->acquire =
176       GST_DEBUG_FUNCPTR (gst_audioringbuffer_acquire);
177   gstringbuffer_class->release =
178       GST_DEBUG_FUNCPTR (gst_audioringbuffer_release);
179   gstringbuffer_class->start = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
180   gstringbuffer_class->resume = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
181   gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop);
182
183   gstringbuffer_class->delay = GST_DEBUG_FUNCPTR (gst_audioringbuffer_delay);
184 }
185
186 typedef guint (*ReadFunc) (GstAudioSrc * src, gpointer data, guint length);
187
188 /* this internal thread does nothing else but read samples from the audio device.
189  * It will read each segment in the ringbuffer and will update the play
190  * pointer. 
191  * The start/stop methods control the thread.
192  */
193 static void
194 audioringbuffer_thread_func (GstRingBuffer * buf)
195 {
196   GstAudioSrc *src;
197   GstAudioSrcClass *csrc;
198   GstAudioRingBuffer *abuf = GST_AUDIORING_BUFFER (buf);
199   ReadFunc readfunc;
200   GstMessage *message;
201   GValue val = { 0 };
202
203   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
204   csrc = GST_AUDIO_SRC_GET_CLASS (src);
205
206   GST_DEBUG_OBJECT (src, "enter thread");
207
208   readfunc = csrc->read;
209   if (readfunc == NULL)
210     goto no_function;
211
212   /* FIXME: maybe we should at least use a custom pointer type here? */
213   g_value_init (&val, G_TYPE_POINTER);
214   g_value_set_pointer (&val, src->thread);
215   message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
216       GST_STREAM_STATUS_TYPE_ENTER, GST_ELEMENT_CAST (src));
217   gst_message_set_stream_status_object (message, &val);
218   GST_DEBUG_OBJECT (src, "posting ENTER stream status");
219   gst_element_post_message (GST_ELEMENT_CAST (src), message);
220
221   while (TRUE) {
222     gint left, len;
223     guint8 *readptr;
224     gint readseg;
225
226     if (gst_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) {
227       gint read;
228
229       left = len;
230       do {
231         read = readfunc (src, readptr, left);
232         GST_LOG_OBJECT (src, "transfered %d bytes of %d to segment %d", read,
233             left, readseg);
234         if (read < 0 || read > left) {
235           GST_WARNING_OBJECT (src,
236               "error reading data %d (reason: %s), skipping segment", read,
237               g_strerror (errno));
238           break;
239         }
240         left -= read;
241         readptr += read;
242       } while (left > 0);
243
244       /* we read one segment */
245       gst_ring_buffer_advance (buf, 1);
246     } else {
247       GST_OBJECT_LOCK (abuf);
248       if (!abuf->running)
249         goto stop_running;
250       if (G_UNLIKELY (g_atomic_int_get (&buf->state) ==
251               GST_RING_BUFFER_STATE_STARTED)) {
252         GST_OBJECT_UNLOCK (abuf);
253         continue;
254       }
255       GST_DEBUG_OBJECT (src, "signal wait");
256       GST_AUDIORING_BUFFER_SIGNAL (buf);
257       GST_DEBUG_OBJECT (src, "wait for action");
258       GST_AUDIORING_BUFFER_WAIT (buf);
259       GST_DEBUG_OBJECT (src, "got signal");
260       if (!abuf->running)
261         goto stop_running;
262       GST_DEBUG_OBJECT (src, "continue running");
263       GST_OBJECT_UNLOCK (abuf);
264     }
265   }
266
267   /* Will never be reached */
268   g_assert_not_reached ();
269   return;
270
271   /* ERROR */
272 no_function:
273   {
274     GST_DEBUG ("no write function, exit thread");
275     return;
276   }
277 stop_running:
278   {
279     GST_OBJECT_UNLOCK (abuf);
280     GST_DEBUG ("stop running, exit thread");
281     message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
282         GST_STREAM_STATUS_TYPE_LEAVE, GST_ELEMENT_CAST (src));
283     gst_message_set_stream_status_object (message, &val);
284     GST_DEBUG_OBJECT (src, "posting LEAVE stream status");
285     gst_element_post_message (GST_ELEMENT_CAST (src), message);
286     return;
287   }
288 }
289
290 static void
291 gst_audioringbuffer_init (GstAudioRingBuffer * ringbuffer,
292     GstAudioRingBufferClass * g_class)
293 {
294   ringbuffer->running = FALSE;
295   ringbuffer->queuedseg = 0;
296
297   ringbuffer->cond = g_cond_new ();
298 }
299
300 static void
301 gst_audioringbuffer_dispose (GObject * object)
302 {
303   GstAudioRingBuffer *ringbuffer = GST_AUDIORING_BUFFER (object);
304
305   if (ringbuffer->cond) {
306     g_cond_free (ringbuffer->cond);
307     ringbuffer->cond = NULL;
308   }
309
310   G_OBJECT_CLASS (ring_parent_class)->dispose (object);
311 }
312
313 static void
314 gst_audioringbuffer_finalize (GObject * object)
315 {
316   G_OBJECT_CLASS (ring_parent_class)->finalize (object);
317 }
318
319 static gboolean
320 gst_audioringbuffer_open_device (GstRingBuffer * buf)
321 {
322   GstAudioSrc *src;
323   GstAudioSrcClass *csrc;
324   gboolean result = TRUE;
325
326   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
327   csrc = GST_AUDIO_SRC_GET_CLASS (src);
328
329   if (csrc->open)
330     result = csrc->open (src);
331
332   if (!result)
333     goto could_not_open;
334
335   return result;
336
337 could_not_open:
338   {
339     return FALSE;
340   }
341 }
342
343 static gboolean
344 gst_audioringbuffer_close_device (GstRingBuffer * buf)
345 {
346   GstAudioSrc *src;
347   GstAudioSrcClass *csrc;
348   gboolean result = TRUE;
349
350   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
351   csrc = GST_AUDIO_SRC_GET_CLASS (src);
352
353   if (csrc->close)
354     result = csrc->close (src);
355
356   if (!result)
357     goto could_not_open;
358
359   return result;
360
361 could_not_open:
362   {
363     return FALSE;
364   }
365 }
366
367 static gboolean
368 gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
369 {
370   GstAudioSrc *src;
371   GstAudioSrcClass *csrc;
372   GstAudioRingBuffer *abuf;
373   gboolean result = FALSE;
374
375   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
376   csrc = GST_AUDIO_SRC_GET_CLASS (src);
377
378   if (csrc->prepare)
379     result = csrc->prepare (src, spec);
380
381   if (!result)
382     goto could_not_open;
383
384   buf->size = spec->segtotal * spec->segsize;
385   buf->memory = g_malloc0 (buf->size);
386
387   abuf = GST_AUDIORING_BUFFER (buf);
388   abuf->running = TRUE;
389
390   src->thread =
391       g_thread_create ((GThreadFunc) audioringbuffer_thread_func, buf, TRUE,
392       NULL);
393   GST_AUDIORING_BUFFER_WAIT (buf);
394
395   return result;
396
397 could_not_open:
398   {
399     return FALSE;
400   }
401 }
402
403 /* function is called with LOCK */
404 static gboolean
405 gst_audioringbuffer_release (GstRingBuffer * buf)
406 {
407   GstAudioSrc *src;
408   GstAudioSrcClass *csrc;
409   GstAudioRingBuffer *abuf;
410   gboolean result = FALSE;
411
412   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
413   csrc = GST_AUDIO_SRC_GET_CLASS (src);
414   abuf = GST_AUDIORING_BUFFER (buf);
415
416   abuf->running = FALSE;
417   GST_AUDIORING_BUFFER_SIGNAL (buf);
418   GST_OBJECT_UNLOCK (buf);
419
420   /* join the thread */
421   g_thread_join (src->thread);
422
423   GST_OBJECT_LOCK (buf);
424
425   /* free the buffer */
426   g_free (buf->memory);
427   buf->memory = NULL;
428
429   if (csrc->unprepare)
430     result = csrc->unprepare (src);
431
432   return result;
433 }
434
435 static gboolean
436 gst_audioringbuffer_start (GstRingBuffer * buf)
437 {
438   GST_DEBUG ("start, sending signal");
439   GST_AUDIORING_BUFFER_SIGNAL (buf);
440
441   return TRUE;
442 }
443
444 static gboolean
445 gst_audioringbuffer_stop (GstRingBuffer * buf)
446 {
447   GstAudioSrc *src;
448   GstAudioSrcClass *csrc;
449
450   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
451   csrc = GST_AUDIO_SRC_GET_CLASS (src);
452
453   /* unblock any pending writes to the audio device */
454   if (csrc->reset) {
455     GST_DEBUG ("reset...");
456     csrc->reset (src);
457     GST_DEBUG ("reset done");
458   }
459 #if 0
460   GST_DEBUG ("stop, waiting...");
461   GST_AUDIORING_BUFFER_WAIT (buf);
462   GST_DEBUG ("stoped");
463 #endif
464
465   return TRUE;
466 }
467
468 static guint
469 gst_audioringbuffer_delay (GstRingBuffer * buf)
470 {
471   GstAudioSrc *src;
472   GstAudioSrcClass *csrc;
473   guint res = 0;
474
475   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
476   csrc = GST_AUDIO_SRC_GET_CLASS (src);
477
478   if (csrc->delay)
479     res = csrc->delay (src);
480
481   return res;
482 }
483
484 /* AudioSrc signals and args */
485 enum
486 {
487   /* FILL ME */
488   LAST_SIGNAL
489 };
490
491 enum
492 {
493   ARG_0,
494 };
495
496 #define _do_init \
497     GST_DEBUG_CATEGORY_INIT (gst_audio_src_debug, "audiosrc", 0, "audiosrc element");
498 #define gst_audio_src_parent_class parent_class
499 G_DEFINE_TYPE_WITH_CODE (GstAudioSrc, gst_audio_src,
500     GST_TYPE_BASE_AUDIO_SRC, _do_init);
501
502 static GstRingBuffer *gst_audio_src_create_ringbuffer (GstBaseAudioSrc * src);
503
504 static void
505 gst_audio_src_class_init (GstAudioSrcClass * klass)
506 {
507   GstBaseAudioSrcClass *gstbaseaudiosrc_class;
508
509   gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
510
511   gstbaseaudiosrc_class->create_ringbuffer =
512       GST_DEBUG_FUNCPTR (gst_audio_src_create_ringbuffer);
513
514   g_type_class_ref (GST_TYPE_AUDIORING_BUFFER);
515 }
516
517 static void
518 gst_audio_src_init (GstAudioSrc * audiosrc)
519 {
520 }
521
522 static GstRingBuffer *
523 gst_audio_src_create_ringbuffer (GstBaseAudioSrc * src)
524 {
525   GstRingBuffer *buffer;
526
527   GST_DEBUG ("creating ringbuffer");
528   buffer = g_object_new (GST_TYPE_AUDIORING_BUFFER, NULL);
529   GST_DEBUG ("created ringbuffer @%p", buffer);
530
531   return buffer;
532 }