summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-05-23 17:28:02 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-05-23 17:28:02 +0000
commit78016b40cfaeac737f703cce3fd799c7faa1807d (patch)
treead195c6a611b4f0cbc29b4e1ca2b5b626466e297 /gst
parent1419d5ac97e5c73248b4d2a4ac7edc21cb17b431 (diff)
gst/audioconvert/gstaudioconvert.c: Implement instant setup switching.
Original commit message from CVS: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_init), (gst_audio_convert_chain), (gst_audio_convert_link_src), (gst_audio_convert_setcaps): Implement instant setup switching.
Diffstat (limited to 'gst')
-rw-r--r--gst/audioconvert/gstaudioconvert.c143
1 files changed, 80 insertions, 63 deletions
diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c
index 7a1676f52..4448c0989 100644
--- a/gst/audioconvert/gstaudioconvert.c
+++ b/gst/audioconvert/gstaudioconvert.c
@@ -61,6 +61,8 @@ static void gst_audio_convert_dispose (GObject * obj);
/* gstreamer functions */
static GstFlowReturn gst_audio_convert_chain (GstPad * pad, GstBuffer * buffer);
+static gboolean gst_audio_convert_link_src (GstAudioConvert * this,
+ GstCaps * sinkcaps, GstAudioConvertCaps * sink_ac_caps);
static gboolean gst_audio_convert_setcaps (GstPad * pad, GstCaps * caps);
static GstCaps *gst_audio_convert_fixate (GstPad * pad, GstCaps * caps);
static GstCaps *gst_audio_convert_getcaps (GstPad * pad);
@@ -195,7 +197,7 @@ gst_audio_convert_init (GstAudioConvert * this)
gst_pad_new_from_template (gst_static_pad_template_get
(&gst_audio_convert_src_template), "src");
gst_pad_set_getcaps_function (this->src, gst_audio_convert_getcaps);
- gst_pad_set_setcaps_function (this->src, gst_audio_convert_setcaps);
+ //gst_pad_set_setcaps_function (this->src, gst_audio_convert_setcaps);
gst_pad_set_fixatecaps_function (this->src, gst_audio_convert_fixate);
gst_element_add_pad (GST_ELEMENT (this), this->src);
@@ -235,22 +237,6 @@ gst_audio_convert_chain (GstPad * pad, GstBuffer * buf)
this = GST_AUDIO_CONVERT (GST_OBJECT_PARENT (pad));
- /* FIXME */
-
-#if 0
- if (!GST_PAD_CAPS (this->sink)) {
- GST_ELEMENT_ERROR (this, CORE, NEGOTIATION, (NULL),
- ("Sink pad (connected to %s:%s) not negotiated before chain function",
- GST_DEBUG_PAD_NAME (gst_pad_get_peer (this->sink))));
- gst_buffer_unref (buf);
- return GST_FLOW_NOT_NEGOTIATED;
- }
- if (!GST_PAD_CAPS (this->src)) {
- gst_buffer_unref (buf);
- return GST_FLOW_NOT_NEGOTIATED;
- }
-#endif
-
/**
* Theory of operation:
* - convert the format (endianness, signedness, width, depth) to
@@ -260,6 +246,16 @@ gst_audio_convert_chain (GstPad * pad, GstBuffer * buf)
*/
GST_STREAM_LOCK (pad);
+ if (!GST_RPAD_CAPS (this->sink)) {
+ goto not_negotiated;
+ } else if (!GST_RPAD_CAPS (this->src)) {
+ if (!gst_audio_convert_link_src (this,
+ GST_RPAD_CAPS (this->sink), &this->sinkcaps))
+ goto no_format;
+ } else if (!this->matrix) {
+ gst_audio_convert_setup_matrix (this);
+ }
+
buf = gst_audio_convert_buffer_to_default_format (this, buf);
buf = gst_audio_convert_channels (this, buf);
buf = gst_audio_convert_buffer_from_default_format (this, buf);
@@ -269,6 +265,23 @@ gst_audio_convert_chain (GstPad * pad, GstBuffer * buf)
GST_STREAM_UNLOCK (pad);
return ret;
+
+not_negotiated:
+ {
+ GST_ELEMENT_ERROR (this, CORE, NEGOTIATION, (NULL),
+ ("Pad not negotiated before chain function was called"));
+ gst_buffer_unref (buf);
+ GST_STREAM_UNLOCK (pad);
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+no_format:
+ {
+ GST_ELEMENT_ERROR (this, CORE, NEGOTIATION, (NULL),
+ ("Could not negotiate format"));
+ gst_buffer_unref (buf);
+ GST_STREAM_UNLOCK (pad);
+ return GST_FLOW_ERROR;
+ }
}
static GstCaps *
@@ -394,42 +407,23 @@ gst_audio_convert_parse_caps (const GstCaps * gst_caps,
}
static gboolean
-gst_audio_convert_setcaps (GstPad * pad, GstCaps * caps)
+gst_audio_convert_link_src (GstAudioConvert * this,
+ GstCaps * sinkcaps, GstAudioConvertCaps * sink_ac_caps)
{
- GstAudioConvert *this;
- GstPad *otherpad;
GstAudioConvertCaps ac_caps = { 0 };
- GstAudioConvertCaps other_ac_caps = { 0 };
- GstCaps **other_prefered, **prefered;
-
- g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
- g_return_val_if_fail (GST_IS_AUDIO_CONVERT (GST_OBJECT_PARENT (pad)), FALSE);
- g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
- this = GST_AUDIO_CONVERT (GST_OBJECT_PARENT (pad));
-
- /* we'll need a new matrix after every new negotiation */
- gst_audio_convert_unset_matrix (this);
-
- ac_caps.pos = NULL;
- if (!gst_audio_convert_parse_caps (caps, &ac_caps))
- return FALSE;
-
- otherpad = (pad == this->src ? this->sink : this->src);
- prefered = (pad == this->src) ? &this->src_prefered : &this->sink_prefered;
- other_prefered =
- (pad == this->src) ? &this->sink_prefered : &this->src_prefered;
-
- *prefered = caps;
-
- /* check passthrough */
- if (gst_pad_peer_accept_caps (otherpad, caps)) {
+ if (gst_pad_peer_accept_caps (this->src, sinkcaps)) {
/* great, so that will be our suggestion then */
- *other_prefered = gst_caps_ref (caps);
+ this->src_prefered = gst_caps_ref (sinkcaps);
+ gst_caps_replace (&GST_RPAD_CAPS (this->src), sinkcaps);
+ ac_caps = *sink_ac_caps;
+ if (ac_caps.pos) {
+ ac_caps.pos = g_memdup (ac_caps.pos, sizeof (gint) * ac_caps.channels);
+ }
} else {
/* nope, find something we can convert to and the peer can
* accept. */
- GstCaps *othercaps = gst_pad_peer_get_caps (otherpad);
+ GstCaps *othercaps = gst_pad_peer_get_caps (this->src);
if (othercaps) {
/* peel off first one */
@@ -439,12 +433,12 @@ gst_audio_convert_setcaps (GstPad * pad, GstCaps * caps)
gst_caps_unref (othercaps);
/* set the rate on the caps, this has to work */
- gst_structure_set (structure, "rate", G_TYPE_INT, ac_caps.rate, NULL);
- gst_structure_set (structure, "channels", G_TYPE_INT, ac_caps.channels,
- NULL);
+ gst_structure_set (structure,
+ "rate", G_TYPE_INT, sink_ac_caps->rate,
+ "channels", G_TYPE_INT, sink_ac_caps->channels, NULL);
if (strcmp (gst_structure_get_name (structure), "audio/x-raw-float") == 0) {
- if (!ac_caps.is_int) {
+ if (!sink_ac_caps->is_int) {
/* copy over */
gst_structure_set (structure, "buffer-frames", G_TYPE_INT,
ac_caps.buffer_frames, NULL);
@@ -455,25 +449,48 @@ gst_audio_convert_setcaps (GstPad * pad, GstCaps * caps)
}
/* this will be our suggestion */
- *other_prefered = targetcaps;
- if (!gst_audio_convert_parse_caps (targetcaps, &other_ac_caps))
+ this->src_prefered = targetcaps;
+ if (!gst_audio_convert_parse_caps (targetcaps, &ac_caps))
return FALSE;
- gst_caps_replace (&GST_RPAD_CAPS (otherpad), targetcaps);
+ gst_caps_replace (&GST_RPAD_CAPS (this->src), targetcaps);
}
}
- if (this->sink == pad) {
- g_free (this->srccaps.pos);
- this->srccaps = other_ac_caps;
+ this->srccaps = ac_caps;
+
+ GST_DEBUG_OBJECT (this, "negotiated pad to %" GST_PTR_FORMAT, sinkcaps);
+
+ return TRUE;
+}
+
+static gboolean
+gst_audio_convert_setcaps (GstPad * pad, GstCaps * caps)
+{
+ GstAudioConvert *this;
+ GstAudioConvertCaps ac_caps = { 0 };
+ gboolean res;
+
+ g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+ g_return_val_if_fail (GST_IS_AUDIO_CONVERT (GST_OBJECT_PARENT (pad)), FALSE);
+ g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
+
+ this = GST_AUDIO_CONVERT (GST_OBJECT_PARENT (pad));
+
+ /* we'll need a new matrix after every new negotiation */
+ gst_audio_convert_unset_matrix (this);
+
+ ac_caps.pos = NULL;
+ if (!gst_audio_convert_parse_caps (caps, &ac_caps))
+ return FALSE;
+
+ this->sink_prefered = caps;
+
+ if ((res = gst_audio_convert_link_src (this, caps, &ac_caps))) {
this->sinkcaps = ac_caps;
- } else {
- g_free (this->sinkcaps.pos);
- this->srccaps = ac_caps;
- this->sinkcaps = other_ac_caps;
+
+ GST_DEBUG_OBJECT (this, "negotiated pad to %" GST_PTR_FORMAT, caps);
}
- GST_DEBUG_OBJECT (this, "negotiated pad to %" GST_PTR_FORMAT, caps);
- gst_audio_convert_setup_matrix (this);
- return TRUE;
+ return res;
}
/* tries to fixate the given field of the given caps to the given int value */