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 |
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. |
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) |
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 /** |