[gegl] gcut: refactoring towards being seconds native



commit cc5c2047384b6c86f4b30fa8cad0fff0da9a5681
Author: Øyvind Kolås <pippin gimp org>
Date:   Thu Jul 27 13:31:29 2017 +0200

    gcut: refactoring towards being seconds native

 gcut/clip.c     |   57 ++++++++++++++++++++++++++++++++----------------------
 gcut/gcut-ui.c  |   34 +++++++++-----------------------
 gcut/gcut.c     |   33 ++++++++++++++++++++-----------
 gcut/gcut.h     |   10 +++++++++
 gcut/renderer.c |    1 +
 5 files changed, 76 insertions(+), 59 deletions(-)
---
diff --git a/gcut/clip.c b/gcut/clip.c
index a876880..c096b00 100644
--- a/gcut/clip.c
+++ b/gcut/clip.c
@@ -189,9 +189,15 @@ double clip_get_end (Clip *clip)
   return clip->end;
 }
 
+static inline double clip_fps (Clip *clip)
+{
+  if (!clip) return 0.0;
+  return clip->fps>0.01?clip->fps:clip->edl->fps;
+}
+
 double clip_get_duration (Clip *clip)
 {
-  double duration = clip_get_end (clip) - clip_get_start (clip) + 1;
+  double duration = clip_get_end (clip) - clip_get_start (clip) + 1.0/clip_fps(clip);
   if (duration < 0) duration = 0;
   if (clip->is_meta)
     return 0;
@@ -257,8 +263,8 @@ static void clip_set_proxied (Clip *clip)
     }
 }
 
-void clip_set_frame_no (Clip *clip, int clip_frame_no);
-void clip_set_frame_no (Clip *clip, int clip_frame_no)
+void clip_set_frame_no (Clip *clip, double clip_frame_no);
+void clip_set_frame_no (Clip *clip, double clip_frame_no)
 {
   if (clip_frame_no < 0)
     clip_frame_no = 0;
@@ -275,10 +281,15 @@ void clip_set_frame_no (Clip *clip, int clip_frame_no)
 
   if (!clip_is_static_source (clip))
     {
+      double fps = clip_fps (clip);
+
       if (clip->edl->use_proxies)
-        gegl_node_set (clip->proxy_loader, "frame", clip_frame_no, NULL);
+      {
+        gegl_node_set (clip->proxy_loader, "frame", (gint)(clip_frame_no * fps), NULL);
+      }
       else
-        gegl_node_set (clip->full_loader, "frame", clip_frame_no, NULL);
+        gegl_node_set (clip->full_loader, "frame", (gint)(clip_frame_no * fps), NULL);
+
     }
 }
 
@@ -348,7 +359,7 @@ void remove_in_betweens (GeglNode *nop_scaled, GeglNode *nop_filtered)
  gegl_node_link_many (nop_scaled, nop_filtered, NULL);
 }
 
-static void clip_rig_chain (Clip *clip, int clip_frame_no)
+static void clip_rig_chain (Clip *clip, double clip_pos)
 {
   GeglEDL *edl = clip->edl;
   int use_proxies = edl->use_proxies;
@@ -373,27 +384,26 @@ static void clip_rig_chain (Clip *clip, int clip_frame_no)
     else
       gegl_node_link_many (clip->chain_loader, clip->loader, NULL);
 
-    gegl_create_chain (clip->path, clip->chain_loader, clip->loader, clip_frame_no - clip->start,
+    gegl_create_chain (clip->path, clip->chain_loader, clip->loader, clip_pos - clip->start,
                        edl->height,
                        NULL, NULL);//&error);
   }
 
-      if (clip->filter_graph)
-        {
-           GError *error = NULL;
-           gegl_create_chain (clip->filter_graph, clip->nop_scaled, clip->nop_crop, clip_frame_no - 
clip->start, edl->height, NULL, &error);
-           if (error)
-             {
-               /* should set error string */
-               fprintf (stderr, "%s\n", error->message);
-               g_error_free (error);
-             }
+  if (clip->filter_graph)
+    {
+       GError *error = NULL;
+       gegl_create_chain (clip->filter_graph, clip->nop_scaled, clip->nop_crop, clip_pos - clip->start, 
edl->height, NULL, &error);
+       if (error)
+         {
+           /* should set error string */
+           fprintf (stderr, "%s\n", error->message);
+           g_error_free (error);
          }
-      /**********************************************************************/
-
+     }
+  /**********************************************************************/
 
-      // flags,..    FULL   PREVIEW   FULL_CACHE|PREVIEW  STORE_FULL_CACHE
-      clip_set_frame_no (clip, clip_frame_no);
+  // flags,..    FULL   PREVIEW   FULL_CACHE|PREVIEW  STORE_FULL_CACHE
+  clip_set_frame_no (clip, clip_pos);
   g_mutex_unlock (&clip->mutex);
 }
 
@@ -403,11 +413,9 @@ void clip_render_pos (Clip *clip, double clip_frame_pos)
   g_mutex_lock (&clip->mutex);
   gegl_node_process (clip->loader); // for the audio fetch
   clip_fetch_audio (clip);
-
   g_mutex_unlock (&clip->mutex);
 }
 
-
 gchar *clip_get_pos_hash (Clip *clip, double clip_frame_pos)
 {
   GeglEDL *edl = clip->edl;
@@ -416,6 +424,9 @@ gchar *clip_get_pos_hash (Clip *clip, double clip_frame_pos)
   GChecksum *hash;
   int is_static_source = clip_is_static_source (clip);
 
+  // quantize to clip/project fps 
+  //clip_frame_pos = ((int)(clip_frame_pos * clip_fps (clip) + 0.5))/ clip_fps (clip);
+
   frame_recipe = g_strdup_printf ("%s: %s %.3f %s %ix%i",
       "gcut-pre-4",
       clip_get_path (clip),
diff --git a/gcut/gcut-ui.c b/gcut/gcut-ui.c
index 81deb1d..6906364 100644
--- a/gcut/gcut-ui.c
+++ b/gcut/gcut-ui.c
@@ -272,12 +272,14 @@ static void drag_dropped (MrgEvent *ev, void *data1, void *data2)
 }
 static void scroll_to_fit (GeglEDL *edl, Mrg *mrg);
 
+
 static void clicked_clip (MrgEvent *e, void *data1, void *data2)
 {
   Clip *clip = data1;
   GeglEDL *edl = data2;
 
   edl->frame_pos_ui = e->x;
+  gcut_snap_ui_pos (edl);
   edl->selection_start = edl->frame_pos_ui;
   edl->selection_end = edl->frame_pos_ui;
   edl->active_clip = clip;
@@ -293,6 +295,7 @@ static void drag_clip (MrgEvent *e, void *data1, void *data2)
 {
   GeglEDL *edl = data2;
   edl->frame_pos_ui = e->x;
+  gcut_snap_ui_pos (edl);
   if (e->x >= edl->selection_start)
   {
     edl->selection_end = e->x;
@@ -331,6 +334,7 @@ static void released_clip (MrgEvent *e, void *data1, void *data2)
   Clip *clip = data1;
   GeglEDL *edl = data2;
   edl->frame_pos_ui = e->x;
+  gcut_snap_ui_pos (edl);
   edl->active_clip = clip;
   if (edl->selection_end < edl->selection_start)
   {
@@ -1511,7 +1515,7 @@ static void zoom_1 (MrgEvent *event, void *data1, void *data2)
 {
   GeglEDL *edl = data1;
   gcut_cache_invalid (edl);
-  edl->scale = 1.0;
+  edl->scale = 1.0/edl->fps;
   scroll_to_fit (edl, event->mrg);
   mrg_event_stop_propagate (event);
   mrg_queue_draw (event->mrg, NULL);
@@ -2952,6 +2956,9 @@ static void gcut_draw (Mrg     *mrg,
      int state = -1;
      int length = 0;
 
+     cairo_save (cr);
+     cairo_scale (cr, 1.0/edl->fps, 1.0);
+
      if (bitlen && ( babl_ticks() - bitticks > 1000 * 1000 * 2))
      {
        /* update cache bitmap if it is more than 2s old */
@@ -2995,6 +3002,8 @@ static void gcut_draw (Mrg     *mrg,
         }
      }
      cairo_fill (cr);
+
+     cairo_restore (cr);
   }
 
   {
@@ -3018,29 +3027,6 @@ static const char *css =
 " document { background: black; }"
 "";
 
-#if 0
-static void edit_filter_graph (MrgEvent *event, void *data1, void *data2)
-{ //XXX
-  GeglEDL *edl = data1;
-
-  //edl->active_source = NULL;
-  edl->filter_edited = !edl->filter_edited;
-  mrg_queue_draw (event->mrg, NULL);
-}
-#endif
-
-#if 0
-static void update_filter (const char *new_string, void *user_data)
-{
-  GeglEDL *edl = user_data;
-  if (edl->active_clip->filter_graph)
-    g_free (edl->active_clip->filter_graph);
-  edl->active_clip->filter_graph = g_strdup (new_string);
-  gcut_cache_invalid (edl);
-  mrg_queue_draw (edl->mrg, NULL);
-}
-#endif
-
 static void toggle_ui_mode  (MrgEvent *event, void *data1, void *data2)
 {
   GeglEDL *edl = data1;
diff --git a/gcut/gcut.c b/gcut/gcut.c
index 3244346..cdaeb9f 100644
--- a/gcut/gcut.c
+++ b/gcut/gcut.c
@@ -236,6 +236,8 @@ gchar *gcut_get_pos_hash_full (GeglEDL *edl, double pos,
   GList *l;
   double clip_start = 0;
   double prev_clip_start = 0;
+  
+  pos = gcut_snap_pos (edl->fps, pos);
 
   for (l = edl->clips; l; l = l->next)
   {
@@ -377,10 +379,13 @@ void gcut_update_buffer (GeglEDL *edl)
  */
 void gcut_set_pos (GeglEDL *edl, double pos)
 {
-  int frame = pos * edl->fps;
+  int frame;
   Clip *clip0; double clip0_pos;
   Clip *clip1; double clip1_pos;
 
+  pos = gcut_snap_pos (edl->fps, pos);
+  frame  = pos * edl->fps;
+
   if ((edl->frame) == frame && (frame != 0))
   {
     return;
@@ -1043,15 +1048,16 @@ static void process_frames_cache (GeglEDL *edl)
   int frame_no = edl->frame_pos_ui * edl->fps;
   int frame_start = frame_no;
   int duration;
+  double fragment = 1.0 / edl->fps;
 
   GList *l;
   double clip_start = 0;
 
   signal(SIGUSR2, handler1);
-  duration = gcut_get_duration (edl);
+  duration = gcut_get_duration (edl) * edl->fps;
   // TODO: use bitmap from ui to speed up check
 
-  edl->frame_pos_ui = frame_start;
+  edl->frame_pos_ui = frame_start / edl->fps;
   if (this_cacher (floor (edl->frame_pos_ui * edl->fps)))
     gcut_set_pos (edl, edl->frame_pos_ui);
    if (stop_cacher)
@@ -1062,7 +1068,7 @@ static void process_frames_cache (GeglEDL *edl)
     Clip *clip = l->data;
     double clip_duration = clip_get_duration (clip);
     int frame_pos_ui = floor (clip_start * edl->fps);
-    if (this_cacher (frame_pos_ui))
+    if (this_cacher (floor (frame_pos_ui * edl->fps)))
     {
       gcut_set_pos (edl, frame_pos_ui / edl->fps);
     }
@@ -1098,15 +1104,16 @@ static inline void set_bit (guchar *bitmap, int no)
 
 guchar *gcut_get_cache_bitmap (GeglEDL *edl, int *length_ret)
 {
-  int duration = gcut_get_duration (edl);
+  double duration = gcut_get_duration (edl);
+  int frames = duration * edl->fps;
   int frame_no;
-  int length = (duration / 8) + 1;
+  int length = (frames / 8) + 1;
   guchar *ret = g_malloc0 (length);
 
   if (length_ret)
     *length_ret = length;
 
-  for (frame_no = 0; frame_no < duration; frame_no++)
+  for (frame_no = 0; frame_no < frames; frame_no++)
   {
     const gchar *hash = gcut_get_pos_hash (edl, frame_no / edl->fps);
     gchar *path = g_strdup_printf ("%s.gcut/cache/%s", edl->parent_path, hash);
@@ -1301,7 +1308,8 @@ int main (int argc, char **argv)
   if (str_has_video_suffix (edl_path))
   {
     char str[1024];
-    int duration;
+    int frames;
+    double duration;
     double fps;
     GeglNode *gegl = gegl_node_new ();
     GeglNode *probe = gegl_node_new_child (gegl, "operation",
@@ -1309,11 +1317,12 @@ int main (int argc, char **argv)
                                            NULL);
     gegl_node_process (probe);
 
-    gegl_node_get (probe, "frames", &duration, NULL);
+    gegl_node_get (probe, "frames", &frames, NULL);
     gegl_node_get (probe, "frame-rate", &fps, NULL);
+    duration = frames / fps;
     g_object_unref (gegl);
 
-    sprintf (str, "%s 0 %i\n", edl_path, duration);
+    sprintf (str, "%s 0.0s %.3fs\n", edl_path, duration);
     {
       char * path = realpath (edl_path, NULL); 
       char * rpath = g_strdup_printf ("%s.edl", path);
@@ -1381,9 +1390,9 @@ int main (int argc, char **argv)
         gcut_free (edl);
         return 0;
       case RUNMODE_CACHE:
-        tot_frames  = gcut_get_duration (edl);
+        tot_frames = gcut_get_duration (edl) * edl->fps;
         if (edl->range_end == 0)
-          edl->range_end = tot_frames-1;
+          edl->range_end = gcut_get_duration (edl);
         process_frames_cache (edl);
         gcut_free (edl);
         return 0;
diff --git a/gcut/gcut.h b/gcut/gcut.h
index 0858c3f..76875ca 100644
--- a/gcut/gcut.h
+++ b/gcut/gcut.h
@@ -253,6 +253,16 @@ gchar *gcut_get_pos_hash_full (GeglEDL *edl, double pos,
                                double *mix);
 int gegl_make_thumb_image (GeglEDL *edl, const char *path, const char *icon_path);
 
+static inline double gcut_snap_pos (double fps, double inpos)
+{
+  return ((int)(inpos * fps + 0.5)) / fps;
+}
+
+static inline void gcut_snap_ui_pos (GeglEDL *edl)
+{
+  edl->frame_pos_ui = gcut_snap_pos (edl->fps, edl->frame_pos_ui);
+}
+
 #ifdef MICRO_RAPTOR_GUI
  /* renderer.h */
 void renderer_toggle_playing (MrgEvent *event, void *data1, void *data2);
diff --git a/gcut/renderer.c b/gcut/renderer.c
index 56910fd..f265069 100644
--- a/gcut/renderer.c
+++ b/gcut/renderer.c
@@ -274,6 +274,7 @@ void playing_iteration (Mrg *mrg, GeglEDL *edl)
            if (end)
              edl->frame_pos_ui = start;
         }
+        gcut_snap_ui_pos (edl);
         edl->active_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
         prev_ticks = ticks;
       }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]