/** * gst_codec_utils_h265_caps_set_level_tier_and_profile: * @caps: the #GstCaps to which the level, tier and profile are to be added * @profile_tier_level: Pointer to the profile_tier_level struct * @len: Length of the data available in @profile_tier_level. * * Sets the level, tier and profile in @caps if it can be determined from * @profile_tier_level. See gst_codec_utils_h265_get_level(), * gst_codec_utils_h265_get_tier() and gst_codec_utils_h265_get_profile() * for more details on the parameters. * * Returns: %TRUE if the level, tier, profile could be set, %FALSE otherwise. * * Since 1.4 */ gboolean gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps, const guint8 * profile_tier_level, guint len) { const gchar *level, *tier, *profile; g_return_val_if_fail (GST_IS_CAPS (caps), FALSE); g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE); g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h265"), FALSE); g_return_val_if_fail (profile_tier_level != NULL, FALSE); level = gst_codec_utils_h265_get_level (profile_tier_level, len); if (level != NULL) gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL); tier = gst_codec_utils_h265_get_tier (profile_tier_level, len); if (tier != NULL) gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL); profile = gst_codec_utils_h265_get_profile (profile_tier_level, len); if (profile != NULL) gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL); GST_LOG ("profile : %s", (profile) ? profile : "---"); GST_LOG ("tier : %s", (tier) ? tier : "---"); GST_LOG ("level : %s", (level) ? level : "---"); return (level != NULL && tier != NULL && profile != NULL); }
static GstCaps * gst_rtp_h265_pay_getcaps (GstRTPBasePayload * payload, GstPad * pad, GstCaps * filter) { GstCaps *template_caps; GstCaps *allowed_caps; GstCaps *caps; GstCaps *icaps; gboolean append_unrestricted; guint i; allowed_caps = gst_pad_peer_query_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload), NULL); if (allowed_caps == NULL) return NULL; template_caps = gst_static_pad_template_get_caps (&gst_rtp_h265_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)) { caps = gst_caps_ref (allowed_caps); goto done; } caps = gst_caps_new_empty (); append_unrestricted = FALSE; 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_empty ("video/x-h265"); const gchar *profile_level_id; profile_level_id = gst_structure_get_string (s, "profile-level-id"); if (profile_level_id && strlen (profile_level_id) == 6) { /* Code taken from gstrtph264pay.c, needs to be revised for H.265 */ 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; profile = gst_codec_utils_h265_get_profile (sps, 3); level = gst_codec_utils_h265_get_level (sps, 3); if (profile && level) { GST_LOG_OBJECT (payload, "In caps, have profile %s and level %s", profile, level); if (!strcmp (profile, "main")) 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_set_static_string (&val, profile); gst_value_list_append_value (&profiles, &val); g_value_set_static_string (&val, "main"); gst_value_list_append_value (&profiles, &val); 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; j < G_N_ELEMENTS (all_levels); 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); } } else { /* Invalid profile-level-id means main */ gst_structure_set (new_s, "profile", G_TYPE_STRING, "main", NULL); } } else { /* No profile-level-id means main or unrestricted */ gst_structure_set (new_s, "profile", G_TYPE_STRING, "main", NULL); append_unrestricted = TRUE; } caps = gst_caps_merge_structure (caps, new_s); }