law: fix caps and negotiation

Fix the caps to include the depth (instead of width twice) in the caps of
audio/x-raw-int.
Fix negotiation to not only copy the rate/channels of the first structure.
This commit is contained in:
Wim Taymans 2009-06-30 15:59:20 +02:00
parent 6d0007372b
commit 89f0c37c9f
6 changed files with 154 additions and 113 deletions

View file

@ -150,50 +150,61 @@ gst_alaw_dec_getcaps (GstPad * pad)
{ {
GstALawDec *alawdec; GstALawDec *alawdec;
GstPad *otherpad; GstPad *otherpad;
GstCaps *base_caps, *othercaps; GstCaps *othercaps, *result;
const GstCaps *templ;
gchar *name;
gint i;
alawdec = GST_ALAW_DEC (GST_PAD_PARENT (pad)); alawdec = GST_ALAW_DEC (GST_PAD_PARENT (pad));
base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); /* figure out the name of the caps we are going to return */
if (pad == alawdec->srcpad) { if (pad == alawdec->srcpad) {
name = "audio/x-raw-int";
otherpad = alawdec->sinkpad; otherpad = alawdec->sinkpad;
} else { } else {
name = "audio/x-alaw";
otherpad = alawdec->srcpad; otherpad = alawdec->srcpad;
} }
/* get caps from the peer, this can return NULL when there is no peer */
othercaps = gst_pad_peer_get_caps (otherpad); othercaps = gst_pad_peer_get_caps (otherpad);
/* get the template caps to make sure we return something acceptable */
templ = gst_pad_get_pad_template_caps (pad);
if (othercaps) { if (othercaps) {
GstStructure *structure; /* there was a peer */
const GValue *orate, *ochans; othercaps = gst_caps_make_writable (othercaps);
const GValue *rate, *chans;
GValue irate = { 0 };
GValue ichans = { 0 };
if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) /* go through the caps and remove the fields we don't want */
goto done; for (i = 0; i < gst_caps_get_size (othercaps); i++) {
GstStructure *structure;
structure = gst_caps_get_structure (othercaps, 0); structure = gst_caps_get_structure (othercaps, i);
orate = gst_structure_get_value (structure, "rate");
ochans = gst_structure_get_value (structure, "channels");
structure = gst_caps_get_structure (base_caps, 0); /* adjust the name */
rate = gst_structure_get_value (structure, "rate"); gst_structure_set_name (structure, name);
chans = gst_structure_get_value (structure, "channels");
if (orate) { if (pad == alawdec->sinkpad) {
gst_value_intersect (&irate, orate, rate); /* remove the fields we don't want */
gst_structure_set_value (structure, "rate", &irate); gst_structure_remove_fields (structure, "width", "depth", "endianness",
"signed", NULL);
} else {
/* add fixed fields */
gst_structure_set (structure, "width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"signed", G_TYPE_BOOLEAN, TRUE, NULL);
}
} }
/* filter against the allowed caps of the pad to return our result */
if (ochans) { result = gst_caps_intersect (othercaps, templ);
gst_value_intersect (&ichans, ochans, chans);
gst_structure_set_value (structure, "channels", &ichans);
}
done:
gst_caps_unref (othercaps); gst_caps_unref (othercaps);
} else {
/* there was no peer, return the template caps */
result = gst_caps_copy (templ);
} }
return base_caps;
return result;
} }
static void static void

View file

@ -301,51 +301,61 @@ gst_alaw_enc_getcaps (GstPad * pad)
{ {
GstALawEnc *alawenc; GstALawEnc *alawenc;
GstPad *otherpad; GstPad *otherpad;
GstCaps *base_caps, *othercaps; GstCaps *othercaps, *result;
const GstCaps *templ;
gchar *name;
gint i;
alawenc = GST_ALAW_ENC (GST_PAD_PARENT (pad)); alawenc = GST_ALAW_ENC (GST_PAD_PARENT (pad));
/* we can do what our template says */ /* figure out the name of the caps we are going to return */
base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
if (pad == alawenc->srcpad) { if (pad == alawenc->srcpad) {
name = "audio/x-alaw";
otherpad = alawenc->sinkpad; otherpad = alawenc->sinkpad;
} else { } else {
name = "audio/x-raw-int";
otherpad = alawenc->srcpad; otherpad = alawenc->srcpad;
} }
/* get caps from the peer, this can return NULL when there is no peer */
othercaps = gst_pad_peer_get_caps (otherpad); othercaps = gst_pad_peer_get_caps (otherpad);
/* get the template caps to make sure we return something acceptable */
templ = gst_pad_get_pad_template_caps (pad);
if (othercaps) { if (othercaps) {
GstStructure *structure; /* there was a peer */
const GValue *orate, *ochans; othercaps = gst_caps_make_writable (othercaps);
const GValue *rate, *chans;
GValue irate = { 0 };
GValue ichans = { 0 };
if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) /* go through the caps and remove the fields we don't want */
goto done; for (i = 0; i < gst_caps_get_size (othercaps); i++) {
GstStructure *structure;
structure = gst_caps_get_structure (othercaps, 0); structure = gst_caps_get_structure (othercaps, i);
orate = gst_structure_get_value (structure, "rate");
ochans = gst_structure_get_value (structure, "channels");
structure = gst_caps_get_structure (base_caps, 0); /* adjust the name */
rate = gst_structure_get_value (structure, "rate"); gst_structure_set_name (structure, name);
chans = gst_structure_get_value (structure, "channels");
if (orate) { if (pad == alawenc->srcpad) {
gst_value_intersect (&irate, orate, rate); /* remove the fields we don't want */
gst_structure_set_value (structure, "rate", &irate); gst_structure_remove_fields (structure, "width", "depth", "endianness",
"signed", NULL);
} else {
/* add fixed fields */
gst_structure_set (structure, "width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"signed", G_TYPE_BOOLEAN, TRUE, NULL);
}
} }
/* filter against the allowed caps of the pad to return our result */
if (ochans) { result = gst_caps_intersect (othercaps, templ);
gst_value_intersect (&ichans, ochans, chans);
gst_structure_set_value (structure, "channels", &ichans);
}
done:
gst_caps_unref (othercaps); gst_caps_unref (othercaps);
} else {
/* there was no peer, return the template caps */
result = gst_caps_copy (templ);
} }
return base_caps;
return result;
} }
static gboolean static gboolean

View file

@ -30,7 +30,7 @@ GstStaticPadTemplate alaw_dec_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
"rate = (int) [ 8000, 192000 ], " "rate = (int) [ 8000, 192000 ], "
"channels = (int) [ 1, 2 ], " "channels = (int) [ 1, 2 ], "
"endianness = (int) BYTE_ORDER, " "endianness = (int) BYTE_ORDER, "
"width = (int) 16, " "width = (int) 16, " "signed = (boolean) True") "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) True")
); );
GstStaticPadTemplate alaw_dec_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GstStaticPadTemplate alaw_dec_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
@ -47,7 +47,7 @@ GstStaticPadTemplate alaw_enc_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
"rate = (int) [ 8000, 192000 ], " "rate = (int) [ 8000, 192000 ], "
"channels = (int) [ 1, 2 ], " "channels = (int) [ 1, 2 ], "
"endianness = (int) BYTE_ORDER, " "endianness = (int) BYTE_ORDER, "
"width = (int) 16, " "width = (int) 16, " "signed = (boolean) True") "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) True")
); );
GstStaticPadTemplate alaw_enc_src_factory = GST_STATIC_PAD_TEMPLATE ("src", GstStaticPadTemplate alaw_enc_src_factory = GST_STATIC_PAD_TEMPLATE ("src",

View file

@ -93,50 +93,60 @@ mulawdec_getcaps (GstPad * pad)
{ {
GstMuLawDec *mulawdec; GstMuLawDec *mulawdec;
GstPad *otherpad; GstPad *otherpad;
GstCaps *base_caps, *othercaps; GstCaps *othercaps, *result;
const GstCaps *templ;
gchar *name;
gint i;
mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad)); mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad));
base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); /* figure out the name of the caps we are going to return */
if (pad == mulawdec->srcpad) { if (pad == mulawdec->srcpad) {
name = "audio/x-raw-int";
otherpad = mulawdec->sinkpad; otherpad = mulawdec->sinkpad;
} else { } else {
name = "audio/x-mulaw";
otherpad = mulawdec->srcpad; otherpad = mulawdec->srcpad;
} }
/* get caps from the peer, this can return NULL when there is no peer */
othercaps = gst_pad_peer_get_caps (otherpad); othercaps = gst_pad_peer_get_caps (otherpad);
/* get the template caps to make sure we return something acceptable */
templ = gst_pad_get_pad_template_caps (pad);
if (othercaps) { if (othercaps) {
GstStructure *structure; /* there was a peer */
const GValue *orate, *ochans; othercaps = gst_caps_make_writable (othercaps);
const GValue *rate, *chans;
GValue irate = { 0 };
GValue ichans = { 0 };
if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) /* go through the caps and remove the fields we don't want */
goto done; for (i = 0; i < gst_caps_get_size (othercaps); i++) {
GstStructure *structure;
structure = gst_caps_get_structure (othercaps, 0); structure = gst_caps_get_structure (othercaps, i);
orate = gst_structure_get_value (structure, "rate");
ochans = gst_structure_get_value (structure, "channels");
structure = gst_caps_get_structure (base_caps, 0); /* adjust the name */
rate = gst_structure_get_value (structure, "rate"); gst_structure_set_name (structure, name);
chans = gst_structure_get_value (structure, "channels");
if (orate) { if (pad == mulawdec->sinkpad) {
gst_value_intersect (&irate, orate, rate); /* remove the fields we don't want */
gst_structure_set_value (structure, "rate", &irate); gst_structure_remove_fields (structure, "width", "depth", "endianness",
"signed", NULL);
} else {
/* add fixed fields */
gst_structure_set (structure, "width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"signed", G_TYPE_BOOLEAN, TRUE, NULL);
}
} }
/* filter against the allowed caps of the pad to return our result */
if (ochans) { result = gst_caps_intersect (othercaps, templ);
gst_value_intersect (&ichans, ochans, chans);
gst_structure_set_value (structure, "channels", &ichans);
}
done:
gst_caps_unref (othercaps); gst_caps_unref (othercaps);
} else {
/* there was no peer, return the template caps */
result = gst_caps_copy (templ);
} }
return base_caps; return result;
} }
GType GType

View file

@ -59,50 +59,60 @@ mulawenc_getcaps (GstPad * pad)
{ {
GstMuLawEnc *mulawenc; GstMuLawEnc *mulawenc;
GstPad *otherpad; GstPad *otherpad;
GstCaps *base_caps, *othercaps; GstCaps *othercaps, *result;
const GstCaps *templ;
gchar *name;
gint i;
mulawenc = GST_MULAWENC (GST_PAD_PARENT (pad)); mulawenc = GST_MULAWENC (GST_PAD_PARENT (pad));
base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); /* figure out the name of the caps we are going to return */
if (pad == mulawenc->srcpad) { if (pad == mulawenc->srcpad) {
name = "audio/x-mulaw";
otherpad = mulawenc->sinkpad; otherpad = mulawenc->sinkpad;
} else { } else {
name = "audio/x-raw-int";
otherpad = mulawenc->srcpad; otherpad = mulawenc->srcpad;
} }
/* get caps from the peer, this can return NULL when there is no peer */
othercaps = gst_pad_peer_get_caps (otherpad); othercaps = gst_pad_peer_get_caps (otherpad);
/* get the template caps to make sure we return something acceptable */
templ = gst_pad_get_pad_template_caps (pad);
if (othercaps) { if (othercaps) {
GstStructure *structure; /* there was a peer */
const GValue *orate, *ochans; othercaps = gst_caps_make_writable (othercaps);
const GValue *rate, *chans;
GValue irate = { 0 };
GValue ichans = { 0 };
if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) /* go through the caps and remove the fields we don't want */
goto done; for (i = 0; i < gst_caps_get_size (othercaps); i++) {
GstStructure *structure;
structure = gst_caps_get_structure (othercaps, 0); structure = gst_caps_get_structure (othercaps, i);
orate = gst_structure_get_value (structure, "rate");
ochans = gst_structure_get_value (structure, "channels");
structure = gst_caps_get_structure (base_caps, 0); /* adjust the name */
rate = gst_structure_get_value (structure, "rate"); gst_structure_set_name (structure, name);
chans = gst_structure_get_value (structure, "channels");
if (orate) { if (pad == mulawenc->srcpad) {
gst_value_intersect (&irate, orate, rate); /* remove the fields we don't want */
gst_structure_set_value (structure, "rate", &irate); gst_structure_remove_fields (structure, "width", "depth", "endianness",
"signed", NULL);
} else {
/* add fixed fields */
gst_structure_set (structure, "width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"signed", G_TYPE_BOOLEAN, TRUE, NULL);
}
} }
/* filter against the allowed caps of the pad to return our result */
if (ochans) { result = gst_caps_intersect (othercaps, templ);
gst_value_intersect (&ichans, ochans, chans);
gst_structure_set_value (structure, "channels", &ichans);
}
done:
gst_caps_unref (othercaps); gst_caps_unref (othercaps);
} else {
/* there was no peer, return the template caps */
result = gst_caps_copy (templ);
} }
return base_caps; return result;
} }
static gboolean static gboolean

View file

@ -29,7 +29,7 @@ GstStaticPadTemplate mulaw_dec_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
"rate = (int) [ 8000, 192000 ], " "rate = (int) [ 8000, 192000 ], "
"channels = (int) [ 1, 2 ], " "channels = (int) [ 1, 2 ], "
"endianness = (int) BYTE_ORDER, " "endianness = (int) BYTE_ORDER, "
"width = (int) 16, " "width = (int) 16, " "signed = (boolean) True") "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) True")
); );
GstStaticPadTemplate mulaw_dec_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GstStaticPadTemplate mulaw_dec_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
@ -46,7 +46,7 @@ GstStaticPadTemplate mulaw_enc_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
"rate = (int) [ 8000, 192000 ], " "rate = (int) [ 8000, 192000 ], "
"channels = (int) [ 1, 2 ], " "channels = (int) [ 1, 2 ], "
"endianness = (int) BYTE_ORDER, " "endianness = (int) BYTE_ORDER, "
"width = (int) 16, " "width = (int) 16, " "signed = (boolean) True") "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) True")
); );
GstStaticPadTemplate mulaw_enc_src_factory = GST_STATIC_PAD_TEMPLATE ("src", GstStaticPadTemplate mulaw_enc_src_factory = GST_STATIC_PAD_TEMPLATE ("src",