Implement asset proxying support

API:
  ges_asset_set_proxy
  ges_asset_get_proxy
  ges_asset_list_proxies
  ges_asset_get_proxy_target

Differential Revision: https://phabricator.freedesktop.org/D504
This commit is contained in:
Thibault Saunier 2015-11-20 23:33:12 +01:00
parent 081c285e22
commit fa512ecdba
10 changed files with 362 additions and 45 deletions

View file

@ -1079,6 +1079,10 @@ ges_asset_request_finish
ges_asset_extract
ges_asset_get_error
ges_list_assets
ges_asset_set_proxy
ges_asset_list_proxies
ges_asset_get_proxy_target
ges_asset_get_proxy
<SUBSECTION Standard>
GESAssetPrivate
GES_ASSET

View file

@ -96,6 +96,8 @@ enum
PROP_0,
PROP_TYPE,
PROP_ID,
PROP_PROXY,
PROP_PROXY_TARGET,
PROP_LAST
};
@ -115,11 +117,14 @@ struct _GESAssetPrivate
GESAssetState state;
GType extractable_type;
/* When a asset is proxied, instanciating it will
/* When an asset is proxied, instanciating it will
* return the asset it points to */
char *proxied_asset_id;
/* The error that accured when a asset has been initialized with error */
GList *proxies;
GESAsset *proxy_target;
/* The error that accured when an asset has been initialized with error */
GError *error;
};
@ -314,6 +319,12 @@ ges_asset_get_property (GObject * object, guint property_id,
case PROP_ID:
g_value_set_string (value, asset->priv->id);
break;
case PROP_PROXY:
g_value_set_object (value, ges_asset_get_proxy (asset));
break;
case PROP_PROXY_TARGET:
g_value_set_object (value, ges_asset_get_proxy_target (asset));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@ -333,6 +344,12 @@ ges_asset_set_property (GObject * object, guint property_id,
case PROP_ID:
asset->priv->id = g_value_dup_string (value);
break;
case PROP_PROXY:
ges_asset_set_proxy (asset, g_value_get_object (value));
break;
case PROP_PROXY_TARGET:
ges_asset_set_proxy (g_value_get_object (value), asset);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@ -377,6 +394,14 @@ ges_asset_class_init (GESAssetClass * klass)
"The unic identifier of the asset", NULL,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
_properties[PROP_PROXY] =
g_param_spec_object ("proxy", "Proxy",
"The asset default proxy.", GES_TYPE_ASSET, G_PARAM_READWRITE);
_properties[PROP_PROXY_TARGET] =
g_param_spec_object ("proxy-target", "Proxy target",
"The target of a proxy asset.", GES_TYPE_ASSET, G_PARAM_READWRITE);
g_object_class_install_properties (object_class, PROP_LAST, _properties);
klass->start_loading = ges_asset_start_loading_default;
@ -593,9 +618,10 @@ ges_asset_request_id_update (GESAsset * asset, gchar ** proposed_id,
}
gboolean
ges_asset_set_proxy (GESAsset * asset, const gchar * new_id)
ges_asset_try_proxy (GESAsset * asset, const gchar * new_id)
{
GESAssetClass *class;
if (g_strcmp0 (asset->priv->id, new_id) == 0) {
GST_WARNING_OBJECT (asset, "Trying to proxy to itself (%s),"
" NOT possible", new_id);
@ -609,9 +635,7 @@ ges_asset_set_proxy (GESAsset * asset, const gchar * new_id)
return FALSE;
}
if (asset->priv->proxied_asset_id)
g_free (asset->priv->proxied_asset_id);
g_free (asset->priv->proxied_asset_id);
asset->priv->state = ASSET_PROXIED;
asset->priv->proxied_asset_id = g_strdup (new_id);
@ -619,10 +643,160 @@ ges_asset_set_proxy (GESAsset * asset, const gchar * new_id)
if (class->inform_proxy)
GES_ASSET_GET_CLASS (asset)->inform_proxy (asset, new_id);
GST_DEBUG_OBJECT (asset, "Now proxied to %s", new_id);
GST_DEBUG_OBJECT (asset, "Trying to proxy to %s", new_id);
return TRUE;
}
static gboolean
_lookup_proxied_asset (const gchar * id, GESAssetCacheEntry * entry,
const gchar * asset_id)
{
return !g_strcmp0 (asset_id, entry->asset->priv->proxied_asset_id);
}
/**
* ges_asset_set_proxy:
* @asset: The #GESAsset to set proxy on
* @proxy: (allow-none): The #GESAsset that should be used as default proxy for @asset or
* %NULL if you want to use the currently set proxy. Note that an asset can proxy one and only
* one other asset.
*
* A proxying asset is an asset that can substitue the real @asset. For example if you
* have a full HD #GESUriClipAsset you might want to set a lower resolution (HD version
* of the same file) as proxy. Note that when an asset is proxied, calling
* #ges_asset_request will actually return the proxy asset.
*
* Returns: The list of proxies @asset has. Note that the default asset to be
* used is always the first in that list.
*/
gboolean
ges_asset_set_proxy (GESAsset * asset, GESAsset * proxy)
{
g_return_val_if_fail (asset == NULL || GES_IS_ASSET (asset), FALSE);
g_return_val_if_fail (proxy == NULL || GES_IS_ASSET (proxy), FALSE);
g_return_val_if_fail (asset != proxy, FALSE);
if (!proxy) {
if (asset->priv->error) {
GST_ERROR_OBJECT (asset,
"Proxy was loaded with error (%s), it should not be 'unproxied'",
asset->priv->error->message);
return FALSE;
}
if (asset->priv->proxies) {
GESAsset *old_proxy = GES_ASSET (asset->priv->proxies->data);
GES_ASSET (asset->priv->proxies->data)->priv->proxy_target = NULL;
g_object_notify_by_pspec (G_OBJECT (old_proxy),
_properties[PROP_PROXY_TARGET]);
}
GST_DEBUG_OBJECT (asset, "%s not proxied anymore", asset->priv->id);
asset->priv->state = ASSET_INITIALIZED;
g_object_notify_by_pspec (G_OBJECT (asset), _properties[PROP_PROXY]);
return TRUE;
}
if (asset == NULL) {
GHashTable *entries_table;
GESAssetCacheEntry *entry;
entries_table = g_hash_table_lookup (type_entries_table,
_extractable_type_name (proxy->priv->extractable_type));
entry = g_hash_table_find (entries_table, (GHRFunc) _lookup_proxied_asset,
(gpointer) ges_asset_get_id (proxy));
if (!entry) {
GST_DEBUG_OBJECT (asset, "Not proxying any asset");
return FALSE;
}
asset = entry->asset;
while (asset->priv->proxies)
asset = asset->priv->proxies->data;
}
if (proxy->priv->proxy_target) {
GST_ERROR_OBJECT (asset,
"Trying to use %s as a proxy, but it is already proxying %s",
proxy->priv->id, proxy->priv->proxy_target->priv->id);
}
if (g_list_find (proxy->priv->proxies, asset)) {
GST_ERROR_OBJECT (asset, "Trying to setup a circular proxying dependency!");
return FALSE;
}
if (g_list_find (asset->priv->proxies, proxy)) {
GST_INFO_OBJECT (asset,
"%" GST_PTR_FORMAT " already marked as proxy, moving to first", proxy);
GES_ASSET (asset->priv->proxies->data)->priv->proxy_target = NULL;
asset->priv->proxies = g_list_remove (asset->priv->proxies, proxy);
}
GST_INFO ("%s is now proxied by %s", asset->priv->id, proxy->priv->id);
asset->priv->proxies = g_list_prepend (asset->priv->proxies, proxy);
proxy->priv->proxy_target = asset;
g_object_notify_by_pspec (G_OBJECT (proxy), _properties[PROP_PROXY_TARGET]);
asset->priv->state = ASSET_PROXIED;
g_object_notify_by_pspec (G_OBJECT (asset), _properties[PROP_PROXY]);
return TRUE;
}
/**
* ges_asset_list_proxies:
* @asset: The #GESAsset to get proxies from
*
* Returns: The list of proxies @asset has. Note that the default asset to be
* used is always the first in that list.
*/
GList *
ges_asset_list_proxies (GESAsset * asset)
{
g_return_val_if_fail (GES_IS_ASSET (asset), NULL);
return asset->priv->proxies;
}
/**
* ges_asset_get_proxy:
* @asset: The #GESAsset to get currenlty used proxy
*
* Returns: (transfer none): The proxy in use for @asset
*/
GESAsset *
ges_asset_get_proxy (GESAsset * asset)
{
g_return_val_if_fail (GES_IS_ASSET (asset), NULL);
if (asset->priv->state == ASSET_PROXIED && asset->priv->proxies) {
return asset->priv->proxies->data;
}
return NULL;
}
/**
* ges_asset_get_proxy_target:
* @proxy: The #GESAsset from which to get the the asset it proxies.
*
* Returns: (transfer none): The #GESAsset that is proxied by @proxy
*/
GESAsset *
ges_asset_get_proxy_target (GESAsset * proxy)
{
g_return_val_if_fail (GES_IS_ASSET (proxy), NULL);
return proxy->priv->proxy_target;
}
/* Caution, this method should be used in rare cases (ie: for the project
* as we can change its ID from a useless one to a proper URI). In most
* cases you want to update the ID creating a proxy
@ -751,19 +925,21 @@ ges_asset_request (GType extractable_type, const gchar * id, GError ** error)
asset = NULL;
goto done;
case ASSET_PROXIED:
asset =
ges_asset_cache_lookup (asset->priv->extractable_type,
asset->priv->proxied_asset_id);
if (asset == NULL) {
GST_ERROR ("Asset against a asset we do not"
if (asset->priv->proxies == NULL) {
GST_ERROR ("Proxied against an asset we do not"
" have in cache, something massively screwed");
goto done;
}
asset = asset->priv->proxies->data;
while (ges_asset_get_proxy (asset))
asset = ges_asset_get_proxy (asset);
break;
case ASSET_INITIALIZED_WITH_ERROR:
GST_WARNING_OBJECT (asset, "Initialized with error, not returning");
if (asset->priv->error)
if (asset->priv->error && error)
*error = g_error_copy (asset->priv->error);
asset = NULL;
goto done;
@ -866,7 +1042,7 @@ ges_asset_request_async (GType extractable_type,
real_id = g_strdup (id);
}
/* Check if we already have a asset for this ID */
/* Check if we already have an asset for this ID */
asset = ges_asset_cache_lookup (extractable_type, real_id);
if (asset) {
GTask *task = g_task_new (asset, NULL, callback, user_data);
@ -892,12 +1068,12 @@ ges_asset_request_async (GType extractable_type,
goto done;
case ASSET_PROXIED:
asset =
ges_asset_cache_lookup (asset->priv->extractable_type,
asset->priv->proxied_asset_id);
asset = ges_asset_get_proxy (asset);
if (asset == NULL) {
GST_ERROR ("Asset proxied against a asset we do not"
" have in cache, something massively screwed");
GST_ERROR ("Asset %s proxied against an asset (%s) we do not"
" have in cache, something massively screwed",
asset->priv->id, asset->priv->proxied_asset_id);
goto done;
}

View file

@ -74,6 +74,10 @@ struct _GESAssetClass
/* Let subclasses know that we proxied an asset */
void (*inform_proxy) (GESAsset *self,
const gchar *proxy_id);
void (*proxied) (GESAsset *self,
GESAsset *proxy);
/* Ask subclasses for a new ID for @self when the asset failed loading
* This function returns %FALSE when the ID could be updated or %TRUE
* otherwize */
@ -100,5 +104,11 @@ GESExtractable * ges_asset_extract (GESAsset * self,
GError **error);
GList * ges_list_assets (GType filter);
gboolean ges_asset_set_proxy (GESAsset *asset, GESAsset *proxy);
GList * ges_asset_list_proxies (GESAsset *asset);
GESAsset * ges_asset_get_proxy_target(GESAsset *proxy);
GESAsset * ges_asset_get_proxy (GESAsset *asset);
G_END_DECLS
#endif /* _GES_ASSET */

View file

@ -100,6 +100,7 @@ typedef struct PendingAsset
GESFormatter *formatter;
gchar *metadatas;
GstStructure *properties;
gchar *proxy_id;
} PendingAsset;
struct _GESBaseXmlFormatterPrivate
@ -467,6 +468,7 @@ _add_all_groups (GESFormatter * self)
static void
_loading_done (GESFormatter * self)
{
GList *assets, *tmp;
GESBaseXmlFormatterPrivate *priv = GES_BASE_XML_FORMATTER (self)->priv;
_add_all_groups (self);
@ -478,6 +480,13 @@ _loading_done (GESFormatter * self)
ges_timeline_set_auto_transition (self->timeline,
priv->timeline_auto_transition);
/* Go over all assets and make sure that all proxies we were 'trying' to set are finally
* properly set */
assets = ges_project_list_assets (self->project, GES_TYPE_EXTRACTABLE);
for (tmp = assets; tmp; tmp = tmp->next) {
ges_asset_set_proxy (NULL, tmp->data);
}
g_hash_table_foreach (priv->layers, (GHFunc) _set_auto_transition, NULL);
ges_project_set_loaded (self->project, self);
}
@ -623,8 +632,8 @@ _free_pending_clip (GESBaseXmlFormatterPrivate * priv, PendingClip * pend)
static void
_free_pending_asset (GESBaseXmlFormatterPrivate * priv, PendingAsset * passet)
{
if (passet->metadatas)
g_free (passet->metadatas);
g_free (passet->metadatas);
g_free (passet->proxy_id);
if (passet->properties)
gst_structure_free (passet->properties);
@ -722,6 +731,13 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, PendingAsset * passet)
goto done;
}
if (passet->proxy_id) {
/* We set the URI to be used as a proxy,
* this will finally be set as the proxy when we
* are done loading all assets */
ges_asset_try_proxy (asset, passet->proxy_id);
}
/* now that we have the GESAsset, we create the GESClips */
pendings = g_hash_table_lookup (priv->assetid_pendingclips, id);
GST_DEBUG_OBJECT (self, "Asset created with ID %s, now creating pending "
@ -825,7 +841,7 @@ _create_profile (GESBaseXmlFormatter * self,
void
ges_base_xml_formatter_add_asset (GESBaseXmlFormatter * self,
const gchar * id, GType extractable_type, GstStructure * properties,
const gchar * metadatas, GError ** error)
const gchar * metadatas, const gchar * proxy_id, GError ** error)
{
PendingAsset *passet;
GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self);
@ -835,6 +851,7 @@ ges_base_xml_formatter_add_asset (GESBaseXmlFormatter * self,
passet = g_slice_new0 (PendingAsset);
passet->metadatas = g_strdup (metadatas);
passet->proxy_id = g_strdup (proxy_id);
passet->formatter = gst_object_ref (self);
if (properties)
passet->properties = gst_structure_copy (properties);

View file

@ -143,7 +143,7 @@ GESAsset*
ges_asset_cache_lookup(GType extractable_type, const gchar * id);
gboolean
ges_asset_set_proxy (GESAsset *asset, const gchar *new_id);
ges_asset_try_proxy (GESAsset *asset, const gchar *new_id);
G_GNUC_INTERNAL gboolean
ges_asset_request_id_update (GESAsset *asset, gchar **proposed_id,
@ -224,6 +224,7 @@ G_GNUC_INTERNAL void ges_base_xml_formatter_add_asset (GESBaseXmlFormatte
GType extractable_type,
GstStructure *properties,
const gchar *metadatas,
const gchar *proxy_id,
GError **error);
G_GNUC_INTERNAL void ges_base_xml_formatter_add_layer (GESBaseXmlFormatter *self,
GType extractable_type,

View file

@ -595,7 +595,7 @@ ges_project_try_updating_id (GESProject * project, GESAsset * asset,
if (new_id) {
GST_DEBUG_OBJECT (project, "new id found: %s", new_id);
if (!ges_asset_set_proxy (asset, new_id)) {
if (!ges_asset_try_proxy (asset, new_id)) {
g_free (new_id);
new_id = NULL;
}
@ -633,6 +633,7 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, GESProject * project)
return;
}
ges_asset_set_proxy (NULL, asset);
ges_project_add_asset (project, asset);
if (asset)
gst_object_unref (asset);
@ -766,6 +767,10 @@ ges_project_create_asset_sync (GESProject * project, const gchar * id,
if (asset) {
retry = FALSE;
if ((!g_hash_table_lookup (project->priv->assets,
ges_asset_get_id (asset))))
g_signal_emit (project, _signals[ASSET_LOADING_SIGNAL], 0, asset);
if (possible_id) {
g_free (possible_id);
ges_uri_assets_validate_uri (id);
@ -776,6 +781,9 @@ ges_project_create_asset_sync (GESProject * project, const gchar * id,
GESAsset *tmpasset;
tmpasset = ges_asset_cache_lookup (extractable_type, id);
g_signal_emit (project, _signals[ASSET_LOADING_SIGNAL], 0, tmpasset);
g_signal_emit (project, _signals[ERROR_LOADING_ASSET], 0, *error, id,
extractable_type);
possible_id = ges_project_try_updating_id (project, tmpasset, *error);
if (possible_id == NULL)
@ -788,6 +796,9 @@ ges_project_create_asset_sync (GESProject * project, const gchar * id,
}
}
if (!ges_asset_get_proxy_target (asset))
ges_asset_set_proxy (NULL, asset);
ges_project_add_asset (project, asset);
return asset;

View file

@ -37,6 +37,7 @@
#include "ges-image-source.h"
#include "ges-audio-test-source.h"
#include "ges-multi-file-source.h"
#include "ges-layer.h"
static void ges_extractable_interface_init (GESExtractableInterface * iface);
@ -260,13 +261,19 @@ extractable_get_id (GESExtractable * self)
return g_strdup (GES_URI_CLIP (self)->priv->uri);
}
static void
static gboolean
extractable_set_asset (GESExtractable * self, GESAsset * asset)
{
gboolean res = TRUE;
GESUriClip *uriclip = GES_URI_CLIP (self);
GESUriClipAsset *filesource_asset = GES_URI_CLIP_ASSET (asset);
GESUriClipAsset *filesource_asset;
GESClip *clip = GES_CLIP (self);
GESLayer *layer = ges_clip_get_layer (clip);
GList *tmp;
g_return_val_if_fail (GES_IS_URI_CLIP_ASSET (asset), FALSE);
filesource_asset = GES_URI_CLIP_ASSET (asset);
if (GST_CLOCK_TIME_IS_VALID (GES_TIMELINE_ELEMENT_DURATION (clip)) == FALSE)
_set_duration0 (GES_TIMELINE_ELEMENT (uriclip),
ges_uri_clip_asset_get_duration (filesource_asset));
@ -277,13 +284,35 @@ extractable_set_asset (GESExtractable * self, GESAsset * asset)
ges_uri_clip_asset_is_image (filesource_asset));
if (ges_clip_get_supported_formats (clip) == GES_TRACK_TYPE_UNKNOWN) {
ges_clip_set_supported_formats (clip,
ges_clip_asset_get_supported_formats
(GES_CLIP_ASSET (filesource_asset)));
ges_clip_asset_get_supported_formats (GES_CLIP_ASSET
(filesource_asset)));
}
GES_TIMELINE_ELEMENT (uriclip)->asset = asset;
if (layer) {
for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
if (GES_IS_SOURCE (tmp->data)) {
GESTrack *track = ges_track_element_get_track (tmp->data);
ges_track_remove_element (track, tmp->data);
}
}
gst_object_ref (clip);
ges_layer_remove_clip (layer, clip);
res = ges_layer_add_clip (layer, clip);
gst_object_unref (clip);
gst_object_unref (layer);
}
if (res) {
g_free (uriclip->priv->uri);
uriclip->priv->uri = g_strdup (ges_asset_get_id (asset));
}
return res;
}
static void
@ -293,7 +322,9 @@ ges_extractable_interface_init (GESExtractableInterface * iface)
iface->check_id = (GESExtractableCheckId) extractable_check_id;
iface->get_parameters_from_id = extractable_get_parameters_from_id;
iface->get_id = extractable_get_id;
iface->set_asset = extractable_set_asset;
iface->get_id = extractable_get_id;
iface->can_update_asset = TRUE;
iface->set_asset_full = extractable_set_asset;
}
static void

View file

@ -32,8 +32,8 @@
G_DEFINE_TYPE (GESXmlFormatter, ges_xml_formatter, GES_TYPE_BASE_XML_FORMATTER);
#define API_VERSION 0
#define MINOR_VERSION 2
#define VERSION 0.2
#define MINOR_VERSION 3
#define VERSION 0.3
#define COLLECT_STR_OPT (G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL)
@ -272,14 +272,15 @@ _parse_asset (GMarkupParseContext * context, const gchar * element_name,
{
GType extractable_type;
const gchar *id, *extractable_type_name, *metadatas = NULL, *properties =
NULL;
NULL, *proxy_id = NULL;
if (!g_markup_collect_attributes (element_name, attribute_names,
attribute_values, error, G_MARKUP_COLLECT_STRING, "id", &id,
G_MARKUP_COLLECT_STRING, "extractable-type-name",
&extractable_type_name,
COLLECT_STR_OPT, "properties", &properties,
COLLECT_STR_OPT, "metadatas", &metadatas, G_MARKUP_COLLECT_INVALID))
COLLECT_STR_OPT, "metadatas", &metadatas,
COLLECT_STR_OPT, "proxy-id", &proxy_id, G_MARKUP_COLLECT_INVALID))
return;
extractable_type = g_type_from_name (extractable_type_name);
@ -299,7 +300,7 @@ _parse_asset (GMarkupParseContext * context, const gchar * element_name,
props = gst_structure_from_string (properties, NULL);
ges_base_xml_formatter_add_asset (GES_BASE_XML_FORMATTER (self), id,
extractable_type, props, metadatas, error);
extractable_type, props, metadatas, proxy_id, error);
if (props)
gst_structure_free (props);
}
@ -910,10 +911,10 @@ _serialize_properties (GObject * object, const gchar * fieldname, ...)
}
static inline void
_save_assets (GString * str, GESProject * project)
_save_assets (GESXmlFormatter * self, GString * str, GESProject * project)
{
char *properties, *metas;
GESAsset *asset;
GESAsset *asset, *proxy;
GList *assets, *tmp;
assets = ges_project_list_assets (project, GES_TYPE_EXTRACTABLE);
@ -923,10 +924,27 @@ _save_assets (GString * str, GESProject * project)
metas = ges_meta_container_metas_to_string (GES_META_CONTAINER (asset));
append_escaped (str,
g_markup_printf_escaped
(" <asset id='%s' extractable-type-name='%s' properties='%s' metadatas='%s' />\n",
(" <asset id='%s' extractable-type-name='%s' properties='%s' metadatas='%s' ",
ges_asset_get_id (asset),
g_type_name (ges_asset_get_extractable_type (asset)), properties,
metas));
/*TODO Save the whole list of proxies */
proxy = ges_asset_get_proxy (asset);
if (proxy) {
append_escaped (str, g_markup_printf_escaped (" proxy-id='%s' ",
ges_asset_get_id (proxy)));
if (!g_list_find (assets, proxy)) {
assets = g_list_append (assets, gst_object_ref (proxy));
if (!tmp->next)
tmp->next = g_list_last (assets);
}
self->priv->min_version = MAX (self->priv->min_version, 3);
}
g_string_append (str, "/>\n");
g_free (properties);
g_free (metas);
}
@ -1433,6 +1451,7 @@ _save (GESFormatter * formatter, GESTimeline * timeline, GError ** error)
gchar *projstr = NULL, *version;
gchar *properties = NULL, *metas = NULL;
GESXmlFormatter *self = GES_XML_FORMATTER (formatter);
GESXmlFormatterPrivate *priv;
@ -1455,10 +1474,10 @@ _save (GESFormatter * formatter, GESTimeline * timeline, GError ** error)
g_string_append (str, " </encoding-profiles>\n");
g_string_append (str, " <ressources>\n");
_save_assets (str, project);
_save_assets (self, str, project);
g_string_append (str, " </ressources>\n");
_save_timeline (GES_XML_FORMATTER (formatter), str, timeline);
_save_timeline (self, str, timeline);
g_string_append (str, "</project>\n</ges>");
projstr = g_strdup_printf ("<ges version='%i.%i'>\n", API_VERSION,

View file

@ -35,6 +35,7 @@ SUPPRESSIONS = $(top_srcdir)/common/gst.supp # $(srcdir)/gst-plugins-bad.supp
clean-local: clean-local-check
check_PROGRAMS = \
ges/asset \
ges/backgroundsource\
ges/basic \
ges/layer \

View file

@ -1,6 +1,7 @@
/* GStreamer Editing Services
*
* Copyright (C) 2012 Volodymyr Rudyi <vladimir.rudoy@gmail.com>
* Copyright (C) 2015 Thibault Saunier <tsaunier@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -18,8 +19,9 @@
* Boston, MA 02111-1307, USA.
*/
#include "../../../ges/ges-internal.h"
#include "test-utils.h"
#undef GST_CAT_DEFAULT
#include "../../../ges/ges-internal.h"
#include <ges/ges.h>
#include <gst/check/gstcheck.h>
@ -53,7 +55,7 @@ GST_START_TEST (test_basic)
GST_END_TEST;
GST_START_TEST (test_change_asset)
GST_START_TEST (test_transition_change_asset)
{
gchar *id;
GESAsset *a;
@ -96,6 +98,43 @@ GST_START_TEST (test_change_asset)
GST_END_TEST;
GST_START_TEST (test_uri_clip_change_asset)
{
GESAsset *asset, *asset1;
GESExtractable *extractable;
GESLayer *layer = ges_layer_new ();
gchar *uri = ges_test_file_uri ("audio_video.ogg");
gchar *uri1 = ges_test_file_uri ("audio_only.ogg");
GESTimeline *timeline = ges_timeline_new_audio_video ();
ges_timeline_add_layer (timeline, layer);
gst_init (NULL, NULL);
ges_init ();
asset = GES_ASSET (ges_uri_clip_asset_request_sync (uri, NULL));
fail_unless (GES_IS_ASSET (asset));
fail_unless_equals_string (ges_asset_get_id (asset), uri);
extractable = GES_EXTRACTABLE (ges_layer_add_asset (layer,
asset, 0, 0, GST_CLOCK_TIME_NONE, GES_TRACK_TYPE_UNKNOWN));
fail_unless (ges_extractable_get_asset (extractable) == asset);
gst_object_unref (asset);
/* Now try to set the a and see if the vtype is properly updated */
asset1 = GES_ASSET (ges_uri_clip_asset_request_sync (uri1, NULL));
fail_unless_equals_int (g_list_length (GES_CONTAINER_CHILDREN (extractable)),
2);
fail_unless (ges_extractable_set_asset (extractable, asset1));
fail_unless_equals_int (g_list_length (GES_CONTAINER_CHILDREN (extractable)),
1);
gst_object_unref (extractable);
}
GST_END_TEST;
GST_START_TEST (test_list_asset)
{
GList *assets;
@ -128,7 +167,8 @@ GST_START_TEST (test_proxy_asset)
nothing = ges_asset_cache_lookup (GES_TYPE_EFFECT, "nothing");
fail_unless (nothing != NULL);
fail_unless (ges_asset_set_proxy (nothing, "identity"));
fail_unless (ges_asset_try_proxy (nothing, "identity"));
fail_unless (ges_asset_set_proxy (NULL, identity));
nothing_at_all = ges_asset_request (GES_TYPE_EFFECT, "nothing_at_all", NULL);
fail_if (nothing_at_all);
@ -137,7 +177,13 @@ GST_START_TEST (test_proxy_asset)
fail_unless (nothing_at_all != NULL);
/* Now we proxy nothing_at_all to nothing which is itself proxied to identity */
fail_unless (ges_asset_set_proxy (nothing_at_all, "nothing"));
fail_unless (ges_asset_try_proxy (nothing_at_all, "nothing"));
fail_unless (ges_asset_set_proxy (NULL, nothing));
fail_unless_equals_int (g_list_length (ges_asset_list_proxies
(nothing_at_all)), 1);
fail_unless_equals_pointer (ges_asset_get_proxy_target (nothing),
nothing_at_all);
/* If we request nothing_at_all we should get the good proxied identity */
nothing_at_all = ges_asset_request (GES_TYPE_EFFECT, "nothing_at_all", NULL);
@ -161,7 +207,8 @@ ges_suite (void)
/* Must be first until we implement deinit */
tcase_add_test (tc_chain, test_list_asset);
tcase_add_test (tc_chain, test_basic);
tcase_add_test (tc_chain, test_change_asset);
tcase_add_test (tc_chain, test_transition_change_asset);
tcase_add_test (tc_chain, test_uri_clip_change_asset);
tcase_add_test (tc_chain, test_proxy_asset);
return s;