else
// Interpolate
{
- double loop_start = command->get_edl()->local_session->loop_start;
- double loop_end = command->get_edl()->local_session->loop_end;
+ double loop_start, loop_end;
+ int play_loop = command->play_loop ? 1 : 0;
+ EDL *edl = command->get_edl();
+ int loop_playback = edl->local_session->loop_playback ? 1 : 0;
+ if( play_loop || !loop_playback ) {
+ loop_start = command->start_position;
+ loop_end = command->end_position;
+ }
+ else {
+ loop_start = edl->local_session->loop_start;
+ loop_end = edl->local_session->loop_end;
+ play_loop = 1;
+ }
double loop_size = loop_end - loop_start;
- if(command->get_direction() == PLAY_FORWARD)
- {
+ if( command->get_direction() == PLAY_FORWARD ) {
// Interpolate
result = tracking_position +
command->get_speed() *
// Compensate for loop
//printf("PlaybackEngine::get_tracking_position 1 %d\n", command->get_edl()->local_session->loop_playback);
- if(command->get_edl()->local_session->loop_playback)
- {
- while(result > loop_end) result -= loop_size;
+ if( play_loop && loop_size > 0 ) {
+ while( result > loop_end ) result -= loop_size;
}
}
- else
- {
+ else {
// Interpolate
result = tracking_position -
command->get_speed() *
1000.0;
// Compensate for loop
- if(command->get_edl()->local_session->loop_playback)
- {
- while(result < loop_start) result += loop_size;
+ if( play_loop && loop_size > 0 ) {
+ while( result < loop_start ) result += loop_size;
}
}
{
start_lock->unlock();
- do
- {
+ while( !done ) {
// Wait for current command to finish
que->output_lock->lock("PlaybackEngine::run");
-
wait_render_engine();
-
// Read the new command
que->input_lock->lock("PlaybackEngine::run");
if(done) return;
command->copy_from(&que->command);
que->command.reset();
que->input_lock->unlock();
-
//printf("PlaybackEngine::run 1 %d\n", command->command);
-
- switch(command->command)
- {
+ switch( command->command ) {
// Parameter change only
- case COMMAND_NONE:
-// command->command = last_command;
- perform_change();
- break;
-
- case PAUSE:
- init_cursor(0);
- pause_lock->lock("PlaybackEngine::run");
- stop_cursor();
- break;
-
- case STOP:
+ case COMMAND_NONE:
+// command->command = last_command;
+ perform_change();
+ break;
+
+ case PAUSE:
+ init_cursor(0);
+ pause_lock->lock("PlaybackEngine::run");
+ stop_cursor();
+ break;
+
+ case STOP:
// No changing
- break;
+ break;
- case CURRENT_FRAME:
- last_command = command->command;
- perform_change();
- arm_render_engine();
+ case CURRENT_FRAME:
+ case LAST_FRAME:
+ last_command = command->command;
+ perform_change();
+ arm_render_engine();
// Dispatch the command
- start_render_engine();
- break;
-
- default:
- last_command = command->command;
- is_playing_back = 1;
- if(command->command == SINGLE_FRAME_FWD ||
- command->command == SINGLE_FRAME_REWIND)
- {
- command->playbackstart = get_tracking_position();
- }
+ start_render_engine();
+ break;
+
+ case SINGLE_FRAME_FWD:
+ case SINGLE_FRAME_REWIND:
+// fall through
+ default:
+ last_command = command->command;
+ is_playing_back = 1;
- perform_change();
- arm_render_engine();
+ perform_change();
+ arm_render_engine();
// Start tracking after arming so the tracking position doesn't change.
// The tracking for a single frame command occurs during PAUSE
- init_tracking();
+ init_tracking();
// Dispatch the command
- start_render_engine();
- break;
+ start_render_engine();
+ break;
}
//printf("PlaybackEngine::run 100\n");
- }while(!done);
+ }
}
+void PlaybackEngine::stop_playback(int wait)
+{
+ que->send_command(STOP, CHANGE_NONE, 0, 0);
+ interrupt_playback(wait);
+ renderengine_lock->lock("PlaybackEngine::stop_playback");
+ if(render_engine)
+ render_engine->wait_done();
+ renderengine_lock->unlock();
+}
+
+
+void PlaybackEngine::issue_command(EDL *edl, int command, int wait_tracking,
+ int use_inout, int update_refresh, int toggle_audio, int loop_play)
+{
+//printf("PlaybackEngine::issue_command 1 %d\n", command);
+// Stop requires transferring the output buffer to a refresh buffer.
+ int do_stop = 0, resume = 0;
+ int prev_command = this->command->command;
+ int prev_single_frame = this->command->single_frame();
+ int prev_audio = this->command->audio_toggle ?
+ !prev_single_frame : prev_single_frame;
+ int cur_single_frame = TransportCommand::single_frame(command);
+ int cur_audio = toggle_audio ?
+ !cur_single_frame : cur_single_frame;
+
+// Dispatch command
+ switch(command) {
+ case FAST_REWIND: // Commands that play back
+ case NORMAL_REWIND:
+ case SLOW_REWIND:
+ case SINGLE_FRAME_REWIND:
+ case SINGLE_FRAME_FWD:
+ case SLOW_FWD:
+ case NORMAL_FWD:
+ case FAST_FWD:
+ case CURRENT_FRAME:
+ case LAST_FRAME:
+ if( !prev_single_frame &&
+ prev_command == command &&
+ cur_audio == prev_audio ) {
+// Same direction pressed twice and no change in audio state, Stop
+ do_stop = 1;
+ break;
+ }
+// Resume or change direction
+ switch( prev_command ) {
+ default:
+ que->send_command(STOP, CHANGE_NONE, 0, 0);
+ interrupt_playback(wait_tracking);
+ resume = 1;
+// fall through
+ case STOP:
+ case COMMAND_NONE:
+ case SINGLE_FRAME_FWD:
+ case SINGLE_FRAME_REWIND:
+ case CURRENT_FRAME:
+ case LAST_FRAME:
+// Start from scratch
+ que->send_command(command, CHANGE_NONE, edl,
+ 1, resume, use_inout, toggle_audio, loop_play,
+ mwindow->preferences->forward_render_displacement);
+ break;
+ }
+ break;
+
+// Commands that stop
+ case STOP:
+ case REWIND:
+ case GOTO_END:
+ do_stop = 1;
+ break;
+ }
+
+ if( do_stop ) {
+ que->send_command(STOP, CHANGE_NONE, 0, 0);
+ interrupt_playback(wait_tracking);
+ }
+}
+
+void PlaybackEngine::refresh_frame(int change_type, EDL *edl, int dir)
+{
+ que->send_command(dir >= 0 ? CURRENT_FRAME : LAST_FRAME,
+ change_type, edl, 1);
+}