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; }
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); }
/* 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; }
static void kms_muxing_pipeline_configure (KmsMuxingPipeline * self) { GstEncodingContainerProfile *cprof; const GList *profiles, *l; GstElement *appsrc; cprof = kms_recording_profile_create_profile (self->priv->profile, TRUE, TRUE); profiles = gst_encoding_container_profile_get_profiles (cprof); for (l = profiles; l != NULL; l = l->next) { GstEncodingProfile *prof = l->data; GstCaps *caps; if (GST_IS_ENCODING_AUDIO_PROFILE (prof)) { appsrc = self->priv->audiosrc; } else if (GST_IS_ENCODING_VIDEO_PROFILE (prof)) { appsrc = self->priv->videosrc; } else continue; caps = gst_encoding_profile_get_input_caps (prof); g_object_set (G_OBJECT (appsrc), "is-live", TRUE, "do-timestamp", FALSE, "min-latency", G_GUINT64_CONSTANT (0), "max-latency", G_GUINT64_CONSTANT (0), "format", GST_FORMAT_TIME, NULL); gst_caps_unref (caps); } g_object_set (G_OBJECT (self->priv->encodebin), "profile", cprof, "audio-jitter-tolerance", 100 * GST_MSECOND, "avoid-reencoding", TRUE, NULL); gst_encoding_profile_unref (cprof); if (self->priv->profile == KMS_RECORDING_PROFILE_MP4) { GstElement *mux = gst_bin_get_by_name (GST_BIN (self->priv->encodebin), "muxer"); g_object_set (G_OBJECT (mux), "fragment-duration", 2000, "streamable", TRUE, NULL); g_object_unref (mux); } else if (self->priv->profile == KMS_RECORDING_PROFILE_WEBM) { GstElement *mux = gst_bin_get_by_name (GST_BIN (self->priv->encodebin), "muxer"); g_object_set (G_OBJECT (mux), "streamable", TRUE, NULL); g_object_unref (mux); } }
static gboolean ges_pipeline_update_caps (GESPipeline * self) { GList *ltrack, *tracks, *lstream; if (!self->priv->profile) return TRUE; GST_DEBUG ("Updating track caps"); tracks = ges_timeline_get_tracks (self->priv->timeline); /* Take each stream of the encoding profile and find a matching * track to set the caps on */ for (ltrack = tracks; ltrack; ltrack = ltrack->next) { GESTrack *track = (GESTrack *) ltrack->data; GList *allstreams; if (!GST_IS_ENCODING_CONTAINER_PROFILE (self->priv->profile)) { if (_track_is_compatible_with_profile (self, track, self->priv->profile)) { gst_object_unref (track); goto done; } else { gst_object_unref (track); continue; } } allstreams = (GList *) gst_encoding_container_profile_get_profiles ( (GstEncodingContainerProfile *) self->priv->profile); /* Find a matching stream setting */ for (lstream = allstreams; lstream; lstream = lstream->next) { GstEncodingProfile *prof = (GstEncodingProfile *) lstream->data; if (_track_is_compatible_with_profile (self, track, prof)) break; } gst_object_unref (track); } done: if (tracks) g_list_free (tracks); GST_DEBUG ("Done updating caps"); return TRUE; }
static gboolean is_video_profile (const GstEncodingProfile *profile) { const GList *i, *profiles_list; if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) { profiles_list = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile)); for (i = profiles_list ; i; i = i->next) if (GST_IS_ENCODING_VIDEO_PROFILE (i->data)) return TRUE; } return FALSE; }
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; }
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 GstCaps * kms_recorder_endpoint_get_caps_from_profile (KmsRecorderEndpoint * self, KmsElementPadType type) { GstEncodingContainerProfile *cprof; const GList *profiles, *l; GstCaps *caps = NULL; switch (type) { case KMS_ELEMENT_PAD_TYPE_VIDEO: cprof = kms_recording_profile_create_profile (self->priv->profile, FALSE, TRUE); break; case KMS_ELEMENT_PAD_TYPE_AUDIO: cprof = kms_recording_profile_create_profile (self->priv->profile, TRUE, FALSE); break; default: return NULL; } profiles = gst_encoding_container_profile_get_profiles (cprof); for (l = profiles; l != NULL; l = l->next) { GstEncodingProfile *prof = l->data; if ((GST_IS_ENCODING_AUDIO_PROFILE (prof) && type == KMS_ELEMENT_PAD_TYPE_AUDIO) || (GST_IS_ENCODING_VIDEO_PROFILE (prof) && type == KMS_ELEMENT_PAD_TYPE_VIDEO)) { caps = gst_encoding_profile_get_input_caps (prof); break; } } gst_encoding_profile_unref (cprof); return caps; }
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 gboolean ges_timeline_pipeline_update_caps (GESTimelinePipeline * self) { GList *ltrack, *tracks, *lstream; if (!self->priv->profile) return TRUE; GST_DEBUG ("Updating track caps"); tracks = ges_timeline_get_tracks (self->priv->timeline); /* Take each stream of the encoding profile and find a matching * track to set the caps on */ for (ltrack = tracks; ltrack; ltrack = ltrack->next) { GESTrack *track = (GESTrack *) ltrack->data; GList *allstreams; allstreams = (GList *) gst_encoding_container_profile_get_profiles ( (GstEncodingContainerProfile *) self->priv->profile); /* Find a matching stream setting */ for (lstream = allstreams; lstream; lstream = lstream->next) { GstEncodingProfile *prof = (GstEncodingProfile *) lstream->data; if (TRACK_COMPATIBLE_PROFILE (track->type, prof)) { if (self->priv->mode == TIMELINE_MODE_SMART_RENDER) { GstCaps *ocaps, *rcaps; GST_DEBUG ("Smart Render mode, setting input caps"); ocaps = gst_encoding_profile_get_input_caps (prof); if (track->type == GES_TRACK_TYPE_AUDIO) rcaps = gst_caps_from_string ("audio/x-raw-int;audio/x-raw-float"); else rcaps = gst_caps_from_string ("video/x-raw-yuv;video/x-raw-rgb"); gst_caps_append (ocaps, rcaps); ges_track_set_caps (track, ocaps); } else { GstCaps *caps = NULL; /* Raw preview or rendering mode */ if (track->type == GES_TRACK_TYPE_VIDEO) caps = gst_caps_from_string ("video/x-raw-yuv;video/x-raw-rgb"); else if (track->type == GES_TRACK_TYPE_AUDIO) gst_caps_from_string ("audio/x-raw-int;audio/x-raw-float"); if (caps) { ges_track_set_caps (track, caps); gst_caps_unref (caps); } } break; } } g_object_unref (track); } if (tracks) g_list_free (tracks); GST_DEBUG ("Done updating caps"); return TRUE; }
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; }
/** * 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; }
static void test_individual_target (GstEncodingTarget * target) { GstEncodingProfile *prof; GstCaps *tmpcaps, *tmpcaps2; GstEncodingProfile *sprof1, *sprof2; GST_DEBUG ("Checking the target properties"); /* Check the target */ fail_unless_equals_string (gst_encoding_target_get_name (target), "myponytarget"); fail_unless_equals_string (gst_encoding_target_get_category (target), "herding"); fail_unless_equals_string (gst_encoding_target_get_description (target), "Plenty of pony glitter profiles"); GST_DEBUG ("Checking the number of profiles the target contains"); fail_unless_equals_int (g_list_length ((GList *) gst_encoding_target_get_profiles (target)), 1); GST_DEBUG ("Checking the container profile"); /* Check the profile */ prof = (GstEncodingProfile *) gst_encoding_target_get_profiles (target)->data; tmpcaps = gst_caps_from_string ("animal/x-pony"); CHECK_PROFILE (prof, "pony", "I don't want a description !", tmpcaps, NULL, 0, 0); gst_caps_unref (tmpcaps); GST_DEBUG ("Checking the container profile has 2 stream profiles"); /* Check the stream profiles */ fail_unless_equals_int (g_list_length ((GList *) gst_encoding_container_profile_get_profiles ( (GstEncodingContainerProfile *) prof)), 2); GST_DEBUG ("Checking the container profile has the audio/x-pony-song stream"); tmpcaps = gst_caps_from_string ("audio/x-pony-song,pretty=True"); tmpcaps2 = gst_caps_from_string ("audio/x-raw-int,channels=1,rate=44100"); sprof1 = (GstEncodingProfile *) gst_encoding_audio_profile_new (tmpcaps, NULL, tmpcaps2, 1); fail_unless (gst_encoding_container_profile_contains_profile ( (GstEncodingContainerProfile *) prof, sprof1)); gst_encoding_profile_unref (sprof1); gst_caps_unref (tmpcaps); gst_caps_unref (tmpcaps2); GST_DEBUG ("Checking the container profile has the video//x-glitter stream"); tmpcaps = gst_caps_from_string ("video/x-glitter,sparkling=True"); tmpcaps2 = gst_caps_from_string ("video/x-raw-yuv,width=640,height=480,framerate=15/1"); sprof2 = (GstEncodingProfile *) gst_encoding_video_profile_new (tmpcaps, "seriously glittery", tmpcaps2, 0); gst_encoding_video_profile_set_variableframerate ((GstEncodingVideoProfile *) sprof2, TRUE); fail_unless (gst_encoding_container_profile_contains_profile ( (GstEncodingContainerProfile *) prof, sprof2)); gst_encoding_profile_unref (sprof2); gst_caps_unref (tmpcaps); gst_caps_unref (tmpcaps2); }