diff --git a/gst/rtp/gstrtpopuspay.c b/gst/rtp/gstrtpopuspay.c index 7a36dceaaf..057c8d0cc3 100644 --- a/gst/rtp/gstrtpopuspay.c +++ b/gst/rtp/gstrtpopuspay.c @@ -54,6 +54,8 @@ GST_STATIC_PAD_TEMPLATE ("src", static gboolean gst_rtp_opus_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps); +static GstCaps *gst_rtp_opus_pay_getcaps (GstRTPBasePayload * payload, + GstPad * pad, GstCaps * filter); static GstFlowReturn gst_rtp_opus_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer); @@ -69,6 +71,7 @@ gst_rtp_opus_pay_class_init (GstRtpOPUSPayClass * klass) element_class = GST_ELEMENT_CLASS (klass); gstbasertppayload_class->set_caps = gst_rtp_opus_pay_setcaps; + gstbasertppayload_class->get_caps = gst_rtp_opus_pay_getcaps; gstbasertppayload_class->handle_buffer = gst_rtp_opus_pay_handle_buffer; gst_element_class_add_pad_template (element_class, @@ -117,7 +120,8 @@ gst_rtp_opus_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps) s = gst_caps_get_structure (caps, 0); if (gst_structure_get_int (s, "channels", &channels)) { if (channels > 2) { - GST_ERROR_OBJECT (payload, "More than 2 channels are not supported yet"); + GST_ERROR_OBJECT (payload, + "More than 2 channels with multistream=FALSE is invalid"); return FALSE; } else if (channels == 2) { sprop_stereo = "1"; @@ -177,3 +181,62 @@ gst_rtp_opus_pay_handle_buffer (GstRTPBasePayload * basepayload, /* Push out */ return gst_rtp_base_payload_push (basepayload, outbuf); } + +static GstCaps * +gst_rtp_opus_pay_getcaps (GstRTPBasePayload * payload, + GstPad * pad, GstCaps * filter) +{ + GstCaps *caps, *peercaps, *tcaps; + GstStructure *s; + const gchar *stereo; + + if (pad == GST_RTP_BASE_PAYLOAD_SRCPAD (payload)) + return + GST_RTP_BASE_PAYLOAD_CLASS (gst_rtp_opus_pay_parent_class)->get_caps + (payload, pad, filter); + + tcaps = gst_pad_get_pad_template_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload)); + peercaps = gst_pad_peer_query_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload), + tcaps); + gst_caps_unref (tcaps); + if (!peercaps) + return + GST_RTP_BASE_PAYLOAD_CLASS (gst_rtp_opus_pay_parent_class)->get_caps + (payload, pad, filter); + + if (gst_caps_is_empty (peercaps)) + return peercaps; + + caps = gst_pad_get_pad_template_caps (GST_RTP_BASE_PAYLOAD_SINKPAD (payload)); + + s = gst_caps_get_structure (peercaps, 0); + stereo = gst_structure_get_string (s, "stereo"); + if (stereo != NULL) { + caps = gst_caps_make_writable (caps); + + if (!strcmp (stereo, "1")) { + GstCaps *caps2 = gst_caps_copy (caps); + + gst_caps_set_simple (caps, "channels", G_TYPE_INT, 2, NULL); + gst_caps_set_simple (caps2, "channels", G_TYPE_INT, 1, NULL); + caps = gst_caps_merge (caps, caps2); + } else if (!strcmp (stereo, "0")) { + GstCaps *caps2 = gst_caps_copy (caps); + + gst_caps_set_simple (caps, "channels", G_TYPE_INT, 1, NULL); + gst_caps_set_simple (caps2, "channels", G_TYPE_INT, 2, NULL); + caps = gst_caps_merge (caps, caps2); + } + } + gst_caps_unref (peercaps); + + if (filter) { + GstCaps *tmp = gst_caps_intersect_full (caps, filter, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + caps = tmp; + } + + GST_DEBUG_OBJECT (payload, "Returning caps: %" GST_PTR_FORMAT, caps); + return caps; +}