From 0075d111b475ca27895ee9476154260b6902940b Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Wed, 22 May 2013 01:58:57 +0200 Subject: [PATCH] rtpjpegpay/depay: Replace framesize caps with width/height The previous implementation had the formatting of SDP attributes happen in each RTP payloader, now instead the constituent values are propagated as caps fields. This allows for applications to do SDP offer/answer based on caps negotiation. Keep parsing a-framerate, x-framerate and x-dimensions in rtpjpegdepay to be backwards compatible with previous payloaders. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=700748 --- gst/rtp/gstrtpjpegdepay.c | 57 ++++++++++++++++++++++++++------------- gst/rtp/gstrtpjpegpay.c | 48 +++++++++++++-------------------- 2 files changed, 56 insertions(+), 49 deletions(-) diff --git a/gst/rtp/gstrtpjpegdepay.c b/gst/rtp/gstrtpjpegdepay.c index f10bf464f7..0dbc736345 100644 --- a/gst/rtp/gstrtpjpegdepay.c +++ b/gst/rtp/gstrtpjpegdepay.c @@ -37,6 +37,11 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("image/jpeg") + /* optional SDP attributes */ + /* + * "width = (int) 0, " + * "height = (int) 0, " + */ ); static GstStaticPadTemplate gst_rtp_jpeg_depay_sink_template = @@ -45,13 +50,15 @@ static GstStaticPadTemplate gst_rtp_jpeg_depay_sink_template = GST_PAD_ALWAYS, GST_STATIC_CAPS ("application/x-rtp, " "media = (string) \"video\", " - "clock-rate = (int) 90000, " "encoding-name = (string) \"JPEG\"; " + "clock-rate = (int) 90000, " + "encoding-name = (string) \"JPEG\"; " /* optional SDP attributes */ /* + * "width = (int) 0, " + * "height = (int) 0, " * "a-framerate = (string) 0.00, " * "x-framerate = (string) 0.00, " - * "a-framesize = (string) 1234-1234, " - * "x-dimensions = (string) \"1234,1234\", " + * "x-dimensions = (string) "0\,0", " */ "application/x-rtp, " "media = (string) \"video\", " @@ -59,10 +66,11 @@ static GstStaticPadTemplate gst_rtp_jpeg_depay_sink_template = "clock-rate = (int) 90000" /* optional SDP attributes */ /* + * "width = (int) 0, " + * "height = (int) 0, " * "a-framerate = (string) 0.00, " * "x-framerate = (string) 0.00, " - * "a-framesize = (string) 1234-1234, " - * "x-dimensions = (string) \"1234,1234\"" + * "x-dimensions = (string) "0\,0", " */ ) ); @@ -430,6 +438,7 @@ gst_rtp_jpeg_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) GstStructure *structure; gint clock_rate; const gchar *media_attr; + gint width = 0, height = 0; rtpjpegdepay = GST_RTP_JPEG_DEPAY (depayload); @@ -450,21 +459,17 @@ gst_rtp_jpeg_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) /* check for optional SDP attributes */ if ((media_attr = gst_structure_get_string (structure, "x-dimensions"))) { - gint w, h; - - if (sscanf (media_attr, "%d,%d", &w, &h) == 2) { - rtpjpegdepay->media_width = w; - rtpjpegdepay->media_height = h; + if (sscanf (media_attr, "%d,%d", &width, &height) != 2 || width <= 0 || + height <= 0) { + goto invalid_dimension; } } - if ((media_attr = gst_structure_get_string (structure, "a-framesize"))) { - gint w, h; - - if (sscanf (media_attr, "%d-%d", &w, &h) == 2) { - rtpjpegdepay->media_width = w; - rtpjpegdepay->media_height = h; - } + if (gst_structure_get_int (structure, "width", &width) && width <= 0) { + goto invalid_dimension; + } + if (gst_structure_get_int (structure, "height", &height) && height <= 0) { + goto invalid_dimension; } /* try to get a framerate */ @@ -494,7 +499,16 @@ gst_rtp_jpeg_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) g_free (s); } + rtpjpegdepay->media_width = width; + rtpjpegdepay->media_height = height; + return TRUE; + +invalid_dimension: + { + GST_ERROR_OBJECT (rtpjpegdepay, "invalid width/height from caps"); + return FALSE; + } } static GstBuffer * @@ -631,8 +645,13 @@ gst_rtp_jpeg_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf) outcaps = gst_caps_new_simple ("image/jpeg", "framerate", GST_TYPE_FRACTION, - rtpjpegdepay->frate_num, rtpjpegdepay->frate_denom, "width", - G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL); + rtpjpegdepay->frate_num, rtpjpegdepay->frate_denom, NULL); + + if (width > 0 && height > 0) { + gst_caps_set_simple (outcaps, "width", G_TYPE_INT, width, "height", + G_TYPE_INT, height, NULL); + } + gst_pad_set_caps (depayload->srcpad, outcaps); gst_caps_unref (outcaps); diff --git a/gst/rtp/gstrtpjpegpay.c b/gst/rtp/gstrtpjpegpay.c index 859d16b16c..bea26e6170 100644 --- a/gst/rtp/gstrtpjpegpay.c +++ b/gst/rtp/gstrtpjpegpay.c @@ -45,7 +45,12 @@ static GstStaticPadTemplate gst_rtp_jpeg_pay_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("image/jpeg; " "video/x-jpeg") + GST_STATIC_CAPS ("image/jpeg, " + " width = (int) [ 1, MAX ], " + " height = (int) [ 1, MAX ]; " + " video/x-jpeg, " + " width = (int) [ 1, MAX ], " + " height = (int) [ 1, MAX ]") ); static GstStaticPadTemplate gst_rtp_jpeg_pay_src_template = @@ -57,8 +62,8 @@ GST_STATIC_PAD_TEMPLATE ("src", " payload = (int) 26 , " " clock-rate = (int) 90000, " " encoding-name = (string) \"JPEG\", " - " width = (int) [ 1, 65536 ], " - " height = (int) [ 1, 65536 ]") + " width = (int) [ 1, MAX ], " + " height = (int) [ 1, MAX ]") ); GST_DEBUG_CATEGORY_STATIC (rtpjpegpay_debug); @@ -293,11 +298,9 @@ gst_rtp_jpeg_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) GstStructure *caps_structure = gst_caps_get_structure (caps, 0); GstRtpJPEGPay *pay; gboolean res; - gint width = -1, height = -1; + gint width, height; gint num = 0, denom; gchar *rate = NULL; - gchar *dim = NULL; - gchar *size; pay = GST_RTP_JPEG_PAY (basepayload); @@ -317,6 +320,8 @@ gst_rtp_jpeg_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) } if (height > 2040 || width > 2040) { + GST_DEBUG_OBJECT (pay, + "width or height > 2040, need to rely on caps instead of RTP header"); pay->height = 0; pay->width = 0; } else { @@ -333,34 +338,17 @@ gst_rtp_jpeg_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) rate = g_strdup_printf("%f", framerate); } - size = g_strdup_printf("%d-%d", width, height); - - if (pay->width == 0) { - GST_DEBUG_OBJECT (pay, - "width or height are greater than 2040, adding x-dimensions to caps"); - dim = g_strdup_printf ("%d,%d", width, height); + if (rate != NULL) { + res = gst_rtp_base_payload_set_outcaps (basepayload, "width", G_TYPE_INT, + width, "height", G_TYPE_INT, height, "a-framerate", G_TYPE_STRING, + rate, NULL); + } else if (rate == NULL) { + res = gst_rtp_base_payload_set_outcaps (basepayload, "width", + G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL); } - if (rate != NULL && dim != NULL) { - res = gst_rtp_base_payload_set_outcaps (basepayload, "a-framerate", - G_TYPE_STRING, rate, "a-framesize", G_TYPE_STRING, size, - "x-dimensions", G_TYPE_STRING, dim, NULL); - } else if (rate != NULL && dim == NULL) { - res = gst_rtp_base_payload_set_outcaps (basepayload, "a-framerate", - G_TYPE_STRING, rate, "a-framesize", G_TYPE_STRING, size, NULL); - } else if (rate == NULL && dim != NULL) { - res = gst_rtp_base_payload_set_outcaps (basepayload, "x-dimensions", - G_TYPE_STRING, dim, "a-framesize", G_TYPE_STRING, size, NULL); - } else { - res = gst_rtp_base_payload_set_outcaps (basepayload, "a-framesize", - G_TYPE_STRING, size, NULL); - } - - if (dim != NULL) - g_free (dim); if (rate != NULL) g_free (rate); - g_free (size); return res;