effect: Determine the effect type as soon as possible

Making it possible to create the nleobject right at the creation
of the element.

Reviewed-by: Thibault Saunier <thibault.saunier@collabora.com>
Differential Revision: https://phabricator.freedesktop.org/D738
This commit is contained in:
Thibault Saunier 2016-01-25 15:57:22 +01:00
parent 3ffdad6db8
commit 8c672f8366
5 changed files with 128 additions and 54 deletions

View file

@ -33,49 +33,35 @@ G_DEFINE_TYPE (GESEffectAsset, ges_effect_asset, GES_TYPE_TRACK_ELEMENT_ASSET);
struct _GESEffectAssetPrivate
{
GESTrackType track_type;
gpointer nothing;
};
/* GESAsset virtual methods implementation */
static void
_fill_track_type (GESAsset * asset)
{
GList *tmp;
GstElement *effect = gst_parse_bin_from_description (ges_asset_get_id (asset),
TRUE, NULL);
GESTrackType ttype;
gchar *bin_desc;
const gchar *id = ges_asset_get_id (asset);
if (effect == NULL)
return;
bin_desc = ges_effect_assect_id_get_type_and_bindesc (id, &ttype, NULL);
for (tmp = GST_BIN_CHILDREN (effect); tmp; tmp = tmp->next) {
GstElementFactory *factory =
gst_element_get_factory (GST_ELEMENT (tmp->data));
const gchar *klass =
gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
if (g_strrstr (klass, "Effect")) {
if (g_strrstr (klass, "Audio")) {
GES_EFFECT_ASSET (asset)->priv->track_type = GES_TRACK_TYPE_AUDIO;
break;
} else if (g_strrstr (klass, "Video")) {
GES_EFFECT_ASSET (asset)->priv->track_type = GES_TRACK_TYPE_VIDEO;
break;
}
}
if (bin_desc) {
ges_track_element_asset_set_track_type (GES_TRACK_ELEMENT_ASSET (asset),
ttype);
} else {
GST_WARNING_OBJECT (asset, "No track type set, you should"
" specify one in [audio, video] as first component" " in the asset id");
}
gst_object_unref (effect);
return;
}
/* GESAsset virtual methods implementation */
static GESExtractable *
_extract (GESAsset * asset, GError ** error)
{
GESExtractable *effect;
if (GES_EFFECT_ASSET (asset)->priv->track_type == GES_TRACK_TYPE_UNKNOWN)
_fill_track_type (asset);
effect = GES_ASSET_CLASS (ges_effect_asset_parent_class)->extract (asset,
error);
@ -85,9 +71,6 @@ _extract (GESAsset * asset, GError ** error)
return NULL;
}
ges_track_element_set_track_type (GES_TRACK_ELEMENT (effect),
GES_EFFECT_ASSET (asset)->priv->track_type);
return effect;
}
@ -96,8 +79,12 @@ ges_effect_asset_init (GESEffectAsset * self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
GES_TYPE_EFFECT_ASSET, GESEffectAssetPrivate);
}
self->priv->track_type = GES_TRACK_TYPE_UNKNOWN;
static void
ges_effect_asset_constructed (GObject * object)
{
_fill_track_type (GES_ASSET (object));
}
static void
@ -117,5 +104,72 @@ ges_effect_asset_class_init (GESEffectAssetClass * klass)
g_type_class_add_private (klass, sizeof (GESEffectAssetPrivate));
object_class->finalize = ges_effect_asset_finalize;
object_class->constructed = ges_effect_asset_constructed;
asset_class->extract = _extract;
}
gchar *
ges_effect_assect_id_get_type_and_bindesc (const char *id,
GESTrackType * track_type, GError ** error)
{
GList *tmp;
GstElement *effect;
gchar **typebin_desc = NULL;
gchar *bindesc = NULL;
*track_type = GES_TRACK_TYPE_UNKNOWN;
typebin_desc = g_strsplit (id, " ", 2);
if (!g_strcmp0 (typebin_desc[0], "audio")) {
*track_type = GES_TRACK_TYPE_AUDIO;
bindesc = g_strdup (typebin_desc[1]);
} else if (!g_strcmp0 (typebin_desc[0], "video")) {
*track_type = GES_TRACK_TYPE_VIDEO;
bindesc = g_strdup (typebin_desc[1]);
} else {
bindesc = g_strdup (id);
}
g_strfreev (typebin_desc);
effect = gst_parse_bin_from_description (bindesc, TRUE, error);
if (effect == NULL) {
g_free (bindesc);
GST_ERROR ("Could not create element from: %s", id);
return NULL;
}
if (*track_type != GES_TRACK_TYPE_UNKNOWN) {
gst_object_unref (effect);
return bindesc;
}
for (tmp = GST_BIN_CHILDREN (effect); tmp; tmp = tmp->next) {
GstElementFactory *factory =
gst_element_get_factory (GST_ELEMENT (tmp->data));
const gchar *klass =
gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
if (g_strrstr (klass, "Effect")) {
if (g_strrstr (klass, "Audio")) {
*track_type = GES_TRACK_TYPE_AUDIO;
break;
} else if (g_strrstr (klass, "Video")) {
*track_type = GES_TRACK_TYPE_VIDEO;
break;
}
}
}
gst_object_unref (effect);
if (*track_type == GES_TRACK_TYPE_UNKNOWN) {
*track_type = GES_TRACK_TYPE_VIDEO;
GST_ERROR ("Could not determine track type for %s, defaulting to video",
id);
}
return bindesc;
}

View file

@ -55,26 +55,44 @@ enum
static gchar *
extractable_check_id (GType type, const gchar * id, GError ** error)
{
GstElement *effect = gst_parse_bin_from_description (id, TRUE, error);
gchar *bin_desc, *real_id;
GESTrackType ttype;
if (effect == NULL)
bin_desc = ges_effect_assect_id_get_type_and_bindesc (id, &ttype, error);
if (bin_desc == NULL)
return NULL;
gst_object_unref (effect);
return g_strdup (id);
if (ttype == GES_TRACK_TYPE_AUDIO)
real_id = g_strdup_printf ("audio %s", bin_desc);
else if (ttype == GES_TRACK_TYPE_VIDEO)
real_id = g_strdup_printf ("video %s", bin_desc);
else
g_assert_not_reached ();
return real_id;
}
static GParameter *
extractable_get_parameters_from_id (const gchar * id, guint * n_params)
{
GParameter *params = g_new0 (GParameter, 2);
GParameter *params = g_new0 (GParameter, 3);
gchar *bin_desc;
GESTrackType ttype;
bin_desc = ges_effect_assect_id_get_type_and_bindesc (id, &ttype, NULL);
params[0].name = "bin-description";
g_value_init (&params[0].value, G_TYPE_STRING);
g_value_set_string (&params[0].value, id);
g_value_set_string (&params[0].value, bin_desc);
*n_params = 1;
params[1].name = "track-type";
g_value_init (&params[1].value, GES_TYPE_TRACK_TYPE);
g_value_set_flags (&params[1].value, ttype);
*n_params = 2;
g_free (bin_desc);
return params;
}
@ -188,27 +206,20 @@ ges_effect_create_element (GESTrackElement * object)
GError *error = NULL;
GESEffect *self = GES_EFFECT (object);
GESTrack *track = ges_track_element_get_track (object);
const gchar *wanted_categories[] = { "Effect", NULL };
if (!track) {
GST_WARNING
("The object %p should be in a Track for the element to be created",
object);
return NULL;
}
GESTrackType type = ges_track_element_get_track_type (object);
if (track->type == GES_TRACK_TYPE_VIDEO) {
if (type == GES_TRACK_TYPE_VIDEO) {
bin_desc = g_strconcat ("videoconvert name=pre_video_convert ! ",
self->priv->bin_description, " ! videoconvert name=post_video_convert",
NULL);
} else if (track->type == GES_TRACK_TYPE_AUDIO) {
} else if (type == GES_TRACK_TYPE_AUDIO) {
bin_desc =
g_strconcat ("audioconvert ! audioresample !",
self->priv->bin_description, NULL);
} else {
GST_DEBUG ("Track type not supported");
return NULL;
g_assert_not_reached ();
}
effect = gst_parse_bin_from_description (bin_desc, TRUE, &error);
@ -234,7 +245,12 @@ ges_effect_create_element (GESTrackElement * object)
* ges_effect_new:
* @bin_description: The gst-launch like bin description of the effect
*
* Creates a new #GESEffect from the description of the bin.
* Creates a new #GESEffect from the description of the bin. It should be
* possible to determine the type of the effect through the element
* 'klass' metadata of the GstElements that will be created.
* In that corner case, you should use:
* #ges_asset_request (GES_TYPE_EFFECT, "audio your ! bin ! description", NULL);
* and extract that asset to be in full control.
*
* Returns: a newly created #GESEffect, or %NULL if something went
* wrong.

View file

@ -148,6 +148,10 @@ ges_asset_try_proxy (GESAsset *asset, const gchar *new_id);
G_GNUC_INTERNAL gboolean
ges_asset_request_id_update (GESAsset *asset, gchar **proposed_id,
GError *error);
G_GNUC_INTERNAL gchar *
ges_effect_assect_id_get_type_and_bindesc (const char *id,
GESTrackType *track_type,
GError **error);
/* GESExtractable internall methods
*

View file

@ -158,7 +158,7 @@ GST_START_TEST (test_proxy_asset)
fail_unless (ges_init ());
identity = ges_asset_request (GES_TYPE_EFFECT, "identity", NULL);
identity = ges_asset_request (GES_TYPE_EFFECT, "video identity", NULL);
fail_unless (identity != NULL);
nothing = ges_asset_request (GES_TYPE_EFFECT, "nothing", NULL);
@ -167,7 +167,7 @@ GST_START_TEST (test_proxy_asset)
nothing = ges_asset_cache_lookup (GES_TYPE_EFFECT, "nothing");
fail_unless (nothing != NULL);
fail_unless (ges_asset_try_proxy (nothing, "identity"));
fail_unless (ges_asset_try_proxy (nothing, "video identity"));
fail_unless (ges_asset_set_proxy (NULL, identity));
nothing_at_all = ges_asset_request (GES_TYPE_EFFECT, "nothing_at_all", NULL);

View file

@ -184,7 +184,7 @@ asset_added_cb (GESProject * project, GESAsset * asset)
GstDiscovererInfo *info;
if (ges_asset_get_extractable_type (asset) == GES_TYPE_EFFECT) {
assert_equals_string (ges_asset_get_id (asset), "agingtv");
assert_equals_string (ges_asset_get_id (asset), "video agingtv");
} else {
info = ges_uri_clip_asset_get_info (GES_URI_CLIP_ASSET (asset));
fail_unless (GST_IS_DISCOVERER_INFO (info));