rtph264depay: determine output h264 layout using caps negotiation

... 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.
This commit is contained in:
Mark Nauwelaerts 2010-12-17 15:38:15 +01:00
parent b87ec0262b
commit 4c368242c0

View 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_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BYTE_STREAM,
g_param_spec_boolean ("byte-stream", "Byte Stream", g_param_spec_boolean ("byte-stream", "Byte Stream",
"Generate byte stream format of NALU", DEFAULT_BYTE_STREAM, "Generate byte stream format of NALU (deprecated; use caps)",
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); DEFAULT_BYTE_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ACCESS_UNIT, g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ACCESS_UNIT,
g_param_spec_boolean ("access-unit", "Access Unit", g_param_spec_boolean ("access-unit", "Access Unit",
"Merge NALU into AU (picture)", DEFAULT_ACCESS_UNIT, "Merge NALU into AU (picture) (deprecated; use caps)",
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); DEFAULT_ACCESS_UNIT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstelement_class->change_state = gst_rtp_h264_depay_change_state; 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 static gboolean
gst_rtp_h264_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) 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 */ /* hex: AVCProfileIndication:8 | profile_compat:8 | AVCLevelIndication:8 */
profile = gst_structure_get_string (structure, "profile-level-id"); 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) { if (rtph264depay->byte_stream && ps != NULL) {
/* for bytestream we only need the parameter sets but we don't error out /* 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. */ * 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); "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); res = gst_pad_set_caps (depayload->srcpad, srccaps);
gst_caps_unref (srccaps); gst_caps_unref (srccaps);