summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Crête <olivier.crete@collabora.com>2015-03-24 13:57:54 -0400
committerTim-Philipp Müller <tim@centricular.com>2016-02-17 14:58:01 +0000
commit89b172b3ed43a5e43dd12b70611e3fd627a35b4a (patch)
tree5827eb8d79572e3495c1e24acee4cc2045f0cc24
parent4df223f3257f29a14086b17c7904b13b71d5ab80 (diff)
downloadgstreamer-plugins-good-89b172b3ed43a5e43dd12b70611e3fd627a35b4a.tar.gz
rtpopuspay: Forward stereo preferences from caps upstream
https://bugzilla.gnome.org/show_bug.cgi?id=746617
-rw-r--r--gst/rtp/gstrtpopuspay.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/gst/rtp/gstrtpopuspay.c b/gst/rtp/gstrtpopuspay.c
index 7a36dceaa..057c8d0cc 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;
+}