rtp: Update codes based on 1.18.4
[platform/upstream/gst-plugins-good.git] / gst / rtp / gstrtpj2kdepay.c
index f629419..132bcf5 100644 (file)
  * Boston, MA 02110-1301, USA.
  */
 
+
+ /**
+ * SECTION:element-rtpj2kdepay
+ * @title: rtpj2kdepay
+ *
+ * Depayload an RTP-payloaded JPEG 2000 image into RTP packets according to RFC 5371
+ * and RFC 5372.
+ * For detailed information see: https://datatracker.ietf.org/doc/rfc5371/
+ * and https://datatracker.ietf.org/doc/rfc5372/
+ */
+
+
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
@@ -25,6 +37,7 @@
 #include <gst/video/video.h>
 
 #include <string.h>
+#include "gstrtpj2kcommon.h"
 #include "gstrtpj2kdepay.h"
 #include "gstrtputils.h"
 
@@ -35,28 +48,24 @@ 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\";")
     );
 
-typedef enum
-{
-  J2K_MARKER = 0xFF,
-  J2K_MARKER_SOC = 0x4F,
-  J2K_MARKER_SOT = 0x90,
-  J2K_MARKER_SOP = 0x91,
-  J2K_MARKER_SOD = 0x93,
-  J2K_MARKER_EOC = 0xD9
-} RtpJ2KMarker;
-
 enum
 {
   PROP_0,
@@ -175,10 +184,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);
 
@@ -186,10 +197,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;
@@ -302,10 +338,10 @@ gst_rtp_j2k_depay_flush_tile (GstRTPBaseDepayload * depayload)
       if (map.size < 12)
         goto invalid_tile;
 
-      if (map.data[0] == 0xff && map.data[1] == J2K_MARKER_SOT) {
+      if (map.data[0] == GST_J2K_MARKER && map.data[1] == GST_J2K_MARKER_SOT) {
         guint Psot, nPsot;
 
-        if (end[0] == 0xff && end[1] == J2K_MARKER_EOC)
+        if (end[0] == GST_J2K_MARKER && end[1] == GST_J2K_MARKER_EOC)
           nPsot = avail - 2;
         else
           nPsot = avail;
@@ -380,9 +416,9 @@ gst_rtp_j2k_depay_flush_frame (GstRTPBaseDepayload * depayload)
      * marker */
     gst_adapter_copy (rtpj2kdepay->f_adapter, end, avail - 2, 2);
 
-    if (end[0] != 0xff && end[1] != 0xd9) {
-      end[0] = 0xff;
-      end[1] = 0xd9;
+    if (end[0] != GST_J2K_MARKER && end[1] != GST_J2K_MARKER_EOC) {
+      end[0] = GST_J2K_MARKER;
+      end[1] = GST_J2K_MARKER_EOC;
 
       GST_DEBUG_OBJECT (rtpj2kdepay, "no EOC marker, adding one");
 
@@ -396,8 +432,7 @@ gst_rtp_j2k_depay_flush_frame (GstRTPBaseDepayload * depayload)
 
     GST_DEBUG_OBJECT (rtpj2kdepay, "pushing buffer of %u bytes", avail);
     outbuf = gst_adapter_take_buffer (rtpj2kdepay->f_adapter, avail);
-    gst_rtp_drop_meta (GST_ELEMENT_CAST (depayload),
-        outbuf, g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
+    gst_rtp_drop_non_video_meta (depayload, outbuf);
     ret = gst_rtp_base_depayload_push (depayload, outbuf);
   } else {
     GST_WARNING_OBJECT (rtpj2kdepay, "empty packet");
@@ -433,7 +468,7 @@ gst_rtp_j2k_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
   payload_len = gst_rtp_buffer_get_payload_len (rtp);
 
   /* we need at least a header */
-  if (payload_len < 8)
+  if (payload_len < GST_RTP_J2K_HEADER_SIZE)
     goto empty_packet;
 
   rtptime = gst_rtp_buffer_get_timestamp (rtp);
@@ -464,7 +499,7 @@ gst_rtp_j2k_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
 
   tile = (payload[2] << 8) | payload[3];
   frag_offset = (payload[5] << 16) | (payload[6] << 8) | payload[7];
-  j2klen = payload_len - 8;
+  j2klen = payload_len - GST_RTP_J2K_HEADER_SIZE;
 
   GST_DEBUG_OBJECT (rtpj2kdepay, "MHF %u, tile %u, frag %u, expected %u", MHF,
       tile, frag_offset, rtpj2kdepay->next_frag);
@@ -481,19 +516,19 @@ gst_rtp_j2k_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
   }
 
   /* check for sync code */
-  if (j2klen > 2 && payload[8] == 0xff) {
-    guint marker = payload[9];
+  if (j2klen > 2 && payload[GST_RTP_J2K_HEADER_SIZE] == GST_J2K_MARKER) {
+    guint marker = payload[GST_RTP_J2K_HEADER_SIZE + 1];
 
     /* packets must start with SOC, SOT or SOP */
     switch (marker) {
-      case J2K_MARKER_SOC:
+      case GST_J2K_MARKER_SOC:
         GST_DEBUG_OBJECT (rtpj2kdepay, "found SOC packet");
         /* flush the previous frame, should have happened when the timestamp
          * changed above. */
         gst_rtp_j2k_depay_flush_frame (depayload);
         rtpj2kdepay->have_sync = TRUE;
         break;
-      case J2K_MARKER_SOT:
+      case GST_J2K_MARKER_SOT:
         /* flush the previous tile */
         gst_rtp_j2k_depay_flush_tile (depayload);
         GST_DEBUG_OBJECT (rtpj2kdepay, "found SOT packet");
@@ -501,7 +536,7 @@ gst_rtp_j2k_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
         /* we sync on the tile now */
         rtpj2kdepay->last_tile = tile;
         break;
-      case J2K_MARKER_SOP:
+      case GST_J2K_MARKER_SOP:
         GST_DEBUG_OBJECT (rtpj2kdepay, "found SOP packet");
         /* flush the previous PU */
         gst_rtp_j2k_depay_flush_pu (depayload);