gstrtpj2k: set sampling field required by RFC
authorAaron Boxer <boxerab@gmail.com>
Fri, 13 May 2016 19:08:24 +0000 (15:08 -0400)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 10 Jun 2016 10:14:44 +0000 (13:14 +0300)
This field is now required in the sink caps.

https://bugzilla.gnome.org/show_bug.cgi?id=766236

gst/rtp/gstrtpj2kcommon.h
gst/rtp/gstrtpj2kdepay.c
gst/rtp/gstrtpj2kpay.c

index e4af8cb..09f1bbb 100644 (file)
 #define __GST_RTP_J2K_COMMON_H__
 
 
+
+/* Sampling values from RFC 5371 for JPEG 2000 over RTP : https://datatracker.ietf.org/doc/rfc5371/C
+
+RGB:  standard Red, Green, Blue color space.
+
+BGR:  standard Blue, Green, Red color space.
+
+RGBA:  standard Red, Green, Blue, Alpha color space.
+
+BGRA:  standard Blue, Green, Red, Alpha color space.
+
+YCbCr-4:4:4:  standard YCbCr color space; no subsampling.
+
+YCbCr-4:2:2:  standard YCbCr color space; Cb and Cr are subsampled horizontally by 1/2.
+
+YCbCr-4:2:0:  standard YCbCr color space; Cb and Cr are subsampled horizontally and vertically by 1/2.
+
+YCbCr-4:1:1:  standard YCbCr color space; Cb and Cr are subsampled vertically by 1/4.
+
+GRAYSCALE:  basically, a single component image of just multilevels of grey.
+*/
+
+
+#define GST_RTP_J2K_RGB       "RGB"
+#define GST_RTP_J2K_BGR       "BGR"
+#define GST_RTP_J2K_RGBA      "RGBA"
+#define GST_RTP_J2K_BGRA      "BGRA"
+#define GST_RTP_J2K_YBRA         "YCbCrA"
+#define GST_RTP_J2K_YBR444    "YCbCr-4:4:4"
+#define GST_RTP_J2K_YBR422    "YCbCr-4:2:2"
+#define GST_RTP_J2K_YBR420    "YCbCr-4:2:0"
+#define GST_RTP_J2K_YBR410    "YCbCr-4:1:0"
+#define GST_RTP_J2K_GRAYSCALE "GRAYSCALE"
+
+#define GST_RTP_J2K_SAMPLING_LIST "sampling = (string) {\"RGB\", \"BGR\", \"RGBA\", \"BGRA\", \"YCbCrA\", \"YCbCr-4:4:4\", \"YCbCr-4:2:2\", \"YCbCr-4:2:0\", \"YCbCr-4:1:1\", \"GRAYSCALE\"}"
+
+typedef enum
+{
+
+  GST_RTP_SAMPLING_NONE,
+  GST_RTP_SAMPLING_RGB,
+  GST_RTP_SAMPLING_BGR,
+  GST_RTP_SAMPLING_RGBA,
+  GST_RTP_SAMPLING_BGRA,
+  GST_RTP_SAMPLING_YBRA,
+  GST_RTP_SAMPLING_YBR444,
+  GST_RTP_SAMPLING_YBR422,
+  GST_RTP_SAMPLING_YBR420,
+  GST_RTP_SAMPLING_YBR410,
+  GST_RTP_SAMPLING_GRAYSCALE
+} GstRtpSampling;
+
+
 /*
 * GstRtpJ2KMarker:
 * @GST_J2K_MARKER: Prefix for JPEG 2000 marker
@@ -29,7 +82,7 @@
 * @GST_J2K_MARKER_SOT: Start of tile
 * @GST_J2K_MARKER_EOC: End of Codestream
 *
-* Identifers for markers in JPEG 2000 codestreams
+* Identifiers for markers in JPEG 2000 code streams
 */
 typedef enum
 {
index 9dba811..6f1b1b2 100644 (file)
@@ -47,16 +47,22 @@ static GstStaticPadTemplate gst_rtp_j2k_depay_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("image/x-jpc")
+    GST_STATIC_CAPS ("image/x-jpc, "
+        "colorspace = (string) { sRGB, sYUV, GRAY }")
     );
 
 static GstStaticPadTemplate gst_rtp_j2k_depay_sink_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("application/x-rtp, "
-        "media = (string) \"video\", "
-        "clock-rate = (int) 90000, " "encoding-name = (string) \"JPEG2000\"")
+        "media = (string) \"video\", " "clock-rate = (int) 90000, "
+        GST_RTP_J2K_SAMPLING_LIST ","
+        "encoding-name = (string) \"JPEG2000\";"
+        "application/x-rtp, "
+        "media = (string) \"video\", " "clock-rate = (int) 90000, "
+        "colorspace = (string) { sRGB, sYUV, GRAY }, "
+        "encoding-name = (string) \"JPEG2000\";")
     );
 
 enum
@@ -177,10 +183,12 @@ gst_rtp_j2k_depay_finalize (GObject * object)
 static gboolean
 gst_rtp_j2k_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
 {
-  GstStructure *structure;
+  GstStructure *structure = NULL;
   gint clock_rate;
-  GstCaps *outcaps;
-  gboolean res;
+  GstCaps *outcaps = NULL;
+  gboolean res = FALSE;
+  const gchar *colorspace = NULL;
+  const gchar *sampling = NULL;
 
   structure = gst_caps_get_structure (caps, 0);
 
@@ -188,10 +196,35 @@ gst_rtp_j2k_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
     clock_rate = 90000;
   depayload->clock_rate = clock_rate;
 
-  outcaps =
-      gst_caps_new_simple ("image/x-jpc", "framerate", GST_TYPE_FRACTION, 0, 1,
-      "fields", G_TYPE_INT, 1, "colorspace", G_TYPE_STRING, "sYUV", NULL);
+  sampling = gst_structure_get_string (structure, "sampling");
+  if (sampling) {
+    if (!strcmp (sampling, GST_RTP_J2K_RGB) ||
+        !strcmp (sampling, GST_RTP_J2K_RGBA) ||
+        !strcmp (sampling, GST_RTP_J2K_BGR) ||
+        !strcmp (sampling, GST_RTP_J2K_BGRA))
+      colorspace = "sRGB";
+    else if (!strcmp (sampling, GST_RTP_J2K_GRAYSCALE))
+      colorspace = "GRAY";
+    else
+      colorspace = "sYUV";
+  } else {
+    GST_ELEMENT_WARNING (depayload, STREAM, DEMUX, NULL,
+        ("Non-compliant stream: sampling field missing. Frames my appear incorrect"));
+    colorspace = gst_structure_get_string (structure, "colorspace");
+    if (!strcmp (colorspace, "GRAY")) {
+      sampling = GST_RTP_J2K_GRAYSCALE;
+    }
+  }
+
+  outcaps = gst_caps_new_simple ("image/x-jpc",
+      "framerate", GST_TYPE_FRACTION, 0, 1,
+      "fields", G_TYPE_INT, 1, "colorspace", G_TYPE_STRING, colorspace, NULL);
+
+  if (sampling)
+    gst_caps_set_simple (outcaps, "sampling", G_TYPE_STRING, sampling, NULL);
+
   res = gst_pad_set_caps (depayload->srcpad, outcaps);
+
   gst_caps_unref (outcaps);
 
   return res;
index 3949ccf..f0b0979 100644 (file)
@@ -48,9 +48,10 @@ static GstStaticPadTemplate gst_rtp_j2k_pay_sink_template =
 GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("image/x-jpc")
+    GST_STATIC_CAPS ("image/x-jpc, " GST_RTP_J2K_SAMPLING_LIST)
     );
 
+
 static GstStaticPadTemplate gst_rtp_j2k_pay_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
@@ -59,7 +60,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
         "  media = (string) \"video\", "
         "  payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
         "  clock-rate = (int) 90000, "
-        "  encoding-name = (string) \"JPEG2000\"")
+        GST_RTP_J2K_SAMPLING_LIST "," "  encoding-name = (string) \"JPEG2000\"")
     );
 
 GST_DEBUG_CATEGORY_STATIC (rtpj2kpay_debug);
@@ -137,24 +138,29 @@ static gboolean
 gst_rtp_j2k_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
 {
   GstStructure *caps_structure = gst_caps_get_structure (caps, 0);
-  GstRtpJ2KPay *pay;
-  gint width = 0, height = 0;
   gboolean res;
+  gint width = 0, height = 0;
+  const gchar *sampling = NULL;
 
-  pay = GST_RTP_J2K_PAY (basepayload);
+  gboolean has_width = gst_structure_get_int (caps_structure, "width", &width);
+  gboolean has_height =
+      gst_structure_get_int (caps_structure, "height", &height);
 
-  /* these properties are not mandatory, we can get them from the stream */
-  if (gst_structure_get_int (caps_structure, "height", &height)) {
-    pay->height = height;
-  }
-  if (gst_structure_get_int (caps_structure, "width", &width)) {
-    pay->width = width;
-  }
+
+  /* sampling is a required field */
+  sampling = gst_structure_get_string (caps_structure, "sampling");
 
   gst_rtp_base_payload_set_options (basepayload, "video", TRUE, "JPEG2000",
       90000);
-  res = gst_rtp_base_payload_set_outcaps (basepayload, NULL);
 
+  if (has_width && has_height)
+    res = gst_rtp_base_payload_set_outcaps (basepayload,
+        "sampling", G_TYPE_STRING, sampling, "width", G_TYPE_INT, width,
+        "height", G_TYPE_INT, height, NULL);
+  else
+    res =
+        gst_rtp_base_payload_set_outcaps (basepayload, "sampling",
+        G_TYPE_STRING, sampling, NULL);
   return res;
 }