#include "edl.h"
#include "edlsession.h"
#include "localsession.h"
+#include "playbackengine.h"
+#include "preferences.h"
#include "tracks.h"
#include "transportque.h"
-TransportCommand::TransportCommand()
+
+TransportCommand::TransportCommand(Preferences *preferences)
{
// In rendering we want a master EDL so settings don't get clobbered
// in the middle of a job.
edl->create_objects();
command = 0;
change_type = 0;
+ this->preferences = preferences;
reset();
}
void TransportCommand::reset()
{
+ command = COMMAND_NONE;
+ change_type = 0;
playbackstart = 0;
start_position = 0;
end_position = 0;
infinite = 0;
realtime = 0;
resume = 0;
- audio_toggle = 0;
- play_loop = 0;
+ locked = 0;
+ toggle_audio = 0;
+ loop_play = 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;
+ speed = 0;
}
EDL* TransportCommand::get_edl()
this->playbackstart = command->playbackstart;
this->realtime = command->realtime;
this->resume = command->resume;
- this->audio_toggle = command->audio_toggle;
- this->play_loop = command->play_loop;
+ this->locked = command->locked;
+ this->toggle_audio = command->toggle_audio;
+ this->loop_play = command->loop_play;
this->displacement = command->displacement;
+ this->speed = command->speed;
}
TransportCommand& TransportCommand::operator=(TransportCommand &command)
return (command == SINGLE_FRAME_FWD || command == SINGLE_FRAME_REWIND ||
command == CURRENT_FRAME || command == LAST_FRAME);
}
-int TransportCommand::single_frame()
-{
- return single_frame(command);
-}
-
int TransportCommand::get_direction(int command)
{
}
return PLAY_FORWARD;
}
-int TransportCommand::get_direction()
-{
- return get_direction(command);
-}
-float TransportCommand::get_speed(int command)
+float TransportCommand::get_speed(int command, float speed)
{
+// fast = 2.0, slow = 0.5
+// float my_fast_speed = 2.0;
+// float my_slow_speed = 0.5;
+float my_fast_speed = preferences->fast_speed;
+float my_slow_speed = preferences->slow_speed;
+
switch(command) {
case SLOW_FWD:
case SLOW_REWIND:
- return 0.5;
+ return speed ? speed : my_slow_speed;
case NORMAL_FWD:
case NORMAL_REWIND:
case FAST_FWD:
case FAST_REWIND:
- return 2.;
+ return speed ? speed : my_fast_speed;
}
return 0.;
}
-float TransportCommand::get_speed()
-{
- return get_speed(command);
-}
// Assume starting without pause
-void TransportCommand::set_playback_range(EDL *edl,
- int use_inout, int toggle_audio, int loop_play, int use_displacement)
+void TransportCommand::set_playback_range(EDL *edl, int use_inout, int do_displacement)
{
- if(!edl) edl = this->edl;
+ if( !edl ) edl = this->edl;
double length = edl->tracks->total_playable_length();
double frame_period = 1.0 / edl->session->frame_rate;
-
displacement = 0;
- audio_toggle = toggle_audio;
- play_loop = loop_play;
start_position = use_inout && edl->local_session->inpoint_valid() ?
edl->local_session->get_inpoint() :
end_position = use_inout && edl->local_session->outpoint_valid() ?
edl->local_session->get_outpoint() :
!loop_play ? edl->local_session->get_selectionend(1) : length;
+ if( start_position >= length )
+ length = edl->tracks->total_length();
- if( !use_inout && EQUIV(start_position, end_position) ) {
+ if( command == REWIND ) {
+ start_position = end_position = 0;
+ command = CURRENT_FRAME;
+ }
+ else if( command == GOTO_END ) {
+ start_position = end_position = length;
+ command = LAST_FRAME;
+ }
+ else if( !use_inout && EQUIV(start_position, end_position) ) {
// starting play at or past end_position, play to end_position of media (for mixers)
- if( start_position >= length )
- length = edl->tracks->total_length();
switch( command ) {
case SLOW_FWD:
case FAST_FWD:
start_position > edl->local_session->loop_end ) {
start_position = edl->local_session->loop_start;
}
+ displacement = realtime && do_displacement ? frame_period : 0;
break; }
case SLOW_REWIND:
}
break;
+ case SINGLE_FRAME_FWD:
+ displacement = realtime && do_displacement ? frame_period : 0;
case CURRENT_FRAME:
case LAST_FRAME:
- case SINGLE_FRAME_FWD:
end_position = start_position + frame_period;
break;
start_position = end_position - frame_period;
break;
}
-
- if( use_displacement && (
- (command != CURRENT_FRAME && get_direction() == PLAY_FORWARD ) ||
- (command != LAST_FRAME && get_direction() == PLAY_REVERSE ) ) ) {
- start_position += frame_period;
- end_position += frame_period;
- displacement = 1;
- }
+ start_position += displacement;
+ end_position += displacement;
}
-
+// if( start_position < 0 )
+// start_position = 0;
+// if( end_position > length )
+// end_position = length;
if( end_position < start_position )
end_position = start_position;
}
-TransportQue::TransportQue()
-{
- input_lock = new Condition(1, "TransportQue::input_lock");
- output_lock = new Condition(0, "TransportQue::output_lock", 1);
-}
-
-TransportQue::~TransportQue()
-{
- delete input_lock;
- 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 loop_play, int use_displacement)
-{
- input_lock->lock("TransportQue::send_command 1");
- this->command.command = command;
-// Mutually exclusive operation
- this->command.change_type |= change_type;
- this->command.realtime = realtime;
- this->command.resume = resume;
-
- if(new_edl)
- {
-// Just change the EDL if the change requires it because renderengine
-// structures won't point to the new EDL otherwise and because copying the
-// EDL for every cursor movement is slow.
- if(change_type == CHANGE_EDL ||
- (uint32_t)change_type == CHANGE_ALL)
- {
-// Copy EDL
- this->command.get_edl()->copy_all(new_edl);
- }
- else
- if(change_type == CHANGE_PARAMS)
- {
- this->command.get_edl()->synchronize_params(new_edl);
- }
-
-// Set playback range
- this->command.set_playback_range(new_edl, use_inout,
- toggle_audio, loop_play, use_displacement);
- }
-
- input_lock->unlock();
-
- output_lock->unlock();
- return 0;
-}
-
-void TransportQue::update_change_type(int change_type)
-{
- input_lock->lock("TransportQue::update_change_type");
- this->command.change_type |= change_type;
- input_lock->unlock();
-}