/** * ges_project_add_encoding_profile: * @project: A #GESProject * @profile: A #GstEncodingProfile to add to the project. If a profile with * the same name already exists, it will be replaced * * Adds @profile to the project. It lets you save in what format * the project has been renders and keep a reference to those formats. * Also, those formats will be saves to the project file when possible. * * Returns: %TRUE if @profile could be added, %FALSE otherwize */ gboolean ges_project_add_encoding_profile (GESProject * project, GstEncodingProfile * profile) { GList *tmp; GESProjectPrivate *priv; g_return_val_if_fail (GES_IS_PROJECT (project), FALSE); g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE); priv = project->priv; for (tmp = priv->encoding_profiles; tmp; tmp = tmp->next) { GstEncodingProfile *tmpprofile = GST_ENCODING_PROFILE (tmp->data); if (g_strcmp0 (gst_encoding_profile_get_name (tmpprofile), gst_encoding_profile_get_name (profile)) == 0) { GST_INFO_OBJECT (project, "Already have profile: %s, replacing it", gst_encoding_profile_get_name (profile)); gst_object_unref (tmp->data); tmp->data = gst_object_ref (profile); return TRUE; } } priv->encoding_profiles = g_list_prepend (priv->encoding_profiles, gst_object_ref (profile)); return TRUE; }
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; }
static GstElement* build_encoder (SjExtractor *extractor) { SjExtractorPrivate *priv; GstElement *encodebin; const char *profile_name; static const char * mp3_pipeline = "lamemp3enc ! xingmux ! id3v2mux"; g_return_val_if_fail (SJ_IS_EXTRACTOR (extractor), NULL); priv = (SjExtractorPrivate*)extractor->priv; g_return_val_if_fail (priv->profile != NULL, NULL); /* encodebin does not use xingmux so do mp3 pipeline ourselves */ profile_name = gst_encoding_profile_get_name (priv->profile); if (strcmp (profile_name, "mp3") == 0) { encodebin = gst_parse_bin_from_description (mp3_pipeline, TRUE, NULL); } else { encodebin = gst_element_factory_make ("encodebin", NULL); if (encodebin == NULL) return NULL; g_object_set (encodebin, "profile", priv->profile, NULL); /* Nice big buffers... */ g_object_set (encodebin, "queue-time-max", 120 * GST_SECOND, NULL); } return encodebin; }
/* 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; }
gboolean gst_encoding_target_add_profile (GstEncodingTarget * target, GstEncodingProfile * profile) { GList *tmp; g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), FALSE); g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE); /* Make sure profile isn't already controlled by this target */ for (tmp = target->profiles; tmp; tmp = tmp->next) { GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data; if (!g_strcmp0 (gst_encoding_profile_get_name (profile), gst_encoding_profile_get_name (prof))) { GST_WARNING ("Profile already present in target"); return FALSE; } } target->profiles = g_list_append (target->profiles, profile); return TRUE; }
static GstEncodingProfile * get_audio_encoding_profile (GstEncodingProfile *profile) { if (GST_IS_ENCODING_AUDIO_PROFILE (profile)) { return profile; } else if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { const GList *l = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile)); for (; l != NULL; l = l->next) { GstEncodingProfile *p = get_audio_encoding_profile (l->data); if (p != NULL) { return p; } } } g_warning ("no audio encoding profile in profile %s", gst_encoding_profile_get_name (profile)); return NULL; }
/** * gst_encoding_target_get_profile: * @target: a #GstEncodingTarget * @name: the name of the profile to retrieve * * Returns: (transfer full): The matching #GstEncodingProfile, or %NULL. */ GstEncodingProfile * gst_encoding_target_get_profile (GstEncodingTarget * target, const gchar * name) { GList *tmp; g_return_val_if_fail (GST_IS_ENCODING_TARGET (target), NULL); g_return_val_if_fail (name != NULL, NULL); for (tmp = target->profiles; tmp; tmp = tmp->next) { GstEncodingProfile *tprof = (GstEncodingProfile *) tmp->data; if (!g_strcmp0 (gst_encoding_profile_get_name (tprof), name)) { gst_encoding_profile_ref (tprof); return tprof; } } return NULL; }
gboolean sj_extractor_supports_profile (GstEncodingProfile *profile) { /* TODO: take a GError to return a message if the profile isn't supported */ const gchar *profile_name = gst_encoding_profile_get_name (profile); if (strcmp (profile_name, "mp3") == 0) { GstElementFactory *factory = gst_element_factory_find ("lamemp3enc"); if (factory == NULL) return FALSE; g_object_unref (factory); factory = gst_element_factory_find ("xingmux"); if (factory == NULL) return FALSE; g_object_unref (factory); factory = gst_element_factory_find ("id3v2mux"); if (factory == NULL) return FALSE; g_object_unref (factory); return TRUE; } return !rb_gst_check_missing_plugins(profile, NULL, NULL); }
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; }
void ges_base_xml_formatter_add_encoding_profile (GESBaseXmlFormatter * self, const gchar * type, const gchar * parent, const gchar * name, const gchar * description, GstCaps * format, const gchar * preset, const gchar * preset_name, guint id, guint presence, GstCaps * restriction, guint pass, gboolean variableframerate, GstStructure * properties, GError ** error) { const GList *tmp; GstEncodingProfile *profile; GstEncodingContainerProfile *parent_profile = NULL; GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self); if (priv->check_only) goto done; if (parent == NULL) { profile = _create_profile (self, type, parent, name, description, format, preset, preset_name, id, presence, restriction, pass, variableframerate); ges_project_add_encoding_profile (GES_FORMATTER (self)->project, profile); gst_object_unref (profile); goto done; } for (tmp = ges_project_list_encoding_profiles (GES_FORMATTER (self)->project); tmp; tmp = tmp->next) { GstEncodingProfile *tmpprofile = GST_ENCODING_PROFILE (tmp->data); if (g_strcmp0 (gst_encoding_profile_get_name (tmpprofile), gst_encoding_profile_get_name (tmpprofile)) == 0) { if (!GST_IS_ENCODING_CONTAINER_PROFILE (tmpprofile)) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Profile '%s' parent %s is not a container...'", name, parent); goto done; } parent_profile = GST_ENCODING_CONTAINER_PROFILE (tmpprofile); break; } } if (parent_profile == NULL) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Profile '%s' parent %s does not exist'", name, parent); goto done; } profile = _create_profile (self, type, parent, name, description, format, preset, preset_name, id, presence, restriction, pass, variableframerate); if (profile == NULL) goto done; gst_encoding_container_profile_add_profile (parent_profile, profile); done: if (format) gst_caps_unref (format); if (restriction) gst_caps_unref (restriction); }
/** * rb_track_transfer_batch_check_profiles: * @batch: a #RBTrackTransferBatch * @missing_plugin_profiles: (out) (element-type GstPbutils.EncodingProfile): holds a #GList of #GstEncodingProfiles on return * @error_count: holds the number of entries that cannot be transferred on return * * Checks that all entries in the batch can be transferred in a format * supported by the destination. If no encoding profile is available for * some entries, but installing additional plugins could make a profile * available, a list of profiles that require additional plugins is returned. * * Return value: %TRUE if some entries can be transferred without additional plugins */ gboolean rb_track_transfer_batch_check_profiles (RBTrackTransferBatch *batch, GList **missing_plugin_profiles, int *error_count) { RBEncoder *encoder = rb_encoder_new (); gboolean ret = FALSE; const GList *l; rb_debug ("checking profiles"); /* first, figure out which profiles that we care about would require additional plugins to use */ g_list_free (batch->priv->missing_plugin_profiles); batch->priv->missing_plugin_profiles = NULL; for (l = gst_encoding_target_get_profiles (batch->priv->target); l != NULL; l = l->next) { GstEncodingProfile *profile = GST_ENCODING_PROFILE (l->data); char *profile_media_type; profile_media_type = rb_gst_encoding_profile_get_media_type (profile); if (profile_media_type != NULL && (rb_gst_media_type_is_lossless (profile_media_type) == FALSE) && rb_encoder_get_missing_plugins (encoder, profile, NULL, NULL)) { batch->priv->missing_plugin_profiles = g_list_append (batch->priv->missing_plugin_profiles, profile); } g_free (profile_media_type); } g_object_unref (encoder); rb_debug ("have %d profiles with missing plugins", g_list_length (batch->priv->missing_plugin_profiles)); for (l = batch->priv->entries; l != NULL; l = l->next) { RhythmDBEntry *entry = (RhythmDBEntry *)l->data; GstEncodingProfile *profile; profile = NULL; if (select_profile_for_entry (batch, entry, &profile, FALSE) == TRUE) { if (profile != NULL) { rb_debug ("found profile %s for %s", gst_encoding_profile_get_name (profile), rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION)); } else { rb_debug ("copying entry %s", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION)); } ret = TRUE; continue; } (*error_count)++; if (select_profile_for_entry (batch, entry, &profile, TRUE) == FALSE) { rb_debug ("unable to transfer %s (media type %s)", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION), rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MEDIA_TYPE)); } else { rb_debug ("require additional plugins to transfer %s (media type %s)", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION), rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MEDIA_TYPE)); if (*missing_plugin_profiles == NULL) { *missing_plugin_profiles = g_list_copy (batch->priv->missing_plugin_profiles); } } } 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 void build_pipeline (SjExtractor *extractor) { SjExtractorPrivate *priv; GstBus *bus; g_return_if_fail (SJ_IS_EXTRACTOR (extractor)); priv = extractor->priv; if (priv->pipeline != NULL) { gst_object_unref (GST_OBJECT (priv->pipeline)); } priv->pipeline = gst_pipeline_new ("pipeline"); bus = gst_element_get_bus (priv->pipeline); gst_bus_add_signal_watch (bus); g_signal_connect (G_OBJECT (bus), "message::error", G_CALLBACK (error_cb), extractor); /* Read from CD */ priv->cdsrc = gst_element_make_from_uri (GST_URI_SRC, "cdda://1", "cd_src", NULL); if (priv->cdsrc == NULL) { g_set_error (&priv->construct_error, SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, _("Could not create GStreamer CD reader")); return; } g_object_set (G_OBJECT (priv->cdsrc), "device", priv->device_path, NULL); if (g_object_class_find_property (G_OBJECT_GET_CLASS (priv->cdsrc), "paranoia-mode")) { g_object_set (G_OBJECT (priv->cdsrc), "paranoia-mode", priv->paranoia_mode, NULL); } /* Get the track format for seeking later */ priv->track_format = gst_format_get_by_nick ("track"); g_assert (priv->track_format != 0); /* Encode */ priv->encodebin = build_encoder (extractor); if (priv->encodebin == NULL) { g_set_error (&priv->construct_error, SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, _("Could not create GStreamer encoders for %s"), gst_encoding_profile_get_name (priv->profile)); return; } /* Connect to the eos so we know when its finished */ g_signal_connect (bus, "message::eos", G_CALLBACK (eos_cb), extractor); /* Write to disk */ priv->filesink = gst_element_factory_make (FILE_SINK, "file_sink"); if (priv->filesink == NULL) { g_set_error (&priv->construct_error, SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, _("Could not create GStreamer file output")); return; } #if 0 g_signal_connect (G_OBJECT (priv->filesink), "allow-overwrite", G_CALLBACK (just_say_yes), extractor); #endif /* Add the elements to the pipeline */ gst_bin_add_many (GST_BIN (priv->pipeline), priv->cdsrc, priv->encodebin, priv->filesink, NULL); /* Link it all together */ if (!gst_element_link_many (priv->cdsrc, priv->encodebin, priv->filesink, NULL)) { g_set_error (&priv->construct_error, SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, _("Could not link pipeline")); return; } priv->rebuild_pipeline = FALSE; }
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; }