I wanted to duplicate the slo-mo effect described in
http://rarevision.com/articles/slow_motion.php but couldn't figure out a way
to do it in Cinelerra without requiring a render and reimport.
Using the frames-to-fields plugin and interlaced material, you can get smooth
50% slow motion if you set your asset frame rate to 15fps and project to
30fps. Theoretically you could set the project frame rate higher to get more
of a slowdown, but it doesn't help if you want to render at 24fps. And it
isn't smooth.
In order to make the effect work in a single render, I added a new frame rate
to the asset list - 9.6 fps (40% of 24fps). I then added a pulldown to the
frames-to-fields plugin that lets you tell the plugin what frame rate the
asset is set to. It uses this frame rate for the call to read_frame instead
of simply dividing the project frame rate in half like it does now
This way you can specify a frame rate of 9.6 in the asset and 24fps in the
project, which gets you the equivalent of 60i->24p in a nice, smooth 40%
slow-motion.
Example clip rendered with Cinelerra with modified frames-to-fields plugin:
http://www.joestewart.org/slomo.mov
Now, I will concede that setting the asset frame rate in two different places
may not be the best way to go about this. Ideally the plugin would detect the
asset frame rate and use it - however, I see no way for plugins to access
asset attributes without changes to the plugin API - and, if that were to
happen, would would occur if the plugin spans multiple assets? Might get
messy.
If this patch isn't desirable, I'm open to suggestions.
-Joe
diff -ru hvirtual-orig/cinelerra/theme.C hvirtual-new/cinelerra/theme.C
--- hvirtual-orig/cinelerra/theme.C 2006-05-17 10:00:30.000000000 -0400
+++ hvirtual-new/cinelerra/theme.C 2006-05-29 11:58:36.000000000 -0400
@@ -152,6 +152,7 @@
sample_rates.append(new BC_ListBoxItem("192000"));
frame_rates.append(new BC_ListBoxItem("1"));
frame_rates.append(new BC_ListBoxItem("5"));
+ frame_rates.append(new BC_ListBoxItem("9.6"));
frame_rates.append(new BC_ListBoxItem("10"));
frame_rates.append(new BC_ListBoxItem("12"));
frame_rates.append(new BC_ListBoxItem("15"));
diff -ru hvirtual-orig/plugins/framefield/framefield.C hvirtual-new/plugins/framefield/framefield.C
--- hvirtual-orig/plugins/framefield/framefield.C 2006-05-17 09:58:08.000000000 -0400
+++ hvirtual-new/plugins/framefield/framefield.C 2006-05-29 11:58:57.000000000 -0400
@@ -33,6 +33,7 @@
int equivalent(FrameFieldConfig &src);
int field_dominance;
int avg;
+ double source_frame_rate;
};
@@ -85,6 +86,21 @@
FrameFieldWindow *gui;
};
+
+class FrameFieldRates : public BC_PopupTextBox
+{
+public:
+ FrameFieldRates(FrameField *plugin, FrameFieldWindow *gui, int x, int y, char *text);
+ int handle_event();
+ FrameField *plugin;
+ FrameFieldWindow *gui;
+};
+
+
+
+
+
+
class FrameFieldWindow : public BC_Window
{
public:
@@ -95,6 +111,9 @@
FrameFieldTop *top;
FrameFieldBottom *bottom;
FrameFieldAvg *avg;
+ FrameFieldRates *frame_rate_box;
+ BC_Title *frame_rate_title;
+ ArrayList<BC_ListBoxItem*> frame_rates;
};
@@ -150,29 +169,28 @@
{
field_dominance = TOP_FIELD_FIRST;
avg = 1;
+ source_frame_rate = 15.0;
}
int FrameFieldConfig::equivalent(FrameFieldConfig &src)
{
return src.field_dominance == field_dominance &&
- src.avg == avg;
+ src.avg == avg &&
+ src.source_frame_rate == source_frame_rate;
}
-
-
-
FrameFieldWindow::FrameFieldWindow(FrameField *plugin, int x, int y)
: BC_Window(plugin->gui_string,
x,
y,
210,
- 160,
+ 220,
200,
- 160,
+ 220,
0,
0,
1)
@@ -183,11 +201,33 @@
void FrameFieldWindow::create_objects()
{
int x = 10, y = 10;
+
+ frame_rates.append(new BC_ListBoxItem("1"));
+ frame_rates.append(new BC_ListBoxItem("5"));
+ frame_rates.append(new BC_ListBoxItem("9.6"));
+ frame_rates.append(new BC_ListBoxItem("10"));
+ frame_rates.append(new BC_ListBoxItem("12"));
+ frame_rates.append(new BC_ListBoxItem("15"));
+ frame_rates.append(new BC_ListBoxItem("23.97"));
+ frame_rates.append(new BC_ListBoxItem("24"));
+ frame_rates.append(new BC_ListBoxItem("25"));
+ frame_rates.append(new BC_ListBoxItem("29.97"));
+ frame_rates.append(new BC_ListBoxItem("30"));
+ frame_rates.append(new BC_ListBoxItem("50"));
+ frame_rates.append(new BC_ListBoxItem("59.94"));
+ frame_rates.append(new BC_ListBoxItem("60"));
+
add_subwindow(top = new FrameFieldTop(plugin, this, x, y));
y += 30;
add_subwindow(bottom = new FrameFieldBottom(plugin, this, x, y));
y += 30;
add_subwindow(avg = new FrameFieldAvg(plugin, this, x, y));
+ y += 30;
+ char string[BCTEXTLEN];
+ add_tool(frame_rate_title = new BC_Title(x, y, _("Source Frame Rate:")));
+ sprintf(string, "%.2f", plugin->config.source_frame_rate);
+ frame_rate_box = new FrameFieldRates(plugin, this, x, y + 20, string);
+ frame_rate_box->create_objects();
show_window();
flush();
}
@@ -277,20 +317,35 @@
-PLUGIN_THREAD_OBJECT(FrameField, FrameFieldThread, FrameFieldWindow)
-
-
-
-
-
+FrameFieldRates::FrameFieldRates(FrameField *plugin, FrameFieldWindow *gui, int x, int y, char
+*text)
+ : BC_PopupTextBox(gui,
+ &gui->frame_rates,
+ text,
+ x,
+ y,
+ 100,
+ 300)
+{
+ this->plugin = plugin;
+ this->gui = gui;
+}
+int FrameFieldRates::handle_event()
+{
+ plugin->config.source_frame_rate = atof(get_text());
+//printf("FrameFieldRates::handle_event 1 %s\n", get_text());
+ plugin->send_configure_change();
+ return 1;
+}
+PLUGIN_THREAD_OBJECT(FrameField, FrameFieldThread, FrameFieldWindow)
@@ -364,7 +419,7 @@
read_frame(src_frame,
0,
current_frame_number,
- frame_rate / 2);
+ config.source_frame_rate);
src_frame_number = current_frame_number;
}
@@ -591,6 +646,7 @@
config.field_dominance = defaults->get("DOMINANCE", config.field_dominance);
config.avg = defaults->get("AVG", config.avg);
+ config.source_frame_rate = defaults->get("SOURCE_FPS", config.source_frame_rate);
return 0;
}
@@ -598,6 +654,7 @@
{
defaults->update("DOMINANCE", config.field_dominance);
defaults->update("AVG", config.avg);
+ defaults->update("SOURCE_FPS", config.source_frame_rate);
defaults->save();
return 0;
}
@@ -611,6 +668,7 @@
output.tag.set_title("FRAME_FIELD");
output.tag.set_property("DOMINANCE", config.field_dominance);
output.tag.set_property("AVG", config.avg);
+ output.tag.set_property("SOURCE_FPS", config.source_frame_rate);
output.append_tag();
output.terminate_string();
}
@@ -629,6 +687,7 @@
{
config.field_dominance = input.tag.get_property("DOMINANCE", config.field_dominance);
config.avg = input.tag.get_property("AVG", config.avg);
+ config.source_frame_rate = input.tag.get_property("SOURCE_FPS", config.source_frame_rate);
}
}
}
@@ -642,12 +701,9 @@
thread->window->lock_window();
thread->window->top->update(config.field_dominance == TOP_FIELD_FIRST);
thread->window->bottom->update(config.field_dominance == BOTTOM_FIELD_FIRST);
+ thread->window->bottom->update(config.source_frame_rate == get_framerate() / 2);
thread->window->unlock_window();
}
}
}
-
-
-
-