gst_plugins_base/gst-libs/gst/audio/gstringbuffer.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    41 
    41 
    42 #include <string.h>
    42 #include <string.h>
    43 
    43 
    44 #include "gstringbuffer.h"
    44 #include "gstringbuffer.h"
    45 
    45 
       
    46 #ifdef __SYMBIAN32__
       
    47 #include <glib_global.h>
       
    48 #endif
       
    49 
    46 GST_DEBUG_CATEGORY_STATIC (gst_ring_buffer_debug);
    50 GST_DEBUG_CATEGORY_STATIC (gst_ring_buffer_debug);
    47 #define GST_CAT_DEFAULT gst_ring_buffer_debug
    51 #define GST_CAT_DEFAULT gst_ring_buffer_debug
    48 
    52 
    49 static void gst_ring_buffer_class_init (GstRingBufferClass * klass);
    53 static void gst_ring_buffer_class_init (GstRingBufferClass * klass);
    50 static void gst_ring_buffer_init (GstRingBuffer * ringbuffer);
    54 static void gst_ring_buffer_init (GstRingBuffer * ringbuffer);
    51 static void gst_ring_buffer_dispose (GObject * object);
    55 static void gst_ring_buffer_dispose (GObject * object);
    52 static void gst_ring_buffer_finalize (GObject * object);
    56 static void gst_ring_buffer_finalize (GObject * object);
    53 
    57 
    54 static gboolean gst_ring_buffer_pause_unlocked (GstRingBuffer * buf);
    58 static gboolean gst_ring_buffer_pause_unlocked (GstRingBuffer * buf);
    55 static void default_clear_all (GstRingBuffer * buf);
       
    56 static guint default_commit (GstRingBuffer * buf, guint64 * sample,
       
    57     guchar * data, gint in_samples, gint out_samples, gint * accum);
       
    58 
    59 
    59 static GstObjectClass *parent_class = NULL;
    60 static GstObjectClass *parent_class = NULL;
    60 
    61 
    61 /* ringbuffer abstract base class */
    62 /* ringbuffer abstract base class */
    62 #ifdef __SYMBIAN32__
    63 #ifdef __SYMBIAN32__
    94 static void
    95 static void
    95 gst_ring_buffer_class_init (GstRingBufferClass * klass)
    96 gst_ring_buffer_class_init (GstRingBufferClass * klass)
    96 {
    97 {
    97   GObjectClass *gobject_class;
    98   GObjectClass *gobject_class;
    98   GstObjectClass *gstobject_class;
    99   GstObjectClass *gstobject_class;
    99   GstRingBufferClass *gstringbuffer_class;
       
   100 
   100 
   101   gobject_class = (GObjectClass *) klass;
   101   gobject_class = (GObjectClass *) klass;
   102   gstobject_class = (GstObjectClass *) klass;
   102   gstobject_class = (GstObjectClass *) klass;
   103   gstringbuffer_class = (GstRingBufferClass *) klass;
       
   104 
   103 
   105   parent_class = g_type_class_peek_parent (klass);
   104   parent_class = g_type_class_peek_parent (klass);
   106 
   105 
   107   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ring_buffer_dispose);
   106   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ring_buffer_dispose);
   108   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ring_buffer_finalize);
   107   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ring_buffer_finalize);
   109 
       
   110   gstringbuffer_class->clear_all = GST_DEBUG_FUNCPTR (default_clear_all);
       
   111   gstringbuffer_class->commit = GST_DEBUG_FUNCPTR (default_commit);
       
   112 }
   108 }
   113 
   109 
   114 static void
   110 static void
   115 gst_ring_buffer_init (GstRingBuffer * ringbuffer)
   111 gst_ring_buffer_init (GstRingBuffer * ringbuffer)
   116 {
   112 {
   276   GST_DEBUG ("acquire ringbuffer: buffer time: %" G_GINT64_FORMAT " usec",
   272   GST_DEBUG ("acquire ringbuffer: buffer time: %" G_GINT64_FORMAT " usec",
   277       spec->buffer_time);
   273       spec->buffer_time);
   278   GST_DEBUG ("acquire ringbuffer: latency time: %" G_GINT64_FORMAT " usec",
   274   GST_DEBUG ("acquire ringbuffer: latency time: %" G_GINT64_FORMAT " usec",
   279       spec->latency_time);
   275       spec->latency_time);
   280   GST_DEBUG ("acquire ringbuffer: total segments: %d", spec->segtotal);
   276   GST_DEBUG ("acquire ringbuffer: total segments: %d", spec->segtotal);
   281   GST_DEBUG ("acquire ringbuffer: latency segments: %d", spec->seglatency);
       
   282   GST_DEBUG ("acquire ringbuffer: segment size: %d bytes = %d samples",
   277   GST_DEBUG ("acquire ringbuffer: segment size: %d bytes = %d samples",
   283       spec->segsize, spec->segsize / spec->bytes_per_sample);
   278       spec->segsize, spec->segsize / spec->bytes_per_sample);
   284   GST_DEBUG ("acquire ringbuffer: buffer size: %d bytes = %d samples",
   279   GST_DEBUG ("acquire ringbuffer: buffer size: %d bytes = %d samples",
   285       spec->segsize * spec->segtotal,
   280       spec->segsize * spec->segtotal,
   286       spec->segsize * spec->segtotal / spec->bytes_per_sample);
   281       spec->segsize * spec->segtotal / spec->bytes_per_sample);
   437       spec->latency_time, GST_SECOND / GST_USECOND);
   432       spec->latency_time, GST_SECOND / GST_USECOND);
   438   /* Round to an integer number of samples */
   433   /* Round to an integer number of samples */
   439   spec->segsize -= spec->segsize % spec->bytes_per_sample;
   434   spec->segsize -= spec->segsize % spec->bytes_per_sample;
   440 
   435 
   441   spec->segtotal = spec->buffer_time / spec->latency_time;
   436   spec->segtotal = spec->buffer_time / spec->latency_time;
   442   /* leave the latency undefined now, implementations can change it but if it's
       
   443    * not changed, we assume the same value as segtotal */
       
   444   spec->seglatency = -1;
       
   445 
   437 
   446   gst_ring_buffer_debug_spec_caps (spec);
   438   gst_ring_buffer_debug_spec_caps (spec);
   447   gst_ring_buffer_debug_spec_buff (spec);
   439   gst_ring_buffer_debug_spec_buff (spec);
   448 
   440 
   449   return TRUE;
   441   return TRUE;
   452 parse_error:
   444 parse_error:
   453   {
   445   {
   454     GST_DEBUG ("could not parse caps");
   446     GST_DEBUG ("could not parse caps");
   455     return FALSE;
   447     return FALSE;
   456   }
   448   }
   457 }
       
   458 
       
   459 /**
       
   460  * gst_ring_buffer_convert:
       
   461  * @buf: the #GstRingBuffer
       
   462  * @src_fmt: the source format
       
   463  * @src_val: the source value
       
   464  * @dest_fmt: the destination format
       
   465  * @dest_val: a location to store the converted value
       
   466  *
       
   467  * Convert @src_val in @src_fmt to the equivalent value in @dest_fmt. The result
       
   468  * will be put in @dest_val.
       
   469  *
       
   470  * Returns: TRUE if the conversion succeeded.
       
   471  *
       
   472  * Since: 0.10.22.
       
   473  */
       
   474 #ifdef __SYMBIAN32__
       
   475 EXPORT_C
       
   476 #endif
       
   477 
       
   478 gboolean
       
   479 gst_ring_buffer_convert (GstRingBuffer * buf,
       
   480     GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
       
   481 {
       
   482   gboolean res = TRUE;
       
   483   gint bps, rate;
       
   484 
       
   485   GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s (%d) to %s (%d)",
       
   486       src_val, gst_format_get_name (src_fmt), src_fmt,
       
   487       gst_format_get_name (dest_fmt), dest_fmt);
       
   488 
       
   489   if (src_fmt == dest_fmt || src_val == -1) {
       
   490     *dest_val = src_val;
       
   491     goto done;
       
   492   }
       
   493 
       
   494   /* get important info */
       
   495   GST_OBJECT_LOCK (buf);
       
   496   bps = buf->spec.bytes_per_sample;
       
   497   rate = buf->spec.rate;
       
   498   GST_OBJECT_UNLOCK (buf);
       
   499 
       
   500   if (bps == 0 || rate == 0) {
       
   501     GST_DEBUG ("no rate or bps configured");
       
   502     res = FALSE;
       
   503     goto done;
       
   504   }
       
   505 
       
   506   switch (src_fmt) {
       
   507     case GST_FORMAT_BYTES:
       
   508       switch (dest_fmt) {
       
   509         case GST_FORMAT_TIME:
       
   510           *dest_val = gst_util_uint64_scale_int (src_val / bps, GST_SECOND,
       
   511               rate);
       
   512           break;
       
   513         case GST_FORMAT_DEFAULT:
       
   514           *dest_val = src_val / bps;
       
   515           break;
       
   516         default:
       
   517           res = FALSE;
       
   518           break;
       
   519       }
       
   520       break;
       
   521     case GST_FORMAT_DEFAULT:
       
   522       switch (dest_fmt) {
       
   523         case GST_FORMAT_TIME:
       
   524           *dest_val = gst_util_uint64_scale_int (src_val, GST_SECOND, rate);
       
   525           break;
       
   526         case GST_FORMAT_BYTES:
       
   527           *dest_val = src_val * bps;
       
   528           break;
       
   529         default:
       
   530           res = FALSE;
       
   531           break;
       
   532       }
       
   533       break;
       
   534     case GST_FORMAT_TIME:
       
   535       switch (dest_fmt) {
       
   536         case GST_FORMAT_DEFAULT:
       
   537           *dest_val = gst_util_uint64_scale_int (src_val, rate, GST_SECOND);
       
   538           break;
       
   539         case GST_FORMAT_BYTES:
       
   540           *dest_val = gst_util_uint64_scale_int (src_val, rate, GST_SECOND);
       
   541           *dest_val *= bps;
       
   542           break;
       
   543         default:
       
   544           res = FALSE;
       
   545           break;
       
   546       }
       
   547       break;
       
   548     default:
       
   549       res = FALSE;
       
   550       break;
       
   551   }
       
   552 done:
       
   553   GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, res, *dest_val);
       
   554 
       
   555   return res;
       
   556 }
   449 }
   557 
   450 
   558 /**
   451 /**
   559  * gst_ring_buffer_set_callback:
   452  * gst_ring_buffer_set_callback:
   560  * @buf: the #GstRingBuffer to set the callback on
   453  * @buf: the #GstRingBuffer to set the callback on
   745   GST_OBJECT_UNLOCK (buf);
   638   GST_OBJECT_UNLOCK (buf);
   746 
   639 
   747   return res;
   640   return res;
   748 }
   641 }
   749 
   642 
       
   643 
   750 /**
   644 /**
   751  * gst_ring_buffer_acquire:
   645  * gst_ring_buffer_acquire:
   752  * @buf: the #GstRingBuffer to acquire
   646  * @buf: the #GstRingBuffer to acquire
   753  * @spec: the specs of the buffer
   647  * @spec: the specs of the buffer
   754  *
   648  *
   792   if (G_UNLIKELY (!res))
   686   if (G_UNLIKELY (!res))
   793     goto acquire_failed;
   687     goto acquire_failed;
   794 
   688 
   795   if (G_UNLIKELY ((bps = buf->spec.bytes_per_sample) == 0))
   689   if (G_UNLIKELY ((bps = buf->spec.bytes_per_sample) == 0))
   796     goto invalid_bps;
   690     goto invalid_bps;
   797 
       
   798   /* if the seglatency was overwritten with something else than -1, use it, else
       
   799    * assume segtotal as the latency */
       
   800   if (buf->spec.seglatency == -1)
       
   801     buf->spec.seglatency = buf->spec.segtotal;
       
   802 
   691 
   803   segsize = buf->spec.segsize;
   692   segsize = buf->spec.segsize;
   804 
   693 
   805   buf->samples_per_seg = segsize / bps;
   694   buf->samples_per_seg = segsize / bps;
   806 
   695 
   949 
   838 
   950   return res;
   839   return res;
   951 }
   840 }
   952 
   841 
   953 /**
   842 /**
   954  * gst_ring_buffer_activate:
       
   955  * @buf: the #GstRingBuffer to activate
       
   956  * @active: the new mode
       
   957  *
       
   958  * Activate @buf to start or stop pulling data.
       
   959  *
       
   960  * MT safe.
       
   961  *
       
   962  * Returns: TRUE if the device could be activated in the requested mode,
       
   963  * FALSE on error.
       
   964  *
       
   965  * Since: 0.10.22.
       
   966  */
       
   967 #ifdef __SYMBIAN32__
       
   968 EXPORT_C
       
   969 #endif
       
   970 
       
   971 gboolean
       
   972 gst_ring_buffer_activate (GstRingBuffer * buf, gboolean active)
       
   973 {
       
   974   gboolean res = FALSE;
       
   975   GstRingBufferClass *rclass;
       
   976 
       
   977   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
       
   978 
       
   979   GST_DEBUG_OBJECT (buf, "activate device");
       
   980 
       
   981   GST_OBJECT_LOCK (buf);
       
   982   if (G_UNLIKELY (active && !buf->acquired))
       
   983     goto not_acquired;
       
   984 
       
   985   if (G_UNLIKELY (buf->abidata.ABI.active == active))
       
   986     goto was_active;
       
   987 
       
   988   rclass = GST_RING_BUFFER_GET_CLASS (buf);
       
   989   /* if there is no activate function we assume it was started/released
       
   990    * in the acquire method */
       
   991   if (G_LIKELY (rclass->activate))
       
   992     res = rclass->activate (buf, active);
       
   993   else
       
   994     res = TRUE;
       
   995 
       
   996   if (G_UNLIKELY (!res))
       
   997     goto activate_failed;
       
   998 
       
   999   buf->abidata.ABI.active = active;
       
  1000 
       
  1001 done:
       
  1002   GST_OBJECT_UNLOCK (buf);
       
  1003 
       
  1004   return res;
       
  1005 
       
  1006   /* ERRORS */
       
  1007 not_acquired:
       
  1008   {
       
  1009     GST_DEBUG_OBJECT (buf, "device not acquired");
       
  1010     g_critical ("Device for %p not acquired", buf);
       
  1011     res = FALSE;
       
  1012     goto done;
       
  1013   }
       
  1014 was_active:
       
  1015   {
       
  1016     res = TRUE;
       
  1017     GST_DEBUG_OBJECT (buf, "device was active in mode %d", active);
       
  1018     goto done;
       
  1019   }
       
  1020 activate_failed:
       
  1021   {
       
  1022     GST_DEBUG_OBJECT (buf, "failed to activate device");
       
  1023     goto done;
       
  1024   }
       
  1025 }
       
  1026 
       
  1027 /**
       
  1028  * gst_ring_buffer_is_active:
       
  1029  * @buf: the #GstRingBuffer
       
  1030  *
       
  1031  * Check if @buf is activated.
       
  1032  *
       
  1033  * MT safe.
       
  1034  *
       
  1035  * Returns: TRUE if the device is active.
       
  1036  *
       
  1037  * Since: 0.10.22.
       
  1038  */
       
  1039 #ifdef __SYMBIAN32__
       
  1040 EXPORT_C
       
  1041 #endif
       
  1042 
       
  1043 gboolean
       
  1044 gst_ring_buffer_is_active (GstRingBuffer * buf)
       
  1045 {
       
  1046   gboolean res;
       
  1047 
       
  1048   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
       
  1049 
       
  1050   GST_OBJECT_LOCK (buf);
       
  1051   res = buf->abidata.ABI.active;
       
  1052   GST_OBJECT_UNLOCK (buf);
       
  1053 
       
  1054   return res;
       
  1055 }
       
  1056 
       
  1057 
       
  1058 /**
       
  1059  * gst_ring_buffer_set_flushing:
   843  * gst_ring_buffer_set_flushing:
  1060  * @buf: the #GstRingBuffer to flush
   844  * @buf: the #GstRingBuffer to flush
  1061  * @flushing: the new mode
   845  * @flushing: the new mode
  1062  *
   846  *
  1063  * Set the ringbuffer to flushing mode or normal mode.
   847  * Set the ringbuffer to flushing mode or normal mode.
  1074   g_return_if_fail (GST_IS_RING_BUFFER (buf));
   858   g_return_if_fail (GST_IS_RING_BUFFER (buf));
  1075 
   859 
  1076   GST_OBJECT_LOCK (buf);
   860   GST_OBJECT_LOCK (buf);
  1077   buf->abidata.ABI.flushing = flushing;
   861   buf->abidata.ABI.flushing = flushing;
  1078 
   862 
       
   863   gst_ring_buffer_clear_all (buf);
  1079   if (flushing) {
   864   if (flushing) {
  1080     gst_ring_buffer_pause_unlocked (buf);
   865     gst_ring_buffer_pause_unlocked (buf);
  1081   } else {
       
  1082     gst_ring_buffer_clear_all (buf);
       
  1083   }
   866   }
  1084   GST_OBJECT_UNLOCK (buf);
   867   GST_OBJECT_UNLOCK (buf);
  1085 }
   868 }
  1086 
   869 
  1087 /**
   870 /**
  1119   /* if stopped, set to started */
   902   /* if stopped, set to started */
  1120   res = g_atomic_int_compare_and_exchange (&buf->state,
   903   res = g_atomic_int_compare_and_exchange (&buf->state,
  1121       GST_RING_BUFFER_STATE_STOPPED, GST_RING_BUFFER_STATE_STARTED);
   904       GST_RING_BUFFER_STATE_STOPPED, GST_RING_BUFFER_STATE_STARTED);
  1122 
   905 
  1123   if (!res) {
   906   if (!res) {
  1124     GST_DEBUG_OBJECT (buf, "was not stopped, try paused");
       
  1125     /* was not stopped, try from paused */
   907     /* was not stopped, try from paused */
  1126     res = g_atomic_int_compare_and_exchange (&buf->state,
   908     res = g_atomic_int_compare_and_exchange (&buf->state,
  1127         GST_RING_BUFFER_STATE_PAUSED, GST_RING_BUFFER_STATE_STARTED);
   909         GST_RING_BUFFER_STATE_PAUSED, GST_RING_BUFFER_STATE_STARTED);
  1128     if (!res) {
   910     if (!res) {
  1129       /* was not paused either, must be started then */
   911       /* was not paused either, must be started then */
  1130       res = TRUE;
   912       res = TRUE;
  1131       GST_DEBUG_OBJECT (buf, "was not paused, must have been started");
   913       GST_DEBUG_OBJECT (buf, "was started");
  1132       goto done;
   914       goto done;
  1133     }
   915     }
  1134     resume = TRUE;
   916     resume = TRUE;
  1135     GST_DEBUG_OBJECT (buf, "resuming");
   917     GST_DEBUG_OBJECT (buf, "resuming");
  1136   }
   918   }
  1287   /* if started, set to stopped */
  1069   /* if started, set to stopped */
  1288   res = g_atomic_int_compare_and_exchange (&buf->state,
  1070   res = g_atomic_int_compare_and_exchange (&buf->state,
  1289       GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_STOPPED);
  1071       GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_STOPPED);
  1290 
  1072 
  1291   if (!res) {
  1073   if (!res) {
  1292     GST_DEBUG_OBJECT (buf, "was not started, try paused");
  1074     /* was not started, must be stopped then */
  1293     /* was not started, try from paused */
  1075     GST_DEBUG_OBJECT (buf, "was not started");
  1294     res = g_atomic_int_compare_and_exchange (&buf->state,
  1076     res = TRUE;
  1295         GST_RING_BUFFER_STATE_PAUSED, GST_RING_BUFFER_STATE_STOPPED);
  1077     goto done;
  1296     if (!res) {
       
  1297       /* was not paused either, must have been stopped then */
       
  1298       res = TRUE;
       
  1299       GST_DEBUG_OBJECT (buf, "was not paused, must have been stopped");
       
  1300       goto done;
       
  1301     }
       
  1302   }
  1078   }
  1303 
  1079 
  1304   /* signal any waiters */
  1080   /* signal any waiters */
  1305   GST_DEBUG_OBJECT (buf, "signal waiter");
  1081   GST_DEBUG_OBJECT (buf, "signal waiter");
  1306   GST_RING_BUFFER_SIGNAL (buf);
  1082   GST_RING_BUFFER_SIGNAL (buf);
  1442 
  1218 
  1443   GST_DEBUG_OBJECT (buf, "set sample to %llu, segbase %d", sample,
  1219   GST_DEBUG_OBJECT (buf, "set sample to %llu, segbase %d", sample,
  1444       buf->segbase);
  1220       buf->segbase);
  1445 }
  1221 }
  1446 
  1222 
  1447 static void
  1223 /**
  1448 default_clear_all (GstRingBuffer * buf)
  1224  * gst_ring_buffer_clear_all:
       
  1225  * @buf: the #GstRingBuffer to clear
       
  1226  *
       
  1227  * Fill the ringbuffer with silence.
       
  1228  *
       
  1229  * MT safe.
       
  1230  */
       
  1231 #ifdef __SYMBIAN32__
       
  1232 EXPORT_C
       
  1233 #endif
       
  1234 
       
  1235 void
       
  1236 gst_ring_buffer_clear_all (GstRingBuffer * buf)
  1449 {
  1237 {
  1450   gint i;
  1238   gint i;
       
  1239 
       
  1240   g_return_if_fail (GST_IS_RING_BUFFER (buf));
  1451 
  1241 
  1452   /* not fatal, we just are not negotiated yet */
  1242   /* not fatal, we just are not negotiated yet */
  1453   if (G_UNLIKELY (buf->spec.segtotal <= 0))
  1243   if (G_UNLIKELY (buf->spec.segtotal <= 0))
  1454     return;
  1244     return;
  1455 
  1245 
  1456   GST_DEBUG_OBJECT (buf, "clear all segments");
  1246   GST_DEBUG_OBJECT (buf, "clear all segments");
  1457 
  1247 
  1458   for (i = 0; i < buf->spec.segtotal; i++) {
  1248   for (i = 0; i < buf->spec.segtotal; i++) {
  1459     gst_ring_buffer_clear (buf, i);
  1249     gst_ring_buffer_clear (buf, i);
  1460   }
  1250   }
  1461 }
       
  1462 
       
  1463 /**
       
  1464  * gst_ring_buffer_clear_all:
       
  1465  * @buf: the #GstRingBuffer to clear
       
  1466  *
       
  1467  * Fill the ringbuffer with silence.
       
  1468  *
       
  1469  * MT safe.
       
  1470  */
       
  1471 #ifdef __SYMBIAN32__
       
  1472 EXPORT_C
       
  1473 #endif
       
  1474 
       
  1475 void
       
  1476 gst_ring_buffer_clear_all (GstRingBuffer * buf)
       
  1477 {
       
  1478   GstRingBufferClass *rclass;
       
  1479 
       
  1480   g_return_if_fail (GST_IS_RING_BUFFER (buf));
       
  1481 
       
  1482   rclass = GST_RING_BUFFER_GET_CLASS (buf);
       
  1483 
       
  1484   if (G_LIKELY (rclass->clear_all))
       
  1485     rclass->clear_all (buf);
       
  1486 }
  1251 }
  1487 
  1252 
  1488 
  1253 
  1489 static gboolean
  1254 static gboolean
  1490 wait_segment (GstRingBuffer * buf)
  1255 wait_segment (GstRingBuffer * buf)
  1603   while (s <= se && d < de) {			\
  1368   while (s <= se && d < de) {			\
  1604     if (!skip)					\
  1369     if (!skip)					\
  1605       memcpy (d, se, bps);			\
  1370       memcpy (d, se, bps);			\
  1606     se -= bps;					\
  1371     se -= bps;					\
  1607     *accum += outr;				\
  1372     *accum += outr;				\
  1608     while (d < de && (*accum << 1) >= inr) {	\
  1373     while ((*accum << 1) >= inr) {		\
  1609       *accum -= inr;				\
  1374       *accum -= inr;				\
  1610       d += bps;					\
  1375       d += bps;					\
  1611     }						\
  1376     }						\
  1612   }						\
  1377   }						\
  1613   in_samples -= (sb - se)/bps;			\
  1378   in_samples -= (sb - se)/bps;			\
  1621   while (s <= se && d < de) {			\
  1386   while (s <= se && d < de) {			\
  1622     if (!skip)					\
  1387     if (!skip)					\
  1623       memcpy (d, se, bps);			\
  1388       memcpy (d, se, bps);			\
  1624     d += bps;					\
  1389     d += bps;					\
  1625     *accum += inr;				\
  1390     *accum += inr;				\
  1626     while (s <= se && (*accum << 1) >= outr) {	\
  1391     while ((*accum << 1) >= outr) {		\
  1627       *accum -= outr;				\
  1392       *accum -= outr;				\
  1628       se -= bps;				\
  1393       se -= bps;				\
  1629     }						\
  1394     }						\
  1630   }						\
  1395   }						\
  1631   in_samples -= (sb - se)/bps;			\
  1396   in_samples -= (sb - se)/bps;			\
  1632   out_samples -= (d - db)/bps;			\
  1397   out_samples -= (d - db)/bps;			\
  1633   GST_DEBUG ("rev_down end %d/%d",*accum,*toprocess);	\
  1398   GST_DEBUG ("rev_down end %d/%d",*accum,*toprocess);	\
  1634 } G_STMT_END
  1399 } G_STMT_END
  1635 
  1400 
  1636 static guint
  1401 /**
  1637 default_commit (GstRingBuffer * buf, guint64 * sample,
  1402  * gst_ring_buffer_commit_full:
       
  1403  * @buf: the #GstRingBuffer to commit
       
  1404  * @sample: the sample position of the data
       
  1405  * @data: the data to commit
       
  1406  * @in_samples: the number of samples in the data to commit
       
  1407  * @out_samples: the number of samples to write to the ringbuffer
       
  1408  * @accum: accumulator for rate conversion.
       
  1409  *
       
  1410  * Commit @in_samples samples pointed to by @data to the ringbuffer @buf. 
       
  1411  *
       
  1412  * @in_samples and @out_samples define the rate conversion to perform on the the
       
  1413  * samples in @data. For negative rates, @out_samples must be negative and
       
  1414  * @in_samples positive.
       
  1415  *
       
  1416  * When @out_samples is positive, the first sample will be written at position @sample
       
  1417  * in the ringbuffer. When @out_samples is negative, the last sample will be written to
       
  1418  * @sample in reverse order.
       
  1419  *
       
  1420  * @out_samples does not need to be a multiple of the segment size of the ringbuffer
       
  1421  * although it is recommended for optimal performance. 
       
  1422  *
       
  1423  * @accum will hold a temporary accumulator used in rate conversion and should be
       
  1424  * set to 0 when this function is first called. In case the commit operation is
       
  1425  * interrupted, one can resume the processing by passing the previously returned
       
  1426  * @accum value back to this function.
       
  1427  *
       
  1428  * Returns: The number of samples written to the ringbuffer or -1 on error. The
       
  1429  * number of samples written can be less than @out_samples when @buf was interrupted
       
  1430  * with a flush or stop.
       
  1431  *
       
  1432  * Since: 0.10.11.
       
  1433  *
       
  1434  * MT safe.
       
  1435  */
       
  1436 #ifdef __SYMBIAN32__
       
  1437 EXPORT_C
       
  1438 #endif
       
  1439 
       
  1440 guint
       
  1441 gst_ring_buffer_commit_full (GstRingBuffer * buf, guint64 * sample,
  1638     guchar * data, gint in_samples, gint out_samples, gint * accum)
  1442     guchar * data, gint in_samples, gint out_samples, gint * accum)
  1639 {
  1443 {
  1640   gint segdone;
  1444   gint segdone;
  1641   gint segsize, segtotal, bps, sps;
  1445   gint segsize, segtotal, bps, sps;
  1642   guint8 *dest, *data_end;
  1446   guint8 *dest, *data_end;
  1643   gint writeseg, sampleoff;
  1447   gint writeseg, sampleoff;
  1644   gint *toprocess;
  1448   gint *toprocess;
  1645   gint inr, outr;
  1449   gint inr, outr;
  1646   gboolean reverse;
  1450   gboolean reverse;
  1647 
  1451 
       
  1452   if (G_UNLIKELY (in_samples == 0 || out_samples == 0))
       
  1453     return in_samples;
       
  1454 
       
  1455   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
  1648   g_return_val_if_fail (buf->data != NULL, -1);
  1456   g_return_val_if_fail (buf->data != NULL, -1);
  1649   g_return_val_if_fail (data != NULL, -1);
  1457   g_return_val_if_fail (data != NULL, -1);
  1650 
  1458 
  1651   dest = GST_BUFFER_DATA (buf->data);
  1459   dest = GST_BUFFER_DATA (buf->data);
  1652   segsize = buf->spec.segsize;
  1460   segsize = buf->spec.segsize;
  1761     goto done;
  1569     goto done;
  1762   }
  1570   }
  1763 }
  1571 }
  1764 
  1572 
  1765 /**
  1573 /**
  1766  * gst_ring_buffer_commit_full:
       
  1767  * @buf: the #GstRingBuffer to commit
       
  1768  * @sample: the sample position of the data
       
  1769  * @data: the data to commit
       
  1770  * @in_samples: the number of samples in the data to commit
       
  1771  * @out_samples: the number of samples to write to the ringbuffer
       
  1772  * @accum: accumulator for rate conversion.
       
  1773  *
       
  1774  * Commit @in_samples samples pointed to by @data to the ringbuffer @buf. 
       
  1775  *
       
  1776  * @in_samples and @out_samples define the rate conversion to perform on the the
       
  1777  * samples in @data. For negative rates, @out_samples must be negative and
       
  1778  * @in_samples positive.
       
  1779  *
       
  1780  * When @out_samples is positive, the first sample will be written at position @sample
       
  1781  * in the ringbuffer. When @out_samples is negative, the last sample will be written to
       
  1782  * @sample in reverse order.
       
  1783  *
       
  1784  * @out_samples does not need to be a multiple of the segment size of the ringbuffer
       
  1785  * although it is recommended for optimal performance. 
       
  1786  *
       
  1787  * @accum will hold a temporary accumulator used in rate conversion and should be
       
  1788  * set to 0 when this function is first called. In case the commit operation is
       
  1789  * interrupted, one can resume the processing by passing the previously returned
       
  1790  * @accum value back to this function.
       
  1791  *
       
  1792  * MT safe.
       
  1793  *
       
  1794  * Returns: The number of samples written to the ringbuffer or -1 on error. The
       
  1795  * number of samples written can be less than @out_samples when @buf was interrupted
       
  1796  * with a flush or stop.
       
  1797  *
       
  1798  * Since: 0.10.11.
       
  1799  */
       
  1800 #ifdef __SYMBIAN32__
       
  1801 EXPORT_C
       
  1802 #endif
       
  1803 
       
  1804 guint
       
  1805 gst_ring_buffer_commit_full (GstRingBuffer * buf, guint64 * sample,
       
  1806     guchar * data, gint in_samples, gint out_samples, gint * accum)
       
  1807 {
       
  1808   GstRingBufferClass *rclass;
       
  1809   guint res = -1;
       
  1810 
       
  1811   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
       
  1812 
       
  1813   if (G_UNLIKELY (in_samples == 0 || out_samples == 0))
       
  1814     return in_samples;
       
  1815 
       
  1816   rclass = GST_RING_BUFFER_GET_CLASS (buf);
       
  1817 
       
  1818   if (G_LIKELY (rclass->commit))
       
  1819     res = rclass->commit (buf, sample, data, in_samples, out_samples, accum);
       
  1820 
       
  1821   return res;
       
  1822 }
       
  1823 
       
  1824 /**
       
  1825  * gst_ring_buffer_commit:
  1574  * gst_ring_buffer_commit:
  1826  * @buf: the #GstRingBuffer to commit
  1575  * @buf: the #GstRingBuffer to commit
  1827  * @sample: the sample position of the data
  1576  * @sample: the sample position of the data
  1828  * @data: the data to commit
  1577  * @data: the data to commit
  1829  * @len: the number of samples in the data to commit
  1578  * @len: the number of samples in the data to commit
  1991   guint8 *data;
  1740   guint8 *data;
  1992   gint segdone;
  1741   gint segdone;
  1993 
  1742 
  1994   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
  1743   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
  1995 
  1744 
       
  1745   /* buffer must be started */
       
  1746   if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED)
       
  1747     return FALSE;
       
  1748 
  1996   g_return_val_if_fail (buf->data != NULL, FALSE);
  1749   g_return_val_if_fail (buf->data != NULL, FALSE);
  1997   g_return_val_if_fail (segment != NULL, FALSE);
  1750   g_return_val_if_fail (segment != NULL, FALSE);
  1998   g_return_val_if_fail (readptr != NULL, FALSE);
  1751   g_return_val_if_fail (readptr != NULL, FALSE);
  1999   g_return_val_if_fail (len != NULL, FALSE);
  1752   g_return_val_if_fail (len != NULL, FALSE);
  2000 
  1753 
  2001   data = GST_BUFFER_DATA (buf->data);
  1754   data = GST_BUFFER_DATA (buf->data);
  2002 
  1755 
  2003   if (buf->callback == NULL) {
       
  2004     /* push mode, fail when nothing is started */
       
  2005     if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED)
       
  2006       return FALSE;
       
  2007   }
       
  2008 
       
  2009   /* get the position of the pointer */
  1756   /* get the position of the pointer */
  2010   segdone = g_atomic_int_get (&buf->segdone);
  1757   segdone = g_atomic_int_get (&buf->segdone);
  2011 
  1758 
  2012   *segment = segdone % buf->spec.segtotal;
  1759   *segment = segdone % buf->spec.segtotal;
  2013   *len = buf->spec.segsize;
  1760   *len = buf->spec.segsize;
  2014   *readptr = data + *segment * *len;
  1761   *readptr = data + *segment * *len;
  2015 
       
  2016   GST_LOG ("prepare read from segment %d (real %d) @%p",
       
  2017       *segment, segdone, *readptr);
       
  2018 
  1762 
  2019   /* callback to fill the memory with data, for pull based
  1763   /* callback to fill the memory with data, for pull based
  2020    * scheduling. */
  1764    * scheduling. */
  2021   if (buf->callback)
  1765   if (buf->callback)
  2022     buf->callback (buf, *readptr, *len, buf->cb_data);
  1766     buf->callback (buf, *readptr, *len, buf->cb_data);
       
  1767 
       
  1768   GST_LOG ("prepare read from segment %d (real %d) @%p",
       
  1769       *segment, segdone, *readptr);
  2023 
  1770 
  2024   return TRUE;
  1771   return TRUE;
  2025 }
  1772 }
  2026 
  1773 
  2027 /**
  1774 /**
  2102  * @allowed: the new value
  1849  * @allowed: the new value
  2103  *
  1850  *
  2104  * Tell the ringbuffer that it is allowed to start playback when
  1851  * Tell the ringbuffer that it is allowed to start playback when
  2105  * the ringbuffer is filled with samples. 
  1852  * the ringbuffer is filled with samples. 
  2106  *
  1853  *
  2107  * MT safe.
       
  2108  *
       
  2109  * Since: 0.10.6
  1854  * Since: 0.10.6
       
  1855  *
       
  1856  * MT safe.
  2110  */
  1857  */
  2111 #ifdef __SYMBIAN32__
  1858 #ifdef __SYMBIAN32__
  2112 EXPORT_C
  1859 EXPORT_C
  2113 #endif
  1860 #endif
  2114 
  1861 
  2116 gst_ring_buffer_may_start (GstRingBuffer * buf, gboolean allowed)
  1863 gst_ring_buffer_may_start (GstRingBuffer * buf, gboolean allowed)
  2117 {
  1864 {
  2118   g_return_if_fail (GST_IS_RING_BUFFER (buf));
  1865   g_return_if_fail (GST_IS_RING_BUFFER (buf));
  2119 
  1866 
  2120   GST_LOG_OBJECT (buf, "may start: %d", allowed);
  1867   GST_LOG_OBJECT (buf, "may start: %d", allowed);
  2121   g_atomic_int_set (&buf->abidata.ABI.may_start, allowed);
  1868   gst_atomic_int_set (&buf->abidata.ABI.may_start, allowed);
  2122 }
  1869 }