4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcsignals.h"
24 #include "condition.h"
26 #include "edlsession.h"
27 #include "localsession.h"
29 #include "transportque.h"
31 TransportCommand::TransportCommand()
33 // In rendering we want a master EDL so settings don't get clobbered
34 // in the middle of a job.
36 edl->create_objects();
42 TransportCommand::~TransportCommand()
44 edl->Garbage::remove_user();
47 void TransportCommand::reset()
55 // Don't reset the change type for commands which don't perform the change
56 if(command != STOP) change_type = 0;
57 command = COMMAND_NONE;
60 EDL* TransportCommand::get_edl()
65 void TransportCommand::delete_edl()
67 edl->Garbage::remove_user();
71 void TransportCommand::new_edl()
74 edl->create_objects();
78 void TransportCommand::copy_from(TransportCommand *command)
80 this->command = command->command;
81 this->change_type = command->change_type;
82 this->edl->copy_all(command->edl);
83 this->start_position = command->start_position;
84 this->end_position = command->end_position;
85 this->playbackstart = command->playbackstart;
86 this->realtime = command->realtime;
87 this->resume = command->resume;
90 TransportCommand& TransportCommand::operator=(TransportCommand &command)
96 int TransportCommand::single_frame()
98 return (command == SINGLE_FRAME_FWD ||
99 command == SINGLE_FRAME_REWIND ||
100 command == CURRENT_FRAME);
104 int TransportCommand::get_direction()
108 case SINGLE_FRAME_FWD:
116 case SINGLE_FRAME_REWIND:
129 float TransportCommand::get_speed()
139 case SINGLE_FRAME_FWD:
140 case SINGLE_FRAME_REWIND:
152 // Assume starting without pause
153 void TransportCommand::set_playback_range(EDL *edl, int use_inout)
155 if(!edl) edl = this->edl;
165 start_position = edl->local_session->get_selectionstart(1);
166 if(EQUIV(edl->local_session->get_selectionend(1), edl->local_session->get_selectionstart(1)))
167 end_position = edl->tracks->total_playable_length();
169 end_position = edl->local_session->get_selectionend(1);
170 // this prevents a crash if start position is after the loop when playing forwards
171 if (edl->local_session->loop_playback &&
172 start_position > edl->local_session->loop_end)
174 start_position = edl->local_session->loop_start;
181 end_position = edl->local_session->get_selectionend(1);
182 if(EQUIV(edl->local_session->get_selectionend(1), edl->local_session->get_selectionstart(1)))
185 start_position = edl->local_session->get_selectionstart(1);
187 // this prevents a crash if start position is before the loop when playing backwards
188 if (edl->local_session->loop_playback &&
189 end_position <= edl->local_session->loop_start)
191 end_position = edl->local_session->loop_end;
196 case SINGLE_FRAME_FWD:
197 start_position = edl->local_session->get_selectionstart(1);
198 end_position = start_position +
200 edl->session->frame_rate;
203 case SINGLE_FRAME_REWIND:
204 start_position = edl->local_session->get_selectionend(1);
205 end_position = start_position -
207 edl->session->frame_rate;
214 if(edl->local_session->inpoint_valid())
215 start_position = edl->local_session->get_inpoint();
216 if(edl->local_session->outpoint_valid())
217 end_position = edl->local_session->get_outpoint();
220 switch(get_direction())
223 playbackstart = start_position;
227 playbackstart = end_position;
233 void TransportCommand::adjust_playback_range()
237 if(edl->local_session->inpoint_valid() ||
238 edl->local_session->outpoint_valid())
240 if(edl->local_session->inpoint_valid())
241 start_position = edl->local_session->get_inpoint();
245 if(edl->local_session->outpoint_valid())
246 end_position = edl->local_session->get_outpoint();
248 end_position = edl->tracks->total_playable_length();
269 TransportQue::TransportQue()
271 input_lock = new Condition(1, "TransportQue::input_lock");
272 output_lock = new Condition(0, "TransportQue::output_lock", 1);
275 TransportQue::~TransportQue()
281 int TransportQue::send_command(int command,
288 input_lock->lock("TransportQue::send_command 1");
289 this->command.command = command;
290 // Mutually exclusive operation
291 this->command.change_type |= change_type;
292 this->command.realtime = realtime;
293 this->command.resume = resume;
297 // Just change the EDL if the change requires it because renderengine
298 // structures won't point to the new EDL otherwise and because copying the
299 // EDL for every cursor movement is slow.
300 if(change_type == CHANGE_EDL ||
301 (uint32_t)change_type == CHANGE_ALL)
304 this->command.get_edl()->copy_all(new_edl);
307 if(change_type == CHANGE_PARAMS)
309 this->command.get_edl()->synchronize_params(new_edl);
312 // Set playback range
313 this->command.set_playback_range(new_edl, use_inout);
316 input_lock->unlock();
318 output_lock->unlock();
322 void TransportQue::update_change_type(int change_type)
324 input_lock->lock("TransportQue::update_change_type");
325 this->command.change_type |= change_type;
326 input_lock->unlock();