00001 #include "bcsignals.h"
00002 #include "clip.h"
00003 #include "condition.h"
00004 #include "edl.h"
00005 #include "edlsession.h"
00006 #include "localsession.h"
00007 #include "tracks.h"
00008 #include "transportque.h"
00009
00010 TransportCommand::TransportCommand()
00011 {
00012
00013
00014 edl = new EDL;
00015 edl->create_objects();
00016 command = 0;
00017 change_type = 0;
00018 reset();
00019 }
00020
00021 TransportCommand::~TransportCommand()
00022 {
00023 delete edl;
00024 }
00025
00026 void TransportCommand::reset()
00027 {
00028 playbackstart = 0;
00029 start_position = 0;
00030 end_position = 0;
00031 infinite = 0;
00032 realtime = 0;
00033 resume = 0;
00034
00035 if(command != STOP) change_type = 0;
00036 command = COMMAND_NONE;
00037 }
00038
00039 EDL* TransportCommand::get_edl()
00040 {
00041 return edl;
00042 }
00043
00044 void TransportCommand::delete_edl()
00045 {
00046 delete edl;
00047 edl = 0;
00048 }
00049
00050 void TransportCommand::new_edl()
00051 {
00052 edl = new EDL;
00053 edl->create_objects();
00054 }
00055
00056
00057 void TransportCommand::copy_from(TransportCommand *command)
00058 {
00059 this->command = command->command;
00060 this->change_type = command->change_type;
00061 this->edl->copy_all(command->edl);
00062 this->start_position = command->start_position;
00063 this->end_position = command->end_position;
00064 this->playbackstart = command->playbackstart;
00065 this->realtime = command->realtime;
00066 this->resume = command->resume;
00067 }
00068
00069 TransportCommand& TransportCommand::operator=(TransportCommand &command)
00070 {
00071 copy_from(&command);
00072 return *this;
00073 }
00074
00075 int TransportCommand::single_frame()
00076 {
00077 return (command == SINGLE_FRAME_FWD ||
00078 command == SINGLE_FRAME_REWIND ||
00079 command == CURRENT_FRAME);
00080 }
00081
00082
00083 int TransportCommand::get_direction()
00084 {
00085 switch(command)
00086 {
00087 case SINGLE_FRAME_FWD:
00088 case NORMAL_FWD:
00089 case FAST_FWD:
00090 case SLOW_FWD:
00091 case CURRENT_FRAME:
00092 return PLAY_FORWARD;
00093 break;
00094
00095 case SINGLE_FRAME_REWIND:
00096 case NORMAL_REWIND:
00097 case FAST_REWIND:
00098 case SLOW_REWIND:
00099 return PLAY_REVERSE;
00100 break;
00101
00102 default:
00103 return PLAY_FORWARD;
00104 break;
00105 }
00106 }
00107
00108 float TransportCommand::get_speed()
00109 {
00110 switch(command)
00111 {
00112 case SLOW_FWD:
00113 case SLOW_REWIND:
00114 return 0.5;
00115 break;
00116
00117 case NORMAL_FWD:
00118 case NORMAL_REWIND:
00119 case SINGLE_FRAME_FWD:
00120 case SINGLE_FRAME_REWIND:
00121 case CURRENT_FRAME:
00122 return 1;
00123 break;
00124
00125 case FAST_FWD:
00126 case FAST_REWIND:
00127 return 2;
00128 break;
00129 }
00130 }
00131
00132
00133 void TransportCommand::set_playback_range(EDL *edl, int use_inout)
00134 {
00135 if(!edl) edl = this->edl;
00136
00137
00138
00139
00140 switch(command)
00141 {
00142 case SLOW_FWD:
00143 case FAST_FWD:
00144 case NORMAL_FWD:
00145 start_position = edl->local_session->get_selectionstart(1);
00146 if(EQUIV(edl->local_session->get_selectionend(1), edl->local_session->get_selectionstart(1)))
00147 end_position = edl->tracks->total_playable_length();
00148 else
00149 end_position = edl->local_session->get_selectionend(1);
00150
00151 if (edl->local_session->loop_playback && start_position > edl->local_session->loop_end)
00152 {
00153 start_position = edl->local_session->loop_start;
00154 }
00155 break;
00156
00157 case SLOW_REWIND:
00158 case FAST_REWIND:
00159 case NORMAL_REWIND:
00160 end_position = edl->local_session->get_selectionend(1);
00161 if(EQUIV(edl->local_session->get_selectionend(1), edl->local_session->get_selectionstart(1)))
00162 start_position = 0;
00163 else
00164 start_position = edl->local_session->get_selectionstart(1);
00165
00166 if (edl->local_session->loop_playback && start_position <= edl->local_session->loop_start)
00167 {
00168 start_position = edl->local_session->loop_end;
00169 end_position = edl->local_session->loop_end;
00170 }
00171 break;
00172
00173 case CURRENT_FRAME:
00174 case SINGLE_FRAME_FWD:
00175 start_position = edl->local_session->get_selectionstart(1);
00176 end_position = start_position +
00177 1.0 /
00178 edl->session->frame_rate;
00179 break;
00180
00181 case SINGLE_FRAME_REWIND:
00182 start_position = edl->local_session->get_selectionend(1);
00183 end_position = start_position -
00184 1.0 /
00185 edl->session->frame_rate;
00186 break;
00187 }
00188
00189
00190 if(use_inout)
00191 {
00192 if(edl->local_session->inpoint_valid())
00193 start_position = edl->local_session->get_inpoint();
00194 if(edl->local_session->outpoint_valid())
00195 end_position = edl->local_session->get_outpoint();
00196 }
00197
00198 switch(get_direction())
00199 {
00200 case PLAY_FORWARD:
00201 playbackstart = start_position;
00202 break;
00203
00204 case PLAY_REVERSE:
00205 playbackstart = end_position;
00206 break;
00207 }
00208
00209 }
00210
00211 void TransportCommand::adjust_playback_range()
00212 {
00213
00214
00215 if(edl->local_session->inpoint_valid() ||
00216 edl->local_session->outpoint_valid())
00217 {
00218 if(edl->local_session->inpoint_valid())
00219 start_position = edl->local_session->get_inpoint();
00220 else
00221 start_position = 0;
00222
00223 if(edl->local_session->outpoint_valid())
00224 end_position = edl->local_session->get_outpoint();
00225 else
00226 end_position = edl->tracks->total_playable_length();
00227 }
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 TransportQue::TransportQue()
00248 {
00249 input_lock = new Condition(1, "TransportQue::input_lock");
00250 output_lock = new Condition(0, "TransportQue::output_lock");
00251 }
00252
00253 TransportQue::~TransportQue()
00254 {
00255 delete input_lock;
00256 delete output_lock;
00257 }
00258
00259 int TransportQue::send_command(int command,
00260 int change_type,
00261 EDL *new_edl,
00262 int realtime,
00263 int resume,
00264 int use_inout)
00265 {
00266 input_lock->lock("TransportQue::send_command 1");
00267 this->command.command = command;
00268
00269 this->command.change_type |= change_type;
00270 this->command.realtime = realtime;
00271 this->command.resume = resume;
00272
00273 if(new_edl)
00274 {
00275
00276
00277
00278 if(change_type == CHANGE_EDL ||
00279 change_type == CHANGE_ALL)
00280 {
00281
00282 this->command.get_edl()->copy_all(new_edl);
00283 }
00284 else
00285 if(change_type == CHANGE_PARAMS)
00286 {
00287 this->command.get_edl()->synchronize_params(new_edl);
00288 }
00289
00290
00291 this->command.set_playback_range(new_edl, use_inout);
00292 }
00293
00294 input_lock->unlock();
00295
00296 output_lock->unlock();
00297 return 0;
00298 }
00299
00300 void TransportQue::update_change_type(int change_type)
00301 {
00302 input_lock->lock("TransportQue::update_change_type");
00303 this->command.change_type |= change_type;
00304 input_lock->unlock();
00305 }