[gegl] gcut: rewrite to use seconds instead of frames as native unit
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] gcut: rewrite to use seconds instead of frames as native unit
- Date: Thu, 27 Jul 2017 18:24:23 +0000 (UTC)
commit 11579be49da1abd91261a86a5208a82707b355e7
Author: Øyvind Kolås <pippin gimp org>
Date: Tue Jul 25 00:47:45 2017 +0200
gcut: rewrite to use seconds instead of frames as native unit
gcut/clip.c | 40 +++---
gcut/gcut-ui.c | 401 ++++++++++++++++++++++++++++++-------------------------
gcut/gcut.c | 265 ++++++++++++++++++++----------------
gcut/gcut.h | 71 +++++-----
gcut/renderer.c | 27 ++--
5 files changed, 435 insertions(+), 369 deletions(-)
---
diff --git a/gcut/clip.c b/gcut/clip.c
index 4d78bd2..a876880 100644
--- a/gcut/clip.c
+++ b/gcut/clip.c
@@ -179,47 +179,47 @@ void clip_set_path (Clip *clip, const char *in_path)
}
}
-int clip_get_start (Clip *clip)
+double clip_get_start (Clip *clip)
{
return clip->start;
}
-int clip_get_end (Clip *clip)
+double clip_get_end (Clip *clip)
{
return clip->end;
}
-int clip_get_frames (Clip *clip)
+double clip_get_duration (Clip *clip)
{
- int frames = clip_get_end (clip) - clip_get_start (clip) + 1;
- if (frames < 0) frames = 0;
+ double duration = clip_get_end (clip) - clip_get_start (clip) + 1;
+ if (duration < 0) duration = 0;
if (clip->is_meta)
return 0;
- return frames;
+ return duration;
}
-void clip_set_start (Clip *clip, int start)
+void clip_set_start (Clip *clip, double start)
{
clip->start = start;
}
-void clip_set_end (Clip *clip, int end)
+void clip_set_end (Clip *clip, double end)
{
clip->end = end;
}
-void clip_set_range (Clip *clip, int start, int end)
+void clip_set_range (Clip *clip, double start, double end)
{
clip_set_start (clip, start);
clip_set_end (clip, end);
}
-void clip_set_full (Clip *clip, const char *path, int start, int end)
+void clip_set_full (Clip *clip, const char *path, double start, double end)
{
clip_set_path (clip, path);
clip_set_range (clip, start, end);
}
-Clip *clip_new_full (GeglEDL *edl, const char *path, int start, int end)
+Clip *clip_new_full (GeglEDL *edl, const char *path, double start, double end)
{
Clip *clip = clip_new (edl);
clip_set_full (clip, path, start, end);
@@ -397,18 +397,18 @@ static void clip_rig_chain (Clip *clip, int clip_frame_no)
g_mutex_unlock (&clip->mutex);
}
-void clip_render_frame (Clip *clip, int clip_frame_no)
+void clip_render_pos (Clip *clip, double clip_frame_pos)
{
- clip_rig_chain (clip, clip_frame_no);
- g_mutex_lock (&clip->mutex);
- gegl_node_process (clip->loader); // for the audio fetch
- clip_fetch_audio (clip);
+ clip_rig_chain (clip, 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);
+ g_mutex_unlock (&clip->mutex);
}
-gchar *clip_get_frame_hash (Clip *clip, int clip_frame_no)
+gchar *clip_get_pos_hash (Clip *clip, double clip_frame_pos)
{
GeglEDL *edl = clip->edl;
gchar *frame_recipe;
@@ -416,10 +416,10 @@ gchar *clip_get_frame_hash (Clip *clip, int clip_frame_no)
GChecksum *hash;
int is_static_source = clip_is_static_source (clip);
- frame_recipe = g_strdup_printf ("%s: %s %i %s %ix%i",
+ frame_recipe = g_strdup_printf ("%s: %s %.3f %s %ix%i",
"gcut-pre-4",
clip_get_path (clip),
- clip->filter_graph || (!is_static_source) ? clip_frame_no : 0,
+ clip->filter_graph || (!is_static_source) ? clip_frame_pos : 0.0,
clip->filter_graph,
edl->video_width,
edl->video_height);
diff --git a/gcut/gcut-ui.c b/gcut/gcut-ui.c
index 40e4670..7001921 100644
--- a/gcut/gcut-ui.c
+++ b/gcut/gcut-ui.c
@@ -6,6 +6,7 @@
#include <string.h>
#include <signal.h>
#include <stdio.h>
+#include <math.h>
#include <mrg.h>
#include <gegl.h>
#include "gcut.h"
@@ -165,17 +166,17 @@ static void insert_string (GeglEDL *edl, const char *string)
#endif
static void insert_clip (GeglEDL *edl, const char *path,
- int in, int out)
+ double in, double out)
{
GList *iter;
Clip *clip, *cur_clip;
- int end_frame = edl->frame_no;
- int clip_frame_no;
+ double end_pos = edl->frame_pos_ui;
+ double clip_frame_pos;
if (in < 0)
in = 0;
if (out < 0)
{
- int duration = 0;
+ double duration = 0;
if (!empty_selection (edl))
{
out = edl->selection_end - edl->selection_start;
@@ -183,7 +184,7 @@ static void insert_clip (GeglEDL *edl, const char *path,
}
else
{
- gcut_get_video_info (path, &duration, NULL);
+ gcut_get_video_info (path, NULL, &duration, NULL);
out = duration;
}
if (out < in)
@@ -191,24 +192,24 @@ static void insert_clip (GeglEDL *edl, const char *path,
}
clip = clip_new_full (edl, path, in, out);
clip->title = g_strdup (basename (path));
- cur_clip = gcut_get_clip (edl, edl->frame_no, &clip_frame_no);
+ cur_clip = gcut_get_clip (edl, edl->frame_pos_ui, &clip_frame_pos);
if (empty_selection (edl))
{
gcut_get_duration (edl);
- if (edl->frame_no != cur_clip->abs_start)
+ if (fabs (edl->frame_pos_ui - cur_clip->abs_start) < 0.001)
{
gcut_get_duration (edl);
- clip_split (cur_clip, clip_frame_no);
- cur_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ clip_split (cur_clip, clip_frame_pos);
+ cur_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
}
}
else
{
Clip *last_clip;
- int sin, sout;
- int cur_clip_frame_no;
- int last_clip_frame_no;
+ double sin, sout;
+ double cur_clip_frame_pos;
+ double last_clip_frame_pos;
sin = edl->selection_start;
sout = edl->selection_end + 1;
@@ -217,33 +218,33 @@ static void insert_clip (GeglEDL *edl, const char *path,
sout = edl->selection_start + 1;
sin = edl->selection_end;
}
- cur_clip = gcut_get_clip (edl, sin, &cur_clip_frame_no);
- clip_split (cur_clip, cur_clip_frame_no);
+ cur_clip = gcut_get_clip (edl, sin, &cur_clip_frame_pos);
+ clip_split (cur_clip, cur_clip_frame_pos);
gcut_get_duration (edl);
- cur_clip = gcut_get_clip (edl, sin, &cur_clip_frame_no);
- last_clip = gcut_get_clip (edl, sout, &last_clip_frame_no);
+ cur_clip = gcut_get_clip (edl, sin, &cur_clip_frame_pos);
+ last_clip = gcut_get_clip (edl, sout, &last_clip_frame_pos);
if (cur_clip == last_clip)
{
- clip_split (last_clip, last_clip_frame_no);
+ clip_split (last_clip, last_clip_frame_pos);
}
- last_clip = edl_get_clip_for_frame (edl, sout);
+ last_clip = edl_get_clip_for_pos (edl, sout);
- cur_clip = edl_get_clip_for_frame (edl, sin);
+ cur_clip = edl_get_clip_for_pos (edl, sin);
while (cur_clip != last_clip)
{
clip_remove (cur_clip);
- cur_clip = edl_get_clip_for_frame (edl, sin);
+ cur_clip = edl_get_clip_for_pos (edl, sin);
}
- edl->frame_no = sin;
+ edl->frame_pos_ui = sin;
}
- cur_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ cur_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
iter = g_list_find (edl->clips, cur_clip);
edl->clips = g_list_insert_before (edl->clips, iter, clip);
- end_frame += out - in + 1;
- edl->frame_no = end_frame;
+ end_pos += out - in + 1;
+ edl->frame_pos_ui = end_pos;
- edl->active_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ edl->active_clip = edl_get_clip_for_pos (edl, end_pos);
gcut_make_proxies (edl);
}
@@ -276,9 +277,9 @@ static void clicked_clip (MrgEvent *e, void *data1, void *data2)
Clip *clip = data1;
GeglEDL *edl = data2;
- edl->frame_no = e->x;
- edl->selection_start = edl->frame_no;
- edl->selection_end = edl->frame_no;
+ edl->frame_pos_ui = e->x;
+ edl->selection_start = edl->frame_pos_ui;
+ edl->selection_end = edl->frame_pos_ui;
edl->active_clip = clip;
edl->playing = 0;
scroll_to_fit (edl, e->mrg);
@@ -291,7 +292,7 @@ static void clicked_clip (MrgEvent *e, void *data1, void *data2)
static void drag_clip (MrgEvent *e, void *data1, void *data2)
{
GeglEDL *edl = data2;
- edl->frame_no = e->x;
+ edl->frame_pos_ui = e->x;
if (e->x >= edl->selection_start)
{
edl->selection_end = e->x;
@@ -329,7 +330,7 @@ static void released_clip (MrgEvent *e, void *data1, void *data2)
{
Clip *clip = data1;
GeglEDL *edl = data2;
- edl->frame_no = e->x;
+ edl->frame_pos_ui = e->x;
edl->active_clip = clip;
if (edl->selection_end < edl->selection_start)
{
@@ -379,14 +380,14 @@ static void prev_cut (MrgEvent *event, void *data1, void *data2)
if (iter)
{
- if (edl->frame_no == edl->active_clip->abs_start)
+ if (fabs (edl->frame_pos_ui - edl->active_clip->abs_start) < 0.001)
{
iter = iter->prev;
if (iter) edl->active_clip = iter->data;
}
}
- edl->frame_no = edl->active_clip->abs_start;
- edl->selection_start = edl->selection_end = edl->frame_no;
+ edl->frame_pos_ui = edl->active_clip->abs_start;
+ edl->selection_start = edl->selection_end = edl->frame_pos_ui;
}
mrg_event_stop_propagate (event);
scroll_to_fit (edl, event->mrg);
@@ -405,16 +406,16 @@ static void next_cut (MrgEvent *event, void *data1, void *data2)
if (iter)
{
edl->active_clip = iter->data;
- edl->frame_no = edl->active_clip->abs_start;
+ edl->frame_pos_ui = edl->active_clip->abs_start;
}
else
{
- edl->frame_no = edl->active_clip->abs_start + clip_get_frames (edl->active_clip);
+ edl->frame_pos_ui = edl->active_clip->abs_start + clip_get_duration (edl->active_clip);
}
}
mrg_event_stop_propagate (event);
mrg_queue_draw (event->mrg, NULL);
- edl->selection_start = edl->selection_end = edl->frame_no;
+ edl->selection_start = edl->selection_end = edl->frame_pos_ui;
scroll_to_fit (edl, event->mrg);
changed++;
}
@@ -422,12 +423,12 @@ static void next_cut (MrgEvent *event, void *data1, void *data2)
static void extend_selection_to_previous_cut (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
- int sel_start, sel_end;
- edl->active_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ double sel_start, sel_end;
+ edl->active_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
gcut_get_selection (edl, &sel_start, &sel_end);
prev_cut (event, data1, data2);
- sel_start = edl->frame_no;
+ sel_start = edl->frame_pos_ui;
gcut_set_selection (edl, sel_start, sel_end);
mrg_event_stop_propagate (event);
@@ -439,11 +440,11 @@ static void extend_selection_to_previous_cut (MrgEvent *event, void *data1, void
static void extend_selection_to_next_cut (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
- int sel_start, sel_end;
+ double sel_start, sel_end;
gcut_get_selection (edl, &sel_start, &sel_end);
next_cut (event, data1, data2);
- sel_start = edl->frame_no;
+ sel_start = edl->frame_pos_ui;
gcut_set_selection (edl, sel_start, sel_end);
mrg_event_stop_propagate (event);
@@ -451,27 +452,35 @@ static void extend_selection_to_next_cut (MrgEvent *event, void *data1, void *da
changed++;
}
+static inline int float_eq(double a, double b)
+{
+ if (fabs(a-b) < 0.0001)
+ return 1;
+ return 0;
+}
+
static void extend_selection_to_the_left (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
- int sel_start, sel_end;
+ double sel_start, sel_end;
+ double fragment = 1.0 / edl->fps;
gcut_get_selection (edl, &sel_start, &sel_end);
- if (edl->frame_no == sel_end)
+ if (float_eq (edl->frame_pos_ui, sel_end))
{
- sel_end --;
- edl->frame_no --;
+ sel_end -= fragment;
+ edl->frame_pos_ui -= fragment;
}
- else if (edl->frame_no == sel_start)
+ else if (float_eq (edl->frame_pos_ui, sel_start))
{
- sel_start --;
- edl->frame_no --;
+ sel_start -= fragment;
+ edl->frame_pos_ui -= fragment;
}
else
{
- sel_start = sel_end = edl->frame_no;
- sel_end --;
- edl->frame_no --;
+ sel_start = sel_end = edl->frame_pos_ui;
+ sel_end -= fragment;
+ edl->frame_pos_ui -= fragment;
}
gcut_set_selection (edl, sel_start, sel_end);
@@ -484,24 +493,26 @@ static void extend_selection_to_the_left (MrgEvent *event, void *data1, void *da
static void extend_selection_to_the_right (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
- int sel_start, sel_end;
+ gdouble sel_start, sel_end;
+
+ double fragment = 1.0 / edl->fps;
gcut_get_selection (edl, &sel_start, &sel_end);
- if (edl->frame_no == sel_end)
+ if (float_eq (edl->frame_pos_ui, sel_end))
{
- sel_end ++;
- edl->frame_no ++;
+ sel_end += fragment;
+ edl->frame_pos_ui += fragment;
}
- else if (edl->frame_no == sel_start)
+ else if (float_eq (edl->frame_pos_ui, sel_start))
{
- sel_start ++;
- edl->frame_no ++;
+ sel_start += fragment;
+ edl->frame_pos_ui += fragment;
}
else
{
- sel_start = sel_end = edl->frame_no;
- sel_end ++;
- edl->frame_no ++;
+ sel_start = sel_end = edl->frame_pos_ui;
+ sel_end += fragment;
+ edl->frame_pos_ui += fragment;
}
gcut_set_selection (edl, sel_start, sel_end);
@@ -511,17 +522,22 @@ static void extend_selection_to_the_right (MrgEvent *event, void *data1, void *d
}
static int ui_tweaks = 0;
-static int are_mergable (Clip *clip1, Clip *clip2, int delta)
+static int are_mergable (Clip *clip1, Clip *clip2, double delta)
{
+ GeglEDL *edl;
+ double fragment;
if (!clip1 || !clip2)
return 0;
+ edl = clip1->edl;
+ fragment = 1.0 / edl->fps;
+
if (!clip1->path)
return 0;
if (!clip2->path)
return 0;
if (strcmp (clip1->path, clip2->path))
return 0;
- if (clip2->start != (clip1->end + 1 + delta))
+ if (!float_eq (clip2->start, (clip1->end + fragment + delta)))
return 0;
if (clip1->filter_graph==NULL && clip2->filter_graph != NULL)
return 0;
@@ -545,7 +561,7 @@ static void clip_remove (Clip *clip)
return;
edl->clips = g_list_remove (edl->clips, clip);
- edl->active_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ edl->active_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
}
static GeglNode *selected_node = NULL;
@@ -753,8 +769,8 @@ static void clip_split (Clip *oldclip, int shift)
static void split_clip (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
- int clip_frame_no = 0;
- Clip *clip = gcut_get_clip (edl, edl->frame_no, &clip_frame_no);
+ double clip_frame_pos = 0;
+ Clip *clip = gcut_get_clip (edl, edl->frame_pos_ui, &clip_frame_pos);
if (!edl->active_clip)
return;
@@ -764,7 +780,7 @@ static void split_clip (MrgEvent *event, void *data1, void *data2)
return;
}
- clip_split (edl->active_clip, clip_frame_no);
+ clip_split (edl->active_clip, clip_frame_pos);
{
//edl->active_clip = clip;
}
@@ -853,7 +869,7 @@ static gboolean save_idle (Mrg *mrg, gpointer edl)
static void set_range (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
- int start, end;
+ double start, end;
gcut_get_selection (edl, &start, &end);
gcut_set_range (edl, start, end);
@@ -968,13 +984,14 @@ static void down (MrgEvent *event, void *data1, void *data2)
static void step_frame_back (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
+ double fragment = 1.0 / edl->fps;
stop_playing (event, data1, data2);
{
edl->selection_start = edl->selection_end;
- edl->frame_no --;
- if (edl->frame_no < 0)
- edl->frame_no = 0;
- edl->active_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ edl->frame_pos_ui -= fragment;
+ if (edl->frame_pos_ui < 0)
+ edl->frame_pos_ui = 0;
+ edl->active_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
}
mrg_event_stop_propagate (event);
mrg_queue_draw (event->mrg, NULL);
@@ -984,11 +1001,12 @@ static void step_frame_back (MrgEvent *event, void *data1, void *data2)
static void step_frame (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
+ double fragment = 1.0 / edl->fps;
stop_playing (event, data1, data2);
{
edl->selection_start = edl->selection_end;
- edl->frame_no ++;
- edl->active_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ edl->frame_pos_ui += fragment;
+ edl->active_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
}
mrg_event_stop_propagate (event);
mrg_queue_draw (event->mrg, NULL);
@@ -999,21 +1017,23 @@ static void clip_end_start_dec (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
Clip *clip1, *clip2;
+ double fragment = 1.0 / edl->fps;
if (edl->selection_start < edl->selection_end)
{
- clip1 = edl_get_clip_for_frame (edl, edl->selection_start);
- clip2 = edl_get_clip_for_frame (edl, edl->selection_end);
+ clip1 = edl_get_clip_for_pos (edl, edl->selection_start);
+ clip2 = edl_get_clip_for_pos (edl, edl->selection_end);
}
else
{
- clip1 = edl_get_clip_for_frame (edl, edl->selection_end);
- clip2 = edl_get_clip_for_frame (edl, edl->selection_start);
+ clip1 = edl_get_clip_for_pos (edl, edl->selection_end);
+ clip2 = edl_get_clip_for_pos (edl, edl->selection_start);
}
- edl->selection_start--;
- edl->selection_end--;
- clip1->end--;
- clip2->start--;
- edl->frame_no--;
+ edl->selection_start-= fragment;
+ edl->selection_end-= fragment;
+ clip1->end-= fragment;
+ clip2->start-= fragment;
+ edl->frame_pos_ui -= fragment;
+
gcut_cache_invalid (edl);
mrg_event_stop_propagate (event);
mrg_queue_draw (event->mrg, NULL);
@@ -1023,21 +1043,23 @@ static void clip_end_start_inc (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
Clip *clip1, *clip2;
+ double fragment = 1.0 / edl->fps;
+
if (edl->selection_start < edl->selection_end)
{
- clip1 = edl_get_clip_for_frame (edl, edl->selection_start);
- clip2 = edl_get_clip_for_frame (edl, edl->selection_end);
+ clip1 = edl_get_clip_for_pos (edl, edl->selection_start);
+ clip2 = edl_get_clip_for_pos (edl, edl->selection_end);
}
else
{
- clip1 = edl_get_clip_for_frame (edl, edl->selection_end);
- clip2 = edl_get_clip_for_frame (edl, edl->selection_start);
+ clip1 = edl_get_clip_for_pos (edl, edl->selection_end);
+ clip2 = edl_get_clip_for_pos (edl, edl->selection_start);
}
- edl->selection_start++;
- edl->selection_end++;
- clip1->end++;
- clip2->start++;
- edl->frame_no++;
+ edl->selection_start+=fragment;
+ edl->selection_end+=fragment;
+ clip1->end+=fragment;
+ clip2->start+=fragment;
+ edl->frame_pos_ui +=fragment;
gcut_cache_invalid (edl);
mrg_event_stop_propagate (event);
@@ -1073,10 +1095,12 @@ static void clip_start_end_dec (MrgEvent *event, void *data1, void *data2)
static void clip_end_inc (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
+ double fragment = 1.0 / edl->fps;
+
if (edl->active_clip)
{
- edl->active_clip->end++;
- edl->frame_no++;
+ edl->active_clip->end+=fragment;
+ edl->frame_pos_ui +=fragment;
}
gcut_cache_invalid (edl);
mrg_event_stop_propagate (event);
@@ -1086,10 +1110,12 @@ static void clip_end_inc (MrgEvent *event, void *data1, void *data2)
static void clip_end_dec (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
+ double fragment = 1.0 / edl->fps;
+
if (edl->active_clip)
{
- edl->active_clip->end--;
- edl->frame_no--;
+ edl->active_clip->end-=fragment;
+ edl->frame_pos_ui -=fragment;
gcut_cache_invalid (edl);
}
mrg_event_stop_propagate (event);
@@ -1100,9 +1126,10 @@ static void clip_end_dec (MrgEvent *event, void *data1, void *data2)
static void clip_start_inc (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
+ double fragment = 1.0 / edl->fps;
if (edl->active_clip)
{
- edl->active_clip->start++;
+ edl->active_clip->start+= fragment;
gcut_cache_invalid (edl);
}
mrg_event_stop_propagate (event);
@@ -1112,9 +1139,10 @@ static void clip_start_inc (MrgEvent *event, void *data1, void *data2)
static void clip_start_dec (MrgEvent *event, void *data1, void *data2)
{
GeglEDL *edl = data1;
+ double fragment = 1.0 / edl->fps;
if (edl->active_clip)
{
- edl->active_clip->start--;
+ edl->active_clip->start-=fragment;
gcut_cache_invalid (edl);
}
mrg_event_stop_propagate (event);
@@ -1234,10 +1262,10 @@ static void render_clip (Mrg *mrg, GeglEDL *edl, const char *clip_path, int clip
static void scroll_to_fit (GeglEDL *edl, Mrg *mrg)
{
/* scroll to fit playhead */
- if ( (edl->frame_no - edl->t0) / edl->scale > mrg_width (mrg) * 0.9)
- edl->t0 = edl->frame_no - (mrg_width (mrg) * 0.8) * edl->scale;
- else if ( (edl->frame_no - edl->t0) / edl->scale < mrg_width (mrg) * 0.1)
- edl->t0 = edl->frame_no - (mrg_width (mrg) * 0.2) * edl->scale;
+ if ( (edl->frame_pos_ui - edl->t0) / edl->scale > mrg_width (mrg) * 0.9)
+ edl->t0 = edl->frame_pos_ui - (mrg_width (mrg) * 0.8) * edl->scale;
+ else if ( (edl->frame_pos_ui - edl->t0) / edl->scale < mrg_width (mrg) * 0.1)
+ edl->t0 = edl->frame_pos_ui - (mrg_width (mrg) * 0.2) * edl->scale;
}
static void shuffle_forward (MrgEvent *event, void *data1, void *data2)
@@ -1266,7 +1294,7 @@ static void shuffle_forward (MrgEvent *event, void *data1, void *data2)
self->next = nextnext;
if (self->next)
self->next->prev = self;
- edl->frame_no += clip_get_frames (next->data);
+ edl->frame_pos_ui += clip_get_duration (next->data);
}
}
@@ -1304,7 +1332,7 @@ static void shuffle_back (MrgEvent *event, void *data1, void *data2)
if (next)
next->prev = prev;
- edl->frame_no -= clip_get_frames (prev->data);
+ edl->frame_pos_ui -= clip_get_duration (prev->data);
}
}
@@ -1320,7 +1348,7 @@ static void slide_forward (MrgEvent *event, void *data1, void *data2)
GList *prev = NULL,
*next = NULL, *self;
- edl->active_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ edl->active_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
self = g_list_find (edl->clips, edl->active_clip);
gcut_cache_invalid (edl);
@@ -1335,6 +1363,7 @@ static void slide_forward (MrgEvent *event, void *data1, void *data2)
if (self)
{
+ double fragment = 1.0 / edl->fps;
next = self->next;
prev = self->prev;
@@ -1346,44 +1375,44 @@ static void slide_forward (MrgEvent *event, void *data1, void *data2)
if (are_mergable (prev_clip, next_clip, 0))
{
- if (clip_get_frames (next_clip) == 1)
+ if (float_eq (clip_get_duration (next_clip), fragment))
{
- prev_clip->end++;
+ prev_clip->end+=fragment;
edl->clips = g_list_remove (edl->clips, next_clip);
- edl->frame_no ++;
+ edl->frame_pos_ui += fragment;
}
else
{
- prev_clip->end ++;
- next_clip->start ++;
- edl->frame_no ++;
+ prev_clip->end += fragment;
+ next_clip->start += fragment;
+ edl->frame_pos_ui += fragment;
}
- } else if (are_mergable (prev_clip, next_clip, clip_get_frames (self_clip)))
+ } else if (are_mergable (prev_clip, next_clip, clip_get_duration (self_clip)))
{
- if (clip_get_frames (next_clip) == 1)
+ if (float_eq (clip_get_duration (next_clip), fragment))
{
- prev_clip->end++;
+ prev_clip->end += fragment;
edl->clips = g_list_remove (edl->clips, next_clip);
- edl->frame_no ++;
+ edl->frame_pos_ui += fragment;
}
else
{
- prev_clip->end ++;
- next_clip->start ++;
- edl->frame_no ++;
+ prev_clip->end += fragment;
+ next_clip->start += fragment;
+ edl->frame_pos_ui += fragment;
}
}
else {
- if (clip_get_frames (next_clip) == 1)
+ if (float_eq (clip_get_duration (next_clip), fragment))
{
- int frame_no = edl->frame_no + 1;
+ double frame_pos = edl->frame_pos_ui + fragment;
shuffle_forward (event, data1, data2);
- edl->frame_no = frame_no;
+ edl->frame_pos_ui = frame_pos;
} else {
- int frame_no = edl->frame_no + 1;
- clip_split (next_clip, next_clip->start + 1);
+ double frame_pos = edl->frame_pos_ui + fragment;
+ clip_split (next_clip, next_clip->start + fragment);
shuffle_forward (event, data1, data2);
- edl->frame_no = frame_no;
+ edl->frame_pos_ui = frame_pos;
}
}
}
@@ -1402,7 +1431,7 @@ static void slide_back (MrgEvent *event, void *data1, void *data2)
*next = NULL,
*self;
- edl->active_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ edl->active_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
self = g_list_find (edl->clips, edl->active_clip);
gcut_cache_invalid (edl);
@@ -1417,6 +1446,7 @@ static void slide_back (MrgEvent *event, void *data1, void *data2)
if (self)
{
+ double fragment = 1.0 / edl->fps;
next = self->next;
prev = self->prev;
@@ -1428,45 +1458,45 @@ static void slide_back (MrgEvent *event, void *data1, void *data2)
if (are_mergable (prev_clip, next_clip, 0))
{
- if (clip_get_frames (prev_clip) == 1)
+ if (float_eq (clip_get_duration (prev_clip), fragment))
{
- next_clip->start --;
+ next_clip->start -= fragment;
edl->clips = g_list_remove (edl->clips, prev_clip);
- edl->frame_no --;
+ edl->frame_pos_ui -= fragment;
}
else
{
- prev_clip->end --;
- next_clip->start --;
- edl->frame_no --;
+ prev_clip->end -= fragment;
+ next_clip->start -= fragment;
+ edl->frame_pos_ui -= fragment;
}
- } else if (are_mergable (prev_clip, next_clip, clip_get_frames (self_clip)))
+ } else if (are_mergable (prev_clip, next_clip, clip_get_duration (self_clip)))
{
- if (clip_get_frames (prev_clip) == 1)
+ if (float_eq (clip_get_duration (prev_clip), fragment))
{
- prev_clip->end--;
+ prev_clip->end-= fragment;
edl->clips = g_list_remove (edl->clips, prev_clip);
- edl->frame_no --;
+ edl->frame_pos_ui -= fragment;
}
else
{
- prev_clip->end --;
- next_clip->start --;
- edl->frame_no --;
+ prev_clip->end -= fragment;
+ next_clip->start -= fragment;
+ edl->frame_pos_ui -= fragment;
}
}
else
{
- if (clip_get_frames (prev_clip) == 1)
+ if (float_eq (clip_get_duration (prev_clip), fragment))
{
- int frame_no = edl->frame_no - 1;
+ double frame_pos = edl->frame_pos_ui - fragment;
shuffle_back (event, data1, data2);
- edl->frame_no = frame_no;
+ edl->frame_pos_ui = frame_pos;
} else {
- int frame_no = edl->frame_no - 1;
+ double frame_pos = edl->frame_pos_ui - fragment;
clip_split (prev_clip, prev_clip->end );
shuffle_back (event, data1, data2);
- edl->frame_no = frame_no;
+ edl->frame_pos_ui = frame_pos;
}
}
}
@@ -1589,7 +1619,7 @@ static void jump_to_pos (MrgEvent *e, void *data1, void *data2)
gint pos = GPOINTER_TO_INT(data2);
fprintf (stderr, "set frame %i\n", pos);
- edl->frame_no = pos;
+ edl->frame_pos_ui = pos;
mrg_event_stop_propagate (e);
mrg_queue_draw (e->mrg, NULL);
}
@@ -1700,9 +1730,9 @@ static void remove_key (MrgEvent *e, void *data1, void *data2)
GeglPath *path = g_object_get_qdata (G_OBJECT (node), anim_quark);
int nodes = gegl_path_get_n_nodes (path);
int i;
- int clip_frame_no=0;
+ double clip_frame_pos=0;
GeglPathItem path_item;
- gcut_get_clip (edl, edl->frame_no, &clip_frame_no);
+ gcut_get_clip (edl, edl->frame_pos_ui, &clip_frame_pos);
for (i = 0; i < nodes; i ++)
{
@@ -1775,30 +1805,31 @@ static void update_double_string (const char *new_string, void *user_data)
GeglPath *path = g_object_get_qdata (G_OBJECT (snode), anim_quark);
int nodes = gegl_path_get_n_nodes (path);
int i;
- int clip_frame_no=0;
+ double clip_frame_pos=0;
+ double fragment = 1.0 / edl->fps;
GeglPathItem path_item;
- gcut_get_clip (edl, edl->frame_no, &clip_frame_no);
+ gcut_get_clip (edl, edl->frame_pos_ui, &clip_frame_pos);
for (i = 0; i < nodes; i ++)
{
gegl_path_get_node (path, i, &path_item);
- if (fabs (path_item.point[0].x - clip_frame_no) < 0.5)
+ if (fabs (path_item.point[0].x - clip_frame_pos) < 0.5 * fragment)
{
- path_item.point[0].x = clip_frame_no;
+ path_item.point[0].x = clip_frame_pos;
path_item.point[0].y = val;
gegl_path_replace_node (path, i, &path_item);
goto done;
}
- else if (path_item.point[0].x > clip_frame_no)
+ else if (path_item.point[0].x > clip_frame_pos)
{
- path_item.point[0].x = clip_frame_no;
+ path_item.point[0].x = clip_frame_pos;
path_item.point[0].y = val;
gegl_path_insert_node (path, i - 1, &path_item);
goto done;
}
}
path_item.type = 'L';
- path_item.point[0].x = clip_frame_no;
+ path_item.point[0].x = clip_frame_pos;
path_item.point[0].y = val;
gegl_path_insert_node (path, -1, &path_item);
done:
@@ -2056,8 +2087,8 @@ static float print_props (Mrg *mrg, GeglEDL *edl, GeglNode *node, float x, float
{
cairo_t *cr = mrg_cr (mrg);
GeglPath *path = g_object_get_qdata (G_OBJECT (node), anim_quark);
- int clip_frame_no;
- gcut_get_clip (edl, edl->frame_no, &clip_frame_no);
+ double clip_frame_pos;
+ gcut_get_clip (edl, edl->frame_pos_ui, &clip_frame_pos);
mrg_printf (mrg, "{anim}");
{
GeglPathItem path_item;
@@ -2066,13 +2097,13 @@ static float print_props (Mrg *mrg, GeglEDL *edl, GeglNode *node, float x, float
for (j = 0 ; j < nodes; j ++)
{
gegl_path_get_node (path, j, &path_item);
- if (fabs (path_item.point[0].x - clip_frame_no) < 0.5)
+ if (fabs (path_item.point[0].x - clip_frame_pos) < 0.5)
{
gpointer *data = g_new0 (gpointer, 4);
data[0]=edl;
data[1]=node;
data[2]=(void*)g_intern_string(props[i]->name);
- data[3]=GINT_TO_POINTER(clip_frame_no);
+ data[3]=GINT_TO_POINTER(clip_frame_pos);
mrg_text_listen_full (mrg, MRG_CLICK, remove_key, data, node, (void*)g_free, NULL);
mrg_printf (mrg, "(key)");
mrg_text_listen_done (mrg);
@@ -2090,7 +2121,8 @@ static float print_props (Mrg *mrg, GeglEDL *edl, GeglNode *node, float x, float
mrg_height (mrg) * SPLIT_VER);
{
- int j;
+ double j;
+ double fragment =1.0 / edl->fps;
gdouble y = 0.0;
gdouble miny = 100000.0;
gdouble maxy = -100000.0;
@@ -2098,7 +2130,7 @@ static float print_props (Mrg *mrg, GeglEDL *edl, GeglNode *node, float x, float
// todo: draw markers for zero, min and max, with labels
// do all curves in one scaled space? - will break for 2 or more magnitudes diffs
- for (j = -10; j < clip_get_frames (edl->active_clip) + 10; j ++)
+ for (j = -1.0; j < clip_get_duration (edl->active_clip) + 1.0; j += fragment)
{
gegl_path_calc_y_for_x (path, j, &y);
if (y < miny) miny = y;
@@ -2109,7 +2141,7 @@ static float print_props (Mrg *mrg, GeglEDL *edl, GeglNode *node, float x, float
gegl_path_calc_y_for_x (path, 0, &y);
y = VID_HEIGHT * 0.9 - ((y - miny) / (maxy - miny)) * VID_HEIGHT * 0.8;
cairo_move_to (cr, 0, y);
- for (j = -10; j < clip_get_frames (edl->active_clip) + 10; j ++)
+ for (j = -1.0; j < clip_get_duration (edl->active_clip) + 1.0; j += fragment)
{
gegl_path_calc_y_for_x (path, j, &y);
y = VID_HEIGHT * 0.9 - ((y - miny) / (maxy - miny)) * VID_HEIGHT * 0.8;
@@ -2653,7 +2685,7 @@ static void update_ui_clip (Clip *clip, int clip_frame_no)
if (clip->is_chain)
gegl_create_chain (clip->path, source_start, source_end,
- clip->edl->frame_no - clip->abs_start,
+ clip->edl->frame_pos_ui - clip->abs_start,
1.0, NULL, &error);
filter_start = gegl_node_new ();
@@ -2666,7 +2698,7 @@ static void update_ui_clip (Clip *clip, int clip_frame_no)
if (clip->filter_graph)
{
gegl_create_chain (clip->filter_graph, filter_start, filter_end,
- clip->edl->frame_no - clip->abs_start,
+ clip->edl->frame_pos_ui - clip->abs_start,
1.0, NULL, &error);
}
ui_clip = clip;
@@ -2751,7 +2783,7 @@ static void gcut_draw (Mrg *mrg,
GList *l;
cairo_t *cr = mrg_cr (mrg);
double t;
- int clip_frame_no;
+ double clip_frame_pos;
int scroll_height = mrg_height (mrg) * (1.0 - SPLIT_VER) * 0.2;
int duration = gcut_get_duration (edl); // causes update of abs_start
float y2 = y - mrg_em (mrg) * 1.5;
@@ -2763,13 +2795,13 @@ static void gcut_draw (Mrg *mrg,
return;
- edl->active_clip = gcut_get_clip (edl, edl->frame_no, &clip_frame_no);
+ edl->active_clip = gcut_get_clip (edl, edl->frame_pos_ui, &clip_frame_pos);
if (edl->active_clip) // && edl->active_clip->filter_graph)
{
Clip *clip = edl->active_clip;
- update_ui_clip (clip, clip_frame_no);
+ update_ui_clip (clip, clip_frame_pos);
mrg_set_style (mrg, "font-size: 2.5%; background-color: #0000; color: #ffff");
@@ -2823,14 +2855,14 @@ static void gcut_draw (Mrg *mrg,
for (l = edl->clips; l; l = l->next)
{
Clip *clip = l->data;
- int frames = clip_get_frames (clip);
- cairo_rectangle (cr, t, y, frames, scroll_height);
+ double duration = clip_get_duration (clip);
+ cairo_rectangle (cr, t, y, duration, scroll_height);
cairo_stroke (cr);
- t += frames;
+ t += duration;
}
{
- int start = 0, end = 0;
+ double start = 0, end = 0;
gcut_get_range (edl, &start, &end);
cairo_rectangle (cr, start, y, end - start, scroll_height);
cairo_set_source_rgba (cr, 0, 0.11, 0.0, 0.5);
@@ -2839,11 +2871,12 @@ static void gcut_draw (Mrg *mrg,
cairo_stroke (cr);
{
- double frame = edl->frame_no;
+ double pos = edl->frame_pos_ui;
+ double fragment = 1.0 / edl->fps;
if (fpx < 1.0)
- cairo_rectangle (cr, frame, y-5, 1.0, 5 + scroll_height);
+ cairo_rectangle (cr, pos, y-5, fragment, 5 + scroll_height);
else
- cairo_rectangle (cr, frame, y-5, fpx, 5 + scroll_height);
+ cairo_rectangle (cr, pos, y-5, fpx, 5 + scroll_height);
cairo_set_source_rgba (cr,1,0,0,0.85);
cairo_fill (cr);
}
@@ -2872,7 +2905,7 @@ static void gcut_draw (Mrg *mrg,
for (l = edl->clips; l; l = l->next)
{
Clip *clip = l->data;
- int frames = clip_get_frames (clip);
+ double duration = clip_get_duration (clip);
if (clip->is_meta)
{
double tx = t, ty = y;
@@ -2886,7 +2919,7 @@ static void gcut_draw (Mrg *mrg,
else
{
Clip *next = clip_get_next (clip);
- render_clip (mrg, edl, clip->path, clip->start, frames, t, y, clip->fade, next?next->fade:0);
+ render_clip (mrg, edl, clip->path, clip->start, duration, t, y, clip->fade, next?next->fade:0);
/* .. check if we are having anim things going on.. if so - print it here */
}
@@ -2900,7 +2933,7 @@ static void gcut_draw (Mrg *mrg,
mrg_listen (mrg, MRG_RELEASE, released_clip, clip, edl);
cairo_stroke (cr);
- t += frames;
+ t += duration;
}
if (!edl->playing){
@@ -2957,11 +2990,12 @@ static void gcut_draw (Mrg *mrg,
}
{
- double frame = edl->frame_no;
+ double pos = edl->frame_pos_ui;
+ double fragment = 1.0 / edl->fps;
if (fpx < 1.0)
- cairo_rectangle (cr, frame, y-PAD_DIM, 1.0, VID_HEIGHT + PAD_DIM * 2);
+ cairo_rectangle (cr, pos, y-PAD_DIM, fragment, VID_HEIGHT + PAD_DIM * 2);
else
- cairo_rectangle (cr, frame, y-PAD_DIM, fpx, VID_HEIGHT + PAD_DIM * 2);
+ cairo_rectangle (cr, pos, y-PAD_DIM, fpx, VID_HEIGHT + PAD_DIM * 2);
cairo_set_source_rgba (cr,1,0,0,1);
cairo_fill (cr);
cairo_restore (cr);
@@ -3051,6 +3085,7 @@ void gcut_ui (Mrg *mrg, void *data)
{
State *o = data;
GeglEDL *edl = o->edl;
+ gdouble fragment = 1.0 / edl->fps;
int long start_time = babl_ticks ();
@@ -3139,7 +3174,7 @@ void gcut_ui (Mrg *mrg, void *data)
mrg_printf (mrg, "frame %i (%i shown)",edl->frame_no, done_frame);
else
#endif
- mrg_printf (mrg, " %i ", edl->frame_no);
+ mrg_printf (mrg, " %f ", edl->frame_pos_ui);
#if 0
if (edl->active_source)
@@ -3173,7 +3208,7 @@ void gcut_ui (Mrg *mrg, void *data)
if (edl->playing)
{
mrg_add_binding (mrg, "space", NULL, "pause", renderer_toggle_playing, edl);
- if (edl->active_clip && edl->frame_no != edl->active_clip->abs_start)
+ if (edl->active_clip && !float_eq (edl->frame_pos_ui, edl->active_clip->abs_start))
mrg_add_binding (mrg, "v", NULL, "split clip", split_clip, edl);
}
else
@@ -3220,7 +3255,7 @@ void gcut_ui (Mrg *mrg, void *data)
if (edl->active_clip)
{
- if (edl->frame_no == edl->active_clip->abs_start)
+ if (float_eq (edl->frame_pos_ui, edl->active_clip->abs_start))
{
GList *iter = g_list_find (edl->clips, edl->active_clip);
Clip *clip2 = NULL;
@@ -3250,7 +3285,7 @@ void gcut_ui (Mrg *mrg, void *data)
{
mrg_add_binding (mrg, "i", NULL, "insert filter", insert_filter, edl);
- if (edl->frame_no == edl->active_clip->abs_start)
+ if (float_eq (edl->frame_pos_ui, edl->active_clip->abs_start))
{
if (empty_selection (edl))
@@ -3271,7 +3306,7 @@ void gcut_ui (Mrg *mrg, void *data)
{
if (empty_selection (edl))
{
- if (edl->frame_no == edl->active_clip->abs_start + clip_get_frames (edl->active_clip)-1)
+ if (float_eq (edl->frame_pos_ui, edl->active_clip->abs_start + clip_get_duration
(edl->active_clip)-fragment))
{
mrg_add_binding (mrg, "control-left/right", NULL, "adjust out", clip_end_inc, edl);
mrg_add_binding (mrg, "control-right", NULL, NULL, clip_end_inc, edl);
diff --git a/gcut/gcut.c b/gcut/gcut.c
index ca8a5f1..eea0ac7 100644
--- a/gcut/gcut.c
+++ b/gcut/gcut.c
@@ -1,6 +1,7 @@
#include "config.h"
#include <string.h>
#include <signal.h>
+#include <math.h>
#include <unistd.h>
#include <ctype.h>
#include <stdio.h>
@@ -129,8 +130,9 @@ GeglEDL *gcut_new (void)
edl->audio_bitrate = DEFAULT_audio_bitrate;
edl->audio_samplerate = DEFAULT_audio_samplerate;
edl->framedrop = DEFAULT_framedrop;
- edl->frame_no = 0; /* frame-no in ui shell */
- edl->frame = -1; /* frame-no in renderer thread */
+ edl->frame_pos_ui = 0.0; /* frame-no in ui shell */
+ edl->frame = -1; /* frame-no in renderer thread */
+ edl->pos = -1.0; /* frame-no in renderer thread */
edl->scale = 1.0;
edl->buffer = gegl_buffer_new (&roi, babl_format ("R'G'B'A u8"));
@@ -176,26 +178,26 @@ void gcut_free (GeglEDL *edl)
}
-Clip *gcut_get_clip (GeglEDL *edl, int frame, int *clip_frame_no)
+Clip *gcut_get_clip (GeglEDL *edl, double frame_pos, double *clip_frame_pos)
{
GList *l;
- int clip_start = 0;
+ double clip_start = 0;
for (l = edl->clips; l; l = l->next)
{
Clip *clip = l->data;
- int clip_frames = clip_get_frames (clip);
+ double clip_duration = clip_get_duration (clip);
if (clip->is_meta)
continue;
- if (frame - clip_start < clip_frames)
+ if (frame_pos - clip_start < clip_duration)
{
/* found right clip */
- if (clip_frame_no)
- *clip_frame_no = (frame - clip_start) + clip_get_start (clip);
+ if (clip_frame_pos)
+ *clip_frame_pos = (frame_pos - clip_start) + clip_get_start (clip);
return clip;
}
- clip_start += clip_frames;
+ clip_start += clip_duration;
}
return NULL;
}
@@ -205,7 +207,7 @@ int cache_misses = 0;
void gcut_set_use_proxies (GeglEDL *edl, int use_proxies)
{
- int frame;
+ double frame_pos;
edl->use_proxies = use_proxies;
if (edl->use_proxies)
@@ -213,11 +215,12 @@ void gcut_set_use_proxies (GeglEDL *edl, int use_proxies)
else
gcut_set_size (edl, edl->video_width, edl->video_height);
- frame = edl->frame;
- if (frame > 0)
+ frame_pos = edl->pos;
+
+ if (frame_pos > 0)
{
edl->frame--;
- gcut_set_frame (edl, frame);
+ gcut_set_pos (edl, frame_pos);
}
}
@@ -225,35 +228,33 @@ void gcut_set_use_proxies (GeglEDL *edl, int use_proxies)
/* computes the hash of a given rendered frame - without altering
* any state
*/
-gchar *gcut_get_frame_hash_full (GeglEDL *edl, int frame,
- Clip **clip0, int *clip0_frame,
- Clip **clip1, int *clip1_frame,
- double *mix)
+gchar *gcut_get_pos_hash_full (GeglEDL *edl, double pos,
+ Clip **clip0, double *clip0_pos,
+ Clip **clip1, double *clip1_pos,
+ double *mix)
{
GList *l;
- int clip_start = 0;
- int prev_clip_start = 0;
-
-
+ double clip_start = 0;
+ double prev_clip_start = 0;
for (l = edl->clips; l; l = l->next)
{
Clip *clip = l->data;
- int clip_frames = clip_get_frames (clip);
+ double clip_duration = clip_get_duration (clip);
if (clip->is_meta)
continue;
- if (frame - clip_start < clip_frames)
+ if (pos - clip_start < clip_duration)
{
- int clip_frame_no = (frame - clip_start) + clip_get_start (clip);
+ double clip_frame_pos = (pos - clip_start) + clip_get_start (clip);
GList *lp = l->prev;
GList *ln = l->next;
Clip *prev = lp?lp->data:NULL;
Clip *next = ln?ln->data:NULL;
- int prev_fade_len;
- int next_fade_len;
+ double prev_fade_len;
+ double next_fade_len;
while (prev && prev->is_meta)
{
@@ -269,11 +270,11 @@ gchar *gcut_get_frame_hash_full (GeglEDL *edl, int frame,
/* XXX: fade in from black if there is no previous clip */
- prev_fade_len = prev ? clip_get_frames (prev) : clip_frames;
- next_fade_len = next ? clip_get_frames (next) : clip_frames;
+ prev_fade_len = prev ? clip_get_duration (prev) : clip_duration;
+ next_fade_len = next ? clip_get_duration (next) : clip_duration;
- if (prev_fade_len > clip_frames) prev_fade_len = clip_frames;
- if (next_fade_len > clip_frames) next_fade_len = clip_frames;
+ if (prev_fade_len > clip_duration) prev_fade_len = clip_duration;
+ if (next_fade_len > clip_duration) next_fade_len = clip_duration;
prev_fade_len /= 2;
next_fade_len /= 2; /* 1/4 the length of the smallest of this or other
@@ -290,11 +291,11 @@ gchar *gcut_get_frame_hash_full (GeglEDL *edl, int frame,
next_fade_len = next->fade/2;
}
- if (prev && frame - clip_start < prev_fade_len) /* in */
+ if (prev && pos - clip_start < prev_fade_len) /* in */
{
- char *clip0_hash = clip_get_frame_hash (clip, clip_frame_no);
- char *clip1_hash = clip_get_frame_hash (prev, frame - prev_clip_start + clip_get_start (prev));
- double ratio = 0.5 + ((frame-clip_start) * 1.0 / prev_fade_len)/2;
+ char *clip0_hash = clip_get_pos_hash (clip, clip_frame_pos);
+ char *clip1_hash = clip_get_pos_hash (prev, pos - prev_clip_start + clip_get_start (prev));
+ double ratio = 0.5 + ((pos -clip_start) * 1.0 / prev_fade_len)/2;
char *str = g_strdup_printf ("%s %s %f", clip1_hash, clip0_hash, ratio);
GChecksum *hash = g_checksum_new (G_CHECKSUM_MD5);
char *ret;
@@ -306,19 +307,19 @@ gchar *gcut_get_frame_hash_full (GeglEDL *edl, int frame,
ret = g_strdup (g_checksum_get_string(hash));
g_checksum_free (hash);
if (clip0) *clip0 = prev;
- if (clip0_frame) *clip0_frame = frame - prev_clip_start + clip_get_start (prev);
+ if (clip0_pos) *clip0_pos = pos - prev_clip_start + clip_get_start (prev);
if (clip1) *clip1 = clip;
- if (clip1_frame) *clip1_frame = clip_frame_no;
+ if (clip1_pos) *clip1_pos = clip_frame_pos;
if (mix) *mix = ratio;
return ret;
}
- if (next && frame - clip_start > clip_frames - next_fade_len)/* out*/
+ if (next && pos - clip_start > clip_duration - next_fade_len)/* out*/
{
- char *clip0_hash = clip_get_frame_hash (clip, clip_frame_no);
- char *clip1_hash = clip_get_frame_hash (next, frame - (clip_start + clip_frames) + clip_get_start
(next));
- double ratio = (1.0-(clip_frames-(frame-clip_start)) * 1.0 / next_fade_len)/2;
+ char *clip0_hash = clip_get_pos_hash (clip, clip_frame_pos);
+ char *clip1_hash = clip_get_pos_hash (next, pos - (clip_start + clip_duration) + clip_get_start
(next));
+ double ratio = (1.0-(clip_duration -(pos -clip_start)) * 1.0 / next_fade_len)/2;
GChecksum *hash = g_checksum_new (G_CHECKSUM_MD5);
char *str = g_strdup_printf ("%s %s %f", clip0_hash, clip1_hash, ratio);
char *ret;
@@ -329,8 +330,8 @@ gchar *gcut_get_frame_hash_full (GeglEDL *edl, int frame,
ret = g_strdup (g_checksum_get_string(hash));
g_checksum_free (hash);
if (clip0) *clip0 = clip;
- if (clip0_frame) *clip0_frame = clip_frame_no;
- if (clip1_frame) *clip1_frame = frame - (clip_start +clip_frames) + clip_get_start (next);
+ if (clip0_pos) *clip0_pos = clip_frame_pos;
+ if (clip1_pos) *clip1_pos = pos - (clip_start +clip_duration) + clip_get_start (next);
if (clip1) *clip1 = next;
if (mix) *mix = ratio;
return ret;
@@ -338,27 +339,27 @@ gchar *gcut_get_frame_hash_full (GeglEDL *edl, int frame,
else
{
if (clip0) *clip0 = clip;
- if (clip0_frame) *clip0_frame = clip_frame_no;
+ if (clip0_pos) *clip0_pos = clip_frame_pos;
if (clip1) *clip1 = NULL;
if (mix) *mix = 0.0;
- return clip_get_frame_hash (clip, clip_frame_no);
+ return clip_get_pos_hash (clip, clip_frame_pos);
}
}
prev_clip_start = clip_start;
- clip_start += clip_frames;
+ clip_start += clip_duration;
}
- if (clip0) *clip0 = NULL;
- if (clip0_frame) *clip0_frame = 0;
- if (clip1_frame) *clip1_frame = 0;
- if (clip1) *clip1 = NULL;
- if (mix) *mix = 0.0;
+ if (clip0) *clip0 = NULL;
+ if (clip0_pos) *clip0_pos = 0;
+ if (clip1_pos) *clip1_pos = 0;
+ if (clip1) *clip1 = NULL;
+ if (mix) *mix = 0.0;
return NULL;
}
-gchar *gcut_get_frame_hash (GeglEDL *edl, int frame)
+gchar *gcut_get_pos_hash (GeglEDL *edl, double pos)
{
- return gcut_get_frame_hash_full (edl, frame, NULL, NULL, NULL, NULL, NULL);
+ return gcut_get_pos_hash_full (edl, pos, NULL, NULL, NULL, NULL, NULL);
}
void gcut_update_buffer (GeglEDL *edl)
@@ -374,10 +375,11 @@ void gcut_update_buffer (GeglEDL *edl)
}
/* calling this causes gcut to rig up its graphs for providing/rendering this frame
*/
-void gcut_set_frame (GeglEDL *edl, int frame)
+void gcut_set_pos (GeglEDL *edl, double pos)
{
- Clip *clip0; int clip0_frame;
- Clip *clip1; int clip1_frame;
+ int frame = pos * edl->fps;
+ Clip *clip0; double clip0_pos;
+ Clip *clip1; double clip1_pos;
if ((edl->frame) == frame && (frame != 0))
{
@@ -388,8 +390,9 @@ void gcut_set_frame (GeglEDL *edl, int frame)
double mix;
- char *frame_hash = gcut_get_frame_hash_full (edl, frame, &clip0, &clip0_frame, &clip1, &clip1_frame, &mix);
+ char *frame_hash = gcut_get_pos_hash_full (edl, pos, &clip0, &clip0_pos, &clip1, &clip1_pos, &mix);
char *cache_path = g_strdup_printf ("%s.gcut/cache/%s", edl->parent_path, frame_hash);
+ edl->pos = pos;
edl->frame = frame;
g_free (frame_hash);
if (g_file_test (cache_path, G_FILE_TEST_IS_REGULAR) &&
@@ -398,7 +401,7 @@ void gcut_set_frame (GeglEDL *edl, int frame)
Clip *clip = NULL;
gegl_node_set (edl->cache_loader, "path", cache_path, NULL);
gegl_node_link_many (edl->cache_loader, edl->result, NULL);
- clip = edl_get_clip_for_frame (edl, edl->frame);
+ clip = edl_get_clip_for_pos (edl, pos);
if (clip)
{
if (clip->audio)
@@ -428,14 +431,14 @@ void gcut_set_frame (GeglEDL *edl, int frame)
if (clip1 == NULL)
{
- clip_render_frame (clip0, clip0_frame);
+ clip_render_pos (clip0, clip0_pos);
gegl_node_link_many (clip0->nop_crop, edl->result, NULL);
}
else
{
gegl_node_set (edl->mix, "ratio", mix, NULL);
- clip_render_frame (clip0, clip0_frame);
- clip_render_frame (clip1, clip1_frame);
+ clip_render_pos (clip0, clip0_pos);
+ clip_render_pos (clip1, clip1_pos);
gegl_node_link_many (clip0->nop_crop, edl->mix, edl->result, NULL);
gegl_node_connect_to (clip1->nop_crop, "output", edl->mix, "aux");
}
@@ -485,39 +488,46 @@ double gcut_get_fps (GeglEDL *edl)
{
return edl->fps;
}
-int gcut_get_frame (GeglEDL *edl)
+double gcut_get_pos (GeglEDL *edl)
{
- return edl->frame;
+ return edl->pos;
}
GeglAudioFragment *gcut_get_audio (GeglEDL *edl)
{
- Clip * clip = edl_get_clip_for_frame (edl, edl->frame);
+ Clip * clip = edl_get_clip_for_pos (edl, edl->pos);
return clip?clip->audio:NULL;
}
-void gcut_get_video_info (const char *path, int *duration, double *fps)
+void gcut_get_video_info (const char *path, int *frames, double *duration, double *fps)
{
GeglNode *gegl = gegl_node_new ();
GeglNode *probe = gegl_node_new_child (gegl, "operation",
"gegl:ff-load", "path", path, NULL);
+ double r_fps;
+ int r_frames;
gegl_node_process (probe);
- if (duration)
- gegl_node_get (probe, "frames", duration, NULL);
+ gegl_node_get (probe, "frames", &r_frames, NULL);
+ gegl_node_get (probe, "frame-rate", &r_fps, NULL);
+
+ if (frames)
+ *frames = r_frames;
if (fps)
- gegl_node_get (probe, "frame-rate", fps, NULL);
+ *fps = r_fps;
+ if (duration)
+ *duration = r_frames / r_fps;
g_object_unref (gegl);
}
-int gcut_get_duration (GeglEDL *edl)
+double gcut_get_duration (GeglEDL *edl)
{
- int count = 0;
+ double count = 0;
GList *l;
for (l = edl->clips; l; l = l->next)
{
((Clip*)(l->data))->abs_start = count;
- count += clip_get_frames (l->data);
+ count += clip_get_duration (l->data);
}
return count;
}
@@ -526,7 +536,7 @@ int gcut_get_duration (GeglEDL *edl)
void gcut_parse_line (GeglEDL *edl, const char *line)
{
- int start = 0; int end = 0;
+ double start = 0; double end = 0;
const char *rest = NULL;
char path[1024];
if (line[0] == '#' ||
@@ -562,7 +572,7 @@ void gcut_parse_line (GeglEDL *edl, const char *line)
if (!strcmp (key, "selection-end")) edl->selection_end = g_strtod (value, NULL);
//if (!strcmp (key, "range-start")) edl->range_start = g_strtod (value, NULL);
//if (!strcmp (key, "range-end")) edl->range_end = g_strtod (value, NULL);
- if (!strcmp (key, "frame-no")) edl->frame_no = g_strtod (value, NULL);
+ if (!strcmp (key, "frame-pos")) edl->frame_pos_ui = g_strtod (value, NULL);
if (!strcmp (key, "frame-scale")) edl->scale = g_strtod (value, NULL);
if (!strcmp (key, "t0")) edl->t0 = g_strtod (value, NULL);
@@ -578,17 +588,28 @@ void gcut_parse_line (GeglEDL *edl, const char *line)
if (!p)
p = line + strlen(line)-1;
{
+ int is_seconds = 0;
if (p>line) p --;
while (p>line && *p == ' ') p --;
- while (p>line && isdigit (*p)) p --;
- end = atoi (p+1);
+ while (p>line && (isdigit (*p) || (*p=='s'))){
+ if (*p == 's') is_seconds = 1;
+ p --;
+ }
+ end = g_strtod (p+1, NULL);
+ if (!is_seconds)
+ end /= edl->fps;
if (p>line) p --;
while (p>line && *p == ' ') p --;
-
- while (p>line && isdigit (*p)) p --;
- start = atoi (p+1);
+ is_seconds = 0;
+ while (p>line && (isdigit (*p) || (*p=='s'))){
+ if (*p == 's') is_seconds = 1;
+ p --;
+ }
+ start = g_strtod (p+1, NULL);
+ if (!is_seconds)
+ start /= edl->fps;
if (p>line) p --;
while (p>line && *p == ' ') p --;
@@ -611,10 +632,15 @@ void gcut_parse_line (GeglEDL *edl, const char *line)
edl->clips = g_list_append (edl->clips, clip);
if (strstr (line, "[fade="))
{
+ int was_seconds = 0;
ff_probe = 1;
rest = strstr (line, "[fade=") + strlen ("[fade=");
- clip->fade = atoi (rest);
- while (*rest && *rest != ']') rest++;
+ clip->fade = g_strtod (rest, NULL);
+ while (*rest && *rest != ']'){ if (*rest == 's') was_seconds =1; rest++;}
+ if (!was_seconds)
+ {
+ clip->fade = clip->fade / edl->fps;
+ }
if (*rest == ']') rest++;
}
@@ -628,7 +654,8 @@ void gcut_parse_line (GeglEDL *edl, const char *line)
if (ff_probe && !clip_is_static_source (clip))
{
- gcut_get_video_info (clip->path, &clip->duration, &clip->fps);
+ int clip_frames;
+ gcut_get_video_info (clip->path, &clip_frames, &clip->duration, &clip->fps);
if (edl->fps == 0.0)
{
@@ -975,10 +1002,10 @@ static void init (int argc, char **argv)
static void encode_frames (GeglEDL *edl)
{
int frame_no;
- for (frame_no = edl->range_start; frame_no <= edl->range_end; frame_no++)
+ for (frame_no = edl->range_start * edl->fps; frame_no <= edl->range_end * edl->fps; frame_no++)
{
- edl->frame_no = frame_no;
- gcut_set_frame (edl, edl->frame_no);
+ int frame_no_ui = frame_no;
+ gcut_set_pos (edl, frame_no_ui / edl->fps);
fprintf (stdout, "\r%1.2f%% %04d / %04d ",
100.0 * (frame_no-edl->range_start) * 1.0 / (edl->range_end - edl->range_start),
@@ -1013,51 +1040,52 @@ static inline int this_cacher (int frame_no)
static void process_frames_cache (GeglEDL *edl)
{
- int frame_no = edl->frame_no;
- int frame_start = edl->frame_no;
+ int frame_no = edl->frame_pos_ui * edl->fps;
+ int frame_start = frame_no;
int duration;
GList *l;
- int clip_start = 0;
+ double clip_start = 0;
signal(SIGUSR2, handler1);
duration = gcut_get_duration (edl);
// TODO: use bitmap from ui to speed up check
- edl->frame_no = frame_start;
- if (this_cacher (edl->frame_no))
- gcut_set_frame (edl, edl->frame_no);
+ edl->frame_pos_ui = frame_start;
+ if (this_cacher (floor (edl->frame_pos_ui * edl->fps)))
+ gcut_set_pos (edl, edl->frame_pos_ui);
if (stop_cacher)
return;
for (l = edl->clips; l; l = l->next)
{
Clip *clip = l->data;
- int clip_frames = clip_get_frames (clip);
- edl->frame_no = clip_start;
- if (this_cacher (edl->frame_no))
+ double clip_duration = clip_get_duration (clip);
+ int frame_pos_ui = floor (clip_start * edl->fps);
+ if (this_cacher (frame_pos_ui))
{
- gcut_set_frame (edl, edl->frame_no);
+ gcut_set_pos (edl, frame_pos_ui / edl->fps);
}
- clip_start += clip_frames;
+ clip_start += clip_duration;
if (stop_cacher)
return;
}
for (frame_no = frame_start - 3; frame_no < duration; frame_no++)
{
- edl->frame_no = frame_no;
- if (this_cacher (edl->frame_no))
- gcut_set_frame (edl, edl->frame_no);
+ int frame_pos_ui = floor (frame_no / edl->fps);
+
+ if (this_cacher (frame_no))
+ gcut_set_pos (edl, frame_pos_ui);
if (stop_cacher)
return;
}
for (frame_no = 0; frame_no < frame_start; frame_no++)
{
- edl->frame_no = frame_no;
- if (this_cacher (edl->frame_no))
- gcut_set_frame (edl, edl->frame_no);
+ int frame_pos_ui = floor (frame_no / edl->fps);
+ if (this_cacher (frame_no))
+ gcut_set_pos (edl, frame_pos_ui);
if (stop_cacher)
return;
}
@@ -1080,7 +1108,7 @@ guchar *gcut_get_cache_bitmap (GeglEDL *edl, int *length_ret)
for (frame_no = 0; frame_no < duration; frame_no++)
{
- const gchar *hash = gcut_get_frame_hash (edl, 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);
if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
set_bit (ret, frame_no);
@@ -1092,8 +1120,8 @@ guchar *gcut_get_cache_bitmap (GeglEDL *edl, int *length_ret)
static void process_frames_cache_stat (GeglEDL *edl)
{
- int frame_no = edl->frame_no;
- int duration;
+ int frame_no = edl->frame_pos_ui / edl->fps;
+ double duration;
signal(SIGUSR2, handler1);
duration = gcut_get_duration (edl);
@@ -1102,9 +1130,9 @@ static void process_frames_cache_stat (GeglEDL *edl)
project
*/
- for (frame_no = 0; frame_no < duration; frame_no++)
+ for (frame_no = 0; frame_no < duration * edl->fps; frame_no++)
{
- const gchar *hash = gcut_get_frame_hash (edl, 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);
if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
fprintf (stdout, "%i ", frame_no);
@@ -1418,7 +1446,7 @@ char *gcut_serialize (GeglEDL *edl)
if (edl->t0 != 1.0)
g_string_append_printf (ser, "t0=%f\n", edl->t0);
- g_string_append_printf (ser, "frame-no=%i\n", edl->frame_no);
+ g_string_append_printf (ser, "frame-pos=%.3f\n", edl->frame_pos_ui);
g_string_append_printf (ser, "\n");
for (l = edl->clips; l; l = l->next)
@@ -1439,11 +1467,11 @@ char *gcut_serialize (GeglEDL *edl)
}
else
{
- g_string_append_printf (ser, "%s %d %d ", path, clip->start, clip->end);
+ g_string_append_printf (ser, "%s %.3fs %.3fs ", path, clip->start, clip->end);
if (clip->filter_graph||clip->fade)
g_string_append_printf (ser, "-- ");
if (clip->fade)
- g_string_append_printf (ser, "[fade=%i] ", clip->fade);
+ g_string_append_printf (ser, "[fade=%.3fs] ", clip->fade);
if (clip->filter_graph)
g_string_append_printf (ser, "%s", clip->filter_graph);
g_string_append_printf (ser, "\n");
@@ -1563,15 +1591,15 @@ gegl_meta_get_audio (const char *path,
#endif
}
-void gcut_set_selection (GeglEDL *edl, int start_frame, int end_frame)
+void gcut_set_selection (GeglEDL *edl, double start_frame, double end_frame)
{
edl->selection_start = start_frame;
edl->selection_end = end_frame;
}
void gcut_get_selection (GeglEDL *edl,
- int *start_frame,
- int *end_frame)
+ double *start_frame,
+ double *end_frame)
{
if (start_frame)
*start_frame = edl->selection_start;
@@ -1579,15 +1607,15 @@ void gcut_get_selection (GeglEDL *edl,
*end_frame = edl->selection_end;
}
-void gcut_set_range (GeglEDL *edl, int start_frame, int end_frame)
+void gcut_set_range (GeglEDL *edl, double start_frame, double end_frame)
{
edl->range_start = start_frame;
edl->range_end = end_frame;
}
void gcut_get_range (GeglEDL *edl,
- int *start_frame,
- int *end_frame)
+ double *start_frame,
+ double *end_frame)
{
if (start_frame)
*start_frame = edl->range_start;
@@ -1595,18 +1623,19 @@ void gcut_get_range (GeglEDL *edl,
*end_frame = edl->range_end;
}
-Clip * edl_get_clip_for_frame (GeglEDL *edl, int frame)
+Clip * edl_get_clip_for_pos (GeglEDL *edl, double pos)
{
GList *l;
- int t = 0;
+ double t = 0;
for (l = edl->clips; l; l = l->next)
{
Clip *clip = l->data;
- if (frame >= t && frame < t + clip_get_frames (clip))
+ double duration = clip_get_duration (clip);
+ if (pos >= t && pos < t + duration)
{
return clip;
}
- t += clip_get_frames (clip);
+ t += duration;
}
return NULL;
}
diff --git a/gcut/gcut.h b/gcut/gcut.h
index fbd3ce9..0858c3f 100644
--- a/gcut/gcut.h
+++ b/gcut/gcut.h
@@ -83,27 +83,27 @@ void gcut_free (GeglEDL *edl);
void gcut_set_fps (GeglEDL *edl,
double fps);
double gcut_get_fps (GeglEDL *edl);
-int gcut_get_duration (GeglEDL *edl);
+double gcut_get_duration (GeglEDL *edl);
void gcut_parse_line (GeglEDL *edl, const char *line);
GeglEDL *gcut_new_from_path (const char *path);
void gcut_load_path (GeglEDL *edl, const char *path);
void gcut_save_path (GeglEDL *edl, const char *path);
GeglAudioFragment *gcut_get_audio (GeglEDL *edl);
-Clip *gcut_get_clip (GeglEDL *edl, int frame, int *clip_frame_no);
+Clip *gcut_get_clip (GeglEDL *edl, double pos, double *clip_frame_pos);
-void gcut_set_frame (GeglEDL *edl, int frame);
-int gcut_get_frame (GeglEDL *edl);
+void gcut_set_pos (GeglEDL *edl, double pos);
+double gcut_get_pos (GeglEDL *edl);
char *gcut_serialize (GeglEDL *edl);
-void gcut_set_range (GeglEDL *edl, int start_frame, int end_frame);
+void gcut_set_range (GeglEDL *edl, double start, double end);
void gcut_get_range (GeglEDL *edl,
- int *start_frame,
- int *end_frame);
+ double *start,
+ double *end);
-void gcut_set_selection (GeglEDL *edl, int start_frame, int end_frame);
+void gcut_set_selection (GeglEDL *edl, double start, double end);
void gcut_get_selection (GeglEDL *edl,
- int *start_frame,
- int *end_frame);
+ double *start,
+ double *end);
char *gcut_make_thumb_path (GeglEDL *edl, const char *clip_path);
guchar *gcut_get_cache_bitmap (GeglEDL *edl, int *length_ret);
@@ -112,26 +112,26 @@ Clip *clip_new (GeglEDL *edl);
void clip_free (Clip *clip);
const char *clip_get_path (Clip *clip);
void clip_set_path (Clip *clip, const char *path);
-int clip_get_start (Clip *clip);
-int clip_get_end (Clip *clip);
-int clip_get_frames (Clip *clip);
-void clip_set_start (Clip *clip, int start);
-void clip_set_end (Clip *clip, int end);
-void clip_set_range (Clip *clip, int start, int end);
+double clip_get_start (Clip *clip);
+double clip_get_end (Clip *clip);
+double clip_get_duration (Clip *clip);
+void clip_set_start (Clip *clip, double start);
+void clip_set_end (Clip *clip, double end);
+void clip_set_range (Clip *clip, double start, double end);
int clip_is_static_source (Clip *clip);
-gchar * clip_get_frame_hash (Clip *clip, int clip_frame_no);
+gchar * clip_get_pos_hash (Clip *clip, double clip_frame_pos);
Clip * clip_get_next (Clip *self);
Clip * clip_get_prev (Clip *self);
void clip_fetch_audio (Clip *clip);
-void clip_set_full (Clip *clip, const char *path, int start, int end);
-Clip * clip_new_full (GeglEDL *edl, const char *path, int start, int end);
+void clip_set_full (Clip *clip, const char *path, double start, double end);
+Clip * clip_new_full (GeglEDL *edl, const char *path, double start, double end);
//void clip_set_frame_no (Clip *clip, int frame_no);
-void clip_render_frame (Clip *clip, int clip_frame_no);
+void clip_render_pos (Clip *clip, double clip_frame_pos);
-Clip * edl_get_clip_for_frame (GeglEDL *edl, int frame);
+Clip * edl_get_clip_for_pos (GeglEDL *edl, double pos);
void gcut_make_proxies (GeglEDL *edl);
-void gcut_get_video_info (const char *path, int *duration, double *fps);
+void gcut_get_video_info (const char *path, int *frames, double *duration, double *fps);
void gegl_meta_set_audio (const char *path,
GeglAudioFragment *audio);
void gegl_meta_get_audio (const char *path,
@@ -147,21 +147,21 @@ struct _Clip
{
char *path; /*path to media file */
char *title;
- int start; /*frame number starting with 0 */
- int end; /*last frame, inclusive fro single frame, make equal to start */
- int duration;
+ double start; /*frame number starting with 0 */
+ double end; /*last frame, inclusive fro single frame, make equal to start */
+ double duration;
int editing;
char *filter_graph; /* chain of gegl filters */
GeglEDL *edl;
double fps;
- int fade; /* the main control for fading in.. */
+ double fade; /* the main control for fading in.. */
int static_source;
int is_chain;
int is_meta;
- int abs_start;
+ double abs_start;
const char *clip_path;
GeglNode *gegl;
@@ -185,7 +185,8 @@ struct _GeglEDL
char *parent_path;
GList *clip_db;
GList *clips;
- int frame; /* render thread, frame_no is ui side */
+ int frame; /* render thread, frame_no_ui is ui side */
+ double pos; /* render thread, frame_pos_ui is ui side */
double fps;
GeglBuffer *buffer;
GeglBuffer *buffer_copy_temp;
@@ -215,8 +216,8 @@ struct _GeglEDL
int video_tolerance;
int audio_bitrate;
int audio_samplerate;
- int frame_no;
- int source_frame_no;
+ double frame_pos_ui;
+ int source_frame_pos;
int use_proxies;
int framedrop;
int ui_mode;
@@ -244,12 +245,12 @@ void gcut_update_buffer (GeglEDL *edl);
void gcut_cache_invalid (GeglEDL *edl);
-gchar *gcut_get_frame_hash (GeglEDL *edl, int frame);
+gchar *gcut_get_pos_hash (GeglEDL *edl, double pos);
-gchar *gcut_get_frame_hash_full (GeglEDL *edl, int frame,
- Clip **clip0, int *clip0_frame,
- Clip **clip1, int *clip1_frame,
- double *mix);
+gchar *gcut_get_pos_hash_full (GeglEDL *edl, double pos,
+ Clip **clip0, double *clip0_pos,
+ Clip **clip1, double *clip1_pos,
+ double *mix);
int gegl_make_thumb_image (GeglEDL *edl, const char *path, const char *icon_path);
#ifdef MICRO_RAPTOR_GUI
diff --git a/gcut/renderer.c b/gcut/renderer.c
index f0d54fa..56910fd 100644
--- a/gcut/renderer.c
+++ b/gcut/renderer.c
@@ -111,16 +111,16 @@ static gpointer renderer_thread (gpointer data)
{
playing_iteration (edl->mrg, edl);
{
- if (edl->frame_no != done_frame)
+ if ((int)(edl->frame_pos_ui * edl->fps) != done_frame)
{
- rendering_frame = edl->frame_no;
+ rendering_frame = edl->frame_pos_ui * edl->fps;
{
GeglRectangle ext = {0,0,edl->width, edl->height};
//GeglRectangle ext = gegl_node_get_bounding_box (edl->result);
gegl_buffer_set_extent (edl->buffer, &ext);
}
- gcut_set_frame (edl, edl->frame_no); /* this does the frame-set, which causes render */
+ gcut_set_pos (edl, edl->frame_pos_ui); /* this does the frame-set, which causes render */
#if 0
{
GeglRectangle ext = gegl_node_get_bounding_box (edl->result);
@@ -187,11 +187,11 @@ void renderer_toggle_playing (MrgEvent *event, void *data1, void *data2)
prev_ticks = babl_ticks ();
}
-static int max_frame (GeglEDL *edl)
+static double max_pos (GeglEDL *edl)
{
GList *l;
int t = 0;
- int start, end;
+ double start, end;
gcut_get_range (edl, &start, &end);
if (end)
@@ -200,7 +200,7 @@ static int max_frame (GeglEDL *edl)
for (l = edl->clips; l; l = l->next)
{
Clip *clip = l->data;
- t += clip_get_frames (clip);
+ t += clip_get_duration (clip);
}
return t;
@@ -211,6 +211,7 @@ void playing_iteration (Mrg *mrg, GeglEDL *edl)
{
long ticks = 0;
double delta = 1;
+ double fragment = 1.0 / edl->fps;
ticks = babl_ticks ();
if (prev_ticks == 0) prev_ticks = ticks;
@@ -264,16 +265,16 @@ void playing_iteration (Mrg *mrg, GeglEDL *edl)
if (edl->active_clip)
{
- int start, end;
- edl->frame_no += delta;
+ double start, end;
+ edl->frame_pos_ui += delta * fragment;
gcut_get_range (edl, &start, &end);
- if (edl->frame_no > max_frame (edl))
+ if (edl->frame_pos_ui > max_pos (edl))
{
- edl->frame_no = 0;
+ edl->frame_pos_ui = 0;
if (end)
- edl->frame_no = start;
+ edl->frame_pos_ui = start;
}
- edl->active_clip = edl_get_clip_for_frame (edl, edl->frame_no);
+ edl->active_clip = edl_get_clip_for_pos (edl, edl->frame_pos_ui);
prev_ticks = ticks;
}
}
@@ -282,5 +283,5 @@ void playing_iteration (Mrg *mrg, GeglEDL *edl)
int renderer_done (GeglEDL *edl)
{
- return done_frame == edl->frame_no; //rendering_frame;
+ return done_frame == (gint)(edl->frame_pos_ui * edl->fps); //rendering_frame;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]