Add methods to more accuratly control the pulling thread of a ringbuffer.

Original commit message from CVS:
* docs/libs/gst-plugins-base-libs-sections.txt:
* gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_convert),
(gst_ring_buffer_activate), (gst_ring_buffer_is_active):
* gst-libs/gst/audio/gstringbuffer.h:
Add methods to more accuratly control the pulling thread of a
ringbuffer.
Add format conversion helper code to the ringbuffer.
API: GstRingBuffer:gst_ring_buffer_activate()
API: GstRingBuffer:gst_ring_buffer_is_active()
API: GstRingBuffer:gst_ring_buffer_convert()
This commit is contained in:
Wim Taymans 2008-10-17 13:19:05 +00:00
parent 927999603a
commit a6b78893c0
4 changed files with 223 additions and 2 deletions

View file

@ -1,3 +1,16 @@
2008-10-17 Wim Taymans <wim.taymans@collabora.co.uk>
* docs/libs/gst-plugins-base-libs-sections.txt:
* gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_convert),
(gst_ring_buffer_activate), (gst_ring_buffer_is_active):
* gst-libs/gst/audio/gstringbuffer.h:
Add methods to more accuratly control the pulling thread of a
ringbuffer.
Add format conversion helper code to the ringbuffer.
API: GstRingBuffer:gst_ring_buffer_activate()
API: GstRingBuffer:gst_ring_buffer_is_active()
API: GstRingBuffer:gst_ring_buffer_convert()
2008-10-16 Wim Taymans <wim.taymans@collabora.co.uk>
* gst-libs/gst/audio/gstaudiosink.c: (audioringbuffer_thread_func),

View file

@ -172,6 +172,9 @@ gst_ring_buffer_acquire
gst_ring_buffer_release
gst_ring_buffer_is_acquired
gst_ring_buffer_activate
gst_ring_buffer_is_active
gst_ring_buffer_start
gst_ring_buffer_pause
gst_ring_buffer_stop
@ -181,6 +184,7 @@ gst_ring_buffer_samples_done
gst_ring_buffer_set_sample
gst_ring_buffer_commit
gst_ring_buffer_commit_full
gst_ring_buffer_convert
gst_ring_buffer_prepare_read
gst_ring_buffer_read

View file

@ -432,6 +432,101 @@ parse_error:
}
}
/**
* gst_ring_buffer_convert:
* @buf: the #GstRingBuffer
* @src_fmt: the source format
* @src_val: the source value
* @dest_fmt: the destination format
* @dest_val: a location to store the converted value
*
* Convert @src_val in @src_fmt to the equivalent value in @dest_fmt. The result
* will be put in @dest_val.
*
* Returns: TRUE if the conversion succeeded.
*
* Since: 0.10.22.
*/
gboolean
gst_ring_buffer_convert (GstRingBuffer * buf,
GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
{
gboolean res = TRUE;
gint bps, rate;
GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s (%d) to %s (%d)",
src_val, gst_format_get_name (src_fmt), src_fmt,
gst_format_get_name (dest_fmt), dest_fmt);
if (src_fmt == dest_fmt || src_val == -1) {
*dest_val = src_val;
goto done;
}
/* get important info */
GST_OBJECT_LOCK (buf);
bps = buf->spec.bytes_per_sample;
rate = buf->spec.rate;
GST_OBJECT_UNLOCK (buf);
if (bps == 0 || rate == 0) {
GST_DEBUG ("no rate or bps configured");
res = FALSE;
goto done;
}
switch (src_fmt) {
case GST_FORMAT_BYTES:
switch (dest_fmt) {
case GST_FORMAT_TIME:
*dest_val = gst_util_uint64_scale_int (src_val / bps, GST_SECOND,
rate);
break;
case GST_FORMAT_DEFAULT:
*dest_val = src_val / bps;
break;
default:
res = FALSE;
break;
}
break;
case GST_FORMAT_DEFAULT:
switch (dest_fmt) {
case GST_FORMAT_TIME:
*dest_val = gst_util_uint64_scale_int (src_val, GST_SECOND, rate);
break;
case GST_FORMAT_BYTES:
*dest_val = src_val * bps;
break;
default:
res = FALSE;
break;
}
break;
case GST_FORMAT_TIME:
switch (dest_fmt) {
case GST_FORMAT_DEFAULT:
*dest_val = gst_util_uint64_scale_int (src_val, rate, GST_SECOND);
break;
case GST_FORMAT_BYTES:
*dest_val = gst_util_uint64_scale_int (src_val, rate, GST_SECOND);
*dest_val *= bps;
break;
default:
res = FALSE;
break;
}
break;
default:
res = FALSE;
break;
}
done:
GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, res, *dest_val);
return res;
}
/**
* gst_ring_buffer_set_callback:
* @buf: the #GstRingBuffer to set the callback on
@ -608,7 +703,6 @@ gst_ring_buffer_device_is_open (GstRingBuffer * buf)
return res;
}
/**
* gst_ring_buffer_acquire:
* @buf: the #GstRingBuffer to acquire
@ -800,6 +894,103 @@ gst_ring_buffer_is_acquired (GstRingBuffer * buf)
return res;
}
/**
* gst_ring_buffer_activate:
* @buf: the #GstRingBuffer to activate
* @active: the new mode
*
* Activate @buf to start or stop pulling data.
*
* Returns: TRUE if the device could be activated in the requested mode,
* FALSE on error.
*
* Since: 0.10.22.
*
* MT safe.
*/
gboolean
gst_ring_buffer_activate (GstRingBuffer * buf, gboolean active)
{
gboolean res = FALSE;
GstRingBufferClass *rclass;
g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
GST_DEBUG_OBJECT (buf, "activate device");
GST_OBJECT_LOCK (buf);
if (G_UNLIKELY (active && !buf->acquired))
goto not_acquired;
if (G_UNLIKELY (buf->abidata.ABI.active == active))
goto was_active;
rclass = GST_RING_BUFFER_GET_CLASS (buf);
/* if there is no activate function we assume it was started/released
* in the acquire method */
if (G_LIKELY (rclass->activate))
res = rclass->activate (buf, active);
else
res = TRUE;
if (G_UNLIKELY (!res))
goto activate_failed;
buf->abidata.ABI.active = active;
done:
GST_OBJECT_UNLOCK (buf);
return res;
/* ERRORS */
not_acquired:
{
GST_DEBUG_OBJECT (buf, "device not acquired");
g_critical ("Device for %p not acquired", buf);
res = FALSE;
goto done;
}
was_active:
{
res = TRUE;
GST_DEBUG_OBJECT (buf, "device was active in mode %d", active);
goto done;
}
activate_failed:
{
GST_DEBUG_OBJECT (buf, "failed to activate device");
goto done;
}
}
/**
* gst_ring_buffer_is_active:
* @buf: the #GstRingBuffer
*
* Check if @buf is activated.
*
* Returns: TRUE if the device is active.
*
* Since: 0.10.22.
*
* MT safe.
*/
gboolean
gst_ring_buffer_is_active (GstRingBuffer * buf)
{
gboolean res;
g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
GST_OBJECT_LOCK (buf);
res = buf->abidata.ABI.active;
GST_OBJECT_UNLOCK (buf);
return res;
}
/**
* gst_ring_buffer_set_flushing:
* @buf: the #GstRingBuffer to flush

View file

@ -279,6 +279,7 @@ struct _GstRingBuffer {
gboolean flushing;
/* ATOMIC */
gint may_start;
gboolean active;
} ABI;
/* adding + 0 to mark ABI change to be undone later */
gpointer _gst_reserved[GST_PADDING + 0];
@ -297,6 +298,7 @@ struct _GstRingBuffer {
* @resume: resume processing of samples after pause
* @stop: stop processing of samples
* @delay: get number of samples queued in device
* @activate: activate the thread that starts pulling. Since 0.10.22
*
* The vmethods that subclasses can override to implement the ringbuffer.
*/
@ -316,8 +318,11 @@ struct _GstRingBufferClass {
guint (*delay) (GstRingBuffer *buf);
/* ABI added */
gboolean (*activate) (GstRingBuffer *buf, gboolean active);
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
gpointer _gst_reserved[GST_PADDING - 1];
};
GType gst_ring_buffer_get_type(void);
@ -330,6 +335,10 @@ gboolean gst_ring_buffer_parse_caps (GstRingBufferSpec *spec, GstCap
void gst_ring_buffer_debug_spec_caps (GstRingBufferSpec *spec);
void gst_ring_buffer_debug_spec_buff (GstRingBufferSpec *spec);
gboolean gst_ring_buffer_convert (GstRingBuffer * buf, GstFormat src_fmt,
gint64 src_val, GstFormat dest_fmt,
gint64 * dest_val);
/* device state */
gboolean gst_ring_buffer_open_device (GstRingBuffer *buf);
gboolean gst_ring_buffer_close_device (GstRingBuffer *buf);
@ -342,6 +351,10 @@ gboolean gst_ring_buffer_release (GstRingBuffer *buf);
gboolean gst_ring_buffer_is_acquired (GstRingBuffer *buf);
/* activating */
gboolean gst_ring_buffer_activate (GstRingBuffer *buf, gboolean active);
gboolean gst_ring_buffer_is_active (GstRingBuffer *buf);
/* flushing */
void gst_ring_buffer_set_flushing (GstRingBuffer *buf, gboolean flushing);