diff --git a/gst/rtp/gstrtph264depay.c b/gst/rtp/gstrtph264depay.c index 915c9fdf11..dc333ba8d4 100644 --- a/gst/rtp/gstrtph264depay.c +++ b/gst/rtp/gstrtph264depay.c @@ -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);