summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2002-06-01 11:00:27 +0000
committerWim Taymans <wim.taymans@gmail.com>2002-06-01 11:00:27 +0000
commit9b020fb093158cbf1c9005ec2ba60623b96753ba (patch)
treeee67d36e4faa9e49d5072b8799053c0eec2d7093 /sys
parentba742744c640657bd0a8bfa86875d10cf8434cd4 (diff)
Some query and convert functions.
Original commit message from CVS: Some query and convert functions.
Diffstat (limited to 'sys')
-rw-r--r--sys/oss/gstosssink.c113
-rw-r--r--sys/oss/gstosssink.h1
2 files changed, 109 insertions, 5 deletions
diff --git a/sys/oss/gstosssink.c b/sys/oss/gstosssink.c
index 1a2283ca..831c24e6 100644
--- a/sys/oss/gstosssink.c
+++ b/sys/oss/gstosssink.c
@@ -53,6 +53,11 @@ static void gst_osssink_set_clock (GstElement *element, GstClock *clock);
static GstClock* gst_osssink_get_clock (GstElement *element);
static GstClockTime gst_osssink_get_time (GstClock *clock, gpointer data);
+static gboolean gst_osssink_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
+ GstFormat *dest_format, gint64 *dest_value);
+static gboolean gst_osssink_query (GstPad *pad, GstPadQueryType type,
+ GstFormat *format, gint64 *value);
+
static GstPadConnectReturn gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps);
static void gst_osssink_set_property (GObject *object, guint prop_id, const GValue *value,
@@ -230,6 +235,8 @@ gst_osssink_init (GstOssSink *osssink)
gst_element_add_pad (GST_ELEMENT (osssink), osssink->sinkpad);
gst_pad_set_connect_function (osssink->sinkpad, gst_osssink_sinkconnect);
gst_pad_set_bufferpool_function (osssink->sinkpad, gst_osssink_get_bufferpool);
+ gst_pad_set_convert_function (osssink->sinkpad, gst_osssink_convert);
+ gst_pad_set_query_function (osssink->sinkpad, gst_osssink_query);
gst_pad_set_chain_function (osssink->sinkpad, gst_osssink_chain);
@@ -264,7 +271,7 @@ gst_osssink_init (GstOssSink *osssink)
static GstPadConnectReturn
gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps)
{
- gint law, endianness, width, depth;
+ gint law, endianness, depth;
gboolean sign;
gint format = -1;
GstOssSink *osssink = GST_OSSSINK (gst_pad_get_parent (pad));
@@ -272,10 +279,10 @@ gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps)
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_CONNECT_DELAYED;
- gst_caps_get_int (caps, "width", &width);
+ gst_caps_get_int (caps, "width", &osssink->width);
gst_caps_get_int (caps, "depth", &depth);
- if (width != depth)
+ if (osssink->width != depth)
return GST_PAD_CONNECT_REFUSED;
/* laws 1 and 2 are 1 bps anyway */
@@ -286,7 +293,7 @@ gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps)
gst_caps_get_boolean (caps, "signed", &sign);
if (law == 0) {
- if (width == 16) {
+ if (osssink->width == 16) {
if (sign == TRUE) {
if (endianness == G_LITTLE_ENDIAN)
format = AFMT_S16_LE;
@@ -301,7 +308,7 @@ gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps)
}
osssink->bps = 2;
}
- else if (width == 8) {
+ else if (osssink->width == 8) {
if (sign == TRUE) {
format = AFMT_S8;
}
@@ -407,6 +414,9 @@ gst_osssink_get_delay (GstOssSink *osssink)
{
gint delay = 0;
+ if (osssink->fd == -1)
+ return 0;
+
if (ioctl (osssink->fd, SNDCTL_DSP_GETODELAY, &delay) < 0) {
audio_buf_info info;
if (ioctl (osssink->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) {
@@ -559,6 +569,99 @@ gst_osssink_chain (GstPad *pad, GstBuffer *buf)
gst_buffer_unref (buf);
}
+static gboolean
+gst_osssink_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
+ GstFormat *dest_format, gint64 *dest_value)
+{
+ gboolean res = TRUE;
+
+ GstOssSink *osssink;
+
+ if (src_format == *dest_format) {
+ *dest_value = src_value;
+ return TRUE;
+ }
+
+ osssink = GST_OSSSINK (gst_pad_get_parent (pad));
+
+ if (osssink->bps == 0 || osssink->channels == 0 || osssink->width == 0)
+ return FALSE;
+
+ switch (src_format) {
+ case GST_FORMAT_BYTES:
+ switch (*dest_format) {
+ case GST_FORMAT_DEFAULT:
+ *dest_format = GST_FORMAT_TIME;
+ case GST_FORMAT_TIME:
+ *dest_value = src_value * GST_SECOND / osssink->bps;
+ break;
+ case GST_FORMAT_SAMPLES:
+ *dest_value = src_value / (osssink->channels * osssink->width);
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ case GST_FORMAT_TIME:
+ switch (*dest_format) {
+ case GST_FORMAT_DEFAULT:
+ *dest_format = GST_FORMAT_BYTES;
+ case GST_FORMAT_BYTES:
+ *dest_value = src_value * osssink->bps / GST_SECOND;
+ break;
+ case GST_FORMAT_SAMPLES:
+ *dest_value = osssink->frequency;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ case GST_FORMAT_SAMPLES:
+ switch (*dest_format) {
+ case GST_FORMAT_DEFAULT:
+ *dest_format = GST_FORMAT_TIME;
+ case GST_FORMAT_TIME:
+ *dest_value = src_value * GST_SECOND / osssink->frequency;
+ break;
+ case GST_FORMAT_BYTES:
+ *dest_value = src_value * osssink->channels * osssink->width;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ default:
+ res = FALSE;
+ }
+
+ return res;
+}
+
+static gboolean
+gst_osssink_query (GstPad *pad, GstPadQueryType type, GstFormat *format, gint64 *value)
+{
+ gboolean res = TRUE;
+ GstOssSink *osssink;
+
+ osssink = GST_OSSSINK (gst_pad_get_parent (pad));
+
+ switch (type) {
+ case GST_PAD_QUERY_LATENCY:
+ if (!gst_osssink_convert (pad,
+ GST_FORMAT_BYTES, gst_osssink_get_delay (osssink),
+ format, value))
+ {
+ res = FALSE;
+ }
+ break;
+ default:
+ res = FALSE;
+ break;
+ }
+
+ return res;
+}
+
static void
gst_osssink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
diff --git a/sys/oss/gstosssink.h b/sys/oss/gstosssink.h
index ed5a3af3..7646de6d 100644
--- a/sys/oss/gstosssink.h
+++ b/sys/oss/gstosssink.h
@@ -74,6 +74,7 @@ struct _GstOssSink {
int fd;
int caps; /* the capabilities */
gint format;
+ gint width;
gint channels;
gint frequency;
gint fragment;