summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@hotmail.com>2014-03-15 15:23:01 +0100
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2015-04-02 19:38:21 -0400
commitcf54d4cc67e687605aba05e5d184cf381d768593 (patch)
tree153ff0754f1ece5072e06798d5e5773586ce4c63
parent896fc208066c0c314d8b9043a4d2f7ffbc8b657e (diff)
rtph263pay/-depay: add framesize SDP attribute
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=726416
-rw-r--r--gst/rtp/gstrtph263depay.c76
-rw-r--r--gst/rtp/gstrtph263pay.c32
-rw-r--r--tests/check/elements/rtp-payloading.c7
3 files changed, 109 insertions, 6 deletions
diff --git a/gst/rtp/gstrtph263depay.c b/gst/rtp/gstrtph263depay.c
index 83e901288..749da5369 100644
--- a/gst/rtp/gstrtph263depay.c
+++ b/gst/rtp/gstrtph263depay.c
@@ -55,9 +55,16 @@ static GstStaticPadTemplate gst_rtp_h263_depay_sink_template =
"media = (string) \"video\", "
"payload = (int) " GST_RTP_PAYLOAD_H263_STRING ", "
"clock-rate = (int) 90000; "
+ /* optional SDP attribute:
+ * "a-framesize = (string) \"1234-1234\", "
+ */
"application/x-rtp, "
"media = (string) \"video\", "
- "clock-rate = (int) 90000, " "encoding-name = (string) \"H263\"")
+ "clock-rate = (int) 90000, " "encoding-name = (string) \"H263\""
+ /* optional SDP attribute:
+ * "a-framesize = (string) \"1234-1234\", "
+ */
+ )
);
#define gst_rtp_h263_depay_parent_class parent_class
@@ -129,20 +136,81 @@ gst_rtp_h263_depay_finalize (GObject * object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static gboolean
+gst_rtp_h263_parse_framesize (GstRTPBaseDepayload * filter,
+ const gchar * media_attr, GstCaps * srccaps)
+{
+ gchar *dimension, *endptr;
+ gint pt, width, height;
+ GstStructure *d;
+
+ /* <payload type number> <width>-<height> */
+
+ pt = g_ascii_strtoull (media_attr, &endptr, 10);
+ if (pt != GST_RTP_PAYLOAD_H263) {
+ GST_ERROR_OBJECT (filter,
+ "Framesize media attribute has incorrect payload type");
+ return FALSE;
+ } else if (*endptr != ' ') {
+ GST_ERROR_OBJECT (filter,
+ "Framesize media attribute has invalid payload type separator");
+ return FALSE;
+ }
+
+ dimension = endptr + 1;
+ width = g_ascii_strtoull (dimension, &endptr, 10);
+ if (width <= 0) {
+ GST_ERROR_OBJECT (filter,
+ "Framesize media attribute width out of valid range");
+ return FALSE;
+ } else if (*endptr != '-') {
+ GST_ERROR_OBJECT (filter,
+ "Framesize media attribute has invalid dimension separator");
+ return FALSE;
+ }
+
+ dimension = endptr + 1;
+ height = g_ascii_strtoull (dimension, &endptr, 10);
+ if (height <= 0) {
+ GST_ERROR_OBJECT (filter,
+ "Framesize media attribute height out of valid range");
+ return FALSE;
+ } else if (*endptr != '\0') {
+ GST_ERROR_OBJECT (filter,
+ "Framesize media attribute unexpectedly has trailing characters");
+ return FALSE;
+ }
+
+ d = gst_caps_get_structure (srccaps, 0);
+ gst_structure_set (d, "width", G_TYPE_INT, width, "height", G_TYPE_INT,
+ height, NULL);
+
+ return TRUE;
+}
+
gboolean
gst_rtp_h263_depay_setcaps (GstRTPBaseDepayload * filter, GstCaps * caps)
{
GstCaps *srccaps;
GstStructure *structure = gst_caps_get_structure (caps, 0);
gint clock_rate;
+ const gchar *framesize;
+
+ srccaps = gst_caps_new_simple ("video/x-h263",
+ "variant", G_TYPE_STRING, "itu",
+ "h263version", G_TYPE_STRING, "h263", NULL);
if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
clock_rate = 90000; /* default */
filter->clock_rate = clock_rate;
- srccaps = gst_caps_new_simple ("video/x-h263",
- "variant", G_TYPE_STRING, "itu",
- "h263version", G_TYPE_STRING, "h263", NULL);
+ framesize = gst_structure_get_string (structure, "a-framesize");
+ if (framesize != NULL) {
+ if (!gst_rtp_h263_parse_framesize (filter, framesize, srccaps)) {
+ return FALSE;
+ }
+ }
+
gst_pad_set_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (filter), srccaps);
gst_caps_unref (srccaps);
diff --git a/gst/rtp/gstrtph263pay.c b/gst/rtp/gstrtph263pay.c
index c664c5b9b..0b7d24ea1 100644
--- a/gst/rtp/gstrtph263pay.c
+++ b/gst/rtp/gstrtph263pay.c
@@ -461,13 +461,43 @@ gst_rtp_h263_pay_finalize (GObject * object)
static gboolean
gst_rtp_h263_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
{
+ GstStructure *s = gst_caps_get_structure (caps, 0);
+ gint width, height;
+ gchar *framesize = NULL;
gboolean res;
+ if (gst_structure_has_field (s, "width") &&
+ gst_structure_has_field (s, "height")) {
+ if (!gst_structure_get_int (s, "width", &width) || width <= 0) {
+ goto invalid_dimension;
+ }
+
+ if (!gst_structure_get_int (s, "height", &height) || height <= 0) {
+ goto invalid_dimension;
+ }
+
+ framesize = g_strdup_printf ("%d-%d", width, height);
+ }
+
payload->pt = GST_RTP_PAYLOAD_H263;
gst_rtp_base_payload_set_options (payload, "video", TRUE, "H263", 90000);
- res = gst_rtp_base_payload_set_outcaps (payload, NULL);
+
+ if (framesize != NULL) {
+ res = gst_rtp_base_payload_set_outcaps (payload,
+ "a-framesize", G_TYPE_STRING, framesize, NULL);
+ } else {
+ res = gst_rtp_base_payload_set_outcaps (payload, NULL);
+ }
+ g_free (framesize);
return res;
+
+ /* ERRORS */
+invalid_dimension:
+ {
+ GST_ERROR_OBJECT (payload, "Invalid width/height from caps");
+ return FALSE;
+ }
}
static void
diff --git a/tests/check/elements/rtp-payloading.c b/tests/check/elements/rtp-payloading.c
index a5db021db..7dc9ce07c 100644
--- a/tests/check/elements/rtp-payloading.c
+++ b/tests/check/elements/rtp-payloading.c
@@ -476,7 +476,12 @@ static int rtp_h263_frame_count = 1;
GST_START_TEST (rtp_h263)
{
rtp_pipeline_test (rtp_h263_frame_data, rtp_h263_frame_data_size,
- rtp_h263_frame_count, "video/x-h263,variant=(string)itu,h263version=h263",
+ rtp_h263_frame_count,
+ "video/x-h263,variant=(string)itu,h263version=h263",
+ "rtph263pay", "rtph263depay", 0, 0, FALSE);
+ rtp_pipeline_test (rtp_h263_frame_data, rtp_h263_frame_data_size,
+ rtp_h263_frame_count,
+ "video/x-h263,variant=(string)itu,h263version=h263,width=10,height=20",
"rtph263pay", "rtph263depay", 0, 0, FALSE);
}