r105: This commit was manufactured by cvs2svn to create tag
[cinelerra_cv/mob.git] / hvirtual / cinelerra / transportque.C
blob7cdafacfa4ff17b588f21be8d12669ae855fa8b1
1 #include "clip.h"
2 #include "edl.h"
3 #include "edlsession.h"
4 #include "localsession.h"
5 #include "tracks.h"
6 #include "transportque.h"
8 TransportCommand::TransportCommand()
10 // In rendering we want a master EDL so settings don't get clobbered
11 // in the middle of a job.
12         edl = new EDL;
13         edl->create_objects();
14         reset();
15         command = 0;
16         change_type = 0;
19 TransportCommand::~TransportCommand()
21         delete edl;
24 void TransportCommand::reset()
26         playbackstart = 0;
27         start_position = 0;
28         end_position = 0;
29         infinite = 0;
30         realtime = 0;
31         resume = 0;
32 // Don't reset the change type for commands which don't perform the change
33         if(command != STOP) change_type = 0;
34         command = COMMAND_NONE;
37 EDL* TransportCommand::get_edl()
39         return edl;
42 TransportCommand& TransportCommand::operator=(TransportCommand &command)
44         this->command = command.command;
45         this->change_type = command.change_type;
46 //printf("TransportCommand::operator= 1\n");
47         *this->edl = *command.edl;
48 //printf("TransportCommand::operator= 2\n");
49         this->start_position = command.start_position;
50         this->end_position = command.end_position;
51         this->playbackstart = command.playbackstart;
52         this->realtime = command.realtime;
53         this->resume = command.resume;
54         return *this;
57 int TransportCommand::single_frame()
59         return (command == SINGLE_FRAME_FWD ||
60                 command == SINGLE_FRAME_REWIND ||
61                 command == CURRENT_FRAME);
65 int TransportCommand::get_direction()
67         switch(command)
68         {
69                 case SINGLE_FRAME_FWD:
70                 case NORMAL_FWD:
71                 case FAST_FWD:
72                 case SLOW_FWD:
73                 case CURRENT_FRAME:
74                         return PLAY_FORWARD;
75                         break;
77                 case SINGLE_FRAME_REWIND:
78                 case NORMAL_REWIND:
79                 case FAST_REWIND:
80                 case SLOW_REWIND:
81                         return PLAY_REVERSE;
82                         break;
84                 default:
85                         return PLAY_FORWARD;
86                         break;
87         }
90 float TransportCommand::get_speed()
92         switch(command)
93         {
94                 case SLOW_FWD:
95                 case SLOW_REWIND:
96                         return 0.5;
97                         break;
98                 
99                 case NORMAL_FWD:
100                 case NORMAL_REWIND:
101                 case SINGLE_FRAME_FWD:
102                 case SINGLE_FRAME_REWIND:
103                 case CURRENT_FRAME:
104                         return 1;
105                         break;
106                 
107                 case FAST_FWD:
108                 case FAST_REWIND:
109                         return 2;
110                         break;
111         }
114 // Assume starting without pause
115 void TransportCommand::set_playback_range(EDL *edl)
117         switch(command)
118         {
119                 case SLOW_FWD:
120                 case FAST_FWD:
121                 case NORMAL_FWD:
122                         start_position = edl->local_session->selectionstart;
123                         if(EQUIV(edl->local_session->selectionend, edl->local_session->selectionstart))
124                                 end_position = edl->tracks->total_playable_length();
125                         else
126                                 end_position = edl->local_session->selectionend;
127 // this prevents a crash if start position is after the loop when playing forwards
128                     if (edl->local_session->loop_playback && start_position > edl->local_session->loop_end)  
129                         {
130                                     start_position = edl->local_session->loop_start;
131                         }
132                         break;
133                 
134                 case SLOW_REWIND:
135                 case FAST_REWIND:
136                 case NORMAL_REWIND:
137                         end_position = edl->local_session->selectionend;
138                         if(EQUIV(edl->local_session->selectionend, edl->local_session->selectionstart))
139                                 start_position = 0;
140                         else
141                                 start_position = edl->local_session->selectionstart;
142 // this prevents a crash if start position is before the loop when playing backwards
143                         if (edl->local_session->loop_playback && start_position <= edl->local_session->loop_start)
144                         {
145                                         start_position = edl->local_session->loop_end;
146                                         end_position = edl->local_session->loop_end;
147                         }
148                         break;
149                 
150                 case CURRENT_FRAME:
151                 case SINGLE_FRAME_FWD:
152                         start_position = edl->local_session->selectionstart;
153                         end_position = start_position + 
154                                 1.0 / 
155                                 edl->session->frame_rate;
156                         break;
157                 
158                 case SINGLE_FRAME_REWIND:
159                         start_position = edl->local_session->selectionend;
160                         end_position = start_position - 
161                                 1.0 / 
162                                 edl->session->frame_rate;
163                         break;
164         }
166         switch(get_direction())
167         {
168                 case PLAY_FORWARD:
169                         playbackstart = start_position;
170                         break;
172                 case PLAY_REVERSE:
173                         playbackstart = end_position;
174                         break;
175         }
176 // printf("TransportCommand::set_playback_range %f %f\n", 
177 // start_position * edl->session->frame_rate, 
178 // end_position * edl->session->frame_rate);
198 TransportQue::TransportQue()
200         output_lock.lock();
203 TransportQue::~TransportQue()
207 int TransportQue::send_command(int command, 
208                 int change_type, 
209                 EDL *new_edl, 
210                 int realtime,
211                 int resume)
213 //printf("TransportQue::send_command 1\n");
214         input_lock.lock();
215         this->command.command = command;
216 // Mutually exclusive operation
217         this->command.change_type |= change_type;
218 //printf("TransportQue::send_command 1 %x\n", change_type);
219 //      if(command == STOP)
220 //              this->command.change_type = CHANGE_NONE;
221 //printf("TransportQue::send_command 2\n");
223         this->command.realtime = realtime;
224         this->command.resume = resume;
226         if(new_edl)
227         {
228 // Just change the EDL if the change requires it because renderengine
229 // structures won't point to the new EDL otherwise and because copying the
230 // EDL for every cursor movement is slow.
231                 if(change_type == CHANGE_EDL ||
232                         change_type == CHANGE_ALL)
233                 {
234 // Copy EDL
235                         *this->command.get_edl() = *new_edl;
236                 }
237                 else
238                 if(change_type == CHANGE_PARAMS)
239                 {
240                         this->command.get_edl()->synchronize_params(new_edl);
241                 }
243 // Set playback range
244                 this->command.set_playback_range(new_edl);
245         }
247 //printf("TransportQue::send_command 3\n");
248 //printf("TransportQue::send_command 2 %p %d %d\n", new_edl, this->command.playbackstart);
249         input_lock.unlock();
250         output_lock.unlock();
251 //printf("TransportQue::send_command 4\n");
252         return 0;
255 void TransportQue::update_change_type(int change_type)
257         input_lock.lock();
258         this->command.change_type |= change_type;
259         input_lock.unlock();