gboolean rb_gst_media_type_matches_profile (GstEncodingProfile *profile, const char *media_type) { const GstCaps *pcaps; const GList *cl; GstCaps *caps; gboolean matches = FALSE; caps = rb_gst_media_type_to_caps (media_type); if (caps == NULL) { return FALSE; } pcaps = gst_encoding_profile_get_format (profile); if (gst_caps_can_intersect (caps, pcaps)) { matches = TRUE; } if (matches == FALSE && GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { for (cl = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile)); cl != NULL; cl = cl->next) { GstEncodingProfile *cp = cl->data; pcaps = gst_encoding_profile_get_format (cp); if (gst_caps_can_intersect (caps, pcaps)) { matches = TRUE; break; } } } return matches; }
static void print_profile (GUPnPDLNAProfile *profile, gpointer unused) { GstEncodingProfile *enc_profile; const GList *tmp; gchar *caps_str; enc_profile = gupnp_dlna_profile_get_encoding_profile (profile); tmp = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (enc_profile)); g_print ("%s %-30s%-35s", gupnp_dlna_profile_get_extended (profile) ? "*" : " ", gupnp_dlna_profile_get_name (profile), gupnp_dlna_profile_get_mime (profile)); if (verbose) { caps_str = gst_caps_to_string (gst_encoding_profile_get_format (enc_profile)); g_print ("\n`- container: %s\n", caps_str); g_free (caps_str); while (tmp) { print_caps (gst_encoding_profile_get_format (GST_ENCODING_PROFILE (tmp->data))); tmp = tmp->next; } } g_print ("\n"); gst_encoding_profile_unref (enc_profile); }
static gboolean check_container (GstDiscovererInfo *info, GstEncodingProfile *profile) { GstDiscovererStreamInfo *stream_info; GType stream_type; GstCaps *stream_caps; gboolean ret = FALSE; const GstCaps *profile_caps = gst_encoding_profile_get_format (profile); /* Top-level GstStreamInformation in the topology will be * the container */ stream_info = gst_discoverer_info_get_stream_info (info); stream_caps = gst_discoverer_stream_info_get_caps (stream_info); stream_type = G_TYPE_FROM_INSTANCE (stream_info); if (stream_type == GST_TYPE_DISCOVERER_CONTAINER_INFO && gst_caps_can_intersect (stream_caps, profile_caps)) ret = TRUE; else if (stream_type != GST_TYPE_DISCOVERER_CONTAINER_INFO && gst_caps_is_empty (profile_caps)) ret = TRUE; gst_discoverer_stream_info_unref (stream_info); gst_caps_unref (stream_caps); return ret; }
static gboolean match_profile (GstEncodingProfile *profile, GstCaps *caps, GType type) { const GList *i, *profiles_list; const gchar *name; /* Profiles with an empty name are used only for inheritance and should * not be matched against. */ name = gst_encoding_profile_get_name (profile); if (name[0] == '\0') return FALSE; profiles_list = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile)); for (i = profiles_list; i; i = i->next){ GstEncodingProfile *enc_profile = GST_ENCODING_PROFILE (i->data); const GstCaps *format = gst_encoding_profile_get_format (enc_profile); if (type == G_TYPE_FROM_INSTANCE (enc_profile) && caps_can_intersect_and_is_subset (caps, format)) return TRUE; } return FALSE; }
/* Serialize the top-level profiles * Note: They don't have to be containerprofiles */ static gboolean serialize_encoding_profile (GKeyFile * out, GstEncodingProfile * prof) { gchar *profgroupname; const GList *tmp; guint i; const gchar *profname, *profdesc, *profpreset, *proftype; GstCaps *profformat; profname = gst_encoding_profile_get_name (prof); profdesc = gst_encoding_profile_get_description (prof); profformat = gst_encoding_profile_get_format (prof); profpreset = gst_encoding_profile_get_preset (prof); proftype = gst_encoding_profile_get_type_nick (prof); profgroupname = g_strdup_printf ("profile-%s", profname); g_key_file_set_string (out, profgroupname, "name", profname); g_key_file_set_value (out, profgroupname, "type", proftype); if (profdesc) { gchar *locale; locale = get_locale (); if (locale != NULL) { g_key_file_set_locale_string (out, profgroupname, "description", locale, profdesc); g_free (locale); } else { g_key_file_set_string (out, profgroupname, "description", profdesc); } } if (profformat) { gchar *tmpc = gst_caps_to_string (profformat); g_key_file_set_string (out, profgroupname, "format", tmpc); g_free (tmpc); } if (profpreset) g_key_file_set_string (out, profgroupname, "preset", profpreset); /* stream profiles */ if (GST_IS_ENCODING_CONTAINER_PROFILE (prof)) { for (tmp = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (prof)), i = 0; tmp; tmp = tmp->next, i++) { GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data; if (!serialize_stream_profiles (out, sprof, profname, i)) return FALSE; } } if (profformat) gst_caps_unref (profformat); g_free (profgroupname); return TRUE; }
char *encoding_profile_get_media_type(GstEncodingProfile *profile) { if (GST_IS_ENCODING_CONTAINER_PROFILE(profile)) { const GList *cl = gst_encoding_container_profile_get_profiles(GST_ENCODING_CONTAINER_PROFILE(profile)); for (; cl != NULL; cl = cl->next) { GstEncodingProfile *p = cl->data; if (GST_IS_ENCODING_AUDIO_PROFILE(p)) { return caps_to_media_type(gst_encoding_profile_get_format(p)); } } /* now what? */ return NULL; } else { return caps_to_media_type(gst_encoding_profile_get_format(profile)); } }
static gboolean gst_encoding_profile_has_format (GstEncodingProfile * profile, const gchar * media_type) { GstCaps *caps; gboolean ret; g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE); caps = gst_encoding_profile_get_format (profile); ret = gst_structure_has_name (gst_caps_get_structure (caps, 0), media_type); gst_caps_unref (caps); return ret; }
void rygel_gst_utils_dump_encoding_profile (GstEncodingProfile *profile, gint indent) { gchar *indent_s; const GstCaps *caps; gchar *format_name; const GstCaps *restriction; g_return_if_fail (profile != NULL); indent_s = g_strnfill ((gsize) indent, ' '); g_debug ("%s%s:", indent_s, gst_encoding_profile_get_name (profile)); caps = gst_encoding_profile_get_format (profile); format_name = gst_caps_to_string (caps); g_debug ("%s Format: %s", indent_s, format_name); g_free (format_name); restriction = gst_encoding_profile_get_restriction (profile); if (restriction) { gchar *restriction_name = gst_caps_to_string (restriction); g_debug ("%s Restriction: %s", indent_s, restriction_name); g_free (restriction_name); } if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { GstEncodingContainerProfile *container = GST_ENCODING_CONTAINER_PROFILE (profile); const GList *subprofile_collection = gst_encoding_container_profile_get_profiles (container); const GList *subprofile_it; for (subprofile_it = subprofile_collection; subprofile_it != NULL; subprofile_it = subprofile_it->next) { GstEncodingProfile *subprofile = GST_ENCODING_PROFILE (subprofile_it->data); rygel_gst_utils_dump_encoding_profile (subprofile, indent + 4); } } g_free (indent_s); }
static GstElementFactory * get_audio_encoder_factory (GstEncodingProfile *profile) { GstEncodingProfile *p = get_audio_encoding_profile (profile); GstElementFactory *f; GList *l; GList *fl; if (p == NULL) return NULL; l = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER, GST_RANK_MARGINAL); fl = gst_element_factory_list_filter (l, gst_encoding_profile_get_format (p), GST_PAD_SRC, FALSE); if (fl != NULL) { f = gst_object_ref (fl->data); } else { g_warning ("no encoder factory for profile %s", gst_encoding_profile_get_name (p)); f = NULL; } gst_plugin_feature_list_free (l); gst_plugin_feature_list_free (fl); return f; }
static gboolean compare_encoding_profile_with_discoverer_stream (GstValidateFileChecker * fc, GstEncodingProfile * prof, GstDiscovererStreamInfo * stream, gchar ** msg) { gboolean ret = TRUE; GstCaps *caps = NULL; const GstCaps *profile_caps; const GstCaps *restriction_caps; caps = gst_discoverer_stream_info_get_caps (stream); profile_caps = gst_encoding_profile_get_format (prof); restriction_caps = gst_encoding_profile_get_restriction (prof); /* TODO need to consider profile caps restrictions */ if (!_gst_caps_can_intersect_safe (caps, profile_caps)) { gchar *caps_str = gst_caps_to_string (caps); gchar *profile_caps_str = gst_caps_to_string (profile_caps); SET_MESSAGE (msg, g_strdup_printf ("Caps '%s' didn't match profile '%s'", profile_caps_str, caps_str)); g_free (caps_str); g_free (profile_caps_str); ret = FALSE; goto end; } if (restriction_caps) { GstStructure *structure; gint i; gboolean found = FALSE; for (i = 0; i < gst_caps_get_size (restriction_caps); i++) { structure = gst_caps_get_structure (restriction_caps, i); structure = gst_structure_copy (structure); gst_structure_set_name (structure, gst_structure_get_name (gst_caps_get_structure (caps, 0))); if (gst_structure_can_intersect (structure, gst_caps_get_structure (caps, 0))) { gst_structure_free (structure); found = TRUE; break; } gst_structure_free (structure); } if (!found) { gchar *caps_str = gst_caps_to_string (caps); gchar *restriction_caps_str = gst_caps_to_string (restriction_caps); SET_MESSAGE (msg, g_strdup_printf ("Caps restriction '%s' wasn't respected on file " "with caps '%s'", restriction_caps_str, caps_str)); g_free (caps_str); g_free (restriction_caps_str); ret = FALSE; goto end; } } if (GST_IS_ENCODING_CONTAINER_PROFILE (prof)) { if (GST_IS_DISCOVERER_CONTAINER_INFO (stream)) { ret = ret & compare_container_profile_with_container_discoverer_stream (fc, (GstEncodingContainerProfile *) prof, (GstDiscovererContainerInfo *) stream, msg); } else { SET_MESSAGE (msg, g_strdup_printf ("Expected container profile but found stream of %s", gst_discoverer_stream_info_get_stream_type_nick (stream))); ret = FALSE; goto end; } } else if (GST_IS_ENCODING_VIDEO_PROFILE (prof)) { if (!GST_IS_DISCOVERER_VIDEO_INFO (stream)) { SET_MESSAGE (msg, g_strdup_printf ("Expected video profile but found stream of %s", gst_discoverer_stream_info_get_stream_type_nick (stream))); ret = FALSE; goto end; } } else if (GST_IS_ENCODING_AUDIO_PROFILE (prof)) { if (!GST_IS_DISCOVERER_AUDIO_INFO (stream)) { SET_MESSAGE (msg, g_strdup_printf ("Expected audio profile but found stream of %s", gst_discoverer_stream_info_get_stream_type_nick (stream))); ret = FALSE; goto end; } } else { g_assert_not_reached (); return FALSE; } end: if (caps) gst_caps_unref (caps); return ret; }
static gboolean compare_container_profile_with_container_discoverer_stream (GstValidateFileChecker * fc, GstEncodingContainerProfile * prof, GstDiscovererContainerInfo * stream, gchar ** msg) { ExpectedStream *expected_streams = NULL; GList *container_streams; const GList *profile_iter; const GList *streams_iter; gint i; gint expected_count = g_list_length ((GList *) gst_encoding_container_profile_get_profiles (prof)); gboolean ret = TRUE; container_streams = gst_discoverer_container_info_get_streams (stream); if (expected_count == 0) { if (g_list_length (container_streams) != 0) { SET_MESSAGE (msg, g_strdup_printf ("No streams expected on this container, but found %u", g_list_length (container_streams))); ret = FALSE; goto end; } } /* initialize expected streams data */ expected_streams = g_malloc0 (sizeof (ExpectedStream) * expected_count); for (i = 0, profile_iter = gst_encoding_container_profile_get_profiles (prof); profile_iter; profile_iter = g_list_next (profile_iter), i++) { GstEncodingProfile *prof = profile_iter->data; ExpectedStream *expected = &(expected_streams[i]); expected->profile = prof; } /* look for the streams on discoverer info */ for (streams_iter = container_streams; streams_iter; streams_iter = g_list_next (streams_iter)) { GstDiscovererStreamInfo *info = streams_iter->data; gboolean found = FALSE; for (i = 0; i < expected_count; i++) { ExpectedStream *expected = &(expected_streams[i]); if (compare_encoding_profile_with_discoverer_stream (fc, expected->profile, info, NULL)) { found = TRUE; break; } } if (!found) { GstCaps *caps = gst_discoverer_stream_info_get_caps (info); gchar *caps_str = gst_caps_to_string (caps); SET_MESSAGE (msg, g_strdup_printf ("Stream with caps '%s' wasn't found on file", caps_str)); g_free (caps_str); gst_caps_unref (caps); ret = FALSE; goto end; } } /* check if all expected streams are present */ for (i = 0; i < expected_count; i++) { ExpectedStream *expected = &(expected_streams[i]); guint presence = gst_encoding_profile_get_presence (expected->profile); if (presence == 0) continue; if (presence != expected->count) { gchar *caps_str = gst_caps_to_string (gst_encoding_profile_get_format (expected->profile)); SET_MESSAGE (msg, g_strdup_printf ("Stream from profile %s (with caps '%s" "' has presence %u but the number of streams found was %d", gst_encoding_profile_get_name (expected->profile), caps_str, presence, expected->count)); g_free (caps_str); ret = FALSE; goto end; } } end: g_free (expected_streams); gst_discoverer_stream_info_list_free (container_streams); return ret; }
static gboolean serialize_stream_profiles (GKeyFile * out, GstEncodingProfile * sprof, const gchar * profilename, guint id) { gchar *sprofgroupname; gchar *tmpc; GstCaps *format, *restriction; const gchar *preset, *name, *description; sprofgroupname = g_strdup_printf ("streamprofile-%s-%d", profilename, id); /* Write the parent profile */ g_key_file_set_value (out, sprofgroupname, "parent", profilename); g_key_file_set_value (out, sprofgroupname, "type", gst_encoding_profile_get_type_nick (sprof)); format = gst_encoding_profile_get_format (sprof); if (format) { tmpc = gst_caps_to_string (format); g_key_file_set_value (out, sprofgroupname, "format", tmpc); g_free (tmpc); } name = gst_encoding_profile_get_name (sprof); if (name) g_key_file_set_string (out, sprofgroupname, "name", name); description = gst_encoding_profile_get_description (sprof); if (description) g_key_file_set_string (out, sprofgroupname, "description", description); preset = gst_encoding_profile_get_preset (sprof); if (preset) g_key_file_set_string (out, sprofgroupname, "preset", preset); restriction = gst_encoding_profile_get_restriction (sprof); if (restriction) { tmpc = gst_caps_to_string (restriction); g_key_file_set_value (out, sprofgroupname, "restriction", tmpc); g_free (tmpc); } g_key_file_set_integer (out, sprofgroupname, "presence", gst_encoding_profile_get_presence (sprof)); if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) { GstEncodingVideoProfile *vp = (GstEncodingVideoProfile *) sprof; g_key_file_set_integer (out, sprofgroupname, "pass", gst_encoding_video_profile_get_pass (vp)); g_key_file_set_boolean (out, sprofgroupname, "variableframerate", gst_encoding_video_profile_get_variableframerate (vp)); } g_free (sprofgroupname); if (format) gst_caps_unref (format); if (restriction) gst_caps_unref (restriction); return TRUE; }
/** * gst_encoding_profile_get_file_extension: * @profile: a #GstEncodingProfile * * Returns: a suitable file extension for @profile, or NULL. */ const gchar * gst_encoding_profile_get_file_extension (GstEncodingProfile * profile) { GstEncodingContainerProfile *cprofile; const gchar *ext = NULL; gboolean has_video; GstCaps *caps; guint num_children; g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), NULL); caps = gst_encoding_profile_get_format (profile); ext = pb_utils_get_file_extension_from_caps (caps); if (!GST_IS_ENCODING_CONTAINER_PROFILE (profile)) goto done; cprofile = GST_ENCODING_CONTAINER_PROFILE (profile); num_children = g_list_length (cprofile->encodingprofiles); /* if it's a tag container profile (e.g. id3mux/apemux), we need * to look at what's inside it */ if (pb_utils_is_tag (caps)) { GST_DEBUG ("tag container profile"); if (num_children == 1) { GstEncodingProfile *child_profile = cprofile->encodingprofiles->data; ext = gst_encoding_profile_get_file_extension (child_profile); } else { GST_WARNING ("expected exactly one child profile with tag profile"); } goto done; } if (num_children == 0) goto done; /* special cases */ has_video = gst_encoding_container_profile_has_video (cprofile); /* Ogg */ if (strcmp (ext, "ogg") == 0) { /* ogg with video => .ogv */ if (has_video) { ext = "ogv"; goto done; } /* ogg with just speex audio => .spx */ if (num_children == 1) { GstEncodingProfile *child_profile = cprofile->encodingprofiles->data; if (GST_IS_ENCODING_AUDIO_PROFILE (child_profile) && gst_encoding_profile_has_format (child_profile, "audio/x-speex")) { ext = "spx"; goto done; } } /* does anyone actually use .oga for ogg audio files? */ goto done; } /* Matroska */ if (has_video && strcmp (ext, "mka") == 0) { ext = "mkv"; goto done; } /* Windows Media / ASF */ if (gst_encoding_profile_has_format (profile, "video/x-ms-asf")) { const GList *l; guint num_wmv = 0, num_wma = 0, num_other = 0; for (l = cprofile->encodingprofiles; l != NULL; l = l->next) { if (gst_encoding_profile_has_format (l->data, "video/x-wmv")) ++num_wmv; else if (gst_encoding_profile_has_format (l->data, "audio/x-wma")) ++num_wma; else ++num_other; } if (num_other > 0) ext = "asf"; else if (num_wmv > 0) ext = "wmv"; else if (num_wma > 0) ext = "wma"; goto done; } done: GST_INFO ("caps %" GST_PTR_FORMAT ", ext: %s", caps, GST_STR_NULL (ext)); gst_caps_unref (caps); return ext; }