summaryrefslogtreecommitdiffstats
path: root/sys/oss/gstosssrc.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2002-12-07 20:54:47 +0000
committerWim Taymans <wim.taymans@gmail.com>2002-12-07 20:54:47 +0000
commit46820010139599cf0ae77e5e75da04b9672f23bf (patch)
treeb3adc39885400c91dec0cad2a7684a659e7b0e2b /sys/oss/gstosssrc.c
parentf5743b63de97d7d5bba29dc769387b42a092cb82 (diff)
More refactoring osssrc has more features now, like query/convert etc
Original commit message from CVS: More refactoring osssrc has more features now, like query/convert etc
Diffstat (limited to 'sys/oss/gstosssrc.c')
-rw-r--r--sys/oss/gstosssrc.c322
1 files changed, 165 insertions, 157 deletions
diff --git a/sys/oss/gstosssrc.c b/sys/oss/gstosssrc.c
index 93c048b1..b3f51693 100644
--- a/sys/oss/gstosssrc.c
+++ b/sys/oss/gstosssrc.c
@@ -51,7 +51,8 @@ enum {
enum {
ARG_0,
ARG_DEVICE,
- ARG_BYTESPERREAD,
+ ARG_BUFFERSIZE,
+ ARG_FRAGMENT,
};
GST_PAD_TEMPLATE_FACTORY (osssrc_src_factory,
@@ -85,16 +86,23 @@ static void gst_osssrc_class_init (GstOssSrcClass *klass);
static void gst_osssrc_init (GstOssSrc *osssrc);
static GstPadConnectReturn gst_osssrc_srcconnect (GstPad *pad, GstCaps *caps);
+static const GstFormat* gst_osssrc_get_formats (GstPad *pad);
+static gboolean gst_osssrc_convert (GstPad *pad,
+ GstFormat src_format, gint64 src_value,
+ GstFormat *dest_format, gint64 *dest_value);
+
static void gst_osssrc_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void gst_osssrc_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static GstElementStateReturn gst_osssrc_change_state (GstElement *element);
-static gboolean gst_osssrc_send_event (GstElement *element, GstEvent *event);
-static void gst_osssrc_close_audio (GstOssSrc *src);
-static gboolean gst_osssrc_open_audio (GstOssSrc *src);
-static gboolean gst_osssrc_sync_parms (GstOssSrc *osssrc);
+static const GstEventMask* gst_osssrc_get_event_masks (GstPad *pad);
+static gboolean gst_osssrc_src_event (GstPad *pad, GstEvent *event);
+static gboolean gst_osssrc_send_event (GstElement *element, GstEvent *event);
+static const GstPadQueryType* gst_osssrc_get_query_types (GstPad *pad);
+static gboolean gst_osssrc_src_query (GstPad *pad, GstPadQueryType type,
+ GstFormat *format, gint64 *value);
static GstBuffer * gst_osssrc_get (GstPad *pad);
@@ -134,12 +142,16 @@ gst_osssrc_class_init (GstOssSrcClass *klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
- g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BYTESPERREAD,
- g_param_spec_ulong("bytes_per_read","bytes_per_read","bytes_per_read",
- 0,G_MAXULONG,0,G_PARAM_READWRITE)); /* CHECKME */
+ g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFFERSIZE,
+ g_param_spec_ulong ("buffersize","Buffer Size","The size of the buffers with samples",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE,
- g_param_spec_string("device","device","oss device (/dev/dspN usually)",
- "default",G_PARAM_READWRITE));
+ g_param_spec_string ("device", "device", "oss device (/dev/dspN usually)",
+ "default", G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FRAGMENT,
+ g_param_spec_int ("fragment", "Fragment",
+ "The fragment as 0xMMMMSSSS (MMMM = total fragments, 2^SSSS = fragment size)",
+ 0, G_MAXINT, 6, G_PARAM_READWRITE));
gobject_class->set_property = gst_osssrc_set_property;
gobject_class->get_property = gst_osssrc_get_property;
@@ -155,25 +167,20 @@ gst_osssrc_init (GstOssSrc *osssrc)
GST_PAD_TEMPLATE_GET (osssrc_src_factory), "src");
gst_pad_set_get_function (osssrc->srcpad, gst_osssrc_get);
gst_pad_set_connect_function (osssrc->srcpad, gst_osssrc_srcconnect);
+ gst_pad_set_convert_function (osssrc->srcpad, gst_osssrc_convert);
+ gst_pad_set_formats_function (osssrc->srcpad, gst_osssrc_get_formats);
+ gst_pad_set_event_function (osssrc->srcpad, gst_osssrc_src_event);
+ gst_pad_set_event_mask_function (osssrc->srcpad, gst_osssrc_get_event_masks);
+ gst_pad_set_query_function (osssrc->srcpad, gst_osssrc_src_query);
+ gst_pad_set_query_type_function (osssrc->srcpad, gst_osssrc_get_query_types);
+
+
gst_element_add_pad (GST_ELEMENT (osssrc), osssrc->srcpad);
- osssrc->device = g_strdup ("/dev/dsp");
- osssrc->fd = -1;
-
- /* adding some default values */
- osssrc->law = 0;
- osssrc->endianness = G_BYTE_ORDER;
- osssrc->sign = TRUE;
- osssrc->depth = 16;
- osssrc->width = 16;
- osssrc->channels = 2;
- osssrc->rate = 44100;
- osssrc->need_eos = FALSE;
-
- osssrc->bytes_per_read = 4096;
+ gst_osscommon_init (&osssrc->common);
+
+ osssrc->buffersize = 4096;
osssrc->curoffset = 0;
- osssrc->basetime = 0;
- osssrc->samples_since_basetime = 0;
}
static GstPadConnectReturn
@@ -186,29 +193,14 @@ gst_osssrc_srcconnect (GstPad *pad, GstCaps *caps)
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_CONNECT_DELAYED;
- gst_caps_get_int (caps, "law", &src->law);
- gst_caps_get_int (caps, "endianness", &src->endianness);
- gst_caps_get_boolean (caps, "signed", &src->sign);
- gst_caps_get_int (caps, "width", &src->width);
- gst_caps_get_int (caps, "depth", &src->depth);
- gst_caps_get_int (caps, "rate", &src->rate);
- gst_caps_get_int (caps, "channels", &src->channels);
+ if (!gst_osscommon_parse_caps (&src->common, caps))
+ return GST_PAD_CONNECT_REFUSED;
- if (!gst_osssrc_sync_parms (src))
+ if (!gst_osscommon_sync_parms (&src->common))
return GST_PAD_CONNECT_REFUSED;
return GST_PAD_CONNECT_OK;
}
-#define GET_FIXED_INT(caps, name, dest) \
-G_STMT_START { \
- if (gst_caps_has_fixed_property (caps, name)) \
- gst_caps_get_int (caps, name, dest); \
-} G_STMT_END
-#define GET_FIXED_BOOLEAN(caps, name, dest) \
-G_STMT_START { \
- if (gst_caps_has_fixed_property (caps, name)) \
- gst_caps_get_boolean (caps, name, dest); \
-} G_STMT_END
static gboolean
gst_osssrc_negotiate (GstPad *pad)
@@ -220,16 +212,10 @@ gst_osssrc_negotiate (GstPad *pad)
allowed = gst_pad_get_allowed_caps (pad);
- /* peel off fixed stuff from the allowed caps */
- GET_FIXED_INT (allowed, "law", &src->law);
- GET_FIXED_INT (allowed, "endianness", &src->endianness);
- GET_FIXED_BOOLEAN (allowed, "signed", &src->sign);
- GET_FIXED_INT (allowed, "width", &src->width);
- GET_FIXED_INT (allowed, "depth", &src->depth);
- GET_FIXED_INT (allowed, "rate", &src->rate);
- GET_FIXED_INT (allowed, "channels", &src->channels);
+ if (!gst_osscommon_merge_fixed_caps (&src->common, allowed))
+ return FALSE;
- if (!gst_osssrc_sync_parms (src))
+ if (!gst_osscommon_sync_parms (&src->common))
return FALSE;
/* set caps on src pad */
@@ -238,13 +224,13 @@ gst_osssrc_negotiate (GstPad *pad)
"oss_src",
"audio/raw",
"format", GST_PROPS_STRING ("int"),
- "law", GST_PROPS_INT (src->law),
- "endianness", GST_PROPS_INT (src->endianness),
- "signed", GST_PROPS_BOOLEAN (src->sign),
- "width", GST_PROPS_INT (src->width),
- "depth", GST_PROPS_INT (src->depth),
- "rate", GST_PROPS_INT (src->rate),
- "channels", GST_PROPS_INT (src->channels)
+ "law", GST_PROPS_INT (src->common.law),
+ "endianness", GST_PROPS_INT (src->common.endianness),
+ "signed", GST_PROPS_BOOLEAN (src->common.sign),
+ "width", GST_PROPS_INT (src->common.width),
+ "depth", GST_PROPS_INT (src->common.depth),
+ "rate", GST_PROPS_INT (src->common.rate),
+ "channels", GST_PROPS_INT (src->common.channels)
)) <= 0)
{
return FALSE;
@@ -258,7 +244,6 @@ gst_osssrc_get (GstPad *pad)
GstOssSrc *src;
GstBuffer *buf;
glong readbytes;
- glong readsamples;
src = GST_OSSSRC(gst_pad_get_parent (pad));
@@ -269,10 +254,10 @@ gst_osssrc_get (GstPad *pad)
return GST_BUFFER (gst_event_new (GST_EVENT_EOS));
}
- buf = gst_buffer_new_and_alloc (src->bytes_per_read);
+ buf = gst_buffer_new_and_alloc (src->buffersize);
- readbytes = read (src->fd,GST_BUFFER_DATA (buf),
- src->bytes_per_read);
+ readbytes = read (src->common.fd,GST_BUFFER_DATA (buf),
+ src->buffersize);
if (readbytes == 0) {
gst_element_set_eos (GST_ELEMENT (src));
@@ -286,16 +271,16 @@ gst_osssrc_get (GstPad *pad)
return NULL;
}
}
+ if (src->common.bps == 0) {
+ gst_element_error (GST_ELEMENT (src), "no format negotiated");
+ return NULL;
+ }
GST_BUFFER_SIZE (buf) = readbytes;
GST_BUFFER_OFFSET (buf) = src->curoffset;
- GST_BUFFER_TIMESTAMP (buf) = src->basetime +
- src->samples_since_basetime * GST_SECOND / src->rate;
+ GST_BUFFER_TIMESTAMP (buf) = src->curoffset * GST_SECOND / src->common.bps;
src->curoffset += readbytes;
- readsamples = readbytes / src->channels;
- if (src->width == 16) readsamples /= 2;
- src->samples_since_basetime += readsamples;
GST_DEBUG (GST_CAT_PLUGIN_INFO, "pushed buffer from soundcard of %ld bytes, timestamp %lld",
readbytes, GST_BUFFER_TIMESTAMP (buf));
@@ -308,19 +293,20 @@ gst_osssrc_set_property (GObject *object, guint prop_id, const GValue *value, GP
{
GstOssSrc *src;
- /* it's not null if we got it, but it might not be ours */
- g_return_if_fail (GST_IS_OSSSRC (object));
-
src = GST_OSSSRC (object);
switch (prop_id) {
- case ARG_BYTESPERREAD:
- src->bytes_per_read = g_value_get_ulong (value);
+ case ARG_BUFFERSIZE:
+ src->buffersize = g_value_get_ulong (value);
break;
case ARG_DEVICE:
- g_free(src->device);
- src->device = g_strdup (g_value_get_string (value));
+ g_free(src->common.device);
+ src->common.device = g_strdup (g_value_get_string (value));
break;
+ case ARG_FRAGMENT:
+ src->common.fragment = g_value_get_int (value);
+ gst_osscommon_sync_parms (&src->common);
+ break;
default:
break;
}
@@ -331,17 +317,17 @@ gst_osssrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSp
{
GstOssSrc *src;
- /* it's not null if we got it, but it might not be ours */
- g_return_if_fail (GST_IS_OSSSRC (object));
-
src = GST_OSSSRC (object);
switch (prop_id) {
- case ARG_BYTESPERREAD:
- g_value_set_ulong (value, src->bytes_per_read);
+ case ARG_BUFFERSIZE:
+ g_value_set_ulong (value, src->buffersize);
break;
case ARG_DEVICE:
- g_value_set_string (value, src->device);
+ g_value_set_string (value, src->common.device);
+ break;
+ case ARG_FRAGMENT:
+ g_value_set_int (value, src->common.fragment);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -361,8 +347,13 @@ gst_osssrc_change_state (GstElement *element)
break;
case GST_STATE_READY_TO_PAUSED:
if (!GST_FLAG_IS_SET (element, GST_OSSSRC_OPEN)) {
- if (!gst_osssrc_open_audio (osssrc))
+ gchar *error;
+ if (!gst_osscommon_open_audio (&osssrc->common, GST_OSSCOMMON_READ, &error)) {
+ gst_element_error (GST_ELEMENT (osssrc), error);
+ g_free (error);
return GST_STATE_FAILURE;
+ }
+ GST_FLAG_SET (osssrc, GST_OSSSRC_OPEN);
}
break;
case GST_STATE_PAUSED_TO_PLAYING:
@@ -370,8 +361,11 @@ gst_osssrc_change_state (GstElement *element)
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
- if (GST_FLAG_IS_SET (element, GST_OSSSRC_OPEN))
- gst_osssrc_close_audio (osssrc);
+ if (GST_FLAG_IS_SET (element, GST_OSSSRC_OPEN)) {
+ gst_osscommon_close_audio (&osssrc->common);
+ GST_FLAG_UNSET (osssrc, GST_OSSSRC_OPEN);
+ }
+ gst_osscommon_init (&osssrc->common);
break;
case GST_STATE_READY_TO_NULL:
break;
@@ -383,103 +377,117 @@ gst_osssrc_change_state (GstElement *element)
return GST_STATE_SUCCESS;
}
+static const GstFormat*
+gst_osssrc_get_formats (GstPad *pad)
+{
+ static const GstFormat formats[] = {
+ GST_FORMAT_TIME,
+ GST_FORMAT_UNITS,
+ GST_FORMAT_BYTES,
+ 0
+ };
+ return formats;
+}
+
static gboolean
-gst_osssrc_send_event (GstElement *element,
- GstEvent *event)
+gst_osssrc_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
+ GstFormat *dest_format, gint64 *dest_value)
+{
+ GstOssSrc *osssrc;
+
+ osssrc = GST_OSSSRC (gst_pad_get_parent (pad));
+
+ return gst_osscommon_convert (&osssrc->common, src_format, src_value,
+ dest_format, dest_value);
+}
+
+static const GstEventMask*
+gst_osssrc_get_event_masks (GstPad *pad)
+{
+ static const GstEventMask gst_osssrc_src_event_masks[] = {
+ { GST_EVENT_EOS, 0 },
+ { GST_EVENT_SIZE, 0 },
+ { 0, }
+ };
+ return gst_osssrc_src_event_masks;
+}
+
+static gboolean
+gst_osssrc_src_event (GstPad *pad, GstEvent *event)
{
- gboolean retval = FALSE;
GstOssSrc *osssrc;
+ gboolean retval = FALSE;
- osssrc = GST_OSSSRC (element);
+ osssrc = GST_OSSSRC (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
osssrc->need_eos = TRUE;
retval = TRUE;
break;
+ case GST_EVENT_SIZE:
+ {
+ GstFormat format;
+ gint64 value;
+
+ format = GST_FORMAT_BYTES;
+
+ /* convert to bytes */
+ if (gst_osscommon_convert (&osssrc->common,
+ GST_EVENT_SIZE_FORMAT (event),
+ GST_EVENT_SIZE_VALUE (event),
+ &format, &value))
+ {
+ osssrc->buffersize = GST_EVENT_SIZE_VALUE (event);
+ g_object_notify (G_OBJECT (osssrc), "buffersize");
+ retval = TRUE;
+ }
+ }
default:
break;
}
-
gst_event_unref (event);
return retval;
}
-static gboolean
-gst_osssrc_open_audio (GstOssSrc *src)
+static gboolean
+gst_osssrc_send_event (GstElement *element,
+ GstEvent *event)
{
- g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_OSSSRC_OPEN), FALSE);
-
- /* first try to open the sound card */
- src->fd = open(src->device, O_RDONLY);
-
- /* if we have it, set the default parameters and go have fun */
- if (src->fd > 0) {
-
- /* set card state */
- GST_DEBUG (GST_CAT_PLUGIN_INFO,"opened audio: %s",src->device);
-
- GST_FLAG_SET (src, GST_OSSSRC_OPEN);
- return TRUE;
- }
+ GstOssSrc *osssrc = GST_OSSSRC (element);
- return FALSE;
+ return gst_osssrc_src_event (osssrc->srcpad, event);
}
-static void
-gst_osssrc_close_audio (GstOssSrc *src)
+static const GstPadQueryType*
+gst_osssrc_get_query_types (GstPad *pad)
{
- g_return_if_fail (GST_FLAG_IS_SET (src, GST_OSSSRC_OPEN));
+ static const GstPadQueryType query_types[] = {
+ GST_PAD_QUERY_POSITION,
+ 0,
+ };
+ return query_types;
+}
- close(src->fd);
- src->fd = -1;
-
- GST_FLAG_UNSET (src, GST_OSSSRC_OPEN);
-}
-
-static gboolean
-gst_osssrc_sync_parms (GstOssSrc *osssrc)
+static gboolean
+gst_osssrc_src_query (GstPad *pad, GstPadQueryType type, GstFormat *format, gint64 *value)
{
- audio_buf_info ispace;
- gint frag;
- /* remember : ioctl on samplerate returns the sample rate the card
- * is actually set to ! Setting it to 44101 Hz could cause it to
- * be set to 44101, for example
- */
- guint rate;
- gint format;
- gint bps;
-
- g_return_val_if_fail (osssrc->fd > 0, FALSE);
-
- /* get rate, we don't modify the original rate as the audio device
- * might not exactly give us the requested value */
- rate = osssrc->rate;
-
- /* transform format parameters to oss format */
- if (!gst_ossformat_get (osssrc->law, osssrc->endianness, osssrc->sign,
- osssrc->width, osssrc->depth, &format, &bps))
- {
- return FALSE;
+ gboolean res = FALSE;
+ GstOssSrc *osssrc;
+
+ osssrc = GST_OSSSRC (gst_pad_get_parent (pad));
+
+ switch (type) {
+ case GST_PAD_QUERY_POSITION:
+ res = gst_osscommon_convert (&osssrc->common,
+ GST_FORMAT_BYTES, osssrc->curoffset,
+ format, value);
+ break;
+ default:
+ break;
}
-
- frag = 0x7fff0006;
-
- ioctl(osssrc->fd, SNDCTL_DSP_SETFRAGMENT, &frag);
- ioctl(osssrc->fd, SNDCTL_DSP_RESET, 0);
-
- ioctl(osssrc->fd, SNDCTL_DSP_SETFMT, &format);
- ioctl(osssrc->fd, SNDCTL_DSP_CHANNELS, &osssrc->channels);
- ioctl(osssrc->fd, SNDCTL_DSP_SPEED, &rate);
- ioctl(osssrc->fd, SNDCTL_DSP_GETISPACE, &ispace);
- ioctl(osssrc->fd, SNDCTL_DSP_GETBLKSIZE, &frag);
-
- g_print("setting sound card to %dHz %d bit %s (%d bytes buffer, %d fragment)\n",
- rate, osssrc->width,
- (osssrc->channels == 2) ? "stereo" : "mono", ispace.bytes, frag);
-
- return TRUE;
-}
+ return res;
+}
gboolean
gst_osssrc_factory_init (GstPlugin *plugin)