[gegl] gegl, bin: gegl_update_anim_time



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]