gst/rtp/gstrtph264pay.*: Make it possible to specify profile-level-id and sprop-param...
authorPeter Kjellerstedt <pkj@axis.com>
Wed, 14 May 2008 17:58:50 +0000 (17:58 +0000)
committerPeter Kjellerstedt <pkj@axis.com>
Wed, 14 May 2008 17:58:50 +0000 (17:58 +0000)
Original commit message from CVS:
* gst/rtp/gstrtph264pay.c: (gst_rtp_h264_pay_class_init),
(gst_rtp_h264_pay_finalize), (gst_rtp_h264_pay_handle_buffer),
(gst_rtp_h264_pay_set_property), (gst_rtp_h264_pay_get_property):
* gst/rtp/gstrtph264pay.h:
Make it possible to specify profile-level-id and sprop-parameter-sets
using properties in case they are not available in-stream.

ChangeLog
common
gst/rtp/gstrtph264pay.c
gst/rtp/gstrtph264pay.h

index 106844d..13e2279 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-05-14  Peter Kjellerstedt  <pkj@axis.com>
+
+       * gst/rtp/gstrtph264pay.c: (gst_rtp_h264_pay_class_init),
+       (gst_rtp_h264_pay_finalize), (gst_rtp_h264_pay_handle_buffer),
+       (gst_rtp_h264_pay_set_property), (gst_rtp_h264_pay_get_property):
+       * gst/rtp/gstrtph264pay.h:
+       Make it possible to specify profile-level-id and sprop-parameter-sets
+       using properties in case they are not available in-stream.
+
 2008-05-14  Stefan Kost  <ensonic@users.sf.net>
 
        * docs/plugins/gst-plugins-good-plugins-docs.sgml:
diff --git a/common b/common
index 2d9c09d..d78efae 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 2d9c09df0fe4ad3f570fea9f649cfc6c4511080d
+Subproject commit d78efae300d4dff0291717ccf7a2b82c713a81ef
index 9938ed7..e5b3532 100644 (file)
@@ -64,11 +64,26 @@ GST_STATIC_PAD_TEMPLATE ("src",
         "clock-rate = (int) 90000, " "encoding-name = (string) \"H264\"")
     );
 
+#define DEFAULT_PROFILE_LEVEL_ID        NULL
+#define DEFAULT_SPROP_PARAMETER_SETS    NULL
+
+enum
+{
+  ARG_0,
+  ARG_PROFILE_LEVEL_ID,
+  ARG_SPROP_PARAMETER_SETS
+};
+
 static void gst_rtp_h264_pay_finalize (GObject * object);
 
 static GstStateChangeReturn gst_rtp_h264_pay_change_state (GstElement * element,
     GstStateChange transition);
 
+static void gst_rtp_h264_pay_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_rtp_h264_pay_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
 static gboolean gst_rtp_h264_pay_setcaps (GstBaseRTPPayload * basepayload,
     GstCaps * caps);
 static GstFlowReturn gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * pad,
@@ -101,6 +116,22 @@ gst_rtp_h264_pay_class_init (GstRtpH264PayClass * klass)
   gstelement_class = (GstElementClass *) klass;
   gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
 
+  gobject_class->set_property = gst_rtp_h264_pay_set_property;
+  gobject_class->get_property = gst_rtp_h264_pay_get_property;
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PROFILE_LEVEL_ID,
+      g_param_spec_string ("profile-level-id", "profile-level-id",
+          "The profile-level-id to set in out caps (set to NULL to extract from stream)",
+          DEFAULT_PROFILE_LEVEL_ID,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass),
+      ARG_SPROP_PARAMETER_SETS, g_param_spec_string ("sprop-parameter-sets",
+          "sprop-parameter-sets",
+          "The sprop-parameter-sets to set in out caps (set to NULL to extract from stream)",
+          DEFAULT_SPROP_PARAMETER_SETS,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gobject_class->finalize = gst_rtp_h264_pay_finalize;
 
   gstelement_class->change_state = gst_rtp_h264_pay_change_state;
@@ -127,10 +158,11 @@ gst_rtp_h264_pay_finalize (GObject * object)
 
   rtph264pay = GST_RTP_H264_PAY (object);
 
-  if (rtph264pay->sps)
-    g_free (rtph264pay->sps);
-  if (rtph264pay->pps)
-    g_free (rtph264pay->pps);
+  g_free (rtph264pay->sps);
+  g_free (rtph264pay->pps);
+
+  g_free (rtph264pay->profile_level_id);
+  g_free (rtph264pay->sprop_parameter_sets);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -574,9 +606,23 @@ gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * basepayload,
   pdata += 4;
   idxdata -= 4;
 
-  /* We know our stream is a valid H264 NAL packet, 
-   * go parse it for SPS/PPS to enrich the caps */
-  gst_rtp_h264_pay_parse_sps_pps (basepayload, pdata, idxdata);
+  if (rtph264pay->profile_level_id != NULL &&
+      rtph264pay->sprop_parameter_sets != NULL) {
+    if (rtph264pay->update_caps) {
+      gst_basertppayload_set_outcaps (basepayload, "profile-level-id",
+          G_TYPE_STRING, rtph264pay->profile_level_id, "sprop-parameter-sets",
+          G_TYPE_STRING, rtph264pay->sprop_parameter_sets, NULL);
+      rtph264pay->update_caps = FALSE;
+
+      GST_DEBUG
+          ("outcaps udpate: profile-level-id=%s, sprop-parameter-sets=%s\n",
+          rtph264pay->profile_level_id, rtph264pay->sprop_parameter_sets);
+    }
+  } else {
+    /* We know our stream is a valid H264 NAL packet,
+     * go parse it for SPS/PPS to enrich the caps */
+    gst_rtp_h264_pay_parse_sps_pps (basepayload, pdata, idxdata);
+  }
 
   nalType = pdata[0] & 0x1f;
   GST_DEBUG_OBJECT (basepayload, "Processing Buffer with NAL TYPE=%d", nalType);
@@ -698,6 +744,48 @@ gst_rtp_h264_pay_change_state (GstElement * element, GstStateChange transition)
   return ret;
 }
 
+static void
+gst_rtp_h264_pay_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstRtpH264Pay *rtph264pay;
+
+  rtph264pay = GST_RTP_H264_PAY (object);
+
+  switch (prop_id) {
+    case ARG_PROFILE_LEVEL_ID:
+      rtph264pay->profile_level_id = g_value_dup_string (value);
+      rtph264pay->update_caps = TRUE;
+      break;
+    case ARG_SPROP_PARAMETER_SETS:
+      rtph264pay->sprop_parameter_sets = g_value_dup_string (value);
+      rtph264pay->update_caps = TRUE;
+      break;
+    default:
+      break;
+  }
+}
+
+static void
+gst_rtp_h264_pay_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstRtpH264Pay *rtph264pay;
+
+  rtph264pay = GST_RTP_H264_PAY (object);
+
+  switch (prop_id) {
+    case ARG_PROFILE_LEVEL_ID:
+      g_value_set_string (value, rtph264pay->profile_level_id);
+      break;
+    case ARG_SPROP_PARAMETER_SETS:
+      g_value_set_string (value, rtph264pay->sprop_parameter_sets);
+      break;
+    default:
+      break;
+  }
+}
+
 gboolean
 gst_rtp_h264_pay_plugin_init (GstPlugin * plugin)
 {
index d5615e5..b0ac096 100644 (file)
@@ -49,6 +49,10 @@ struct _GstRtpH264Pay
 
   gboolean packetized;
   guint nal_length_size;
+
+  gchar *profile_level_id;
+  gchar *sprop_parameter_sets;
+  gboolean update_caps;
 };
 
 struct _GstRtpH264PayClass