diff options
author | Tim-Philipp Müller <tim.muller@collabora.co.uk> | 2012-02-08 23:03:28 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim.muller@collabora.co.uk> | 2012-02-10 14:08:55 +0000 |
commit | 5b25f3737b488c3ddd7f5c2d4f9bd68a46e44da7 (patch) | |
tree | d8e6ccb8a612db7d437043b498fad12e83131c2e /gst | |
parent | 6872b408730fd4eaacbb26fca79ebfb3f204e761 (diff) |
rtph264pay: add stream-format and alignment to h264 sink caps
We're happy to accept both byte-stream and avc, advertise
that on the sink caps and fix up _get_caps() function to
not just return "video/x-h264".
https://bugzilla.gnome.org/show_bug.cgi?id=606662
Diffstat (limited to 'gst')
-rw-r--r-- | gst/rtp/gstrtph264pay.c | 149 |
1 files changed, 82 insertions, 67 deletions
diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c index b648f0847..9f5006edc 100644 --- a/gst/rtp/gstrtph264pay.c +++ b/gst/rtp/gstrtph264pay.c @@ -45,10 +45,13 @@ GST_DEBUG_CATEGORY_STATIC (rtph264pay_debug); */ static GstStaticPadTemplate gst_rtp_h264_pay_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", + GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-h264") + GST_STATIC_CAPS ("video/x-h264, " + "stream-format = (string) byte-stream, alignment = (string) { nal, au };" + "video/x-h264, " + "stream-format = (string) avc, alignment = (string) au") ); static GstStaticPadTemplate gst_rtp_h264_pay_src_template = @@ -271,98 +274,110 @@ static const gchar *all_levels[] = { static GstCaps * gst_rtp_h264_pay_getcaps (GstBaseRTPPayload * payload, GstPad * pad) { + GstCaps *template_caps; GstCaps *allowed_caps; + GstCaps *caps, *icaps; + guint i; allowed_caps = gst_pad_peer_get_caps_reffed (GST_BASE_RTP_PAYLOAD_SRCPAD (payload)); - if (allowed_caps) { - GstCaps *caps = NULL; - guint i; + if (allowed_caps == NULL) + return NULL; - if (gst_caps_is_any (allowed_caps)) { - gst_caps_unref (allowed_caps); - goto any; - } + template_caps = + gst_static_pad_template_get_caps (&gst_rtp_h264_pay_sink_template); + + if (gst_caps_is_any (allowed_caps)) { + caps = gst_caps_ref (template_caps); + goto done; + } - if (gst_caps_is_empty (allowed_caps)) - return allowed_caps; + if (gst_caps_is_empty (allowed_caps)) { + caps = gst_caps_ref (allowed_caps); + goto done; + } - caps = gst_caps_new_empty (); + caps = gst_caps_new_empty (); - for (i = 0; i < gst_caps_get_size (allowed_caps); i++) { - GstStructure *s = gst_caps_get_structure (allowed_caps, i); - GstStructure *new_s = gst_structure_new ("video/x-h264", NULL); - const gchar *profile_level_id; + for (i = 0; i < gst_caps_get_size (allowed_caps); i++) { + GstStructure *s = gst_caps_get_structure (allowed_caps, i); + GstStructure *new_s = gst_structure_new ("video/x-h264", NULL); + const gchar *profile_level_id; - profile_level_id = gst_structure_get_string (s, "profile-level-id"); + profile_level_id = gst_structure_get_string (s, "profile-level-id"); - if (profile_level_id && strlen (profile_level_id) == 6) { - const gchar *profile; - const gchar *level; - long int spsint; - guint8 sps[3]; + if (profile_level_id && strlen (profile_level_id) == 6) { + const gchar *profile; + const gchar *level; + long int spsint; + guint8 sps[3]; - spsint = strtol (profile_level_id, NULL, 16); - sps[0] = spsint >> 16; - sps[1] = spsint >> 8; - sps[2] = spsint; + spsint = strtol (profile_level_id, NULL, 16); + sps[0] = spsint >> 16; + sps[1] = spsint >> 8; + sps[2] = spsint; - profile = gst_codec_utils_h264_get_profile (sps, 3); - level = gst_codec_utils_h264_get_level (sps, 3); + profile = gst_codec_utils_h264_get_profile (sps, 3); + level = gst_codec_utils_h264_get_level (sps, 3); - if (profile && level) { - GST_LOG_OBJECT (payload, "In caps, have profile %s and level %s", - profile, level); + if (profile && level) { + GST_LOG_OBJECT (payload, "In caps, have profile %s and level %s", + profile, level); - if (!strcmp (profile, "constrained-baseline")) - gst_structure_set (new_s, "profile", G_TYPE_STRING, profile, NULL); - else { - GValue val = { 0, }; - GValue profiles = { 0, }; + if (!strcmp (profile, "constrained-baseline")) + gst_structure_set (new_s, "profile", G_TYPE_STRING, profile, NULL); + else { + GValue val = { 0, }; + GValue profiles = { 0, }; - g_value_init (&profiles, GST_TYPE_LIST); - g_value_init (&val, G_TYPE_STRING); + g_value_init (&profiles, GST_TYPE_LIST); + g_value_init (&val, G_TYPE_STRING); - g_value_set_static_string (&val, profile); - gst_value_list_append_value (&profiles, &val); + g_value_set_static_string (&val, profile); + gst_value_list_append_value (&profiles, &val); - g_value_set_static_string (&val, "constrained-baseline"); - gst_value_list_append_value (&profiles, &val); + g_value_set_static_string (&val, "constrained-baseline"); + gst_value_list_append_value (&profiles, &val); - gst_structure_take_value (new_s, "profile", &profiles); - } + gst_structure_take_value (new_s, "profile", &profiles); + } - if (!strcmp (level, "1")) - gst_structure_set (new_s, "level", G_TYPE_STRING, level, NULL); - else { - GValue levels = { 0, }; - GValue val = { 0, }; - int j; - - g_value_init (&levels, GST_TYPE_LIST); - g_value_init (&val, G_TYPE_STRING); - - for (j = 0; all_levels[j]; j++) { - g_value_set_static_string (&val, all_levels[j]); - gst_value_list_prepend_value (&levels, &val); - if (!strcmp (level, all_levels[j])) - break; - } - gst_structure_take_value (new_s, "level", &levels); + if (!strcmp (level, "1")) + gst_structure_set (new_s, "level", G_TYPE_STRING, level, NULL); + else { + GValue levels = { 0, }; + GValue val = { 0, }; + int j; + + g_value_init (&levels, GST_TYPE_LIST); + g_value_init (&val, G_TYPE_STRING); + + for (j = 0; all_levels[j]; j++) { + g_value_set_static_string (&val, all_levels[j]); + gst_value_list_prepend_value (&levels, &val); + if (!strcmp (level, all_levels[j])) + break; } + gst_structure_take_value (new_s, "level", &levels); } } - - gst_caps_merge_structure (caps, new_s); } - gst_caps_unref (allowed_caps); - return caps; + gst_caps_merge_structure (caps, new_s); } -any: - return gst_caps_new_simple ("video/x-h264", NULL); + icaps = gst_caps_intersect (caps, template_caps); + gst_caps_unref (caps); + caps = icaps; + +done: + + gst_caps_unref (template_caps); + gst_caps_unref (allowed_caps); + + GST_LOG_OBJECT (payload, "returning caps %" GST_PTR_FORMAT, caps); + return caps; } /* take the currently configured SPS and PPS lists and set them on the caps as |