[gegl] gegl, bin: gegl_update_anim_time
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] gegl, bin: gegl_update_anim_time
- Date: Fri, 26 Apr 2019 15:08:45 +0000 (UTC)
commit 1feb70926d36949fab6b513c4602dc0c628215a3
Author: Øyvind Kolås <pippin gimp org>
Date: Thu Apr 25 14:17:43 2019 +0200
gegl, bin: gegl_update_anim_time
This call updates all properties with associated animation key-frames to
the specified time.
bin/lua/init.lua | 2 +
bin/lua/viewer.lua | 8 ++-
bin/ui-core.c | 94 +++++++++++++++++++++-----
bin/ui-viewer.c | 15 -----
bin/ui.h | 2 +
docs/source-overview.txt | 4 +-
gegl/gegl-serialize.c | 169 +++++++++++++++++++++++++++++++++++++++--------
gegl/gegl-utils.h | 15 ++++-
8 files changed, 248 insertions(+), 61 deletions(-)
---
diff --git a/bin/lua/init.lua b/bin/lua/init.lua
index 887693f9d..03a6cc275 100644
--- a/bin/lua/init.lua
+++ b/bin/lua/init.lua
@@ -117,6 +117,8 @@ struct _GeState {
GeglNode *decode_load;
GeglNode *decode_store;
int playing;
+ double pos;
+ double duration;
int color_managed_display;
int is_video;
diff --git a/bin/lua/viewer.lua b/bin/lua/viewer.lua
index bce20d1c1..039df15d2 100644
--- a/bin/lua/viewer.lua
+++ b/bin/lua/viewer.lua
@@ -393,8 +393,8 @@ mrg:add_binding("alt-right", NULL, "next image",
mrg:add_binding("alt-left", NULL, "rev image",
function() ffi.C.argvs_eval ("prev") end)
-mrg:add_binding("control-s", NULL, "toggle slideshow",
- function() ffi.C.argvs_eval ("toggle slideshow") end)
+mrg:add_binding("control-s", NULL, "toggle playing",
+ function() ffi.C.argvs_eval ("toggle playing") end)
mrg:add_binding("control-m", NULL, "toggle mipmap",
function() ffi.C.argvs_eval ("toggle mipmap") end)
@@ -452,3 +452,7 @@ if o.show_controls ~= 0 then
end
cr:restore()
+
+if o.playing ~= 0 then
+ print 'o'
+end
diff --git a/bin/ui-core.c b/bin/ui-core.c
index 54c0c48cd..0bff68ad8 100644
--- a/bin/ui-core.c
+++ b/bin/ui-core.c
@@ -162,7 +162,6 @@ ge_state_init (GeState *o)
//o->preview_quality = 2.0;
o->slide_pause = 5.0;
o->paint_color = g_strdup ("white");
- o->slide_enabled = 0;
o->show_bindings = 0;
o->sort_order = SORT_ORDER_CUSTOM | SORT_ORDER_AZ;
o->ui_consumer = g_hash_table_new (g_direct_hash, g_direct_equal);
@@ -453,10 +452,10 @@ Setting settings[]=
INT_PROP(show_thumbbar, "show the thumbbar"),
INT_PROP(show_bounding_box, "show bounding box of active node"),
INT_PROP(show_controls, "show image viewer controls (maybe merge with show-graph and give better name)"),
- INT_PROP(slide_enabled, "slide show going"),
INT_PROP(nearest_neighbor, "nearest neighbor"),
FLOAT_PROP(slide_pause, "display scale factor"),
-
+ FLOAT_PROP(pos, "clip time position"),
+ FLOAT_PROP(duration, "clip duration, computed on load of clip"),
};
@@ -1079,6 +1078,15 @@ int mrg_ui_main (int argc, char **argv, char **ops)
return 0;
}
+int cmd_apos (COMMAND_ARGS); /* "apos", 1, "<>", "set the animation time"*/
+int
+cmd_apos (COMMAND_ARGS)
+{
+ GeState *o = global_state;
+ gegl_update_anim_time (o->sink, "output", g_strtod (argv[1], NULL));
+ return 0;
+}
+
int cmd_thumb (COMMAND_ARGS); /* "thumb", 0, "<>", "generate thumbnail for active image"*/
int
cmd_thumb (COMMAND_ARGS)
@@ -4168,6 +4176,9 @@ static void do_commandline_run (MrgEvent *event, void *data1, void *data2)
static void iterate_frame (GeState *o)
{
Mrg *mrg = o->mrg;
+ static uint32_t prev_ms = 0;
+ if (prev_ms == 0)
+ prev_ms = mrg_ms (mrg);
if (g_str_has_suffix (o->src_path, ".gif") ||
g_str_has_suffix (o->src_path, ".GIF"))
@@ -4246,6 +4257,44 @@ static void iterate_frame (GeState *o)
}
}
}
+
+ {
+ static uint32_t frame_accum = 0;
+ uint32_t ms = mrg_ms (mrg);
+ uint32_t delta = ms - prev_ms;
+
+ if (delta < 500) /* filter out any big pauses - ok for slideshow but
+ make realtime video playback more wrong, with buffering
+ that already is bad on clip change */
+ {
+ o->pos += delta/1000.0;
+
+
+ if (frame_accum > 1000 / 25) // 25fps
+ {
+ gegl_update_anim_time (o->sink, "output", o->pos);
+ frame_accum = 0;
+ }
+ frame_accum += delta;
+
+ }
+
+ if (o->pos > o->duration)
+ {
+ argvs_eval ("next");
+ }
+ else
+ {
+ fprintf (stderr, "%.3f/%.3f %f%%\n", o->pos, o->duration, 100.0*(o->pos/o->duration ));
+ }
+
+
+ mrg_queue_draw (mrg, NULL);
+
+ prev_ms = ms;
+ }
+
+
}
@@ -5472,6 +5521,12 @@ static void load_path_inner (GeState *o,
if (o->dir_scale <= 0.001)
o->dir_scale = 1.0;
o->rev = 0;
+
+ o->duration = meta_get_attribute_float (o, NULL, o->entry_no, "duration");
+ if (o->duration < 0)
+ o->duration = o->slide_pause;
+
+ o->pos = 0.0;
o->is_video = 0;
o->prev_frame_played = 0;
o->thumbbar_pan_x = 0;
@@ -5542,7 +5597,10 @@ static void load_path_inner (GeState *o,
if (is_xml_fragment (meta))
o->gegl = gegl_node_new_from_xml (meta, containing_path);
else
- o->gegl = gegl_node_new_from_serialized (meta, containing_path);
+ {
+ o->gegl = gegl_node_new_from_serialized (meta, containing_path);
+ gegl_update_anim_time (o->gegl, "output", 0.0);
+ }
g_free (containing_path);
o->sink = o->gegl;
o->source = NULL;
@@ -5615,7 +5673,7 @@ static void load_path_inner (GeState *o,
gegl_create_chain_argv (o->ops,
gegl_node_get_producer (o->sink, "input", NULL),
- o->sink, 0, gegl_node_get_bounding_box (o->sink).height,
+ o->sink, 2.1, gegl_node_get_bounding_box (o->sink).height,
containing_path,
&error);
g_free (containing_path);
@@ -5649,7 +5707,7 @@ void ui_load_path (GeState *o)
thumb_queue_item_free (item);
}
- o->playing = 0;
+ //o->playing = 0;
load_path_inner (o, o->path);
populate_path_list (o);
@@ -6460,11 +6518,19 @@ cmd_info (COMMAND_ARGS)
GeglOperation *operation;
GeglRectangle extent;
- if (o->is_dir)
{
- char *path = get_item_path (o);
+ char *path;
char **attributes = NULL;
char **keys = NULL;
+
+ if (o->is_dir)
+ {
+ path = get_item_path (o);
+ }
+ else
+ {
+ path = g_strdup (o->path);
+ }
if (!path)
return -1;
@@ -6486,8 +6552,6 @@ cmd_info (COMMAND_ARGS)
printf ("\n");
g_free (path);
-
- return 0;
}
if (!node)
@@ -6568,7 +6632,7 @@ cmd_set (COMMAND_ARGS)
return 0;
}
-int cmd_toggle (COMMAND_ARGS); /* "toggle", 1, "<editing|fullscreen|cheatsheet|mipmap|controls|slideshow>",
""*/
+int cmd_toggle (COMMAND_ARGS); /* "toggle", 1, "<editing|fullscreen|cheatsheet|mipmap|controls|playing>",
""*/
int
cmd_toggle (COMMAND_ARGS)
{
@@ -6634,12 +6698,9 @@ cmd_toggle (COMMAND_ARGS)
{
o->show_controls = !o->show_controls;
}
- else if (!strcmp(argv[1], "slideshow"))
+ else if (!strcmp(argv[1], "playing"))
{
- o->slide_enabled = !o->slide_enabled;
- if (o->slide_timeout)
- mrg_remove_idle (o->mrg, o->slide_timeout);
- o->slide_timeout = 0;
+ o->playing = !o->playing;
}
queue_draw (o);
return 0;
@@ -7121,6 +7182,7 @@ int cmd_parent (COMMAND_ARGS) /* "parent", 0, "", "enter parent collection (swit
char *lastslash = strrchr (o->path, '/');
int entry_no = 0;
+ o->playing = 0;
if (o->rev)
argvs_eval ("save");
diff --git a/bin/ui-viewer.c b/bin/ui-viewer.c
index e3f5dd4e3..74f546f8f 100644
--- a/bin/ui-viewer.c
+++ b/bin/ui-viewer.c
@@ -78,7 +78,6 @@ static int fade_thumbbar_cb (Mrg *mrg, void *data)
return 0;
}
-
static void on_thumbbar_motion (MrgEvent *e, void *data1, void *data2)
{
GeState *o = data1;
@@ -94,15 +93,6 @@ static void on_thumbbar_motion (MrgEvent *e, void *data1, void *data2)
}
}
-
-static int slide_cb (Mrg *mrg, void *data)
-{
- GeState *o = data;
- o->slide_timeout = 0;
- argvs_eval ("next");
- return 0;
-}
-
static void draw_edit (Mrg *mrg, float x, float y, float w, float h)
{
cairo_t *cr = mrg_cr (mrg);
@@ -475,11 +465,6 @@ void ui_viewer (GeState *o)
if (o->show_thumbbar)
draw_thumb_bar (o);
- if (o->slide_enabled && o->slide_timeout == 0)
- {
- o->slide_timeout =
- mrg_add_timeout (o->mrg, o->slide_pause * 1000, slide_cb, o);
- }
cairo_restore (cr);
mrg_add_binding (mrg, "control-s", NULL, NULL, ui_run_command, "toggle slideshow");
diff --git a/bin/ui.h b/bin/ui.h
index 1815f7f15..c95c57c27 100644
--- a/bin/ui.h
+++ b/bin/ui.h
@@ -143,6 +143,8 @@ struct _GeState {
GeglNode *decode_load;
GeglNode *decode_store;
int playing;
+ double pos;
+ double duration;
int color_managed_display;
int is_video;
diff --git a/docs/source-overview.txt b/docs/source-overview.txt
index ad168285d..b00d4188f 100644
--- a/docs/source-overview.txt
+++ b/docs/source-overview.txt
@@ -54,6 +54,8 @@ Source overview
│ the corresponding sourcetree with correct documentation
│ etc.
│
- ├──bin gegl binary, for processing XML compositions to png files.
+ ├──bin gegl binary, a commandline too for running chains of
+ │ operations as well as a media browser and manipulation
+ │ ui written with cairo/microraptor gui.
│
└──tools some small utilities to help the build.
diff --git a/gegl/gegl-serialize.c b/gegl/gegl-serialize.c
index eb1dea940..0571f1685 100644
--- a/gegl/gegl-serialize.c
+++ b/gegl/gegl-serialize.c
@@ -82,6 +82,122 @@ static void each_knot_rel (const GeglPathItem *path_node,
g_string_append_printf (str, "%srel ", fstr);
}
+
+void
+gegl_update_anim_time (GeglNode *node,
+ const char *output_pad,
+ gdouble time)
+{
+ GeglNode *iter = NULL;
+ if (!node)
+ return;
+ /* call recursively with producers? */
+ /* brute-force existance of animation quarks set on all relevant properties
+ * */
+ if (gegl_node_has_pad (node, "input"))
+ {
+ gchar *pad_name = NULL;
+ iter = gegl_node_get_producer (node, "input", &pad_name);
+ if (iter && pad_name)
+ gegl_update_anim_time (iter, pad_name, time);
+ if (pad_name)
+ g_free (pad_name);
+ }
+ if (gegl_node_has_pad (node, "aux"))
+ {
+ gchar *pad_name = NULL;
+ iter = gegl_node_get_producer (node, "aux", &pad_name);
+ if (iter && pad_name)
+ gegl_update_anim_time (iter, pad_name, time);
+ if (pad_name)
+ g_free (pad_name);
+ }
+
+ {
+ gint i;
+ guint n_properties;
+ GParamSpec **properties;
+
+ properties = gegl_operation_list_properties (gegl_node_get_operation (
+ node),
+ &n_properties);
+ for (i = 0; i < n_properties; i++)
+ {
+ const gchar *property_name = g_param_spec_get_name (
+ properties[i]);
+ GType property_type = G_PARAM_SPEC_VALUE_TYPE (properties[i]);
+ char tmpbuf[1024];
+ GeglPath *anim_path = NULL;
+ GQuark anim_quark;//, rel_quark;
+ sprintf (tmpbuf, "%s-anim", property_name);
+ anim_quark = g_quark_from_string (tmpbuf);
+ anim_path = g_object_get_qdata (G_OBJECT (node), anim_quark);
+
+ if (property_type == G_TYPE_FLOAT)
+ {
+ if (anim_path)
+ {
+ gdouble y;
+ gegl_path_calc_y_for_x (anim_path, time, &y);
+ gegl_node_set (node, property_name, y, NULL);
+ }
+ }
+ else if (property_type == G_TYPE_DOUBLE)
+ {
+ if (anim_path)
+ {
+ gdouble y;
+ gegl_path_calc_y_for_x (anim_path, time, &y);
+ gegl_node_set (node, property_name, y, NULL);
+ }
+ }
+ else if (property_type == G_TYPE_INT)
+ {
+ if (anim_path)
+ {
+ gdouble y;
+ gegl_path_calc_y_for_x (anim_path, time, &y);
+ gegl_node_set (node, property_name, (int)y, NULL);
+ }
+ }
+ else if (property_type == G_TYPE_UINT)
+ {
+ if (anim_path)
+ {
+ gdouble y;
+ gegl_path_calc_y_for_x (anim_path, time, &y);
+ gegl_node_set (node, property_name, (guint32)y, NULL);
+ }
+ }
+ else if (property_type == G_TYPE_BOOLEAN)
+ {
+ }
+ else if (property_type == G_TYPE_STRING)
+ {
+ }
+ else if (g_type_is_a (property_type, G_TYPE_ENUM))
+ {
+ }
+ else if (property_type == GEGL_TYPE_COLOR)
+ {
+ }
+ else if (property_type == GEGL_TYPE_PATH)
+ {
+ }
+ else if (property_type == G_TYPE_POINTER &&
+ GEGL_IS_PARAM_SPEC_FORMAT (properties[i]))
+ {
+ }
+ else
+ {
+ }
+
+ }
+ //g_free (properties);
+ }
+}
+
+
void
gegl_create_chain_argv (char **ops,
GeglNode *start,
@@ -840,30 +956,30 @@ gegl_serialize2 (GeglNode *start,
const GValue*default_value = g_param_spec_get_default_value (
properties[i]);
char tmpbuf[1024];
- GeglPath *path = NULL;
+ GeglPath *anim_path = NULL;
gboolean printed = FALSE;
char *rel_orig = NULL;
GQuark anim_quark, rel_quark;
- sprintf (tmpbuf, "%s-anim", properties[i]->name);
+ sprintf (tmpbuf, "%s-anim", property_name);
anim_quark = g_quark_from_string (tmpbuf);
- sprintf (tmpbuf, "%s-rel", properties[i]->name);
+ sprintf (tmpbuf, "%s-rel", property_name);
rel_quark = g_quark_from_string (tmpbuf);
- path = g_object_get_qdata (G_OBJECT (iter), anim_quark);
+ anim_path = g_object_get_qdata (G_OBJECT (iter), anim_quark);
rel_orig = g_object_get_qdata (G_OBJECT (iter), rel_quark);
if (property_type == G_TYPE_FLOAT)
{
gfloat defval = g_value_get_float (default_value);
gfloat value;
- gegl_node_get (iter, properties[i]->name, &value, NULL);
+ gegl_node_get (iter, property_name, &value, NULL);
- if (path)
+ if (anim_path)
{
g_string_append_printf (s2, " %s={ ", property_name);
if (rel_orig)
- gegl_path_foreach (path, each_knot_rel, s2);
+ gegl_path_foreach (anim_path, each_knot_rel, s2);
else
- gegl_path_foreach (path, each_knot, s2);
+ gegl_path_foreach (anim_path, each_knot, s2);
g_string_append_printf (s2, " } ");
}
else if (value != defval || (!trim_defaults))
@@ -883,13 +999,13 @@ gegl_serialize2 (GeglNode *start,
gdouble value;
gegl_node_get (iter, property_name, &value, NULL);
- if (path)
+ if (anim_path)
{
g_string_append_printf (s2, " %s={ ", property_name);
if (rel_orig)
- gegl_path_foreach (path, each_knot_rel, s2);
+ gegl_path_foreach (anim_path, each_knot_rel, s2);
else
- gegl_path_foreach (path, each_knot, s2);
+ gegl_path_foreach (anim_path, each_knot, s2);
g_string_append_printf (s2, " } ");
}
else if (value != defval || (!trim_defaults))
@@ -908,15 +1024,15 @@ gegl_serialize2 (GeglNode *start,
gint defval = g_value_get_int (default_value);
gint value;
gchar str[64];
- gegl_node_get (iter, properties[i]->name, &value, NULL);
+ gegl_node_get (iter, property_name, &value, NULL);
- if (path)
+ if (anim_path)
{
g_string_append_printf (s2, " %s={ ", property_name);
if (rel_orig)
- gegl_path_foreach (path, each_knot_rel, s2);
+ gegl_path_foreach (anim_path, each_knot_rel, s2);
else
- gegl_path_foreach (path, each_knot, s2);
+ gegl_path_foreach (anim_path, each_knot, s2);
g_string_append_printf (s2, " } ");
}
else if (value != defval || (!trim_defaults))
@@ -934,15 +1050,15 @@ gegl_serialize2 (GeglNode *start,
guint defval = g_value_get_uint (default_value);
guint value;
gchar str[64];
- gegl_node_get (iter, properties[i]->name, &value, NULL);
+ gegl_node_get (iter, property_name, &value, NULL);
- if (path)
+ if (anim_path)
{
g_string_append_printf (s2, " %s={ ", property_name);
if (rel_orig)
- gegl_path_foreach (path, each_knot_rel, s2);
+ gegl_path_foreach (anim_path, each_knot_rel, s2);
else
- gegl_path_foreach (path, each_knot, s2);
+ gegl_path_foreach (anim_path, each_knot, s2);
g_string_append_printf (s2, " } ");
}
else if (value != defval || (!trim_defaults))
@@ -959,7 +1075,7 @@ gegl_serialize2 (GeglNode *start,
{
gboolean value;
gboolean defval = g_value_get_boolean (default_value);
- gegl_node_get (iter, properties[i]->name, &value, NULL);
+ gegl_node_get (iter, property_name, &value, NULL);
if (value != defval || (!trim_defaults))
{
if (flags & GEGL_SERIALIZE_INDENT)
@@ -977,7 +1093,7 @@ gegl_serialize2 (GeglNode *start,
{
gchar *value;
const gchar *defval = g_value_get_string (default_value);
- gegl_node_get (iter, properties[i]->name, &value, NULL);
+ gegl_node_get (iter, property_name, &value, NULL);
if (!g_str_equal (defval, value) || (!trim_defaults))
{
if (flags & GEGL_SERIALIZE_INDENT)
@@ -994,7 +1110,7 @@ gegl_serialize2 (GeglNode *start,
gint defval = g_value_get_enum (default_value);
gint value;
- gegl_node_get (iter, properties[i]->name, &value, NULL);
+ gegl_node_get (iter, property_name, &value, NULL);
if (value != defval || (!trim_defaults))
{
GEnumValue *evalue = g_enum_get_value (eclass, value);
@@ -1011,7 +1127,7 @@ gegl_serialize2 (GeglNode *start,
GeglColor *defcolor = g_value_get_object (default_value);
gchar *value;
gchar *defvalue = NULL;
- gegl_node_get (iter, properties[i]->name, &color, NULL);
+ gegl_node_get (iter, property_name, &color, NULL);
g_object_get (color, "string", &value, NULL);
if (defcolor)
{
@@ -1033,7 +1149,7 @@ gegl_serialize2 (GeglNode *start,
{
gchar *svg_path;
GeglPath *path;
- gegl_node_get (iter, properties[i]->name, &path, NULL);
+ gegl_node_get (iter, property_name, &path, NULL);
svg_path = gegl_path_to_string (path);
g_object_unref (path);
if (flags & GEGL_SERIALIZE_INDENT)
@@ -1048,7 +1164,7 @@ gegl_serialize2 (GeglNode *start,
{
const Babl *format;
const gchar *value = "";
- gegl_node_get (iter, properties[i]->name, &format, NULL);
+ gegl_node_get (iter, property_name, &format, NULL);
if (format)
value = babl_get_name (format);
if (value[0] || (!trim_defaults))
@@ -1123,6 +1239,7 @@ gegl_node_new_from_serialized (const gchar *chaindata,
{
GeglNode *ret;
GeglNode *foo;
+ gdouble time = 0.0;
ret = gegl_node_new ();
gegl_node_set (ret, "operation", "gegl:nop", NULL);
@@ -1130,7 +1247,7 @@ gegl_node_new_from_serialized (const gchar *chaindata,
gegl_node_set (foo, "operation", "gegl:nop", NULL);
gegl_node_link_many (foo, ret, NULL);
- gegl_create_chain (chaindata, foo, ret, 0, 1024, path_root, NULL);
+ gegl_create_chain (chaindata, foo, ret, time, 1024, path_root, NULL);
return ret;
}
diff --git a/gegl/gegl-utils.h b/gegl/gegl-utils.h
index b0a43b14d..3551c2e7c 100644
--- a/gegl/gegl-utils.h
+++ b/gegl/gegl-utils.h
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
*
- * Copyright 2003 Calvin Williamson
+ * Copyright 2003-2018 GEGL contributors.
*/
@@ -92,6 +92,19 @@ GeglNode *gegl_node_new_from_serialized (const gchar *chaindata,
const gchar *path_root);
+
+/**
+ * gegl_update_anim_time:
+ * @node: a a GeglNode
+ * @output_pad: the output pad to render, pass "output" here most of the time.
+ * @time: the time to set the properties which have keyfraes attached to
+ */
+
+void gegl_update_anim_time (GeglNode *node,
+ const char *output_pad,
+ double time);
+
+
/**
* gegl_buffer_set_color:
* @buffer: a #GeglBuffer
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]