gst_plugins_base/gst-libs/gst/audio/gstaudiosrc.c
changeset 0 0e761a78d257
child 8 4a7fac7dd34a
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     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 #ifdef __SYMBIAN32__
       
    75 #include <glib_global.h>
       
    76 #endif
       
    77 
       
    78 GST_DEBUG_CATEGORY_STATIC (gst_audio_src_debug);
       
    79 #define GST_CAT_DEFAULT gst_audio_src_debug
       
    80 
       
    81 #define GST_TYPE_AUDIORING_BUFFER        \
       
    82         (gst_audioringbuffer_get_type())
       
    83 #define GST_AUDIORING_BUFFER(obj)        \
       
    84         (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIORING_BUFFER,GstAudioRingBuffer))
       
    85 #define GST_AUDIORING_BUFFER_CLASS(klass) \
       
    86         (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIORING_BUFFER,GstAudioRingBufferClass))
       
    87 #define GST_AUDIORING_BUFFER_GET_CLASS(obj) \
       
    88         (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_AUDIORING_BUFFER, GstAudioRingBufferClass))
       
    89 #define GST_IS_AUDIORING_BUFFER(obj)     \
       
    90         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIORING_BUFFER))
       
    91 #define GST_IS_AUDIORING_BUFFER_CLASS(klass)\
       
    92         (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIORING_BUFFER))
       
    93 
       
    94 typedef struct _GstAudioRingBuffer GstAudioRingBuffer;
       
    95 typedef struct _GstAudioRingBufferClass GstAudioRingBufferClass;
       
    96 
       
    97 #define GST_AUDIORING_BUFFER_GET_COND(buf) (((GstAudioRingBuffer *)buf)->cond)
       
    98 #define GST_AUDIORING_BUFFER_WAIT(buf)     (g_cond_wait (GST_AUDIORING_BUFFER_GET_COND (buf), GST_OBJECT_GET_LOCK (buf)))
       
    99 #define GST_AUDIORING_BUFFER_SIGNAL(buf)   (g_cond_signal (GST_AUDIORING_BUFFER_GET_COND (buf)))
       
   100 #define GST_AUDIORING_BUFFER_BROADCAST(buf)(g_cond_broadcast (GST_AUDIORING_BUFFER_GET_COND (buf)))
       
   101 
       
   102 struct _GstAudioRingBuffer
       
   103 {
       
   104   GstRingBuffer object;
       
   105 
       
   106   gboolean running;
       
   107   gint queuedseg;
       
   108 
       
   109   GCond *cond;
       
   110 };
       
   111 
       
   112 struct _GstAudioRingBufferClass
       
   113 {
       
   114   GstRingBufferClass parent_class;
       
   115 };
       
   116 
       
   117 static void gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass);
       
   118 static void gst_audioringbuffer_init (GstAudioRingBuffer * ringbuffer,
       
   119     GstAudioRingBufferClass * klass);
       
   120 static void gst_audioringbuffer_dispose (GObject * object);
       
   121 static void gst_audioringbuffer_finalize (GObject * object);
       
   122 
       
   123 static GstRingBufferClass *ring_parent_class = NULL;
       
   124 
       
   125 static gboolean gst_audioringbuffer_open_device (GstRingBuffer * buf);
       
   126 static gboolean gst_audioringbuffer_close_device (GstRingBuffer * buf);
       
   127 static gboolean gst_audioringbuffer_acquire (GstRingBuffer * buf,
       
   128     GstRingBufferSpec * spec);
       
   129 static gboolean gst_audioringbuffer_release (GstRingBuffer * buf);
       
   130 static gboolean gst_audioringbuffer_start (GstRingBuffer * buf);
       
   131 static gboolean gst_audioringbuffer_stop (GstRingBuffer * buf);
       
   132 static guint gst_audioringbuffer_delay (GstRingBuffer * buf);
       
   133 
       
   134 /* ringbuffer abstract base class */
       
   135 static GType
       
   136 gst_audioringbuffer_get_type (void)
       
   137 {
       
   138   static GType ringbuffer_type = 0;
       
   139 
       
   140   if (!ringbuffer_type) {
       
   141     static const GTypeInfo ringbuffer_info = {
       
   142       sizeof (GstAudioRingBufferClass),
       
   143       NULL,
       
   144       NULL,
       
   145       (GClassInitFunc) gst_audioringbuffer_class_init,
       
   146       NULL,
       
   147       NULL,
       
   148       sizeof (GstAudioRingBuffer),
       
   149       0,
       
   150       (GInstanceInitFunc) gst_audioringbuffer_init,
       
   151       NULL
       
   152     };
       
   153 
       
   154     ringbuffer_type =
       
   155         g_type_register_static (GST_TYPE_RING_BUFFER, "GstAudioSrcRingBuffer",
       
   156         &ringbuffer_info, 0);
       
   157   }
       
   158   return ringbuffer_type;
       
   159 }
       
   160 
       
   161 static void
       
   162 gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass)
       
   163 {
       
   164   GObjectClass *gobject_class;
       
   165   GstObjectClass *gstobject_class;
       
   166   GstRingBufferClass *gstringbuffer_class;
       
   167 
       
   168   gobject_class = (GObjectClass *) klass;
       
   169   gstobject_class = (GstObjectClass *) klass;
       
   170   gstringbuffer_class = (GstRingBufferClass *) klass;
       
   171 
       
   172   ring_parent_class = g_type_class_peek_parent (klass);
       
   173 
       
   174   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_audioringbuffer_dispose);
       
   175   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_audioringbuffer_finalize);
       
   176 
       
   177   gstringbuffer_class->open_device =
       
   178       GST_DEBUG_FUNCPTR (gst_audioringbuffer_open_device);
       
   179   gstringbuffer_class->close_device =
       
   180       GST_DEBUG_FUNCPTR (gst_audioringbuffer_close_device);
       
   181   gstringbuffer_class->acquire =
       
   182       GST_DEBUG_FUNCPTR (gst_audioringbuffer_acquire);
       
   183   gstringbuffer_class->release =
       
   184       GST_DEBUG_FUNCPTR (gst_audioringbuffer_release);
       
   185   gstringbuffer_class->start = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
       
   186   gstringbuffer_class->resume = GST_DEBUG_FUNCPTR (gst_audioringbuffer_start);
       
   187   gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_audioringbuffer_stop);
       
   188 
       
   189   gstringbuffer_class->delay = GST_DEBUG_FUNCPTR (gst_audioringbuffer_delay);
       
   190 }
       
   191 
       
   192 typedef guint (*ReadFunc) (GstAudioSrc * src, gpointer data, guint length);
       
   193 
       
   194 /* this internal thread does nothing else but read samples from the audio device.
       
   195  * It will read each segment in the ringbuffer and will update the play
       
   196  * pointer. 
       
   197  * The start/stop methods control the thread.
       
   198  */
       
   199 static void
       
   200 audioringbuffer_thread_func (GstRingBuffer * buf)
       
   201 {
       
   202   GstAudioSrc *src;
       
   203   GstAudioSrcClass *csrc;
       
   204   GstAudioRingBuffer *abuf = GST_AUDIORING_BUFFER (buf);
       
   205   ReadFunc readfunc;
       
   206 
       
   207   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
       
   208   csrc = GST_AUDIO_SRC_GET_CLASS (src);
       
   209 
       
   210   GST_DEBUG_OBJECT (src, "enter thread");
       
   211 
       
   212   readfunc = csrc->read;
       
   213   if (readfunc == NULL)
       
   214     goto no_function;
       
   215 
       
   216   while (TRUE) {
       
   217     gint left, len;
       
   218     guint8 *readptr;
       
   219     gint readseg;
       
   220 
       
   221     if (gst_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) {
       
   222       gint read = 0;
       
   223 
       
   224       left = len;
       
   225       do {
       
   226         read = readfunc (src, readptr + read, left);
       
   227         GST_LOG_OBJECT (src, "transfered %d bytes of %d to segment %d", read,
       
   228             left, readseg);
       
   229         if (read < 0 || read > left) {
       
   230           GST_WARNING_OBJECT (src,
       
   231               "error reading data (reason: %s), skipping segment",
       
   232               g_strerror (errno));
       
   233           break;
       
   234         }
       
   235         left -= read;
       
   236       } while (left > 0);
       
   237 
       
   238       /* we read one segment */
       
   239       gst_ring_buffer_advance (buf, 1);
       
   240     } else {
       
   241       GST_OBJECT_LOCK (abuf);
       
   242       if (!abuf->running)
       
   243         goto stop_running;
       
   244       GST_DEBUG_OBJECT (src, "signal wait");
       
   245       GST_AUDIORING_BUFFER_SIGNAL (buf);
       
   246       GST_DEBUG_OBJECT (src, "wait for action");
       
   247       GST_AUDIORING_BUFFER_WAIT (buf);
       
   248       GST_DEBUG_OBJECT (src, "got signal");
       
   249       if (!abuf->running)
       
   250         goto stop_running;
       
   251       GST_DEBUG_OBJECT (src, "continue running");
       
   252       GST_OBJECT_UNLOCK (abuf);
       
   253     }
       
   254   }
       
   255   GST_DEBUG_OBJECT (src, "exit thread");
       
   256 
       
   257   return;
       
   258 
       
   259   /* ERROR */
       
   260 no_function:
       
   261   {
       
   262     GST_DEBUG ("no write function, exit thread");
       
   263     return;
       
   264   }
       
   265 stop_running:
       
   266   {
       
   267     GST_OBJECT_UNLOCK (abuf);
       
   268     GST_DEBUG ("stop running, exit thread");
       
   269     return;
       
   270   }
       
   271 }
       
   272 
       
   273 static void
       
   274 gst_audioringbuffer_init (GstAudioRingBuffer * ringbuffer,
       
   275     GstAudioRingBufferClass * g_class)
       
   276 {
       
   277   ringbuffer->running = FALSE;
       
   278   ringbuffer->queuedseg = 0;
       
   279 
       
   280   ringbuffer->cond = g_cond_new ();
       
   281 }
       
   282 
       
   283 static void
       
   284 gst_audioringbuffer_dispose (GObject * object)
       
   285 {
       
   286   GstAudioRingBuffer *ringbuffer = GST_AUDIORING_BUFFER (object);
       
   287 
       
   288   if (ringbuffer->cond) {
       
   289     g_cond_free (ringbuffer->cond);
       
   290     ringbuffer->cond = NULL;
       
   291   }
       
   292 
       
   293   G_OBJECT_CLASS (ring_parent_class)->dispose (object);
       
   294 }
       
   295 
       
   296 static void
       
   297 gst_audioringbuffer_finalize (GObject * object)
       
   298 {
       
   299   G_OBJECT_CLASS (ring_parent_class)->finalize (object);
       
   300 }
       
   301 
       
   302 static gboolean
       
   303 gst_audioringbuffer_open_device (GstRingBuffer * buf)
       
   304 {
       
   305   GstAudioSrc *src;
       
   306   GstAudioSrcClass *csrc;
       
   307   gboolean result = TRUE;
       
   308 
       
   309   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
       
   310   csrc = GST_AUDIO_SRC_GET_CLASS (src);
       
   311 
       
   312   if (csrc->open)
       
   313     result = csrc->open (src);
       
   314 
       
   315   if (!result)
       
   316     goto could_not_open;
       
   317 
       
   318   return result;
       
   319 
       
   320 could_not_open:
       
   321   {
       
   322     return FALSE;
       
   323   }
       
   324 }
       
   325 
       
   326 static gboolean
       
   327 gst_audioringbuffer_close_device (GstRingBuffer * buf)
       
   328 {
       
   329   GstAudioSrc *src;
       
   330   GstAudioSrcClass *csrc;
       
   331   gboolean result = TRUE;
       
   332 
       
   333   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
       
   334   csrc = GST_AUDIO_SRC_GET_CLASS (src);
       
   335 
       
   336   if (csrc->close)
       
   337     result = csrc->close (src);
       
   338 
       
   339   if (!result)
       
   340     goto could_not_open;
       
   341 
       
   342   return result;
       
   343 
       
   344 could_not_open:
       
   345   {
       
   346     return FALSE;
       
   347   }
       
   348 }
       
   349 
       
   350 static gboolean
       
   351 gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
       
   352 {
       
   353   GstAudioSrc *src;
       
   354   GstAudioSrcClass *csrc;
       
   355   GstAudioRingBuffer *abuf;
       
   356   gboolean result = FALSE;
       
   357 
       
   358   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
       
   359   csrc = GST_AUDIO_SRC_GET_CLASS (src);
       
   360 
       
   361   if (csrc->prepare)
       
   362     result = csrc->prepare (src, spec);
       
   363 
       
   364   if (!result)
       
   365     goto could_not_open;
       
   366 
       
   367   /* allocate one more segment as we need some headroom */
       
   368   spec->segtotal++;
       
   369 
       
   370   buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
       
   371   memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));
       
   372 
       
   373   abuf = GST_AUDIORING_BUFFER (buf);
       
   374   abuf->running = TRUE;
       
   375 
       
   376   src->thread =
       
   377       g_thread_create ((GThreadFunc) audioringbuffer_thread_func, buf, TRUE,
       
   378       NULL);
       
   379   GST_AUDIORING_BUFFER_WAIT (buf);
       
   380 
       
   381   return result;
       
   382 
       
   383 could_not_open:
       
   384   {
       
   385     return FALSE;
       
   386   }
       
   387 }
       
   388 
       
   389 /* function is called with LOCK */
       
   390 static gboolean
       
   391 gst_audioringbuffer_release (GstRingBuffer * buf)
       
   392 {
       
   393   GstAudioSrc *src;
       
   394   GstAudioSrcClass *csrc;
       
   395   GstAudioRingBuffer *abuf;
       
   396   gboolean result = FALSE;
       
   397 
       
   398   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
       
   399   csrc = GST_AUDIO_SRC_GET_CLASS (src);
       
   400   abuf = GST_AUDIORING_BUFFER (buf);
       
   401 
       
   402   abuf->running = FALSE;
       
   403   GST_AUDIORING_BUFFER_SIGNAL (buf);
       
   404   GST_OBJECT_UNLOCK (buf);
       
   405 
       
   406   /* join the thread */
       
   407   g_thread_join (src->thread);
       
   408 
       
   409   GST_OBJECT_LOCK (buf);
       
   410 
       
   411   /* free the buffer */
       
   412   gst_buffer_unref (buf->data);
       
   413   buf->data = NULL;
       
   414 
       
   415   if (csrc->unprepare)
       
   416     result = csrc->unprepare (src);
       
   417 
       
   418   return result;
       
   419 }
       
   420 
       
   421 static gboolean
       
   422 gst_audioringbuffer_start (GstRingBuffer * buf)
       
   423 {
       
   424   GstAudioSrc *src;
       
   425 
       
   426   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
       
   427 
       
   428   GST_DEBUG ("start, sending signal");
       
   429   GST_AUDIORING_BUFFER_SIGNAL (buf);
       
   430 
       
   431   return TRUE;
       
   432 }
       
   433 
       
   434 static gboolean
       
   435 gst_audioringbuffer_stop (GstRingBuffer * buf)
       
   436 {
       
   437   GstAudioSrc *src;
       
   438   GstAudioSrcClass *csrc;
       
   439 
       
   440   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
       
   441   csrc = GST_AUDIO_SRC_GET_CLASS (src);
       
   442 
       
   443   /* unblock any pending writes to the audio device */
       
   444   if (csrc->reset) {
       
   445     GST_DEBUG ("reset...");
       
   446     csrc->reset (src);
       
   447     GST_DEBUG ("reset done");
       
   448   }
       
   449 
       
   450   GST_DEBUG ("stop, waiting...");
       
   451   GST_AUDIORING_BUFFER_WAIT (buf);
       
   452   GST_DEBUG ("stoped");
       
   453 
       
   454   return TRUE;
       
   455 }
       
   456 
       
   457 static guint
       
   458 gst_audioringbuffer_delay (GstRingBuffer * buf)
       
   459 {
       
   460   GstAudioSrc *src;
       
   461   GstAudioSrcClass *csrc;
       
   462   guint res = 0;
       
   463 
       
   464   src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
       
   465   csrc = GST_AUDIO_SRC_GET_CLASS (src);
       
   466 
       
   467   if (csrc->delay)
       
   468     res = csrc->delay (src);
       
   469 
       
   470   return res;
       
   471 }
       
   472 
       
   473 /* AudioSrc signals and args */
       
   474 enum
       
   475 {
       
   476   /* FILL ME */
       
   477   LAST_SIGNAL
       
   478 };
       
   479 
       
   480 enum
       
   481 {
       
   482   ARG_0,
       
   483 };
       
   484 
       
   485 #define _do_init(bla) \
       
   486     GST_DEBUG_CATEGORY_INIT (gst_audio_src_debug, "audiosrc", 0, "audiosrc element");
       
   487 
       
   488 GST_BOILERPLATE_FULL (GstAudioSrc, gst_audio_src, GstBaseAudioSrc,
       
   489     GST_TYPE_BASE_AUDIO_SRC, _do_init);
       
   490 
       
   491 static GstRingBuffer *gst_audio_src_create_ringbuffer (GstBaseAudioSrc * src);
       
   492 
       
   493 static void
       
   494 gst_audio_src_base_init (gpointer g_class)
       
   495 {
       
   496 }
       
   497 
       
   498 static void
       
   499 gst_audio_src_class_init (GstAudioSrcClass * klass)
       
   500 {
       
   501   GObjectClass *gobject_class;
       
   502   GstElementClass *gstelement_class;
       
   503   GstBaseSrcClass *gstbasesrc_class;
       
   504   GstPushSrcClass *gstpushsrc_class;
       
   505   GstBaseAudioSrcClass *gstbaseaudiosrc_class;
       
   506 
       
   507   gobject_class = (GObjectClass *) klass;
       
   508   gstelement_class = (GstElementClass *) klass;
       
   509   gstbasesrc_class = (GstBaseSrcClass *) klass;
       
   510   gstpushsrc_class = (GstPushSrcClass *) klass;
       
   511   gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
       
   512 
       
   513   gstbaseaudiosrc_class->create_ringbuffer =
       
   514       GST_DEBUG_FUNCPTR (gst_audio_src_create_ringbuffer);
       
   515 }
       
   516 
       
   517 static void
       
   518 gst_audio_src_init (GstAudioSrc * audiosrc, GstAudioSrcClass * g_class)
       
   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 }