DeactivateFocusPolicy *focus_deactivate = new DeactivateFocusPolicy(pwindow, x1, y1);
add_subwindow(focus_deactivate);
y1 += focus_deactivate->get_h() + 5;
+ ForwardRenderDisplacement *displacement = new ForwardRenderDisplacement(pwindow, x1, y1);
+ add_subwindow(displacement);
+ y1 += displacement->get_h() + 5;
add_subwindow(thumbnails = new ViewThumbnails(x1, y1, pwindow));
if( y < y1 ) y = y1;
}
return 1;
}
+ForwardRenderDisplacement::ForwardRenderDisplacement(PreferencesWindow *pwindow, int x, int y)
+ : BC_CheckBox(x, y, pwindow->thread->preferences->forward_render_displacement,
+ _("Forward render enable displacement"))
+{
+ this->pwindow = pwindow;
+}
+
+int ForwardRenderDisplacement::handle_event()
+{
+ pwindow->thread->preferences->forward_render_displacement = get_value();
+ return 1;
+}
+
PreferencesWindow *pwindow;
};
+class ForwardRenderDisplacement : public BC_CheckBox
+{
+public:
+ ForwardRenderDisplacement(PreferencesWindow *pwindow, int x, int y);
+ int handle_event();
+ PreferencesWindow *pwindow;
+};
+
#endif
int File::read_frame(VFrame *frame, int is_thread)
{
const int debug = 0;
-
+//printf("File::read_frame pos=%jd cache=%d 1frame=%d\n",
+// current_frame, use_cache, asset->single_frame);
if( debug ) PRINT_TRACE
//printf("File::read_frame %d\n", __LINE__);
case SINGLE_FRAME_FWD:
case SINGLE_FRAME_REWIND:
- command->playbackstart = get_tracking_position();
// fall through
default:
last_command = command->command;
// Resume or change direction
switch( prev_command ) {
default:
- engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
+ engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
engine->interrupt_playback(wait_tracking);
resume = 1;
// fall through
case SINGLE_FRAME_REWIND:
// Start from scratch
engine->que->send_command(command, CHANGE_NONE, get_edl(),
- 1, resume, use_inout, toggle_audio);
+ 1, resume, use_inout, toggle_audio,
+ mwindow->preferences->forward_render_displacement);
break;
}
break;
// Commands that stop
case STOP:
- do_stop = 1;
- break;
-
case REWIND:
case GOTO_END:
- engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
- engine->interrupt_playback(wait_tracking);
- break;
+ do_stop = 1;
+ break;
}
if( do_stop ) {
- engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
+ engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
engine->interrupt_playback(wait_tracking);
}
}
// stop transport
if( prev_command != STOP && prev_command != COMMAND_NONE &&
prev_command != SINGLE_FRAME_FWD && prev_command != SINGLE_FRAME_REWIND ) {
- engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
+ engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
engine->interrupt_playback(0);
}
mwindow->gui->lock_window("PlayTransport::change_position");
case NORMAL_FWD:
case FAST_FWD:
engine->que->send_command(prev_command, CHANGE_NONE,
- get_edl(), 1, 1, using_inout);
+ get_edl(), 1, 1, using_inout, 0);
}
}
bd_warn_root = 1;
popupmenu_btnup = 1;
textbox_focus_policy = 0;
+ forward_render_displacement = 0;
dvd_yuv420p_interlace = 0;
// Default brender asset
bd_warn_root = that->bd_warn_root;
popupmenu_btnup = that->popupmenu_btnup;
textbox_focus_policy = that->textbox_focus_policy;
+ forward_render_displacement = that->forward_render_displacement;
dvd_yuv420p_interlace = that->dvd_yuv420p_interlace;
renderfarm_nodes.remove_all_objects();
renderfarm_ports.remove_all();
bd_warn_root = defaults->get("BD_WARN_ROOT", bd_warn_root);
popupmenu_btnup = defaults->get("POPUPMENU_BTNUP", popupmenu_btnup);
textbox_focus_policy = defaults->get("TEXTBOX_FOCUS_POLICY", textbox_focus_policy);
+ forward_render_displacement = defaults->get("FORWARD_RENDER_DISPLACEMENT", forward_render_displacement);
dvd_yuv420p_interlace = defaults->get("DVD_YUV420P_INTERLACE", dvd_yuv420p_interlace);
use_brender = defaults->get("USE_BRENDER", use_brender);
brender_fragment = defaults->get("BRENDER_FRAGMENT", brender_fragment);
defaults->update("BD_WARN_ROOT", bd_warn_root);
defaults->update("POPUPMENU_BTNUP", popupmenu_btnup);
defaults->update("TEXTBOX_FOCUS_POLICY", textbox_focus_policy);
+ defaults->update("FORWARD_RENDER_DISPLACEMENT", forward_render_displacement);
defaults->update("DVD_YUV420P_INTERLACE", dvd_yuv420p_interlace);
brender_asset->save_defaults(defaults, "BRENDER_", 1, 1, 1, 0, 0);
defaults->update("USE_BRENDER", use_brender);
int popupmenu_btnup;
// textbox focus policy: click, leave
int textbox_focus_policy;
+// forward playback starts next frame, not this frame
+ int forward_render_displacement;
// use dvd yuv420p interlace format
int dvd_yuv420p_interlace;
}
}
+ if( playback_engine->is_playing_back && command->displacement ) {
+ double position = playback_engine->tracking_position -
+ 1./command->get_edl()->session->frame_rate;
+ playback_engine->tracking_position = position >= 0 ? position : 0;
+ }
+
if(!interrupted) playback_engine->command->command = STOP;
playback_engine->stop_tracking();
realtime = 0;
resume = 0;
audio_toggle = 0;
+ displacement = 0;
// Don't reset the change type for commands which don't perform the change
if(command != STOP) change_type = 0;
command = COMMAND_NONE;
this->realtime = command->realtime;
this->resume = command->resume;
this->audio_toggle = command->audio_toggle;
+ this->displacement = command->displacement;
}
TransportCommand& TransportCommand::operator=(TransportCommand &command)
}
// Assume starting without pause
-void TransportCommand::set_playback_range(EDL *edl, int use_inout, int toggle_audio)
+void TransportCommand::set_playback_range(EDL *edl,
+ int use_inout, int toggle_audio, int use_displacement)
{
if(!edl) edl = this->edl;
- switch(command)
- {
+ double length = edl->tracks->total_playable_length();
+ double frame_period = 1.0 / edl->session->frame_rate;
+ double start = edl->local_session->get_selectionstart(1);
+ double end = edl->local_session->get_selectionend(1);
+
+ displacement = 0;
+ if( use_inout ) {
+ if( edl->local_session->inpoint_valid() )
+ start_position = edl->local_session->get_inpoint();
+ if( edl->local_session->outpoint_valid() )
+ end_position = edl->local_session->get_outpoint();
+ }
+ else if( !EQUIV(start, end) ) {
+ start_position = start;
+ end_position = end;
+ }
+ else {
+ switch( command ) {
case SLOW_FWD:
case FAST_FWD:
- case NORMAL_FWD:
- start_position = edl->local_session->get_selectionstart(1);
- if(EQUIV(edl->local_session->get_selectionend(1), edl->local_session->get_selectionstart(1)))
- end_position = edl->tracks->total_playable_length();
- else
- end_position = edl->local_session->get_selectionend(1);
+ case NORMAL_FWD: {
+ start_position = start;
+ end_position = length;
// this prevents a crash if start position is after the loop when playing forwards
- if (edl->local_session->loop_playback &&
- start_position > edl->local_session->loop_end)
- {
- start_position = edl->local_session->loop_start;
+ if( edl->local_session->loop_playback &&
+ start_position > edl->local_session->loop_end ) {
+ start_position = edl->local_session->loop_start;
}
- break;
+ break; }
case SLOW_REWIND:
case FAST_REWIND:
case NORMAL_REWIND:
- end_position = edl->local_session->get_selectionend(1);
- if(EQUIV(edl->local_session->get_selectionend(1), edl->local_session->get_selectionstart(1)))
- start_position = 0;
- else
- start_position = edl->local_session->get_selectionstart(1);
-
+ end_position = end;
+ start_position = 0;
// this prevents a crash if start position is before the loop when playing backwards
- if (edl->local_session->loop_playback &&
- end_position <= edl->local_session->loop_start)
- {
+ if( edl->local_session->loop_playback &&
+ end_position <= edl->local_session->loop_start ) {
end_position = edl->local_session->loop_end;
}
break;
case CURRENT_FRAME:
case SINGLE_FRAME_FWD:
- start_position = edl->local_session->get_selectionstart(1);
- end_position = start_position + 1.0 / edl->session->frame_rate;
+ start_position = start;
+ end_position = start_position + frame_period;
break;
case SINGLE_FRAME_REWIND:
- end_position = edl->local_session->get_selectionend(1);
- start_position = end_position - 1.0 / edl->session->frame_rate;
- break;
- }
-
-
- if(use_inout)
- {
- if(edl->local_session->inpoint_valid())
- start_position = edl->local_session->get_inpoint();
- if(edl->local_session->outpoint_valid())
- end_position = edl->local_session->get_outpoint();
- }
-
- switch(get_direction())
- {
- case PLAY_FORWARD:
- playbackstart = start_position;
+ end_position = end;
+ start_position = end_position - frame_period;
break;
+ }
- case PLAY_REVERSE:
- playbackstart = end_position;
- break;
+ if( use_displacement && command != CURRENT_FRAME &&
+ get_direction() == PLAY_FORWARD ) {
+ start_position += frame_period;
+ end_position += frame_period;
+ displacement = 1;
+ }
}
+ playbackstart = get_direction() == PLAY_FORWARD ? start_position : end_position;
audio_toggle = toggle_audio;
}
delete output_lock;
}
-int TransportQue::send_command(int command, int change_type, EDL *new_edl,
- int realtime, int resume, int use_inout, int toggle_audio)
+int TransportQue::send_command(int command, int change_type,
+ EDL *new_edl, int realtime, int resume,
+ int use_inout, int toggle_audio, int use_displacement)
{
input_lock->lock("TransportQue::send_command 1");
this->command.command = command;
}
// Set playback range
- this->command.set_playback_range(new_edl, use_inout, toggle_audio);
+ this->command.set_playback_range(new_edl,
+ use_inout, toggle_audio, use_displacement);
}
input_lock->unlock();
void copy_from(TransportCommand *command);
TransportCommand& operator=(TransportCommand &command);
// Get the range to play back from the EDL
- void set_playback_range(EDL *edl=0, int use_inout=0, int toggle_audio=0);
+ void set_playback_range(EDL *edl=0,
+ int use_inout=0, int toggle_audio=0, int use_displacement=0);
// Adjust playback range with in/out points for rendering
void playback_range_adjust_inout();
int infinite;
// Position used when starting playback
double playbackstart;
+// start position at this=0/next=1 frame
+ int displacement;
// Send output to device
int realtime;
// Use persistant starting point
// Persistent starting point
int resume = 0,
int use_inout = 0,
- int toggle_audio = 0);
+ int toggle_audio = 0,
+ int use_displacement = 0);
void update_change_type(int change_type);
TransportCommand command;
// before we start dropping.
int64_t current_sample, start_sample, end_sample; // Absolute counts.
int64_t skip_countdown = VRENDER_THRESHOLD; // frames remaining until drop
- int64_t delay_countdown = VRENDER_THRESHOLD; // Frames remaining until delay
+ int64_t delay_countdown = 0; // Frames remaining until delay
// Number of frames before next reconfigure
int64_t current_input_length;
// Number of frames to skip.
current_sample = (int64_t)(renderengine->sync_position() *
renderengine->command->get_speed());
// latest sample at which the frame can be shown.
- end_sample = Units::tosamples(session_frame,
+ end_sample = Units::tosamples(session_frame + 1,
renderengine->get_edl()->session->sample_rate,
renderengine->get_edl()->session->frame_rate);
// earliest sample by which the frame needs to be shown.
- start_sample = Units::tosamples(session_frame - 1,
+ start_sample = Units::tosamples(session_frame,
renderengine->get_edl()->session->sample_rate,
renderengine->get_edl()->session->frame_rate);
# plugin info
#
# Name of plugin followed by: and then description.
-# Additional lines start with a blank/tab.
+# Additional lines start with 2 tabs.
+# Lines should be less than 70 characters long.
+# For usage/readability, a period (.) creates space.
#
1080 to 480: Extracts 2 1920x540 fields from 1920x1080
image, resizes them separately, and
IrisSquare: Video switches segments via a small rectangular view
that gradually grows to full size.
Shape Wipe: Wipe a specific shape across the video. Available
- shapes are: circle, clock, heart, tile2x2h, tile2x2v.
+ shapes are: burst, circle, clock, heart, specks, spiral,
+ tile2x2h, tile2x2v.
Slide: Image slides into view - can set: Left/Right/In/Out.
Wipe: Wipe the image across screen starting left or right.
Zoom: Zoom out video at X/Y magnification for some seconds.