mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-27 09:38:17 +00:00
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:
parent
6d0007372b
commit
89f0c37c9f
6 changed files with 154 additions and 113 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in a new issue