gst_plugins_base/gst-libs/gst/audio/gstbaseaudiosrc.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    40 
    40 
    41 #include "gstbaseaudiosrc.h"
    41 #include "gstbaseaudiosrc.h"
    42 
    42 
    43 #include "gst/gst-i18n-plugin.h"
    43 #include "gst/gst-i18n-plugin.h"
    44 
    44 
       
    45 #ifdef __SYMBIAN32__
       
    46 #include <glib_global.h>
       
    47 #endif
       
    48 
    45 GST_DEBUG_CATEGORY_STATIC (gst_base_audio_src_debug);
    49 GST_DEBUG_CATEGORY_STATIC (gst_base_audio_src_debug);
    46 #define GST_CAT_DEFAULT gst_base_audio_src_debug
    50 #define GST_CAT_DEFAULT gst_base_audio_src_debug
    47 
    51 
    48 #ifdef __SYMBIAN32__
       
    49 EXPORT_C
       
    50 #endif
       
    51 
       
    52 GType
       
    53 gst_base_audio_src_slave_method_get_type (void)
       
    54 {
       
    55   static GType slave_method_type = 0;
       
    56   static const GEnumValue slave_method[] = {
       
    57     {GST_BASE_AUDIO_SRC_SLAVE_RESAMPLE, "Resampling slaving", "resample"},
       
    58     {GST_BASE_AUDIO_SRC_SLAVE_RETIMESTAMP, "Re-timestamp", "re-timestamp"},
       
    59     {GST_BASE_AUDIO_SRC_SLAVE_SKEW, "Skew", "skew"},
       
    60     {GST_BASE_AUDIO_SRC_SLAVE_NONE, "No slaving", "none"},
       
    61     {0, NULL, NULL},
       
    62   };
       
    63 
       
    64   if (!slave_method_type) {
       
    65     slave_method_type =
       
    66         g_enum_register_static ("GstBaseAudioSrcSlaveMethod", slave_method);
       
    67   }
       
    68   return slave_method_type;
       
    69 }
       
    70 
       
    71 #define GST_BASE_AUDIO_SRC_GET_PRIVATE(obj)  \
    52 #define GST_BASE_AUDIO_SRC_GET_PRIVATE(obj)  \
    72    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_AUDIO_SRC, GstBaseAudioSrcPrivate))
    53    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_AUDIO_SRC, GstBaseAudioSrcPrivate))
    73 
    54 
    74 struct _GstBaseAudioSrcPrivate
    55 struct _GstBaseAudioSrcPrivate
    75 {
    56 {
    76   gboolean provide_clock;
    57   gboolean provide_clock;
    77 
       
    78   /* the clock slaving algorithm in use */
       
    79   GstBaseAudioSrcSlaveMethod slave_method;
       
    80 };
    58 };
    81 
    59 
    82 /* BaseAudioSrc signals and args */
    60 /* BaseAudioSrc signals and args */
    83 enum
    61 enum
    84 {
    62 {
    86   LAST_SIGNAL
    64   LAST_SIGNAL
    87 };
    65 };
    88 
    66 
    89 #define DEFAULT_BUFFER_TIME     ((200 * GST_MSECOND) / GST_USECOND)
    67 #define DEFAULT_BUFFER_TIME     ((200 * GST_MSECOND) / GST_USECOND)
    90 #define DEFAULT_LATENCY_TIME    ((10 * GST_MSECOND) / GST_USECOND)
    68 #define DEFAULT_LATENCY_TIME    ((10 * GST_MSECOND) / GST_USECOND)
    91 #define DEFAULT_ACTUAL_BUFFER_TIME     -1
       
    92 #define DEFAULT_ACTUAL_LATENCY_TIME    -1
       
    93 #define DEFAULT_PROVIDE_CLOCK   TRUE
    69 #define DEFAULT_PROVIDE_CLOCK   TRUE
    94 #define DEFAULT_SLAVE_METHOD    GST_BASE_AUDIO_SRC_SLAVE_RETIMESTAMP
       
    95 
    70 
    96 enum
    71 enum
    97 {
    72 {
    98   PROP_0,
    73   PROP_0,
    99   PROP_BUFFER_TIME,
    74   PROP_BUFFER_TIME,
   100   PROP_LATENCY_TIME,
    75   PROP_LATENCY_TIME,
   101   PROP_ACTUAL_BUFFER_TIME,
    76   PROP_PROVIDE_CLOCK
   102   PROP_ACTUAL_LATENCY_TIME,
       
   103   PROP_PROVIDE_CLOCK,
       
   104   PROP_SLAVE_METHOD,
       
   105   PROP_LAST
       
   106 };
    77 };
   107 
    78 
   108 static void
    79 static void
   109 _do_init (GType type)
    80 _do_init (GType type)
   110 {
    81 {
   113 
    84 
   114 #ifdef ENABLE_NLS
    85 #ifdef ENABLE_NLS
   115   GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
    86   GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
   116       LOCALEDIR);
    87       LOCALEDIR);
   117   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
    88   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
   118   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
       
   119 #endif /* ENABLE_NLS */
    89 #endif /* ENABLE_NLS */
   120 }
    90 }
   121 
    91 
   122 GST_BOILERPLATE_FULL (GstBaseAudioSrc, gst_base_audio_src, GstPushSrc,
    92 GST_BOILERPLATE_FULL (GstBaseAudioSrc, gst_base_audio_src, GstPushSrc,
   123     GST_TYPE_PUSH_SRC, _do_init);
    93     GST_TYPE_PUSH_SRC, _do_init);
   175   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_base_audio_src_dispose);
   145   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_base_audio_src_dispose);
   176 
   146 
   177   g_object_class_install_property (gobject_class, PROP_BUFFER_TIME,
   147   g_object_class_install_property (gobject_class, PROP_BUFFER_TIME,
   178       g_param_spec_int64 ("buffer-time", "Buffer Time",
   148       g_param_spec_int64 ("buffer-time", "Buffer Time",
   179           "Size of audio buffer in microseconds", 1,
   149           "Size of audio buffer in microseconds", 1,
   180           G_MAXINT64, DEFAULT_BUFFER_TIME,
   150           G_MAXINT64, DEFAULT_BUFFER_TIME, G_PARAM_READWRITE));
   181           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   182 
   151 
   183   g_object_class_install_property (gobject_class, PROP_LATENCY_TIME,
   152   g_object_class_install_property (gobject_class, PROP_LATENCY_TIME,
   184       g_param_spec_int64 ("latency-time", "Latency Time",
   153       g_param_spec_int64 ("latency-time", "Latency Time",
   185           "Audio latency in microseconds", 1,
   154           "Audio latency in microseconds", 1,
   186           G_MAXINT64, DEFAULT_LATENCY_TIME,
   155           G_MAXINT64, DEFAULT_LATENCY_TIME, G_PARAM_READWRITE));
   187           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   188 
       
   189   /**
       
   190    * GstBaseAudioSrc:actual-buffer-time:
       
   191    *
       
   192    * Actual configured size of audio buffer in microseconds.
       
   193    *
       
   194    * Since: 0.10.20
       
   195    **/
       
   196   g_object_class_install_property (gobject_class, PROP_ACTUAL_BUFFER_TIME,
       
   197       g_param_spec_int64 ("actual-buffer-time", "Actual Buffer Time",
       
   198           "Actual configured size of audio buffer in microseconds",
       
   199           DEFAULT_ACTUAL_BUFFER_TIME, G_MAXINT64, DEFAULT_ACTUAL_BUFFER_TIME,
       
   200           G_PARAM_READABLE));
       
   201 
       
   202   /**
       
   203    * GstBaseAudioSrc:actual-latency-time:
       
   204    *
       
   205    * Actual configured audio latency in microseconds.
       
   206    *
       
   207    * Since: 0.10.20
       
   208    **/
       
   209   g_object_class_install_property (gobject_class, PROP_ACTUAL_LATENCY_TIME,
       
   210       g_param_spec_int64 ("actual-latency-time", "Actual Latency Time",
       
   211           "Actual configured audio latency in microseconds",
       
   212           DEFAULT_ACTUAL_LATENCY_TIME, G_MAXINT64, DEFAULT_ACTUAL_LATENCY_TIME,
       
   213           G_PARAM_READABLE));
       
   214 
   156 
   215   g_object_class_install_property (gobject_class, PROP_PROVIDE_CLOCK,
   157   g_object_class_install_property (gobject_class, PROP_PROVIDE_CLOCK,
   216       g_param_spec_boolean ("provide-clock", "Provide Clock",
   158       g_param_spec_boolean ("provide-clock", "Provide Clock",
   217           "Provide a clock to be used as the global pipeline clock",
   159           "Provide a clock to be used as the global pipeline clock",
   218           DEFAULT_PROVIDE_CLOCK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   160           DEFAULT_PROVIDE_CLOCK, G_PARAM_READWRITE));
   219 
       
   220   g_object_class_install_property (gobject_class, PROP_SLAVE_METHOD,
       
   221       g_param_spec_enum ("slave-method", "Slave Method",
       
   222           "Algorithm to use to match the rate of the masterclock",
       
   223           GST_TYPE_BASE_AUDIO_SRC_SLAVE_METHOD, DEFAULT_SLAVE_METHOD,
       
   224           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   225 
   161 
   226   gstelement_class->change_state =
   162   gstelement_class->change_state =
   227       GST_DEBUG_FUNCPTR (gst_base_audio_src_change_state);
   163       GST_DEBUG_FUNCPTR (gst_base_audio_src_change_state);
   228   gstelement_class->provide_clock =
   164   gstelement_class->provide_clock =
   229       GST_DEBUG_FUNCPTR (gst_base_audio_src_provide_clock);
   165       GST_DEBUG_FUNCPTR (gst_base_audio_src_provide_clock);
   239   gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_base_audio_src_fixate);
   175   gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_base_audio_src_fixate);
   240 
   176 
   241   /* ref class from a thread-safe context to work around missing bit of
   177   /* ref class from a thread-safe context to work around missing bit of
   242    * thread-safety in GObject */
   178    * thread-safety in GObject */
   243   g_type_class_ref (GST_TYPE_AUDIO_CLOCK);
   179   g_type_class_ref (GST_TYPE_AUDIO_CLOCK);
   244   g_type_class_ref (GST_TYPE_RING_BUFFER);
       
   245 }
   180 }
   246 
   181 
   247 static void
   182 static void
   248 gst_base_audio_src_init (GstBaseAudioSrc * baseaudiosrc,
   183 gst_base_audio_src_init (GstBaseAudioSrc * baseaudiosrc,
   249     GstBaseAudioSrcClass * g_class)
   184     GstBaseAudioSrcClass * g_class)
   251   baseaudiosrc->priv = GST_BASE_AUDIO_SRC_GET_PRIVATE (baseaudiosrc);
   186   baseaudiosrc->priv = GST_BASE_AUDIO_SRC_GET_PRIVATE (baseaudiosrc);
   252 
   187 
   253   baseaudiosrc->buffer_time = DEFAULT_BUFFER_TIME;
   188   baseaudiosrc->buffer_time = DEFAULT_BUFFER_TIME;
   254   baseaudiosrc->latency_time = DEFAULT_LATENCY_TIME;
   189   baseaudiosrc->latency_time = DEFAULT_LATENCY_TIME;
   255   baseaudiosrc->priv->provide_clock = DEFAULT_PROVIDE_CLOCK;
   190   baseaudiosrc->priv->provide_clock = DEFAULT_PROVIDE_CLOCK;
   256   baseaudiosrc->priv->slave_method = DEFAULT_SLAVE_METHOD;
       
   257   /* reset blocksize we use latency time to calculate a more useful 
   191   /* reset blocksize we use latency time to calculate a more useful 
   258    * value based on negotiated format. */
   192    * value based on negotiated format. */
   259   GST_BASE_SRC (baseaudiosrc)->blocksize = 0;
   193   GST_BASE_SRC (baseaudiosrc)->blocksize = 0;
   260 
   194 
   261   baseaudiosrc->clock = gst_audio_clock_new ("GstAudioSrcClock",
   195   baseaudiosrc->clock = gst_audio_clock_new ("GstAudioSrcClock",
   272 {
   206 {
   273   GstBaseAudioSrc *src;
   207   GstBaseAudioSrc *src;
   274 
   208 
   275   src = GST_BASE_AUDIO_SRC (object);
   209   src = GST_BASE_AUDIO_SRC (object);
   276 
   210 
   277   GST_OBJECT_LOCK (src);
       
   278   if (src->clock)
   211   if (src->clock)
   279     gst_object_unref (src->clock);
   212     gst_object_unref (src->clock);
   280   src->clock = NULL;
   213   src->clock = NULL;
   281 
   214 
   282   if (src->ringbuffer) {
   215   if (src->ringbuffer) {
   283     gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
   216     gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
   284     src->ringbuffer = NULL;
   217     src->ringbuffer = NULL;
   285   }
   218   }
   286   GST_OBJECT_UNLOCK (src);
       
   287 
   219 
   288   G_OBJECT_CLASS (parent_class)->dispose (object);
   220   G_OBJECT_CLASS (parent_class)->dispose (object);
   289 }
   221 }
   290 
   222 
   291 static GstClock *
   223 static GstClock *
   416   GST_OBJECT_UNLOCK (src);
   348   GST_OBJECT_UNLOCK (src);
   417 
   349 
   418   return result;
   350   return result;
   419 }
   351 }
   420 
   352 
   421 /**
       
   422  * gst_base_audio_src_set_slave_method:
       
   423  * @src: a #GstBaseAudioSrc
       
   424  * @method: the new slave method
       
   425  *
       
   426  * Controls how clock slaving will be performed in @src. 
       
   427  *
       
   428  * Since: 0.10.20
       
   429  */
       
   430 #ifdef __SYMBIAN32__
       
   431 EXPORT_C
       
   432 #endif
       
   433 
       
   434 void
       
   435 gst_base_audio_src_set_slave_method (GstBaseAudioSrc * src,
       
   436     GstBaseAudioSrcSlaveMethod method)
       
   437 {
       
   438   g_return_if_fail (GST_IS_BASE_AUDIO_SRC (src));
       
   439 
       
   440   GST_OBJECT_LOCK (src);
       
   441   src->priv->slave_method = method;
       
   442   GST_OBJECT_UNLOCK (src);
       
   443 }
       
   444 
       
   445 /**
       
   446  * gst_base_audio_src_get_slave_method:
       
   447  * @src: a #GstBaseAudioSrc
       
   448  *
       
   449  * Get the current slave method used by @src.
       
   450  *
       
   451  * Returns: The current slave method used by @src.
       
   452  *
       
   453  * Since: 0.10.20
       
   454  */
       
   455 #ifdef __SYMBIAN32__
       
   456 EXPORT_C
       
   457 #endif
       
   458 
       
   459 GstBaseAudioSrcSlaveMethod
       
   460 gst_base_audio_src_get_slave_method (GstBaseAudioSrc * src)
       
   461 {
       
   462   GstBaseAudioSrcSlaveMethod result;
       
   463 
       
   464   g_return_val_if_fail (GST_IS_BASE_AUDIO_SRC (src), -1);
       
   465 
       
   466   GST_OBJECT_LOCK (src);
       
   467   result = src->priv->slave_method;
       
   468   GST_OBJECT_UNLOCK (src);
       
   469 
       
   470   return result;
       
   471 }
       
   472 
       
   473 static void
   353 static void
   474 gst_base_audio_src_set_property (GObject * object, guint prop_id,
   354 gst_base_audio_src_set_property (GObject * object, guint prop_id,
   475     const GValue * value, GParamSpec * pspec)
   355     const GValue * value, GParamSpec * pspec)
   476 {
   356 {
   477   GstBaseAudioSrc *src;
   357   GstBaseAudioSrc *src;
   486       src->latency_time = g_value_get_int64 (value);
   366       src->latency_time = g_value_get_int64 (value);
   487       break;
   367       break;
   488     case PROP_PROVIDE_CLOCK:
   368     case PROP_PROVIDE_CLOCK:
   489       gst_base_audio_src_set_provide_clock (src, g_value_get_boolean (value));
   369       gst_base_audio_src_set_provide_clock (src, g_value_get_boolean (value));
   490       break;
   370       break;
   491     case PROP_SLAVE_METHOD:
       
   492       gst_base_audio_src_set_slave_method (src, g_value_get_enum (value));
       
   493       break;
       
   494     default:
   371     default:
   495       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   372       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   496       break;
   373       break;
   497   }
   374   }
   498 }
   375 }
   510       g_value_set_int64 (value, src->buffer_time);
   387       g_value_set_int64 (value, src->buffer_time);
   511       break;
   388       break;
   512     case PROP_LATENCY_TIME:
   389     case PROP_LATENCY_TIME:
   513       g_value_set_int64 (value, src->latency_time);
   390       g_value_set_int64 (value, src->latency_time);
   514       break;
   391       break;
   515     case PROP_ACTUAL_BUFFER_TIME:
       
   516       GST_OBJECT_LOCK (src);
       
   517       if (src->ringbuffer && src->ringbuffer->acquired)
       
   518         g_value_set_int64 (value, src->ringbuffer->spec.buffer_time);
       
   519       else
       
   520         g_value_set_int64 (value, DEFAULT_ACTUAL_BUFFER_TIME);
       
   521       GST_OBJECT_UNLOCK (src);
       
   522       break;
       
   523     case PROP_ACTUAL_LATENCY_TIME:
       
   524       GST_OBJECT_LOCK (src);
       
   525       if (src->ringbuffer && src->ringbuffer->acquired)
       
   526         g_value_set_int64 (value, src->ringbuffer->spec.latency_time);
       
   527       else
       
   528         g_value_set_int64 (value, DEFAULT_ACTUAL_LATENCY_TIME);
       
   529       GST_OBJECT_UNLOCK (src);
       
   530       break;
       
   531     case PROP_PROVIDE_CLOCK:
   392     case PROP_PROVIDE_CLOCK:
   532       g_value_set_boolean (value, gst_base_audio_src_get_provide_clock (src));
   393       g_value_set_boolean (value, gst_base_audio_src_get_provide_clock (src));
   533       break;
       
   534     case PROP_SLAVE_METHOD:
       
   535       g_value_set_enum (value, gst_base_audio_src_get_slave_method (src));
       
   536       break;
   394       break;
   537     default:
   395     default:
   538       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   396       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   539       break;
   397       break;
   540   }
   398   }
   602   spec->buffer_time =
   460   spec->buffer_time =
   603       spec->segtotal * spec->segsize * GST_MSECOND / (spec->rate *
   461       spec->segtotal * spec->segsize * GST_MSECOND / (spec->rate *
   604       spec->bytes_per_sample);
   462       spec->bytes_per_sample);
   605 
   463 
   606   gst_ring_buffer_debug_spec_buff (spec);
   464   gst_ring_buffer_debug_spec_buff (spec);
   607 
       
   608   g_object_notify (G_OBJECT (src), "actual-buffer-time");
       
   609   g_object_notify (G_OBJECT (src), "actual-latency-time");
       
   610 
   465 
   611   return TRUE;
   466   return TRUE;
   612 
   467 
   613   /* ERRORS */
   468   /* ERRORS */
   614 parse_error:
   469 parse_error:
   681 
   536 
   682 static gboolean
   537 static gboolean
   683 gst_base_audio_src_event (GstBaseSrc * bsrc, GstEvent * event)
   538 gst_base_audio_src_event (GstBaseSrc * bsrc, GstEvent * event)
   684 {
   539 {
   685   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
   540   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
   686   gboolean res;
       
   687 
       
   688   res = TRUE;
       
   689 
   541 
   690   switch (GST_EVENT_TYPE (event)) {
   542   switch (GST_EVENT_TYPE (event)) {
   691     case GST_EVENT_FLUSH_START:
   543     case GST_EVENT_FLUSH_START:
   692       GST_DEBUG_OBJECT (bsrc, "flush-start");
       
   693       gst_ring_buffer_pause (src->ringbuffer);
   544       gst_ring_buffer_pause (src->ringbuffer);
   694       gst_ring_buffer_clear_all (src->ringbuffer);
   545       gst_ring_buffer_clear_all (src->ringbuffer);
   695       break;
   546       break;
   696     case GST_EVENT_FLUSH_STOP:
   547     case GST_EVENT_FLUSH_STOP:
   697       GST_DEBUG_OBJECT (bsrc, "flush-stop");
       
   698       /* always resync on sample after a flush */
   548       /* always resync on sample after a flush */
   699       src->next_sample = -1;
   549       src->next_sample = -1;
   700       gst_ring_buffer_clear_all (src->ringbuffer);
   550       gst_ring_buffer_clear_all (src->ringbuffer);
   701       break;
   551       break;
   702     case GST_EVENT_SEEK:
       
   703       GST_DEBUG_OBJECT (bsrc, "refuse to seek");
       
   704       res = FALSE;
       
   705       break;
       
   706     default:
   552     default:
   707       GST_DEBUG_OBJECT (bsrc, "dropping event %p", event);
   553       break;
   708       break;
   554   }
   709   }
   555   return TRUE;
   710   return res;
       
   711 }
   556 }
   712 
   557 
   713 /* get the next offset in the ringbuffer for reading samples.
   558 /* get the next offset in the ringbuffer for reading samples.
   714  * If the next sample is too far away, this function will position itself to the
   559  * If the next sample is too far away, this function will position itself to the
   715  * next most recent sample, creating discontinuity */
   560  * next most recent sample, creating discontinuity */
   744    * reading). */
   589    * reading). */
   745   diff = segdone - readseg;
   590   diff = segdone - readseg;
   746   if (diff >= segtotal) {
   591   if (diff >= segtotal) {
   747     GST_DEBUG_OBJECT (src, "dropped, align to segment %d", segdone);
   592     GST_DEBUG_OBJECT (src, "dropped, align to segment %d", segdone);
   748     /* sample would be dropped, position to next playable position */
   593     /* sample would be dropped, position to next playable position */
   749     sample = ((guint64) (segdone)) * sps;
   594     sample = (segdone - segtotal + 1) * sps;
   750   }
   595   }
   751 
   596 
   752   return sample;
   597   return sample;
   753 }
   598 }
   754 
   599 
   830     GST_WARNING_OBJECT (src,
   675     GST_WARNING_OBJECT (src,
   831         "create DISCONT of %" G_GUINT64_FORMAT " samples at sample %"
   676         "create DISCONT of %" G_GUINT64_FORMAT " samples at sample %"
   832         G_GUINT64_FORMAT, sample - src->next_sample, sample);
   677         G_GUINT64_FORMAT, sample - src->next_sample, sample);
   833     GST_ELEMENT_WARNING (src, CORE, CLOCK,
   678     GST_ELEMENT_WARNING (src, CORE, CLOCK,
   834         (_("Can't record audio fast enough")),
   679         (_("Can't record audio fast enough")),
   835         ("Dropped %" G_GUINT64_FORMAT " samples. This is most likely because "
   680         ("dropped %" G_GUINT64_FORMAT " samples", sample - src->next_sample));
   836             "downstream can't keep up and is consuming samples too slowly.",
       
   837             sample - src->next_sample));
       
   838     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
   681     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
   839   }
   682   }
   840 
   683 
   841   src->next_sample = sample + samples;
   684   src->next_sample = sample + samples;
   842 
   685 
   844   timestamp = gst_util_uint64_scale_int (sample, GST_SECOND, spec->rate);
   687   timestamp = gst_util_uint64_scale_int (sample, GST_SECOND, spec->rate);
   845   duration = gst_util_uint64_scale_int (src->next_sample, GST_SECOND,
   688   duration = gst_util_uint64_scale_int (src->next_sample, GST_SECOND,
   846       spec->rate) - timestamp;
   689       spec->rate) - timestamp;
   847 
   690 
   848   GST_OBJECT_LOCK (src);
   691   GST_OBJECT_LOCK (src);
   849   if (!(clock = GST_ELEMENT_CLOCK (src)))
   692   clock = GST_ELEMENT_CLOCK (src);
   850     goto no_sync;
   693   if (clock != NULL && clock != src->clock) {
   851 
   694     GstClockTime base_time, latency;
   852   if (clock != src->clock) {
   695 
   853     /* we are slaved, check how to handle this */
   696     /* We are slaved to another clock, take running time of the clock and just
   854     switch (src->priv->slave_method) {
   697      * timestamp against it. Somebody else in the pipeline should figure out the
   855       case GST_BASE_AUDIO_SRC_SLAVE_RESAMPLE:
   698      * clock drift, for now. We keep the duration we calculated above. */
   856         /* not implemented, use skew algorithm. This algorithm should
   699     timestamp = gst_clock_get_time (clock);
   857          * work on the readout pointer and produces more or less samples based
       
   858          * on the clock drift */
       
   859       case GST_BASE_AUDIO_SRC_SLAVE_SKEW:
       
   860       {
       
   861         GstClockTime running_time;
       
   862         GstClockTime base_time;
       
   863         GstClockTime current_time;
       
   864         guint64 running_time_sample;
       
   865         gint running_time_segment;
       
   866         gint current_segment;
       
   867         gint segment_skew;
       
   868         gint sps;
       
   869 
       
   870         /* samples per segment */
       
   871         sps = ringbuffer->samples_per_seg;
       
   872 
       
   873         /* get the current time */
       
   874         current_time = gst_clock_get_time (clock);
       
   875 
       
   876         /* get the basetime */
       
   877         base_time = GST_ELEMENT_CAST (src)->base_time;
       
   878 
       
   879         /* get the running_time */
       
   880         running_time = current_time - base_time;
       
   881 
       
   882         /* the running_time converted to a sample (relative to the ringbuffer) */
       
   883         running_time_sample =
       
   884             gst_util_uint64_scale_int (running_time, spec->rate, GST_SECOND);
       
   885 
       
   886         /* the segmentnr corrensponding to running_time, round down */
       
   887         running_time_segment = running_time_sample / sps;
       
   888 
       
   889         /* the segment currently read from the ringbuffer */
       
   890         current_segment = sample / sps;
       
   891 
       
   892         /* the skew we have between running_time and the ringbuffertime */
       
   893         segment_skew = running_time_segment - current_segment;
       
   894 
       
   895         GST_DEBUG_OBJECT (bsrc, "\n running_time = %" GST_TIME_FORMAT
       
   896             "\n timestamp     = %" GST_TIME_FORMAT
       
   897             "\n running_time_segment = %d"
       
   898             "\n current_segment      = %d"
       
   899             "\n segment_skew         = %d",
       
   900             GST_TIME_ARGS (running_time),
       
   901             GST_TIME_ARGS (timestamp),
       
   902             running_time_segment, current_segment, segment_skew);
       
   903 
       
   904         /* Resync the ringbuffer if:
       
   905          * 1. We get one segment into the future.
       
   906          *    This is clearly a lie, because we can't
       
   907          *    possibly have a buffer with timestamp 1 at
       
   908          *    time 0. (unless it has time-travelled...)
       
   909          *
       
   910          * 2. We are more than the length of the ringbuffer behind.
       
   911          *    The length of the ringbuffer then gets to dictate
       
   912          *    the threshold for what is concidered "too late"
       
   913          *
       
   914          * 3. If this is our first buffer.
       
   915          *    We know that we should catch up to running_time
       
   916          *    the first time we are ran.
       
   917          */
       
   918         if ((segment_skew < 0) ||
       
   919             (segment_skew >= ringbuffer->spec.segtotal) ||
       
   920             (current_segment == 0)) {
       
   921           gint segments_written;
       
   922           gint first_segment;
       
   923           gint last_segment;
       
   924           gint new_last_segment;
       
   925           gint segment_diff;
       
   926           gint new_first_segment;
       
   927           guint64 new_sample;
       
   928 
       
   929           /* we are going to say that the last segment was captured at the current time
       
   930              (running_time), minus one segment of creation-latency in the ringbuffer.
       
   931              This can be thought of as: The segment arrived in the ringbuffer at time X, and
       
   932              that means it was created at time X - (one segment). */
       
   933           new_last_segment = running_time_segment - 1;
       
   934 
       
   935           /* for better readablity */
       
   936           first_segment = current_segment;
       
   937 
       
   938           /* get the amount of segments written from the device by now */
       
   939           segments_written = g_atomic_int_get (&ringbuffer->segdone);
       
   940 
       
   941           /* subtract the base to segments_written to get the number of the
       
   942              last written segment in the ringbuffer (one segment written = segment 0) */
       
   943           last_segment = segments_written - ringbuffer->segbase - 1;
       
   944 
       
   945           /* we see how many segments the ringbuffer was timeshifted */
       
   946           segment_diff = new_last_segment - last_segment;
       
   947 
       
   948           /* we move the first segment an equal amount */
       
   949           new_first_segment = first_segment + segment_diff;
       
   950 
       
   951           /* and we also move the segmentbase the same amount */
       
   952           ringbuffer->segbase -= segment_diff;
       
   953 
       
   954           /* we calculate the new sample value */
       
   955           new_sample = ((guint64) new_first_segment) * sps;
       
   956 
       
   957           /* and get the relative time to this -> our new timestamp */
       
   958           timestamp =
       
   959               gst_util_uint64_scale_int (new_sample, GST_SECOND, spec->rate);
       
   960 
       
   961           /* we update the next sample accordingly */
       
   962           src->next_sample = new_sample + samples;
       
   963 
       
   964           GST_DEBUG_OBJECT (bsrc,
       
   965               "Timeshifted the ringbuffer with %d segments: "
       
   966               "Updating the timestamp to %" GST_TIME_FORMAT ", "
       
   967               "and src->next_sample to %" G_GUINT64_FORMAT, segment_diff,
       
   968               GST_TIME_ARGS (timestamp), src->next_sample);
       
   969         }
       
   970         break;
       
   971       }
       
   972       case GST_BASE_AUDIO_SRC_SLAVE_RETIMESTAMP:
       
   973       {
       
   974         GstClockTime base_time, latency;
       
   975 
       
   976         /* We are slaved to another clock, take running time of the pipeline clock and
       
   977          * timestamp against it. Somebody else in the pipeline should figure out the
       
   978          * clock drift. We keep the duration we calculated above. */
       
   979         timestamp = gst_clock_get_time (clock);
       
   980         base_time = GST_ELEMENT_CAST (src)->base_time;
       
   981 
       
   982         if (timestamp > base_time)
       
   983           timestamp -= base_time;
       
   984         else
       
   985           timestamp = 0;
       
   986 
       
   987         /* subtract latency */
       
   988         latency =
       
   989             gst_util_uint64_scale_int (total_samples, GST_SECOND, spec->rate);
       
   990         if (timestamp > latency)
       
   991           timestamp -= latency;
       
   992         else
       
   993           timestamp = 0;
       
   994       }
       
   995       case GST_BASE_AUDIO_SRC_SLAVE_NONE:
       
   996         break;
       
   997     }
       
   998   } else {
       
   999     GstClockTime base_time;
       
  1000 
       
  1001     /* to get the timestamp against the clock we also need to add our offset */
       
  1002     timestamp = gst_audio_clock_adjust (clock, timestamp);
       
  1003 
       
  1004     /* we are not slaved, subtract base_time */
       
  1005     base_time = GST_ELEMENT_CAST (src)->base_time;
   700     base_time = GST_ELEMENT_CAST (src)->base_time;
  1006 
   701 
  1007     if (timestamp > base_time) {
   702     if (timestamp > base_time)
  1008       timestamp -= base_time;
   703       timestamp -= base_time;
  1009       GST_LOG_OBJECT (src,
   704     else
  1010           "buffer timestamp %" GST_TIME_FORMAT " (base_time %" GST_TIME_FORMAT
       
  1011           ")", GST_TIME_ARGS (timestamp), GST_TIME_ARGS (base_time));
       
  1012     } else {
       
  1013       GST_LOG_OBJECT (src,
       
  1014           "buffer timestamp 0, ts %" GST_TIME_FORMAT " <= base_time %"
       
  1015           GST_TIME_FORMAT, GST_TIME_ARGS (timestamp),
       
  1016           GST_TIME_ARGS (base_time));
       
  1017       timestamp = 0;
   705       timestamp = 0;
  1018     }
   706 
  1019   }
   707     /* subtract latency */
  1020 
   708     latency = gst_util_uint64_scale_int (total_samples, GST_SECOND, spec->rate);
  1021 no_sync:
   709     if (timestamp > latency)
       
   710       timestamp -= latency;
       
   711     else
       
   712       timestamp = 0;
       
   713   }
  1022   GST_OBJECT_UNLOCK (src);
   714   GST_OBJECT_UNLOCK (src);
  1023 
   715 
  1024   GST_BUFFER_TIMESTAMP (buf) = timestamp;
   716   GST_BUFFER_TIMESTAMP (buf) = timestamp;
  1025   GST_BUFFER_DURATION (buf) = duration;
   717   GST_BUFFER_DURATION (buf) = duration;
  1026   GST_BUFFER_OFFSET (buf) = sample;
   718   GST_BUFFER_OFFSET (buf) = sample;
  1027   GST_BUFFER_OFFSET_END (buf) = sample + samples;
   719   GST_BUFFER_OFFSET_END (buf) = sample + samples;
       
   720 
       
   721   gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (bsrc)));
  1028 
   722 
  1029   *outbuf = buf;
   723   *outbuf = buf;
  1030 
   724 
  1031   return GST_FLOW_OK;
   725   return GST_FLOW_OK;
  1032 
   726 
  1089   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (element);
   783   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (element);
  1090 
   784 
  1091   switch (transition) {
   785   switch (transition) {
  1092     case GST_STATE_CHANGE_NULL_TO_READY:
   786     case GST_STATE_CHANGE_NULL_TO_READY:
  1093       GST_DEBUG_OBJECT (src, "NULL->READY");
   787       GST_DEBUG_OBJECT (src, "NULL->READY");
  1094       GST_OBJECT_LOCK (src);
       
  1095       if (src->ringbuffer == NULL) {
   788       if (src->ringbuffer == NULL) {
  1096         gst_audio_clock_reset (GST_AUDIO_CLOCK (src->clock), 0);
       
  1097         src->ringbuffer = gst_base_audio_src_create_ringbuffer (src);
   789         src->ringbuffer = gst_base_audio_src_create_ringbuffer (src);
  1098       }
   790       }
  1099       GST_OBJECT_UNLOCK (src);
       
  1100       if (!gst_ring_buffer_open_device (src->ringbuffer))
   791       if (!gst_ring_buffer_open_device (src->ringbuffer))
  1101         goto open_failed;
   792         goto open_failed;
  1102       break;
   793       break;
  1103     case GST_STATE_CHANGE_READY_TO_PAUSED:
   794     case GST_STATE_CHANGE_READY_TO_PAUSED:
  1104       GST_DEBUG_OBJECT (src, "READY->PAUSED");
   795       GST_DEBUG_OBJECT (src, "READY->PAUSED");
  1131       gst_ring_buffer_release (src->ringbuffer);
   822       gst_ring_buffer_release (src->ringbuffer);
  1132       break;
   823       break;
  1133     case GST_STATE_CHANGE_READY_TO_NULL:
   824     case GST_STATE_CHANGE_READY_TO_NULL:
  1134       GST_DEBUG_OBJECT (src, "READY->NULL");
   825       GST_DEBUG_OBJECT (src, "READY->NULL");
  1135       gst_ring_buffer_close_device (src->ringbuffer);
   826       gst_ring_buffer_close_device (src->ringbuffer);
  1136       GST_OBJECT_LOCK (src);
       
  1137       gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
   827       gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
  1138       src->ringbuffer = NULL;
   828       src->ringbuffer = NULL;
  1139       GST_OBJECT_UNLOCK (src);
       
  1140       break;
   829       break;
  1141     default:
   830     default:
  1142       break;
   831       break;
  1143   }
   832   }
  1144 
   833