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(); } } } - - - -