static void bin_element_added (GstTracer * runner, GstClockTime ts, GstBin * bin, GstElement * element, gboolean result) { GstObject *parent; GstValidateElementMonitor *monitor = g_object_get_data (G_OBJECT (element), "validate-monitor"); if (!monitor) return; if (!monitor->is_decoder) return; parent = gst_object_get_parent (GST_OBJECT (element)); do { if (GES_IS_TRACK (parent)) { GstElementClass *klass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)); const gchar *klassname = gst_element_class_get_metadata (klass, GST_ELEMENT_METADATA_KLASS); if (GES_IS_AUDIO_TRACK (parent) && strstr (klassname, "Audio") == NULL) { GST_VALIDATE_REPORT (monitor, WRONG_DECODER_ADDED, "Adding non audio decoder %s in audio track %s.", GST_OBJECT_NAME (element), GST_OBJECT_NAME (parent)); } else if (GES_IS_VIDEO_TRACK (parent) && strstr (klassname, "Video") == NULL && strstr (klassname, "Image") == NULL) { GST_VALIDATE_REPORT (monitor, WRONG_DECODER_ADDED, "Adding non video decoder %s in video track %s.", GST_OBJECT_NAME (element), GST_OBJECT_NAME (parent)); } gst_object_unref (parent); break; } gst_object_unref (parent); parent = gst_object_get_parent (parent); } while (parent); }
/** * ges_pipeline_set_render_settings: * @pipeline: a #GESPipeline * @output_uri: the URI to which the timeline will be rendered * @profile: the #GstEncodingProfile to use to render the timeline. * * Specify where the pipeline shall be rendered and with what settings. * * A copy of @profile and @output_uri will be done internally, the caller can * safely free those values afterwards. * * This method must be called before setting the pipeline mode to * #GES_PIPELINE_MODE_RENDER * * Returns: %TRUE if the settings were aknowledged properly, else %FALSE */ gboolean ges_pipeline_set_render_settings (GESPipeline * pipeline, const gchar * output_uri, GstEncodingProfile * profile) { GError *err = NULL; GstEncodingProfile *set_profile; g_return_val_if_fail (GES_IS_PIPELINE (pipeline), FALSE); /* FIXME Properly handle multi track, for now GESPipeline * only hanles single track per type, so we should just set the * presence to 1. */ if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { const GList *tmpprofiles = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile)); GList *tmptrack, *tracks = ges_timeline_get_tracks (pipeline->priv->timeline); for (; tmpprofiles; tmpprofiles = tmpprofiles->next) { for (tmptrack = tracks; tmptrack; tmptrack = tmptrack->next) { if ((GST_IS_ENCODING_AUDIO_PROFILE (tmpprofiles->data) && GES_IS_AUDIO_TRACK (tmptrack->data)) || (GST_IS_ENCODING_VIDEO_PROFILE (tmpprofiles->data) && GES_IS_VIDEO_TRACK (tmptrack->data))) { GST_DEBUG_OBJECT (pipeline, "Setting presence to 1!"); gst_encoding_profile_set_presence (tmpprofiles->data, 1); gst_encoding_profile_set_allow_dynamic_output (tmpprofiles->data, FALSE); } } } g_list_free_full (tracks, gst_object_unref); } /* Clear previous URI sink if it existed */ /* FIXME : We should figure out if it was added to the pipeline, * and if so, remove it. */ if (pipeline->priv->urisink) { gst_object_unref (pipeline->priv->urisink); pipeline->priv->urisink = NULL; } pipeline->priv->urisink = gst_element_make_from_uri (GST_URI_SINK, output_uri, "urisink", &err); if (G_UNLIKELY (pipeline->priv->urisink == NULL)) { GST_ERROR_OBJECT (pipeline, "Couldn't not create sink for URI %s: '%s'", output_uri, ((err && err->message) ? err->message : "failed to create element")); g_clear_error (&err); return FALSE; } if (pipeline->priv->profile) gst_encoding_profile_unref (pipeline->priv->profile); g_object_set (pipeline->priv->encodebin, "avoid-reencoding", !(!(pipeline->priv->mode & GES_PIPELINE_MODE_SMART_RENDER)), NULL); g_object_set (pipeline->priv->encodebin, "profile", profile, NULL); g_object_get (pipeline->priv->encodebin, "profile", &set_profile, NULL); if (set_profile == NULL) { GST_ERROR_OBJECT (pipeline, "Profile %" GST_PTR_FORMAT " could no be set", profile); return FALSE; } /* We got a referencer when getting back the profile */ pipeline->priv->profile = profile; return TRUE; }