rtph264depay: determine output h264 layout using caps negotiation
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 17 Dec 2010 14:38:15 +0000 (15:38 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 17 Dec 2010 14:38:27 +0000 (15:38 +0100)
... thereby (partially) deprecating properties currently controlling whether
or not byte-stream output or NAL/AU alignment (though properties still determine
fallback if nothing specified in caps).

Fixes #606662.

gst/rtp/gstrtph264depay.c

index 915c9fd..dc333ba 100644 (file)
@@ -130,12 +130,12 @@ gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass)
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BYTE_STREAM,
       g_param_spec_boolean ("byte-stream", "Byte Stream",
-          "Generate byte stream format of NALU", DEFAULT_BYTE_STREAM,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+          "Generate byte stream format of NALU (deprecated; use caps)",
+          DEFAULT_BYTE_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ACCESS_UNIT,
       g_param_spec_boolean ("access-unit", "Access Unit",
-          "Merge NALU into AU (picture)", DEFAULT_ACCESS_UNIT,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+          "Merge NALU into AU (picture) (deprecated; use caps)",
+          DEFAULT_ACCESS_UNIT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   gstelement_class->change_state = gst_rtp_h264_depay_change_state;
 
@@ -214,6 +214,65 @@ gst_rtp_h264_depay_get_property (GObject * object, guint prop_id,
   }
 }
 
+static void
+gst_rtp_h264_depay_negotiate (GstRtpH264Depay * rtph264depay)
+{
+  GstCaps *caps;
+  gint byte_stream = -1;
+  gint merge = -1;
+
+  caps =
+      gst_pad_get_allowed_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (rtph264depay));
+
+  GST_DEBUG_OBJECT (rtph264depay, "allowed caps: %" GST_PTR_FORMAT, caps);
+
+  if (caps) {
+    if (gst_caps_get_size (caps) > 0) {
+      GstStructure *s = gst_caps_get_structure (caps, 0);
+      const gchar *str = NULL;
+
+      if ((str = gst_structure_get_string (s, "stream-format"))) {
+        if (strcmp (str, "avc") == 0) {
+          byte_stream = FALSE;
+        } else if (strcmp (str, "byte-stream") == 0) {
+          byte_stream = TRUE;
+        } else {
+          GST_DEBUG_OBJECT (rtph264depay, "unknown stream-format: %s", str);
+        }
+      }
+
+      if ((str = gst_structure_get_string (s, "alignment"))) {
+        if (strcmp (str, "au") == 0) {
+          merge = TRUE;
+        } else if (strcmp (str, "nal") == 0) {
+          merge = FALSE;
+        } else {
+          GST_DEBUG_OBJECT (rtph264depay, "unknown alignment: %s", str);
+        }
+      }
+    }
+    gst_caps_unref (caps);
+  }
+
+  if (byte_stream >= 0) {
+    GST_DEBUG_OBJECT (rtph264depay, "downstream requires byte-stream %d",
+        byte_stream);
+    if (rtph264depay->byte_stream != byte_stream) {
+      GST_WARNING_OBJECT (rtph264depay,
+          "overriding property setting based on caps");
+      rtph264depay->byte_stream = byte_stream;
+    }
+  }
+  if (merge >= 0) {
+    GST_DEBUG_OBJECT (rtph264depay, "downstream requires merge %d", merge);
+    if (rtph264depay->merge != merge) {
+      GST_WARNING_OBJECT (rtph264depay,
+          "overriding property setting based on caps");
+      rtph264depay->merge = merge;
+    }
+  }
+}
+
 static gboolean
 gst_rtp_h264_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
 {
@@ -239,6 +298,9 @@ gst_rtp_h264_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
   /* hex: AVCProfileIndication:8 | profile_compat:8 | AVCLevelIndication:8 */
   profile = gst_structure_get_string (structure, "profile-level-id");
 
+  /* negotiate with downstream w.r.t. output format and alignment */
+  gst_rtp_h264_depay_negotiate (rtph264depay);
+
   if (rtph264depay->byte_stream && ps != NULL) {
     /* for bytestream we only need the parameter sets but we don't error out
      * when they are not there, we assume they are in the stream. */
@@ -385,6 +447,10 @@ gst_rtp_h264_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
         "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
   }
 
+  gst_caps_set_simple (srccaps, "stream-format", G_TYPE_STRING,
+      rtph264depay->byte_stream ? "byte-stream" : "avc",
+      "alignment", G_TYPE_STRING, rtph264depay->merge ? "au" : "nal", NULL);
+
   res = gst_pad_set_caps (depayload->srcpad, srccaps);
   gst_caps_unref (srccaps);