diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2002-06-01 11:00:27 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2002-06-01 11:00:27 +0000 |
commit | 9b020fb093158cbf1c9005ec2ba60623b96753ba (patch) | |
tree | ee67d36e4faa9e49d5072b8799053c0eec2d7093 /sys | |
parent | ba742744c640657bd0a8bfa86875d10cf8434cd4 (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.c | 113 | ||||
-rw-r--r-- | sys/oss/gstosssink.h | 1 |
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; |