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
This commit is contained in:
Sebastian Rasmussen 2013-05-22 01:58:57 +02:00 committed by Sebastian Dröge
parent d8825e2a5c
commit 0075d111b4
2 changed files with 56 additions and 49 deletions

View file

@ -37,6 +37,11 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("image/jpeg") GST_STATIC_CAPS ("image/jpeg")
/* optional SDP attributes */
/*
* "width = (int) 0, "
* "height = (int) 0, "
*/
); );
static GstStaticPadTemplate gst_rtp_jpeg_depay_sink_template = static GstStaticPadTemplate gst_rtp_jpeg_depay_sink_template =
@ -45,13 +50,15 @@ static GstStaticPadTemplate gst_rtp_jpeg_depay_sink_template =
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-rtp, " GST_STATIC_CAPS ("application/x-rtp, "
"media = (string) \"video\", " "media = (string) \"video\", "
"clock-rate = (int) 90000, " "encoding-name = (string) \"JPEG\"; " "clock-rate = (int) 90000, "
"encoding-name = (string) \"JPEG\"; "
/* optional SDP attributes */ /* optional SDP attributes */
/* /*
* "width = (int) 0, "
* "height = (int) 0, "
* "a-framerate = (string) 0.00, " * "a-framerate = (string) 0.00, "
* "x-framerate = (string) 0.00, " * "x-framerate = (string) 0.00, "
* "a-framesize = (string) 1234-1234, " * "x-dimensions = (string) "0\,0", "
* "x-dimensions = (string) \"1234,1234\", "
*/ */
"application/x-rtp, " "application/x-rtp, "
"media = (string) \"video\", " "media = (string) \"video\", "
@ -59,10 +66,11 @@ static GstStaticPadTemplate gst_rtp_jpeg_depay_sink_template =
"clock-rate = (int) 90000" "clock-rate = (int) 90000"
/* optional SDP attributes */ /* optional SDP attributes */
/* /*
* "width = (int) 0, "
* "height = (int) 0, "
* "a-framerate = (string) 0.00, " * "a-framerate = (string) 0.00, "
* "x-framerate = (string) 0.00, " * "x-framerate = (string) 0.00, "
* "a-framesize = (string) 1234-1234, " * "x-dimensions = (string) "0\,0", "
* "x-dimensions = (string) \"1234,1234\""
*/ */
) )
); );
@ -430,6 +438,7 @@ gst_rtp_jpeg_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
GstStructure *structure; GstStructure *structure;
gint clock_rate; gint clock_rate;
const gchar *media_attr; const gchar *media_attr;
gint width = 0, height = 0;
rtpjpegdepay = GST_RTP_JPEG_DEPAY (depayload); rtpjpegdepay = GST_RTP_JPEG_DEPAY (depayload);
@ -450,21 +459,17 @@ gst_rtp_jpeg_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
/* check for optional SDP attributes */ /* check for optional SDP attributes */
if ((media_attr = gst_structure_get_string (structure, "x-dimensions"))) { if ((media_attr = gst_structure_get_string (structure, "x-dimensions"))) {
gint w, h; if (sscanf (media_attr, "%d,%d", &width, &height) != 2 || width <= 0 ||
height <= 0) {
if (sscanf (media_attr, "%d,%d", &w, &h) == 2) { goto invalid_dimension;
rtpjpegdepay->media_width = w;
rtpjpegdepay->media_height = h;
} }
} }
if ((media_attr = gst_structure_get_string (structure, "a-framesize"))) { if (gst_structure_get_int (structure, "width", &width) && width <= 0) {
gint w, h; goto invalid_dimension;
if (sscanf (media_attr, "%d-%d", &w, &h) == 2) {
rtpjpegdepay->media_width = w;
rtpjpegdepay->media_height = h;
} }
if (gst_structure_get_int (structure, "height", &height) && height <= 0) {
goto invalid_dimension;
} }
/* try to get a framerate */ /* try to get a framerate */
@ -494,7 +499,16 @@ gst_rtp_jpeg_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
g_free (s); g_free (s);
} }
rtpjpegdepay->media_width = width;
rtpjpegdepay->media_height = height;
return TRUE; return TRUE;
invalid_dimension:
{
GST_ERROR_OBJECT (rtpjpegdepay, "invalid width/height from caps");
return FALSE;
}
} }
static GstBuffer * static GstBuffer *
@ -631,8 +645,13 @@ gst_rtp_jpeg_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
outcaps = outcaps =
gst_caps_new_simple ("image/jpeg", "framerate", GST_TYPE_FRACTION, gst_caps_new_simple ("image/jpeg", "framerate", GST_TYPE_FRACTION,
rtpjpegdepay->frate_num, rtpjpegdepay->frate_denom, "width", rtpjpegdepay->frate_num, rtpjpegdepay->frate_denom, NULL);
G_TYPE_INT, width, "height", G_TYPE_INT, height, 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_pad_set_caps (depayload->srcpad, outcaps);
gst_caps_unref (outcaps); gst_caps_unref (outcaps);

View file

@ -45,7 +45,12 @@ static GstStaticPadTemplate gst_rtp_jpeg_pay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, 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 = static GstStaticPadTemplate gst_rtp_jpeg_pay_src_template =
@ -57,8 +62,8 @@ GST_STATIC_PAD_TEMPLATE ("src",
" payload = (int) 26 , " " payload = (int) 26 , "
" clock-rate = (int) 90000, " " clock-rate = (int) 90000, "
" encoding-name = (string) \"JPEG\", " " encoding-name = (string) \"JPEG\", "
" width = (int) [ 1, 65536 ], " " width = (int) [ 1, MAX ], "
" height = (int) [ 1, 65536 ]") " height = (int) [ 1, MAX ]")
); );
GST_DEBUG_CATEGORY_STATIC (rtpjpegpay_debug); 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); GstStructure *caps_structure = gst_caps_get_structure (caps, 0);
GstRtpJPEGPay *pay; GstRtpJPEGPay *pay;
gboolean res; gboolean res;
gint width = -1, height = -1; gint width, height;
gint num = 0, denom; gint num = 0, denom;
gchar *rate = NULL; gchar *rate = NULL;
gchar *dim = NULL;
gchar *size;
pay = GST_RTP_JPEG_PAY (basepayload); pay = GST_RTP_JPEG_PAY (basepayload);
@ -317,6 +320,8 @@ gst_rtp_jpeg_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
} }
if (height > 2040 || width > 2040) { 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->height = 0;
pay->width = 0; pay->width = 0;
} else { } else {
@ -333,34 +338,17 @@ gst_rtp_jpeg_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
rate = g_strdup_printf("%f", framerate); rate = g_strdup_printf("%f", framerate);
} }
size = g_strdup_printf("%d-%d", width, height); if (rate != NULL) {
res = gst_rtp_base_payload_set_outcaps (basepayload, "width", G_TYPE_INT,
if (pay->width == 0) { width, "height", G_TYPE_INT, height, "a-framerate", G_TYPE_STRING,
GST_DEBUG_OBJECT (pay, rate, NULL);
"width or height are greater than 2040, adding x-dimensions to caps"); } else if (rate == NULL) {
dim = g_strdup_printf ("%d,%d", width, height); 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) if (rate != NULL)
g_free (rate); g_free (rate);
g_free (size);
return res; return res;