gstreamer/tests/check/ges/asset.c
Henry Wilkes 7f65b7be0c asset: fix handling of proxies
Previous usage of the property proxy-target seemed to alternate between
the two definitions:
+ The asset we are the default proxy of
+ The asset we are in the proxy list of
Now, the latter definition is used, which seems more useful to a user
since knowing the latter can easily allow you to find out the former.

The previous behaviour of ges_asset_set_proxy (asset, NULL) was not very
clear. It is now defined so that it clears all the proxies for 'asset'.
This means that after this call, the GESAsset:proxy property will indeed
be NULL.

Also fixed:
+ We can call ges_asset_set_proxy (asset, proxy) when 'proxy' is already
  in the proxy list of 'asset'.
+ Handling of removing the default proxy in ges_asset_unproxy. This was
  sending out the wrong notifies.
+ Prohibiting circular proxying. Before we could only prevent one case,
  we should now be able to prevent all cases. This will prevent a hang
  in ges_asset_request.
2020-03-05 17:04:51 -03:00

755 lines
25 KiB
C

/* 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
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "test-utils.h"
/* #include "../../../ges/ges-internal.h" */
#include <ges/ges.h>
#include <gst/check/gstcheck.h>
static GMainLoop *mainloop;
static void
source_asset_created (GObject * source, GAsyncResult * res,
gpointer expected_ok)
{
GError *error = NULL;
GESAsset *a = ges_asset_request_finish (res, &error);
if (GPOINTER_TO_INT (expected_ok)) {
fail_unless (a != NULL);
fail_unless (error == NULL);
g_object_unref (a);
} else {
fail_unless (a == NULL);
assert_equals_int (error->domain, GST_RESOURCE_ERROR);
}
g_clear_error (&error);
g_main_loop_quit (mainloop);
}
GST_START_TEST (test_basic)
{
ges_init ();
mainloop = g_main_loop_new (NULL, FALSE);
ges_asset_request_async (GES_TYPE_URI_CLIP,
"file:///this/is/not/for/real", NULL, source_asset_created,
GINT_TO_POINTER (FALSE));
g_main_loop_run (mainloop);
g_main_loop_unref (mainloop);
ges_deinit ();
}
GST_END_TEST;
typedef struct _CustomContextData
{
GMutex lock;
GCond cond;
gboolean finish;
gboolean expected_ok;
gchar *uri;
} CustomContextData;
static gpointer
custom_context_thread_func (CustomContextData * data)
{
GMainContext *context;
context = g_main_context_new ();
mainloop = g_main_loop_new (context, FALSE);
g_main_context_push_thread_default (context);
/* To use custom context, we need to call ges_init() in the thread */
fail_unless (ges_init ());
ges_asset_request_async (GES_TYPE_URI_CLIP,
data->uri, NULL, source_asset_created,
GINT_TO_POINTER (data->expected_ok));
g_main_loop_run (mainloop);
g_main_context_pop_thread_default (context);
ges_deinit ();
g_main_context_unref (context);
g_main_loop_unref (mainloop);
data->finish = TRUE;
g_cond_signal (&data->cond);
return NULL;
}
GST_START_TEST (test_custom_context)
{
GThread *thread;
CustomContextData data;
mainloop = NULL;
g_mutex_init (&data.lock);
g_cond_init (&data.cond);
/* ensure default context here, but we will not use the default context */
g_main_context_default ();
/* first run with invalid uri */
data.finish = FALSE;
data.expected_ok = FALSE;
data.uri = g_strdup ("file:///this/is/not/for/real");
thread = g_thread_new ("test-custom-context-thread",
(GThreadFunc) custom_context_thread_func, &data);
g_mutex_lock (&data.lock);
while (data.finish)
g_cond_wait (&data.cond, &data.lock);
g_mutex_unlock (&data.lock);
g_thread_join (thread);
g_free (data.uri);
/* second run with valid uri */
data.finish = FALSE;
data.expected_ok = TRUE;
data.uri = ges_test_file_uri ("audio_video.ogg");
thread = g_thread_new ("test-custom-context-thread",
(GThreadFunc) custom_context_thread_func, &data);
g_mutex_lock (&data.lock);
while (data.finish)
g_cond_wait (&data.cond, &data.lock);
g_mutex_unlock (&data.lock);
g_thread_join (thread);
g_free (data.uri);
g_mutex_clear (&data.lock);
g_cond_clear (&data.cond);
}
GST_END_TEST;
GST_START_TEST (test_transition_change_asset)
{
gchar *id;
GESAsset *a;
GESExtractable *extractable;
ges_init ();
a = ges_asset_request (GES_TYPE_TRANSITION_CLIP, "box-wipe-lc", NULL);
fail_unless (GES_IS_ASSET (a));
fail_unless_equals_string (ges_asset_get_id (a), "box-wipe-lc");
extractable = ges_asset_extract (a, NULL);
fail_unless (ges_extractable_get_asset (extractable) == a);
id = ges_extractable_get_id (extractable);
fail_unless_equals_string (id, "box-wipe-lc");
g_free (id);
g_object_set (extractable, "vtype", 2, NULL);
id = ges_extractable_get_id (extractable);
fail_unless_equals_string (id, "bar-wipe-tb");
g_free (id);
fail_if (ges_extractable_get_asset (extractable) == a);
gst_object_unref (a);
a = ges_extractable_get_asset (extractable);
fail_unless_equals_string (ges_asset_get_id (a), "bar-wipe-tb");
/* Now try to set the a and see if the vtype is properly updated */
a = ges_asset_request (GES_TYPE_TRANSITION_CLIP, "box-wipe-lc", NULL);
ges_extractable_set_asset (extractable, a);
gst_object_unref (a);
fail_unless_equals_int (GES_TRANSITION_CLIP (extractable)->vtype, 26);
gst_object_unref (extractable);
ges_deinit ();
}
GST_END_TEST;
GST_START_TEST (test_uri_clip_change_asset)
{
GESAsset *asset, *asset1;
GESExtractable *extractable;
GESLayer *layer;
gchar *uri;
gchar *uri1;
GESTimeline *timeline;
ges_init ();
layer = ges_layer_new ();
uri = ges_test_file_uri ("audio_video.ogg");
uri1 = ges_test_file_uri ("audio_only.ogg");
timeline = ges_timeline_new_audio_video ();
ges_timeline_add_layer (timeline, layer);
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_if (ges_extractable_set_asset (extractable, asset1));
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (extractable),
ges_uri_clip_asset_get_duration (GES_URI_CLIP_ASSET (asset1)));
fail_unless (ges_extractable_set_asset (extractable, asset1));
fail_unless_equals_int (g_list_length (GES_CONTAINER_CHILDREN (extractable)),
1);
gst_object_unref (extractable);
g_free (uri);
g_free (uri1);
ges_deinit ();
}
GST_END_TEST;
GST_START_TEST (test_list_asset)
{
GList *assets;
GEnumClass *enum_class;
ges_init ();
enum_class = g_type_class_peek (GES_VIDEO_STANDARD_TRANSITION_TYPE_TYPE);
fail_unless (ges_init ());
fail_if (ges_list_assets (GES_TYPE_OVERLAY_CLIP));
assets = ges_list_assets (GES_TYPE_TRANSITION_CLIP);
/* note: we do not have a a for value=0 "Transition not set" */
assert_equals_int (g_list_length (assets), enum_class->n_values - 1);
g_list_free (assets);
ges_deinit ();
}
GST_END_TEST;
/*
* NOTE: this test is commented out because it requires the internal
* ges_asset_finish_proxy method. This method replaces the behaviour of
* ges_asset_set_proxy (NULL, proxy), which is no longer supported.
*
* ges_asset_cache_lookup and ges_asset_try_proxy are similarly internal,
* but they are marked with GES_API in ges-internal.h
* The newer ges_asset_finish_proxy is not marked as GES_API, because it
* would add it to the symbols list, and could therefore not be easily
* removed.
*
* Once we have a nice way to call internal methods for tests, we should
* uncomment this.
*
GST_START_TEST (test_proxy_asset)
{
GESAsset *identity, *nothing, *nothing_at_all;
fail_unless (ges_init ());
identity = ges_asset_request (GES_TYPE_EFFECT, "video identity", NULL);
fail_unless (identity != NULL);
nothing = ges_asset_request (GES_TYPE_EFFECT, "nothing", NULL);
fail_if (nothing);
nothing = ges_asset_cache_lookup (GES_TYPE_EFFECT, "nothing");
fail_unless (nothing != NULL);
fail_unless (ges_asset_try_proxy (nothing, "video identity"));
fail_unless (ges_asset_finish_proxy (identity));
nothing_at_all = ges_asset_request (GES_TYPE_EFFECT, "nothing_at_all", NULL);
fail_if (nothing_at_all);
nothing_at_all = ges_asset_cache_lookup (GES_TYPE_EFFECT, "nothing_at_all");
fail_unless (nothing_at_all != NULL);
// Now we proxy nothing_at_all to nothing which is itself proxied to identity
fail_unless (ges_asset_try_proxy (nothing_at_all, "nothing"));
fail_unless (ges_asset_finish_proxy (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);
fail_unless (nothing_at_all == identity);
gst_object_unref (identity);
gst_object_unref (nothing_at_all);
ges_deinit ();
}
GST_END_TEST;
*/
static void
_count_cb (GObject * obj, GParamSpec * pspec, gpointer key)
{
guint count = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (obj), key));
g_object_set_data (G_OBJECT (obj), key, GUINT_TO_POINTER (count + 1));
}
#define _CONNECT_PROXY_SIGNALS(asset) \
g_signal_connect (asset, "notify::proxy", G_CALLBACK (_count_cb), \
(gchar *)"test-data-proxy-count"); \
g_signal_connect (asset, "notify::proxy-target", G_CALLBACK (_count_cb), \
(gchar *)"test-data-target-count");
/* test that @asset has the properties proxy = @proxy and
* proxy-target = @proxy_target
* Also check that the callback for "notify::proxy" (set up in
* _CONNECT_PROXY_SIGNALS) has been called @p_count times, and the
* callback for "notify::target-proxy" has been called @t_count times.
*/
#define _assert_proxy_state(asset, proxy, proxy_target, p_count, t_count) \
{ \
const gchar *id = ges_asset_get_id (asset); \
guint found_p_count = GPOINTER_TO_UINT (g_object_get_data ( \
G_OBJECT (asset), "test-data-proxy-count")); \
guint found_t_count = GPOINTER_TO_UINT (g_object_get_data ( \
G_OBJECT (asset), "test-data-target-count")); \
GESAsset *found_proxy = ges_asset_get_proxy (asset); \
GESAsset *found_target = ges_asset_get_proxy_target (asset); \
fail_unless (found_proxy == proxy, "Asset '%s' has the proxy '%s' " \
"rather than the expected '%s'", id, \
found_proxy ? ges_asset_get_id (found_proxy) : NULL, \
proxy ? ges_asset_get_id (proxy) : NULL); \
fail_unless (found_target == proxy_target, "Asset '%s' has the proxy " \
"target '%s' rather than the expected '%s'", id, \
found_target ? ges_asset_get_id (found_target) : NULL, \
proxy_target ? ges_asset_get_id (proxy_target) : NULL); \
fail_unless (p_count == found_p_count, "notify::proxy for asset '%s' " \
"was called %u times, rather than the expected %u times", \
id, found_p_count, p_count); \
fail_unless (t_count == found_t_count, "notify::target-proxy for " \
"asset '%s' was called %u times, rather than the expected %u times", \
id, found_t_count, t_count); \
}
#define _assert_proxy_list(asset, cmp_list) \
{ \
const gchar * id = ges_asset_get_id (asset); \
int i; \
GList *tmp; \
for (i = 0, tmp = ges_asset_list_proxies (asset); cmp_list[i] && tmp; \
i++, tmp = tmp->next) { \
GESAsset *proxy = tmp->data; \
fail_unless (proxy == cmp_list[i], "The asset '%s' has '%s' as its " \
"%ith proxy, rather than the expected '%s'", id, \
ges_asset_get_id (proxy), i, ges_asset_get_id (cmp_list[i])); \
} \
fail_unless (tmp == NULL, "Found more proxies for '%s' than expected", \
id); \
fail_unless (cmp_list[i] == NULL, "Found less proxies (%i) for '%s' " \
"than expected", i, id); \
}
#define _assert_effect_asset_request(req_id, expect) \
{ \
GESAsset *requested = ges_asset_request (GES_TYPE_EFFECT, req_id, NULL); \
fail_unless (requested == expect, "Requested asset for id '%s' is " \
"'%s' rather than the expected '%s'", req_id, \
requested ? ges_asset_get_id (requested) : NULL, \
ges_asset_get_id (expect)); \
gst_object_unref (requested); \
}
GST_START_TEST (test_proxy_setters)
{
GESAsset *proxies[] = { NULL, NULL, NULL, NULL };
GESAsset *asset, *alt_asset;
GESAsset *proxy0, *proxy1, *proxy2;
gchar asset_id[] = "video agingtv ! videobalance";
gchar alt_asset_id[] = "video gamma";
gchar proxy0_id[] = "video videobalance contrast=0.0";
gchar proxy1_id[] = "video videobalance contrast=1.0";
gchar proxy2_id[] = "video videobalance contrast=2.0";
ges_init ();
asset = ges_asset_request (GES_TYPE_EFFECT, asset_id, NULL);
alt_asset = ges_asset_request (GES_TYPE_EFFECT, alt_asset_id, NULL);
proxy0 = ges_asset_request (GES_TYPE_EFFECT, proxy0_id, NULL);
proxy1 = ges_asset_request (GES_TYPE_EFFECT, proxy1_id, NULL);
proxy2 = ges_asset_request (GES_TYPE_EFFECT, proxy2_id, NULL);
/* make sure our assets are unique */
fail_unless (asset);
fail_unless (alt_asset);
fail_unless (proxy0);
fail_unless (proxy1);
fail_unless (proxy2);
fail_unless (asset != alt_asset);
fail_unless (asset != proxy0);
fail_unless (asset != proxy1);
fail_unless (asset != proxy2);
fail_unless (alt_asset != proxy0);
fail_unless (alt_asset != proxy1);
fail_unless (alt_asset != proxy2);
fail_unless (proxy0 != proxy1);
fail_unless (proxy0 != proxy1);
fail_unless (proxy0 != proxy2);
fail_unless (proxy1 != proxy2);
_CONNECT_PROXY_SIGNALS (asset);
_CONNECT_PROXY_SIGNALS (alt_asset);
_CONNECT_PROXY_SIGNALS (proxy0);
_CONNECT_PROXY_SIGNALS (proxy1);
_CONNECT_PROXY_SIGNALS (proxy2);
/* no proxies to start with */
_assert_proxy_state (asset, NULL, NULL, 0, 0);
_assert_proxy_state (alt_asset, NULL, NULL, 0, 0);
_assert_proxy_state (proxy0, NULL, NULL, 0, 0);
_assert_proxy_state (proxy1, NULL, NULL, 0, 0);
_assert_proxy_state (proxy2, NULL, NULL, 0, 0);
_assert_proxy_list (asset, proxies);
_assert_proxy_list (alt_asset, proxies);
_assert_proxy_list (proxy0, proxies);
_assert_proxy_list (proxy1, proxies);
_assert_proxy_list (proxy2, proxies);
/* id for an asset with no proxy returns itself */
_assert_effect_asset_request (asset_id, asset);
_assert_effect_asset_request (alt_asset_id, alt_asset);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* set a proxy */
fail_unless (ges_asset_set_proxy (asset, proxy0));
_assert_proxy_state (asset, proxy0, NULL, 1, 0);
_assert_proxy_state (proxy0, NULL, asset, 0, 1);
_assert_proxy_state (proxy1, NULL, NULL, 0, 0);
_assert_proxy_state (proxy2, NULL, NULL, 0, 0);
proxies[0] = proxy0;
_assert_proxy_list (asset, proxies);
/* requesting the same asset should return the proxy instead */
_assert_effect_asset_request (asset_id, proxy0);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* can't proxy a different asset */
/* Raises ERROR */
fail_unless (ges_asset_set_proxy (alt_asset, proxy0) == FALSE);
_assert_proxy_state (alt_asset, NULL, NULL, 0, 0);
_assert_proxy_state (asset, proxy0, NULL, 1, 0);
_assert_proxy_state (proxy0, NULL, asset, 0, 1);
_assert_proxy_state (proxy1, NULL, NULL, 0, 0);
_assert_proxy_state (proxy2, NULL, NULL, 0, 0);
_assert_proxy_list (asset, proxies);
_assert_effect_asset_request (asset_id, proxy0);
_assert_effect_asset_request (proxy0_id, proxy0);
/* set the same proxy again is safe */
fail_unless (ges_asset_set_proxy (asset, proxy0));
/* notify::proxy callback count increases, even though we set the same
* proxy. This is the default behaviour for setters. */
_assert_proxy_state (asset, proxy0, NULL, 2, 0);
/* but the notify::target-proxy has not increased for the proxy */
_assert_proxy_state (proxy0, NULL, asset, 0, 1);
_assert_proxy_state (proxy1, NULL, NULL, 0, 0);
_assert_proxy_state (proxy2, NULL, NULL, 0, 0);
_assert_proxy_list (asset, proxies);
_assert_effect_asset_request (asset_id, proxy0);
_assert_effect_asset_request (proxy0_id, proxy0);
/* replace the proxy with a new one */
fail_unless (ges_asset_set_proxy (asset, proxy1));
_assert_proxy_state (asset, proxy1, NULL, 3, 0);
/* first proxy still keeps its target */
_assert_proxy_state (proxy0, NULL, asset, 0, 1);
_assert_proxy_state (proxy1, NULL, asset, 0, 1);
_assert_proxy_state (proxy2, NULL, NULL, 0, 0);
proxies[0] = proxy1;
proxies[1] = proxy0;
_assert_proxy_list (asset, proxies);
_assert_effect_asset_request (asset_id, proxy1);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* replace again */
fail_unless (ges_asset_set_proxy (asset, proxy2));
_assert_proxy_state (asset, proxy2, NULL, 4, 0);
_assert_proxy_state (proxy0, NULL, asset, 0, 1);
_assert_proxy_state (proxy1, NULL, asset, 0, 1);
_assert_proxy_state (proxy2, NULL, asset, 0, 1);
proxies[0] = proxy2;
proxies[1] = proxy1;
proxies[2] = proxy0;
_assert_proxy_list (asset, proxies);
_assert_effect_asset_request (asset_id, proxy2);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* move proxy0 back to being the default */
fail_unless (ges_asset_set_proxy (asset, proxy0));
_assert_proxy_state (asset, proxy0, NULL, 5, 0);
_assert_proxy_state (proxy0, NULL, asset, 0, 1);
_assert_proxy_state (proxy1, NULL, asset, 0, 1);
_assert_proxy_state (proxy2, NULL, asset, 0, 1);
proxies[0] = proxy0;
proxies[1] = proxy2;
proxies[2] = proxy1;
_assert_proxy_list (asset, proxies);
_assert_effect_asset_request (asset_id, proxy0);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* remove proxy2 */
fail_unless (ges_asset_unproxy (asset, proxy2));
/* notify::proxy not released since we have not switched defaults */
_assert_proxy_state (asset, proxy0, NULL, 5, 0);
_assert_proxy_state (proxy0, NULL, asset, 0, 1);
_assert_proxy_state (proxy1, NULL, asset, 0, 1);
_assert_proxy_state (proxy2, NULL, NULL, 0, 2);
proxies[0] = proxy0;
proxies[1] = proxy1;
proxies[2] = NULL;
_assert_proxy_list (asset, proxies);
_assert_effect_asset_request (asset_id, proxy0);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* make proxy2 a proxy for proxy0 */
fail_unless (ges_asset_set_proxy (proxy0, proxy2));
_assert_proxy_state (asset, proxy0, NULL, 5, 0);
_assert_proxy_state (proxy0, proxy2, asset, 1, 1);
_assert_proxy_state (proxy1, NULL, asset, 0, 1);
_assert_proxy_state (proxy2, NULL, proxy0, 0, 3);
proxies[0] = proxy0;
proxies[1] = proxy1;
proxies[2] = NULL;
_assert_proxy_list (asset, proxies);
proxies[0] = proxy2;
proxies[1] = NULL;
_assert_proxy_list (proxy0, proxies);
/* original id will now follows two proxy links to get proxy2 */
_assert_effect_asset_request (asset_id, proxy2);
_assert_effect_asset_request (proxy0_id, proxy2);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* remove proxy0 from asset, should now default to proxy1 */
fail_unless (ges_asset_unproxy (asset, proxy0));
/* notify::proxy released since we have switched defaults */
_assert_proxy_state (asset, proxy1, NULL, 6, 0);
_assert_proxy_state (proxy0, proxy2, NULL, 1, 2);
_assert_proxy_state (proxy1, NULL, asset, 0, 1);
_assert_proxy_state (proxy2, NULL, proxy0, 0, 3);
proxies[0] = proxy1;
proxies[1] = NULL;
_assert_proxy_list (asset, proxies);
proxies[0] = proxy2;
proxies[1] = NULL;
_assert_proxy_list (proxy0, proxies);
_assert_effect_asset_request (asset_id, proxy1);
_assert_effect_asset_request (proxy0_id, proxy2);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* remove proxy2 from proxy0 */
fail_unless (ges_asset_unproxy (proxy0, proxy2));
_assert_proxy_state (asset, proxy1, NULL, 6, 0);
_assert_proxy_state (proxy0, NULL, NULL, 2, 2);
_assert_proxy_state (proxy1, NULL, asset, 0, 1);
_assert_proxy_state (proxy2, NULL, NULL, 0, 4);
proxies[0] = proxy1;
proxies[1] = NULL;
_assert_proxy_list (asset, proxies);
proxies[0] = NULL;
_assert_proxy_list (proxy0, proxies);
_assert_effect_asset_request (asset_id, proxy1);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
/* make both proxy0 and proxy2 proxies of proxy1 */
fail_unless (ges_asset_set_proxy (proxy1, proxy0));
_assert_proxy_state (asset, proxy1, NULL, 6, 0);
_assert_proxy_state (proxy0, NULL, proxy1, 2, 3);
_assert_proxy_state (proxy1, proxy0, asset, 1, 1);
_assert_proxy_state (proxy2, NULL, NULL, 0, 4);
fail_unless (ges_asset_set_proxy (proxy1, proxy2));
_assert_proxy_state (asset, proxy1, NULL, 6, 0);
_assert_proxy_state (proxy0, NULL, proxy1, 2, 3);
_assert_proxy_state (proxy1, proxy2, asset, 2, 1);
_assert_proxy_state (proxy2, NULL, proxy1, 0, 5);
proxies[0] = proxy1;
proxies[1] = NULL;
_assert_proxy_list (asset, proxies);
proxies[0] = proxy2;
proxies[1] = proxy0;
proxies[2] = NULL;
_assert_proxy_list (proxy1, proxies);
_assert_effect_asset_request (asset_id, proxy2);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy2);
_assert_effect_asset_request (proxy2_id, proxy2);
/* should not be able to set up any circular proxies */
/* Raises ERROR */
fail_unless (ges_asset_set_proxy (proxy1, asset) == FALSE);
_assert_proxy_state (asset, proxy1, NULL, 6, 0);
_assert_proxy_state (proxy0, NULL, proxy1, 2, 3);
_assert_proxy_state (proxy1, proxy2, asset, 2, 1);
_assert_proxy_state (proxy2, NULL, proxy1, 0, 5);
/* Raises ERROR */
fail_unless (ges_asset_set_proxy (proxy0, asset) == FALSE);
_assert_proxy_state (asset, proxy1, NULL, 6, 0);
_assert_proxy_state (proxy0, NULL, proxy1, 2, 3);
_assert_proxy_state (proxy1, proxy2, asset, 2, 1);
_assert_proxy_state (proxy2, NULL, proxy1, 0, 5);
/* Raises ERROR */
fail_unless (ges_asset_set_proxy (proxy2, asset) == FALSE);
_assert_proxy_state (asset, proxy1, NULL, 6, 0);
_assert_proxy_state (proxy0, NULL, proxy1, 2, 3);
_assert_proxy_state (proxy1, proxy2, asset, 2, 1);
_assert_proxy_state (proxy2, NULL, proxy1, 0, 5);
/* remove last proxy from asset, should set its proxy to NULL */
fail_unless (ges_asset_unproxy (asset, proxy1));
_assert_proxy_state (asset, NULL, NULL, 7, 0);
_assert_proxy_state (proxy0, NULL, proxy1, 2, 3);
_assert_proxy_state (proxy1, proxy2, NULL, 2, 2);
_assert_proxy_state (proxy2, NULL, proxy1, 0, 5);
proxies[0] = NULL;
_assert_proxy_list (asset, proxies);
proxies[0] = proxy2;
proxies[1] = proxy0;
proxies[2] = NULL;
_assert_proxy_list (proxy1, proxies);
/* get asset back */
_assert_effect_asset_request (asset_id, asset);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy2);
_assert_effect_asset_request (proxy2_id, proxy2);
/* set the proxy property to NULL for proxy1, should remove all of
* its proxies */
fail_unless (ges_asset_set_proxy (proxy1, NULL));
_assert_proxy_state (asset, NULL, NULL, 7, 0);
/* only one notify for proxy1, but two separate ones for ex-proxies */
_assert_proxy_state (proxy0, NULL, NULL, 2, 4);
_assert_proxy_state (proxy1, NULL, NULL, 3, 2);
_assert_proxy_state (proxy2, NULL, NULL, 0, 6);
proxies[0] = NULL;
_assert_proxy_list (asset, proxies);
_assert_proxy_list (proxy0, proxies);
_assert_proxy_list (proxy1, proxies);
_assert_proxy_list (proxy2, proxies);
_assert_effect_asset_request (asset_id, asset);
_assert_effect_asset_request (proxy0_id, proxy0);
_assert_effect_asset_request (proxy1_id, proxy1);
_assert_effect_asset_request (proxy2_id, proxy2);
gst_object_unref (asset);
gst_object_unref (alt_asset);
gst_object_unref (proxy0);
gst_object_unref (proxy1);
gst_object_unref (proxy2);
ges_deinit ();
}
GST_END_TEST;
static Suite *
ges_suite (void)
{
Suite *s = suite_create ("ges");
TCase *tc_chain = tcase_create ("a");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_basic);
tcase_add_test (tc_chain, test_custom_context);
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_list_asset);
tcase_add_test (tc_chain, test_proxy_setters);
return s;
}
GST_CHECK_MAIN (ges);